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:
Spoike 2008-01-23 01:31:01 +00:00
parent ae0a8461b7
commit 7584ae2e34
6 changed files with 122 additions and 55 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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