Compare commits

...
3 Commits
Author SHA1 Message Date
Andreas Lierschaft dc89e6ee0c Drachenseelensystem entfernen (3/3): geloeschte Quelldateien aus Build entfernen
Letzter Schritt: game.2008.vcproj (6 <File>-Eintraege) und Makefile
(Quelldateiliste) verweisen nicht mehr auf DragonSoul.h/.cpp,
dragon_soul_table.h/.cpp, char_dragonsoul.cpp und questlua_dragonsoul.cpp -
diese Dateien wurden bereits im ersten Schritt geloescht.
2026-08-17 22:50:08 +02:00
Andreas Lierschaft 11db2b3870 Drachenseelensystem entfernen (2/3): DS-Code aus gemeinsam genutzten Dateien entfernen
Zweiter Schritt der vollstaendigen Entfernung des Drachenseelensystems
(Kernsystem + Alchemie/Refine, per Nutzerentscheidung komplett raus,
Drachenseelen sollen ueberhaupt nicht mehr aktivierbar sein).

Entfernt alle DragonSoul_*/DSManager-Aufrufe, ITEM_DS/ITEM_SPECIAL_DS/
ITEM_EXTRACT-Handling, das Drachenseelen-Inventar (pDSItems/wDSItemGrid),
Deck-Aktivierung, den Refine-Netzwerkpfad (HEADER_CG_DRAGON_SOUL_REFINE),
den GM-Befehl /dragon_soul sowie alle Aufrufstellen in char_item.cpp,
item.cpp, exchange.cpp, shop(Ex).cpp, input_db.cpp, input_main.cpp,
cmd(_gm).cpp.

Sicherheitsprinzip beachtet: numerische Enum-Werte, von denen andere,
bleibende Slot-Bereiche relativ abhaengen (v.a. BELT_INVENTORY_SLOT_START
via DRAGON_SOUL_EQUIP_SLOT_*, sowie EItemTypes' ITEM_DS/ITEM_SPECIAL_DS/
ITEM_EXTRACT vor ITEM_SECONDARY_COIN/RING/BELT), wurden bewusst NICHT
entfernt oder neu nummeriert, um Item-Positionen/-Typen bestehender
Spieler-Datenbankeintraege nicht stillschweigend zu verschieben - nur der
Code, der sie fuer Drachenseelen benutzt hat, wurde entfernt.
2026-08-17 22:48:27 +02:00
Andreas Lierschaft 18c6772d35 Drachenseelensystem entfernen (1/3): komplett eigene Dateien loeschen
Erster Schritt der vollstaendigen Entfernung des Drachenseelensystems.
Loescht DragonSoul.h/.cpp (DSManager), dragon_soul_table.h/.cpp,
char_dragonsoul.cpp, questlua_dragonsoul.cpp sowie die zugehoerige
Datentabelle dragon_soul_table.txt. Diese Dateien sind zu 100% auf das
Drachenseelensystem beschraenkt und werden komplett entfernt.

