From a2683559ceccc8393bc23492f42bf5a5e5a76c3a Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 15 Nov 2022 10:17:23 +0100 Subject: [PATCH] - refactored Duke's cactus. --- source/core/actorlist.cpp | 2 +- source/games/duke/src/duke3d.h | 1 + source/games/duke/src/funct.h | 1 + source/games/duke/src/game.cpp | 11 ++++ source/games/duke/src/sectors_d.cpp | 37 +---------- source/games/duke/src/sectors_r.cpp | 42 +++---------- source/games/duke/src/spawn.cpp | 6 +- source/games/duke/src/spawn_d.cpp | 2 - source/games/duke/src/spawn_r.cpp | 2 - source/games/duke/src/vmexports.cpp | 24 +++++++ wadsrc/static/filter/duke/engine/engine.def | 2 + .../static/filter/redneck/engine/engine.def | 2 + wadsrc/static/zscript.txt | 1 + .../zscript/games/duke/actors/cactus.zs | 63 +++++++++++++++++++ wadsrc/static/zscript/games/duke/dukeactor.zs | 2 + 15 files changed, 120 insertions(+), 78 deletions(-) create mode 100644 wadsrc/static/zscript/games/duke/actors/cactus.zs diff --git a/source/core/actorlist.cpp b/source/core/actorlist.cpp index 9af69377e..641f6409c 100644 --- a/source/core/actorlist.cpp +++ b/source/core/actorlist.cpp @@ -355,7 +355,7 @@ DCoreActor* InsertActor(PClass* type, sectortype* sector, int stat, bool tail) #define setter(flag, var) if (actorinfo->DefaultFlags & flag) actor->spr.var = actorinfo->defsprite.var; - if (actorinfo->DefaultFlags & DEFF_STATNUM) stat = actorinfo->defsprite.statnum; + if (stat < 0 && (actorinfo->DefaultFlags & DEFF_STATNUM)) stat = actorinfo->defsprite.statnum; setter(DEFF_PICNUM, picnum); setter(DEFF_ANG, angle); setter(DEFF_XVEL, xint); diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h index 256ef959a..8d263c39d 100644 --- a/source/games/duke/src/duke3d.h +++ b/source/games/duke/src/duke3d.h @@ -117,6 +117,7 @@ void CallInitialize(DDukeActor* actor); void CallTick(DDukeActor* actor); void CallAction(DDukeActor* actor); void CallOnHit(DDukeActor* actor, DDukeActor* hitter); +void CallOnHurt(DDukeActor* actor, player_struct* hitter); void CallOnUse(DDukeActor* actor, player_struct* user); bool CallAnimate(DDukeActor* actor, tspritetype* hitter); diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index 498d28e16..5ddfafda4 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -172,6 +172,7 @@ void OnEvent(int id, int pnum = -1, DDukeActor* snum = nullptr, int dist = -1); DDukeActor* CreateActor(sectortype* whatsectp, const DVector3& pos, int s_pn, int8_t s_shd, const DVector2& scale, DAngle s_ang, double s_vel, double s_zvel, DDukeActor* s_ow, int8_t s_stat); DDukeActor* CreateActor(sectortype* whatsectp, const DVector3& pos, PClassActor* cls, int8_t s_shd, const DVector2& scale, DAngle s_ang, double s_vel, double s_zvel, DDukeActor* s_ow, int8_t s_stat); +DDukeActor* SpawnActor(sectortype* whatsectp, const DVector3& pos, PClassActor* cls, int8_t s_shd, const DVector2& scale, DAngle s_ang, double s_vel, double s_zvel, DDukeActor* s_ow, int8_t s_stat = -1); void ceilingglass(DDukeActor* snum, sectortype* sectnum, int cnt); void spriteglass(DDukeActor* snum, int cnt); diff --git a/source/games/duke/src/game.cpp b/source/games/duke/src/game.cpp index e102d6010..c9d748c5a 100644 --- a/source/games/duke/src/game.cpp +++ b/source/games/duke/src/game.cpp @@ -435,6 +435,17 @@ void CallOnHit(DDukeActor* actor, DDukeActor* hitter) } } +void CallOnHurt(DDukeActor* actor, player_struct* hitter) +{ + IFVIRTUALPTR(actor, DDukeActor, onHurt) + { + VMValue val[2] = { actor, hitter }; + VMCall(func, val, 2, nullptr, 0); + } +} + + + void CallOnUse(DDukeActor* actor, player_struct* user) { IFVIRTUALPTR(actor, DDukeActor, onUse) diff --git a/source/games/duke/src/sectors_d.cpp b/source/games/duke/src/sectors_d.cpp index 9161bd44f..d8b190404 100644 --- a/source/games/duke/src/sectors_d.cpp +++ b/source/games/duke/src/sectors_d.cpp @@ -885,18 +885,7 @@ void checkplayerhurt_d(player_struct* p, const Collision& coll) { if (coll.type == kHitSprite) { - switch (coll.actor()->spr.picnum) - { - case CACTUS: - if (p->hurt_delay < 8) - { - p->GetActor()->spr.extra -= 5; - p->hurt_delay = 16; - SetPlayerPal(p, PalEntry(32, 32, 0, 0)); - S_PlayActorSound(DUKE_LONGTERM_PAIN, p->GetActor()); - } - break; - } + CallOnHurt(coll.actor(), p); return; } @@ -1064,30 +1053,6 @@ void checkhitsprite_d(DDukeActor* targ, DDukeActor* proj) } } break; - case CACTUS: - // case CACTUSBROKE: - if (actorflag(proj, SFLAG_INFLAME)) - { - for (k = 0; k < 64; k++) - { - auto a = randomAngle(); - auto vel = krandf(4) + 4; - auto zvel = -krandf(16) - targ->vel.Z * 0.25; - - auto spawned = CreateActor(targ->sector(), targ->spr.pos.plusZ(-48), PClass::FindActor("DukeScrap"), -8, DVector2(0.75, 0.75), a, vel, zvel, targ, STAT_MISC); - if (spawned) - { - if (spawned) spawned->spriteextra = Scrap3 + krand() & 3; - spawned->spr.pal = 6; - } - } - - if (targ->spr.picnum == CACTUS) - targ->spr.picnum = CACTUSBROKE; - targ->spr.cstat &= ~CSTAT_SPRITE_BLOCK_ALL; - } - break; - case HANGLIGHT: case GENERICPOLE2: for (k = 0; k < 6; k++) diff --git a/source/games/duke/src/sectors_r.cpp b/source/games/duke/src/sectors_r.cpp index c11f2c3b6..c504eaece 100644 --- a/source/games/duke/src/sectors_r.cpp +++ b/source/games/duke/src/sectors_r.cpp @@ -1383,18 +1383,13 @@ void checkplayerhurt_r(player_struct* p, const Collision &coll) SetPlayerPal(p, PalEntry(32, 32, 0, 0)); S_PlayActorSound(DUKE_LONGTERM_PAIN, p->GetActor()); } - break; - case CACTUS: - if (!isRRRA() && p->hurt_delay < 8) - { - p->GetActor()->spr.extra -= 5; - p->hurt_delay = 16; - SetPlayerPal(p, PalEntry(32, 32, 0, 0)); - S_PlayActorSound(DUKE_LONGTERM_PAIN, p->GetActor()); - } - break; + return; + + default: + CallOnHurt(coll.actor(), p); + return; } - return; + } if (coll.type != kHitWall) return; @@ -2061,7 +2056,8 @@ void checkhitsprite_r(DDukeActor* targ, DDukeActor* proj) auto vel = krandf(4) + 4; auto zvel = -krandf(16) - targ->vel.Z * 0.25; - CreateActor(targ->sector(), targ->spr.pos.plusZ(-8), SCRAP6 + (krand() & 15), -8, DVector2(0.75, 0.75), a, vel, zvel, targ, 5); + auto spawned = CreateActor(targ->sector(), targ->spr.pos.plusZ(-8), PClass::FindActor("DukeScrap"), -8, DVector2(0.75, 0.75), a, vel, zvel, targ, 5); + if (spawned) spawned->spriteextra = Scrap6 + (krand() & 15); } break; case BOWLINGBALL: @@ -2108,28 +2104,6 @@ void checkhitsprite_r(DDukeActor* targ, DDukeActor* proj) } break; - case CACTUS: - // case CACTUSBROKE: - if (actorflag(proj, SFLAG_INFLAME)) - { - for (k = 0; k < 64; k++) - { - auto a = randomAngle(); - auto vel = krandf(4) + 4; - auto zvel = -krandf(16) - targ->vel.Z * 0.25; - - auto spawned = CreateActor(targ->sector(), targ->spr.pos.plusZ(-krandf(48)), SCRAP6 + (krand() & 3), -8, DVector2(0.75, 0.75), a, vel, zvel, targ, 5); - if (spawned) spawned->spr.pal = 8; - } - - if (targ->spr.picnum == CACTUS) - targ->spr.picnum = CACTUSBROKE; - targ->spr.cstat &= ~CSTAT_SPRITE_BLOCK_ALL; - // else deletesprite(i); - } - break; - - case FANSPRITE: targ->spr.picnum = FANSPRITEBROKE; targ->spr.cstat &= ~CSTAT_SPRITE_BLOCK_ALL; diff --git a/source/games/duke/src/spawn.cpp b/source/games/duke/src/spawn.cpp index bb584851c..bc58e8051 100644 --- a/source/games/duke/src/spawn.cpp +++ b/source/games/duke/src/spawn.cpp @@ -77,7 +77,7 @@ DDukeActor* CreateActor(sectortype* whatsectp, const DVector3& pos, PClassActor* act->spr.pos = pos; if (s_pn != -1) act->spr.picnum = s_pn; // if -1 use the class default. act->spr.shade = s_shd; - act->spr.scale = DVector2(scale.X, scale.Y); + if (!scale.isZero()) act->spr.scale = DVector2(scale.X, scale.Y); act->spr.angle = s_ang; act->vel.X = s_vel; @@ -134,9 +134,9 @@ DDukeActor* CreateActor(sectortype* whatsectp, const DVector3& pos, PClassActor* return CreateActor(whatsectp, pos, cls, -1, s_shd, scale, s_ang, s_vel, s_zvel, s_ow, s_stat); } -DDukeActor* SpawnActor(sectortype* whatsectp, const DVector3& pos, int s_pn, int8_t s_shd, const DVector2& scale, DAngle s_ang, double s_vel, double s_zvel, DDukeActor* s_ow, int8_t s_stat) +DDukeActor* SpawnActor(sectortype* whatsectp, const DVector3& pos, PClassActor* cls, int8_t s_shd, const DVector2& scale, DAngle s_ang, double s_vel, double s_zvel, DDukeActor* s_ow, int8_t s_stat) { - auto actor = CreateActor(whatsectp, pos, s_pn, s_shd, scale, s_ang, s_vel, s_zvel, s_ow, s_stat); + auto actor = CreateActor(whatsectp, pos, cls, s_shd, scale, s_ang, s_vel, s_zvel, s_ow, s_stat); if (actor) fi.spawninit(s_ow, actor, nullptr); return actor; } diff --git a/source/games/duke/src/spawn_d.cpp b/source/games/duke/src/spawn_d.cpp index 43090297d..48248a164 100644 --- a/source/games/duke/src/spawn_d.cpp +++ b/source/games/duke/src/spawn_d.cpp @@ -390,8 +390,6 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray* case SCALE: case VACUUM: case FANSPRITE: - case CACTUS: - case CACTUSBROKE: case HANGLIGHT: case FETUS: case FETUSBROKE: diff --git a/source/games/duke/src/spawn_r.cpp b/source/games/duke/src/spawn_r.cpp index f1774e72a..fb19c284f 100644 --- a/source/games/duke/src/spawn_r.cpp +++ b/source/games/duke/src/spawn_r.cpp @@ -384,8 +384,6 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray* case SCALE: case VACUUM: case FANSPRITE: - case CACTUS: - case CACTUSBROKE: case CAMERALIGHT: case MOVIECAMERA: case IVUNIT: diff --git a/source/games/duke/src/vmexports.cpp b/source/games/duke/src/vmexports.cpp index b85f70a51..de4a0b95b 100644 --- a/source/games/duke/src/vmexports.cpp +++ b/source/games/duke/src/vmexports.cpp @@ -611,6 +611,30 @@ DEFINE_ACTION_FUNCTION_NATIVE(_DukeSpriteIterator, Next, duke_nextSprite) ACTION_RETURN_POINTER(duke_nextSprite(self)); } +DDukeActor* DukeLevel_SpawnActor(DukeLevel* self, sectortype* sect, double x, double y, double z, PClassActor* type, int shade, double scalex, double scaley, double angle, double vel, double zvel, DDukeActor* owner, int stat) +{ + return SpawnActor(sect, DVector3(x, y, z), type, shade, DVector2(scalex, scaley), DAngle::fromDeg(angle), vel, zvel, owner, stat); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_DukeLevel, SpawnActor, DukeLevel_SpawnActor) +{ + PARAM_SELF_STRUCT_PROLOGUE(DukeLevel); + PARAM_POINTER(sect, sectortype); + PARAM_FLOAT(x); + PARAM_FLOAT(y); + PARAM_FLOAT(z); + PARAM_CLASS(type, DDukeActor); + PARAM_INT(shade); + PARAM_FLOAT(scalex); + PARAM_FLOAT(scaley); + PARAM_FLOAT(angle); + PARAM_FLOAT(vel); + PARAM_FLOAT(zvel); + PARAM_OBJECT(owner, DDukeActor); + PARAM_INT(stat); + ACTION_RETURN_POINTER(DukeLevel_SpawnActor(self, sect, x, y, z, static_cast(type), shade, scalex, scaley, angle, vel, zvel, owner, stat)); +} + DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, playerfriction); DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, gravity); DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, respawnactortime); diff --git a/wadsrc/static/filter/duke/engine/engine.def b/wadsrc/static/filter/duke/engine/engine.def index c92455940..dd8208ce2 100644 --- a/wadsrc/static/filter/duke/engine/engine.def +++ b/wadsrc/static/filter/duke/engine/engine.def @@ -12,4 +12,6 @@ spawnclasses 908 = DukeTree1 910 = DukeTree2 990 = DukeTire + 911 = DukeCactus + 939 = DukeCactusBroke } diff --git a/wadsrc/static/filter/redneck/engine/engine.def b/wadsrc/static/filter/redneck/engine/engine.def index bd0797ccd..36badf852 100644 --- a/wadsrc/static/filter/redneck/engine/engine.def +++ b/wadsrc/static/filter/redneck/engine/engine.def @@ -11,5 +11,7 @@ spawnclasses 1191 = DukeTree1 1193 = DukeTree2 1230 = DukeTire + 1194 = DukeCactus + 1203 = DukeCactusBroke } diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 50737723f..e381d36d2 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -54,6 +54,7 @@ version "4.9" #include "zscript/games/duke/actors/waterfountain.zs" #include "zscript/games/duke/actors/flammables.zs" #include "zscript/games/duke/actors/scrap.zs" +#include "zscript/games/duke/actors/cactus.zs" #include "zscript/games/blood/bloodgame.zs" #include "zscript/games/blood/ui/menu.zs" diff --git a/wadsrc/static/zscript/games/duke/actors/cactus.zs b/wadsrc/static/zscript/games/duke/actors/cactus.zs new file mode 100644 index 000000000..a06e971db --- /dev/null +++ b/wadsrc/static/zscript/games/duke/actors/cactus.zs @@ -0,0 +1,63 @@ + +class DukeCactusBroke : DukeActor +{ + default + { + clipdist 8; + statnum STAT_ACTOR; + pic "CACTUSBROKE"; + } + + override void Initialize() + { + self.cstat |= CSTAT_SPRITE_BLOCK_ALL; + } +} + +class DukeCactus : DukeCactusBroke +{ + default + { + clipdist 8; + statnum STAT_ACTOR; + spriteset "CACTUS", "CACTUSBROKE"; + } + + + override void onHit(DukeActor hitter) + { + if (self.spritesetindex == 0 && hitter.actorflag1(SFLAG_INFLAME)) + { + let scrap = Raze.isRR()? DukeScrap.Scrap6 : DukeScrap.Scrap3; + + for (int k = 0; k < 64; k++) + { + double ang = frandom(0, 360); + double vel = frandom(4, 8); + double zvel = -frandom(0, 16) - self.vel.Z * 0.25; + + let spawned = dlevel.SpawnActor(self.sector, self.pos.plusZ(-48), "DukeScrap", -8, (0.75, 0.75), ang, vel, zvel, self); + if (spawned) + { + spawned.spriteextra = DukeScrap.Scrap3 + random(0, 3); + spawned.pal = 6; + } + } + + setSpritePic(1); + self.cstat &= ~CSTAT_SPRITE_BLOCK_ALL; + } + } + + override void onHurt(DukePlayer p) + { + if (self.spritesetindex == 0 && p.hurt_delay < 8) + { + p.actor.extra -= 5; + p.hurt_delay = 16; + p.pals = Color(32, 32, 0, 0); + p.actor.PlayActorSound(DukeSnd.DUKE_LONGTERM_PAIN); + } + } +} + diff --git a/wadsrc/static/zscript/games/duke/dukeactor.zs b/wadsrc/static/zscript/games/duke/dukeactor.zs index b8568a66b..7ef03823a 100644 --- a/wadsrc/static/zscript/games/duke/dukeactor.zs +++ b/wadsrc/static/zscript/games/duke/dukeactor.zs @@ -78,6 +78,7 @@ class DukeActor : CoreActor native virtual void Initialize() {} virtual void Tick() {} virtual void onHit(DukeActor hitter) {} + virtual void onHurt(DukePlayer p) {} virtual void onUse(DukePlayer user) {} virtual bool animate(tspritetype tspr) { return false; } virtual void RunState() {} // this is the CON function. @@ -101,6 +102,7 @@ extend struct _ // On the script side we do not really want scattered global data that is publicly accessible. struct DukeLevel { + native DukeActor SpawnActor(sectortype sect, Vector3 pos, class type, int shade, Vector2 scale, double angle, double vel, double zvel, DukeActor owner, int stat = -1); } struct DukeStatIterator