From 2a38e83a2fe8faff12336132238ba40d0b99b25d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 30 Apr 2023 08:57:28 +0200 Subject: [PATCH] - moved the animation code out of execute so it can be used without CON. --- source/games/duke/src/actors.cpp | 75 +++++++++++++++++++++++++++--- source/games/duke/src/funct.h | 1 - source/games/duke/src/gameexec.cpp | 42 ++--------------- 3 files changed, 72 insertions(+), 46 deletions(-) diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index 5809d5a1b..59a62c6ba 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -49,6 +49,40 @@ This file is a combination of code from the following sources: BEGIN_DUKE_NS + +void moveactor(DDukeActor* actor, int p, double pdist) +{ + if (actor->killit_flag == 1) + { + // if player was set to squish, first stop that.. + if (ps[p].actorsqu == actor) + ps[p].actorsqu = nullptr; + actor->flags2 |= SFLAG2_DIENOW; + } + else + { + move(actor, p, pdist); + + if (actor->spr.statnum == STAT_ACTOR) + { + if (badguy(actor)) + { + if (actor->spr.scale.X > 0.9375) return; + if (ud.respawn_monsters == 1 && actor->spr.extra <= 0) return; + } + else if (ud.respawn_items == 1 && (actor->spr.cstat & CSTAT_SPRITE_INVISIBLE)) return; + } + + if (actor->spr.statnum == STAT_ACTOR || (actor->spr.statnum == STAT_STANDABLE && (actor->flags1 & SFLAG_CHECKSLEEP))) + { + if (actor->timetosleep > 1) + actor->timetosleep--; + else if (actor->timetosleep == 1) + ChangeActorStat(actor, STAT_ZOMBIEACTOR); + } + } + +} //--------------------------------------------------------------------------- // // this is the implementation of DDukeActor::Tick. It is native so that @@ -97,18 +131,37 @@ void TickActor(DDukeActor* self) self->curframe = 0; } - if (!execute(self, p, pdist)) + self->killit_flag = 0; + bool conres = execute(self, p, pdist); + if (!conres && (self->flags4 & SFLAG4_CONOVERRIDE)) { + Printf("CON substituted for %s\n", self->GetClass()->TypeName); self->state_player = &ps[p]; self->state_dist = pdist; + self->flags4 |= SFLAG4_INRUNSTATE; IFVIRTUALPTR(self, DDukeActor, RunState) { VMValue val[] = { self }; - VMCall(func, val, 1, nullptr, 0); + try + { + VMCall(func, val, 1, nullptr, 0); + } + catch(const CDukeKillEvent& ev) + { + if (ev.Type() == 1) + { + self->Destroy(); + return; + } + } } + self->flags4 &= ~SFLAG4_INRUNSTATE; self->state_player = nullptr; self->state_dist = -1; + conres = true; } + // moveactor gets only called for actors with a scripted runner. + if (conres) moveactor(self, p, pdist); } } @@ -868,6 +921,13 @@ void tickstat(int stat, bool deleteinvalid) else if (stat != STAT_ACTOR || !badguy(act) || !monsterCheatCheck(act)) { CallTick(act); + + // check if DIENOW was set by Tick() + if ((act->flags2 & SFLAG2_DIENOW)) + { + addkill(act); + act->Destroy(); + } } } } @@ -3984,6 +4044,9 @@ void alterang(int ang, DDukeActor* actor, int playernum) //--------------------------------------------------------------------------- // // special checks for RR's extended sector types, now available everywhere +// +// note that we cannot kill stuff in here, we have to defer this until the +// end of the Tick() function. // //--------------------------------------------------------------------------- @@ -3998,7 +4061,7 @@ static int fallspecial(DDukeActor* actor, int playernum) { spawn(actor, RedneckRock2Class); spawn(actor, RedneckRock2Class); - addspritetodelete(); + actor->flags2 |= SFLAG2_DIENOW; } return 0; } @@ -4008,14 +4071,14 @@ static int fallspecial(DDukeActor* actor, int playernum) { spawnguts(actor, DukeJibs6Class, 5); S_PlayActorSound(SQUISHED, actor); - addspritetodelete(); + actor->flags2 |= SFLAG2_DIENOW; } return 0; } else if (actor->sector()->lotag == ST_803_KILLROCKS) { if (actor->GetClass() == RedneckRock2Class) - addspritetodelete(); + actor->flags2 |= SFLAG2_DIENOW; return 0; } } @@ -4034,7 +4097,7 @@ static int fallspecial(DDukeActor* actor, int playernum) else if (!actor->isPlayer()) { if (!actor->spriteextra) - addspritetodelete(); + actor->flags2 |= SFLAG2_DIENOW; return 0; } actor->attackertype = DukeShotSparkClass; diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index 0a894f3a4..804a1df1b 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -196,7 +196,6 @@ DDukeActor* dospawnsprite(DDukeActor* actj, int pn); void spriteinit(DDukeActor*, TArray& actors); DDukeActor* spawninit(DDukeActor* actj, DDukeActor* act, TArray* actors); -void addspritetodelete(int spnum=0); void checkavailinven(player_struct* p); bool initspriteforspawn(DDukeActor* spn); void initshell(DDukeActor* actj, DDukeActor* acti, bool isshell); diff --git a/source/games/duke/src/gameexec.cpp b/source/games/duke/src/gameexec.cpp index 0495902d8..31591c7d4 100644 --- a/source/games/duke/src/gameexec.cpp +++ b/source/games/duke/src/gameexec.cpp @@ -79,12 +79,6 @@ struct ParseState }; int furthestcanseepoint(DDukeActor* i, DDukeActor* ts, DVector2& pos); -bool killthesprite = false; - -void addspritetodelete(int spnum) -{ - killthesprite = true; -} sectortype* toSect(int index) { @@ -3186,6 +3180,7 @@ void LoadActor(DDukeActor *actor, int p, int x) s.g_x = x; // ?? s.g_ac = actor; + if ((actor->flags4 & SFLAG4_CONOVERRIDE) && overridecon) return; auto coninf = actor->conInfo(); if (coninf == nullptr) return; auto addr = coninf->loadeventscriptptr; @@ -3216,6 +3211,8 @@ void LoadActor(DDukeActor *actor, int p, int x) bool execute(DDukeActor *actor,int p,double pdist) { + if ((actor->flags4 & SFLAG4_CONOVERRIDE) && overridecon) return false; + auto coninf = actor->conInfo(); if (coninf == nullptr) return false; @@ -3225,45 +3222,12 @@ bool execute(DDukeActor *actor,int p,double pdist) s.g_x = int(pdist / maptoworld); // ?? s.g_ac = actor; s.insptr = coninf? &ScriptCode[4 + coninf->scriptaddress] : nullptr; - actor->killit_flag = 0; int done; do done = s.parse(); while( done == 0 ); - if(actor->killit_flag == 1) - { - // if player was set to squish, first stop that.. - if(ps[p].actorsqu == actor) - ps[p].actorsqu = nullptr; - killthesprite = true; - } - else - { - move(actor, p, pdist); - - if (actor->spr.statnum == STAT_ACTOR) - { - if (badguy(actor)) - { - if (actor->spr.scale.X > 0.9375 ) goto quit; - if (ud.respawn_monsters == 1 && actor->spr.extra <= 0) goto quit; - } - else if (ud.respawn_items == 1 && (actor->spr.cstat & CSTAT_SPRITE_INVISIBLE)) goto quit; - } - - if (actor->spr.statnum == STAT_ACTOR || (actor->spr.statnum == STAT_STANDABLE && (actor->flags1 & SFLAG_CHECKSLEEP))) - { - if (actor->timetosleep > 1) - actor->timetosleep--; - else if (actor->timetosleep == 1) - ChangeActorStat(actor, STAT_ZOMBIEACTOR); - } - } -quit: - if (killthesprite) actor->Destroy(); - killthesprite = false; return true; }