Der Build kompiliert nach diesem Zwischenschritt noch NICHT (verwaiste
#include "DragonSoul.h" und Aufrufe in weiteren Dateien folgen in einem
separaten Commit) - das ist innerhalb dieser mehrteiligen Entfernung
erwartet.
2026-08-17 22:18:27 +02:00
33 changed files with 11 additions and 3736 deletions
-39
View File
@@ -22,15 +22,9 @@ enum EItemMisc
const BYTE ITEM_SOCKET_REMAIN_SEC = 0; const BYTE ITEM_SOCKET_REMAIN_SEC = 0;
enum EItemValueIdice enum EItemValueIdice
{ {
ITEM_VALUE_DRAGON_SOUL_POLL_OUT_BONUS_IDX = 0,
ITEM_VALUE_CHARGING_AMOUNT_IDX = 0, ITEM_VALUE_CHARGING_AMOUNT_IDX = 0,
ITEM_VALUE_SECONDARY_COIN_UNIT_IDX = 0, ITEM_VALUE_SECONDARY_COIN_UNIT_IDX = 0,
}; };
enum EItemDragonSoulSockets
{
ITEM_SOCKET_DRAGON_SOUL_ACTIVE_IDX = 2,
ITEM_SOCKET_CHARGING_AMOUNT_IDX = 2,
};
// 헐 이거 미친거 아니야? // 헐 이거 미친거 아니야?
// 나중에 소켓 확장하면 어쩌려고 이지랄 -_-;;; // 나중에 소켓 확장하면 어쩌려고 이지랄 -_-;;;
enum EItemUniqueSockets enum EItemUniqueSockets
@@ -127,33 +121,6 @@ enum EDragonSoulSubType
DS_SLOT_MAX, DS_SLOT_MAX,
}; };
enum EDragonSoulGradeTypes
{
DRAGON_SOUL_GRADE_NORMAL,
DRAGON_SOUL_GRADE_BRILLIANT,
DRAGON_SOUL_GRADE_RARE,
DRAGON_SOUL_GRADE_ANCIENT,
DRAGON_SOUL_GRADE_LEGENDARY,
DRAGON_SOUL_GRADE_MAX,
};
enum EDragonSoulStepTypes
{
DRAGON_SOUL_STEP_LOWEST,
DRAGON_SOUL_STEP_LOW,
DRAGON_SOUL_STEP_MID,
DRAGON_SOUL_STEP_HIGH,
DRAGON_SOUL_STEP_HIGHEST,
DRAGON_SOUL_STEP_MAX,
};
#define DRAGON_SOUL_STRENGTH_MAX 7
enum EDSInventoryMaxNum
{
DRAGON_SOUL_INVENTORY_MAX_NUM = DS_SLOT_MAX * DRAGON_SOUL_GRADE_MAX * DRAGON_SOUL_BOX_SIZE,
};
enum EFishSubTypes enum EFishSubTypes
{ {
FISH_ALIVE, FISH_ALIVE,
@@ -219,12 +186,6 @@ enum EUseSubTypes
USE_PUT_INTO_RING_SOCKET, // 30 반지 소켓에 사용할 수 있는 아이템 (유니크 반지 말고, 새로 추가된 반지 슬롯) USE_PUT_INTO_RING_SOCKET, // 30 반지 소켓에 사용할 수 있는 아이템 (유니크 반지 말고, 새로 추가된 반지 슬롯)
}; };
enum EExtractSubTypes
{
EXTRACT_DRAGON_SOUL,
EXTRACT_DRAGON_HEART,
};
enum EAutoUseSubTypes enum EAutoUseSubTypes
{ {
AUTOUSE_POTION, AUTOUSE_POTION,
-8
View File
@@ -56,10 +56,6 @@ enum EMisc
MOB_SKILL_MAX_NUM = 5, MOB_SKILL_MAX_NUM = 5,
POINT_MAX_NUM = 255, POINT_MAX_NUM = 255,
DRAGON_SOUL_BOX_SIZE = 32,
DRAGON_SOUL_BOX_COLUMN_NUM = 8,
DRAGON_SOUL_BOX_ROW_NUM = DRAGON_SOUL_BOX_SIZE / DRAGON_SOUL_BOX_COLUMN_NUM,
DRAGON_SOUL_REFINE_GRID_SIZE = 15,
MAX_AMOUNT_OF_MALL_BONUS = 20, MAX_AMOUNT_OF_MALL_BONUS = 20,
WEAR_MAX_NUM = 32, WEAR_MAX_NUM = 32,
@@ -141,8 +137,6 @@ enum EWearPositions
enum EDragonSoulDeckType enum EDragonSoulDeckType
{ {
DRAGON_SOUL_DECK_0,
DRAGON_SOUL_DECK_1,
DRAGON_SOUL_DECK_MAX_NUM = 2, DRAGON_SOUL_DECK_MAX_NUM = 2,
DRAGON_SOUL_DECK_RESERVED_MAX_NUM = 3, // NOTE: 중요! 아직 사용중이진 않지만, 3페이지 분량을 예약 해 둠. DS DECK을 늘릴 경우 반드시 그 수만큼 RESERVED에서 차감해야 함! DRAGON_SOUL_DECK_RESERVED_MAX_NUM = 3, // NOTE: 중요! 아직 사용중이진 않지만, 3페이지 분량을 예약 해 둠. DS DECK을 늘릴 경우 반드시 그 수만큼 RESERVED에서 차감해야 함!
@@ -732,8 +726,6 @@ typedef struct SItemPos
case EQUIPMENT: case EQUIPMENT:
case BELT_INVENTORY: case BELT_INVENTORY:
return cell < INVENTORY_AND_EQUIP_SLOT_MAX; return cell < INVENTORY_AND_EQUIP_SLOT_MAX;
case DRAGON_SOUL_INVENTORY:
return cell < (DRAGON_SOUL_INVENTORY_MAX_NUM);
// 동적으로 크기가 정해지는 window는 valid 체크를 할 수가 없다. // 동적으로 크기가 정해지는 window는 valid 체크를 할 수가 없다.
case SAFEBOX: case SAFEBOX:
case MALL: case MALL:
File diff suppressed because it is too large Load Diff
-60
View File
@@ -1,60 +0,0 @@
#ifndef __INC_METIN_II_GAME_DRAGON_SOUL_H__
#define __INC_METIN_II_GAME_DRAGON_SOUL_H__
#include "../../common/length.h"
class CHARACTER;
class CItem;
class DragonSoulTable;
class DSManager : public singleton<DSManager>
{
public:
DSManager();
~DSManager();
bool ReadDragonSoulTableFile(const char * c_pszFileName);
void GetDragonSoulInfo(DWORD dwVnum, OUT BYTE& bType, OUT BYTE& bGrade, OUT BYTE& bStep, OUT BYTE& bRefine) const;
// fixme : titempos로
WORD GetBasePosition(const LPITEM pItem) const;
bool IsValidCellForThisItem(const LPITEM pItem, const TItemPos& Cell) const;
int GetDuration(const LPITEM pItem) const;
// 용혼석을 받아서 특정 용심을 추출하는 함수
bool ExtractDragonHeart(LPCHARACTER ch, LPITEM pItem, LPITEM pExtractor = NULL);
// 특정 용혼석(pItem)을 장비창에서 제거할 때에 성공 여부를 결정하고,
// 실패시 부산물을 주는 함수.(부산물은 dragon_soul_table.txt에 정의)
// DestCell에 invalid한 값을 넣으면 성공 시, 용혼석을 빈 공간에 자동 추가.
// 실패 시, 용혼석(pItem)은 delete됨.
// 추출아이템이 있다면 추출 성공 확률이 pExtractor->GetValue(0)%만큼 증가함.
// 부산물은 언제나 자동 추가.
bool PullOut(LPCHARACTER ch, TItemPos DestCell, IN OUT LPITEM& pItem, LPITEM pExtractor = NULL);
// 용혼석 업그레이드 함수
bool DoRefineGrade(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_SOUL_REFINE_GRID_SIZE]);
bool DoRefineStep(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_SOUL_REFINE_GRID_SIZE]);
bool DoRefineStrength(LPCHARACTER ch, TItemPos (&aItemPoses)[DRAGON_SOUL_REFINE_GRID_SIZE]);
bool DragonSoulItemInitialize(LPITEM pItem);
bool IsTimeLeftDragonSoul(LPITEM pItem) const;
int LeftTime(LPITEM pItem) const;
bool ActivateDragonSoul(LPITEM pItem);
bool DeactivateDragonSoul(LPITEM pItem, bool bSkipRefreshOwnerActiveState = false);
bool IsActiveDragonSoul(LPITEM pItem) const;
private:
void SendRefineResultPacket(LPCHARACTER ch, BYTE bSubHeader, const TItemPos& pos);
// 캐릭터의 용혼석 덱을 살펴보고, 활성화 된 용혼석이 없다면, 캐릭터의 용혼석 활성 상태를 off 시키는 함수.
void RefreshDragonSoulState(LPCHARACTER ch);
DWORD MakeDragonSoulVnum(BYTE bType, BYTE grade, BYTE step, BYTE refine);
bool PutAttributes(LPITEM pDS);
bool RefreshItemAttributes(LPITEM pItem);
DragonSoulTable* m_pTable;
};
#endif
+2 -2
View File
@@ -150,8 +150,8 @@ CPPFILE = BattleArena.cpp FSM.cpp MarkConvert.cpp MarkImage.cpp MarkManager.cpp
BlueDragon.cpp BlueDragon_Binder.cpp DragonLair.cpp questlua_dragonlair.cpp\ BlueDragon.cpp BlueDragon_Binder.cpp DragonLair.cpp questlua_dragonlair.cpp\
skill_power.cpp affect.cpp SpeedServer.cpp questlua_speedserver.cpp\ skill_power.cpp affect.cpp SpeedServer.cpp questlua_speedserver.cpp\
auction_manager.cpp FileMonitor_FreeBSD.cpp ClientPackageCryptInfo.cpp cipher.cpp\ auction_manager.cpp FileMonitor_FreeBSD.cpp ClientPackageCryptInfo.cpp cipher.cpp\
buff_on_attributes.cpp check_server.cpp dragon_soul_table.cpp DragonSoul.cpp\ buff_on_attributes.cpp check_server.cpp \
group_text_parse_tree.cpp char_dragonsoul.cpp questlua_dragonsoul.cpp\ group_text_parse_tree.cpp \
shop_manager.cpp shopEx.cpp item_manager_read_tables.cpp shop_manager.cpp shopEx.cpp item_manager_read_tables.cpp
ifeq ($(UNAME_S),Linux) ifeq ($(UNAME_S),Linux)
+3 -3
View File
@@ -95,9 +95,9 @@ enum EAffectTypes
AFFECT_AUTO_HP_RECOVERY = 534, AFFECT_AUTO_HP_RECOVERY = 534,
AFFECT_AUTO_SP_RECOVERY = 535, AFFECT_AUTO_SP_RECOVERY = 535,
AFFECT_DRAGON_SOUL_QUALIFIED = 540, // AFFECT_DRAGON_SOUL_QUALIFIED = 540, // reserviert, Drachenseelensystem entfernt, Werte nicht wiederverwenden (alte DB-Zeilen)
AFFECT_DRAGON_SOUL_DECK_0 = 541, // AFFECT_DRAGON_SOUL_DECK_0 = 541,
AFFECT_DRAGON_SOUL_DECK_1 = 542, // AFFECT_DRAGON_SOUL_DECK_1 = 542,
AFFECT_RAMADAN_ABILITY = 300, AFFECT_RAMADAN_ABILITY = 300,
-22
View File
@@ -60,7 +60,6 @@
#ifdef __PET_SYSTEM__ #ifdef __PET_SYSTEM__
#include "PetSystem.h" #include "PetSystem.h"
#endif #endif
#include "DragonSoul.h"
extern const BYTE g_aBuffOnAttrPoints; extern const BYTE g_aBuffOnAttrPoints;
extern bool RaceToJob(unsigned race, unsigned *ret_job); extern bool RaceToJob(unsigned race, unsigned *ret_job);
@@ -382,8 +381,6 @@ void CHARACTER::Initialize()
m_fAttMul = 1.0f; m_fAttMul = 1.0f;
m_fDamMul = 1.0f; m_fDamMul = 1.0f;
m_pointsInstant.iDragonSoulActiveDeck = -1;
memset(&m_tvLastSyncTime, 0, sizeof(m_tvLastSyncTime)); memset(&m_tvLastSyncTime, 0, sizeof(m_tvLastSyncTime));
m_iSyncHackCount = 0; m_iSyncHackCount = 0;
} }
@@ -469,7 +466,6 @@ void CHARACTER::Destroy()
if (NULL == m_pkMobData) if (NULL == m_pkMobData)
{ {
DragonSoul_CleanUp();
ClearItem(); ClearItem();
} }
@@ -2384,24 +2380,6 @@ void CHARACTER::ComputePoints()
} }
} }
// 용혼석 시스템
// ComputePoints에서는 케릭터의 모든 속성값을 초기화하고,
// 아이템, 버프 등에 관련된 모든 속성값을 재계산하기 때문에,
// 용혼석 시스템도 ActiveDeck에 있는 모든 용혼석의 속성값을 다시 적용시켜야 한다.
if (DragonSoul_IsDeckActivated())
{
for (int i = WEAR_MAX_NUM + DS_SLOT_MAX * DragonSoul_GetActiveDeck();
i < WEAR_MAX_NUM + DS_SLOT_MAX * (DragonSoul_GetActiveDeck() + 1); i++)
{
LPITEM pItem = GetWear(i);
if (pItem)
{
if (DSManager::instance().IsTimeLeftDragonSoul(pItem))
pItem->ModifyPoints(true);
}
}
}
if (GetHP() > GetMaxHP()) if (GetHP() > GetMaxHP())
PointChange(POINT_HP, GetMaxHP() - GetHP()); PointChange(POINT_HP, GetMaxHP() - GetHP());
-40
View File
@@ -397,10 +397,6 @@ typedef struct character_point_instant
LPITEM pItems[INVENTORY_AND_EQUIP_SLOT_MAX]; LPITEM pItems[INVENTORY_AND_EQUIP_SLOT_MAX];
BYTE bItemGrid[INVENTORY_AND_EQUIP_SLOT_MAX]; BYTE bItemGrid[INVENTORY_AND_EQUIP_SLOT_MAX];
// 용혼석 인벤토리.
LPITEM pDSItems[DRAGON_SOUL_INVENTORY_MAX_NUM];
WORD wDSItemGrid[DRAGON_SOUL_INVENTORY_MAX_NUM];
// by mhh // by mhh
LPITEM pCubeItems[CUBE_MAX_NUM]; LPITEM pCubeItems[CUBE_MAX_NUM];
LPCHARACTER pCubeNpc; LPCHARACTER pCubeNpc;
@@ -415,8 +411,6 @@ typedef struct character_point_instant
BYTE bBlockMode; BYTE bBlockMode;
int iDragonSoulActiveDeck;
LPENTITY m_pDragonSoulRefineWindowOpener;
} CHARACTER_POINT_INSTANT; } CHARACTER_POINT_INSTANT;
#define TRIGGERPARAM LPCHARACTER ch, LPCHARACTER causer #define TRIGGERPARAM LPCHARACTER ch, LPCHARACTER causer
@@ -1129,8 +1123,6 @@ class CHARACTER : public CEntity, public CFSM, public CHorseRider
void AutoGiveItem(LPITEM item, bool longOwnerShip = false); void AutoGiveItem(LPITEM item, bool longOwnerShip = false);
int GetEmptyInventory(BYTE size) const; int GetEmptyInventory(BYTE size) const;
int GetEmptyDragonSoulInventory(LPITEM pItem) const;
void CopyDragonSoulItemGrid(std::vector<WORD>& vDragonSoulItemGrid) const;
int CountEmptyInventory() const; int CountEmptyInventory() const;
@@ -2009,38 +2001,6 @@ class CHARACTER : public CEntity, public CFSM, public CHorseRider
void SetItemAward_cmd(char* cmd) { strcpy(itemAward_cmd,cmd); } void SetItemAward_cmd(char* cmd) { strcpy(itemAward_cmd,cmd); }
//void SetItemAward_flag(bool flag) { itemAward_flag = flag; } //void SetItemAward_flag(bool flag) { itemAward_flag = flag; }
public:
//용혼석
// 캐릭터의 affect, quest가 load 되기 전에 DragonSoul_Initialize를 호출하면 안된다.
// affect가 가장 마지막에 로드되어 LoadAffect에서 호출함.
void DragonSoul_Initialize();
bool DragonSoul_IsQualified() const;
void DragonSoul_GiveQualification();
int DragonSoul_GetActiveDeck() const;
bool DragonSoul_IsDeckActivated() const;
bool DragonSoul_ActivateDeck(int deck_idx);
void DragonSoul_DeactivateAll();
// 반드시 ClearItem 전에 불러야 한다.
// 왜냐하면....
// 용혼석 하나 하나를 deactivate할 때마다 덱에 active인 용혼석이 있는지 확인하고,
// active인 용혼석이 하나도 없다면, 캐릭터의 용혼석 affect와, 활성 상태를 제거한다.
//
// 하지만 ClearItem 시, 캐릭터가 착용하고 있는 모든 아이템을 unequip하는 바람에,
// 용혼석 Affect가 제거되고, 결국 로그인 시, 용혼석이 활성화되지 않는다.
// (Unequip할 때에는 로그아웃 상태인지, 아닌지 알 수 없다.)
// 용혼석만 deactivate시키고 캐릭터의 용혼석 덱 활성 상태는 건드리지 않는다.
void DragonSoul_CleanUp();
// 용혼석 강화창
public:
bool DragonSoul_RefineWindow_Open(LPENTITY pEntity);
bool DragonSoul_RefineWindow_Close();
LPENTITY DragonSoul_RefineWindow_GetOpener() { return m_pointsInstant.m_pDragonSoulRefineWindowOpener; }
bool DragonSoul_RefineWindow_CanRefine();
private: private:
// SyncPosition을 악용하여 타유저를 이상한 곳으로 보내는 핵 방어하기 위하여, // SyncPosition을 악용하여 타유저를 이상한 곳으로 보내는 핵 방어하기 위하여,
// SyncPosition이 일어날 때를 기록. // SyncPosition이 일어날 때를 기록.
-3
View File
@@ -16,7 +16,6 @@
#include "arena.h" #include "arena.h"
#include "horsename_manager.h" #include "horsename_manager.h"
#include "item.h" #include "item.h"
#include "DragonSoul.h"
#define IS_NO_SAVE_AFFECT(type) ((type) == AFFECT_WAR_FLAG || (type) == AFFECT_REVIVE_INVISIBLE || ((type) >= AFFECT_PREMIUM_START && (type) <= AFFECT_PREMIUM_END)) #define IS_NO_SAVE_AFFECT(type) ((type) == AFFECT_WAR_FLAG || (type) == AFFECT_REVIVE_INVISIBLE || ((type) >= AFFECT_PREMIUM_START && (type) <= AFFECT_PREMIUM_END))
#define IS_NO_CLEAR_ON_DEATH_AFFECT(type) ((type) == AFFECT_BLOCK_CHAT || ((type) >= 500 && (type) < 600)) #define IS_NO_CLEAR_ON_DEATH_AFFECT(type) ((type) == AFFECT_BLOCK_CHAT || ((type) >= 500 && (type) < 600))
@@ -529,8 +528,6 @@ void CHARACTER::LoadAffect(DWORD dwCount, TPacketAffectElement * pElements)
m_bIsLoadedAffect = true; m_bIsLoadedAffect = true;
// 용혼석 셋팅 로드 및 초기화
DragonSoul_Initialize();
} }
bool CHARACTER::AddAffect(DWORD dwType, BYTE bApplyOn, long lApplyValue, DWORD dwFlag, long lDuration, long lSPCost, bool bOverride, bool IsCube ) bool CHARACTER::AddAffect(DWORD dwType, BYTE bApplyOn, long lApplyValue, DWORD dwFlag, long lDuration, long lSPCost, bool bOverride, bool IsCube )
-145
View File
@@ -1,145 +0,0 @@
#include "stdafx.h"
#include "char.h"
#include "item.h"
#include "desc.h"
#include "DragonSoul.h"
#include "log.h"
// 용혼석 초기화
// 용혼석 on/off는 Affect로 저장되기 때문에,
// 용혼석 Affect가 있다면 덱에 있는 용혼석을 activate해야한다.
// 또한 용혼석 사용 자격은 QuestFlag로 저장해 놓았기 때문에,
// 퀘스트 Flag에서 용혼석 사용 자격을 읽어온다.
// 캐릭터의 affect, quest가 load 되기 전에 DragonSoul_Initialize를 호출하면 안된다.
// affect가 가장 마지막에 로드되어 LoadAffect에서 호출함.
void CHARACTER::DragonSoul_Initialize()
{
for (int i = INVENTORY_MAX_NUM + WEAR_MAX_NUM; i < DRAGON_SOUL_EQUIP_SLOT_END; i++)
{
LPITEM pItem = GetItem(TItemPos(INVENTORY, i));
if (NULL != pItem)
pItem->SetSocket(ITEM_SOCKET_DRAGON_SOUL_ACTIVE_IDX, 0);
}
if (FindAffect(AFFECT_DRAGON_SOUL_DECK_0))
{
DragonSoul_ActivateDeck(DRAGON_SOUL_DECK_0);
}
else if (FindAffect(AFFECT_DRAGON_SOUL_DECK_1))
{
DragonSoul_ActivateDeck(DRAGON_SOUL_DECK_1);
}
}
int CHARACTER::DragonSoul_GetActiveDeck() const
{
return m_pointsInstant.iDragonSoulActiveDeck;
}
bool CHARACTER::DragonSoul_IsDeckActivated() const
{
return m_pointsInstant.iDragonSoulActiveDeck >= 0;
}
bool CHARACTER::DragonSoul_IsQualified() const
{
return FindAffect(AFFECT_DRAGON_SOUL_QUALIFIED) != NULL;
}
void CHARACTER::DragonSoul_GiveQualification()
{
if(NULL == FindAffect(AFFECT_DRAGON_SOUL_QUALIFIED))
{
LogManager::instance().CharLog(this, 0, "DS_QUALIFIED", "");
}
AddAffect(AFFECT_DRAGON_SOUL_QUALIFIED, APPLY_NONE, 0, AFF_NONE, INFINITE_AFFECT_DURATION, 0, false, false);
//SetQuestFlag("dragon_soul.is_qualified", 1);
//// 자격있다면 POINT_DRAGON_SOUL_IS_QUALIFIED는 무조건 1
//PointChange(POINT_DRAGON_SOUL_IS_QUALIFIED, 1 - GetPoint(POINT_DRAGON_SOUL_IS_QUALIFIED));
}
bool CHARACTER::DragonSoul_ActivateDeck(int deck_idx)
{
if (deck_idx < DRAGON_SOUL_DECK_0 || deck_idx >= DRAGON_SOUL_DECK_MAX_NUM)
{
return false;
}
if (DragonSoul_GetActiveDeck() == deck_idx)
return true;
DragonSoul_DeactivateAll();
if (!DragonSoul_IsQualified())
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("용혼석 상자가 활성화되지 않았습니다."));
return false;
}
AddAffect(AFFECT_DRAGON_SOUL_DECK_0 + deck_idx, APPLY_NONE, 0, 0, INFINITE_AFFECT_DURATION, 0, false);
m_pointsInstant.iDragonSoulActiveDeck = deck_idx;
for (int i = DRAGON_SOUL_EQUIP_SLOT_START + DS_SLOT_MAX * deck_idx;
i < DRAGON_SOUL_EQUIP_SLOT_START + DS_SLOT_MAX * (deck_idx + 1); i++)
{
LPITEM pItem = GetInventoryItem(i);
if (NULL != pItem)
DSManager::instance().ActivateDragonSoul(pItem);
}
return true; //fix
}
void CHARACTER::DragonSoul_DeactivateAll()
{
for (int i = DRAGON_SOUL_EQUIP_SLOT_START; i < DRAGON_SOUL_EQUIP_SLOT_END; i++)
{
DSManager::instance().DeactivateDragonSoul(GetInventoryItem(i), true);
}
m_pointsInstant.iDragonSoulActiveDeck = -1;
RemoveAffect(AFFECT_DRAGON_SOUL_DECK_0);
RemoveAffect(AFFECT_DRAGON_SOUL_DECK_1);
}
void CHARACTER::DragonSoul_CleanUp()
{
for (int i = DRAGON_SOUL_EQUIP_SLOT_START; i < DRAGON_SOUL_EQUIP_SLOT_END; i++)
{
DSManager::instance().DeactivateDragonSoul(GetInventoryItem(i), true);
}
}
bool CHARACTER::DragonSoul_RefineWindow_Open(LPENTITY pEntity)
{
if (NULL == m_pointsInstant.m_pDragonSoulRefineWindowOpener)
{
m_pointsInstant.m_pDragonSoulRefineWindowOpener = pEntity;
}
TPacketGCDragonSoulRefine PDS;
PDS.header = HEADER_GC_DRAGON_SOUL_REFINE;
PDS.bSubType = DS_SUB_HEADER_OPEN;
LPDESC d = GetDesc();
if (NULL == d)
{
sys_err ("User(%s)'s DESC is NULL POINT.", GetName());
return false;
}
d->Packet(&PDS, sizeof(PDS));
return true;
}
bool CHARACTER::DragonSoul_RefineWindow_Close()
{
m_pointsInstant.m_pDragonSoulRefineWindowOpener = NULL;
return true;
}
bool CHARACTER::DragonSoul_RefineWindow_CanRefine()
{
return NULL != m_pointsInstant.m_pDragonSoulRefineWindowOpener;
}
+4 -421
View File
@@ -42,7 +42,6 @@
#include "shop.h" #include "shop.h"
#include "../../common/VnumHelper.h" #include "../../common/VnumHelper.h"
#include "DragonSoul.h"
#include "buff_on_attributes.h" #include "buff_on_attributes.h"
#include "belt_inventory_helper.h" #include "belt_inventory_helper.h"
@@ -221,7 +220,7 @@ bool CHARACTER::CanHandleItem(bool bSkipCheckRefine, bool bSkipObserver)
if (m_bUnderRefine) if (m_bUnderRefine)
return false; return false;
if (IsCubeOpen() || NULL != DragonSoul_RefineWindow_GetOpener()) if (IsCubeOpen())
return false; return false;
if (IsWarping()) if (IsWarping())
@@ -250,13 +249,6 @@ LPITEM CHARACTER::GetItem(TItemPos Cell) const
return NULL; return NULL;
} }
return m_pointsInstant.pItems[wCell]; return m_pointsInstant.pItems[wCell];
case DRAGON_SOUL_INVENTORY:
if (wCell >= DRAGON_SOUL_INVENTORY_MAX_NUM)
{
sys_err("CHARACTER::GetInventoryItem: invalid DS item cell %d", wCell);
return NULL;
}
return m_pointsInstant.pDSItems[wCell];
default: default:
return NULL; return NULL;
@@ -338,61 +330,6 @@ void CHARACTER::SetItem(TItemPos Cell, LPITEM pItem)
m_pointsInstant.pItems[wCell] = pItem; m_pointsInstant.pItems[wCell] = pItem;
} }
break; break;
// 용혼석 인벤토리
case DRAGON_SOUL_INVENTORY:
{
LPITEM pOld = m_pointsInstant.pDSItems[wCell];
if (pOld)
{
if (wCell < DRAGON_SOUL_INVENTORY_MAX_NUM)
{
for (int i = 0; i < pOld->GetSize(); ++i)
{
int p = wCell + (i * DRAGON_SOUL_BOX_COLUMN_NUM);
if (p >= DRAGON_SOUL_INVENTORY_MAX_NUM)
continue;
if (m_pointsInstant.pDSItems[p] && m_pointsInstant.pDSItems[p] != pOld)
continue;
m_pointsInstant.wDSItemGrid[p] = 0;
}
}
else
m_pointsInstant.wDSItemGrid[wCell] = 0;
}
if (pItem)
{
if (wCell >= DRAGON_SOUL_INVENTORY_MAX_NUM)
{
sys_err("CHARACTER::SetItem: invalid DS item cell %d", wCell);
return;
}
if (wCell < DRAGON_SOUL_INVENTORY_MAX_NUM)
{
for (int i = 0; i < pItem->GetSize(); ++i)
{
int p = wCell + (i * DRAGON_SOUL_BOX_COLUMN_NUM);
if (p >= DRAGON_SOUL_INVENTORY_MAX_NUM)
continue;
// wCell + 1 로 하는 것은 빈곳을 체크할 때 같은
// 아이템은 예외처리하기 위함
m_pointsInstant.wDSItemGrid[p] = wCell + 1;
}
}
else
m_pointsInstant.wDSItemGrid[wCell] = wCell + 1;
}
m_pointsInstant.pDSItems[wCell] = pItem;
}
break;
default: default:
sys_err ("Invalid Inventory type %d", window_type); sys_err ("Invalid Inventory type %d", window_type);
return; return;
@@ -411,7 +348,7 @@ void CHARACTER::SetItem(TItemPos Cell, LPITEM pItem)
pack.vnum = pItem->GetVnum(); pack.vnum = pItem->GetVnum();
pack.flags = pItem->GetFlag(); pack.flags = pItem->GetFlag();
pack.anti_flags = pItem->GetAntiFlag(); pack.anti_flags = pItem->GetAntiFlag();
pack.highlight = (Cell.window_type == DRAGON_SOUL_INVENTORY); pack.highlight = false;
thecore_memcpy(pack.alSockets, pItem->GetSockets(), sizeof(pack.alSockets)); thecore_memcpy(pack.alSockets, pItem->GetSockets(), sizeof(pack.alSockets));
@@ -445,9 +382,6 @@ void CHARACTER::SetItem(TItemPos Cell, LPITEM pItem)
else else
pItem->SetWindow(EQUIPMENT); pItem->SetWindow(EQUIPMENT);
break; break;
case DRAGON_SOUL_INVENTORY:
pItem->SetWindow(DRAGON_SOUL_INVENTORY);
break;
} }
} }
} }
@@ -455,7 +389,7 @@ void CHARACTER::SetItem(TItemPos Cell, LPITEM pItem)
LPITEM CHARACTER::GetWear(BYTE bCell) const LPITEM CHARACTER::GetWear(BYTE bCell) const
{ {
// > WEAR_MAX_NUM : 용혼석 슬롯들. // > WEAR_MAX_NUM : 용혼석 슬롯들.
if (bCell >= WEAR_MAX_NUM + DRAGON_SOUL_DECK_MAX_NUM * DS_SLOT_MAX) if (bCell >= WEAR_MAX_NUM)
{ {
sys_err("CHARACTER::GetWear: invalid wear cell %d", bCell); sys_err("CHARACTER::GetWear: invalid wear cell %d", bCell);
return NULL; return NULL;
@@ -467,7 +401,7 @@ LPITEM CHARACTER::GetWear(BYTE bCell) const
void CHARACTER::SetWear(BYTE bCell, LPITEM item) void CHARACTER::SetWear(BYTE bCell, LPITEM item)
{ {
// > WEAR_MAX_NUM : 용혼석 슬롯들. // > WEAR_MAX_NUM : 용혼석 슬롯들.
if (bCell >= WEAR_MAX_NUM + DRAGON_SOUL_DECK_MAX_NUM * DS_SLOT_MAX) if (bCell >= WEAR_MAX_NUM)
{ {
sys_err("CHARACTER::SetItem: invalid item cell %d", bCell); sys_err("CHARACTER::SetItem: invalid item cell %d", bCell);
return; return;
@@ -504,17 +438,6 @@ void CHARACTER::ClearItem()
SyncQuickslot(QUICKSLOT_TYPE_ITEM, i, 255); SyncQuickslot(QUICKSLOT_TYPE_ITEM, i, 255);
} }
} }
for (i = 0; i < DRAGON_SOUL_INVENTORY_MAX_NUM; ++i)
{
if ((item = GetItem(TItemPos(DRAGON_SOUL_INVENTORY, i))))
{
item->SetSkipSave(true);
ITEM_MANAGER::instance().FlushDelayedSave(item);
item->RemoveFromCharacter();
M2_DESTROY_ITEM(item);
}
}
} }
bool CHARACTER::IsEmptyItemGrid(TItemPos Cell, BYTE bSize, int iExceptionCell) const bool CHARACTER::IsEmptyItemGrid(TItemPos Cell, BYTE bSize, int iExceptionCell) const
@@ -614,67 +537,6 @@ bool CHARACTER::IsEmptyItemGrid(TItemPos Cell, BYTE bSize, int iExceptionCell) c
} }
} }
break; break;
case DRAGON_SOUL_INVENTORY:
{
WORD wCell = Cell.cell;
if (wCell >= DRAGON_SOUL_INVENTORY_MAX_NUM)
return false;
// bItemCell은 0이 false임을 나타내기 위해 + 1 해서 처리한다.
// 따라서 iExceptionCell에 1을 더해 비교한다.
iExceptionCell++;
if (m_pointsInstant.wDSItemGrid[wCell])
{
if (m_pointsInstant.wDSItemGrid[wCell] == iExceptionCell)
{
if (bSize == 1)
return true;
int j = 1;
do
{
BYTE p = wCell + (DRAGON_SOUL_BOX_COLUMN_NUM * j);
if (p >= DRAGON_SOUL_INVENTORY_MAX_NUM)
return false;
if (m_pointsInstant.wDSItemGrid[p])
if (m_pointsInstant.wDSItemGrid[p] != iExceptionCell)
return false;
}
while (++j < bSize);
return true;
}
else
return false;
}
// 크기가 1이면 한칸을 차지하는 것이므로 그냥 리턴
if (1 == bSize)
return true;
else
{
int j = 1;
do
{
BYTE p = wCell + (DRAGON_SOUL_BOX_COLUMN_NUM * j);
if (p >= DRAGON_SOUL_INVENTORY_MAX_NUM)
return false;
if (m_pointsInstant.bItemGrid[p])
if (m_pointsInstant.wDSItemGrid[p] != iExceptionCell)
return false;
}
while (++j < bSize);
return true;
}
}
} }
} }
@@ -688,34 +550,6 @@ int CHARACTER::GetEmptyInventory(BYTE size) const
return -1; return -1;
} }
int CHARACTER::GetEmptyDragonSoulInventory(LPITEM pItem) const
{
if (NULL == pItem || !pItem->IsDragonSoul())
return -1;
if (!DragonSoul_IsQualified())
{
return -1;
}
BYTE bSize = pItem->GetSize();
WORD wBaseCell = DSManager::instance().GetBasePosition(pItem);
if (WORD_MAX == wBaseCell)
return -1;
for (int i = 0; i < DRAGON_SOUL_BOX_SIZE; ++i)
if (IsEmptyItemGrid(TItemPos(DRAGON_SOUL_INVENTORY, i + wBaseCell), bSize))
return i + wBaseCell;
return -1;
}
void CHARACTER::CopyDragonSoulItemGrid(std::vector<WORD>& vDragonSoulItemGrid) const
{
vDragonSoulItemGrid.resize(DRAGON_SOUL_INVENTORY_MAX_NUM);
std::copy(m_pointsInstant.wDSItemGrid, m_pointsInstant.wDSItemGrid + DRAGON_SOUL_INVENTORY_MAX_NUM, vDragonSoulItemGrid.begin());
}
int CHARACTER::CountEmptyInventory() const int CHARACTER::CountEmptyInventory() const
{ {
int count = 0; int count = 0;
@@ -1962,23 +1796,6 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell)
else else
UnequipItem(item); UnequipItem(item);
break; break;
// 착용하지 않은 용혼석은 사용할 수 없다.
// 정상적인 클라라면, 용혼석에 관하여 item use 패킷을 보낼 수 없다.
// 용혼석 착용은 item move 패킷으로 한다.
// 착용한 용혼석은 추출한다.
case ITEM_DS:
{
if (!item->IsEquipped())
return false;
return DSManager::instance().PullOut(this, NPOS, item);
break;
}
case ITEM_SPECIAL_DS:
if (!item->IsEquipped())
EquipItem(item);
else
UnequipItem(item);
break;
case ITEM_FISH: case ITEM_FISH:
{ {
@@ -2098,14 +1915,6 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell)
} }
} }
if( (dwBoxVnum > 51500 && dwBoxVnum < 52000) || (dwBoxVnum >= 50255 && dwBoxVnum <= 50260) ) // 용혼원석들
{
if( !(this->DragonSoul_IsQualified()) )
{
ChatPacket(CHAT_TYPE_INFO,LC_TEXT("먼저 용혼석 퀘스트를 완료하셔야 합니다."));
return false;
}
}
if (GiveItemFromSpecialItemGroup(dwBoxVnum, dwVnums, dwCounts, item_gets, count)) if (GiveItemFromSpecialItemGroup(dwBoxVnum, dwVnums, dwCounts, item_gets, count))
{ {
@@ -2435,94 +2244,6 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell)
switch (item->GetSubType()) switch (item->GetSubType())
{ {
case USE_TIME_CHARGE_PER:
{
LPITEM pDestItem = GetItem(DestCell);
if (NULL == pDestItem)
{
return false;
}
// 우선 용혼석에 관해서만 하도록 한다.
if (pDestItem->IsDragonSoul())
{
int ret;
char buf[128];
if (item->GetVnum() == DRAGON_HEART_VNUM)
{
ret = pDestItem->GiveMoreTime_Per((float)item->GetSocket(ITEM_SOCKET_CHARGING_AMOUNT_IDX));
}
else
{
ret = pDestItem->GiveMoreTime_Per((float)item->GetValue(ITEM_VALUE_CHARGING_AMOUNT_IDX));
}
if (ret > 0)
{
if (item->GetVnum() == DRAGON_HEART_VNUM)
{
sprintf(buf, "Inc %ds by item{VN:%d SOC%d:%d}", ret, item->GetVnum(), ITEM_SOCKET_CHARGING_AMOUNT_IDX, item->GetSocket(ITEM_SOCKET_CHARGING_AMOUNT_IDX));
}
else
{
sprintf(buf, "Inc %ds by item{VN:%d VAL%d:%d}", ret, item->GetVnum(), ITEM_VALUE_CHARGING_AMOUNT_IDX, item->GetValue(ITEM_VALUE_CHARGING_AMOUNT_IDX));
}
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d초 만큼 충전되었습니다."), ret);
item->SetCount(item->GetCount() - 1);
LogManager::instance().ItemLog(this, item, "DS_CHARGING_SUCCESS", buf);
return true;
}
else
{
if (item->GetVnum() == DRAGON_HEART_VNUM)
{
sprintf(buf, "No change by item{VN:%d SOC%d:%d}", item->GetVnum(), ITEM_SOCKET_CHARGING_AMOUNT_IDX, item->GetSocket(ITEM_SOCKET_CHARGING_AMOUNT_IDX));
}
else
{
sprintf(buf, "No change by item{VN:%d VAL%d:%d}", item->GetVnum(), ITEM_VALUE_CHARGING_AMOUNT_IDX, item->GetValue(ITEM_VALUE_CHARGING_AMOUNT_IDX));
}
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("충전할 수 없습니다."));
LogManager::instance().ItemLog(this, item, "DS_CHARGING_FAILED", buf);
return false;
}
}
else
return false;
}
break;
case USE_TIME_CHARGE_FIX:
{
LPITEM pDestItem = GetItem(DestCell);
if (NULL == pDestItem)
{
return false;
}
// 우선 용혼석에 관해서만 하도록 한다.
if (pDestItem->IsDragonSoul())
{
int ret = pDestItem->GiveMoreTime_Fix(item->GetValue(ITEM_VALUE_CHARGING_AMOUNT_IDX));
char buf[128];
if (ret)
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("%d초 만큼 충전되었습니다."), ret);
sprintf(buf, "Increase %ds by item{VN:%d VAL%d:%d}", ret, item->GetVnum(), ITEM_VALUE_CHARGING_AMOUNT_IDX, item->GetValue(ITEM_VALUE_CHARGING_AMOUNT_IDX));
LogManager::instance().ItemLog(this, item, "DS_CHARGING_SUCCESS", buf);
item->SetCount(item->GetCount() - 1);
return true;
}
else
{
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("충전할 수 없습니다."));
sprintf(buf, "No change by item{VN:%d VAL%d:%d}", item->GetVnum(), ITEM_VALUE_CHARGING_AMOUNT_IDX, item->GetValue(ITEM_VALUE_CHARGING_AMOUNT_IDX));
LogManager::instance().ItemLog(this, item, "DS_CHARGING_FAILED", buf);
return false;
}
}
else
return false;
}
break;
case USE_SPECIAL: case USE_SPECIAL:
switch (item->GetVnum()) switch (item->GetVnum())
@@ -5207,33 +4928,6 @@ bool CHARACTER::UseItemEx(LPITEM item, TItemPos DestCell)
} }
} }
break; break;
case ITEM_EXTRACT:
{
LPITEM pDestItem = GetItem(DestCell);
if (NULL == pDestItem)
{
return false;
}
switch (item->GetSubType())
{
case EXTRACT_DRAGON_SOUL:
if (pDestItem->IsDragonSoul())
{
return DSManager::instance().PullOut(this, NPOS, pDestItem, item);
}
return false;
case EXTRACT_DRAGON_HEART:
if (pDestItem->IsDragonSoul())
{
return DSManager::instance().ExtractDragonHeart(this, pDestItem, item);
}
return false;
default:
return false;
}
}
break;
case ITEM_NONE: case ITEM_NONE:
sys_err("Item type NONE %s", item->GetName()); sys_err("Item type NONE %s", item->GetName());
break; break;
@@ -5444,8 +5138,6 @@ bool CHARACTER::DropItem(TItemPos Cell, BYTE bCount)
if (!CanHandleItem()) if (!CanHandleItem())
{ {
if (NULL != DragonSoul_RefineWindow_GetOpener())
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("강화창을 연 상태에서는 아이템을 옮길 수 없습니다."));
return false; return false;
} }
@@ -5648,8 +5340,6 @@ bool CHARACTER::MoveItem(TItemPos Cell, TItemPos DestCell, BYTE count)
if (!CanHandleItem()) if (!CanHandleItem())
{ {
if (NULL != DragonSoul_RefineWindow_GetOpener())
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("강화창을 연 상태에서는 아이템을 옮길 수 없습니다."));
return false; return false;
} }
@@ -5677,27 +5367,6 @@ bool CHARACTER::MoveItem(TItemPos Cell, TItemPos DestCell, BYTE count)
} }
else else
{ {
if (item->IsDragonSoul())
{
if (item->IsEquipped())
{
return DSManager::instance().PullOut(this, DestCell, item);
}
else
{
if (DestCell.window_type != DRAGON_SOUL_INVENTORY)
{
return false;
}
if (!DSManager::instance().IsValidCellForThisItem(item, DestCell))
return false;
}
}
// 용혼석이 아닌 아이템은 용혼석 인벤에 들어갈 수 없다.
else if (DRAGON_SOUL_INVENTORY == DestCell.window_type)
return false;
LPITEM item2; LPITEM item2;
if ((item2 = GetItem(DestCell)) && item != item2 && item2->IsStackable() && if ((item2 = GetItem(DestCell)) && item != item2 && item2->IsStackable() &&
@@ -5952,30 +5621,15 @@ bool CHARACTER::PickupItem(DWORD dwVID)
} }
int iEmptyCell; int iEmptyCell;
if (item->IsDragonSoul())
{
if ((iEmptyCell = GetEmptyDragonSoulInventory(item)) == -1)
{
sys_log(0, "No empty ds inventory pid %u size %ud itemid %u", GetPlayerID(), item->GetSize(), item->GetID());
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지하고 있는 아이템이 너무 많습니다."));
return false;
}
}
else
{
if ((iEmptyCell = GetEmptyInventory(item->GetSize())) == -1) if ((iEmptyCell = GetEmptyInventory(item->GetSize())) == -1)
{ {
sys_log(0, "No empty inventory pid %u size %ud itemid %u", GetPlayerID(), item->GetSize(), item->GetID()); sys_log(0, "No empty inventory pid %u size %ud itemid %u", GetPlayerID(), item->GetSize(), item->GetID());
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지하고 있는 아이템이 너무 많습니다.")); ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지하고 있는 아이템이 너무 많습니다."));
return false; return false;
} }
}
item->RemoveFromGround(); item->RemoveFromGround();
if (item->IsDragonSoul())
item->AddToCharacter(this, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyCell));
else
item->AddToCharacter(this, TItemPos(INVENTORY, iEmptyCell)); item->AddToCharacter(this, TItemPos(INVENTORY, iEmptyCell));
char szHint[32+1]; char szHint[32+1];
@@ -6001,21 +5655,6 @@ bool CHARACTER::PickupItem(DWORD dwVID)
int iEmptyCell; int iEmptyCell;
if (item->IsDragonSoul())
{
if (!(owner && (iEmptyCell = owner->GetEmptyDragonSoulInventory(item)) != -1))
{
owner = this;
if ((iEmptyCell = GetEmptyDragonSoulInventory(item)) == -1)
{
owner->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("소지하고 있는 아이템이 너무 많습니다."));
return false;
}
}
}
else
{
if (!(owner && (iEmptyCell = owner->GetEmptyInventory(item->GetSize())) != -1)) if (!(owner && (iEmptyCell = owner->GetEmptyInventory(item->GetSize())) != -1))
{ {
owner = this; owner = this;
@@ -6026,13 +5665,9 @@ bool CHARACTER::PickupItem(DWORD dwVID)
return false; return false;
} }
} }
}
item->RemoveFromGround(); item->RemoveFromGround();
if (item->IsDragonSoul())
item->AddToCharacter(owner, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyCell));
else
item->AddToCharacter(owner, TItemPos(INVENTORY, iEmptyCell)); item->AddToCharacter(owner, TItemPos(INVENTORY, iEmptyCell));
char szHint[32+1]; char szHint[32+1];
@@ -6147,9 +5782,6 @@ bool CHARACTER::UnequipItem(LPITEM item)
if (false == CanUnequipNow(item)) if (false == CanUnequipNow(item))
return false; return false;
if (item->IsDragonSoul())
pos = GetEmptyDragonSoulInventory(item);
else
pos = GetEmptyInventory(item->GetSize()); pos = GetEmptyInventory(item->GetSize());
// HARD CODING // HARD CODING
@@ -6157,11 +5789,6 @@ bool CHARACTER::UnequipItem(LPITEM item)
ShowAlignment(true); ShowAlignment(true);
item->RemoveFromCharacter(); item->RemoveFromCharacter();
if (item->IsDragonSoul())
{
item->AddToCharacter(this, TItemPos(DRAGON_SOUL_INVENTORY, pos));
}
else
item->AddToCharacter(this, TItemPos(INVENTORY, pos)); item->AddToCharacter(this, TItemPos(INVENTORY, pos));
CheckMaximumPoints(); CheckMaximumPoints();
@@ -6286,25 +5913,6 @@ bool CHARACTER::EquipItem(LPITEM item, int iCandidateCell)
LogManager::instance().ItemLog(this, item, "ITEM_SPLIT", szSplitBuf); LogManager::instance().ItemLog(this, item, "ITEM_SPLIT", szSplitBuf);
} }
// 용혼석 특수 처리
if (item->IsDragonSoul())
{
// 같은 타입의 용혼석이 이미 들어가 있다면 착용할 수 없다.
// 용혼석은 swap을 지원하면 안됨.
if(GetInventoryItem(INVENTORY_MAX_NUM + iWearCell))
{
ChatPacket(CHAT_TYPE_INFO, "이미 같은 종류의 용혼석을 착용하고 있습니다.");
return false;
}
if (!item->EquipTo(this, iWearCell))
{
return false;
}
}
// 용혼석이 아님.
else
{
// 착용할 곳에 아이템이 있다면, // 착용할 곳에 아이템이 있다면,
if (GetWear(iWearCell) && !IS_SET(GetWear(iWearCell)->GetFlag(), ITEM_FLAG_IRREMOVABLE)) if (GetWear(iWearCell) && !IS_SET(GetWear(iWearCell)->GetFlag(), ITEM_FLAG_IRREMOVABLE))
{ {
@@ -6326,7 +5934,6 @@ bool CHARACTER::EquipItem(LPITEM item, int iCandidateCell)
SyncQuickslot(QUICKSLOT_TYPE_ITEM, bOldCell, iWearCell); SyncQuickslot(QUICKSLOT_TYPE_ITEM, bOldCell, iWearCell);
} }
} }
}
if (true == item->IsEquipped()) if (true == item->IsEquipped())
{ {
@@ -6650,20 +6257,10 @@ void CHARACTER::AutoGiveItem(LPITEM item, bool longOwnerShip)
} }
int cell; int cell;
if (item->IsDragonSoul())
{
cell = GetEmptyDragonSoulInventory(item);
}
else
{
cell = GetEmptyInventory (item->GetSize()); cell = GetEmptyInventory (item->GetSize());
}
if (cell != -1) if (cell != -1)
{ {
if (item->IsDragonSoul())
item->AddToCharacter(this, TItemPos(DRAGON_SOUL_INVENTORY, cell));
else
item->AddToCharacter(this, TItemPos(INVENTORY, cell)); item->AddToCharacter(this, TItemPos(INVENTORY, cell));
LogManager::instance().ItemLog(this, item, "SYSTEM", item->GetName()); LogManager::instance().ItemLog(this, item, "SYSTEM", item->GetName());
@@ -6770,11 +6367,6 @@ LPITEM CHARACTER::AutoGiveItem(DWORD dwItemVnum, BYTE bCount, int iRarePct, bool
} }
int iEmptyCell; int iEmptyCell;
if (item->IsDragonSoul())
{
iEmptyCell = GetEmptyDragonSoulInventory(item);
}
else
iEmptyCell = GetEmptyInventory(item->GetSize()); iEmptyCell = GetEmptyInventory(item->GetSize());
if (iEmptyCell != -1) if (iEmptyCell != -1)
@@ -6782,9 +6374,6 @@ LPITEM CHARACTER::AutoGiveItem(DWORD dwItemVnum, BYTE bCount, int iRarePct, bool
if (bMsg) if (bMsg)
ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아이템 획득: %s"), item->GetName()); ChatPacket(CHAT_TYPE_INFO, LC_TEXT("아이템 획득: %s"), item->GetName());
if (item->IsDragonSoul())
item->AddToCharacter(this, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyCell));
else
item->AddToCharacter(this, TItemPos(INVENTORY, iEmptyCell)); item->AddToCharacter(this, TItemPos(INVENTORY, iEmptyCell));
LogManager::instance().ItemLog(this, item, "SYSTEM", item->GetName()); LogManager::instance().ItemLog(this, item, "SYSTEM", item->GetName());
@@ -7584,9 +7173,6 @@ bool CHARACTER::IsValidItemPosition(TItemPos Pos) const
case EQUIPMENT: case EQUIPMENT:
return cell < (INVENTORY_AND_EQUIP_SLOT_MAX); return cell < (INVENTORY_AND_EQUIP_SLOT_MAX);
case DRAGON_SOUL_INVENTORY:
return cell < (DRAGON_SOUL_INVENTORY_MAX_NUM);
case SAFEBOX: case SAFEBOX:
if (NULL != m_pkSafebox) if (NULL != m_pkSafebox)
return m_pkSafebox->IsValidPosition(cell); return m_pkSafebox->IsValidPosition(cell);
@@ -7725,9 +7311,6 @@ bool CHARACTER::CanUnequipNow(const LPITEM item, const TItemPos& srcCell, const
{ {
int pos = -1; int pos = -1;
if (item->IsDragonSoul())
pos = GetEmptyDragonSoulInventory(item);
else
pos = GetEmptyInventory(item->GetSize()); pos = GetEmptyInventory(item->GetSize());
VERIFY_MSG( -1 == pos, "소지품에 빈 공간이 없습니다." ); VERIFY_MSG( -1 == pos, "소지품에 빈 공간이 없습니다." );
-2
View File
@@ -137,8 +137,6 @@ bool CHARACTER::SwapQuickslot(BYTE a, BYTE b)
void CHARACTER::ChainQuickslotItem(LPITEM pItem, BYTE bType, BYTE bOldPos) void CHARACTER::ChainQuickslotItem(LPITEM pItem, BYTE bType, BYTE bOldPos)
{ {
if (pItem->IsDragonSoul())
return;
for ( int i=0; i < QUICKSLOT_MAX_NUM; ++i ) for ( int i=0; i < QUICKSLOT_MAX_NUM; ++i )
{ {
if ( m_quickslot[i].type == bType && m_quickslot[i].pos == bOldPos ) if ( m_quickslot[i].type == bType && m_quickslot[i].pos == bOldPos )
-4
View File
@@ -272,8 +272,6 @@ ACMD (do_attr_full_set);
ACMD (do_all_skill_master); ACMD (do_all_skill_master);
// 아이템 착용. icon이 없어 클라에서 확인 할 수 없는 아이템 착용을 위해 만듦. // 아이템 착용. icon이 없어 클라에서 확인 할 수 없는 아이템 착용을 위해 만듦.
ACMD (do_use_item); ACMD (do_use_item);
ACMD (do_dragon_soul);
ACMD (do_ds_list);
ACMD (do_clear_affect); ACMD (do_clear_affect);
struct command_info cmd_info[] = struct command_info cmd_info[] =
@@ -584,8 +582,6 @@ struct command_info cmd_info[] =
{ "all_skill_master", do_all_skill_master, 0, POS_DEAD, GM_LOW_WIZARD}, { "all_skill_master", do_all_skill_master, 0, POS_DEAD, GM_LOW_WIZARD},
{ "use_item", do_use_item, 0, POS_DEAD, GM_LOW_WIZARD}, { "use_item", do_use_item, 0, POS_DEAD, GM_LOW_WIZARD},
{ "dragon_soul", do_dragon_soul, 0, POS_DEAD, GM_PLAYER },
{ "ds_list", do_ds_list, 0, POS_DEAD, GM_PLAYER },
{ "do_clear_affect", do_clear_affect, 0, POS_DEAD, GM_LOW_WIZARD}, { "do_clear_affect", do_clear_affect, 0, POS_DEAD, GM_LOW_WIZARD},
{ "\n", NULL, 0, POS_DEAD, GM_IMPLEMENTOR } /* 반드시 이 것이 마지막이어야 한다. */ { "\n", NULL, 0, POS_DEAD, GM_IMPLEMENTOR } /* 반드시 이 것이 마지막이어야 한다. */
-67
View File
@@ -35,7 +35,6 @@
#include "pcbang.h" #include "pcbang.h"
#include "threeway_war.h" #include "threeway_war.h"
#include "unique_item.h" #include "unique_item.h"
#include "DragonSoul.h"
extern bool DropEvent_RefineBox_SetValue(const std::string& name, int value); extern bool DropEvent_RefineBox_SetValue(const std::string& name, int value);
@@ -533,28 +532,6 @@ ACMD(do_item)
if (item) if (item)
{ {
if (item->IsDragonSoul())
{
int iEmptyPos = ch->GetEmptyDragonSoulInventory(item);
if (iEmptyPos != -1)
{
item->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
LogManager::instance().ItemLog(ch, item, "GM", item->GetName());
}
else
{
M2_DESTROY_ITEM(item);
if (!ch->DragonSoul_IsQualified())
{
ch->ChatPacket(CHAT_TYPE_INFO, "Àκ¥ÀÌ È°¼ºÈ­ µÇÁö ¾ÊÀ½.");
}
else
ch->ChatPacket(CHAT_TYPE_INFO, "Not enough inventory space.");
}
}
else
{
int iEmptyPos = ch->GetEmptyInventory(item->GetSize()); int iEmptyPos = ch->GetEmptyInventory(item->GetSize());
if (iEmptyPos != -1) if (iEmptyPos != -1)
@@ -567,7 +544,6 @@ ACMD(do_item)
M2_DESTROY_ITEM(item); M2_DESTROY_ITEM(item);
ch->ChatPacket(CHAT_TYPE_INFO, "Not enough inventory space."); ch->ChatPacket(CHAT_TYPE_INFO, "Not enough inventory space.");
} }
}
} }
else else
{ {
@@ -931,13 +907,6 @@ ACMD(do_item_purge)
ch->SyncQuickslot(QUICKSLOT_TYPE_ITEM, i, 255); ch->SyncQuickslot(QUICKSLOT_TYPE_ITEM, i, 255);
} }
} }
for (i = 0; i < DRAGON_SOUL_INVENTORY_MAX_NUM; ++i)
{
if ((item = ch->GetItem(TItemPos(DRAGON_SOUL_INVENTORY, i ))))
{
ITEM_MANAGER::instance().RemoveItem(item, "PURGE");
}
}
} }
ACMD(do_state) ACMD(do_state)
@@ -4373,39 +4342,3 @@ ACMD (do_clear_affect)
ch->ClearAffect(true); ch->ClearAffect(true);
} }
ACMD (do_dragon_soul)
{
char arg1[512];
const char* rest = one_argument (argument, arg1, sizeof(arg1));
switch (arg1[0])
{
case 'a':
{
one_argument (rest, arg1, sizeof(arg1));
int deck_idx;
if (str_to_number(deck_idx, arg1) == false)
{
return;
}
ch->DragonSoul_ActivateDeck(deck_idx);
}
break;
case 'd':
{
ch->DragonSoul_DeactivateAll();
}
break;
}
}
ACMD (do_ds_list)
{
for (int i = 0; i < DRAGON_SOUL_INVENTORY_MAX_NUM; i++)
{
TItemPos cell(DRAGON_SOUL_INVENTORY, i);
LPITEM item = ch->GetItem(cell);
if (item != NULL)
ch->ChatPacket(CHAT_TYPE_INFO, "cell : %d, name : %s, id : %d", item->GetCell(), item->GetName(), item->GetID());
}
}
-902
View File
@@ -1,902 +0,0 @@
#include "stdafx.h"
#include "constants.h"
#include "group_text_parse_tree.h"
#include "dragon_soul_table.h"
#include "item_manager.h"
#include <boost/lexical_cast.hpp>
const std::string g_astGradeName[] =
{
"grade_normal",
"grade_brilliant",
"grade_rare",
"grade_ancient",
"grade_legendary",
};
const std::string g_astStepName[] =
{
"step_lowest",
"step_low",
"step_mid",
"step_high",
"step_highest",
};
const std::string g_astMaterialName[] =
{
"material_leather",
"material_blood",
"material_root",
"material_needle",
"material_jewel",
"material_ds_refine_normal",
"material_ds_refine_blessed",
"material_ds_refine_holly",
};
bool DragonSoulTable::ReadDragonSoulTableFile(const char * c_pszFileName)
{
m_pLoader = new CGroupTextParseTreeLoader;
CGroupTextParseTreeLoader& loader = *m_pLoader;
if (false == loader.Load(c_pszFileName))
{
sys_err ("dragon_soul_table.txt load error");
return false;
}
// Group VnumMapper Reading.
if (!ReadVnumMapper())
return false;
// Group BasicApplys Reading.
if (!ReadBasicApplys())
return false;
// Group AdditionalApplys Reading.
if (!ReadAdditionalApplys())
return false;
m_pApplyNumSettingNode = loader.GetGroup("applynumsettings");
m_pWeightTableNode = loader.GetGroup("weighttables");
m_pRefineGradeTableNode = loader.GetGroup("refinegradetables");
m_pRefineStepTableNode = loader.GetGroup("refinesteptables");
m_pRefineStrengthTableNode = loader.GetGroup("refinestrengthtables");
m_pDragonHeartExtTableNode = loader.GetGroup("dragonheartexttables");
m_pDragonSoulExtTableNode = loader.GetGroup("dragonsoulexttables");
if (CheckApplyNumSettings()
&& CheckWeightTables()
&& CheckRefineGradeTables()
&& CheckRefineStepTables()
&& CheckRefineStrengthTables()
&& CheckDragonHeartExtTables()
&& CheckDragonSoulExtTables())
{
return true;
}
else
{
sys_err ("DragonSoul table Check failed.");
return false;
}
}
bool DragonSoulTable::GetDragonSoulGroupName(BYTE bType, std::string& stGroupName) const
{
DragonSoulTable::TMapTypeToName::const_iterator it = m_map_type_to_name.find (bType);
if (it != m_map_type_to_name.end())
{
stGroupName = it->second;
return true;
}
else
{
sys_err ("Invalid DragonSoul Type(%d)", bType);
return false;
}
}
bool DragonSoulTable::ReadVnumMapper()
{
std::string stName;
// Group VnumMapper Reading.
CGroupNode* pGroupNode = m_pLoader->GetGroup("vnummapper");
if (NULL == pGroupNode)
{
sys_err ("dragon_soul_table.txt need VnumMapper.");
return false;
}
{
int n = pGroupNode->GetRowCount();
if (0 == n)
{
sys_err ("Group VnumMapper is Empty.");
return false;
}
std::set <BYTE> setTypes;
for (int i = 0; i < n; i++)
{
const CGroupNode::CGroupNodeRow* pRow;
pGroupNode->GetRow(i, &pRow);
std::string stDragonSoulName;
BYTE bType;
if (!pRow->GetValue("dragonsoulname", stDragonSoulName))
{
sys_err ("In Group VnumMapper, No DragonSoulName column.");
return false;
}
if (!pRow->GetValue("type", bType))
{
sys_err ("In Group VnumMapper, %s's Vnum is invalid", stDragonSoulName.c_str());
return false;
}
if (setTypes.end() != setTypes.find(bType))
{
sys_err ("In Group VnumMapper, duplicated vnum exist.");
return false;
}
m_map_name_to_type.insert(TMapNameToType::value_type(stDragonSoulName, bType));
m_map_type_to_name.insert(TMapTypeToName::value_type(bType, stDragonSoulName));
m_vecDragonSoulTypes.push_back(bType);
m_vecDragonSoulNames.push_back(stDragonSoulName);
}
}
return true;
}
bool DragonSoulTable::ReadBasicApplys()
{
CGroupNode* pGroupNode = m_pLoader->GetGroup("basicapplys");
if (NULL == pGroupNode)
{
sys_err ("dragon_soul_table.txt need BasicApplys.");
return false;
}
for (uint i = 0; i < m_vecDragonSoulNames.size(); i++)
{
CGroupNode* pChild;
if (NULL == (pChild = pGroupNode->GetChildNode(m_vecDragonSoulNames[i])))
{
sys_err ("In Group BasicApplys, %s group is not defined.", m_vecDragonSoulNames[i].c_str());
return false;
}
TVecApplys vecApplys;
int n = pChild->GetRowCount();
// BasicApply Group은 Key가 1부터 시작함.
for (int j = 1; j <= n; j++)
{
std::stringstream ss;
ss << j;
const CGroupNode::CGroupNodeRow* pRow = NULL;
pChild->GetRow(ss.str(), &pRow);
if (NULL == pRow)
{
sys_err("In Group BasicApplys, No %d row.", j);
}
EApplyTypes at;
int av;
std::string stTypeName;
if (!pRow->GetValue("apply_type", stTypeName))
{
sys_err ("In Group BasicApplys, %s group's apply_type is empty.", m_vecDragonSoulNames[i].c_str());
return false;
}
if (!(at = (EApplyTypes)FN_get_apply_type(stTypeName.c_str())))
{
sys_err ("In Group BasicApplys, %s group's apply_type %s is invalid.", m_vecDragonSoulNames[i].c_str(), stTypeName.c_str());
return false;
}
if (!pRow->GetValue("apply_value", av))
{
sys_err ("In Group BasicApplys, %s group's apply_value %s is invalid.", m_vecDragonSoulNames[i].c_str(), av);
return false;
}
vecApplys.push_back(SApply(at, av));
}
m_map_basic_applys_group.insert (TMapApplyGroup::value_type (m_map_name_to_type[m_vecDragonSoulNames[i]], vecApplys));
}
return true;
}
bool DragonSoulTable::ReadAdditionalApplys()
{
CGroupNode* pGroupNode = m_pLoader->GetGroup("additionalapplys");
if (NULL == pGroupNode)
{
sys_err ("dragon_soul_table.txt need AdditionalApplys.");
return false;
}
for (int i = 0; i < m_vecDragonSoulNames.size(); i++)
{
CGroupNode* pChild;
if (NULL == (pChild = pGroupNode->GetChildNode(m_vecDragonSoulNames[i])))
{
sys_err ("In Group AdditionalApplys, %s group is not defined.", m_vecDragonSoulNames[i].c_str());
return false;
}
TVecApplys vecApplys;
int n = pChild->GetRowCount();
for (int j = 0; j < n; j++)
{
const CGroupNode::CGroupNodeRow* pRow;
pChild->GetRow(j, &pRow);
EApplyTypes at;
int av;
float prob;
std::string stTypeName;
if (!pRow->GetValue("apply_type", stTypeName))
{
sys_err ("In Group AdditionalApplys, %s group's apply_type is empty.", m_vecDragonSoulNames[i].c_str());
return false;
}
if (!(at = (EApplyTypes)FN_get_apply_type(stTypeName.c_str())))
{
sys_err ("In Group AdditionalApplys, %s group's apply_type %s is invalid.", m_vecDragonSoulNames[i].c_str(), stTypeName.c_str());
return false;
}
if (!pRow->GetValue("apply_value", av))
{
sys_err ("In Group AdditionalApplys, %s group's apply_value %s is invalid.", m_vecDragonSoulNames[i].c_str(), av);
return false;
}
if (!pRow->GetValue("prob", prob))
{
sys_err ("In Group AdditionalApplys, %s group's probability %s is invalid.", m_vecDragonSoulNames[i].c_str(), prob);
return false;
}
vecApplys.push_back(SApply(at, av, prob));
}
m_map_additional_applys_group.insert (TMapApplyGroup::value_type (m_map_name_to_type[m_vecDragonSoulNames[i]], vecApplys));
}
return true;
}
bool DragonSoulTable::CheckApplyNumSettings ()
{
// Group ApplyNumSettings Reading.
if (NULL == m_pApplyNumSettingNode)
{
sys_err ("dragon_soul_table.txt need ApplyNumSettings.");
return false;
}
else
{
for (int i = 0; i < m_vecDragonSoulTypes.size(); i++)
{
for (int j = 0; j < DRAGON_SOUL_GRADE_MAX; j++)
{
int basis, add_min, add_max;
if (!GetApplyNumSettings(m_vecDragonSoulTypes[i], j, basis, add_min, add_max))
{
sys_err ("In %s group of ApplyNumSettings, values in Grade(%s) row is invalid.",
m_vecDragonSoulNames[i].c_str(), g_astGradeName[j].c_str());
return false;
}
}
}
}
return true;
}
bool DragonSoulTable::CheckWeightTables ()
{
// Group WeightTables Reading.
if (NULL == m_pWeightTableNode)
{
sys_err ("dragon_soul_table.txt need WeightTables.");
return false;
}
else
{
for (int i = 0; i < m_vecDragonSoulTypes.size(); i++)
{
for (int j = 0; j < DRAGON_SOUL_GRADE_MAX; j++)
{
for (int k = 0; k < DRAGON_SOUL_STEP_MAX; k++)
{
for (int l = 0; l < DRAGON_SOUL_STRENGTH_MAX; l++)
{
float fWeight;
if (!GetWeight(m_vecDragonSoulTypes[i], j, k, l, fWeight))
{
sys_err ("In %s group of WeightTables, value(Grade(%s), Step(%s), Strength(%d) is invalid.",
m_vecDragonSoulNames[i].c_str(), g_astGradeName[j].c_str(), g_astStepName[k].c_str(), l);
}
}
}
}
}
}
return true;
}
bool DragonSoulTable::CheckRefineGradeTables()
{
// Group UpgradeTables Reading.
if (NULL == m_pRefineGradeTableNode)
{
sys_err ("dragon_soul_table.txt need RefineGradeTables.");
return false;
}
else
{
for (int i = 0; i < m_vecDragonSoulTypes.size(); i++)
{
for (int j = 0; j < DRAGON_SOUL_GRADE_MAX - 1; j++)
{
int need_count, fee;
std::vector <float> vec_probs;
if (!GetRefineGradeValues(m_vecDragonSoulTypes[i], j, need_count, fee, vec_probs))
{
sys_err ("In %s group of RefineGradeTables, values in Grade(%s) row is invalid.",
m_vecDragonSoulNames[i].c_str(), g_astGradeName[j].c_str());
return false;
}
if (need_count < 1)
{
sys_err ("In %s group of RefineGradeTables, need_count of Grade(%s) is less than 1.",
m_vecDragonSoulNames[i].c_str(), g_astGradeName[j].c_str());
return false;
}
if (fee < 0)
{
sys_err ("In %s group of RefineGradeTables, fee of Grade(%s) is less than 0.",
m_vecDragonSoulNames[i].c_str(), g_astGradeName[j].c_str());
return false;
}
if (DRAGON_SOUL_GRADE_MAX != vec_probs.size())
{
sys_err ("In %s group of RefineGradeTables, probability list size is not %d.", DRAGON_SOUL_GRADE_MAX);
return false;
}
for (int k = 0; k < vec_probs.size(); k++)
{
if (vec_probs[k] < 0.f)
{
sys_err ("In %s group of RefineGradeTables, probability(index : %d) is less than 0.", k);
return false;
}
}
}
}
}
return true;
}
bool DragonSoulTable::CheckRefineStepTables ()
{
// Group ImproveTables Reading.
if (NULL == m_pRefineStrengthTableNode)
{
sys_err ("dragon_soul_table.txt need RefineStepTables.");
return false;
}
else
{
for (int i = 0; i < m_vecDragonSoulTypes.size(); i++)
{
for (int j = 0; j < DRAGON_SOUL_STEP_MAX - 1; j++)
{
int need_count, fee;
std::vector <float> vec_probs;
if (!GetRefineStepValues(m_vecDragonSoulTypes[i], j, need_count, fee, vec_probs))
{
sys_err ("In %s group of RefineStepTables, values in Step(%s) row is invalid.",
m_vecDragonSoulNames[i].c_str(), g_astStepName[j].c_str());
return false;
}
if (need_count < 1)
{
sys_err ("In %s group of RefineStepTables, need_count of Step(%s) is less than 1.",
m_vecDragonSoulNames[i].c_str(), g_astStepName[j].c_str());
return false;
}
if (fee < 0)
{
sys_err ("In %s group of RefineStepTables, fee of Step(%s) is less than 0.",
m_vecDragonSoulNames[i].c_str(), g_astStepName[j].c_str());
return false;
}
if (DRAGON_SOUL_GRADE_MAX != vec_probs.size())
{
sys_err ("In %s group of RefineStepTables, probability list size is not %d.",
m_vecDragonSoulNames[i].c_str(), DRAGON_SOUL_GRADE_MAX);
return false;
}
for (int k = 0; k < vec_probs.size(); k++)
{
if (vec_probs[k] < 0.f)
{
sys_err ("In %s group of RefineStepTables, probability(index : %d) is less than 0.",
m_vecDragonSoulNames[i].c_str(), k);
return false;
}
}
}
}
}
return true;
}
bool DragonSoulTable::CheckRefineStrengthTables()
{
CGroupNode* pGroupNode = m_pRefineStrengthTableNode;
// Group RefineTables Reading.
if (NULL == pGroupNode)
{
sys_err ("dragon_soul_table.txt need RefineStrengthTables.");
return false;
}
for (int i = 0; i < m_vecDragonSoulTypes.size(); i++)
{
for (int j = MATERIAL_DS_REFINE_NORMAL; j <= MATERIAL_DS_REFINE_HOLLY; j++)
{
int fee;
float prob;
for (int k = 0; k < DRAGON_SOUL_STRENGTH_MAX -1; k++)
{
if (!GetRefineStrengthValues(m_vecDragonSoulTypes[i], j, k, fee, prob))
{
sys_err ("In %s group of RefineStrengthTables, value(Material(%s), Strength(%d)) or fee are invalid.",
m_vecDragonSoulNames[i].c_str(), g_astMaterialName[j].c_str(), k);
return false;
}
if (fee < 0)
{
sys_err ("In %s group of RefineStrengthTables, fee of Material(%s) is less than 0.",
m_vecDragonSoulNames[i].c_str(), g_astMaterialName[j].c_str());
return false;
}
if (prob < 0.f)
{
sys_err ("In %s group of RefineStrengthTables, probability(Material(%s), Strength(%d)) is less than 0.",
m_vecDragonSoulNames[i].c_str(), g_astMaterialName[j].c_str(), k);
return false;
}
}
}
}
return true;
}
bool DragonSoulTable::CheckDragonHeartExtTables()
{
// Group DragonHeartExtTables Reading.
if (NULL == m_pDragonHeartExtTableNode)
{
sys_err ("dragon_soul_table.txt need DragonHeartExtTables.");
return false;
}
for (int i = 0; i < m_vecDragonSoulTypes.size(); i++)
{
for (int j = 0; j < DRAGON_SOUL_GRADE_MAX; j++)
{
std::vector <float> vec_chargings;
std::vector <float> vec_probs;
if (!GetDragonHeartExtValues(m_vecDragonSoulTypes[i], j, vec_chargings, vec_probs))
{
sys_err ("In %s group of DragonHeartExtTables, CHARGING row or Grade(%s) row are invalid.",
m_vecDragonSoulNames[i].c_str(), g_astGradeName[j].c_str());
return false;
}
if (vec_chargings.size() != vec_probs.size())
{
sys_err ("In %s group of DragonHeartExtTables, CHARGING row size(%d) are not equal Grade(%s) row size(%d).",
m_vecDragonSoulNames[i].c_str(), vec_chargings.size(), vec_probs.size());
return false;
}
for (int k = 0; k < vec_chargings.size(); k++)
{
if (vec_chargings[k] < 0.f)
{
sys_err ("In %s group of DragonHeartExtTables, CHARGING value(index : %d) is less than 0",
m_vecDragonSoulNames[i].c_str(), k);
return false;
}
}
for (int k = 0; k < vec_probs.size(); k++)
{
if (vec_probs[k] < 0.f)
{
sys_err ("In %s group of DragonHeartExtTables, Probability(Grade : %s, index : %d) is less than 0",
m_vecDragonSoulNames[i].c_str(), g_astGradeName[j].c_str(), k);
return false;
}
}
}
}
return true;
}
bool DragonSoulTable::CheckDragonSoulExtTables()
{
// Group DragonSoulExtTables Reading.
if (NULL == m_pDragonSoulExtTableNode)
{
sys_err ("dragon_soul_table.txt need DragonSoulExtTables.");
return false;
}
for (int i = 0; i < m_vecDragonSoulTypes.size(); i++)
{
for (int j = 0; j < DRAGON_SOUL_GRADE_MAX; j++)
{
float prob;
DWORD by_product;
if (!GetDragonSoulExtValues(m_vecDragonSoulTypes[i], j, prob, by_product))
{
sys_err ("In %s group of DragonSoulExtTables, Grade(%s) row is invalid.",
m_vecDragonSoulNames[i].c_str(), g_astGradeName[j].c_str());
return false;
}
if (prob < 0.f)
{
sys_err ("In %s group of DragonSoulExtTables, Probability(Grade : %s) is less than 0",
m_vecDragonSoulNames[i].c_str(), g_astGradeName[j].c_str());
return false;
}
if (0 != by_product && NULL == ITEM_MANAGER::instance().GetTable(by_product))
{
sys_err ("In %s group of DragonSoulExtTables, ByProduct(%d) of Grade %s is not exist.",
m_vecDragonSoulNames[i].c_str(), by_product, g_astGradeName[j].c_str());
return false;
}
}
}
return true;
}
bool DragonSoulTable::GetBasicApplys(BYTE ds_type, OUT TVecApplys& vec_basic_applys)
{
TMapApplyGroup::iterator it = m_map_basic_applys_group.find(ds_type);
if (m_map_basic_applys_group.end() == it)
{
return false;
}
vec_basic_applys = it->second;
return true;
}
bool DragonSoulTable::GetAdditionalApplys(BYTE ds_type, OUT TVecApplys& vec_additional_applys)
{
TMapApplyGroup::iterator it = m_map_additional_applys_group.find(ds_type);
if (m_map_additional_applys_group.end() == it)
{
return false;
}
vec_additional_applys = it->second;
return true;
}
bool DragonSoulTable::GetApplyNumSettings(BYTE ds_type, BYTE grade_idx, OUT int& basis, OUT int& add_min, OUT int& add_max)
{
if (grade_idx >= DRAGON_SOUL_GRADE_MAX)
{
sys_err ("Invalid dragon soul grade_idx(%d).", grade_idx);
return false;
}
std::string stValue;
std::string stDragonSoulName;
if (!GetDragonSoulGroupName(ds_type, stDragonSoulName))
{
sys_err ("Invalid dragon soul type(%d).", ds_type);
return false;
}
if (!m_pApplyNumSettingNode->GetGroupValue(stDragonSoulName, "basis", g_astGradeName[grade_idx], basis))
{
sys_err ("Invalid basis value. DragonSoulGroup(%s) Grade(%s)", stDragonSoulName.c_str(), g_astGradeName[grade_idx].c_str());
return false;
}
if (!m_pApplyNumSettingNode->GetGroupValue(stDragonSoulName, "add_min", g_astGradeName[grade_idx], add_min))
{
sys_err ("Invalid add_min value. DragonSoulGroup(%s) Grade(%s)", stDragonSoulName.c_str(), g_astGradeName[grade_idx].c_str());
return false;
}
if (!m_pApplyNumSettingNode->GetGroupValue(stDragonSoulName, "add_max", g_astGradeName[grade_idx], add_max))
{
sys_err ("Invalid add_max value. DragonSoulGroup(%s) Grade(%s)", stDragonSoulName.c_str(), g_astGradeName[grade_idx].c_str());
return false;
}
return true;
}
bool DragonSoulTable::GetWeight(BYTE ds_type, BYTE grade_idx, BYTE step_index, BYTE strength_idx, OUT float& fWeight)
{
if (grade_idx >= DRAGON_SOUL_GRADE_MAX || step_index >= DRAGON_SOUL_STEP_MAX || strength_idx >= DRAGON_SOUL_STRENGTH_MAX)
{
sys_err ("Invalid dragon soul grade_idx(%d) step_index(%d) strength_idx(%d).", grade_idx, step_index, strength_idx);
return false;
}
std::string stValue;
std::string stDragonSoulName;
if (!GetDragonSoulGroupName(ds_type, stDragonSoulName))
{
sys_err ("Invalid dragon soul type(%d).", ds_type);
return false;
}
CGroupNode* pDragonSoulGroup = m_pWeightTableNode->GetChildNode(stDragonSoulName);
if (NULL != pDragonSoulGroup)
{
if (pDragonSoulGroup->GetGroupValue(g_astGradeName[grade_idx], g_astStepName[step_index], strength_idx, fWeight))
{
return true;
}
}
// default group을 살펴봄.
pDragonSoulGroup = m_pWeightTableNode->GetChildNode("default");
if (NULL != pDragonSoulGroup)
{
if (!pDragonSoulGroup->GetGroupValue(g_astGradeName[grade_idx], g_astStepName[step_index], strength_idx, fWeight))
{
sys_err ("Invalid float. DragonSoulGroup(%s) Grade(%s) Row(%s) Col(%d))", stDragonSoulName.c_str(), g_astGradeName[grade_idx].c_str(), g_astStepName[step_index].c_str(), strength_idx);
return false;
}
else
return true;
}
sys_err ("Invalid value. DragonSoulGroup(%s) Grade(%s) Row(%s) Col(%d))", stDragonSoulName.c_str(), g_astGradeName[grade_idx].c_str(), g_astStepName[step_index].c_str(), strength_idx);
return false;
}
bool DragonSoulTable::GetRefineGradeValues(BYTE ds_type, BYTE grade_idx, OUT int& need_count, OUT int& fee, OUT std::vector<float>& vec_probs)
{
if (grade_idx >= DRAGON_SOUL_GRADE_MAX -1)
{
sys_err ("Invalid dragon soul grade_idx(%d).", grade_idx);
return false;
}
std::string stValue;
std::string stDragonSoulName;
if (!GetDragonSoulGroupName(ds_type, stDragonSoulName))
{
sys_err ("Invalid dragon soul type(%d).", ds_type);
return false;
}
const CGroupNode::CGroupNodeRow * pRow;
if (!m_pRefineGradeTableNode->GetGroupRow(stDragonSoulName, g_astGradeName[grade_idx], &pRow))
{
sys_err ("Invalid row. DragonSoulGroup(%s) Grade(%s)", stDragonSoulName.c_str(), g_astGradeName[grade_idx].c_str());
return false;
}
if (!pRow->GetValue("need_count", need_count))
{
sys_err ("Invalid value. DragonSoulGroup(%s) Grade(%s) Col(need_count)", stDragonSoulName.c_str(), g_astGradeName[grade_idx].c_str());
return false;
}
if (!pRow->GetValue("fee", fee))
{
sys_err ("Invalid value. DragonSoulGroup(%s) Grade(%s) Col(fee)", stDragonSoulName.c_str(), g_astGradeName[grade_idx].c_str());
return false;
}
vec_probs.resize(DRAGON_SOUL_GRADE_MAX);
for (int i = 0; i < DRAGON_SOUL_GRADE_MAX; i++)
{
if (!pRow->GetValue(g_astGradeName[i], vec_probs[i]))
{
sys_err ("Invalid value. DragonSoulGroup(%s) Grade(%s) Col(%s)", stDragonSoulName.c_str(), g_astGradeName[grade_idx].c_str(), g_astGradeName[i].c_str());
return false;
}
}
return true;
}
bool DragonSoulTable::GetRefineStepValues(BYTE ds_type, BYTE step_idx, OUT int& need_count, OUT int& fee, OUT std::vector<float>& vec_probs)
{
if (step_idx >= DRAGON_SOUL_STEP_MAX - 1)
{
sys_err ("Invalid dragon soul step_idx(%d).", step_idx);
return false;
}
std::string stValue;
std::string stDragonSoulName;
if (!GetDragonSoulGroupName(ds_type, stDragonSoulName))
{
sys_err ("Invalid dragon soul type(%d).", ds_type);
return false;
}
const CGroupNode::CGroupNodeRow * pRow;
if (!m_pRefineStepTableNode->GetGroupRow(stDragonSoulName, g_astStepName[step_idx], &pRow))
{
sys_err ("Invalid row. DragonSoulGroup(%s) Step(%s)", stDragonSoulName.c_str(), g_astStepName[step_idx].c_str());
return false;
}
if (!pRow->GetValue("need_count", need_count))
{
sys_err ("Invalid value. DragonSoulGroup(%s) Step(%s) Col(need_count)", stDragonSoulName.c_str(), g_astStepName[step_idx].c_str());
return false;
}
if (!pRow->GetValue("fee", fee))
{
sys_err ("Invalid value. DragonSoulGroup(%s) Step(%s) Col(fee)", stDragonSoulName.c_str(), g_astStepName[step_idx].c_str());
return false;
}
vec_probs.resize(DRAGON_SOUL_STEP_MAX);
for (int i = 0; i < DRAGON_SOUL_STEP_MAX; i++)
{
if (!pRow->GetValue(g_astStepName[i], vec_probs[i]))
{
sys_err ("Invalid value. DragonSoulGroup(%s) Step(%s) Col(%s)", stDragonSoulName.c_str(), g_astStepName[step_idx].c_str(), g_astStepName[i].c_str());
return false;
}
}
return true;
}
bool DragonSoulTable::GetRefineStrengthValues(BYTE ds_type, BYTE material_type, BYTE strength_idx, OUT int& fee, OUT float& prob)
{
if (material_type < MATERIAL_DS_REFINE_NORMAL || material_type > MATERIAL_DS_REFINE_HOLLY)
{
sys_err ("Invalid dragon soul material_type(%d).", material_type);
return false;
}
std::string stValue;
std::string stDragonSoulName;
if (!GetDragonSoulGroupName(ds_type, stDragonSoulName))
{
sys_err ("Invalid dragon soul type(%d).", ds_type);
return false;
}
if (!m_pRefineStrengthTableNode->GetGroupValue(stDragonSoulName, g_astMaterialName[material_type], "fee", fee))
{
sys_err ("Invalid fee. DragonSoulGroup(%s) Material(%s)",
stDragonSoulName.c_str(), g_astMaterialName[material_type].c_str());
return false;
}
std::string stStrengthIdx = boost::lexical_cast <std::string> ((int)strength_idx);
if (!m_pRefineStrengthTableNode->GetGroupValue(stDragonSoulName, g_astMaterialName[material_type], stStrengthIdx, prob))
{
sys_err ("Invalid prob. DragonSoulGroup(%s) Material(%s) Strength(%d)",
stDragonSoulName.c_str(), g_astMaterialName[material_type].c_str(), strength_idx);
return false;
}
return true;
}
bool DragonSoulTable::GetDragonHeartExtValues(BYTE ds_type, BYTE grade_idx, OUT std::vector<float>& vec_chargings, OUT std::vector<float>& vec_probs)
{
if (grade_idx >= DRAGON_SOUL_GRADE_MAX)
{
sys_err ("Invalid dragon soul grade_idx(%d).", grade_idx);
return false;
}
std::string stDragonSoulName;
if (!GetDragonSoulGroupName(ds_type, stDragonSoulName))
{
sys_err ("Invalid dragon soul type(%d).", ds_type);
return false;
}
const CGroupNode::CGroupNodeRow * pRow;
if (!m_pDragonHeartExtTableNode->GetGroupRow(stDragonSoulName, "charging", &pRow))
{
sys_err ("Invalid CHARGING row. DragonSoulGroup(%s)", stDragonSoulName.c_str());
return false;
}
int n = pRow->GetSize();
vec_chargings.resize(n);
for (int i = 0; i < n; i++)
{
if (!pRow->GetValue(i, vec_chargings[i]))
{
sys_err ("Invalid CHARGING value. DragonSoulGroup(%s), Col(%d)", stDragonSoulName.c_str(), i);
return false;
}
}
if (!m_pDragonHeartExtTableNode->GetGroupRow(stDragonSoulName, g_astGradeName[grade_idx], &pRow))
{
sys_err ("Invalid row. DragonSoulGroup(%s) Grade(%s)", stDragonSoulName.c_str(), g_astGradeName[grade_idx].c_str());
return false;
}
int m = pRow->GetSize();
if (n != m)
{
sys_err ("Invalid row size(%d). It must be same CHARGING row size(%d). DragonSoulGroup(%s) Grade(%s)", m, n,
stDragonSoulName.c_str(), g_astGradeName[grade_idx].c_str());
return false;
}
vec_probs.resize(m);
for (int i = 0; i < m; i++)
{
if (!pRow->GetValue(i, vec_probs[i]))
{
sys_err ("Invalid value. DragonSoulGroup(%s), Grade(%s) Col(%d)", stDragonSoulName.c_str(), g_astGradeName[grade_idx].c_str(), i);
return false;
}
}
return true;
}
bool DragonSoulTable::GetDragonSoulExtValues(BYTE ds_type, BYTE grade_idx, OUT float& prob, OUT DWORD& by_product)
{
if (grade_idx >= DRAGON_SOUL_GRADE_MAX)
{
sys_err ("Invalid dragon soul grade_idx(%d).", grade_idx);
return false;
}
std::string stValue;
std::string stDragonSoulName;
if (!GetDragonSoulGroupName(ds_type, stDragonSoulName))
{
sys_err ("Invalid dragon soul type(%d).", ds_type);
return false;
}
if (!m_pDragonSoulExtTableNode->GetGroupValue(stDragonSoulName, g_astGradeName[grade_idx], "prob", prob))
{
sys_err ("Invalid Prob. DragonSoulGroup(%s) Grade(%s)",
stDragonSoulName.c_str(), g_astGradeName[grade_idx].c_str(), g_astGradeName[grade_idx].c_str());
return false;
}
if (!m_pDragonSoulExtTableNode->GetGroupValue(stDragonSoulName, g_astGradeName[grade_idx], "byproduct", by_product))
{
sys_err ("Invalid fee. DragonSoulGroup(%s) Grade(%d)",
stDragonSoulName.c_str(), g_astGradeName[grade_idx].c_str(), grade_idx);
return false;
}
return true;
}
DragonSoulTable::DragonSoulTable()
{
m_pLoader = NULL;
}
DragonSoulTable::~DragonSoulTable ()
{
if (m_pLoader)
delete m_pLoader;
}
-74
View File
@@ -1,74 +0,0 @@
#ifndef __INC_METIN_II_DRAGON_SOUL_TABLE_H__
#define __INC_METIN_II_DRAGON_SOUL_TABLE_H__
struct SApply
{
SApply (EApplyTypes at, int av, float p = 0.f) : apply_type(at), apply_value(av), prob(p) {}
EApplyTypes apply_type;
int apply_value;
float prob;
};
const int DRAGON_SOUL_ADDITIONAL_ATTR_START_IDX = 3;
class CGroupNode;
class CGroupTextParseTreeLoader;
class DragonSoulTable
{
public:
DragonSoulTable();
~DragonSoulTable();
typedef std::vector <SApply> TVecApplys;
typedef std::map <BYTE, TVecApplys> TMapApplyGroup;
bool ReadDragonSoulTableFile(const char * c_pszFileName);
bool GetDragonSoulGroupName(BYTE bType, std::string& stGroupName) const;
bool GetBasicApplys(BYTE ds_type, OUT TVecApplys& vec_basic_applys);
bool GetAdditionalApplys(BYTE ds_type, OUT TVecApplys& vec_additional_attrs);
bool GetApplyNumSettings(BYTE ds_type, BYTE grade_idx, OUT int& basis, OUT int& add_min, OUT int& add_max);
bool GetWeight(BYTE ds_type, BYTE grade_idx, BYTE step_index, BYTE strength_idx, OUT float& fWeight);
bool GetRefineGradeValues(BYTE ds_type, BYTE grade_idx, OUT int& need_count, OUT int& fee, OUT std::vector<float>& vec_probs);
bool GetRefineStepValues(BYTE ds_type, BYTE step_idx, OUT int& need_count, OUT int& fee, OUT std::vector<float>& vec_probs);
bool GetRefineStrengthValues(BYTE ds_type, BYTE material_type, BYTE strength_idx, OUT int& fee, OUT float& prob);
bool GetDragonHeartExtValues(BYTE ds_type, BYTE grade_idx, OUT std::vector<float>& vec_chargings, OUT std::vector<float>& vec_probs);
bool GetDragonSoulExtValues(BYTE ds_type, BYTE grade_idx, OUT float& prob, OUT DWORD& by_product);
private:
CGroupTextParseTreeLoader* m_pLoader;
std::string stFileName;
// caching m_pLoader's child nodes.
CGroupNode* m_pApplyNumSettingNode;
CGroupNode* m_pWeightTableNode;
CGroupNode* m_pRefineGradeTableNode;
CGroupNode* m_pRefineStepTableNode;
CGroupNode* m_pRefineStrengthTableNode;
CGroupNode* m_pDragonHeartExtTableNode;
CGroupNode* m_pDragonSoulExtTableNode;
typedef std::map <std::string, BYTE> TMapNameToType;
typedef std::map <BYTE, std::string> TMapTypeToName;
std::vector <std::string> m_vecDragonSoulNames;
std::vector <BYTE> m_vecDragonSoulTypes;
TMapNameToType m_map_name_to_type;
TMapTypeToName m_map_type_to_name;
TMapApplyGroup m_map_basic_applys_group;
TMapApplyGroup m_map_additional_applys_group;
bool ReadVnumMapper();
bool ReadBasicApplys();
bool ReadAdditionalApplys();
// table check functions.
bool CheckApplyNumSettings();
bool CheckWeightTables();
bool CheckRefineGradeTables();
bool CheckRefineStepTables();
bool CheckRefineStrengthTables();
bool CheckDragonHeartExtTables();
bool CheckDragonSoulExtTables();
};
#endif
-65
View File
@@ -12,7 +12,6 @@
#include "locale_service.h" #include "locale_service.h"
#include "../../common/length.h" #include "../../common/length.h"
#include "exchange.h" #include "exchange.h"
#include "DragonSoul.h"
void exchange_packet(LPCHARACTER ch, BYTE sub_header, bool is_me, DWORD arg1, TItemPos arg2, DWORD arg3, void * pvData = NULL); void exchange_packet(LPCHARACTER ch, BYTE sub_header, bool is_me, DWORD arg1, TItemPos arg2, DWORD arg3, void * pvData = NULL);
@@ -325,68 +324,11 @@ bool CExchange::CheckSpace()
s_grid2.Put(i - INVENTORY_MAX_NUM / 2, 1, item->GetSize()); s_grid2.Put(i - INVENTORY_MAX_NUM / 2, 1, item->GetSize());
} }
// 아... 뭔가 개병신 같지만... 용혼석 인벤을 노멀 인벤 보고 따라 만든 내 잘못이다 ㅠㅠ
static std::vector <WORD> s_vDSGrid(DRAGON_SOUL_INVENTORY_MAX_NUM);
// 일단 용혼석을 교환하지 않을 가능성이 크므로, 용혼석 인벤 복사는 용혼석이 있을 때 하도록 한다.
bool bDSInitialized = false;
for (i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i) for (i = 0; i < EXCHANGE_ITEM_MAX_NUM; ++i)
{ {
if (!(item = m_apItems[i])) if (!(item = m_apItems[i]))
continue; continue;
if (item->IsDragonSoul())
{
if (!victim->DragonSoul_IsQualified())
{
return false;
}
if (!bDSInitialized)
{
bDSInitialized = true;
victim->CopyDragonSoulItemGrid(s_vDSGrid);
}
bool bExistEmptySpace = false;
WORD wBasePos = DSManager::instance().GetBasePosition(item);
if (wBasePos >= DRAGON_SOUL_INVENTORY_MAX_NUM)
return false;
for (int i = 0; i < DRAGON_SOUL_BOX_SIZE; i++)
{
WORD wPos = wBasePos + i;
// if (0 == s_vDSGrid[wBasePos])
if (0 == s_vDSGrid[wPos]) // Fix
{
bool bEmpty = true;
for (int j = 1; j < item->GetSize(); j++)
{
if (s_vDSGrid[wPos + j * DRAGON_SOUL_BOX_COLUMN_NUM])
{
bEmpty = false;
break;
}
}
if (bEmpty)
{
for (int j = 0; j < item->GetSize(); j++)
{
s_vDSGrid[wPos + j * DRAGON_SOUL_BOX_COLUMN_NUM] = wPos + 1;
}
bExistEmptySpace = true;
break;
}
}
if (bExistEmptySpace)
break;
}
if (!bExistEmptySpace)
return false;
}
else
{
int iPos = s_grid1.FindBlank(1, item->GetSize()); int iPos = s_grid1.FindBlank(1, item->GetSize());
if (iPos >= 0) if (iPos >= 0)
@@ -407,7 +349,6 @@ bool CExchange::CheckSpace()
} }
} }
} }
}
return true; return true;
} }
@@ -425,9 +366,6 @@ bool CExchange::Done()
if (!(item = m_apItems[i])) if (!(item = m_apItems[i]))
continue; continue;
if (item->IsDragonSoul())
empty_pos = victim->GetEmptyDragonSoulInventory(item);
else
empty_pos = victim->GetEmptyInventory(item->GetSize()); empty_pos = victim->GetEmptyInventory(item->GetSize());
if (empty_pos < 0) if (empty_pos < 0)
@@ -448,9 +386,6 @@ bool CExchange::Done()
m_pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, item->GetCell(), 255); m_pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, item->GetCell(), 255);
item->RemoveFromCharacter(); item->RemoveFromCharacter();
if (item->IsDragonSoul())
item->AddToCharacter(victim, TItemPos(DRAGON_SOUL_INVENTORY, empty_pos));
else
item->AddToCharacter(victim, TItemPos(INVENTORY, empty_pos)); item->AddToCharacter(victim, TItemPos(INVENTORY, empty_pos));
ITEM_MANAGER::instance().FlushDelayedSave(item); ITEM_MANAGER::instance().FlushDelayedSave(item);
-24
View File
@@ -358,10 +358,6 @@
RelativePath=".\char_change_empire.cpp" RelativePath=".\char_change_empire.cpp"
> >
</File> </File>
<File
RelativePath=".\char_dragonsoul.cpp"
>
</File>
<File <File
RelativePath=".\char_hackshield.cpp" RelativePath=".\char_hackshield.cpp"
> >
@@ -538,14 +534,6 @@
RelativePath=".\dev_log.h" RelativePath=".\dev_log.h"
> >
</File> </File>
<File
RelativePath=".\dragon_soul_table.cpp"
>
</File>
<File
RelativePath=".\dragon_soul_table.h"
>
</File>
<File <File
RelativePath=".\DragonLair.cpp" RelativePath=".\DragonLair.cpp"
> >
@@ -554,14 +542,6 @@
RelativePath=".\DragonLair.h" RelativePath=".\DragonLair.h"
> >
</File> </File>
<File
RelativePath=".\DragonSoul.cpp"
>
</File>
<File
RelativePath=".\DragonSoul.h"
>
</File>
<File <File
RelativePath=".\dungeon.cpp" RelativePath=".\dungeon.cpp"
> >
@@ -1102,10 +1082,6 @@
RelativePath=".\questlua_dragonlair.cpp" RelativePath=".\questlua_dragonlair.cpp"
> >
</File> </File>
<File
RelativePath=".\questlua_dragonsoul.cpp"
>
</File>
<File <File
RelativePath=".\questlua_dungeon.cpp" RelativePath=".\questlua_dungeon.cpp"
> >
-13
View File
@@ -46,7 +46,6 @@
#include "map_location.h" #include "map_location.h"
// #include "HackShield.h" // #include "HackShield.h"
#include "DragonSoul.h"
#ifdef __AUCTION__ #ifdef __AUCTION__
#include "auction_manager.h" #include "auction_manager.h"
@@ -928,7 +927,6 @@ void CInputDB::Boot(const char* data)
char szSpecialItemGroupFileName[FILE_NAME_LEN]; char szSpecialItemGroupFileName[FILE_NAME_LEN];
char szMapIndexFileName[FILE_NAME_LEN]; char szMapIndexFileName[FILE_NAME_LEN];
char szItemVnumMaskTableFileName[FILE_NAME_LEN]; char szItemVnumMaskTableFileName[FILE_NAME_LEN];
char szDragonSoulTableFileName[FILE_NAME_LEN];
snprintf(szCommonDropItemFileName, sizeof(szCommonDropItemFileName), snprintf(szCommonDropItemFileName, sizeof(szCommonDropItemFileName),
"%s/common_drop_item.txt", LocaleService_GetBasePath().c_str()); "%s/common_drop_item.txt", LocaleService_GetBasePath().c_str());
@@ -944,8 +942,6 @@ void CInputDB::Boot(const char* data)
"%s/index", LocaleService_GetMapPath().c_str()); "%s/index", LocaleService_GetMapPath().c_str());
snprintf(szItemVnumMaskTableFileName, sizeof(szItemVnumMaskTableFileName), snprintf(szItemVnumMaskTableFileName, sizeof(szItemVnumMaskTableFileName),
"%s/ori_to_new_table.txt", LocaleService_GetBasePath().c_str()); "%s/ori_to_new_table.txt", LocaleService_GetBasePath().c_str());
snprintf(szDragonSoulTableFileName, sizeof(szDragonSoulTableFileName),
"%s/dragon_soul_table.txt", LocaleService_GetBasePath().c_str());
sys_log(0, "Initializing Informations of Cube System"); sys_log(0, "Initializing Informations of Cube System");
if (!Cube_InformationInitialize()) if (!Cube_InformationInitialize())
@@ -1009,14 +1005,6 @@ void CInputDB::Boot(const char* data)
return; return;
} }
sys_log(0, "LoadLocaleFile: DragonSoulTable: %s", szDragonSoulTableFileName);
if (!DSManager::instance().ReadDragonSoulTableFile(szDragonSoulTableFileName))
{
sys_err("cannot load DragonSoulTable: %s", szDragonSoulTableFileName);
//thecore_shutdown();
//return;
}
// END_OF_LOCALE_SERVICE // END_OF_LOCALE_SERVICE
@@ -1577,7 +1565,6 @@ void CInputDB::ItemLoad(LPDESC d, const char * c_pData)
switch (p->window) switch (p->window)
{ {
case INVENTORY: case INVENTORY:
case DRAGON_SOUL_INVENTORY:
item->AddToCharacter(ch, TItemPos(p->window, p->pos)); item->AddToCharacter(ch, TItemPos(p->window, p->pos));
break; break;
-64
View File
@@ -40,7 +40,6 @@
#include "locale_service.h" #include "locale_service.h"
// #include "HackShield.h" // #include "HackShield.h"
// #include "XTrapManager.h" // #include "XTrapManager.h"
#include "DragonSoul.h"
extern void SendShout(const char * szText, BYTE bEmpire); extern void SendShout(const char * szText, BYTE bEmpire);
extern int g_nPortalLimitTime; extern int g_nPortalLimitTime;
@@ -2105,7 +2104,6 @@ void CInputMain::SafeboxCheckin(LPCHARACTER ch, const char * c_pData)
} }
pkItem->RemoveFromCharacter(); pkItem->RemoveFromCharacter();
if (!pkItem->IsDragonSoul())
ch->SyncQuickslot(QUICKSLOT_TYPE_ITEM, p->ItemPos.cell, 255); ch->SyncQuickslot(QUICKSLOT_TYPE_ITEM, p->ItemPos.cell, 255);
pkSafebox->Add(p->bSafePos, pkItem); pkSafebox->Add(p->bSafePos, pkItem);
@@ -2139,40 +2137,6 @@ void CInputMain::SafeboxCheckout(LPCHARACTER ch, const char * c_pData, bool bMal
if (!ch->IsEmptyItemGrid(p->ItemPos, pkItem->GetSize())) if (!ch->IsEmptyItemGrid(p->ItemPos, pkItem->GetSize()))
return; return;
// 아이템 몰에서 인벤으로 옮기는 부분에서 용혼석 특수 처리
// (몰에서 만드는 아이템은 item_proto에 정의된대로 속성이 붙기 때문에,
// 용혼석의 경우, 이 처리를 하지 않으면 속성이 하나도 붙지 않게 된다.)
if (pkItem->IsDragonSoul())
{
if (bMall)
{
DSManager::instance().DragonSoulItemInitialize(pkItem);
}
if (DRAGON_SOUL_INVENTORY != p->ItemPos.window_type)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<창고> 옮길 수 없는 위치입니다."));
return;
}
TItemPos DestPos = p->ItemPos;
if (!DSManager::instance().IsValidCellForThisItem(pkItem, DestPos))
{
int iCell = ch->GetEmptyDragonSoulInventory(pkItem);
if (iCell < 0)
{
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<창고> 옮길 수 없는 위치입니다."));
return ;
}
DestPos = TItemPos (DRAGON_SOUL_INVENTORY, iCell);
}
pkSafebox->Remove(p->bSafePos);
pkItem->AddToCharacter(ch, DestPos);
ITEM_MANAGER::instance().FlushDelayedSave(pkItem);
}
else
{
if (DRAGON_SOUL_INVENTORY == p->ItemPos.window_type) if (DRAGON_SOUL_INVENTORY == p->ItemPos.window_type)
{ {
ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<창고> 옮길 수 없는 위치입니다.")); ch->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("<창고> 옮길 수 없는 위치입니다."));
@@ -2195,7 +2159,6 @@ void CInputMain::SafeboxCheckout(LPCHARACTER ch, const char * c_pData, bool bMal
} }
pkItem->AddToCharacter(ch, p->ItemPos); pkItem->AddToCharacter(ch, p->ItemPos);
ITEM_MANAGER::instance().FlushDelayedSave(pkItem); ITEM_MANAGER::instance().FlushDelayedSave(pkItem);
}
DWORD dwID = pkItem->GetID(); DWORD dwID = pkItem->GetID();
db_clientdesc->DBPacketHeader(HEADER_GD_ITEM_FLUSH, 0, sizeof(DWORD)); db_clientdesc->DBPacketHeader(HEADER_GD_ITEM_FLUSH, 0, sizeof(DWORD));
@@ -3349,33 +3312,6 @@ int CInputMain::Analyze(LPDESC d, BYTE bHeader, const char * c_pData)
// } // }
// break; // break;
case HEADER_CG_DRAGON_SOUL_REFINE:
{
TPacketCGDragonSoulRefine* p = reinterpret_cast <TPacketCGDragonSoulRefine*>((void*)c_pData);
switch(p->bSubType)
{
case DS_SUB_HEADER_CLOSE:
ch->DragonSoul_RefineWindow_Close();
break;
case DS_SUB_HEADER_DO_REFINE_GRADE:
{
DSManager::instance().DoRefineGrade(ch, p->ItemGrid);
}
break;
case DS_SUB_HEADER_DO_REFINE_STEP:
{
DSManager::instance().DoRefineStep(ch, p->ItemGrid);
}
break;
case DS_SUB_HEADER_DO_REFINE_STRENGTH:
{
DSManager::instance().DoRefineStrength(ch, p->ItemGrid);
}
break;
}
}
break;
} }
return (iExtraLen); return (iExtraLen);
} }
+2 -142
View File
@@ -17,7 +17,6 @@
#include "item.h" #include "item.h"
#include "item_manager.h" #include "item_manager.h"
#include "affect.h" #include "affect.h"
#include "DragonSoul.h"
#include "buff_on_attributes.h" #include "buff_on_attributes.h"
#include "belt_inventory_helper.h" #include "belt_inventory_helper.h"
#include "../../common/VnumHelper.h" #include "../../common/VnumHelper.h"
@@ -251,8 +250,6 @@ bool CItem::SetCount(DWORD count)
RemoveFromCharacter(); RemoveFromCharacter();
if (!IsDragonSoul())
{
LPITEM pItem = pOwner->FindSpecifyItem(GetVnum()); LPITEM pItem = pOwner->FindSpecifyItem(GetVnum());
if (NULL != pItem) if (NULL != pItem)
@@ -263,16 +260,12 @@ bool CItem::SetCount(DWORD count)
{ {
pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, wCell, 255); pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, wCell, 255);
} }
}
M2_DESTROY_ITEM(this); M2_DESTROY_ITEM(this);
} }
else else
{ {
if (!IsDragonSoul())
{
m_pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, m_wCell, 255); m_pOwner->SyncQuickslot(QUICKSLOT_TYPE_ITEM, m_wCell, 255);
}
M2_DESTROY_ITEM(RemoveFromCharacter()); M2_DESTROY_ITEM(RemoveFromCharacter());
} }
@@ -308,15 +301,6 @@ LPITEM CItem::RemoveFromCharacter()
{ {
if (GetWindow() != SAFEBOX && GetWindow() != MALL) if (GetWindow() != SAFEBOX && GetWindow() != MALL)
{ {
if (IsDragonSoul())
{
if (m_wCell >= DRAGON_SOUL_INVENTORY_MAX_NUM)
sys_err("CItem::RemoveFromCharacter: pos >= DRAGON_SOUL_INVENTORY_MAX_NUM");
else
pOwner->SetItem(TItemPos(m_bWindow, m_wCell), NULL);
}
else
{
TItemPos cell(INVENTORY, m_wCell); TItemPos cell(INVENTORY, m_wCell);
if (false == cell.IsDefaultInventoryPosition() && false == cell.IsBeltInventoryPosition()) // 아니면 소지품에? if (false == cell.IsDefaultInventoryPosition() && false == cell.IsBeltInventoryPosition()) // 아니면 소지품에?
@@ -325,7 +309,6 @@ LPITEM CItem::RemoveFromCharacter()
{ {
pOwner->SetItem(cell, NULL); pOwner->SetItem(cell, NULL);
} }
}
} }
m_pOwner = NULL; m_pOwner = NULL;
@@ -352,14 +335,6 @@ bool CItem::AddToCharacter(LPCHARACTER ch, TItemPos Cell)
return false; return false;
} }
} }
else if (DRAGON_SOUL_INVENTORY == window_type)
{
if (m_wCell >= DRAGON_SOUL_INVENTORY_MAX_NUM)
{
sys_err("CItem::AddToCharacter: cell overflow: %s to %s cell %d", m_pProto->szName, ch->GetName(), m_wCell);
return false;
}
}
if (ch->GetDesc()) if (ch->GetDesc())
m_dwLastOwnerPID = ch->GetPlayerID(); m_dwLastOwnerPID = ch->GetPlayerID();
@@ -483,34 +458,10 @@ bool CItem::CanUsedBy(LPCHARACTER ch)
int CItem::FindEquipCell(LPCHARACTER ch, int iCandidateCell) int CItem::FindEquipCell(LPCHARACTER ch, int iCandidateCell)
{ {
// 코스츔 아이템(ITEM_COSTUME)은 WearFlag 없어도 됨. (sub type으로 착용위치 구분. 귀찮게 또 wear flag 줄 필요가 있나..) // 코스츔 아이템(ITEM_COSTUME)은 WearFlag 없어도 됨. (sub type으로 착용위치 구분. 귀찮게 또 wear flag 줄 필요가 있나..)
// 용혼석(ITEM_DS, ITEM_SPECIAL_DS)도 SUB_TYPE으로 구분. 신규 반지, 벨트는 ITEM_TYPE으로 구분 -_- if ((0 == GetWearFlag() || ITEM_TOTEM == GetType()) && ITEM_COSTUME != GetType() && ITEM_RING != GetType() && ITEM_BELT != GetType())
if ((0 == GetWearFlag() || ITEM_TOTEM == GetType()) && ITEM_COSTUME != GetType() && ITEM_DS != GetType() && ITEM_SPECIAL_DS != GetType() && ITEM_RING != GetType() && ITEM_BELT != GetType())
return -1; return -1;
// 용혼석 슬롯을 WEAR로 처리할 수가 없어서(WEAR는 최대 32개까지 가능한데 용혼석을 추가하면 32가 넘는다.) if (GetType() == ITEM_COSTUME)
// 인벤토리의 특정 위치((INVENTORY_MAX_NUM + WEAR_MAX_NUM)부터 (INVENTORY_MAX_NUM + WEAR_MAX_NUM + DRAGON_SOUL_DECK_MAX_NUM * DS_SLOT_MAX - 1)까지)를
// 용혼석 슬롯으로 정함.
// return 할 때에, INVENTORY_MAX_NUM을 뺀 이유는,
// 본래 WearCell이 INVENTORY_MAX_NUM를 빼고 return 하기 때문.
if (GetType() == ITEM_DS || GetType() == ITEM_SPECIAL_DS)
{
if (iCandidateCell < 0)
{
return WEAR_MAX_NUM + GetSubType();
}
else
{
for (int i = 0; i < DRAGON_SOUL_DECK_MAX_NUM; i++)
{
if (WEAR_MAX_NUM + i * DS_SLOT_MAX + GetSubType() == iCandidateCell)
{
return iCandidateCell;
}
}
return -1;
}
}
else if (GetType() == ITEM_COSTUME)
{ {
if (GetSubType() == COSTUME_BODY) if (GetSubType() == COSTUME_BODY)
return WEAR_COSTUME_BODY; return WEAR_COSTUME_BODY;
@@ -813,8 +764,6 @@ bool CItem::IsEquipable() const
case ITEM_ROD: case ITEM_ROD:
case ITEM_PICK: case ITEM_PICK:
case ITEM_UNIQUE: case ITEM_UNIQUE:
case ITEM_DS:
case ITEM_SPECIAL_DS:
case ITEM_RING: case ITEM_RING:
case ITEM_BELT: case ITEM_BELT:
return true; return true;
@@ -832,23 +781,11 @@ bool CItem::EquipTo(LPCHARACTER ch, BYTE bWearCell)
return false; return false;
} }
// 용혼석 슬롯 index는 WEAR_MAX_NUM 보다 큼.
if (IsDragonSoul())
{
if (bWearCell < WEAR_MAX_NUM || bWearCell >= WEAR_MAX_NUM + DRAGON_SOUL_DECK_MAX_NUM * DS_SLOT_MAX)
{
sys_err("EquipTo: invalid dragon soul cell (this: #%d %s wearflag: %d cell: %d)", GetOriginalVnum(), GetName(), GetSubType(), bWearCell - WEAR_MAX_NUM);
return false;
}
}
else
{
if (bWearCell >= WEAR_MAX_NUM) if (bWearCell >= WEAR_MAX_NUM)
{ {
sys_err("EquipTo: invalid wear cell (this: #%d %s wearflag: %d cell: %d)", GetOriginalVnum(), GetName(), GetWearFlag(), bWearCell); sys_err("EquipTo: invalid wear cell (this: #%d %s wearflag: %d cell: %d)", GetOriginalVnum(), GetName(), GetWearFlag(), bWearCell);
return false; return false;
} }
}
if (ch->GetWear(bWearCell)) if (ch->GetWear(bWearCell))
{ {
@@ -899,12 +836,6 @@ bool CItem::EquipTo(LPCHARACTER ch, BYTE bWearCell)
m_pOwner->SetImmuneFlag(dwImmuneFlag); m_pOwner->SetImmuneFlag(dwImmuneFlag);
//P3NG3R immun fix end //P3NG3R immun fix end
if (IsDragonSoul())
{
DSManager::instance().ActivateDragonSoul(this);
}
else
{
ModifyPoints(true); ModifyPoints(true);
StartUniqueExpireEvent(); StartUniqueExpireEvent();
if (-1 != GetProto()->cLimitTimerBasedOnWearIndex) if (-1 != GetProto()->cLimitTimerBasedOnWearIndex)
@@ -913,7 +844,6 @@ bool CItem::EquipTo(LPCHARACTER ch, BYTE bWearCell)
// ACCESSORY_REFINE // ACCESSORY_REFINE
StartAccessorySocketExpireEvent(); StartAccessorySocketExpireEvent();
// END_OF_ACCESSORY_REFINE // END_OF_ACCESSORY_REFINE
}
ch->BuffOnAttr_AddBuffsFromItem(this); ch->BuffOnAttr_AddBuffsFromItem(this);
@@ -947,14 +877,7 @@ bool CItem::Unequip()
if (IsRideItem()) if (IsRideItem())
ClearMountAttributeAndAffect(); ClearMountAttributeAndAffect();
if (IsDragonSoul())
{
DSManager::instance().DeactivateDragonSoul(this);
}
else
{
ModifyPoints(false); ModifyPoints(false);
}
StopUniqueExpireEvent(); StopUniqueExpireEvent();
@@ -1391,15 +1314,7 @@ EVENTFUNC(timer_based_on_wear_expire_event)
pkItem->SetTimerBasedOnWearExpireEvent(NULL); pkItem->SetTimerBasedOnWearExpireEvent(NULL);
pkItem->SetSocket(ITEM_SOCKET_REMAIN_SEC, 0); pkItem->SetSocket(ITEM_SOCKET_REMAIN_SEC, 0);
// 일단 timer based on wear 용혼석은 시간 다 되었다고 없애지 않는다.
if (pkItem->IsDragonSoul())
{
DSManager::instance().DeactivateDragonSoul(pkItem);
}
else
{
ITEM_MANAGER::instance().RemoveItem(pkItem, "TIMER_BASED_ON_WEAR_EXPIRE"); ITEM_MANAGER::instance().RemoveItem(pkItem, "TIMER_BASED_ON_WEAR_EXPIRE");
}
return 0; return 0;
} }
pkItem->SetSocket(ITEM_SOCKET_REMAIN_SEC, remain_time); pkItem->SetSocket(ITEM_SOCKET_REMAIN_SEC, remain_time);
@@ -2062,61 +1977,6 @@ void CItem::CopyToRawData (TPlayerItem* new_item)
} }
#endif #endif
bool CItem::IsDragonSoul()
{
return GetType() == ITEM_DS;
}
int CItem::GiveMoreTime_Per(float fPercent)
{
if (IsDragonSoul())
{
DWORD duration = DSManager::instance().GetDuration(this);
int remain_sec = GetSocket(ITEM_SOCKET_REMAIN_SEC);
int given_time = fPercent * duration / 100;
if (remain_sec == duration)
return false;
if ((given_time + remain_sec) >= duration)
{
SetSocket(ITEM_SOCKET_REMAIN_SEC, duration);
return duration - remain_sec;
}
else
{
SetSocket(ITEM_SOCKET_REMAIN_SEC, given_time + remain_sec);
return given_time;
}
}
// 우선 용혼석에 관해서만 하도록 한다.
else
return 0;
}
int CItem::GiveMoreTime_Fix(DWORD dwTime)
{
if (IsDragonSoul())
{
DWORD duration = DSManager::instance().GetDuration(this);
int remain_sec = GetSocket(ITEM_SOCKET_REMAIN_SEC);
if (remain_sec == duration)
return false;
if ((dwTime + remain_sec) >= duration)
{
SetSocket(ITEM_SOCKET_REMAIN_SEC, duration);
return duration - remain_sec;
}
else
{
SetSocket(ITEM_SOCKET_REMAIN_SEC, dwTime + remain_sec);
return dwTime;
}
}
// 우선 용혼석에 관해서만 하도록 한다.
else
return 0;
}
int CItem::GetDuration() int CItem::GetDuration()
{ {
if(!GetProto()) if(!GetProto())
-5
View File
@@ -254,11 +254,6 @@ class CItem : public CEntity
DWORD GetMaskVnum() { return m_dwMaskVnum; } DWORD GetMaskVnum() { return m_dwMaskVnum; }
bool IsMaskedItem() { return m_dwMaskVnum != 0; } bool IsMaskedItem() { return m_dwMaskVnum != 0; }
// 용혼석
bool IsDragonSoul();
int GiveMoreTime_Per(float fPercent);
int GiveMoreTime_Fix(DWORD dwTime);
private: private:
TItemTable const * m_pProto; // 프로토 타잎 TItemTable const * m_pProto; // 프로토 타잎
-13
View File
@@ -20,7 +20,6 @@
#include "high_risk.h" #include "high_risk.h"
#include "../../common/VnumHelper.h" #include "../../common/VnumHelper.h"
#include "DragonSoul.h"
#include "cube.h" #include "cube.h"
ITEM_MANAGER::ITEM_MANAGER() ITEM_MANAGER::ITEM_MANAGER()
@@ -409,11 +408,6 @@ LPITEM ITEM_MANAGER::CreateItem(DWORD vnum, DWORD count, DWORD id, bool bTryMagi
} }
} }
// 새로 생성되는 용혼석 처리.
if (item->IsDragonSoul() && 0 == id)
{
DSManager::instance().DragonSoulItemInitialize(item);
}
return item; return item;
} }
@@ -1579,13 +1573,6 @@ void ITEM_MANAGER::CreateQuestDropItem(LPCHARACTER pkChr, LPCHARACTER pkKiller,
pkKiller->AutoGiveItem (xmas_sock, 1); pkKiller->AutoGiveItem (xmas_sock, 1);
} }
//if (pkChr->GetLevel() >= 30 && (GetDropPerKillPct(50, 100, iDeltaPercent, "ds_drop") >= number(1, iRandRange)))
//{
// const static DWORD dragon_soul_gemstone = 30270;
// if ((item = CreateItem(dragon_soul_gemstone, 1, 0, true)))
// vec_item.push_back(item);
//}
if ( GetDropPerKillPct(100, g_iUseLocale ? 2000 : 800, iDeltaPercent, "halloween_drop") >= number(1, iRandRange) ) if ( GetDropPerKillPct(100, g_iUseLocale ? 2000 : 800, iDeltaPercent, "halloween_drop") >= number(1, iRandRange) )
{ {
const static DWORD halloween_item = 30321; const static DWORD halloween_item = 30321;
-2
View File
@@ -62,7 +62,6 @@
#include "skill_power.h" #include "skill_power.h"
#include "SpeedServer.h" #include "SpeedServer.h"
// #include "XTrapManager.h" // #include "XTrapManager.h"
#include "DragonSoul.h"
#include <boost/bind.hpp> #include <boost/bind.hpp>
#ifndef __WIN32__ #ifndef __WIN32__
#include "limit_time.h" #include "limit_time.h"
@@ -515,7 +514,6 @@ int main(int argc, char **argv)
// CXTrapManager XTManager; // CXTrapManager XTManager;
CSpeedServerManager SSManager; CSpeedServerManager SSManager;
DSManager dsManager;
#ifdef __AUCTION__ #ifdef __AUCTION__
AuctionManager auctionManager; AuctionManager auctionManager;
-43
View File
@@ -107,7 +107,6 @@ enum
HEADER_CG_HS_ACK = 203, HEADER_CG_HS_ACK = 203,
HEADER_CG_XTRAP_ACK = 204, HEADER_CG_XTRAP_ACK = 204,
HEADER_CG_DRAGON_SOUL_REFINE = 205,
HEADER_CG_STATE_CHECKER = 206, HEADER_CG_STATE_CHECKER = 206,
HEADER_CG_CLIENT_VERSION = 0xfd, HEADER_CG_CLIENT_VERSION = 0xfd,
@@ -293,7 +292,6 @@ enum
HEADER_GC_SPECIFIC_EFFECT = 208, HEADER_GC_SPECIFIC_EFFECT = 208,
HEADER_GC_DRAGON_SOUL_REFINE = 209,
HEADER_GC_RESPOND_CHANNELSTATUS = 210, HEADER_GC_RESPOND_CHANNELSTATUS = 210,
@@ -2332,47 +2330,6 @@ typedef struct SPacketGCSpecificEffect
char effect_file[MAX_EFFECT_FILE_NAME]; char effect_file[MAX_EFFECT_FILE_NAME];
} TPacketGCSpecificEffect; } TPacketGCSpecificEffect;
// ¿ëÈ¥¼®
enum EDragonSoulRefineWindowRefineType
{
DragonSoulRefineWindow_UPGRADE,
DragonSoulRefineWindow_IMPROVEMENT,
DragonSoulRefineWindow_REFINE,
};
enum EPacketCGDragonSoulSubHeaderType
{
DS_SUB_HEADER_OPEN,
DS_SUB_HEADER_CLOSE,
DS_SUB_HEADER_DO_REFINE_GRADE,
DS_SUB_HEADER_DO_REFINE_STEP,
DS_SUB_HEADER_DO_REFINE_STRENGTH,
DS_SUB_HEADER_REFINE_FAIL,
DS_SUB_HEADER_REFINE_FAIL_MAX_REFINE,
DS_SUB_HEADER_REFINE_FAIL_INVALID_MATERIAL,
DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MONEY,
DS_SUB_HEADER_REFINE_FAIL_NOT_ENOUGH_MATERIAL,
DS_SUB_HEADER_REFINE_FAIL_TOO_MUCH_MATERIAL,
DS_SUB_HEADER_REFINE_SUCCEED,
};
typedef struct SPacketCGDragonSoulRefine
{
SPacketCGDragonSoulRefine() : header (HEADER_CG_DRAGON_SOUL_REFINE)
{}
BYTE header;
BYTE bSubType;
TItemPos ItemGrid[DRAGON_SOUL_REFINE_GRID_SIZE];
} TPacketCGDragonSoulRefine;
typedef struct SPacketGCDragonSoulRefine
{
SPacketGCDragonSoulRefine() : header(HEADER_GC_DRAGON_SOUL_REFINE)
{}
BYTE header;
BYTE bSubType;
TItemPos Pos;
} TPacketGCDragonSoulRefine;
typedef struct SPacketCGStateCheck typedef struct SPacketCGStateCheck
{ {
BYTE header; BYTE header;
-1
View File
@@ -226,7 +226,6 @@ CPacketInfoCG::CPacketInfoCG()
// Set(HEADER_CG_HS_ACK, sizeof(TPacketGCHSCheck), "HackShieldResponse", false); // Set(HEADER_CG_HS_ACK, sizeof(TPacketGCHSCheck), "HackShieldResponse", false);
// Set(HEADER_CG_XTRAP_ACK, sizeof(TPacketXTrapCSVerify), "XTrapResponse", false); // Set(HEADER_CG_XTRAP_ACK, sizeof(TPacketXTrapCSVerify), "XTrapResponse", false);
Set(HEADER_CG_DRAGON_SOUL_REFINE, sizeof(TPacketCGDragonSoulRefine), "DragonSoulRefine", false);
Set(HEADER_CG_STATE_CHECKER, sizeof(BYTE), "ServerStateCheck", false); Set(HEADER_CG_STATE_CHECKER, sizeof(BYTE), "ServerStateCheck", false);
} }
-1
View File
@@ -489,7 +489,6 @@ namespace quest
RegisterDanceEventFunctionTable(); RegisterDanceEventFunctionTable();
RegisterDragonLairFunctionTable(); RegisterDragonLairFunctionTable();
RegisterSpeedServerFunctionTable(); RegisterSpeedServerFunctionTable();
RegisterDragonSoulFunctionTable();
{ {
luaL_reg member_functions[] = luaL_reg member_functions[] =
-1
View File
@@ -33,7 +33,6 @@ namespace quest
extern void RegisterDanceEventFunctionTable(); extern void RegisterDanceEventFunctionTable();
extern void RegisterDragonLairFunctionTable(); extern void RegisterDragonLairFunctionTable();
extern void RegisterSpeedServerFunctionTable(); extern void RegisterSpeedServerFunctionTable();
extern void RegisterDragonSoulFunctionTable();
extern void combine_lua_string(lua_State* L, std::ostringstream &s); extern void combine_lua_string(lua_State* L, std::ostringstream &s);
-69
View File
@@ -1,69 +0,0 @@
#include "stdafx.h"
#include "config.h"
#include "questmanager.h"
#include "char.h"
#undef sys_err
#ifndef __WIN32__
#define sys_err(fmt, args...) quest::CQuestManager::instance().QuestError(__FUNCTION__, __LINE__, fmt, ##args)
#else
#define sys_err(fmt, ...) quest::CQuestManager::instance().QuestError(__FUNCTION__, __LINE__, fmt, __VA_ARGS__)
#endif
namespace quest
{
int ds_open_refine_window(lua_State* L)
{
const LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr();
if (NULL == ch)
{
sys_err ("NULL POINT ERROR");
return 0;
}
if (ch->DragonSoul_IsQualified())
ch->DragonSoul_RefineWindow_Open(CQuestManager::instance().GetCurrentNPCCharacterPtr());
return 0;
}
int ds_give_qualification(lua_State* L)
{
const LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr();
if (NULL == ch)
{
sys_err ("NULL POINT ERROR");
return 0;
}
ch->DragonSoul_GiveQualification();
return 0;
}
int ds_is_qualified(lua_State* L)
{
const LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr();
if (NULL == ch)
{
sys_err ("NULL POINT ERROR");
lua_pushnumber(L, 0);
return 1;
}
lua_pushnumber(L, ch->DragonSoul_IsQualified());
return 1;
}
void RegisterDragonSoulFunctionTable()
{
luaL_reg ds_functions[] =
{
{ "open_refine_window" , ds_open_refine_window },
{ "give_qualification" , ds_give_qualification },
{ "is_qualified" , ds_is_qualified },
{ NULL , NULL }
};
CQuestManager::instance().AddLuaFunctionTable("ds", ds_functions);
}
};
-13
View File
@@ -268,14 +268,7 @@ int CShop::Buy(LPCHARACTER ch, BYTE pos)
} }
int iEmptyPos; int iEmptyPos;
if (item->IsDragonSoul())
{
iEmptyPos = ch->GetEmptyDragonSoulInventory(item);
}
else
{
iEmptyPos = ch->GetEmptyInventory(item->GetSize()); iEmptyPos = ch->GetEmptyInventory(item->GetSize());
}
if (iEmptyPos < 0) if (iEmptyPos < 0)
{ {
@@ -362,9 +355,6 @@ int CShop::Buy(LPCHARACTER ch, BYTE pos)
} }
item->RemoveFromCharacter(); item->RemoveFromCharacter();
if (item->IsDragonSoul())
item->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
else
item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos)); item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
ITEM_MANAGER::instance().FlushDelayedSave(item); ITEM_MANAGER::instance().FlushDelayedSave(item);
@@ -388,9 +378,6 @@ int CShop::Buy(LPCHARACTER ch, BYTE pos)
} }
else else
{ {
if (item->IsDragonSoul())
item->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
else
item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos)); item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
ITEM_MANAGER::instance().FlushDelayedSave(item); ITEM_MANAGER::instance().FlushDelayedSave(item);
LogManager::instance().ItemLog(ch, item, "BUY", item->GetName()); LogManager::instance().ItemLog(ch, item, "BUY", item->GetName());
-10
View File
@@ -173,14 +173,7 @@ int CShopEx::Buy(LPCHARACTER ch, BYTE pos)
return SHOP_SUBHEADER_GC_SOLD_OUT; return SHOP_SUBHEADER_GC_SOLD_OUT;
int iEmptyPos; int iEmptyPos;
if (item->IsDragonSoul())
{
iEmptyPos = ch->GetEmptyDragonSoulInventory(item);
}
else
{
iEmptyPos = ch->GetEmptyInventory(item->GetSize()); iEmptyPos = ch->GetEmptyInventory(item->GetSize());
}
if (iEmptyPos < 0) if (iEmptyPos < 0)
{ {
@@ -200,9 +193,6 @@ int CShopEx::Buy(LPCHARACTER ch, BYTE pos)
} }
if (item->IsDragonSoul())
item->AddToCharacter(ch, TItemPos(DRAGON_SOUL_INVENTORY, iEmptyPos));
else
item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos)); item->AddToCharacter(ch, TItemPos(INVENTORY, iEmptyPos));
ITEM_MANAGER::instance().FlushDelayedSave(item); ITEM_MANAGER::instance().FlushDelayedSave(item);
-6
View File
@@ -106,12 +106,6 @@ enum
REWARD_BOX_UNIQUE_ITEM_CAPE_OF_COURAGE = 76007, REWARD_BOX_UNIQUE_ITEM_CAPE_OF_COURAGE = 76007,
// 용혼석 추출 확률을 높여주는 아이템
DRAGON_SOUL_EXTRACTOR_GROUP = 10600,
// 용심 추출해주는 아이템
DRAGON_HEART_EXTRACTOR_GROUP = 10601,
// 용혼석에서 추출할 때 주는 용심.
DRAGON_HEART_VNUM = 100000,
}; };
#endif /* __INC_METIN2_UNIQUE_ITEM_H */ #endif /* __INC_METIN2_UNIQUE_ITEM_H */
@@ -1,314 +0,0 @@
# 용혼석 테이블들...
# TAB 으로 구분되니 엑셀로 볼 것.
# vim으로 본다면 탭간 간격을 조정하고 볼 것. (set ts=16 추천)
# 큰 따옴표로 묶인 부분은 안 구분.
# \" 이딴거 지원 안함.
# 용혼석 Vnum에 대한 comment
# ITEM VNUM을 10만 자리부터, FEDCBA라고 한다면
# FE : 용혼석 종류. D : 등급
# C : 단계 B : 강화
# A : 여벌의 번호들...
# 이 체계에서 벗어나는 용혼석은 용서하지 않을 것이다.
# ok?
# 용혼석이 너무나도 많기 때문에 Vnum이 중구난방이면,
# Special item group에서 group으로 묶어서 처리하기도 힘들고-_-,
# VnumHelper.h에서 처리하는 것도 힘들다. -_-
# Group 잡는데만 수천줄을 써야할 지도...
# Vnum에 체계를 잡아서 자릿수 기반으로 해야만 한다.
# Table은 "Group"과 "이름"으로 시작한다.
# Table 내부에 또 Table이 있을 수 있다.
# 그렇다고 엉뚱한 테이블을 써놓는다고 서버가 인식하는 것은 아니다.
# 필요한 테이블은 다음과 같다.
# BaseVnums, BaseAttrs, AddtionalAttrs, AttrSettings, UpgradeTable, ImproveTable,
# RefineTable, UpgradeMoneys, ImproveTable, RefineMoneys, WeightTable, DurationTable,
# DragonHeartExtTable, DragonSoulExtTable
# 확률 테이블의 값은 기본적으로 float이다.
# 중요 !!!!!
# 테이블을 보다 보면 #--#이라 쓰여진 부분이 있는데 절대로 지우지 말것.
#
# 이건 vnum to 이름 mapping.
# 이걸로 특정 vnum의 용혼석이 어떤 종류의 용혼석인지(이름이 뭔지) 알아낸 후,
# 그 용혼석에 해당하는 속성을 찾는다.
# 또한 여기에 적혀있지 않은 용혼석이 밑에 Group 정의하는 부분에 있다면
# 에러.
Group VnumMapper
{
# 시작 vnum.
# 여기서 써야할 부분은 위에 설명한 FE에 해당하는 부분.
# FE를 써줄 것
#--# DragonSoulName Type
1 백룡석 11
2 화룡석 12
3 풍룡석 13
4 철룡석 14
5 뇌룡석 15
6 흑룡석 16
}
Group BasicApplys
{
Group 백룡석
{
# 1부터 순서대로 부여된다.
#--# Apply_Type Apply_value
1 INT 10
2 RESIST_ICE 10
}
Group 화룡석
{
#--# Apply_Type Apply_value
1 STR 10
2 RESIST_FIRE 10
}
Group 풍룡석
{
#--# Apply_Type Apply_value
1 MAX_SP 500
2 RESIST_WIND 10
}
Group 철룡석
{
#--# Apply_Type Apply_value
1 DEX 10
2 RESIST_EARTH 10
}
Group 뇌룡석
{
#--# Apply_Type Apply_value
1 MAX_HP 1500
2 RESIST_ELEC 10
}
Group 흑룡석
{
#--# Apply_Type Apply_value
1 CON 10
2 RESIST_DARK 10
}
}
Group AdditionalApplys
{
Group 백룡석
{
# 앞의 첫 컬럼은 순서와 관계 없다. 철저히 확률에 따라 속성이 부여될 뿐이다.
#--# Apply_Type Apply_value Prob
1 MAGIC_ATT_GRADE 15 10
2 MAGIC_DEF_GRADE 15 10
3 SKILL_DAMAGE_BONUS 15 10
4 SKILL_DEFEND_BONUS 15 10
}
Group 화룡석
{
#--# Apply_Type Apply_value Prob
1 ATT_BONUS 300 10
2 DEF_BONUS 200 10
3 NORMAL_HIT_DAMAGE_BONUS 15 10
4 NORMAL_HIT_DEFEND_BONUS 15 10
}
Group 풍룡석
{
#--# Apply_Type Apply_value Prob
1 MAX_HP 3000 10
2 HP_REGEN 10 10
3 STEAL_HP 10 10
4 KILL_HP_RECOVER 5 10
5 MAX_HP_PCT 20 10
}
Group 철룡석
{
#--# Apply_Type Apply_value Prob
1 ATT_BONUS_TO_WARRIOR 15 10
2 ATT_BONUS_TO_ASSASSIN 15 10
3 ATT_BONUS_TO_SURA 15 10
4 ATT_BONUS_TO_SHAMAN 15 10
5 RESIST_WARRIOR 15 10
6 RESIST_ASSASSIN 15 10
7 RESIST_SURA 15 10
8 RESIST_SHAMAN 15 10
}
Group 뇌룡석
{
#--# Apply_Type Apply_value Prob
1 MAX_SP 1500 10
2 SP_REGEN 10 10
3 STEAL_SP 10 10
4 KILL_SP_RECOVER 5 10
5 MAX_SP_PCT 20 10
}
Group 흑룡석
{
#--# Apply_Type Apply_value Prob
1 BLOCK 10 10
2 DODGE 10 10
3 REFLECT_MELEE 10 10
4 RESIST_CRITICAL 10 10
5 RESIST_PENETRATE 10 10
}
}
# 여기부터 Default를 둔다.
# Default 값을 모든 용혼석이 따르고,
# 특정 값이 있는 용혼석은 Default를 바탕으로 그 값을 덮어쓴다.
# 등급에 따른 속성수
# 단, basis, add_max는 3보다 크면 안된다.
Group ApplyNumSettings
{
Group Default
{
#--# GRADE_NORMAL GRADE_BRILLIANT GRADE_RARE GRADE_ANCIENT GRADE_LEGENDARY
basis 1 1 1 2 2
add_min 0 0 0 0 0
add_max 0 1 2 2 3
}
# Group 백룡석
# {
# #--# GRADE_NORMAL GRADE_BRILLIANT GRADE_RARE GRADE_ANCIENT GRADE_LEGENDARY
# basis 1 1 1 2 2
# }
}
# 용혼석 가중치 테이블.
# 이 테이블에서 값이 0이라면 그 이상의 강화는 불가능하다고 판단한다.
Group WeightTables
{
Group Default
{
Group GRADE_NORMAL
{
# 단계 강화
#--# 0 1 2 3 4 5 6
STEP_LOWEST 1 2 3 0 0 0 0
STEP_LOW 2 3 4 0 0 0 0
STEP_MID 3 4 5 6 0 0 0
STEP_HIGH 4 5 6 7 0 0 0
STEP_HIGHEST 5 6 7 8 10 0 0
}
Group GRADE_BRILLIANT
{
STEP_LOWEST 3 4 5 6 0 0 0
STEP_LOW 4 5 6 8 0 0 0
STEP_MID 5 6 8 10 0 0 0
STEP_HIGH 6 8 10 12 15 0 0
STEP_HIGHEST 8 10 12 15 20 0 0
}
Group GRADE_RARE
{
#--# 0 1 2 3 4 5 6
STEP_LOWEST 6 7 9 11 15 0 0
STEP_LOW 7 9 11 15 20 0 0
STEP_MID 9 11 15 20 25 0 0
STEP_HIGH 11 15 20 25 30 0 0
STEP_HIGHEST 15 20 25 30 40 0 0
}
Group GRADE_ANCIENT
{
#--# 0 1 2 3 4 5 6
STEP_LOWEST 10 12 15 18 20 0 0
STEP_LOW 12 15 18 20 25 0 0
STEP_MID 15 18 20 25 35 0 0
STEP_HIGH 18 20 25 35 40 0 0
STEP_HIGHEST 20 25 35 40 60 80 0
}
Group GRADE_LEGENDARY
{
#--# 0 1 2 3 4 5 6
STEP_LOWEST 30 35 40 45 50 0 0
STEP_LOW 35 40 45 50 55 0 0
STEP_MID 40 45 50 55 65 0 0
STEP_HIGH 45 50 55 65 75 90 0
STEP_HIGHEST 50 55 65 75 90 105 120
}
}
# Group 백룡석
# {
# Group GRADE_NORMAL
# {
# #--# 0 1 2 3 4 5 6
# STEP_LOWEST 10 20 53 0 0 0 0
# STEP_HIGHEST 50 60 37 18 10 0 0
# }
# }
}
# 개량 table
Group RefineGradeTables
{
Group Default
{
#--# NEED_COUNT FEE GRADE_NORMAL GRADE_BRILLIANT GRADE_RARE GRADE_ANCIENT GRADE_LEGENDARY
GRADE_NORMAL 15 30000 70 25 5 0 0
GRADE_BRILLIANT 10 50000 25 70 5 0 0
GRADE_RARE 5 70000 8 15 75 2 0
GRADE_ANCIENT 3 100000 2 3 8 85 2
}
}
Group RefineStepTables
{
Group Default
{
#--# NEED_COUNT FEE STEP_LOWEST STEP_LOW STEP_MID STEP_HIGH STEP_HIGHEST
STEP_LOWEST 4 20000 70 25 5 0 0
STEP_LOW 3 30000 25 70 5 0 0
STEP_MID 2 40000 10 20 80 1 0
STEP_HIGH 1 50000 2 3 5 89 1
}
}
Group RefineStrengthTables
{
Group Default
{
# MATERIAL_DS_REFINE_NORMAL : GRADE_NORMAL 강화석
# MATERIAL_DS_REFINE_BLESSED : 축복의 강화석
# MATERIAL_DS_REFINE_HOLLY : 용신의 강화석
#--# FEE 0 1 2 3 4 5
MATERIAL_DS_REFINE_NORMAL 10000 100 80 70 50 30 20
MATERIAL_DS_REFINE_BLESSED 20000 100 88 77 55 33 22
MATERIAL_DS_REFINE_HOLLY 30000 100 90 80 60 40 30
}
}
# 용심은 100000(임시 vnum)이고, 충전량은 socket (0)에 박아넣는다.
# 단, special item group에 vnum 10053으로 정의되어있는 다른 용심들은 Value(0)에 있는 값이 충전량.
# 용심 추출 확률 테이블
# 충전량이 0이라는 것은 추출 실패라는 거.
Group DragonHeartExtTables
{
Group Default
{
#--# 1 2 3 4 5
# 용심 충전량(%)
CHARGING 0 5 15 30 50
# 등급과 충전량에 따른 확률 테이블
# 등급 확률
GRADE_NORMAL 50 35 12 2 1
GRADE_BRILLIANT 35 40 20 4 1
GRADE_RARE 20 35 30 12 3
GRADE_ANCIENT 15 30 35 15 5
GRADE_LEGENDARY 10 20 40 20 10
}
}
# 용혼석 추출 확률 테이블.
# 이것도 1, 2안이 있어 통합할 수 있는 방안으로 감.
# 추출 확률을 정할 수 있고, 실패 부산물도 정할 수 있음.(0이면 안줌)
Group DragonSoulExtTables
{
Group Default
{
#실패 부산물
#--# Prob ByProduct
GRADE_NORMAL 50 30270
GRADE_BRILLIANT 40 30270
GRADE_RARE 30 30270
GRADE_ANCIENT 30 30270
GRADE_LEGENDARY 20 30270
}
}