From da0b4297517d94bdd484625be8343bc3f4550b7d Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Fri, 16 Dec 2022 16:56:47 +0100 Subject: [PATCH] - migrated attackertype to class objects. --- source/common/engine/serializer.h | 7 +++ source/games/duke/src/actors.cpp | 4 +- source/games/duke/src/actors_d.cpp | 54 +++++++------------ source/games/duke/src/actors_r.cpp | 25 +++++---- source/games/duke/src/duke3d.h | 3 ++ source/games/duke/src/flags_d.cpp | 1 - source/games/duke/src/flags_r.cpp | 12 ++--- source/games/duke/src/game.cpp | 13 +++++ source/games/duke/src/gamedef.cpp | 4 +- source/games/duke/src/gameexec.cpp | 14 ++--- source/games/duke/src/inlines.h | 20 ------- source/games/duke/src/player_r.cpp | 6 +-- source/games/duke/src/sectors_d.cpp | 6 +-- source/games/duke/src/sectors_r.cpp | 4 +- source/games/duke/src/spawn.cpp | 9 ++-- source/games/duke/src/types.h | 12 +++-- source/games/duke/src/vmexports.cpp | 16 +----- .../redneck.ridesagain/rmapinfo.spawnclasses | 1 + .../games/duke/actors/_placeholders.zs | 9 ++++ .../static/zscript/games/duke/actors/crack.zs | 2 +- .../zscript/games/duke/actors/greenslime.zs | 4 +- wadsrc/static/zscript/games/duke/dukeactor.zs | 11 ++-- 22 files changed, 109 insertions(+), 128 deletions(-) diff --git a/source/common/engine/serializer.h b/source/common/engine/serializer.h index 63bfb3529..d8d787f4a 100644 --- a/source/common/engine/serializer.h +++ b/source/common/engine/serializer.h @@ -308,6 +308,13 @@ inline FSerializer& Serialize(FSerializer& arc, const char* key, BitArray& value } template<> FSerializer& Serialize(FSerializer& arc, const char* key, PClass*& clst, PClass** def); +template<> inline FSerializer& Serialize(FSerializer& arc, const char* key, PClassActor*& clst, PClassActor** def) +{ + PClass* c = (PClass*)clst; + Serialize(arc, key, c, (PClass**)def); + clst = (PClassActor*)c; + return arc; +} template<> FSerializer& Serialize(FSerializer& arc, const char* key, FFont*& font, FFont** def); template<> FSerializer &Serialize(FSerializer &arc, const char *key, Dictionary *&dict, Dictionary **def); diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index 74077efb0..0fb4d5c03 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -585,7 +585,7 @@ void movefallers(void) int j = fi.ifhitbyweapon(act); if (j >= 0) { - if (gs.actorinfo[j].flags2 & SFLAG2_EXPLOSIVE) + if (j == 2) // explosive { if (act->spr.extra <= 0) { @@ -3358,7 +3358,7 @@ void fall_common(DDukeActor *actor, int playernum, int JIBS6, int DRONE, int BLO SKIPJIBS: - actor->attackertype = SHOTSPARK1; + actor->attackertype = PClass::FindActor(NAME_DukeShotSpark); actor->hitextra = 1; actor->vel.Z = 0; } diff --git a/source/games/duke/src/actors_d.cpp b/source/games/duke/src/actors_d.cpp index 0cbe66cfd..28c5d6dc1 100644 --- a/source/games/duke/src/actors_d.cpp +++ b/source/games/duke/src/actors_d.cpp @@ -131,7 +131,7 @@ bool ifsquished(DDukeActor* actor, int p) if (actor->spr.pal == 1) { - actor->attackertype = DTILE_SHOTSPARK1; + actor->attackertype = PClass::FindActor(NAME_DukeShotSpark); actor->hitextra = 1; return false; } @@ -239,29 +239,8 @@ void hitradius_d(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int h if (dist < radius && cansee(act2->spr.pos.plusZ(-8), act2->sector(), actor->spr.pos.plusZ(-12), actor->sector())) { act2->hitang = (act2->spr.pos - actor->spr.pos).Angle(); + act2->attackertype = CallGetRadiusDamageType(actor, act2->spr.extra); - if (actor->spr.picnum == DTILE_RPG && act2->spr.extra > 0) - act2->attackertype = DTILE_RPG; - else if (!isWorldTour()) - { - if (actor->spr.picnum == DTILE_SHRINKSPARK) - act2->attackertype = DTILE_SHRINKSPARK; - else act2->attackertype = DTILE_RADIUSEXPLOSION; - } - else - { - if (actor->spr.picnum == DTILE_SHRINKSPARK || actor->spr.picnum == DTILE_FLAMETHROWERFLAME) - act2-> attackertype = actor->spr.picnum; - else if (actor->spr.picnum != DTILE_FIREBALL || !Owner || !Owner->isPlayer()) - { - if (actor->spr.picnum == DTILE_LAVAPOOL) - act2->attackertype = DTILE_FLAMETHROWERFLAME; - else - act2->attackertype = DTILE_RADIUSEXPLOSION; - } - else - act2->attackertype = DTILE_FLAMETHROWERFLAME; - } if (actor->spr.picnum != DTILE_SHRINKSPARK && (!isWorldTour() || actor->spr.picnum != DTILE_LAVAPOOL)) { @@ -298,7 +277,7 @@ void hitradius_d(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int h { int p = act2->spr.yint; - if (isWorldTour() && act2->attackertype == DTILE_FLAMETHROWERFLAME && Owner->isPlayer()) + if (act2->attackertype->TypeName == NAME_DukeFlamethrowerFlame && Owner->isPlayer()) { ps[p].numloogs = -1 - actor->spr.yint; } @@ -433,11 +412,12 @@ int ifhitbyweapon_d(DDukeActor *actor) if (actor->hitextra >= 0) { + auto adef = actor->attackerDefaults(); if (actor->spr.extra >= 0) { if (actor->isPlayer()) { - if (ud.god && actor->attackertype != DTILE_SHRINKSPARK) return -1; + if (ud.god && !(adef->flags3 & SFLAG3_LIGHTDAMAGE)) return -1; p = actor->PlayerIndex(); @@ -451,7 +431,7 @@ int ifhitbyweapon_d(DDukeActor *actor) if (hitowner) { - if (actor->spr.extra <= 0 && actor->attackertype != DTILE_FREEZEBLAST) + if (actor->spr.extra <= 0 && !(adef->flags2 & SFLAG2_FREEZEDAMAGE)) { actor->spr.extra = 0; @@ -465,7 +445,7 @@ int ifhitbyweapon_d(DDukeActor *actor) } } - if (attackerflag(actor, SFLAG2_DOUBLEDMGTHRUST)) + if (adef->flags2 & SFLAG2_DOUBLEDMGTHRUST) { ps[p].vel.XY() += actor->hitang.ToVector() * actor->hitextra * 0.25; } @@ -477,13 +457,12 @@ int ifhitbyweapon_d(DDukeActor *actor) else { if (actor->hitextra == 0) - if (actor->attackertype == DTILE_SHRINKSPARK && actor->spr.scale.X < 0.375) + if (actor->attackertype->TypeName == NAME_DukeShrinkSpark && actor->spr.scale.X < 0.375) return -1; - if (isWorldTour() && actor->attackertype == DTILE_FIREFLY && actor->spr.scale.X < 0.75) + if (actor->attackertype->TypeName == NAME_DukeFirefly && actor->spr.scale.X < 0.75) { - if (actor->attackertype != DTILE_RADIUSEXPLOSION && actor->attackertype != DTILE_RPG) - return -1; + return -1; } actor->spr.extra -= actor->hitextra; @@ -493,13 +472,18 @@ int ifhitbyweapon_d(DDukeActor *actor) } actor->hitextra = -1; - return actor->attackertype; + // makeshift damage type reporting. Needs improvement and generalization later. + int res = 0; + if (adef->flags2 & SFLAG2_FREEZEDAMAGE) res |= 1; + if (adef->flags2 & SFLAG2_EXPLOSIVE) res |= 2; + return res; } } - if (ud.multimode < 2 || !isWorldTour() - || actor->attackertype != DTILE_FLAMETHROWERFLAME + if (ud.multimode < 2 + || actor->attackertype == nullptr + || actor->attackertype->TypeName != NAME_DukeFlamethrowerFlame || actor->hitextra >= 0 || actor->spr.extra > 0 || !actor->isPlayer() @@ -521,7 +505,7 @@ int ifhitbyweapon_d(DDukeActor *actor) actor->SetHitOwner(ps[p].GetActor()); actor->hitextra = -1; - return DTILE_FLAMETHROWERFLAME; + return 0; } } diff --git a/source/games/duke/src/actors_r.cpp b/source/games/duke/src/actors_r.cpp index 273933aff..9f3ac1409 100644 --- a/source/games/duke/src/actors_r.cpp +++ b/source/games/duke/src/actors_r.cpp @@ -231,13 +231,7 @@ void hitradius_r(DDukeActor* actor, int r, int hp1, int hp2, int hp3, int h } act2->hitang = (act2->spr.pos - actor->spr.pos).Angle(); - - if (actor->spr.picnum == RTILE_RPG && act2->spr.extra > 0) - act2->attackertype = RTILE_RPG; - else if ((isRRRA()) && actor->spr.picnum == RTILE_RPG2 && act2->spr.extra > 0) - act2->attackertype = RTILE_RPG; - else - act2->attackertype = RTILE_RADIUSEXPLOSION; + act2->attackertype = CallGetRadiusDamageType(actor, act2->spr.extra); if (dist < radius / 3) { @@ -374,6 +368,7 @@ int ifhitbyweapon_r(DDukeActor *actor) if (actor->hitextra >= 0) { + auto adef = actor->attackerDefaults(); if (actor->spr.extra >= 0) { if (actor->isPlayer()) @@ -392,7 +387,7 @@ int ifhitbyweapon_r(DDukeActor *actor) if (hitowner) { - if (actor->spr.extra <= 0 && actor->attackertype != RTILE_FREEZEBLAST) + if (actor->spr.extra <= 0 && !(adef->flags2 & SFLAG2_FREEZEDAMAGE)) { actor->spr.extra = 0; @@ -406,7 +401,7 @@ int ifhitbyweapon_r(DDukeActor *actor) } } - if (attackerflag(actor, SFLAG2_DOUBLEDMGTHRUST)) + if (adef->flags2 & SFLAG2_DOUBLEDMGTHRUST) { ps[p].vel.XY() += actor->hitang.ToVector() * actor->hitextra * 0.25; } @@ -428,7 +423,11 @@ int ifhitbyweapon_r(DDukeActor *actor) } actor->hitextra = -1; - return actor->attackertype; + // makeshift damage type reporting. Needs improvement and generalization later. + int res = 0; + if (adef->flags2 & SFLAG2_FREEZEDAMAGE) res |= 1; + if (adef->flags2 & SFLAG2_EXPLOSIVE) res |= 2; + return res; } } @@ -1570,7 +1569,7 @@ static int fallspecial(DDukeActor *actor, int playernum) addspritetodelete(); return 0; } - actor->attackertype = RTILE_SHOTSPARK1; + actor->attackertype = PClass::FindActor(NAME_DukeShotSpark); actor->hitextra = 1; } else if (tilesurface(actor->sector()->floortexture) == TSURF_MAGMA) @@ -1579,7 +1578,7 @@ static int fallspecial(DDukeActor *actor, int playernum) { if ((krand() & 3) == 1) { - actor->attackertype = RTILE_SHOTSPARK1; + actor->attackertype = PClass::FindActor(NAME_DukeShotSpark); actor->hitextra = 5; } } @@ -1631,7 +1630,7 @@ void destroyit(DDukeActor *actor) { if (a3->spr.picnum == RTILE_DESTRUCTO) { - a3->attackertype = RTILE_SHOTSPARK1; + a3->attackertype = PClass::FindActor(NAME_DukeShotSpark); a3->hitextra = 1; } } diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h index 2139ca674..2913005e0 100644 --- a/source/games/duke/src/duke3d.h +++ b/source/games/duke/src/duke3d.h @@ -124,6 +124,9 @@ void CallPlayFTASound(DDukeActor* actor); void CallStandingOn(DDukeActor* actor, player_struct* p); void CallRunState(DDukeActor* actor); int CallTriggerSwitch(DDukeActor* actor, player_struct* p); +PClassActor* CallGetRadiusDamageType(DDukeActor* actor, int targhealth); + + extern FTextureID mirrortex, foftex; diff --git a/source/games/duke/src/flags_d.cpp b/source/games/duke/src/flags_d.cpp index 9f1ffbabf..ea650ea32 100644 --- a/source/games/duke/src/flags_d.cpp +++ b/source/games/duke/src/flags_d.cpp @@ -255,7 +255,6 @@ void initactorflags_d() setflag(SFLAG3_BLOODY, { DTILE_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_LOOKALLAROUND; gs.actorinfo[DTILE_ORGANTIC].aimoffset = 32; gs.actorinfo[DTILE_ROTATEGUN].aimoffset = 32; diff --git a/source/games/duke/src/flags_r.cpp b/source/games/duke/src/flags_r.cpp index 998d98d14..8b828127c 100644 --- a/source/games/duke/src/flags_r.cpp +++ b/source/games/duke/src/flags_r.cpp @@ -95,8 +95,8 @@ void initactorflags_r() setflag(SFLAG_INTERNAL_BADGUY, { RTILE_PIG, RTILE_HEN }); - gs.actorinfo[RTILE_DRONE].flags |= SFLAG_NOWATERDIP; - gs.actorinfo[RTILE_VIXEN].flags |= SFLAG_LOOKALLAROUND; + //gs.actorinfo[RTILE_DRONE].flags |= SFLAG_NOWATERDIP; + //gs.actorinfo[RTILE_VIXEN].flags |= SFLAG_LOOKALLAROUND; if (isRRRA()) { setflag(SFLAG_LOOKALLAROUND, { RTILE_COOT, RTILE_COOTSTAYPUT, RTILE_BIKERB, RTILE_BIKERBV2, RTILE_CHEER, RTILE_CHEERB, @@ -197,7 +197,7 @@ void initactorflags_r() // Animals were not supposed to have this, but due to a coding bug the logic was unconditional for everything in the game. for (auto& ainf : gs.actorinfo) { - ainf.flags |= SFLAG_MOVEFTA_WAKEUPCHECK; + //ainf.flags |= SFLAG_MOVEFTA_WAKEUPCHECK; } @@ -221,11 +221,11 @@ void initactorflags_r() setflag(SFLAG2_FLOATING, { RTILE_UFO1_RR, RTILE_UFO2, RTILE_UFO3, RTILE_UFO4, RTILE_UFO5 }); } - gs.actorinfo[RTILE_RPG2].flags |= SFLAG_FORCEAUTOAIM; + //gs.actorinfo[RTILE_RPG2].flags |= SFLAG_FORCEAUTOAIM; // clear some bad killcount defaults - for (auto t : { RTILE_COW, RTILE_HEN, RTILE_PIG, RTILE_MINECARTKILLER, RTILE_UFOBEAM }) gs.actorinfo[t].flags &= ~SFLAG_KILLCOUNT; - if (isRRRA()) gs.actorinfo[RTILE_WACOWINDER].flags &= ~SFLAG_KILLCOUNT; + //for (auto t : { RTILE_COW, RTILE_HEN, RTILE_PIG, RTILE_MINECARTKILLER, RTILE_UFOBEAM }) gs.actorinfo[t].flags &= ~SFLAG_KILLCOUNT; + //if (isRRRA()) gs.actorinfo[RTILE_WACOWINDER].flags &= ~SFLAG_KILLCOUNT; gs.weaponsandammosprites[0] = RTILE_CROSSBOWSPRITE; gs.weaponsandammosprites[1] = RTILE_RIFLEGUNSPRITE; diff --git a/source/games/duke/src/game.cpp b/source/games/duke/src/game.cpp index 95c7ef709..1aa2e71c5 100644 --- a/source/games/duke/src/game.cpp +++ b/source/games/duke/src/game.cpp @@ -571,6 +571,19 @@ int CallTriggerSwitch(DDukeActor* actor, player_struct* p) return nval; } +PClassActor* CallGetRadiusDamageType(DDukeActor* actor, int targhealth) +{ + PClassActor* nval = nullptr; + IFVIRTUALPTR(actor, DDukeActor, GetRadiusDamageType) + { + VMReturn ret; + ret.PointerAt((void**)&nval); + VMValue val[] = { actor, targhealth }; + VMCall(func, val, 2, &ret, 1); + } + return nval; +} + CCMD(changewalltexture) { diff --git a/source/games/duke/src/gamedef.cpp b/source/games/duke/src/gamedef.cpp index 4be8641f6..a452df32e 100644 --- a/source/games/duke/src/gamedef.cpp +++ b/source/games/duke/src/gamedef.cpp @@ -1204,10 +1204,10 @@ int ConCompiler::parsecommand() if (tw == concmd_useractor) { if (j & 1) - gs.actorinfo[lnum].flags |= SFLAG_BADGUY | SFLAG_KILLCOUNT; + gs.actorinfo[lnum].enemyflags |= SFLAG_BADGUY | SFLAG_KILLCOUNT; if (j & 2) - gs.actorinfo[lnum].flags |= (SFLAG_BADGUY | SFLAG_KILLCOUNT | SFLAG_BADGUYSTAYPUT); + gs.actorinfo[lnum].enemyflags |= (SFLAG_BADGUY | SFLAG_KILLCOUNT | SFLAG_BADGUYSTAYPUT); } for (j = 0; j < 4; j++) diff --git a/source/games/duke/src/gameexec.cpp b/source/games/duke/src/gameexec.cpp index 6e6741ed2..82fd4de97 100644 --- a/source/games/duke/src/gameexec.cpp +++ b/source/games/duke/src/gameexec.cpp @@ -1245,10 +1245,6 @@ void DoActor(bool bSet, int lVar1, int lLabelID, int lVar2, DDukeActor* sActor, if (bSet) act->cgg = lValue; else SetGameVarID(lVar2, act->cgg, sActor, sPlayer); break; - case ACTOR_HTPICNUM: - if (bSet) act->attackertype = lValue; - else SetGameVarID(lVar2, act->attackertype, sActor, sPlayer); - break; case ACTOR_HTANG: if (bSet) act->hitang = mapangle(lValue); else SetGameVarID(lVar2, act->hitang.Buildang(), sActor, sPlayer); @@ -1908,7 +1904,7 @@ int ParseState::parse(void) case concmd_ifwasweapon: case concmd_ifspawnedby: // these two are the same insptr++; - parseifelse( g_ac->attackertype == *insptr); + parseifelse( g_ac->attackertype == GetSpawnType(*insptr)); break; case concmd_ifai: insptr++; @@ -2079,12 +2075,8 @@ int ParseState::parse(void) case concmd_guts: { insptr += 2; - auto info = spawnMap.CheckKey(*(insptr - 1)); - if (info) - { - auto clstype = info->cls; - if (clstype) spawnguts(g_ac, clstype, *insptr); - } + auto clstype = GetSpawnType(*(insptr - 1)); + if (clstype) spawnguts(g_ac, clstype, *insptr); insptr++; break; } diff --git a/source/games/duke/src/inlines.h b/source/games/duke/src/inlines.h index 74e464977..c5c2dc59e 100644 --- a/source/games/duke/src/inlines.h +++ b/source/games/duke/src/inlines.h @@ -52,26 +52,6 @@ inline int iseffector(DDukeActor* actor) } -inline int badguypic(int const tileNum) -{ - return ((gs.actorinfo[tileNum].flags & (SFLAG_INTERNAL_BADGUY | SFLAG_BADGUY)) != 0); -} - -inline int bossguypic(int const tileNum) -{ - return ((gs.actorinfo[tileNum].flags & (SFLAG_BOSS)) != 0); -} - -inline int attackerflag(DDukeActor* actor, EDukeFlags1 mask) -{ - return (((gs.actorinfo[actor->attackertype].flags) & mask) != 0); -} - -inline int attackerflag(DDukeActor* actor, EDukeFlags2 mask) -{ - return (((gs.actorinfo[actor->attackertype].flags2) & mask) != 0); -} - inline void setflag(EDukeFlags1 flag, const std::initializer_list& types) { for (auto val : types) diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index f81889737..8d0ceda82 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -2281,7 +2281,7 @@ void onMotorcycleHit(int snum, DDukeActor* victim) } else victim->SetHitOwner(p->GetActor()); - victim->attackertype = RTILE_MOTOHIT; + victim->attackertype = PClass::FindActor(NAME_RedneckMotoHit); victim->hitextra = int(p->MotoSpeed * 0.5); p->MotoSpeed -= p->MotoSpeed / 4.; p->TurbCount = 6; @@ -2315,7 +2315,7 @@ void onBoatHit(int snum, DDukeActor* victim) } else victim->SetHitOwner(p->GetActor()); - victim->attackertype = RTILE_MOTOHIT; + victim->attackertype = PClass::FindActor(NAME_RedneckMotoHit); victim->hitextra = int(p->MotoSpeed * 0.25); p->MotoSpeed -= p->MotoSpeed / 4.; p->TurbCount = 6; @@ -3201,7 +3201,7 @@ void processinput_r(int snum) { if (badguy(clz.actor())) { - clz.actor()->attackertype = RTILE_MOTOHIT; + clz.actor()->attackertype = PClass::FindActor(NAME_RedneckMotoHit); clz.actor()->hitextra = int(2 + (p->MotoSpeed * 0.5)); p->MotoSpeed -= p->MotoSpeed * (1. / 16.); } diff --git a/source/games/duke/src/sectors_d.cpp b/source/games/duke/src/sectors_d.cpp index 3bbadfbd4..caec9af00 100644 --- a/source/games/duke/src/sectors_d.cpp +++ b/source/games/duke/src/sectors_d.cpp @@ -225,7 +225,7 @@ void checkhitdefault_d(DDukeActor* targ, DDukeActor* proj) if ((proj->flags2 & SFLAG2_FREEZEDAMAGE) && ((targ->isPlayer() && targ->spr.pal == 1) || (gs.freezerhurtowner == 0 && proj->GetOwner() == targ))) return; - int hitpic = proj->spr.picnum; + auto hitpic = static_cast(proj->GetClass()); auto Owner = proj->GetOwner(); if (Owner && Owner->isPlayer()) { @@ -233,8 +233,8 @@ void checkhitdefault_d(DDukeActor* targ, DDukeActor* proj) return; auto tOwner = targ->GetOwner(); - if (isWorldTour() && hitpic == DTILE_FIREBALL && tOwner && tOwner->spr.picnum != DTILE_FIREBALL) - hitpic = DTILE_FLAMETHROWERFLAME; + if (hitpic->TypeName == NAME_DukeFireball && tOwner && tOwner->GetClass()->TypeName != NAME_DukeFireball) + hitpic = PClass::FindActor(NAME_DukeFlamethrowerFlame); } targ->attackertype = hitpic; diff --git a/source/games/duke/src/sectors_r.cpp b/source/games/duke/src/sectors_r.cpp index db35492ce..24c062180 100644 --- a/source/games/duke/src/sectors_r.cpp +++ b/source/games/duke/src/sectors_r.cpp @@ -210,7 +210,7 @@ void checkhitdefault_r(DDukeActor* targ, DDukeActor* proj) if (proj->spr.picnum == RTILE_FREEZEBLAST && ((targ->isPlayer() && targ->spr.pal == 1) || (gs.freezerhurtowner == 0 && proj->GetOwner() == targ))) return; - targ->attackertype = proj->spr.picnum; + targ->attackertype = static_cast(proj->GetClass()); targ->hitextra += proj->spr.extra; if (targ->spr.picnum != RTILE_COW) targ->hitang = proj->spr.Angles.Yaw; @@ -646,7 +646,7 @@ void tearitup(sectortype* sect) { if (act->spr.picnum == RTILE_DESTRUCTO) { - act->attackertype = RTILE_SHOTSPARK1; + act->attackertype = PClass::FindActor(NAME_DukeShotSpark); act->hitextra = 1; } } diff --git a/source/games/duke/src/spawn.cpp b/source/games/duke/src/spawn.cpp index d84fb2208..bae2bb8b1 100644 --- a/source/games/duke/src/spawn.cpp +++ b/source/games/duke/src/spawn.cpp @@ -107,7 +107,7 @@ DDukeActor* CreateActor(sectortype* whatsectp, const DVector3& pos, PClassActor* if (s_ow) { - act->attackertype = s_ow->spr.picnum; + act->attackertype = static_cast(s_ow->GetClass()); act->floorz = s_ow->floorz; act->ceilingz = s_ow->ceilingz; } @@ -168,7 +168,7 @@ DDukeActor* SpawnActor(sectortype* whatsectp, const DVector3& pos, PClassActor* bool initspriteforspawn(DDukeActor* act) { SetupGameVarsForActor(act); - act->attackertype = act->spr.picnum; + act->attackertype = static_cast(act->GetClass()); act->timetosleep = 0; act->hitextra = -1; @@ -268,7 +268,7 @@ DDukeActor* spawn(DDukeActor* actj, int pn) auto spawned = CreateActor(actj->sector(), actj->spr.pos, pn, 0, DVector2(0, 0), nullAngle, 0., 0., actj, 0); if (spawned) { - spawned->attackertype = actj->spr.picnum; + spawned->attackertype = static_cast(actj->GetClass()); return spawninit(actj, spawned, nullptr); } } @@ -282,7 +282,7 @@ DDukeActor* spawn(DDukeActor* actj, PClassActor * cls) auto spawned = CreateActor(actj->sector(), actj->spr.pos, cls, 0, DVector2(0, 0), nullAngle, 0., 0., actj, 0); if (spawned) { - spawned->attackertype = actj->spr.picnum; + spawned->attackertype = static_cast(actj->GetClass()); return spawninit(actj, spawned, nullptr); } } @@ -322,6 +322,7 @@ bool commonEnemySetup(DDukeActor* self, DDukeActor* owner) addtokills(self); + self->flags1 &= ~SFLAG_KILLCOUNT; self->timetosleep = 0; if (!self->mapSpawned) { diff --git a/source/games/duke/src/types.h b/source/games/duke/src/types.h index 919993cd6..b29202666 100644 --- a/source/games/duke/src/types.h +++ b/source/games/duke/src/types.h @@ -25,9 +25,7 @@ struct STATUSBARTYPE struct ActorInfo { uint32_t scriptaddress; - EDukeFlags1 flags; - EDukeFlags2 flags2; - EDukeFlags3 flags3; + EDukeFlags1 enemyflags; // placeholder during parsing. Since CON gets parsed before the spawn type table we cannot copy these to their final location yet. int aimoffset; int falladjustz; int gutsoffset; @@ -39,11 +37,17 @@ class DDukeActor : public DCoreActor HAS_OBJECT_POINTERS public: TObjPtr ownerActor, hitOwnerActor; + PClassActor* attackertype; + + const DDukeActor* attackerDefaults() + { + return static_cast(GetDefaultByType(attackertype? attackertype : RUNTIME_CLASS(DDukeActor))); + } uint8_t cgg; uint8_t spriteextra; // moved here for easier maintenance. This was originally a hacked in field in the sprite structure called 'filler'. uint16_t movflag; - short attackertype, hitextra; + short hitextra; short tempval, basepicnum; unsigned short timetosleep; bool mapSpawned; diff --git a/source/games/duke/src/vmexports.cpp b/source/games/duke/src/vmexports.cpp index 0dd2e6d29..f205b579d 100644 --- a/source/games/duke/src/vmexports.cpp +++ b/source/games/duke/src/vmexports.cpp @@ -212,6 +212,7 @@ DEFINE_GLOBAL(camsprite) //--------------------------------------------------------------------------- DEFINE_FIELD(DDukeActor, ownerActor) +DEFINE_FIELD(DDukeActor, attackertype) DEFINE_FIELD(DDukeActor, hitOwnerActor) DEFINE_FIELD(DDukeActor, cgg) DEFINE_FIELD(DDukeActor, spriteextra) @@ -726,21 +727,6 @@ DEFINE_ACTION_FUNCTION(DDukeActor, actorflag3) ACTION_RETURN_BOOL(!!(self->flags3 & EDukeFlags3::FromInt(mask))); } -DEFINE_ACTION_FUNCTION(DDukeActor, attackerflag1) -{ - PARAM_SELF_PROLOGUE(DDukeActor); - PARAM_INT(mask); - ACTION_RETURN_BOOL(!!attackerflag(self, EDukeFlags1::FromInt(mask))); -} - -DEFINE_ACTION_FUNCTION(DDukeActor, attackerflag2) -{ - PARAM_SELF_PROLOGUE(DDukeActor); - PARAM_INT(mask); - ACTION_RETURN_BOOL(!!attackerflag(self, EDukeFlags2::FromInt(mask))); -} - - //--------------------------------------------------------------------------- // // DukePlayer diff --git a/wadsrc/static/filter/redneck.ridesagain/rmapinfo.spawnclasses b/wadsrc/static/filter/redneck.ridesagain/rmapinfo.spawnclasses index 5ecda1b4a..3fd88544a 100644 --- a/wadsrc/static/filter/redneck.ridesagain/rmapinfo.spawnclasses +++ b/wadsrc/static/filter/redneck.ridesagain/rmapinfo.spawnclasses @@ -192,4 +192,5 @@ spawnclasses 78 = RedneckMotoAmmo 8460 = RedneckBoatAmmo + 7170 = RedneckMotoHit } diff --git a/wadsrc/static/zscript/games/duke/actors/_placeholders.zs b/wadsrc/static/zscript/games/duke/actors/_placeholders.zs index 8fab8858e..dab4536a4 100644 --- a/wadsrc/static/zscript/games/duke/actors/_placeholders.zs +++ b/wadsrc/static/zscript/games/duke/actors/_placeholders.zs @@ -69,6 +69,15 @@ class DukeShotSpark : DukeActor } } +class RedneckMotoHit : DukeActor +{ + default + { + pic "MOTOHIT"; + } +} + + // placeholders for CON scripted actors where we need the class. class DukeForceRipple : DukeActor diff --git a/wadsrc/static/zscript/games/duke/actors/crack.zs b/wadsrc/static/zscript/games/duke/actors/crack.zs index 4f9a9b8ec..189a93854 100644 --- a/wadsrc/static/zscript/games/duke/actors/crack.zs +++ b/wadsrc/static/zscript/games/duke/actors/crack.zs @@ -32,7 +32,7 @@ class DukeCrack : DukeActor { self.temp_data[0] = self.cstat; self.temp_angle = self.angle; - if (self.ifhitbyweapon() >= 0 && self.attackerflag2(SFLAG2_EXPLOSIVE)) + if (self.ifhitbyweapon() == 2) // explosive damage { DukeStatIterator it; for(let a1 = it.First(STAT_STANDABLE); a1; a1 = it.Next()) diff --git a/wadsrc/static/zscript/games/duke/actors/greenslime.zs b/wadsrc/static/zscript/games/duke/actors/greenslime.zs index 6cb29852e..94cd58420 100644 --- a/wadsrc/static/zscript/games/duke/actors/greenslime.zs +++ b/wadsrc/static/zscript/games/duke/actors/greenslime.zs @@ -70,7 +70,7 @@ class DukeGreenSlime : DukeActor j = self.ifhitbyweapon(); if (j >= 0) { - if (self.attackerflag2(SFLAG2_FREEZEDAMAGE)) + if (j == 1) // freeze damage return; for (j = 16; j >= 0; j--) { @@ -216,7 +216,7 @@ class DukeGreenSlime : DukeActor if (p.somethingonplayer == self) p.somethingonplayer = nullptr; - if (self.attackerflag2(SFLAG2_FREEZEDAMAGE)) + if (j == 1) // freeze damage { self.PlayActorSound("SOMETHINGFROZE"); self.temp_data[0] = -5; self.temp_data[3] = 0; diff --git a/wadsrc/static/zscript/games/duke/dukeactor.zs b/wadsrc/static/zscript/games/duke/dukeactor.zs index 3c90ef626..78ee4728f 100644 --- a/wadsrc/static/zscript/games/duke/dukeactor.zs +++ b/wadsrc/static/zscript/games/duke/dukeactor.zs @@ -145,14 +145,15 @@ class DukeActor : CoreActor native native void SetSpritesetImage(int index); native int GetSpritesetSize(); + native class attackertype; native DukeActor ownerActor, hitOwnerActor; native uint8 cgg; native uint8 spriteextra; // moved here for easier maintenance. This was originally a hacked in field in the sprite structure called 'filler'. - native int16 /*attackertype, hitang,*/ hitextra, movflag; + native int16 hitextra, movflag; native int16 tempval; /*, dispicnum;*/ native int16 timetosleep; native bool mapSpawned; - native double floorz, ceilingz; + native double floorz, ceilingz, hitang; native int saved_ammo; native int palvals; native int temp_data[6]; @@ -207,6 +208,10 @@ class DukeActor : CoreActor native { return false; } + virtual class GetRadiusDamageType(int targhealth) + { + return 'DukeRadiusExplosion'; + } native void RandomScrap(); native void hitradius(int r, int hp1, int hp2, int hp3, int hp4); @@ -231,8 +236,6 @@ class DukeActor : CoreActor native 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);