#include "stdafx.h" #include "Camp.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include CCamp::CCamp(MonsterCreateInfo& MonsterCreate, unsigned long dwCampID, unsigned long dwGID, unsigned long dwHP, unsigned short wObjectType, unsigned char cState, unsigned char cSubState, unsigned char cUpgradeStep, unsigned char cMaterial, unsigned char cSiegeCount, const CampRight& campRight, bool bFullHP) : CSiegeObject(MonsterCreate, dwCampID, dwGID, dwHP, wObjectType, cState, cSubState, cUpgradeStep, cMaterial, cSiegeCount, bFullHP), m_CampRight(campRight), m_dwLastAttackedTick(0), m_dwCmdSenderCID(0) { } CCamp::~CCamp() { } void CCamp::NormalBehavior(unsigned long dwTick) { // ¼±°ø ó¸® if (NULL == m_lpTarget && true == m_MonsterInfo.m_bFirstAttack) { SearchPlayer(); } } void CCamp::AttackBehavior(unsigned long dwTick) { PERFORMANCE_CHECK(FunctionTimingCheck) // ±¸ÃàÁß, ±¸Ãà Ãë¼ÒÁß, ÆÄ±«µÇ¾úÀ¸¸é °ø°ÝÇÒ ¼ö ¾ø´Ù. if (Siege::DEVELOPING == m_cState || Siege::CANCELING == m_cState || Siege::DESTROYED == m_cState) { CancelTarget(); return; } // ¸¶¹ý ij½ºÆÃ ÁßÀ϶§´Â.. ¾Æ¹«·± ´Ù¸¥ ÇൿÀ» ÇØ¼­´Â ¾ÈµÈ´Ù. if (true == m_bCasting) { CastingAttackAction(); return; } m_lpTarget = m_Threat.GetTarget(); if (NULL == m_lpTarget || (m_lpTarget && true == m_lpTarget->GetEnchantInfo().GetFlag(Skill::SpellID::Hide))) { CancelTarget(); return; } const float fDY = fabs(m_lpTarget->GetCurrentPos().m_fPointY - GetCurrentPos().m_fPointY); const float fDX = m_lpTarget->GetCurrentPos().m_fPointX - GetCurrentPos().m_fPointX; const float fDZ = m_lpTarget->GetCurrentPos().m_fPointZ - GetCurrentPos().m_fPointZ; const float fDistance = sqrtf((fDX * fDX) + (fDZ * fDZ)); // °Å¸® üũ if (fDistance > Siege::CAMP_ATTACK_RANGE || 0 == m_lpTarget->GetStatus().m_nNowHP) { CancelTarget(); return; } if (0 >= m_lCurrentFrame) { // °ø°Ý ¹üÀ§ ¹ÛÀÌ´Ù. if (true == SkillAttack()) // ½ºÅ³ °ø°ÝÀ» »ç¿ëÇϴ°¡ üũ { SkillAttackAction(); } if (false == m_bAttacking) { m_lCurrentFrame = m_MotionInfo.m_dwFrame; } } else { // °ø°Ý ¹üÀ§ ¾ÈÀÌ´Ù. if (false == m_bAttacking) { if (true == SkillAttack()) // ½ºÅ³ °ø°ÝÀ» »ç¿ëÇϴ°¡ üũ { SkillAttackAction(); } } } // ¹æÇâÀ» °íÁ¤½ÃÄѵдÙ. m_MotionInfo.m_fDirection = 0; } void CCamp::SearchPlayer(void) { // TODO : ÇØ»óµµ Á¶ÀýÀ» ÅëÇØ float °è»êÀ» ¾ø¾Öº¸ÀÚ. if (NULL == m_CellPos.m_lpCell) { ERRLOG1(g_Log, "CID:0X%08 °ø¼º ¿ÀºêÁ§Æ®°¡ ¼¿ ¹üÀ§ ¹Û¿¡ ÀÖ½À´Ï´Ù.", m_dwCID); return; } CCell* pCell = NULL; CCharacter* pTempTarget = NULL; CCharacter* pCurrentTarget = NULL; const float fSquareSearchRange = (float)(Siege::CAMP_ATTACK_RANGE * Siege::CAMP_ATTACK_RANGE); for (int nCellCount = 0; nCellCount < CCell::CONNECT_NUM; ++nCellCount) { pCell = m_CellPos.m_lpCell->GetConnectCell(nCellCount); if (NULL == pCell || false == pCell->IsCharacter()) { continue; } pTempTarget = pCell->GetFirstCharacter(); while (NULL != pTempTarget) { const float fDistY = fabs(pTempTarget->GetCurrentPos().m_fPointY - GetCurrentPos().m_fPointY); if (pTempTarget->GetStatus().m_nNowHP > 0 && EnemyCheck::EC_ENEMY == IsEnemy(pTempTarget)) { if (false == pTempTarget->GetEnchantInfo().GetFlag(Skill::SpellID::Stealth) && false == pTempTarget->GetEnchantInfo().GetFlag(Skill::SpellID::Invincible) && false == pTempTarget->GetEnchantInfo().GetFlag(Skill::SpellID::Hide)) { const float fDX = pTempTarget->GetCurrentPos().m_fPointX - GetCurrentPos().m_fPointX; const float fDZ = pTempTarget->GetCurrentPos().m_fPointZ - GetCurrentPos().m_fPointZ; const float fDistance = (fDX * fDX) + (fDZ * fDZ); if (fDistance < fSquareSearchRange) { pCurrentTarget = pTempTarget; break; } } } pTempTarget = pCell->GetNextCharacter(); } } if (NULL != pCurrentTarget) { m_Threat.AddToThreatList(pCurrentTarget, 1); m_nCurrentState = CFSM::GetInstance().StateTransition(m_nCurrentState, INPUT_ID_SEEN_PLAYER); } } bool CCamp::Attack(AtType attackType, unsigned char cDefenderNum, CAggresiveCreature** ppDefenders, unsigned char* cDefenserJudges, unsigned short* wDefenserMPHeal) { return CSkillMonster::Attack(attackType, cDefenderNum, ppDefenders, cDefenserJudges, wDefenserMPHeal); } bool CCamp::Dead(CAggresiveCreature* pOffencer) { 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; m_nCurrentState = CFSM::GetInstance().StateTransition(m_nCurrentState, INPUT_ID_ZERO_HP); // Å©¸®ÃÄ ¸Å´ÏÁ®¿¡¼­ »èÁ¦ (ÇØ´ç ¼¿¿¡¼­µµ »èÁ¦ÇÑ´Ù.) CCreatureManager::GetInstance().DeleteCreature(m_dwCID); // Áß°è ¼­¹ö·Î ÆÐŶ Àü¼Û GET_SINGLE_DISPATCH(lpDBAgentDispatch, CDBAgentDispatch, CDBAgentDispatch::GetDispatchTable()); if (lpDBAgentDispatch) { if ( pOffencer ) { DETLOG3(g_Log, "±æµå ¿ä»õ À̺¥Æ® ·Î±× : ÆÄ±«µÈ ¿ä»õ ¾ÆÀ̵ð(0x%08x), ÆÄ±«ÇÑ Ä³¸¯ÅÍ ¾ÆÀ̵ð(0x%08x), ÆÄ±«ÇÑ ±æµå ¾ÆÀ̵ð(0x%08x)", GetCampID(), pOffencer->GetCID(), pOffencer->GetGID()); return GameClientSendPacket::SendCharCampCmdToDBAgent(lpDBAgentDispatch->GetSendStream(), pOffencer->GetCID(), GetCampID(), pOffencer->GetGID(), 0, PktCampCmd::CAMP_DESTROY, PktBase::NO_SERVER_ERR); } else { return GameClientSendPacket::SendCharCampCmdToDBAgent(lpDBAgentDispatch->GetSendStream(), 0, GetCampID(), 0, 0, PktCampCmd::CAMP_DESTROY, PktBase::NO_SERVER_ERR); } } return false; } bool CCamp::ToStarterKit(bool bFullMaterial) { // ¾ÆÀÌÅÛ »ý¼º Item::CItem* lpItem = Item::CItemFactory::GetInstance().CreateItem(Item::EtcItemID::CAMP_KIT_ID); if (NULL == lpItem) { ERRLOG0(g_Log, "±æµå ¿ä»õ »ý¼º ½ºÅ¸Æ®Å¶ ¾ÆÀÌÅÛ »ý¼º¿¡ ½ÇÆÐÇß½À´Ï´Ù."); return false; } CGuild* lpGuild = Guild::CGuildMgr::GetInstance().GetGuild(m_dwGID); if (NULL != lpGuild) { Guild::MemberInfo MasterInfo = lpGuild->GetMaster(); unsigned long dwMasterID = MasterInfo.m_dwCID; CCharacter* lpCharacter = CCreatureManager::GetInstance().GetCharacter( dwMasterID ); 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); } return true; } } // ¹Ù´Ú¿¡ ¾ÆÀÌÅÛ ¶³¾î¶ß¸®±â CCell::ItemInfo itemInfo; GetCellPos().m_lpCell->SetItem(GetCurrentPos(), lpItem, 0, 0, CCell::NONE, itemInfo); return true; } // ±æµå ¿ä»õ ÆÄ±«½Ã ±æµå ¸¶½ºÅÍ¿¡°Ô µ·À» µ¹·ÁÁØ´Ù. (·Î±×ÀÎÇØÀÖÀ»¶§¸¸) // (·Î±×¾Æ¿ôÇØ ÀÖÀ» ¶§´Â Áß°è ¼­¹ö¿¡¼­ µ·À» µ¹·ÁÁִ ó¸®¸¦ ÇÑ´Ù.) void CCamp::AddGoldToMaster(unsigned long dwGold) { CGuild* lpGuild = Guild::CGuildMgr::GetInstance().GetGuild(m_dwGID); if (lpGuild) { Guild::MemberInfo& MasterInfo = lpGuild->GetMaster(); CCharacter* lpMaster = CCreatureManager::GetInstance().GetCharacter( MasterInfo.m_dwCID ); if (lpMaster) { lpMaster->AddGold(dwGold, true); } } } // ±æµå ¿ä»õ ±¸Ãà ¿Ï·á bool CCamp::Build(unsigned char cUpgradeStep) { m_cState = Siege::COMPLETE; UpdateObjectInfo(); // ÇØ´ç ÁøÁö°¡ ÀÖ´Â ¹Ý°æ 5¼¿ À̳»¿¡ Àü¼Û PktCampCmd pktCC; pktCC.m_dwCID = m_dwCID; pktCC.m_dwCampID = GetCampID(); pktCC.m_cState = m_cState; pktCC.m_dwValue1 = 0; pktCC.m_dwValue2 = 0; pktCC.m_cSubCmd = PktCampCmd::CAMP_BUILD_COMPLETE; char* szPacket = reinterpret_cast(&pktCC); if (PacketWrap::WrapCrypt(szPacket, sizeof(PktCampCmd), CmdCampCmd, 0, 0)) { // Vincent - ºê·Îµå ij½ºÆ® Å×½ºÆ® ÄÚµå //SendToRadiusCell(szPacket, sizeof(PktCampCmd), CmdCampCmd); //SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktCampCmd), CmdCampCmd); // Vincent - ¸ðµç ij¸¯ÅÍ¿¡°Ô Àü¼ÛÇØ¾ß ¶óÁö¸Ê Á¤º¸°¡ Á¦´ë·Î °»½ÅµÈ´Ù. CCreatureManager::GetInstance().SendAllCharacter(szPacket, sizeof(PktCampCmd), CmdCampCmd); return true; } return false; } bool CCamp::Cancel() { const int MAX_BUFFER = sizeof(PktCampCmd); char szBuffer[MAX_BUFFER]; PktCampCmd* lpPktCC = reinterpret_cast(szBuffer); lpPktCC->m_dwCID = m_dwCID; lpPktCC->m_dwCampID = GetCampID(); lpPktCC->m_cState = Siege::DESTROYED; lpPktCC->m_dwValue1 = 0; lpPktCC->m_dwValue2 = 0; lpPktCC->m_cSubCmd = PktCampCmd::CAMP_DESTROY; if (true == PacketWrap::WrapCrypt(szBuffer, MAX_BUFFER, CmdCampCmd, 0 ,0)) { CCreatureManager::GetInstance().SendAllCharacter(szBuffer, MAX_BUFFER, CmdCampCmd); return true; } return false; } // ±æµå ¿ä»õ ¾÷±×·¹ÀÌµå ¿Ï·á bool CCamp::Upgrade(unsigned char cUpgradeStep) { m_cState = Siege::COMPLETE; m_cUpgradeStep = cUpgradeStep; UpdateObjectInfo(Siege::UPGRADE_HP); // ÇØ´ç ÁøÁö°¡ ÀÖ´Â ¹Ý°æ 5¼¿ À̳»¿¡ Àü¼Û PktCampCmd pktCC; pktCC.m_dwCID = m_dwCID; pktCC.m_dwCampID = GetCampID(); pktCC.m_cState = m_cState; pktCC.m_dwValue1 = m_cUpgradeStep; pktCC.m_dwValue2 = 0; pktCC.m_cSubCmd = PktCampCmd::CAMP_UPGRADE_COMPLETE; char* szPacket = reinterpret_cast(&pktCC); if (PacketWrap::WrapCrypt(szPacket, sizeof(PktCampCmd), CmdCampCmd, 0, 0)) { // Vincent - ºê·Îµå ij½ºÆ® Å×½ºÆ® ÄÚµå //SendToRadiusCell(szPacket, sizeof(PktCampCmd), CmdCampCmd); SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktCampCmd), CmdCampCmd); } return true; } // ±æµå ¿ä»õ ¼ö¸® ¿Ï·á bool CCamp::Repair(unsigned short wRepairHP) { m_cState = Siege::COMPLETE; UpdateObjectInfo(Siege::REPAIR_HP, wRepairHP); // ÇØ´ç ÁøÁö°¡ ÀÖ´Â ¹Ý°æ 5¼¿ À̳»¿¡ Àü¼Û PktCampCmd pktCC; pktCC.m_dwCID = m_dwCID; pktCC.m_dwCampID = GetCampID(); pktCC.m_cState = m_cState; pktCC.m_dwValue1 = m_CreatureStatus.m_nNowHP; pktCC.m_dwValue2 = 0; pktCC.m_cSubCmd = PktCampCmd::CAMP_REPAIR_COMPLETE; char* szPacket = reinterpret_cast(&pktCC); if (PacketWrap::WrapCrypt(szPacket, sizeof(PktCampCmd), CmdCampCmd, 0, 0)) { // Vincent - ºê·Îµå ij½ºÆ® Å×½ºÆ® ÄÚµå //SendToRadiusCell(szPacket, sizeof(PktCampCmd), CmdCampCmd); SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktCampCmd), CmdCampCmd); } return true; } bool CCamp::Destroy(unsigned long dwOffencerGID) { const int MAX_BUFFER = sizeof(PktCampCmd); char szBuffer[MAX_BUFFER]; PktCampCmd* lpPktCC = reinterpret_cast(szBuffer); lpPktCC->m_dwCID = m_dwCID; lpPktCC->m_dwCampID = GetCampID(); lpPktCC->m_cState = Siege::DESTROYED; lpPktCC->m_dwValue1 = 0; lpPktCC->m_dwValue2 = 0; lpPktCC->m_cSubCmd = PktCampCmd::CAMP_DESTROY; if (true == PacketWrap::WrapCrypt(szBuffer, MAX_BUFFER, CmdCampCmd, 0 ,0)) { CCreatureManager::GetInstance().SendAllCharacter(szBuffer, MAX_BUFFER, CmdCampCmd); // ÀÚÀç µå¶ø CCell* lpCell = CCellManager::GetInstance().GetCell(0, static_cast(GetCurrentPos().m_fPointX), static_cast(GetCurrentPos().m_fPointY), static_cast(GetCurrentPos().m_fPointZ)); if (NULL == lpCell) { ERRLOG4(g_Log, "CampID:0x%08x ÀÚÀ縦 µå¶øÇÒ ±æµå ¿ä»õÀÇ À§Ä¡°¡ ÀÌ»óÇÕ´Ï´Ù. X:%.1f, Y:%.1f, Z:%.1f", GetCampID(), GetCurrentPos().m_fPointX, GetCurrentPos().m_fPointY, GetCurrentPos().m_fPointZ); return false; } unsigned char cAmount = m_cMaterial + Siege::GetUpgradeMaterialNum(m_wObjectType) * m_cUpgradeStep / 2; while (cAmount > 0) { Item::CItem* lpMaterial = Item::CItemFactory::GetInstance().CreateItem(Item::EtcItemID::SIEGE_MATERIAL_ID); if (NULL == lpMaterial) { ERRLOG0(g_Log, "°ø¼º º´±â Á¦ÀÛ¿ë ÀÚÀç ¾ÆÀÌÅÛ »ý¼º¿¡ ½ÇÆÐÇß½À´Ï´Ù."); return false; } unsigned char cMaxNum = lpMaterial->GetMaxNumOrDurability(); if (cAmount < cMaxNum) { lpMaterial->SetNumOrDurability(cAmount); cMaxNum = cAmount; cAmount = 0; } else { lpMaterial->SetNumOrDurability(cMaxNum); cAmount -= cMaxNum; } CCell::ItemInfo itemInfo; lpCell->SetItem(GetCurrentPos(), lpMaterial, 0, dwOffencerGID, (0 == dwOffencerGID) ? CCell::NONE : CCell::GUILD, itemInfo); } return true; } return false; } bool CCamp::ChangeType(unsigned short wChangeType) { m_cState = Siege::COMPLETE; // ÇØ´ç ÁøÁö°¡ ÀÖ´Â ¹Ý°æ 5¼¿ À̳»¿¡ Àü¼Û PktCampCmd pktCC; pktCC.m_dwCID = m_dwCID; pktCC.m_dwCampID = GetCampID(); pktCC.m_cState = m_cState; pktCC.m_dwValue1 = wChangeType; pktCC.m_dwValue2 = 0; pktCC.m_cSubCmd = PktCampCmd::CAMP_CHANGE_COMPLETE; char* szPacket = reinterpret_cast(&pktCC); if (PacketWrap::WrapCrypt(szPacket, sizeof(PktCampCmd), CmdCampCmd, 0, 0)) { // Vincent - ºê·Îµå ij½ºÆ® Å×½ºÆ® ÄÚµå //SendToRadiusCell(szPacket, sizeof(PktCampCmd), CmdCampCmd); SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktCampCmd), CmdCampCmd); } return true; } // ±æµå ¿ä»õ Á¤º¸ ¾÷µ¥ÀÌÆ® bool CCamp::Update(unsigned char cState, unsigned long dwValue1, unsigned long dwValue2, unsigned long dwNoValue, unsigned char cSubCmd) { m_cState = cState; UpdateObjectInfo(); // ÇØ´ç ÁøÁö°¡ ÀÖ´Â ¹Ý°æ 5¼¿ À̳»¿¡ Àü¼Û PktCampCmd pktCC; pktCC.m_dwCID = m_dwCID; pktCC.m_dwCampID = GetCampID(); pktCC.m_cState = m_cState; pktCC.m_dwValue1 = dwValue1; pktCC.m_dwValue2 = dwValue2; pktCC.m_cSubCmd = cSubCmd; // ÀÚÀç ¼Ò¸ð¸¦ ÇÊ¿ä·ÎÇÑ ¸í·ÉÀº ³²Àº ÀÚÀçÀÇ °¹¼ö¸¦ º¸³»ÁØ´Ù. switch (cSubCmd) { case PktCampCmd::CAMP_UPGRADE: { m_cUpgradeStep = static_cast(dwValue1); pktCC.m_dwValue2 = m_cMaterial; } break; case PktCampCmd::CAMP_REPAIR: case PktCampCmd::CAMP_CHANGE_TYPE: { pktCC.m_dwValue2 = m_cMaterial; } break; } char* szPacket = reinterpret_cast(&pktCC); if (PacketWrap::WrapCrypt(szPacket, sizeof(PktCampCmd), CmdCampCmd, 0, 0)) { // Vincent - ºê·Îµå ij½ºÆ® Å×½ºÆ® ÄÚµå //SendToRadiusCell(szPacket, sizeof(PktCampCmd), CmdCampCmd); SendToRange(Siege::BROADCAST_RADIUS, szPacket, sizeof(PktCampCmd), CmdCampCmd); } return true; } void CCamp::SetRight(CampRight campRight) { m_CampRight = campRight; // ÇØ´ç ±æµåÀÇ ±æµå¿øµé¿¡°Ô Àü¼Û Guild::CGuild* lpGuild = Guild::CGuildMgr::GetInstance().GetGuild(GetGID()); if (lpGuild) { PktCampRight pktCR; pktCR.m_dwCID = m_dwCID; pktCR.m_dwCampID = GetCampID(); pktCR.m_CampRight = m_CampRight; char* szPacket = reinterpret_cast(&pktCR); if (PacketWrap::WrapCrypt(szPacket, sizeof(PktCampRight), CmdCampRight, 0, 0)) { lpGuild->SendAllMember(szPacket, sizeof(PktCampRight), CmdCampRight); } } } bool CCamp::CheckRight(unsigned char cRightType, unsigned long dwCID, unsigned long dwGID) { Guild::CGuild* lpGuild = Guild::CGuildMgr::GetInstance().GetGuild(m_dwGID); if (lpGuild) { if (m_CampRight.Check(cRightType, lpGuild->GetTitle(dwCID))) { return true; } } return false; } void CCamp::SendAttackedMessage() { unsigned long dwNowTime = timeGetTime(); if ( dwNowTime - m_dwLastAttackedTick >= Siege::CAMP_ATTACKED_INTERVAL ) { // Áß°è ¼­¹ö·Î ÆÐŶ Àü¼Û GET_SINGLE_DISPATCH(lpDBAgentDispatch, CDBAgentDispatch, CDBAgentDispatch::GetDispatchTable()); if (lpDBAgentDispatch) { if (IsWorldWeapon()) { GameClientSendPacket::SendCharCampMessageToDBAgent(lpDBAgentDispatch->GetSendStream(), GetCampID(), PktCampMessage::MSGCMD_WEAPON_ATTACKED, PktBase::NO_SERVER_ERR); } else { GameClientSendPacket::SendCharCampMessageToDBAgent(lpDBAgentDispatch->GetSendStream(), GetCampID(), PktCampMessage::MSGCMD_ATTACKED, PktBase::NO_SERVER_ERR); } } m_dwLastAttackedTick = dwNowTime; } } unsigned long CCamp::GetRepairGold() const { int nDiffHP = m_CreatureStatus.m_StatusInfo.m_nMaxHP - m_CreatureStatus.m_nNowHP; return nDiffHP * Siege::CAMP_REPAIR_GOLD_PER_HP; }