From 82515e1d760772cab64374cf99c17c1451d847a6 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 29 Nov 2022 20:28:16 +0100 Subject: [PATCH] - scriptified the World Tour's flamethrower#s fireball. Also using a better method to mark the trailing balls than checking the owner. --- source/games/duke/src/actors_d.cpp | 253 ------------------ .../filter/duke.worldtour/engine/engine.def | 6 + .../zscript/games/duke/actors/projectiles.zs | 109 ++++++++ 3 files changed, 115 insertions(+), 253 deletions(-) create mode 100644 wadsrc/static/filter/duke.worldtour/engine/engine.def diff --git a/source/games/duke/src/actors_d.cpp b/source/games/duke/src/actors_d.cpp index 41b4a1b21..dc8e3182f 100644 --- a/source/games/duke/src/actors_d.cpp +++ b/source/games/duke/src/actors_d.cpp @@ -746,253 +746,6 @@ void movestandables_d(void) // //--------------------------------------------------------------------------- -static bool movefireball(DDukeActor* actor) -{ - auto Owner = actor->GetOwner(); - - if (actor->sector()->lotag == 2) - { - actor->Destroy(); - return true; - } - - if (!Owner || Owner->spr.picnum != FIREBALL) - { - if (actor->temp_data[0] >= 1 && actor->temp_data[0] < 6) - { - float siz = 1.0f - (actor->temp_data[0] * 0.2f); - DDukeActor* trail = actor->temp_actor; - auto ball = spawn(actor, FIREBALL); - if (ball) - { - actor->temp_actor = ball; - - ball->vel.X = actor->vel.X; - ball->vel.Z = actor->vel.Z; - if (actor->temp_data[0] > 1) - { - if (trail) - { - ball->spr.pos = trail->temp_pos; - ball->vel = trail->temp_pos2; - } - } - double scale = actor->spr.scale.X * siz; - ball->spr.scale = DVector2(scale, scale); - ball->spr.cstat = actor->spr.cstat; - ball->spr.extra = 0; - - ball->temp_pos = ball->spr.pos; - ball->temp_pos2 = ball->vel; - - ChangeActorStat(ball, STAT_PROJECTILE); - } - } - actor->temp_data[0]++; - } - if (actor->vel.Z < 15000. / 256.) - actor->vel.Z += 200 / 256.; - return false; -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -static bool weaponhitsprite(DDukeActor* proj, DDukeActor *targ, bool fireball) -{ - if (!isWorldTour() || proj->spr.picnum != FIREBALL || fireball) - fi.checkhitsprite(targ, proj); - - if (targ->isPlayer()) - { - int p = targ->spr.yint; - auto Owner = proj->GetOwner(); - - if (ud.multimode >= 2 && fireball && Owner && Owner->isPlayer()) - { - ps[p].numloogs = -1 - proj->spr.yint; - } - - S_PlayActorSound(PISTOL_BODYHIT, targ); - - } - return false; -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -static bool weaponhitwall(DDukeActor *proj, walltype* wal, const DVector3 &oldpos) -{ - if (proj->spr.picnum != RPG && proj->spr.picnum != FREEZEBLAST && proj->spr.picnum != SPIT && - (!isWorldTour() || proj->spr.picnum != FIREBALL) && - (wal->overpicnum == MIRROR || wal->picnum == MIRROR)) - { - DAngle k = wal->delta().Angle(); - proj->spr.Angles.Yaw = k * 2 - proj->spr.Angles.Yaw; - proj->SetOwner(proj); - spawn(proj, TRANSPORTERSTAR); - return true; - } - else - { - SetActor(proj, oldpos); - fi.checkhitwall(proj, wal, proj->spr.pos, proj->spr.picnum); - } - return false; -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -static bool weaponhitsector(DDukeActor* proj, const DVector3& oldpos, bool fireball) -{ - SetActor(proj, oldpos); - - if (proj->vel.Z < 0) - { - if (proj->sector()->ceilingstat & CSTAT_SECTOR_SKY) - if (proj->sector()->ceilingpal == 0) - { - proj->Destroy(); - return true; - } - - fi.checkhitceiling(proj->sector()); - } - else if (fireball) - { - auto spawned = spawn(proj, LAVAPOOL); - if (spawned) - { - spawned->SetOwner(proj); - spawned->SetHitOwner(proj); - spawned->spr.yint = proj->spr.yint; - } - proj->Destroy(); - return true; - } - return false; -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -static void weaponcommon_d(DDukeActor* proj) -{ - double vel = proj->vel.X; - double velz = proj->vel.Z; - - int p = -1; - - auto oldpos = proj->spr.pos; - getglobalz(proj); - - switch (proj->spr.picnum) - { - case FIREBALL: - if (movefireball(proj)) return; - break; - } - - Collision coll; - movesprite_ex(proj, DVector3(proj->spr.Angles.Yaw.ToVector() * vel, velz), CLIPMASK1, coll); - - - if (!proj->insector()) - { - proj->Destroy(); - return; - } - - if (coll.type != kHitSprite && proj->spr.picnum != FREEZEBLAST) - { - if (proj->spr.pos.Z < proj->ceilingz) - { - coll.setSector(proj->sector()); - proj->vel.Z -= 1/256.; - } - else - if ((proj->spr.pos.Z > proj->floorz && proj->sector()->lotag != 1) || - (proj->spr.pos.Z > proj->floorz + 16 && proj->sector()->lotag == 1)) - { - coll.setSector(proj->sector()); - if (proj->sector()->lotag != 1) - proj->vel.Z += 1/256.; - } - } - - if (coll.type != 0) - { - bool fireball = (isWorldTour() && proj->spr.picnum == FIREBALL && (!proj->GetOwner() || proj->GetOwner()->spr.picnum != FIREBALL)); - - if (coll.type == kHitSprite) - { - if (weaponhitsprite(proj, coll.actor(), fireball)) return; - } - else if (coll.type == kHitWall) - { - if (weaponhitwall(proj, coll.hitWall, oldpos)) return; - } - else if (coll.type == kHitSector) - { - if (weaponhitsector(proj, oldpos, fireball)) return; - } - - if (proj->spr.picnum != SPIT) - { - if (proj->spr.picnum != COOLEXPLOSION1 && proj->spr.picnum != FREEZEBLAST && (!isWorldTour() || proj->spr.picnum != FIREBALL)) - { - auto spawned = spawn(proj, EXPLOSION2); - if (spawned) - { - auto scale = proj->spr.scale.X * 0.5; - spawned->spr.scale = DVector2(scale,scale); - if (coll.type == kHitSector) - { - if (proj->vel.Z < 0) - { - spawned->spr.cstat |= CSTAT_SPRITE_YFLIP; - spawned->spr.pos.Z += 72; - } - } - } - } - if (fireball) - { - auto spawned = spawn(proj, EXPLOSION2); - if (spawned) - { - auto scale = proj->spr.scale.X * 0.5; - spawned->spr.scale = DVector2(scale,scale); - } - } - } - if (proj->spr.picnum != COOLEXPLOSION1) - { - proj->Destroy(); - return; - } - } -} -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - void moveweapons_d(void) { DukeStatIterator it(STAT_PROJECTILE); @@ -1012,12 +765,6 @@ void moveweapons_d(void) switch(act->spr.picnum) { - case FIREBALL: - // Twentieth Anniversary World Tour - if (act->spr.picnum == FIREBALL && !isWorldTour()) break; - weaponcommon_d(act); - break; - case SHOTSPARK1: { double x; diff --git a/wadsrc/static/filter/duke.worldtour/engine/engine.def b/wadsrc/static/filter/duke.worldtour/engine/engine.def new file mode 100644 index 000000000..5405507b4 --- /dev/null +++ b/wadsrc/static/filter/duke.worldtour/engine/engine.def @@ -0,0 +1,6 @@ + +spawnclasses +{ + 5163 = DukeFireball +} + diff --git a/wadsrc/static/zscript/games/duke/actors/projectiles.zs b/wadsrc/static/zscript/games/duke/actors/projectiles.zs index 6aa743a14..7eda30cd3 100644 --- a/wadsrc/static/zscript/games/duke/actors/projectiles.zs +++ b/wadsrc/static/zscript/games/duke/actors/projectiles.zs @@ -583,3 +583,112 @@ class DukeCoolExplosion1 : DukeProjectile // octabrain shot. } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class DukeFireball : DukeProjectile // WorldTour only +{ + default + { + pic "FIREBALL"; + } + + override bool premoveeffect() + { + let Owner = self.ownerActor; + + if (self.sector.lotag == 2) + { + self.Destroy(); + return true; + } + + if (self.detail != 1) + { + if (self.temp_data[0] >= 1 && self.temp_data[0] < 6) + { + double siz = 1.0 - (self.temp_data[0] * 0.2); + DukeActor trail = self.temp_actor; + let ball = self.spawn('DukeFireball'); + if (ball) + { + self.temp_actor = ball; + + ball.vel.X = self.vel.X; + ball.vel.Z = self.vel.Z; + ball.angle = self.angle; + if (self.temp_data[0] > 1) + { + if (trail) + { + ball.pos = trail.temp_pos; + ball.vel = trail.temp_pos2; + } + } + double scale = self.scale.X * siz; + ball.scale = (scale, scale); + ball.cstat = self.cstat; + ball.extra = 0; + + ball.temp_pos = ball.pos; + ball.temp_pos2 = ball.vel; + ball.detail = 1; + + ball.ChangeStat(STAT_PROJECTILE); + } + } + self.temp_data[0]++; + } + if (self.vel.Z < 15000. / 256.) + self.vel.Z += 200 / 256.; + return false; + } + + override bool weaponhitsprite_pre(DukeActor targ) + { + if (self.detail != 1) + return super.weaponhitsprite_pre(targ); + return false; + } + + override bool weaponhitplayer(DukeActor targ) + { + let p = targ.GetPlayer(); + let Owner = self.ownerActor; + + if (p && ud.multimode >= 2 && Owner && Owner.isPlayer()) + { + p.numloogs = -1 - self.yint; + } + return Super.weaponhitplayer(targ); + } + + override bool weaponhitsector() + { + if (super.weaponhitsector()) return true; + if (self.detail != 1) + { + let spawned = self.spawn('DukeLavapool'); + if (spawned) + { + spawned.ownerActor = self; + spawned.hitOwnerActor = self; + spawned.yint = self.yint; + } + self.Destroy(); + return true; + } + return false; + } + + override bool animate(tspritetype tspr) + { + tspr.shade = -127; + return true; + } + +} +