#include "stdafx.h" #include "SiegeArms.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include CSiegeArms::CSiegeArms(MonsterCreateInfo& MonsterCreate, unsigned long dwOwnerID, unsigned char cNation, unsigned long dwHP, unsigned short wObjectType, unsigned char cState, unsigned char cUpgradeStep) : CSiegeObject(MonsterCreate, dwOwnerID, cNation, dwHP, wObjectType, cState, cUpgradeStep) { } CSiegeArms::~CSiegeArms() { } bool CSiegeArms::AttackCID(CCharacter* lpRideChar, AtType attackType, AtNode& attackNode, unsigned short& wError) { PERFORMANCE_CHECK(FunctionTimingCheck); if (NULL == lpRideChar || m_CreatureStatus.m_nNowHP == 0) { wError = PktAtAck::FAIL_ALREADY_DEAD; return true; } if (0 == (attackType.m_wType & AtType::SKILL_BIT)) { wError = PktAtAck::FAIL_NOT_SIEGE_ATTACK; return false; } const Skill::ProtoType* pThisSkill = CSkillMgr::GetInstance().GetSkillProtoType(attackType.m_wType); if (NULL == pThisSkill) { ERRLOG2(g_Log, "CID:0x%08x Á¸ÀçÇÏÁö ¾Ê´Â ½ºÅ³ ¾ÆÀ̵ðÀÔ´Ï´Ù. Skill ID:0x%04x", m_dwCID, attackType.m_wType); return false; } const unsigned short wLockCount = GetSkillLockCount(attackType.m_wType); if (wLockCount < 0 || wLockCount >= CSkillMgr::MAX_SKILL_LOCKCOUNT) { ERRLOG3(g_Log, "CID:0x%08x ¾²·Á´Â ½ºÅ³ÀÇ ¶ôÄ«¿îÆ®°¡ ÀÌ»óÇÕ´Ï´Ù. SkillType : 0x%04x, LockCount : %d", m_dwCID, attackType.m_wType, wLockCount); return false; } unsigned char cDefenderNum = attackNode.m_wDefenserNum > AtNode::MAX_DEFENDER_NUM ? AtNode::MAX_DEFENDER_NUM : attackNode.m_wDefenserNum; // ÃÖ´ë ¹æ¾îÀÚ ¼ö Á¦ÇÑ CAggresiveCreature* lpAggresiveCreature[AtNode::MAX_DEFENDER_NUM] = {0, }; unsigned short wDefenserMPHeal[AtNode::MAX_DEFENDER_NUM] = {0, }; char cTargetType = Skill::Target::ENEMY; if (0 == cDefenderNum) { if (0 != attackType.m_cMissileAttack) { return MissileAttack(attackType, 0, pThisSkill[attackType.m_cSkillLockCount].m_fEffectExtent, Math::Const::PI * 2, cTargetType); } else { // ij½ºÆÃ¿¡ ½ÇÆÐÇÑ °æ¿ì return Attack(attackType, cDefenderNum, lpAggresiveCreature, attackNode.m_cDefenserJudge, wDefenserMPHeal); } } else { if (0 == pThisSkill[wLockCount].m_fMaxRange && 0 == pThisSkill[attackType.m_cSkillLockCount].m_fEffectExtent) { if (m_dwCID != attackNode.m_dwDefenser[0]) { ERRLOG2(g_Log, "CID:0x%08x ÀÚ±âÀڽſ¡°Ô¸¸ ¾µ ¼ö ÀÖ´Â ½ºÅ³ÀÔ´Ï´Ù. SkillID:0x%04x", m_dwCID, attackType.m_wType); return false; } } // °ø¼ºº´±â´Â ¸ó½ºÅ͸¦ °ø°ÝÇÒ¼ö ¾ø´Ù. Creature::CreatureType eCreatureType = Creature::GetCreatureType(attackNode.m_dwDefenser[0]); if (Creature::CT_MONSTER == eCreatureType || Creature::CT_STRUCT == eCreatureType) { wError = PktAtAck::FAIL_TO_MONSTER; return false; } // ½ºÅ³ °Å¸® üũ CAggresiveCreature* lpTargetCreature = NULL; // Target Creature ¾ò¾î¿À±â if (0 != GetMapIndex()) { lpTargetCreature = CCreatureManager::GetInstance().GetAggresiveCreature(attackNode.m_dwDefenser[0]); if (lpTargetCreature && lpTargetCreature->GetMapIndex() != GetMapIndex()) lpTargetCreature = NULL; } else { lpTargetCreature = CCreatureManager::GetInstance().GetAggresiveCreature(attackNode.m_dwDefenser[0]); } // Target Creature ó¸®Çϱâ if (NULL != lpTargetCreature) { float fSquareTargetDistance = (m_CurrentPos.m_fPointX - lpTargetCreature->GetCurrentPos().m_fPointX) * (m_CurrentPos.m_fPointX - lpTargetCreature->GetCurrentPos().m_fPointX) + (m_CurrentPos.m_fPointZ - lpTargetCreature->GetCurrentPos().m_fPointZ) * (m_CurrentPos.m_fPointZ - lpTargetCreature->GetCurrentPos().m_fPointZ); float fSquareEffectDistance = (pThisSkill[wLockCount].m_fMaxRange + Skill::ERROR_OF_DISTANCE) * (pThisSkill[wLockCount].m_fMaxRange + Skill::ERROR_OF_DISTANCE); if (fSquareTargetDistance > fSquareEffectDistance) { wError = PktAtAck::FAIL_TOO_FAR; return false; } } if (pThisSkill[attackType.m_cSkillLockCount].m_eTargetType == Skill::Target::FRIEND || pThisSkill[attackType.m_cSkillLockCount].m_eTargetType == Skill::Target::DEAD_FRIEND || pThisSkill[attackType.m_cSkillLockCount].m_eTargetType == Skill::Target::FRIEND_EXCEPT_SELF || pThisSkill[attackType.m_cSkillLockCount].m_eTargetType == Skill::Target::FRIEND_OBJECT || pThisSkill[attackType.m_cSkillLockCount].m_eTargetType == Skill::Target::PARTY || pThisSkill[attackType.m_cSkillLockCount].m_eTargetType == Skill::Target::SUMMON) { //cTargetType = Skill::Target::FRIEND; wError = PktAtAck::FAIL_FRIENDLY_ATTACK; return false; } // Ŭ¶óÀÌ¾ðÆ®°¡ ³Ñ°ÜÁØ Å¸°ÙµéÀ» üũÇÑ´Ù. (¹üÀ§ ¸¶¹ý¿¡ °É¸®´Â Ÿ°ÙÀº µû·Î üũ) for (unsigned char cDefender = 0; cDefender < cDefenderNum; ++cDefender) { // Target Creature ¾ò±â CAggresiveCreature* lpCreature = NULL; Creature::CreatureType eCreatureType = Creature::GetCreatureType(attackNode.m_dwDefenser[cDefender]); if (Creature::CT_MONSTER == eCreatureType || Creature::CT_STRUCT == eCreatureType) { continue; } lpCreature = CCreatureManager::GetInstance().GetAggresiveCreature(attackNode.m_dwDefenser[cDefender]); if (lpCreature && lpCreature->GetMapIndex() != GetMapIndex()) { lpCreature = NULL; } if (NULL != lpCreature) { // ±àÁ¤ÀûÀÎ °ø°Ý(-_-) if (Skill::Target::FRIEND == cTargetType) { wError = PktAtAck::FAIL_FRIENDLY_ATTACK; return false; } // ºÎÁ¤ÀûÀÎ °ø°Ý(ÁøÂ¥ °ø°Ý) else { // Àڱ⸦ Áß½ÉÀ¸·Î ÇÏ´Â ¹üÀ§Çü ½ºÅ³ÀÇ °æ¿ì Ÿ°ÙÀ» ÀÚ½ÅÀ¸·Î ¼¼ÆÃÇÕ´Ï´Ù. // (ÀÌ °æ¿ì this´Â MultiAttack() ÇÔ¼ö°¡ ŸÄÏ¿¡¼­ Á¦¿Ü½ÃÄÑ ÁÝ´Ï´Ù.) if (EnemyCheck::EC_ENEMY == IsEnemy(lpCreature) || lpCreature == this) { lpAggresiveCreature[cDefender] = lpCreature; } } } } if (0 == cDefenderNum || NULL == lpAggresiveCreature[0]) { return Attack(attackType, cDefenderNum, lpAggresiveCreature, attackNode.m_cDefenserJudge, wDefenserMPHeal); } // ¹üÀ§ ¸¶¹ý üũ if (0 != pThisSkill[attackType.m_cSkillLockCount].m_fEffectExtent) { if (Skill::Target::PARTY == pThisSkill[attackType.m_cSkillLockCount].m_eTargetType) { wError = PktAtAck::FAIL_FRIENDLY_ATTACK; return false; } else { return CAggresiveCreature::MultiAttack(attackType, cDefenderNum, lpAggresiveCreature, attackNode.m_cDefenserJudge, lpAggresiveCreature[0]->GetCurrentPos(), 0, pThisSkill[attackType.m_cSkillLockCount].m_fEffectExtent, Math::Const::PI * 2, cTargetType); } } } return Attack(attackType, cDefenderNum, lpAggresiveCreature, attackNode.m_cDefenserJudge, wDefenserMPHeal); } bool CSiegeArms::Attack(AtType attackType, unsigned char cDefenderNum, CAggresiveCreature** ppDefenders, unsigned char* cDefenserJudges, unsigned short* wDefenserMPHeal) { if (m_CreatureStatus.m_nNowHP == 0) { ERRLOG1(g_Log, "CID:0x%08x Á×Àº °ø¼º ¿ÀºêÁ§Æ®°¡ °ø°ÝÇÏ·Á°í ÇÏ¿´½À´Ï´Ù.", m_dwCID); return false; } if (cDefenderNum > AtNode::MAX_DEFENDER_NUM) { ERRLOG2(g_Log, "CID:0x%08x °ø¼º ¿ÀºêÁ§Æ®°¡ °ø°ÝÇÒ ¶§, ¹æ¾îÀÚÀÇ ¼ýÀÚ°¡ ÃÖ´ë ¹æ¾îÀÚ ¼ýÀÚ¸¦ ³Ñ¾ú½À´Ï´Ù. ¹æ¾îÀÚ¼ö : %d", m_dwCID, cDefenderNum); cDefenderNum = AtNode::MAX_DEFENDER_NUM; } if (0 == (attackType.m_wType & AtType::SKILL_BIT) && 0 == cDefenderNum) { ERRLOG0(g_Log, "½ºÅ³ÀÌ ¾Æ´Ñ ÀÏ¹Ý °ø°ÝÀº, ¹Ýµå½Ã Ÿ°ÙÀÌ ÀÖÀ» °æ¿ì¿¡¸¸ ¼­¹ö·Î º¸³»¾ß ÇÕ´Ï´Ù."); return false; } if (0 != (attackType.m_wType & AtType::SKILL_BIT)) { const Skill::ProtoType* pSkillProtoType = CSkillMgr::GetInstance().GetSkillProtoType(attackType.m_wType); if (NULL == pSkillProtoType) { ERRLOG2(g_Log, "CID:0x%08x Á¸ÀçÇÏÁö ¾Ê´Â ½ºÅ³ ¾ÆÀ̵ðÀÔ´Ï´Ù. Skill ID:0x%04x", m_dwCID, attackType.m_wType); return false; } } if ( IsRidable() ) { CCharacter* lpRider = CCreatureManager::GetInstance().GetCharacter(m_dwRiderCID); if (!lpRider) { ERRLOG2(g_Log, "CID:0x%08x °ø¼º ¿ÀºêÁ§Æ®¿¡ Ÿ°íÀִ ij¸¯ÅͰ¡ ¾ø½À´Ï´Ù. RiderCID : 0x%08x", m_dwCID, m_dwRiderCID); return false; } // °ø°Ý½Ã ¹«Àû »óŰ¡ Ç®¸°´Ù. lpRider->GetSpellMgr().GetAffectedInfo().RemoveEnchantBySpellType(Skill::SpellID::Invincible); } unsigned char cOffencerJudge = 0; unsigned short wOffencerMPHeal = 0; unsigned short wError = PktAtAck::NO_SERVER_ERR; 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); m_cConsumeMPCount = std::min(cDefenderNum, unsigned char(AtNode::MAX_MONSTER_DEFENDER_NUM)); unsigned char cDefender = 0; unsigned char cIndex = 0; for (; cIndex < cDefenderNum; ++cIndex) { // MP ¼Ò¸ð ŸÀֱ̹îÁöÀÇ Ä«¿îÆ® (¹üÀ§ ¸¶¹ýÀº ÇÑ ¹ø¸¸ MP ¼Ò¸ð) --m_cConsumeMPCount; if (NULL == ppDefenders[cIndex]) { continue; } if (0 == ppDefenders[cIndex]->GetStatus().m_nNowHP) { continue; } // ÃÖ´ë ¹æ¾îÀÚ ¼ö Á¦ÇÑ (¸ó½ºÅʹ ij¸¯ÅͿʹ º°µµ ó¸®) Creature::CreatureType eCreatureType = Creature::GetCreatureType(ppDefenders[cIndex]->GetCID()); if (Creature::CT_MONSTER == eCreatureType || Creature::CT_STRUCT == eCreatureType) { continue; } // TODO : °ø°Ý ¹æÇâÀ» ¼³Á¤ÇØÁݽôÙ. cDefenserJudges[cDefender] = ClientConstants::Judge_Front; wDefenserMPHeal[cDefender] = 0; const unsigned short nPrevHP = ppDefenders[cIndex]->GetStatus().m_nNowHP; const unsigned short nPrevMP = ppDefenders[cIndex]->GetStatus().m_nNowMP; const unsigned short wPrevAttackerHP = m_CreatureStatus.m_nNowHP; // ´ë¹ÌÁö ¹Ý¿µ lpDefenserNode[cDefender].m_wDamage = ppDefenders[cIndex]->ApplyDamage(attackType, this, cOffencerJudge, cDefenserJudges[cDefender], wOffencerMPHeal, wDefenserMPHeal[cDefender], wError); const unsigned short nNowHP = ppDefenders[cIndex]->GetStatus().m_nNowHP; const unsigned short nNowMP = ppDefenders[cIndex]->GetStatus().m_nNowMP; // ½ºÅ³¿¡ ÀÇÇÑ ÀÚ»ì ¹æÁö if (0 == m_CreatureStatus.m_nNowHP) { m_CreatureStatus.m_nNowHP = wPrevAttackerHP; wError = PktAtAck::FAIL_SUICIDE; break; } else { if (Creature::CT_PC == Creature::GetCreatureType(ppDefenders[cIndex]->GetCID())) { CCharacter* lpDefendCharacter = (CCharacter *)ppDefenders[cIndex]; CMonster* lpSummonee = lpDefendCharacter->GetSummonee(); if (NULL != lpSummonee) { lpSummonee->GuardMe(this, lpDefenserNode[cDefender].m_wDamage); } lpDefendCharacter->CalculateEquipDurability((ClientConstants::Judge_Guard == cDefenserJudges[cDefender]) ? AtType::GUARD : AtType::DEFENCE); CGameClientDispatch* lpDispatch = lpDefendCharacter->GetDispatcher(); if (NULL != lpDispatch) { GameClientSendPacket::SendCharAttacked(lpDispatch->GetSendStream(), this, lpDefendCharacter, attackType, m_MotionInfo.m_fDirection, lpDefenserNode[cDefender].m_wDamage, cDefenserJudges[cDefender], wDefenserMPHeal[cDefender], PktBase::NO_SERVER_ERR); } } // °ø°Ý ÆÐŶ ¸¸µé±â lpDefenserNode[cDefender].m_dwCharID = ppDefenders[cIndex]->GetCID(); lpDefenserNode[cDefender].m_sCurrHP = nNowHP; lpDefenserNode[cDefender].m_sCurrMP = nNowMP; lpDefenserNode[cDefender].m_wMaxHP = ppDefenders[cIndex]->GetStatus().m_StatusInfo.m_nMaxHP; lpDefenserNode[cDefender].m_wMaxMP = ppDefenders[cIndex]->GetStatus().m_StatusInfo.m_nMaxMP; lpDefenserNode[cDefender].m_wMPHeal = wDefenserMPHeal[cDefender]; lpDefenserNode[cDefender].m_cJudge = cDefenserJudges[cDefender]; } ++cDefender; } if (0 != (attackType.m_wType & AtType::SKILL_BIT)) { if (0 == cDefender) { Skill::CFunctions::ConsumeMP(attackType, this, 0); } } lpPktAtAck->m_dwCharID = m_dwCID; lpPktAtAck->m_AtType = attackType; lpPktAtAck->m_wHP = m_CreatureStatus.m_nNowHP; lpPktAtAck->m_wMP = m_CreatureStatus.m_nNowMP; lpPktAtAck->m_wMPHeal = wOffencerMPHeal; lpPktAtAck->m_cJudge = cOffencerJudge; lpPktAtAck->m_cDefenserNum = cDefender; if ( IsRidable() ) { CCharacter* lpRider = CCreatureManager::GetInstance().GetCharacter(m_dwRiderCID); if (lpRider && lpRider->GetDispatcher()) { CSendStream& SendStream = (lpRider->GetDispatcher())->GetSendStream(); if (true == SendStream.WrapCompress( szBuffer, sizeof(PktAtAck) + cDefender * sizeof(DefenserNode), CmdCharAttack, 0, wError) && PktBase::NO_SERVER_ERR == wError) { CCell* lpCell = GetCellPos().m_lpCell; if (lpCell) { lpCell->SendAttackInfo(m_dwCID, attackType, cDefender, lpDefenserNode); return true; } } } } else { CCell* lpCell = GetCellPos().m_lpCell; if (lpCell) { lpCell->SendAttackInfo(m_dwCID, attackType, cDefender, lpDefenserNode); return true; } } return false; } bool CSiegeArms::MissileAttack(AtType attackType, float fDir, float nRange, float fAngle, char cTargetType) { if (Siege::LONG_RANGE_SIEGE_ARMS != m_wObjectType) { return false; } CCell* lpCell = NULL; // µà¾ó »óŶó¸é µà¾ó ¼¿·Î ó¸® if(CServerSetup::GetInstance().GetDuelModeCheck() && NULL != GetDuelOpponent()) { lpCell = CDuelCellManager::GetInstance().GetCell(GetCID()); } else { lpCell = CCellManager::GetInstance().GetCell(m_CellPos.m_wMapIndex, static_cast(attackType.m_DstPos.fPointX), static_cast(attackType.m_DstPos.fPointY), static_cast(attackType.m_DstPos.fPointZ)); } if (NULL == lpCell) { ERRLOG0(g_Log, "CID:0x%08x °ø°Ý ¸ñÇ¥ ÁöÁ¡ÀÇ ¼¿ÀÌ Á¸ÀçÇÏÁö ¾Ê½À´Ï´Ù."); return false; } CAggresiveCreature* ppDefenders[AtNode::MAX_DEFENDER_NUM] = {0, }; unsigned char cDefenserJudges[AtNode::MAX_DEFENDER_NUM] = {0, }; unsigned short wDefenserMPHeal[AtNode::MAX_DEFENDER_NUM] = {0, }; int nDefenderNum = 0; for (int nDirection = 0; nDirection < CCell::CONNECT_NUM && nDefenderNum < AtNode::MAX_DEFENDER_NUM; ++nDirection) { CCell* lpConnectCell = lpCell->GetConnectCell(nDirection); if (NULL == lpConnectCell) { continue; } CAggresiveCreature* lpTempTarget = lpConnectCell->GetFirstAggresiveCreature(); // Ÿ°ÙÀÌ ¾ø°Å³ª, ¹æ¾îÀÚ ¼ö°¡ ÃÖ´ë°¡ µÇ¸é, ·çÇÁ¸¦ ºüÁ®³ª°©´Ï´Ù. while (NULL != lpTempTarget && nDefenderNum < AtNode::MAX_DEFENDER_NUM) { // °ø°Ý¿¡ ´ëÇÑ ¿¹¿Ü»óȲ bool bException = false; // º´±â¿¡ ž½ÂÇÑ Ä³¸¯ÅÍ´Â °ø°ÝÇÏÁö ¾Ê´Â´Ù. ´ë½Å º´±â¸¦ °ø°ÝÇÑ´Ù. if (Creature::CT_PC == Creature::GetCreatureType(lpTempTarget->GetCID())) { CCharacter* lpRideChar = reinterpret_cast(lpTempTarget); if (true == lpRideChar->IsRideArms()) { bException = true; } } EnemyCheck::EnemyType eTargetType = IsEnemy(lpTempTarget); if ((EnemyCheck::EC_NEUTRAL == eTargetType) || (Skill::Target::FRIEND == cTargetType && EnemyCheck::EC_ENEMY == eTargetType) || (Skill::Target::ENEMY == cTargetType && EnemyCheck::EC_FRIEND == eTargetType)) { bException = true; } // °ãÄ¡´Â °Ô ÀÖÀ¸¸é ó¸®ÇÏÁö ¾Ê´Â´Ù. for (int nIndex = 0; nIndex < nDefenderNum; nIndex++) { if (ppDefenders[nIndex] == lpTempTarget) { bException = true; break; } } if (false == bException) { const float fDX = lpTempTarget->GetCurrentPos().m_fPointX - attackType.m_DstPos.fPointX; const float fDZ = lpTempTarget->GetCurrentPos().m_fPointZ - attackType.m_DstPos.fPointZ; const float fDistance = (fDX * fDX) + (fDZ * fDZ); const float fSquareAttackRange = nRange * nRange; if (fDistance <= fSquareAttackRange) { const float fTempfDir = CalcDir2D(attackType.m_DstPos.fPointX, attackType.m_DstPos.fPointZ, lpTempTarget->GetCurrentPos().m_fPointX, lpTempTarget->GetCurrentPos().m_fPointZ); const float fDifference = (fTempfDir >= fDir) ? (fTempfDir-fDir) : (fDir-fTempfDir); if (fDifference <= fAngle && 0 < lpTempTarget->GetStatus().m_nNowHP) { ppDefenders[nDefenderNum] = lpTempTarget; cDefenserJudges[nDefenderNum] = ClientConstants::Judge_Front; wDefenserMPHeal[nDefenderNum] = 0; ++nDefenderNum; } } } lpTempTarget = lpConnectCell->GetNextAggresiveCreature(); } } if (AtNode::MAX_DEFENDER_NUM < nDefenderNum) { SERLOG0(g_Log, "½ºÅà ¿À¹ö·± : ¹æ¾îÀÚ¼ö°¡ ÃÖ´ëÄ¡¸¦ ³Ñ¾î¼Ì½À´Ï´Ù."); } return Attack(attackType, nDefenderNum, ppDefenders, cDefenserJudges, wDefenserMPHeal); } bool CSiegeArms::Dead(CAggresiveCreature* pOffencer) { if (NULL == pOffencer) return false; if (STATE_ID_DIE == m_nCurrentState) return false; m_CreatureStatus.m_nNowHP = 0; m_dwLastBehaviorTick = m_dwLastTime = CPulse::GetInstance().GetLastTick(); m_lCurrentFrame = FPS; m_bAttacking = false; m_bCasting = false; // Ÿ°í ÀÖ´ø ij¸¯ÅÍ´Â Á״´Ù. if (0 != m_dwRiderCID) { CCharacter* lpRider = CCreatureManager::GetInstance().GetCharacter(m_dwRiderCID); if (lpRider) { lpRider->GetOff(); lpRider->Kill(pOffencer); } m_dwRiderCID = 0; } // Å©¸®ÃÄ ¸Å´ÏÁ®¿¡¼­ »èÁ¦ (ÇØ´ç ¼¿¿¡¼­µµ »èÁ¦ÇÑ´Ù.) CCreatureManager::GetInstance().DeleteCreature(m_dwCID); // Áß°è ¼­¹ö·Î ÆÐŶ Àü¼Û GET_SINGLE_DISPATCH(lpDBAgentDispatch, CDBAgentDispatch, CDBAgentDispatch::GetDispatchTable()); if (lpDBAgentDispatch) { return GameClientSendPacket::SendCharSiegeArmsCmdToDBAgent(lpDBAgentDispatch->GetSendStream(), 0, m_dwCID, 0, PktSiegeArmsCmd::SIEGE_DESTROY_ARMS, PktSiegeArmsCmd::NO_SERVER_ERR); } return false; } bool CSiegeArms::ToStarterKit(bool bMaterial) { unsigned short wItemProtoTypeID; switch (m_wObjectType) { case Siege::SHORT_RANGE_SIEGE_ARMS: wItemProtoTypeID = Item::EtcItemID::SHORT_RANGE_ARMS_KIT_ID; break; case Siege::LONG_RANGE_SIEGE_ARMS: wItemProtoTypeID = Item::EtcItemID::LONG_RANGE_ARMS_KIT_ID; break; case Siege::AIRSHIP: wItemProtoTypeID = Item::EtcItemID::AIRSHIP_KIT_ID; break; } // ½ºÅ¸Æ®Å¶ ¾ÆÀÌÅÛ »ý¼º Item::CItem* lpItem = Item::CItemFactory::GetInstance().CreateItem(wItemProtoTypeID); if (NULL == lpItem) { ERRLOG0(g_Log, "±æµå ¿ä»õ »ý¼º ½ºÅ¸Æ®Å¶ ¾ÆÀÌÅÛ »ý¼º¿¡ ½ÇÆÐÇß½À´Ï´Ù."); return false; } CCharacter* lpCharacter = CCreatureManager::GetInstance().GetCharacter( m_dwOwnerID ); if (NULL != lpCharacter) { if (false == lpCharacter->GiveItem(lpItem)) { ERRLOG0(g_Log, "±æµå ¿ä»õ »ý¼º ½ºÅ¸Æ®Å¶À» µ¹·ÁÁִµ¥ ½ÇÆÐÇÏ¿´½À´Ï´Ù."); DELETE_ITEM(lpItem); return false; } // GievItem À¸·Î ½ºÅÃµÈ °æ¿ì if (lpItem->IsSet(Item::DetailData::STACKABLE) && 0 == lpItem->GetNumOrDurability()) { DELETE_ITEM(lpItem); } if(bMaterial) { GiveBackSiegeMaterial(); } return true; } // ¿ì¼± Àӽ÷ΠÁÖ¼® ó¸®. if(bMaterial) { GiveBackSiegeMaterial(); } // ¹Ù´Ú¿¡ ¾ÆÀÌÅÛ ¶³¾î¶ß¸®±â CCell::ItemInfo itemInfo; GetCellPos().m_lpCell->SetItem(GetCurrentPos(), lpItem, 0, 0, CCell::NONE, itemInfo); return true; } bool CSiegeArms::GiveBackSiegeMaterial() { // ¾÷±×·¹À̵忡 µû¸¥ °¹¼ö ¼³Á¤ unsigned char cNum = 0; const CMonsterMgr::MonsterProtoType* lpProtoType = CMonsterMgr::GetInstance().GetMonsterProtoType(m_wObjectType); if (lpProtoType) { cNum = Siege::SIEGE_ARMS_UPGRADE_MATERIAL_NUM / 2; } if (cNum > 0) { // ÀÚÀç ¾ÆÀÌÅÛ µ¹·ÁÁÖ±â Item::CItem* lpMaterial = Item::CItemFactory::GetInstance().CreateItem(Item::EtcItemID::SIEGE_MATERIAL_ID); if (NULL == lpMaterial) { ERRLOG0(g_Log, "°ø¼º º´±â Á¦ÀÛ¿ë ÀÚÀç ¾ÆÀÌÅÛ »ý¼º¿¡ ½ÇÆÐÇß½À´Ï´Ù."); return false; } lpMaterial->SetNumOrDurability(cNum); CCharacter* lpCharacter = CCreatureManager::GetInstance().GetCharacter(m_dwOwnerID); if (NULL != lpCharacter) { if (false == lpCharacter->GiveItem(lpMaterial)) { ERRLOG0(g_Log, "°ø¼º º´±â Á¦ÀÛ¿ë ÀÚÀ縦 µ¹·ÁÁִµ¥ ½ÇÆÐÇÏ¿´½À´Ï´Ù."); DELETE_ITEM(lpMaterial); return false; } // GievItem À¸·Î ½ºÅÃµÈ °æ¿ì if (lpMaterial->IsSet(Item::DetailData::STACKABLE) && 0 == lpMaterial->GetNumOrDurability()) { DELETE_ITEM(lpMaterial); } return true; } CCell::ItemInfo itemInfo; GetCellPos().m_lpCell->SetItem(GetCurrentPos(), lpMaterial, 0, 0, CCell::NONE, itemInfo); } return true; } unsigned short CSiegeArms::GetRepairMaterialNum() { unsigned long dwHp = m_CreatureStatus.m_StatusInfo.m_nMaxHP - m_CreatureStatus.m_nNowHP; unsigned long dwPerHp = m_CreatureStatus.m_StatusInfo.m_nMaxHP/Siege::SIEGE_ARMS_REPAIR_HP_PER_MATERIAL; unsigned short wNum = static_cast(dwHp / dwPerHp); if((dwHp%dwPerHp)!=0) { wNum++; } return wNum; } bool CSiegeArms::Build(unsigned char cUpgradeStep) { m_cState = Siege::COMPLETE; m_cUpgradeStep = cUpgradeStep; UpdateObjectInfo(); // °ø¼º º´±â°¡ ÀÖ´Â ¹Ý°æ 5¼¿ À̳»¿¡ Àü¼Û PktSiegeArmsCmd pktSAC; pktSAC.m_dwCID = GetOwnerID(); pktSAC.m_dwArmsID = m_dwCID; pktSAC.m_cState = m_cState; pktSAC.m_dwValue = m_cUpgradeStep; pktSAC.m_cSubCmd = PktSiegeArmsCmd::SIEGE_CREATE_ARMS_COMPLETE; char* szPacket = reinterpret_cast(&pktSAC); if (PacketWrap::WrapCrypt(szPacket, sizeof(PktSiegeArmsCmd), CmdSiegeArmsCmd, 0, 0)) { // Vincent - ºê·Îµå ij½ºÆ® Å×½ºÆ® ÄÚµå //SendToRadiusCell(szPacket, sizeof(PktSiegeArmsCmd), CmdSiegeArmsCmd); SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktSiegeArmsCmd), CmdSiegeArmsCmd); } return true; } bool CSiegeArms::Repair(unsigned short wRepairHP) { m_cState = Siege::COMPLETE; UpdateObjectInfo(Siege::REPAIR_HP, wRepairHP); // °ø¼º º´±â°¡ ÀÖ´Â ¹Ý°æ 5¼¿ À̳»¿¡ Àü¼Û PktSiegeArmsCmd pktSAC; pktSAC.m_dwCID = GetOwnerID(); pktSAC.m_dwArmsID = m_dwCID; pktSAC.m_cState = m_cState; pktSAC.m_dwValue = m_CreatureStatus.m_nNowHP; pktSAC.m_cSubCmd = PktSiegeArmsCmd::SIEGE_REPAIR_ARMS_COMPLETE; char* szPacket = reinterpret_cast(&pktSAC); if (PacketWrap::WrapCrypt(szPacket, sizeof(PktSiegeArmsCmd), CmdSiegeArmsCmd, 0, 0)) { // Vincent - ºê·Îµå ij½ºÆ® Å×½ºÆ® ÄÚµå //SendToRadiusCell(szPacket, sizeof(PktSiegeArmsCmd), CmdSiegeArmsCmd); SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktSiegeArmsCmd), CmdSiegeArmsCmd); } return true; } bool CSiegeArms::Destroy(unsigned char cOffencerNation, bool bTakeGold) { m_cState = Siege::DESTROYED; m_cUpgradeStep = 0; m_CreatureStatus.m_nNowHP = 0; // °ø¼º º´±â°¡ ÀÖ´Â ¹Ý°æ 5¼¿ À̳»¿¡ Àü¼Û PktSiegeArmsCmd pktSAC; pktSAC.m_dwCID = GetOwnerID(); pktSAC.m_dwArmsID = m_dwCID; pktSAC.m_cState = m_cState; pktSAC.m_dwValue = m_cUpgradeStep; pktSAC.m_cSubCmd = PktSiegeArmsCmd::SIEGE_DESTROY_ARMS; // CreatureManager ¿¡¼­ »èÁ¦ CCreatureManager::GetInstance().DeleteCreature(m_dwCID); char* szPacket = reinterpret_cast(&pktSAC); if (PacketWrap::WrapCrypt(szPacket, sizeof(PktSiegeArmsCmd), CmdSiegeArmsCmd, 0, 0)) { // Vincent - ºê·Îµå ij½ºÆ® Å×½ºÆ® ÄÚµå //SendToRadiusCell(szPacket, sizeof(PktSiegeArmsCmd), CmdSiegeArmsCmd); SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktSiegeArmsCmd), CmdSiegeArmsCmd); } return true; } bool CSiegeArms::Update(unsigned char cState, unsigned long dwValue1, unsigned long dwValue2, unsigned long dwNoValue, unsigned char cSubCmd) { m_cState = cState; UpdateObjectInfo(); // °ø¼º º´±â°¡ ÀÖ´Â ¹Ý°æ 5¼¿ À̳»¿¡ Àü¼Û PktSiegeArmsCmd pktSAC; pktSAC.m_dwCID = GetOwnerID(); pktSAC.m_dwArmsID = m_dwCID; pktSAC.m_cState = m_cState; pktSAC.m_dwValue = dwValue1; pktSAC.m_cSubCmd = cSubCmd; char* szPacket = reinterpret_cast(&pktSAC); if (PacketWrap::WrapCrypt(szPacket, sizeof(PktSiegeArmsCmd), CmdSiegeArmsCmd, 0, 0)) { // Vincent - ºê·Îµå ij½ºÆ® Å×½ºÆ® ÄÚµå //SendToRadiusCell(szPacket, sizeof(PktSiegeArmsCmd), CmdSiegeArmsCmd); SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktSiegeArmsCmd), CmdSiegeArmsCmd); } return true; } bool CSiegeArms::Ride(unsigned long dwCID) { if (0 == m_dwRiderCID) { CCharacter* lpRider = CCreatureManager::GetInstance().GetCharacter(dwCID); if (lpRider && dwCID == m_dwOwnerID) { m_dwRiderCID = dwCID; lpRider->Ride(m_dwCID); lpRider->SkillClear(); // ºÎÇϰ¡ Å©¸é °ÔÀÓ¼­¹ö¿¡·Î ½Ã°£ üũ ·çƾÀ» ¿Å°Ü¿Àµµ·Ï ¼öÁ¤ÇÏÀÚ!! // Áß°è ¼­¹ö·Î ÆÐŶ Àü¼Û (½Ã°£ üũ¶§¹®¿¡...) GET_SINGLE_DISPATCH(lpDBAgentDispatch, CDBAgentDispatch, CDBAgentDispatch::GetDispatchTable()); if (lpDBAgentDispatch) { GameClientSendPacket::SendCharSiegeArmsCmdToDBAgent(lpDBAgentDispatch->GetSendStream(), dwCID, m_dwCID, 0, PktSiegeArmsCmd::SIEGE_RIDE_ARMS, PktBase::NO_SERVER_ERR); } // Ride ÇÔ¼ö ÀÚü¿¡¼­ Ŭ¶óÀÌ¾ðÆ®¿¡°Ô ÆÐŶÀ» º¸³»ÁØ´Ù. PktSiegeArmsCmd pktSAC; pktSAC.m_dwCID = GetOwnerID(); pktSAC.m_dwArmsID = m_dwCID; pktSAC.m_cState = m_cState; pktSAC.m_dwValue = dwCID; pktSAC.m_cSubCmd = PktSiegeArmsCmd::SIEGE_RIDE_ARMS; char* szPacket = reinterpret_cast(&pktSAC); if (PacketWrap::WrapCrypt(szPacket, sizeof(PktSiegeArmsCmd), CmdSiegeArmsCmd, 0, 0)) { SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktSiegeArmsCmd), CmdSiegeArmsCmd); } return true; } } return false; } bool CSiegeArms::GetOff(unsigned long dwCID) { if (Siege::NOT_RIDER != IsRider(dwCID)) { CCharacter* lpRider = CCreatureManager::GetInstance().GetCharacter(dwCID); if (lpRider) { m_dwRiderCID = 0; lpRider->GetOff(); GET_SINGLE_DISPATCH(lpDBAgentDispatch, CDBAgentDispatch, CDBAgentDispatch::GetDispatchTable()); // °ø¼ºº´±â¿¡¼­ ³»·È´Ù´Â Á¤º¸¸¦ DBAgent ¼­¹ö¿¡ ¾Ë·ÁÁØ´Ù. if (0 != lpDBAgentDispatch) { CSendStream& AgentSendStream = lpDBAgentDispatch->GetSendStream(); GameClientSendPacket::SendCharSiegeArmsCmdToDBAgent(AgentSendStream, dwCID, m_dwCID, 0, PktSiegeArmsCmd::SIEGE_GETOFF_ARMS, PktBase::NO_SERVER_ERR); } // GetOff ÇÔ¼ö ÀÚü¿¡¼­ Ŭ¶óÀÌ¾ðÆ®¿¡°Ô ÆÐŶÀ» º¸³»ÁØ´Ù. PktSiegeArmsCmd pktSAC; pktSAC.m_dwCID = GetOwnerID(); pktSAC.m_dwArmsID = m_dwCID; pktSAC.m_cState = m_cState; pktSAC.m_dwValue = dwCID; pktSAC.m_cSubCmd = PktSiegeArmsCmd::SIEGE_GETOFF_ARMS; char* szPacket = reinterpret_cast(&pktSAC); if (PacketWrap::WrapCrypt(szPacket, sizeof(PktSiegeArmsCmd), CmdSiegeArmsCmd, 0, 0)) { SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktSiegeArmsCmd), CmdSiegeArmsCmd); } return true; } } return false; }