#include "stdafx.h" #include "Object.h" #include "DummyClient.h" #include "Monster_Common.h" #include "GameResourceManager.h" #include "ObjectManager.h" #include "WorldManager.h" cMonster::cMonster( cObjectManager* manager ) : cObject( eOBJECTTYPE_MONSTER, manager ) { mGotoX = 0.0f; mGotoY = 0.0f; mLastGotoX = 0; mLastGotoY = 0; mObjectId = 0; mMoveSpeed = 0; mMoveOverTime = 0; mMoveStopRange = 0.0f; mDesiredDir = -NiPoint3::UNIT_Y; mMoveSpeedType = eMOVESPEED_WALK; mPathIndex = 0; mPathCount = 0; mpMonsterInfo = 0; mHP = 0; mMP = 0; mMaxHP = 0; mMaxMP = 0; mFixedObjectSizePer = 0; mFixedObjectSize = 0.0f; } cMonster::~cMonster() { } bool cMonster::Init( sMonsterData* baseInfo, NiPoint3 pos, NiMatrix3 rotate ) { mObjectId = baseInfo->mMonsterIdx; mpMonsterInfo = GAMERESOURCEMAN->GetMonsterListInfo( baseInfo->mMonsterClassIdx ); if( mpMonsterInfo == NULL ) return false; mTrans.m_Translate = pos; mTrans.m_Rotate = rotate; mMaxHP = baseInfo->mMaxHP; mMaxMP = baseInfo->mMaxMP; mHP = baseInfo->mHP; mMP = baseInfo->mMP; mMoveSpeed = baseInfo->mMoveSpeed; mDesiredDir = rotate*mDesiredDir; mDesiredDir.Unitize(); float scale = 1.0f; if( mpMonsterInfo->mMonsterScale > 0.0f ) { scale = mpMonsterInfo->mMonsterScale; } else { assert(0); } mFixedObjectSize = mpMonsterInfo->mMonsterFixSize * scale; mFixedObjectSizePer = baseInfo->mScale; return true; } void cMonster::Process( unsigned long deltaTime, unsigned long accumTime ) { deltaTime; accumTime; switch( mState ) { case eOBJECT_STATE_MOVE: { if( mPathCount == 0 ) return; /// À̵¿ÁßÀ̸é NiPoint3 pos = mTrans.m_Translate; /// ¸ó½ºÅÍ À̵¿ ¼Óµµ float speed = (float)mMoveSpeed; /// ¹æÇâ ¼³Á¤ NiPoint2 dir1; dir1.x = mGotoX - pos.x; dir1.y = mGotoY - pos.y; dir1.Unitize(); const unsigned long limitOverTime = 10; unsigned long plusTime; /// ¸ñÀûÁöÁ¡ ³Ñ¾î¼­ ÀúÀåµÈ ½Ã°£À» À̵¿½Ã + if( mMoveOverTime > limitOverTime ) plusTime = limitOverTime; else plusTime = mMoveOverTime; mMoveOverTime = mMoveOverTime - plusTime; /// ¼Óµµ * °æ°ú½Ã°£ ¸¸Å­ÀÇ ¿¹»ó À̵¿ À§Ä¡ °è»ê pos.x += dir1.x * speed * ((deltaTime + plusTime) *0.001f); pos.y += dir1.y * speed * ((deltaTime + plusTime) *0.001f); pos.z = 0.0f; /// ¸ñÀûÁö ÁÂÇ¥¿Í ¿¹»ó À̵¿ À§Ä¡¸¦ ºñ±³ NiPoint2 dir2; dir2.x = mGotoX - pos.x; dir2.y = mGotoY - pos.y; dir2.Unitize(); if( dir2.Dot(dir1) <= 0.0f ) { NiPoint2 overPoint( pos.x, pos.y ); NiPoint2 nextPos( mGotoX, mGotoY ); /// ±æÃ£±â °æ·Î ¸ñÀû ÁöÁ¡À» ³Ñ¾î¼± °æ¿ì ³ÑÀº °Å¸®¸¸Å­ ½Ã°£ º¸°ü float overLength = ( overPoint - nextPos ).Length(); mMoveOverTime = mMoveOverTime + (unsigned long)((overLength/speed)*1000.0f); pos.x = mGotoX; pos.y = mGotoY; if( mPathIndex < mPathCount-1 ) { NiPoint2& nextPos = mPathArray[++mPathIndex]; Move( nextPos.x, nextPos.y ); } else { mPathCount = 0; mPathIndex = 0; mMoveOverTime = 0; SetState( eOBJECT_STATE_IDLE ); } } /// ¸ó½ºÅͰ¡ ¸ñÀûÁö¿¡¼­ ±Ùó(ÀÏÁ¤¹üÀ§)±îÁö µµ´ÞÇϸé Á¤ÁöÇÏ´Â ¸ðµâ if( mMoveStopRange != 0.0f ) { /// ¸ó½ºÅͰ¡ °¡·Á°íÇÏ´Â °æ·ÎÀÇ ÃÖÁ¾ ¸ñÀûÁö NiPoint3 targetPos; NiPoint3 monsterGuessPos( pos.x, pos.y, 0.0f ); /// ³ôÀ̰ª °è»ê if( WORLDMAN->CalcHeight( mManager->GetFolderIdx(), &monsterGuessPos.z, monsterGuessPos.x, monsterGuessPos.y ) == false ) assert(NULL); float moveStopRangeFix = 0.0f; cDummyClient* hero = mManager->GetHero(); if( hero->GetObjectID() == mTarget.index ) { if( hero->IsDie() ) { targetPos.x = mLastGotoX; targetPos.y = mLastGotoY; if( WORLDMAN->CalcHeight( mManager->GetFolderIdx(), &targetPos.z, targetPos.x, targetPos.y ) == false ) assert(NULL); } else { targetPos = hero->GetPos(); } moveStopRangeFix = GetFixedObjectSize() + hero->GetFixedObjectSize() + mMoveStopRange; } else { cObject* pBaseObject = GetTargetObject(); if( pBaseObject == NULL || pBaseObject->GetState() == eOBJECT_STATE_DIE ) { targetPos.x = mLastGotoX; targetPos.y = mLastGotoY; if( WORLDMAN->CalcHeight( mManager->GetFolderIdx(), &targetPos.z, targetPos.x, targetPos.y ) == false ) assert(NULL); } else { targetPos = pBaseObject->GetPos(); } moveStopRangeFix = GetFixedObjectSize() + pBaseObject->GetFixedObjectSize() + mMoveStopRange; } /// ÃÖÁ¾ ¸ñÀûÁöÁÖº¯¿¡ ÀÏÁ¤ ¹üÀ§¿¡¼­ ¼­¾ßÇÒ »çÀÌÁî cRangeCheck rangecheck( moveStopRangeFix ); /// ÃÖÁ¾ ¸ñÀûÁö¿Í ÇöÀç À§Ä¡ÀÇ °Å¸®¸¦ ºñ±³ if( rangecheck.IsRange( monsterGuessPos, targetPos ) ) { /// ÁÂÇ¥ º¸Á¤ NiPoint3 p; NiPoint3 d = GetPos() - targetPos; d.Unitize(); p.x = targetPos.x + ((moveStopRangeFix-1.0f)*d.x); p.y = targetPos.y + ((moveStopRangeFix-1.0f)*d.y); if( WORLDMAN->CalcHeight( mManager->GetFolderIdx(), &p.z, p.x, p.y ) ) { mTrans.m_Translate = p; mLastGotoX = p.x; mLastGotoY = p.y; } else { assert(0); } mMoveStopRange = 0.0f; SetState( eOBJECT_STATE_IDLE ); return; } } /// ³ôÀ̰ª °è»ê if( WORLDMAN->CalcHeight( mManager->GetFolderIdx(), &pos.z, pos.x, pos.y ) ) { mTrans.m_Translate = pos; } else { assert( 0 ); SetState( eOBJECT_STATE_IDLE ); } } break; default: break; } } bool cMonster::Move( float x, float y ) { /// Ãß°¡: ºÎµå·¯¿î ¹æÇâ ÀüȯÀ» ³Öµµ·Ï ÇÑ´Ù. NiPoint3 kWorldTranslate = NiPoint3(x, y, 0.0f); NiPoint3 kCurTranslate = mTrans.m_Translate; kCurTranslate.z = 0.0f; NiPoint3 kAt = kCurTranslate - kWorldTranslate; if( kAt == NiPoint3::ZERO ) return false; if( kAt.SqrLength() < 0.001f ) { return false; } kAt.Unitize(); float fDot = mDesiredDir.Dot(-kAt); if( fDot < 1.0f - FLT_EPSILON )//0.999999f) { float fAngle = NiACos(fDot); if(mDesiredDir.Cross(-kAt).z > 0) fAngle = -fAngle; mDesiredDir = -kAt; NiMatrix3 kZRot; kZRot.MakeZRotation(fAngle); mTrans.m_Rotate = mTrans.m_Rotate*kZRot; } // Animation Setting - Run SetState( eOBJECT_STATE_MOVE ); /// ¸ñÀûÁö ¼³Á¤ mGotoX = x; mGotoY = y; return true; } void cMonster::SetPathArray( NiPoint2* moveArray, unsigned int count ) { assert( moveArray ); count = (count < MAX_PATH_COUNT) ? count : MAX_PATH_COUNT; for( unsigned int i = 0; i < count; ++i ) { mPathArray[i].x = moveArray[i].x; mPathArray[i].y = moveArray[i].y; } mPathIndex = 0; mPathCount = count; if( mPathCount ) { Move( mPathArray[0].x, mPathArray[0].y ); mLastGotoX = mPathArray[count-1].x; mLastGotoY = mPathArray[count-1].y; } } void cMonster::HPChange( unsigned long objectHP, unsigned long objectMaxHP ) { assert(objectHP != 0); assert( objectHP <= objectMaxHP ); mHP = objectHP; mMaxHP = objectMaxHP; } void cMonster::HPChangeDie( unsigned long objectMaxHP ) { mHP = 0; mMaxHP = objectMaxHP; SetState( eOBJECT_STATE_DIE ); } void cMonster::SetMoveSpeed( unsigned int moveSpeed, eMOVE_SPEED_TYPE moveSpeedType ) { mMoveSpeed = moveSpeed; /// ±âÁ¸°ª À¯Áö if( eMOVESPEED_STOP != moveSpeedType ) mMoveSpeedType = moveSpeedType; } void cMonster::MoveStop( float x, float y ) { mGotoX = x; mGotoY = y; mLastGotoX = x; mLastGotoY = y; mPathIndex = 0; mPathCount = 0; float height = 0.0f; if( WORLDMAN->CalcHeight(mManager->GetFolderIdx(), &height, x, y) == false ) assert(0); mTrans.m_Translate = NiPoint3(x,y,height); SetState( eOBJECT_STATE_IDLE ); } void cMonster::SetState( unsigned char state ) { if( mState ==eOBJECT_STATE_DIE ) return; mState = (eOBJECTSTATE)state; } float cMonster::GetFixedObjectSize() { return mFixedObjectSize; } void cMonster::SetFixedObjectSizeScale( unsigned short scalePer, bool init ) { mFixedObjectSizePer = scalePer; if( mpMonsterInfo == NULL ) { assert(0); return ; } float scale = 1.0f; if( mpMonsterInfo->mMonsterScale > 0.0f ) { scale = mpMonsterInfo->mMonsterScale; } else { assert(0); } mFixedObjectSize = mpMonsterInfo->mMonsterFixSize * (float)scalePer * 0.01f; }