Add support for Source styled surfaceproperties.txt definitions, which
is incorporated into func_breakable/pushable already. Mods can now control material/surface properties without code.
This commit is contained in:
parent
736ecb61f8
commit
70fe95e5a7
|
@ -0,0 +1,76 @@
|
|||
"PropData.txt"
|
||||
{
|
||||
"gs_material_glass"
|
||||
{
|
||||
"breakable_model" "gibs_glass"
|
||||
}
|
||||
"gs_material_wood"
|
||||
{
|
||||
"breakable_model" "gibs_wood"
|
||||
}
|
||||
"gs_material_metal"
|
||||
{
|
||||
"breakable_model" "gibs_metalplate"
|
||||
}
|
||||
"gs_material_flesh"
|
||||
{
|
||||
"breakable_model" "gibs_flesh"
|
||||
}
|
||||
"gs_material_cinderblock"
|
||||
{
|
||||
"breakable_model" "gibs_cinder"
|
||||
}
|
||||
"gs_material_tile"
|
||||
{
|
||||
"breakable_model" "gibs_ceiling"
|
||||
}
|
||||
"gs_material_computer"
|
||||
{
|
||||
"breakable_model" "gibs_computer"
|
||||
}
|
||||
"gs_material_unbreakableglass"
|
||||
{
|
||||
"breakable_model" "gibs_glass"
|
||||
}
|
||||
"gs_material_rocks"
|
||||
{
|
||||
"breakable_model" "gibs_rock"
|
||||
}
|
||||
|
||||
|
||||
"BreakableModels"
|
||||
{
|
||||
"gibs_glass"
|
||||
{
|
||||
"models/glassgibs.mdl" "5.0"
|
||||
}
|
||||
"gibs_wood"
|
||||
{
|
||||
"models/woodgibs.mdl" "5.0"
|
||||
}
|
||||
"gibs_metalplate"
|
||||
{
|
||||
"models/metalplategibs.mdl" "5.0"
|
||||
}
|
||||
"gibs_flesh"
|
||||
{
|
||||
"models/fleshgibs.mdl" "5.0"
|
||||
}
|
||||
"gibs_ceiling"
|
||||
{
|
||||
"models/ceilinggibs.mdl" "5.0"
|
||||
}
|
||||
"gibs_computer"
|
||||
{
|
||||
"models/computergibs.mdl" "5.0"
|
||||
}
|
||||
"gibs_rock"
|
||||
{
|
||||
"models/rockgibs.mdl" "5.0"
|
||||
}
|
||||
"gibs_cinder"
|
||||
{
|
||||
"models/cindergibs.mdl" "5.0"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
gs_material_glass
|
||||
{
|
||||
gamematerial Y
|
||||
bulletimpact "func_breakable.impact_glass"
|
||||
}
|
||||
|
||||
gs_material_wood
|
||||
{
|
||||
gamematerial W
|
||||
bulletimpact "func_breakable.impact_wood"
|
||||
}
|
||||
|
||||
gs_material_metal
|
||||
{
|
||||
gamematerial M
|
||||
bulletimpact "func_breakable.impact_metal"
|
||||
}
|
||||
|
||||
gs_material_flesh
|
||||
{
|
||||
gamematerial F
|
||||
bulletimpact "func_breakable.impact_flesh"
|
||||
}
|
||||
|
||||
gs_material_cinderblock
|
||||
{
|
||||
gamematerial C
|
||||
bulletimpact "func_breakable.impact_cinderblock"
|
||||
}
|
||||
|
||||
gs_material_tile
|
||||
{
|
||||
gamematerial T
|
||||
bulletimpact "func_breakable.impact_tile"
|
||||
}
|
||||
|
||||
gs_material_computer
|
||||
{
|
||||
gamematerial P
|
||||
bulletimpact "func_breakable.impact_computer"
|
||||
}
|
||||
|
||||
gs_material_unbreakableglass
|
||||
{
|
||||
gamematerial Y
|
||||
bulletimpact "func_breakable.impact_glassunbreakable"
|
||||
}
|
||||
|
||||
gs_material_rocks
|
||||
{
|
||||
gamematerial C
|
||||
bulletimpact "func_breakable.impact_rock"
|
||||
}
|
|
@ -5,7 +5,6 @@
|
|||
#includelist
|
||||
baseentity.h
|
||||
decals.h
|
||||
materials.h
|
||||
client/defs.h
|
||||
client/basefx.qc
|
||||
shared/baseentity.qc
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2020 Marco Hladik <marco@icculus.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* submodel materials */
|
||||
enum
|
||||
{
|
||||
GSMATERIAL_GLASS,
|
||||
GSMATERIAL_WOOD,
|
||||
GSMATERIAL_METAL,
|
||||
GSMATERIAL_FLESH,
|
||||
GSMATERIAL_CINDER,
|
||||
GSMATERIAL_TILE,
|
||||
GSMATERIAL_COMPUTER,
|
||||
GSMATERIAL_GLASS_UNBREAKABLE,
|
||||
GSMATERIAL_ROCK,
|
||||
GSMATERIAL_NONE
|
||||
};
|
||||
|
||||
/* straight from q3map2 */
|
||||
#define SURF_NODAMAGE 0x1i /* never give falling damage */
|
||||
#define SURF_SLICK 0x2i /* effects game physics */
|
||||
#define SURF_SKY 0x4i /* lighting from environment map */
|
||||
#define SURF_LADDER 0x8i /* climb this surface */
|
||||
#define SURF_NOIMPACT 0x10i /* don't make missile explosions */
|
||||
#define SURF_NOMARKS 0x20i /* don't leave missile marks */
|
||||
#define SURF_Q3FLESH 0x40i /* make flesh sounds and effects */
|
||||
#define SURF_NODRAW 0x80i /* don't generate a drawsurface at all */
|
||||
#define SURF_HINT 0x100i /* make a primary bsp splitter */
|
||||
#define SURF_SKIP 0x200i /* completely ignore, allowing non-closed brushes */
|
||||
#define SURF_NOLIGHTMAP 0x400i /* surface doesn't need a lightmap */
|
||||
#define SURF_POINTLIGHT 0x800i /* generate lighting info at vertexes */
|
||||
#define SURF_METALSTEPS 0x1000i /* clanking footsteps */
|
||||
#define SURF_NOSTEPS 0x2000i /* no footstep sounds */
|
||||
#define SURF_NONSOLID 0x4000i /* don't collide against curves with this set */
|
||||
#define SURF_LIGHTFILTER 0x8000i /* act as a light filter during q3map -light */
|
||||
#define SURF_ALPHASHADOW 0x10000i /* do per-pixel light shadow casting in q3map */
|
||||
#define SURF_NODLIGHT 0x20000i /* don't dlight even if solid (solid lava, skies) */
|
||||
#define SURF_DUST 0x40000i /* leave a dust trail when walking on this surface */
|
|
@ -5,7 +5,6 @@
|
|||
#includelist
|
||||
baseentity.h
|
||||
decals.h
|
||||
materials.h
|
||||
shared/baseentity.qc
|
||||
server/baseoutput.qc
|
||||
server/basetrigger.qc
|
||||
|
|
|
@ -196,7 +196,7 @@ CBasePhysics::Death(void)
|
|||
|
||||
string gibeffect = GetPropData(PROPINFO_BREAKMODEL);
|
||||
int breakcount = GetPropData(PROPINFO_BREAKCOUNT);
|
||||
BreakModel_Spawn(origin, [0,0,0], [100,100], 100, breakcount, gibeffect);
|
||||
BreakModel_Spawn(absmin, absmax, [0,0,0], 100, breakcount, gibeffect);
|
||||
|
||||
/* handle explosions */
|
||||
float flExplodeMag, flExplodeRad;
|
||||
|
|
|
@ -103,6 +103,18 @@ const string funcbreakable_objtable[] = {
|
|||
};
|
||||
#endif
|
||||
|
||||
const string funcbreakable_surftable[] = {
|
||||
"gs_material_glass",
|
||||
"gs_material_wood",
|
||||
"gs_material_metal",
|
||||
"gs_material_flesh",
|
||||
"gs_material_cinderblock",
|
||||
"gs_material_tile",
|
||||
"gs_material_computer",
|
||||
"gs_material_unbreakableglass",
|
||||
"gs_material_rocks"
|
||||
};
|
||||
|
||||
class func_breakable:CBaseTrigger
|
||||
{
|
||||
float m_flDelay;
|
||||
|
@ -131,36 +143,8 @@ func_breakable::Pain(void)
|
|||
if (spawnflags & SF_TRIGGER) {
|
||||
return;
|
||||
}
|
||||
if (serverkeyfloat("*bspversion") != BSPVER_HL) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (m_iMaterial) {
|
||||
case BREAKMT_GLASS:
|
||||
Sound_Play(this, CHAN_VOICE, "func_breakable.impact_glass");
|
||||
break;
|
||||
case BREAKMT_COMPUTER:
|
||||
Sound_Play(this, CHAN_VOICE, "func_breakable.impact_computer");
|
||||
break;
|
||||
case BREAKMT_GLASS_UNBREAKABLE:
|
||||
Sound_Play(this, CHAN_VOICE, "func_breakable.impact_glassunbreakable");
|
||||
break;
|
||||
case BREAKMT_WOOD:
|
||||
Sound_Play(this, CHAN_VOICE, "func_breakable.impact_wood");
|
||||
break;
|
||||
case BREAKMT_METAL:
|
||||
Sound_Play(this, CHAN_VOICE, "func_breakable.impact_metal");
|
||||
break;
|
||||
case BREAKMT_FLESH:
|
||||
Sound_Play(this, CHAN_VOICE, "func_breakable.impact_flesh");
|
||||
break;
|
||||
case BREAKMT_CINDER:
|
||||
Sound_Play(this, CHAN_VOICE, "func_breakable.impact_cinder");
|
||||
break;
|
||||
case BREAKMT_ROCK:
|
||||
Sound_Play(this, CHAN_VOICE, "func_breakable.impact_rock");
|
||||
break;
|
||||
}
|
||||
Sound_Play(this, CHAN_VOICE, SurfData_GetInfo(m_iMaterial, SURFDATA_SND_BULLETIMPACT));
|
||||
}
|
||||
|
||||
|
||||
|
@ -168,7 +152,7 @@ void
|
|||
func_breakable::Explode(void)
|
||||
{
|
||||
vector rp = absmin + (0.5 * (absmax - absmin));
|
||||
FX_BreakModel(vlen(size) / 10, absmin, absmax, [0,0,0], m_iMaterial);
|
||||
FX_BreakModel(vlen(size) / 10, absmin, absmax, [0,0,0], SurfData_GetInfo(m_iMaterial, SURFDATA_MATERIAL));
|
||||
FX_Explosion(rp);
|
||||
Damage_Radius(rp, this, m_flExplodeMag, m_flExplodeRad, TRUE, 0);
|
||||
UseTargets(this, TRIG_TOGGLE, 0.0f); /* delay... ignored. */
|
||||
|
@ -220,7 +204,7 @@ func_breakable::Death(void)
|
|||
think = Explode;
|
||||
nextthink = time + random(0.0,0.5);
|
||||
} else {
|
||||
FX_BreakModel(vlen(size) / 10, absmin, absmax, [0,0,0], m_iMaterial);
|
||||
FX_BreakModel(vlen(size) / 10, absmin, absmax, [0,0,0], SurfData_GetInfo(m_iMaterial, SURFDATA_MATERIAL));
|
||||
/* TODO: ability to have whoever destroyed the crate be the activator */
|
||||
UseTargets(this, TRIG_TOGGLE, 0.0f);
|
||||
Hide();
|
||||
|
@ -296,15 +280,15 @@ func_breakable::Respawn(void)
|
|||
|
||||
health = GetSpawnHealth();
|
||||
|
||||
if (!health) {
|
||||
health = 15;
|
||||
}
|
||||
|
||||
if (HasPropData()) {
|
||||
health = GetPropData(PROPINFO_HEALTH);
|
||||
m_flExplodeMag = GetPropData(PROPINFO_EXPLOSIVE_DMG);
|
||||
m_flExplodeRad = GetPropData(PROPINFO_EXPLOSIVE_RADIUS);
|
||||
}
|
||||
|
||||
if (!health) {
|
||||
health = 15;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -312,7 +296,8 @@ func_breakable::SpawnKey(string strKey, string strValue)
|
|||
{
|
||||
switch (strKey) {
|
||||
case "material":
|
||||
m_iMaterial = stoi(strValue);
|
||||
float id = stof(strValue);
|
||||
SurfData_SetStage(funcbreakable_surftable[id]);
|
||||
break;
|
||||
case "explodemagnitude":
|
||||
m_flExplodeMag = stof(strValue);
|
||||
|
@ -341,35 +326,21 @@ func_breakable::SpawnKey(string strKey, string strValue)
|
|||
void
|
||||
func_breakable::func_breakable(void)
|
||||
{
|
||||
/* func_breakable defaults to glass */
|
||||
if (classname == "func_breakable") {
|
||||
PropData_SetStage(funcbreakable_surftable[0]);
|
||||
SurfData_SetStage(funcbreakable_surftable[0]);
|
||||
} else {
|
||||
PropData_SetStage(funcbreakable_surftable[1]);
|
||||
SurfData_SetStage(funcbreakable_surftable[1]);
|
||||
}
|
||||
|
||||
/* proper init */
|
||||
CBaseTrigger::CBaseTrigger();
|
||||
|
||||
/* contrary to what some map designers think, angles are not supported */
|
||||
GetSpawnAngles() = angles = [0,0,0];
|
||||
|
||||
switch (m_iMaterial) {
|
||||
case BREAKMT_GLASS:
|
||||
Sound_Precache("func_breakable.impact_glass");
|
||||
break;
|
||||
case BREAKMT_COMPUTER:
|
||||
Sound_Precache("func_breakable.impact_computer");
|
||||
break;
|
||||
case BREAKMT_GLASS_UNBREAKABLE:
|
||||
Sound_Precache("func_breakable.impact_glassunbreakable");
|
||||
break;
|
||||
case BREAKMT_WOOD:
|
||||
Sound_Precache("func_breakable.impact_wood");
|
||||
break;
|
||||
case BREAKMT_METAL:
|
||||
Sound_Precache("func_breakable.impact_metal");
|
||||
break;
|
||||
case BREAKMT_FLESH:
|
||||
Sound_Precache("func_breakable.impact_flesh");
|
||||
break;
|
||||
case BREAKMT_CINDER:
|
||||
Sound_Precache("func_breakable.impact_cinder");
|
||||
break;
|
||||
case BREAKMT_ROCK:
|
||||
Sound_Precache("func_breakable.impact_rock");
|
||||
break;
|
||||
}
|
||||
/* precache impact sound */
|
||||
Sound_Precache(SurfData_GetInfo(m_iMaterial, SURFDATA_SND_BULLETIMPACT));
|
||||
}
|
||||
|
|
|
@ -921,6 +921,18 @@ CBaseEntity::GetPropData(int type)
|
|||
{
|
||||
return Prop_GetInfo(m_iPropData, type);
|
||||
}
|
||||
|
||||
int
|
||||
CBaseEntity::HasSurfaceData(void)
|
||||
{
|
||||
return (m_iMaterial != -1) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
__variant
|
||||
CBaseEntity::GetSurfaceData(int type)
|
||||
{
|
||||
return SurfData_GetInfo(m_iMaterial, type);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -940,6 +952,7 @@ CBaseEntity::CBaseEntity(void)
|
|||
return;
|
||||
|
||||
m_iPropData = -1;
|
||||
m_iMaterial = -1;
|
||||
|
||||
/* Not in Deathmatch */
|
||||
if (spawnflags & 2048) {
|
||||
|
@ -959,6 +972,7 @@ CBaseEntity::CBaseEntity(void)
|
|||
|
||||
/* tokenization complete, now we can load propdata */
|
||||
m_iPropData = PropData_Finish();
|
||||
m_iMaterial = SurfData_Finish();
|
||||
|
||||
m_oldAngle = angles;
|
||||
m_oldOrigin = origin;
|
||||
|
|
|
@ -388,6 +388,7 @@ init(float prevprogs)
|
|||
iprint("Initializing Server-Module");
|
||||
Plugin_Init();
|
||||
PropData_Init();
|
||||
SurfData_Init();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -14,61 +14,6 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/* HLBSP materials.txt character id's */
|
||||
//#define MATID_UNUSED1 'A'
|
||||
#define MATID_BLOODYFLESH 'B'
|
||||
#define MATID_CONCRETE 'C'
|
||||
#define MATID_DIRT 'D'
|
||||
//#define MATID_UNUSED2 'E'
|
||||
#define MATID_FLESH 'F'
|
||||
#define MATID_GRATE 'G'
|
||||
#define MATID_ALIEN 'H'
|
||||
//#define MATID_UNUSED3 'I'
|
||||
//#define MATID_GRASS 'J'
|
||||
//#define MATID_PLASTIC 'L'
|
||||
#define MATID_METAL 'M'
|
||||
#define MATID_FOLIAGE 'O'
|
||||
#define MATID_COMPUTER 'P'
|
||||
//#define MATID_ASPHALT 'Q'
|
||||
//#define MATID_BRICK 'R'
|
||||
#define MATID_SLOSH 'S'
|
||||
#define MATID_TILE 'T'
|
||||
#define MATID_CARDBOARD 'U'
|
||||
#define MATID_VENT 'V'
|
||||
#define MATID_WOOD 'W'
|
||||
//#define MATID_UNUSED4 'X'
|
||||
#define MATID_GLASS 'Y'
|
||||
//#define MATID_UNUSED5 'Z'
|
||||
|
||||
/* CS defines snow as 'N' on GoldSrc, whereas in Source it's reserved for sand */
|
||||
#ifdef CSTRIKE
|
||||
#define MATID_SNOW 'N'
|
||||
#define MATID_SAND 'K'
|
||||
#else
|
||||
#define MATID_SNOW 'K'
|
||||
#define MATID_SAND 'N'
|
||||
#endif
|
||||
|
||||
/* other notes:
|
||||
|
||||
in The Wastes (2003) 'I' is sand, 'U' is plaster,
|
||||
'R' is rust.
|
||||
*/
|
||||
|
||||
/* modern additions, not implemented yet */
|
||||
#define MATID_CLAY 1
|
||||
#define MATID_PLASTER 2
|
||||
#define MATID_ROCK 3
|
||||
#define MATID_RUBBER 4
|
||||
#define MATID_SHEETROCK 5
|
||||
#define MATID_CLOTH 6
|
||||
#define MATID_CARPET 7
|
||||
#define MATID_PAPER 8
|
||||
#define MATID_UPHOLSTERY 9
|
||||
#define MATID_PUDDLE 10
|
||||
#define MATID_MUD 11
|
||||
#define MATID_SANDBARREL 12
|
||||
|
||||
void Footsteps_Init(void);
|
||||
void Footsteps_HLBSP(base_player target);
|
||||
void Footsteps_VVBSP(base_player target);
|
||||
|
|
|
@ -17,6 +17,12 @@
|
|||
/* FIXME: world.... sigh, we should box this into a worldspawn class */
|
||||
.string materials_file;
|
||||
|
||||
float
|
||||
HLMaterials_Fetch(string tex_name)
|
||||
{
|
||||
return (float)hash_get(hashMaterials, tex_name);
|
||||
}
|
||||
|
||||
void
|
||||
HLMaterials_Load(string filename)
|
||||
{
|
||||
|
|
|
@ -36,124 +36,7 @@ TraceAttack_Apply(entity eAttacker, int iWeapon)
|
|||
void
|
||||
TraceAttack_ImpactWorld(void)
|
||||
{
|
||||
string tex_name;
|
||||
float surf;
|
||||
|
||||
switch (serverkeyfloat("*bspversion")) {
|
||||
case BSPVER_HL:
|
||||
surf = getsurfacenearpoint(trace_ent, trace_endpos);
|
||||
tex_name = Materials_FixName(getsurfacetexture(trace_ent, surf));
|
||||
|
||||
/* our hashtable is the key to all this */
|
||||
switch ((float)hash_get(hashMaterials, tex_name)) {
|
||||
case MATID_ALIEN:
|
||||
FX_Impact(IMPACT_ALIEN, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case MATID_COMPUTER:
|
||||
FX_Impact(IMPACT_COMPUTER, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case MATID_CONCRETE:
|
||||
FX_Impact(IMPACT_CONCRETE, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case MATID_DIRT:
|
||||
FX_Impact(IMPACT_DIRT, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case MATID_BLOODYFLESH:
|
||||
case MATID_FLESH:
|
||||
FX_Impact(IMPACT_FLESH, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case MATID_FOLIAGE:
|
||||
FX_Impact(IMPACT_FOLIAGE, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case MATID_GLASS:
|
||||
FX_Impact(IMPACT_GLASS, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case MATID_GRATE:
|
||||
FX_Impact(IMPACT_GRATE, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case MATID_METAL:
|
||||
FX_Impact(IMPACT_METAL, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case MATID_SAND:
|
||||
FX_Impact(IMPACT_SAND, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case MATID_SLOSH:
|
||||
FX_Impact(IMPACT_SLOSH, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case MATID_SNOW:
|
||||
FX_Impact(IMPACT_SNOW, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case MATID_TILE:
|
||||
FX_Impact(IMPACT_TILE, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case MATID_VENT:
|
||||
FX_Impact(IMPACT_VENT, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case MATID_WOOD:
|
||||
FX_Impact(IMPACT_WOOD, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
default:
|
||||
FX_Impact(IMPACT_DEFAULT, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case BSPVER_Q3: /* Q3 */
|
||||
case BSPVER_RTCW: /* RtCW */
|
||||
case BSPVER_RBSP: /* RFVBSP */
|
||||
switch (trace_surfaceflagsi) {
|
||||
case SURF_ALIEN:
|
||||
FX_Impact(IMPACT_ALIEN, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case SURF_COMPUTER:
|
||||
FX_Impact(IMPACT_COMPUTER, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case SURF_CONCRETE:
|
||||
FX_Impact(IMPACT_CONCRETE, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case SURF_DIRT:
|
||||
FX_Impact(IMPACT_DIRT, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case SURF_BLOODYFLESH:
|
||||
FX_Impact(IMPACT_FLESH, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case SURF_FOLIAGE:
|
||||
FX_Impact(IMPACT_FOLIAGE, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case SURF_GLASS:
|
||||
FX_Impact(IMPACT_GLASS, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case SURF_GRATE:
|
||||
FX_Impact(IMPACT_GRATE, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case SURF_METAL:
|
||||
FX_Impact(IMPACT_METAL, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case SURF_SAND:
|
||||
FX_Impact(IMPACT_SAND, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case SURF_SLOSH:
|
||||
FX_Impact(IMPACT_SLOSH, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case SURF_SNOW:
|
||||
FX_Impact(IMPACT_SNOW, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case SURF_TILE:
|
||||
FX_Impact(IMPACT_TILE, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case SURF_VENT:
|
||||
FX_Impact(IMPACT_VENT, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case SURF_WOOD:
|
||||
FX_Impact(IMPACT_WOOD, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
default:
|
||||
FX_Impact(IMPACT_DEFAULT, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
FX_Impact(IMPACT_DEFAULT, trace_endpos, trace_plane_normal);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* cast a single bullet shot */
|
||||
|
@ -211,43 +94,7 @@ TraceAttack_FireSingle(vector vecPos, vector vAngle, int iDamage, int iWeapon)
|
|||
|
||||
/* impact per bullet */
|
||||
if (trace_ent.iBleeds == 0) {
|
||||
if (trace_ent == world) {
|
||||
TraceAttack_ImpactWorld();
|
||||
} else {
|
||||
CBaseEntity foo = (CBaseEntity)trace_ent;
|
||||
switch (foo.m_iMaterial) {
|
||||
case BREAKMT_GLASS:
|
||||
FX_Impact(IMPACT_GLASS, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case BREAKMT_WOOD:
|
||||
FX_Impact(IMPACT_WOOD, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case BREAKMT_METAL:
|
||||
FX_Impact(IMPACT_METAL, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case BREAKMT_FLESH:
|
||||
FX_Impact(IMPACT_FLESH, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case BREAKMT_CINDER:
|
||||
FX_Impact(IMPACT_CONCRETE, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case BREAKMT_TILE:
|
||||
FX_Impact(IMPACT_TILE, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case BREAKMT_COMPUTER:
|
||||
FX_Impact(IMPACT_COMPUTER, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case BREAKMT_GLASS_UNBREAKABLE:
|
||||
FX_Impact(IMPACT_GLASS, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case BREAKMT_ROCK:
|
||||
FX_Impact(IMPACT_DEFAULT, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
case BREAKMT_NONE:
|
||||
FX_Impact(IMPACT_DEFAULT, trace_endpos, trace_plane_normal);
|
||||
break;
|
||||
}
|
||||
}
|
||||
SurfData_Impact(trace_ent, trace_surfaceflagsi, trace_endpos, trace_plane_normal);
|
||||
}
|
||||
|
||||
/* combine them into one single Damage_Apply call later */
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "spectator.h"
|
||||
#include "platform.h"
|
||||
#include "propdata.h"
|
||||
#include "surfaceproperties.h"
|
||||
#include "vehicles.h"
|
||||
|
||||
#define BSPVER_PREREL 28
|
||||
|
|
|
@ -7,5 +7,6 @@ math.qc
|
|||
player.qc
|
||||
player_pmove.qc
|
||||
propdata.qc
|
||||
surfaceproperties.qc
|
||||
vehicles.qc
|
||||
#endlist
|
||||
|
|
|
@ -37,7 +37,70 @@ typedef enum
|
|||
IMPACT_WOOD
|
||||
} impactType_t;
|
||||
|
||||
/* TW/NEXT specific game flags */
|
||||
typedef enum
|
||||
{
|
||||
GSMATERIAL_GLASS,
|
||||
GSMATERIAL_WOOD,
|
||||
GSMATERIAL_METAL,
|
||||
GSMATERIAL_FLESH,
|
||||
GSMATERIAL_CINDER,
|
||||
GSMATERIAL_TILE,
|
||||
GSMATERIAL_COMPUTER,
|
||||
GSMATERIAL_GLASS_UNBREAKABLE,
|
||||
GSMATERIAL_ROCK,
|
||||
GSMATERIAL_NONE
|
||||
} materialType_t;
|
||||
|
||||
|
||||
/* HLBSP materials.txt character id's */
|
||||
//#define MATID_UNUSED1 'A'
|
||||
#define MATID_BLOODYFLESH 'B'
|
||||
#define MATID_CONCRETE 'C'
|
||||
#define MATID_DIRT 'D'
|
||||
//#define MATID_UNUSED2 'E'
|
||||
#define MATID_FLESH 'F'
|
||||
#define MATID_GRATE 'G'
|
||||
#define MATID_ALIEN 'H'
|
||||
//#define MATID_UNUSED3 'I'
|
||||
//#define MATID_GRASS 'J'
|
||||
//#define MATID_PLASTIC 'L'
|
||||
#define MATID_METAL 'M'
|
||||
#define MATID_FOLIAGE 'O'
|
||||
#define MATID_COMPUTER 'P'
|
||||
//#define MATID_ASPHALT 'Q'
|
||||
//#define MATID_BRICK 'R'
|
||||
#define MATID_SLOSH 'S'
|
||||
#define MATID_TILE 'T'
|
||||
#define MATID_CARDBOARD 'U'
|
||||
#define MATID_VENT 'V'
|
||||
#define MATID_WOOD 'W'
|
||||
//#define MATID_UNUSED4 'X'
|
||||
#define MATID_GLASS 'Y'
|
||||
//#define MATID_UNUSED5 'Z'
|
||||
|
||||
/* CS defines snow as 'N' on GoldSrc, whereas in Source it's reserved for sand */
|
||||
#ifdef CSTRIKE
|
||||
#define MATID_SNOW 'N'
|
||||
#define MATID_SAND 'K'
|
||||
#else
|
||||
#define MATID_SNOW 'K'
|
||||
#define MATID_SAND 'N'
|
||||
#endif
|
||||
|
||||
/* modern additions, not implemented yet */
|
||||
#define MATID_CLAY 1
|
||||
#define MATID_PLASTER 2
|
||||
#define MATID_ROCK 3
|
||||
#define MATID_RUBBER 4
|
||||
#define MATID_SHEETROCK 5
|
||||
#define MATID_CLOTH 6
|
||||
#define MATID_CARPET 7
|
||||
#define MATID_PAPER 8
|
||||
#define MATID_UPHOLSTERY 9
|
||||
#define MATID_PUDDLE 10
|
||||
#define MATID_MUD 11
|
||||
#define MATID_SANDBARREL 12
|
||||
|
||||
|
||||
/* q3 bsp base flags */
|
||||
#define SURF_NODAMAGE 0x1i // never give falling damage
|
||||
|
|
|
@ -73,6 +73,7 @@ typedef struct
|
|||
float damage_explosive;
|
||||
float explosive_damage; /* once the damage/radius keys are set, make explosion upon break */
|
||||
float explosive_radius;
|
||||
string breakable_particle; /* name of BreakableModels entry in PropData.txt */
|
||||
string breakable_model; /* name of BreakableModels entry in PropData.txt */
|
||||
int breakable_count;
|
||||
} propdata_t;
|
||||
|
|
|
@ -92,6 +92,9 @@ PropData_ParseField(int i, int a)
|
|||
case "explosive_radius":
|
||||
g_propdata[i].explosive_radius = stof(argv(1));
|
||||
break;
|
||||
case "breakable_particle":
|
||||
g_propdata[i].breakable_particle = argv(1);
|
||||
break;
|
||||
case "breakable_model":
|
||||
g_propdata[i].breakable_model = argv(1);
|
||||
break;
|
||||
|
@ -411,7 +414,7 @@ PropData_Finish(void)
|
|||
|
||||
/* BreakModel related helper API */
|
||||
void
|
||||
BreakModel_Spawn(vector pos, vector dir, vector spread, float speed, int count, string type)
|
||||
BreakModel_Spawn(vector smins, vector smaxs, vector dir, float speed, int count, string type)
|
||||
{
|
||||
int index;
|
||||
index = (int)hash_get(g_hashbreakmodel, type, -1);
|
||||
|
@ -425,6 +428,7 @@ BreakModel_Spawn(vector pos, vector dir, vector spread, float speed, int count,
|
|||
int modelcount = x / 2;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
vector endpos;
|
||||
string mname;
|
||||
float fadetime;
|
||||
entity gib;
|
||||
|
@ -437,14 +441,16 @@ BreakModel_Spawn(vector pos, vector dir, vector spread, float speed, int count,
|
|||
mname = argv((r * 2));
|
||||
fadetime = stof(argv((r * 2) + 1));
|
||||
|
||||
endpos[0] = smins[0] + ( random() * ( smaxs[0] - smins[0] ) );
|
||||
endpos[1] = smins[1] + ( random() * ( smaxs[1] - smins[1] ) );
|
||||
endpos[2] = smins[2] + ( random() * ( smaxs[2] - smins[2] ) );
|
||||
|
||||
gib = spawn();
|
||||
setmodel(gib, mname);
|
||||
setsize(gib, [0,0,0], [0,0,0]);
|
||||
setorigin(gib, pos);
|
||||
setorigin(gib, endpos);
|
||||
makevectors(dir);
|
||||
gib.velocity = v_forward * speed;
|
||||
gib.velocity += random(-1,1) * spread[0] * v_right;
|
||||
gib.velocity += random(-1,1) * spread[1] * v_up;
|
||||
gib.avelocity = vectoangles(gib.velocity);
|
||||
gib.movetype = MOVETYPE_BOUNCE;
|
||||
|
||||
|
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
Surface Data Specs
|
||||
|
||||
Scripts are formatted like our sound shaders:
|
||||
|
||||
typename
|
||||
{
|
||||
key/value pairs
|
||||
...
|
||||
}
|
||||
|
||||
Available keys are:
|
||||
"base" <string> what type to inherit
|
||||
"gamematerial" <char> material character, e.g. W for wood
|
||||
"climbable" <bool> ???
|
||||
"thickness" <float> non-solid, air (?) thickness
|
||||
"density" <int> material density in kg / m^3
|
||||
|
||||
"elasticity" <float> 0.0 - 1.0 ; soft to hard
|
||||
"friction" <float> friction multiplier
|
||||
"dampening" <float> drag multiplier
|
||||
"jumpfactor" <float> bouncyness?
|
||||
"maxspeedfactor" <float> maxvelocity?
|
||||
|
||||
"stepleft" <string> footstep left
|
||||
"stepright" <string> footstep right
|
||||
"bulletimpact" <string> sound shader to play on impact
|
||||
"scraperough" <string> sound shader to play on rough scraping
|
||||
"scrapesmooth" <string> sound shader to play on smooth scraping
|
||||
"impacthard" <string> sound shader for hard impacts
|
||||
"impactsoft" <string> sound shader for soft impacts
|
||||
|
||||
"shake" <string> sound to play when object is being shaken
|
||||
"strain" <string> sound to play when object is being strained?
|
||||
"break" <string> sound to play when object breaks
|
||||
"roll/rolling" <string> sound to play when object rolls
|
||||
|
||||
none of these are concerning us right now:
|
||||
"audioreflectivity" <float>
|
||||
"audiohardnessfactor" <float>
|
||||
"audioroughnessfactor" <float>
|
||||
"scrapeRoughThreshold" <float>
|
||||
"impactHardThreshold" <float>
|
||||
"audioHardMinVelocity" <float>
|
||||
*/
|
||||
#ifdef SERVER
|
||||
|
||||
typedef struct
|
||||
{
|
||||
string m_strBase;
|
||||
float m_flMaterial;
|
||||
float m_flThickness;
|
||||
float m_flDensity;
|
||||
float m_flElasticity;
|
||||
float m_flFriction;
|
||||
float m_flDampening;
|
||||
float m_flJumpFactor;
|
||||
float m_flMaxSpeedFactor;
|
||||
|
||||
string m_sndStepLeft;
|
||||
string m_sndStepRight;
|
||||
string m_sndBulletImpact;
|
||||
string m_sndScrapeRough;
|
||||
string m_sndScrapeSoft;
|
||||
string m_sndImpactHard;
|
||||
string m_sndImpactSoft;
|
||||
string m_sndShake;
|
||||
string m_sndStrain;
|
||||
string m_sndRoll;
|
||||
string m_sndBreak;
|
||||
} surfaceData_t;
|
||||
|
||||
/* entity will have to have a .surfdata field pointing to an id */
|
||||
surfaceData_t *g_surfdata;
|
||||
int g_surfdata_count;
|
||||
var hashtable g_hashsurfdata;
|
||||
|
||||
/* querying API */
|
||||
typedef enum
|
||||
{
|
||||
SURFDATA_MATERIAL,
|
||||
SURFDATA_THICKNESS,
|
||||
SURFDATA_DENSITY,
|
||||
SURFDATA_ELASTICITY,
|
||||
SURFDATA_FRICTION,
|
||||
SURFDATA_DAMPENING,
|
||||
SURFDATA_JUMPFACTOR,
|
||||
SURFDATA_MAXSPEEDFACTOR,
|
||||
SURFDATA_SND_STEPLEFT,
|
||||
SURFDATA_SND_STEPRIGHT,
|
||||
SURFDATA_SND_BULLETIMPACT,
|
||||
SURFDATA_SND_SCRAPEROUGH,
|
||||
SURFDATA_SND_SCRAPESOFT,
|
||||
SURFDATA_SND_IMPACTHARD,
|
||||
SURFDATA_SND_IMPACTSOFT,
|
||||
SURFDATA_SND_SHAKE,
|
||||
SURFDATA_SND_STRAIN,
|
||||
SURFDATA_SND_ROLL,
|
||||
SURFDATA_SND_BREAK,
|
||||
SURFDATA_FX_IMPACT,
|
||||
} surfinfo_t;
|
||||
|
||||
/* initialized SurfaceKit */
|
||||
void SurfData_Init(void);
|
||||
|
||||
/* Prepares an object for SurfaceKit initialization */
|
||||
void SurfData_SetStage(string type);
|
||||
|
||||
/* Finishes initialization, returns valid SurfaceKit id */
|
||||
int SurfData_Finish(void);
|
||||
|
||||
/* Call an impact effect against an entity surface */
|
||||
void SurfData_Impact(entity e, int fl, vector org, vector ang);
|
||||
|
||||
/* Get information from a Surface */
|
||||
__variant SurfData_GetInfo(int, int);
|
||||
#endif
|
|
@ -0,0 +1,437 @@
|
|||
/*
|
||||
* Copyright (c) 2016-2021 Marco Hladik <marco@icculus.org>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
|
||||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef SERVER
|
||||
float HLMaterials_Fetch(string);
|
||||
|
||||
/* takes a material id (e.g. 'W' for wood) and returns an breakmodel id */
|
||||
static materialType_t
|
||||
SurfData_IDtoMaterial(float mat)
|
||||
{
|
||||
switch (mat) {
|
||||
case MATID_GLASS:
|
||||
return GSMATERIAL_GLASS;
|
||||
break;
|
||||
case MATID_WOOD:
|
||||
return GSMATERIAL_WOOD;
|
||||
break;
|
||||
case MATID_METAL:
|
||||
return GSMATERIAL_METAL;
|
||||
break;
|
||||
case MATID_FLESH:
|
||||
return GSMATERIAL_FLESH;
|
||||
break;
|
||||
case MATID_CONCRETE:
|
||||
return GSMATERIAL_CINDER;
|
||||
break;
|
||||
case MATID_TILE:
|
||||
return GSMATERIAL_TILE;
|
||||
break;
|
||||
case MATID_COMPUTER:
|
||||
return GSMATERIAL_COMPUTER;
|
||||
break;
|
||||
case MATID_ROCK:
|
||||
return GSMATERIAL_ROCK;
|
||||
break;
|
||||
default:
|
||||
return GSMATERIAL_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
/* takes a material id (e.g. 'W' for wood) and returns an impact */
|
||||
static impactType_t
|
||||
SurfData_IDtoImpact(float mat)
|
||||
{
|
||||
switch (mat) {
|
||||
case MATID_GLASS:
|
||||
return IMPACT_GLASS;
|
||||
break;
|
||||
case MATID_WOOD:
|
||||
return IMPACT_WOOD;
|
||||
break;
|
||||
case MATID_METAL:
|
||||
return IMPACT_METAL;
|
||||
break;
|
||||
case MATID_FLESH:
|
||||
return IMPACT_FLESH;
|
||||
break;
|
||||
case MATID_CONCRETE:
|
||||
return IMPACT_CONCRETE;
|
||||
break;
|
||||
case MATID_TILE:
|
||||
return IMPACT_TILE;
|
||||
break;
|
||||
case MATID_COMPUTER:
|
||||
return IMPACT_COMPUTER;
|
||||
break;
|
||||
case MATID_GLASS:
|
||||
return IMPACT_GLASS;
|
||||
break;
|
||||
default:
|
||||
return IMPACT_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
/* takes a surfaceflag material bit and returns an impact */
|
||||
static impactType_t
|
||||
SurfData_SurfaceFlagtoImpact(int fl)
|
||||
{
|
||||
switch (fl) {
|
||||
case SURF_ALIEN:
|
||||
return IMPACT_ALIEN;
|
||||
case SURF_COMPUTER:
|
||||
return IMPACT_COMPUTER;
|
||||
case SURF_CONCRETE:
|
||||
return IMPACT_CONCRETE;
|
||||
case SURF_DIRT:
|
||||
return IMPACT_DIRT;
|
||||
case SURF_BLOODYFLESH:
|
||||
return IMPACT_FLESH;
|
||||
case SURF_FOLIAGE:
|
||||
return IMPACT_FOLIAGE;
|
||||
case SURF_GLASS:
|
||||
return IMPACT_GLASS;
|
||||
case SURF_GRATE:
|
||||
return IMPACT_GRATE;
|
||||
case SURF_METAL:
|
||||
return IMPACT_METAL;
|
||||
case SURF_SAND:
|
||||
return IMPACT_SAND;
|
||||
case SURF_SLOSH:
|
||||
return IMPACT_SLOSH;
|
||||
case SURF_SNOW:
|
||||
return IMPACT_SNOW;
|
||||
case SURF_TILE:
|
||||
return IMPACT_TILE;
|
||||
case SURF_VENT:
|
||||
return IMPACT_VENT;
|
||||
case SURF_WOOD:
|
||||
return IMPACT_WOOD;
|
||||
default:
|
||||
return IMPACT_DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
SurfData_ParseField(int i, int a)
|
||||
{
|
||||
switch (argv(0)) {
|
||||
case "base":
|
||||
g_surfdata[i].m_strBase = argv(1);
|
||||
break;
|
||||
case "gamematerial":
|
||||
string mat = argv(1);
|
||||
g_surfdata[i].m_flMaterial = str2chr(mat, 0);
|
||||
break;
|
||||
case "thickness":
|
||||
g_surfdata[i].m_flThickness = stof(argv(1));
|
||||
break;
|
||||
case "density":
|
||||
g_surfdata[i].m_flDensity = stof(argv(1));
|
||||
break;
|
||||
case "elasticity":
|
||||
g_surfdata[i].m_flElasticity = stof(argv(1));
|
||||
break;
|
||||
case "friction":
|
||||
g_surfdata[i].m_flFriction = stof(argv(1));
|
||||
break;
|
||||
case "dampening":
|
||||
g_surfdata[i].m_flDampening = stof(argv(1));
|
||||
break;
|
||||
case "jumpfactor":
|
||||
g_surfdata[i].m_flJumpFactor = stof(argv(1));
|
||||
break;
|
||||
case "maxspeedfactor":
|
||||
g_surfdata[i].m_flMaxSpeedFactor = stof(argv(1));
|
||||
break;
|
||||
case "stepleft":
|
||||
g_surfdata[i].m_sndStepLeft = argv(1);
|
||||
break;
|
||||
case "stepright":
|
||||
g_surfdata[i].m_sndStepRight = argv(1);
|
||||
break;
|
||||
case "bulletimpact":
|
||||
g_surfdata[i].m_sndBulletImpact = argv(1);
|
||||
break;
|
||||
case "scraperough":
|
||||
g_surfdata[i].m_sndScrapeRough = argv(1);
|
||||
break;
|
||||
case "scrapesmooth":
|
||||
g_surfdata[i].m_sndScrapeSoft = argv(1);
|
||||
break;
|
||||
case "impacthard":
|
||||
g_surfdata[i].m_sndImpactHard = argv(1);
|
||||
break;
|
||||
case "impactsoft":
|
||||
g_surfdata[i].m_sndImpactSoft = argv(1);
|
||||
break;
|
||||
case "shake":
|
||||
g_surfdata[i].m_sndShake = argv(1);
|
||||
break;
|
||||
case "strain":
|
||||
g_surfdata[i].m_sndStrain = argv(1);
|
||||
break;
|
||||
case "break":
|
||||
g_surfdata[i].m_sndRoll = argv(1);
|
||||
break;
|
||||
case "roll":
|
||||
case "rolling":
|
||||
g_surfdata[i].m_sndBreak = argv(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* concerned with dealing with keeping track of braces and parsing lines */
|
||||
static int
|
||||
SurfData_Parse(string line)
|
||||
{
|
||||
int c;
|
||||
string key;
|
||||
static string t_name;
|
||||
static int braced = 0;
|
||||
static int i;
|
||||
|
||||
c = tokenize_console(line);
|
||||
key = argv(0);
|
||||
|
||||
switch(key) {
|
||||
case "{":
|
||||
braced++;
|
||||
break;
|
||||
case "}":
|
||||
/* increase counter when done */
|
||||
if (t_name)
|
||||
i++;
|
||||
|
||||
braced--;
|
||||
t_name = "";
|
||||
break;
|
||||
default:
|
||||
if (braced == 1 && t_name != "") {
|
||||
SurfData_ParseField(i, c);
|
||||
} else if (braced == 0) {
|
||||
t_name = strtolower(line);
|
||||
hash_add(g_hashsurfdata, t_name, (int)i);
|
||||
}
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
SurfData_Load(string type)
|
||||
{
|
||||
int index;
|
||||
|
||||
if (!type)
|
||||
return -1;
|
||||
|
||||
type = strtolower(type);
|
||||
|
||||
index = (int)hash_get(g_hashsurfdata, type, -1);
|
||||
|
||||
if (index < 0) {
|
||||
crossprint(sprintf("^1 SurfData_Load: type %s is not defined\n", type));
|
||||
return -1;
|
||||
} else {
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
/* stripped down ParseLine that just counts how many slots we have to allocate */
|
||||
static void
|
||||
SurfData_CountLine(string line)
|
||||
{
|
||||
int c;
|
||||
string key;
|
||||
static string t_name;
|
||||
static int braced = 0;
|
||||
|
||||
c = tokenize_console(line);
|
||||
key = argv(0);
|
||||
|
||||
switch(key) {
|
||||
case "{":
|
||||
braced++;
|
||||
break;
|
||||
case "}":
|
||||
braced--;
|
||||
t_name = "";
|
||||
break;
|
||||
default:
|
||||
/* new definition starts */
|
||||
if (braced == 0) {
|
||||
t_name = strtolower(line);
|
||||
|
||||
if (t_name)
|
||||
g_surfdata_count++;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Public API functions */
|
||||
__variant
|
||||
SurfData_GetInfo(int i, int type)
|
||||
{
|
||||
if (i < 0)
|
||||
return __NULL__;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case SURFDATA_MATERIAL:
|
||||
return (__variant)SurfData_IDtoMaterial(g_surfdata[i].m_flMaterial);
|
||||
case SURFDATA_THICKNESS:
|
||||
return (__variant)g_surfdata[i].m_flThickness;
|
||||
case SURFDATA_DENSITY:
|
||||
return (__variant)g_surfdata[i].m_flDensity;
|
||||
case SURFDATA_ELASTICITY:
|
||||
return (__variant)g_surfdata[i].m_flElasticity;
|
||||
case SURFDATA_FRICTION:
|
||||
return (__variant)g_surfdata[i].m_flFriction;
|
||||
case SURFDATA_DAMPENING:
|
||||
return (__variant)g_surfdata[i].m_flDampening;
|
||||
case SURFDATA_JUMPFACTOR:
|
||||
return (__variant)g_surfdata[i].m_flJumpFactor;
|
||||
case SURFDATA_MAXSPEEDFACTOR:
|
||||
return (__variant)g_surfdata[i].m_flMaxSpeedFactor;
|
||||
case SURFDATA_SND_STEPLEFT:
|
||||
return (__variant)g_surfdata[i].m_sndStepLeft;
|
||||
case SURFDATA_SND_STEPRIGHT:
|
||||
return (__variant)g_surfdata[i].m_sndStepRight;
|
||||
case SURFDATA_SND_BULLETIMPACT:
|
||||
return (__variant)g_surfdata[i].m_sndBulletImpact;
|
||||
case SURFDATA_SND_SCRAPEROUGH:
|
||||
return (__variant)g_surfdata[i].m_sndScrapeRough;
|
||||
case SURFDATA_SND_SCRAPESOFT:
|
||||
return (__variant)g_surfdata[i].m_sndScrapeSoft;
|
||||
case SURFDATA_SND_IMPACTHARD:
|
||||
return (__variant)g_surfdata[i].m_sndImpactHard;
|
||||
case SURFDATA_SND_IMPACTSOFT:
|
||||
return (__variant)g_surfdata[i].m_sndImpactSoft;
|
||||
case SURFDATA_SND_SHAKE:
|
||||
return (__variant)g_surfdata[i].m_sndShake;
|
||||
case SURFDATA_SND_STRAIN:
|
||||
return (__variant)g_surfdata[i].m_sndStrain;
|
||||
case SURFDATA_SND_ROLL:
|
||||
return (__variant)g_surfdata[i].m_sndRoll;
|
||||
case SURFDATA_SND_BREAK:
|
||||
return (__variant)g_surfdata[i].m_sndBreak;
|
||||
case SURFDATA_FX_IMPACT:
|
||||
return (__variant)SurfData_IDtoImpact(g_surfdata[i].m_flMaterial);
|
||||
default:
|
||||
return __NULL__;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SurfData_Shutdown(void)
|
||||
{
|
||||
if (g_surfdata) {
|
||||
memfree(g_surfdata);
|
||||
}
|
||||
g_surfdata_count = 0;
|
||||
g_hashsurfdata = 0;
|
||||
}
|
||||
|
||||
void
|
||||
SurfData_Init(void)
|
||||
{
|
||||
filestream fh;
|
||||
string line;
|
||||
int index;
|
||||
|
||||
/* remove old data */
|
||||
SurfData_Shutdown();
|
||||
|
||||
index = g_surfdata_count;
|
||||
|
||||
/* create the hash-table if it doesn't exist */
|
||||
if (!g_hashsurfdata) {
|
||||
g_hashsurfdata = hash_createtab(2, HASH_ADD);
|
||||
}
|
||||
|
||||
/* Defaults go here */
|
||||
|
||||
fh = fopen("scripts/surfaceproperties.txt", FILE_READ);
|
||||
if (fh < 0) {
|
||||
print("^1[SURFDATA] Can't find surfaceproperties.txt\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* count content */
|
||||
while ((line = fgets(fh))) {
|
||||
SurfData_CountLine(line);
|
||||
}
|
||||
|
||||
/* alocate our stuff */
|
||||
g_surfdata = (surfaceData_t *)memalloc(sizeof(surfaceData_t) * g_surfdata_count);
|
||||
|
||||
fseek(fh, 0);
|
||||
|
||||
while ((line = fgets(fh))) {
|
||||
/* when we found it, quit */
|
||||
SurfData_Parse(line);
|
||||
}
|
||||
fclose(fh);
|
||||
}
|
||||
|
||||
static string g_curSurfData;
|
||||
void
|
||||
SurfData_SetStage(string type)
|
||||
{
|
||||
g_curSurfData = type;
|
||||
}
|
||||
|
||||
int
|
||||
SurfData_Finish(void)
|
||||
{
|
||||
string toload = g_curSurfData;
|
||||
g_curSurfData = __NULL__;
|
||||
|
||||
if (toload) {
|
||||
return SurfData_Load(toload);
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SurfData_Impact(entity e, int fl, vector org, vector ang)
|
||||
{
|
||||
if (e == world) { /* the static world */
|
||||
switch (serverkeyfloat("*bspversion")) {
|
||||
case BSPVER_HL:
|
||||
float surf;
|
||||
string tex_name;
|
||||
surf = getsurfacenearpoint(e, org);
|
||||
tex_name = Materials_FixName(getsurfacetexture(e, surf));
|
||||
FX_Impact(SurfData_IDtoImpact(HLMaterials_Fetch(tex_name)), org, ang);
|
||||
break;
|
||||
case BSPVER_Q3: /* Q3 */
|
||||
case BSPVER_RTCW: /* RtCW */
|
||||
case BSPVER_RBSP: /* RFVBSP */
|
||||
FX_Impact(SurfData_SurfaceFlagtoImpact(fl), org, ang);
|
||||
break;
|
||||
default:
|
||||
FX_Impact(IMPACT_DEFAULT, org, ang);
|
||||
}
|
||||
} else { /* props, entities */
|
||||
CBaseEntity foo = (CBaseEntity)e;
|
||||
FX_Impact(SurfData_GetInfo(foo.m_iMaterial, SURFDATA_FX_IMPACT), org, ang);
|
||||
}
|
||||
}
|
||||
#endif
|
Loading…
Reference in New Issue