diff --git a/wadsrc/static/zscript.txt b/wadsrc/static/zscript.txt index f500f3490..820ac19a1 100644 --- a/wadsrc/static/zscript.txt +++ b/wadsrc/static/zscript.txt @@ -61,10 +61,8 @@ version "4.10" #include "zscript/games/duke/actors/_placeholders.zs" #include "zscript/games/duke/actors/projectiles.zs" -#include "zscript/games/duke/actors/mortar.zs" #include "zscript/games/duke/actors/recon.zs" #include "zscript/games/duke/actors/greenslime.zs" -#include "zscript/games/duke/actors/heavyhbomb.zs" #include "zscript/games/duke/actors/burning.zs" #include "zscript/games/duke/actors/dukedecos.zs" @@ -161,6 +159,18 @@ version "4.10" #include "zscript/games/duke/actors/dukestuff/rubbercan.zs" #include "zscript/games/duke/actors/dukestuff/stuff.zs" +#include "zscript/games/duke/actors/dukeweapons/projectilebase.zs" +#include "zscript/games/duke/actors/dukeweapons/freezer.zs" +#include "zscript/games/duke/actors/dukeweapons/grower.zs" +#include "zscript/games/duke/actors/dukeweapons/heavyhbomb.zs" +#include "zscript/games/duke/actors/dukeweapons/hitscan.zs" +#include "zscript/games/duke/actors/dukeweapons/melee.zs" +#include "zscript/games/duke/actors/dukeweapons/mortar.zs" +#include "zscript/games/duke/actors/dukeweapons/projectiles.zs" +#include "zscript/games/duke/actors/dukeweapons/rpg.zs" +#include "zscript/games/duke/actors/dukeweapons/shrinker.zs" +#include "zscript/games/duke/actors/dukeweapons/tripbomb.zs" + #include "zscript/games/duke/actors/redneckcstuff/airplane.zs" #include "zscript/games/duke/actors/redneckcstuff/balloons.zs" #include "zscript/games/duke/actors/redneckcstuff/bowling.zs" @@ -174,14 +184,6 @@ version "4.10" #include "zscript/games/duke/actors/redneckcstuff/rrcactus.zs" #include "zscript/games/duke/actors/redneckcstuff/rrteleport.zs" -#include "zscript/games/duke/actors/dukeweapons/melee.zs" -#include "zscript/games/duke/actors/dukeweapons/hitscan.zs" -#include "zscript/games/duke/actors/dukeweapons/projectiles.zs" -#include "zscript/games/duke/actors/dukeweapons/shrinker.zs" -#include "zscript/games/duke/actors/dukeweapons/grower.zs" -#include "zscript/games/duke/actors/dukeweapons/tripbomb.zs" -#include "zscript/games/duke/actors/dukeweapons/freezer.zs" -#include "zscript/games/duke/actors/dukeweapons/rpg.zs" #include "zscript/games/duke/actors/redneckweapons/crossbow.zs" #include "zscript/games/duke/actors/redneckweapons/boatcannon.zs" diff --git a/wadsrc/static/zscript/games/duke/actors/_placeholders.zs b/wadsrc/static/zscript/games/duke/actors/_placeholders.zs index 02733060b..745a05963 100644 --- a/wadsrc/static/zscript/games/duke/actors/_placeholders.zs +++ b/wadsrc/static/zscript/games/duke/actors/_placeholders.zs @@ -1,16 +1,3 @@ -class DukeRadiusExplosion : DukeActor -{ - default - { - pic "RADIUSEXPLOSION"; - +INFLAME; - +DIENOW; - +EXPLOSIVE; - +DOUBLEDMGTHRUST; - +BREAKMIRRORS; - } -} - class DukeSectorEffector : DukeActor { //This never gets ticked, the handler goes directly to the native implementations. diff --git a/wadsrc/static/zscript/games/duke/actors/dukeweapons/freezer.zs b/wadsrc/static/zscript/games/duke/actors/dukeweapons/freezer.zs index 754e89648..826d257e3 100644 --- a/wadsrc/static/zscript/games/duke/actors/dukeweapons/freezer.zs +++ b/wadsrc/static/zscript/games/duke/actors/dukeweapons/freezer.zs @@ -9,6 +9,7 @@ class DukeFreezeBlast : DukeProjectile default { pic "FREEZEBLAST"; + Strength FREEZETHROWER_WEAPON_STRENGTH; +FULLBRIGHT; +FREEZEDAMAGE; +REFLECTIVE; diff --git a/wadsrc/static/zscript/games/duke/actors/dukeweapons/grower.zs b/wadsrc/static/zscript/games/duke/actors/dukeweapons/grower.zs index c565e60e3..4acd23832 100644 --- a/wadsrc/static/zscript/games/duke/actors/dukeweapons/grower.zs +++ b/wadsrc/static/zscript/games/duke/actors/dukeweapons/grower.zs @@ -4,6 +4,7 @@ class DukeGrowSpark : DukeActor default { spriteset "GROWSPARK", "GROWSPARK1", "GROWSPARK2", "GROWSPARK3"; + Strength GROWSPARK_WEAPON_STRENGTH; +FULLBRIGHT; +NOFLOORPAL; } @@ -85,4 +86,3 @@ class DukeGrowSpark : DukeActor return true; } } - diff --git a/wadsrc/static/zscript/games/duke/actors/heavyhbomb.zs b/wadsrc/static/zscript/games/duke/actors/dukeweapons/heavyhbomb.zs similarity index 99% rename from wadsrc/static/zscript/games/duke/actors/heavyhbomb.zs rename to wadsrc/static/zscript/games/duke/actors/dukeweapons/heavyhbomb.zs index 51da8311c..6572a7a59 100644 --- a/wadsrc/static/zscript/games/duke/actors/heavyhbomb.zs +++ b/wadsrc/static/zscript/games/duke/actors/dukeweapons/heavyhbomb.zs @@ -4,6 +4,7 @@ class DukePipeBomb : DukeActor default { pic "HEAVYHBOMB"; + Strength HANDBOMB_WEAPON_STRENGTH; +INFLAME; +EXPLOSIVE; +DOUBLEDMGTHRUST; diff --git a/wadsrc/static/zscript/games/duke/actors/dukeweapons/hitscan.zs b/wadsrc/static/zscript/games/duke/actors/dukeweapons/hitscan.zs index 866ac0a91..600f2144c 100644 --- a/wadsrc/static/zscript/games/duke/actors/dukeweapons/hitscan.zs +++ b/wadsrc/static/zscript/games/duke/actors/dukeweapons/hitscan.zs @@ -284,12 +284,14 @@ class DukeShotSpark : DukeActor +FORCERUNCON; +LIGHTDAMAGE; statnum STAT_MISC; + Strength PISTOL_WEAPON_STRENGTH; } override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) { return HitscanAttack(actor, p, pos, ang, 5.625, 4, 11.25, false); } + } class DukeShotgunShot : DukeActor @@ -297,6 +299,7 @@ class DukeShotgunShot : DukeActor default { pic "SHOTGUN"; + Strength SHOTGUN_WEAPON_STRENGTH; } override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) @@ -310,6 +313,7 @@ class DukeChaingunShot : DukeActor default { pic "CHAINGUN"; + Strength CHAINGUN_WEAPON_STRENGTH; } override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) @@ -321,6 +325,11 @@ class DukeChaingunShot : DukeActor // RR' damage properties are a bit different. class RedneckShotSpark : DukeShotSpark { + default + { + Strength CASUL_WEAPON_STRENGTH; + } + override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) { return HitscanAttack(actor, p, pos, ang, 5.625, 4, 11.25, false); @@ -339,6 +348,10 @@ class RedneckShotgunShot : DukeShotgunShot class RedneckChaingunShot : DukeChaingunShot { + default + { + Strength RIFLE_WEAPON_STRENGTH; + } override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) { return HitscanAttack(actor, p, pos, ang, 5.625, 4, 11.25, true); diff --git a/wadsrc/static/zscript/games/duke/actors/dukeweapons/melee.zs b/wadsrc/static/zscript/games/duke/actors/dukeweapons/melee.zs index cd892f80e..0823f84a9 100644 --- a/wadsrc/static/zscript/games/duke/actors/dukeweapons/melee.zs +++ b/wadsrc/static/zscript/games/duke/actors/dukeweapons/melee.zs @@ -10,6 +10,7 @@ class DukeMeleeAttack : DukeActor pic "KNEE"; +DIENOW; DukeMeleeAttack.extradamage 0; + Strength KNEE_WEAPON_STRENGTH; DukeMeleeAttack.attacksound "KICK_HIT"; } @@ -131,6 +132,7 @@ class RedneckBuzzSaw : DukeMeleeAttack default { pic "BUZSAW"; + Strength BUZSAW_WEAPON_STRENGTH; } } @@ -141,6 +143,7 @@ class RedneckSlingbladeAttack : DukeMeleeAttack pic "SLINGBLADE"; DukeMeleeAttack.extradamage 50; // extra attack power. DukeMeleeAttack.attacksound "SLINGHIT"; + Strength SLINGBLADE_WEAPON_STRENGTH; } } diff --git a/wadsrc/static/zscript/games/duke/actors/mortar.zs b/wadsrc/static/zscript/games/duke/actors/dukeweapons/mortar.zs similarity index 98% rename from wadsrc/static/zscript/games/duke/actors/mortar.zs rename to wadsrc/static/zscript/games/duke/actors/dukeweapons/mortar.zs index 1c7025d19..d1af75290 100644 --- a/wadsrc/static/zscript/games/duke/actors/mortar.zs +++ b/wadsrc/static/zscript/games/duke/actors/dukeweapons/mortar.zs @@ -3,6 +3,8 @@ class DukeMortar : DukeActor default { pic "MORTER"; + Strength MORTER_WEAPON_STRENGTH; + DukeMortar.ceilingdist 3; DukeMortar.spawnscale 0.5; +HITRADIUS_DONTHURTSHOOTER; @@ -184,6 +186,7 @@ class DukeBounceMine : DukeMortar default { pic "BOUNCEMINE"; + Strength BOUNCEMINE_WEAPON_STRENGTH; } override void Initialize() diff --git a/wadsrc/static/zscript/games/duke/actors/dukeweapons/projectilebase.zs b/wadsrc/static/zscript/games/duke/actors/dukeweapons/projectilebase.zs new file mode 100644 index 000000000..37dcb6025 --- /dev/null +++ b/wadsrc/static/zscript/games/duke/actors/dukeweapons/projectilebase.zs @@ -0,0 +1,454 @@ +// 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. + +extend class DukeActor +{ + // placed in DukeActor so it remains reusable. + void bounce() + { + Vector3 vect = (self.angle.ToVector() * self.vel.X, self.vel.Z); + let sectp = self.sector; + + double daang = sectp.walls[0].delta().Angle(); + + double k; + if (self.pos.Z < (self.floorz + self.ceilingz) * 0.5) + k = sectp.ceilingheinum; + else + k = sectp.floorheinum; + + Vector3 davec = (sin(daang) * k, -cos(daang) * k, 4096); + + double dotp = vect dot davec; + double l = davec.LengthSquared(); + + vect -= davec * (2 * dotp / l); + + self.vel.Z = vect.Z; + self.vel.X = vect.XY.Length(); + self.angle = vect.Angle(); + } +} + +class DukeProjectile : DukeActor +{ + default + { + statnum STAT_PROJECTILE; + } + + Vector3 oldpos; // holds the position before the current move + meta Sound SpawnSound; + + property SpawnSound: SpawnSound; + + override void Initialize() + { + // do not call the parent's function here. + } + + // 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.OnHit(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; + if (!targ.isPlayer()) return false; + return self.weaponhitplayer(targ); + } + + virtual bool weaponhitwall(walltype wal) + { + if (self.bMIRRORREFLECT && 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.bREFLECTIVE) + { + 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; + oldpos = self.pos; + + int p = -1; + + if (self.bUNDERWATERSLOWDOWN && 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); + } + } +} + + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class DukeFirelaser : DukeProjectile // Liztrooper shot +{ + default + { + spriteset "FIRELASER", "FIRELASER2", "FIRELASER3", "FIRELASER4", "FIRELASER5", "FIRELASER6"; + Strength FIRELASER_WEAPON_STRENGTH; + +INFLAME; + +FULLBRIGHT; + +MIRRORREFLECT; + } + override bool postmoveeffect(CollisionData coll) + { + if (Super.postmoveeffect(coll)) return true; + for (int k = -3; k < 2; k++) + { + double zAdd = k * self.vel.Z / 24; + let spawned = dlevel.SpawnActor(self.sector, self.pos.plusZ(zAdd) + self.angle.ToVector() * k * 2., 'DukeFireLaserTrail', -40 + (k << 2), self.scale, 0, 0., 0., self.ownerActor, STAT_MISC); + + if (spawned) + { + spawned.opos = self.opos - self.pos + spawned.pos; + spawned.cstat = CSTAT_SPRITE_YCENTER; + spawned.pal = self.pal; + } + } + return false; + } + + override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const + { + pos.Z -= 2; + shootprojectile1(actor, p, pos, ang, 52.5, 0); + return true; + } + + +} + +class DukeFirelaserTrail : DukeActor +{ + default + { + spriteset "FIRELASER", "FIRELASER2", "FIRELASER3", "FIRELASER4", "FIRELASER5", "FIRELASER6"; + +FULLBRIGHT; + } + + override void Tick() + { + if (self.extra == 999) + { + self.Destroy(); + } + } + + override bool animate(tspritetype tspr) + { + self.extra = 999; + if (Raze.isRR()) tspr.setSpritePic(self, ((PlayClock >> 2) % 6)); + return true; + } + + +} + +class RedneckFirelaser : DukeFirelaser +{ + default + { + spriteset "FIRELASER", "FIRELASER2", "FIRELASER3", "FIRELASER4", "FIRELASER5", "FIRELASER6"; + Strength FIRELASER_RR_WEAPON_STRENGTH; + } + + override bool animate(tspritetype tspr) + { + tspr.setSpritePic(self, ((PlayClock >> 2) % 6)); + return true; + } + + override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const + { + pos.Z -= 4; + shootprojectile1(actor, p, pos, ang, 52.5, 0, 0.125); + return true; + } + +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class DukeSpit : DukeProjectile +{ + default + { + pic "SPIT"; + Strength SPIT_WEAPON_STRENGTH; + } + + override bool postmoveeffect(CollisionData coll) + { + Super.postmoveeffect(coll); + if (self.vel.Z < 24) + self.vel.Z += gs.gravity - 112 / 256.; + return false; + } + + override bool weaponhitplayer(DukeActor targ) + { + if (Super.weaponhitplayer(targ)) return true; + + let p = targ.GetPlayer(); + + p.addPitch(-14.04); + p.centerview(); + + if (p.loogcnt == 0) + { + if (!p.actor.CheckSoundPlaying("PLAYER_LONGTERM_PAIN")) + p.actor.PlayActorSound("PLAYER_LONGTERM_PAIN"); + + int j = random(3, 7); + p.numloogs = j; + p.loogcnt = 24 * 4; + for (int x = 0; x < j; x++) + { + p.loogie[x].X = random(0, 319); + p.loogie[x].Y = random(0, 199); + } + } + return false; + } + + override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const + { + pos.Z -= 10; + shootprojectile1(actor, p, pos, ang, 292/16., 0); + return true; + } +} + +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + +class DukeCoolExplosion1 : DukeProjectile // octabrain shot. +{ + default + { + spriteset "COOLEXPLOSION1", "COOLEXPLOSION2", "COOLEXPLOSION3", "COOLEXPLOSION4", "COOLEXPLOSION5", + "COOLEXPLOSION6", "COOLEXPLOSION7", "COOLEXPLOSION8", "COOLEXPLOSION9", "COOLEXPLOSION10", + "COOLEXPLOSION11", "COOLEXPLOSION12", "COOLEXPLOSION13", "COOLEXPLOSION14", "COOLEXPLOSION15", + "COOLEXPLOSION16", "COOLEXPLOSION17", "COOLEXPLOSION18", "COOLEXPLOSION19", "COOLEXPLOSION20"; + +FULLBRIGHT; + +MIRRORREFLECT; + +SPECIALINIT; + Strength COOL_EXPLOSION_STRENGTH; + } + + override void Initialize() + { + if (!bSIMPLEINIT) + { + // looks like this case is never used anywhere. + self.cstat = CSTAT_SPRITE_YCENTER | self.randomXFlip(); + self.angle = self.ownerActor.angle; + self.shade = -64; + + double c, f; + [c, f] = self.sector.getSlopes(self.pos.XY); + if (self.pos.Z > f - 12) + self.pos.Z = f - 12; + } + } + + override bool premoveeffect() + { + if (!self.CheckSoundPlaying("WIERDSHOT_FLY")) + self.PlayActorSound("WIERDSHOT_FLY"); + return false; + } + + override bool weaponhitsprite_pre(DukeActor targ) + { + if (!targ.isPlayer()) + { + return true; + } + self.vel.X = self.vel.Z = 0; + return super.weaponhitsprite_pre(targ); + } + + override bool weaponhitwall(walltype wal) + { + self.vel.X = self.vel.Z = 0; + return super.weaponhitwall(wal); + } + + override bool weaponhitsector() + { + self.vel.X = self.vel.Z = 0; + return super.weaponhitsector(); + } + + override void posthiteffect(CollisionData coll) + { + // don't destroy. + } + + override void Tick() + { + Super.Tick(); + if (++self.shade >= 40) + { + self.Destroy(); + } + } + + override bool animate(tspritetype tspr) + { + tspr.setSpritePic(self, clamp((self.shade >> 1), 0, 19)); + return true; + } + + override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const + { + pos.Z -= 10; + let spawned = shootprojectile1(actor, p, pos, ang, 292/16., 0); + if (spawned) + { + spawned.shade = 0; + // special hack case. + if (actor.bSPECIALINIT) + { + let ovel = spawned.vel.X; + spawned.vel.X = 64; + spawned.DoMove(CLIPMASK0); + spawned.vel.X = ovel; + spawned.Angle += frandom(-22.5, 22.5); + } + } + + return true; + } + +} + diff --git a/wadsrc/static/zscript/games/duke/actors/dukeweapons/projectiles.zs b/wadsrc/static/zscript/games/duke/actors/dukeweapons/projectiles.zs index fa7d2d0ea..db7613463 100644 --- a/wadsrc/static/zscript/games/duke/actors/dukeweapons/projectiles.zs +++ b/wadsrc/static/zscript/games/duke/actors/dukeweapons/projectiles.zs @@ -1,5 +1,36 @@ extend class DukeActor { + const KNEE_WEAPON_STRENGTH = 10; + const PISTOL_WEAPON_STRENGTH = 6; + const HANDBOMB_WEAPON_STRENGTH = 140; + const RPG_WEAPON_STRENGTH = 140; + const SHRINKER_WEAPON_STRENGTH = 0; + const GROWSPARK_WEAPON_STRENGTH = 15; + const SHOTGUN_WEAPON_STRENGTH = 10; + const CHAINGUN_WEAPON_STRENGTH = 9; + const FREEZETHROWER_WEAPON_STRENGTH = 20; + const COOL_EXPLOSION_STRENGTH = 38; + const TRIPBOMB_STRENGTH = 100; + const FIRELASER_WEAPON_STRENGTH = 7; + const MORTER_WEAPON_STRENGTH = 50; + const BOUNCEMINE_WEAPON_STRENGTH = 150; + const SPIT_WEAPON_STRENGTH = 8; + const BULLET_WEAPON_STRENGTH = 30; + + const SLINGBLADE_WEAPON_STRENGTH = 50; + const CASUL_WEAPON_STRENGTH = 20; + const ALIENGISMO_WEAPON_STRENGTH = 15; + const RIFLE_WEAPON_STRENGTH = 20; + const PLASMATHROWER_WEAPON_STRENGTH = 10; + const POWDERKEG_STRENGTH = 100; + const FIRELASER_RR_WEAPON_STRENGTH = 25; + const SHITBALL_WEAPON_STRENGTH = 8; + const BOWLINGBALL_WEAPON_STRENGTH = 5; + const THROWSAW_WEAPON_STRENGTH = 100; + const BUZSAW_WEAPON_STRENGTH = 20; + + + DukeActor shootprojectile1(DukeActor actor, DukePlayer p, Vector3 pos, double ang, double vel, double zofs_post = 0, double scale = 0) const { sectortype sect = actor.sector; @@ -58,3 +89,17 @@ extend class DukeActor return (0, 0, 0); } } + +class DukeRadiusExplosion : DukeActor +{ + default + { + pic "RADIUSEXPLOSION"; + +INFLAME; + +DIENOW; + +EXPLOSIVE; + +DOUBLEDMGTHRUST; + +BREAKMIRRORS; + } +} + diff --git a/wadsrc/static/zscript/games/duke/actors/dukeweapons/rpg.zs b/wadsrc/static/zscript/games/duke/actors/dukeweapons/rpg.zs index c0534d22b..c5ed1dc18 100644 --- a/wadsrc/static/zscript/games/duke/actors/dukeweapons/rpg.zs +++ b/wadsrc/static/zscript/games/duke/actors/dukeweapons/rpg.zs @@ -9,6 +9,7 @@ class DukeRPG : DukeProjectile default { pic "RPG"; + Strength RPG_WEAPON_STRENGTH; +FULLBRIGHT; +INFLAME; +UNDERWATERSLOWDOWN; diff --git a/wadsrc/static/zscript/games/duke/actors/dukeweapons/shrinker.zs b/wadsrc/static/zscript/games/duke/actors/dukeweapons/shrinker.zs index 82292efc5..6dff03f4e 100644 --- a/wadsrc/static/zscript/games/duke/actors/dukeweapons/shrinker.zs +++ b/wadsrc/static/zscript/games/duke/actors/dukeweapons/shrinker.zs @@ -64,6 +64,7 @@ class DukeShrinkSpark : DukeProjectile default { spriteset "SHRINKSPARK", "SHRINKSPARK1", "SHRINKSPARK2", "SHRINKSPARK3"; + Strength SHRINKER_WEAPON_STRENGTH; +FULLBRIGHT; +MIRRORREFLECT; +NOFLOORPAL; diff --git a/wadsrc/static/zscript/games/duke/actors/dukeweapons/tripbomb.zs b/wadsrc/static/zscript/games/duke/actors/dukeweapons/tripbomb.zs index 4ff56b212..17008331c 100644 --- a/wadsrc/static/zscript/games/duke/actors/dukeweapons/tripbomb.zs +++ b/wadsrc/static/zscript/games/duke/actors/dukeweapons/tripbomb.zs @@ -12,7 +12,7 @@ class DukeTripBomb : DukeActor default { pic "TRIPBOMB"; - // Note: The trip bomb has its health defined through CON! Value is 100. Con-based definitions will take precendence. + Strength TRIPBOMB_STRENGTH; strength 100; +CHECKSLEEP; +HITRADIUS_FORCEEFFECT; diff --git a/wadsrc/static/zscript/games/duke/actors/projectiles.zs b/wadsrc/static/zscript/games/duke/actors/projectiles.zs index 28ee63066..8a97c041b 100644 --- a/wadsrc/static/zscript/games/duke/actors/projectiles.zs +++ b/wadsrc/static/zscript/games/duke/actors/projectiles.zs @@ -1,451 +1,3 @@ -// 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. - -extend class DukeActor -{ - // placed in DukeActor so it remains reusable. - void bounce() - { - Vector3 vect = (self.angle.ToVector() * self.vel.X, self.vel.Z); - let sectp = self.sector; - - double daang = sectp.walls[0].delta().Angle(); - - double k; - if (self.pos.Z < (self.floorz + self.ceilingz) * 0.5) - k = sectp.ceilingheinum; - else - k = sectp.floorheinum; - - Vector3 davec = (sin(daang) * k, -cos(daang) * k, 4096); - - double dotp = vect dot davec; - double l = davec.LengthSquared(); - - vect -= davec * (2 * dotp / l); - - self.vel.Z = vect.Z; - self.vel.X = vect.XY.Length(); - self.angle = vect.Angle(); - } -} - -class DukeProjectile : DukeActor -{ - default - { - statnum STAT_PROJECTILE; - } - - Vector3 oldpos; // holds the position before the current move - meta Sound SpawnSound; - - property SpawnSound: SpawnSound; - - override void Initialize() - { - // do not call the parent's function here. - } - // 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.OnHit(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; - if (!targ.isPlayer()) return false; - return self.weaponhitplayer(targ); - } - - virtual bool weaponhitwall(walltype wal) - { - if (self.bMIRRORREFLECT && 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.bREFLECTIVE) - { - 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; - oldpos = self.pos; - - int p = -1; - - if (self.bUNDERWATERSLOWDOWN && 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); - } - } -} - - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class DukeFirelaser : DukeProjectile // Liztrooper shot -{ - default - { - spriteset "FIRELASER", "FIRELASER2", "FIRELASER3", "FIRELASER4", "FIRELASER5", "FIRELASER6"; - +INFLAME; - +FULLBRIGHT; - +MIRRORREFLECT; - } - override bool postmoveeffect(CollisionData coll) - { - if (Super.postmoveeffect(coll)) return true; - for (int k = -3; k < 2; k++) - { - double zAdd = k * self.vel.Z / 24; - let spawned = dlevel.SpawnActor(self.sector, self.pos.plusZ(zAdd) + self.angle.ToVector() * k * 2., 'DukeFireLaserTrail', -40 + (k << 2), self.scale, 0, 0., 0., self.ownerActor, STAT_MISC); - - if (spawned) - { - spawned.opos = self.opos - self.pos + spawned.pos; - spawned.cstat = CSTAT_SPRITE_YCENTER; - spawned.pal = self.pal; - } - } - return false; - } - - override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const - { - pos.Z -= 2; - shootprojectile1(actor, p, pos, ang, 52.5, 0); - return true; - } - - -} - -class DukeFirelaserTrail : DukeActor -{ - default - { - spriteset "FIRELASER", "FIRELASER2", "FIRELASER3", "FIRELASER4", "FIRELASER5", "FIRELASER6"; - +FULLBRIGHT; - } - - override void Tick() - { - if (self.extra == 999) - { - self.Destroy(); - } - } - - override bool animate(tspritetype tspr) - { - self.extra = 999; - if (Raze.isRR()) tspr.setSpritePic(self, ((PlayClock >> 2) % 6)); - return true; - } - - -} - -class RedneckFirelaser : DukeFirelaser -{ - default - { - spriteset "FIRELASER", "FIRELASER2", "FIRELASER3", "FIRELASER4", "FIRELASER5", "FIRELASER6"; - } - - override bool animate(tspritetype tspr) - { - tspr.setSpritePic(self, ((PlayClock >> 2) % 6)); - return true; - } - - override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const - { - pos.Z -= 4; - shootprojectile1(actor, p, pos, ang, 52.5, 0, 0.125); - return true; - } - -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class DukeSpit : DukeProjectile -{ - default - { - pic "SPIT"; - } - - override bool postmoveeffect(CollisionData coll) - { - Super.postmoveeffect(coll); - if (self.vel.Z < 24) - self.vel.Z += gs.gravity - 112 / 256.; - return false; - } - - override bool weaponhitplayer(DukeActor targ) - { - if (Super.weaponhitplayer(targ)) return true; - - let p = targ.GetPlayer(); - - p.addPitch(-14.04); - p.centerview(); - - if (p.loogcnt == 0) - { - if (!p.actor.CheckSoundPlaying("PLAYER_LONGTERM_PAIN")) - p.actor.PlayActorSound("PLAYER_LONGTERM_PAIN"); - - int j = random(3, 7); - p.numloogs = j; - p.loogcnt = 24 * 4; - for (int x = 0; x < j; x++) - { - p.loogie[x].X = random(0, 319); - p.loogie[x].Y = random(0, 199); - } - } - return false; - } - - override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const - { - pos.Z -= 10; - shootprojectile1(actor, p, pos, ang, 292/16., 0); - return true; - } -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -class DukeCoolExplosion1 : DukeProjectile // octabrain shot. -{ - default - { - spriteset "COOLEXPLOSION1", "COOLEXPLOSION2", "COOLEXPLOSION3", "COOLEXPLOSION4", "COOLEXPLOSION5", - "COOLEXPLOSION6", "COOLEXPLOSION7", "COOLEXPLOSION8", "COOLEXPLOSION9", "COOLEXPLOSION10", - "COOLEXPLOSION11", "COOLEXPLOSION12", "COOLEXPLOSION13", "COOLEXPLOSION14", "COOLEXPLOSION15", - "COOLEXPLOSION16", "COOLEXPLOSION17", "COOLEXPLOSION18", "COOLEXPLOSION19", "COOLEXPLOSION20"; - +FULLBRIGHT; - +MIRRORREFLECT; - +SPECIALINIT; - } - - override void Initialize() - { - if (!bSIMPLEINIT) - { - // looks like this case is never used anywhere. - self.cstat = CSTAT_SPRITE_YCENTER | self.randomXFlip(); - self.angle = self.ownerActor.angle; - self.shade = -64; - - double c, f; - [c, f] = self.sector.getSlopes(self.pos.XY); - if (self.pos.Z > f - 12) - self.pos.Z = f - 12; - } - } - - override bool premoveeffect() - { - if (!self.CheckSoundPlaying("WIERDSHOT_FLY")) - self.PlayActorSound("WIERDSHOT_FLY"); - return false; - } - - override bool weaponhitsprite_pre(DukeActor targ) - { - if (!targ.isPlayer()) - { - return true; - } - self.vel.X = self.vel.Z = 0; - return super.weaponhitsprite_pre(targ); - } - - override bool weaponhitwall(walltype wal) - { - self.vel.X = self.vel.Z = 0; - return super.weaponhitwall(wal); - } - - override bool weaponhitsector() - { - self.vel.X = self.vel.Z = 0; - return super.weaponhitsector(); - } - - override void posthiteffect(CollisionData coll) - { - // don't destroy. - } - - override void Tick() - { - Super.Tick(); - if (++self.shade >= 40) - { - self.Destroy(); - } - } - - override bool animate(tspritetype tspr) - { - tspr.setSpritePic(self, clamp((self.shade >> 1), 0, 19)); - return true; - } - - override bool ShootThis(DukeActor actor, DukePlayer p, Vector3 pos, double ang) const - { - pos.Z -= 10; - let spawned = shootprojectile1(actor, p, pos, ang, 292/16., 0); - if (spawned) - { - spawned.shade = 0; - // special hack case. - if (actor.bSPECIALINIT) - { - let ovel = spawned.vel.X; - spawned.vel.X = 64; - spawned.DoMove(CLIPMASK0); - spawned.vel.X = ovel; - spawned.Angle += frandom(-22.5, 22.5); - } - } - - return true; - } - -} //--------------------------------------------------------------------------- //