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

ensure trust spells are level appropriate #581

Merged
merged 2 commits into from
May 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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