#include "stdafx.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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include "ExpTable.h" #include "Character.h" #include "CharacterCreate.h" #include "CharRespawnMgr.h" #include const int CCharacter::CalculateFixLevelGap(CAggresiveCreature *pDefender) { Creature::CreatureType eCreatureType = Creature::GetCreatureType(pDefender->GetCID()); if (Creature::CT_MONSTER == eCreatureType || Creature::CT_SUMMON == eCreatureType || Creature::CT_STRUCT == eCreatureType) { CMonster* lpMonster = reinterpret_cast(pDefender); return (lpMonster->CalculateFixLevelGap(this) * -1); } return CAggresiveCreature::CalculateLevelGap(pDefender); } void CCharacter::Casting(AtType attackType, AtNode& attackNode) { // ij½ºÆÃ½Ã Ç®¸®´Â ÀÎæƮµé m_SpellMgr.GetAffectedInfo().RemoveEnchantBySpellType(Skill::SpellID::Invincible); m_SpellMgr.GetAffectedInfo().RemoveEnchantBySpellType(Skill::SpellID::CounterAttack); } bool CCharacter::AttackCID(AtType attackType, AtNode& attackNode, unsigned short& wError) { PERFORMANCE_CHECK(FunctionTimingCheck); if (true == m_bLogout || m_CreatureStatus.m_nNowHP == 0) { wError = PktAtAck::FAIL_ALREADY_DEAD; return true; } 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 wDefenderMPHeal[AtNode::MAX_DEFENDER_NUM] = {0, }; char cTargetType = Skill::Target::ENEMY; Skill::Target::Type eSkillTargetType = Skill::Target::ENEMY; // ij½ºÆÃ¿¡ ½ÇÆÐÇÑ ½ºÅ³ÀÇ °æ¿ì cDefenderNum ÀÌ 0 À¸·Î ³Ñ¾î¿Â´Ù. if (0 == cDefenderNum) { return Attack(attackType, cDefenderNum, lpAggresiveCreature, attackNode.m_cDefenserJudge, wDefenderMPHeal); } // ¼Ò¼È¿É¼ÇÀ̸é if (0x4000 < attackType.m_wType && attackType.m_wType < 0x5000) { const Skill::ProtoType* pThisSkill = CSkillMgr::GetInstance().GetSkillProtoType(attackType.m_wType); if (0 == 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; } eSkillTargetType = pThisSkill[attackType.m_cSkillLockCount].m_eTargetType; cTargetType = Skill::Target::FRIEND; } else if (0 != (attackType.m_wType & AtType::SKILL_BIT)) { const Skill::ProtoType* pThisSkill = CSkillMgr::GetInstance().GetSkillProtoType(attackType.m_wType); if (0 == pThisSkill) { ERRLOG2(g_Log, "CID:0x%08x Á¸ÀçÇÏÁö ¾Ê´Â ½ºÅ³ ¾ÆÀ̵ðÀÔ´Ï´Ù. Skill ID:0x%04x", m_dwCID, attackType.m_wType); return false; } unsigned short wLockCount = GetSkillLockCount(attackType.m_wType); // °Ô´õ ½ºÅ³Àº ½ºÅ³¿¡ µî·ÏµÇÁö ¾Ê¾Æµµ »ç¿ë°¡´ÉÇÏ´Ù. if(0x9E00 < attackType.m_wType && attackType.m_wType <= 0x9EFF) { wLockCount = attackType.m_cSkillLockCount; } 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; } 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; } } // ½ºÅ³ °Å¸® üũ CAggresiveCreature* lpTargetCreature = 0; // Target Creature ¾ò¾î¿À±â if (0 != GetMapIndex()) { // Ÿ°ÙÀÌ ¸ó½ºÅÍÀΰ¡? Creature::CreatureType eCreatureType = Creature::GetCreatureType(attackNode.m_dwDefenser[0]); if (Creature::CT_MONSTER == eCreatureType || Creature::CT_SUMMON == eCreatureType || Creature::CT_STRUCT == eCreatureType) { VirtualArea::CVirtualArea* lpVirtualArea = VirtualArea::CVirtualAreaMgr::GetInstance().GetVirtualArea(GetMapIndex()); if (0 != lpVirtualArea) { CVirtualMonsterMgr* lpVirtualMonsterMgr = lpVirtualArea->GetMonsterManager(); if (0 != lpVirtualMonsterMgr) { lpTargetCreature = lpVirtualMonsterMgr->GetAggresiveCreature(attackNode.m_dwDefenser[0]); } } } else { lpTargetCreature = CCreatureManager::GetInstance().GetAggresiveCreature(attackNode.m_dwDefenser[0]); if (0 != lpTargetCreature) { if (lpTargetCreature->GetMapIndex() != GetMapIndex()) { lpTargetCreature = 0; } } } } else { lpTargetCreature = CCreatureManager::GetInstance().GetAggresiveCreature(attackNode.m_dwDefenser[0]); } // Target Creature ó¸®Çϱâ if (0 != 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) { eSkillTargetType = pThisSkill[attackType.m_cSkillLockCount].m_eTargetType; cTargetType = Skill::Target::FRIEND; } } // Ŭ¶óÀÌ¾ðÆ®°¡ ³Ñ°ÜÁØ Å¸°ÙµéÀ» üũÇÑ´Ù. (¹üÀ§ ¸¶¹ý¿¡ °É¸®´Â Ÿ°ÙÀº µû·Î üũ) for (unsigned char cDefender = 0; cDefender < cDefenderNum; ++cDefender) { // Target Creature ¾ò±â CAggresiveCreature* lpCreature = 0; if (0 != GetMapIndex()) { Creature::CreatureType eCreatureType = Creature::GetCreatureType(attackNode.m_dwDefenser[cDefender]); if (Creature::CT_MONSTER == eCreatureType || Creature::CT_SUMMON == eCreatureType || Creature::CT_STRUCT == eCreatureType) { VirtualArea::CVirtualArea* lpVirtualArea = VirtualArea::CVirtualAreaMgr::GetInstance().GetVirtualArea(GetMapIndex()); if (0 != lpVirtualArea) { CVirtualMonsterMgr* lpVirtualMonsterMgr = lpVirtualArea->GetMonsterManager(); if (0 != lpVirtualMonsterMgr) { lpCreature = lpVirtualMonsterMgr->GetAggresiveCreature(attackNode.m_dwDefenser[cDefender]); } } } else { lpCreature = CCreatureManager::GetInstance().GetAggresiveCreature(attackNode.m_dwDefenser[cDefender]); if (lpCreature && lpCreature->GetMapIndex() != GetMapIndex()) { lpCreature = 0; } } } else { lpCreature = CCreatureManager::GetInstance().GetAggresiveCreature(attackNode.m_dwDefenser[cDefender]); } if (0 != lpCreature) { // ±àÁ¤ÀûÀÎ °ø°Ý(-_-) if (Skill::Target::FRIEND == cTargetType) { if (Creature::CT_PC == Creature::GetCreatureType(lpCreature->GetCID())) { CCharacter *lpCharacter = reinterpret_cast(lpCreature); if (true == lpCharacter->GetEnchantInfo().GetFlag(Skill::SpellID::Hide)) { continue; } if (false == lpCharacter->IsPeaceMode() && true == IsPeaceMode()) { wError = PktAtAck::FAIL_PEACE_TO_WAR; return false; } if (lpCharacter->GetCellPos().m_lpCell) { if (lpCharacter->GetCellPos().m_lpCell->IsDetectionCell() && Skill::IsStealthSkill(attackType.m_wType)) { wError = PktAtAck::FAIL_NOT_STEALTH; return false; } } } else if (Creature::CT_SIEGE_OBJECT == Creature::GetCreatureType(lpCreature->GetCID())) { wError = PktAtAck::FAIL_TO_SIEGE_OBJECT; return false; } else { CMonster *lpMonster = reinterpret_cast(lpCreature); if (lpMonster->GetPattern() == MonsterInfo::PATTERN_STRUCTURE) { continue; } } EnemyCheck::EnemyType eEnemyType = IsEnemy(lpCreature); switch (eSkillTargetType) { case Skill::Target::FRIEND: case Skill::Target::FRIEND_EXCEPT_SELF: case Skill::Target::DEAD_FRIEND: { if (EnemyCheck::EC_FRIEND == eEnemyType) { lpAggresiveCreature[cDefender] = lpCreature; } } break; case Skill::Target::PARTY: { if (EnemyCheck::EC_FRIEND == eEnemyType) { if (NULL != GetParty() && NULL != lpCreature->GetParty() && GetParty()->GetUID() == lpCreature->GetParty()->GetUID()) { lpAggresiveCreature[cDefender] = lpCreature; } else if (GetGID() == lpCreature->GetGID()) { if (NULL == GetParty() || (NULL != GetParty() && NULL == reinterpret_cast(GetParty())->GetHostileParty())) { // Vincent : ±æµå°£ ÆÀ ¹èƲ ÁßÀ϶§¸¸À» Ã¼Å©ÇØ¾ßÇÑ´Ù. // if ( ±æµå°£ ÆÀ ¹èƲ Áß ) lpAggresiveCreature[cDefender] = lpCreature; } } } } break; } } // ºÎÁ¤ÀûÀÎ °ø°Ý(ÁøÂ¥ °ø°Ý) else { // Àڱ⸦ Áß½ÉÀ¸·Î ÇÏ´Â ¹üÀ§Çü ½ºÅ³ÀÇ °æ¿ì Ÿ°ÙÀ» ÀÚ½ÅÀ¸·Î ¼¼ÆÃÇÕ´Ï´Ù. // (ÀÌ °æ¿ì this´Â MultiAttack() ÇÔ¼ö°¡ ŸÄÏ¿¡¼­ Á¦¿Ü½ÃÄÑ ÁÝ´Ï´Ù.) if (EnemyCheck::EC_ENEMY == IsEnemy(lpCreature) || lpCreature == this) { lpAggresiveCreature[cDefender] = lpCreature; } } } } if (0 != (attackType.m_wType & AtType::SKILL_BIT)) { if (0 == cDefenderNum || 0 == lpAggresiveCreature[0]) { return Attack(attackType, cDefenderNum, lpAggresiveCreature, attackNode.m_cDefenserJudge, wDefenderMPHeal); } const Skill::ProtoType* pSkillProtoType = CSkillMgr::GetInstance().GetSkillProtoType(attackType.m_wType); if (0 == pSkillProtoType) { ERRLOG2(g_Log, "CID:0x%08x Á¸ÀçÇÏÁö ¾Ê´Â ½ºÅ³ ¾ÆÀ̵ðÀÔ´Ï´Ù. Skill ID:0x%04x", m_dwCID, attackType.m_wType); return false; } // ¹üÀ§ ¸¶¹ý üũ if (0 != pSkillProtoType[attackType.m_cSkillLockCount].m_fEffectExtent) { if (Skill::Target::PARTY == pSkillProtoType[attackType.m_cSkillLockCount].m_eTargetType) { CParty* lpParty = lpAggresiveCreature[0]->GetParty(); if (0 != lpParty) { return lpParty->Attack(attackType, lpAggresiveCreature, attackNode.m_cDefenserJudge, this, pSkillProtoType[attackType.m_cSkillLockCount].m_fEffectExtent, cTargetType); } } else { return MultiAttack(attackType, cDefenderNum, lpAggresiveCreature, attackNode.m_cDefenserJudge, lpAggresiveCreature[0]->GetCurrentPos(), 0, pSkillProtoType[attackType.m_cSkillLockCount].m_fEffectExtent, Math::Const::PI * 2, cTargetType); } } } return Attack(attackType, cDefenderNum, lpAggresiveCreature, attackNode.m_cDefenserJudge, wDefenderMPHeal); } bool CCharacter::Attack(AtType attackType, unsigned char cDefenderNum, CAggresiveCreature** ppDefenders, unsigned char* cDefenserJudges, unsigned short* wDefenderMPHeal) { if (0 == (attackType.m_wType & AtType::SKILL_BIT) && 0 == cDefenderNum) { ERRLOG0(g_Log, "½ºÅ³ÀÌ ¾Æ´Ñ ÀÏ¹Ý °ø°ÝÀº, ¹Ýµå½Ã Ÿ°ÙÀÌ ÀÖÀ» °æ¿ì¿¡¸¸ ¼­¹ö·Î º¸³»¾ß ÇÕ´Ï´Ù."); return false; } bool bBrokenCounter = true; bool bBrokenStealth = true; bool bCheckDeadTarget = true; // ½ºÅ³ »ç¿ë½ÃÀÇ ¿¹¿Ü ó¸® if (0 != (attackType.m_wType & AtType::SKILL_BIT)) { const Skill::ProtoType* pSkillProtoType = CSkillMgr::GetInstance().GetSkillProtoType(attackType.m_wType); if (0 == pSkillProtoType) { ERRLOG2(g_Log, "CID:0x%08x Á¸ÀçÇÏÁö ¾Ê´Â ½ºÅ³ ¾ÆÀ̵ðÀÔ´Ï´Ù. Skill ID:0x%04x", m_dwCID, attackType.m_wType); return false; } // æƮ »ç¿ë½Ã¿¡´Â Ä«¿îÅÍ ¾îÅðú ½ºÅÚ½º°¡ Ç®¸®Áö ¾Ê´Â´Ù. if (Skill::Type::CHANT == pSkillProtoType->m_eSkillType) { bBrokenCounter = false; bBrokenStealth = false; } else { // Ä«¿îÅÍ ¾îÅÃÀÌ Ç®¸®Áö ¾Ê´Â À¯Çü (Ä«¿îÅÍ ¾îÅÃ) if (0x8605 == attackType.m_wType) { bBrokenCounter = false; } // °íÁ¤ÀûÀ¸·Î ½ºÅÚ½º°¡ Ç®¸®Áö ¾Ê´Â À¯Çü(½ºÅÚ½º, ij¸ðÇöóÁã, ´Ïµé½ºÇÍ, ´ë°ÅÆÄÀ̾î, ¹ã ¼Â) if (0x8704 == attackType.m_wType || 0x8805 == attackType.m_wType || 0x9504 == attackType.m_wType || 0x9804 == attackType.m_wType || 0x8205 == attackType.m_wType || 0x9805 == attackType.m_wType || 0x8707 == attackType.m_wType) { bBrokenStealth = false; } // È®·üÀûÀ¸·Î ½ºÅÚ½º°¡ Ç®¸®Áö ¾Ê´Â À¯Çü(¹éº», ¿îÁî ºí·¡½ºÆ®) //if (0x8702 == attackType.m_wType) //{ // CAggresiveCreature* lpMySelf = reinterpret_cast(CCreatureManager::GetInstance().GetCreature(m_dwCID)); // if (4 == lpMySelf->GetSkillLockCount(0x8704)) // { // unsigned char cSuccessRate = static_cast(20 + (attackType.m_cSkillLevel * 5)); // if (cSuccessRate > Math::Random::ComplexRandom(100)) // { // bBrokenStealth = false; // } // } //} //if (0x9802 == attackType.m_wType) //{ // CAggresiveCreature* lpMySelf = reinterpret_cast(CCreatureManager::GetInstance().GetCreature(m_dwCID)); // if (4 == lpMySelf->GetSkillLockCount(0x9804)) // { // unsigned char cSuccessRate = static_cast(20 + (attackType.m_cSkillLevel * 5)); // if (cSuccessRate > Math::Random::ComplexRandom(100)) // { // bBrokenStealth = false; // } // } //} if (0x8702 == attackType.m_wType || 0x9802 == attackType.m_wType) { CSpell* pSpell = m_SpellMgr.GetAffectedInfo().GetSpell(Skill::SpellID::Stealth); if (NULL != pSpell) { if (4 <= pSpell->GetSkillLockCount()) { unsigned char cSuccessRate = 20 + (pSpell->GetSkillLevel() * 5); if (cSuccessRate > Math::Random::ComplexRandom(100)) { bBrokenStealth = false; } } } } } // Á×Àº Ÿ°Ù¿¡°Ô ¾µ ¼ö ÀÖ´Â ½ºÅ³ if (Skill::Target::DEAD_FRIEND == pSkillProtoType->m_eTargetType || Skill::Target::DEAD_ENEMY == pSkillProtoType->m_eTargetType) { bCheckDeadTarget = false; } } unsigned char cOffencerJudge = 0; unsigned short wOffencerMPHeal = 0; unsigned short wOffencerPrevHP = GetStatus().m_nNowHP; unsigned short wOffencerPrevMP = GetStatus().m_nNowMP; 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 nMonsterDefenderNum = 0; unsigned char cDefender = 0; unsigned char cIndex = 0; for (; cIndex < cDefenderNum; ++cIndex) { // MP ¼Ò¸ð ŸÀֱ̹îÁöÀÇ Ä«¿îÆ® (¹üÀ§ ¸¶¹ýÀº ÇÑ ¹ø¸¸ MP ¼Ò¸ð) --m_cConsumeMPCount; if (0 == ppDefenders[cIndex]) { continue; } if (true == bCheckDeadTarget && 0 == ppDefenders[cIndex]->GetStatus().m_nNowHP) { continue; } // ÃÖ´ë ¹æ¾îÀÚ ¼ö Á¦ÇÑ (¸ó½ºÅʹ ij¸¯ÅͿʹ º°µµ ó¸®) Creature::CreatureType eCreatureType = Creature::GetCreatureType(ppDefenders[cIndex]->GetCID()); if (Creature::CT_MONSTER == eCreatureType || Creature::CT_SUMMON == eCreatureType || Creature::CT_STRUCT == eCreatureType) { nMonsterDefenderNum++; if (nMonsterDefenderNum > AtNode::MAX_MONSTER_DEFENDER_NUM) { continue; } } // ij¸¯ÅÍ ÀÏ¹Ý °ø°Ý½Ã °Å¸® üũ if (0 == (attackType.m_wType & AtType::SKILL_BIT)) { const Position& targetPos = ppDefenders[cIndex]->GetCurrentPos(); float fSquareTargetDistance = (m_CurrentPos.m_fPointX - targetPos.m_fPointX) * (m_CurrentPos.m_fPointX - targetPos.m_fPointX) + (m_CurrentPos.m_fPointZ - targetPos.m_fPointZ) * (m_CurrentPos.m_fPointZ - targetPos.m_fPointZ); // ±ÙÁ¢ °ø°Ý if (AtType::RIGHT_MELEE == attackType.m_wType || AtType::LEFT_MELEE == attackType.m_wType) { if (fSquareTargetDistance > MELEE_ATTACK_RANGE * MELEE_ATTACK_RANGE) { // edith 2008.07.11 ±ÙÁ¢°ø°Ý °Å¸® Á¦ÇÑ ·Î±× Á¦¿Ü. // ERRLOG2(g_Log, "CID:%10u ±ÙÁ¢ °ø°ÝÀ¸·Î ³Ê¹« ¸Ö¸® Àִ Ÿ°ÙÀ» °ø°ÝÇÏ·Á ÇÕ´Ï´Ù. °Å¸®:%.2f(m)", // m_dwCID, fSquareTargetDistance); continue; } } // ¿ø°Å¸® °ø°Ý else if (AtType::BOW == attackType.m_wType || AtType::CROSSBOW == attackType.m_wType) { if (fSquareTargetDistance > RANGE_ATTACK_RANGE * RANGE_ATTACK_RANGE) { ERRLOG2(g_Log, "CID:%10u ¿ø°Å¸® °ø°ÝÀ¸·Î ³Ê¹« ¸Ö¸® Àִ Ÿ°ÙÀ» °ø°ÝÇÏ·Á ÇÕ´Ï´Ù. °Å¸®:%.2f(m)", m_dwCID, fSquareTargetDistance); continue; } } } // TODO : °ø°Ý ¹æÇâÀ» ¼³Á¤ÇØÁݽôÙ. cDefenserJudges[cDefender] = ClientConstants::Judge_Front; wDefenderMPHeal[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, wDefenderMPHeal[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 (0 != lpSummonee) { lpSummonee->GuardMe(this, lpDefenserNode[cDefender].m_wDamage); } if(ClientConstants::Judge_Chant == cDefenserJudges[cDefender] && lpDefenserNode[cDefender].m_wDamage == 0) { // edith 2009.06.20 ¸¶³ªºÎÁ·½Ã æƮ»ç¿ëÇÏ¸é µ¥¹ÌÁö0ÁÖ°í ÀåºñÀÇ ³»±¸µµ¸¦ ±ï´Â ¹ö±× // æƮ ½ºÅ³ÀÌ°í µ¥¹ÌÁö°¡ 0À϶§ ³»±¸µµ¸¦ ´Þ°ÔÇÏÁö ¾Ê´Â´Ù. } else { lpDefendCharacter->CalculateEquipDurability((ClientConstants::Judge_Guard == cDefenserJudges[cDefender]) ? AtType::GUARD : AtType::DEFENCE); } CGameClientDispatch* lpDispatch = lpDefendCharacter->GetDispatcher(); if (0 != lpDispatch) { GameClientSendPacket::SendCharAttacked(lpDispatch->GetSendStream(), this, lpDefendCharacter, attackType, m_MotionInfo.m_fDirection, lpDefenserNode[cDefender].m_wDamage, cDefenserJudges[cDefender], wDefenderMPHeal[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 = wDefenderMPHeal[cDefender]; lpDefenserNode[cDefender].m_cJudge = cDefenserJudges[cDefender]; } ++cDefender; } // -------------------------------------------------------------------------------------- // °ø°Ý½Ã Ç®¸®´Â ÀÎæƮµé m_SpellMgr.GetAffectedInfo().RemoveEnchantBySpellType(Skill::SpellID::Invincible); if (true == bBrokenCounter) { m_SpellMgr.GetAffectedInfo().RemoveEnchantBySpellType(Skill::SpellID::CounterAttack); } if (true == bBrokenStealth) { CSpell* pSpell = m_SpellMgr.GetAffectedInfo().GetSpell(Skill::SpellID::Stealth); if (NULL != pSpell) { if (4 <= pSpell->GetSkillLockCount()) { m_SpellMgr.GetCastingInfo().ClearChant();; } } m_SpellMgr.GetAffectedInfo().RemoveEnchantBySpellType(Skill::SpellID::Stealth); } // -------------------------------------------------------------------------------------- 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 (0 != m_lpGameClientDispatch) { CSendStream& SendStream = m_lpGameClientDispatch->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 (0 != lpCell) { lpCell->SendAttackInfo(m_dwCID, attackType, cDefender, lpDefenserNode); } // °ø°ÝÀÚ°¡ ÈúÀ̳ª ¸¶³ªÈúÀÏ °æ¿ì °ø°ÝÀÚÀÇ Èú¸µ Á¤º¸µµ AttackInfo ·Î º¸³»ÁØ´Ù. if (ClientConstants::Judge_Heal == cOffencerJudge || ClientConstants::Judge_ManaHeal == cOffencerJudge) { if (0 != lpCell) { DefenserNode node; node.m_dwCharID = m_dwCID; node.m_wMaxHP = GetStatus().m_StatusInfo.m_nMaxHP; node.m_wMaxMP = GetStatus().m_StatusInfo.m_nMaxMP; node.m_sCurrHP = GetStatus().m_nNowHP; node.m_sCurrMP = GetStatus().m_nNowMP; node.m_wMPHeal = wOffencerMPHeal; node.m_wDamage = 0; node.m_cJudge = cOffencerJudge; if (ClientConstants::Judge_Heal == cOffencerJudge && node.m_sCurrHP > wOffencerPrevHP) { node.m_wDamage = node.m_sCurrHP - wOffencerPrevHP; } else if (ClientConstants::Judge_ManaHeal == cOffencerJudge) { node.m_wDamage = wOffencerMPHeal; } lpCell->SendAttackInfo(m_dwCID, attackType, 1, &node); } } return true; } } return false; } bool CCharacter::Dead(CAggresiveCreature* pOffencer) { if (0 != m_lpSummonee) { m_lpSummonee->Dead(0); } // ¼º¹®À» ¸·°í ÀÖ´ø ÁßÀ̾ú´Ù¸é... ¼º¹® ¸·±â¸¦ Ãë¼ÒÇÑ´Ù. if (0 != m_dwProtectGateCID) { CCastleGate* lpGate = reinterpret_cast( CSiegeObjectMgr::GetInstance().GetSiegeObject(m_dwProtectGateCID) ); if (lpGate) { lpGate->DeleteProtectGate(this); // Ŭ¶óÀÌ¾ðÆ®¿¡°Ô Àü¼Û CGameClientDispatch* lpDispatch = GetDispatcher(); if (0 != lpDispatch) { GameClientSendPacket::SendCharCastleCmd(lpDispatch->GetSendStream(), lpGate->GetCastleID(), lpGate->GetCID(), 0, 0, PktCastleCmd::CASTLE_GATE_PROTECT_CANCEL, PktCastleCmd::NO_SERVER_ERR); } } } if (0 != pOffencer) { if (0 != pOffencer->GetMapIndex()) { VirtualArea::CVirtualArea* lpVirtualArea = VirtualArea::CVirtualAreaMgr::GetInstance().GetVirtualArea(pOffencer->GetMapIndex()); if (lpVirtualArea) { CVirtualMonsterMgr* lpVirtualMonsterMgr = lpVirtualArea->GetMonsterManager(); if (lpVirtualMonsterMgr && true == lpVirtualMonsterMgr->IsSummonee(pOffencer->GetCID())) { CSummonMonster* lpSummonee = reinterpret_cast(pOffencer); pOffencer = lpSummonee->GetMaster(); } } } else { if (true == CCreatureManager::GetInstance().IsSummonee(pOffencer->GetCID())) { CSummonMonster* lpSummonee = reinterpret_cast(pOffencer); pOffencer = lpSummonee->GetMaster(); } } } GAMELOG::ERRType eReturnCode = 0; __int64 dwPrevExp = m_CreatureStatus.m_nExp; m_FightInfo.m_nRestoreExp = 0; if (0 != pOffencer) { switch (Creature::GetCreatureType(pOffencer->GetCID())) { case Creature::CT_MONSTER: case Creature::CT_STRUCT: m_eLastDeadType = DEAD_BY_MONSTER; break; case Creature::CT_PC: case Creature::CT_SUMMON: m_eLastDeadType = DEAD_BY_CHARACTER; if (EnemyCheck::EC_ENEMY == IsEnemy(pOffencer)) { CalculateFame(reinterpret_cast(pOffencer)); // ¹èƲ ±×¶ó¿îµå ¼­¹öÀÇ °æ¿ì Flag ÀüÀ϶§ Á¡¼ö¸¦ ó¸®ÇØÁØ´Ù. (°°Àº Á¾Á· µà¾óÀ϶§´Â Á¦¿Ü) if (0 != pOffencer && pOffencer->GetMapIndex() != 0) { CCharacter* lpOffencerChar = reinterpret_cast(pOffencer); if (GetRace() != lpOffencerChar->GetRace()) { VirtualArea::CVirtualArea* lpVirtualArea = VirtualArea::CVirtualAreaMgr::GetInstance().GetVirtualArea(pOffencer->GetMapIndex()); if (0 != lpVirtualArea && lpVirtualArea->GetVirtualType() == VirtualArea::BGSERVERMAP) { VirtualArea::CBGServerMap* lpBGServerMap = reinterpret_cast(lpVirtualArea); if (VirtualArea::FRAG == lpBGServerMap->GetMapType()) { lpBGServerMap->KillChar(GetCID(), lpOffencerChar); // ·Î±× ³²±â±â DETLOG10(g_Log, "Battle Server Log :: (Channel : %d, %s) - " "CID : 0x%08x ij¸¯ÅÍ(%s, %s)°¡ CID : 0x%08x ij¸¯ÅÍ(%s, %s)¸¦ Á׿´½À´Ï´Ù. (ÇöÀç Score - HM: %d AK: %d)", (lpBGServerMap->GetMapIndex() & ~VirtualArea::BGSERVERMAP), lpBGServerMap->GetMapTypeName(), lpOffencerChar->GetCID(), lpOffencerChar->GetCharacterName(), (lpOffencerChar->GetRace() == CClass::HUMAN) ? "HUMAN" : "AKHAN", GetCID(), GetCharacterName(), (GetRace() == CClass::HUMAN) ? "HUMAN" : "AKHAN", lpBGServerMap->GetMapInfo().m_wScore[CClass::HUMAN], lpBGServerMap->GetMapInfo().m_wScore[CClass::AKHAN]); } } } } } break; } } else { m_eLastDeadType = DEAD_BY_SUICIDE; } DuelInit(PktDuC::DUC_DEAD); GAMELOG::LogCharDead(*this, dwPrevExp, m_CreatureStatus.m_nExp, pOffencer, m_CreatureStatus.m_nLevel, eReturnCode); // ij¸¯ÅÍ¿¡ ÇöÁ¦ °É·ÁÀÖ´Â ½ºÆçµéÁß ¿µ±¸ÀûÀ¸·Î Àû¿ëµÇ¾ß ÇÒ ½ºÆçµéÀ» ÀúÀåÇÑ´Ù. const SPELL spell = m_SpellMgr.GetAffectedInfo().GetSpellInfo(TRUE); SetSpell(spell); SetDead(TRUE); m_SpellMgr.GetAffectedInfo().Disenchant(Skill::SpellType::NONE, Skill::SpellTarget::ALL_ENCHANT, Skill::Disenchant::DEAD, 1, Skill::Disenchant::INFINITE_NUM); m_SpellMgr.GetAffectedInfo().Disenchant(Skill::SpellType::ETERNAL_SPELL, Skill::SpellTarget::ALL_ENCHANT, Skill::Disenchant::NONE, 1, Skill::Disenchant::INFINITE_NUM); // ij½ºÆÃ °ü·Ã ÀÎæÀ» Ŭ¸®¾î ÇÑ´Ù. m_SpellMgr.GetCastingInfo().ClearEnchant(); m_SpellMgr.GetCastingInfo().ClearChant(); // À̺κÐÀº Á×¾úÀ»´ë ½ºÅ³À» ÀÎæƮ ½ÃŰ´Â °ÍÀÌ´Ï »«´Ù. // CAggresiveCreature::Dead(pOffencer); if (0 != GetParty()) { // ÆÄƼ¿ø »ç¸ÁÀ» ¾Ë¸°´Ù. GameClientSendPacket::SendCharDeadToParty( this, pOffencer, PktDeadInfo::DEAD); } return (0 == eReturnCode); } void CCharacter::SaveSpell(BOOL bDead) { // ij¸¯ÅÍ¿¡ ÇöÁ¦ °É·ÁÀÖ´Â ½ºÆçµéÁß ¿µ±¸ÀûÀ¸·Î Àû¿ëµÇ¾ß ÇÒ ½ºÆçµéÀ» ÀúÀåÇÑ´Ù. const SPELL spell = m_SpellMgr.GetAffectedInfo().GetSpellInfo(bDead); SetSpell(spell); } bool CCharacter::Respawn(unsigned char cType, const Position& Pos) { Position newPos; // Á×Àº »óŰ¡ ¾Æ´Ñµ¥ ¸®½ºÆùÀ» Çϸé. ½ºÆçÀ» ÀúÀåÇØ³õ°í Àç»ç¿ëÀ» ÇÑ´Ù. if(!IsDead()) { // ij¸¯ÅÍ¿¡ ÇöÁ¦ °É·ÁÀÖ´Â ½ºÆçµéÁß ¿µ±¸ÀûÀ¸·Î Àû¿ëµÇ¾ß ÇÒ ½ºÆçµéÀ» ÀúÀåÇÑ´Ù. const SPELL spell = m_SpellMgr.GetAffectedInfo().GetSpellInfo(); SetSpell(spell); } SetDead(FALSE); // edith 2009.08.26 ¸®½ºÆù ¸Þ´ÏÁ®¿¡¼­ ij¸¯ÅÍ »èÁ¦ µ¿±âÈ­¸¦ À§ÇØ Å¸¿î¾ÆÀ̵𸦠ÃʱâÈ­ÇÔ. // ÀÌ·¸°Ô Ÿ¿î ¾ÆÀ̵𰡠ÃʱâÈ­ µÇ¾ú´Ù¸é ¸®½ºÆù ÇÁ·Î½ÃÁ®¿¡¼­ ¹«½ÃÇÑ´Ù. SetRespawnTownID(0); if (0 == Pos.m_fPointX && 0 == Pos.m_fPointY && 0 == Pos.m_fPointZ) { newPos = CCharRespawnMgr::GetInstance().GetDefaultRespawnPos(GetNation()); m_DBData.m_Pos.LastPoint.fPointX = newPos.m_fPointX; m_DBData.m_Pos.LastPoint.fPointY = newPos.m_fPointY; m_DBData.m_Pos.LastPoint.fPointZ = newPos.m_fPointZ; } else { newPos = Pos; } if (0 == CCellManager::GetInstance().GetCell(m_CellPos.m_wMapIndex, Pos.PositionToPOS())) { ERRLOG1(g_Log, "CID : 0x%08x, ¼¿ ¹üÀ§ ¹Û¿¡¼­ ¸®½ºÆùÇÏ¿´½À´Ï´Ù. ij¸¯ÅÍ Ãʱ⠻ý¼º À§Ä¡·Î ¿öÇÁ½Ãŵ´Ï´Ù.", m_dwCID); if (0 != GetMapIndex()) { VirtualArea::CVirtualArea* lpVirtualArea = VirtualArea::CVirtualAreaMgr::GetInstance().GetVirtualArea(GetMapIndex()); if (lpVirtualArea) { m_CurrentPos = lpVirtualArea->GetRespawnPosition( GetRace(), Math::Random::ComplexRandom( lpVirtualArea->GetMaxRespawnPos() ) ); } } else { m_CurrentPos = CCharRespawnMgr::GetInstance().GetDefaultRespawnPos(GetNation()); } m_DBData.m_Pos.LastPoint.fPointX = newPos.m_fPointX; m_DBData.m_Pos.LastPoint.fPointY = newPos.m_fPointY; m_DBData.m_Pos.LastPoint.fPointZ = newPos.m_fPointZ; } __int64 dwPrevExp = m_CreatureStatus.m_nExp; // 1. ÇöÁ¦ °É¸° ¸ðµç ÀÎæƮ¸¦ ¾ø¿¡¹ö¸°´Ù. // ij¸¯ÅͰ¡ Á×¾úÀ»¶§ ÀÎæƮ°¡ ³²¾ÆÀ־ Ŭ¶óÀÌ¾ðÆ®¿¡¼­ ¸ðµç ÀÎæƮ ÀÌÆåÆ®¸¦ Á¦°ÅÇϱ⠶§¹®¿¡ ¸ðµç ÀÎæƮ¸¦ Á¦°ÅÇß´Ù ´Ù½Ã°Ç´Ù. m_SpellMgr.GetAffectedInfo().Disenchant(Skill::SpellType::NONE, Skill::SpellTarget::ALL_ENCHANT, Skill::Disenchant::NONE, 1, Skill::Disenchant::INFINITE_NUM); m_SpellMgr.GetAffectedInfo().Disenchant(Skill::SpellType::ETERNAL_SPELL, Skill::SpellTarget::ALL_ENCHANT, Skill::Disenchant::NONE, 1, Skill::Disenchant::INFINITE_NUM); m_SpellMgr.GetCastingInfo().ClearEnchant(); // Chant´Â, ³»°¡ °Ç ½ºÅ³¸¸ DisableÇÑ´Ù. ( ³ª¿¡°Ô °É¸°°Ç ±»ÀÌ DisableÇÒ ÇÊ¿ä ¾ø´Ù. ) m_SpellMgr.GetCastingInfo().ClearChant(); // edith 2008.06.03 ¼®»ó ÀÎþƮȿ°ú if (SERVER_ID::STONE_WAR1 <= CServerSetup::GetInstance().GetServerZone() && CServerSetup::GetInstance().GetServerZone() <= SERVER_ID::STONE_WAR3) { bool bAddRealmStatueEnchant = false; if (true == CServerSetup::GetInstance().UseContents(GameRYL::STONE_BATTLE)) { // ±¹°¡ ÀüÀï ½Ã°£ÀÌ ¾Æ´Ï¶ó¸é, ¼®»ó ÀÎæƮ È¿°ú¸¦ °É¾îÁØ´Ù. if (!CGameTimeMgr::GetInstance().IsRealmWarTime()) { bAddRealmStatueEnchant = true; } } /* // edith 2008.07.17 ¼®»óÀü¿ë Á¸°ú °ø¼ºÀü¿ë Á¸ÀÌ ³ª´²Á³±â ¶§¹®¿¡ ÇØ´ç ·ÎÁ÷ÀÌ ÇÊ¿ä¾ø´Ù. if (true == CServerSetup::GetInstance().UseContents(GameRYL::SIEGE)) { // °ø¼ºÀü ÄÁÅÙÃ÷ Æ÷ÇԽà °ø¼ºÀü ½Ã°£µµ ¾Æ´Ï¶ó¸é, ¼®»ó ÀÎæƮ È¿°ú¸¦ °É¾îÁØ´Ù. if (CGameTimeMgr::GetInstance().IsSiegeWarTime()) { bAddRealmStatueEnchant = false; } } */ /* // ¼®»ó ÀÎæƮ È¿°ú¸¦ Àû¿ëÇÒ ¼ö ÀÖ´Â »óȲÀ̶ó¸é.... if (bAddRealmStatueEnchant) { // edith 2008.06.03 ¼®»óÀüÀÌ ³¡³¯¶§ 11½Ã°£ ¹öÇÁ¸¦ °É¾îÁØ´Ù. CCreatureManager::GetInstance().AddRealmStatueEnchant(this); } */ // ±¹°¡ÀüÀï °øÇåÈÆÀå Æ÷ÀÎÆ® È¿°ú. if (CGameTimeMgr::GetInstance().IsRealmWarTime() && (SERVER_ID::STONE_WAR1 <= CServerSetup::GetInstance().GetServerZone() && CServerSetup::GetInstance().GetServerZone() <= SERVER_ID::STONE_WAR3)) { RealmSkill::RealmInchantAdd(this); } } // edith 2009.06.13 16¹ø Á¸ / 17¹ø Á¸¿¡¼­ ¹«Àû½Ã°£ Á¶Á¤ int InvincibleTime = 30; if (SERVER_ID::STONE_WAR1 <= CServerSetup::GetInstance().GetServerZone() && CServerSetup::GetInstance().GetServerZone() <= SERVER_ID::STONE_WAR3) InvincibleTime = 15; switch (cType) { case CCharRespawnMgr::RST_RESURRECTION : // ·¹Àú·º¼ÇÀ¸·Î ºÎȰ if (0 == m_CreatureStatus.m_nNowHP) { m_CreatureStatus.m_nNowHP = m_CreatureStatus.m_StatusInfo.m_nMaxHP * RESURRECTION_RECOVERY_PERCENTAGE / 100; m_CreatureStatus.m_nNowMP = m_CreatureStatus.m_StatusInfo.m_nMaxMP * RESURRECTION_RECOVERY_PERCENTAGE / 100; m_CreatureStatus.m_nExp += m_FightInfo.m_nRestoreExp; m_FightInfo.m_nRestoreExp = 0; } break; case CCharRespawnMgr::RST_BATTLE : // ¹èƲ ·ÎÇÑ¿¡¼­ ¸®½ºÆù ½Ã if (0 == m_CreatureStatus.m_nNowHP) { m_CreatureStatus.m_nNowHP = m_CreatureStatus.m_StatusInfo.m_nMaxHP; m_CreatureStatus.m_nNowMP = m_CreatureStatus.m_StatusInfo.m_nMaxMP; } if (!CServerSetup::GetInstance().IsBattleGameServer()) { // 30Ãʰ£ ¹«Àû Skill::CAddSpell( CSpell::Spell_Info(Skill::CProcessTable::ProcessInfo::m_NullProtoType, this, Skill::SpellType::MAGICAL_SPELL, Skill::SpellID::Invincible, 1, InvincibleTime))(this); } break; case CCharRespawnMgr::RST_TOWN : // Áװųª Æ÷Å» ÀÌ¿ëÀ¸·Î ¸¶À»¿¡¼­ ºÎȰ (ÀϹÝÀûÀÎ ¸®½ºÆù) if (0 == m_CreatureStatus.m_nNowHP) { m_CreatureStatus.m_nNowHP = m_CreatureStatus.m_StatusInfo.m_nMaxHP * TOWN_RECOVERY_PERCENTAGE / 100; m_CreatureStatus.m_nNowMP = m_CreatureStatus.m_StatusInfo.m_nMaxMP * TOWN_RECOVERY_PERCENTAGE / 100; if (!CServerSetup::GetInstance().IsBattleGameServer()) { // 30Ãʰ£ ¹«Àû Skill::CAddSpell( CSpell::Spell_Info(Skill::CProcessTable::ProcessInfo::m_NullProtoType, this, Skill::SpellType::MAGICAL_SPELL, Skill::SpellID::Invincible, 1, InvincibleTime))(this); } } break; case CCharRespawnMgr::RST_FORTRESS : // Áװųª Æ÷Å» ÀÌ¿ëÀ¸·Î ¿ä»õ³ª ¼º¿¡¼­ ºÎȰ if (0 == m_CreatureStatus.m_nNowHP) { m_CreatureStatus.m_nNowHP = m_CreatureStatus.m_StatusInfo.m_nMaxHP * FORTRESS_RECOVERY_PERCENTAGE / 100; m_CreatureStatus.m_nNowMP = m_CreatureStatus.m_StatusInfo.m_nMaxMP * FORTRESS_RECOVERY_PERCENTAGE / 100; if (!CServerSetup::GetInstance().IsBattleGameServer()) { // 30Ãʰ£ ¹«Àû Skill::CAddSpell( CSpell::Spell_Info(Skill::CProcessTable::ProcessInfo::m_NullProtoType, this, Skill::SpellType::MAGICAL_SPELL, Skill::SpellID::Invincible, 1, InvincibleTime))(this); } } break; } // edith 2008.07.08 ¹èƲ±×¶ó¿îµå¼­¹ö¿¡¼­ Á×À¸¸é ¿¡³ÊÁö ÃÖ´ë·Î.. if (SERVER_ID::STONE_WAR1 <= CServerSetup::GetInstance().GetServerZone() && CServerSetup::GetInstance().GetServerZone() <= SERVER_ID::STONE_WAR3) { // ³ªÁß¿¡ 30Ãʰ£ ¹«Àû °É·Á¸é °ÉÀÚ. m_CreatureStatus.m_nNowHP = m_CreatureStatus.m_StatusInfo.m_nMaxHP; m_CreatureStatus.m_nNowMP = m_CreatureStatus.m_StatusInfo.m_nMaxMP; } if (0 != m_lpGameClientDispatch) { CSendStream& SendStream = m_lpGameClientDispatch->GetSendStream(); char* lpBuffer = SendStream.GetBuffer(sizeof(PktRsAck)); if (0 != lpBuffer) { PktRsAck* lpPktRsAck = reinterpret_cast(lpBuffer); lpPktRsAck->m_dwCharID = m_dwCID; lpPktRsAck->m_Position = newPos.PositionToPOS(); lpPktRsAck->m_wHP = m_CreatureStatus.m_nNowHP; lpPktRsAck->m_wMP = m_CreatureStatus.m_nNowMP; lpPktRsAck->m_dlExp = m_CreatureStatus.m_nExp; lpPktRsAck->m_dwGold = m_DBData.m_Info.Gold; SendStream.WrapCrypt(sizeof(PktRsAck), CmdCharRespawn, 0, 0); } } // 2. ij¸¯ÅͰ¡ Á×¾úÀ»¶§ ÀúÀåÇØµÐ ÀÎæƮ¸¦ ´Ù½Ã°Ç´Ù. // ij¸¯ÅͰ¡ Á×¾úÀ»¶§ ÀÎæƮ°¡ ³²¾ÆÀ־ Ŭ¶óÀÌ¾ðÆ®¿¡¼­ ¸ðµç ÀÎæƮ ÀÌÆåÆ®¸¦ Á¦°ÅÇϱ⠶§¹®¿¡ ¸ðµç ÀÎæƮ¸¦ Á¦°ÅÇß´Ù ´Ù½Ã°Ç´Ù. const SPELL spell = GetSpell(); m_SpellMgr.SetSpell(spell); // ¼®»óÀüÀÌ ³¡³­ ´ÙÀ½¿¡ ¸®½ºÆùÀ» ÇßÀ¸¸é ¹öÇÁ¸¦ ´Ù½Ã °É¾îÁØ´Ù. if(IsRealmWarBuffer()) CCreatureManager::GetInstance().AddRealmStatueEnchant(this); SetRealmWarBuffer(FALSE); if (cType != CCharRespawnMgr::RST_RESURRECTION) { switch(m_eLastDeadType) { case DEAD_BY_NONE: // ¿Ã ¼ö ¾øÀ½ case DEAD_BY_CHARACTER: // ij¸¯ÅÍ¿¡ ÀÇÇØ »ç¸Á break; case DEAD_BY_SUICIDE: // ÀÚ»ì // ÀÚ»ì½Ã ³»±¸µµ °¨¼Ò CalculateAllEquipDurability(DURABILITY_DECREASE_PERSENT_BY_SUICIDE); break; case DEAD_BY_MONSTER: // ¸ó½ºÅÍ¿¡ ÀÇÇØ »ç¸Á if (!CServerSetup::GetInstance().GetDeathPenaltyEvent()) { unsigned char cDecreasePersent = 0; if(m_AbilityValue[Skill::Type::AB_ENDUR_SHILD] != 0) cDecreasePersent = DURABILITY_DECREASE_PERSENT_BY_MONSTER*m_AbilityValue[Skill::Type::AB_ENDUR_SHILD]/100; // ¸ó½ºÅÍ¿¡°Ô Á×¾úÀ» ¶§ ³»±¸µµ °¨¼Ò CalculateAllEquipDurability(DURABILITY_DECREASE_PERSENT_BY_MONSTER-cDecreasePersent); } break; } } // ´Ù½Ã »ì¾Æ³µÀ¸´Ï, »ç¸Á ŸÀÔÀ» NONEÀ¸·Î ÃʱâÈ­ÇÑ´Ù m_eLastDeadType = DEAD_BY_NONE; // ij¸¯ÅÍ ¸®½ºÆù ·Î±× GAMELOG::LogCharRespawn(*this, dwPrevExp, m_CreatureStatus.m_nExp, 0); return true; } // ¹èƲ ±×¶ó¿îµå¿¡¼­ Ãʱ⠷¹º§ Á¸À¸·Î ÀÚµ¿ ¸®½ºÆù ½ÃÄÑÁÖ´Â ÇÔ¼ö bool CCharacter::AutoRespawn() { if (SERVER_ID::ZONE3 == CServerSetup::GetInstance().GetServerZone()) { // ¸®½ºÆù ÁÂÇ¥ const POS respawnPos[CClass::MAX_RACE] = { { 1403.06f, 18.25f, 1958.41f }, { 2014.29f, 63.50f, 1648.47f } }; // ÀÚµ¿À¸·Î °¢ÀÚÀÇ Ãʱ⠷¾ Á¸À¸·Î À̵¿½ÃŲ´Ù. unsigned char cZone = SERVER_ID::NONE; switch (GetRace()) { case CClass::HUMAN: cZone = SERVER_ID::ZONE1; break; case CClass::AKHAN: cZone = SERVER_ID::ZONE2; break; default: ERRLOG2(g_Log, "CID:0x%08x ij¸¯ÅÍÀÇ ±¹°¡°¡ ÀÌ»óÇÕ´Ï´Ù. ±¹°¡:%d", GetCID(), GetRace()); return false; } GetStatus().m_nNowHP = GetStatus().m_StatusInfo.m_nMaxHP; GetStatus().m_nNowMP = GetStatus().m_StatusInfo.m_nMaxMP; SetDead(FALSE); // ä³ÎÀÌ 2°³ ÀÌ»ó ÀÖ´Â °æ¿ì ä³ÎâÀ» ¶ç¿öÁÖ°í Á¸À̵¿Àº µÇÁö ¾Ê½À´Ï´Ù. // ÀÌ °æ¿ì ä³ÎâÀ» ¶ç¿ö³õ°í ¹öƼ¸é ¸í¼ºÀ» ¾òÀ» ¼öµµ ÀÖÀ¸¹Ç·Î 1ä³Î·Î °­Á¦ À̵¿½ÃŰ°Ô ¼öÁ¤ÇÏ¿´½À´Ï´Ù. (2004-09-17 by ·Îµò) if (false == MoveZone(respawnPos[ GetRace() ], cZone, 0)) { ERRLOG1(g_Log, "CID:0x%08x ¹èƲ±×¶ó¿îµå Å»Ãâ¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù.", GetCID()); return false; } return true; } return false; } bool CCharacter::AttackUsingBow(unsigned short wType) { Item::CEquipment* lpEquipment = m_Equipments.GetLeftHand(); if (0 == lpEquipment) { return true; } switch (wType) { case AtType::BOW: case AtType::CROSSBOW: { if (wType == AtType::BOW && lpEquipment->GetItemInfo().m_DetailData.m_cItemType != Item::ItemType::ARROW) { return false; } if (wType == AtType::CROSSBOW && lpEquipment->GetItemInfo().m_DetailData.m_cItemType != Item::ItemType::BOLT) { return false; } if (false == UseAmmo(reinterpret_cast(lpEquipment))) { ERRLOG1(g_Log, "CID:0x%08x È­»ì(º¼Æ®) »ç¿ë¿¡ ½ÇÆÐÇÏ¿´½À´Ï´Ù.", m_dwCID); return false; } if (0 != m_lpGameClientDispatch) { GameClientSendPacket::SendCharEquipDurability(m_lpGameClientDispatch->GetSendStream(), m_dwCID, lpEquipment->GetPos().m_cIndex, lpEquipment->GetNumOrDurability(), 0, PktBase::NO_SERVER_ERR); } } break; default: { if (lpEquipment->GetItemInfo().m_DetailData.m_cItemType == Item::ItemType::ARROW || lpEquipment->GetItemInfo().m_DetailData.m_cItemType == Item::ItemType::BOLT) { return false; } } break; } if (0 == lpEquipment->GetNumOrDurability() && true == lpEquipment->IsSet(Item::DetailData::STACKABLE)) { CalculateStatusData(false); if (false == m_Equipments.RemoveItem(lpEquipment->GetPos())) { ERRLOG1(g_Log, "CID:0x%08x ½ºÅà ¾ÆÀÌÅÛÀ» Àåºñ¿¡¼­ Áö¿ì´Â µ¥ ½ÇÆÐÇß½À´Ï´Ù.", m_dwCID); } } return true; } bool CCharacter::UseAmmo(Item::CUseItem* pUseItem) { using namespace Item::ItemType; // ¾Ë¸ÂÀº Á¾·ùÀÇ ÅºÈ¯ÀÎÁö üũ switch (pUseItem->GetItemInfo().m_DetailData.m_cItemType) { case ARROW: { // È­»ì Item::CEquipment* pUsingWeapon = m_Equipments.GetRightHand(); if (0 == pUsingWeapon) { return false; } if (pUsingWeapon->GetItemInfo().m_DetailData.m_cItemType != BOW) { return false; } pUseItem->SetNumOrDurability(pUseItem->GetNumOrDurability() - 1); } break; case BOLT: { // º¼Æ® Item::CEquipment* pUsingWeapon = m_Equipments.GetRightHand(); if (0 == pUsingWeapon) { return false; } if (pUsingWeapon->GetItemInfo().m_DetailData.m_cItemType != CROSSBOW) { return false; } pUseItem->SetNumOrDurability(pUseItem->GetNumOrDurability() - 1); } break; case AMMO: { // źȯ Item::CEquipment* lpSkillArm = m_Equipments.GetLeftHand(); if (0 == lpSkillArm) { return false; } if (lpSkillArm->GetItemInfo().m_DetailData.m_cItemType != SKILL_A_GUN) { return false; } } break; } return true; } bool CCharacter::IsPeaceMode(void) { // MichaelBless ÀϽà Çǽº¸ðµå·Î ¼³Á¤ // ½ÅÀÇ ´ëÁö¿¡ ÀÖÀ¸¸é ÆòÈ­ ¸ðµå if (SERVER_ID::ZONE12 == CServerSetup::GetInstance().GetServerZone()) { if(GetEnchantInfo().GetFlag(Skill::SpellID::MichaelBless)) return true; } /* // ½ÅÀÇ ´ëÁö¿¡ ÀÖÀ¸¸é ÆòÈ­ ¸ðµå if (SERVER_ID::ZONE12 == CServerSetup::GetInstance().GetServerZone()) { return true; } */ /* if (true == CServerSetup::GetInstance().UseContents(GameRYL::STONE_BATTLE)) { // Ä«³ª¹ø¿¡ ÀÖ´õ¶óµµ ±æµåÀü ½Ã°£ÀÌ ¾Æ´Ï¶ó¸é ÆòÈ­ ¸ðµå if (SERVER_ID::CAPITAL == CServerSetup::GetInstance().GetServerZone() && !CGameTimeMgr::GetInstance().IsGuildWarTime()) { return true; } } */ CGuild* lpGuild = CGuildMgr::GetInstance().GetGuild(GetGID()); if (NULL != lpGuild) { if (Guild::JOIN_WAIT != lpGuild->GetTitle(m_dwCID)) { return lpGuild->IsPeaceMode(); } } return false; } char CCharacter::GetEliteBonus(void) { EliteBonus::EliteBonusData eliteBonus = CCreatureManager::GetInstance().GetEliteBonus(); char cBonus = eliteBonus.m_cLevel * ((GetRace() == eliteBonus.m_cNation) ? 1 : (-1)); // Áß·¾Á¸ º¸È£Ã¥ const char cServerZone = CServerSetup::GetInstance().GetServerZone(); if ((Creature::KARTERANT == GetNation() && SERVER_ID::ZONE5 == cServerZone) || (Creature::MERKADIA == GetNation() && SERVER_ID::ZONE4 == cServerZone)) { cBonus -= 7; } // ¸í¼º¿¡ µû¸¥ ó¸® cBonus += GetCaste(); if (cBonus > EliteBonus::MAX_BONUS_LEVEL) { return EliteBonus::MAX_BONUS_LEVEL; } if (cBonus < EliteBonus::MAX_BONUS_LEVEL * (-1)) { return EliteBonus::MAX_BONUS_LEVEL * (-1); } return cBonus; } char CCharacter::GetCaste(void) { if (m_DBData.m_Info.Fame <= 2000) { return 0; } if (m_DBData.m_Info.Fame <= 10000) { return 1; } if (m_DBData.m_Info.Fame <= 25000) { return 2; } if (m_DBData.m_Info.Fame <= 50000) { return 3; } if (m_DBData.m_Info.Fame <= 75000) { return 4; } if (m_DBData.m_Info.Fame <= 100000) { return 5; } if (m_DBData.m_Info.Fame <= 150000) { return 6; } if (m_DBData.m_Info.Fame <= 250000) { return 7; } if (m_DBData.m_Info.Fame <= 500000) { return 8; } return 9; } void CCharacter::CalculateFame(CCharacter* lpWinnerCharacter) { CGameClientDispatch* lpDispatch = 0; CCharacter* lpLoserCharacter = reinterpret_cast(this); unsigned char cWinnerCmd = PktFIAck::FAME_WIN; unsigned char cLoserCmd = PktFIAck::FAME_LOSE; // ¹Ð¾îÁֱ⠹æÁö (¹Ì±¹ÀÇ Åä³Ê¸ÕÆ® ¼­¹ö±º¿¡¼­´Â PvP½ÃÀÇ ¸í¼º ¾îºä¡ ¹æÁöÃ¥ÀÌ °­È­µÈ´Ù.) const unsigned long dwLimitFame = 1000; if (0 == lpLoserCharacter->GetFame() && dwLimitFame <= lpWinnerCharacter->GetFame()) { cWinnerCmd = PktFIAck::FAME_WIN_LARGE_GAP; } // ¿¬»ç ¹æÁö if (true == lpLoserCharacter->GetThreat().SaveEnemy(lpWinnerCharacter->GetCID())) { cWinnerCmd = PktFIAck::FAME_WIN_CONTINUE; cLoserCmd = PktFIAck::FAME_LOSE_CONTINUE; } else { GET_SINGLE_DISPATCH(lpDBAgentDispatch, CDBAgentDispatch, CDBAgentDispatch::GetDispatchTable()); if(lpDBAgentDispatch) { CSendStream& SendStream = lpDBAgentDispatch->GetSendStream(); char* lpBuffer = SendStream.GetBuffer(sizeof(PktSaveEnemy)); if(lpBuffer) { PktSaveEnemy* lpPktSaveEnemy = reinterpret_cast(lpBuffer); lpPktSaveEnemy->m_dwCID = m_dwCID; lpPktSaveEnemy->m_dwAttackedCID = lpWinnerCharacter->GetCID(); lpPktSaveEnemy->m_dwTick = 0; if(!SendStream.WrapCrypt(sizeof(PktSaveEnemy), CmdSaveEnemy, 0, 0)) { ERRLOG1(g_Log, "CID:0x%08x ¿¬»ç ¹æÁö ÆÐŶÀ» º¸³»Áö ¸øÇß½À´Ï´Ù.", m_dwCID); } } } } // edith 2009.07.16 ±æµåÀüÀ϶© °°Àº Á¾Á·ÀÌ´õ¶óµµ Á×ÀÌ¸é ¸í¼ÍÀ» ¹Þ°ÔÇÑ´Ù. if (SERVER_ID::CAPITAL == CServerSetup::GetInstance().GetServerZone()) { // ±æµå ÀüÀï ½Ã°£À̸é if(CGameTimeMgr::GetInstance().IsGuildWarTime()) { // ¹«½ÃÇÑ´Ù. } else { // edith 2008.08.18 °°Àº Á¾Á·ÀÌ¸é ¹«½ÃÇÑ´Ù. ¿¬»ç ¹× ±âŸ »óȲÀ» ¹«½Ã if(lpWinnerCharacter->GetRace() == lpLoserCharacter->GetRace()) { cWinnerCmd = PktFIAck::FAME_INFO; cLoserCmd = PktFIAck::FAME_INFO; } } } else { // edith 2008.08.18 °°Àº Á¾Á·ÀÌ¸é ¹«½ÃÇÑ´Ù. ¿¬»ç ¹× ±âŸ »óȲÀ» ¹«½Ã if(lpWinnerCharacter->GetRace() == lpLoserCharacter->GetRace()) { cWinnerCmd = PktFIAck::FAME_INFO; cLoserCmd = PktFIAck::FAME_INFO; } } // µà¾ó »óÅ if (lpLoserCharacter->GetDuelOpponent() == lpWinnerCharacter) { cWinnerCmd = PktFIAck::FAME_WIN_DUEL; cLoserCmd = PktFIAck::FAME_LOSE_DUEL; } // ÆÀ¹èƲ »óÅ CCharacterParty* lpLoserParty = reinterpret_cast(lpLoserCharacter->GetParty()); CCharacterParty* lpWinnerParty = reinterpret_cast(lpWinnerCharacter->GetParty()); if (NULL != lpLoserParty && NULL != lpWinnerParty) { if (lpLoserParty->GetHostileParty() == lpWinnerParty) { cWinnerCmd = PktFIAck::FAME_WIN_DUEL; cLoserCmd = PktFIAck::FAME_LOSE_DUEL; } } // edith 2009.12.26 ·¹º§ 20ÀÌ»óÀ̸é Á×¾úÀ»¶§ ¸í¼ºÃ³¸®¸¦ ÇÏÁö ¾Ê´Â´Ù. // ¸¸¾à ½ÂÀÚ¿Í ÆÐÀÚÀÇ ·¹º§ÀÌ 20·¡º§ÀÌ ³ÑÀ¸¸é ¸í¼ºÃ³¸®¸¦ ÇÏÁö ¾Ê´Â´Ù if (NULL == lpWinnerParty) { int iLevelGap = lpWinnerCharacter->GetLevel() - lpLoserCharacter->GetLevel(); if(iLevelGap >= 20) { cWinnerCmd = PktFIAck::FAME_WIN_LEVELMIN; cLoserCmd = PktFIAck::FAME_LOSE_LEVELMIN; } } GAMELOG::ERRType eReturnCode = 0; // ----------------------------------------------------------------------------------------------------- // ÀÒÀ» ¶§ÀÇ ±ÔÄ¢ if (PktFIAck::FAME_LOSE == cLoserCmd) { unsigned long dwPrevFame = lpLoserCharacter->GetFame(); unsigned long lReduceFame = std::min(static_cast(10), lpLoserCharacter->GetFame()); unsigned long dwNextFame = dwPrevFame - lReduceFame; lpLoserCharacter->SetFame(dwNextFame); GAMELOG::LogFameLoseBattle(*lpLoserCharacter, lpWinnerCharacter, lpLoserParty, dwPrevFame, dwNextFame, eReturnCode); CCharacterParty* lpLoserParty = reinterpret_cast(lpLoserCharacter->GetParty()); if (NULL != lpLoserParty) { lpLoserParty->SendDivisionFame(lpWinnerCharacter, lpLoserCharacter, cLoserCmd, 0); } } lpDispatch = lpLoserCharacter->GetDispatcher(); if (NULL != lpDispatch) { GameClientSendPacket::SendCharFameInfo(lpDispatch->GetSendStream(), lpLoserCharacter, lpWinnerCharacter->GetCharacterName(), lpLoserCharacter->GetCharacterName(), lpWinnerCharacter->GetNation(), static_cast(lpWinnerCharacter->GetClass()), cLoserCmd, PktBase::NO_SERVER_ERR); } // ----------------------------------------------------------------------------------------------------- // ¾òÀ» ¶§ÀÇ ±ÔÄ¢ unsigned long dwAcquireAmount = 10; // ÆÄƼ°¡ ¾Æ´Ò¶§ if (NULL == lpWinnerParty) { unsigned long dwPrevFame = 0; unsigned long dwNextFame = 0; unsigned long dwPrevMileage = 0; unsigned long dwNextMileage = 0; if (PktFIAck::FAME_WIN == cWinnerCmd) { // ¸í¼º¿¡ ´ëÇÑ Ã³¸® dwPrevFame = lpWinnerCharacter->GetFame(); unsigned long dwGetFame = std::min(dwAcquireAmount * static_cast(CServerSetup::GetInstance().GetFameDefault() / 100.0f), UINT_MAX - lpWinnerCharacter->GetFame()); dwNextFame = dwPrevFame + dwGetFame; lpWinnerCharacter->SetFame(dwNextFame); } if (PktFIAck::FAME_WIN == cWinnerCmd || PktFIAck::FAME_WIN_LEVELMIN == cWinnerCmd ) { // ¸Þ´Þ¿¡ ´ëÇÑ Ã³¸® dwPrevMileage = lpWinnerCharacter->GetMileage(); dwNextMileage = dwPrevMileage; // edith 2009.06.27 ¸Þ´ÞÀº ¼®»óÀü, ±æµåÀü¿¡¼­ ÀûÀ» Á×À϶§¸¸ ¾ò´Â´Ù. if (SERVER_ID::CAPITAL == CServerSetup::GetInstance().GetServerZone()) { // ±æµå ÀüÀï ½Ã°£À̸é if (CGameTimeMgr::GetInstance().IsGuildWarTime()) { unsigned long dwGetMileage = std::min(dwAcquireAmount * static_cast(CServerSetup::GetInstance().GetMileageDefault() / 100.0f), UINT_MAX - lpWinnerCharacter->GetMileage()); dwNextMileage = dwPrevMileage + dwGetMileage; } } else if (SERVER_ID::STONE_WAR1 <= CServerSetup::GetInstance().GetServerZone() && CServerSetup::GetInstance().GetServerZone() <= SERVER_ID::STONE_WAR3) { // ±¹°¡ ÀüÀï ½Ã°£À̸é if (CGameTimeMgr::GetInstance().IsRealmWarTime()) { unsigned long dwGetMileage = std::min(dwAcquireAmount * static_cast(CServerSetup::GetInstance().GetMileageDefault() / 100.0f), UINT_MAX - lpWinnerCharacter->GetMileage()); dwNextMileage = dwPrevMileage + dwGetMileage; } } lpWinnerCharacter->SetMileage(dwNextMileage); GAMELOG::LogFameGetBattle(*lpWinnerCharacter, lpLoserCharacter, lpWinnerParty, dwPrevFame, dwNextFame, dwPrevMileage, dwNextMileage, eReturnCode); } lpDispatch = lpWinnerCharacter->GetDispatcher(); if (NULL != lpDispatch) { GameClientSendPacket::SendCharFameInfo(lpDispatch->GetSendStream(), lpWinnerCharacter, lpWinnerCharacter->GetCharacterName(), lpLoserCharacter->GetCharacterName(), lpLoserCharacter->GetNation(), (unsigned char)lpLoserCharacter->GetClass(), cWinnerCmd, PktBase::NO_SERVER_ERR); } } else { // ÆÄƼÀ϶§ lpWinnerParty->SendDivisionFame(lpWinnerCharacter, lpLoserCharacter, cWinnerCmd, static_cast(dwAcquireAmount)); } } void BattleInclination::SetCharData(CCreature& creature, BattleInclination::CharData& charData, bool bSetRideArmsInfo) { charData.m_dwCID = creature.GetCID(); // ij¸¯ÅÍ CID charData.m_dwGID = creature.GetGID(); // ij¸¯ÅÍ GID charData.m_dwCastleID = 0; // °ø¼º º´±âÀÎ °æ¿ì, ¼ÓÇÑ ¼ºÀÇ ID¸¦ ³ÖÀ½. charData.m_cNation = creature.GetNation(); // ij¸¯ÅÍ ±¹Àû charData.m_cSiegeState = 0; // °ø¼º º´±âÀÎ °æ¿ì, °ø¼º º´±â »óŸ¦ ³ÖÀ½. charData.m_cFlags = 0; // ±âŸ Á¤º¸ charData.m_cAdminLevel = 0; charData.m_dwPID = 0; charData.m_wObjectType = 0; charData.m_wKind = 0; charData.m_cCreatureType = Creature::GetCreatureType(creature.GetCID()); charData.m_cRealmWarFlag = 0; charData.m_cGuildWarFlag = 0; charData.m_cTacticsFlag = 0; charData.m_cRide = creature.IsRideArms(); // ±æµå °¡ÀÔ ´ë±âÀÚ´Â GID ¿¡ 0 À» ³ÖÀ½. Guild::CGuild* lpGuild = Guild::CGuildMgr::GetInstance().GetGuild( charData.m_dwGID ); if ( lpGuild ) { if(Creature::GetCreatureType(charData.m_dwCID)==Creature::CT_PC) { CCharacter& character = static_cast(creature); unsigned char cTacticsFlag = character.GetTacticsFlag(); if (Guild::JOIN_WAIT == lpGuild->GetTitle( charData.m_dwCID )) { charData.m_dwGID = 0; } charData.m_cTacticsFlag = cTacticsFlag; } } CParty* lpParty = creature.GetParty(); if (lpParty) { charData.m_dwPID = lpParty->GetUID(); } charData.SetPeaceMode(creature.IsPeaceMode()); charData.SetSafetyZone(CCellManager::GetInstance().IsSafetyZone(creature.GetCurrentPos())); charData.SetGODMode(creature.GetEnchantInfo().GetFlag(Skill::SpellID::Invincible)); bool bHasDevelopingCamp, bHasCompleteCamp; CSiegeObjectMgr::GetInstance().HasCampByGID(charData.m_dwGID, bHasDevelopingCamp, bHasCompleteCamp); charData.SetHasDevelopingCamp(bHasDevelopingCamp); charData.SetHasCamp(bHasCompleteCamp); switch (Creature::GetCreatureType(charData.m_dwCID)) { case Creature::CT_SIEGE_OBJECT: { CSiegeObject& siegeObject = static_cast(creature); charData.m_dwGID = siegeObject.GetGID(); charData.SetCastleObject(siegeObject.IsCastleObject()); charData.SetCastleNPC(siegeObject.IsCastleNPC()); charData.m_dwCastleID = siegeObject.GetCastleID(); charData.m_cSiegeState = siegeObject.GetState(); charData.m_wObjectType = siegeObject.GetObjectType(); // ±æµå ¿ä»õ´Â ¹«Á¶°Ç ±æµåÀü Âü¿©ÁßÀÎ »óÅÂÀÌ´Ù. charData.m_cGuildWarFlag = Creature::WAR_ON ; } break; case Creature::CT_PC: { CCharacter& character = static_cast(creature); charData.m_cAdminLevel = character.GetAdminLevel(); charData.m_cRealmWarFlag = character.GetRealmWarFlag(); charData.m_cGuildWarFlag = character.GetGuildWarFlag(); // ÆÀ¹èƲ ¼¼ÆÃ (ÃßÈÄ ±æµå°£ ¹èƲÀÌ Ãß°¡µÇ¸é ¼öÁ¤ ÇÊ¿ä) if (NULL != character.GetParty()) { if (NULL != reinterpret_cast(character.GetParty())->GetHostileParty()) { charData.SetTeamBattle(true); } } if(bSetRideArmsInfo && character.IsRideArms()) { CSiegeObject* lpSiegeObject = CSiegeObjectMgr::GetInstance().GetSiegeObject(character.GetRideArmsCID()); if(lpSiegeObject) { charData.m_dwGID = lpSiegeObject->GetGID(); charData.SetCastleObject(lpSiegeObject->IsCastleObject()); charData.SetCastleNPC(lpSiegeObject->IsCastleNPC()); charData.m_dwCastleID = lpSiegeObject->GetCastleID(); charData.m_cSiegeState = lpSiegeObject->GetState(); charData.m_wObjectType = lpSiegeObject->GetObjectType(); } } } break; case Creature::CT_MONSTER: case Creature::CT_SUMMON: case Creature::CT_STRUCT: { CMonster& monster = static_cast(creature); charData.m_wKind = monster.GetKID(); } break; } } void BattleInclination::SetRelationData(CCreature& ownerCreature, CCreature& targetCreature, BattleInclination::RelationData& relationData) { relationData.m_cVSFlag = 0; relationData.m_bHostileGuild = false; if (Creature::CT_PC == Creature::GetCreatureType(ownerCreature.GetCID()) && Creature::CT_PC == Creature::GetCreatureType(targetCreature.GetCID())) { CCharacter& ownerCharacter = static_cast(ownerCreature); CCharacter& targetCharacter = static_cast(targetCreature); if (NULL != ownerCharacter.GetDuelOpponent()) { if (ownerCharacter.GetDuelOpponent()->GetCID() == targetCharacter.GetCID()) { relationData.m_cVSFlag |= BattleInclination::VS_CHARACTER; } } if (NULL != ownerCharacter.GetParty() && NULL != targetCharacter.GetParty()) { CCharacterParty* lpHostileParty = reinterpret_cast(ownerCharacter.GetParty())->GetHostileParty(); if (NULL != lpHostileParty) { if (lpHostileParty->GetUID() == targetCharacter.GetParty()->GetUID()) { relationData.m_cVSFlag |= BattleInclination::VS_PARTY; } } } } // Rodin : ±æµå°£ ¹èƲ Á¤º¸ Guild::CGuild* lpGuild = Guild::CGuildMgr::GetInstance().GetGuild(ownerCreature.GetGID()); if (NULL != lpGuild) { if (true == lpGuild->IsEnemyGuild(targetCreature.GetGID())) { relationData.m_bHostileGuild = true; } } lpGuild = Guild::CGuildMgr::GetInstance().GetGuild(targetCreature.GetGID()); if (NULL != lpGuild) { if (true == lpGuild->IsEnemyGuild(ownerCreature.GetGID())) { relationData.m_bHostileGuild = true; } } } EnemyCheck::EnemyType CCharacter::IsEnemy(CCreature* lpTarget, unsigned char* lpResult) { if (NULL == lpTarget) { ERRLOG1(g_Log, "CID:0x%08x ÇǾƽĺ°ÇÒ Å¸°ÙÀÌ ¾ø½À´Ï´Ù.", m_dwCID); return EnemyCheck::EC_NEUTRAL; } BattleInclination::CharData ownerInfo; BattleInclination::CharData targetInfo; BattleInclination::SetCharData(*this, ownerInfo); BattleInclination::SetCharData(*lpTarget, targetInfo); BattleInclination::RelationData relationInfo; BattleInclination::SetRelationData(*this, *lpTarget, relationInfo); unsigned char cResultFromStruct = 0; unsigned long dwResult = EnemyCheck::CCheckTable::GetInstance().IsEnemyFromStruct( ownerInfo, targetInfo, relationInfo, cResultFromStruct); if (NULL != lpResult) { *lpResult = cResultFromStruct; } return static_cast(dwResult); } void CCharacter::SendAttackedToParty(unsigned long dwAttackerID, AtType atType, unsigned short wDamage, unsigned char cDefenserJudge, unsigned short wMPHeal) { if (0 != m_pParty) { bool bLastSendTimeCheck = true; if(atType.m_wType & AtType::SKILL_BIT) { // (ÀϹݰø°ÝÀ̳ª Ÿ°Ù ŸÀÔÀÌ Enemy, MeleeÀÎ ½ºÅ³À» ¹ÞÀº °æ¿ì - ½Ã°£ üũ) // Friend, Frexme, Frdead, Party ½Ã°£ üũ ÇÏÁö ¾ÊÀ½. const Skill::ProtoType* lpProtoType = CSkillMgr::GetInstance().GetSkillProtoType(atType.m_wType); if(0 != lpProtoType) { switch(lpProtoType[atType.m_cSkillLockCount].m_eTargetType) { case Skill::Target::FRIEND: case Skill::Target::FRIEND_EXCEPT_SELF: case Skill::Target::DEAD_FRIEND: case Skill::Target::PARTY: bLastSendTimeCheck = false; break; } } } unsigned long dwCurrentTime = 0; if(!bLastSendTimeCheck || 500 <= (dwCurrentTime = timeGetTime()) - m_dwLastSendPartyAttackInfoTime) { m_dwLastSendPartyAttackInfoTime = dwCurrentTime; CCharacterParty* lpParty = static_cast(m_pParty); if(!lpParty) { return; } const int MAX_BUFFER = sizeof(PktAtAck) + sizeof(DefenserNode); char szPacket[MAX_BUFFER]; unsigned short wPacketSize = sizeof(PktAtInfo) + sizeof(DefenserNode); PktAtInfo* lpPktAtInfo = reinterpret_cast(szPacket); DefenserNode* lpDefenserNode = reinterpret_cast(lpPktAtInfo + 1); lpPktAtInfo->m_dwCharID = dwAttackerID; lpPktAtInfo->m_AtType = atType; lpPktAtInfo->m_cDefenserNum = 1; lpDefenserNode->m_dwCharID = m_dwCID; // ¹æ¾îÀÚ Ä³¸¯ÅÍ ¾ÆÀ̵ð lpDefenserNode->m_wMaxHP = m_CreatureStatus.m_StatusInfo.m_nMaxHP; // ÃÖ´ë HP lpDefenserNode->m_sCurrHP = m_CreatureStatus.m_nNowHP; // ÇöÀç HP lpDefenserNode->m_wMaxMP = m_CreatureStatus.m_StatusInfo.m_nMaxMP; // ÃÖ´ë MP lpDefenserNode->m_sCurrMP = m_CreatureStatus.m_nNowMP; // ÇöÀç MP lpDefenserNode->m_wMPHeal = wMPHeal; // MP ȸº¹·® lpDefenserNode->m_wDamage = wDamage; // µ¥¹ÌÁö °ª lpDefenserNode->m_cJudge = cDefenserJudge; // ÆÇÁ¤ °ª if (PacketWrap::WrapCrypt(szPacket, wPacketSize, CmdCharAttackInfo, 0, 0)) { // ÁÖº¯ ¼¿¿¡´Â °¡±â ¶§¹®¿¡, ¸Ö¸® ¶³¾îÁø ÆÄƼ ¸â¹ö¿¡°Ô¸¸ º¸³»¸é µÈ´Ù. lpParty->SendNotNearCellMember(szPacket, wPacketSize, m_CellPos.m_lpCell, CmdCharAttackInfo); } } } } void CCharacter::SkillClear() { CAffectedSpell& cAffectedInfo = m_SpellMgr.GetAffectedInfo(); cAffectedInfo.ClearAll(); CCastingSpell& cCastingInfo = m_SpellMgr.GetCastingInfo(); cCastingInfo.ClearAll(); }