From be6ead173a70148fac474118f587d06981d58736 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Thu, 1 Dec 2022 20:11:38 +0100 Subject: [PATCH] - scriptified several smaller actors --- source/core/gamefuncs.cpp | 2 +- source/core/gamefuncs.h | 2 +- source/core/namedef_custom.h | 3 + source/core/vmexports.cpp | 9 + source/games/duke/src/actors.cpp | 271 ------------------ source/games/duke/src/actors_d.cpp | 62 ---- source/games/duke/src/actors_r.cpp | 83 +----- source/games/duke/src/animatesprites_d.cpp | 29 -- source/games/duke/src/animatesprites_r.cpp | 25 -- source/games/duke/src/constants.h | 3 + source/games/duke/src/dispatch.cpp | 1 - source/games/duke/src/flags_d.cpp | 6 +- source/games/duke/src/flags_r.cpp | 5 +- source/games/duke/src/inlines.h | 8 + source/games/duke/src/namelist_d.h | 11 + source/games/duke/src/namelist_r.h | 16 +- source/games/duke/src/names.h | 1 - source/games/duke/src/player_r.cpp | 2 +- source/games/duke/src/sectors_d.cpp | 16 -- source/games/duke/src/spawn.cpp | 77 ++--- source/games/duke/src/spawn_d.cpp | 79 +---- source/games/duke/src/spawn_r.cpp | 70 ----- source/games/duke/src/vmexports.cpp | 43 ++- .../filter/dukeengine/engine/defines.def | 1 + .../static/filter/dukelike/engine/engine.def | 17 ++ .../static/filter/redneck/engine/engine.def | 20 +- wadsrc/static/filter/redneck/sndinfo.txt | 2 +- wadsrc/static/zscript.txt | 8 +- wadsrc/static/zscript/coreactor.zs | 1 + .../zscript/games/duke/actors/bloodpool.zs | 141 +++++++++ .../zscript/games/duke/actors/glasspieces.zs | 64 +++++ .../static/zscript/games/duke/actors/neon.zs | 66 +++++ .../zscript/games/duke/actors/nukebutton.zs | 41 +++ .../static/zscript/games/duke/actors/paper.zs | 116 ++++++++ .../static/zscript/games/duke/actors/shell.zs | 125 ++++++++ .../zscript/games/duke/actors/watersplash.zs | 99 +++++++ wadsrc/static/zscript/games/duke/dukeactor.zs | 30 ++ wadsrc/static/zscript/games/duke/dukegame.zs | 5 +- 38 files changed, 853 insertions(+), 707 deletions(-) create mode 100644 wadsrc/static/zscript/games/duke/actors/bloodpool.zs create mode 100644 wadsrc/static/zscript/games/duke/actors/glasspieces.zs create mode 100644 wadsrc/static/zscript/games/duke/actors/neon.zs create mode 100644 wadsrc/static/zscript/games/duke/actors/nukebutton.zs create mode 100644 wadsrc/static/zscript/games/duke/actors/paper.zs create mode 100644 wadsrc/static/zscript/games/duke/actors/shell.zs create mode 100644 wadsrc/static/zscript/games/duke/actors/watersplash.zs diff --git a/source/core/gamefuncs.cpp b/source/core/gamefuncs.cpp index 5b1402925..3ef5336c1 100644 --- a/source/core/gamefuncs.cpp +++ b/source/core/gamefuncs.cpp @@ -1309,7 +1309,7 @@ int FindBestSector(const DVector3& pos) // //========================================================================== -bool isAwayFromWall(DCoreActor* ac, double delta) +int isAwayFromWall(DCoreActor* ac, double delta) { sectortype* s1; diff --git a/source/core/gamefuncs.h b/source/core/gamefuncs.h index 43fcbc59e..e87902857 100644 --- a/source/core/gamefuncs.h +++ b/source/core/gamefuncs.h @@ -440,7 +440,7 @@ enum EFindNextSector Find_FloorDown = Find_Floor | Find_Down, }; sectortype* nextsectorneighborzptr(sectortype* sectp, double startz, int flags); -bool isAwayFromWall(DCoreActor* ac, double delta); +int isAwayFromWall(DCoreActor* ac, double delta); // important note: This returns positive for 'in front' with renderer coordinates. diff --git a/source/core/namedef_custom.h b/source/core/namedef_custom.h index c667fc62d..495159f70 100644 --- a/source/core/namedef_custom.h +++ b/source/core/namedef_custom.h @@ -20,6 +20,9 @@ xx(DukeActivator) xx(DukeActivatorLocked) xx(DukeLocator) xx(DukeGenericDestructible) +xx(DukeGlassPieces) +xx(DukeGlassPieces1) +xx(DukeGlassPieces2) xx(spawnstate) xx(brokenstate) diff --git a/source/core/vmexports.cpp b/source/core/vmexports.cpp index e56b37df2..321a5293d 100644 --- a/source/core/vmexports.cpp +++ b/source/core/vmexports.cpp @@ -858,6 +858,15 @@ DEFINE_ACTION_FUNCTION_NATIVE(DCoreActor, Normalize180, Normalize180) ACTION_RETURN_FLOAT(angle.Normalized180().Degrees()); } +DEFINE_ACTION_FUNCTION_NATIVE(DCoreActor, isAwayFromWall, isAwayFromWall) +{ + PARAM_SELF_PROLOGUE(DCoreActor); + PARAM_FLOAT(dist); + ACTION_RETURN_INT(isAwayFromWall(self, dist)); + return 0; +} + + DEFINE_FIELD_X(Collision, CollisionBase, type) diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index ba45cb73a..b5b873f93 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -626,277 +626,6 @@ void detonate(DDukeActor *actor, int explosion) // //--------------------------------------------------------------------------- -void watersplash2(DDukeActor* actor) -{ - auto sectp = actor->sector(); - actor->temp_data[0]++; - if (actor->temp_data[0] == 1) - { - if (sectp->lotag != 1 && sectp->lotag != 2) - { - actor->Destroy(); - return; - } - if (!S_CheckSoundPlaying(ITEM_SPLASH)) - S_PlayActorSound(ITEM_SPLASH, actor); - } - if (actor->temp_data[0] == 3) - { - actor->temp_data[0] = 0; - actor->temp_data[1]++; - } - if (actor->temp_data[1] == 5) - actor->Destroy(); -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -bool money(DDukeActor* actor, int BLOODPOOL) -{ - auto sectp = actor->sector(); - - actor->vel.X = krandf(0.5) + BobVal(actor->temp_data[0]) * 2; - actor->temp_data[0] += (krand() & 63); - if ((actor->temp_data[0] & 2047) > 512 && (actor->temp_data[0] & 2047) < 1596) - { - if (sectp->lotag == 2) - { - if (actor->vel.Z < 0.25) - actor->vel.Z += gs.gravity / 32. + krandf(1/32.); - } - else - if (actor->vel.Z < 0.5625) - actor->vel.Z += gs.gravity / 32. + krandf(1 / 32.); - } - - ssp(actor, CLIPMASK0); - - if ((krand() & 3) == 0) - SetActor(actor, actor->spr.pos); - - if (!actor->insector()) - { - actor->Destroy(); - return false; - } - double l = getflorzofslopeptr(actor->sector(), actor->spr.pos); - - if (actor->spr.pos.Z > l) - { - actor->spr.pos.Z = l; - - insertspriteq(actor); - actor->spr.picnum++; - - DukeStatIterator it(STAT_MISC); - while (auto aa = it.Next()) - { - if (aa->spr.picnum == BLOODPOOL) - { - double dist = (aa->spr.pos.XY() - actor->spr.pos.XY()).Length(); - if (dist < 348/16.) - { - actor->spr.pal = 2; - break; - } - } - } - } - return true; -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -bool bloodpool(DDukeActor* actor, bool puke) -{ - auto sectp = actor->sector(); - - if (actor->temp_data[0] == 0) - { - actor->temp_data[0] = 1; - if (sectp->floorstat & CSTAT_SECTOR_SLOPE) - { - actor->Destroy(); - return false; - } - else insertspriteq(actor); - } - - makeitfall(actor); - - double xx; - int p = findplayer(actor, &xx); - - actor->spr.pos.Z = actor->floorz - FOURSLEIGHT_F; - - if (actor->temp_data[2] < 32) - { - actor->temp_data[2]++; - if (actor->spr.detail == 1) - { - if (actor->spr.scale.X < 1 && actor->spr.scale.Y < 1) - { - actor->spr.scale.X += ((krand() & 3) * REPEAT_SCALE); - actor->spr.scale.Y += ((krand() & 3) * REPEAT_SCALE); - } - } - else - { - if (actor->spr.scale.X < 0.5 && actor->spr.scale.Y < 0.5) - { - actor->spr.scale.X += ((krand() & 3) * REPEAT_SCALE); - actor->spr.scale.Y += ((krand() & 3) * REPEAT_SCALE); - } - } - } - - if (xx < 844 / 16. && actor->spr.scale.X > 0.09375 && actor->spr.scale.Y > 0.09375) - { - if (actor->spr.pal == 0 && (krand() & 255) < 16 && !puke) - { - if (ps[p].boot_amount > 0) - ps[p].boot_amount--; - else - { - if (!S_CheckSoundPlaying(DUKE_LONGTERM_PAIN)) - S_PlayActorSound(DUKE_LONGTERM_PAIN, ps[p].GetActor()); - ps[p].GetActor()->spr.extra--; - SetPlayerPal(&ps[p], PalEntry(32, 16, 0, 0)); - } - } - - if (actor->temp_data[1] == 1) return false; - actor->temp_data[1] = 1; - - if (actor->spr.detail == 1) - ps[p].footprintcount = 10; - else ps[p].footprintcount = 3; - - ps[p].footprintpal = actor->spr.pal; - ps[p].footprintshade = actor->spr.shade; - - if (actor->temp_data[2] == 32) - { - actor->spr.scale.X += (-0.09375); - actor->spr.scale.Y += (-0.09375); - } - } - else actor->temp_data[1] = 0; - return true; -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -void shell(DDukeActor* actor, bool morecheck) -{ - auto sectp = actor->sector(); - - ssp(actor, CLIPMASK0); - - if (!actor->insector() || morecheck) - { - actor->Destroy(); - return; - } - - if (sectp->lotag == 2) - { - actor->temp_data[1]++; - if (actor->temp_data[1] > 8) - { - actor->temp_data[1] = 0; - actor->temp_data[0]++; - actor->temp_data[0] &= 3; - } - if (actor->vel.Z < 0.5) actor-> vel.Z += (gs.gravity / 13); // 8 - else actor->vel.Z -= 0.25; - if (actor->vel.X > 0) - actor->vel.X -= 0.25; - else actor->vel.X = 0; - } - else - { - actor->temp_data[1]++; - if (actor->temp_data[1] > 3) - { - actor->temp_data[1] = 0; - actor->temp_data[0]++; - actor->temp_data[0] &= 3; - } - if (actor->vel.Z < 2) actor->vel.Z += (gs.gravity / 3); // 52; - if(actor->vel.X > 0) - actor->vel.X -= 1/16.; - else - { - actor->Destroy(); - } - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -void glasspieces(DDukeActor* actor) -{ - auto sectp = actor->sector(); - - makeitfall(actor); - - if (actor->vel.Z > 16) actor->vel.Z = 16; - if (!actor->insector()) - { - actor->Destroy(); - return; - } - - if (actor->spr.pos.Z == actor->floorz - FOURSLEIGHT_F && actor->temp_data[0] < 3) - { - actor->vel.Z = -(3 - actor->temp_data[0]) - krandf(2); - if (sectp->lotag == 2) - actor->vel.Z *= 0.5; - - actor->spr.scale *= 0.5; - if (rnd(96)) - SetActor(actor, actor->spr.pos); - actor->temp_data[0]++;//Number of bounces - } - else if (actor->temp_data[0] == 3) - { - actor->Destroy(); - return; - } - - if(actor->vel.X > 0) - { - actor->vel.X -= 1/8.; - actor->spr.cstat = randomFlip(); - } - else actor->vel.X = 0; - - ssp(actor, CLIPMASK0); -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - void gutsdir(DDukeActor* actor, int gtype, int n, int p) { double scale; diff --git a/source/games/duke/src/actors_d.cpp b/source/games/duke/src/actors_d.cpp index 42c05ab05..9118e0339 100644 --- a/source/games/duke/src/actors_d.cpp +++ b/source/games/duke/src/actors_d.cpp @@ -1288,58 +1288,6 @@ void moveexplosions_d(void) // STATNUM 5 if (isWorldTour()) fireflyflyingeffect(act); continue; - case NEON1: - case NEON2: - case NEON3: - case NEON4: - case NEON5: - case NEON6: - - if ((global_random / (act->spr.lotag + 1) & 31) > 4) act->spr.shade = -127; - else act->spr.shade = 127; - continue; - - case NUKEBUTTON: - case NUKEBUTTON + 1: - case NUKEBUTTON + 2: - case NUKEBUTTON + 3: - - if (act->temp_data[0]) - { - act->temp_data[0]++; - auto Owner = act->GetOwner(); - if (act->temp_data[0] == 8) act->spr.picnum = NUKEBUTTON + 1; - else if (act->temp_data[0] == 16 && Owner) - { - act->spr.picnum = NUKEBUTTON + 2; - ps[Owner->PlayerIndex()].fist_incs = 1; - } - if (Owner && ps[Owner->PlayerIndex()].fist_incs == 26) - act->spr.picnum = NUKEBUTTON + 3; - } - continue; - - case WATERSPLASH2: - watersplash2(act); - continue; - - case MONEY + 1: - case MAIL + 1: - case PAPER + 1: - act->vel.Z = act->floorz = getflorzofslopeptr(act->sector(), act->spr.pos.X, act->spr.pos.Y); - break; - case MONEY: - case MAIL: - case PAPER: - money(act, BLOODPOOL); - break; - - case BLOODPOOL: - case PUKE: - bloodpool(act, act->spr.picnum == PUKE); - - continue; - case LAVAPOOL: case ONFIRE: case ONFIRESMOKE: @@ -1367,16 +1315,6 @@ void moveexplosions_d(void) // STATNUM 5 execute(act, p, xx); continue; - case SHELL: - case SHOTGUNSHELL: - shell(act, sectp->floorz + 24 < act->spr.pos.Z); - continue; - - case GLASSPIECES: - case GLASSPIECES1: - case GLASSPIECES2: - glasspieces(act); - continue; } } } diff --git a/source/games/duke/src/actors_r.cpp b/source/games/duke/src/actors_r.cpp index 2481704b7..460f8f256 100644 --- a/source/games/duke/src/actors_r.cpp +++ b/source/games/duke/src/actors_r.cpp @@ -1458,6 +1458,10 @@ void moveexplosions_r(void) // STATNUM 5 DukeStatIterator it(STAT_MISC); while (auto act = it.Next()) { + if (act->time == 959) + { + int a = 0; + } t = &act->temp_data[0]; auto sectp = act->sector(); @@ -1483,73 +1487,6 @@ void moveexplosions_r(void) // STATNUM 5 continue; } break; - case NEON1: - case NEON2: - case NEON3: - case NEON4: - case NEON5: - case NEON6: - - if ((global_random / (act->spr.lotag + 1) & 31) > 4) act->spr.shade = -127; - else act->spr.shade = 127; - continue; - - case MUD: - - act->temp_data[0]++; - if (act->temp_data[0] == 1) - { - if (sectp->floorpicnum != 3073) - { - act->Destroy(); - continue; - } - if (S_CheckSoundPlaying(22)) - S_PlayActorSound(22, act); - } - if (act->temp_data[0] == 3) - { - act->temp_data[0] = 0; - act->temp_data[1]++; - } - if (act->temp_data[1] == 5) - act->Destroy(); - continue; - - case WATERSPLASH2: - watersplash2(act); - continue; - - case FEATHER + 1: // feather - act->spr.pos.Z = act->floorz = getflorzofslopeptr(act->sector(), act->spr.pos.X, act->spr.pos.Y); - if (act->sector()->lotag == 800) - { - act->Destroy(); - continue; - } - break; - case FEATHER: - if (!money(act, BLOODPOOL)) continue; - - if (act->sector()->lotag == 800) - if (act->spr.pos.Z >= act->sector()->floorz - 8) - { - act->Destroy(); - continue; - } - - break; - - case BLOODPOOL: - if (!bloodpool(act, false)) continue; - - if (act->sector()->lotag == 800) - if (act->spr.pos.Z >= act->sector()->floorz - 8) - { - act->Destroy(); - } - continue; - case BURNING: case WATERBUBBLE: case SMALLSMOKE: @@ -1562,18 +1499,6 @@ void moveexplosions_r(void) // STATNUM 5 p = findplayer(act, &xx); execute(act, p, xx); continue; - - case SHELL: - case SHOTGUNSHELL: - shell(act, false); - continue; - - case GLASSPIECES: - case GLASSPIECES1: - case GLASSPIECES2: - case POPCORN: - glasspieces(act); - continue; } } } diff --git a/source/games/duke/src/animatesprites_d.cpp b/source/games/duke/src/animatesprites_d.cpp index 604db4dc8..eccf69362 100644 --- a/source/games/duke/src/animatesprites_d.cpp +++ b/source/games/duke/src/animatesprites_d.cpp @@ -66,8 +66,6 @@ void animatesprites_d(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi if (isWorldTour() && !wt_commentary) t->scale = DVector2(0, 0); break; - case BLOODPOOL: - case PUKE: case FOOTPRINTS: case FOOTPRINTS2: case FOOTPRINTS3: @@ -93,13 +91,6 @@ void animatesprites_d(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi case BULLETHOLE: t->shade = 16; continue; - case NEON1: - case NEON2: - case NEON3: - case NEON4: - case NEON5: - case NEON6: - continue; default: if (((t->cstat & CSTAT_SPRITE_ALIGNMENT_WALL)) || (badguypic(t->picnum) && t->extra > 0) || t->statnum == STAT_PLAYER) continue; @@ -183,20 +174,12 @@ void animatesprites_d(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi case DUKELYINGDEAD: t->pos.Z += 24; break; - case BLOODPOOL: case FOOTPRINTS: case FOOTPRINTS2: case FOOTPRINTS3: case FOOTPRINTS4: if (t->pal == 6) t->shade = -127; - case PUKE: - case MONEY: - case MONEY + 1: - case MAIL: - case MAIL + 1: - case PAPER: - case PAPER + 1: break; case BURNING: case BURNING2: @@ -538,18 +521,6 @@ void animatesprites_d(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi break; - case WATERSPLASH2: - t->picnum = WATERSPLASH2 + t1; - break; - case SHELL: - t->picnum = h->spr.picnum + (h->temp_data[0] & 1); - [[fallthrough]]; - case SHOTGUNSHELL: - t->cstat |= (CSTAT_SPRITE_XFLIP | CSTAT_SPRITE_YFLIP); - if (h->temp_data[0] > 1) t->cstat &= ~CSTAT_SPRITE_XFLIP; - if (h->temp_data[0] > 2) t->cstat &= ~(CSTAT_SPRITE_XFLIP | CSTAT_SPRITE_YFLIP); - break; - } h->dispicnum = t->picnum; diff --git a/source/games/duke/src/animatesprites_r.cpp b/source/games/duke/src/animatesprites_r.cpp index 13c4b803a..fbf39ab63 100644 --- a/source/games/duke/src/animatesprites_r.cpp +++ b/source/games/duke/src/animatesprites_r.cpp @@ -55,7 +55,6 @@ void animatesprites_r(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi switch (t->picnum) { - case BLOODPOOL: case FOOTPRINTS: case FOOTPRINTS2: case FOOTPRINTS3: @@ -85,13 +84,6 @@ void animatesprites_r(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi case RRTILE8096: if (isRRRA()) continue; - case NEON1: - case NEON2: - case NEON3: - case NEON4: - case NEON5: - case NEON6: - continue; default: if (((t->cstat & CSTAT_SPRITE_ALIGNMENT_WALL)) || (badguypic(t->picnum) && t->extra > 0) || t->statnum == STAT_PLAYER) { @@ -179,15 +171,12 @@ void animatesprites_r(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi if (h->spr.extra > 0) t->pos.Z += 6; break; - case BLOODPOOL: case FOOTPRINTS: case FOOTPRINTS2: case FOOTPRINTS3: case FOOTPRINTS4: if (t->pal == 6) t->shade = -127; - case FEATHER: - case FEATHER + 1: break; case POWDERKEG: continue; @@ -690,20 +679,6 @@ void animatesprites_r(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi t->picnum = h->spr.picnum + k + ((h->temp_data[0] < 4) * 5); if (OwnerAc) t->shade = OwnerAc->spr.shade; break; - case MUD: - t->picnum = MUD + t1; - break; - case WATERSPLASH2: - t->picnum = WATERSPLASH2 + t1; - break; - case SHELL: - t->picnum = h->spr.picnum + (h->temp_data[0] & 1); - [[fallthrough]]; - case SHOTGUNSHELL: - t->cstat |= CSTAT_SPRITE_XFLIP | CSTAT_SPRITE_YFLIP; - if (h->temp_data[0] > 1) t->cstat &= ~CSTAT_SPRITE_XFLIP; - if (h->temp_data[0] > 2) t->cstat &= ~CSTAT_SPRITE_XFLIP | CSTAT_SPRITE_YFLIP; - break; } h->dispicnum = t->picnum; diff --git a/source/games/duke/src/constants.h b/source/games/duke/src/constants.h index 83d4b667c..ace79f8fd 100644 --- a/source/games/duke/src/constants.h +++ b/source/games/duke/src/constants.h @@ -395,6 +395,8 @@ DEFINE_TFLAGS_OPERATORS(EDukeFlags2) enum sflags3_t { SFLAG3_DONTDIVEALIVE = 0x00000001, + SFLAG3_BLOODY = 0x00000002, + SFLAG3_BROWNBLOOD = 0x00000004, }; @@ -414,6 +416,7 @@ enum TFLAG_OUTERSPACE = 1 << 7, TFLAG_NOBLOODSPLAT = 1 << 8, TFLAG_NOCIRCLEREFLECT = 1 << 9, + TFLAG_MUDDY = 1 << 10, }; enum diff --git a/source/games/duke/src/dispatch.cpp b/source/games/duke/src/dispatch.cpp index 5917dd537..c43493af3 100644 --- a/source/games/duke/src/dispatch.cpp +++ b/source/games/duke/src/dispatch.cpp @@ -200,7 +200,6 @@ int TILE_FOOTPRINTS4; int TILE_CLOUDYSKIES; int TILE_ACCESSSWITCH; int TILE_ACCESSSWITCH2; -int TILE_GLASSPIECES; int TILE_HEN; int TILE_MIRROR; int TILE_LOADSCREEN; diff --git a/source/games/duke/src/flags_d.cpp b/source/games/duke/src/flags_d.cpp index 2ff54f3a2..4117a3073 100644 --- a/source/games/duke/src/flags_d.cpp +++ b/source/games/duke/src/flags_d.cpp @@ -110,7 +110,7 @@ void initactorflags_d() setflag(SFLAG2_CAMERA, { CAMERA1 }); setflag(SFLAG2_DONTANIMATE, { TRIPBOMB, LASERLINE }); setflag(SFLAG2_INTERPOLATEANGLE, { BEARINGPLATE }); - setflag(SFLAG2_GREENBLOOD, { OOZFILTER, NEWBEAST }); + setflag(SFLAG2_GREENBLOOD, { OOZFILTER, NEWBEAST, NUKEBARREL }); setflag(SFLAG2_ALWAYSROTATE1, { RAT, CAMERA1 }); setflag(SFLAG2_ALWAYSROTATE2, { RPG }); setflag(SFLAG2_DIENOW, { RADIUSEXPLOSION, KNEE }); @@ -125,6 +125,7 @@ void initactorflags_d() setflag(SFLAG2_NONSMOKYROCKET, { BOSS2 }); // If this wasn't needed for a CON defined actor it could be handled better setflag(SFLAG2_MIRRORREFLECT, { SHRINKSPARK, FIRELASER, COOLEXPLOSION1 }); setflag(SFLAG2_UNDERWATERSLOWDOWN, { RPG }); + setflag(SFLAG3_BROWNBLOOD, { FECES }); if (isWorldTour()) { @@ -201,6 +202,8 @@ void initactorflags_d() }); setflag(SFLAG2_FORCESECTORSHADE, { GREENSLIME }); + setflag(SFLAG3_DONTDIVEALIVE, { GREENSLIME, SHARK, OCTABRAIN }); + setflag(SFLAG3_BLOODY, { BLOODPOOL }); // The feature guarded by this flag does not exist in Duke, it always acts as if the flag was set. for (auto& ainf : gs.actorinfo) ainf.flags |= SFLAG_MOVEFTA_CHECKSEE; @@ -247,7 +250,6 @@ void initactorflags_d() TILE_CLOUDYSKIES = CLOUDYSKIES; TILE_ACCESSSWITCH = ACCESSSWITCH; TILE_ACCESSSWITCH2 = ACCESSSWITCH2; - TILE_GLASSPIECES = GLASSPIECES; TILE_MIRROR = MIRROR; TILE_LOADSCREEN = LOADSCREEN; TILE_CROSSHAIR = CROSSHAIR; diff --git a/source/games/duke/src/flags_r.cpp b/source/games/duke/src/flags_r.cpp index 6910ccb59..7e08fd79a 100644 --- a/source/games/duke/src/flags_r.cpp +++ b/source/games/duke/src/flags_r.cpp @@ -175,13 +175,15 @@ void initactorflags_r() setflag(SFLAG2_BREAKMIRRORS, { RADIUSEXPLOSION, RPG, HYDRENT, DYNAMITE, SEENINE, OOZFILTER, EXPLODINGBARREL, POWDERKEG }); if (isRRRA()) setflag(SFLAG2_BREAKMIRRORS, { RPG2 }); setflag(SFLAG2_CAMERA, { CAMERA1 }); - setflag(SFLAG2_GREENBLOOD, { OOZFILTER }); + setflag(SFLAG2_GREENBLOOD, { OOZFILTER, NUKEBARREL }); setflag(SFLAG2_ALWAYSROTATE1, { RAT, CAMERA1 }); setflag(SFLAG2_ALWAYSROTATE2, { RPG }); setflag(SFLAG2_DIENOW, { RADIUSEXPLOSION }); setflag(SFLAG2_NORADIUSPUSH, { HULK }); setflag(SFLAG2_FREEZEDAMAGE | SFLAG2_REFLECTIVE, { FREEZEBLAST }); setflag(SFLAG2_FLOATING, { DRONE }); + setflag(SFLAG3_BLOODY, { BLOODPOOL }); + setflag(SFLAG3_BROWNBLOOD, { FECES }); setflag(SFLAG2_TRIGGERRESPAWN, { FEM10, @@ -257,7 +259,6 @@ void initactorflags_r() TILE_CLOUDYSKIES = CLOUDYSKIES; TILE_ACCESSSWITCH = ACCESSSWITCH; TILE_ACCESSSWITCH2 = ACCESSSWITCH2; - TILE_GLASSPIECES = GLASSPIECES; TILE_MIRROR = MIRROR; TILE_HEN = HEN; TILE_LOADSCREEN = LOADSCREEN; diff --git a/source/games/duke/src/inlines.h b/source/games/duke/src/inlines.h index 54911b45c..fbe5414b0 100644 --- a/source/games/duke/src/inlines.h +++ b/source/games/duke/src/inlines.h @@ -100,6 +100,14 @@ inline void setflag(EDukeFlags2 flag, const std::initializer_list& types) } } +inline void setflag(EDukeFlags3 flag, const std::initializer_list& types) +{ + for (auto val : types) + { + gs.actorinfo[val].flags3 |= flag; + } +} + inline bool inventory(DDukeActor* S) { return actorflag(S, SFLAG_INVENTORY); diff --git a/source/games/duke/src/namelist_d.h b/source/games/duke/src/namelist_d.h index 34d0bd2db..500a4108d 100644 --- a/source/games/duke/src/namelist_d.h +++ b/source/games/duke/src/namelist_d.h @@ -67,6 +67,9 @@ x(SPACELIGHTSWITCHON, 139) x(FRANKENSTINESWITCH, 140) x(FRANKENSTINESWITCHON, 141) x(NUKEBUTTON, 142) +x(NUKEBUTTON1, 143) +x(NUKEBUTTON2, 144) +x(NUKEBUTTON3, 145) x(MULTISWITCH, 146) x(MULTISWITCH_2, 147) x(MULTISWITCH_3, 148) @@ -366,6 +369,7 @@ x(NUKEBARRELDENTED, 1228) x(NUKEBARRELLEAKED, 1229) x(CANWITHSOMETHING, 1232) x(MONEY, 1233) +x(MONEY1, 1234) x(BANNER, 1236) x(EXPLODINGBARREL, 1238) x(EXPLODINGBARREL2, 1239) @@ -424,6 +428,10 @@ x(COOLEXPLOSION18, 1377) x(COOLEXPLOSION19, 1378) x(COOLEXPLOSION20, 1379) x(WATERSPLASH2, 1380) +x(WATERSPLASH2A, 1381) +x(WATERSPLASH2B, 1382) +x(WATERSPLASH2C, 1383) +x(WATERSPLASH2D, 1384) x(FIREVASE, 1390) x(SCRATCH, 1393) x(FEM7, 1395) @@ -634,6 +642,7 @@ x(FALLINGCLIP, 2530) x(CLIPINHAND, 2531) x(HAND, 2532) x(SHELL, 2533) +x(SHELL1, 2534) x(SHOTGUNSHELL, 2535) x(CHAINGUN, 2536) x(RPGGUN, 2544) @@ -793,6 +802,7 @@ x(ROBOTDOG, 4402) x(ROBOTPIRATE, 4404) x(ROBOTMOUSE, 4407) x(MAIL, 4410) +x(MAIL1, 4411) x(MAILBAG, 4413) x(HOTMEAT, 4427) x(COFFEEMUG, 4438) @@ -803,6 +813,7 @@ x(DESKPHONE, 4454) x(GUMBALLMACHINE, 4458) x(GUMBALLMACHINEBROKE, 4459) x(PAPER, 4460) +x(PAPER1, 4461) x(MACE, 4464) x(GENERICPOLE2, 4465) x(XXXSTACY, 4470) diff --git a/source/games/duke/src/namelist_r.h b/source/games/duke/src/namelist_r.h index 04baa3e07..43856d719 100644 --- a/source/games/duke/src/namelist_r.h +++ b/source/games/duke/src/namelist_r.h @@ -439,6 +439,7 @@ x(NUKEBARRELDENTED, 1305) x(NUKEBARRELLEAKED, 1306) x(CANWITHSOMETHING, 1309) x(FEATHER, 1310) +x(FEATHER1, 1311) x(BANNER, 1313) x(EXPLODINGBARREL, 1315) x(EXPLODINGBARREL2, 1316) @@ -462,6 +463,10 @@ x(INDY, 1357) x(FETUS, 1360) x(FETUSBROKE, 1361) x(WATERSPLASH2, 1383) +x(WATERSPLASH2A, 1384) +x(WATERSPLASH2B, 1385) +x(WATERSPLASH2C, 1386) +x(WATERSPLASH2D, 1387) x(FIREVASE, 1388) x(SCRATCH, 1389) x(BLOOD, 1391) @@ -473,7 +478,10 @@ x(DEVISTATORBLAST, 1410) x(TONGUE, 1414) x(MORTER, 1416) x(MUD, 1420) -x(SHRINKEREXPLOSION, 1421) +x(MUD1, 1421) +x(MUD2, 1422) +x(MUD3, 1423) +x(MUD4, 1424) x(RADIUSEXPLOSION, 1426) x(FORCERIPPLE, 1427) x(CANNONBALL, 1437) @@ -600,6 +608,7 @@ x(FALLINGCLIP, 1699) x(CLIPINHAND, 1700) x(HAND, 1701) x(SHELL, 1702) +x(SHELL1, 1703) x(SHOTGUNSHELL, 1704) x(RPGMUZZLEFLASH, 1714) x(CATLITE, 1721) @@ -773,7 +782,7 @@ y(RRTILE2656, 2656) y(RRTILE2676, 2676) y(RRTILE2689, 2689) y(RRTILE2697, 2697) -y(RRTILE2702, 2702) +y(MUDDYPATH, 2702) y(RRTILE2707, 2707) y(RRTILE2732, 2732) x(HATRACK, 2717) @@ -792,7 +801,6 @@ x(TEDDYBEAR, 2735) x(ROBOTDOG, 2737) x(ROBOTPIRATE, 2739) x(ROBOTMOUSE, 2740) -x(MAIL, 2741) x(MAILBAG, 2742) x(HOTMEAT, 2744) x(COFFEEMUG, 2745) @@ -920,7 +928,7 @@ x(OCEANSPRITE5, 3059) x(GENERICPOLE, 3061) x(CONE, 3062) x(HANGLIGHT, 3063) -y(RRTILE3073, 3073) +x(MUDDY, 3073) y(RRTILE3083, 3083) y(RRTILE3100, 3100) y(RRTILE3114, 3114) diff --git a/source/games/duke/src/names.h b/source/games/duke/src/names.h index 5b8a4c082..2b7d4dc73 100644 --- a/source/games/duke/src/names.h +++ b/source/games/duke/src/names.h @@ -25,7 +25,6 @@ extern int TILE_FOOTPRINTS4; extern int TILE_CLOUDYSKIES; extern int TILE_ACCESSSWITCH; extern int TILE_ACCESSSWITCH2; -extern int TILE_GLASSPIECES; extern int TILE_HEN; extern int TILE_MIRROR; extern int TILE_LOADSCREEN; diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index 565b6b5e9..6d0fd0f09 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -3622,7 +3622,7 @@ void processinput_r(int snum) } else - if (psectp->floorpicnum == RRTILE3073 || psectp->floorpicnum == RRTILE2702) + if (psectp->floorpicnum == MUDDY || psectp->floorpicnum == MUDDYPATH) { if (p->OnMotorcycle) { diff --git a/source/games/duke/src/sectors_d.cpp b/source/games/duke/src/sectors_d.cpp index cfaa1b1e0..6f821fd58 100644 --- a/source/games/duke/src/sectors_d.cpp +++ b/source/games/duke/src/sectors_d.cpp @@ -1407,22 +1407,6 @@ void checksectors_d(int snum) S_PlayActorSound(FLUSH_TOILET, neartagsprite); return; - case NUKEBUTTON: - { - walltype* wal; - hitawall(p, &wal); - if (wal != nullptr && wal->overpicnum == 0) - if (neartagsprite->temp_data[0] == 0) - { - neartagsprite->temp_data[0] = 1; - neartagsprite->SetOwner(p->GetActor()); - p->buttonpalette = neartagsprite->spr.pal; - if (p->buttonpalette) - ud.secretlevel = neartagsprite->spr.lotag; - else ud.secretlevel = 0; - } - return; - } case PLUG: S_PlayActorSound(SHORT_CIRCUIT, pact); p->GetActor()->spr.extra -= 2 + (krand() & 3); diff --git a/source/games/duke/src/spawn.cpp b/source/games/duke/src/spawn.cpp index d98f3c5c6..fb8a66ff6 100644 --- a/source/games/duke/src/spawn.cpp +++ b/source/games/duke/src/spawn.cpp @@ -434,57 +434,6 @@ void initfootprint(DDukeActor* actj, DDukeActor* act) // //--------------------------------------------------------------------------- -void initshell(DDukeActor* actj, DDukeActor* act, bool isshell) -{ - if (actj) - { - int snum; - DAngle ang; - - if (actj->isPlayer()) - { - snum = actj->PlayerIndex(); - ang = ps[snum].GetActor()->spr.Angles.Yaw - mapangle((krand() & 63) + 8); //Fine tune - - act->temp_data[0] = krand() & 1; - act->spr.pos.Z = 3 + ps[snum].GetActor()->getOffsetZ() + ps[snum].pyoff + (ps[snum].Angles.getPitchWithView().Tan() * 8.) + (!isshell ? 3 : 0); - act->vel.Z = -krandf(1); - } - else - { - ang = act->spr.Angles.Yaw; - act->spr.pos.Z = actj->spr.pos.Z - gs.playerheight + 3; - } - - act->spr.pos.XY() = actj->spr.pos.XY() + ang.ToVector() * 8; - - act->spr.shade = -8; - - if (isNamWW2GI()) - { - // to the right, with feeling - act->spr.Angles.Yaw = ang + DAngle90; - act->vel.X = 1.875; - } - else - { - act->spr.Angles.Yaw = ang - DAngle90; - act->vel.X = 1.25; - } - - double scale = isRR() && isshell ? 0.03125 : 0.0625; - act->spr.scale = DVector2(scale, scale); - - ChangeActorStat(act, STAT_MISC); - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - void spawneffector(DDukeActor* actor, TArray* actors) { auto sectp = actor->sector(); @@ -963,6 +912,20 @@ void spawneffector(DDukeActor* actor, TArray* actors) // //--------------------------------------------------------------------------- +inline PClassActor* GlassClass(int j) +{ + static PClassActor* glasses[3]; + if (glasses[0] == nullptr) + { + static const FName glassnames[] = { NAME_DukeGlassPieces, NAME_DukeGlassPieces1, NAME_DukeGlassPieces2 }; + for (int i = 0; i < 3; i++) + { + glasses[i] = PClass::FindActor(glassnames[i]); + } + } + return glasses[j % 3]; +} + void lotsofglass(DDukeActor *actor, walltype* wal, int n) { int j; @@ -976,7 +939,7 @@ void lotsofglass(DDukeActor *actor, walltype* wal, int n) auto vel = krandf(4) + 2; auto zvel = 4 - krandf(4); - CreateActor(actor->sector(), actor->spr.pos, TILE_GLASSPIECES + (j % 3), -32, DVector2(0.5625, 0.5625), a, vel, zvel, actor, 5); + CreateActor(actor->sector(), actor->spr.pos, GlassClass(j), -32, DVector2(0.5625, 0.5625), a, vel, zvel, actor, 5); } return; } @@ -1003,7 +966,7 @@ void lotsofglass(DDukeActor *actor, walltype* wal, int n) auto vel = krandf(4) + 2; auto zvel = 4 - krandf(4); - CreateActor(actor->sector(), DVector3(pos, z), TILE_GLASSPIECES + (j % 3), -32, DVector2(0.5625, 0.5625), angl, vel, zvel, actor, 5); + CreateActor(actor->sector(), DVector3(pos, z), GlassClass(j), -32, DVector2(0.5625, 0.5625), angl, vel, zvel, actor, 5); } } } @@ -1022,7 +985,7 @@ void spriteglass(DDukeActor* actor, int n) auto vel = krandf(4) + 2; auto zvel = -2 - krandf(8); - auto k = CreateActor(actor->sector(), actor->spr.pos.plusZ(-(krand() & 16)), TILE_GLASSPIECES + (j % 3), krand() & 15, DVector2(0.5625, 0.5625), a, vel, zvel, actor, 5); + auto k = CreateActor(actor->sector(), actor->spr.pos.plusZ(-(krand() & 16)), GlassClass(j), krand() & 15, DVector2(0.5625, 0.5625), a, vel, zvel, actor, 5); if (k) k->spr.pal = actor->spr.pal; } } @@ -1047,7 +1010,7 @@ void ceilingglass(DDukeActor* actor, sectortype* sectp, int n) auto vel = krandf(2); double z = sectp->ceilingz + krandf(16); - CreateActor(sectp, DVector3(pos, z), TILE_GLASSPIECES + (j % 3), -32, DVector2(0.5625, 0.5625), a, vel, 0, actor, 5); + CreateActor(sectp, DVector3(pos, z), GlassClass(j), -32, DVector2(0.5625, 0.5625), a, vel, 0, actor, 5); } } } @@ -1071,7 +1034,7 @@ void lotsofcolourglass(DDukeActor* actor, walltype* wal, int n) auto vel = krandf(4) + 2; auto zvel = 4 - krandf(4); - auto k = CreateActor(actor->sector(), actor->spr.pos.plusZ(-(krand() & 63)), TILE_GLASSPIECES + (j % 3), -32, DVector2(0.5625, 0.5625), a, vel, zvel, actor, 5); + auto k = CreateActor(actor->sector(), actor->spr.pos.plusZ(-(krand() & 63)), GlassClass(j), -32, DVector2(0.5625, 0.5625), a, vel, zvel, actor, 5); if (k) k->spr.pal = krand() & 15; } return; @@ -1095,7 +1058,7 @@ void lotsofcolourglass(DDukeActor* actor, walltype* wal, int n) auto vel = krandf(4) + 2; auto zvel = - krandf(8); - auto k = CreateActor(actor->sector(), DVector3(pos, z), TILE_GLASSPIECES + (j % 3), -32, DVector2(0.5625, 0.5625), a, vel, zvel, actor, 5); + auto k = CreateActor(actor->sector(), DVector3(pos, z), GlassClass(j), -32, DVector2(0.5625, 0.5625), a, vel, zvel, actor, 5); if (k) k->spr.pal = krand() & 7; } } diff --git a/source/games/duke/src/spawn_d.cpp b/source/games/duke/src/spawn_d.cpp index c38592af8..6467fd454 100644 --- a/source/games/duke/src/spawn_d.cpp +++ b/source/games/duke/src/spawn_d.cpp @@ -151,48 +151,6 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray* act->spr.scale = DVector2(0, 0); ChangeActorStat(act, STAT_MISC); break; - case WATERSPLASH2: - if (actj) - { - SetActor(act, actj->spr.pos); - double s = 0.125 + (krand() & 7) * REPEAT_SCALE; - act->spr.scale = DVector2(s, s); - } - else - { - double s = 0.25 + (krand() & 15) * REPEAT_SCALE; - act->spr.scale = DVector2(s, s); - } - - act->spr.shade = -16; - act->spr.cstat |= CSTAT_SPRITE_YCENTER; - if (actj) - { - if (actj->sector()->lotag == 2) - { - act->spr.pos.Z = getceilzofslopeptr(act->sector(), act->spr.pos) + 16; - act->spr.cstat |= CSTAT_SPRITE_YFLIP; - } - else if (actj->sector()->lotag == 1) - act->spr.pos.Z = getflorzofslopeptr(act->sector(), act->spr.pos); - } - - if (sectp->floorpicnum == FLOORSLIME || - sectp->ceilingpicnum == FLOORSLIME) - act->spr.pal = 7; - [[fallthrough]]; - case NEON1: - case NEON2: - case NEON3: - case NEON4: - case NEON5: - case NEON6: - if (act->spr.picnum != WATERSPLASH2) - act->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL; - [[fallthrough]]; - case NUKEBUTTON: - ChangeActorStat(act, STAT_MISC); - break; case NATURALLIGHTNING: act->spr.cstat &= ~CSTAT_SPRITE_BLOCK_ALL; act->spr.cstat |= CSTAT_SPRITE_INVISIBLE; @@ -212,29 +170,11 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray* case LAVAPOOL: if (!isWorldTour()) // Twentieth Anniversary World Tour return act; - [[fallthrough]]; - case BLOODPOOL: - case PUKE: if (spawnbloodpoolpart1(act)) break; - if (actj && act->spr.picnum != PUKE) - { - if (actj->spr.pal == 1) - act->spr.pal = 1; - else if (actj->spr.pal != 6 && actj->spr.picnum != NUKEBARREL) - { - if (actj->spr.picnum == FECES) - act->spr.pal = 7; // Brown - else act->spr.pal = 2; // Red - } - else act->spr.pal = 0; // green - } act->spr.cstat |= CSTAT_SPRITE_ALIGNMENT_FLOOR; - if (act->spr.picnum == LAVAPOOL) // Twentieth Anniversary World Tour - { - act->spr.pos.Z = getflorzofslopeptr(act->sector(), act->spr.pos) - 0.78125; - } + act->spr.pos.Z = getflorzofslopeptr(act->sector(), act->spr.pos) - 0.78125; [[fallthrough]]; case FECES: @@ -366,25 +306,9 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray* act->spr.scale = DVector2(0.046875, 0.046875); act->spr.cstat = CSTAT_SPRITE_ALIGNMENT_WALL | randomFlip(); insertspriteq(act); - [[fallthrough]]; - case MONEY: - case MAIL: - case PAPER: - if (act->spr.picnum == MONEY || act->spr.picnum == MAIL || act->spr.picnum == PAPER) - { - act->temp_data[0] = krand() & 2047; - act->spr.cstat = randomFlip(); - act->spr.scale = DVector2(0.125, 0.125); - act->spr.Angles.Yaw = randomAngle(); - } ChangeActorStat(act, STAT_MISC); break; - case SHELL: //From the player - case SHOTGUNSHELL: - initshell(actj, act, act->spr.picnum == SHELL); - break; - case ONFIRE: // Twentieth Anniversary World Tour if (!isWorldTour()) @@ -416,7 +340,6 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray* } else if (act->spr.picnum == SMALLSMOKE || act->spr.picnum == ONFIRE) { - // 64 "money" act->spr.scale = DVector2(0.375, 0.375); } else if (act->spr.picnum == BURNING || act->spr.picnum == BURNING2) diff --git a/source/games/duke/src/spawn_r.cpp b/source/games/duke/src/spawn_r.cpp index 0af6a94dd..236ba83b9 100644 --- a/source/games/duke/src/spawn_r.cpp +++ b/source/games/duke/src/spawn_r.cpp @@ -118,47 +118,6 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray* pistonsound = 1; break; - case WATERSPLASH2: - case MUD: - if (actj) - { - SetActor(act, actj->spr.pos); - double s = 0.125 + (krand() & 7) * REPEAT_SCALE; - act->spr.scale = DVector2(s, s); - } - else - { - double s = 0.25 + (krand() & 15) * REPEAT_SCALE; - act->spr.scale = DVector2(s, s); - } - - act->spr.shade = -16; - act->spr.cstat |= CSTAT_SPRITE_YCENTER; - if (actj) - { - if (actj->sector()->lotag == 2) - { - act->spr.pos.Z = getceilzofslopeptr(act->sector(), act->spr.pos) + 16; - act->spr.cstat |= CSTAT_SPRITE_YFLIP; - } - else if (actj->sector()->lotag == 1) - act->spr.pos.Z = getceilzofslopeptr(act->sector(), act->spr.pos); - } - - if (sectp->floorpicnum == FLOORSLIME || - sectp->ceilingpicnum == FLOORSLIME) - act->spr.pal = 7; - [[fallthrough]]; - case NEON1: - case NEON2: - case NEON3: - case NEON4: - case NEON5: - case NEON6: - if (act->spr.picnum != WATERSPLASH2) - act->spr.cstat |= CSTAT_SPRITE_BLOCK_ALL; - ChangeActorStat(act, STAT_MISC); - break; case TRANSPORTERSTAR: case TRANSPORTERBEAM: spawntransporter(actj, act, act->spr.picnum == TRANSPORTERBEAM); @@ -169,22 +128,6 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray* act->spr.pos.Z -= 26; ChangeActorStat(act, STAT_MISC); break; - case BLOODPOOL: - if (spawnbloodpoolpart1(act)) break; - - if (actj) - { - if (actj->spr.pal == 1) - act->spr.pal = 1; - else if (actj->spr.pal != 6 && actj->spr.picnum != NUKEBARREL) - { - act->spr.pal = 2; // Red - } - else act->spr.pal = 0; // green - } - act->spr.cstat |= CSTAT_SPRITE_ALIGNMENT_FLOOR; - [[fallthrough]]; - case HYDRENT: case SATELITE: case FUELPOD: @@ -279,22 +222,9 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray* act->spr.scale = DVector2(0.046875, 0.046875); act->spr.cstat = CSTAT_SPRITE_ALIGNMENT_WALL | randomFlip(); insertspriteq(act); - [[fallthrough]]; - case FEATHER: - if (act->spr.picnum == FEATHER) - { - act->temp_data[0] = krand() & 2047; - act->spr.cstat = randomFlip(); - act->spr.scale = DVector2(0.125, 0.125); - act->spr.Angles.Yaw = randomAngle(); - } ChangeActorStat(act, STAT_MISC); break; - case SHELL: //From the player - case SHOTGUNSHELL: - initshell(actj, act, act->spr.picnum == SHELL); - break; case EXPLOSION2: case EXPLOSION3: case BURNING: diff --git a/source/games/duke/src/vmexports.cpp b/source/games/duke/src/vmexports.cpp index 23767b9ac..b61c6754c 100644 --- a/source/games/duke/src/vmexports.cpp +++ b/source/games/duke/src/vmexports.cpp @@ -16,12 +16,10 @@ int PicForName(int intname) static std::pair classes[] = { { "DukeToiletWater", "TOILETWATER" }, { "DukeBurning", "BURNIMG"}, - {"DukeBloodPool","BLOODPOOL"}, {"DukeExplosion2","EXPLOSION2"}, {"DukeExplosion2Bot","EXPLOSION2BOT"}, {"DukeTransporterStar", "TRANSPORTERSTAR"}, {"RedneckRabbit","RABBIT"}, - {"RedneckFeather","FEATHER"}, {"DukeBatteryAmmo", "BATTERYAMMO"}, {"DukeSixpak", "SIXPAK"}, {"DukeAtomicHealth", "ATOMICHEALTH"}, @@ -31,7 +29,6 @@ int PicForName(int intname) {"RedneckCircleStuck", "CIRCLESTUCK"}, {"DukePigCop", "PIGCOP"}, {"DukeSmallSmoke", "SMALLSMOKE"}, - {"DukeMoney", "MONEY"}, {"DukeBurning", "BURNING"}, }; @@ -710,6 +707,13 @@ DEFINE_ACTION_FUNCTION(DDukeActor, actorflag2) ACTION_RETURN_BOOL(!!actorflag(self, EDukeFlags2::FromInt(mask))); } +DEFINE_ACTION_FUNCTION(DDukeActor, actorflag3) +{ + PARAM_SELF_PROLOGUE(DDukeActor); + PARAM_INT(mask); + ACTION_RETURN_BOOL(!!actorflag(self, EDukeFlags3::FromInt(mask))); +} + DEFINE_ACTION_FUNCTION(DDukeActor, attackerflag1) { PARAM_SELF_PROLOGUE(DDukeActor); @@ -1082,6 +1086,27 @@ DEFINE_ACTION_FUNCTION_NATIVE(_DukePlayer, addweapon, DukePlayer_addweapon) } +DEFINE_ACTION_FUNCTION(_DukePlayer, hitablockingwall) +{ + PARAM_SELF_STRUCT_PROLOGUE(player_struct); + walltype* pwal; + hitawall(self, &pwal); + ACTION_RETURN_BOOL(pwal && pwal->overpicnum > 0); +} + +inline double DukePlayer_GetPitchwithView(player_struct* pl) +{ + return pl->Angles.getPitchWithView().Degrees(); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_DukePlayer, GetPitchwithView, DukePlayer_GetPitchwithView) +{ + PARAM_SELF_STRUCT_PROLOGUE(player_struct); + ACTION_RETURN_FLOAT(DukePlayer_GetPitchwithView(self)); +} + + + static DDukeActor* duke_firstStat(DukeStatIterator* it, int statnum) { it->Reset(statnum); @@ -1214,6 +1239,18 @@ DEFINE_ACTION_FUNCTION_NATIVE(_DukeLevel, floorflags, duke_floorflags) ACTION_RETURN_INT(duke_floorflags(sect)); } +int duke_ceilingflags(sectortype* sector) +{ + return tileflags(sector->floorpicnum); +} + +DEFINE_ACTION_FUNCTION_NATIVE(_DukeLevel, ceilingflags, duke_ceilingflags) +{ + PARAM_PROLOGUE; + PARAM_POINTER(sect, sectortype); + ACTION_RETURN_INT(duke_ceilingflags(sect)); +} + int duke_wallflags(walltype* wal, int which) { return tileflags(which? wal->overpicnum : wal->picnum); diff --git a/wadsrc/static/filter/dukeengine/engine/defines.def b/wadsrc/static/filter/dukeengine/engine/defines.def index 288635735..fe88ac1c0 100644 --- a/wadsrc/static/filter/dukeengine/engine/defines.def +++ b/wadsrc/static/filter/dukeengine/engine/defines.def @@ -11,3 +11,4 @@ define TFLAG_BLOCKDOOR 64 define TFLAG_OUTERSPACE 128 define TFLAG_NOBLOODSPLAT 256 define TFLAG_NOCIRCLEREFLECT 512 +define TFLAG_MUDDY 1024 diff --git a/wadsrc/static/filter/dukelike/engine/engine.def b/wadsrc/static/filter/dukelike/engine/engine.def index a4af3b5f5..46d757433 100644 --- a/wadsrc/static/filter/dukelike/engine/engine.def +++ b/wadsrc/static/filter/dukelike/engine/engine.def @@ -80,6 +80,23 @@ spawnclasses 940 = DukeBounceMine 1650 = DukeMortar 2999 = DukeFrameEffect + 925 = DukeNeon1 + 926 = DukeNeon2 + 1007 = DukeNeon3 + 1008 = DukeNeon4 + 1009 = DukeNeon5 + 1046 = DukeNeon6 + 142 = DukeNukeButton + 1233 = DukeMoney + 4460 = DukePaper + 4410 = DukeMail + 1380 = DukeWaterSplash + 1031 = DukeGlassPieces1 + 1032 = DukeGlassPieces2 + 1033 = DukeGlassPieces3 + 2533 = DukeShell + 2535 = DukeShotgunShell + 1226 = DukeBloodPool 1272 = DukeTrash 634 = DukeBolt1 diff --git a/wadsrc/static/filter/redneck/engine/engine.def b/wadsrc/static/filter/redneck/engine/engine.def index dec301f93..422868e0d 100644 --- a/wadsrc/static/filter/redneck/engine/engine.def +++ b/wadsrc/static/filter/redneck/engine/engine.def @@ -74,6 +74,21 @@ spawnclasses 1280 = DukeBottle10 1172 = DukeVase 4095 = DukeFrameEffect + 1200 = DukeNeon1 + 1201 = DukeNeon2 + 1241 = DukeNeon3 + 1242 = DukeNeon4 + 1243 = DukeNeon5 + 1264 = DukeNeon6 + 1310 = RedneckFeather + 1383 = DukeWaterSplash + 1420 = RedneckMudSplash + 1256 = DukeGlassPieces1 + 1257 = DukeGlassPieces2 + 1258 = DukeGlassPieces3 + 1702 = DukeShell + 1704 = DukeShotgunShell + 1303 = DukeBloodPool 26 = RedneckDynamite 1416 = RedneckMortar @@ -332,4 +347,7 @@ tileflag TFLAG_BLOCKDOOR { RRTILE3819 RRTILE3827 RRTILE3837 - } \ No newline at end of file + } + +tileflag TFLAG_MUDDY { MUDDY MUDDYPATH } + \ No newline at end of file diff --git a/wadsrc/static/filter/redneck/sndinfo.txt b/wadsrc/static/filter/redneck/sndinfo.txt index 05ca8f854..393389814 100644 --- a/wadsrc/static/filter/redneck/sndinfo.txt +++ b/wadsrc/static/filter/redneck/sndinfo.txt @@ -20,7 +20,7 @@ $conreserve VENT_BUST 18 $conreserve GLASS_BREAKING 19 $conreserve GLASS_HEAVYBREAK 20 $conreserve BUBBLES 21 -$conreserve SPLASH 22 +$conreserve ITEM_SPLASH 22 $conreserve BUB_HRT2 23 $conreserve BUB_HRT3 24 $conreserve PLAYER_GASP 25 diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 1723eac98..c977aa948 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -90,7 +90,13 @@ version "4.10" #include "zscript/games/duke/actors/helicopt.zs" #include "zscript/games/duke/actors/greenslime.zs" #include "zscript/games/duke/actors/heavyhbomb.zs" -#include "zscript/games/duke/actors/mortar.zs" +#include "zscript/games/duke/actors/neon.zs" +#include "zscript/games/duke/actors/nukebutton.zs" +#include "zscript/games/duke/actors/paper.zs" +#include "zscript/games/duke/actors/watersplash.zs" +#include "zscript/games/duke/actors/glasspieces.zs" +#include "zscript/games/duke/actors/shell.zs" +#include "zscript/games/duke/actors/bloodpool.zs" #include "zscript/games/duke/actors/redneckmisc.zs" diff --git a/wadsrc/static/zscript/coreactor.zs b/wadsrc/static/zscript/coreactor.zs index 990153d63..44034a4ab 100644 --- a/wadsrc/static/zscript/coreactor.zs +++ b/wadsrc/static/zscript/coreactor.zs @@ -67,6 +67,7 @@ class CoreActor native native void backuppos(); native void setPosition(Vector3 pos); native void setPositionZ(Vector3 pos); + native bool isAwayFromWall(double dist); native clearscope static double deltaangle(double ang1, double ang2); native clearscope static double absangle(double ang1, double ang2); diff --git a/wadsrc/static/zscript/games/duke/actors/bloodpool.zs b/wadsrc/static/zscript/games/duke/actors/bloodpool.zs new file mode 100644 index 000000000..9a68ddb1f --- /dev/null +++ b/wadsrc/static/zscript/games/duke/actors/bloodpool.zs @@ -0,0 +1,141 @@ +class DukeBloodPool : DukeActor +{ + default + { + pic "BLOODPOOL"; + statnum STAT_MISC; + } + + virtual void SetPalette() + { + let Owner = self.ownerActor; + if (Owner) + { + if (Owner.pal == 1) + self.pal = 1; // Blue + else if (Owner.pal == 6 || Owner.actorflag2(SFLAG2_GREENBLOOD)) + { + self.pal = 0; // Green + self.temp_data[5] = 1; // this hurts! + } + else if (Owner.actorflag3(SFLAG3_BROWNBLOOD)) + self.pal = 7; // Brown + else + self.pal = 2; // Red + } + } + + override void Initialize() + { + if (!checkLocationForFloorSprite(6.75)) return; + SetPalette(); + self.cstat |= CSTAT_SPRITE_ALIGNMENT_FLOOR; + if (self.OwnerActor) + self.scale = (REPEAT_SCALE, REPEAT_SCALE); + } + + override void Tick() + { + let sectp = self.sector; + + if (self.temp_data[0] == 0) + { + self.temp_data[0] = 1; + if (sectp.floorstat & CSTAT_SECTOR_SLOPE) + { + self.Destroy(); + return; + } + else self.insertspriteq(); + } + if (Raze.isRR() && self.sector.lotag == 800) + { + self.Destroy(); + return; + } + + self.makeitfall(); + + double xx; + DukePlayer plr; + [plr, xx] = self.findplayer(); + + self.pos.Z = self.floorz - 0.125; + + if (self.temp_data[2] < 32) + { + self.temp_data[2]++; + if (self.detail == 1) + { + if (self.scale.X < 1 && self.scale.Y < 1) + { + self.scale.X += (random(0, 3) * REPEAT_SCALE); + self.scale.Y += (random(0, 3) * REPEAT_SCALE); + } + } + else + { + if (self.scale.X < 0.5 && self.scale.Y < 0.5) + { + self.scale.X += (random(0, 3) * REPEAT_SCALE); + self.scale.Y += (random(0, 3) * REPEAT_SCALE); + } + } + } + + if (xx < 844 / 16. && self.scale.X > 0.09375 && self.scale.Y > 0.09375) + { + if (random(0, 256) < 16 && self.temp_data[5]) + { + if (plr.boot_amount > 0) + plr.boot_amount--; + else + { + if (!plr.actor.CheckSoundPlaying("PLAYER_LONGTERM_PAIN")) + plr.actor.PlayActorSound("PLAYER_LONGTERM_PAIN"); + plr.actor.extra--; + plr.pals = Color(32, 16, 0, 0); + } + } + + if (self.temp_data[1] == 1) return; + self.temp_data[1] = 1; + + if (self.detail == 1) + plr.footprintcount = 10; + else plr.footprintcount = 3; + + plr.footprintpal = self.pal; + plr.footprintshade = self.shade; + + if (self.temp_data[2] == 32) + { + self.scale.X += (-0.09375); + self.scale.Y += (-0.09375); + } + } + else self.temp_data[1] = 0; + } + + override bool Animate(tspritetype t) + { + if (self.shade == 127) t.shade = self.shade; + if (t.pal == 6) t.shade = -127; + return true; + } +} + + +class DukePuke : DukeBloodPool +{ + default + { + pic "PUKE"; + } + + override bool Animate(tspritetype t) + { + if (self.shade == 127) t.shade = self.shade; + return true; + } +} diff --git a/wadsrc/static/zscript/games/duke/actors/glasspieces.zs b/wadsrc/static/zscript/games/duke/actors/glasspieces.zs new file mode 100644 index 000000000..85d232f95 --- /dev/null +++ b/wadsrc/static/zscript/games/duke/actors/glasspieces.zs @@ -0,0 +1,64 @@ + +class DukeGlassPieces : DukeActor +{ + default + { + spriteset "GLASSPIECES"; + } + override void Tick() + { + let sectp = self.sector; + + self.makeitfall(); + + if (self.vel.Z > 16) self.vel.Z = 16; + if (sectp == null) + { + self.Destroy(); + return; + } + + if (self.pos.Z == self.floorz - 1 && self.temp_data[0] < 3) + { + self.vel.Z = -(3 - self.temp_data[0]) - frandom(0, 2); + if (sectp.lotag == 2) + self.vel.Z *= 0.5; + + self.scale *= 0.5; + if (Duke.rnd(96)) + self.SetPosition(self.pos); + self.temp_data[0]++;//Number of bounces + } + else if (self.temp_data[0] == 3) + { + self.Destroy(); + return; + } + + if(self.vel.X > 0) + { + self.vel.X -= 1/8.; + self.cstat = randomFlip(); + } + else self.vel.X = 0; + + self.DoMove(CLIPMASK0); + } +} + +class DukeGlassPieces1 : DukeGlassPieces +{ + default + { + spriteset "GLASSPIECES1"; + } +} + +class DukeGlassPieces2 : DukeGlassPieces +{ + default + { + spriteset "GLASSPIECES2"; + } +} + diff --git a/wadsrc/static/zscript/games/duke/actors/neon.zs b/wadsrc/static/zscript/games/duke/actors/neon.zs new file mode 100644 index 000000000..24c46ce70 --- /dev/null +++ b/wadsrc/static/zscript/games/duke/actors/neon.zs @@ -0,0 +1,66 @@ +class DukeNeon1 : DukeActor +{ + default + { + statnum STAT_MISC; + pic "NEON1"; + } + + override void Initialize() + { + self.cstat |= CSTAT_SPRITE_BLOCK_ALL; + } + + override void Tick() + { + if ((Duke.global_random() / (self.lotag + 1) & 31) > 4) self.shade = -127; + else self.shade = 127; + } + + override bool Animate(tspritetype t) + { + t.shade = self.shade; + return true; + } +} + +class DukeNeon2 : DukeNeon1 +{ + default + { + pic "NEON2"; + } +} + +class DukeNeon3 : DukeNeon1 +{ + default + { + pic "NEON3"; + } +} + +class DukeNeon4 : DukeNeon1 +{ + default + { + pic "NEON4"; + } +} + +class DukeNeon5 : DukeNeon1 +{ + default + { + pic "NEON5"; + } +} + +class DukeNeon6 : DukeNeon1 +{ + default + { + pic "NEON6"; + } +} + diff --git a/wadsrc/static/zscript/games/duke/actors/nukebutton.zs b/wadsrc/static/zscript/games/duke/actors/nukebutton.zs new file mode 100644 index 000000000..8d2fd4c0b --- /dev/null +++ b/wadsrc/static/zscript/games/duke/actors/nukebutton.zs @@ -0,0 +1,41 @@ + +class DukeNukeButton : DukeActor +{ + default + { + spriteset "NUKEBUTTON", "NUKEBUTTON1", "NUKEBUTTON2", "NUKEBUTTON3"; + statnum STAT_MISC; + } + + override void Tick() + { + if (self.temp_data[0]) + { + self.temp_data[0]++; + let Owner = self.ownerActor; + if (self.temp_data[0] == 8) self.setSpritesetImage(1); + else if (self.temp_data[0] == 16 && Owner) + { + self.setSpritesetImage(2); + Owner.GetPlayer().fist_incs = 1; + } + if (Owner && Owner.GetPlayer().fist_incs == 26) + self.setSpritesetImage(3); + } + } + + override bool OnUse(DukePlayer p) + { + if (self.temp_data[0] == 0 && !p.hitablockingwall()) + { + self.temp_data[0] = 1; + self.ownerActor = p.actor; + p.buttonpalette = self.pal; + if (p.buttonpalette) + ud.secretlevel = self.lotag; + else ud.secretlevel = 0; + } + return true; + } +} + diff --git a/wadsrc/static/zscript/games/duke/actors/paper.zs b/wadsrc/static/zscript/games/duke/actors/paper.zs new file mode 100644 index 000000000..ec89d89c1 --- /dev/null +++ b/wadsrc/static/zscript/games/duke/actors/paper.zs @@ -0,0 +1,116 @@ + +class DukeMoney : DukeActor +{ + default + { + statnum STAT_MISC; + spriteset "MONEY", "MONEY1"; + ScaleX 0.125; + ScaleY 0.125; + } + + override void Initialize() + { + self.temp_data[0] = random(0, 2047); + self.cstat = self.randomFlip(); + self.angle = frandom(0, 360); + } + + override void Tick() + { + let sectp = self.sector; + + if (self.spriteSetIndex == 1) + { + double x; + [x, self.floorz] = sectp.getSlopes(self.pos.XY); + self.vel.Z = self.floorz; + return; + } + + self.vel.X = frandom(0, 0.5) + Raze.BobVal(self.temp_data[0]) * 2; + self.temp_data[0] += random(0, 63); + if ((self.temp_data[0] & 2047) > 512 && (self.temp_data[0] & 2047) < 1596) + { + if (sectp.lotag == ST_2_UNDERWATER) + { + if (self.vel.Z < 0.25) + self.vel.Z += gs.gravity / 32. + frandom(0, 1/32.); + } + else + if (self.vel.Z < 0.5625) + self.vel.Z += gs.gravity / 32. + frandom(0, 1 / 32.); + } + + self.DoMove(CLIPMASK0); + + if ( random(0, 3) == 0) + self.SetPosition(self.pos); + + if (self.sector == null) + { + self.Destroy(); + return; + } + double x, l; + [x, l] = sectp.getSlopes(self.pos.XY); + + + if (self.pos.Z > l) + { + self.pos.Z = l; + self.insertspriteq(); + self.setSpriteSetImage(1); + + DukeStatIterator it; + for (let aa = it.First(STAT_MISC); aa; aa = it.Next()) + { + if (aa.actorflag3(SFLAG3_BLOODY)) + { + double dist = (aa.pos.XY - self.pos.XY).Length(); + if (dist < 348/16.) + { + self.pal = 2; + break; + } + } + } + } + } +} + +class DukeMail : DukeMoney +{ + default + { + spriteset "MAIL", "MAIL1"; + } +} + +class DukePaper : DukeMoney +{ + default + { + spriteset "PAPER", "PAPER1"; + } +} + +class RedneckFeather : DukeMoney +{ + default + { + spriteset "FEATHER", "FEATHER1"; + } + + override void Tick() + { + Super.Tick(); + if (self.sector.lotag == 800) + { + if ((self.pos.Z >= self.sector.floorz - 8) || self.spritesetindex == 1) + self.Destroy(); + } + } + +} + diff --git a/wadsrc/static/zscript/games/duke/actors/shell.zs b/wadsrc/static/zscript/games/duke/actors/shell.zs new file mode 100644 index 000000000..5b22ad968 --- /dev/null +++ b/wadsrc/static/zscript/games/duke/actors/shell.zs @@ -0,0 +1,125 @@ + +class DukeShell : DukeActor +{ + default + { + shade -8; + statnum STAT_MISC; + spriteset "SHELL", "SHELL1"; + } + + void initshell(bool isshell, double direction) + { + let Owner = self.OwnerActor; + if (Owner && Owner != self) + { + double ang; + + if (Owner.isPlayer()) + { + let plr = Owner.GetPlayer(); + let pactor = plr.actor; + ang = pactor.angle - Raze.BAngToDegree * (random(8, 71)); //Fine tune + + self.temp_data[0] = random(0, 1); + self.pos.Z = 3 + pactor.pos.Z + pactor.viewzoffset + plr.pyoff + tan(plr.getPitchWithView()) * 8. + (!isshell ? 3 : 0); + self.vel.Z = -frandom(0, 1); + } + else + { + ang = self.angle; + self.pos.Z = Owner.pos.Z - gs.playerheight + 3; + } + + self.pos.XY = Owner.pos.XY + ang.ToVector() * 8; + + if (direction > 0) + { + // to the right, with feeling + self.angle = ang + 90; + self.vel.X = direction; + } + else + { + self.angle = ang - 90; + self.vel.X = -direction; + } + + double scale = Raze.isRR() && isshell ? 0.03125 : 0.0625; + self.scale = (scale, scale); + } + } + + override void Initialize() + { + initshell(true, Raze.isNamWW2GI()? 1.875 : -1.25); + } + + override void Tick() + { + let sectp = self.sector; + + self.DoMove(CLIPMASK0); + + if (sectp == null || sectp.floorz + 24 < self.pos.Z) + { + self.Destroy(); + return; + } + + if (sectp.lotag == ST_2_UNDERWATER) + { + self.temp_data[1]++; + if (self.temp_data[1] > 8) + { + self.temp_data[1] = 0; + self.temp_data[0]++; + self.temp_data[0] &= 3; + } + if (self.vel.Z < 0.5) self. vel.Z += (gs.gravity / 13); // 8 + else self.vel.Z -= 0.25; + if (self.vel.X > 0) + self.vel.X -= 0.25; + else self.vel.X = 0; + } + else + { + self.temp_data[1]++; + if (self.temp_data[1] > 3) + { + self.temp_data[1] = 0; + self.temp_data[0]++; + self.temp_data[0] &= 3; + } + if (self.vel.Z < 2) self.vel.Z += (gs.gravity / 3); // 52; + if(self.vel.X > 0) + self.vel.X -= 1/16.; + else + { + self.Destroy(); + } + } + } + + override bool animate(tspritetype t) + { + if (self.GetSpriteSetsize() > 0) t.setspritepic(self, self.temp_data[0] & 1); + t.cstat |= (CSTAT_SPRITE_XFLIP | CSTAT_SPRITE_YFLIP); + if (self.temp_data[0] > 1) t.cstat &= ~CSTAT_SPRITE_XFLIP; + if (self.temp_data[0] > 2) t.cstat &= ~(CSTAT_SPRITE_XFLIP | CSTAT_SPRITE_YFLIP); + return true; + } +} + +class DukeShotgunShell : DukeShell +{ + default + { + spriteset "SHOTGUNSHELL"; + } + + override void Initialize() + { + initshell(false, Raze.isNamWW2GI()? 1.875 : -1.25); + } +} diff --git a/wadsrc/static/zscript/games/duke/actors/watersplash.zs b/wadsrc/static/zscript/games/duke/actors/watersplash.zs new file mode 100644 index 000000000..506ab8bf3 --- /dev/null +++ b/wadsrc/static/zscript/games/duke/actors/watersplash.zs @@ -0,0 +1,99 @@ +class DukeWatersplash : DukeActor +{ + default + { + shade -16; + statnum STAT_MISC; + spriteset "WATERSPLASH2", "WATERSPLASH2A", "WATERSPLASH2B", "WATERSPLASH2C", "WATERSPLASH2D"; + } + + override void Initialize() + { + let Owner = self.ownerActor; + let sectp = self.sector; + if (Owner) + { + self.SetPosition(Owner.pos); + double s = 0.125 + random(0, 7) * REPEAT_SCALE; + self.scale = (s, s); + } + else + { + double s = 0.25 + random(0, 15) * REPEAT_SCALE; + self.scale = (s, s); + } + + self.cstat |= CSTAT_SPRITE_YCENTER; + if (Owner) + { + double c, f; + [c, f] = self.sector.getSlopes(self.pos.XY); + if (Owner.sector.lotag == ST_2_UNDERWATER) + { + self.pos.Z = c + 16; + self.cstat |= CSTAT_SPRITE_YFLIP; + } + else if (Owner.sector.lotag == ST_1_ABOVE_WATER) + self.pos.Z = f; + } + + if ((dlevel.floorflags(sectp) & Duke.TFLAG_SLIME) || (dlevel.ceilingflags(sectp) & Duke.TFLAG_SLIME)) + self.pal = 7; + self.ChangeStat(STAT_MISC); + } + + void DoTick(bool check) + { + let sectp = self.sector; + self.temp_data[0]++; + if (self.temp_data[0] == 1) + { + if (check) + { + self.Destroy(); + return; + } + if (!Duke.CheckSoundPlaying("ITEM_SPLASH")) + self.PlayActorSound("ITEM_SPLASH"); + } + if (self.temp_data[0] == 3) + { + self.temp_data[0] = 0; + self.temp_data[1]++; + } + if (self.temp_data[1] == 5) + { + self.Destroy(); + return; + } + + self.setspritesetImage(self.temp_data[1]); + } + + override void Tick() + { + let sectp = self.sector; + DoTick(sectp.lotag != ST_1_ABOVE_WATER && sectp.lotag != ST_2_UNDERWATER); + } +} + +class RedneckMudSplash : DukeWatersplash +{ + default + { + spriteset "MUD", "MUD1", "MUD2", "MUD3", "MUD4"; + } + + override void Initialize() + { + Super.Initialize(); + self.cstat |= CSTAT_SPRITE_BLOCK_ALL; + } + + override void Tick() + { + let sectp = self.sector; + DoTick(dlevel.floorflags(sectp) & Duke.TFLAG_MUDDY); + } +} + diff --git a/wadsrc/static/zscript/games/duke/dukeactor.zs b/wadsrc/static/zscript/games/duke/dukeactor.zs index d482f61e6..6b61283b3 100644 --- a/wadsrc/static/zscript/games/duke/dukeactor.zs +++ b/wadsrc/static/zscript/games/duke/dukeactor.zs @@ -222,6 +222,7 @@ class DukeActor : CoreActor native // temporary flag accessors - need to be eliminated once we can have true actor flags native int actorflag1(int mask); native int actorflag2(int mask); + native int actorflag3(int mask); native int attackerflag1(int mask); native int attackerflag2(int mask); @@ -252,6 +253,27 @@ class DukeActor : CoreActor native else self.ChangeStat(STAT_ZOMBIEACTOR); } } + + int checkLocationForFloorSprite(double radius) + { + bool away = self.isAwayFromWall(radius); + + if (!away) + { + self.scale = (0, 0); + self.ChangeStat(STAT_MISC); + return false; + } + + if (self.sector.lotag == ST_1_ABOVE_WATER) + { + self.scale = (0, 0); + self.ChangeStat(STAT_MISC); + return false; + } + return true; + } + } extend struct _ @@ -271,6 +293,7 @@ struct DukeLevel native static void operatemasterswitches(int lotag); native static void operateactivators(int lotag, DukePlayer p); native static int floorflags(sectortype s); + native static int ceilingflags(sectortype s); native static int wallflags(walltype s, int which); native static void AddCycler(sectortype sector, int lotag, int shade, int shade2, int hitag, int state); native static void addtorch(sectortype sector, int shade, int lotag); @@ -377,3 +400,10 @@ enum sflags2_t SFLAG2_UNDERWATERSLOWDOWN = 0x20000000, }; + +enum sflags3_t +{ + SFLAG3_DONTDIVEALIVE = 0x00000001, + SFLAG3_BLOODY = 0x00000002, + SFLAG3_BROWNBLOOD = 0x00000004, +}; diff --git a/wadsrc/static/zscript/games/duke/dukegame.zs b/wadsrc/static/zscript/games/duke/dukegame.zs index bf806bb62..9742d1d4f 100644 --- a/wadsrc/static/zscript/games/duke/dukegame.zs +++ b/wadsrc/static/zscript/games/duke/dukegame.zs @@ -80,6 +80,7 @@ struct Duke native TFLAG_OUTERSPACE = 1 << 7, TFLAG_NOBLOODSPLAT = 1 << 8, TFLAG_NOCIRCLEREFLECT = 1 << 9, + TFLAG_MUDDY = 1 << 10, }; enum ESoundFlags @@ -354,6 +355,8 @@ struct DukePlayer native native int CheckWeapRec(DukeActor item, bool checkonly); native void addammo(int type, int amount); native void addweapon(int type, bool switchit); + native bool hitablockingwall(); + native double getPitchWithView(); } @@ -446,7 +449,7 @@ struct DukeUserDefs native native readonly uint8 clipping; native readonly uint8 user_pals[MAXPLAYERS]; native readonly int16 from_bonus; - native readonly int16 last_level, secretlevel; + native int16 last_level, secretlevel; native readonly int const_visibility; native readonly int coop; native readonly int respawn_monsters, respawn_items, respawn_inventory, recstat, monsters_off, brightness;