Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…ePlus into features
  • Loading branch information
doug1234 committed Feb 26, 2024
2 parents 3fbe11a + 2863e8a commit c8c084b
Show file tree
Hide file tree
Showing 65 changed files with 1,084 additions and 94 deletions.
32 changes: 29 additions & 3 deletions TemplePlus/action_sequence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2138,6 +2138,20 @@ int32_t ActionSequenceSystem::DoAoosByAdjcentEnemies(objHndl obj)
// return _AOOSthg2_100981C0(obj);
}

int32_t ActionSequenceSystem::ProvokeAooFrom(objHndl provoker, objHndl enemy)
{
if (objects.GetFlags(enemy) & OF_INVULNERABLE) // see above
return 0;

if (!combatSys.CanMeleeTarget(enemy, provoker)) return 0;
if (critterSys.IsFriendly(provoker, enemy)) return 0;
if (!d20Sys.d20QueryWithData(enemy, DK_QUE_AOOPossible, provoker)) return 0;
if (!d20Sys.d20QueryWithData(enemy, DK_QUE_AOOWillTake, provoker)) return 0;

DoAoo(enemy, provoker);
return 1;
}

bool ActionSequenceSystem::SpellTargetsFilterInvalid(D20Actn& d20a){

auto valid = true;
Expand Down Expand Up @@ -2810,13 +2824,25 @@ void ActionSequenceSystem::ActionPerform()
}

