Add support for func_breakable its spawnobject key.

This commit is contained in:
Marco Cawthorne 2020-05-30 14:57:01 +02:00
parent c036ccc318
commit fcb99ad427
8 changed files with 100 additions and 26 deletions

View file

@ -70,11 +70,44 @@ enum
BREAKMT_NONE
};
#ifdef VALVE
const string funcbreakable_objtable[22] = {
"",
"spawnfunc_item_battery",
"spawnfunc_item_healthkit",
"weapon_9mmhandgun",
"weapon_9mmclip",
"weapon_9mmAR",
"spawnfunc_ammo_9mmAR",
"spawnfunc_ammo_ARgrenades",
"weapon_shotgun",
"spawnfunc_ammo_buckshot",
"weapon_crossbow",
"spawnfunc_ammo_crossbow",
"weapon_357",
"spawnfunc_ammo_357",
"weapon_rpg",
"spawnfunc_ammo_rpgclip",
"spawnfunc_ammo_gaussclip",
"weapon_hegrenade",
"weapon_tripmine",
"weapon_satchel",
"weapon_snark",
"weapon_hornetgun"
};
#else
const string funcbreakable_objtable[] = {
""
};
#endif
class func_breakable:CBaseTrigger
{
float m_iMaterial;
float m_flDelay;
float m_flExplodeMag;
string m_strBreakSpawn;
/*entity m_pressAttacker;
int m_pressType;
int m_pressDamage;*/
@ -128,25 +161,49 @@ void func_breakable::Pain (int body)
void func_breakable::Explode(void)
{
vector vWorldPos;
vWorldPos[0] = absmin[0] + (0.5 * (absmax[0] - absmin[0]));
vWorldPos[1] = absmin[1] + (0.5 * (absmax[1] - absmin[1]));
vWorldPos[2] = absmin[2] + (0.5 * (absmax[2] - absmin[2]));
vector rp = absmin + (0.5 * (absmax - absmin));
FX_BreakModel(vlen(size) / 10, absmin, absmax, [0,0,0], m_iMaterial);
FX_Explosion(vWorldPos);
Damage_Radius(vWorldPos, this, m_flExplodeMag, m_flExplodeMag * 2.5f, TRUE, 0);
FX_Explosion(rp);
Damage_Radius(rp, this, m_flExplodeMag, m_flExplodeMag * 2.5f, TRUE, 0);
CBaseTrigger::UseTargets();
CBaseEntity::Hide();
}
void func_breakable::Death(int body)
{
static void break_spawnobject(void) {
/* these might get overwritten by the entity spawnfunction */
vector neworg = self.origin;
/* become the classname assigned */
CBaseEntity t = (CBaseEntity)self;
callfunction(self.classname);
/* apply the saved values back */
t.origin = t.m_oldOrigin = neworg;
/* spawn anew */
if (t.Respawn)
t.Respawn();
}
if (m_iMaterial == BREAKMT_GLASS_UNBREAKABLE) {
return;
}
health = 0;
eActivator = g_eAttacker;
if (m_strBreakSpawn != "" && isfunction(m_strBreakSpawn)) {
entity unit = spawn();
unit.classname = m_strBreakSpawn;
unit.think = break_spawnobject;
unit.nextthink = time;
unit.real_owner = this;
setorigin(unit, absmin + (0.5 * (absmax - absmin)));
print(sprintf("breakable spawning %s\n", unit.classname));
}
/* This may seem totally absurd. That's because it is. It's very
* unreliable but exploding breakables in close proximity it WILL cause
* an OVERFLOW because we'll be busy running through thousands
@ -186,7 +243,7 @@ void func_breakable::PlayerTouch(void)
if (fDamage >= health) {
touch = __NULL__;
Damage_Apply(this, other, fDamage, 0, DMG_CRUSH);
if ((m_iMaterial == BREAKMT_GLASS) || (m_iMaterial == BREAKMT_COMPUTER)) {
Damage_Apply(other, this, fDamage / 4, 0, DMG_CRUSH);
}
@ -248,16 +305,12 @@ void func_breakable::func_breakable(void)
vvm_angles = stov(argv(i+1));
break;
case "vvm_model":
vector realorg;
// hack, gotta get the world pos */
solid = SOLID_BSP;
SetModel(model);
realorg[0] = absmin[0] + (0.5 * (absmax[0] - absmin[0]));
realorg[1] = absmin[1] + (0.5 * (absmax[1] - absmin[1]));
realorg[2] = absmin[2] + (0.5 * (absmax[2] - absmin[2]));
/* change the origin */
origin = realorg;
origin = absmin + (0.5 * (absmax - absmin));
m_oldOrigin = origin;
/* Now we can fake being a point entity. */
@ -275,6 +328,12 @@ void func_breakable::func_breakable(void)
case "explodemagnitude":
m_flExplodeMag = stof(argv(i+1));
break;
case "spawnobject":
m_strBreakSpawn = funcbreakable_objtable[stoi(argv(i+1))];
break;
case "spawnonbreak":
m_strBreakSpawn = argv(i+1);
break;
default:
break;
}

View file

@ -111,7 +111,7 @@ m_init(void)
Music_MenuStart();
}
localcmd(sprintf("pkg addsource http://www.frag-net.com/dl/valve_packages\npkg addsource http://www.frag-net.com/dl/%s_packages\nwait;wait;pkg update\n", games[gameinfo_current].gamedir));
/* localcmd(sprintf("pkg addsource http://www.frag-net.com/dl/valve_packages\npkg addsource http://www.frag-net.com/dl/%s_packages\nwait;wait;pkg update\n", games[gameinfo_current].gamedir)); */
if (autocvar_menu_updating || !autocvar_menu_installedpackages) {
g_menupage = PAGE_UPDATES;

View file

@ -1,4 +1,4 @@
/*
/*
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
*
* Permission to use, copy, modify, and distribute this software for any
@ -32,7 +32,7 @@ void item_ammo::touch(void)
Weapons_RefreshAmmo(pl);
Logging_Pickup(other, this, __NULL__);
if (cvar("sv_playerslots") == 1) {
if (real_owner || cvar("sv_playerslots") == 1) {
remove(self);
} else {
Hide();
@ -51,7 +51,10 @@ void item_ammo::Respawn(void)
think = __NULL__;
nextthink = -1;
Sound_Play(this, CHAN_ITEM, "ammo.respawn");
if (real_owner)
Sound_Play(this, CHAN_ITEM, "ammo.respawn");
droptofloor();
}

View file

@ -54,7 +54,7 @@ void item_battery::touch(void)
Logging_Pickup(other, this, __NULL__);
Sound_Play(other, CHAN_ITEM, "item.battery");
if (cvar("sv_playerslots") == 1) {
if (real_owner || cvar("sv_playerslots") == 1) {
remove(self);
} else {
Hide();
@ -73,7 +73,10 @@ void item_battery::Respawn(void)
think = __NULL__;
nextthink = -1;
Sound_Play(this, CHAN_ITEM, "item.respawn");
if (!real_owner)
Sound_Play(this, CHAN_ITEM, "item.respawn");
droptofloor();
}

View file

@ -42,7 +42,7 @@ void item_healthkit::touch(void)
Sound_Play(this, CHAN_ITEM, "item.healthkit");
Logging_Pickup(other, this, __NULL__);
if (cvar("sv_playerslots") == 1) {
if (real_owner || cvar("sv_playerslots") == 1) {
remove(self);
} else {
Hide();
@ -61,7 +61,10 @@ void item_healthkit::Respawn(void)
think = __NULL__;
nextthink = -1;
Sound_Play(this, CHAN_ITEM, "item.respawn");
if (!real_owner)
Sound_Play(this, CHAN_ITEM, "item.respawn");
droptofloor();
}

View file

@ -49,7 +49,7 @@ void item_longjump::touch(void)
CBaseTrigger::UseTargets();
if (cvar("sv_playerslots") == 1) {
if (real_owner || cvar("sv_playerslots") == 1) {
remove(self);
} else {
Hide();
@ -68,7 +68,9 @@ void item_longjump::Respawn(void)
think = __NULL__;
nextthink = -1;
sound(this, CHAN_ITEM, "items/suitchargeok1.wav", 1, ATTN_NORM, 150);
if (!real_owner)
Sound_Play(this, CHAN_ITEM, "item.respawn");
}
void item_longjump::item_longjump(void)

View file

@ -48,7 +48,7 @@ void item_suit::touch(void)
CBaseTrigger::UseTargets();
if (cvar("sv_playerslots") == 1) {
if (real_owner || cvar("sv_playerslots") == 1) {
remove(self);
} else {
Hide();
@ -67,7 +67,9 @@ void item_suit::Respawn(void)
think = __NULL__;
nextthink = -1;
sound(this, CHAN_ITEM, "items/suitchargeok1.wav", 1, ATTN_NORM, 150);
if (!real_owner)
Sound_Play(this, CHAN_ITEM, "item.respawn");
}
void item_suit::item_suit(void)

View file

@ -30,7 +30,7 @@ void item_pickup::touch(void)
CBaseTrigger::UseTargets();
if (m_iWasDropped == 1 || cvar("sv_playerslots") == 1) {
if (real_owner || m_iWasDropped == 1 || cvar("sv_playerslots") == 1) {
remove(self);
} else {
Hide();
@ -67,7 +67,9 @@ void item_pickup::Respawn(void)
nextthink = -1;
if (!m_iWasDropped && cvar("sv_playerslots") > 1) {
Sound_Play(this, CHAN_ITEM, "item.respawn");
if (!real_owner)
Sound_Play(this, CHAN_ITEM, "item.respawn");
m_iClip = -1;
}