void CStateMachinen::DoScriptMove(CMonster& monster, eStateEvent event) { StateParameter& stateParamter = monster.mStateParamter; switch(event) { case eSEVENT_Enter: { VECTOR3 position = { float(monster.GetFiniteStateMachine().GetMemory().GetVariable("__move_x__")), 0, float(monster.GetFiniteStateMachine().GetMemory().GetVariable("__move_z__")), }; monster.OnMove( &position); stateParamter.nextTime = gCurTime + CCharMove::GetMoveEstimateTime( &monster); break; } case eSEVENT_Process: { if( stateParamter.nextTime > gCurTime ) { break; } SetState( &monster, eMA_STAND); break; } } }
bool FightStateScript::CheckTracer(BaseType::EntityType *entity) { if(m_State == TRACING) { int ret = m_SkillTracer.Run(entity); if(ret == SkillTracer::TIMEOUT || ret == SkillTracer::FAILED) { OnUseSkillEnd(ret); } if(ret == SkillTracer::Okay) { MonsterAI *ai = dynamic_cast<MonsterAI*>(entity); CMonster *monster = dynamic_cast<CMonster*>(entity->GetOwner()); CServerRegion *region = dynamic_cast<CServerRegion*>(monster->GetFather()); CMoveShape *target = AIUtils::FindShape(region, m_SkillTracer.m_TargetID); if(target == NULL) { OnUseSkillEnd(SkillTracer::FAILED); } else { ai->BeginSkill(m_SkillTracer.m_SkillID, m_SkillTracer.m_SkillLvl, target); long actTime = monster->GetActModify(m_SkillTracer.m_SkillID); ai->SetTimer(AIDriver::SCRIPT_EVENT, actTime); } } return true; } return false; }
int _tmain(int argc, _TCHAR* argv[]) { // 注册错误回调函数 FKAISystem::RegisterErrorMsgReceiver( OutPut ); // 初始化状态机表 FKAISystem::SetStateFilesDirectory( "Bin/Data/AIScript" ); CMonster* pMonster = new CMonster(); pMonster->Init("状态机表名称"); for( ;; ) { // 获取帧间隔时间 static float lastTime = 0; lastTime = g_fAccumTime; g_fAccumTime = (float)timeGetTime() / 1000.0f; g_fTimeFromLastFrame = g_fAccumTime - lastTime; //最低帧数控制 if (g_fTimeFromLastFrame>0.2f) g_fTimeFromLastFrame = 0.2f; // 每帧间隔CPU休眠时间 if(g_dwSleepTime > 0) Sleep(g_dwSleepTime); pMonster->Update( g_fTimeFromLastFrame ); } pMonster->Destory(); return 0; }
bool CObjectManager::Start() { for (int i = 0; i < MAX_MONSTER; ++i) { CMonster *pMonster = new CMonster(); //pMonster->Initalize(); // Warning : Initalize -> Clear -> SetIndex 순서 바뀌면 안됨 pMonster->SetIndex(i); InsertMonsterToMap(i, pMonster); //if (0 == i) //{ // pMonster->SetMonsterType(MonsterType::MONSTER_TYPE_END); // continue; // 0은 더미 NPC라서 풀에 넣을 필요없음 //} //else if (i < DEFENDER_MONSTER_START) //{ // pMonster->SetMonsterType(MonsterType::ATTACKER); //} //else if (i < SURPPORT_MONSTER_START) //{ // pMonster->SetMonsterType(MonsterType::DEFENDER); //} //else //{ // pMonster->SetMonsterType(MonsterType::SUPPORTER); //} if (0 == i) continue; m_monsterPool.push(pMonster); } return true; }
void CStateMachinen::DoPause(CMonster& monster, eStateEvent event) { StateParameter& stateParamter = monster.mStateParamter; switch(event) { case eSEVENT_Enter: { const DWORD pausedTick = monster.GetFiniteStateMachine().GetMemory().GetVariable( "__tick__"); stateParamter.nextTime = gCurTime + pausedTick; break; } case eSEVENT_Process: { if(gCurTime > stateParamter.nextTime) { const eMONSTER_ACTION pausedAction = eMONSTER_ACTION(monster.GetFiniteStateMachine().GetMemory().GetVariable( "__lastState__")); SetState( &monster, pausedAction); } break; } } }
void SummonDeadState::Execute(BaseType::EntityType *entity) { if (entity == NULL) { LogError(AI_MODULE, "entity object is null."); return; } CMonster *monster = static_cast<CMonster*>(entity->GetOwner()); monster->AddDelEvent(0); }
void CPlayer::skillDamage(AdvancedAttribute targetAttr) { CMonster *pTargetMonster = dynamic_cast<CMonster *>(getTargetObject()); if(pTargetMonster != NULL) { AdvancedAttribute monsterAdv = pTargetMonster->getAdvAttr(); pTargetMonster->addHate(getUID(), targetAttr.iHP - monsterAdv.iHP); } CUnitObject::skillDamage(targetAttr); }
//***************************************************************************************** void CAnt::Process( //Process an ant for movement. //Params: const int /*nLastCommand*/, //(in) Last swordsman command. CCueEvents &CueEvents) //(in/out) Accepts pointer to a cues object that will be populated //with codes indicating events that happened that may correspond to //sound or graphical effects. { //If another monster has already got the player, don't move this one there too. if (CueEvents.HasOccurred(CID_MonsterKilledPlayer)) return; //Decide where to move to. UINT wSX, wSY; if (!GetTarget(wSX,wSY)) return; //If next to the target then jump out and kill it. //The ant is not killed, but is largely immobile out of water. if (abs(static_cast<int>(this->wX - wSX)) <= 1 && abs(static_cast<int>(this->wY - wSY)) <= 1) { bool bAttack = this->pCurrentGame->IsPlayerAt(wSX, wSY); if (!bAttack) { CMonster *pMonster = this->pCurrentGame->pRoom->GetMonsterAtSquare(wSX, wSY); if (pMonster && pMonster->IsAttackableTarget()) bAttack = true; } if (bAttack) { //Move onto target if possible. const int dx = wSX - this->wX; const int dy = wSY - this->wY; const UINT wOSquare = this->pCurrentGame->pRoom->GetOSquare(wSX,wSY); if (!(bIsWall(wOSquare) || bIsCrumblyWall(wOSquare) || bIsDoor(wOSquare) || DoesArrowPreventMovement(dx, dy) || this->pCurrentGame->pRoom->DoesSquarePreventDiagonal(this->wX, this->wY, dx, dy))) { MakeStandardMove(CueEvents, dx, dy); SetOrientation(dx, dy); return; } } } //Get movement offsets. int dxFirst, dyFirst, dx, dy; if (!GetDirectMovement(wSX, wSY, dxFirst, dyFirst, dx, dy)) return; //Move roach to new destination square. MakeStandardMove(CueEvents,dx,dy); SetOrientation(dxFirst, dyFirst); }
void CGameProc::Loaddata() { int nMonsterCnt; nMonsterCnt=GetPrivateProfileInt("map0","monstercnt",0,"data\\map.txt"); for (int i=0;i<nMonsterCnt;i++) { CMonster *pMonster; pMonster=new CMonster(); pMonster->Create(i,m_pD3DDevice); m_xMonsterList.MoveCurrentToTop(); m_xMonsterList.AddNode(pMonster); } }
void FightStateScript::ReceiveEvent(BaseType::EntityType *entity, const BaseType::EventType &ev) { SelfType::ReceiveEvent(entity, ev); if(ev.Type() == ET_SCRIPT_USESKILL) { const ScriptUseSkillEvent &sev = (const ScriptUseSkillEvent&) ev; CMonster *monster = dynamic_cast<CMonster*>(entity->GetOwner()); CServerRegion *region = dynamic_cast<CServerRegion*>(monster->GetFather()); MonsterAI *ai = dynamic_cast<MonsterAI*>(entity); long id = sev.id; long lvl = sev.lvl; long actTime = monster->GetActModify(sev.id); if(sev.type == ScriptUseSkillEvent::SHAPE) { if(sev.trace) { // trace the target m_SkillTracer.Init(id, lvl, sev.targetId, sev.traceTime); m_skillScriptID = sev.scriptId; m_State = TRACING; entity->Resume(0); return ; } else { CMoveShape *target = AIUtils::FindShape(region, sev.targetId); if(target == NULL) { OnUseSkillEnd(SkillTracer::FAILED); return ; } ai->BeginSkill(id, lvl, target); } } else if(sev.type == ScriptUseSkillEvent::CELL) { ai->BeginSkill(id, lvl, sev.x, sev.y); } m_skillScriptID = sev.scriptId; // register act time timer ai->SetTimer(AIDriver::SCRIPT_EVENT, actTime); } else if(ev.Type() == ET_SCRIPT_SKILLEND) { OnUseSkillEnd(SkillTracer::Okay); } else if(ev.Type() == ET_KILL) { entity->ChangeState(ST_DEAD); } }
void CMonsterGen::OnLoop() { if(MeatGen(rate) && monsterCount < monsterMax) { CMonster* monsterPiece = new CMonster(); if (monsterPiece->OnLoad("monster.png", 64, 64, 8) == false) { return; } monsterPiece->X = SDL_GetTicks()%624 + (rand()%500); monsterPiece->Y = SDL_GetTicks()%300 + (rand()%400); monsterPiece->ID = 1337*(monsterType) + meatID; meatID++; monsterCount++; CEntity::EntityList.push_back(monsterPiece); } }
void CObjectManager::DeleteMonster(const UINT id) { CMonster* pMon = FindMonster(id); if (m_monsterMappingHashMap.erase(id)) { //#ifdef _DEBUG //cout << "CObjectManager Mapping HashMap -> Monster Erase : " << id << endl; //#endif } InsertMonsterToPool(pMon); pMon->Clear(); }
void MonsterAI::EscapeSpring() { CMonster *monster = static_cast<CMonster*>(GetOwner()); if (monster == NULL) { LogError(AI_MODULE, "MosterAI has no owner object..."); return; } if(monster->GetHP() * 100.0f / monster->GetMaxHP() <= monster->GetEscapePoint()) { // change to escape state ChangeState(ST_ESCAPE); } }
//LMA: moving to long long... //void CMonster::AddDamage( CCharacter* enemy, long long hitpower) void CMonster::AddDamage( CCharacter* enemy, long long hitpower) { //Log(MSG_INFO,"In CMonster::AddDamage"); CPlayer* player = NULL; if(enemy->IsMonster( )) { CMonster* monster = (CMonster*) enemy; if(!enemy->IsSummon( )) return; player = monster->GetOwner( ); if(player==NULL) return; } else { player = (CPlayer*) enemy; } if(MonsterDrop->firsthit==0 && hitpower > 0) { MonsterDrop->firsthit = player->CharInfo->charid; MonsterDrop->firstlevel = player->Stats->Level; if( player->Party->party!=NULL ) thisparty = player->Party->party; else thisparty = NULL; } for(UINT i=0;i<PlayersDamage.size();i++) { MonsterDamage* thisplayer = PlayersDamage.at(i); if(thisplayer->charid == player->CharInfo->charid) { if( hitpower > Stats->HP ) { //hitpower += (long int)Stats->HP + (long int)( Stats->HP * 0.10 ); hitpower += Stats->HP + (long long) ( Stats->HP * 0.10 ); } thisplayer->damage += hitpower; return; } } MonsterDamage* newplayer = new MonsterDamage; newplayer->charid = player->CharInfo->charid; if( hitpower > Stats->HP ) { //hitpower += (long int)Stats->HP + (long int)( Stats->HP * 0.10 ); hitpower += Stats->HP + (long long)( Stats->HP * 0.10 ); } newplayer->damage = hitpower; PlayersDamage.push_back( newplayer ); }
static int IsValidOper( CShopManager *pShopMgr, CMessage *pMsg, const CGUID &npcID, long lShopID ) { CPlayer *pPlayer = pMsg->GetPlayer(); CServerRegion *pRegion = pMsg->GetRegion(); if( pPlayer == NULL || pRegion == NULL ) { return -2; } if( pPlayer->IsDied() ) { return -1; } if( pPlayer->GetCurrentProgress() != CPlayer::PROGRESS_FBUSINESS ) { PutoutLog( LOG_FILE, LT_WARNING, "The Player [%s] is not in PROGRESS_FBUSINESS state.", pPlayer->GetName() ); return -1; } SetPlayerState( pPlayer, true ); CMonster *pNPC = (CMonster*) pRegion->FindAroundObject( pPlayer, TYPE_MONSTER, npcID ); if( pNPC == NULL ) { return -1; } CShop *pShop = pShopMgr->GetShop( lShopID ); if( pShop == NULL ) { return -1; } // NPC是否与商店对应 if( strcmp( pNPC->GetOriginName(), pShop->GetNpcOrigName() ) != 0 ) { return -1; } if( pNPC->Distance( pPlayer ) > 10 ) { return -1; } return 0; }
BOOL Guard::CanAttackCurrent() { if( !HasTarget() ) { return FALSE; } CMoveShape *pTarget = GetTarget(); long dis = m_pOwner->Distance( pTarget ); long attack_range = static_cast<CMonster*>( m_pOwner )->GetAttribute( string( "C_GuardRange" ) ); if( dis > attack_range ) { return FALSE; } CMonster *pSelf = static_cast<CMonster*>( m_pOwner ); DWORD ai_ref = 0; if( pTarget->GetType() == TYPE_PLAYER ) { CPlayer *pPlayer = static_cast<CPlayer*>( pTarget ); // ai reference 1 ai_ref = pSelf->GetAIReferrence( 0 ); if( ai_ref >= 0 ) { if( pPlayer->GetPVPValue() >= ai_ref && !IsSameCamp( pPlayer, pSelf ) ) { return TRUE; } } // ai reference 2 ai_ref = pSelf->GetAIReferrence( 1 ); if( ai_ref > 0 ) { if( pPlayer->GetPkValue() >= ai_ref ) { return TRUE; } } } // actually, it's not necessary to judge monsters, that because the property for the monsters will // not changed .So ignored here. // ... return FALSE; }
void test_derived_archive() { CMonster monster; monster.mod_hp(10000); monster.mod_mp(500); std::string name("test"); monster.set_name(name); std::stringstream ss; boost::archive::binary_oarchive oa(ss); oa << monster; CMonster monster2; boost::archive::binary_iarchive ia(ss); ia >> monster2; std::cout << "hp is " << monster2.get_hp() << " mp is " << monster2.get_mp() << std::endl; std::cout << "name is " << monster2.get_name() << std::endl; }
void MonsterAI::GBHSpring(long hurt) { CMonster *monster = static_cast<CMonster*>(GetOwner()); if (monster == NULL) { LogError(AI_MODULE, "MosterAI has no owner object..."); return; } int hurtProportionHp= (int) (monster->GetMaxHP() * monster->GetHurtProportion() / 100); int hp= monster->GetHP(); int lastHp= hp + hurt; if(hurtProportionHp < lastHp && hurtProportionHp >= hp) { //RunScript(monster->GetGBHScriptName().c_str()); } }
bool CLaser::HitMonster(vec2 From, vec2 To) { vec2 At; CCharacter *pOwnerChar = GameServer()->GetPlayerChar(m_Owner); if (!pOwnerChar) return false; CMonster *pHit = GameServer()->m_World.IntersectMonster(m_Pos, To, 8.0f, At); if(!pHit) return false; m_From = From; m_Pos = At; m_Energy = -1; pHit->TakeDamage(normalize(To-From)*0.1f, m_Damage, m_Owner, At); return true; }
bool MonsterAI::BeginSkill(long skillId, long skillLvl, long x, long y, CMoveShape* target) { if (target == NULL) { LogError(AI_MODULE, "Target object is null."); return false; } LogDebug(AI_MODULE, "skillId=%d, skillLvl=%d, x=%d, y=%d, target=%s", skillId, skillLvl, x, y, target->GetExID().tostring()); CMonster *monster = static_cast<CMonster*>(GetOwner()); monster->InitSkillInstance(skillId, skillLvl, 0, 0, 0, NULL_GUID, 5); if(!BaseAI::BeginSkill(monster->GetInstanceSkill(), x, y, target)) { Resume(OPER_FAILED_TIME); return false; } return true; }
CMoveShape *Guard::SearchByAIRef4( const ShapeListType &monster_list, DWORD ai_ref ) { LONG min_distance = 0x7ffffff; CMoveShape *pTarget = NULL; for( ShapeListType::const_iterator it = monster_list.begin(); it != monster_list.end(); ++ it ) { CMonster *pMonster = MONSTER_CASTC( *it ); LONG distance = m_pOwner->Distance( pMonster ); if( pMonster->GetNpcType() == NT_Guard && _ai_ref4_helper( static_cast<CMonster*>( m_pOwner ), pMonster, ai_ref ) && distance < min_distance ) { min_distance = distance; pTarget = pMonster; } } return pTarget; }
void CStateMachinen::DoRunAway(CMonster& monster, eStateEvent evt) { StateParameter& stateParamter = monster.mStateParamter; if( monster.GetAbnormalStatus()->IsStun || monster.GetAbnormalStatus()->IsFreezing || monster.GetAbnormalStatus()->IsStone || monster.GetAbnormalStatus()->IsSlip || monster.GetAbnormalStatus()->IsMoveStop || monster.GetAbnormalStatus()->IsParalysis ) { return; } switch(evt) { case eSEVENT_Enter: { monster.RemoveAllAggro(); monster.SetTObject(0); VECTOR3 position = {0}; position.x = float(monster.GetFiniteStateMachine().GetMemory().GetVariable( "__runaway_x__")); position.z = float(monster.GetFiniteStateMachine().GetMemory().GetVariable( "__runaway_z__")); monster.OnMove( &position); stateParamter.nextTime = gCurTime + CCharMove::GetMoveEstimateTime(&monster) + 1000; break; } case eSEVENT_Process: { if(gCurTime > stateParamter.nextTime) { SetState( &monster, eMA_STAND); break; } break; } } }
void SummonDeadState::Enter(BaseType::EntityType *entity, const AITransition &tran) { if (entity == NULL) { LogError(AI_MODULE, "entity object is null."); return; } CMonster *monster = static_cast<CMonster*>(entity->GetOwner()); entity->Stop(); entity->Resume(GlobalSetup::GetSetup()->dwMonsterKeepDeadTime); SKILL::SummVine *vine = dynamic_cast<SKILL::SummVine*>(monster->GetSummmon()); if (vine == NULL) { LogError(AI_MODULE, "monster->GetSummon() error: vine is null."); } assert(vine); if (vine != NULL) { //GetInst(SKILL::SummonMan).RemoveSummon(vine); } }
void SummonPeaceState::Execute(BaseType::EntityType *entity) { if (entity == NULL) { LogError(AI_MODULE, "entity is null."); return; } if(SearchEnemy(entity)) { return; } /// Stand ... Don't move MonsterAI *ai = static_cast<MonsterAI*>(entity); CMonster *monster = static_cast<CMonster*>(entity->GetOwner()); if (monster == NULL) { LogError(AI_MODULE, "MonsterAI do not have owner."); } assert(ai && monster); ai->Stand(monster->GetStopFrame()); }
bool OnGS2C_MonsterStopMove(GS2C_MonsterStopMove *value) { if ( !gMap ) { return true; } CMonster* pMonster = GetMapMonster(value->id); if ( pMonster) { ////just for test //if(pMonster->GetPropertyInt(RoleProperty_Cloth) == 9006) //{ // CCLOG("stopmove,cur:(%d,%d),step:(%d,%d), posX:%d,posY:%d", pMonster->GetCellX(),pMonster->GetCellY(), // pMonster->GetStepX(),pMonster->GetStepY(), // value->posX,value->posY); //} pMonster->StopTo(value->posX,value->posY); } return true; }
bool OnGS2C_MonsterMoveInfo(GS2C_MonsterMoveInfo *value) { CMonster* pMonster = GetMapMonster(value->id); if ( pMonster ) { ////just for test //if(pMonster->GetPropertyInt(RoleProperty_Cloth) == 9006) //{ // CCLOG("move info,cur posX:%d,posY:%d", value->posX,value->posY); // for ( size_t i = 0;i<value->posInfos.size();++i ) // { // pk::PosInfo pt = value->posInfos[i]; // CCLOG(" path,(%d,%d)", pt.x,pt.y); // } //} APath path; CHero::PosInfoToPath(value->posX,value->posY,value->posInfos,path); pMonster->Move(path); } return true; }
void CMap::CheckForMonster() { // In this function we go through all of the monsters and see if we // hit any of them. If so, we want to attack them. for(int i = 0; i < (int)m_vMonsters.size(); i++) { CMonster *pMonster = &m_vMonsters[i]; // Go through every player in the party to see if any attacked the monster for(int i = 0; i < g_Player.GetPartySize(); i++) { CPlayer *pPlayer = g_Player.GetPartyMember(i); POINT position = pPlayer->GetPosition(); // Check if the current player's position is the same as the monster if(position.x == pMonster->GetIndex().x && position.y == pMonster->GetIndex().y) { // Have the player attack the monster pPlayer->Attack(pMonster); } } } }
bool MonsterAI::RandomRun() { CMonster *monster = static_cast<CMonster*>(GetOwner()); if (monster == NULL) { LogError(AI_MODULE, "MosterAI has no owner object..."); } assert(monster); if(random(10000) < monster->GetMoveRandomValue()) { long dir = 0; long curX = monster->GetTileX(); long curY = monster->GetTileY(); long dis = monster->Distance(curX, curY, m_BornPos.x, m_BornPos.y); if(dis > monster->GetPeaceMoveRange()) { dir = GetLineDir(curX, curY, m_BornPos.x, m_BornPos.y); long gdir = (8 - dir) % 8; if(gdir >= 2 || gdir <= 6) { dir = (dir + random(3) - 1 + 8) % 8; } } else { dir = random(8); } long maxRunTimes = monster->GetMaxRunTimes(); long minRunTimes = monster->GetMinRunTimes(); AI_EVENT_SENDER(this).MoveByStep(dir, random(maxRunTimes - minRunTimes) + minRunTimes); // drive the ai Resume(0); } else { Stand(monster->GetStopFrame()); } return true; }
LRESULT CGameProc::OnRButtonDown(WPARAM wParam, LPARAM lParam) { m_bRCapture=true; m_Oldpt.x = LOWORD(lParam); m_Oldpt.y = HIWORD(lParam); if (Pick(m_Oldpt)) { if (g_pPlayer->CalculateTagDistanceSquece()<50*50&&g_pPlayer->m_pTargetInfo->TaskIndex!=0) { //判断任务怪死亡没有 if (g_pChatPopWnd->m_nTaskState==2) { m_xMonsterList.MoveCurrentToTop(); for (int nCnt=0;nCnt<m_xMonsterList.GetCounter();nCnt++) { CMonster *pMonster; pMonster=m_xMonsterList.GetCurrentData(); if (pMonster->m_xMonsterInfo.Id==2) { if (!pMonster->IsDead()) { g_pChatPopWnd->m_nTaskState=1; } } m_xMonsterList.MoveNextNode(); } } g_pChatPopWnd->Open(); m_xTaskScript.CallFun(g_pPlayer->m_pTargetInfo->TaskIndex); } } return true; }
void GuardSearch::Execute( BaseType::EntityType *entity ) { CMonster *pSelf = dynamic_cast<CMonster*>( entity->GetOwner() ); ShapeListType player_list; ShapeListType monster_list; CServerRegion *pRegion = static_cast<CServerRegion*>( pSelf->GetFather() ); CMoveShape *pTarget = NULL; if( CanAttackCurrent( pSelf, entity ) ) { return; } // find the around players pRegion->FindAroundObject( pSelf, TYPE_PLAYER, player_list ); // find the around monsters including the guards. pRegion->FindAroundObject( pSelf, TYPE_MONSTER, monster_list ); // filter the result Filter filter( static_cast<CMonster*>( pSelf ) ); filter_shape( player_list, filter ); filter_shape( monster_list, filter ); // retrieve the ai reference DWORD ai_ref = pSelf->GetAIReferrence( 0 ); if( ai_ref >= 0 ) { pTarget = SearchByAIRef1( pSelf, player_list, ai_ref ); } if( pTarget == NULL && ( ai_ref = pSelf->GetAIReferrence( 1 ) ) > 0 ) { pTarget = SearchByAIRef2( pSelf, player_list, ai_ref ); } if( pTarget == NULL && ( ai_ref = pSelf->GetAIReferrence( 2 ) ) > 0 ) { pTarget = SearchByAIRef3( pSelf, monster_list, ai_ref ); } if( pTarget == NULL && ( ai_ref = pSelf->GetAIReferrence( 3 ) ) > 0 ) { pTarget = SearchByAIRef4( pSelf, monster_list, ai_ref ); } if( pTarget != NULL ) { // search successfully entity->SetTarget( pTarget->GetExID(), pTarget->GetType() ); } else if( entity->HasTarget() ) { AI_EVENT_SENDER( entity ).ReturnPeace(); } }