diff --git a/progs/fte-server.src b/progs/fte-server.src index 5023726..39758aa 100644 --- a/progs/fte-server.src +++ b/progs/fte-server.src @@ -34,6 +34,7 @@ ../source/server/weapons/frames_core.qc ../source/server/weapons/rocket_launcher.qc ../source/server/weapons/ray_gun.qc +../source/server/weapons/flamethrower.qc ../source/server/weapons/weapon_core.qc ../source/server/entities/powerups.qc diff --git a/progs/standard.src b/progs/standard.src index 34be927..4ddfcbc 100644 --- a/progs/standard.src +++ b/progs/standard.src @@ -38,7 +38,9 @@ ../source/server/weapons/frames_core.qc ../source/server/weapons/rocket_launcher.qc ../source/server/weapons/ray_gun.qc +../source/server/weapons/flamethrower.qc ../source/server/weapons/weapon_core.qc + ../source/server/entities/powerups.qc ../source/server/ai/ai_core.qc diff --git a/source/server/weapons/flamethrower.qc b/source/server/weapons/flamethrower.qc new file mode 100644 index 0000000..b31f12e --- /dev/null +++ b/source/server/weapons/flamethrower.qc @@ -0,0 +1,196 @@ +/* + server/weapons/flamethrower.qc + + Core logic for the Ray Gun special weapon. + Modified from Unofficial Patch implementation. + + Copyright (C) 2021-2023 NZ:P Team + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to: + + Free Software Foundation, Inc. + 59 Temple Place - Suite 330 + Boston, MA 02111-1307, USA + + +*/ + +// +// Flame_LingerThink() +// Play particle effect, remove after expire time. +// +void() Flame_LingerThink = +{ + +#ifdef FTE + + te_flamejet(self.origin, v_up*8, 5); + +#else + + particle (self.origin, v_up*8, 0, 0); + +#endif // FTE + + if (self.ltime < time) + remove(self); + + self.nextthink = time + 0.1; +} + +// +// Flame_Linger(org, whodunit) +// Spawns in the lingering Flame particle effects. +// +void(vector org, entity whodunit) Flame_Linger = +{ + entity linger = spawn(); + + setorigin(linger, org); + + linger.owner = whodunit.owner; + linger.think = Flame_LingerThink; + linger.nextthink = time + 0.1; + linger.ltime = time + 5; +} + +// +// Flame_Touch +// Something makes contact with the Flames. +// +void() Flame_Touch = +{ + if (other == world) { + Flame_Linger(self.origin, self); + remove(self); + } else { + if (other.onfire || other.owner.onfire) + return; + if (other.classname == "ai_zombie_head" || other.classname == "ai_zombie_larm" + || other.classname == "ai_zombie_rarm") { + other.owner.onfire = true; + other.owner.ltime = time + 2; + addmoney(self.owner, 10, true); + } else if (other.classname == "ai_zombie" || other.classname == "ai_dog") { + other.onfire = true; + other.firer = self.owner; + other.ltime = time + 2; + addmoney(self.owner, 10, true); + } + } +} + +// +// Flame_DropDissapate() +// Fallen Flame touches a brush, have it linger. +// +void() Flame_DropCatch = +{ + if (other == world) { + Flame_Linger(self.origin + '0 0 5', self); + remove(self); + } +} + +// +// Flame_DropDissapate() +// Droplets did not make it to the ground in time. +// +void() Flame_DropDissapate = +{ + remove(self); +} + +// +// Flame_Drop() +// Some bits of the flame should fall to the ground, and make it +// dangerous to contact. +// +void() Flame_Drop = +{ + entity drop = spawn(); + + drop.owner = self.owner; + + setmodel(drop, "models/sprites/flame.spr"); + setsize(drop, '0 0 0', '0 0 0'); + setorigin(drop, self.origin); + + drop.touch = Flame_DropCatch; + drop.think = Flame_DropDissapate; + drop.nextthink = time + 0.8; + drop.solid = SOLID_TRIGGER; + drop.movetype = MOVETYPE_BOUNCE; + + drop.velocity = v_up*-55; +} + + +// +// Flame_Buildup() +// This is the Flames beginning to combus before falling +// to the ground. +// +void() Flame_Buildup = +{ + self.frame++; + + if (self.frame > 11) { + if (random() > 0.75) + Flame_Drop(); + remove(self); + } + + self.nextthink = time + 0.05; +} + +// +// W_FireFlame() +// Called by weapon_core for the Flamethrower firetype. Sets up the +// beam/missile and prepares it for impact and force forward. +// +void() W_FireFlame = +{ + + entity flamespr; + vector rand_angle; + + flamespr = spawn(); + flamespr.owner = self; + flamespr.movetype = MOVETYPE_FLYMISSILE; + flamespr.solid = SOLID_TRIGGER; + flamespr.classname = "flamethrower_sprite"; + flamespr.state = 0; + flamespr.finaldest = self.v_angle; + + // Randomize the output a tad. + rand_angle = self.v_angle; + rand_angle_x += random()*10; + rand_angle_y += random()*10; + makevectors(rand_angle); + + flamespr.velocity = aim(self, 1000); + flamespr.velocity *= 600; + + flamespr.owner = self; + + flamespr.think = Flame_Buildup; + flamespr.nextthink = time + 0.01; + flamespr.touch = Flame_Touch; + + setmodel(flamespr, "models/sprites/flame.spr"); + setorigin(flamespr, self.origin + self.view_ofs - v_up*10 + v_forward*30); + setsize(flamespr, '0 0 0', '0 0 0'); +} \ No newline at end of file diff --git a/source/server/weapons/weapon_core.qc b/source/server/weapons/weapon_core.qc index 57e97e8..8d65a52 100644 --- a/source/server/weapons/weapon_core.qc +++ b/source/server/weapons/weapon_core.qc @@ -1176,143 +1176,6 @@ void() W_FireTesla = LightningDamage (self.origin, trace_endpos + v_forward*4, self, 30); } -void() Flame_LingerThink = -{ - -#ifdef FTE - - te_flamejet(self.origin, v_up*8, 5); - -#else - - particle (self.origin, v_up*8, 0, 0); - -#endif // FTE - - if (self.ltime < time) - remove(self); - - self.nextthink = time + 0.1; -} - -// spawn linger effect/entity -void(vector org, entity whodunit) Flame_Linger = -{ - local entity linger = spawn(); - - setorigin(linger, org); - - linger.owner = whodunit.owner; - linger.think = Flame_LingerThink; - linger.nextthink = time + 0.1; - linger.ltime = time + 5; -} - -void() Flame_Touch = -{ - if (other == world) { - Flame_Linger(self.origin, self); - remove(self); - } else { - if (other.onfire || other.owner.onfire) - return; - if (other.classname == "ai_zombie_head" || other.classname == "ai_zombie_larm" - || other.classname == "ai_zombie_rarm") { - other.owner.onfire = true; - other.owner.ltime = time + 2; - addmoney(self.owner, 10, true); - } else if (other.classname == "ai_zombie" || other.classname == "ai_dog") { - other.onfire = true; - other.firer = self.owner; - other.ltime = time + 2; - addmoney(self.owner, 10, true); - } - } -} - -// fallen flame touches something -void() Flame_DropCatch = -{ - if (other == world) { - Flame_Linger(self.origin + '0 0 5', self); - remove(self); - } -} - -// drop didn't make it to the ground in time to spread -void() Flame_DropDissapate = -{ - remove(self); -} - -// rare chance some falls -void() Flame_Drop = -{ - local entity drop = spawn(); - - drop.owner = self.owner; - - setmodel(drop, "models/sprites/flame.spr"); - setsize(drop, '0 0 0', '0 0 0'); - setorigin(drop, self.origin); - - drop.touch = Flame_DropCatch; - drop.think = Flame_DropDissapate; - drop.nextthink = time + 0.8; - drop.solid = SOLID_TRIGGER; - drop.movetype = MOVETYPE_BOUNCE; - - drop.velocity = v_up*-55; -} - -// increase frames, remove/drop -void() Flame_Buildup = -{ - self.frame++; - - if (self.frame > 11) { - if (random() > 0.75) - Flame_Drop(); - remove(self); - } - - self.nextthink = time + 0.05; -} - -void() W_FireM2 = -{ - - local entity flamespr; - local vector rand_angle; - - flamespr = spawn(); - flamespr.owner = self; - flamespr.movetype = MOVETYPE_FLYMISSILE; - flamespr.solid = SOLID_TRIGGER; - flamespr.classname = "flamethrower_sprite"; - flamespr.state = 0; - flamespr.finaldest = self.v_angle; - - // calc some randomness - rand_angle = self.v_angle; - rand_angle_x += random()*10; - rand_angle_y += random()*10; - - makevectors(rand_angle); - flamespr.velocity = aim(self, 1000); - flamespr.velocity *= 600; - - flamespr.owner = self; - - flamespr.think = Flame_Buildup; - flamespr.nextthink = time + 0.01; - flamespr.touch = Flame_Touch; - - setmodel(flamespr, "models/sprites/flame.spr"); - setorigin(flamespr, self.origin + self.view_ofs - '0 0 10'); - setsize(flamespr, '0 0 0', '0 0 0'); -} - void(float side) W_Fire = { if (self.weapon == W_M2 || self.weapon == W_FIW && self.cooldown) @@ -1462,7 +1325,7 @@ void(float side) W_Fire = W_FireTesla(); break; case FIRETYPE_FLAME: - W_FireM2(); + W_FireFlame(); break; default: break; }