Change 'material' over to 'surfaceprop'. Implement new networked event EV_SURFIMPACT.
Surfaceproperty impacts are now fully done on the client. Server has no concept of impacts beyond the point of announcing them. The next step: NSTraceAttack should be fully shared between client/server so that the local player doesn't need to be told about their own EV_SURFIMPACT events by the server, thus saving a bit of bandwidth.
This commit is contained in:
parent
df794ef44d
commit
36fdd443d2
8 changed files with 95 additions and 123 deletions
|
@ -122,28 +122,30 @@ bot::WeaponAttack(void)
|
|||
}
|
||||
|
||||
var float g_botalert_timer;
|
||||
|
||||
void
|
||||
BotLib_Alert(vector pos, float radius, float t)
|
||||
{
|
||||
CGameRules rules = g_grMode;
|
||||
|
||||
/* sometimes many alert-sounds happen at once... we don't really want that */
|
||||
/* sometimes many alert-sounds happen at once... we don't really want
|
||||
* that */
|
||||
if (g_botalert_timer > time)
|
||||
return;
|
||||
|
||||
for (entity w = world; (w = find(w, ::targetname, "_nuclide_bot_"));) {
|
||||
for (entity w = world; (w = find(w,::targetname, "_nuclide_bot_"));) {
|
||||
/* out of radius */
|
||||
if (vlen(pos - w.origin) > radius)
|
||||
continue;
|
||||
|
||||
bot f = (bot)w;
|
||||
bot f = (bot) w;
|
||||
|
||||
/* they already got a target of some kind */
|
||||
if (f.m_eTarget)
|
||||
continue;
|
||||
|
||||
/* if they're our friend... ignore*/
|
||||
if (rules.IsTeamplay())
|
||||
/* if they're our friend... ignore */
|
||||
if (rules.IsTeamplay())
|
||||
if (w.team == t)
|
||||
continue;
|
||||
|
||||
|
|
|
@ -52,6 +52,7 @@ CSQC_Init(float apilevel, string enginename, float engineversion)
|
|||
|
||||
/* Sound shaders */
|
||||
Sound_Init();
|
||||
SurfData_Init();
|
||||
PropData_Init();
|
||||
precache_sound("common/wpn_hudon.wav");
|
||||
precache_sound("common/wpn_hudoff.wav");
|
||||
|
|
|
@ -118,6 +118,9 @@ Event_Parse(float type)
|
|||
g_view.SetCameraAngle(a);
|
||||
g_view.SetClientAngle(a);
|
||||
break;
|
||||
case EV_SURFIMPACT:
|
||||
SurfData_Impact_Parse();
|
||||
break;
|
||||
case EV_CLEARDECALS:
|
||||
CMD_Cleardecals();
|
||||
break;
|
||||
|
|
|
@ -65,7 +65,7 @@ Materials_LoadFromMat(string filename)
|
|||
command = strtolower(argv(0));
|
||||
parameters = argv(1);
|
||||
|
||||
if (command == "material") {
|
||||
if (command == "surfaceprop") {
|
||||
hash_add(g_hashMaterials, materialname, parameters, EV_STRING);
|
||||
print(sprintf("added Material %S type %S\n", materialname, parameters));
|
||||
break;
|
||||
|
|
|
@ -55,7 +55,9 @@ Returns the closest point entity of a given classname.
|
|||
world means it failed. most likely.
|
||||
=================
|
||||
*/
|
||||
entity Entity_FindClosest(entity target, string cname) {
|
||||
entity
|
||||
Entity_FindClosest(entity target, string cname)
|
||||
{
|
||||
entity best = world;
|
||||
float bestdist;
|
||||
float dist;
|
||||
|
@ -74,6 +76,7 @@ entity Entity_FindClosest(entity target, string cname) {
|
|||
return best;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
Entity_SelectRandom
|
||||
|
@ -83,13 +86,14 @@ Check for world at all times. If world is returned then the given classname
|
|||
will most likely never return anything valid.
|
||||
=================
|
||||
*/
|
||||
entity Entity_SelectRandom(string cname)
|
||||
entity
|
||||
Entity_SelectRandom(string cname)
|
||||
{
|
||||
entity spot = world;
|
||||
float max = 0;
|
||||
|
||||
/* count our max count */
|
||||
for (entity e = world;(e = find(e, ::classname, cname));) {
|
||||
for (entity e = world; (e = find(e,::classname, cname));) {
|
||||
max++;
|
||||
}
|
||||
|
||||
|
|
|
@ -49,5 +49,6 @@ enum
|
|||
EV_CHAT_VOX,
|
||||
EV_VIEWMODEL,
|
||||
EV_CLEARDECALS,
|
||||
EV_SURFIMPACT,
|
||||
EV_SEPARATOR
|
||||
};
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
Available keys are:
|
||||
"base" <string> what type to inherit
|
||||
"gamematerial" <char> material character, e.g. W for wood
|
||||
which are looked up in scripts/decals.txt at a later time.
|
||||
"climbable" <bool> ???
|
||||
"thickness" <float> non-solid, air (?) thickness
|
||||
"density" <int> material density in kg / m^3
|
||||
|
@ -59,7 +60,6 @@
|
|||
"impactHardThreshold" <float>
|
||||
"audioHardMinVelocity" <float>
|
||||
*/
|
||||
#ifdef SERVER
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -86,6 +86,8 @@ typedef struct
|
|||
string m_sndBreak;
|
||||
|
||||
string m_fxBulletImpact;
|
||||
float m_fxBulletImpactID;
|
||||
string _name;
|
||||
} surfaceData_t;
|
||||
|
||||
/* entity will have to have a .surfdata field pointing to an id */
|
||||
|
@ -116,6 +118,7 @@ typedef enum
|
|||
SURFDATA_SND_ROLL,
|
||||
SURFDATA_SND_BREAK,
|
||||
SURFDATA_FX_BULLETIMPACT,
|
||||
SURFDATA_FX_BULLETIMPACTID
|
||||
} surfinfo_t;
|
||||
|
||||
/* initialized SurfaceKit */
|
||||
|
@ -134,4 +137,7 @@ void SurfData_Impact(entity e, int fl, vector org, vector ang);
|
|||
|
||||
/* Get information from a Surface */
|
||||
__variant SurfData_GetInfo(int, int);
|
||||
#endif
|
||||
|
||||
#ifdef CLIENT
|
||||
void SurfData_Impact_Parse(void);
|
||||
#endif
|
|
@ -14,104 +14,6 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef SERVER
|
||||
/* takes a material id (e.g. 'W' for wood) and returns an breakmodel id */
|
||||
static materialType_t
|
||||
SurfData_IDtoMaterial(float mat)
|
||||
{
|
||||
#if 0
|
||||
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;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* takes a material id (e.g. 'W' for wood) and returns an impact */
|
||||
static impactType_t
|
||||
SurfData_IDtoImpact(float mat)
|
||||
{
|
||||
#if 0
|
||||
switch (mat) {
|
||||
case MATID_GLASS:
|
||||
return IMPACT_GLASS;
|
||||
break;
|
||||
case MATID_WOOD:
|
||||
return IMPACT_WOOD;
|
||||
break;
|
||||
case MATID_GRATE:
|
||||
return IMPACT_GRATE;
|
||||
break;
|
||||
case MATID_METAL:
|
||||
return IMPACT_METAL;
|
||||
break;
|
||||
case MATID_VENT:
|
||||
return IMPACT_VENT;
|
||||
break;
|
||||
case MATID_BLOODYFLESH:
|
||||
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;
|
||||
case MATID_DIRT:
|
||||
return IMPACT_DIRT;
|
||||
break;
|
||||
case MATID_FOLIAGE:
|
||||
return IMPACT_FOLIAGE;
|
||||
break;
|
||||
case MATID_SAND:
|
||||
return IMPACT_SAND;
|
||||
break;
|
||||
case MATID_SNOW:
|
||||
return IMPACT_SNOW;
|
||||
break;
|
||||
case MATID_SLOSH:
|
||||
return IMPACT_SLOSH;
|
||||
break;
|
||||
case MATID_ALIEN:
|
||||
return IMPACT_ALIEN;
|
||||
break;
|
||||
default:
|
||||
return IMPACT_DEFAULT;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* takes a surfaceflag material bit and returns an impact */
|
||||
static impactType_t
|
||||
SurfData_SurfaceFlagtoImpact(int fl)
|
||||
|
@ -220,6 +122,9 @@ SurfData_ParseField(int i, int a)
|
|||
break;
|
||||
case "fx_bulletimpact":
|
||||
g_surfdata[i].m_fxBulletImpact = argv(1);
|
||||
#ifdef CLIENT
|
||||
g_surfdata[i].m_fxBulletImpactID = particleeffectnum(g_surfdata[i].m_fxBulletImpact);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -254,6 +159,7 @@ SurfData_Parse(string line)
|
|||
SurfData_ParseField(i, c);
|
||||
} else if (braced == 0) {
|
||||
t_name = strtolower(line);
|
||||
g_surfdata[i]._name = t_name;
|
||||
hash_add(g_hashsurfdata, t_name, (int)i);
|
||||
}
|
||||
}
|
||||
|
@ -330,6 +236,19 @@ SurfData_TexToSurfData(string tex_name)
|
|||
return SurfData_Load(mat);
|
||||
}
|
||||
|
||||
string
|
||||
SurfData_DataForMatID(float matid)
|
||||
{
|
||||
int id = -1;
|
||||
for (int i = 0; i < g_surfdata_count; i++) {
|
||||
if (matid == g_surfdata[i].m_flMaterial) {
|
||||
return g_surfdata[i]._name;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Public API functions */
|
||||
__variant
|
||||
SurfData_GetInfo(int i, int type)
|
||||
|
@ -340,7 +259,7 @@ SurfData_GetInfo(int i, int type)
|
|||
switch (type)
|
||||
{
|
||||
case SURFDATA_MATERIAL:
|
||||
return (__variant)SurfData_IDtoMaterial(g_surfdata[i].m_flMaterial);
|
||||
return __NULL__;
|
||||
case SURFDATA_THICKNESS:
|
||||
return (__variant)g_surfdata[i].m_flThickness;
|
||||
case SURFDATA_DENSITY:
|
||||
|
@ -379,6 +298,8 @@ SurfData_GetInfo(int i, int type)
|
|||
return (__variant)g_surfdata[i].m_sndBreak;
|
||||
case SURFDATA_FX_BULLETIMPACT:
|
||||
return (__variant)g_surfdata[i].m_fxBulletImpact;
|
||||
case SURFDATA_FX_BULLETIMPACTID:
|
||||
return (__variant)g_surfdata[i].m_fxBulletImpactID;
|
||||
default:
|
||||
return __NULL__;
|
||||
}
|
||||
|
@ -488,9 +409,54 @@ SurfData_Finish(void)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SurfData_Impact_Net(entity e, vector org)
|
||||
{
|
||||
#ifdef CLIENT
|
||||
string tex_name = getsurfacetexture(world, getsurfacenearpoint(world, org));
|
||||
|
||||
string impactsfx = SurfData_GetInfo(SurfData_TexToSurfData(tex_name), SURFDATA_SND_BULLETIMPACT);
|
||||
|
||||
string impactfx = SurfData_GetInfo(SurfData_TexToSurfData(tex_name), SURFDATA_FX_BULLETIMPACT);
|
||||
float impactid = SurfData_GetInfo(SurfData_TexToSurfData(tex_name), SURFDATA_FX_BULLETIMPACTID);
|
||||
|
||||
NSLog("ent: %s texture: %s", e.classname, tex_name);
|
||||
NSLog("playing impact sfx %S at %v", impactsfx, org);
|
||||
NSLog("emitting impact fx %S at %v", impactfx, org);
|
||||
|
||||
Sound_PlayAt(org, impactsfx);
|
||||
pointparticles( impactid, org, [0,0,0], 1 );
|
||||
#else
|
||||
WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET);
|
||||
WriteByte(MSG_MULTICAST, EV_SURFIMPACT);
|
||||
WriteCoord(MSG_MULTICAST, org[0]);
|
||||
WriteCoord(MSG_MULTICAST, org[1]);
|
||||
WriteCoord(MSG_MULTICAST, org[2]);
|
||||
WriteEntity(MSG_MULTICAST, e);
|
||||
multicast(org, MULTICAST_PVS);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef CLIENT
|
||||
void
|
||||
SurfData_Impact_Parse(void)
|
||||
{
|
||||
entity surfnum = __NULL__;
|
||||
vector impactorg = [0.0f, 0.0f, 0.0f];
|
||||
|
||||
impactorg[0] = readcoord();
|
||||
impactorg[1] = readcoord();
|
||||
impactorg[2] = readcoord();
|
||||
surfnum = findfloat(world, ::entnum, readentitynum()-1);
|
||||
SurfData_Impact_Net(surfnum, impactorg);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
SurfData_Impact(entity e, int fl, vector org, vector ang)
|
||||
{
|
||||
#ifdef SERVER
|
||||
static void SurfData_Impact_SurfaceParm(entity e, int fl, vector org, vector ang) {
|
||||
/* provided for backwards compatibility with the old surfaceflag based materials */
|
||||
#ifdef OLD_MATERIALS
|
||||
|
@ -505,18 +471,7 @@ SurfData_Impact(entity e, int fl, vector org, vector ang)
|
|||
FX_Impact(IMPACT_DEFAULT, org, ang);
|
||||
}
|
||||
#else
|
||||
float surf = getsurfacenearpoint(e, org);
|
||||
string tex_name = getsurfacetexture(e, surf);
|
||||
|
||||
string impactsfx = SurfData_GetInfo(SurfData_TexToSurfData(tex_name), SURFDATA_SND_BULLETIMPACT);
|
||||
|
||||
string impactfx = SurfData_GetInfo(SurfData_TexToSurfData(tex_name), SURFDATA_FX_BULLETIMPACT);
|
||||
|
||||
NSLog("playing impact sfx %S at %v", impactsfx, org);
|
||||
NSLog("playing impact fx %S at %v", impactfx, org);
|
||||
|
||||
Sound_PlayAt(org, impactsfx);
|
||||
|
||||
SurfData_Impact_Net(e, org);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -531,5 +486,5 @@ SurfData_Impact(entity e, int fl, vector org, vector ang)
|
|||
else
|
||||
SurfData_Impact_SurfaceParm(e, fl, org, ang);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue