From d253468b22caa06d9530251073e915587d0ca07c Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Mon, 14 Nov 2022 23:55:46 +0100 Subject: [PATCH] - scriptified the scraps. A Duke-ish mess of epic proportions. --- source/core/actorlist.cpp | 18 +++ source/core/thingdef_properties.cpp | 2 +- source/games/duke/src/actors.cpp | 66 +---------- source/games/duke/src/actors_d.cpp | 40 ++++--- source/games/duke/src/actors_r.cpp | 15 +-- source/games/duke/src/animatesprites_d.cpp | 23 ---- source/games/duke/src/animatesprites_r.cpp | 22 ---- source/games/duke/src/dispatch.cpp | 5 +- source/games/duke/src/duke3d.h | 2 +- source/games/duke/src/flags_d.cpp | 2 +- source/games/duke/src/flags_r.cpp | 2 +- source/games/duke/src/funct.h | 2 +- source/games/duke/src/gameexec.cpp | 61 +++++----- source/games/duke/src/global.h | 1 + source/games/duke/src/namelist_d.h | 29 ++++- source/games/duke/src/namelist_r.h | 22 +++- source/games/duke/src/names.h | 1 - source/games/duke/src/sectors_d.cpp | 16 ++- source/games/duke/src/sectors_r.cpp | 3 +- source/games/duke/src/vmexports.cpp | 33 ++++++ wadsrc/static/zscript.txt | 1 + .../static/zscript/games/duke/actors/scrap.zs | 104 ++++++++++++++++++ wadsrc/static/zscript/games/duke/dukeactor.zs | 1 + wadsrc/static/zscript/games/duke/dukegame.zs | 1 + wadsrc/static/zscript/maptypes.zs | 3 + 25 files changed, 300 insertions(+), 175 deletions(-) create mode 100644 wadsrc/static/zscript/games/duke/actors/scrap.zs diff --git a/source/core/actorlist.cpp b/source/core/actorlist.cpp index 464424c78..9af69377e 100644 --- a/source/core/actorlist.cpp +++ b/source/core/actorlist.cpp @@ -665,3 +665,21 @@ DEFINE_ACTION_FUNCTION_NATIVE(DCoreActor, setpositionz, coreactor_setpositionz) } +void tspritetype_setSpritePic(tspritetype* targ, DCoreActor* self, unsigned z) +{ + auto& spriteset = static_cast(self->GetClass())->ActorInfo()->SpriteSet; + if (z < spriteset.Size()) + { + targ->picnum = spriteset[z]; + } +} + +DEFINE_ACTION_FUNCTION_NATIVE(_tspritetype, setSpritePic, tspritetype_setSpritePic) +{ + PARAM_SELF_STRUCT_PROLOGUE(tspritetype); + PARAM_OBJECT(owner, DCoreActor); + PARAM_INT(z); + tspritetype_setSpritePic(self, owner, z); + return 0; +} + diff --git a/source/core/thingdef_properties.cpp b/source/core/thingdef_properties.cpp index ea32342b7..3f96d3caf 100644 --- a/source/core/thingdef_properties.cpp +++ b/source/core/thingdef_properties.cpp @@ -490,7 +490,7 @@ DEFINE_PROPERTY(owner, I, CoreActor) //========================================================================== // //========================================================================== -DEFINE_PROPERTY(spriteset, Ssssssssssssssssssss, CoreActor) +DEFINE_PROPERTY(spriteset, Sssssssssssssssssssssssssssssss, CoreActor) { info->ActorInfo()->SpriteSet.Clear(); for (int i = 0; i < PROP_PARM_COUNT; ++i) diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index 6a6537671..fa9dc0800 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -71,7 +71,11 @@ void RANDOMSCRAP(DDukeActor* origin) auto vel = krandf(4) + 4; auto zvel = -krandf(8) - 2; - CreateActor(origin->sector(), origin->spr.pos + offset, TILE_SCRAP6 + (r4 & 15), -8, DVector2(v, v), a, vel, zvel, origin, 5); + auto spawned = CreateActor(origin->sector(), origin->spr.pos + offset, PClass::FindActor("DukeScrap"), -8, DVector2(v, v), a, vel, zvel, origin, STAT_MISC); + if (spawned) + { + spawned->spriteextra = (r4 & 15); + } } //--------------------------------------------------------------------------- @@ -2187,66 +2191,6 @@ void glasspieces(DDukeActor* actor) // //--------------------------------------------------------------------------- -void scrap(DDukeActor* actor, int SCRAP1, int SCRAP6) -{ - auto sectp = actor->sector(); - - if(actor->vel.X > 0) - actor->vel.X -= 1/16.; - else actor->vel.X = 0; - - if (actor->vel.Z > 4 && actor->vel.Z < 5) - { - SetActor(actor, actor->spr.pos); - sectp = actor->sector(); - } - - if (actor->spr.pos.Z < sectp->floorz - 2) - { - if (actor->temp_data[1] < 1) actor->temp_data[1]++; - else - { - actor->temp_data[1] = 0; - - if (actor->spr.picnum < SCRAP6 + 8) - { - if (actor->temp_data[0] > 6) - actor->temp_data[0] = 0; - else actor->temp_data[0]++; - } - else - { - if (actor->temp_data[0] > 2) - actor->temp_data[0] = 0; - else actor->temp_data[0]++; - } - } - if (actor->vel.Z < 16) actor->vel.Z += (gs.gravity - 50 / 256.); - actor->spr.pos += actor->spr.angle.ToVector() * actor->vel.X; - actor->spr.pos.Z += actor->vel.Z; - } - else - { - if (actor->spr.picnum == SCRAP1 && actor->spr.yint > 0) - { - auto spawned = spawn(actor, actor->spr.yint); - if (spawned) - { - SetActor(spawned, actor->spr.pos); - getglobalz(spawned); - spawned->spr.hitag = spawned->spr.lotag = 0; - } - } - deletesprite(actor); - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - 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 8ebbec41c..f4b71a4d5 100644 --- a/source/games/duke/src/actors_d.cpp +++ b/source/games/duke/src/actors_d.cpp @@ -1006,8 +1006,12 @@ static void movefireext(DDukeActor* actor) auto a = randomAngle(); auto vel = krandf(4) + 4; auto zvel = -krandf(16) - actor->vel.Z * 0.25; - auto spawned = CreateActor(actor->sector(), actor->spr.pos.plusZ(krandf(-48)), SCRAP3 + (krand() & 3), -8, DVector2(0.75, 0.75), a, vel, zvel, actor, 5); - if(spawned) spawned->spr.pal = 2; + auto spawned = CreateActor(actor->sector(), actor->spr.pos.plusZ(krandf(-48)), PClass::FindActor("DukeScrap"), -8, DVector2(0.75, 0.75), a, vel, zvel, actor, STAT_MISC); + if (spawned) + { + if (spawned) spawned->spriteextra = SCRAP3 - gs.firstdebris + krand() & 3; + spawned->spr.pal = 2; + } } spawn(actor, EXPLOSION2); @@ -2139,8 +2143,12 @@ static void greenslime(DDukeActor *actor) auto vel = krandf(4) + 4; auto zvel = -krandf(16) - actor->vel.Z * 0.25; - auto spawned = CreateActor(actor->sector(), actor->spr.pos.plusZ(-8), SCRAP3 + (krand() & 3), -8, DVector2(0.75, 0.75), a, vel, zvel, actor, 5); - spawned->spr.pal = 6; + auto spawned = CreateActor(actor->sector(), actor->spr.pos.plusZ(-8), PClass::FindActor("DukeScrap"), -8, DVector2(0.75, 0.75), a, vel, zvel, actor, STAT_MISC); + if (spawned) + { + if (spawned) spawned->spriteextra = SCRAP3 - gs.firstdebris + krand() & 3; + spawned->spr.pal = 6; + } } S_PlayActorSound(SLIM_DYING, actor); @@ -2251,8 +2259,12 @@ static void greenslime(DDukeActor *actor) auto vel = krandf(4) + 4; auto zvel = -krandf(16) - actor->vel.Z * 0.25; - auto spawned = CreateActor(actor->sector(), actor->spr.pos.plusZ(-8), SCRAP3 + (krand() & 3), -8, DVector2(0.75, 0.75), a, vel, zvel, actor, 5); - if (spawned) spawned->spr.pal = 6; + auto spawned = CreateActor(actor->sector(), actor->spr.pos.plusZ(-8), PClass::FindActor("DukeScrap"), -8, DVector2(0.75, 0.75), a, vel, zvel, actor, STAT_MISC); + if (spawned) + { + if (spawned) spawned->spriteextra = SCRAP3 - gs.firstdebris + krand() & 3; + spawned->spr.pal = 6; + } } actor->temp_data[0] = -3; deletesprite(actor); @@ -2969,6 +2981,13 @@ void moveexplosions_d(void) // STATNUM 5 continue; } + if (act->GetClass() != RUNTIME_CLASS(DDukeActor)) + { + CallTick(act); + continue; + } + + auto sectp = act->sector(); switch (act->spr.picnum) @@ -3122,11 +3141,6 @@ void moveexplosions_d(void) // STATNUM 5 glasspieces(act); continue; } - - if (act->spr.picnum >= SCRAP6 && act->spr.picnum <= SCRAP5 + 3) - { - scrap(act, SCRAP1, SCRAP6); - } } } @@ -3674,9 +3688,9 @@ void fall_d(DDukeActor *actor, int g_p) fall_common(actor, g_p, JIBS6, DRONE, BLOODPOOL, SHOTSPARK1, SQUISHED, THUD, nullptr); } -bool spawnweapondebris_d(int picnum, int dnum) +bool spawnweapondebris_d(int picnum) { - return picnum == BLIMP && dnum == SCRAP1; + return picnum == BLIMP; } void respawnhitag_d(DDukeActor* actor) diff --git a/source/games/duke/src/actors_r.cpp b/source/games/duke/src/actors_r.cpp index b2de79410..68552199d 100644 --- a/source/games/duke/src/actors_r.cpp +++ b/source/games/duke/src/actors_r.cpp @@ -2870,6 +2870,12 @@ void moveexplosions_r(void) // STATNUM 5 continue; } + if (act->GetClass() != RUNTIME_CLASS(DDukeActor)) + { + CallTick(act); + continue; + } + switch (act->spr.picnum) { case SHOTGUNSPRITE: @@ -3069,11 +3075,6 @@ void moveexplosions_r(void) // STATNUM 5 glasspieces(act); continue; } - - if (act->spr.picnum >= SCRAP6 && act->spr.picnum <= SCRAP5 + 3) - { - scrap(act, SCRAP1, SCRAP6); - } } } @@ -3921,9 +3922,9 @@ void mamaspawn(DDukeActor *actor) } } -bool spawnweapondebris_r(int picnum, int dnum) +bool spawnweapondebris_r(int picnum) { - return dnum == SCRAP1; + return true; } void respawnhitag_r(DDukeActor *actor) diff --git a/source/games/duke/src/animatesprites_d.cpp b/source/games/duke/src/animatesprites_d.cpp index 2a9cb28ce..68fae5f14 100644 --- a/source/games/duke/src/animatesprites_d.cpp +++ b/source/games/duke/src/animatesprites_d.cpp @@ -455,29 +455,6 @@ void animatesprites_d(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi if (t->pal == 6) t->shade = -120; [[fallthrough]]; - case SCRAP1: - case SCRAP2: - case SCRAP3: - case SCRAP4: - case SCRAP5: - case SCRAP6: - case SCRAP6 + 1: - case SCRAP6 + 2: - case SCRAP6 + 3: - case SCRAP6 + 4: - case SCRAP6 + 5: - case SCRAP6 + 6: - case SCRAP6 + 7: - - if (h->attackertype == BLIMP && t->picnum == SCRAP1 && h->spr.yint >= 0) - t->picnum = h->spr.yint; - else t->picnum += h->temp_data[0]; - t->shade -= 6; - - if (sectp->floorpal) - copyfloorpal(t, sectp); - break; - case WATERBUBBLE: if (t->sectp->floorpicnum == FLOORSLIME) { diff --git a/source/games/duke/src/animatesprites_r.cpp b/source/games/duke/src/animatesprites_r.cpp index 1ad1db67b..d29e397a4 100644 --- a/source/games/duke/src/animatesprites_r.cpp +++ b/source/games/duke/src/animatesprites_r.cpp @@ -580,28 +580,6 @@ void animatesprites_r(tspriteArray& tsprites, const DVector2& viewVec, DAngle vi t->shade = 16; [[fallthrough]]; - case SCRAP1: - case SCRAP2: - case SCRAP3: - case SCRAP4: - case SCRAP5: - case SCRAP6: - case SCRAP6 + 1: - case SCRAP6 + 2: - case SCRAP6 + 3: - case SCRAP6 + 4: - case SCRAP6 + 5: - case SCRAP6 + 6: - case SCRAP6 + 7: - - if (t->picnum == SCRAP1 && h->spr.yint >= 0) - t->picnum = h->spr.yint; - else t->picnum += h->temp_data[0]; - - if (sectp->floorpal) - copyfloorpal(t, sectp); - break; - case WATERBUBBLE: if (t->sectp->floorpicnum == FLOORSLIME) { diff --git a/source/games/duke/src/dispatch.cpp b/source/games/duke/src/dispatch.cpp index 90db556f3..615bcf639 100644 --- a/source/games/duke/src/dispatch.cpp +++ b/source/games/duke/src/dispatch.cpp @@ -74,8 +74,8 @@ int ifhitbyweapon_r(DDukeActor* sn); int ifhitbyweapon_d(DDukeActor* sn); void fall_d(DDukeActor* i, int g_p); void fall_r(DDukeActor* i, int g_p); -bool spawnweapondebris_d(int picnum, int dnum); -bool spawnweapondebris_r(int picnum, int dnum); +bool spawnweapondebris_d(int picnum); +bool spawnweapondebris_r(int picnum); void respawnhitag_d(DDukeActor* g_sp); void respawnhitag_r(DDukeActor* g_sp); void move_d(DDukeActor* i, int g_p, int g_x); @@ -193,7 +193,6 @@ void SetDispatcher() int TILE_W_FORCEFIELD; -int TILE_SCRAP6; int TILE_APLAYER; int TILE_DRONE; int TILE_MENUSCREEN; diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h index 6400ca171..256ef959a 100644 --- a/source/games/duke/src/duke3d.h +++ b/source/games/duke/src/duke3d.h @@ -92,7 +92,7 @@ struct Dispatcher void (*guts)(DDukeActor* s, int gtype, int n, int p); int (*ifhitbyweapon)(DDukeActor* sectnum); void (*fall)(DDukeActor* actor, int g_p); - bool (*spawnweapondebris)(int picnum, int dnum); + bool (*spawnweapondebris)(int picnum); void (*respawnhitag)(DDukeActor* g_sp); void (*move)(DDukeActor* i, int g_p, int g_x); diff --git a/source/games/duke/src/flags_d.cpp b/source/games/duke/src/flags_d.cpp index 976b91451..933529593 100644 --- a/source/games/duke/src/flags_d.cpp +++ b/source/games/duke/src/flags_d.cpp @@ -310,9 +310,9 @@ void initactorflags_d() gs.weaponsandammosprites[12] = RPGAMMO; gs.weaponsandammosprites[13] = FREEZESPRITE; gs.weaponsandammosprites[14] = FREEZEAMMO; + gs.firstdebris = SCRAP6; TILE_W_FORCEFIELD = W_FORCEFIELD; - TILE_SCRAP6 = SCRAP6; TILE_APLAYER = APLAYER; TILE_DRONE = DRONE; TILE_MENUSCREEN = MENUSCREEN; diff --git a/source/games/duke/src/flags_r.cpp b/source/games/duke/src/flags_r.cpp index 60725a8b1..d7defeda7 100644 --- a/source/games/duke/src/flags_r.cpp +++ b/source/games/duke/src/flags_r.cpp @@ -282,7 +282,6 @@ void initactorflags_r() gs.weaponsandammosprites[14] = FREEZEAMMO; TILE_W_FORCEFIELD = W_FORCEFIELD; - TILE_SCRAP6 = SCRAP6; TILE_APLAYER = APLAYER; TILE_DRONE = DRONE; TILE_MENUSCREEN = MENUSCREEN; @@ -319,6 +318,7 @@ void initactorflags_r() TILE_EGG = EGG; gs.playerheight = PHEIGHT_RR; + gs.firstdebris = SCRAP6; } END_DUKE_NS diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index 3f91eb508..498d28e16 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -61,7 +61,6 @@ bool jibs(DDukeActor* i, int JIBS6, bool timeout, bool callsetsprite, bool floor bool bloodpool(DDukeActor* i, bool puke); void shell(DDukeActor* i, bool morecheck); void glasspieces(DDukeActor* i); -void scrap(DDukeActor* i, int SCRAP1, int SCRAP6); void handle_se00(DDukeActor* i); void handle_se01(DDukeActor* i); @@ -172,6 +171,7 @@ void getglobalz(DDukeActor* s); 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); void ceilingglass(DDukeActor* snum, sectortype* sectnum, int cnt); void spriteglass(DDukeActor* snum, int cnt); diff --git a/source/games/duke/src/gameexec.cpp b/source/games/duke/src/gameexec.cpp index dac4d867e..4ab30e4f8 100644 --- a/source/games/duke/src/gameexec.cpp +++ b/source/games/duke/src/gameexec.cpp @@ -2152,41 +2152,42 @@ int ParseState::parse(void) break; case concmd_debris: { - int dnum; + insptr++; + int dnum = *insptr - gs.firstdebris; + insptr++; + int count = *insptr; + bool weap = fi.spawnweapondebris(g_ac->spr.picnum); - insptr++; - dnum = *insptr; - insptr++; - bool weap = fi.spawnweapondebris(g_ac->spr.picnum, dnum); - if(g_ac->insector()) - for(j=(*insptr)-1;j>=0;j--) + if(g_ac->insector()) + for(j = count; j >= 0; j--) + { + if(weap) + s = 0; + else s = (krand()%3); + DVector3 offs; + offs.X = krandf(16) - 8; + offs.Y = krandf(16) - 8; + offs.Z = -krandf(16) - 8; + + auto a = randomAngle(); + auto vel = krandf(8) + 2; + auto zvel = -krandf(8); + DVector2 scale(0.5 + (krand() & 15) * REPEAT_SCALE, 0.5 + (krand() & 15) * REPEAT_SCALE); + + auto spawned = CreateActor(g_ac->sector(), g_ac->spr.pos + offs, PClass::FindActor("DukeScrap"), g_ac->spr.shade, scale, a, vel, zvel, g_ac, STAT_MISC); + if (spawned) { - if(weap) - s = 0; - else s = (krand()%3); - DVector3 offs; - offs.X = krandf(16) - 8; - offs.Y = krandf(16) - 8; - offs.Z = -krandf(16) - 8; - - auto a = randomAngle(); - auto vel = krandf(8) + 2; - auto zvel = -krandf(8); - DVector2 scale(0.5 + (krand() & 15) * REPEAT_SCALE, 0.5 + (krand() & 15) * REPEAT_SCALE); - - auto spawned = CreateActor(g_ac->sector(), g_ac->spr.pos + offs, dnum + s, g_ac->spr.shade, scale, a, vel, zvel, g_ac, 5); - if (spawned) - { - if (weap) - spawned->spr.yint = gs.weaponsandammosprites[j % 14]; - else spawned->spr.yint = -1; - spawned->spr.pal = g_ac->spr.pal; - } + spawned->spriteextra = dnum + s; + if (weap) + spawned->spr.yint = (j % 15) + 1; + else spawned->spr.yint = -1; + spawned->spr.pal = g_ac->spr.pal; } - insptr++; } - break; + insptr++; + } + break; case concmd_count: insptr++; g_t[0] = (short) *insptr; diff --git a/source/games/duke/src/global.h b/source/games/duke/src/global.h index a62a28d1e..2790e03c8 100644 --- a/source/games/duke/src/global.h +++ b/source/games/duke/src/global.h @@ -35,6 +35,7 @@ struct DukeGameInfo int lasermode; int freezerhurtowner; int impact_damage; + int firstdebris; TileInfo tileinfo[MAXTILES]; // This is not from EDuke32. ActorInfo actorinfo[MAXTILES]; diff --git a/source/games/duke/src/namelist_d.h b/source/games/duke/src/namelist_d.h index 961c82b5f..7e3fa46ab 100644 --- a/source/games/duke/src/namelist_d.h +++ b/source/games/duke/src/namelist_d.h @@ -476,15 +476,38 @@ x(FLOORFLAME, 2333) x(ROTATEGUN, 2360) x(GREENSLIME, 2370) x(WATERDRIPSPLASH, 2380) + + x(SCRAP6, 2390) +x(SCRAP6A, 2391) +x(SCRAP6B, 2392) +x(SCRAP6C, 2393) +x(SCRAP6D, 2394) +x(SCRAP6E, 2395) +x(SCRAP6F, 2396) +x(SCRAP6G, 2397) +x(SCRAP6H, 2398) +x(SCRAP6I, 2399) x(SCRAP1, 2400) +x(SCRAP1A, 2401) +x(SCRAP1B, 2402) +x(SCRAP1C, 2403) x(SCRAP2, 2404) +x(SCRAP2A, 2405) +x(SCRAP2B, 2406) +x(SCRAP2C, 2407) x(SCRAP3, 2408) -x(SCRAP3A, 2408) -x(SCRAP3B, 2409) -x(SCRAP3C, 2410) +x(SCRAP3A, 2409) +x(SCRAP3B, 2410) +x(SCRAP3C, 2411) x(SCRAP4, 2412) +x(SCRAP4A, 2413) +x(SCRAP4B, 2414) +x(SCRAP4C, 2415) x(SCRAP5, 2416) +x(SCRAP5A, 2417) +x(SCRAP5B, 2418) +x(SCRAP5C, 2419) x(ORGANTIC, 2420) x(BETAVERSION, 2440) x(PLAYERISHERE, 2442) diff --git a/source/games/duke/src/namelist_r.h b/source/games/duke/src/namelist_r.h index 7e348242f..bee5460e2 100644 --- a/source/games/duke/src/namelist_r.h +++ b/source/games/duke/src/namelist_r.h @@ -479,15 +479,35 @@ x(FLOORFLAME, 1558) x(GREENSLIME, 1575) x(WATERDRIPSPLASH, 1585) x(SCRAP6, 1595) +x(SCRAP6A, 1596) +x(SCRAP6B, 1597) +x(SCRAP6C, 1598) +x(SCRAP6D, 1599) +x(SCRAP6E, 1600) +x(SCRAP6F, 1601) +x(SCRAP6G, 1602) +x(SCRAP6H, 1603) +x(SCRAP6I, 1604) x(SCRAP1, 1605) +x(SCRAP1A, 1606) +x(SCRAP1B, 1607) +x(SCRAP1C, 1608) x(SCRAP2, 1609) +x(SCRAP2A, 1610) +x(SCRAP2B, 1611) +x(SCRAP2C, 1612) x(SCRAP3, 1613) x(SCRAP3A, 1614) x(SCRAP3B, 1615) x(SCRAP3C, 1616) x(SCRAP4, 1617) +x(SCRAP4A, 1618) +x(SCRAP4B, 1619) +x(SCRAP4C, 1620) x(SCRAP5, 1621) -x(ROTATEGUN, 1624) +x(SCRAP5A, 1622) +x(SCRAP5B, 1623) +x(SCRAP5C, 1624) x(BETAVERSION, 1629) x(PLAYERISHERE, 1630) x(PLAYERWASHERE, 1631) diff --git a/source/games/duke/src/names.h b/source/games/duke/src/names.h index b055653c9..89090f7c2 100644 --- a/source/games/duke/src/names.h +++ b/source/games/duke/src/names.h @@ -4,7 +4,6 @@ BEGIN_DUKE_NS // These are all globally accessed tiles. extern int TILE_W_FORCEFIELD; -extern int TILE_SCRAP6; extern int TILE_APLAYER; extern int TILE_DRONE; extern int TILE_MENUSCREEN; diff --git a/source/games/duke/src/sectors_d.cpp b/source/games/duke/src/sectors_d.cpp index e7a83daaf..8049bdda7 100644 --- a/source/games/duke/src/sectors_d.cpp +++ b/source/games/duke/src/sectors_d.cpp @@ -1074,8 +1074,12 @@ void checkhitsprite_d(DDukeActor* targ, DDukeActor* proj) auto vel = krandf(4) + 4; auto zvel = -krandf(16) - targ->vel.Z * 0.25; - auto spawned = CreateActor(targ->sector(), targ->spr.pos.plusZ(-48), SCRAP3 + (krand() & 3), -8, DVector2(0.75, 0.75), a, vel, zvel, targ, 5); - spawned->spr.pal = 8; + 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 - gs.firstdebris + krand() & 3; + spawned->spr.pal = 6; + } } if (targ->spr.picnum == CACTUS) @@ -1091,7 +1095,8 @@ void checkhitsprite_d(DDukeActor* targ, DDukeActor* proj) auto a = randomAngle(); auto vel = krandf(4) + 4; auto zvel = -krandf(16) - targ->vel.Z * 0.25; - CreateActor(targ->sector(), targ->spr.pos.plusZ(-8), SCRAP1 + (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, STAT_MISC); + if (spawned) spawned->spriteextra = SCRAP1 - gs.firstdebris + krand() & 15; } S_PlayActorSound(GLASS_HEAVYBREAK, targ); deletesprite(targ); @@ -1120,8 +1125,9 @@ void checkhitsprite_d(DDukeActor* targ, DDukeActor* proj) auto vel = krandf(8) + 4; auto zvel = -krandf(2) - 1; - CreateActor(targ->sector(), DVector3(targ->spr.pos.XY(), targ->sector()->floorz - 12 - j * 2), SCRAP1 + (krand() & 15), -8, DVector2(1, 1), - a, vel, zvel, targ, 5); + auto spawned = CreateActor(targ->sector(), DVector3(targ->spr.pos.XY(), targ->sector()->floorz - 12 - j * 2), PClass::FindActor("DukeScrap"), -8, DVector2(1, 1), a, vel, zvel, targ, 5); + if (spawned) spawned->spriteextra = SCRAP1 - gs.firstdebris + krand() & 15; + } spawn(targ, EXPLOSION2); deletesprite(targ); diff --git a/source/games/duke/src/sectors_r.cpp b/source/games/duke/src/sectors_r.cpp index 7e5b83960..76a723489 100644 --- a/source/games/duke/src/sectors_r.cpp +++ b/source/games/duke/src/sectors_r.cpp @@ -2149,8 +2149,9 @@ void checkhitsprite_r(DDukeActor* targ, DDukeActor* proj) auto vel = krandf(8) + 4; auto zvel = -krandf(2) - 1; - CreateActor(targ->sector(), DVector3(targ->spr.pos.XY(), targ->sector()->floorz - 12 - j * 2), SCRAP1 + (krand() & 15), -8, DVector2(1, 1), + auto spawned = CreateActor(targ->sector(), DVector3(targ->spr.pos.XY(), targ->sector()->floorz - 12 - j * 2), PClass::FindActor("DukeScrap"), -8, DVector2(1, 1), a, vel, zvel, targ, 5); + if (spawned) spawned->spriteextra = SCRAP1 - gs.firstdebris + krand() & 15; } spawn(targ, EXPLOSION2); deletesprite(targ); diff --git a/source/games/duke/src/vmexports.cpp b/source/games/duke/src/vmexports.cpp index 26ae508bf..ecf8c6a2f 100644 --- a/source/games/duke/src/vmexports.cpp +++ b/source/games/duke/src/vmexports.cpp @@ -219,6 +219,19 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, spawn, DukeActor_Spawn) ACTION_RETURN_POINTER(DukeActor_Spawn(self, type)); } +DDukeActor* DukeActor_spawnweaponorammo(DDukeActor* origin, unsigned intname) +{ + if (intname > 14) return nullptr; + return spawn(origin, gs.weaponsandammosprites[intname]); +} + +DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, spawnweaponorammo, DukeActor_spawnweaponorammo) +{ + PARAM_SELF_PROLOGUE(DDukeActor); + PARAM_INT(type); + ACTION_RETURN_POINTER(DukeActor_spawnweaponorammo(self, type)); +} + void DukeActor_Lotsofglass(DDukeActor* origin, int count) { lotsofglass(origin, nullptr, count); @@ -618,6 +631,26 @@ DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, freezerhurtowner); DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, impact_damage); DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, playerheight); DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, displayflags); +DEFINE_FIELD_X(DukeGameInfo, DukeGameInfo, firstdebris); DEFINE_GLOBAL_UNSIZED(gs) + +// this is only a temporary helper until weaponsandammosprites can be migrated to real class types. We absolutely do not want any access to tile numbers in the scripts - even now. +void tspritetype_setWeaponOrAmmoSprite(tspritetype* targ, unsigned z) +{ + if (z < 15) + { + targ->picnum = gs.weaponsandammosprites[z]; + } +} + +DEFINE_ACTION_FUNCTION_NATIVE(_tspritetype, setWeaponOrAmmoSprite, tspritetype_setWeaponOrAmmoSprite) +{ + PARAM_SELF_STRUCT_PROLOGUE(tspritetype); + PARAM_INT(z); + tspritetype_setWeaponOrAmmoSprite(self, z); + return 0; +} + + END_DUKE_NS diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 9c3247de4..50737723f 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -53,6 +53,7 @@ version "4.9" #include "zscript/games/duke/actors/crane.zs" #include "zscript/games/duke/actors/waterfountain.zs" #include "zscript/games/duke/actors/flammables.zs" +#include "zscript/games/duke/actors/scrap.zs" #include "zscript/games/blood/bloodgame.zs" #include "zscript/games/blood/ui/menu.zs" diff --git a/wadsrc/static/zscript/games/duke/actors/scrap.zs b/wadsrc/static/zscript/games/duke/actors/scrap.zs new file mode 100644 index 000000000..eeb0e8299 --- /dev/null +++ b/wadsrc/static/zscript/games/duke/actors/scrap.zs @@ -0,0 +1,104 @@ + +class DukeScrap : DukeActor +{ + default + { + statnum STAT_MISC; + } + + enum EScrap + { + Scrap6 = 0, + Scrap1 = 10, + Scrap2 = 14, + Scrap3 = 18, + Scrap4 = 22, + Scrap5 = 26, + ScrapMax = 30 + } + + default + { + spriteset + "SCRAP6", "SCRAP6A", "SCRAP6B", "SCRAP6C", "SCRAP6D", "SCRAP6E", "SCRAP6F", "SCRAP6G", "SCRAP6H", "SCRAP6I", + "SCRAP1", "SCRAP1A", "SCRAP1B", "SCRAP1C", + "SCRAP2", "SCRAP2A", "SCRAP2B", "SCRAP2C", + "SCRAP3", "SCRAP3A", "SCRAP3B", "SCRAP3C", + "SCRAP4", "SCRAP4A", "SCRAP4B", "SCRAP4C", + "SCRAP5", "SCRAP5A", "SCRAP5B", "SCRAP5C"; + } + + static const int8 brighter[] = { 1,1,1,1,1,1,1,1,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0}; // this is one of those cases where Duke's switch/case mess left handling incomplete. + + override void Tick() + { + let sectp = self.sector; + + if(self.vel.X > 0) + self.vel.X -= 1/16.; + else self.vel.X = 0; + + if (self.vel.Z > 4 && self.vel.Z < 5) + { + self.SetPosition(self.pos); + sectp = self.sector; + } + + if (self.pos.Z < sectp.floorz - 2) + { + if (self.temp_data[1] < 1) self.temp_data[1]++; + else + { + self.temp_data[1] = 0; + + if (self.spriteextra < Scrap6 + 8) + { + if (self.temp_data[0] > 6) + self.temp_data[0] = 0; + else self.temp_data[0]++; + } + else + { + if (self.temp_data[0] > 2) + self.temp_data[0] = 0; + else self.temp_data[0]++; + } + } + if (self.vel.Z < 16) self.vel.Z += (gs.gravity - 50 / 256.); + self.pos += self.angle.ToVector() * self.vel.X; + self.pos.Z += self.vel.Z; + } + else + { + if (self.spriteextra == Scrap1 && self.yint > 0) + { + let spawned = self.spawnweaponorammo(self.yint - 1); // fixme later! + if (spawned) + { + spawned.SetPosition(self.pos); + spawned.getglobalz(); + spawned.hitag = spawned.lotag = 0; + } + } + self.Destroy(); + } + } + + override bool animate(tspritetype tspr) + { + if (self.spriteextra == Scrap1 && self.yint > 0) + { + tspr.setWeaponOrAmmoSprite(self.yint - 1); // needed so that we don't have to export tile numbers to scripting. + } + else + { + let frame = self.spriteextra + self.temp_data[0]; + if (frame < 0 || frame >= ScrapMax) frame = Scrap3; + tspr.setSpritePic(self, frame); + if (brighter[frame]) tspr.shade -= 6; + } + return true; + } + +} + diff --git a/wadsrc/static/zscript/games/duke/dukeactor.zs b/wadsrc/static/zscript/games/duke/dukeactor.zs index 2118724f2..b8568a66b 100644 --- a/wadsrc/static/zscript/games/duke/dukeactor.zs +++ b/wadsrc/static/zscript/games/duke/dukeactor.zs @@ -70,6 +70,7 @@ class DukeActor : CoreActor native native int domove(int clipmask); native void PlayActorSound(int snd); native DukeActor spawn(Name type); + native DukeActor spawnweaponorammo(int type); native void lotsofglass(int count); native void makeitfall(); diff --git a/wadsrc/static/zscript/games/duke/dukegame.zs b/wadsrc/static/zscript/games/duke/dukegame.zs index eee42a1c2..05e70dd00 100644 --- a/wadsrc/static/zscript/games/duke/dukegame.zs +++ b/wadsrc/static/zscript/games/duke/dukegame.zs @@ -1268,5 +1268,6 @@ struct DukeGameInfo native readonly native int freezerhurtowner; readonly native int impact_damage; readonly native double playerheight; + readonly native int firstdebris; readonly native int displayflags; } diff --git a/wadsrc/static/zscript/maptypes.zs b/wadsrc/static/zscript/maptypes.zs index 1e640bd31..76e8f4999 100644 --- a/wadsrc/static/zscript/maptypes.zs +++ b/wadsrc/static/zscript/maptypes.zs @@ -305,6 +305,9 @@ struct tspritetype native native CoreActor ownerActor; native int time; + native void setSpritePic(CoreActor actor, int index); // index into actor's spriteset. + native void setWeaponOrAmmoSprite(int num); + } enum ESprextFlags