2016-12-03 15:17:55 +00:00
|
|
|
/*
|
2018-06-14 10:05:23 +00:00
|
|
|
Copyright 2016-2018 Marco "eukara" Hladik
|
|
|
|
|
|
|
|
MIT LICENSE
|
2016-12-03 15:17:55 +00:00
|
|
|
|
2018-06-14 10:05:23 +00:00
|
|
|
Permission is hereby granted, free of charge, to any person
|
|
|
|
obtaining a copy of this software and associated documentation
|
|
|
|
files (the "Software"), to deal in the Software without
|
|
|
|
restriction, including without limitation the rights to use,
|
|
|
|
copy, modify, merge, publish, distribute, sublicense, and/or
|
|
|
|
sell copies of the Software, and to permit persons to whom the
|
|
|
|
Software is furnished to do so, subject to the following conditions:
|
2016-12-03 15:17:55 +00:00
|
|
|
|
2018-06-14 10:05:23 +00:00
|
|
|
The above copyright notice and this permission notice shall be
|
|
|
|
included in all copies or substantial portions of the Software.
|
2016-12-03 15:17:55 +00:00
|
|
|
|
2018-06-14 10:05:23 +00:00
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
|
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
|
|
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
|
|
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
|
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
|
|
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
|
|
OTHER DEALINGS IN THE SOFTWARE.
|
2016-12-03 15:17:55 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
// Entity information from http://twhl.info/wiki.php?id=164
|
2016-12-04 01:27:15 +00:00
|
|
|
/*
|
|
|
|
|
|
|
|
Flags
|
|
|
|
|
|
|
|
Only Trigger (1) - Entity can only be activated (broken) by being triggered.
|
|
|
|
Touch (2) - Brush will break on touch.
|
|
|
|
Pressure (4) - Brush will break when pressured (e.g. player walking on it).
|
|
|
|
*/
|
|
|
|
|
|
|
|
#define SF_TRIGGER 1
|
|
|
|
#define SF_TOUCH 2
|
|
|
|
#define SF_PRESSURE 4
|
2016-12-03 15:17:55 +00:00
|
|
|
|
2017-01-10 18:24:45 +00:00
|
|
|
/*
|
|
|
|
=================
|
|
|
|
func_breakable_pain
|
|
|
|
=================
|
|
|
|
*/
|
2017-01-08 14:11:34 +00:00
|
|
|
void func_breakable_pain( int iNull ) {
|
2016-12-03 15:17:55 +00:00
|
|
|
switch ( self.material ) {
|
|
|
|
case MATERIAL_GLASS:
|
|
|
|
case MATERIAL_COMPUTER:
|
|
|
|
case MATERIAL_GLASS_UNBREAKABLE:
|
2017-01-14 15:00:31 +00:00
|
|
|
sound( self, CHAN_VOICE, sprintf( "debris/glass%d.wav", random( 1, 4 ) ), 1.0, ATTN_NORM );
|
2016-12-03 15:17:55 +00:00
|
|
|
break;
|
|
|
|
case MATERIAL_WOOD:
|
2017-01-14 15:00:31 +00:00
|
|
|
sound( self, CHAN_VOICE, sprintf( "debris/wood%d.wav", random( 1, 4 ) ), 1.0, ATTN_NORM );
|
2016-12-03 15:17:55 +00:00
|
|
|
break;
|
|
|
|
case MATERIAL_METAL:
|
2017-01-14 15:00:31 +00:00
|
|
|
sound( self, CHAN_VOICE, sprintf( "debris/metal%d.wav", random( 1, 4 ) ), 1.0, ATTN_NORM );
|
2016-12-03 15:17:55 +00:00
|
|
|
break;
|
|
|
|
case MATERIAL_FLESH:
|
2017-01-14 15:00:31 +00:00
|
|
|
float fRand = floor( random( 1, 8 ) );
|
|
|
|
if ( fRand == 4 ) { // sigh
|
|
|
|
fRand = 5;
|
|
|
|
}
|
|
|
|
sound( self, CHAN_VOICE, sprintf( "debris/flesh%d.wav", fRand ), 1.0, ATTN_NORM );
|
2016-12-03 15:17:55 +00:00
|
|
|
break;
|
|
|
|
case MATERIAL_CINDER:
|
|
|
|
case MATERIAL_ROCK:
|
2017-01-14 15:00:31 +00:00
|
|
|
sound( self, CHAN_VOICE, sprintf( "debris/concrete%d.wav", random( 1, 4 ) ), 1.0, ATTN_NORM );
|
2016-12-03 15:17:55 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-10 18:24:45 +00:00
|
|
|
/*
|
|
|
|
=================
|
|
|
|
func_breakable_die
|
|
|
|
=================
|
|
|
|
*/
|
|
|
|
void func_breakable_die( int iNull ) {
|
2017-06-23 07:23:24 +00:00
|
|
|
// Make sure this is dead
|
|
|
|
if ( self.vUse == __NULL__ ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
self.health = 0;
|
|
|
|
self.vUse = __NULL__;
|
2016-12-04 01:27:15 +00:00
|
|
|
Effect_BreakModel( self.absmin, self.absmax, self.velocity, self.material );
|
|
|
|
Entities_UseTargets();
|
2016-12-07 19:38:26 +00:00
|
|
|
Entities_Remove();
|
2016-12-03 15:17:55 +00:00
|
|
|
}
|
|
|
|
|
2017-01-10 18:24:45 +00:00
|
|
|
/*
|
|
|
|
=================
|
|
|
|
func_breakable_use
|
|
|
|
=================
|
|
|
|
*/
|
2017-01-09 21:07:23 +00:00
|
|
|
void func_breakable_use( void ) {
|
2017-01-08 14:11:34 +00:00
|
|
|
func_breakable_die( 0 );
|
|
|
|
}
|
2017-01-10 18:24:45 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
=================
|
|
|
|
func_breakable_touch
|
|
|
|
=================
|
|
|
|
*/
|
2016-12-04 01:27:15 +00:00
|
|
|
void func_breakable_touch( void ) {
|
|
|
|
static void func_breakable_touch_NULL( void ) { }
|
|
|
|
|
|
|
|
if( other.classname != "player" ) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( self.spawnflags & SF_TOUCH ) {
|
2017-01-08 14:11:34 +00:00
|
|
|
int fDamage = (float)(vlen( self.velocity ) * 0.01f );
|
2016-12-04 01:27:15 +00:00
|
|
|
|
|
|
|
if ( fDamage >= self.health ) {
|
|
|
|
self.touch = func_breakable_touch_NULL;
|
2017-11-11 21:46:04 +00:00
|
|
|
Damage_Apply( self, other, fDamage, self.absmin, FALSE );
|
2016-12-04 01:27:15 +00:00
|
|
|
|
2017-01-08 14:11:34 +00:00
|
|
|
if ( ( self.material == MATERIAL_GLASS ) || ( self.material == MATERIAL_COMPUTER ) ) {
|
2017-11-11 21:46:04 +00:00
|
|
|
Damage_Apply( other, self, fDamage / 4, other.origin, FALSE );
|
2016-12-04 01:27:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-09 21:07:23 +00:00
|
|
|
if ( ( self.spawnflags & SF_PRESSURE ) && ( other.absmin_z >= self.maxs_z - 2 ) ) {
|
2017-01-08 14:11:34 +00:00
|
|
|
self.think = func_breakable_use;
|
2016-12-04 01:27:15 +00:00
|
|
|
|
|
|
|
if ( self.delay == 0 ) {
|
2017-01-08 14:11:34 +00:00
|
|
|
self.delay = 0.1f;
|
2016-12-04 01:27:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
self.nextthink = self.ltime + self.delay;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-10 18:24:45 +00:00
|
|
|
/*
|
|
|
|
=================
|
|
|
|
func_breakable_respawn
|
|
|
|
|
|
|
|
Respawns the breakable entity
|
|
|
|
=================
|
|
|
|
*/
|
2017-01-09 17:28:23 +00:00
|
|
|
void func_breakable_respawn( void ) {
|
|
|
|
if ( self.spawnflags & SF_TRIGGER ) {
|
|
|
|
self.takedamage = DAMAGE_NO;
|
|
|
|
} else {
|
|
|
|
self.takedamage = DAMAGE_YES;
|
|
|
|
self.vPain = func_breakable_pain;
|
|
|
|
self.vDeath = func_breakable_die;
|
|
|
|
self.iBleeds = FALSE;
|
|
|
|
}
|
|
|
|
|
2017-01-09 21:07:23 +00:00
|
|
|
if ( ( self.spawnflags & SF_TOUCH ) || ( self.spawnflags & SF_PRESSURE ) ) {
|
2017-01-09 17:28:23 +00:00
|
|
|
self.touch = func_breakable_touch;
|
|
|
|
}
|
|
|
|
|
|
|
|
self.vUse = func_breakable_use;
|
|
|
|
}
|
|
|
|
|
2016-12-03 15:17:55 +00:00
|
|
|
/*
|
|
|
|
=================
|
|
|
|
SPAWN: func_breakable
|
|
|
|
|
|
|
|
Entry function for the brushes that can die etc.
|
|
|
|
=================
|
|
|
|
*/
|
|
|
|
void func_breakable( void ) {
|
2016-12-07 19:38:26 +00:00
|
|
|
func_wall();
|
|
|
|
func_breakable_respawn();
|
2016-12-04 01:27:15 +00:00
|
|
|
|
2016-12-07 19:38:26 +00:00
|
|
|
Entities_InitRespawnable( func_breakable_respawn );
|
2016-12-03 15:17:55 +00:00
|
|
|
}
|