diff options
| -rw-r--r-- | gamedata/engine.kv | 11 | ||||
| -rw-r--r-- | src/build/mkentprops.c | 13 | ||||
| -rw-r--r-- | src/engineapi.c | 14 | ||||
| -rw-r--r-- | src/gametype.h | 1 | 
4 files changed, 27 insertions, 12 deletions
| diff --git a/gamedata/engine.kv b/gamedata/engine.kv index 39fa1df..80caa74 100644 --- a/gamedata/engine.kv +++ b/gamedata/engine.kv @@ -26,16 +26,19 @@ vtidx_GetGameDirectory {  		2013 35  	}  	Client013 { -		L4Dx 36 // AND THEN THEY CHANGED IT BACK LATER! +		L4Dx 36 // AND THEN THEY CHANGED IT BACK LATER! (on 2.0.4.1)  		default 35 // <- most things have this!  	}  	Client012 37 // dmomm, ep1, ...  } -// TODO(compat): apparently this changed, in early versions it's NOT 99! -// Come up with some way to detect it properly!?  vtidx_GetEngineBuildNumber { -	//L4D2 99 +	L4D2 { +		Client013 99 +		//Client014 ??? // TODO(compat): find out what this (maybe 136?) +	}  } + +// VEngineServer  vtidx_PEntityOfEntIndex { OrangeBox 19 } // probably OE too but???  sz_edict { diff --git a/src/build/mkentprops.c b/src/build/mkentprops.c index 5dd2fea..e99873b 100644 --- a/src/build/mkentprops.c +++ b/src/build/mkentprops.c @@ -144,11 +144,11 @@ _( "static void initentprops(struct ServerClass *class) {")  F( "	for (int needclasses = %d; class; class = class->next) {", nclasses)  	char *else1 = "";  	for (struct class *c = classes.x[0]; c; c = c->hdr.x[0]) { -		// TODO(opt): some sort of PHF instead of chained strcmp, if we ever -		// have more than a few classes/properties? +		// TODO(opt): some sort of PHF or trie instead of chained strcmp, if we +		// ever have more than a few classes/properties?  F( "		%sif (!strcmp(class->name, \"%s\")) {", else1, c->name)  _( "			struct SendTable *st = class->table;") -				// christ this is awful :( +				// XXX: christ this is all awful :(  F( "			int needprops = %d;", c->props.sz)  _( "			for (struct SendProp *p = st->props; (char *)p -")  _( "					(char *)st->props < st->nprops * sz_SendProp;") @@ -159,7 +159,12 @@ _( "					p = mem_offset(p, sz_SendProp)) {")  F( "				%sif (!strcmp(*(const char **)mem_offset(p, off_SP_varname), \"%s\")) {",  		else2, (*pp)->propname) // ugh  F( "					has_%s = true;", (*pp)->varname) -F( "					%s = *(int *)mem_offset(p, off_SP_offset);", (*pp)->varname) +			// from AM L4D2 SDK headers: +			// > SENDPROP_VECTORELEM makes [offset] negative to start with so we +			// > can detect that and set the SPROP_IS_VECTOR_ELEM flag. +			// apparently if we're loaded via VDF, it hasn't been flipped back +			// yet. just calling abs() on it as an easy solution. +F( "					%s = abs(*(int *)mem_offset(p, off_SP_offset));", (*pp)->varname)  _( "					if (!--needprops) break;")  _( "				}")  			else2 = "else "; diff --git a/src/engineapi.c b/src/engineapi.c index 369bebd..ec3d857 100644 --- a/src/engineapi.c +++ b/src/engineapi.c @@ -15,6 +15,7 @@   */  #include <stdbool.h> // used in generated code +#include <stdlib.h> // "  #include <string.h> // "  #include "con_.h" @@ -43,6 +44,8 @@ void *globalvars;  DECL_VFUNC_DYN(void *, GetAllServerClasses)  DECL_VFUNC_DYN(int, GetEngineBuildNumber) +DECL_VFUNC(int, GetEngineBuildNumber_newl4d2, 99) // duping gamedata entry, yuck +  #include <entpropsinit.gen.h>  bool engineapi_init(int pluginver) { @@ -84,9 +87,13 @@ bool engineapi_init(int pluginver) {  		_gametype_tag |= _gametype_tag_Portal1;  	} -	// TERRIBLE HACK: TODO(compat): come up with a better method later -	if (GAMETYPE_MATCHES(L4D2) && os_access(OS_LIT( -			"update/maps/c14m1_junkyard.bsp"), R_OK) != -1) { +	// Ugly HACK: we want to call GetEngineBuildNumber to find out if we're on a +	// Last Stand version (because they changed entity vtables for some reason), +	// but that function also got moved in 2.0.4.1 which means we can't call it +	// till gamedata is set up, so we have to have a bit of redundant logic here +	// to bootstrap things. +	if (GAMETYPE_MATCHES(L4D2) && GAMETYPE_MATCHES(Client013) && +			VCALL(engclient, GetEngineBuildNumber_newl4d2) >= 2200) {  		_gametype_tag |= _gametype_tag_TheLastStand;  	} @@ -100,7 +107,6 @@ bool engineapi_init(int pluginver) {  			has_off_SP_varname && has_off_SP_offset) {  		initentprops(VCALL(srvdll, GetAllServerClasses));  	} -  	return true;  } diff --git a/src/gametype.h b/src/gametype.h index c825ee6..2464000 100644 --- a/src/gametype.h +++ b/src/gametype.h @@ -59,6 +59,7 @@ extern u64 _gametype_tag;  #define _gametype_tag_L4Dbased	(_gametype_tag_L4Dx | _gametype_tag_Portal2)  #define _gametype_tag_OrangeBoxbased \  	(_gametype_tag_OrangeBox | _gametype_tag_2013) +#define _gametype_tag_Portal (_gametype_tag_Portal1 | _gametype_tag_Portal2)  #define GAMETYPE_MATCHES(x) !!(_gametype_tag & (_gametype_tag_##x)) | 
