From 47f8e411858de8f8b0d7124b2066528bd084fe31 Mon Sep 17 00:00:00 2001 From: Marco Hladik Date: Thu, 2 Apr 2020 22:42:30 +0200 Subject: [PATCH] Gearbox: ammo_spore should behave like it is meant to. WEAPON_SPORELAUNCHER got some changes to support its alt-fire and yellow blood decals on impact --- src/gs-entbase/server/baseentity.cpp | 4 + src/gs-entbase/server/infodecal.cpp | 1 - src/server/gearbox/ammo_op4.cpp | 79 +++++++++++-- src/server/valve/ammo.cpp | 1 - src/shared/decals.c | 12 +- src/shared/gearbox/w_sporelauncher.c | 160 +++++++++++++++++++++------ 6 files changed, 204 insertions(+), 53 deletions(-) diff --git a/src/gs-entbase/server/baseentity.cpp b/src/gs-entbase/server/baseentity.cpp index 48fbe4ca..f4900efa 100644 --- a/src/gs-entbase/server/baseentity.cpp +++ b/src/gs-entbase/server/baseentity.cpp @@ -192,6 +192,10 @@ void CBaseEntity::ParentUpdate(void) SendFlags |= BASEFL_CHANGED_EFFECTS; oldnet_effects = effects; } + if (m_iBody != oldnet_body) { + SendFlags |= BASEFL_CHANGED_BODY; + oldnet_body = m_iBody; + } #ifdef GS_RENDERFX if (m_old_iRenderFX != m_iRenderFX) { SendFlags |= BASEFL_CHANGED_RENDERFX; diff --git a/src/gs-entbase/server/infodecal.cpp b/src/gs-entbase/server/infodecal.cpp index a2c3fcca..33923ae7 100644 --- a/src/gs-entbase/server/infodecal.cpp +++ b/src/gs-entbase/server/infodecal.cpp @@ -30,7 +30,6 @@ It will pick the nearest wall (currently checking a distance of 128 units, which is probably overkill). No angle has to be supplied. */ - class infodecal:CBaseTrigger { string m_strTexture; diff --git a/src/server/gearbox/ammo_op4.cpp b/src/server/gearbox/ammo_op4.cpp index 52d91f08..f49af736 100644 --- a/src/server/gearbox/ammo_op4.cpp +++ b/src/server/gearbox/ammo_op4.cpp @@ -84,33 +84,94 @@ HALF-LIFE: OPPOSING FORCE (1999) ENTITY Ammo for the Spore Launcher. A single ammo_spore will provide 1 spore. - -TODO: -It needs to be static (no pickup), and needs to -fire a projectile upon inflicted damage. +The angle key refers to the direction the entity will fire (?) +when shot. The model itself uses decal-like logic to determine +the direction the model is aiming. */ class ammo_spore:item_ammo { void() ammo_spore; virtual void() touch; + virtual void() Respawn; + virtual void(int) Death; }; void ammo_spore::ammo_spore(void) { + movetype = MOVETYPE_NONE; model = "models/spore_ammo.mdl"; item_ammo::item_ammo(); } +void +ammo_spore::Death(int) +{ + makevectors(m_oldAngle); + Sporelauncher_AltFire(this, origin, v_forward); + frame = 2; + m_iBody = 0; + solid = SOLID_NOT; + think = Respawn; + nextthink = time + 10.0f; +} + +void ammo_spore::Respawn(void) +{ + frame = 1; + m_iBody = 2; + movetype = MOVETYPE_NONE; + takedamage = DAMAGE_YES; + health = 1; + + if (m_oldModel) { + setmodel(this, m_oldModel); + } + + solid = SOLID_NOT; + setsize(this, [0,0,0], [0,0,0]); + setorigin(this, m_oldOrigin); + + decal_pickwall(this, m_oldOrigin); + + /* we never hit any wall. */ + if (g_tracedDecal.fraction == 1.0f) { + print(sprintf("^xFA0Warning^7: ammo_spore tracing failed at %v\n", origin)); + return; + } + + origin = g_tracedDecal.endpos; + makevectors(vectoangles(g_tracedDecal.endpos - origin )); + vector cpl = v_forward - (v_forward * g_tracedDecal.normal) * g_tracedDecal.normal; + + if (g_tracedDecal.normal[2] == 0) { + cpl = [0, 0, 1]; + } + angles = vectoangles(cpl, g_tracedDecal.normal); + + solid = SOLID_BBOX; + setsize(this, [-16,-16,-16], [16,16,16]); + think = __NULL__; + nextthink = -1; +} + void ammo_spore::touch(void) { - if (other.classname == "player") { + if not (other.flags & FL_CLIENT) { + return; + } + + player pl = (player)other; + if (pl.ammo_spore < 20) { + pl.ammo_spore = bound(0, pl.ammo_spore + 1, 20); player pl = (player)other; - if (pl.ammo_spore < 20) { - pl.ammo_spore = bound(0, pl.ammo_spore + 1, 20); - item_ammo::touch(); - } + Weapons_RefreshAmmo(pl); + Logging_Pickup(other, this, __NULL__); + frame = 2; + m_iBody = 0; + think = Respawn; + nextthink = time + 10.0f; } } diff --git a/src/server/valve/ammo.cpp b/src/server/valve/ammo.cpp index b66396f4..3d4b3891 100644 --- a/src/server/valve/ammo.cpp +++ b/src/server/valve/ammo.cpp @@ -64,7 +64,6 @@ void item_ammo::item_ammo(void) m_oldModel = model; setmodel(this, m_oldModel); CBaseEntity::CBaseEntity(); - item_ammo::Respawn(); } /*QUAKED ammo_357 (0 0 0.8) (-16 -16 0) (16 16 32) diff --git a/src/shared/decals.c b/src/shared/decals.c index b7500e6e..b1e39194 100644 --- a/src/shared/decals.c +++ b/src/shared/decals.c @@ -123,7 +123,7 @@ decal::Place(vector org, string dname) return; } - makevectors(vectoangles(g_tracedDecal.endpos - self.origin )); + makevectors(vectoangles(g_tracedDecal.endpos - origin )); vector cpl = v_forward - (v_forward * g_tracedDecal.normal) * g_tracedDecal.normal; if (g_tracedDecal.normal[2] == 0) { @@ -134,10 +134,10 @@ decal::Place(vector org, string dname) m_strTexture = dname; #ifdef SSQC - self.angles = vectoangles(cpl, g_tracedDecal.normal); - self.solid = SOLID_NOT; - self.pvsflags = PVSF_NOREMOVE | PVSF_IGNOREPVS; - self.SendFlags = 1; + angles = vectoangles(cpl, g_tracedDecal.normal); + solid = SOLID_NOT; + pvsflags = PVSF_NOREMOVE | PVSF_IGNOREPVS; + SendFlags = 1; #else size = drawgetimagesize(m_strTexture); @@ -189,7 +189,7 @@ void Decals_Init(void) decal Decals_Next(vector pos) { decal ret = g_decals; - g_decals = g_decals.owner; + g_decals = (decal)g_decals.owner; /* Check for a tempdecal within a radius of 8 units and overwrite that one * instead */ diff --git a/src/shared/gearbox/w_sporelauncher.c b/src/shared/gearbox/w_sporelauncher.c index 7e407eee..fd05d374 100644 --- a/src/shared/gearbox/w_sporelauncher.c +++ b/src/shared/gearbox/w_sporelauncher.c @@ -35,6 +35,98 @@ enum SLSTATE_RELOAD_END }; +#ifdef SSQC +void Sporelauncher_Fire(entity spawner, vector org, vector dir) +{ + static void Spore_Touch(void) { + int r; + string hitsnd; + + if (other.takedamage == DAMAGE_YES) { + Damage_Apply(other, self.owner, 50, WEAPON_SPORELAUNCHER, DMG_GENERIC); + } else { + Decals_Place(self.origin, sprintf("{yblood%d", floor(random(1,7)))); + } + + r = floor(random(0,3)); + hitsnd = "weapons/spore_hit1.wav"; + switch (r) { + case 0: + hitsnd = "weapons/spore_hit2.wav"; + break; + case 1: + hitsnd = "weapons/spore_hit3.wav"; + break; + } + sound(self, CHAN_BODY, hitsnd, 1.0f, ATTN_NORM); + remove(self); + } + + entity blob = spawn(); + setmodel(blob, "models/spore.mdl"); + blob.owner = spawner; + blob.velocity = dir * 2000; + blob.movetype = MOVETYPE_BOUNCE; + blob.solid = SOLID_BBOX; + //bolt.flags |= FL_LAGGEDMOVE; + blob.gravity = 0.5f; + blob.angles = vectoangles(blob.velocity); + blob.avelocity[2] = 10; + blob.touch = Spore_Touch; + setsize(blob, [0,0,0], [0,0,0]); + setorigin(blob, org); + + sound(spawner, CHAN_WEAPON, "weapons/splauncher_fire.wav", 1, ATTN_NORM); +} +void Sporelauncher_AltFire(entity spawner, vector org, vector dir) +{ + static void Spore_Explode(void) { + int r; + string hitsnd; + + Damage_Radius(self.origin, self.owner, 100, 256, 1, WEAPON_SPORELAUNCHER); + r = floor(random(0,3)); + hitsnd = "weapons/spore_hit1.wav"; + switch (r) { + case 0: + hitsnd = "weapons/spore_hit2.wav"; + break; + case 1: + hitsnd = "weapons/spore_hit3.wav"; + break; + } + sound(self, CHAN_BODY, hitsnd, 1.0f, ATTN_NORM); + remove(self); + } + static void Spore_Touch(void) { + Decals_Place(self.origin, sprintf("{yblood%d", floor(random(1,7)))); + if (other.takedamage == DAMAGE_YES) { + Spore_Explode(); + } else if (self.think == __NULL__) { + self.think = Spore_Explode; + self.nextthink = time + 2.0f; + } + self.velocity *= 0.5f; + } + + entity blob = spawn(); + setmodel(blob, "models/spore.mdl"); + blob.owner = spawner; + blob.velocity = dir * 2000; + blob.movetype = MOVETYPE_BOUNCE; + blob.solid = SOLID_BBOX; + //bolt.flags |= FL_LAGGEDMOVE; + blob.gravity = 0.5f; + blob.angles = vectoangles(blob.velocity); + blob.avelocity[2] = 10; + blob.touch = Spore_Touch; + setsize(blob, [0,0,0], [0,0,0]); + setorigin(blob, org); + + sound(spawner, CHAN_WEAPON, "weapons/splauncher_fire.wav", 1, ATTN_NORM); +} +#endif + void w_sporelauncher_precache(void) { @@ -126,51 +218,47 @@ w_sporelauncher_primary(void) } #ifdef SSQC - static void Spore_Touch(void) { - int r; - string hitsnd; - - if (other.takedamage == DAMAGE_YES) { - Damage_Apply(other, self.owner, 50, WEAPON_SPORELAUNCHER, DMG_GENERIC); - } - - r = floor(random(0,3)); - hitsnd = "weapons/spore_hit1.wav"; - switch (r) { - case 0: - hitsnd = "weapons/spore_hit2.wav"; - break; - case 1: - hitsnd = "weapons/spore_hit3.wav"; - break; - } - sound(self, CHAN_BODY, hitsnd, 1.0f, ATTN_NORM); - remove(self); + if (pl.sporelauncher_mag <= 0) { + return; } + Weapons_MakeVectors(); + Sporelauncher_Fire(self, Weapons_GetCameraPos() + (v_forward * 16), v_forward); + + pl.sporelauncher_mag--; + Weapons_UpdateAmmo(pl, pl.sporelauncher_mag, pl.ammo_spore, -1); +#else + if (pl.a_ammo1 <= 0) { + return; + } + + Weapons_ViewPunchAngle([-2,0,0]); + Weapons_ViewAnimation(SPORE_FIRE); +#endif + + pl.w_attack_next = 0.75f; + pl.w_idle_next = 10.0f; +} + +void +w_sporelauncher_secondary(void) +{ + player pl = (player)self; + + if (pl.w_attack_next > 0.0) { + return; + } + +#ifdef SSQC if (pl.sporelauncher_mag <= 0) { return; } Weapons_MakeVectors(); - entity blob = spawn(); - setmodel(blob, "models/spore.mdl"); - setorigin(blob, Weapons_GetCameraPos() + (v_forward * 16)); - blob.owner = self; - blob.velocity = v_forward * 2000; - blob.movetype = MOVETYPE_BOUNCE; - blob.solid = SOLID_BBOX; - //bolt.flags |= FL_LAGGEDMOVE; - blob.gravity = 0.5f; - blob.angles = vectoangles(blob.velocity); - blob.avelocity[2] = 10; - blob.touch = Spore_Touch; - blob.weapon = pl.viewzoom == 1.0 ? 1 : 0; - setsize(blob, [0,0,0], [0,0,0]); + Sporelauncher_AltFire(self, Weapons_GetCameraPos() + (v_forward * 16), v_forward); pl.sporelauncher_mag--; Weapons_UpdateAmmo(pl, pl.sporelauncher_mag, pl.ammo_spore, -1); - sound(self, CHAN_WEAPON, "weapons/splauncher_fire.wav", 1, ATTN_NORM); #else if (pl.a_ammo1 <= 0) { return; @@ -354,7 +442,7 @@ weapon_t w_sporelauncher = .draw = w_sporelauncher_draw, .holster = w_sporelauncher_holster, .primary = w_sporelauncher_primary, - .secondary = w_sporelauncher_primary, + .secondary = w_sporelauncher_secondary, .reload = w_sporelauncher_reload, .release = w_sporelauncher_release, .crosshair = w_sporelauncher_crosshair,