/////////////////////////////////////////////////////////////////////////////////// // // Purpose : CellÀ» °ü¸®Çϴ Ŭ·¡½º // /////////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "Cell.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include unsigned char CCell::ms_CellSize = CCell::CELL_SIZE_DEFAULT; class CCellObjectUIDMgr { public: static CCellObjectUIDMgr& GetInstance(); unsigned long GetNewObjectUID() { return m_dwCellObjectUID++; } private: CCellObjectUIDMgr() : m_dwCellObjectUID(1) { } unsigned long m_dwCellObjectUID; }; CCellObjectUIDMgr& CCellObjectUIDMgr::GetInstance() { static CCellObjectUIDMgr cellObjectUIDMgr; return cellObjectUIDMgr; } class CFindCreatureFromCID : public std::unary_function { public: explicit CFindCreatureFromCID(unsigned long dwCID) : m_dwCID(dwCID) { } bool operator() (CCreature* pCreature) { return (m_dwCID == pCreature->GetCID()) ? true : false; } private: const unsigned long m_dwCID; }; CCell::ItemInfo::ItemInfo() : m_lpItem(NULL), m_dwGold(0), m_dwOwnerID(0), m_wPulse(0), m_cAutoRouting(0) { UID.m_nUniqueID = 0; } void CCell::ItemInfo::MakeFieldObject(FieldObject& fieldObject) { fieldObject.m_nOID = UID.m_nUniqueID; // ¼Ò¼öÁ¡ ÇÑÀÚ¸®¼ö±îÁö Á¤º¸¸¦ ³²±â±âÀ§Çؼ­ 10À» °öÇØÁØ´Ù. fieldObject.m_usXPos = static_cast(m_Pos.m_fPointX * 10.0f); fieldObject.m_usYPos = static_cast(m_Pos.m_fPointY * 10.0f); fieldObject.m_usZPos = static_cast(m_Pos.m_fPointZ * 10.0f); if (CServerSetup::GetInstance().GetServerZone() == SERVER_ID::BATTLE_SERVER && 0 != fieldObject.m_usYPos) { // Y ÁÂÇ¥°¡ 0ÀÌ ¾Æ´Ñ°æ¿ì(¸ó½ºÅͰ¡ ¶³¾î¶ß¸°°Ô ¾Æ´Ñ°æ¿ì), ¹èƲ·ÎÇÑÀº 1m ¸¦ ³ô¿©ÁØ´Ù. fieldObject.m_usYPos += 10; } if (0 != m_lpItem) { fieldObject.m_cNum = m_lpItem->GetNumOrDurability(); fieldObject.m_dwTypeID = m_lpItem->GetPrototypeID(); } else { fieldObject.m_cNum = 1; fieldObject.m_dwTypeID = (CCell::MONEY_BIT + m_dwGold); } } CCell::CCell() : m_lpBroadcast2ndBuffer(0), m_wMapIndex(0), m_cIndexX(0), m_cIndexZ(0), m_cTurnOfGetAggresiveCreature(TURN_OF_CHARACTER), m_dwCastleEmblemCID(0), m_eWeather(CCell::WEATHER_FINE) { m_MonsterIt = m_lstMonster.end(); m_CharacterIt = m_lstCharacter.end(); m_SiegeObjectIt = m_lstSiegeObject.end(); std::fill_n(m_lpConnectCell, int(CONNECT_NUM), reinterpret_cast(0)); std::fill_n(m_lpSortedConnectedCell, int(CONNECT_NUM), reinterpret_cast(0)); m_lpConnectCell[NO] = this; } CCell::~CCell(void) { for (ItemList::iterator itr = m_lstItem.begin(); itr != m_lstItem.end(); ++itr) { ItemInfo& itemInfo = *itr; if (NULL != itemInfo.m_lpItem) { DELETE_ITEM(itemInfo.m_lpItem); } } ReleaseAllBuffer(m_lpBroadcast2ndBuffer); } void CCell::Initialize(unsigned char cIndexX, unsigned char cIndexZ) { m_cIndexX = cIndexX; m_cIndexZ = cIndexZ; std::partial_sort_copy(m_lpConnectCell, m_lpConnectCell + CCell::CONNECT_NUM, m_lpSortedConnectedCell, m_lpSortedConnectedCell + CCell::CONNECT_NUM); } CMonster* CCell::GetFirstMonster(void) { if (false == m_lstMonster.empty()) { m_MonsterIt = m_lstMonster.begin(); return *m_MonsterIt; } return NULL; } CSiegeObject* CCell::GetFirstAirShip(void) { m_SiegeObjectIt = m_lstSiegeObject.begin(); while (m_SiegeObjectIt != m_lstSiegeObject.end()) { CSiegeObject* lpSiegeObject = *m_SiegeObjectIt; if (lpSiegeObject && Siege::AIRSHIP == lpSiegeObject->GetObjectType()) { return lpSiegeObject; } ++m_SiegeObjectIt; } return NULL; } CSiegeObject* CCell::GetNextAirShip(void) { while (++m_SiegeObjectIt != m_lstSiegeObject.end()) { CSiegeObject* lpSiegeObject = *m_SiegeObjectIt; if (lpSiegeObject && Siege::AIRSHIP == lpSiegeObject->GetObjectType()) { return lpSiegeObject; } } return NULL; } CSiegeObject* CCell::GetFirstSiegeObject() { m_SiegeObjectIt = m_lstSiegeObject.begin(); while (m_SiegeObjectIt != m_lstSiegeObject.end()) { CSiegeObject* lpSiegeObject = *m_SiegeObjectIt; if (lpSiegeObject) { return lpSiegeObject; } ++m_SiegeObjectIt; } return NULL; } CSiegeObject* CCell::GetNextSiegeObject() { while (++m_SiegeObjectIt != m_lstSiegeObject.end()) { CSiegeObject* lpSiegeObject = *m_SiegeObjectIt; if (lpSiegeObject) { return lpSiegeObject; } } return NULL; } CCharacter* CCell::GetFirstCharacter(void) { if (false == m_lstCharacter.empty()) { m_CharacterIt = m_lstCharacter.begin(); return *m_CharacterIt; } return 0; } CAggresiveCreature* CCell::GetFirstAggresiveCreature(void) { m_cTurnOfGetAggresiveCreature = TURN_OF_CHARACTER; CAggresiveCreature* pCreature = reinterpret_cast(GetFirstCharacter()); if (NULL == pCreature) { m_cTurnOfGetAggresiveCreature = TURN_OF_SIEGE_OBJECT; pCreature = reinterpret_cast(GetFirstSiegeObject()); if (NULL == pCreature) { m_cTurnOfGetAggresiveCreature = TURN_OF_MONSTER; return reinterpret_cast(GetFirstMonster()); } } return pCreature; } CAggresiveCreature* CCell::GetNextAggresiveCreature(void) { CAggresiveCreature* pCreature = NULL; switch (m_cTurnOfGetAggresiveCreature) { case TURN_OF_CHARACTER: { pCreature = reinterpret_cast(GetNextCharacter()); if (NULL == pCreature) { m_cTurnOfGetAggresiveCreature = TURN_OF_SIEGE_OBJECT; pCreature = reinterpret_cast(GetFirstSiegeObject()); if (NULL == pCreature) { m_cTurnOfGetAggresiveCreature = TURN_OF_MONSTER; pCreature = reinterpret_cast(GetFirstMonster()); } } return pCreature; } break; case TURN_OF_SIEGE_OBJECT: { pCreature = reinterpret_cast(GetNextSiegeObject()); if (NULL == pCreature) { m_cTurnOfGetAggresiveCreature = TURN_OF_MONSTER; pCreature = reinterpret_cast(GetFirstMonster()); } return pCreature; } break; case TURN_OF_MONSTER: { pCreature = reinterpret_cast(GetNextMonster()); return pCreature; } break; } return NULL; } void CCell::KillAll(CCharacter* lpAttacker) { if (true == m_lstMonster.empty()) { return; } const int MAX_BUFFER = sizeof(PktAtAck) + AtNode::MAX_DEFENDER_NUM * sizeof(DefenserNode); char szBuffer[MAX_BUFFER]; PktAtAck* lpPktAtAck = reinterpret_cast(szBuffer); DefenserNode* lpDefenserNode = reinterpret_cast(lpPktAtAck + 1); CMonster* lpDeadMonster[AtNode::MAX_DEFENDER_NUM] = { NULL, }; MonsterList::iterator it = m_lstMonster.begin(); unsigned char cDefenderNum = 0; for (; it != m_lstMonster.end() && cDefenderNum < AtNode::MAX_DEFENDER_NUM; ++it, ++cDefenderNum) { lpDeadMonster[cDefenderNum] = *it; unsigned short usNowHP = lpDeadMonster[cDefenderNum]->GetStatus().m_nNowHP; lpDeadMonster[cDefenderNum]->GetStatus().m_nNowHP = 0; lpDefenserNode[cDefenderNum].m_wDamage = usNowHP; lpDefenserNode[cDefenderNum].m_dwCharID = lpDeadMonster[cDefenderNum]->GetCID(); lpDefenserNode[cDefenderNum].m_sCurrHP = lpDeadMonster[cDefenderNum]->GetStatus().m_nNowHP; lpDefenserNode[cDefenderNum].m_sCurrMP = lpDeadMonster[cDefenderNum]->GetStatus().m_nNowMP; lpDefenserNode[cDefenderNum].m_wMaxHP = lpDeadMonster[cDefenderNum]->GetStatus().m_StatusInfo.m_nMaxHP; lpDefenserNode[cDefenderNum].m_wMaxMP = lpDeadMonster[cDefenderNum]->GetStatus().m_StatusInfo.m_nMaxMP; lpDefenserNode[cDefenderNum].m_wMPHeal = 0; lpDefenserNode[cDefenderNum].m_cJudge = ClientConstants::Judge_Front; } for (int nIndex = 0; nIndex < cDefenderNum; ++nIndex) { if (NULL == lpDeadMonster[nIndex]) { break; } lpDeadMonster[nIndex]->GetThreat().AddToThreatList(lpAttacker, 1L); lpDeadMonster[nIndex]->Dead(lpAttacker); lpDeadMonster[nIndex]->GetThreat().ClearAll(); } lpPktAtAck->m_dwCharID = lpAttacker->GetCID(); AtType attackType; attackType.m_wType = AtType::RIGHT_MELEE; lpPktAtAck->m_AtType = attackType; lpPktAtAck->m_wHP = lpAttacker->GetStatus().m_nNowHP; lpPktAtAck->m_wMP = lpAttacker->GetStatus().m_nNowMP; lpPktAtAck->m_wMPHeal = 0; lpPktAtAck->m_cJudge = ClientConstants::Judge_Front; lpPktAtAck->m_cDefenserNum = cDefenderNum; CCell* lpCell = lpAttacker->GetCellPos().m_lpCell; CGameClientDispatch* lpDispatch = lpAttacker->GetDispatcher(); if (0 != lpDispatch && lpDispatch->GetSendStream().WrapCompress(szBuffer, sizeof(PktAtAck) + cDefenderNum * sizeof(DefenserNode), CmdCharAttack, 0, 0) && 0 != lpCell) { lpCell->SendAttackInfo(lpAttacker->GetCID(), attackType, cDefenderNum, lpDefenserNode); } } void CCell::UpgradeByEmblem(unsigned long dwCID) { m_dwCastleEmblemCID = dwCID; CSiegeObject* lpEmblem = CSiegeObjectMgr::GetInstance().GetSiegeObject(m_dwCastleEmblemCID); if (lpEmblem) { CCharacter* lpCharacter = GetFirstCharacter(); while (lpCharacter) { if (EnemyCheck::EC_ENEMY == lpEmblem->IsEnemy(lpCharacter)) { // ÇØ´ç ij¸¯ÅÍ¿¡°Ô ½ºÅÚ½º¸¦ »ç¿ëÇÒ¼ö ¾ø´Ù´Â Á¤º¸¸¦ º¸³½´Ù. SendStealthInfo(*lpCharacter, false); if (true == lpCharacter->GetEnchantInfo().GetFlag(Skill::SpellID::Stealth)) { DetectionAttack(lpEmblem, lpCharacter); } } lpCharacter = GetNextCharacter(); } } } void CCell::DegradeByEmblem() { CSiegeObject* lpEmblem = CSiegeObjectMgr::GetInstance().GetSiegeObject(m_dwCastleEmblemCID); if (lpEmblem) { CCharacter* lpCharacter = GetFirstCharacter(); while (lpCharacter) { if (EnemyCheck::EC_ENEMY == lpEmblem->IsEnemy(lpCharacter)) { // ÇØ´ç ij¸¯ÅÍ¿¡°Ô ½ºÅÚ½º¸¦ »ç¿ë °¡´É Á¤º¸¸¦ º¸³½´Ù. SendStealthInfo(*lpCharacter, true); } lpCharacter = GetNextCharacter(); } } m_dwCastleEmblemCID = 0; } void CCell::DetectionAttack(CSiegeObject* lpEmblem, CAggresiveCreature* lpTargetCreature) { if (NULL == lpEmblem || NULL == lpTargetCreature) return; AtType attackType; attackType.m_cSkillLockCount = 0; attackType.m_cSkillLevel = 1; attackType.m_cAtCount = 0; attackType.m_cCasting = 0; attackType.m_wType = 0x8201; // Detection CAggresiveCreature* lpAggresiveCreature[AtNode::MAX_DEFENDER_NUM] = {0, }; unsigned char cDefenserJudge[AtNode::MAX_DEFENDER_NUM] = {0, }; unsigned short wDefenserMPHeal[AtNode::MAX_DEFENDER_NUM] = {0, }; lpAggresiveCreature[0] = lpTargetCreature; lpEmblem->SetFullMP(); lpEmblem->Attack(attackType, 1, lpAggresiveCreature, cDefenserJudge, wDefenserMPHeal); } bool CCell::SendStealthInfo(CCharacter& character, bool bUseStealth) { CGameClientDispatch* lpDispatch = 0; if (0 != (lpDispatch = character.GetDispatcher()) && GameClientSendPacket::SendStealthInfo(lpDispatch->GetSendStream(), bUseStealth)) { return true; } ERRLOG1(g_Log, "CID:0x%08x ij¸¯ÅÍ¿¡°Ô ½ºÅÚ½º »ç¿ë À¯¹« Á¤º¸ Àü¼Û ½ÇÆÐ", character.GetCID()); return false; } /////////////////////////////////////////////////////////////////////////////////// // Function : CCell::SetCreature // // Description : Creature(¸ó½ºÅͳª À¯Àú)¸¦ Cell¿¡ ³ÖÀ½ // // Inputs : dwCID - CreatureÀÇ ID // pObject - CreatureÀÇ Æ÷ÀÎÅÍ // eCellMoveType - À̵¿ ŸÀÔ(CCell::SendCellLogin Âü°í) // // Outputs : None. // // Returns : None. /////////////////////////////////////////////////////////////////////////////////// void CCell::SetCreature(unsigned long dwCID, CCreature* lpCreature, CCell* lpLastLogoutCell) { if (0 == lpCreature) { ERRLOG1(g_Log, "Creature Æ÷ÀÎÅͰ¡ NULLÀÔ´Ï´Ù. CID: 0x%08x", dwCID); return; } if (NULL != GetCreature(dwCID)) { ERRLOG1(g_Log, "ÀÌ ¼¿¿¡´Â ÀÌ¹Ì ÀÌ Å©¸®Ãİ¡ Á¸ÀçÇÕ´Ï´Ù. CID: 0x%08x", dwCID); return; } CAggresiveCreature* lpAggresiveCreature = static_cast(lpCreature); switch (Creature::GetCreatureType(dwCID)) { case Creature::CT_PC: { CCharacter* lpCharacter = static_cast(lpCreature); m_lstCharacter.push_back(lpCharacter); // ¼º ¼ÒÀ¯ »ó¡¹°ÀÇ µðÅØ¼Ç ¿µ¿ª¾È¿¡ ÀÖ´Â ¼¿À̶ó¸é if (0 != m_dwCastleEmblemCID) { CSiegeObject* lpEmblem = CSiegeObjectMgr::GetInstance().GetSiegeObject(m_dwCastleEmblemCID); if (lpEmblem && EnemyCheck::EC_ENEMY == lpEmblem->IsEnemy(lpCharacter)) { // ÇØ´ç ij¸¯ÅÍ¿¡°Ô ½ºÅÚ½º¸¦ »ç¿ëÇÏÁö ¸øÇÑ´Ù´Â Á¤º¸¸¦ º¸³½´Ù. SendStealthInfo(*lpCharacter, false); if (lpCharacter->GetEnchantInfo().GetFlag(Skill::SpellID::Stealth)) { DetectionAttack(lpEmblem, lpCharacter); } } } else { // ÇØ´ç ij¸¯ÅÍ¿¡°Ô ½ºÅÚ½º »ç¿ë °¡´É Á¤º¸¸¦ º¸³½´Ù. SendStealthInfo(*lpCharacter, true); } } break; case Creature::CT_MONSTER: case Creature::CT_SUMMON: case Creature::CT_STRUCT: m_lstMonster.push_back(static_cast(lpCreature)); break; case Creature::CT_SIEGE_OBJECT: m_lstSiegeObject.push_back(static_cast(lpCreature)); break; } SendCellLogin(lpAggresiveCreature, lpLastLogoutCell); } /////////////////////////////////////////////////////////////////////////////////// // Function : CCell::GetCreature // // Description : ¼¿¿¡ ¼ÓÇÑ CreatureÀÇ Æ÷ÀÎÅ͸¦ ¾òÀ½ // // Inputs : dwCID - ¾ò°íÀÚÇÏ´Â ³à¼®ÀÇ CID // // Outputs : None. // // Returns : LPCCreature - ¾ò´Â ³à¼®ÀÇ Æ÷ÀÎÅÍ /////////////////////////////////////////////////////////////////////////////////// CCreature* CCell::GetCreature(unsigned long dwCID) { CFindCreatureFromCID findCID(dwCID); switch (Creature::GetCreatureType(dwCID)) { case Creature::CT_PC: { CharacterList::iterator itr = std::find_if(m_lstCharacter.begin(), m_lstCharacter.end(), findCID); if (itr != m_lstCharacter.end()) { return (CCreature *)*itr; } } break; case Creature::CT_MONSTER: case Creature::CT_SUMMON: case Creature::CT_STRUCT: { MonsterList::iterator itr = std::find_if(m_lstMonster.begin(), m_lstMonster.end(), findCID); if (itr != m_lstMonster.end()) { return (CCreature *)*itr; } } break; case Creature::CT_SIEGE_OBJECT: { SiegeObjectList::iterator itr = std::find_if(m_lstSiegeObject.begin(), m_lstSiegeObject.end(), findCID); if (itr != m_lstSiegeObject.end()) { return (CCreature *)*itr; } } break; } return NULL; } /////////////////////////////////////////////////////////////////////////////////// // Function : CCell::DeleteCreature // // Description : ¼¿¿¡¼­ ¿øÇÏ´Â CreatureÀ» Áö¿ò // // Inputs : dwCID - Áö¿ì°íÀÚ ÇÏ´Â CreatureÀÇ CID // eCellMoveType - À̵¿ ŸÀÔ(CCell::SendCellLogout Âü°í) // // Outputs : None. // // Returns : None. /////////////////////////////////////////////////////////////////////////////////// void CCell::DeleteCreature(unsigned long dwCID, CCell* lpPrepareLoginCell) { CFindCreatureFromCID findCID(dwCID); switch (Creature::GetCreatureType(dwCID)) { case Creature::CT_PC: { CharacterList::iterator itr = std::find_if(m_lstCharacter.begin(), m_lstCharacter.end(), findCID); if (itr != m_lstCharacter.end()) { SendCellLogout(*itr, lpPrepareLoginCell);; m_lstCharacter.erase(itr); } else { ERRLOG1(g_Log, "ÀÌ ¼¿¿¡´Â ÀÌ Ä³¸¯ÅͰ¡ Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù. CID: 0x%08x", dwCID); } } break; case Creature::CT_MONSTER: case Creature::CT_SUMMON: case Creature::CT_STRUCT: { MonsterList::iterator itr = std::find_if(m_lstMonster.begin(), m_lstMonster.end(), findCID); if (itr != m_lstMonster.end()) { SendCellLogout(*itr, lpPrepareLoginCell);; m_lstMonster.erase(itr); } else { ERRLOG1(g_Log, "ÀÌ ¼¿¿¡´Â ÀÌ ¸ó½ºÅͰ¡ Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù. CID: 0x%08x", dwCID); } } break; case Creature::CT_SIEGE_OBJECT: { SiegeObjectList::iterator itr = std::find_if(m_lstSiegeObject.begin(), m_lstSiegeObject.end(), findCID); if (itr != m_lstSiegeObject.end()) { m_lstSiegeObject.erase(itr); } else { ERRLOG1(g_Log, "ÀÌ ¼¿¿¡´Â ÀÌ ÇØ´ç °ø¼º°ü·Ã ¿ÀºêÁ§Æ®°¡ Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù. CID: 0x%08x", dwCID); } } break; } } void CCell::SetItem(const Position& Pos, Item::CItem* lpItem, unsigned long dwGold, unsigned long dwOwnerID, unsigned char cAutoRouting, CCell::ItemInfo& cellItemInfo) { cellItemInfo.m_Pos = Pos; cellItemInfo.UID.m_Field.dwUID = CCellObjectUIDMgr::GetInstance().GetNewObjectUID(); cellItemInfo.UID.m_Field.wMapIndex = m_wMapIndex; cellItemInfo.UID.m_Field.cCellX = m_cIndexX; cellItemInfo.UID.m_Field.cCellZ = m_cIndexZ; cellItemInfo.m_lpItem = lpItem; cellItemInfo.m_dwGold = dwGold; cellItemInfo.m_dwOwnerID = dwOwnerID; cellItemInfo.m_cAutoRouting = cAutoRouting; cellItemInfo.m_wPulse = (NONE == cAutoRouting) ? ITEM_RIGHT_TIME : ITEM_LIFE_TIME; m_lstItem.push_front(cellItemInfo); SendPullDownInfo(dwOwnerID, cellItemInfo); } /////////////////////////////////////////////////////////////////////////////////// // Function : CCell::GetItem // // Description : ¼¿¿¡ ¶³¾îÁ® ÀÖ´Â ¾ÆÀÌÅÛÀ» ¾òÀ½ // // Inputs : dwCreatureID - ¾ÆÀÌÅÛÀ» ¾òÀ¸·Á´Â Å©¸®ÃÄÀÇ ID // nItemInfoID - ¾ÆÀÌÅÛÀÇ À¯´ÏÅ© ID // // Outputs : lppItem - ¾ÆÀÌÅÛÀÇ Æ÷ÀÎÅÍ. ¾ø´Â ¾ÆÀÌÅÛÀ̰ųª ¼ÒÀ¯±ÇÀÌ ¾ø´Â Å©¸®Ãİ¡ ¿äûÇϸé NULL. // dwMoney_Out - ±Ý¾× // // Returns : CCell::ErrorCode - ¿¡·¯ ÄÚµå /////////////////////////////////////////////////////////////////////////////////// CCell::ErrorCode CCell::GetItem(unsigned long dwCreatureID, unsigned __int64 nItemInfoID, Item::CItem** lppItem, unsigned long& dwMoney_Out) { *lppItem = NULL; dwMoney_Out = 0; CAggresiveCreature* lpPickkingCreature = CCreatureManager::GetInstance().GetAggresiveCreature(dwCreatureID); if (NULL == lpPickkingCreature) { return E_NOT_OWNER_OF_ITEM; } if (0 == m_lstItem.size()) { return E_NOT_ITEM; } ItemList::iterator pos = m_lstItem.begin(); ItemList::iterator end = m_lstItem.end(); for (; pos != end; ++pos) { if (pos->UID.m_nUniqueID == nItemInfoID) { break; } } if (pos == end) { return E_NOT_ITEM; } ItemInfo& itemInfo = *pos; // ¼ÒÀ¯±Ç üũ if (itemInfo.m_dwOwnerID != 0) { if (GUILD == itemInfo.m_cAutoRouting) { Guild::CGuild* lpGuild = Guild::CGuildMgr::GetInstance().GetGuild(itemInfo.m_dwOwnerID); if (!lpGuild) { return E_NOT_EXIST_GUILD; } if (lpPickkingCreature->GetGID() != lpGuild->GetGID()) { return E_NOT_OWNER_OF_ITEM; } } else if (dwCreatureID != itemInfo.m_dwOwnerID) { // À¯Àú°¡ ¶³¾î¶ß·È°Å³ª ÇØ¼­ ¼ÒÀ¯±ÇÀÌ ³²¿¡°Ô ÀÖ´Â °æ¿ì if (NONE == itemInfo.m_cAutoRouting) { return E_NOT_OWNER_OF_ITEM; } // ¸ó½ºÅͰ¡ ¶³¾î¶ß¸° ¾ÆÀÌÅÛ (¿ÀÅä·çÆÃ Àü) CAggresiveCreature* lpOwnerCreature = CCreatureManager::GetInstance().GetAggresiveCreature(itemInfo.m_dwOwnerID); if (NULL != lpOwnerCreature && NULL != lpPickkingCreature) { CParty* lpOwnerParty = lpOwnerCreature->GetParty(); if (NULL == lpOwnerParty || lpOwnerParty != lpPickkingCreature->GetParty()) { return E_NOT_OWNER_OF_ITEM; } } } } Item::CItem* lpItem = NULL; if (0 != itemInfo.m_dwGold) { dwMoney_Out = itemInfo.m_dwGold; if (Creature::CT_PC == Creature::GetCreatureType(dwCreatureID) && reinterpret_cast(lpPickkingCreature)->GetGold() > ULONG_MAX - dwMoney_Out) { return E_GOLD_OVERFLOW; } } else { lpItem = itemInfo.m_lpItem; if(lpItem == NULL) { return E_NOT_ITEM; } if (lpItem->IsSet(Item::DetailData::STACKABLE) && 0 == lpItem->GetNumOrDurability()) { return E_NOT_ITEM; } } ErrorCode eErrorCode = S_SUCCESS; if (PARTY == itemInfo.m_cAutoRouting) { // ¿ÀÅä ·çÆÃ CParty* lpParty = lpPickkingCreature->GetParty(); if (NULL != lpParty) { if (true == lpParty->AutoRouting(lpPickkingCreature, lpItem, dwMoney_Out)) { eErrorCode = S_AUTO_ROUTING; } } } else if (GUILD == itemInfo.m_cAutoRouting) { // ¿ÀÅä ·çÆÃ Guild::CGuild* lpGuild = Guild::CGuildMgr::GetInstance().GetGuild(itemInfo.m_dwOwnerID); if (NULL != lpGuild) { if (true == lpGuild->AutoRouting(lpPickkingCreature, lpItem, dwMoney_Out)) { eErrorCode = S_AUTO_ROUTING; } } } // TODO : ÃßÈÄ¿¡ ¾²ÀÌ°Ô µÇ¸é ¼öÁ¤ÀÌ ÇÊ¿äÇÕ´Ï´Ù. (¿ÀÅä·çÆÃ±îÁö °í·ÁÇØ¼­...) /* if (NULL != lpItem && Creature::CT_PC == Creature::GetCreatureType(lpPickkingCreature->GetCID())) { if (Item::ItemType::EVENT_DROP == lpItem->GetItemInfo().m_DetailData.m_cItemType) { char szChatMessage[PktChat::PktChatMaxSize]; CCharacter* lpCharacter = static_cast(lpPickkingCreature); int nSize = _snprintf(szChatMessage, PktChat::PktChatMaxSize - 1, "[¾Ë¸²] ÃàÇÏÇÕ´Ï´Ù~! %s´Ô²²¼­ %sÀ»(¸¦) ¾òÀ¸¼Ì½À´Ï´Ù~!", lpCharacter->GetCharacterName(), lpItem->GetItemInfo().m_SpriteData.m_szName); szChatMessage[PktChat::PktChatMaxSize - 1] = 0; CChatPacket chatPacket(szChatMessage, 0, PktChat::NOTICE); if (chatPacket.IsValid()) { CCreatureManager::GetInstance().SendAllCharacter( chatPacket.GetCompressedPacket(), chatPacket.GetCompressedSize(), CmdCharChat); } DETLOG3(g_Log, "CID:0x%08x À̺¥Æ® ·Î±× : %s(ÀÌ)°¡ %sÀ»(¸¦) ¾ò¾ú½À´Ï´Ù.", lpCharacter->GetCID(), lpCharacter->GetCharacterName(), lpItem->GetItemInfo().m_SpriteData.m_szName); } } */ *lppItem = lpItem; m_lstItem.erase(pos); SendPickUpInfo(dwCreatureID, nItemInfoID); return eErrorCode; } /////////////////////////////////////////////////////////////////////////////////// // Function : CCell::CheckDeleteItem // // Description : ¸Ê À§¿¡¼­ÀÇ ¾ÆÀÌÅÛ Áö¼Ó ½Ã°£À» üũÇÑ´Ù. // // Inputs : None. // // Outputs : None. // // Returns : None. /////////////////////////////////////////////////////////////////////////////////// void CCell::CheckDeleteItem(void) { if (true == m_lstItem.empty()) { return; } for (ItemList::iterator itr = m_lstItem.begin(); itr != m_lstItem.end();) { ItemInfo& itemInfo = *itr; itemInfo.m_wPulse -= CHECK_TIME; if (itemInfo.m_wPulse <= NO_OWNER_TIME) { itemInfo.m_dwOwnerID = 0; } if (itemInfo.m_wPulse <= 0) { // '¶¥ÀÌ ¾ÆÀÌÅÛÀÌ Áݴ´Ù'¶ó´Â »ý°¢... SendPickUpInfo(0, itemInfo.UID.m_nUniqueID); if (itemInfo.m_lpItem != NULL) { DELETE_ITEM(itemInfo.m_lpItem); } m_lstItem.erase(itr++); continue; } ++itr; } } /////////////////////////////////////////////////////////////////////////////////// // Function : CCell::DeleteAllItem // // Description : ¸Ê À§ÀÇ ¾ÆÀÌÅÛÀ» ¸ðµÎ Áö¿î´Ù. // // Inputs : None. // // Outputs : None. // // Returns : None. /////////////////////////////////////////////////////////////////////////////////// void CCell::DeleteAllItem(void) { if (true == m_lstItem.empty()) { return; } for (ItemList::iterator itr = m_lstItem.begin(); itr != m_lstItem.end();) { ItemInfo& itemInfo = *itr; itemInfo.m_dwOwnerID = 0; // '¶¥ÀÌ ¾ÆÀÌÅÛÀÌ Áݴ´Ù'¶ó´Â »ý°¢... SendPickUpInfo(0, itemInfo.UID.m_nUniqueID); if (itemInfo.m_lpItem != NULL) { DELETE_ITEM(itemInfo.m_lpItem); } m_lstItem.erase(itr++); } } void CCell::SendPullDownInfo(unsigned long dwOwnerID, ItemInfo& itemInfo) { PktPDInfo pktPDInfo; memset(&pktPDInfo, 0, sizeof(PktPDInfo)); pktPDInfo.m_dwCharID = dwOwnerID; itemInfo.MakeFieldObject(pktPDInfo.m_FieldObject); // ³»ºÎ¿¡¼­ WrapÀ» ¾Ë¾Æ¼­ ÇÔ. SendAllNearCellCharacter(&pktPDInfo, sizeof(PktPDInfo), CmdCharPullDownInfo); } /////////////////////////////////////////////////////////////////////////////////// // Function : CCell::SendPickUpInfo // // Description : ¾ÆÀÌÅÛÀ» ´©±º°¡ ÁÖ¿ü´Ù´Â Á¤º¸¸¦ ÁÖÀ§ ij¸¯Å͵鿡°Ô º¸³¿ // // Inputs : dwCreatureID - ÁÖ¿î ³à¼®ÀÇ ¾ÆÀ̵ð // nItemInfoID - ¾ø¾îÁø ¾ÆÀÌÅÛÀÇ ¾ÆÀ̵ð // // Outputs : None. // // Returns : None. /////////////////////////////////////////////////////////////////////////////////// void CCell::SendPickUpInfo(unsigned long dwCreatureID, unsigned __int64 nItemInfoID) { PktPUInfo pktPUInfo; memset(&pktPUInfo, 0, sizeof(PktPUInfo)); pktPUInfo.m_dwCharID = dwCreatureID; pktPUInfo.m_nObjectID = nItemInfoID; // ³»ºÎ¿¡¼­ WrapÀ» ¾Ë¾Æ¼­ ÇÔ. SendAllNearCellCharacter(&pktPUInfo, sizeof(PktPUInfo), CmdCharPickUpInfo); } //Interface///////////////////////////////////////////////////////////////////////////////////// // // °ø°Ý Á¤º¸ // // Parameter : // 1st : // 2st : // // Do : // °ø°ÝÇÑ °æ¿ì ÁÖº¯ ¼¿ÀÇ Ä³¸¯Å͵鿡°Ô AttackInfo ¸¦ º¸³½´Ù. (UDP -> TCP : 2004-04-20) // // Return : // /////////////////////////////////////////////////////////////////////////////////////////////// void CCell::SendAttackInfo(unsigned long AttackerID_In, const AtType &AtType_In, unsigned char DefenserNum_In, DefenserNode* lpNode_In) { const int MAX_BUFFER = sizeof(PktAtAck) + AtNode::MAX_DEFENDER_NUM * sizeof(DefenserNode); char szBuffer[MAX_BUFFER]; memset(szBuffer, 0, MAX_BUFFER); // ¹æ¾îÀÚ °³¼ö ÀçÁ¶Á¤(ÃÖ´ë °³¼ö ³ÑÀ» ¼ö ¾ø°Ô) DefenserNum_In = std::min(DefenserNum_In, unsigned char(AtNode::MAX_DEFENDER_NUM)); unsigned short wPacketSize = sizeof(PktAtInfo) + sizeof(DefenserNode) * DefenserNum_In; PktAtInfo* lpPktAtInfo = reinterpret_cast(szBuffer); DefenserNode* lpDefenserNode = reinterpret_cast(lpPktAtInfo + 1); lpPktAtInfo->m_dwCharID = AttackerID_In; lpPktAtInfo->m_AtType = AtType_In; lpPktAtInfo->m_cDefenserNum = DefenserNum_In; CopyMemory(lpDefenserNode, lpNode_In, sizeof(DefenserNode) * DefenserNum_In); // ³»ºÎ¿¡¼­ WrapÀ» ¾Ë¾Æ¼­ ÇÑ´Ù. SendAllNearCellCharacter(lpPktAtInfo, wPacketSize, CmdCharAttackInfo); } // MON_TODO : by Vincent - 2004 : 3 : 3 //Interface///////////////////////////////////////////////////////////////////////////////////// // // ¸ó½ºÅÍ ½ºÅ³ ij½ºÆ® Á¤º¸ // // Parameter : // 1st : // 2st : // // Do : // ¸ó½ºÅͰ¡ ½ºÅ³À» »ç¿ëÇÑ °æ¿ì ÁÖº¯ ¼¿ÀÇ Ä³¸¯Å͵鿡°Ô CastObjectInfo ¸¦ º¸³½´Ù. // // Return : // /////////////////////////////////////////////////////////////////////////////////////////////// void CCell::SendCastObjectInfo(unsigned long SenderID, unsigned long ReceiverID, CastObject& CastObject_In) { PktCOInfo pktCOInfo; memset(&pktCOInfo, 0, sizeof(PktCOInfo)); pktCOInfo.m_dwSenderID = SenderID; pktCOInfo.m_dwReceiverID = ReceiverID; pktCOInfo.m_sCastObject = CastObject_In; SendAllNearCellCharacter(&pktCOInfo, sizeof(PktCOInfo), CmdCharCastObjectInfo); } //------------------------------------------------------------------------------------------------ void CCell::SendAllNearCellCharacter(const PktBase* lpPktBase, unsigned short usLength, unsigned char cCMD) { __declspec(thread) static char szPacket[PktMaxLen]; unsigned long dwPacket = PktMaxLen; if (PacketWrap::WrapCompress(szPacket, dwPacket, reinterpret_cast(lpPktBase), usLength, cCMD, 0, 0)) { CCell** lppConnectCellBound = m_lpConnectCell + CCell::CONNECT_NUM; for (CCell** lppCell = m_lpConnectCell; lppCell != lppConnectCellBound; ++lppCell) { CCell* lpCell = *lppCell; if (NULL != lpCell) { lpCell->SendNowAllCharacter( reinterpret_cast(szPacket), static_cast(dwPacket), cCMD); } } } } void CCell::SendAllCharacter(const PktBase* lpPktBase, unsigned short usLength, unsigned char cCMD) { __declspec(thread) static char szPacket[PktMaxLen]; unsigned long dwPacket = PktMaxLen; if (PacketWrap::WrapCompress(szPacket, dwPacket, reinterpret_cast(lpPktBase), usLength, cCMD, 0, 0)) { SendNowAllCharacter( reinterpret_cast(szPacket), static_cast(dwPacket), cCMD); } /* if (sizeof(PktBase) <= usLength) { if (0 == m_lpSendAllBuffer || m_lpSendAllBuffer->remain() < usLength) { // ¹öÆÛ°¡ ¾ø°Å³ª, ¹öÆÛ ±æÀ̰¡ ºÎÁ·Çϰųª, ÆÐŶ Ä«¿îÆ®°¡ ¸¹ÀÌ ½×¿´À¸¸é ÆÐŶÀ» Àü¼ÛÇÑ´Ù. FlushSendAllBuffer(); // ¹öÆÛ¸¦ »õ·Î »ý¼ºÇÑ´Ù. m_lpSendAllBuffer = CREATE_BUFFER( CCellManager::GetInstance().GetBufferFactory(), PktMaxLen - 1024); if (0 != m_lpSendAllBuffer) { // ¹öÆÛ »ý¼ºÈÄ, Çì´õ ºÎºÐÀ» ºñ¿öµÐ´Ù. m_lpSendAllBuffer->wr_ptr(sizeof(PktBase)); } } if (0 != m_lpSendAllBuffer) { // ¾ÐÃà Çì´õ¸¦ ºÙÀδÙ. ¾ÐÃà Çì´õ Æ÷¸ËÀº ±æÀÌ 2byte, Ä¿¸Çµå 1byteÀÌ´Ù. // ±æÀÌ´Â Çì´õ Æ÷ÇÔ ÆÐŶ ±æÀÌÀÌ´Ù. unsigned short usDataLength = usLength - sizeof(PktBase); unsigned short usPacketLength = usDataLength + sizeof(usPacketLength) + sizeof(cCMD); m_lpSendAllBuffer->push(&usPacketLength, sizeof(usPacketLength)); m_lpSendAllBuffer->push(&cCMD, sizeof(cCMD)); // µ¥ÀÌÅÍ¿¡¼­ Çì´õ¸¦ Á¦°ÅÇÏ°í º¹»çÇÑ´Ù. m_lpSendAllBuffer->push(lpPktBase + 1, usDataLength); } } */ } void CCell::SendNowAllNearCellCharacter(const char* szData, unsigned short usLength, unsigned char cCMD) { CCell** lppConnectCellBound = m_lpConnectCell + CCell::CONNECT_NUM; for (CCell** lppCell = m_lpConnectCell; lppCell != lppConnectCellBound; ++lppCell) { CCell* lpCell = *lppCell; if (NULL != lpCell) { lpCell->SendNowAllCharacter(szData, usLength, cCMD); } } } void CCell::SendNowAllCharacter(const char* szData, unsigned short usLength, unsigned char cCMD) { CharacterList::iterator pos = m_lstCharacter.begin(); CharacterList::iterator end = m_lstCharacter.end(); CCharacter* lpCharacter = 0; CGameClientDispatch* lpDispatch = 0; for (; pos != end; ++pos) { lpCharacter = *pos; if (0 != lpCharacter && 0 != (lpDispatch = lpCharacter->GetDispatcher())) { lpDispatch->GetSendStream().PutBuffer(szData, usLength, cCMD); } } } CCell* CCell::GetConnectCell(unsigned int nDir) { if (nDir <= CONNECT_NUM) { return m_lpConnectCell[nDir]; } ERRLOG1(g_Log, "Cannot get incorrect direction cell : %d", nDir); return NULL; } void CCell::SetConnectCell(unsigned int nDir, CCell* lpConnectedCell) { if (nDir <= CONNECT_NUM) { m_lpConnectCell[nDir] = lpConnectedCell; } else { ERRLOG1(g_Log, "Cannot set incorrect direction cell : %d", nDir); } } bool CCell::IsNearCell(CCell* lpNearCell) { CCell** lppConnectedCellPastEnd = m_lpConnectCell + CONNECT_NUM; for (CCell** lppCell = m_lpConnectCell; lppCell != lppConnectedCellPastEnd; ++lppCell) { if (*lppCell == lpNearCell) { return true; } } return false; } size_t CCell::GetNearCellCharacterNum() const { size_t nCharacterNum = 0; CCell* const* lppConnectCellBound = m_lpConnectCell + CCell::CONNECT_NUM; for (CCell* const* lppCell = m_lpConnectCell; lppCell != lppConnectCellBound; ++lppCell) { CCell* lpCell = *lppCell; if (NULL != lpCell) { nCharacterNum += lpCell->GetCharacterNum(); } } return nCharacterNum; }; void CCell::RespawnAllCharacter(unsigned char cExceptNation) { if (0 == m_lstCharacter.size()) return; CharacterList::iterator itr = m_lstCharacter.begin(); CCharacter* lpCharacter = NULL; while (itr != m_lstCharacter.end()) { lpCharacter = (*itr); if (lpCharacter && cExceptNation != lpCharacter->GetNation()) { lpCharacter->Respawn(); if (0 != lpCharacter->GetPID()) { // ÆÄƼ¿ø ¸®½ºÆùÀ» ¾Ë¸°´Ù. GameClientSendPacket::SendCharDeadToParty(lpCharacter, 0, PktDeadInfo::RESPAWN); } } ++itr; } }