else{
bool preempted = false;
switch (d20->D20ActionTriggersAoO(d20a, &tbStatus))
{
case 0:
break;
case 2:
preempted = ProvokeAooFrom(d20a->d20APerformer, d20a->d20ATarget);
break;
case 1:
default:
preempted = DoAoosByAdjcentEnemies(d20a->d20APerformer);
break;
}

if ( d20->D20ActionTriggersAoO(d20a, &tbStatus) && DoAoosByAdjcentEnemies(d20a->d20APerformer)) {
if (preempted) {
logger->debug("ActionPerform: \t Sequence Preempted {}", d20a->d20APerformer);
--*(curIdx);
sequencePerform();
}
else{
} else {
curSeq->tbStatus = tbStatus;
*(uint32_t*)(&curSeq->tbStatus.tbsFlags) |= TBSF_HasActedThisRound;
InterruptCounterspell(d20a);
Expand Down
1 change: 1 addition & 0 deletions TemplePlus/action_sequence.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ struct ActionSequenceSystem : temple::AddressTable
uint32_t seqCheckFuncs(TurnBasedStatus *tbStatus);
void DoAoo(objHndl, objHndl);
int32_t DoAoosByAdjcentEnemies(objHndl);
int32_t ProvokeAooFrom(objHndl provoker, objHndl enemy);

bool SpellTargetsFilterInvalid(D20Actn &d20a);
void HandleInterruptSequence();
Expand Down
81 changes: 51 additions & 30 deletions TemplePlus/animgoals/anim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,62 +457,83 @@ int AnimSystem::PushAnimate(objHndl obj, int anim) {
return addresses.PushAnimate(obj, anim);
}

BOOL AnimSystem::PushSpellCast(SpellPacketBody & spellPkt, objHndl item)
void AnimSystem::SetGoalDataForSpellPacket(SpellPacketBody & pkt, AnimSlotGoalStackEntry & goalData, bool wand, bool conjure)
{

// note: the original included the spell ID generation & registration, this is separated here.
auto caster = spellPkt.caster;
auto caster = pkt.caster;
auto casterObj = objSystem->GetObject(caster);
AnimSlotGoalStackEntry goalData;
if (!goalData.InitWithInterrupt(caster, ag_throw_spell_w_cast_anim))
return FALSE;
SpellEntry ent(pkt.spellEnum);

goalData.skillData.number = spellPkt.spellId;

SpellEntry spEntry(spellPkt.spellEnum);
goalData.skillData.number = pkt.spellId;

// if self-targeted spell
if (spEntry.IsBaseModeTarget(UiPickerType::Single) && spellPkt.targetCount == 0 ){
goalData.target.obj = spellPkt.caster;

if (spellPkt.aoeCenter.location.location == 0){
if (ent.IsBaseModeTarget(UiPickerType::Single) && pkt.targetCount == 0) {
goalData.target.obj = caster;
if (pkt.aoeCenter.location.location == 0)
goalData.targetTile.location = casterObj->GetLocationFull();
}
else{
goalData.targetTile.location = spellPkt.aoeCenter.location;
}
}
else
goalData.targetTile.location = pkt.aoeCenter.location;

else{
auto tgt = spellPkt.targetListHandles[0];
} else {
auto tgt = pkt.targetListHandles[0];
goalData.target.obj = tgt;
if (tgt && spellPkt.aoeCenter.location.location == 0 ){
if (tgt && pkt.aoeCenter.location.location == 0) {
goalData.targetTile.location = objSystem->GetObject(tgt)->GetLocationFull();
}
else {
goalData.targetTile.location = spellPkt.aoeCenter.location;
} else {
goalData.targetTile.location = pkt.aoeCenter.location;
}
}

if (inventory.UsesWandAnim(item)){
goalData.animIdPrevious.number = temple::GetRef<int(__cdecl)(int)>(0x100757C0)(spEntry.spellSchoolEnum); // GetAnimIdWand
if (wand){
goalData.animIdPrevious.number = GetWandAnimId(ent.spellSchoolEnum, conjure);
}
else{
goalData.animIdPrevious.number = temple::GetRef<int(__cdecl)(int)>(0x100757B0)(spEntry.spellSchoolEnum); // GetSpellSchoolAnimId
goalData.animIdPrevious.number = GetCastingAnimId(ent.spellSchoolEnum, conjure);
}
}

BOOL AnimSystem::PushSpellCast(SpellPacketBody & spellPkt, objHndl item)
{
// note: the original included the spell ID generation & registration, this is separated here.
AnimSlotGoalStackEntry goalData;
if (!goalData.InitWithInterrupt(spellPkt.caster, ag_throw_spell_w_cast_anim))
return FALSE;

SetGoalDataForSpellPacket(spellPkt, goalData, inventory.UsesWandAnim(item), false);

return goalData.Push(nullptr);
}

BOOL AnimSystem::PushSpellDismiss(SpellPacketBody & pkt)
{
AnimSlotGoalStackEntry goalData;
if (!goalData.InitWithInterrupt(pkt.caster, ag_throw_spell_w_cast_anim))
return FALSE;

SetGoalDataForSpellPacket(pkt, goalData, true, true);

return goalData.Push(nullptr);
}

int AnimSystem::GetWandAnimId(int school, bool conjure) {
auto dec = conjure ? 1 : 0;
return temple::GetRef<int(__cdecl)(int)>(0x100757C0)(school) - dec;
}

int AnimSystem::GetCastingAnimId(int school, bool conjure) {
auto dec = conjure ? 1 : 0;
return temple::GetRef<int(__cdecl)(int)>(0x100757B0)(school) - dec;
}


BOOL AnimSystem::PushSpellInterrupt(const objHndl& caster, objHndl item, AnimGoalType animGoalType, int spellSchool){
AnimSlotGoalStackEntry goalData;
goalData.InitWithInterrupt(caster, animGoalType);
goalData.target.obj = (*actSeqSys.actSeqCur)->spellPktBody.caster;
goalData.skillData.number = 0;
if (inventory.UsesWandAnim(item))
goalData.animIdPrevious.number = temple::GetRef<int(__cdecl)(int)>(0x100757C0)(spellSchool); // GetAnimIdWand
goalData.animIdPrevious.number = GetWandAnimId(spellSchool);
else
goalData.animIdPrevious.number = temple::GetRef<int(__cdecl)(int)>(0x100757B0)(spellSchool); // GetSpellSchoolAnimId
goalData.animIdPrevious.number = GetCastingAnimId(spellSchool);

return goalData.Push(nullptr);
}
Expand Down
9 changes: 8 additions & 1 deletion TemplePlus/animgoals/anim.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,16 @@ friend struct AnimSlotGoalStackEntry;
pushes spell animation, including wand animation if relevant
*/
BOOL PushSpellCast(SpellPacketBody &spellPkt, objHndl item);

BOOL PushSpellInterrupt(const objHndl& caster, objHndl item, AnimGoalType animGoalType, int spellSchool);

/*
pushes an animation for dismissing an active spell
*/
BOOL PushSpellDismiss(SpellPacketBody &spellPkt);
int GetWandAnimId(int school, bool conjure = false);
int GetCastingAnimId(int school, bool conjure = false);
void SetGoalDataForSpellPacket(SpellPacketBody &pkt, AnimSlotGoalStackEntry &goalData, bool wand, bool conjure=false);

/*
used by the general out-of-combat mouse LMB click handler
*/
Expand Down
Loading

0 comments on commit c8c084b

Please sign in to comment.