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:
Marco Cawthorne 2022-10-26 12:50:08 -07:00
parent df794ef44d
commit 36fdd443d2
Signed by: eukara
GPG Key ID: CE2032F0A2882A22
8 changed files with 95 additions and 123 deletions

View File

@ -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;

View File

@ -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");

View File

@ -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;

View File

@ -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;

View File

@ -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++;
}

View File

@ -49,5 +49,6 @@ enum
EV_CHAT_VOX,
EV_VIEWMODEL,
EV_CLEARDECALS,
EV_SURFIMPACT,
EV_SEPARATOR
};

View File

@ -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

View File

@ -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
}