#include "stdafx.h" #include "CastleArms.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include CCastleArms::CCastleArms(MonsterCreateInfo& MonsterCreate, const CastleObjectInfo& CastleObject) : CSiegeObject(MonsterCreate, CastleObject) { } CCastleArms::~CCastleArms() { } bool CCastleArms::AttackCID(CCharacter* lpRideChar, AtType attackType, AtNode& attackNode, unsigned short& wError) { PERFORMANCE_CHECK(FunctionTimingCheck); if (Siege::CASTLE_ARMS_NPC == m_wObjectType) { wError = PktAtAck::SERVER_ERROR; return true; } 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 CCastleArms::Attack(AtType attackType, unsigned char cDefenderNum, CAggresiveCreature** ppDefenders, unsigned char* cDefenserJudges, unsigned short* wDefenserMPHeal) { if (Siege::CASTLE_ARMS_NPC == m_wObjectType) { return false; } 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 CCastleArms::MissileAttack(AtType attackType, float fDir, float nRange, float fAngle, char cTargetType) { if (Siege::LONG_RANGE_CASTLE_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 CCastleArms::Dead(CAggresiveCreature* pOffencer) { if (Siege::CASTLE_ARMS_NPC == m_wObjectType) { return true; } if (NULL == pOffencer) return false; if (STATE_ID_DIE == m_nCurrentState) return false; //m_wObjectType = Siege::CASTLE_ARMS_NPC; 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; m_dwOwnerID = 0; } // Áß°è ¼­¹ö·Î ÆÐŶ Àü¼Û GET_SINGLE_DISPATCH(lpDBAgentDispatch, CDBAgentDispatch, CDBAgentDispatch::GetDispatchTable()); if (lpDBAgentDispatch) { return GameClientSendPacket::SendCharCastleCmdToDBAgent(lpDBAgentDispatch->GetSendStream(), pOffencer->GetCID(), GetCastleID(), m_dwCID, PktCastleCmd::DESTROY, 0, PktCastleCmd::CASTLE_DESTROY_ARMS, PktBase::NO_SERVER_ERR); } return false; } bool CCastleArms::Upgrade(unsigned char cUpgradeStep) { m_cState = Siege::COMPLETE; m_cUpgradeStep = cUpgradeStep; UpdateObjectInfo(Siege::UPGRADE_HP); // ¼ö¼º º´±â°¡ ÀÖ´Â ¹Ý°æ 5¼¿ À̳»¿¡ Àü¼Û PktCastleCmd pktCC; pktCC.m_dwCastleID = GetCastleID(); pktCC.m_dwCastleObjectID = m_dwCID; pktCC.m_cState = m_cState; pktCC.m_dwValue1 = m_cUpgradeStep; // ¾÷±×·¹ÀÌµå ´Ü°è pktCC.m_dwValue2 = 0; pktCC.m_cSubCmd = PktCastleCmd::CASTLE_UPGRADE_ARMS_COMPLETE; char* szPacket = reinterpret_cast(&pktCC); if (PacketWrap::WrapCrypt(szPacket, sizeof(PktCastleCmd), CmdCastleCmd, 0, 0)) { // Vincent - ºê·Îµå ij½ºÆ® Å×½ºÆ® ÄÚµå //SendToRadiusCell(szPacket, sizeof(PktCastleCmd), CmdCastleCmd); SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktCastleCmd), CmdCastleCmd); } return true; } bool CCastleArms::Repair(unsigned short wRepairHP) { m_cState = Siege::COMPLETE; UpdateObjectInfo(Siege::REPAIR_HP, wRepairHP); // ¼ö¼º º´±â°¡ ÀÖ´Â ¹Ý°æ 5¼¿ À̳»¿¡ Àü¼Û PktCastleCmd pktCC; pktCC.m_dwCastleID = GetCastleID(); pktCC.m_dwCastleObjectID = m_dwCID; pktCC.m_cState = m_cState; pktCC.m_dwValue1 = wRepairHP; pktCC.m_dwValue2 = m_CreatureStatus.m_nNowHP; // ÇöÀç HP pktCC.m_cSubCmd = PktCastleCmd::CASTLE_REPAIR_ARMS_COMPLETE; char* szPacket = reinterpret_cast(&pktCC); if (PacketWrap::WrapCrypt(szPacket, sizeof(PktCastleCmd), CmdCastleCmd, 0, 0)) { // Vincent - ºê·Îµå ij½ºÆ® Å×½ºÆ® ÄÚµå //SendToRadiusCell(szPacket, sizeof(PktCastleCmd), CmdCastleCmd); SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktCastleCmd), CmdCastleCmd); } return true; } bool CCastleArms::Destroy(unsigned char cOffencerNation, bool bTakeGold) { if (!IsCastleArms() || Siege::CASTLE_ARMS_NPC == m_wObjectType) { m_dwOwnerID = 0; return false; } // »ý»ê ºñ¿ëÀÇ Àý¹ÝÀ» µ¹·ÁÁØ´Ù. if (true == bTakeGold) { CCharacter* lpOwner = CCreatureManager::GetInstance().GetCharacter(m_dwOwnerID); if (0 != lpOwner) { lpOwner->AddGold(m_MonsterInfo.m_dwDevelopGold / 2, true); } } m_wObjectType = Siege::CASTLE_ARMS_NPC; m_cState = Siege::COMPLETE; m_cUpgradeStep = 0; m_dwOwnerID = 0; UpdateObjectInfo(); m_CreatureStatus.m_nNowHP = 0; // ¼ö¼º º´±â°¡ ÀÖ´Â ¹Ý°æ 5¼¿ À̳»¿¡ Àü¼Û PktCastleCmd pktCC; pktCC.m_dwCID = 0; pktCC.m_dwCastleID = GetCastleID(); pktCC.m_dwCastleObjectID = m_dwCID; pktCC.m_cState = m_cState; pktCC.m_dwValue1 = m_wObjectType; // º´±â °ü¸® NPC Type ID pktCC.m_dwValue2 = 0; pktCC.m_cSubCmd = PktCastleCmd::CASTLE_DESTROY_ARMS; char* szPacket = reinterpret_cast(&pktCC); if (PacketWrap::WrapCrypt(szPacket, sizeof(PktCastleCmd), CmdCastleCmd, 0, 0)) { // Vincent - ºê·Îµå ij½ºÆ® Å×½ºÆ® ÄÚµå //SendToRadiusCell(szPacket, sizeof(PktCastleCmd), CmdCastleCmd); SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktCastleCmd), CmdCastleCmd); } return true; } bool CCastleArms::Update(unsigned char cState, unsigned long dwValue1, unsigned long dwValue2, unsigned long dwOnwerID, unsigned char cSubCmd) { if (!IsCastleArms()) { return false; } m_cState = cState; if (cSubCmd == PktCastleCmd::CASTLE_CREATE_ARMS) { dwValue2 = (dwValue2 & 0x0000FFFF); m_wObjectType = static_cast(dwValue2); m_dwOwnerID = dwOnwerID; // °³ÀÎ ±Ý°í¿¡¼­ dwValue1 ¸¸Å­ÀÇ µ·À» ±ï´Â´Ù. CCharacter* lpOwner = CCreatureManager::GetInstance().GetCharacter(m_dwOwnerID); if (0 != lpOwner) { lpOwner->DeductGold(dwValue1, true); } UpdateObjectInfo(Siege::FULL_HP); } else if (cSubCmd == PktCastleCmd::CASTLE_REPAIR_ARMS) { // °³ÀÎ ±Ý°í¿¡¼­ dwValue1 ¸¸Å­ÀÇ µ·À» ±ï´Â´Ù. CCharacter* lpOwner = CCreatureManager::GetInstance().GetCharacter(m_dwOwnerID); if (0 != lpOwner) { lpOwner->DeductGold(dwValue1, true); } UpdateObjectInfo(); } else { UpdateObjectInfo(); } // ¼ö¼º º´±â°¡ ÀÖ´Â ¹Ý°æ 5¼¿ À̳»¿¡ Àü¼Û PktCastleCmd pktCC; pktCC.m_dwCID = m_dwOwnerID; pktCC.m_dwCastleID = GetCastleID(); pktCC.m_dwCastleObjectID = m_dwCID; pktCC.m_cState = m_cState; pktCC.m_dwValue1 = dwValue1; pktCC.m_dwValue2 = dwValue2; pktCC.m_cSubCmd = cSubCmd; char* szPacket = reinterpret_cast(&pktCC); if (PacketWrap::WrapCrypt(szPacket, sizeof(PktCastleCmd), CmdCastleCmd, 0, 0)) { // Vincent - ºê·Îµå ij½ºÆ® Å×½ºÆ® ÄÚµå //SendToRadiusCell(szPacket, sizeof(PktCastleCmd), CmdCastleCmd); SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktCastleCmd), CmdCastleCmd); } return true; } bool CCastleArms::ChangeType(unsigned short wType) { m_wObjectType = wType; m_cState = Siege::COMPLETE; m_cUpgradeStep = 0; UpdateObjectInfo(); // ¼ö¼º º´±â°¡ ÀÖ´Â ¹Ý°æ 5¼¿ À̳»¿¡ Àü¼Û PktCastleCmd pktCC; pktCC.m_dwCastleID = GetCastleID(); pktCC.m_dwCastleObjectID = m_dwCID; pktCC.m_cState = m_cState; pktCC.m_dwValue1 = wType; // º´±â ŸÀÔ pktCC.m_dwValue2 = 0; pktCC.m_cSubCmd = PktCastleCmd::CASTLE_CREATE_ARMS_COMPLETE; char* szPacket = reinterpret_cast(&pktCC); if (PacketWrap::WrapCrypt(szPacket, sizeof(PktCastleCmd), CmdCastleCmd, 0, 0)) { // Vincent - ºê·Îµå ij½ºÆ® Å×½ºÆ® ÄÚµå //SendToRadiusCell(szPacket, sizeof(PktCastleCmd), CmdCastleCmd); SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktCastleCmd), CmdCastleCmd); } return true; } bool CCastleArms::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 (NULL == lpDBAgentDispatch) { ERRLOG0(g_Log, "¿¡ÀÌÀüÆ® ¾ò±â ½ÇÆÐ."); return false; } else { GameClientSendPacket::SendCharCastleCmdToDBAgent(lpDBAgentDispatch->GetSendStream(), dwCID, m_dwCampOrCastleID, m_dwCID, 0, 0, PktCastleCmd::CASTLE_RIDE_ARMS, PktBase::NO_SERVER_ERR); } // Ride ÇÔ¼ö ÀÚü¿¡¼­ ÆÐŶÀ» º¸³»ÁØ´Ù. PktCastleCmd pktCC; pktCC.m_dwCastleID = GetCastleID(); pktCC.m_dwCastleObjectID = m_dwCID; pktCC.m_cState = m_cState; pktCC.m_dwValue1 = dwCID; // ž½ÂÀÚ CID pktCC.m_dwValue2 = 0; pktCC.m_cSubCmd = PktCastleCmd::CASTLE_RIDE_ARMS; char* szPacket = reinterpret_cast(&pktCC); if (PacketWrap::WrapCrypt(szPacket, sizeof(PktCastleCmd), CmdCastleCmd, 0, 0)) { SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktCastleCmd), CmdCastleCmd); } return true; } } return false; } bool CCastleArms::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()); if (NULL == lpDBAgentDispatch) { ERRLOG0(g_Log, "¿¡ÀÌÀüÆ® ¾ò±â ½ÇÆÐ."); return false; } else { GameClientSendPacket::SendCharCastleCmdToDBAgent(lpDBAgentDispatch->GetSendStream(), dwCID, m_dwCampOrCastleID, m_dwCID, 0, 0, PktCastleCmd::CASTLE_GETOFF_ARMS, PktBase::NO_SERVER_ERR); } // GetOff ÇÔ¼ö ÀÚü¿¡¼­ ÆÐŶÀ» º¸³»ÁØ´Ù. PktCastleCmd pktCC; pktCC.m_dwCastleID = GetCastleID(); pktCC.m_dwCastleObjectID = m_dwCID; pktCC.m_cState = m_cState; pktCC.m_dwValue1 = dwCID; // ³»¸° »ç¶÷ CID pktCC.m_dwValue2 = 0; pktCC.m_cSubCmd = PktCastleCmd::CASTLE_GETOFF_ARMS; char* szPacket = reinterpret_cast(&pktCC); if (PacketWrap::WrapCrypt(szPacket, sizeof(PktCastleCmd), CmdCastleCmd, 0, 0)) { SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktCastleCmd), CmdCastleCmd); } return true; } } return false; }