void CAIPetDummy::ActionMagicCasting() { m_PPathFind->LookAt(m_PMagicState->GetTarget()->loc.p); STATESTATUS status = m_PMagicState->Update(m_Tick); if(status == STATESTATUS_INTERRUPT) { m_ActionType = ACTION_MAGIC_INTERRUPT; ActionMagicInterrupt(); } else if(status == STATESTATUS_ERROR) { TransitionBack(true); } else if(status == STATESTATUS_FINISH) { m_ActionType = ACTION_MAGIC_FINISH; ActionMagicFinish(); } else { m_PPet->loc.zone->PushPacket(m_PPet,CHAR_INRANGE, new CEntityUpdatePacket(m_PPet, ENTITY_UPDATE)); } }
void CAIPetDummy::ActionSleep() { if (!m_PPet->StatusEffectContainer->HasPreventActionEffect()) { TransitionBack(); } }
void CAIPetDummy::ActionEngage() { DSP_DEBUG_BREAK_IF(m_PBattleTarget == nullptr); if (m_PPet->PMaster == nullptr || m_PPet->PMaster->isDead()) { m_ActionType = ACTION_FALL; ActionFall(); return; } if (battleutils::HasClaim(m_PPet, m_PBattleTarget)) { m_PPet->animation = ANIMATION_ATTACK; m_PPet->updatemask |= UPDATE_HP; m_LastActionTime = m_Tick - 1000; TransitionBack(true); } else { m_PPet->animation = ANIMATION_NONE; m_PPet->updatemask |= UPDATE_HP; if (m_PPet->PMaster->objtype == TYPE_PC) { ((CCharEntity*)m_PPet->PMaster)->pushPacket(new CMessageBasicPacket(((CCharEntity*)m_PPet->PMaster), ((CCharEntity*)m_PPet->PMaster), 0, 0, 12)); m_ActionType = ACTION_DISENGAGE; return; } } }
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 CAIPetDummy::ActionSleep() { if (!m_PPet->StatusEffectContainer->HasPreventActionEffect()) { TransitionBack(); } m_PPet->loc.zone->PushPacket(m_PPet,CHAR_INRANGE, new CEntityUpdatePacket(m_PPet, ENTITY_UPDATE)); }
void CAIPetDummy::ActionMagicInterrupt() { m_LastActionTime = m_Tick; m_LastMagicTime = m_Tick; m_PMagicState->InterruptSpell(); m_PSpell = nullptr; m_PBattleSubTarget = nullptr; TransitionBack(); }
void CAIPetDummy::preparePetAbility(CBattleEntity* PTarg){ if (m_PMobSkill != nullptr){ apAction_t Action; m_PPet->m_ActionList.clear(); // find correct targe if (m_PMobSkill->getValidTargets() & TARGET_SELF) { //self m_PBattleSubTarget = m_PPet; } else if (m_PMobSkill->getValidTargets() & TARGET_PLAYER_PARTY) { // Only overwrite the sub target if it it not specified or // the input target doesn't match the sub target. if (m_PBattleSubTarget == nullptr || PTarg != m_PBattleSubTarget) { m_PBattleSubTarget = m_PPet->PMaster; } } else { if (m_PBattleTarget != nullptr) { m_PBattleSubTarget = m_PBattleTarget; } DSP_DEBUG_BREAK_IF(m_PBattleSubTarget == nullptr); } Action.ActionTarget = m_PBattleSubTarget; Action.reaction = REACTION_HIT; Action.speceffect = SPECEFFECT_HIT; Action.animation = 0; Action.param = m_PMobSkill->getMsgForAction(); Action.messageID = 43; //readies message Action.knockback = 0; m_skillTP = m_PPet->health.tp; m_PPet->health.tp = 0; m_PPet->m_ActionList.push_back(Action); m_PPet->loc.zone->PushPacket(m_PPet, CHAR_INRANGE, new CActionPacket(m_PPet)); m_LastActionTime = m_Tick; m_ActionType = ACTION_MOBABILITY_USING; } else{ ShowWarning("ai_pet_dummy::ActionAbilityFinish Pet skill is NULL \n"); TransitionBack(true); } }
void CAIPetDummy::ActionDisengage() { if( m_PPet->PMaster==NULL || m_PPet->PMaster->isDead()){ m_ActionType = ACTION_FALL; ActionFall(); return; } m_PPet->animation = ANIMATION_NONE; m_LastActionTime = m_Tick; m_PBattleTarget = NULL; TransitionBack(); m_PPet->loc.zone->PushPacket(m_PPet, CHAR_INRANGE, new CEntityUpdatePacket(m_PPet, ENTITY_UPDATE)); }
void CAIPetDummy::ActionMagicInterrupt() { m_LastActionTime = m_Tick; m_LastMagicTime = m_Tick; m_PMagicState->InterruptSpell(); m_PPet->loc.zone->PushPacket(m_PPet,CHAR_INRANGE, new CEntityUpdatePacket(m_PPet, ENTITY_UPDATE)); m_PSpell = NULL; m_PBattleSubTarget = NULL; TransitionBack(); }
void CAIPetDummy::ActionDisengage() { if (m_PPet->PMaster == nullptr || m_PPet->PMaster->isDead()){ m_ActionType = ACTION_FALL; ActionFall(); return; } m_queueSic = false; m_PPet->animation = ANIMATION_NONE; m_PPet->updatemask |= UPDATE_HP; m_LastActionTime = m_Tick; m_PBattleTarget = nullptr; TransitionBack(); }
void CAIPetDummy::ActionMagicCasting() { m_PPathFind->LookAt(m_PMagicState->GetTarget()->loc.p); STATESTATUS status = m_PMagicState->Update(m_Tick); if (status == STATESTATUS_INTERRUPT) { m_ActionType = ACTION_MAGIC_INTERRUPT; ActionMagicInterrupt(); } else if (status == STATESTATUS_ERROR) { TransitionBack(true); } else if (status == STATESTATUS_FINISH) { m_ActionType = ACTION_MAGIC_FINISH; ActionMagicFinish(); } }
void CAIPetDummy::ActionMagicStart() { // disabled DSP_DEBUG_BREAK_IF(m_PSpell == nullptr); DSP_DEBUG_BREAK_IF(m_PBattleSubTarget == nullptr); m_LastActionTime = m_Tick; m_LastMagicTime = m_Tick; STATESTATUS status = m_PMagicState->CastSpell(GetCurrentSpell(), m_PBattleSubTarget); if (status == STATESTATUS_START) { m_ActionType = ACTION_MAGIC_CASTING; } else { TransitionBack(true); } }
void CAIPetDummy::ActionMagicStart() { // disabled DSP_DEBUG_BREAK_IF(m_PSpell == NULL); DSP_DEBUG_BREAK_IF(m_PBattleSubTarget == NULL); m_LastActionTime = m_Tick; m_LastMagicTime = m_Tick; STATESTATUS status = m_PMagicState->CastSpell(m_PSpell, m_PBattleSubTarget); if(status == STATESTATUS_START) { m_ActionType = ACTION_MAGIC_CASTING; m_PPet->loc.zone->PushPacket(m_PPet,CHAR_INRANGE, new CEntityUpdatePacket(m_PPet, ENTITY_UPDATE)); } else { TransitionBack(true); } }
void CAIUltimateSummon::ActionEngage() { DSP_DEBUG_BREAK_IF(m_PBattleTarget == NULL); if( m_PPet->PMaster==NULL || m_PPet->PMaster->isDead()) { m_ActionType = ACTION_FALL; ActionFall(); return; } bool hasClaim = false; if(m_PBattleTarget->m_OwnerID.id == m_PPet->PMaster->id) hasClaim = true; if(m_PBattleTarget->m_OwnerID.id == 0) hasClaim = true; if(m_PPet->PMaster->PParty != NULL) { // alliance if (m_PPet->PMaster->PParty->m_PAlliance != NULL) { for (uint8 a = 0; a < m_PPet->PMaster->PParty->m_PAlliance->partyList.size(); ++a) { for (uint8 i = 0; i < m_PPet->PMaster->PParty->m_PAlliance->partyList.at(a)->members.size(); ++i) { if (m_PPet->PMaster->PParty->m_PAlliance->partyList.at(a)->members[i]->id == m_PBattleTarget->m_OwnerID.id) hasClaim = true; } } } else // party for (uint8 i = 0; i < m_PPet->PMaster->PParty->members.size(); ++i) { if (m_PPet->PMaster->PParty->members[i]->id == m_PBattleTarget->m_OwnerID.id) hasClaim = true; } } if(hasClaim) { m_PPet->animation = ANIMATION_ATTACK; m_LastActionTime = m_Tick - 1000; TransitionBack(true); m_PPet->loc.zone->PushPacket(m_PPet,CHAR_INRANGE, new CEntityUpdatePacket(m_PPet, ENTITY_UPDATE)); } else { m_PPet->animation = ANIMATION_NONE; if(m_PPet->PMaster->objtype == TYPE_PC) { ((CCharEntity*)m_PPet->PMaster)->pushPacket(new CMessageBasicPacket(((CCharEntity*)m_PPet->PMaster), ((CCharEntity*)m_PPet->PMaster),0,0,12)); m_ActionType = ACTION_ROAMING; return; } } }
void CAIPetDummy::ActionEngage() { DSP_DEBUG_BREAK_IF(m_PBattleTarget == nullptr); if (m_PPet->PMaster == nullptr || m_PPet->PMaster->isDead()) { m_ActionType = ACTION_FALL; ActionFall(); return; } bool hasClaim = false; if (m_PBattleTarget->m_OwnerID.id == m_PPet->PMaster->id) hasClaim = true; if (m_PBattleTarget->m_OwnerID.id == 0) hasClaim = true; if (m_PPet->PMaster->PParty != nullptr) { // alliance if (m_PPet->PMaster->PParty->m_PAlliance != nullptr) { for (uint8 a = 0; a < m_PPet->PMaster->PParty->m_PAlliance->partyList.size(); ++a) { for (uint8 i = 0; i < m_PPet->PMaster->PParty->m_PAlliance->partyList.at(a)->members.size(); ++i) { if (m_PPet->PMaster->PParty->m_PAlliance->partyList.at(a)->members[i]->id == m_PBattleTarget->m_OwnerID.id) hasClaim = true; } } } else // party for (uint8 i = 0; i < m_PPet->PMaster->PParty->members.size(); ++i) { if (m_PPet->PMaster->PParty->members[i]->id == m_PBattleTarget->m_OwnerID.id) hasClaim = true; } } if (hasClaim) { m_PPet->animation = ANIMATION_ATTACK; m_PPet->updatemask |= UPDATE_HP; m_LastActionTime = m_Tick - 1000; TransitionBack(true); } else { m_PPet->animation = ANIMATION_NONE; m_PPet->updatemask |= UPDATE_HP; if (m_PPet->PMaster->objtype == TYPE_PC) { ((CCharEntity*)m_PPet->PMaster)->pushPacket(new CMessageBasicPacket(((CCharEntity*)m_PPet->PMaster), ((CCharEntity*)m_PPet->PMaster), 0, 0, 12)); m_ActionType = ACTION_DISENGAGE; return; } } }
void CAIPetDummy::ActionAbilityStart() { if (m_PPet->StatusEffectContainer->HasPreventActionEffect()) { return; } if (m_PPet->objtype == TYPE_MOB && m_PPet->PMaster->objtype == TYPE_PC) { if (m_MasterCommand == MASTERCOMMAND_SIC && m_PPet->health.tp >= 1000 && m_PBattleTarget != nullptr) { m_MasterCommand = MASTERCOMMAND_NONE; CMobEntity* PMob = (CMobEntity*)m_PPet->PMaster->PPet; std::vector<CMobSkill*> MobSkills = battleutils::GetMobSkillsByFamily(PMob->m_Family); if (MobSkills.size() > 0) { int maxSearch = 10; // keep looking for an ability until one is valid do { SetCurrentMobSkill(MobSkills.at(dsprand::GetRandomNumber(MobSkills.size()))); } while (luautils::OnMobSkillCheck(m_PBattleTarget, m_PPet, GetCurrentMobSkill()) != 0 && maxSearch--); // could not find skill if (maxSearch == 0) { TransitionBack(true); return; } preparePetAbility(m_PBattleTarget); return; } return; } } if (m_PPet->getPetType() == PETTYPE_JUG_PET){ if (m_MasterCommand == MASTERCOMMAND_SIC && m_PPet->health.tp >= 1000 && m_PBattleTarget != nullptr){ //choose random tp move m_MasterCommand = MASTERCOMMAND_NONE; if (m_PPet->PetSkills.size() > 0){ SetCurrentMobSkill(m_PPet->PetSkills.at(dsprand::GetRandomNumber(m_PPet->PetSkills.size()))); preparePetAbility(m_PBattleTarget); return; } } } else if (m_PPet->getPetType() == PETTYPE_AVATAR){ for (int i = 0; i < m_PPet->PetSkills.size(); i++){ if (m_PPet->PetSkills[i]->getAnimationTime() == m_MasterCommand){ SetCurrentMobSkill(m_PPet->PetSkills[i]); m_MasterCommand = MASTERCOMMAND_NONE; preparePetAbility(m_PPet); return; } } m_MasterCommand = MASTERCOMMAND_NONE; } else if (m_PPet->getPetType() == PETTYPE_WYVERN){ WYVERNTYPE wyverntype = m_PPet->getWyvernType(); if (m_MasterCommand == MASTERCOMMAND_ELEMENTAL_BREATH && (wyverntype == WYVERNTYPE_MULTIPURPOSE || wyverntype == WYVERNTYPE_OFFENSIVE)){ m_MasterCommand = MASTERCOMMAND_NONE; //offensive or multipurpose wyvern if (m_PBattleTarget != nullptr){ //prepare elemental breaths int skip = dsprand::GetRandomNumber(6); int hasSkipped = 0; for (int i = 0; i < m_PPet->PetSkills.size(); i++){ if (m_PPet->PetSkills[i]->getValidTargets() == TARGET_ENEMY){ if (hasSkipped == skip){ SetCurrentMobSkill(m_PPet->PetSkills[i]); break; } else{ hasSkipped++; } } } preparePetAbility(m_PBattleTarget); return; } } else if (m_MasterCommand == MASTERCOMMAND_HEALING_BREATH && (wyverntype == WYVERNTYPE_DEFENSIVE || wyverntype == WYVERNTYPE_MULTIPURPOSE)) { m_MasterCommand = MASTERCOMMAND_NONE; m_PBattleSubTarget = nullptr; //TODO: CHECK FOR STATUS EFFECTS FOR REMOVE- BREATH (higher priority than healing breaths) // if(m_PPet->PMaster->PParty==nullptr){//solo with master-kun CItemArmor* masterHeadItem = ((CCharEntity*)(m_PPet->PMaster))->getEquip(SLOT_HEAD); uint16 masterHead = masterHeadItem ? masterHeadItem->getID() : 0; // Determine what the required HP percentage will need to be // at or under in order for healing breath to activate. uint8 requiredHPP = 0; if (((CCharEntity*)(m_PPet->PMaster))->objtype == TYPE_PC && (masterHead == 12519 || masterHead == 15238)) { //Check for player & AF head, or +1 if (wyverntype == WYVERNTYPE_DEFENSIVE) { //healer wyvern requiredHPP = 50; } else if (wyverntype == WYVERNTYPE_MULTIPURPOSE) { //hybrid wyvern requiredHPP = 33; } } else { if (wyverntype == WYVERNTYPE_DEFENSIVE) { //healer wyvern requiredHPP = 33; } else if (wyverntype == WYVERNTYPE_MULTIPURPOSE) { //hybrid wyvern requiredHPP = 25; } } // Only attempt to find a target if there is an HP percentage to calculate. if (requiredHPP) { CBattleEntity* master = m_PPet->PMaster; // Check the master first. if (master->GetHPP() <= requiredHPP) { m_PBattleSubTarget = master; } // Otherwise if this is a healer wyvern, and the member is in a party // check all of the party members who qualify. else if (wyverntype == WYVERNTYPE_DEFENSIVE && master->PParty != nullptr) { master->ForParty([this, requiredHPP](CBattleEntity* PTarget){ if (PTarget->GetHPP() <= requiredHPP) { m_PBattleSubTarget = PTarget; } }); } } if (m_PBattleSubTarget != nullptr){ //target to heal //get highest breath for wyverns level m_PMobSkill = nullptr; for (int i = 0; i < m_PPet->PetSkills.size(); i++){ if (m_PPet->PetSkills[i]->getValidTargets() == TARGET_PLAYER_PARTY){ if (m_PPet->PetSkills[i]->getID() == 638 && m_PPet->PMaster->GetMLevel() < 20){ //can only using hb1 SetCurrentMobSkill(m_PPet->PetSkills[i]); break; } else if (m_PPet->PetSkills[i]->getID() == 639 && m_PPet->PMaster->GetMLevel() < 40){ //can only using hb2 SetCurrentMobSkill(m_PPet->PetSkills[i]); break; } else if (m_PPet->PetSkills[i]->getID() == 640 && m_PPet->PMaster->GetMLevel() >= 40){ //can only using hb3 SetCurrentMobSkill(m_PPet->PetSkills[i]); break; } } } preparePetAbility(m_PBattleSubTarget); return; } } } TransitionBack(true); }
void CAIPetDummy::ActionAbilityStart() { if(m_PPet->StatusEffectContainer->HasPreventActionEffect()) { return; } if(m_PPet->objtype == TYPE_MOB && m_PPet->PMaster->objtype == TYPE_PC) { if(m_MasterCommand == MASTERCOMMAND_SIC && m_PPet->health.tp >= 100 && m_PBattleTarget != NULL) { m_MasterCommand = MASTERCOMMAND_NONE; CMobEntity* PMob = (CMobEntity*)m_PPet->PMaster->PPet; std::vector<CMobSkill*> MobSkills = battleutils::GetMobSkillsByFamily(PMob->m_Family); if(MobSkills.size() > 0) { int maxSearch = 10; // keep looking for an ability until one is valid do { m_PMobSkill = MobSkills.at(rand() % MobSkills.size()); } while(luautils::OnMobSkillCheck(m_PBattleTarget, m_PPet, m_PMobSkill) != 0 && maxSearch--); // could not find skill if(maxSearch == 0) { TransitionBack(true); return; } preparePetAbility(m_PBattleTarget); return; } return; } } if(m_PPet->getPetType()==PETTYPE_JUG_PET){ if(m_MasterCommand==MASTERCOMMAND_SIC && m_PPet->health.tp>=100 && m_PBattleTarget!=NULL){ //choose random tp move m_MasterCommand = MASTERCOMMAND_NONE; if(m_PPet->PetSkills.size()>0){ m_PMobSkill = m_PPet->PetSkills.at(rand() % m_PPet->PetSkills.size()); preparePetAbility(m_PBattleTarget); return; } } } else if(m_PPet->getPetType()==PETTYPE_AVATAR){ for(int i=0; i<m_PPet->PetSkills.size(); i++){ if(m_PPet->PetSkills[i]->getAnimationTime() == m_MasterCommand){ m_PMobSkill = m_PPet->PetSkills[i]; m_MasterCommand = MASTERCOMMAND_NONE; preparePetAbility(m_PPet); return; } } m_MasterCommand = MASTERCOMMAND_NONE; } else if(m_PPet->getPetType()==PETTYPE_WYVERN){ WYVERNTYPE wyverntype = m_PPet->getWyvernType(); if(m_MasterCommand==MASTERCOMMAND_ELEMENTAL_BREATH && (wyverntype == WYVERNTYPE_MULTIPURPOSE || wyverntype == WYVERNTYPE_OFFENSIVE)){ m_MasterCommand = MASTERCOMMAND_NONE; //offensive or multipurpose wyvern if(m_PBattleTarget != NULL){ //prepare elemental breaths int skip = rand()%6; int hasSkipped = 0; for(int i=0; i<m_PPet->PetSkills.size(); i++){ if(m_PPet->PetSkills[i]->getValidTargets() == TARGET_ENEMY){ if(hasSkipped == skip){ m_PMobSkill = m_PPet->PetSkills[i]; break; } else{ hasSkipped++; } } } preparePetAbility(m_PBattleTarget); return; } } else if(m_MasterCommand==MASTERCOMMAND_HEALING_BREATH && (wyverntype == WYVERNTYPE_DEFENSIVE || wyverntype == WYVERNTYPE_MULTIPURPOSE)) { m_MasterCommand = MASTERCOMMAND_NONE; m_PBattleSubTarget = NULL; //TODO: CHECK FOR STATUS EFFECTS FOR REMOVE- BREATH (higher priority than healing breaths) // if(m_PPet->PMaster->PParty==NULL){//solo with master-kun uint16 masterHead = ((CCharEntity*)(m_PPet->PMaster))->getStorage(LOC_INVENTORY)->GetItem(((CCharEntity*)(m_PPet->PMaster))->equip[SLOT_HEAD])->getID(); if(((CCharEntity*)(m_PPet->PMaster))->objtype == TYPE_PC && (masterHead == 12519 || masterHead == 15238)) { //Check for player & AF head, or +1 if(m_PPet->PMaster->GetHPP() <= 50 && wyverntype == WYVERNTYPE_DEFENSIVE){//healer wyvern m_PBattleSubTarget = m_PPet->PMaster; } else if(m_PPet->PMaster->GetHPP() <= 33 && wyverntype == WYVERNTYPE_MULTIPURPOSE){//hybrid wyvern m_PBattleSubTarget = m_PPet->PMaster; } } else { if(m_PPet->PMaster->GetHPP() <= 33 && wyverntype == WYVERNTYPE_DEFENSIVE) {//healer wyvern m_PBattleSubTarget = m_PPet->PMaster; } else if(m_PPet->PMaster->GetHPP() <= 25 && wyverntype == WYVERNTYPE_MULTIPURPOSE) {//hybrid wyvern m_PBattleSubTarget = m_PPet->PMaster; } } // } // else{ //group play // //for( int i=0; i< // } if(m_PBattleSubTarget != NULL){ //target to heal //get highest breath for wyverns level m_PMobSkill = NULL; for(int i=0; i<m_PPet->PetSkills.size(); i++){ if(m_PPet->PetSkills[i]->getValidTargets() == TARGET_PLAYER_PARTY){ if(m_PPet->PetSkills[i]->getID()==638 && m_PPet->PMaster->GetMLevel() < 20){ //can only using hb1 m_PMobSkill = m_PPet->PetSkills[i]; break; } else if(m_PPet->PetSkills[i]->getID()==639 && m_PPet->PMaster->GetMLevel() < 40){ //can only using hb2 m_PMobSkill = m_PPet->PetSkills[i]; break; } else if(m_PPet->PetSkills[i]->getID()==640 && m_PPet->PMaster->GetMLevel() >= 40){ //can only using hb3 m_PMobSkill = m_PPet->PetSkills[i]; break; } } } preparePetAbility(m_PBattleSubTarget); return; } } } TransitionBack(true); }