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.
This commit is contained in:
Marco Cawthorne 2023-03-17 11:35:27 -07:00
parent a52d7d3bbc
commit c1a098b493
Signed by: eukara
GPG Key ID: CE2032F0A2882A22
7 changed files with 100 additions and 73 deletions

View File

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

View File

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

View File

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

View File

@ -51,6 +51,7 @@ enum
EV_VIEWMODEL,
EV_CLEARDECALS,
EV_SURFIMPACT,
EV_SURFIMPACTID,
EV_DECALGROUP,
EV_BREAKMODEL,
EV_SEPARATOR

View File

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

View File

@ -139,4 +139,5 @@ __variant SurfData_GetInfo(int, int);
#ifdef CLIENT
void SurfData_Impact_Parse(void);
void SurfData_ImpactID_Parse(void);
#endif

View File

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