Changed the pf_clientstat function and parameters to match the ordering originally documented in the ext_csqc extension I posted on wiki.quakesrc.org, as per krimzon's recommendation. Updated qclib to support querying fields based on their offset rather than purely a name basis, to support the clientstat change.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@2869 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
ae0a8461b7
commit
7584ae2e34
6 changed files with 122 additions and 55 deletions
|
@ -292,6 +292,26 @@ char *PR_VarString (progfuncs_t *progfuncs, int first)
|
|||
return out;
|
||||
}
|
||||
|
||||
int PR_QueryField (progfuncs_t *progfuncs, unsigned int fieldoffset, etype_t *type, char **name, evalc_t *fieldcache)
|
||||
{
|
||||
fdef_t *var;
|
||||
var = ED_FieldAtOfs(progfuncs, fieldoffset);
|
||||
if (!var)
|
||||
return false;
|
||||
|
||||
if (type)
|
||||
*type = var->type & ~(DEF_SAVEGLOBAL|DEF_SHARED);
|
||||
if (name)
|
||||
*name = var->name;
|
||||
if (fieldcache)
|
||||
{
|
||||
fieldcache->ofs32 = var;
|
||||
fieldcache->varname = var->name;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
eval_t *GetEdictFieldValue(progfuncs_t *progfuncs, struct edict_s *ed, char *name, evalc_t *cache)
|
||||
{
|
||||
fdef_t *var;
|
||||
|
@ -312,6 +332,9 @@ eval_t *GetEdictFieldValue(progfuncs_t *progfuncs, struct edict_s *ed, char *nam
|
|||
return NULL;
|
||||
}
|
||||
cache->ofs32 = var;
|
||||
cache->varname = var->name;
|
||||
if (!ed)
|
||||
return (void*)~0; //something not null
|
||||
return (eval_t *) &(((int*)(((edictrun_t*)ed)->fields))[var->ofs]);
|
||||
}
|
||||
if (cache->ofs32 == NULL)
|
||||
|
@ -545,7 +568,9 @@ progfuncs_t deffuncs = {
|
|||
PR_AllocTempString,
|
||||
|
||||
PR_StringToProgs,
|
||||
PR_StringToNative
|
||||
PR_StringToNative,
|
||||
0,
|
||||
PR_QueryField
|
||||
};
|
||||
#undef printf
|
||||
|
||||
|
|
|
@ -436,6 +436,7 @@ ddef32_t *ED_FindTypeGlobalFromProgs32 (progfuncs_t *progfuncs, char *name, prog
|
|||
ddef16_t *ED_FindGlobalFromProgs16 (progfuncs_t *progfuncs, char *name, progsnum_t prnum);
|
||||
ddef32_t *ED_FindGlobalFromProgs32 (progfuncs_t *progfuncs, char *name, progsnum_t prnum);
|
||||
fdef_t *ED_FindField (progfuncs_t *progfuncs, char *name);
|
||||
fdef_t *ED_FieldAtOfs (progfuncs_t *progfuncs, unsigned int ofs);
|
||||
dfunction_t *ED_FindFunction (progfuncs_t *progfuncs, char *name, progsnum_t *pnum, progsnum_t fromprogs);
|
||||
func_t PR_FindFunc(progfuncs_t *progfncs, char *funcname, progsnum_t pnum);
|
||||
void PR_Configure (progfuncs_t *progfncs, int addressable_size, int max_progs);
|
||||
|
|
|
@ -133,6 +133,8 @@ struct progfuncs_s {
|
|||
string_t (*StringToProgs) (progfuncs_t *prinst, char *str);
|
||||
char *(*StringToNative) (progfuncs_t *prinst, string_t str);
|
||||
int stringtablesize;
|
||||
|
||||
int (*QueryField) (progfuncs_t *prinst, unsigned int fieldoffset, etype_t *type, char **name, evalc_t *fieldcache); //find info on a field definition at an offset
|
||||
};
|
||||
|
||||
typedef struct progexterns_s {
|
||||
|
|
|
@ -572,57 +572,57 @@ void PR_LoadGlabalStruct(void)
|
|||
|
||||
if (progstype == PROG_H2)
|
||||
{
|
||||
SV_QCStat(ev_float, "level", STAT_H2_LEVEL);
|
||||
SV_QCStat(ev_float, "intelligence", STAT_H2_INTELLIGENCE);
|
||||
SV_QCStat(ev_float, "wisdom", STAT_H2_WISDOM);
|
||||
SV_QCStat(ev_float, "strength", STAT_H2_STRENGTH);
|
||||
SV_QCStat(ev_float, "dexterity", STAT_H2_DEXTERITY);
|
||||
SV_QCStat(ev_float, "bluemana", STAT_H2_BLUEMANA);
|
||||
SV_QCStat(ev_float, "greenmana", STAT_H2_GREENMANA);
|
||||
SV_QCStat(ev_float, "experience", STAT_H2_EXPERIENCE);
|
||||
SV_QCStat(ev_float, "cnt_torch", STAT_H2_CNT_TORCH);
|
||||
SV_QCStat(ev_float, "cnt_h_boost", STAT_H2_CNT_H_BOOST);
|
||||
SV_QCStat(ev_float, "cnt_sh_boost", STAT_H2_CNT_SH_BOOST);
|
||||
SV_QCStat(ev_float, "cnt_mana_boost", STAT_H2_CNT_MANA_BOOST);
|
||||
SV_QCStat(ev_float, "cnt_teleport", STAT_H2_CNT_TELEPORT);
|
||||
SV_QCStat(ev_float, "cnt_tome", STAT_H2_CNT_TOME);
|
||||
SV_QCStat(ev_float, "cnt_summon", STAT_H2_CNT_SUMMON);
|
||||
SV_QCStat(ev_float, "cnt_invisibility", STAT_H2_CNT_INVISIBILITY);
|
||||
SV_QCStat(ev_float, "cnt_glyph", STAT_H2_CNT_GLYPH);
|
||||
SV_QCStat(ev_float, "cnt_haste", STAT_H2_CNT_HASTE);
|
||||
SV_QCStat(ev_float, "cnt_blast", STAT_H2_CNT_BLAST);
|
||||
SV_QCStat(ev_float, "cnt_polymorph", STAT_H2_CNT_POLYMORPH);
|
||||
SV_QCStat(ev_float, "cnt_flight", STAT_H2_CNT_FLIGHT);
|
||||
SV_QCStat(ev_float, "cnt_cubeofforce", STAT_H2_CNT_CUBEOFFORCE);
|
||||
SV_QCStat(ev_float, "cnt_invincibility", STAT_H2_CNT_INVINCIBILITY);
|
||||
SV_QCStat(ev_float, "artifact_active", STAT_H2_ARTIFACT_ACTIVE);
|
||||
SV_QCStat(ev_float, "artifact_low", STAT_H2_ARTIFACT_LOW);
|
||||
SV_QCStat(ev_float, "movetype", STAT_H2_MOVETYPE);
|
||||
SV_QCStat(ev_entity, "cameramode", STAT_H2_CAMERAMODE);
|
||||
SV_QCStat(ev_float, "hasted", STAT_H2_HASTED);
|
||||
SV_QCStat(ev_float, "inventory", STAT_H2_INVENTORY);
|
||||
SV_QCStat(ev_float, "rings_active", STAT_H2_RINGS_ACTIVE);
|
||||
SV_QCStatName(ev_float, "level", STAT_H2_LEVEL);
|
||||
SV_QCStatName(ev_float, "intelligence", STAT_H2_INTELLIGENCE);
|
||||
SV_QCStatName(ev_float, "wisdom", STAT_H2_WISDOM);
|
||||
SV_QCStatName(ev_float, "strength", STAT_H2_STRENGTH);
|
||||
SV_QCStatName(ev_float, "dexterity", STAT_H2_DEXTERITY);
|
||||
SV_QCStatName(ev_float, "bluemana", STAT_H2_BLUEMANA);
|
||||
SV_QCStatName(ev_float, "greenmana", STAT_H2_GREENMANA);
|
||||
SV_QCStatName(ev_float, "experience", STAT_H2_EXPERIENCE);
|
||||
SV_QCStatName(ev_float, "cnt_torch", STAT_H2_CNT_TORCH);
|
||||
SV_QCStatName(ev_float, "cnt_h_boost", STAT_H2_CNT_H_BOOST);
|
||||
SV_QCStatName(ev_float, "cnt_sh_boost", STAT_H2_CNT_SH_BOOST);
|
||||
SV_QCStatName(ev_float, "cnt_mana_boost", STAT_H2_CNT_MANA_BOOST);
|
||||
SV_QCStatName(ev_float, "cnt_teleport", STAT_H2_CNT_TELEPORT);
|
||||
SV_QCStatName(ev_float, "cnt_tome", STAT_H2_CNT_TOME);
|
||||
SV_QCStatName(ev_float, "cnt_summon", STAT_H2_CNT_SUMMON);
|
||||
SV_QCStatName(ev_float, "cnt_invisibility", STAT_H2_CNT_INVISIBILITY);
|
||||
SV_QCStatName(ev_float, "cnt_glyph", STAT_H2_CNT_GLYPH);
|
||||
SV_QCStatName(ev_float, "cnt_haste", STAT_H2_CNT_HASTE);
|
||||
SV_QCStatName(ev_float, "cnt_blast", STAT_H2_CNT_BLAST);
|
||||
SV_QCStatName(ev_float, "cnt_polymorph", STAT_H2_CNT_POLYMORPH);
|
||||
SV_QCStatName(ev_float, "cnt_flight", STAT_H2_CNT_FLIGHT);
|
||||
SV_QCStatName(ev_float, "cnt_cubeofforce", STAT_H2_CNT_CUBEOFFORCE);
|
||||
SV_QCStatName(ev_float, "cnt_invincibility", STAT_H2_CNT_INVINCIBILITY);
|
||||
SV_QCStatName(ev_float, "artifact_active", STAT_H2_ARTIFACT_ACTIVE);
|
||||
SV_QCStatName(ev_float, "artifact_low", STAT_H2_ARTIFACT_LOW);
|
||||
SV_QCStatName(ev_float, "movetype", STAT_H2_MOVETYPE);
|
||||
SV_QCStatName(ev_entity, "cameramode", STAT_H2_CAMERAMODE);
|
||||
SV_QCStatName(ev_float, "hasted", STAT_H2_HASTED);
|
||||
SV_QCStatName(ev_float, "inventory", STAT_H2_INVENTORY);
|
||||
SV_QCStatName(ev_float, "rings_active", STAT_H2_RINGS_ACTIVE);
|
||||
|
||||
SV_QCStat(ev_float, "rings_low", STAT_H2_RINGS_LOW);
|
||||
SV_QCStat(ev_float, "armor_amulet", STAT_H2_AMULET);
|
||||
SV_QCStat(ev_float, "armor_bracer", STAT_H2_BRACER);
|
||||
SV_QCStat(ev_float, "armor_breastplate", STAT_H2_BREASTPLATE);
|
||||
SV_QCStat(ev_float, "armor_helmet", STAT_H2_HELMET);
|
||||
SV_QCStat(ev_float, "ring_flight", STAT_H2_FLIGHT_T);
|
||||
SV_QCStat(ev_float, "ring_water", STAT_H2_WATER_T);
|
||||
SV_QCStat(ev_float, "ring_turning", STAT_H2_TURNING_T);
|
||||
SV_QCStat(ev_float, "ring_regeneration", STAT_H2_REGEN_T);
|
||||
SV_QCStat(ev_string, "puzzle_inv1", STAT_H2_PUZZLE1A);
|
||||
SV_QCStat(ev_string, "puzzle_inv2", STAT_H2_PUZZLE2A);
|
||||
SV_QCStat(ev_string, "puzzle_inv3", STAT_H2_PUZZLE3A);
|
||||
SV_QCStat(ev_string, "puzzle_inv4", STAT_H2_PUZZLE4A);
|
||||
SV_QCStat(ev_string, "puzzle_inv5", STAT_H2_PUZZLE5A);
|
||||
SV_QCStat(ev_string, "puzzle_inv6", STAT_H2_PUZZLE6A);
|
||||
SV_QCStat(ev_string, "puzzle_inv7", STAT_H2_PUZZLE7A);
|
||||
SV_QCStat(ev_string, "puzzle_inv8", STAT_H2_PUZZLE8A);
|
||||
SV_QCStat(ev_float, "max_health", STAT_H2_MAXHEALTH);
|
||||
SV_QCStat(ev_float, "max_mana", STAT_H2_MAXMANA);
|
||||
SV_QCStat(ev_float, "flags", STAT_H2_FLAGS);
|
||||
SV_QCStatName(ev_float, "rings_low", STAT_H2_RINGS_LOW);
|
||||
SV_QCStatName(ev_float, "armor_amulet", STAT_H2_AMULET);
|
||||
SV_QCStatName(ev_float, "armor_bracer", STAT_H2_BRACER);
|
||||
SV_QCStatName(ev_float, "armor_breastplate", STAT_H2_BREASTPLATE);
|
||||
SV_QCStatName(ev_float, "armor_helmet", STAT_H2_HELMET);
|
||||
SV_QCStatName(ev_float, "ring_flight", STAT_H2_FLIGHT_T);
|
||||
SV_QCStatName(ev_float, "ring_water", STAT_H2_WATER_T);
|
||||
SV_QCStatName(ev_float, "ring_turning", STAT_H2_TURNING_T);
|
||||
SV_QCStatName(ev_float, "ring_regeneration", STAT_H2_REGEN_T);
|
||||
SV_QCStatName(ev_string, "puzzle_inv1", STAT_H2_PUZZLE1A);
|
||||
SV_QCStatName(ev_string, "puzzle_inv2", STAT_H2_PUZZLE2A);
|
||||
SV_QCStatName(ev_string, "puzzle_inv3", STAT_H2_PUZZLE3A);
|
||||
SV_QCStatName(ev_string, "puzzle_inv4", STAT_H2_PUZZLE4A);
|
||||
SV_QCStatName(ev_string, "puzzle_inv5", STAT_H2_PUZZLE5A);
|
||||
SV_QCStatName(ev_string, "puzzle_inv6", STAT_H2_PUZZLE6A);
|
||||
SV_QCStatName(ev_string, "puzzle_inv7", STAT_H2_PUZZLE7A);
|
||||
SV_QCStatName(ev_string, "puzzle_inv8", STAT_H2_PUZZLE8A);
|
||||
SV_QCStatName(ev_float, "max_health", STAT_H2_MAXHEALTH);
|
||||
SV_QCStatName(ev_float, "max_mana", STAT_H2_MAXMANA);
|
||||
SV_QCStatName(ev_float, "flags", STAT_H2_FLAGS);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9079,10 +9079,16 @@ void PF_gettaginfo(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
|||
VectorCopy((result+8), axis[2]);
|
||||
}
|
||||
|
||||
//the first implementation of this function was (float type, float num, string name)
|
||||
//it is now float num, float type, .field
|
||||
void PF_clientstat(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
{
|
||||
#if 0 //this is the old code
|
||||
char *name = PF_VarString(prinst, 2, pr_globals);
|
||||
SV_QCStat(G_FLOAT(OFS_PARM0), name, G_FLOAT(OFS_PARM1));
|
||||
SV_QCStatName(G_FLOAT(OFS_PARM0), name, G_FLOAT(OFS_PARM1));
|
||||
#else
|
||||
SV_QCStatFieldIdx(G_FLOAT(OFS_PARM1), G_INT(OFS_PARM2)+prinst->fieldadjust, G_FLOAT(OFS_PARM0));
|
||||
#endif
|
||||
}
|
||||
|
||||
void PF_runclientphys(progfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||
|
|
|
@ -997,7 +997,8 @@ void SV_SetMoveVars(void);
|
|||
// sv_send.c
|
||||
//
|
||||
qboolean SV_ChallengePasses(int challenge);
|
||||
void SV_QCStat(int type, char *name, int statnum);
|
||||
void SV_QCStatName(int type, char *name, int statnum);
|
||||
void SV_QCStatFieldIdx(int type, unsigned int fieldindex, int statnum);
|
||||
void SV_ClearQCStats(void);
|
||||
|
||||
void SV_SendClientMessages (void);
|
||||
|
|
|
@ -1179,7 +1179,7 @@ typedef struct {
|
|||
} qcstat_t;
|
||||
qcstat_t qcstats[MAX_CL_STATS-32];
|
||||
int numqcstats;
|
||||
void SV_QCStat(int type, char *name, int statnum)
|
||||
void SV_QCStatEval(int type, char *name, evalc_t *cache, int statnum)
|
||||
{
|
||||
int i;
|
||||
if (numqcstats == sizeof(qcstats)/sizeof(qcstats[0]))
|
||||
|
@ -1194,12 +1194,42 @@ void SV_QCStat(int type, char *name, int statnum)
|
|||
break;
|
||||
}
|
||||
if (i == numqcstats)
|
||||
{
|
||||
if (i == sizeof(qcstats)/sizeof(qcstats[0]))
|
||||
{
|
||||
Con_Printf("Too many stats specified for csqc\n");
|
||||
return;
|
||||
}
|
||||
numqcstats++;
|
||||
}
|
||||
|
||||
qcstats[i].type = type;
|
||||
qcstats[i].statnum = statnum;
|
||||
Q_strncpyz(qcstats[i].name, name, sizeof(qcstats[i].name));
|
||||
memset(&qcstats[i].evalc, 0, sizeof(evalc_t));
|
||||
memcpy(&qcstats[i].evalc, cache, sizeof(evalc_t));
|
||||
}
|
||||
|
||||
void SV_QCStatName(int type, char *name, int statnum)
|
||||
{
|
||||
evalc_t cache;
|
||||
if (!svprogfuncs->GetEdictFieldValue(svprogfuncs, NULL, name, &cache))
|
||||
return;
|
||||
|
||||
SV_QCStatEval(type, name, &cache, statnum);
|
||||
}
|
||||
|
||||
void SV_QCStatFieldIdx(int type, unsigned int fieldindex, int statnum)
|
||||
{
|
||||
evalc_t cache;
|
||||
char *name;
|
||||
etype_t ftype;
|
||||
|
||||
if (!svprogfuncs->QueryField(svprogfuncs, fieldindex, &ftype, &name, &cache))
|
||||
{
|
||||
Con_Printf("invalid field for csqc stat\n");
|
||||
return;
|
||||
}
|
||||
SV_QCStatEval(type, name, &cache, statnum);
|
||||
}
|
||||
|
||||
void SV_ClearQCStats(void)
|
||||
|
@ -1216,6 +1246,8 @@ void SV_UpdateQCStats(edict_t *ent, int *stats)
|
|||
{
|
||||
eval_t *eval;
|
||||
eval = svprogfuncs->GetEdictFieldValue(svprogfuncs, ent, qcstats[i].name, &qcstats[i].evalc);
|
||||
if (!eval)
|
||||
continue;
|
||||
|
||||
switch(qcstats[i].type)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue