bool CAbilityState::CanUseAbility() { if (m_PEntity->objtype == TYPE_MOB || m_PEntity->objtype == TYPE_PET) return true; if (m_PEntity->objtype == TYPE_PC) { auto PAbility = GetAbility(); auto PChar = static_cast<CCharEntity*>(m_PEntity); if (PChar->PRecastContainer->HasRecast(RECAST_ABILITY, PAbility->getRecastId(), PAbility->getRecastTime())) { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 0, MSGBASIC_WAIT_LONGER)); return false; } if (PChar->StatusEffectContainer->HasStatusEffect({EFFECT_AMNESIA, EFFECT_IMPAIRMENT})) { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 0, MSGBASIC_UNABLE_TO_USE_JA2)); return false; } std::unique_ptr<CMessageBasicPacket> errMsg; auto PTarget = GetTarget(); if (PChar->IsValidTarget(PTarget->targid, PAbility->getValidTarget(), errMsg)) { if (PChar != PTarget && distance(PChar->loc.p, PTarget->loc.p) > PAbility->getRange()) { PChar->pushPacket(new CMessageBasicPacket(PChar, PTarget, 0, 0, MSGBASIC_TOO_FAR_AWAY)); return false; } if (!m_PEntity->PAI->TargetFind->canSee(&PTarget->loc.p)) { m_errorMsg = std::make_unique<CMessageBasicPacket>(m_PEntity, PTarget, PAbility->getID(), 0, MSGBASIC_CANNOT_PERFORM_ACTION); return false; } if (PAbility->getID() >= ABILITY_HEALING_RUBY) { // Blood pact MP costs are stored under animation ID if (PChar->health.mp < PAbility->getAnimationID()) { PChar->pushPacket(new CMessageBasicPacket(PChar, PTarget, 0, 0, MSGBASIC_UNABLE_TO_USE_JA)); return false; } } CBaseEntity* PMsgTarget = PChar; int32 errNo = luautils::OnAbilityCheck(PChar, PTarget, PAbility, &PMsgTarget); if (errNo != 0) { PChar->pushPacket(new CMessageBasicPacket(PChar, PMsgTarget, PAbility->getID() + 16, PAbility->getID(), errNo)); return false; } return true; } return false; } return true; }
bool CanLearnAbility(CBattleEntity* PUser, uint16 AbilityID) { if (GetAbility(AbilityID) != nullptr) { uint8 Job = PAbilityList[AbilityID]->getJob(); uint8 JobLvl = PAbilityList[AbilityID]->getLevel(); return ((PUser->GetMJob() == Job && PUser->GetMLevel() >= JobLvl) || (PUser->GetSJob() == Job && PUser->GetSLevel() >= JobLvl)); } return false; }
void Player::AddAbility(Game_Manager * gm_, const char * abil_name) { Ability * abil = nullptr; Ability::GetAbilityByName(this, abil_name, &abil); assert(abil != nullptr); GetAbility(gm_, abil); for(auto it = select_abil_list.begin();it!=select_abil_list.end();it++) delete (*it); select_abil_list.clear(); ability_select = false; remain_ability--; if(remain_ability) Ability::GetAbility(this, select_ability_num); }