Implemented env_render, cycler_sprite, trigger_multiple and a few other bits
This commit is contained in:
parent
a75b6d1dda
commit
dac1623b0d
12 changed files with 361 additions and 2305 deletions
|
@ -155,6 +155,20 @@ enum {
|
|||
EV_MODELGIB,
|
||||
};
|
||||
|
||||
// Submodel materials
|
||||
enum {
|
||||
MATERIAL_GLASS = 0,
|
||||
MATERIAL_WOOD,
|
||||
MATERIAL_METAL,
|
||||
MATERIAL_FLESH,
|
||||
MATERIAL_CINDER,
|
||||
MATERIAL_TILE,
|
||||
MATERIAL_COMPUTER,
|
||||
MATERIAL_GLASS_UNBREAKABLE,
|
||||
MATERIAL_ROCK,
|
||||
MATERIAL_NONE
|
||||
};
|
||||
|
||||
float clamp(float d, float imin, float imax) {
|
||||
float t;
|
||||
|
||||
|
|
47
Source/Server/AmbientSound.c
Normal file
47
Source/Server/AmbientSound.c
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
OpenCS Project
|
||||
Copyright (C) 2015 Marco "eukara" Hladik
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
void ambient_generic_use( void ) {
|
||||
sound( self, CHAN_VOICE, self.message, 1, self.style );
|
||||
}
|
||||
|
||||
void ambient_generic( void ) {
|
||||
precache_sound( self.message );
|
||||
|
||||
if ( self.spawnflags & 1 ) {
|
||||
self.style = ATTN_NONE;
|
||||
} else if ( self.spawnflags & 2 ) {
|
||||
self.style = ATTN_IDLE;
|
||||
} else if ( self.spawnflags & 4 ) {
|
||||
self.style = ATTN_STATIC;
|
||||
} else if ( self.spawnflags & 8 ) {
|
||||
self.style = ATTN_NORM;
|
||||
} else {
|
||||
self.style = ATTN_STATIC;
|
||||
}
|
||||
|
||||
if ( self.spawnflags & 32 ) {
|
||||
sound( self, CHAN_VOICE, self.message, 1, self.style );
|
||||
} else {
|
||||
ambientsound( self.origin, self.message, 1, self.style );
|
||||
}
|
||||
|
||||
self.vUse = ambient_generic_use;
|
||||
}
|
|
@ -18,9 +18,9 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
void Damage_Apply( entity eTarget, entity eAttacker, float fWeapon, vector vHitPos ) {
|
||||
void Damage_Apply( entity eTarget, entity eAttacker, int iDamage, vector vHitPos ) {
|
||||
|
||||
eTarget.health = eTarget.health - wptTable[ self.weapon ].iDamage; // TODO: Body part multipliers
|
||||
eTarget.health = eTarget.health - iDamage; // TODO: Body part multipliers
|
||||
|
||||
if ( eTarget.iBleeds == TRUE ) {
|
||||
makevectors( eAttacker.angles );
|
||||
|
|
|
@ -88,3 +88,6 @@ float OpenCSGunBase_PrimaryFire( void );
|
|||
float OpenCSGunBase_Reload( void );
|
||||
|
||||
void TraceAttack_FireBullets( int iShots );
|
||||
|
||||
// WIP
|
||||
string __fullspawndata;
|
||||
|
|
|
@ -18,20 +18,54 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
void Entities_UseTargets( void ) {
|
||||
entity eFind = findchain( targetname, self.target );
|
||||
|
||||
while ( eFind ) {
|
||||
entity eOldSelf = self;
|
||||
self = eFind;
|
||||
eFind.vUse();
|
||||
self = eOldSelf;
|
||||
eFind = eFind.chain;
|
||||
}
|
||||
}
|
||||
|
||||
enum {
|
||||
RENDERMODE_NORMAL = 0,
|
||||
RENDERMODE_COLOR,
|
||||
RENDERMODE_TEXTURE,
|
||||
RENDERMODE_GLOW,
|
||||
RENDERMODE_SOLID,
|
||||
RENDERMODE_ADDITIVE
|
||||
};
|
||||
|
||||
void Entities_RenderSetup( void ) {
|
||||
// GoldSrc-Rendermode support
|
||||
if ( self.rendermode != RENDERMODE_NORMAL ) {
|
||||
self.alpha = ( self.renderamt / 255 );
|
||||
if( self.alpha == 0 ) {
|
||||
self.alpha = 0.0001;
|
||||
}
|
||||
|
||||
if ( self.rendermode == RENDERMODE_ADDITIVE ) {
|
||||
self.effects = EF_ADDITIVE;
|
||||
} else if ( self.rendermode == RENDERMODE_GLOW ) {
|
||||
self.effects = EF_FULLBRIGHT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void func_wall( void ) {
|
||||
static void func_wall_use( void ) {
|
||||
self.skin = 1 - self.skin;
|
||||
}
|
||||
self.angles = '0 0 0';
|
||||
self.movetype = MOVETYPE_PUSH;
|
||||
self.solid = SOLID_BSP;
|
||||
|
||||
setmodel (self, self.model);
|
||||
|
||||
// GoldSrc-Rendermode support
|
||||
if( self.rendermode == 2 ) {
|
||||
self.alpha = ( self.renderamt / 255 );
|
||||
} else if ( self.rendermode == 5 ) {
|
||||
self.effects = EF_ADDITIVE;
|
||||
self.alpha = ( self.renderamt / 255 );
|
||||
}
|
||||
setmodel( self, self.model );
|
||||
self.vUse = func_wall_use;
|
||||
Entities_RenderSetup();
|
||||
}
|
||||
|
||||
void func_door( void ) {
|
||||
|
@ -51,21 +85,3 @@ void func_water( void ) {
|
|||
func_wall();
|
||||
self.skin = CONTENT_WATER;
|
||||
}
|
||||
|
||||
void ambient_generic( void ) {
|
||||
precache_sound( self.message );
|
||||
|
||||
if ( self.spawnflags & 1 ) {
|
||||
self.style = ATTN_NONE;
|
||||
} else if ( self.spawnflags & 2 ) {
|
||||
self.style = ATTN_IDLE;
|
||||
} else if ( self.spawnflags & 4 ) {
|
||||
self.style = ATTN_STATIC;
|
||||
} else if ( self.spawnflags & 8 ) {
|
||||
self.style = ATTN_NORM;
|
||||
} else {
|
||||
self.style = ATTN_STATIC;
|
||||
}
|
||||
|
||||
ambientsound( self.origin, self.message, 1, self.style );
|
||||
}
|
||||
|
|
48
Source/Server/EnvObjects.c
Normal file
48
Source/Server/EnvObjects.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
OpenCS Project
|
||||
Copyright (C) 2015 Marco "eukara" Hladik
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
as published by the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
void cycler_sprite( void ) {
|
||||
static void cycler_sprite_use( void ) {
|
||||
remove( self );
|
||||
}
|
||||
|
||||
precache_model( self.model );
|
||||
setmodel( self, self.model );
|
||||
self.vUse = cycler_sprite_use;
|
||||
|
||||
Entities_RenderSetup();
|
||||
}
|
||||
|
||||
void env_render( void ) {
|
||||
static void env_render_use( void ) {
|
||||
entity eFind = findchain( targetname, self.target );
|
||||
|
||||
while ( eFind ) {
|
||||
entity eOldSelf = self;
|
||||
eFind.rendermode = self.rendermode;
|
||||
eFind.rendercolor = self.rendercolor;
|
||||
eFind.alpha = self.alpha;
|
||||
eFind = eFind.chain;
|
||||
}
|
||||
}
|
||||
|
||||
Entities_RenderSetup();
|
||||
self.vUse = env_render_use;
|
||||
}
|
|
@ -20,21 +20,21 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
|
||||
// Entity information from http://twhl.info/wiki.php?id=164
|
||||
|
||||
/*
|
||||
|
||||
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
|
||||
|
||||
// These are the material types apparently
|
||||
.float material;
|
||||
enum {
|
||||
MATERIAL_GLASS = 0,
|
||||
MATERIAL_WOOD,
|
||||
MATERIAL_METAL,
|
||||
MATERIAL_FLESH,
|
||||
MATERIAL_CINDER,
|
||||
MATERIAL_TILE,
|
||||
MATERIAL_COMPUTER,
|
||||
MATERIAL_GLASS_UNBREAKABLE,
|
||||
MATERIAL_ROCK,
|
||||
MATERIAL_NONE
|
||||
};
|
||||
|
||||
// Whenever it gets damaged
|
||||
void func_breakable_pain( void ) {
|
||||
|
@ -111,11 +111,44 @@ void func_breakable_die( void ) {
|
|||
sound( self, CHAN_VOICE, sprintf( "%s%d.wav", sTypeSample, ceil( random() * iTypeCount ) ), 1.0, ATTN_NORM );
|
||||
}
|
||||
|
||||
Effect_BreakModel( self.origin, self.size, self.velocity, self.style );
|
||||
Effect_BreakModel( self.absmin, self.absmax, self.velocity, self.material );
|
||||
Entities_UseTargets();
|
||||
|
||||
remove( self );
|
||||
}
|
||||
|
||||
void func_breakable_touch( void ) {
|
||||
static void func_breakable_touch_NULL( void ) { }
|
||||
|
||||
if( other.classname != "player" ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( self.spawnflags & SF_TOUCH ) {
|
||||
int fDamage = (float)(vlen( self.velocity ) * 0.01);
|
||||
|
||||
if ( fDamage >= self.health ) {
|
||||
|
||||
self.touch = func_breakable_touch_NULL;
|
||||
Damage_Apply( self, other, fDamage, self.absmin );
|
||||
|
||||
if ( self.material == MATERIAL_GLASS || self.material == MATERIAL_COMPUTER ) {
|
||||
Damage_Apply( other, self, fDamage/4, other.origin );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ( self.spawnflags & SF_PRESSURE ) && other.absmin_z >= self.maxs_z - 2 ) {
|
||||
self.think = func_breakable_die;
|
||||
|
||||
if ( self.delay == 0 ) {
|
||||
self.delay = 0.1;
|
||||
}
|
||||
|
||||
self.nextthink = self.ltime + self.delay;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SPAWN: func_breakable
|
||||
|
@ -125,8 +158,19 @@ Entry function for the brushes that can die etc.
|
|||
*/
|
||||
void func_breakable( void ) {
|
||||
func_wall();
|
||||
self.vPain = func_breakable_pain;
|
||||
self.vDeath = func_breakable_die;
|
||||
self.iBleeds = FALSE;
|
||||
self.takedamage = DAMAGE_YES;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if ( self.spawnflags & SF_TOUCH || self.spawnflags & SF_PRESSURE ) {
|
||||
self.touch = func_breakable_touch;
|
||||
}
|
||||
|
||||
self.vUse = func_breakable_die;
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ void TraceAttack_FireBullets( int iShots ) {
|
|||
traceline( vSrc, vSrc + ( vDir * 2048 ), FALSE, self);
|
||||
if (trace_fraction != 1.0) {
|
||||
if ( trace_ent.takedamage == DAMAGE_YES ) {
|
||||
Damage_Apply( trace_ent, self, self.weapon, trace_endpos );
|
||||
Damage_Apply( trace_ent, self, wptTable[ self.weapon ].iDamage, trace_endpos );
|
||||
} else {
|
||||
pointparticles( EFFECT_GUNSHOT, trace_endpos, '0 0 0', 1 );
|
||||
}
|
||||
|
|
79
Source/Server/Triggers.c
Normal file
79
Source/Server/Triggers.c
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
TRIGGER_MULTIPLE
|
||||
http://twhl.info/wiki.php?id=139
|
||||
|
||||
Target (target) - When an entity is activated, it triggers the entity with the name specified by Target.
|
||||
Name (targetname) - Property used to identify entities.
|
||||
Master (master) - The name of a multisource (or game_team_master) entity. A master must usually be active in order for the entity to work. Thus they act almost like an on/off switch, in their simplest form, and like an AND gate in the case of the multisource.
|
||||
Delay before trigger (delay) - Usually the time in seconds before an entity should trigger its target (after being triggered itself). Under other SmartEdit names, delay might also be the time to wait before performing some other action.
|
||||
Kill target (killtarget) - Remove this entity from the game when triggered
|
||||
Target Path (netname)
|
||||
Sound style (sounds)
|
||||
Message (message)
|
||||
Delay before reset (wait) - Time in seconds before the entity is ready to be re-triggered.
|
||||
*/
|
||||
|
||||
// This is what they use...
|
||||
.string killtarget;
|
||||
.float wait;
|
||||
.float delay;
|
||||
|
||||
void trigger_multiple_trigger( void ) {
|
||||
Entities_UseTargets();
|
||||
|
||||
if ( self.killtarget ) {
|
||||
entity eFind = findchain( killtarget, self.target );
|
||||
while ( eFind ) {
|
||||
entity eRemoveMe = eFind;
|
||||
remove( eRemoveMe );
|
||||
eFind = eFind.chain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
SPAWN: trigger_multiple
|
||||
|
||||
Entry function for this nice trigger object.
|
||||
=================
|
||||
*/
|
||||
void trigger_multiple( void ) {
|
||||
static void trigger_multiple_use( void ) {
|
||||
if ( self.delay ) {
|
||||
self.think = trigger_multiple_trigger;
|
||||
self.nextthink = self.ltime + self.delay;
|
||||
} else {
|
||||
trigger_multiple_trigger();
|
||||
}
|
||||
}
|
||||
|
||||
static void trigger_multiple_touch( void ) {
|
||||
if ( self.fAttackFinished > self.ltime ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( other.classname == "player" ) {
|
||||
trigger_multiple_use();
|
||||
self.fAttackFinished = self.ltime + self.wait;
|
||||
}
|
||||
}
|
||||
|
||||
self.angles = '0 0 0';
|
||||
self.solid = SOLID_TRIGGER;
|
||||
|
||||
setmodel( self, self.model );
|
||||
self.model = 0;
|
||||
|
||||
self.vUse = trigger_multiple_use;
|
||||
self.touch = trigger_multiple_touch;
|
||||
}
|
||||
|
||||
void multi_manager( void ) {
|
||||
static void multi_manager_use( void ) {
|
||||
eprint( self );
|
||||
}
|
||||
self.message = __fullspawndata;
|
||||
self.think = multi_manager_use;
|
||||
self.nextthink = self.ltime + 5;
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -40,6 +40,9 @@ Timer.c
|
|||
Main.c
|
||||
EntHostage.c
|
||||
Entities.c
|
||||
Triggers.c
|
||||
AmbientSound.c
|
||||
EnvObjects.c
|
||||
FuncBreakable.c
|
||||
FuncLadder.c
|
||||
FuncHostageRescue.c
|
||||
|
|
|
@ -18,34 +18,80 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
void Effect_BreakModel( vector vPos, vector vSize, vector vVel, float fStyle ) {
|
||||
void Effect_BreakModel( vector vMins, vector vMaxs, vector vVel, float fStyle ) {
|
||||
#ifdef SSQC
|
||||
WriteByte( MSG_MULTICAST, SVC_CGAMEPACKET );
|
||||
WriteByte( MSG_MULTICAST, EV_MODELGIB );
|
||||
WriteCoord( MSG_MULTICAST, vPos_x);
|
||||
WriteCoord( MSG_MULTICAST, vPos_y);
|
||||
WriteCoord( MSG_MULTICAST, vPos_z);
|
||||
WriteCoord( MSG_MULTICAST, vSize_x);
|
||||
WriteCoord( MSG_MULTICAST, vSize_y);
|
||||
WriteCoord( MSG_MULTICAST, vSize_z);
|
||||
WriteCoord( MSG_MULTICAST, vMins_x);
|
||||
WriteCoord( MSG_MULTICAST, vMins_y);
|
||||
WriteCoord( MSG_MULTICAST, vMins_z);
|
||||
WriteCoord( MSG_MULTICAST, vMaxs_x);
|
||||
WriteCoord( MSG_MULTICAST, vMaxs_y);
|
||||
WriteCoord( MSG_MULTICAST, vMaxs_z);
|
||||
WriteByte( MSG_MULTICAST, fStyle );
|
||||
|
||||
msg_entity = self;
|
||||
multicast( '0 0 0', MULTICAST_PVS );
|
||||
#else
|
||||
static void Effect_BreakModel_Remove( void ) { remove( self ) ; }
|
||||
|
||||
float fCount = 20; // TODO: Generate gibcount based around size.
|
||||
vector vRandPos;
|
||||
vector vPos;
|
||||
string sModel = "";
|
||||
|
||||
switch ( fStyle ) {
|
||||
case MATERIAL_GLASS:
|
||||
case MATERIAL_GLASS_UNBREAKABLE:
|
||||
sModel = "models/glassgibs.mdl";
|
||||
break;
|
||||
case MATERIAL_WOOD:
|
||||
sModel = "models/woodgibs.mdl";
|
||||
break;
|
||||
case MATERIAL_METAL:
|
||||
sModel = "models/metalplategibs.mdl";
|
||||
break;
|
||||
case MATERIAL_FLESH:
|
||||
sModel = "models/fleshgibs.mdl";;
|
||||
break;
|
||||
case MATERIAL_CINDER:
|
||||
sModel = "models/cindergibs.mdl";
|
||||
break;
|
||||
case MATERIAL_TILE:
|
||||
sModel = "models/ceilinggibs.mdl";
|
||||
break;
|
||||
case MATERIAL_COMPUTER:
|
||||
sModel = "models/computergibs.mdl";
|
||||
break;
|
||||
case MATERIAL_ROCK:
|
||||
sModel = "models/rockgibs.mdl";
|
||||
break;
|
||||
default:
|
||||
sModel = "models/cindergibs.mdl";
|
||||
}
|
||||
|
||||
while ( fCount > 0 ) {
|
||||
entity eGib = spawn();
|
||||
|
||||
vRandPos_x = random() * vSize_x;
|
||||
vRandPos_y = random() * vSize_y;
|
||||
vRandPos_z = random() * vSize_z;
|
||||
vRandPos = vRandPos - ( vSize / 2 );
|
||||
vPos_x = vMins_x + ( random() * ( vMaxs_x - vMins_x ) );
|
||||
vPos_y = vMins_y + ( random() * ( vMaxs_y - vMins_y ) );
|
||||
vPos_z = vMins_z + ( random() * ( vMaxs_z - vMins_z ) );
|
||||
|
||||
setorigin( eGib, vPos );
|
||||
setmodel( eGib, sModel ); // Placeholder
|
||||
eGib.movetype = MOVETYPE_BOUNCE;
|
||||
eGib.solid = SOLID_NOT;
|
||||
|
||||
eGib.avelocity_x = random()*600;
|
||||
eGib.avelocity_y = random()*600;
|
||||
eGib.avelocity_z = random()*600;
|
||||
eGib.think = Effect_BreakModel_Remove;
|
||||
eGib.nextthink = time + 10;
|
||||
|
||||
if ( ( fStyle == MATERIAL_GLASS ) || ( fStyle == MATERIAL_GLASS_UNBREAKABLE ) ) {
|
||||
eGib.effects = EF_ADDITIVE;
|
||||
eGib.alpha = 0.3;
|
||||
}
|
||||
|
||||
setorigin( eGib, vPos + vRandPos );
|
||||
setmodel( eGib, "models/head.mdl" ); // Placeholder
|
||||
fCount--;
|
||||
eGib.drawmask = MASK_ENGINE;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue