#ifdef SVQC
+
+#include "../../../server/_all.qh"
+
+#include "../../../server/g_subs.qh"
+#include "../../../server/waypointsprites.qh"
+#include "../../../server/g_damage.qh"
+#include "../../../server/bot/bot.qh"
+#include "../../common/csqcmodel_settings.qh"
+#include "../../../csqcmodellib/sv_model.qh"
+#include "../../../server/weapons/common.qh"
+
.entity sprite;
.float dmg;
// spawnflags:
// 1 = start disabled (needs to be triggered to activate)
// 2 = indicate damage
+// 4 = don't take direct damage (needs to be triggered to 'explode', then triggered again to restore)
// notes:
// for mdl_dead to work, origin must be set (using a common/origin brush).
// Otherwise mdl_dead will be displayed at the map origin, and nobody would
// want that!
-void func_breakable_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force);
+void func_breakable_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force);
//
// func_breakable
//
void LaunchDebris (string debrisname, vector force)
{
- local entity dbr;
-
- dbr = spawn();
+ entity dbr = spawn();
setorigin(dbr, self.absmin
- + '1 0 0' * random() * (self.absmax_x - self.absmin_x)
- + '0 1 0' * random() * (self.absmax_y - self.absmin_y)
- + '0 0 1' * random() * (self.absmax_z - self.absmin_z));
+ + '1 0 0' * random() * (self.absmax.x - self.absmin.x)
+ + '0 1 0' * random() * (self.absmax.y - self.absmin.y)
+ + '0 0 1' * random() * (self.absmax.z - self.absmin.z));
setmodel (dbr, debrisname );
dbr.skin = self.debrisskin;
dbr.colormap = self.colormap; // inherit team colors
dbr.solid = self.debrissolid;
if(dbr.solid != SOLID_BSP) // SOLID_BSP has exact collision, MAYBE this works? TODO check this out
setsize(dbr, '0 0 0', '0 0 0'); // needed for performance, until engine can deal better with it
- dbr.velocity_x = self.debrisvelocity_x + self.debrisvelocityjitter_x * crandom();
- dbr.velocity_y = self.debrisvelocity_y + self.debrisvelocityjitter_y * crandom();
- dbr.velocity_z = self.debrisvelocity_z + self.debrisvelocityjitter_z * crandom();
+ dbr.velocity_x = self.debrisvelocity.x + self.debrisvelocityjitter.x * crandom();
+ dbr.velocity_y = self.debrisvelocity.y + self.debrisvelocityjitter.y * crandom();
+ dbr.velocity_z = self.debrisvelocity.z + self.debrisvelocityjitter.z * crandom();
self.velocity = self.velocity + force * self.debrisdamageforcescale;
- dbr.avelocity_x = random()*self.debrisavelocityjitter_x;
- dbr.avelocity_y = random()*self.debrisavelocityjitter_y;
- dbr.avelocity_z = random()*self.debrisavelocityjitter_z;
+ dbr.avelocity_x = random()*self.debrisavelocityjitter.x;
+ dbr.avelocity_y = random()*self.debrisavelocityjitter.y;
+ dbr.avelocity_z = random()*self.debrisavelocityjitter.z;
dbr.damageforcescale = self.debrisdamageforcescale;
if(dbr.damageforcescale)
dbr.takedamage = DAMAGE_YES;
self.colormod = '1 0 0' + '0 1 0' * (2 * h - 0.5);
else
self.colormod = '1 1 1';
-
+
CSQCMODEL_AUTOUPDATE();
}
void func_breakable_look_destroyed()
{
- float floor_z;
+ float floorZ;
if(self.solid == SOLID_BSP) // in case a misc_follow moved me, save the current origin first
self.dropped_origin = self.origin;
if(self.mdl_dead == "")
- self.model = "";
+ self.effects |= EF_NODRAW;
else {
if (self.origin == '0 0 0') { // probably no origin brush, so don't spawn in the middle of the map..
- floor_z = self.absmin_z;
+ floorZ = self.absmin.z;
setorigin(self,((self.absmax+self.absmin)*.5));
- self.origin_z = floor_z;
+ self.origin_z = floorZ;
}
setmodel(self, self.mdl_dead);
+ self.effects &= ~EF_NODRAW;
}
+ CSQCMODEL_AUTOUPDATE();
+
self.solid = SOLID_NOT;
}
void func_breakable_look_restore()
{
setmodel(self, self.mdl);
+ self.effects &= ~EF_NODRAW;
+
if(self.mdl_dead != "") // only do this if we use mdl_dead, to behave better with misc_follow
setorigin(self, self.dropped_origin);
+
+ CSQCMODEL_AUTOUPDATE();
+
self.solid = SOLID_BSP;
}
{
self.health = self.max_health;
self.takedamage = DAMAGE_NO;
- self.bot_attack = FALSE;
+ self.bot_attack = false;
self.event_damage = func_null;
self.state = 1;
+ if(self.spawnflags & 4)
+ self.use = func_null;
func_breakable_colormod();
+ if (self.noise1)
+ stopsound (self, CH_TRIGGER_SINGLE);
}
void func_breakable_behave_restore()
WaypointSprite_UpdateMaxHealth(self.sprite, self.max_health);
WaypointSprite_UpdateHealth(self.sprite, self.health);
}
- self.takedamage = DAMAGE_AIM;
- self.bot_attack = TRUE;
- self.event_damage = func_breakable_damage;
+ if(!(self.spawnflags & 4))
+ {
+ self.takedamage = DAMAGE_AIM;
+ self.bot_attack = true;
+ self.event_damage = func_breakable_damage;
+ }
self.state = 0;
self.nextthink = 0; // cancel auto respawn
func_breakable_colormod();
+ if (self.noise1)
+ sound (self, CH_TRIGGER_SINGLE, self.noise1, VOL_BASE, ATTEN_NORM);
+}
+
+void func_breakable_init_for_player(entity player)
+{
+ if (self.noise1 && self.state == 0 && clienttype(player) == CLIENTTYPE_REAL)
+ {
+ msg_entity = player;
+ soundto (MSG_ONE, self, CH_TRIGGER_SINGLE, self.noise1, VOL_BASE, ATTEN_NORM);
+ }
}
void func_breakable_destroyed()
{
func_breakable_look_destroyed();
func_breakable_behave_destroyed();
-
+
CSQCMODEL_AUTOUPDATE();
}
{
func_breakable_look_restore();
func_breakable_behave_restore();
-
+
CSQCMODEL_AUTOUPDATE();
}
self.message = oldmsg;
}
-void func_breakable_damage(entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+void func_breakable_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
{
if(self.state == 1)
return;
if(self.team)
if(attacker.team == self.team)
return;
+ self.pain_finished = time;
self.health = self.health - damage;
if(self.sprite)
{
func_breakable_behave_destroyed();
else
func_breakable_behave_restore();
-
+
CSQCMODEL_AUTOUPDATE();
}
// destructible walls that can be used to trigger target_objective_decrease
-void spawnfunc_func_breakable() {
+void spawnfunc_func_breakable()
+{
float n, i;
if(!self.health)
self.health = 100;
self.mdl = self.model;
SetBrushEntityModel();
- self.use = func_breakable_restore;
+ if(self.spawnflags & 4)
+ self.use = func_breakable_destroy;
+ else
+ self.use = func_breakable_restore;
+
+ if(self.spawnflags & 4)
+ {
+ self.takedamage = DAMAGE_NO;
+ self.event_damage = func_null;
+ self.bot_attack = false;
+ }
// precache all the models
if (self.mdl_dead)
precache_model(argv(i));
if(self.noise)
precache_sound(self.noise);
+ if(self.noise1)
+ precache_sound(self.noise1);
self.team_saved = self.team;
self.dropped_origin = self.origin;
self.reset = func_breakable_reset;
func_breakable_reset();
-
+
+ self.init_for_player_needed = 1;
+ self.init_for_player = func_breakable_init_for_player;
+
CSQCMODEL_AUTOINIT();
}