From 36fdd443d25faa6437f6d4b3394c9b26831c2cdc Mon Sep 17 00:00:00 2001 From: Marco Cawthorne Date: Wed, 26 Oct 2022 12:50:08 -0700 Subject: [PATCH] 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. --- src/botlib/bot_combat.qc | 12 ++- src/client/entry.qc | 1 + src/client/event.qc | 3 + src/shared/NSMaterial.qc | 2 +- src/shared/entities.h | 10 +- src/shared/events.h | 1 + src/shared/surfaceproperties.h | 10 +- src/shared/surfaceproperties.qc | 179 ++++++++++++-------------------- 8 files changed, 95 insertions(+), 123 deletions(-) diff --git a/src/botlib/bot_combat.qc b/src/botlib/bot_combat.qc index a3ae740c..d6445ce2 100644 --- a/src/botlib/bot_combat.qc +++ b/src/botlib/bot_combat.qc @@ -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; diff --git a/src/client/entry.qc b/src/client/entry.qc index 2cd63dce..af1681d0 100644 --- a/src/client/entry.qc +++ b/src/client/entry.qc @@ -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"); diff --git a/src/client/event.qc b/src/client/event.qc index a8d1a918..c645d4a4 100644 --- a/src/client/event.qc +++ b/src/client/event.qc @@ -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; diff --git a/src/shared/NSMaterial.qc b/src/shared/NSMaterial.qc index 29c55d87..c7eaf971 100644 --- a/src/shared/NSMaterial.qc +++ b/src/shared/NSMaterial.qc @@ -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; diff --git a/src/shared/entities.h b/src/shared/entities.h index 4781824a..185f0656 100644 --- a/src/shared/entities.h +++ b/src/shared/entities.h @@ -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++; } diff --git a/src/shared/events.h b/src/shared/events.h index 5916a2c8..d814e7b5 100644 --- a/src/shared/events.h +++ b/src/shared/events.h @@ -49,5 +49,6 @@ enum EV_CHAT_VOX, EV_VIEWMODEL, EV_CLEARDECALS, + EV_SURFIMPACT, EV_SEPARATOR }; diff --git a/src/shared/surfaceproperties.h b/src/shared/surfaceproperties.h index e13b8b4e..ebd36013 100644 --- a/src/shared/surfaceproperties.h +++ b/src/shared/surfaceproperties.h @@ -28,6 +28,7 @@ Available keys are: "base" what type to inherit "gamematerial" material character, e.g. W for wood + which are looked up in scripts/decals.txt at a later time. "climbable" ??? "thickness" non-solid, air (?) thickness "density" material density in kg / m^3 @@ -59,7 +60,6 @@ "impactHardThreshold" "audioHardMinVelocity" */ -#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 \ No newline at end of file diff --git a/src/shared/surfaceproperties.qc b/src/shared/surfaceproperties.qc index 72049d7b..0c8f337d 100644 --- a/src/shared/surfaceproperties.qc +++ b/src/shared/surfaceproperties.qc @@ -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 +}