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
This commit is contained in:
Marco Cawthorne 2020-04-02 22:42:30 +02:00
parent 79ddd3228c
commit 47f8e41185
6 changed files with 204 additions and 53 deletions

View file

@ -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;

View file

@ -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;

View file

@ -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;
}
}

View file

@ -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)

View file

@ -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 */

View file

@ -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,