void CAIPetDummy::CheckCurrentAction(uint32 tick) { m_Tick = tick; //uncharm any pets if time is up if(tick > m_PPet->charmTime && m_PPet->isCharmed) { petutils::DespawnPet(m_PPet->PMaster); return; } switch(m_ActionType) { case ACTION_NONE: break; case ACTION_ROAMING: ActionRoaming(); break; case ACTION_DEATH: ActionDeath(); break; case ACTION_SPAWN: ActionSpawn(); break; case ACTION_FALL: ActionFall(); break; case ACTION_ENGAGE: ActionEngage(); break; case ACTION_ATTACK: ActionAttack(); break; case ACTION_SLEEP: ActionSleep(); break; case ACTION_DISENGAGE: ActionDisengage(); break; case ACTION_MOBABILITY_START: ActionAbilityStart(); break; case ACTION_MOBABILITY_USING: ActionAbilityUsing(); break; case ACTION_MOBABILITY_FINISH: ActionAbilityFinish(); break; case ACTION_MOBABILITY_INTERRUPT: ActionAbilityInterrupt(); break; case ACTION_MAGIC_START: ActionMagicStart(); break; case ACTION_MAGIC_CASTING: ActionMagicCasting(); break; case ACTION_MAGIC_FINISH: ActionMagicFinish(); break; default : DSP_DEBUG_BREAK_IF(true); } }
void CAICharCharm::CheckCurrentAction(uint32 tick) { m_Tick = tick; CBattleEntity* PSelf = m_PChar; switch (m_ActionType) { case ACTION_NONE: ActionRoaming(); break; case ACTION_ROAMING: ActionRoaming(); break; case ACTION_ATTACK: ActionAttack(); break; case ACTION_ENGAGE: ActionEngage(); break; case ACTION_DISENGAGE: ActionDisengage(); break; case ACTION_FALL: ActionFall(); break; case ACTION_SLEEP: ActionSleep(); break; case ACTION_MAGIC_START: TransitionBack(true); break; case ACTION_RANGED_START: TransitionBack(true); break; case ACTION_ITEM_START: TransitionBack(true); break; case ACTION_CHANGE_TARGET: TransitionBack(true); break; case ACTION_WEAPONSKILL_START: TransitionBack(true); break; case ACTION_JOBABILITY_START: TransitionBack(true); break; case ACTION_RAISE_MENU_SELECTION: TransitionBack(true); break; default: DSP_DEBUG_BREAK_IF(true); } if (m_PChar && PSelf->PBattleAI == this) { m_PChar->UpdateEntity(); } }
void CAIMobDummy::ActionAbilityStart() { DSP_DEBUG_BREAK_IF(m_PBattleTarget == NULL); std::vector<CMobSkill*> MobSkills = battleutils::GetMobSkillsByFamily(m_PMob->m_Family); // не у всех монстов прописаны способности, так что выходим из процедуры, если способность не найдена if (MobSkills.size() == 0) { m_PMob->health.tp = 0; m_ActionType = ACTION_ATTACK; ActionAttack(); return; } m_LastActionTime = m_Tick; m_PMobSkill = MobSkills.at(rand() % MobSkills.size()); apAction_t Action; m_PMob->m_ActionList.clear(); Action.ActionTarget = m_PBattleTarget; Action.reaction = REACTION_HIT; Action.speceffect = SPECEFFECT_HIT; Action.animation = 0; Action.param = m_PMobSkill->getID() + 256; Action.messageID = 43; Action.flag = 0; m_PMob->m_ActionList.push_back(Action); m_PMob->loc.zone->PushPacket(m_PMob, CHAR_INRANGE, new CActionPacket(m_PMob)); m_ActionType = ACTION_MOBABILITY_FINISH; }
void CAIAutomatonDummy::CheckCurrentAction(uint32 tick) { m_Tick = tick; CBattleEntity* PSelf = m_PPet; switch (m_ActionType) { case ACTION_NONE: break; case ACTION_ROAMING: ActionRoaming(); break; case ACTION_DEATH: ActionDeath(); break; case ACTION_SPAWN: ActionSpawn(); break; case ACTION_FALL: ActionFall(); break; case ACTION_ENGAGE: ActionEngage(); break; case ACTION_ATTACK: ActionAttack(); break; case ACTION_SLEEP: ActionSleep(); break; case ACTION_DISENGAGE: ActionDisengage(); break; case ACTION_MOBABILITY_START: ActionAbilityStart(); break; case ACTION_MOBABILITY_USING: ActionAbilityUsing(); break; case ACTION_MOBABILITY_FINISH: ActionAbilityFinish(); break; case ACTION_MOBABILITY_INTERRUPT: ActionAbilityInterrupt(); break; case ACTION_MAGIC_START: ActionMagicStart(); break; case ACTION_MAGIC_CASTING: ActionMagicCasting(); break; case ACTION_MAGIC_FINISH: ActionMagicFinish(); break; default: DSP_DEBUG_BREAK_IF(true); } //check if this AI was replaced (the new AI will update if this is the case) if (m_PPet && PSelf->PBattleAI == this) { m_PPet->UpdateEntity(); } }
void CAIMobDummy::ActionEngage() { m_PMob->animation = ANIMATION_ATTACK; m_ActionType = ACTION_ATTACK; m_LastActionTime = m_Tick - 1000; ActionAttack(); }
void CAICharCharm::TransitionBack(bool skipWait /*= false*/) { m_PBattleSubTarget = nullptr; if (m_PChar->animation == ANIMATION_ATTACK) { m_ActionType = ACTION_ATTACK; if (skipWait) { ActionAttack(); } } else { m_ActionType = ACTION_NONE; } }
void CAIAutomatonDummy::TransitionBack(bool skipWait /*= false*/) { if (m_PPet->animation == ANIMATION_ATTACK) { m_ActionType = ACTION_ATTACK; if (skipWait) { ActionAttack(); } } else { m_ActionType = ACTION_ROAMING; if (skipWait) { ActionRoaming(); } } }
void CAIUltimateSummon::TransitionBack(bool skipWait) { if(m_PPet->animation == ANIMATION_ATTACK) { m_ActionType = ACTION_ATTACK; if(skipWait) { ActionAttack(); } } else { m_ActionType = ACTION_ROAMING; if(skipWait) { ActionRoaming(); } } }
void CAIUltimateSummon::CheckCurrentAction(uint32 tick) { m_Tick = tick; switch(m_ActionType) { case ACTION_NONE: break; case ACTION_ROAMING: ActionRoaming(); break; case ACTION_DEATH: ActionDeath(); break; case ACTION_SPAWN: ActionSpawn(); break; case ACTION_FALL: ActionFall(); break; case ACTION_ENGAGE: ActionEngage(); break; case ACTION_ATTACK: ActionAttack(); break; case ACTION_SLEEP: ActionSleep(); break; case ACTION_MOBABILITY_START: ActionAbilityStart(); break; case ACTION_MOBABILITY_USING: ActionAbilityUsing(); break; case ACTION_MOBABILITY_FINISH: ActionAbilityFinish(); break; case ACTION_MOBABILITY_INTERRUPT: ActionAbilityInterrupt(); break; default : DSP_DEBUG_BREAK_IF(true); } }
void CAIMobDummy::CheckCurrentAction(uint32 tick) { m_Tick = tick; switch(m_ActionType) { case ACTION_NONE: break; case ACTION_ROAMING: ActionRoaming(); break; case ACTION_ENGAGE: ActionEngage(); break; case ACTION_DISENGAGE: ActionDisengage(); break; case ACTION_FALL: ActionFall(); break; case ACTION_DROPITEMS: ActionDropItems(); break; case ACTION_DEATH: ActionDeath(); break; case ACTION_FADE_OUT: ActionFadeOut(); break; case ACTION_SPAWN: ActionSpawn(); break; case ACTION_ATTACK: ActionAttack(); break; case ACTION_MOBABILITY_START: ActionAbilityStart(); break; case ACTION_MOBABILITY_FINISH: ActionAbilityFinish(); break; case ACTION_MOBABILITY_INTERRUPT: ActionAbilityInterrupt(); break; default : DSP_DEBUG_BREAK_IF(true); } }
void CAIMobDummy::ActionAttack() { m_PBattleTarget = m_PMob->PEnmityContainer->GetHighestEnmity(); if (m_PBattleTarget == NULL) { m_ActionType = ACTION_DISENGAGE; return; } if (m_PBattleTarget->isDead()) { if (m_PMob->m_OwnerID == m_PBattleTarget->id) { m_PMob->m_OwnerID = 0; } m_PMob->PEnmityContainer->Clear(m_PBattleTarget->id); ActionAttack(); return; } m_PMob->loc.p.rotation = getangle(m_PMob->loc.p, m_PBattleTarget->loc.p); if (m_PMob->PParty != NULL) { for (uint16 i = 0; i < m_PMob->PParty->members.size(); ++i) { CMobEntity* PPartyMember = (CMobEntity*)m_PMob->PParty->members[i]; if (PPartyMember->PBattleAI->GetCurrentAction() == ACTION_ROAMING && distance(m_PMob->loc.p, PPartyMember->loc.p) < 10) { PPartyMember->PEnmityContainer->AddBaseEnmity(m_PBattleTarget); } } } if (distance(m_PMob->loc.p, m_PBattleTarget->loc.p) <= m_PMob->m_ModelSize) { if ((m_Tick - m_LastActionTime) > m_PMob->m_Weapons[SLOT_MAIN]->getDelay()) { if (battleutils::IsParalised(m_PMob)) { m_PMob->loc.zone->PushPacket(m_PMob, CHAR_INRANGE, new CMessageBasicPacket(m_PMob,m_PBattleTarget,0,0,29)); } else if (battleutils::IsIntimidated(m_PMob, m_PBattleTarget)) { m_PMob->loc.zone->PushPacket(m_PMob, CHAR_INRANGE, new CMessageBasicPacket(m_PMob,m_PBattleTarget,0,0,106)); } else { if (m_PMob->health.tp > 100 && rand()%100 > 55) { m_ActionType = ACTION_MOBABILITY_START; ActionAbilityStart(); return; } apAction_t Action; m_PMob->m_ActionList.clear(); Action.ActionTarget = m_PBattleTarget; Action.reaction = REACTION_EVADE; Action.speceffect = SPECEFFECT_NONE; Action.animation = 0; Action.param = 0; Action.messageID = 15; Action.flag = 0; uint16 damage = 0; if (m_PBattleTarget->StatusEffectContainer->HasStatusEffect(EFFECT_PERFECT_DODGE)) { Action.messageID = 32; } else if ( rand()%90 < battleutils::GetHitRate(m_PMob, m_PBattleTarget) ) { if (battleutils::IsAbsorbByShadow(m_PBattleTarget)) { Action.messageID = 0; m_PBattleTarget->loc.zone->PushPacket(m_PBattleTarget,CHAR_INRANGE_SELF, new CMessageBasicPacket(m_PBattleTarget,m_PBattleTarget,0,1,31)); } else { Action.reaction = REACTION_HIT; Action.speceffect = SPECEFFECT_HIT; Action.messageID = 1; float DamageRatio = battleutils::GetDamageRatio(m_PMob, m_PBattleTarget); if ( rand()%100 < battleutils::GetCritHitRate(m_PMob, m_PBattleTarget) ) { DamageRatio += 1; DamageRatio = (DamageRatio > 3 ? 3 : DamageRatio); Action.speceffect = SPECEFFECT_CRITICAL_HIT; Action.messageID = 67; } damage = (uint16)((m_PMob->m_Weapons[SLOT_MAIN]->getDamage() + battleutils::GetFSTR(m_PMob, m_PBattleTarget)) * DamageRatio); } } else if (m_PBattleTarget->objtype == TYPE_PC) { charutils::TrySkillUP((CCharEntity*)m_PBattleTarget, SKILL_EVA, m_PMob->GetMLevel()); } Action.param = battleutils::TakePhysicalDamage(m_PMob, m_PBattleTarget, damage); m_PMob->m_ActionList.push_back(Action); m_PMob->PEnmityContainer->UpdateEnmityFromAttack(m_PBattleTarget, Action.param); m_PMob->loc.zone->PushPacket(m_PMob, CHAR_INRANGE, new CActionPacket(m_PMob)); } m_LastActionTime = m_Tick; } } else { battleutils::MoveTo(m_PMob, m_PBattleTarget->loc.p, 2); } m_PMob->loc.zone->PushPacket(m_PMob,CHAR_INRANGE, new CEntityUpdatePacket(m_PMob, ENTITY_UPDATE)); }