Add support for func_breakable its spawnobject key.
This commit is contained in:
parent
c036ccc318
commit
fcb99ad427
8 changed files with 100 additions and 26 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue