Skip to content

Commit

Permalink
Wall of Fire
Browse files Browse the repository at this point in the history
  • Loading branch information
DMD authored and DMD committed Apr 6, 2018
1 parent c1a0b6b commit c7e1e96
Show file tree
Hide file tree
Showing 32 changed files with 348 additions and 42 deletions.
9 changes: 9 additions & 0 deletions TemplePlus/anim.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,15 @@ void AnimationGoals::GoalDestinationAdd(objHndl handle, LocAndOffsets loc){
gdIdx = 0;
}

void AnimationGoals::SetRuninfoDeallocCallback(void(* cb)()){
temple::GetRef<void(__cdecl*)()>(0x10AA4BB4) = cb;
}

bool AnimationGoals::InterruptAllForTbCombat(){
static auto interruptAllForTbCombat = temple::GetRef<BOOL(__cdecl)()>(0x1000C950);
return interruptAllForTbCombat();
}

BOOL AnimationGoals::GetSlot(AnimSlotId * runId, AnimSlot **runSlotOut){
if (!runId){
logger->error("Null runId in GetSlot()");
Expand Down
2 changes: 2 additions & 0 deletions TemplePlus/anim.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ friend class AnimSystem;

void GoalDestinationRemove(objHndl);
void GoalDestinationAdd(objHndl handle, LocAndOffsets loc);
void SetRuninfoDeallocCallback(void(__cdecl* cb)());
bool InterruptAllForTbCombat();
private:
BOOL GetSlot(AnimSlotId* runId, AnimSlot **runSlotOut);
};
Expand Down
43 changes: 38 additions & 5 deletions TemplePlus/combat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
#include "condition.h"
#include "legacyscriptsystem.h"
#include "config/config.h"
#include "d20_obj_registry.h"
#include "anim.h"


struct CombatSystemAddresses : temple::AddressTable
Expand Down Expand Up @@ -131,6 +133,9 @@ class CombatSystemReplacements : public TempleFix
orgActionBarResetCallback = replaceFunction(0x10062E60, ActionBarResetCallback);
orgTurnStart2 = replaceFunction(0x100638F0, TurnStart2);
orgCombatTurnAdvance = replaceFunction(0x100634E0, CombatTurnAdvance);
replaceFunction<BOOL(__cdecl)()>(0x10062A30, [](){ // Combat End
return combatSys.CombatEnd()?TRUE:FALSE;
});

orgCheckRangedWeaponAmmo = replaceFunction(0x100654E0, CheckRangedWeaponAmmo);

Expand Down Expand Up @@ -822,8 +827,7 @@ void LegacyCombatSystem::Subturn()

if (!actor){
logger->error("Combat Subturn: Coudn't start TB combat Turn due to no Active Critters!");
static auto combatEnd = temple::GetRef<int(__cdecl)()>(0x10062A30);
combatEnd();
CombatEnd();
return;
}

Expand Down Expand Up @@ -979,8 +983,7 @@ void LegacyCombatSystem::CritterExitCombatMode(objHndl handle) {
return;
}

static auto combatEnd = temple::GetRef<int(__cdecl)()>(0x10062A30);
if (!combatEnd())
if (!CombatEnd())
return;

static auto uiCombatResetCallback = temple::GetRef<int(__cdecl*)()>(0x10AA83F8);
Expand All @@ -1001,9 +1004,39 @@ void LegacyCombatSystem::CritterExitCombatMode(objHndl handle) {
// temple::GetRef<void(__cdecl)(objHndl)>(0x100630F0)(handle);
}

bool LegacyCombatSystem::CombatEnd(){
//static auto combatEnd = temple::GetRef<int(__cdecl)()>(0x10062A30);
if (!isCombatActive() )
return true;

d20ObjRegistrySys.D20ObjRegistrySendSignalAll(DK_SIG_Combat_End, 0, 0);
*combatSys.combatModeActive = 0;
animationGoals.SetRuninfoDeallocCallback(nullptr);
if (!animationGoals.InterruptAllForTbCombat()){
logger->debug("CombatEnd: Anim goal interrupt FAILED!");
}
static auto actSeqResetOnCombatEnd = temple::GetRef<void(__cdecl)()>(0x10097BE0);
actSeqResetOnCombatEnd();
auto &mResettingCombatSystem = temple::GetRef<BOOL>(0x10AA8448);
if (!mResettingCombatSystem)
tbSys.ExecuteExitCombatScriptForInitiativeList();
tbSys.TbCombatEnd();
if (!mResettingCombatSystem){
auto N = party.GroupListGetLen();
for (auto i=0; i < N; i++){
auto partyMember = party.GroupListGetMemberN(i);
temple::GetRef<void(__cdecl)(objHndl)>(0x100B70A0)(partyMember);
}
auto combatGiveXp = temple::GetRef<void(__cdecl)()>(0x100B88C0);
combatGiveXp();
}
return true;
}

bool LegacyCombatSystem::isCombatActive()
{
return *combatSys.combatModeActive != 0;
auto isActive = *combatSys.combatModeActive;
return isActive != 0;
}

bool LegacyCombatSystem::IsAutoAttack(){
Expand Down
1 change: 1 addition & 0 deletions TemplePlus/combat.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ struct LegacyCombatSystem : temple::AddressTable {
void CombatAdvanceTurn(objHndl obj);
BOOL IsBrawlInProgress();
void CritterExitCombatMode(objHndl handle);
bool CombatEnd(); // ends combat mode


uint32_t* combatModeActive;
Expand Down
39 changes: 33 additions & 6 deletions TemplePlus/condition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ CondStructNew ConditionSystem::mCondHezrouStenchHit;

struct ConditionSystemAddresses : temple::AddressTable
{
void(__cdecl* SetPermanentModArgsFromDataFields)(Dispatcher* dispatcher, CondStruct* condStruct, int* condArgs);
void(__cdecl*SetPermanentModArgsFromDataFields)(Dispatcher* dispatcher, CondStruct* condStruct, int* condArgs);
int(__cdecl*RemoveSpellCondition)(DispatcherCallbackArgs args);
int(__cdecl*RemoveSpellMod)(DispatcherCallbackArgs args);
ConditionSystemAddresses()
Expand Down Expand Up @@ -690,8 +690,8 @@ int RemoveSpellConditionAndMod(DispatcherCallbackArgs args)
{
auto argsCopy = args;
argsCopy.dispKey = DK_SIG_Action_Recipient;
addresses.RemoveSpellCondition(argsCopy);
addresses.RemoveSpellMod(argsCopy);
argsCopy.RemoveSpell();
argsCopy.RemoveSpellMod();
return 0;
};

Expand Down Expand Up @@ -3413,6 +3413,8 @@ int SpellCallbacks::ConcentratingActionSequenceHandler(DispatcherCallbackArgs ar
continue;
if (d20a.d20ActType == D20A_CAST_SPELL && d20a.spellId == spellId)
break;
if (d20a.d20Caf & D20CAF_FREE_ACTION) // added in Temple+ - free actions won't take up your standard action
continue;
DispatcherCallbackArgs dca;
dca.dispIO = nullptr;
dca.dispType = dispTypeD20Signal;
Expand Down Expand Up @@ -3918,11 +3920,9 @@ int SpellCallbacks::SpellDismissSignalHandler(DispatcherCallbackArgs args) {
if (dispIo->data1 != spellId)
return 0;

auto spellRemove = temple::GetRef<int(__cdecl)(DispatcherCallbackArgs)>(0x100D7620);

if (spPkt.spellEnum == 315 || args.GetData1() == 1 || spPkt.targetCount > 0){
floatSys.FloatSpellLine(args.objHndCaller, 20000, FloatLineColor::White); // a spell has expired
spellRemove(args);
args.RemoveSpell();
args.RemoveSpellMod();
}

Expand All @@ -3942,6 +3942,13 @@ int SpellCallbacks::DismissSignalHandler(DispatcherCallbackArgs args){
if (spPkt.aoeObj && spPkt.aoeObj != args.objHndCaller){
d20Sys.d20SendSignal(spPkt.aoeObj, DK_SIG_Dismiss_Spells, spPkt.spellId, 0);
}
// Spell objects. Added in Temple+ for Wall spells
for (auto i = 0u; i < spPkt.numSpellObjs && i < 128; i++) {
auto spellObj = spPkt.spellObjs[i].obj;
if (!spellObj || spellObj == args.objHndCaller) continue;
d20Sys.d20SendSignal(spellObj, DK_SIG_Dismiss_Spells, spPkt.spellId, 0);
}

for (auto i=0u; i < spPkt.targetCount; i++){
auto tgt = spPkt.targetListHandles[i];
if (!tgt || tgt == args.objHndCaller)
Expand All @@ -3961,16 +3968,24 @@ int SpellCallbacks::DismissSignalHandler(DispatcherCallbackArgs args){
d20Sys.d20SendSignal(spellObj, DK_SIG_Spell_End, spPkt.spellId, 0);
}


// adding this speciically for grease because I want to be careful
auto SP_GREASE_ENUM = 200;
if (spPkt.spellEnum == SP_GREASE_ENUM){
conds.ConditionRemove(args.objHndCaller, args.subDispNode->condNode);
}

// By now all effects should have been removed. Cross your fingers!
d20Sys.d20SendSignal(args.objHndCaller, DK_SIG_Spell_End, spPkt.spellId, 0);

}
return 0;
}

void DispatcherCallbackArgs::RemoveSpellMod() {
spCallbacks.SpellRemoveMod(*this);
}

int SpellCallbacks::SpellRemoveMod(DispatcherCallbackArgs args){

DispIoD20Signal *evtObj = nullptr;
Expand All @@ -3992,6 +4007,7 @@ int SpellCallbacks::SpellRemoveMod(DispatcherCallbackArgs args){
case DK_SIG_TouchAttackAdded:
case DK_SIG_Teleport_Prepare:
case DK_SIG_Teleport_Reconnect:
case DK_SIG_Combat_End:
break;
default:
if (evtObj && evtObj->data1 != args.GetCondArg(0))
Expand All @@ -4007,10 +4023,21 @@ int SpellCallbacks::SpellRemoveMod(DispatcherCallbackArgs args){
if (spPkt.spellEnum != 0){
floatSys.FloatCombatLine(args.objHndCaller, 5060); // Stop Concentration
d20Sys.d20SendSignal(args.objHndCaller, DK_SIG_Concentration_Broken, spellId, 0);

if (spPkt.caster && spPkt.caster != args.objHndCaller){
d20Sys.d20SendSignal(spPkt.caster, DK_SIG_Concentration_Broken, spellId, 0);
}

for (auto i=0u; i < spPkt.targetCount; i++){
if (args.objHndCaller != spPkt.targetListHandles[i])
d20Sys.d20SendSignal(spPkt.targetListHandles[i], DK_SIG_Concentration_Broken, spellId, 0);
}
// added in Temple+: Concentration_Broken on the spell objects
for (auto i=0; i < spPkt.numSpellObjs && i < 128; i++){
auto spObj = spPkt.spellObjs[i].obj;
if (!spObj || spObj == args.objHndCaller) continue;
d20Sys.d20SendSignal(spObj, DK_SIG_Concentration_Broken, spellId, 0);
}
}
}
break;
Expand Down
13 changes: 13 additions & 0 deletions TemplePlus/d20.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ static_assert(sizeof(D20ActionDef) == 0x30, "D20ActionDef struct has the wrong s
int (__cdecl *OrgD20Init)(GameSystemConf* conf);

class D20ActionCallbacks {
// see NewD20ActionsInit
public:
#define ActionCheck(fname) static ActionErrorCode ActionCheck ## fname ## (D20Actn* d20a, TurnBasedStatus* tbStat)
#define AddToSeq(fname) static ActionErrorCode AddToSeq ## fname ## (D20Actn* d20a, ActnSeq* actSeq, TurnBasedStatus* tbStat);
Expand Down Expand Up @@ -123,6 +124,7 @@ class D20ActionCallbacks {
static ActionErrorCode PerformQuiveringPalm(D20Actn* d20a);
static ActionErrorCode PerformSneak(D20Actn* d20a);
static ActionErrorCode PerformStandardAttack(D20Actn* d20a);
static ActionErrorCode PerformStopConcentration(D20Actn* d20a);
static ActionErrorCode PerformTripAttack(D20Actn* d20a);
static ActionErrorCode PerformUseItem(D20Actn* d20a);

Expand Down Expand Up @@ -432,6 +434,8 @@ void LegacyD20System::NewD20ActionsInit()
d20Defs[d20Type].actionCheckFunc = d20Callbacks.ActionCheckCastSpell;
d20Defs[d20Type].projectileHitFunc = d20Callbacks.ProjectileHitSpell;
d20Defs[d20Type].actionCost = d20Callbacks.ActionCostCastSpell;
d20Defs[d20Type].flags = static_cast<D20ADF>(d20Defs[d20Type].flags | (D20ADF::D20ADF_Breaks_Concentration)); // casting spells should break concentration since active concentration requires a standard action!


d20Type = D20A_USE_ITEM;
d20Defs[d20Type].addToSeqFunc = d20Callbacks.AddToSeqSpellCast;
Expand All @@ -452,6 +456,8 @@ void LegacyD20System::NewD20ActionsInit()
d20Type = D20A_DISMISS_SPELLS;
d20Defs[d20Type].performFunc = d20Callbacks.PerformDismissSpell;

d20Type = D20A_STOP_CONCENTRATION;
d20Defs[d20Type].performFunc = d20Callbacks.PerformStopConcentration;

d20Type = D20A_BARDIC_MUSIC;
d20Defs[d20Type].flags = (D20ADF)( D20ADF_MagicEffectTargeting | D20ADF_Breaks_Concentration );
Expand Down Expand Up @@ -1139,6 +1145,11 @@ ActionErrorCode D20ActionCallbacks::PerformStandardAttack(D20Actn* d20a)
return AEC_OK;
}

ActionErrorCode D20ActionCallbacks::PerformStopConcentration(D20Actn* d20a){
d20Sys.d20SendSignal(d20a->d20APerformer, DK_SIG_Remove_Concentration, d20a->d20APerformer);
return AEC_OK;
}

ActionErrorCode D20ActionCallbacks::PerformTripAttack(D20Actn* d20a)
{
if (!d20a->d20ATarget)
Expand Down Expand Up @@ -2803,6 +2814,8 @@ ActionErrorCode D20ActionCallbacks::PerformCastSpell(D20Actn* d20a){
d20Sys.d20SendSignal(tgt, DK_SIG_Spell_Cast, spellId, 0);
}

d20Sys.d20SendSignal(d20a->d20APerformer, DK_SIG_Remove_Concentration, 0, 0);

/*if (party.IsInParty(d20a->d20APerformer)){
auto dummy = 1;
} else
Expand Down
2 changes: 1 addition & 1 deletion TemplePlus/d20_class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ int D20ClassSystem::GetClassHitDice(Stat classEnum){

int D20ClassSystem::GetClassEnum(const std::string& s){
for (auto &classSpec:classSpecs){
if (!strcmpi(tolower(classSpec.second.conditionName).c_str(), tolower(s).c_str()))
if (!_strcmpi(tolower(classSpec.second.conditionName).c_str(), tolower(s).c_str()))
return classSpec.first;
}
return 0;
Expand Down
6 changes: 3 additions & 3 deletions TemplePlus/dispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1212,9 +1212,9 @@ void DispatcherCallbackArgs::RemoveCondition(){
conds.ConditionRemove(this->objHndCaller, this->subDispNode->condNode);
}

void DispatcherCallbackArgs::RemoveSpellMod(){
auto removeSpellMod = temple::GetRef<void(__cdecl)(DispatcherCallbackArgs)>(0x100CBAB0);
removeSpellMod(*this);
void DispatcherCallbackArgs::RemoveSpell(){
auto removeSpell = temple::GetRef<void(__cdecl)(DispatcherCallbackArgs)>(0x100D7620);
removeSpell(*this);
}

DispIoAttackBonus::DispIoAttackBonus(){
Expand Down
1 change: 1 addition & 0 deletions TemplePlus/dispatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ struct DispatcherCallbackArgs {
void SetCondArgObjHndl(uint32_t argIdx, const objHndl& handle);
void RemoveCondition(); // note: this is the low level function
void RemoveSpellMod();
void RemoveSpell(); // general spell remover

};

Expand Down
2 changes: 1 addition & 1 deletion TemplePlus/dungeon_master.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -942,7 +942,7 @@ void DungeonMaster::RenderEditedObj() {
static int classCur = 0;
static auto classNameGetter = [](void*data, int idx, const char** outTxt)->bool
{
if (idx >= classNames.size())
if ((uint32_t)idx >= classNames.size())
return false;
*outTxt = classNames[idx].c_str();
return true;
Expand Down
21 changes: 21 additions & 0 deletions TemplePlus/float_line.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,27 @@ void FloatLineSystem::FloatCombatLineWithExtraString(const objHndl& obj, int com
floatMesLine(obj, 1, floatColor, text.c_str());
}

void FloatLineSystem::FloatSpellLine(objHndl target, int lineId, FloatLineColor color, const char* prefix,
const char* suffix){
char text[1024] = {0,};
auto line = spellSys.GetSpellMesline(lineId);
if (prefix){
if (suffix){
sprintf(text, "%s%s%s", prefix, line, suffix);
}
else{
sprintf(text, "%s%s", prefix, line);
}
}
else if (suffix){
sprintf(text, "%s%s", line, suffix);
}
else{
sprintf(text, "%s", line);
}
floatMesLine(target, 1, color, text);
}

FloatLineSystem::FloatLineSystem()
{

Expand Down
4 changes: 1 addition & 3 deletions TemplePlus/float_line.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ struct FloatLineSystem : temple::AddressTable
/*
Float a text line from mes/spells.mes with an optional prefix and suffix text.
*/
void FloatSpellLine(objHndl target, int lineId, FloatLineColor color, const char *prefix = 0, const char *suffix = 0) {
_FloatSpellLine(target, lineId, color, prefix, suffix);
}
void FloatSpellLine(objHndl target, int lineId, FloatLineColor color, const char *prefix = 0, const char *suffix = 0);

FloatLineSystem();

Expand Down
Loading

0 comments on commit c7e1e96

Please sign in to comment.