From c1a098b4932bfe08620c76edc237ced5082cfbc0 Mon Sep 17 00:00:00 2001 From: Marco Cawthorne Date: Fri, 17 Mar 2023 11:35:27 -0700 Subject: [PATCH] Impacts against models will now be tested against their materials. No more bitfield surfaceparm lookups in compiled models - simply set the surfaceprop inside the used material file. However, since we don't get the full material path currently, the material has to be in the same dir as the model. This may change if FTEQW exposes the full impact material path. --- src/client/event.qc | 3 + src/gs-entbase/shared/worldspawn.qc | 2 + src/shared/defs.h | 19 ++++ src/shared/events.h | 1 + src/shared/materials.qc | 12 ++- src/shared/surfaceproperties.h | 1 + src/shared/surfaceproperties.qc | 135 +++++++++++++--------------- 7 files changed, 100 insertions(+), 73 deletions(-) diff --git a/src/client/event.qc b/src/client/event.qc index 308503d7..f9afb9ce 100644 --- a/src/client/event.qc +++ b/src/client/event.qc @@ -178,6 +178,9 @@ Event_Parse(float type) case EV_SURFIMPACT: SurfData_Impact_Parse(); break; + case EV_SURFIMPACTID: + SurfData_ImpactID_Parse(); + break; case EV_DECALGROUP: DecalGroups_Receive(); break; diff --git a/src/gs-entbase/shared/worldspawn.qc b/src/gs-entbase/shared/worldspawn.qc index 8c7dddf4..29c58ad0 100644 --- a/src/gs-entbase/shared/worldspawn.qc +++ b/src/gs-entbase/shared/worldspawn.qc @@ -82,6 +82,8 @@ worldspawn::Spawned(void) cvar_set("r_hdr_irisadaptation_multiplier", ftos(g_flHDRIrisMultiplier)); cvar_set("r_hdr_irisadaptation_fade_up", ftos(g_flHDRIrisFadeUp)); cvar_set("r_hdr_irisadaptation_fade_down", ftos(g_flHDRIrisFadeDown)); + + Destroy(); } void diff --git a/src/shared/defs.h b/src/shared/defs.h index bfda0250..269e53b2 100644 --- a/src/shared/defs.h +++ b/src/shared/defs.h @@ -333,3 +333,22 @@ crandom(void) return ((random() - 0.5f) * 2.0f); } +string +dirname(string input) +{ + if (!input) { + return ""; + } + + int c = tokenizebyseparator(input, "/", "\\ ", "!"); + string newpath = ""; + + for (int i = 0; i < (c-1); i++) { + newpath = sprintf("%s/%s", newpath, argv(i)); + } + + /* Kill the first / */ + newpath = substring(newpath, 1, strlen(newpath)-1); + + return newpath; +} diff --git a/src/shared/events.h b/src/shared/events.h index 6b742ed0..eb7f29a4 100644 --- a/src/shared/events.h +++ b/src/shared/events.h @@ -51,6 +51,7 @@ enum EV_VIEWMODEL, EV_CLEARDECALS, EV_SURFIMPACT, + EV_SURFIMPACTID, EV_DECALGROUP, EV_BREAKMODEL, EV_SEPARATOR diff --git a/src/shared/materials.qc b/src/shared/materials.qc index 21702bc7..30bd84d1 100644 --- a/src/shared/materials.qc +++ b/src/shared/materials.qc @@ -67,7 +67,7 @@ Materials_LoadFromMat(string filename) if (command == "surfaceprop") { hash_add(g_hashMaterials, materialname, parameters, EV_STRING); - //print(sprintf("added Material %S type %S\n", materialname, parameters)); + print(sprintf("added Material %S type %S\n", materialname, parameters)); break; } } @@ -232,5 +232,15 @@ Materials_Init(void) for (int i = 0; i < search_getsize(searchy); i++) { Materials_LoadFromMat(search_getfilename(searchy, i)); } + search_end(searchy); + + /* don't judge me for this abhorrent path, father */ + searchhandle mdlsearch = search_begin("models/*/*/*/*.mat:models/*/*/*.mat:models/*/*.mat:models/*.mat", SEARCH_MULTISEARCH | SEARCH_NAMESORT, TRUE); + for (int i = 0; i < search_getsize(mdlsearch); i++) { + string mdlmat = search_getfilename(mdlsearch, i); + printf("model: %S\n", mdlmat); + Materials_LoadFromMat(mdlmat); + } + search_end(mdlsearch); } } diff --git a/src/shared/surfaceproperties.h b/src/shared/surfaceproperties.h index 32b02c30..ee218bc1 100644 --- a/src/shared/surfaceproperties.h +++ b/src/shared/surfaceproperties.h @@ -139,4 +139,5 @@ __variant SurfData_GetInfo(int, int); #ifdef CLIENT void SurfData_Impact_Parse(void); +void SurfData_ImpactID_Parse(void); #endif \ No newline at end of file diff --git a/src/shared/surfaceproperties.qc b/src/shared/surfaceproperties.qc index 82742e95..836aaf19 100644 --- a/src/shared/surfaceproperties.qc +++ b/src/shared/surfaceproperties.qc @@ -14,46 +14,6 @@ * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* 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) { @@ -397,24 +357,10 @@ SurfData_Finish(void) } +#ifdef SERVER void SurfData_Impact_Net(entity e, vector org) { -#ifdef CLIENT - string tex_name = getsurfacetexture(e, getsurfacenearpoint(e, 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]); @@ -422,10 +368,26 @@ SurfData_Impact_Net(entity e, vector org) WriteCoord(MSG_MULTICAST, org[2]); WriteEntity(MSG_MULTICAST, e); multicast(org, MULTICAST_PVS); -#endif } +void +SurfData_ImpactID_Net(int id, vector org, vector ang) +{ + WriteByte(MSG_MULTICAST, SVC_CGAMEPACKET); + WriteByte(MSG_MULTICAST, EV_SURFIMPACTID); + WriteCoord(MSG_MULTICAST, org[0]); + WriteCoord(MSG_MULTICAST, org[1]); + WriteCoord(MSG_MULTICAST, org[2]); + WriteCoord(MSG_MULTICAST, ang[0]); + WriteCoord(MSG_MULTICAST, ang[1]); + WriteCoord(MSG_MULTICAST, ang[2]); + WriteInt(MSG_MULTICAST, id); + multicast(org, MULTICAST_PVS); +} +#endif + #ifdef CLIENT +/** Called by EV_SURFIMPACT */ void SurfData_Impact_Parse(void) { @@ -436,7 +398,44 @@ SurfData_Impact_Parse(void) impactorg[1] = readcoord(); impactorg[2] = readcoord(); surfnum = findfloat(world, ::entnum, readentitynum()-1); - SurfData_Impact_Net(surfnum, impactorg); + + string tex_name = getsurfacetexture(surfnum, getsurfacenearpoint(surfnum, impactorg)); + + 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("SurfData_Impact_Parse:"); + NSLog("\tent: %S texture: %S", surfnum.classname, tex_name); + NSLog("\tplaying impact sfx %S at %v", impactsfx, impactorg); + NSLog("\temitting impact fx %S at %v", impactfx, impactorg); + + Sound_PlayAt(impactorg, impactsfx); + pointparticles( impactid, impactorg, [0,0,0], 1 ); +} + +/** Called by EV_SURFIMPACTID */ +void +SurfData_ImpactID_Parse(void) +{ + int matid = __NULL__; + vector impactorg = g_vec_null; + vector impactang = g_vec_null; + + impactorg[0] = readcoord(); + impactorg[1] = readcoord(); + impactorg[2] = readcoord(); + + impactang[0] = readcoord(); + impactang[1] = readcoord(); + impactang[2] = readcoord(); + matid = readint(); + + string impactsfx = SurfData_GetInfo(matid, SURFDATA_SND_BULLETIMPACT); + float impactid = SurfData_GetInfo(matid, SURFDATA_FX_BULLETIMPACTID); + Sound_PlayAt(impactorg, impactsfx); + pointparticles( impactid, impactorg, normalize(impactang), 1 ); } #endif @@ -445,26 +444,18 @@ 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 - switch (serverkeyfloat("*bspversion")) { - case BSPVER_Q3: /* Q3 */ - case BSPVER_RTCW: /* RtCW */ - case BSPVER_RBSP: /* RFVBSP */ - fl &= ~SURF_MASK; - FX_Impact(SurfData_SurfaceFlagtoImpact(fl), org, ang); - break; - default: - FX_Impact(IMPACT_DEFAULT, org, ang); - } - #else SurfData_Impact_Net(e, org); - #endif } /* the static world */ if (e == world || e.takedamage == DAMAGE_NO) { - SurfData_Impact_SurfaceParm(e, fl, org, ang); + if (trace_surfacename != "") { + string n = strcat(dirname(e.model), "/", trace_surfacename); + int texdata = SurfData_TexToSurfData(n); + NSLog("SurfData_Impact: %S %i\n", n, texdata); + SurfData_ImpactID_Net(texdata, org, ang); + } else + SurfData_Impact_SurfaceParm(e, fl, org, ang); } else { /* anything with takedamage = DAMAGE_YES is a NSurfacePropEntity. */ NSSurfacePropEntity foo = (NSSurfacePropEntity)e;