X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=pr_cmds.c;h=d3d608abdfda69ec03ee14bb04b83df34395b901;hb=e61e64e24dc955e55dee4b26ffa4ea1e6fbe7701;hp=a7468f0a39368aff17728db196df3077e7b04638;hpb=e119924277152e9f2bb99b7d51fb6c83b622eda8;p=xonotic%2Fdarkplaces.git diff --git a/pr_cmds.c b/pr_cmds.c index a7468f0a..d3d608ab 100644 --- a/pr_cmds.c +++ b/pr_cmds.c @@ -91,6 +91,7 @@ char *ENGINE_EXTENSIONS = "DP_HALFLIFE_MAP " "DP_HALFLIFE_MAP_CVAR " "DP_INPUTBUTTONS " +"DP_LITSUPPORT " "DP_MONSTERWALK " "DP_MOVETYPEBOUNCEMISSILE " "DP_MOVETYPEFOLLOW " @@ -141,6 +142,7 @@ char *ENGINE_EXTENSIONS = "NEH_CMD_PLAY2 " "NEH_RESTOREGAME " "TW_SV_STEPCONTROL " +"DP_QC_FS_SEARCH " // Black: same as in the menu qc ; qboolean checkextension(char *name) @@ -266,6 +268,10 @@ void PF_setorigin (void) float *org; e = G_EDICT(OFS_PARM0); + if (e == sv.edicts) + Host_Error("setorigin: can not modify world entity\n"); + if (e->e->free) + Host_Error("setorigin: can not modify free entity\n"); org = G_VECTOR(OFS_PARM1); VectorCopy (org, e->v->origin); SV_LinkEdict (e, false); @@ -304,6 +310,10 @@ void PF_setsize (void) float *min, *max; e = G_EDICT(OFS_PARM0); + if (e == sv.edicts) + Host_Error("setsize: can not modify world entity\n"); + if (e->e->free) + Host_Error("setsize: can not modify free entity\n"); min = G_VECTOR(OFS_PARM1); max = G_VECTOR(OFS_PARM2); SetMinMaxSize (e, min, max, false); @@ -325,6 +335,10 @@ void PF_setmodel (void) int i; e = G_EDICT(OFS_PARM0); + if (e == sv.edicts) + Host_Error("setmodel: can not modify world entity\n"); + if (e->e->free) + Host_Error("setmodel: can not modify free entity\n"); m = G_STRING(OFS_PARM1); // check to see if model was properly precached @@ -796,6 +810,8 @@ void PF_TraceToss (void) pr_xfunction->builtinsprofile += 600; ent = G_EDICT(OFS_PARM0); + if (ent == sv.edicts) + Host_Error("tracetoss: can not use world entity\n"); ignore = G_EDICT(OFS_PARM1); trace = SV_Trace_Toss (ent, ignore); @@ -960,7 +976,7 @@ void PF_stuffcmd (void) ================= PF_localcmd -Sends text over to the client's execution buffer +Sends text to server console localcmd (string) ================= @@ -1113,6 +1129,9 @@ void PF_Remove (void) Host_Error("remove: tried to remove world\n"); if (NUM_FOR_EDICT(ed) <= svs.maxclients) Host_Error("remove: tried to remove a client\n"); + // LordHavoc: not an error because id1 progs did this in some cases (killtarget removes entities, even if they are already removed in some cases...) + if (ed->e->free && developer.integer) + Con_Printf("remove: tried to remove an entity that was already removed\n"); ED_Free (ed); } @@ -1350,6 +1369,10 @@ void PF_walkmove (void) int oldself; ent = PROG_TO_EDICT(pr_global_struct->self); + if (ent == sv.edicts) + Host_Error("walkmove: can not modify world entity\n"); + if (ent->e->free) + Host_Error("walkmove: can not modify free entity\n"); yaw = G_FLOAT(OFS_PARM0); dist = G_FLOAT(OFS_PARM1); @@ -1391,6 +1414,10 @@ void PF_droptofloor (void) trace_t trace; ent = PROG_TO_EDICT(pr_global_struct->self); + if (ent == sv.edicts) + Host_Error("droptofloor: can not modify world entity\n"); + if (ent->e->free) + Host_Error("droptofloor: can not modify free entity\n"); VectorCopy (ent->v->origin, end); end[2] -= 256; @@ -1534,6 +1561,10 @@ void PF_aim (void) float speed; ent = G_EDICT(OFS_PARM0); + if (ent == sv.edicts) + Host_Error("aim: can not use world entity\n"); + if (ent->e->free) + Host_Error("aim: can not use free entity\n"); speed = G_FLOAT(OFS_PARM1); VectorCopy (ent->v->origin, start); @@ -1610,6 +1641,10 @@ void PF_changeyaw (void) float ideal, current, move, speed; ent = PROG_TO_EDICT(pr_global_struct->self); + if (ent == sv.edicts) + Host_Error("changeyaw: can not modify world entity\n"); + if (ent->e->free) + Host_Error("changeyaw: can not modify free entity\n"); current = ANGLEMOD(ent->v->angles[1]); ideal = ent->v->ideal_yaw; speed = ent->v->yaw_speed; @@ -1653,6 +1688,10 @@ void PF_changepitch (void) eval_t *val; ent = G_EDICT(OFS_PARM0); + if (ent == sv.edicts) + Host_Error("changepitch: can not modify world entity\n"); + if (ent->e->free) + Host_Error("changepitch: can not modify free entity\n"); current = ANGLEMOD( ent->v->angles[0] ); if ((val = GETEDICTFIELDVALUE(ent, eval_idealpitch))) ideal = val->_float; @@ -1725,7 +1764,7 @@ sizebuf_t *WriteDest (void) ent = PROG_TO_EDICT(pr_global_struct->msg_entity); entnum = NUM_FOR_EDICT(ent); if (entnum < 1 || entnum > svs.maxclients || !svs.clients[entnum-1].active) - Con_Printf("WriteDest: tried to write to non-client\n"); + Host_Error("WriteDest: tried to write to non-client\n"); return &svs.clients[entnum-1].message; case MSG_ALL: @@ -1791,6 +1830,10 @@ void PF_makestatic (void) int i, large; ent = G_EDICT(OFS_PARM0); + if (ent == sv.edicts) + Host_Error("makestatic: can not modify world entity\n"); + if (ent->e->free) + Host_Error("makestatic: can not modify free entity\n"); large = false; if (ent->v->modelindex >= 256 || ent->v->frame >= 256) @@ -2060,7 +2103,15 @@ void PF_copyentity (void) { edict_t *in, *out; in = G_EDICT(OFS_PARM0); + if (in == sv.edicts) + Host_Error("copyentity: can not read world entity\n"); + if (in->e->free) + Host_Error("copyentity: can not read free entity\n"); out = G_EDICT(OFS_PARM1); + if (out == sv.edicts) + Host_Error("copyentity: can not modify world entity\n"); + if (out->e->free) + Host_Error("copyentity: can not modify free entity\n"); memcpy(out->v, in->v, progs->entityfields * 4); } @@ -2955,6 +3006,11 @@ void PF_setattachment (void) int i, modelindex; model_t *model; + if (e == sv.edicts) + Host_Error("setattachment: can not modify world entity\n"); + if (e->e->free) + Host_Error("setattachment: can not modify free entity\n"); + if (tagentity == NULL) tagentity = sv.edicts; @@ -2968,9 +3024,8 @@ void PF_setattachment (void) if (tagentity != NULL && tagentity != sv.edicts && tagname && tagname[0]) { modelindex = (int)tagentity->v->modelindex; - if (modelindex >= 0 && modelindex < MAX_MODELS) + if (modelindex >= 0 && modelindex < MAX_MODELS && (model = sv.models[modelindex])) { - model = sv.models[modelindex]; if (model->data_overridetagnamesforskin && (unsigned int)tagentity->v->skin < (unsigned int)model->numskins && model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].num_overridetagnames) for (i = 0;i < model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].num_overridetagnames;i++) if (!strcmp(tagname, model->data_overridetagnamesforskin[(unsigned int)tagentity->v->skin].data_overridetagnames[i].name)) @@ -2988,6 +3043,159 @@ void PF_setattachment (void) } +///////////////////////////////////////// +// DP_QC_FS_SEARCH extension + +// qc fs search handling +#define MAX_SEARCHES 128 + +fssearch_t *pr_fssearchlist[MAX_SEARCHES]; + +void PR_Search_Init(void) +{ + memset(pr_fssearchlist,0,sizeof(pr_fssearchlist)); +} + +void PR_Search_Reset(void) +{ + int i; + // reset the fssearch list + for(i = 0; i < MAX_SEARCHES; i++) + if(pr_fssearchlist[i]) + FS_FreeSearch(pr_fssearchlist[i]); + memset(pr_fssearchlist,0,sizeof(pr_fssearchlist)); +} + +/* +========= +PF_search_begin + +float search_begin(string pattern, float caseinsensitive, float quiet) +========= +*/ +void PF_search_begin(void) +{ + int handle; + char *pattern; + int caseinsens, quiet; + + pattern = G_STRING(OFS_PARM0); + + PR_CheckEmptyString(pattern); + + caseinsens = G_FLOAT(OFS_PARM1); + quiet = G_FLOAT(OFS_PARM2); + + for(handle = 0; handle < MAX_SEARCHES; handle++) + if(!pr_fssearchlist[handle]) + break; + + if(handle >= MAX_SEARCHES) + { + Con_Printf("PR_search_begin: ran out of search handles (%i)\n", MAX_SEARCHES); + G_FLOAT(OFS_RETURN) = -2; + return; + } + + if(!(pr_fssearchlist[handle] = FS_Search(pattern,caseinsens, quiet))) + G_FLOAT(OFS_RETURN) = -1; + else + G_FLOAT(OFS_RETURN) = handle; +} + +/* +========= +VM_search_end + +void search_end(float handle) +========= +*/ +void PF_search_end(void) +{ + int handle; + + handle = G_FLOAT(OFS_PARM0); + + if(handle < 0 || handle >= MAX_SEARCHES) + { + Con_Printf("PF_search_end: invalid handle %i\n", handle); + return; + } + if(pr_fssearchlist[handle] == NULL) + { + Con_Printf("PF_search_end: no such handle %i\n", handle); + return; + } + + FS_FreeSearch(pr_fssearchlist[handle]); + pr_fssearchlist[handle] = NULL; +} + +/* +========= +VM_search_getsize + +float search_getsize(float handle) +========= +*/ +void PF_search_getsize(void) +{ + int handle; + + handle = G_FLOAT(OFS_PARM0); + + if(handle < 0 || handle >= MAX_SEARCHES) + { + Con_Printf("PF_search_getsize: invalid handle %i\n", handle); + return; + } + if(pr_fssearchlist[handle] == NULL) + { + Con_Printf("PF_search_getsize: no such handle %i\n", handle); + return; + } + + G_FLOAT(OFS_RETURN) = pr_fssearchlist[handle]->numfilenames; +} + +/* +========= +VM_search_getfilename + +string search_getfilename(float handle, float num) +========= +*/ +void PF_search_getfilename(void) +{ + int handle, filenum; + char *tmp; + + handle = G_FLOAT(OFS_PARM0); + filenum = G_FLOAT(OFS_PARM1); + + if(handle < 0 || handle >= MAX_SEARCHES) + { + Con_Printf("PF_search_getfilename: invalid handle %i\n", handle); + return; + } + if(pr_fssearchlist[handle] == NULL) + { + Con_Printf("PF_search_getfilename: no such handle %i\n", handle); + return; + } + if(filenum < 0 || filenum >= pr_fssearchlist[handle]->numfilenames) + { + Con_Printf("PF_search_getfilename: invalid filenum %i\n", filenum); + return; + } + + tmp = PR_GetTempString(); + strcpy(tmp, pr_fssearchlist[handle]->filenames[filenum]); + + G_INT(OFS_RETURN) = PR_SetString(tmp); +} + + builtin_t pr_builtin[] = { NULL, // #0 @@ -3158,10 +3366,10 @@ PF_clientcommand, // #440 void(entity e, string s) clientcommand (KRIMZON_SV_P PF_tokenize, // #441 float(string s) tokenize (KRIMZON_SV_PARSECLIENTCOMMAND) PF_argv, // #442 string(float n) argv (KRIMZON_SV_PARSECLIENTCOMMAND) PF_setattachment, // #443 void(entity e, entity tagentity, string tagname) setattachment (DP_GFX_QUAKE3MODELTAGS) -NULL, // #444 -NULL, // #445 -NULL, // #446 -NULL, // #447 +PF_search_begin, // #444 +PF_search_end, // #445 +PF_search_getsize, // #446 +PF_search_getfilename, // #447 NULL, // #448 NULL, // #449 a a a a a // #450-499 (LordHavoc) @@ -3174,11 +3382,13 @@ void PR_Cmd_Init(void) { pr_strings_mempool = Mem_AllocPool("pr_stringszone"); PR_Files_Init(); + PR_Search_Init(); } void PR_Cmd_Reset(void) { Mem_EmptyPool(pr_strings_mempool); + PR_Search_Reset(); PR_Files_CloseAll(); }