Skip to content
This repository has been archived by the owner on Dec 4, 2020. It is now read-only.

Commit

Permalink
Merge pull request #581 from brianmask/trust
Browse files Browse the repository at this point in the history
Ensure trust spells are level appropriate
  • Loading branch information
zircon-tpl authored May 7, 2020
2 parents e529b01 + f3550d4 commit 651b919
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 5 deletions.
20 changes: 18 additions & 2 deletions src/map/ai/helpers/gambits_container.cpp
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
#include "gambits_container.h"

#include "../../spell.h"
#include "../../utils/battleutils.h"

void CGambitsContainer::AddGambit(G_SELECTOR selector, G_TRIGGER trigger, uint16 trigger_condition, G_REACTION reaction, G_REACTION_MODIFIER reaction_mod, uint16 reaction_arg, uint16 retry_delay)
{
actions.push_back(Action_t{ selector, trigger, trigger_condition, reaction, reaction_mod, reaction_arg, retry_delay });
bool available = true;
if (reaction == G_REACTION::MA && reaction_mod == G_REACTION_MODIFIER::SELECT_SPECIFIC)
{
if (!spell::CanUseSpell(static_cast<CBattleEntity*>(POwner), static_cast<SpellID>(reaction_arg)))
{
available = false;
}
}
if (available)
{
actions.push_back(Action_t{ selector, trigger, trigger_condition, reaction, reaction_mod, reaction_arg, retry_delay });
}
}

void CGambitsContainer::Tick(time_point tick)
Expand Down Expand Up @@ -135,7 +147,11 @@ void CGambitsContainer::Tick(time_point tick)
{
if (action.reaction_mod == G_REACTION_MODIFIER::SELECT_SPECIFIC)
{
controller->Cast(target->targid, static_cast<SpellID>(action.reaction_arg));
auto spell_id = POwner->SpellContainer->GetAvailable(static_cast<SpellID>(action.reaction_arg));
if (spell_id.has_value())
{
controller->Cast(target->targid, static_cast<SpellID>(spell_id.value()));
}
}
else if (action.reaction_mod == G_REACTION_MODIFIER::SELECT_HIGHEST)
{
Expand Down
13 changes: 11 additions & 2 deletions src/map/mob_spell_container.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,15 @@ void CMobSpellContainer::RemoveSpell(SpellID spellId)
m_hasSpells = !(m_gaList.empty() && m_damageList.empty() && m_buffList.empty() && m_debuffList.empty() && m_healList.empty() && m_naList.empty());
}

std::optional<SpellID> CMobSpellContainer::GetAvailable(SpellID spellId)
{
auto spell = spell::GetSpell(spellId);
bool hasEnoughMP = spell->getMPCost() <= m_PMob->health.mp;
bool isNotInRecast = !m_PMob->PRecastContainer->Has(RECAST_MAGIC, static_cast<uint16>(spellId));

return (isNotInRecast && hasEnoughMP) ? std::optional<SpellID>(spellId) : std::nullopt;
}

std::optional<SpellID> CMobSpellContainer::GetBestAvailable(SPELLFAMILY family)
{
std::vector<SpellID> matches;
Expand All @@ -117,9 +126,9 @@ std::optional<SpellID> CMobSpellContainer::GetBestAvailable(SPELLFAMILY family)
{
auto spell = spell::GetSpell(id);
bool sameFamily = (family == SPELLFAMILY_NONE) ? true : spell->getSpellFamily() == family;
bool hasEnougnMP = spell->getMPCost() <= m_PMob->health.mp;
bool hasEnoughMP = spell->getMPCost() <= m_PMob->health.mp;
bool isNotInRecast = !m_PMob->PRecastContainer->Has(RECAST_MAGIC, static_cast<uint16>(id));
if (sameFamily && hasEnougnMP && isNotInRecast)
if (sameFamily && hasEnoughMP && isNotInRecast)
{
matches.push_back(id);
}
Expand Down
1 change: 1 addition & 0 deletions src/map/mob_spell_container.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class CMobSpellContainer
void AddSpell(SpellID spellId);
void RemoveSpell(SpellID spellId);

std::optional<SpellID> GetAvailable(SpellID spellId);
std::optional<SpellID> GetBestAvailable(SPELLFAMILY family);

std::vector<SpellID> m_gaList;
Expand Down
8 changes: 7 additions & 1 deletion src/map/spell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -602,8 +602,14 @@ namespace spell
{
// cant cast cause im hidden or untargetable
if (PCaster->IsNameHidden() || static_cast<CMobEntity*>(PCaster)->IsUntargetable())
{
return false;

}
// ensure trust level is appropriate+
if (PCaster->objtype == TYPE_TRUST && PCaster->GetMLevel() < JobMLVL)
{
return false;
}
// Mobs can cast any non-given char spell
return true;
}
Expand Down

0 comments on commit 651b919

Please sign in to comment.