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
|
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
|
class func_breakable:CBaseTrigger
|
||||||
{
|
{
|
||||||
float m_iMaterial;
|
float m_iMaterial;
|
||||||
float m_flDelay;
|
float m_flDelay;
|
||||||
float m_flExplodeMag;
|
float m_flExplodeMag;
|
||||||
|
string m_strBreakSpawn;
|
||||||
|
|
||||||
/*entity m_pressAttacker;
|
/*entity m_pressAttacker;
|
||||||
int m_pressType;
|
int m_pressType;
|
||||||
int m_pressDamage;*/
|
int m_pressDamage;*/
|
||||||
|
@ -128,25 +161,49 @@ void func_breakable::Pain (int body)
|
||||||
|
|
||||||
void func_breakable::Explode(void)
|
void func_breakable::Explode(void)
|
||||||
{
|
{
|
||||||
vector vWorldPos;
|
vector rp = absmin + (0.5 * (absmax - absmin));
|
||||||
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]));
|
|
||||||
FX_BreakModel(vlen(size) / 10, absmin, absmax, [0,0,0], m_iMaterial);
|
FX_BreakModel(vlen(size) / 10, absmin, absmax, [0,0,0], m_iMaterial);
|
||||||
FX_Explosion(vWorldPos);
|
FX_Explosion(rp);
|
||||||
Damage_Radius(vWorldPos, this, m_flExplodeMag, m_flExplodeMag * 2.5f, TRUE, 0);
|
Damage_Radius(rp, this, m_flExplodeMag, m_flExplodeMag * 2.5f, TRUE, 0);
|
||||||
CBaseTrigger::UseTargets();
|
CBaseTrigger::UseTargets();
|
||||||
CBaseEntity::Hide();
|
CBaseEntity::Hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
void func_breakable::Death(int body)
|
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) {
|
if (m_iMaterial == BREAKMT_GLASS_UNBREAKABLE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
health = 0;
|
health = 0;
|
||||||
eActivator = g_eAttacker;
|
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
|
/* This may seem totally absurd. That's because it is. It's very
|
||||||
* unreliable but exploding breakables in close proximity it WILL cause
|
* unreliable but exploding breakables in close proximity it WILL cause
|
||||||
* an OVERFLOW because we'll be busy running through thousands
|
* an OVERFLOW because we'll be busy running through thousands
|
||||||
|
@ -248,16 +305,12 @@ void func_breakable::func_breakable(void)
|
||||||
vvm_angles = stov(argv(i+1));
|
vvm_angles = stov(argv(i+1));
|
||||||
break;
|
break;
|
||||||
case "vvm_model":
|
case "vvm_model":
|
||||||
vector realorg;
|
|
||||||
// hack, gotta get the world pos */
|
// hack, gotta get the world pos */
|
||||||
solid = SOLID_BSP;
|
solid = SOLID_BSP;
|
||||||
SetModel(model);
|
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 */
|
/* change the origin */
|
||||||
origin = realorg;
|
origin = absmin + (0.5 * (absmax - absmin));
|
||||||
m_oldOrigin = origin;
|
m_oldOrigin = origin;
|
||||||
|
|
||||||
/* Now we can fake being a point entity. */
|
/* Now we can fake being a point entity. */
|
||||||
|
@ -275,6 +328,12 @@ void func_breakable::func_breakable(void)
|
||||||
case "explodemagnitude":
|
case "explodemagnitude":
|
||||||
m_flExplodeMag = stof(argv(i+1));
|
m_flExplodeMag = stof(argv(i+1));
|
||||||
break;
|
break;
|
||||||
|
case "spawnobject":
|
||||||
|
m_strBreakSpawn = funcbreakable_objtable[stoi(argv(i+1))];
|
||||||
|
break;
|
||||||
|
case "spawnonbreak":
|
||||||
|
m_strBreakSpawn = argv(i+1);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,7 +111,7 @@ m_init(void)
|
||||||
Music_MenuStart();
|
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) {
|
if (autocvar_menu_updating || !autocvar_menu_installedpackages) {
|
||||||
g_menupage = PAGE_UPDATES;
|
g_menupage = PAGE_UPDATES;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
|
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
|
||||||
*
|
*
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
@ -32,7 +32,7 @@ void item_ammo::touch(void)
|
||||||
Weapons_RefreshAmmo(pl);
|
Weapons_RefreshAmmo(pl);
|
||||||
Logging_Pickup(other, this, __NULL__);
|
Logging_Pickup(other, this, __NULL__);
|
||||||
|
|
||||||
if (cvar("sv_playerslots") == 1) {
|
if (real_owner || cvar("sv_playerslots") == 1) {
|
||||||
remove(self);
|
remove(self);
|
||||||
} else {
|
} else {
|
||||||
Hide();
|
Hide();
|
||||||
|
@ -51,7 +51,10 @@ void item_ammo::Respawn(void)
|
||||||
|
|
||||||
think = __NULL__;
|
think = __NULL__;
|
||||||
nextthink = -1;
|
nextthink = -1;
|
||||||
|
|
||||||
|
if (real_owner)
|
||||||
Sound_Play(this, CHAN_ITEM, "ammo.respawn");
|
Sound_Play(this, CHAN_ITEM, "ammo.respawn");
|
||||||
|
|
||||||
droptofloor();
|
droptofloor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ void item_battery::touch(void)
|
||||||
Logging_Pickup(other, this, __NULL__);
|
Logging_Pickup(other, this, __NULL__);
|
||||||
Sound_Play(other, CHAN_ITEM, "item.battery");
|
Sound_Play(other, CHAN_ITEM, "item.battery");
|
||||||
|
|
||||||
if (cvar("sv_playerslots") == 1) {
|
if (real_owner || cvar("sv_playerslots") == 1) {
|
||||||
remove(self);
|
remove(self);
|
||||||
} else {
|
} else {
|
||||||
Hide();
|
Hide();
|
||||||
|
@ -73,7 +73,10 @@ void item_battery::Respawn(void)
|
||||||
|
|
||||||
think = __NULL__;
|
think = __NULL__;
|
||||||
nextthink = -1;
|
nextthink = -1;
|
||||||
|
|
||||||
|
if (!real_owner)
|
||||||
Sound_Play(this, CHAN_ITEM, "item.respawn");
|
Sound_Play(this, CHAN_ITEM, "item.respawn");
|
||||||
|
|
||||||
droptofloor();
|
droptofloor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ void item_healthkit::touch(void)
|
||||||
Sound_Play(this, CHAN_ITEM, "item.healthkit");
|
Sound_Play(this, CHAN_ITEM, "item.healthkit");
|
||||||
Logging_Pickup(other, this, __NULL__);
|
Logging_Pickup(other, this, __NULL__);
|
||||||
|
|
||||||
if (cvar("sv_playerslots") == 1) {
|
if (real_owner || cvar("sv_playerslots") == 1) {
|
||||||
remove(self);
|
remove(self);
|
||||||
} else {
|
} else {
|
||||||
Hide();
|
Hide();
|
||||||
|
@ -61,7 +61,10 @@ void item_healthkit::Respawn(void)
|
||||||
|
|
||||||
think = __NULL__;
|
think = __NULL__;
|
||||||
nextthink = -1;
|
nextthink = -1;
|
||||||
|
|
||||||
|
if (!real_owner)
|
||||||
Sound_Play(this, CHAN_ITEM, "item.respawn");
|
Sound_Play(this, CHAN_ITEM, "item.respawn");
|
||||||
|
|
||||||
droptofloor();
|
droptofloor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ void item_longjump::touch(void)
|
||||||
|
|
||||||
CBaseTrigger::UseTargets();
|
CBaseTrigger::UseTargets();
|
||||||
|
|
||||||
if (cvar("sv_playerslots") == 1) {
|
if (real_owner || cvar("sv_playerslots") == 1) {
|
||||||
remove(self);
|
remove(self);
|
||||||
} else {
|
} else {
|
||||||
Hide();
|
Hide();
|
||||||
|
@ -68,7 +68,9 @@ void item_longjump::Respawn(void)
|
||||||
|
|
||||||
think = __NULL__;
|
think = __NULL__;
|
||||||
nextthink = -1;
|
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)
|
void item_longjump::item_longjump(void)
|
||||||
|
|
|
@ -48,7 +48,7 @@ void item_suit::touch(void)
|
||||||
|
|
||||||
CBaseTrigger::UseTargets();
|
CBaseTrigger::UseTargets();
|
||||||
|
|
||||||
if (cvar("sv_playerslots") == 1) {
|
if (real_owner || cvar("sv_playerslots") == 1) {
|
||||||
remove(self);
|
remove(self);
|
||||||
} else {
|
} else {
|
||||||
Hide();
|
Hide();
|
||||||
|
@ -67,7 +67,9 @@ void item_suit::Respawn(void)
|
||||||
|
|
||||||
think = __NULL__;
|
think = __NULL__;
|
||||||
nextthink = -1;
|
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)
|
void item_suit::item_suit(void)
|
||||||
|
|
|
@ -30,7 +30,7 @@ void item_pickup::touch(void)
|
||||||
|
|
||||||
CBaseTrigger::UseTargets();
|
CBaseTrigger::UseTargets();
|
||||||
|
|
||||||
if (m_iWasDropped == 1 || cvar("sv_playerslots") == 1) {
|
if (real_owner || m_iWasDropped == 1 || cvar("sv_playerslots") == 1) {
|
||||||
remove(self);
|
remove(self);
|
||||||
} else {
|
} else {
|
||||||
Hide();
|
Hide();
|
||||||
|
@ -67,7 +67,9 @@ void item_pickup::Respawn(void)
|
||||||
nextthink = -1;
|
nextthink = -1;
|
||||||
|
|
||||||
if (!m_iWasDropped && cvar("sv_playerslots") > 1) {
|
if (!m_iWasDropped && cvar("sv_playerslots") > 1) {
|
||||||
|
if (!real_owner)
|
||||||
Sound_Play(this, CHAN_ITEM, "item.respawn");
|
Sound_Play(this, CHAN_ITEM, "item.respawn");
|
||||||
|
|
||||||
m_iClip = -1;
|
m_iClip = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue