#include "StdAfx.h" #include "actionescape.h" #include "GameSrv.h" #include "Monster.h" #include "SkillManager.h" #include "Player.h" #include "ObjectManager.h" #include "AIManager.h" cActionEscape::cActionEscape(void) : cAction( eACT_ESCAPE ) { mIsSetPath = false; } cActionEscape::~cActionEscape(void) { } void cActionEscape::ActionInit( cMonster* pMonster, unsigned long accumTime ) { if( pMonster == NULL ) return; cAction::ActionInit( pMonster, accumTime ); /// µµ¸Á ½ÃÀÛ ½Ã°£ ¼³Á¤ mEscapeStartTime = accumTime; /// Áß°£ ÄÚ½º º¯°æ ¿©ºÎ mCourseChange = rand() % 2 == 0 ? true : false; /// ¸ó½ºÅ͸¦ µµ¸Á ¼Óµµ·Î ¼³Á¤ pMonster->SetMoveSpeed( pMonster->GetMonsterInfo()->mActionRunSpd, eMOVESPEED_RUN ); if( pMonster->GetMoveSpeed() <= 0 ) return; /// À̵¿ ÃÖ´ë/ÃÖ¼Ò °Å¸®¸¦ ±¸ÇÔ unsigned long escapeMaxRange = ESCAPE_MAXIMUM_TIME / SECOND_THOUSAND * pMonster->GetMoveSpeed(); unsigned long escapeMinRange = ESCAPE_MINIMUM_TIME / SECOND_THOUSAND * pMonster->GetMoveSpeed(); pMonster->SendSpeech( eMONSTERTALK_ESCAPE ); /// ½ºÅ³ »ç¿ëÀÌ ³¡³¯¶§ ±îÁö °æ·Î¼³Á¤ ¾ÈÇÔ if( SKILLMANAGER->IsUsingSkill( eOBJECTTYPE_MONSTER, pMonster->GetObjectID() ) ) return; /// À̵¿ ÁÂÇ¥¸¦ ¼³Á¤ mIsSetPath = EscapeTargetPos( pMonster, escapeMinRange, escapeMaxRange, pMonster->GetXPos(), pMonster->GetYPos() ); } eACTION_CHANGE cActionEscape::Action( cMonster* pMonster, unsigned long deltaTime, unsigned long accumTime ) { if( pMonster == NULL ) return eACTCH_ERROR; const sMonsterScript* pMonsterScript = pMonster->GetMonsterInfo(); if( pMonsterScript == NULL ) { assert(NULL); NETWORK2->PostServerEvent("cActionEscape::Action pMonsterScript == NULL"); return eACTCH_ERROR; } /// ½ºÅ³ »ç¿ëÀÌ ³¡³¯¶§±îÁö ´ë±â if( SKILLMANAGER->IsUsingSkill( eOBJECTTYPE_MONSTER, pMonster->GetObjectID() ) ) return eACTCH_CONTINUE; /// µµ¸Á ½ÃÀÛ ½ÃÁ¡ºÎÅÍ °æ°ú ½Ã°£ unsigned long elapseTime = 0; if( accumTime > mEscapeStartTime ) elapseTime = accumTime - mEscapeStartTime; /// µµ¸Á °æ°ú ½Ã°£ÀÌ Áö³­°æ¿ì »óÅ º¯°æ if( ESCAPE_MAXIMUM_TIME < elapseTime ) { /// 081205 PKH Ÿ°Ù ¼±Á¤ if( pMonster->GetTarget() == 0 ) pMonster->ChangeActionTarget(); else pMonster->ActionChange( eACT_FOLLOW ); return eACTCH_CONTINUE; } /// Áß°£ ÄÚ½º º¯°æ if( mCourseChange == true ) { if( ESCAPE_CHANGE_TIME < elapseTime ) { mCourseChange = false; /// À̵¿ ¼³Á¤ long escapeMaxRange = 0; if( ESCAPE_MAXIMUM_TIME > elapseTime ) escapeMaxRange = ESCAPE_MAXIMUM_TIME - elapseTime; if( pMonster->GetMoveSpeed() != 0 ) escapeMaxRange = escapeMaxRange / SECOND_THOUSAND * pMonster->GetMoveSpeed(); if( escapeMaxRange > 0 ) EscapeTargetPos( pMonster, 0, escapeMaxRange, pMonster->GetXPos(), pMonster->GetYPos() ); } } /// °æ·Î ¼³Á¤ÀÌ ¾ÈµÇÀÖ´Â °æ¿ì if( mIsSetPath == false ) { /// À̵¿ ¼³Á¤ long escapeMaxRange = 0; if( ESCAPE_MAXIMUM_TIME > elapseTime ) escapeMaxRange = ESCAPE_MAXIMUM_TIME - elapseTime; long escapeMinRange = 0; if( ESCAPE_MINIMUM_TIME > elapseTime ) escapeMinRange = ESCAPE_MINIMUM_TIME - elapseTime; if( pMonster->GetMoveSpeed() != 0 ) { escapeMaxRange = escapeMaxRange / SECOND_THOUSAND * pMonster->GetMoveSpeed(); escapeMinRange = escapeMinRange / SECOND_THOUSAND * pMonster->GetMoveSpeed(); } if( escapeMaxRange > 0 ) mIsSetPath = EscapeTargetPos( pMonster, escapeMinRange, escapeMaxRange, pMonster->GetXPos(), pMonster->GetYPos() ); } /// °æ·Î ¼³Á¤ÀÌ µÈ°æ¿ì if( mIsSetPath == true ) { /// ¸ó½ºÅÍ À̵¿ if( pMonster->MoveUpdate( deltaTime ) == false ) { cBaseObject* pTarget = pMonster->GetTarget(); if( pTarget == NULL ) return eACTCH_ESCAPE_FOLLOW; if( pTarget->GetStateDie() == true ) return eACTCH_ESCAPE_FOLLOW; /// ÃßÀû ½Ã°£ Àç¼³Á¤ - ÇöÀç½Ã°£ + ÃßÀû½Ã°£ + µµ¸Á¿Â½Ã°£ pMonster->SetFollowEndTime( accumTime + pMonsterScript->mFollowTime + ( accumTime - mEscapeStartTime ) ); NiPoint2 targetPos = pTarget->GetPos(); /// ´Ù½Ã ÂѾư¥ Ÿ°ÙÀÌ ¸ø°¡´Â Áö¿ª Àΰæ¿ì ÀÚÀ¯À̵¿ if( AIMANAGER->IsPossible( pTarget->GetMapNumber(), targetPos.x, targetPos.y, pTarget->GetObject() ) == false ) return eACTCH_ESCAPE_END; else return eACTCH_ESCAPE_FOLLOW; } } return eACTCH_CONTINUE; } bool cActionEscape::EscapeTargetPos( cMonster* pMonster, unsigned long escapeMinRange, unsigned long escapeMaxRange, float centerX, float centerY ) { if( pMonster == NULL ) return false; /// À¯È¿ °Å¸® long validityRange = escapeMaxRange - escapeMinRange; if( validityRange < 1 ) validityRange = 1; /// À¯È¿ ¹üÀ§ ¼³Á¤ float escapePosX = centerX - validityRange + ( rand() % ( validityRange * 2 ) ); float escapePosY = centerY - validityRange + ( rand() % ( validityRange * 2 ) ); /// ¼³Á¤µÈ ¹üÀ§¿¡ ÃÖ¼Ò »çÀÌÁî ¸¸Å­ Áõ°¡ if( escapePosX > centerX ) escapePosX += escapeMinRange; else if( escapePosX < centerX ) escapePosX -= escapeMinRange; if( escapePosY > centerY ) escapePosY += escapeMinRange; else if( escapePosY < centerY ) escapePosY -= escapeMinRange; /// °¥¼ö ¾ø´Â Áö¿ªÀÌ¸é ´Ù½Ã ¼±Á¤ if( AIMANAGER->IsPossible( pMonster->GetMapNumber(), escapePosX, escapePosY, pMonster->GetObject() ) == false ) return false; return pMonster->SetPath( escapePosX, escapePosY ) != 0; }