diff --git a/source/core/thingdef_properties.cpp b/source/core/thingdef_properties.cpp index f6d6d44a9..770ea320b 100644 --- a/source/core/thingdef_properties.cpp +++ b/source/core/thingdef_properties.cpp @@ -492,7 +492,7 @@ DEFINE_PROPERTY(owner, I, CoreActor) //========================================================================== DEFINE_PROPERTY(spriteset, Sssssssssssssssssssssssssssssss, CoreActor) { - info->ActorInfo()->SpriteSet.Clear(); + info->ActorInfo()->SpriteSetNames.Clear(); for (int i = 0; i < PROP_PARM_COUNT; ++i) { PROP_STRING_PARM(n, i); diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index 80d150641..908092848 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -884,83 +884,6 @@ void movetouchplate(DDukeActor* actor, int plate) // //--------------------------------------------------------------------------- -void moveooz(DDukeActor* actor, int seenine, int seeninedead, int ooz, int explosion) -{ - int j; - if (actor->spr.shade != -32 && actor->spr.shade != -33) - { - if (actor->spr.scale.X != 0) - j = (fi.ifhitbyweapon(actor) >= 0); - else - j = 0; - - if (j || actor->spr.shade == -31) - { - if (j) actor->spr.lotag = 0; - - actor->temp_data[3] = 1; - - DukeStatIterator it(STAT_STANDABLE); - while (auto act2 = it.Next()) - { - if (actor->spr.hitag == act2->spr.hitag && actorflag(act2, SFLAG2_BRIGHTEXPLODE)) - act2->spr.shade = -32; - } - } - } - else - { - if (actor->spr.shade == -32) - { - if (actor->spr.lotag > 0) - { - actor->spr.lotag -= 3; - if (actor->spr.lotag <= 0) actor->spr.lotag = -99; - } - else - actor->spr.shade = -33; - } - else - { - if (actor->spr.scale.X > 0) - { - actor->temp_data[2]++; - if (actor->temp_data[2] == 3) - { - if (actor->spr.picnum == ooz) - { - actor->temp_data[2] = 0; - detonate(actor, explosion); - return; - } - if (actor->spr.picnum != (seeninedead + 1)) - { - actor->temp_data[2] = 0; - - if (actor->spr.picnum == seeninedead) actor->spr.picnum++; - else if (actor->spr.picnum == seenine) - actor->spr.picnum = seeninedead; - } - else - { - detonate(actor, explosion); - return; - } - } - return; - } - detonate(actor, explosion); - return; - } - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - void movecanwithsomething(DDukeActor* actor) { makeitfall(actor); diff --git a/source/games/duke/src/actors_d.cpp b/source/games/duke/src/actors_d.cpp index 670f5c26f..26e97d7b0 100644 --- a/source/games/duke/src/actors_d.cpp +++ b/source/games/duke/src/actors_d.cpp @@ -945,11 +945,6 @@ void movestandables_d(void) continue; } - else if (picnum == OOZFILTER || picnum == SEENINE || picnum == SEENINEDEAD || picnum == (SEENINEDEAD + 1)) - { - moveooz(act, SEENINE, SEENINEDEAD, OOZFILTER, EXPLOSION2); - } - else if (picnum == MASTERSWITCH) { movemasterswitch(act); diff --git a/source/games/duke/src/actors_r.cpp b/source/games/duke/src/actors_r.cpp index e0c0e67eb..a8ba65f00 100644 --- a/source/games/duke/src/actors_r.cpp +++ b/source/games/duke/src/actors_r.cpp @@ -793,11 +793,6 @@ void movestandables_r(void) continue; } - else if (picnum == OOZFILTER || picnum == SEENINE || picnum == SEENINEDEAD || picnum == (SEENINEDEAD + 1)) - { - moveooz(act, SEENINE, SEENINEDEAD, OOZFILTER, EXPLOSION2); - } - else if (picnum == MASTERSWITCH) { movemasterswitch(act); diff --git a/source/games/duke/src/constants.h b/source/games/duke/src/constants.h index 533fc7279..8bcdb86af 100644 --- a/source/games/duke/src/constants.h +++ b/source/games/duke/src/constants.h @@ -359,6 +359,7 @@ enum sflags2_t SFLAG2_CAMERA = 0x00000100, SFLAG2_DONTANIMATE = 0x00000200, SFLAG2_INTERPOLATEANGLE = 0x00000400, + SFLAG2_GREENBLOOD = 0x00000800, }; using EDukeFlags2 = TFlags; diff --git a/source/games/duke/src/dispatch.cpp b/source/games/duke/src/dispatch.cpp index 615bcf639..3571fbac2 100644 --- a/source/games/duke/src/dispatch.cpp +++ b/source/games/duke/src/dispatch.cpp @@ -53,6 +53,8 @@ bool checkhitceiling_d(sectortype* sn); bool checkhitceiling_r(sectortype* sn); void checkhitsprite_d(DDukeActor* i, DDukeActor* sn); void checkhitsprite_r(DDukeActor* i, DDukeActor* sn); +void checkhitdefault_d(DDukeActor* i, DDukeActor* sn); +void checkhitdefault_r(DDukeActor* i, DDukeActor* sn); void checksectors_d(int snum); void checksectors_r(int snum); @@ -119,6 +121,7 @@ void SetDispatcher() checkhitwall_d, checkhitceiling_d, checkhitsprite_d, + checkhitdefault_d, checksectors_d, spawninit_d, @@ -161,6 +164,7 @@ void SetDispatcher() checkhitwall_r, checkhitceiling_r, checkhitsprite_r, + checkhitdefault_r, checksectors_r, spawninit_r, diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h index 8d263c39d..3c1ec3495 100644 --- a/source/games/duke/src/duke3d.h +++ b/source/games/duke/src/duke3d.h @@ -79,6 +79,7 @@ struct Dispatcher void (*checkhitwall)(DDukeActor* spr, walltype* dawall, const DVector3& pos, int atwith); bool (*checkhitceiling)(sectortype* sn); void (*checkhitsprite)(DDukeActor* i, DDukeActor* sn); + void (*checkhitdefault)(DDukeActor* i, DDukeActor* sn); void (*checksectors)(int low); DDukeActor* (*spawninit)(DDukeActor* actj, DDukeActor* act, TArray* actors); diff --git a/source/games/duke/src/flags_d.cpp b/source/games/duke/src/flags_d.cpp index 933529593..043cfa7b2 100644 --- a/source/games/duke/src/flags_d.cpp +++ b/source/games/duke/src/flags_d.cpp @@ -224,6 +224,7 @@ void initactorflags_d() setflag(SFLAG2_CAMERA, { CAMERA1 }); setflag(SFLAG2_DONTANIMATE, { TRIPBOMB, LASERLINE }); setflag(SFLAG2_INTERPOLATEANGLE, { BEARINGPLATE }); + setflag(SFLAG2_GREENBLOOD, { OOZFILTER, NEWBEAST }); if (isWorldTour()) { diff --git a/source/games/duke/src/flags_r.cpp b/source/games/duke/src/flags_r.cpp index d7defeda7..0a7152c2a 100644 --- a/source/games/duke/src/flags_r.cpp +++ b/source/games/duke/src/flags_r.cpp @@ -251,6 +251,7 @@ 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 }); // 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) diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index fbe4a4d39..8d96ae3b9 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -31,7 +31,6 @@ void movefta(); void clearcameras(int i, player_struct* p); void RANDOMSCRAP(DDukeActor* i); -void movecrane(DDukeActor* i, int crane); void detonate(DDukeActor* i, int explosion); void movemasterswitch(DDukeActor* i); void movetrash(DDukeActor* i); @@ -42,7 +41,6 @@ void movecanwithsomething(DDukeActor* i); void bounce(DDukeActor* i); void movetongue(DDukeActor* i, int tongue, int jaw); void rpgexplode(DDukeActor* i, int j, const DVector3& pos, int EXPLOSION2, int EXPLOSIONBOT2, int newextra, int playsound); -void moveooz(DDukeActor* i, int seenine, int seeninedead, int ooz, int explosion); void lotsofstuff(DDukeActor* s, int n, int spawntype); bool respawnmarker(DDukeActor* i, int yellow, int green); bool rat(DDukeActor* i, bool makesound); @@ -133,7 +131,7 @@ void quickkill(player_struct* p); int setpal(player_struct* p); int madenoise(int playerNum); int haskey(sectortype* sect, int snum); -void shootbloodsplat(DDukeActor* i, int p, const DVector3& pos, DAngle ang, int atwith, int BIGFORCE, int OOZFILTER, int NEWBEAST); +void shootbloodsplat(DDukeActor* i, int p, const DVector3& pos, DAngle ang, int atwith, int BIGFORCE); void breakwall(int newpn, DDukeActor* spr, walltype* dawallnum); int callsound(sectortype* sectnum,DDukeActor* snum, bool endstate = false); diff --git a/source/games/duke/src/namelist_d.h b/source/games/duke/src/namelist_d.h index 7e3fa46ab..48b2e3842 100644 --- a/source/games/duke/src/namelist_d.h +++ b/source/games/duke/src/namelist_d.h @@ -345,6 +345,7 @@ x(EXPLODINGBARREL2, 1239) x(FIREBARREL, 1240) x(SEENINE, 1247) x(SEENINEDEAD, 1248) +x(SEENINEDEAD1, 1249) x(STEAM, 1250) x(CEILINGSTEAM, 1255) x(PIPE6B, 1260) diff --git a/source/games/duke/src/namelist_r.h b/source/games/duke/src/namelist_r.h index 5d763f523..34be5ac27 100644 --- a/source/games/duke/src/namelist_r.h +++ b/source/games/duke/src/namelist_r.h @@ -411,6 +411,7 @@ x(EXPLODINGBARREL2, 1316) x(FIREBARREL, 1317) x(SEENINE, 1324) x(SEENINEDEAD, 1325) +x(SEENINEDEAD1, 1326) x(STEAM, 1327) x(CEILINGSTEAM, 1332) x(PIPE6B, 1337) diff --git a/source/games/duke/src/player.cpp b/source/games/duke/src/player.cpp index 131f39388..5c1d6cea6 100644 --- a/source/games/duke/src/player.cpp +++ b/source/games/duke/src/player.cpp @@ -1008,7 +1008,7 @@ int haskey(sectortype* sectp, int snum) // //--------------------------------------------------------------------------- -void shootbloodsplat(DDukeActor* actor, int p, const DVector3& pos, DAngle ang, int atwith, int BIGFORCE, int OOZFILTER, int NEWBEAST) +void shootbloodsplat(DDukeActor* actor, int p, const DVector3& pos, DAngle ang, int atwith, int BIGFORCE) { auto sectp = actor->sector(); double zvel; @@ -1059,7 +1059,7 @@ void shootbloodsplat(DDukeActor* actor, int p, const DVector3& pos, DAngle ang, spawned->spr.cstat |= randomXFlip(); ssp(spawned, CLIPMASK0); SetActor(spawned, spawned->spr.pos); - if (actor->spr.picnum == OOZFILTER || actor->spr.picnum == NEWBEAST) + if (actorflag(actor, SFLAG2_GREENBLOOD)) spawned->spr.pal = 6; } } diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index 37ac10a0a..95282c531 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -1126,7 +1126,7 @@ void shoot_d(DDukeActor* actor, int atwith) case BLOODSPLAT2: case BLOODSPLAT3: case BLOODSPLAT4: - shootbloodsplat(actor, p, spos, sang, atwith, BIGFORCE, OOZFILTER, NEWBEAST); + shootbloodsplat(actor, p, spos, sang, atwith, BIGFORCE); break; case KNEE: diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index 3a5055d71..51ec9b400 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -853,7 +853,7 @@ void shoot_r(DDukeActor* actor, int atwith) case BLOODSPLAT2: case BLOODSPLAT3: case BLOODSPLAT4: - shootbloodsplat(actor, p, spos, sang, atwith, BIGFORCE, OOZFILTER, -1); + shootbloodsplat(actor, p, spos, sang, atwith, BIGFORCE); return; case SLINGBLADE: diff --git a/source/games/duke/src/premap_d.cpp b/source/games/duke/src/premap_d.cpp index 945fcbdc1..81a4f1c3a 100644 --- a/source/games/duke/src/premap_d.cpp +++ b/source/games/duke/src/premap_d.cpp @@ -155,8 +155,6 @@ static void cachespritenum(DDukeActor* actor) maxc = 10; break; case EXPLODINGBARREL: - case SEENINE: - case OOZFILTER: maxc = 3; break; case NUKEBARREL: diff --git a/source/games/duke/src/premap_r.cpp b/source/games/duke/src/premap_r.cpp index 9a984076d..3ef86e172 100644 --- a/source/games/duke/src/premap_r.cpp +++ b/source/games/duke/src/premap_r.cpp @@ -263,8 +263,6 @@ static void cachespritenum(DDukeActor* actor) maxc = 6; break; case EXPLODINGBARREL: - case SEENINE: - case OOZFILTER: maxc = 3; break; case NUKEBARREL: diff --git a/source/games/duke/src/sectors_d.cpp b/source/games/duke/src/sectors_d.cpp index 17d840fdd..0882b9a05 100644 --- a/source/games/duke/src/sectors_d.cpp +++ b/source/games/duke/src/sectors_d.cpp @@ -999,9 +999,124 @@ bool checkhitceiling_d(sectortype* sectp) // //--------------------------------------------------------------------------- +void checkhitdefault_d(DDukeActor* targ, DDukeActor* proj) +{ + if ((targ->spr.cstat & CSTAT_SPRITE_ALIGNMENT_WALL) && targ->spr.hitag == 0 && targ->spr.lotag == 0 && targ->spr.statnum == 0) + return; + + if ((proj->spr.picnum == FREEZEBLAST || proj->GetOwner() != targ) && targ->spr.statnum != 4) + { + if (badguy(targ) == 1) + { + if (isWorldTour() && targ->spr.picnum == FIREFLY && targ->spr.scale.X < 0.75) + return; + + if (proj->spr.picnum == RPG) proj->spr.extra <<= 1; + + if ((targ->spr.picnum != DRONE) && (targ->spr.picnum != ROTATEGUN) && (targ->spr.picnum != COMMANDER) && (targ->spr.picnum < GREENSLIME || targ->spr.picnum > GREENSLIME + 7)) + if (proj->spr.picnum != FREEZEBLAST) + //if (actortype[targ->spr.picnum] == 0) //TRANSITIONAL. Cannot be done right with EDuke mess backing the engine. + { + auto spawned = spawn(proj, JIBS6); + if (spawned) + { + if (proj->spr.pal == 6) + spawned->spr.pal = 6; + spawned->spr.pos.Z += 4; + spawned->vel.X = 1; + spawned->spr.scale = DVector2(0.375, 0.375); + spawned->spr.angle = DAngle22_5 / 4 - randomAngle(22.5 / 2); + } + } + + auto Owner = proj->GetOwner(); + + if (Owner && Owner->spr.picnum == APLAYER && targ->spr.picnum != ROTATEGUN && targ->spr.picnum != DRONE) + if (ps[Owner->PlayerIndex()].curr_weapon == SHOTGUN_WEAPON) + { + fi.shoot(targ, BLOODSPLAT3); + fi.shoot(targ, BLOODSPLAT1); + fi.shoot(targ, BLOODSPLAT2); + fi.shoot(targ, BLOODSPLAT4); + } + + if (targ->spr.picnum != TANK && !bossguy(targ) && targ->spr.picnum != RECON && targ->spr.picnum != ROTATEGUN) + { + if ((targ->spr.cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == 0) + targ->spr.angle = proj->spr.angle + DAngle180; + + targ->vel.X = -proj->spr.extra * 0.25; + auto sp = targ->sector(); + pushmove(targ->spr.pos, &sp, 8, 4, 4, CLIPMASK0); + if (sp != targ->sector() && sp != nullptr) + ChangeActorSect(targ, sp); + } + + if (targ->spr.statnum == 2) + { + ChangeActorStat(targ, 1); + targ->timetosleep = SLEEPTIME; + } + if ((targ->spr.scale.X < 0.375 || targ->spr.picnum == SHARK) && proj->spr.picnum == SHRINKSPARK) return; + } + + if (targ->spr.statnum != 2) + { + if (proj->spr.picnum == FREEZEBLAST && ((targ->spr.picnum == APLAYER && targ->spr.pal == 1) || (gs.freezerhurtowner == 0 && proj->GetOwner() == targ))) + return; + + + int hitpic = proj->spr.picnum; + auto Owner = proj->GetOwner(); + if (Owner && Owner->spr.picnum == APLAYER) + { + if (targ->spr.picnum == APLAYER && ud.coop != 0 && ud.ffire == 0) + return; + + auto tOwner = targ->GetOwner(); + if (isWorldTour() && hitpic == FIREBALL && tOwner && tOwner->spr.picnum != FIREBALL) + hitpic = FLAMETHROWERFLAME; + } + + targ->attackertype = hitpic; + targ->hitextra += proj->spr.extra; + targ->hitang = proj->spr.angle; + targ->SetHitOwner(Owner); + } + + if (targ->spr.statnum == 10) + { + auto p = targ->spr.yint; + if (ps[p].newOwner != nullptr) + { + ps[p].newOwner = nullptr; + ps[p].restorexyz(); + ps[p].angle.restore(); + + updatesector(ps[p].pos, &ps[p].cursector); + + DukeStatIterator it(STAT_ACTOR); + while (auto itActor = it.Next()) + { + if (actorflag(itActor, SFLAG2_CAMERA)) itActor->spr.yint = 0; + } + } + + if (targ->spr.scale.X < 0.375 && proj->spr.picnum == SHRINKSPARK) + return; + + auto hitowner = targ->GetHitOwner(); + if (!hitowner || hitowner->spr.picnum != APLAYER) + if (ud.player_skill >= 3) + proj->spr.extra += (proj->spr.extra >> 1); + } + + } +} + void checkhitsprite_d(DDukeActor* targ, DDukeActor* proj) { - int j, k, p; + int j, k; if (targ->GetClass() != RUNTIME_CLASS(DDukeActor)) { @@ -1312,117 +1427,7 @@ void checkhitsprite_d(DDukeActor* targ, DDukeActor* proj) if (!targ) break; [[fallthrough]]; default: - if ((targ->spr.cstat & CSTAT_SPRITE_ALIGNMENT_WALL) && targ->spr.hitag == 0 && targ->spr.lotag == 0 && targ->spr.statnum == 0) - break; - - if ((proj->spr.picnum == FREEZEBLAST || proj->GetOwner() != targ) && targ->spr.statnum != 4) - { - if (badguy(targ) == 1) - { - if (isWorldTour() && targ->spr.picnum == FIREFLY && targ->spr.scale.X < 0.75) - break; - - if (proj->spr.picnum == RPG) proj->spr.extra <<= 1; - - if ((targ->spr.picnum != DRONE) && (targ->spr.picnum != ROTATEGUN) && (targ->spr.picnum != COMMANDER) && (targ->spr.picnum < GREENSLIME || targ->spr.picnum > GREENSLIME + 7)) - if (proj->spr.picnum != FREEZEBLAST) - //if (actortype[targ->spr.picnum] == 0) //TRANSITIONAL. Cannot be done right with EDuke mess backing the engine. - { - auto spawned = spawn(proj, JIBS6); - if (spawned) - { - if (proj->spr.pal == 6) - spawned->spr.pal = 6; - spawned->spr.pos.Z += 4; - spawned->vel.X = 1; - spawned->spr.scale = DVector2(0.375, 0.375); - spawned->spr.angle = DAngle22_5 / 4 - randomAngle(22.5 / 2); - } - } - - auto Owner = proj->GetOwner(); - - if (Owner && Owner->spr.picnum == APLAYER && targ->spr.picnum != ROTATEGUN && targ->spr.picnum != DRONE) - if (ps[Owner->PlayerIndex()].curr_weapon == SHOTGUN_WEAPON) - { - fi.shoot(targ, BLOODSPLAT3); - fi.shoot(targ, BLOODSPLAT1); - fi.shoot(targ, BLOODSPLAT2); - fi.shoot(targ, BLOODSPLAT4); - } - - if (targ->spr.picnum != TANK && !bossguy(targ) && targ->spr.picnum != RECON && targ->spr.picnum != ROTATEGUN) - { - if ((targ->spr.cstat & CSTAT_SPRITE_ALIGNMENT_MASK) == 0) - targ->spr.angle = proj->spr.angle + DAngle180; - - targ->vel.X = -proj->spr.extra * 0.25; - auto sp = targ->sector(); - pushmove(targ->spr.pos, &sp, 8, 4, 4, CLIPMASK0); - if (sp != targ->sector() && sp != nullptr) - ChangeActorSect(targ, sp); - } - - if (targ->spr.statnum == 2) - { - ChangeActorStat(targ, 1); - targ->timetosleep = SLEEPTIME; - } - if ((targ->spr.scale.X < 0.375 || targ->spr.picnum == SHARK) && proj->spr.picnum == SHRINKSPARK) return; - } - - if (targ->spr.statnum != 2) - { - if (proj->spr.picnum == FREEZEBLAST && ((targ->spr.picnum == APLAYER && targ->spr.pal == 1) || (gs.freezerhurtowner == 0 && proj->GetOwner() == targ))) - return; - - - int hitpic = proj->spr.picnum; - auto Owner = proj->GetOwner(); - if (Owner && Owner->spr.picnum == APLAYER) - { - if (targ->spr.picnum == APLAYER && ud.coop != 0 && ud.ffire == 0) - return; - - auto tOwner = targ->GetOwner(); - if (isWorldTour() && hitpic == FIREBALL && tOwner && tOwner->spr.picnum != FIREBALL) - hitpic = FLAMETHROWERFLAME; - } - - targ->attackertype = hitpic; - targ->hitextra += proj->spr.extra; - targ->hitang = proj->spr.angle; - targ->SetHitOwner(Owner); - } - - if (targ->spr.statnum == 10) - { - p = targ->spr.yint; - if (ps[p].newOwner != nullptr) - { - ps[p].newOwner = nullptr; - ps[p].restorexyz(); - ps[p].angle.restore(); - - updatesector(ps[p].pos, &ps[p].cursector); - - DukeStatIterator it(STAT_ACTOR); - while (auto itActor = it.Next()) - { - if (actorflag(itActor, SFLAG2_CAMERA)) itActor->spr.yint = 0; - } - } - - if (targ->spr.scale.X < 0.375 && proj->spr.picnum == SHRINKSPARK) - return; - - auto hitowner = targ->GetHitOwner(); - if (!hitowner || hitowner->spr.picnum != APLAYER) - if (ud.player_skill >= 3) - proj->spr.extra += (proj->spr.extra >> 1); - } - - } + checkhitdefault_d(targ, proj); break; } } diff --git a/source/games/duke/src/sectors_r.cpp b/source/games/duke/src/sectors_r.cpp index 87fbc769d..024530fa6 100644 --- a/source/games/duke/src/sectors_r.cpp +++ b/source/games/duke/src/sectors_r.cpp @@ -1513,9 +1513,92 @@ bool checkhitceiling_r(sectortype* sectp) // //--------------------------------------------------------------------------- +void checkhitdefault_r(DDukeActor* targ, DDukeActor* proj) +{ + if ((targ->spr.cstat & CSTAT_SPRITE_ALIGNMENT_WALL) && targ->spr.hitag == 0 && targ->spr.lotag == 0 && targ->spr.statnum == 0) + return; + + if ((proj->spr.picnum == SHRINKSPARK || proj->spr.picnum == FREEZEBLAST || proj->GetOwner() != targ) && targ->spr.statnum != 4) + { + if (badguy(targ) == 1) + { + if (proj->spr.picnum == RPG) proj->spr.extra <<= 1; + else if (isRRRA() && proj->spr.picnum == RPG2) proj->spr.extra <<= 1; + + if ((targ->spr.picnum != DRONE)) + if (proj->spr.picnum != FREEZEBLAST) + //if (actortype[targ->spr.picnum] == 0) //TRANSITIONAL. Cannot be done right with EDuke mess backing the engine. + { + auto spawned = spawn(proj, JIBS6); + if (spawned) + { + if (proj->spr.pal == 6) + spawned->spr.pal = 6; + spawned->spr.pos.Z += 4; + spawned->vel.X = 1; + spawned->spr.scale = DVector2(0.375, 0.375); + spawned->spr.angle = DAngle22_5 / 4 - randomAngle(22.5 / 2); + } + } + + auto Owner = proj->GetOwner(); + + if (Owner && Owner->spr.picnum == APLAYER && targ->spr.picnum != DRONE) + if (ps[Owner->PlayerIndex()].curr_weapon == SHOTGUN_WEAPON) + { + fi.shoot(targ, BLOODSPLAT3); + fi.shoot(targ, BLOODSPLAT1); + fi.shoot(targ, BLOODSPLAT2); + fi.shoot(targ, BLOODSPLAT4); + } + + if (targ->spr.statnum == 2) + { + ChangeActorStat(targ, 1); + targ->timetosleep = SLEEPTIME; + } + } + + if (targ->spr.statnum != 2) + { + if (proj->spr.picnum == FREEZEBLAST && ((targ->spr.picnum == APLAYER && targ->spr.pal == 1) || (gs.freezerhurtowner == 0 && proj->GetOwner() == targ))) + return; + + targ->attackertype = proj->spr.picnum; + targ->hitextra += proj->spr.extra; + if (targ->spr.picnum != COW) + targ->hitang = proj->spr.angle; + targ->SetHitOwner(proj->GetOwner()); + } + + if (targ->spr.statnum == 10) + { + auto p = targ->PlayerIndex(); + if (ps[p].newOwner != nullptr) + { + ps[p].newOwner = nullptr; + ps[p].restorexyz(); + + updatesector(ps[p].pos, &ps[p].cursector); + + DukeStatIterator it(STAT_EFFECTOR); + while (auto act = it.Next()) + { + if (actorflag(act, SFLAG2_CAMERA)) act->spr.yint = 0; + } + } + auto Owner = targ->GetHitOwner(); + if (!Owner || Owner->spr.picnum != APLAYER) + if (ud.player_skill >= 3) + proj->spr.extra += (proj->spr.extra >> 1); + } + + } +} + void checkhitsprite_r(DDukeActor* targ, DDukeActor* proj) { - int j, k, p; + int j, k; if (targ->GetClass() != RUNTIME_CLASS(DDukeActor)) { @@ -2278,85 +2361,7 @@ void checkhitsprite_r(DDukeActor* targ, DDukeActor* proj) if (!targ) break; [[fallthrough]]; default: - if ((targ->spr.cstat & CSTAT_SPRITE_ALIGNMENT_WALL) && targ->spr.hitag == 0 && targ->spr.lotag == 0 && targ->spr.statnum == 0) - break; - - if ((proj->spr.picnum == SHRINKSPARK || proj->spr.picnum == FREEZEBLAST || proj->GetOwner() != targ) && targ->spr.statnum != 4) - { - if (badguy(targ) == 1) - { - if (proj->spr.picnum == RPG) proj->spr.extra <<= 1; - else if (isRRRA() && proj->spr.picnum == RPG2) proj->spr.extra <<= 1; - - if ((targ->spr.picnum != DRONE)) - if (proj->spr.picnum != FREEZEBLAST) - //if (actortype[targ->spr.picnum] == 0) //TRANSITIONAL. Cannot be done right with EDuke mess backing the engine. - { - auto spawned = spawn(proj, JIBS6); - if (spawned) - { - if (proj->spr.pal == 6) - spawned->spr.pal = 6; - spawned->spr.pos.Z += 4; - spawned->vel.X = 1; - spawned->spr.scale = DVector2(0.375, 0.375); - spawned->spr.angle = DAngle22_5/4 - randomAngle(22.5/2); - } - } - - auto Owner = proj->GetOwner(); - - if (Owner && Owner->spr.picnum == APLAYER && targ->spr.picnum != DRONE) - if (ps[Owner->PlayerIndex()].curr_weapon == SHOTGUN_WEAPON) - { - fi.shoot(targ, BLOODSPLAT3); - fi.shoot(targ, BLOODSPLAT1); - fi.shoot(targ, BLOODSPLAT2); - fi.shoot(targ, BLOODSPLAT4); - } - - if (targ->spr.statnum == 2) - { - ChangeActorStat(targ, 1); - targ->timetosleep = SLEEPTIME; - } - } - - if (targ->spr.statnum != 2) - { - if (proj->spr.picnum == FREEZEBLAST && ((targ->spr.picnum == APLAYER && targ->spr.pal == 1) || (gs.freezerhurtowner == 0 && proj->GetOwner() == targ))) - return; - - targ->attackertype = proj->spr.picnum; - targ->hitextra += proj->spr.extra; - if (targ->spr.picnum != COW) - targ->hitang = proj->spr.angle; - targ->SetHitOwner(proj->GetOwner()); - } - - if (targ->spr.statnum == 10) - { - p = targ->PlayerIndex(); - if (ps[p].newOwner != nullptr) - { - ps[p].newOwner = nullptr; - ps[p].restorexyz(); - - updatesector(ps[p].pos, &ps[p].cursector); - - DukeStatIterator it(STAT_EFFECTOR); - while (auto act = it.Next()) - { - if (actorflag(act, SFLAG2_CAMERA)) act->spr.yint = 0; - } - } - auto Owner = targ->GetHitOwner(); - if (!Owner || Owner->spr.picnum != APLAYER) - if (ud.player_skill >= 3) - proj->spr.extra += (proj->spr.extra >> 1); - } - - } + checkhitdefault_r(targ, proj); break; } } diff --git a/source/games/duke/src/spawn_d.cpp b/source/games/duke/src/spawn_d.cpp index 76d692593..2bc2b6aa2 100644 --- a/source/games/duke/src/spawn_d.cpp +++ b/source/games/duke/src/spawn_d.cpp @@ -1041,23 +1041,6 @@ DDukeActor* spawninit_d(DDukeActor* actj, DDukeActor* act, TArray* case SECTOREFFECTOR: spawneffector(act, actors); - - break; - - - case SEENINE: - case OOZFILTER: - - act->spr.shade = -16; - if (act->spr.scale.X <= 0.125) - { - act->spr.cstat = CSTAT_SPRITE_INVISIBLE; - act->spr.scale = DVector2(0, 0); - } - else act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL; - act->spr.extra = gs.impact_damage << 2; - act->SetOwner(act); - ChangeActorStat(act, STAT_STANDABLE); break; case TOILET: diff --git a/source/games/duke/src/spawn_r.cpp b/source/games/duke/src/spawn_r.cpp index bfa77c081..f05a8343b 100644 --- a/source/games/duke/src/spawn_r.cpp +++ b/source/games/duke/src/spawn_r.cpp @@ -1271,21 +1271,6 @@ DDukeActor* spawninit_r(DDukeActor* actj, DDukeActor* act, TArray* spawneffector(act, actors); break; - case SEENINE: - case OOZFILTER: - - act->spr.shade = -16; - if (act->spr.scale.X <= 0.125) - { - act->spr.cstat = CSTAT_SPRITE_INVISIBLE; - act->spr.scale = DVector2(0, 0); - } - else act->spr.cstat = CSTAT_SPRITE_BLOCK_ALL; - act->spr.extra = gs.impact_damage << 2; - act->SetOwner(act); - ChangeActorStat(act, STAT_STANDABLE); - break; - case EMPTYBIKE: if (!isRRRA()) goto default_case; if (ud.multimode < 2 && act->spr.pal == 1) diff --git a/source/games/duke/src/vmexports.cpp b/source/games/duke/src/vmexports.cpp index 4bc01e540..1b2b0767e 100644 --- a/source/games/duke/src/vmexports.cpp +++ b/source/games/duke/src/vmexports.cpp @@ -138,6 +138,18 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, SetSpritesetImage, setSpritesetImage) return 0; } +static int getSpritesetSize(DDukeActor* self) +{ + auto& spriteset = static_cast(self->GetClass())->ActorInfo()->SpriteSet; + return spriteset.Size(); +} + +DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, GetSpritesetSize, getSpritesetSize) +{ + PARAM_SELF_PROLOGUE(DDukeActor); + ACTION_RETURN_INT(getSpritesetSize(self)); +} + DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, getglobalz, getglobalz) { PARAM_SELF_PROLOGUE(DDukeActor); @@ -332,6 +344,18 @@ DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, detonate, DukeActor_detonate) return 0; } +void DukeActor_checkhitdefault(DDukeActor* origin, DDukeActor* proj) +{ + fi.checkhitdefault(origin, proj); +} + +DEFINE_ACTION_FUNCTION_NATIVE(DDukeActor, checkhitdefault, DukeActor_checkhitdefault) +{ + PARAM_SELF_PROLOGUE(DDukeActor); + PARAM_OBJECT(proj, DDukeActor); + DukeActor_checkhitdefault(self, proj); + return 0; +} // temporary helpers to hide the fact that these flags are not part of the actor yet. DEFINE_ACTION_FUNCTION(DDukeActor, actorflag1) diff --git a/wadsrc/static/filter/duke/engine/engine.def b/wadsrc/static/filter/duke/engine/engine.def index f93eb82a1..f0ae6ce9e 100644 --- a/wadsrc/static/filter/duke/engine/engine.def +++ b/wadsrc/static/filter/duke/engine/engine.def @@ -21,4 +21,7 @@ spawnclasses 548 = DukeCrack3 549 = DukeCrack4 916 = DukeFireext + 1079 = DukeOozFilter + 1247 = DukeSeenine + } diff --git a/wadsrc/static/filter/redneck/engine/engine.def b/wadsrc/static/filter/redneck/engine/engine.def index d44976efd..45f87c031 100644 --- a/wadsrc/static/filter/redneck/engine/engine.def +++ b/wadsrc/static/filter/redneck/engine/engine.def @@ -17,5 +17,7 @@ spawnclasses 1076 = DukeCrack2 1077 = DukeCrack3 1078 = DukeCrack4 + 1273 = DukeOozFilter + 1324 = DukeSeenine } diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 14d5150a4..28c128d7b 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -58,6 +58,7 @@ version "4.10" #include "zscript/games/duke/actors/tripbomb.zs" #include "zscript/games/duke/actors/crack.zs" #include "zscript/games/duke/actors/fireext.zs" +#include "zscript/games/duke/actors/oozfilter.zs" #include "zscript/games/blood/bloodgame.zs" #include "zscript/games/blood/ui/menu.zs" diff --git a/wadsrc/static/zscript/games/duke/actors/oozfilter.zs b/wadsrc/static/zscript/games/duke/actors/oozfilter.zs new file mode 100644 index 000000000..2f72e620d --- /dev/null +++ b/wadsrc/static/zscript/games/duke/actors/oozfilter.zs @@ -0,0 +1,96 @@ + +class DukeOozFilter : DukeActor +{ + default + { + statnum STAT_STANDABLE; + spriteset "OOZFILTER"; + } + + override void Initialize() + { + self.shade = -16; + if (self.scale.X <= 0.125) + { + self.cstat = CSTAT_SPRITE_INVISIBLE; + self.scale = (0, 0); + } + else self.cstat = CSTAT_SPRITE_BLOCK_ALL; + self.extra = gs.impact_damage << 2; + self.ownerActor = self; + } + + override void Tick() + { + int j; + if (self.shade != -32 && self.shade != -33) + { + if (self.scale.X != 0) + j = self.ifhitbyweapon(); + else + j = -1; + + if (j >= 0 || self.shade == -31) + { + if (j >= 0) self.lotag = 0; + + self.temp_data[3] = 1; + + DukeStatIterator it; + for(let act2 = it.first(STAT_STANDABLE); act2; act2 = it.Next()) + { + if (self.hitag == act2.hitag && act2.actorflag2(SFLAG2_BRIGHTEXPLODE)) + act2.shade = -32; + } + } + } + else + { + if (self.shade == -32) + { + if (self.lotag > 0) + { + self.lotag -= 3; + if (self.lotag <= 0) self.lotag = -99; + } + else + { + self.shade = -33; + } + } + else + { + if (self.scale.X > 0) + { + self.temp_data[2]++; + if (self.temp_data[2] == 3) + { + if (self.spritesetindex < self.getSpriteSetSize() - 1) + { + self.temp_data[2] = 0; + self.setSpriteSetImage(self.spritesetindex + 1); + } + else + { + self.detonate('DukeExplosion2'); + } + } + return; + } + self.detonate('DukeExplosion2'); + } + } + } + +} + +class DukeSeenine : DukeOozFilter +{ + default + { + spriteset "SEENINE", "SEENINEDEAD", "SEENINEDEAD1"; + } + +} + + diff --git a/wadsrc/static/zscript/games/duke/dukeactor.zs b/wadsrc/static/zscript/games/duke/dukeactor.zs index ecda4494c..62a11b225 100644 --- a/wadsrc/static/zscript/games/duke/dukeactor.zs +++ b/wadsrc/static/zscript/games/duke/dukeactor.zs @@ -24,6 +24,7 @@ class DukeActor : CoreActor native }; native void SetSpritesetImage(int index); + native int GetSpritesetSize(); native DukeActor ownerActor, hitOwnerActor; native uint8 cgg; @@ -76,11 +77,12 @@ class DukeActor : CoreActor native native void lotsofglass(int count); native void makeitfall(); native void detonate(name type); + native void checkhitdefault(DukeActor proj); virtual void BeginPlay() {} virtual void Initialize() {} virtual void Tick() {} - virtual void onHit(DukeActor hitter) {} + virtual void onHit(DukeActor hitter) { checkhitdefault(hitter); } virtual void onHurt(DukePlayer p) {} virtual void onUse(DukePlayer user) {} virtual bool animate(tspritetype tspr) { return false; }