#include "stdafx.h" #include "Monster.h" #include "GameField.h" #include "IdleState.h" #include "WanderState.h" #include "TrackState.h" #include "AttackState.h" #include "HelpState.h" #include "DeadState.h" #include "ThrustState.h" #include "JumpState.h" #include "FallApartState.h" #include "ReturnState.h" #include "RetreatState.h" #include "FlyingState.h" #include "KnockDownState.h" #include "RunAwayState.h" #include "ChaosState.h" #include "Map.h" #include "GameZone.h" #include "GameRoom.h" #include "GameParty.h" #include "GamePartyManager.h" #include "StatusManager.h" #include "CharacterFormula.h" #include "AIParamParser.h" #include "DropManager.h" #include "NPCStateManager.h" #include "PatrolState.h" #include "TargetManager.h" #include "FatigueManager.h" #include "ItemExpDistributor.h" #include "QuestManager_Concrete.h" #include #include "Player.h" #include "GameServerEx.h" #include #include "..\\.\\SolarTrigger\\TriggerMsg.h" #include "TriggerManagerEx.h" #ifdef _NA_007065_20140217_CHAOSZONE_GOLDRUSH #include "World/ChaosZoneSystem/ChaosZoneManager.h" #endif //_NA_007065_20140217_CHAOSZONE_GOLDRUSH #include "MonsterBookParser.h" //_NA_007086_20140318_MONSTERBOOK //-------------------------------------------------------------------------------------------------- Monster::Monster() : m_bSummoned(FALSE) , m_LiveIdle( util::SimpleTimer() ) { SetObjectType( MONSTER_OBJECT ); } //-------------------------------------------------------------------------------------------------- Monster::~Monster() { } //-------------------------------------------------------------------------------------------------- BOOL Monster::Init() { WzVector wzVec = { 0, 0, 0 }; SetRegenPos( wzVec ); return NPC::Init(); } //-------------------------------------------------------------------------------------------------- void Monster::InitMonster( WORD NPCCode, BYTE byMoveType, DWORD dwMoveAreaID ) { this->Init(); m_LinkedAction = AppliedNpcDependencyChain::Instance()->GetNpcLinkAction( NPCCode, MONSTER_OBJECT ); NPC::SetBaseInfo( NPCCode, byMoveType, dwMoveAreaID ); } //-------------------------------------------------------------------------------------------------- VOID Monster::Release() { NPC::Release(); } //-------------------------------------------------------------------------------------------------- BOOL Monster::Update( DWORD dwDeltaTick ) { if( m_bSummoned && m_LiveIdle.IsExpired() ) { OnDead(); } return NPC::Update( dwDeltaTick ); } //-------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------- // ¹æÈ² ¹üÀ§ BOOL Monster::IsOutOfWanderRadius() { if( Policyment.FIELD & Policyment.PCC_IN_SSQ_FIELD ) return FALSE; float fDistToRegenPos = GetDist2( m_RegenPos ); // TODO: ¿ì¼± ÀÚ½ÅÀÌ ¸®Á¨µÈ °÷À¸·ÎºÎÅÍ 50m ¶³¾îÁö¸é ¸®Á¨¿µ¿ªÀ» ¹þ¾î³­ °ÍÀ¸·Î ÇÑ´Ù. AI_TYPE_INFO* pAITypeInfo = AIParamParser::Instance()->GetTypeInfo(GetBaseInfo()->m_wAICode); if( fDistToRegenPos > pAITypeInfo->m_fWANDER_RADIUS_FROM_REGENAREA*pAITypeInfo->m_fWANDER_RADIUS_FROM_REGENAREA ) { return TRUE; } return FALSE; } //-------------------------------------------------------------------------------------------------- // À̰Ŵ ½Î¿ì´Ù¸»°í ¹«Á¶°Ç µ¹¾Æ°¡°Ô µÇ´Â ÃÖ´ë ¿µ¿ª BOOL Monster::IsOutOfRegenLocationLimit( WzVector &vTargetPos ) { if( Policyment.FIELD & Policyment.PCC_IN_SSQ_FIELD ) return FALSE; // 50m¸¦ ¹þ¾î³ª¸é ¹«Á¶°Ç µ¹¾Æ°£´Ù. float fDistToRegenPos = GetDist2( m_RegenPos ); AI_TYPE_INFO* pAITypeInfo = AIParamParser::Instance()->GetTypeInfo(GetBaseInfo()->m_wAICode); if( fDistToRegenPos > pAITypeInfo->m_fREGEN_LOCATION_LIMIT*pAITypeInfo->m_fREGEN_LOCATION_LIMIT ) return TRUE; #ifdef _NA_003649_20111115_BATTLE_ZONE_HARDMODE // ³ôÀÌ Á¦ÇÑ Ã¼Å© float fHeightDiff = fabs( GetHeightDiff( m_RegenPos ) ); if( fHeightDiff > pAITypeInfo->m_fMOVE_HEIGHT_LIMIT ) return TRUE; #else AI_COMMON_INFO& stAICommonInfo = AIParamParser::Instance()->GetCommonInfo(); if( !stAICommonInfo.m_fMOVE_HEIGHT_LIMIT ) return FALSE; // ³ôÀÌ Á¦ÇÑ Ã¼Å© float fHeightDiff = fabs( GetHeightDiff( m_RegenPos ) ); if( fHeightDiff > stAICommonInfo.m_fMOVE_HEIGHT_LIMIT ) return TRUE; #endif //_NA_003649_20111115_BATTLE_ZONE_HARDMODE return FALSE; } //-------------------------------------------------------------------------------------------------- VOID Monster::OnDead() { if( !GetField() ) return; if( m_bSummoned && !m_LiveIdle.GetExpireTime() ) { m_bSummoned = 0; NPC::OnDead(); return; } // Á¸À¸·Î À̺¥Æ® Àü´Þ if( GetGameZonePtr() ) GetGameZonePtr()->OnKillMonster( this ); ////////////////////////////////////////////////////////////////////////// // (WAVERIX)(THINKING) // - SSQ¿¡¼­´Â ¸ó½ºÅÍ Á×À» ½Ã ±âÁ¸°ú´Â ´Ù¸¥ 󸮸¦ ¿ä±¸ÇÑ´Ù... // ¿©±â¼­ ¿¹¿Ü󸮸¦ Çϱ⠺¸´Ù´Â Monster»ó¼ÓÀÌ ³ªÀ» °ÍÀÌ´Ù. // - ÃÖ´ëÇÑ Monster¿Í µ¿ÀÏÇÑ Äڵ带 »ç¿ëÇϱâ À§ÇØ °´Ã¼ ŸÀÔ¿¡ ´ëÇØ // // // - SSQMonster -> Monster ////////////////////////////////////////////////////////////////////////// // Á×Àº ÈÄ¿¡ º¯½ÅÀ» ÇÒ °æ¿ì °æÇèÄ¡³ª ¾ÆÀÌÅÛÀ» ÁÖÁö ¾Ê´Â´Ù. const BOOL bTransform = IsSpecialAction( eNPC_SPECIAL_ACTION_TRANSFORMATION ); // °æÇèÄ¡, ¾ÆÀÌÅÛ¿¡ ´ëÇÑ ¼ÒÀ¯±ÇÀÚ¸¦ ±¸ÇÑ´Ù.(¾ÆÀÌÅÛÀº Player¸¸ ¸ÔÁö¸¸ °æÇèÄ¡´Â ÆêÀ̳ª ¿ëº´ÀÌ ¸ÔÀ»Áöµµ ¸ð¸¥´Ù...) Character* pExpOwner = g_ItemExpDistributor.DecideExpOwnership( this ); Player* pItemOwner = g_ItemExpDistributor.DecideItemOwnership( this ); if( pExpOwner && !bTransform ) { // °æÇèÄ¡¸¦ ºÐ¹èÇÑ´Ù. g_ItemExpDistributor.DistributeExp( this, pExpOwner ); } if( pItemOwner && !bTransform ) { // ¾ÆÀÌÅÛÀ» µå¶ø½ÃŲ´Ù. BYTE byDropRatio = pItemOwner->GetFatigueManager()->GetItemDropRatio(); StatusField& rStatus = pItemOwner->GetStatusManager()->Status; if( rStatus.FIELD & rStatus.ENABLE_GM_DROP_LIST_ALL ) byDropRatio = 100; if( random(1, 100) <= byDropRatio ) { // ¾ÆÀÌÅÛÀ» ¸ÕÀú È®·ü°è»êÈÄ ½ÇÆÐÇÏ¸é µ· È®·ü °è»ê WzVector vDropPos; GetPos( &vDropPos ); // ÇöÀç ¾ÆÀÌÅÛ¿¡ ´ëÇÑ ¼ÒÀ¯±ÇÀÌ ¾ø´Ù! //g_DropManager.Drop( GetField(), GetSectorIndex(), &vDropPos, pItemOwner, GetObjectKey(), GetBaseInfo(), (eNPC_GRADE)GetBaseInfo()->m_byGrade, GetDisplayLevel() ); g_DropManager.DelayedDrop_( GetField(), GetSectorIndex(), &vDropPos, pItemOwner, GetObjectKey(), GetBaseInfo(), (eNPC_GRADE)GetBaseInfo()->m_byGrade, GetDisplayLevel()); } } // for Trigger & Quest & ItemDeleteEvent m_LinkedAction.OnDead( GetField(), this, ( pItemOwner && !bTransform ) ? pItemOwner : NULL, m_dwKillerObjectKey ); NPC::OnDead(); if( GetBaseInfo()->m_byGrade == eNPC_LUCKY_MONSTER || GetBaseInfo()->m_byGrade == eNPC_BOSS) GAMELOG->LogKillSpecialMonster(pItemOwner, GetBaseInfo()->m_MonsterCode, GetBaseInfo()->m_byGrade); #ifdef _NA_007065_20140217_CHAOSZONE_GOLDRUSH ChaosZoneManager* chaoszone_manager = GetChaosZoneManager(); if (chaoszone_manager != NULL) { #ifdef _NA_008334_20150608_SONNENSCHEIN ChaosZoneType type = chaoszone_manager->GetChaosZoneType(); if (type == eCHAOSZONE_TYPE_GOLDRUSH || type == eCHAOSZONE_TYPE_SONNENSCHEIN ) { Character* const killer = GetField()->FindCharacter(m_dwKillerObjectKey); chaoszone_manager->DeadCharacter(static_cast(this), killer); } #else if (chaoszone_manager->GetChaosZoneType() == eCHAOSZONE_TYPE_GOLDRUSH) { Character* const killer = GetField()->FindCharacter(m_dwKillerObjectKey); chaoszone_manager->DeadCharacter(static_cast(this), killer); } #endif //_NA_008334_20150608_SONNENSCHEIN } #endif //_NA_007065_20140217_CHAOSZONE_GOLDRUSH #ifdef _NA_007086_20140318_MONSTERBOOK // moved to AppliedNpcDependencyChain::OnMonsterDeadProcess(...) #endif //_NA_007086_20140318_MONSTERBOOK } //-------------------------------------------------------------------------------------------------- VOID Monster::StartSummonedTimer(DWORD time) { if( time != 0 ) { m_bSummoned = TRUE; m_LiveIdle.SetTimer( time ); } else m_bSummoned = FALSE; }