From d946ebb74d976b7eed684cceb128c8bc596e505f Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Tue, 29 Nov 2022 14:22:16 +0100 Subject: [PATCH] - added Projectile base class. Not hooked up yet, this only defines the framework for what comes. --- wadsrc/static/zscript.txt | 1 + .../zscript/games/duke/actors/projectiles.zs | 161 ++++++++++++++++++ 2 files changed, 162 insertions(+) create mode 100644 wadsrc/static/zscript/games/duke/actors/projectiles.zs diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index 79d435830..c98c883f9 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -59,6 +59,7 @@ version "4.10" #include "zscript/games/duke/actors/respawnmarker.zs" #include "zscript/games/duke/actors/bloodsplats.zs" +#include "zscript/games/duke/actors/projectiles.zs" #include "zscript/games/duke/actors/rat.zs" #include "zscript/games/duke/actors/jibs.zs" #include "zscript/games/duke/actors/crane.zs" diff --git a/wadsrc/static/zscript/games/duke/actors/projectiles.zs b/wadsrc/static/zscript/games/duke/actors/projectiles.zs new file mode 100644 index 000000000..f614b9ba1 --- /dev/null +++ b/wadsrc/static/zscript/games/duke/actors/projectiles.zs @@ -0,0 +1,161 @@ +// Note: Duke's handling is dumb enough to make it impossible for other actors than the predefined projectile type to be used as projectile - +// even if it is given the right statnum the projectile code won't get called for it. +// So even in the future any projectile needs to inherit from this to gain the needed feature support. + +class DukeProjectile : DukeActor +{ + default + { + statnum STAT_PROJECTILE; + } + + Vector3 oldpos; // holds the position before the current move + double velx, vely; // holds the actual velocity for the current move. This can differ from the actor's internal values. + Sound SpawnSound; + + // this large batch of subsequently called virtuals is owed to the spaghetti-like implementation of the orignal moveprojectiles function. + + virtual bool premoveeffect() + { + return false; + } + + virtual bool postmoveeffect(CollisionData coll) + { + if (coll.type != kHitSprite) + { + if (self.pos.Z < self.ceilingz) + { + coll.setSector(self.sector); + self.vel.Z -= 1/256.; + } + else if ((self.pos.Z > self.floorz && self.sector.lotag != ST_1_ABOVE_WATER) || + (self.pos.Z > self.floorz + 16 && self.sector.lotag == ST_1_ABOVE_WATER)) + { + coll.setSector(self.sector); + if (self.sector.lotag != ST_1_ABOVE_WATER) + self.vel.Z += 1/256.; + } + } + return false; + } + + virtual bool weaponhitsprite_pre(DukeActor targ) + { + targ.checkhitsprite(self); + return false; + } + + virtual bool weaponhitplayer(DukeActor targ) + { + targ.PlayActorSound("PISTOL_BODYHIT"); + return false; + } + + protected bool weaponhitsprite(DukeActor targ) + { + if (self.weaponhitsprite_pre(targ)) return true; + return self.weaponhitplayer(targ); + } + + virtual bool weaponhitwall(walltype wal) + { + if (self.actorflag2(SFLAG2_MIRRORREFLECT) && dlevel.isMirror(wal)) + { + let k = wal.delta().Angle(); + self.angle = k * 2 - self.angle; + self.ownerActor = self; + self.spawn("DukeTransporterStar"); + return true; + } + else + { + self.SetPosition(oldpos); + dlevel.checkhitwall(wal, self, self.pos); + + if (self.actorflag2(SFLAG2_REFLECTIVE)) + { + if (!dlevel.isMirror(wal)) + { + self.extra >>= 1; + self.yint--; + } + + let k = wal.delta().Angle(); + self.angle = k * 2 - self.angle; + return true; + } + } + return false; + } + + virtual bool weaponhitsector() + { + self.SetPosition(oldpos); + + if (self.vel.Z < 0) + { + if ((self.sector.ceilingstat & CSTAT_SECTOR_SKY) && (self.sector.ceilingpal == 0)) + { + self.Destroy(); + return true; + } + + dlevel.checkhitceiling(self.sector, self); + } + return false; + } + + virtual void posthiteffect(CollisionData coll) + { + self.Destroy(); + } + + override void Tick() + { + double vel = self.vel.X; + double velz = self.vel.Z; + let oldpos = self.pos; + + int p = -1; + + if (self.actorflag2(SFLAG2_UNDERWATERSLOWDOWN) && self.sector.lotag == ST_2_UNDERWATER) + { + vel *= 0.5; + velz *= 0.5; + } + + self.getglobalz(); + if (self.premoveeffect()) return; + + CollisionData coll; + self.movesprite_ex((self.angle.ToVector() * vel, velz), CLIPMASK1, coll); + + if (!self.sector) + { + self.Destroy(); + return; + } + + if (self.postmoveeffect(coll)) return; + + if (coll.type != 0) + { + if (coll.type == kHitSprite) + { + if (self.weaponhitsprite(DukeActor(coll.hitactor()))) return; + } + else if (coll.type == kHitWall) + { + if (weaponhitwall(coll.hitWall())) return; + } + else if (coll.type == kHitSector) + { + if (weaponhitsector()) return; + } + posthiteffect(coll); + } + } +} + +