diff --git a/engine/common/pr_common.h b/engine/common/pr_common.h index 3140a86dc..5580a8785 100644 --- a/engine/common/pr_common.h +++ b/engine/common/pr_common.h @@ -644,15 +644,18 @@ enum terrainedit_e ter_lower, //vector pos, float radius, float heightchange ter_tex_kill, //vector pos, void junk, void junk, string texname ter_tex_get, //vector pos, void junk, float imagenum - ter_mix_paint, //vector pos, float radius, float percent, string texname - ter_mix_concentrate, //vector pos, float radius, float percent - ter_mix_noise, //vector pos, float radius, float percent - ter_mix_blur, //vector pos, float radius, float percent + ter_tex_blend, //vector pos, float radius, float percent, string texname + ter_tex_concentrate, //vector pos, float radius, float percent + ter_tex_noise, //vector pos, float radius, float percent + ter_tex_blur, //vector pos, float radius, float percent ter_water_set, //vector pos, float radius, float newwaterheight ter_mesh_add, //entity ent ter_mesh_kill, //vector pos, float radius ter_tint, //vector pos, float radius, float percent, vector newcol, float newalph ter_height_flatten, //vector pos, float radius, float percent + ter_tex_replace, //vector pos, float radius, string texname + ter_reset, //vector pos, float radius + ter_reloadsect, //vector pos, float radius // ter_poly_add, //add a poly, woo // ter_poly_remove, //remove polys diff --git a/engine/gl/gl_heightmap.c b/engine/gl/gl_heightmap.c index 758821217..72d56a66f 100644 --- a/engine/gl/gl_heightmap.c +++ b/engine/gl/gl_heightmap.c @@ -89,7 +89,7 @@ enum TSF_COMPRESSED = 1u<<31, //these flags should not be found on disk - TSF_FAILEDLOAD = 1u<<27, //placeholder to avoid excess disk access in border regions + TSF_FAILEDLOAD = 1u<<27, //placeholder to avoid excess disk access in border regions, means it still has default settings (unless edited). not saved unless its edited. TSF_NOTIFY = 1u<<28, //modified on server, waiting for clients to be told about the change. TSF_RELIGHT = 1u<<29, //height edited, needs relighting. TSF_DIRTY = 1u<<30, //its heightmap has changed, the mesh needs rebuilding @@ -1736,7 +1736,7 @@ static qboolean Terr_SaveSection(heightmap_t *hm, hmsection_t *s, int sx, int sy for (x = 0; x < SECTIONSPERBLOCK; x++) { s = Terr_GetSection(hm, sx+x, sy+y, TGS_LOAD); - if (s) + if (s && (s->flags & (TSF_EDITED|TSF_FAILEDLOAD)) != TSF_FAILEDLOAD) { dbh.offset[y*SECTIONSPERBLOCK + x] = VFS_TELL(f); Terr_Save(hm, s, f, sx+x, sy+y, writever); @@ -1757,6 +1757,9 @@ static qboolean Terr_SaveSection(heightmap_t *hm, hmsection_t *s, int sx, int sy dsection_t dsh; fname = Terr_DiskSectionName(hm, sx, sy); + if (s && (s->flags & (TSF_EDITED|TSF_FAILEDLOAD)) != TSF_FAILEDLOAD) + return FS_Remove(fname, FS_GAMEONLY); //delete the file if the section got reverted to default, and wasn't later modified. + FS_CreatePath(fname, FS_GAMEONLY); f = FS_OpenVFS(fname, "wb", FS_GAMEONLY); if (!f) @@ -1910,15 +1913,28 @@ qboolean Terrain_LocateSection(char *name, flocation_t *loc) } #endif -void Terr_DestroySection(heightmap_t *hm, hmsection_t *s, qboolean lightmapreusable) +void Terr_ClearSection(hmsection_t *s) { + struct hmwater_s *w; int i; - RemoveLink(&s->recycle); - for (i = 0; i < s->numents; i++) s->ents[i]->refs-=1; s->numents = 0; + while(s->water) + { + w = s->water; + s->water = w->next; + Z_Free(w); + } +} + +void Terr_DestroySection(heightmap_t *hm, hmsection_t *s, qboolean lightmapreusable) +{ + RemoveLink(&s->recycle); + + Terr_ClearSection(s); + #ifndef SERVERONLY if (s->lightmap >= 0) { @@ -3856,7 +3872,7 @@ static void ted_waterset(void *ctx, hmsection_t *s, int idx, float wx, float wy, //FIXME: what about holes? } -static void ted_mixconcentrate(void *ctx, hmsection_t *s, int idx, float wx, float wy, float w) +static void ted_texconcentrate(void *ctx, hmsection_t *s, int idx, float wx, float wy, float w) { unsigned char *lm = ted_getlightmap(s, idx); s->flags |= TSF_NOTIFY|TSF_EDITED; @@ -3888,7 +3904,7 @@ static void ted_mixconcentrate(void *ctx, hmsection_t *s, int idx, float wx, flo } } -static void ted_mixnoise(void *ctx, hmsection_t *s, int idx, float wx, float wy, float w) +static void ted_texnoise(void *ctx, hmsection_t *s, int idx, float wx, float wy, float w) { unsigned char *lm = ted_getlightmap(s, idx); vec4_t v; @@ -3909,7 +3925,7 @@ static void ted_mixnoise(void *ctx, hmsection_t *s, int idx, float wx, float wy, lm[2] = lm[2]*(1-w) + (v[2]*(w)); } -static void ted_mixpaint(void *ctx, hmsection_t *s, int idx, float wx, float wy, float w) +static void ted_texpaint(void *ctx, hmsection_t *s, int idx, float wx, float wy, float w) { unsigned char *lm = ted_getlightmap(s, idx); const char *texname = ctx; @@ -3968,8 +3984,14 @@ static void ted_mixpaint(void *ctx, hmsection_t *s, int idx, float wx, float wy, } } +static void ted_texreplace(void *ctx, hmsection_t *s, int idx, float wx, float wy, float w) +{ + if (w > 0) + ted_texpaint(ctx, s, idx, wx, wy, 1); +} + /* -static void ted_mixlight(void *ctx, hmsection_t *s, int idx, float wx, float wy, float w) +static void ted_texlight(void *ctx, hmsection_t *s, int idx, float wx, float wy, float w) { unsigned char *lm = ted_getlightmap(s, idx); vec3_t pos, pos2; @@ -4006,7 +4028,7 @@ static void ted_mixlight(void *ctx, hmsection_t *s, int idx, float wx, float wy, lm[3] = d*255; } */ -static void ted_mixset(void *ctx, hmsection_t *s, int idx, float wx, float wy, float w) +static void ted_texset(void *ctx, hmsection_t *s, int idx, float wx, float wy, float w) { unsigned char *lm = ted_getlightmap(s, idx); if (w > 1) @@ -4018,7 +4040,7 @@ static void ted_mixset(void *ctx, hmsection_t *s, int idx, float wx, float wy, f lm[0] = lm[0]*(1-w) + (255*((float*)ctx)[2]*(w)); } -static void ted_mixtally(void *ctx, hmsection_t *s, int idx, float wx, float wy, float w) +static void ted_textally(void *ctx, hmsection_t *s, int idx, float wx, float wy, float w) { unsigned char *lm = ted_getlightmap(s, idx); ((float*)ctx)[0] += lm[0]*w; @@ -4043,7 +4065,9 @@ static void ted_tint(void *ctx, hmsection_t *s, int idx, float wx, float wy, flo enum { tid_linear, - tid_exponential + tid_exponential, + tid_square_linear, + tid_square_exponential, }; //calls 'func' for each tile upon the terrain. the 'tile' can be either height or texel static void ted_itterate(heightmap_t *hm, int distribution, float *pos, float radius, float strength, int steps, void(*func)(void *ctx, hmsection_t *s, int idx, float wx, float wy, float strength), void *ctx) @@ -4056,6 +4080,12 @@ static void ted_itterate(heightmap_t *hm, int distribution, float *pos, float ra hmsection_t *s; float w, xd, yd; + if (radius < 0) + { + radius *= -1; + distribution |= 2; + } + min[0] = floor((pos[0] - radius)/(hm->sectionsize) - 1.5); min[1] = floor((pos[1] - radius)/(hm->sectionsize) - 1.5); max[0] = ceil((pos[0] + radius)/(hm->sectionsize) + 1.5); @@ -4091,14 +4121,30 @@ static void ted_itterate(heightmap_t *hm, int distribution, float *pos, float ra // if (xd < 0) // xd = 0; - if (radius*radius >= (xd*xd+yd*yd)) + switch(distribution) { - if (distribution == tid_exponential) - w = sqrt((radius*radius) - ((xd*xd)+(yd*yd))); - else - w = radius - sqrt(xd*xd+yd*yd); + case tid_exponential: + w = radius*radius - (xd*xd+yd*yd); + if (w > 0) + func(ctx, s, tx+ty*steps, wx, wy, sqrt(w)*strength/(radius)); + break; + case tid_linear: + w = radius - sqrt(xd*xd+yd*yd); if (w > 0) func(ctx, s, tx+ty*steps, wx, wy, w*strength/(radius)); + break; + case tid_square_exponential: + w = max(fabs(xd), fabs(yd)); + w = radius*radius - w*w; + if (w > 0) + func(ctx, s, tx+ty*steps, wx, wy, sqrt(w)*strength/(radius)); + break; + case tid_square_linear: + w = max(fabs(xd), fabs(yd)); + w = radius - w; + if (w > 0) + func(ctx, s, tx+ty*steps, wx, wy, w*strength/(radius)); + break; } } } @@ -4259,20 +4305,23 @@ void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_g // case ter_mixset: // ted_itterate(hm, tid_exponential, pos, radius, 1, SECTTEXSIZE, ted_mixset, G_VECTOR(OFS_PARM4)); // break; - case ter_mix_paint: - ted_itterate(hm, tid_exponential, pos, radius, quant/10, SECTTEXSIZE, ted_mixpaint, (void*)PR_GetStringOfs(prinst, OFS_PARM4)); + case ter_tex_blend: + ted_itterate(hm, tid_exponential, pos, radius, quant/10, SECTTEXSIZE, ted_texpaint, (void*)PR_GetStringOfs(prinst, OFS_PARM4)); break; - case ter_mix_concentrate: - ted_itterate(hm, tid_exponential, pos, radius, 1, SECTTEXSIZE, ted_mixconcentrate, NULL); + case ter_tex_replace: + ted_itterate(hm, tid_exponential, pos, radius, 1, SECTTEXSIZE, ted_texreplace, (void*)PR_GetStringOfs(prinst, OFS_PARM3)); break; - case ter_mix_noise: - ted_itterate(hm, tid_exponential, pos, radius, 1, SECTTEXSIZE, ted_mixnoise, NULL); + case ter_tex_concentrate: + ted_itterate(hm, tid_exponential, pos, radius, 1, SECTTEXSIZE, ted_texconcentrate, NULL); break; - case ter_mix_blur: + case ter_tex_noise: + ted_itterate(hm, tid_exponential, pos, radius, 1, SECTTEXSIZE, ted_texnoise, NULL); + break; + case ter_tex_blur: Vector4Set(tally, 0, 0, 0, 0); - ted_itterate(hm, tid_exponential, pos, radius, 1, SECTTEXSIZE, ted_mixtally, &tally); + ted_itterate(hm, tid_exponential, pos, radius, 1, SECTTEXSIZE, ted_textally, &tally); VectorScale(tally, 1/(tally[3]*255), tally); - ted_itterate(hm, tid_exponential, pos, radius, quant, SECTTEXSIZE, ted_mixset, &tally); + ted_itterate(hm, tid_exponential, pos, radius, quant, SECTTEXSIZE, ted_texset, &tally); break; case ter_tex_get: { @@ -4301,6 +4350,23 @@ void QCBUILTIN PF_terrain_edit(pubprogfuncs_t *prinst, struct globalvars_s *pr_g ted_texkill(Terr_GetSection(hm, x, y, TGS_FORCELOAD), PR_GetStringOfs(prinst, OFS_PARM4)); } break; + case ter_reset: + { + int x, y; + hmsection_t *s; + x = pos[0] / hm->sectionsize; + y = pos[1] / hm->sectionsize; + x = bound(hm->firstsegx, x, hm->maxsegx-1); + y = bound(hm->firstsegy, y, hm->maxsegy-1); + s = Terr_GetSection(hm, x, y, TGS_LOAD); + if (s) + { + s->flags = (s->flags & ~TSF_EDITED) | TSF_FAILEDLOAD; + Terr_ClearSection(s); + Terr_GenerateDefault(hm, s); + } + } + break; case ter_mesh_add: { vec3_t axis[3]; diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 4c23d5168..3882eb45c 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -10680,14 +10680,17 @@ void PR_DumpPlatform_f(void) {"TEREDIT_HEIGHT_LOWER","const float", CS, NULL, ter_lower}, {"TEREDIT_TEX_KILL", "const float", CS, NULL, ter_tex_kill}, {"TEREDIT_TEX_GET", "const float", CS, NULL, ter_tex_get}, - {"TEREDIT_MIX_PAINT", "const float", CS, NULL, ter_mix_paint}, - {"TEREDIT_MIX_UNIFY", "const float", CS, NULL, ter_mix_concentrate}, - {"TEREDIT_MIX_NOISE", "const float", CS, NULL, ter_mix_noise}, - {"TEREDIT_MIX_BLUR", "const float", CS, NULL, ter_mix_blur}, + {"TEREDIT_TEX_BLEND", "const float", CS, NULL, ter_tex_blend}, + {"TEREDIT_TEX_UNIFY", "const float", CS, NULL, ter_tex_concentrate}, + {"TEREDIT_TEX_NOISE", "const float", CS, NULL, ter_tex_noise}, + {"TEREDIT_TEX_BLUR", "const float", CS, NULL, ter_tex_blur}, {"TEREDIT_WATER_SET", "const float", CS, NULL, ter_water_set}, {"TEREDIT_MESH_ADD", "const float", CS, NULL, ter_mesh_add}, {"TEREDIT_MESH_KILL", "const float", CS, NULL, ter_mesh_kill}, {"TEREDIT_TINT", "const float", CS, NULL, ter_tint}, + {"TEREDIT_TEX_REPLACE", "const float", CS, NULL, ter_tex_replace}, + {"TEREDIT_RESET_SECT", "const float", CS, NULL, ter_reset}, + {"TEREDIT_RELOAD_SECT", "const float", CS, NULL, ter_reloadsect}, {"SLIST_HOSTCACHEVIEWCOUNT", "const float", CS|MENU, NULL, SLIST_HOSTCACHEVIEWCOUNT}, {"SLIST_HOSTCACHETOTALCOUNT", "const float", CS|MENU, NULL, SLIST_HOSTCACHETOTALCOUNT}, diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index 1852b71a8..fc6845de7 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -917,7 +917,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us for (i = 1; exts[i]; i++) { depth = COM_FDepthFile(va(exts[i], server), false); - if (depth < 0) + if (depth < bestdepth) { bestdepth = depth; Q_snprintfz (sv.modelname, sizeof(sv.modelname), exts[i], server); diff --git a/quakec/csaddon/src/csaddon.qc b/quakec/csaddon/src/csaddon.qc index a5e80c047..9dbbd8a9e 100644 --- a/quakec/csaddon/src/csaddon.qc +++ b/quakec/csaddon/src/csaddon.qc @@ -23,6 +23,8 @@ vector mousediff; vector originalmousepos; float mousedown; float shiftdown; +vector mousenear; +vector mousefar; string pointedshadername; vector pointedsurfacenormal; @@ -36,11 +38,21 @@ void() wrap_renderscene = vector col; local float i; + //don't do anything if this is a subview. this avoids getting confused. + if (!(float)getproperty(VF_DRAWWORLD)) + { + renderscene(); + return; + } + vidsize = getproperty(VF_SCREENVSIZE); /*inactive? then show nothing*/ if (!autocvar_ca_show) { + mousefar = unproject((vidsize*0.5) + '0 0 8192'); + mousenear = unproject(vidsize*0.5); + if (isdemo()) spline_overrides(gettime(5)); renderscene(); @@ -104,6 +116,9 @@ void() wrap_renderscene = setproperty(VF_DRAWENGINESBAR, 0); setproperty(VF_DRAWCROSSHAIR, 0); + mousefar = unproject(curmousepos + '0 0 8192'); + mousenear = unproject(curmousepos); + if (autocvar_ca_editormode == MODE_LIGHTEDIT) editor_lights_add(); else if (autocvar_ca_editormode == MODE_ENTSEDIT) @@ -276,8 +291,8 @@ void() CSQC_Input_Frame = vector t, o; if ((input_buttons & 1) && pointedshadername == "") { - t = unproject((vidsize*0.5) + '0 0 8192'); - o = unproject(vidsize*0.5); + t = mousefar; + o = mousenear; if (vlen(o - t) > 8192) t = o + normalize(t)*8192; traceline(o, t, TRUE, world); @@ -318,8 +333,8 @@ void() CSQC_Input_Frame = } else { - t = unproject((vidsize*0.5) + '0 0 8192'); - o = unproject(vidsize*0.5); + t = mousefar; + o = mousenear; if (vlen(o - t) > 8192) t = o + normalize(t)*8192; traceline(o, t, TRUE, world); diff --git a/quakec/csaddon/src/csfixups.qc b/quakec/csaddon/src/csfixups.qc index d12b5b3b6..f4026b4fa 100644 --- a/quakec/csaddon/src/csfixups.qc +++ b/quakec/csaddon/src/csfixups.qc @@ -18,3 +18,6 @@ void() csfixups = ptr_self = (entity*)externvalue(0, "&self"); }; + +vector mousenear; +vector mousefar; diff --git a/quakec/csaddon/src/csplat.qc b/quakec/csaddon/src/csplat.qc index 0b2ac8cd5..e989ea4d1 100644 --- a/quakec/csaddon/src/csplat.qc +++ b/quakec/csaddon/src/csplat.qc @@ -1,30 +1,38 @@ /* -This file was automatically generated by FTE QuakeWorld v1.01 +This file was automatically generated by FTE QuakeWorld v1.03 This file can be regenerated by issuing the following command: pr_dumpplatform -FFTE -Fdefines -TCS -O csplat Available options: --Ffte - target only FTE (optimations and additional extensions) --Tnq - dump specifically NQ fields --Tqw - dump specifically QW fields --Tcs - dump specifically CSQC fields --Fdefines - generate #defines instead of constants --O - write to a different qc file +-Ffte - target only FTE (optimations and additional extensions) +-Tnq - dump specifically NQ fields +-Tqw - dump specifically QW fields +-Tcs - dump specifically CSQC fields +-Tmenu - dump specifically menuqc fields +-Fdefines - generate #defines instead of constants +-O - write to a different qc file */ #pragma noref 1 +#pragma warning error Q101 /*too many parms*/ +#pragma warning error Q105 /*too few parms*/ +#pragma warning error Q208 /*system crc unknown*/ +#pragma warning enable F301 /*non-utf-8 strings*/ +#pragma warning enable F302 /*uninitialised locals*/ #pragma target FTE +#ifndef CSQC #define CSQC -entity self; -entity other; -entity world; -float time; -float cltime; -float frametime; -float player_localentnum; -float player_localnum; -float maxclients; -float clientcommandframe; -float servercommandframe; -string mapname; +#endif +entity self; /* The magic me */ +entity other; /* Valid in touch functions, this is the entity that we touched. */ +entity world; /* The null entity. Hurrah. Readonly after map spawn time. */ +float time; /* The current game time. Stops when paused. */ +float cltime; /* A local timer that ticks relative to local time regardless of latency, packetloss, or pause. */ +float frametime; /* The time since the last physics/render/input frame. */ +float player_localentnum; /* This is entity number the player is seeing from/spectating, or the player themself, can change mid-map. */ +float player_localnum; /* The 0-based player index, valid for getplayerkeyvalue calls. */ +float maxclients; /* Maximum number of player slots on the server. */ +float clientcommandframe; /* This is the input-frame sequence. frames < clientcommandframe have been sent to the server. frame==clientcommandframe is still being generated and can still change. */ +float servercommandframe; /* This is the input-frame that was last acknowledged by the server. Input frames greater than this should be applied to the player's entity. */ +string mapname; /* The short name of the map. */ float intermission; vector v_forward, v_up, v_right; vector view_angles; @@ -41,10 +49,11 @@ float input_buttons; float input_impulse; void end_sys_globals; .float modelindex; -.vector absmin, absmax; -.float entnum; -.float drawmask; -.void() predraw; +.vector absmin; +.vector absmax; +.float entnum; /* The entity number as its known on the server. */ +.float drawmask; /* Acts as a filter in the addentities call. */ +.float() predraw; /* Called by addentities after the filter and before the entity is actually drawn. Do your interpolation and animation in here. Should return one of the PREDRAW_* constants. */ .float movetype; .float solid; .vector origin; @@ -57,13 +66,14 @@ void end_sys_globals; .float renderflags; .string model; .float frame; -.float frame1time; +.float frame1time; /* The absolute time into the animation/framegroup specified by .frame. */ .float frame2; -.float frame2time; -.float lerpfrac; +.float frame2time; /* The absolute time into the animation/framegroup specified by .frame2. */ +.float lerpfrac; /* If 0, use frame1 only. If 1, use frame2 only. Mix them together for values between. */ .float skin; .float effects; -.vector mins, maxs; +.vector mins; +.vector maxs; .vector size; .void() touch; .void() think; @@ -77,47 +87,76 @@ void end_sys_globals; void end_sys_fields; .vector punchangle; .float gravity; -.float hull; -.entity movechain; -.void() chainmoved; -.void(float old, float new) contentstransition; -.float dimension_solid; -.float dimension_hit; +.float hull; /* Overrides the hull used by the entity for walkmove/movetogoal and not traceline/tracebox. */ +.entity movechain; /* This is a linked list of entities which will be moved whenever this entity moves, logically they are attached to this entity. */ +.void() chainmoved; /* Called when the entity is moved as a result of being part of another entity's .movechain */ +.void(float old, float new) contentstransition; /* This function is called when the entity moves between water and air. If specified, default splash sounds will be disabled allowing you to provide your own. */ +.float dimension_solid; /* This is the bitmask of dimensions which the entity is solid within. */ +.float dimension_hit; /* This is the bitmask of dimensions which the entity will be blocked by. If other.dimension_solid & self.dimension_hit, our traces will impact and not proceed. If its false, the traces will NOT impact, allowing self to pass straight through. */ .float hitcontentsmask; -.float scale; -.float fatness; -.float alpha; +.float scale; /* Multiplier that resizes the entity. 1 is normal sized, 2 is double sized. scale 0 is remapped to 1. In SSQC, this is limited to 1/16th precision, with a maximum just shy of 16. */ +.float fatness; /* How many QuakeUnits to push the entity's verticies along their normals by. */ +.float alpha; /* The transparency of the entity. 1 means opaque, 0.0001 means virtually invisible. 0 is remapped to 1, for compatibility. */ .entity tag_entity; -.float skeletonindex; +.float tag_index; +.float skeletonindex; /* This object serves as a container for the skeletal bone states used to override the animation data. */ .vector colormod; .vector glowmod; -.vector gravitydir; +.vector gravitydir; /* Specifies the direction in which gravity acts. Must be normalised. '0 0 0' also means down. Use '0 0 1' if you want the player to be able to run on ceilings. */ +.vector(vector org, vector ang) camera_transform; /* Provides portal transform information for portal surfaces attached to this entity. Also used to open up pvs in ssqc. */ +.float geomtype; .float friction; .float erp; .float jointtype; .float mass; .float bouncefactor; .float bouncestop; -.float forceshader; -.float baseframe; -.float baseframe2; -.float baseframe1time; -.float baseframe2time; -.float baselerpfrac; -.float basebone; -.float bonecontrol1; -.float bonecontrol2; -.float bonecontrol3; -.float bonecontrol4; -.float bonecontrol5; -.float subblendfrac; -.float basesubblendfrac; -.float ideal_pitch; +.float idealpitch; .float pitch_speed; -var float physics_mode = 2; -float gamespeed; +.float forceshader; /* Contains a shader handle used to replace all surfaces upon the entity. */ +.float baseframe; /* See basebone */ +.float baseframe2; /* See basebone */ +.float baseframe1time; /* See basebone */ +.float baseframe2time; /* See basebone */ +.float baselerpfrac; /* See basebone */ +.float basebone; /* The base* frame animations are equivelent to their non-base versions, except that they only affect bone numbers below the 'basebone' value. This means that the base* animation can affect the legs of a skeletal model independantly of the normal animation fields affecting the torso area. For more complex animation than this, use skeletal objects. */ +.float bonecontrol1; /* Halflife model format bone controller. On player models, this typically affects the spine's yaw. */ +.float bonecontrol2; /* Halflife model format bone controller. On player models, this typically affects the spine's yaw. */ +.float bonecontrol3; /* Halflife model format bone controller. On player models, this typically affects the spine's yaw. */ +.float bonecontrol4; /* Halflife model format bone controller. On player models, this typically affects the spine's yaw. */ +.float bonecontrol5; /* Halflife model format bone controller. This typically affects the mouth. */ +.float subblendfrac; /* Weird animation value specific to halflife models. On player models, this typically affects the spine's pitch. */ +.float basesubblendfrac; /* See basebone */ +noref void(float reqid, float responsecode, string resourcebody) URI_Get_Callback; /* Called as an eventual result of the uri_get builtin. */ +noref void(float apilevel, string enginename, float engineversion) CSQC_Init; /* Called at startup. enginename and engineversion are arbitary hints and can take any form. enginename should be consistant between revisions, but this cannot truely be relied upon. */ +noref void() CSQC_WorldLoaded; /* Called after model+sound precaches have been executed. Gives a chance for the qc to read the entity lump from the bsp. */ +noref void() CSQC_Shutdown; /* Specifies that the csqc is going down. Save your persistant settings here. */ +noref void(float vwidth, float vheight, float notmenu) CSQC_UpdateView; /* Called every single video frame. The CSQC is responsible for rendering the entire screen. */ +noref void(string msg) CSQC_Parse_StuffCmd; /* Gives the CSQC a chance to intercept stuffcmds. Use the tokenize builtin to parse the message. Unrecognised commands would normally be localcmded, but its probably better to drop unrecognised stuffcmds completely. */ +noref float(string msg) CSQC_Parse_CenterPrint; /* Gives the CSQC a chance to intercept centerprints. Return true if you wish the engine to otherwise ignore the centerprint. */ +noref void(string printmsg, float printlvl) CSQC_Parse_Print; /* Gives the CSQC a chance to intercept sprint/bprint builtin calls. CSQC should filter by the client's current msg setting and then pass the message on to the print command, or handle them itself. */ +noref void() CSQC_Parse_Event; /* Called when the client receives an SVC_CGAMEPACKET. The csqc should read the data or call the error builtin if it does not recognise the message. */ +noref float(float evtype, float scanx, float chary, float devid) CSQC_InputEvent; /* Called whenever a key is pressed, the mouse is moved, etc. evtype will be one of the IE_* constants. The other arguments vary depending on the evtype. Key presses are not guarenteed to have both scan and unichar values set at the same time. */ +noref void() CSQC_Input_Frame; /* Called just before each time clientcommandframe is updated. You can edit the input_* globals in order to apply your own player inputs within csqc, which may allow you a convienient way to pass certain info to ssqc. */ +noref float(string cmd) CSQC_ConsoleCommand; /* Called if the user uses any console command registed via registercommand. */ +noref float(string text, string info) CSQC_ConsoleLink; /* Called if the user clicks a ^[text\infokey\infovalue^] link. Use infoget to read/check each supported key. Return true if you wish the engine to not attempt to handle the link itself. */ +noref void(float isnew) CSQC_Ent_Update; +noref void() CSQC_Ent_Remove; +noref float(float entnum, float channel, string soundname, float vol, float attenuation, vector pos, float pitchmod) CSQC_Event_Sound; +noref float(string resname, string restype) CSQC_LoadResource; /* Called each time some resource is being loaded. CSQC can invoke various draw calls to provide a loading screen, until WorldLoaded is called. */ +noref float() CSQC_Parse_TempEntity; /* Please don't use this. Use CSQC_Parse_Event and multicasts instead. */ +noref void(string cmdtext) GameCommand; +var float physics_mode = 2; /* 0: original csqc - physics are not run +1: DP-compat. Thinks occur, but not true movetypes. +2: movetypes occur just as they do in ssqc. */ +float gamespeed; /* Set by the engine, this is the value of the sv_gamespeed cvar */ +float numclientseats; /* This is the number of splitscreen clients currently running on this client. */ +var vector drawfontscale = '1 1 0'; /* Specifies a scaler for all text rendering. There are other ways to implement this. */ +float drawfont; /* Allows you to choose exactly which font is to be used to draw text. Fonts can be registered/allocated with the loadfont builtin. */ +#define FONT_DEFAULT 0 #define TRUE 1 -#define FALSE 0 +#define FALSE 0 /* File not found... */ +#define M_PI 3 /* File not found... */ #define MOVETYPE_NONE 0 #define MOVETYPE_WALK 3 #define MOVETYPE_STEP 4 @@ -129,36 +168,85 @@ float gamespeed; #define MOVETYPE_BOUNCE 10 #define MOVETYPE_BOUNCEMISSILE 11 #define MOVETYPE_FOLLOW 12 -#define MOVETYPE_PHYSICS 32 +#define MOVETYPE_WALLWALK 31 /* Players using this movetype will be able to orient themselves to walls, and then run up them. */ +#define MOVETYPE_PHYSICS 32 /* Enable the use of ODE physics upon this entity. */ #define SOLID_NOT 0 #define SOLID_TRIGGER 1 #define SOLID_BBOX 2 #define SOLID_SLIDEBOX 3 #define SOLID_BSP 4 #define SOLID_CORPSE 5 -#define SOLID_LADDER 20 +#define SOLID_LADDER 20 /* Obsolete and may be removed at some point. Use skin=CONTENT_LADDER and solid_bsp or solid_trigger instead. */ #define SOLID_PHYSICS_BOX 32 #define SOLID_PHYSICS_SPHERE 33 #define SOLID_PHYSICS_CAPSULE 34 +#define SOLID_PHYSICS_TRIMESH 35 +#define SOLID_PHYSICS_CYLINDER 36 +#define GEOMTYPE_NONE -1 +#define GEOMTYPE_SOLID 0 +#define GEOMTYPE_BOX 1 +#define GEOMTYPE_SPHERE 2 +#define GEOMTYPE_CAPSULE 3 +#define GEOMTYPE_TRIMESH 4 +#define GEOMTYPE_CYLINDER 5 +#define GEOMTYPE_CAPSULE_X 6 +#define GEOMTYPE_CAPSULE_Y 7 +#define GEOMTYPE_CAPSULE_Z 8 +#define GEOMTYPE_CYLINDER_X 9 +#define GEOMTYPE_CYLINDER_Y 10 +#define GEOMTYPE_CYLINDER_Z 11 #define JOINTTYPE_FIXED -1 #define JOINTTYPE_POINT 1 #define JOINTTYPE_HINGE 2 #define JOINTTYPE_SLIDER 3 #define JOINTTYPE_UNIVERSAL 4 #define JOINTTYPE_HINGE2 5 +#define GE_MAXENTS -1 /* Valid for getentity, ignores the entity argument. Returns the maximum number of entities which may be valid, to avoid having to poll 65k when only 100 are used. */ +#define GE_ACTIVE 0 /* Valid for getentity. Returns whether this entity is known to the client or not. */ +#define GE_ORIGIN 1 /* Valid for getentity. Returns the interpolated .origin. */ +#define GE_FORWARD 2 /* Valid for getentity. Returns the interpolated forward vector. */ +#define GE_RIGHT 3 /* Valid for getentity. Returns the entity's right vector. */ +#define GE_UP 4 /* Valid for getentity. Returns the entity's up vector. */ +#define GE_SCALE 5 /* Valid for getentity. Returns the entity .scale. */ +#define GE_ORIGINANDVECTORS 6 /* Valid for getentity. Returns interpolated .origin, but also sets v_forward, v_right, and v_up accordingly. Use vectoangles(v_forward,v_up) to determine the angles. */ +#define GE_ALPHA 7 /* Valid for getentity. Returns the entity alpha. */ +#define GE_COLORMOD 8 /* Valid for getentity. Returns the colormod vector. */ +#define GE_PANTSCOLOR 9 /* Valid for getentity. Returns the entity's lower color (from .colormap), as a palette range value. */ +#define GE_SHIRTCOLOR 10 /* Valid for getentity. Returns the entity's lower color (from .colormap), as a palette range value. */ +#define GE_SKIN 11 /* Valid for getentity. Returns the entity's .skin index. */ +#define GE_MINS 12 /* Valid for getentity. Guesses the entity's .min vector. */ +#define GE_MAXS 13 /* Valid for getentity. Guesses the entity's .max vector. */ +#define GE_ABSMIN 14 /* Valid for getentity. Guesses the entity's .absmin vector. */ +#define GE_ABSMAX 15 /* Valid for getentity. Guesses the entity's .absmax vector. */ #define CONTENT_EMPTY -1 #define CONTENT_SOLID -2 #define CONTENT_WATER -3 #define CONTENT_SLIME -4 #define CONTENT_LAVA -5 #define CONTENT_SKY -6 -#define CHAN_AUTO 0 +#define CONTENT_LADDER -16 /* If this value is assigned to a solid_bsp's .skin field, the entity will become a ladder volume. */ +#define CHAN_AUTO 0 /* The automatic channel, play as many sounds on this channel as you want, and they'll all play, however the other channels will replace each other. */ #define CHAN_WEAPON 1 #define CHAN_VOICE 2 #define CHAN_ITEM 3 #define CHAN_BODY 4 -#define ATTN_NONE 0 -#define ATTN_NORM 1 +#define ATTN_NONE 0 /* Sounds with this attenuation can be heard throughout the map */ +#define ATTN_NORM 1 /* Standard attenuation */ +#define ATTN_IDLE 2 /* Extra attenuation so that sounds don't travel too far. */ +#define ATTN_STATIC 3 /* Even more attenuation to avoid torches drowing out everything else throughout the map. */ +#define INFOKEY_P_PING "ping" /* The player's ping time, in milliseconds. */ +#define INFOKEY_P_NAME "name" /* The player's name. */ +#define INFOKEY_P_TOPCOLOR "topcolor" /* The player's upper/shirt colour (palette index). */ +#define INFOKEY_P_BOTTOMCOLOR "bottomcolor" /* The player's lower/pants/trouser colour (palette index). */ +#define INFOKEY_P_TOPCOLOR_RGB "topcolor_rgb" /* The player's upper/shirt colour as an rgb value in a format usable with stov. */ +#define INFOKEY_P_BOTTOMCOLOR_RGB "bottomcolor_rgb" /* The player's lower/pants/trouser colour as an rgb value in a format usable with stov. */ +#define INFOKEY_P_MUTED "ignored" /* 0: we can see the result of the player's say/say_team commands. 1: we see no say/say_team messages from this player. Use the ignore command to toggle this value. */ +#define INFOKEY_P_VOIP_MUTED "vignored" /* 0: we can hear this player when they speak (assuming voip is generally enabled). 1: we ignore everything this player says. Use cl_voip_mute to change the values. */ +#define INFOKEY_P_ENTERTIME "entertime" /* Reads the timestamp at which the player entered the game, in terms of csqc's time global. */ +#define INFOKEY_P_FRAGS "frags" /* Reads a player's frag count. */ +#define INFOKEY_P_PACKETLOSS "pl" /* Reads a player's packetloss, as a percentage. */ +#define INFOKEY_P_VOIPSPEAKING "voipspeaking" /* Boolean value that says whether the given player is currently sending voice information. */ +#define INFOKEY_P_VOIPLOUDNESS "voiploudness" /* Only valid for the local player. Gives a value between 0 and 1 to indicate to the user how loud their mic is. */ #define FL_FLY 1 #define FL_SWIM 2 #define FL_CLIENT 8 @@ -169,14 +257,15 @@ float gamespeed; #define FL_PARTIALGROUND 1024 #define FL_WATERJUMP 2048 #define FL_JUMPRELEASED 4096 -#define FL_FINDABLE_NONSOLID 16384 +#define FL_FINDABLE_NONSOLID 16384 /* Allows this entity to be found with findradius */ #define MOVE_NORMAL 0 -#define MOVE_NOMONSTERS 1 -#define MOVE_MISSILE 2 -#define MOVE_HITMODEL 4 -#define MOVE_TRIGGERS 16 -#define MOVE_EVERYTHING 32 -#define MOVE_ENTCHAIN 128 +#define MOVE_NOMONSTERS 1 /* The trace will ignore all non-solid_bsp entities. */ +#define MOVE_MISSILE 2 /* The trace will use a bbox size of +/- 15 against entities with FL_MONSTER set. */ +#define MOVE_HITMODEL 4 /* Traces will impact the actual mesh of the model instead of merely their bounding box. Should generally only be used for tracelines. Note that this flag is unreliable as an object can animate through projectiles. The bounding box MUST be set to completely encompass the entity or those extra areas will be non-solid (leaving a hole for things to go through). */ +#define MOVE_TRIGGERS 16 /* This trace type will impact only triggers. It will ignore non-solid entities. */ +#define MOVE_EVERYTHING 32 /* This type of trace will hit solids and triggers alike. Even non-solid entities. */ +#define MOVE_ENTCHAIN 128 /* Returns a list of entities impacted via the trace_ent.chain field */ +#define MOVE_ONLYENT 256 /* Traces that use this trace type will collide against *only* the entity specified, and will ignore all owner/solid/dimension etc fields, they will still adhere to contents though. */ #define EF_BRIGHTFIELD 1 #define EF_MUZZLEFLASH 2 #define EF_BRIGHTLIGHT 4 @@ -186,6 +275,11 @@ float gamespeed; #define EF_RED 128 #define EF_FULLBRIGHT 512 #define EF_NODEPTHTEST 8192 +#define PFLAGS_NOSHADOW 1 /* Associated RT lights attached will not cast shadows, making them significantly faster to draw. */ +#define PFLAGS_CORONA 2 /* Enables support of coronas on the associated rtlights. */ +#define HASHT_PERSISTANT 0 /* Special hash table index for hash_add and hash_get. Entries in this table will persist over map changes (and doesn't need to be created/deleted). */ +#define HASH_REPLACE 1 /* Used with hash_add. Attempts to remove the old value instead of adding two values for a single key. */ +#define HASH_STRING 2 /* Used with hash_add. Specifies that the contents of the string argument should be internally zoned. */ #define STAT_HEALTH 0 #define STAT_WEAPON 2 #define STAT_AMMO 3 @@ -198,63 +292,70 @@ float gamespeed; #define STAT_ACTIVEWEAPON 10 #define STAT_TOTALSECRETS 11 #define STAT_TOTALMONSTERS 12 -#define STAT_SECRETS 13 -#define STAT_MONSTERS 14 +#define STAT_FOUNDSECRETS 13 +#define STAT_KILLEDMONSTERS 14 #define STAT_ITEMS 15 #define STAT_VIEWHEIGHT 16 -#define STAT_VIEW2 20 +#define STAT_VIEW2 20 /* This stat contains the number of the entity in the server's .view2 field. */ #define STAT_VIEWZOOM 21 -#define VF_MIN 1 +#define VF_MIN 1 /* The top-left of the 3d viewport in screenspace. The VF_ values are used via the setviewprop/getviewprop builtins. */ #define VF_MIN_X 2 #define VF_MIN_Y 3 -#define VF_SIZE 4 +#define VF_SIZE 4 /* The width+height of the 3d viewport in screenspace. */ #define VF_SIZE_X 5 #define VF_SIZE_Y 6 -#define VF_VIEWPORT 7 -#define VF_FOV 8 -#define VF_FOVX 9 -#define VF_ORIGIN 11 +#define VF_VIEWPORT 7 /* vector+vector. Two argument shortcut for VF_MIN and VF_SIZE */ +#define VF_FOV 8 /* sets both fovx and fovy. consider using afov instead. */ +#define VF_FOVX 9 /* horizontal field of view. does not consider aspect at all. */ +#define VF_FOVY 10 /* vertical field of view. does not consider aspect at all. */ +#define VF_ORIGIN 11 /* The origin of the view. Not of the player. */ #define VF_ORIGIN_X 12 #define VF_ORIGIN_Y 13 #define VF_ORIGIN_Z 14 -#define VF_ANGLES 15 +#define VF_ANGLES 15 /* The angles the view will be drawn at. Not the angle the client reports to the server. */ #define VF_ANGLES_X 16 #define VF_ANGLES_Y 17 #define VF_ANGLES_Z 18 -#define VF_DRAWWORLD 19 -#define VF_DRAWENGINESBAR 20 -#define VF_DRAWCROSSHAIR 21 +#define VF_DRAWWORLD 19 /* boolean. If set to 1, the engine will draw the world and static/persistant rtlights. If 0, the world will be skipped and everything will be fullbright. */ +#define VF_DRAWENGINESBAR 20 /* boolean. If set to 1, the sbar will be drawn, and viewsize will be honoured automatically. */ +#define VF_DRAWCROSSHAIR 21 /* boolean. If set to 1, the engine will draw its default crosshair. */ #define VF_CL_VIEWANGLES 33 #define VF_CL_VIEWANGLES_X 34 #define VF_CL_VIEWANGLES_Y 35 #define VF_CL_VIEWANGLES_Z 36 -#define VF_PERSPECTIVE 200 -#define VF_LPLAYER 202 -#define VF_AFOV 203 -#define VF_SCREENVSIZE 204 -#define VF_SCREENPSIZE 205 -#define RF_VIEWMODEL 1 -#define RF_EXTERNALMODEL 2 -#define RF_DEPTHHACK 4 -#define RF_ADDITIVE 8 -#define RF_USEAXIS 16 -#define RF_NOSHADOW 32 -#define RF_FRAMETIMESARESTARTTIMES 64 -#define RF_NOAUTOADD 128 -#define IE_KEYDOWN 0 -#define IE_KEYUP 1 -#define IE_MOUSEDELTA 2 -#define IE_MOUSEABS 3 +#define VF_PERSPECTIVE 200 /* 1: regular rendering. Fov specifies the angle. 0: isometric-style. Fov specifies the number of Quake Units each side of the viewport. */ +#define VF_LPLAYER 202 /* The 'seat' number, used when running splitscreen. */ +#define VF_AFOV 203 /* Aproximate fov. Matches the 'fov' cvar. The engine handles the aspect ratio for you. */ +#define VF_SCREENVSIZE 204 /* Provides a reliable way to retrieve the current virtual screen size (even if the screen is automatically scaled to retain aspect). */ +#define VF_SCREENPSIZE 205 /* Provides a reliable way to retrieve the current physical screen size (cvars need vid_restart for them to take effect). */ +#define VF_VIEWENTITY 206 /* Changes the RF_EXTERNALMODEL flag on entities to match the new selection, and removes entities flaged with RF_VIEWENTITY. Requires cunning use of .entnum and typically requires calling addentities(MASK_VIEWMODEL) too. */ +#define VF_RT_DESTCOLOUR 209 /* The FrameBuffer texture index to write colour info into. 1-based. Additional arguments are: format (rgba8=1,rgba16f=2,rgba32f=3), sizexy. Written to by both 3d and 2d rendering. */ +#define VF_RT_SOURCECOLOUR 210 /* The FrameBuffer texture index to use with shaders that specify a $sourcecolour map. */ +#define VF_RT_DEPTH 211 /* The FrameBuffer texture index to use as a depth buffer. Also used for shaders that specify $sourcedepth. 1-based. Additional arguments are: format (16=4,24=5,32=6), sizexy. */ +#define VF_RT_RIPPLE 212 /* The FrameBuffer texture index to use as a ripplemap (target for shaders with 'sort ripple'). Also used for shaders that specify $ripplemap. 1-based. Additional arguments are: format, sizexy. */ +#define RF_VIEWMODEL 1 /* Specifies that the entity is a view model, and that its origin is relative to the current view position. These entities are also subject to viewweapon bob. */ +#define RF_EXTERNALMODEL 2 /* Specifies that this entity should be displayed in mirrors (and may still cast shadows), but will not otherwise be visible. */ +#define RF_DEPTHHACK 4 /* Hacks the depth values such that the entity uses depth values as if it were closer to the screen. This is useful when combined with viewmodels to avoid weapons poking in to walls. */ +#define RF_ADDITIVE 8 /* Shaders from this entity will temporarily be hacked to use an additive blend mode instead of their normal blend mode. */ +#define RF_USEAXIS 16 /* The entity will be oriented according to the current v_forward+v_right+v_up vector values instead of the entity's .angles field. */ +#define RF_NOSHADOW 32 /* This entity will not cast shadows. Often useful on view models. */ +#define RF_FRAMETIMESARESTARTTIMES 64 /* Specifies that the frame1time, frame2time field are timestamps (denoting the start of the animation) rather than time into the animation. */ +#define IE_KEYDOWN 0 /* Specifies that a key was pressed. Second argument is the scan code. Third argument is the unicode (printable) char value. Fourth argument denotes which keyboard(or mouse, if its a mouse 'scan' key) the event came from. Note that some systems may completely separate scan codes and unicode values, with a 0 value for the unspecified argument. */ +#define IE_KEYUP 1 /* Specifies that a key was released. Arguments are the same as IE_KEYDOWN. On some systems, this may be fired instantly after IE_KEYDOWN was fired. */ +#define IE_MOUSEDELTA 2 /* Specifies that a mouse was moved (touch screens and tablets typically give IE_MOUSEABS events instead, use _windowed_mouse 0 to test code to cope with either). Second argument is the X displacement, third argument is the Y displacement. Fourth argument is which mouse or touch event triggered the event. */ +#define IE_MOUSEABS 3 /* Specifies that a mouse cursor or touch event was moved to a specific location relative to the virtual screen space. Second argument is the new X position, third argument is the new Y position. Fourth argument is which mouse or touch event triggered the event. */ #define IE_ACCELEROMETER 4 -#define FILE_READ 0 -#define FILE_APPEND 1 -#define FILE_WRITE 2 -#define FILE_READNL 4 -#define FILE_MMAP_READ 5 -#define FILE_MMAP_RW 6 -#define MOVE_LAGGED 64 -#define MASK_ENGINE 1 -#define MASK_VIEWMODEL 2 +#define IE_FOCUS 5 /* Specifies that input focus was given. parama says mouse focus, paramb says keyboard focus. If either are -1, then it is unchanged. */ +#define FILE_READ 0 /* The file may be read via fgets to read a single line at a time. */ +#define FILE_APPEND 1 /* Like FILE_WRITE, but writing starts at the end of the file. */ +#define FILE_WRITE 2 /* fputs will be used to write to the file. */ +#define FILE_READNL 4 /* Like FILE_READ, except newlines are not special. fgets reads the entire file into a tempstring. */ +#define FILE_MMAP_READ 5 /* The file will be loaded into memory. fgets returns a pointer to the first byte (and will always return the same value for this file). Cast this to your datatype. */ +#define FILE_MMAP_RW 6 /* Like FILE_MMAP_READ, except any changes to the data will be written back to disk once the file is closed. */ +#define MASK_ENGINE 1 /* Valid as an argument for addentities. If specified, all non-csqc entities will be added to the scene. */ +#define MASK_VIEWMODEL 2 /* Valid as an argument for addentities. If specified, the regular engine viewmodel will be added to the scene. */ +#define PREDRAW_AUTOADD 0 /* Valid as a return value from the predraw function. Returning this will cause the engine to automatically invoke addentity(self) for you. */ +#define PREDRAW_NEXT 1 /* Valid as a return value from the predraw function. Returning this will simply move on to the next entity without the autoadd behaviour, so can be used for particle/invisible/special entites, or entities that were explicitly drawn with addentity. */ #define LFIELD_ORIGIN 0 #define LFIELD_COLOUR 1 #define LFIELD_RADIUS 2 @@ -286,56 +387,178 @@ float gamespeed; #define TEREDIT_HEIGHT_LOWER 7 #define TEREDIT_TEX_KILL 8 #define TEREDIT_TEX_GET 9 -#define TEREDIT_MIX_PAINT 10 -#define TEREDIT_MIX_UNIFY 11 -#define TEREDIT_MIX_NOISE 12 -#define TEREDIT_MIX_BLUR 13 +#define TEREDIT_TEX_BLEND 10 +#define TEREDIT_TEX_UNIFY 11 +#define TEREDIT_TEX_NOISE 12 +#define TEREDIT_TEX_BLUR 13 #define TEREDIT_WATER_SET 14 #define TEREDIT_MESH_ADD 15 #define TEREDIT_MESH_KILL 16 #define TEREDIT_TINT 17 -void(vector vang) makevectors = #1; -void(entity e, vector o) setorigin = #2; -void(entity e, string m) setmodel = #3; -void(entity e, vector min, vector max) setsize = #4; -float() random = #7; -void(entity e, float chan, string samp, float vol, float atten, optional float speedpct, optional float flags) sound = #8; -vector(vector v) normalize = #9; -void(string e) error = #10; -void(string e) objerror = #11; -float(vector v) vlen = #12; -float(vector v) vectoyaw = #13; -entity() spawn = #14; -void(entity e) remove = #15; -void(vector v1, vector v2, float nomonsters, entity ent) traceline = #16; -entity(entity start, .string fld, string match) find = #18; -void(string s) precache_sound = #19; -void(string s) precache_model = #20; -entity(vector org, float rad) findradius = #22; -void(string s, ...) dprint = #25; -string(float val) ftos = #26; -string(vector val) vtos = #27; -void() coredump = #28; -void() traceon = #29; -void() traceoff = #30; -void(entity e) eprint = #31; -float(float yaw, float dist) walkmove = #32; -float() droptofloor = #34; -void(float lightstyle, string stylestring) lightstyle = #35; -float(float) rint = #36; -float(float) floor = #37; -float(float) ceil = #38; -//float(vector v) qtest_canreach = #39; -float(entity ent) checkbottom = #40; -float(vector pos) pointcontents = #41; -float(float) fabs = #43; -float(string) cvar = #45; -void(string, ...) localcmd = #46; -entity(entity) nextent = #47; -void(vector pos, vector dir, float colour, float count) particle = #48; +#define TEREDIT_TEX_REPLACE 19 +#define TEREDIT_RESET_SECT 20 +#define TEREDIT_RELOAD_SECT 21 +#define SLIST_HOSTCACHEVIEWCOUNT 0 +#define SLIST_HOSTCACHETOTALCOUNT 1 +#define SLIST_MASTERQUERYCOUNT 2 +#define SLIST_MASTERREPLYCOUNT 3 +#define SLIST_SERVERQUERYCOUNT 4 +#define SLIST_SERVERREPLYCOUNT 5 +#define SLIST_SORTFIELD 6 +#define SLIST_SORTDESCENDING 7 +#define SLIST_TEST_CONTAINS 0 +#define SLIST_TEST_NOTCONTAIN 1 +#define SLIST_TEST_LESSEQUAL 2 +#define SLIST_TEST_LESS 3 +#define SLIST_TEST_EQUAL 4 +#define SLIST_TEST_GREATER 5 +#define SLIST_TEST_GREATEREQUAL 6 +#define SLIST_TEST_NOTEQUAL 7 +#define SLIST_TEST_STARTSWITH 8 +#define SLIST_TEST_NOTSTARTSWITH 9 +void(vector vang) makevectors = #1; /* + Takes an angle vector (pitch,yaw,roll). Writes its results into v_forward, v_right, v_up vectors. */ + +void(entity e, vector o) setorigin = #2; /* + Changes e's origin to be equal to o. Also relinks collision state (as well as setting absmin+absmax), which is required after changing .solid */ + +void(entity e, string m) setmodel = #3; /* + Looks up m in the model precache list, and sets both e.model and e.modelindex to match. BSP models will set e.mins and e.maxs accordingly, other models depend upon the value of sv_gameplayfix_setmodelrealbox - for compatibility you should always call setsize after all pickups or non-bsp models. Also relinks collision state. */ + +void(entity e, vector min, vector max) setsize = #4; /* + Sets the e's mins and maxs fields. Also relinks collision state, which sets absmin and absmax too. */ + +float() random = #7; /* + Returns a random value between 0 and 1. Be warned, this builtin can return 1 in most engines, which can break arrays. */ + +void(entity e, float chan, string samp, float vol, float atten, optional float speedpct, optional float flags) sound = #8; /* + Starts a sound centered upon the given entity. + chan is the entity sound channel to use, channel 0 will allow you to mix many samples at once, others will replace the old sample + 'samp' must have been precached first + if specified, 'speedpct' should normally be around 100 (or =0), 200 for double speed or 50 for half speed. + flags&1 means the sound should be sent reliably. */ + +vector(vector v) normalize = #9; /* + Shorten or lengthen a direction vector such that it is only one quake unit long. */ + +void(string e) error = #10; /* + Ends the game with an easily readable error message. */ + +void(string e) objerror = #11; /* + Displays a non-fatal easily readable error message concerning the self entity, including a field dump. self will be removed! */ + +float(vector v) vlen = #12; /* + Returns the square root of the dotproduct of a vector with itself. Or in other words the length of a distance vector, in quake units. */ + +float(vector v) vectoyaw = #13; /* + Given a direction vector, returns the yaw (_y) angle in which that direction vector points. */ + +entity() spawn = #14; /* + Adds a brand new entity into the world! Hurrah, you're now a parent! */ + +void(entity e) remove = #15; /* + Destroys the given entity and clears some limited fields (including model, modelindex, solid, classname). Any references to the entity following the call are an error. After two seconds, the entity will be reused, in the interim you can unfortunatly still read its fields to see if the reference is no longer valid. */ + +void(vector v1, vector v2, float flags, entity ent) traceline = #16; /* + Traces an infinitely thin line through the world from v1 towards v2. + Will not collide with ent, ent.owner, or any entity who's owner field refers to ent. + There are no side effects beyond the trace_* globals being written. + flags&MOVE_NOMONSTERS will not impact on non-bsp entities. + flags&MOVE_MISSILE will impact with increased size. + flags&MOVE_HITMODEL will impact upon model meshes, instead of their bounding boxes. + flags&MOVE_TRIGGERS will also stop on triggers + flags&MOVE_EVERYTHING will stop if it hits anything, even non-solid entities. + flags&MOVE_LAGGED will backdate entity positions for the purposes of this builtin according to the indicated player ent's latency, to provide lag compensation. */ + +entity(entity start, .string fld, string match) find = #18; /* + Scan for the next entity with a given field set to the given 'match' value. start should be either world, or the previous entity that was found. Returns world on failure/if there are no more. */ + +string(string s) precache_sound = #19; /* + Precaches a sound, making it known to clients and loading it from disk. This builtin (strongly) should be called during spawn functions. This builtin must be called for the sound before the sound builtin is called, or it might not even be heard. */ + +string(string s) precache_model = #20; /* + Precaches a model, making it known to clients and loading it from disk if it has a .bsp extension. This builtin (strongly) should be called during spawn functions. This must be called for each model name before setmodel may use that model name. + Modelindicies precached in SSQC will always be positive. CSQC precaches will be negative if they are not also on the server. */ + +entity(vector org, float rad) findradius = #22; /* + Finds all entities within a distance of the 'org' specified. One entity is returned directly, while other entities are returned via that entity's .chain field. */ + +void(string s, ...) dprint = #25; /* + NQ: Prints the given message on the server's console, but only if the developer cvar is set. Arguments will be concatenated into a single message. */ + +void(string s, ...) dprint = #25; /* + QW: Unconditionally prints the given message on the server's console. Arguments will be concatenated into a single message. */ + +string(float val) ftos = #26; /* + Returns a tempstring containing a representation of the given float. Precision depends upon engine. */ + +string(vector val) vtos = #27; /* + Returns a tempstring containing a representation of the given vector. Precision depends upon engine. */ + +void() coredump = #28; /* + Writes out a coredump. This contains stack, globals, and field info for all ents. This can be handy for debugging. */ + +void() traceon = #29; /* + Enables tracing. This may be spammy, slow, and stuff. Set debugger 1 in order to use fte's qc debugger. */ + +void() traceoff = #30; /* + Disables tracing again. */ + +void(entity e) eprint = #31; /* + Debugging builtin that prints all fields of the given entity to the console. */ + +float(float yaw, float dist, optional float settraceglobals) walkmove = #32; /* + Attempt to walk the entity at a given angle for a given distance. + if settraceglobals is set, the trace_* globals will be set, showing the results of the movement. + This function will trigger touch events. */ + +float() droptofloor = #34; /* + Instantly moves the entity downwards until it hits the ground. If the entity would need to drop more than 'pr_droptofloorunits' quake units, its position will be considered invalid and the builtin will abort. */ + +void(float lightstyle, string stylestring, optional float channels) lightstyle = #35; /* + Specifies an auto-animating string that specifies the light intensity for entities using that lightstyle. + a is off, z is fully lit. Should be lower case only. + channels&1 enables red light. + channels&2 enables green light. + channels&4 enables blue light. */ + +float(float) rint = #36; /* + Rounds the given float up or down to the closest integeral value. X.5 rounds away from 0 */ + +float(float) floor = #37; /* + Rounds the given float downwards, even when negative. */ + +float(float) ceil = #38; /* + Rounds the given float upwards, even when negative. */ + +float(entity ent) checkbottom = #40; /* + Expensive checks to ensure that the entity is actually sitting on something solid, returns true if it is. */ + +float(vector pos) pointcontents = #41; /* + Checks the given point to see what is there. Returns one of the SOLID_* constants. Just because a spot is empty does not mean that the player can stand there due to the size of the player - use tracebox for such tests. */ + +float(float) fabs = #43; /* + Removes the sign of the float, making it positive if it is negative. */ + +float(string) cvar = #45; /* + Returns the numeric value of the named cvar */ + +void(string, ...) localcmd = #46; /* + Adds the string to the console command queue. Commands will not be executed immediately, but rather at the start of the following frame. */ + +entity(entity) nextent = #47; /* + Returns the following entity. Skips over removed entities. Returns world when passed the last valid entity. */ + +void(vector pos, vector dir, float colour, float count) particle = #48; /* + Spawn 'count' particles around 'pos' moving in the direction 'dir', with a palette colour index between 'colour' and 'colour+8'. */ + #define ChangeYaw changeyaw -void() changeyaw = #49; -vector(vector fwd, optional vector up) vectoangles = #51; +void() changeyaw = #49; /* + Changes the self.angles_y field towards self.ideal_yaw by up to self.yawspeed. */ + +vector(vector fwd, optional vector up) vectoangles = #51; /* + Returns the angles required to orient an entity to look in the given direction. The 'up' argument is required if you wish to set a roll angle, otherwise it will be limited to just monster-style turning. */ + float(float angle) sin = #60; /* Part of DP_QC_SINCOSSQRTPOW*/ float(float angle) cos = #61; /* Part of DP_QC_SINCOSSQRTPOW*/ float(float value) sqrt = #62; /* Part of DP_QC_SINCOSSQRTPOW*/ @@ -343,22 +566,51 @@ void(entity ent) changepitch = #63; /* Part of DP_QC_CHANGEPITCH*/ void(entity ent, entity ignore) tracetoss = #64; string(entity ent) etos = #65; /* Part of DP_QC_ETOS*/ void(float step) movetogoal = #67; -void(entity e) makestatic = #69; -void(string cvarname, string valuetoset) cvar_set = #72; +string(string s) precache_file = #68; /* + This builtin does nothing. It was used only as a hint for pak generation. */ + +void(entity e) makestatic = #69; /* + Sends a copy of the entity's renderable fields to all clients, and REMOVES the entity, preventing further changes. This means it will be unmutable and non-solid. */ + +void(string cvarname, string valuetoset) cvar_set = #72; /* + Instantly sets a cvar to the given string value. */ + void (vector pos, string samp, float vol, float atten) ambientsound = #74; -void(string str) precache_model2 = #75; -void(string str) precache_sound2 = #76; +string(string str) precache_model2 = #75; +string(string str) precache_sound2 = #76; +string(string str) precache_file2 = #77; float(string) stof = #81; /* Part of FRIK_FILE, FTE_STRINGS, QW_ENGINE, ZQ_QC_STRINGS*/ -void(vector start, vector mins, vector maxs, vector end, float nomonsters, entity ent) tracebox = #90; /* Part of DP_QC_TRACEBOX*/ -vector() randomvec = #91; /* Part of DP_QC_RANDOMVEC*/ +void(vector start, vector mins, vector maxs, vector end, float nomonsters, entity ent) tracebox = #90; /* Part of DP_QC_TRACEBOX + Exactly like traceline, but a box instead of a uselessly thin point. Acceptable sizes are limited by bsp format, q1bsp has strict acceptable size values. */ + +vector() randomvec = #91; /* Part of DP_QC_RANDOMVEC + Returns a vector with random values. Each axis is independantly a value between -1 and 1 inclusive. */ + vector(vector org) getlight = #92; -void(string cvarname, string defaultvalue) registercvar = #93; /* Part of DP_REGISTERCVAR*/ -float(float a, float b, ...) min = #94; /* Part of DP_QC_MINMAXBOUND*/ -float(float a, float b, ...) max = #95; /* Part of DP_QC_MINMAXBOUND*/ -float(float minimum, float val, float maximum) bound = #96; /* Part of DP_QC_MINMAXBOUND*/ +void(string cvarname, string defaultvalue) registercvar = #93; /* Part of DP_REGISTERCVAR + Creates a new cvar on the fly. If it does not already exist, it will be given the specified value. If it does exist, this is a no-op. + This builtin has the limitation that it does not apply to configs or commandlines. Such configs will need to use the set or seta command causing this builtin to be a noop. + In engines that support it, you will generally find the autocvar feature easier and more efficient to use. */ + +float(float a, float b, ...) min = #94; /* Part of DP_QC_MINMAXBOUND + Returns the lowest value of its arguments. */ + +float(float a, float b, ...) max = #95; /* Part of DP_QC_MINMAXBOUND + Returns the highest value of its arguments. */ + +float(float minimum, float val, float maximum) bound = #96; /* Part of DP_QC_MINMAXBOUND + Returns val, unless minimum is higher, or maximum is less. */ + float(float value, float exp) pow = #97; /* Part of DP_QC_SINCOSSQRTPOW*/ -entity(entity start, .float fld, float match) findfloat = #98; /* Part of DP_QC_FINDFLOAT*/ -float(string extname) checkextension = #99; +entity(entity start, .float fld, float match) findfloat = #98; /* Part of DP_QC_FINDFLOAT + Equivelent to the find builtin, but instead of comparing strings, this builtin compares floats. This builtin requires multiple calls in order to scan all entities - set start to the previous call's return value. + world is returned when there are no more entities. */ + +float(string extname) checkextension = #99; /* + Checks for an extension by its name (eg: checkextension("FRIK_FILE") says that its okay to go ahead and use strcat). + Use cvar("pr_checkextension") to see if this builtin exists. */ + +float(float value) anglemod = #102; float(string filename, float mode, optional float mmapminsize) fopen = #110; /* Part of FRIK_FILE*/ void(float fhandle) fclose = #111; /* Part of FRIK_FILE*/ string(float fhandle) fgets = #112; /* Part of FRIK_FILE*/ @@ -367,132 +619,420 @@ float(string s) strlen = #114; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS* string(string s1, optional string s2, ...) strcat = #115; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS*/ string(string s, float start, float length) substring = #116; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS*/ vector(string s) stov = #117; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS*/ -string(string s) strzone = #118; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS*/ +string(string s, ...) strzone = #118; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS*/ void(string s) strunzone = #119; /* Part of FRIK_FILE, FTE_STRINGS, ZQ_QC_STRINGS*/ -float(string modelname, optional float queryonly) getmodelindex = #200; -__variant(float prnum, string funcname, ...) externcall = #201; /* Part of FTE_MULTIPROGS*/ -float(string progsname) addprogs = #202; /* Part of FTE_MULTIPROGS*/ -__variant(float prnum, string varname) externvalue = #203; /* Part of FTE_MULTIPROGS*/ -void(float prnum, __variant newval, string varname) externset = #204; /* Part of FTE_MULTIPROGS*/ -float(string input, string token) instr = #206; /* Part of FTE_MULTIPROGS*/ -void(float portal, float state) openportal = #207; -void(optional __variant ret) abort = #211; /* Part of FTE_MULTITHREADED*/ +float(string modelname, optional float queryonly) getmodelindex = #200; /* + Acts as an alternative to precache_model(foo);setmodel(bar, foo); return bar.modelindex; + If queryonly is set and the model was not previously precached, the builtin will return 0 without needlessly precaching the model. */ + +__variant(float prnum, string funcname, ...) externcall = #201; /* Part of FTE_MULTIPROGS + Directly call a function in a different/same progs by its name. + prnum=0 is the 'default' or 'main' progs. + prnum=-1 means current progs. + prnum=-2 will scan through the active progs and will use the first it finds. */ + +float(string progsname) addprogs = #202; /* Part of FTE_MULTIPROGS + Loads an additional .dat file into the current qcvm. The returned handle can be used with any of the externcall/externset/externvalue builtins. + There are cvars that allow progs to be loaded automatically. */ + +__variant(float prnum, string varname) externvalue = #203; /* Part of FTE_MULTIPROGS + Reads a global in the named progs by the name of that global. + prnum=0 is the 'default' or 'main' progs. + prnum=-1 means current progs. + prnum=-2 will scan through the active progs and will use the first it finds. */ + +void(float prnum, __variant newval, string varname) externset = #204; /* Part of FTE_MULTIPROGS + Sets a global in the named progs by name. + prnum=0 is the 'default' or 'main' progs. + prnum=-1 means current progs. + prnum=-2 will scan through the active progs and will use the first it finds. */ + +float(string input, string token) instr = #206; /* Part of FTE_MULTIPROGS + Returns substring(input, strstrpot(input, token), -1), or the null string if token was not found in input. You're probably better off using strstrpos. */ + +void(entity portal, float state) openportal = #207; /* + Opens or closes the portals associated with a door or some such on q2 or q3 maps. On Q2BSPs, the entity should be the 'func_areaportal' entity - its style field will say which portal to open. On Q3BSPs, the entity is the door itself, the portal will be determined by the two areas found from a preceding setorigin call. */ + +void(optional __variant ret) abort = #211; /* Part of FTE_MULTITHREADED + QC execution is aborted. Parent QC functions on the stack will be skipped, effectively this forces all QC functions to 'return ret' until execution returns to the engine. If ret is ommited, it is assumed to be 0. */ + void(vector org, vector dmin, vector dmax, float colour, float effect, float count) particle2 = #215; /* Part of FTE_HEXEN2*/ void(vector org, vector box, float colour, float effect, float count) particle3 = #216; /* Part of FTE_HEXEN2*/ void(vector org, float radius, float colour, float effect, float count) particle4 = #217; /* Part of FTE_HEXEN2*/ float(float number, float quantity) bitshift = #218; /* Part of EXT_BITSHIFT*/ void(vector pos) te_lightningblood = #219; /* Part of FTE_TE_STANDARDEFFECTBUILTINS*/ -float(string s1, string sub, optional float startidx) strstrofs = #221; /* Part of FTE_STRINGS*/ -float(string str, float index) str2chr = #222; /* Part of FTE_STRINGS*/ -string(float chr, ...) chr2str = #223; /* Part of FTE_STRINGS*/ -string(float ccase, float redalpha, float redchars, string str, ...) strconv = #224; /* Part of FTE_STRINGS*/ -string(float pad, string str1, ...) strpad = #225; /* Part of FTE_STRINGS*/ -string(string old, string key, string value) infoadd = #226; /* Part of FTE_STRINGS*/ -string(string info, string key) infoget = #227; /* Part of FTE_STRINGS*/ -float(string s1, string s2, float len) strncmp = #228; /* Part of FTE_STRINGS*/ -float(string s1, string s2) strcasecmp = #229; /* Part of FTE_STRINGS*/ -float(string s1, string s2, float len) strncasecmp = #230; /* Part of FTE_STRINGS*/ -void() calltimeofday = #231; /* Part of FTE_CALLTIMEOFDAY*/ +float(string s1, string sub, optional float startidx) strstrofs = #221; /* Part of FTE_STRINGS + Returns the 0-based offset of sub within the s1 string, or -1 if sub is not in s1. + If startidx is set, this builtin will ignore matches before that 0-based offset. */ + +float(string str, float index) str2chr = #222; /* Part of FTE_STRINGS + Retrieves the character value at offset 'index'. */ + +string(float chr, ...) chr2str = #223; /* Part of FTE_STRINGS + The input floats are considered character values, and are concatenated. */ + +string(float ccase, float redalpha, float redchars, string str, ...) strconv = #224; /* Part of FTE_STRINGS + Converts quake chars in the input string amongst different representations. + ccase specifies the new case for letters. + 0: not changed. + 1: forced to lower case. + 2: forced to upper case. + redalpha and redchars switch between colour ranges. + 0: no change. + 1: Forced white. + 2: Forced red. + 3: Forced gold(low) (numbers only). + 4: Forced gold (high) (numbers only). + 5+6: Forced to white and red alternately. + You should not use this builtin in combination with UTF-8. */ + +string(float pad, string str1, ...) strpad = #225; /* Part of FTE_STRINGS + Pads the string with spaces, to ensure its a specific length (so long as a fixed-width font is used, anyway). If pad is negative, the spaces are added on the left. If positive the padding is on the right. */ + +string(string old, string key, string value) infoadd = #226; /* Part of FTE_STRINGS + Returns a new tempstring infostring with the named value changed (or added if it was previously unspecified). Key and value may not contain the \ character. */ + +string(string info, string key) infoget = #227; /* Part of FTE_STRINGS + Reads a named value from an infostring. The returned value is a tempstring */ + +#define strcmp strncmp +float(string s1, string s2, optional float len, optional float s1ofs, optional float s2ofs) strncmp = #228; /* Part of FTE_STRINGS + Compares up to 'len' chars in the two strings. s1ofs allows you to treat s2 as a substring to compare against, or should be 0. + Returns 0 if the two strings are equal, a negative value if s1 appears numerically lower, and positive if s1 appears numerically higher. */ + +float(string s1, string s2) strcasecmp = #229; /* Part of FTE_STRINGS + Compares the two strings without case sensitivity. + Returns 0 if they are equal. The sign of the return value may be significant, but should not be depended upon. */ + +float(string s1, string s2, float len, optional float s1ofs, optional float s2ofs) strncasecmp = #230; /* Part of FTE_STRINGS + Compares up to 'len' chars in the two strings without case sensitivity. s1ofs allows you to treat s2 as a substring to compare against, or should be 0. + Returns 0 if they are equal. The sign of the return value may be significant, but should not be depended upon. */ + +void() calltimeofday = #231; /* Part of FTE_CALLTIMEOFDAY + Asks the engine to instantly call the qc's 'timeofday' function, before returning. For compatibility with mvdsv. + timeofday should have the prototype: void(float secs, float mins, float hour, float day, float mon, float year, string strvalue) + The strftime builtin is more versatile and less weird. */ + void(vector angle) rotatevectorsbyangle = #235; void(vector fwd, vector right, vector up) rotatevectorsbyvectors = #236; float(float mdlindex, string skinname) skinforname = #237; -#ifdef CSQC -float(string shadername, optional string defaultshader, ...) shaderforname = #238; -#endif +float(string shadername, optional string defaultshader, ...) shaderforname = #238; /* Part of FTE_FORCESHADER + Caches the named shader and returns a handle to it. + If the shader could not be loaded from disk (missing file or ruleset_allow_shaders 0), it will be created from the 'defaultshader' string if specified, or a 'skin shader' default will be used. + defaultshader if not empty should include the outer {} that you would ordinarily find in a shader. */ + void(vector org, optional float count) te_bloodqw = #239; /* Part of FTE_TE_STANDARDEFFECTBUILTINS*/ -#ifdef CSQC +float(vector viewpos, entity entity) checkpvs = #240; /* Part of FTE_QC_CHECKPVS*/ vector(entity ent, float tagnum) rotatevectorsbytag = #244; -#endif -int(string) stoi = #259; /* Part of FTE_QC_INTCONV*/ -string(int) itos = #260; /* Part of FTE_QC_INTCONV*/ -int(string) stoh = #261; /* Part of FTE_QC_INTCONV*/ -string(int) htos = #262; /* Part of FTE_QC_INTCONV*/ -float(float modlindex, optional float useabstransforms) skel_create = #263; -float(float skel, entity ent, float modelindex, float retainfrac, float firstbone, float lastbone, optional float addfrac) skel_build = #264; -float(float skel) skel_get_numbones = #265; -string(float skel, float bonenum) skel_get_bonename = #266; -float(float skel, float bonenum) skel_get_boneparent = #267; -float(float skel, string tagname) skel_find_bone = #268; -vector(float skel, float bonenum) skel_get_bonerel = #269; -vector(float skel, float bonenum) skel_get_boneabs = #270; -void(float skel, float bonenum, vector org, optional vector fwd, optional vector right, optional vector up) skel_set_bone = #271; -void(float skel, float bonenum, vector org, optional vector fwd, optional vector right, optional vector up) skel_mul_bone = #272; -void(float skel, float startbone, float endbone, vector org, optional vector fwd, optional vector right, optional vector up) skel_mul_bones = #273; -void(float skeldst, float skelsrc, float startbone, float entbone) skel_copybones = #274; -void(float skel) skel_delete = #275; -float(float modidx, string framename) frameforname = #276; -float(float modidx, float framenum) frameduration = #277; -void(float action, vector pos, float radius, float quant) terrain_edit = #278; -void() touchtriggers = #279; -float(entity skelent, string dollname, float parentskel) skel_ragupdate = #281; -float*(float skel) skel_mmap = #282; -void(entity ent, float bonenum, vector org, optional vector angorfwd, optional vector right, optional vector up) skel_set_bone_world = #283; +int(string) stoi = #259; /* Part of FTE_QC_INTCONV + Converts the given string into an integer. Base 8, 10, or 16 is determined based upon the format of the string. */ + +string(int) itos = #260; /* Part of FTE_QC_INTCONV + Converts the passed integer into a base10 string. */ + +int(string) stoh = #261; /* Part of FTE_QC_INTCONV + Reads a base-16 string (with or without 0x prefix) as an integer. Bugs out if given a base 8 or base 10 string. :P */ + +string(int) htos = #262; /* Part of FTE_QC_INTCONV + Formats an integer as a base16 string, with leading 0s and no prefix. Always returns 8 characters. */ + +float(float modlindex, optional float useabstransforms) skel_create = #263; /* Part of FTE_CSQC_SKELETONOBJECTS + Allocates a new uninitiaised skeletal object, with enough bone info to animate the given model. + eg: self.skeletonobject = skel_create(self.modelindex); */ + +float(float skel, entity ent, float modelindex, float retainfrac, float firstbone, float lastbone, optional float addfrac) skel_build = #264; /* Part of FTE_CSQC_SKELETONOBJECTS + Animation data (according to the entity's frame info) is pulled from the specified model and blended into the specified skeletal object. + If retainfrac is set to 0 on the first call and 1 on the others, you can blend multiple animations together according to the addfrac value. The final weight should be 1. Other values will result in scaling and/or other weirdness. You can use firstbone and lastbone to update only part of the skeletal object, to allow legs to animate separately from torso, use 0 for both arguments to specify all, as bones are 1-based. */ + +float(float skel) skel_get_numbones = #265; /* Part of FTE_CSQC_SKELETONOBJECTS + Retrives the number of bones in the model. The valid range is 1<=bone<=numbones. */ + +string(float skel, float bonenum) skel_get_bonename = #266; /* Part of FTE_CSQC_SKELETONOBJECTS + Retrieves the name of the specified bone. Mostly only for debugging. */ + +float(float skel, float bonenum) skel_get_boneparent = #267; /* Part of FTE_CSQC_SKELETONOBJECTS + Retrieves which bone this bone's position is relative to. Bone 0 refers to the entity's position rather than an actual bone */ + +float(float skel, string tagname) skel_find_bone = #268; /* Part of FTE_CSQC_SKELETONOBJECTS + Finds a bone by its name, from the model that was used to create the skeletal object. */ + +vector(float skel, float bonenum) skel_get_bonerel = #269; /* Part of FTE_CSQC_SKELETONOBJECTS + Gets the bone position and orientation relative to the bone's parent. Return value is the offset, and v_forward, v_right, v_up contain the orientation. */ + +vector(float skel, float bonenum) skel_get_boneabs = #270; /* Part of FTE_CSQC_SKELETONOBJECTS + Gets the bone position and orientation relative to the entity. Return value is the offset, and v_forward, v_right, v_up contain the orientation. + Use gettaginfo for world coord+orientation. */ + +void(float skel, float bonenum, vector org, optional vector fwd, optional vector right, optional vector up) skel_set_bone = #271; /* Part of FTE_CSQC_SKELETONOBJECTS + Sets a bone position relative to its parent. If the orientation arguments are not specified, v_forward+v_right+v_up are used instead. */ + +void(float skel, float bonenum, vector org, optional vector fwd, optional vector right, optional vector up) skel_mul_bone = #272; /* Part of FTE_CSQC_SKELETONOBJECTS + Transforms a single bone by a matrix. You can use makevectors to generate a rotation matrix from an angle. */ + +void(float skel, float startbone, float endbone, vector org, optional vector fwd, optional vector right, optional vector up) skel_mul_bones = #273; /* Part of FTE_CSQC_SKELETONOBJECTS + Transforms an entire consecutive range of bones by a matrix. You can use makevectors to generate a rotation matrix from an angle, but you'll probably want to divide the angle by the number of bones. */ + +void(float skeldst, float skelsrc, float startbone, float entbone) skel_copybones = #274; /* Part of FTE_CSQC_SKELETONOBJECTS + Copy bone data from one skeleton directly into another. */ + +void(float skel) skel_delete = #275; /* Part of FTE_CSQC_SKELETONOBJECTS + Deletes a skeletal object. The actual delete is delayed, allowing the skeletal object to be deleted in an entity's predraw function yet still be valid by the time the addentity+renderscene builtins need it. Also uninstanciates any ragdoll currently in effect on the skeletal object. */ + +float(float modidx, string framename) frameforname = #276; /* Part of FTE_CSQC_SKELETONOBJECTS + Looks up a framegroup from a model by name, avoiding the need for hardcoding. Returns -1 on error. */ + +float(float modidx, float framenum) frameduration = #277; /* Part of FTE_CSQC_SKELETONOBJECTS + Retrieves the duration (in seconds) of the specified framegroup. */ + +void(float action, optional vector pos, optional float radius, optional float quant, ...) terrain_edit = #278; /* + Realtime terrain editing. Actions are the TEREDIT_ constants. */ + +void() touchtriggers = #279; /* + Triggers a touch events between self and every entity that it is in contact with. This should typically just be the triggers touch functions. */ + +float(entity skelent, string dollcmd, float animskel) skel_ragupdate = #281; /* + Updates the skeletal object attached to the entity according to its origin and other properties. + if animskel is non-zero, the ragdoll will animate towards the bone state in the animskel skeletal object, otherwise they will pick up the model's base pose which may not give nice results. + If dollcmd is not set, the ragdoll will update (this should be done each frame). + If the doll is updated without having a valid doll, the model's default .doll will be instanciated. + commands: + doll foo.doll : sets up the entity to use the named doll file + dollstring TEXT : uses the doll file directly embedded within qc, with that extra prefix. + cleardoll : uninstanciates the doll without destroying the skeletal object. + animate 0.5 : specifies the strength of the ragdoll as a whole + animatebody somebody 0.5 : specifies the strength of the ragdoll on a specific body (0 will disable ragdoll animations on that body). + enablejoint somejoint 1 : enables (or disables) a joint. Disabling joints will allow the doll to shatter. */ + +float*(float skel) skel_mmap = #282; /* + Map the bones in VM memory. They can then be accessed via pointers. Each bone is 12 floats, the four vectors interleaved (sadly). */ + +void(entity ent, float bonenum, vector org, optional vector angorfwd, optional vector right, optional vector up) skel_set_bone_world = #283; /* + Sets the world position of a bone within the given entity's attached skeletal object. The world position is dependant upon the owning entity's position. If no orientation argument is specified, v_forward+v_right+v_up are used for the orientation instead. If 1 is specified, it is understood as angles. If 3 are specified, they are the forawrd/right/up vectors to use. */ + string(float modidx, float framenum) frametoname = #284; string(float modidx, float skin) skintoname = #285; -#ifdef CSQC -void() clearscene = #300; -void(float mask) addentities = #301; -void(entity ent) addentity = #302; +float(float tabsize, optional float defaulttype) hash_createtab = #287; /* Part of FTE_QC_HASHTABLES + Creates a hash table object with at least 'tabsize' slots. hash table with index 0 is a game-persistant table and will NEVER be returned by this builtin (except as an error return). */ + +void(float table) hash_destroytab = #288; /* Part of FTE_QC_HASHTABLES + Destroys a hash table object. */ + +void(float table, string name, __variant value, optional float flags, optional float type) hash_add = #289; /* Part of FTE_QC_HASHTABLES + Adds the given key with the given value to the table. + If flags&HASH_REPLACE, the old value will be removed, if not set then multiple values may be added for a single key, they won't overwrite. + The type argument describes how the value should be stored and saved to files. While you can claim that all variables are just vectors, being more precise can result in less issues with tempstrings or saved games. */ + +__variant(float table, string name, __variant deflt, optional float requiretype, optional float index) hash_get = #290; /* Part of FTE_QC_HASHTABLES + looks up the specified key name in the hash table. returns deflt if key was not found. If stringsonly=1, the return value will be in the form of a tempstring, otherwise it'll be the original value argument exactly as it was. If requiretype is specified, then values not of the specified type will be ignored. Hurrah for multiple types with the same name. */ + +__variant(float table, string name) hash_delete = #291; /* Part of FTE_QC_HASHTABLES + removes the named key. returns the value of the object that was destroyed, or 0 on error. */ + +string(float table, float idx) hash_getkey = #292; /* Part of FTE_QC_HASHTABLES + gets some random key name. add+delete can change return values of this, so don't blindly increment the key index if you're removing all. */ + +float(string name) checkcommand = #294; /* Part of FTE_QC_CHECKCOMMAND + Checks to see if the supplied name is a valid command, cvar, or alias. Returns 0 if it does not exist. */ + +string(string s) argescape = #295; /* + Marks up a string so that it can be reliably tokenized as a single argument later. */ + +void() clearscene = #300; /* + Forgets all rentities, polygons, and temporary dlights. Resets all view properties to their default values. */ + +void(float mask) addentities = #301; /* + Walks through all entities effectively doing this: + if (ent.drawmask&mask){ ent.predaw(); if (wasremoved(ent)||(ent.renderflags&RF_NOAUTOADD))continue; addentity(ent); } + If mask&MASK_DELTA, non-csqc entities, particles, and related effects will also be added to the rentity list. + If mask&MASK_STDVIEWMODEL then the default view model will also be added. */ + +void(entity ent) addentity = #302; /* + Copies the entity fields into a new rentity for later rendering via addscene. */ + #define setviewprop setproperty -float(float property, ...) setproperty = #303; -void() renderscene = #304; -float(vector org, float radius, vector lightcolours) dynamiclight_add = #305; -void(string texturename, optional float flags) R_BeginPolygon = #306; -void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex = #307; -void() R_EndPolygon = #308; +float(float property, ...) setproperty = #303; /* + Allows you to override default view properties like viewport, fov, and whether the engine hud will be drawn. Different VF_ values have slightly different arguments, some are vectors, some floats. */ + +void() renderscene = #304; /* + Draws all entities, polygons, and particles on the rentity list (which were added via addentities or addentity), using the various view properties set via setproperty. There is no ordering dependancy. + The scene must generally be cleared again before more entities are added, as entities will persist even over to the next frame. + You may call this builtin multiple times per frame, but should only be called from CSQC_UpdateView. */ + +float(vector org, float radius, vector lightcolours, optional float style, optional string cubemapname, optional float pflags) dynamiclight_add = #305; /* + Adds a temporary dlight, ready to be drawn via addscene. */ + +void(string texturename, optional float flags) R_BeginPolygon = #306; /* + Specifies the shader to use for the following polygons, along with optional flags. + If flags&4, the polygon will be drawn as soon as the EndPolygon call is made, rather than waiting for renderscene. This allows complex 2d effects. */ + +void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex = #307; /* + Specifies a polygon vertex with its various properties. */ + +void() R_EndPolygon = #308; /* + Ends the current polygon. At least 3 verticies must have been specified. You do not need to call beginpolygon if you wish to draw another polygon with the same shader. */ + #define getviewprop getproperty -__variant(float property) getproperty = #309; -vector (vector v) unproject = #310; -vector (vector v) project = #311; -void(float width, vector pos1, vector pos2) drawline = #315; -float(string name) iscachedpic = #316; -string(string name, float trywad) precache_pic = #317; -vector(string picname) draw_getimagesize = #318; -void(string name) freepic = #319; -float(vector position, float character, vector scale, vector rgb, float alpha, optional float flag) drawcharacter = #320; -float(vector position, string text, vector scale, vector rgb, float alpha, optional float flag) drawrawstring = #321; -float(vector position, string pic, vector size, vector rgb, float alpha, optional float flag) drawpic = #322; -float(vector position, vector size, vector rgb, float alpha, optional float flag) drawfill = #323; -void(float x, float y, float width, float height) drawsetcliparea = #324; -void(void) drawresetcliparea = #325; -float(vector position, string text, vector scale, vector rgb, float alpha, float flag) drawstring = #326; -float(string text, float usecolours, optional vector fontsize) stringwidth = #327; -void(vector pos, vector sz, string pic, vector srcpos, vector srcsz, vector rgb, float alpha, float flag) drawsubpic = #328; -float(float stnum) getstati = #330; -#define getstatf getstatbits -float(float stnum, optional float firstbit, optional float bitcount) getstatbits = #331; -string(float firststnum) getstats = #332; -void(entity e, float mdlindex) setmodelindex = #333; -string(float mdlindex) modelnameforindex = #334; -#endif -float(string effectname) particleeffectnum = #335; -void(float effectnum, entity ent, vector start, vector end) trailparticles = #336; -void(float effectnum, vector origin, optional vector dir, optional float count) pointparticles = #337; -#ifdef CSQC -void(string s, ...) cprint = #338; -#endif -void(string s, ...) print = #339; -#ifdef CSQC -string(float keynum) keynumtostring = #340; -float(string keyname) stringtokeynum = #341; -string(float keynum) getkeybind = #342; -vector() getmousepos = #344; -float(float framenum) getinputstate = #345; -void(float sens) setsensitivityscaler = #346; -#endif -void(entity ent) runstandardplayerphysics = #347; -#ifdef CSQC -string(float playernum, string keyname) getplayerkeyvalue = #348; -float() isdemo = #349; -float() isserver = #350; -void(vector origin, vector forward, vector right, vector up) SetListener = #351; -void(string cmdname) registercommand = #352; -#endif -float(entity ent) wasfreed = #353; -#ifdef CSQC -string(string key) serverkey = #354; -string() getentitytoken = #355; -void(string evname, string evargs, ...) sendevent = #359; +__variant(float property) getproperty = #309; /* + Retrieve a currently-set (typically view) property, allowing you to read the current viewport or other things. Due to cheat protection, certain values may be unretrievable. */ + +vector (vector v) unproject = #310; /* + Transform a 2d screen-space point (with depth) into a 3d world-space point, according the various origin+angle+fov etc settings set via setproperty. */ + +vector (vector v) project = #311; /* + Transform a 3d world-space point into a 2d screen-space point, according the various origin+angle+fov etc settings set via setproperty. */ + +void(float width, vector pos1, vector pos2, vector rgb, float alpha, optional float drawflag) drawline = #315; /* + Draws a 2d line between the two 2d points. */ + +float(string name) iscachedpic = #316; /* + Checks to see if the image is currently loaded. Engines might lie, or cache between maps. */ + +string(string name, optional float trywad) precache_pic = #317; /* + Forces the engine to load the named image. If trywad is specified, the specified name must any lack path and extension. */ + +#define draw_getimagesize drawgetimagesize +vector(string picname) drawgetimagesize = #318; /* + Returns the dimensions of the named image. Images specified with .lmp should give the original .lmp's dimensions even if texture replacements use a different resolution. */ + +void(string name) freepic = #319; /* + Tells the engine that the image is no longer needed. The image will appear to be new the next time its needed. */ + +float(vector position, float character, vector size, vector rgb, float alpha, optional float drawflag) drawcharacter = #320; /* + Draw the given quake character at the given position. + If flag&4, the function will consider the char to be a unicode char instead (or display as a ? if outside the 32-127 range). + size should normally be something like '8 8 0'. + rgb should normally be '1 1 1' + alpha normally 1. + Software engines may assume the named defaults. + Note that ALL text may be rescaled on the X axis due to variable width fonts. The X axis may even be ignored completely. */ + +float(vector position, string text, vector size, vector rgb, float alpha, optional float drawflag) drawrawstring = #321; /* + Draws the specified string without using any markup at all, even in engines that support it. + If UTF-8 is globally enabled in the engine, then that encoding is used (without additional markup), otherwise it is raw quake chars. + Software engines may assume a size of '8 8 0', rgb='1 1 1', alpha=1, flag&3=0, but it is not an error to draw out of the screen. */ + +float(vector position, string pic, vector size, vector rgb, float alpha, optional float drawflag) drawpic = #322; /* + Draws an shader within the given 2d screen box. Software engines may omit support for rgb+alpha, but must support rescaling, and must clip to the screen without crashing. */ + +float(vector position, vector size, vector rgb, float alpha, optional float drawflag) drawfill = #323; /* + Draws a solid block over the given 2d box, with given colour, alpha, and blend mode (specified via flags). + flags&3=0 simple blend. + flags&3=1 additive blend */ + +void(float x, float y, float width, float height) drawsetcliparea = #324; /* + Specifies a 2d clipping region (aka: scissor test). 2d draw calls will all be clipped to this 2d box, the area outside will not be modified by any 2d draw call (even 2d polygons). */ + +void(void) drawresetcliparea = #325; /* + Reverts the scissor/clip area to the whole screen. */ + +float(vector position, string text, vector size, vector rgb, float alpha, float drawflag) drawstring = #326; /* + Draws a string, interpreting markup and recolouring as appropriate. */ + +float(string text, float usecolours, optional vector fontsize) stringwidth = #327; /* + Calculates the width of the screen in virtual pixels. If usecolours is 1, markup that does not affect the string width will be ignored. Will always be decoded as UTF-8 if UTF-8 is globally enabled. + If the char size is not specified, '8 8 0' will be assumed. */ + +void(vector pos, vector sz, string pic, vector srcpos, vector srcsz, vector rgb, float alpha, optional float drawflag) drawsubpic = #328; /* + Draws a rescaled subsection of an image to the screen. */ + +float(float stnum) getstati = #330; /* + Retrieves the numerical value of the given EV_INTEGER or EV_ENTITY stat (converted to a float). */ + +#define getstatbits getstatf +float(float stnum, optional float firstbit, optional float bitcount) getstatf = #331; /* + Retrieves the numerical value of the given EV_FLOAT stat. If firstbit and bitcount are specified, retrieves the upper bits of the STAT_ITEMS stat. */ + +string(float firststnum) getstats = #332; /* + Retrieves the value of the given EV_STRING stat, as a tempstring. + Older engines may use 4 consecutive integer stats, with a limit of 15 chars (yes, really. 15.), but FTE uses a separate namespace for string stats and has a much higher length limit. */ + +void(entity e, float mdlindex) setmodelindex = #333; /* + Sets a model by precache index instead of by name. Otherwise identical to setmodel. */ + +string(float mdlindex) modelnameforindex = #334; /* + Retrieves the name of the model based upon a precache index. This can be used to reduce csqc network traffic by enabling model matching. */ + +float(string effectname) particleeffectnum = #335; /* + Precaches the named particle effect. If your effect name is of the form 'foo.bar' then particles/foo.cfg will be loaded by the client if foo.bar was not already defined. + Different engines will have different particle systems, this specifies the QC API only. */ + +void(float effectnum, entity ent, vector start, vector end) trailparticles = #336; /* + Draws the given effect between the two named points. If ent is not world, distances will be cached in the entity in order to avoid framerate dependancies. The entity is not otherwise used. */ + +void(float effectnum, vector origin, optional vector dir, optional float count) pointparticles = #337; /* + Spawn a load of particles from the given effect at the given point traveling or aiming along the direction specified. The number of particles are scaled by the count argument. */ + +void(string s, ...) cprint = #338; /* + Print into the center of the screen just as ssqc's centerprint would appear. */ + +void(string s, ...) print = #339; /* + Unconditionally print on the local system's console, even in ssqc (doesn't care about the value of the developer cvar). */ + +string(float keynum) keynumtostring = #340; /* + Returns a hunam-readable name for the given keycode, as a tempstring. */ + +float(string keyname) stringtokeynum = #341; /* + Looks up the key name in the same way that the bind command would, returning the keycode for that key. */ + +string(float keynum) getkeybind = #342; /* + Finds the current binding for the given key (ignores modifiers like shift/alt/ctrl). */ + +void(float usecursor) setcursormode = #343; /* + Pass TRUE if you want the engine to release the mouse cursor (absolute input events + touchscreen mode). Pass FALSE if you want the engine to grab the cursor (relative input events + standard looking) */ + +vector() getmousepos = #344; /* + Nasty convoluted DP extension. Typically returns deltas instead of positions. Use CSQC_InputEvent for such things in csqc mods. */ + +float(float inputsequencenum) getinputstate = #345; /* + Looks up an input frame from the log, setting the input_* globals accordingly. + The sequence number range used for prediction should normally be servercommandframe < sequence <= clientcommandframe. + The sequence equal to clientcommandframe will change between input frames. */ + +void(float sens) setsensitivityscaler = #346; /* + Temporarily scales the player's mouse sensitivity based upon something like zoom, avoiding potential cvar saving and thus corruption. */ + +void(entity ent) runstandardplayerphysics = #347; /* + Perform the engine's standard player movement prediction upon the given entity using the input_* globals to describe movement. */ + +string(float playernum, string keyname) getplayerkeyvalue = #348; /* + Look up a player's userinfo, to discover things like their name, topcolor, bottomcolor, skin, team, *ver. + Also includes scoreboard info like frags, ping, pl, userid, entertime, as well as voipspeaking and voiploudness. */ + +float() isdemo = #349; /* + Returns if the client is currently playing a demo or not */ + +float() isserver = #350; /* + Returns if the client is acting as the server (aka: listen server) */ + +void(vector origin, vector forward, vector right, vector up, optional float inwater) SetListener = #351; /* + Sets the position of the view, as far as the audio subsystem is concerned. This should be called once per CSQC_UpdateView as it will otherwise revert to default. */ + +void(string cmdname) registercommand = #352; /* + Register the given console command, for easy console use. + Console commands that are later used will invoke CSQC_ConsoleCommand. */ + +float(entity ent) wasfreed = #353; /* + Quickly check to see if the entity is currently free. This function is only valid during the two-second non-reuse window, after that it may give bad results. Try one second to make it more robust. */ + +string(string key) serverkey = #354; /* + Look up a key in the server's public serverinfo string */ + +string(optional string resetstring) getentitytoken = #355; /* + Grab the next token in the map's entity lump. + If resetstring is not specified, the next token will be returned with no other sideeffects. + If empty, will reset from the map before returning the first token, probably {. + If not empty, will tokenize from that string instead. + Always returns tempstrings. */ + +float(string s) findfont = #356; /* + Looks up a named font slot. Matches the actual font name as a last resort. */ + +float(string fontname, string fontmaps, string sizes, float slot, optional float fix_scale, optional float fix_voffset) loadfont = #357; /* + too convoluted for me to even try to explain correct usage. Try drawfont = loadfont("foo", "cour", "16", 0, 0, 0); to switch to the courier font, if you have the freetype2 library in windows.. */ + +void(string evname, string evargs, ...) sendevent = #359; /* + Invoke Cmd_evname_evargs in ssqc. evargs must be a string of initials refering to the types of the arguments to pass. v=vector, e=entity(.entnum field is sent), f=float, i=int. 6 arguments max - you can get more if you pack your floats into vectors. */ + float() readbyte = #360; float() readchar = #361; float() readshort = #362; @@ -502,19 +1042,67 @@ float() readangle = #365; string() readstring = #366; float() readfloat = #367; float() readentitynum = #368; -float(string modelname, float(float isnew) updatecallback, float flags) deltalisten = #371; -__variant(float lno, float fld) dynamiclight_get = #372; -void(float lno, float fld, __variant value) dynamiclight_set = #373; -string(float efnum, float body) particleeffectquery = #374; -#endif -void*(int size) memalloc = #384; /* Part of FTE_MEMALLOC*/ -void(void *ptr) memfree = #385; /* Part of FTE_MEMALLOC*/ -void(void *dst, void *src, int size) memcpy = #386; /* Part of FTE_MEMALLOC*/ -void(void *dst, int val, int size) memset = #387; /* Part of FTE_MEMALLOC*/ +float(string modelname, float(float isnew) updatecallback, float flags) deltalisten = #371; /* + Specifies a per-modelindex callback to listen for engine-networking entity updates. Such entities are automatically interpolated by the engine (unless flags specifies not to). + The various standard entity fields will be overwritten each frame before the updatecallback function is called. */ + +__variant(float lno, float fld) dynamiclight_get = #372; /* + Retrieves a property from the given dynamic/rt light. Return type depends upon the light field requested. */ + +void(float lno, float fld, __variant value) dynamiclight_set = #373; /* + Changes a property on the given dynamic/rt light. Value type depends upon the light field to be changed. */ + +string(float efnum, float body) particleeffectquery = #374; /* + Retrieves either the name or the body of the effect with the given number. The effect body is regenerated from internal state, and can be changed before being reapplied via the localcmd builtin. */ + +void(string shadername, vector origin, vector up, vector side, vector rgb, float alpha) adddecal = #375; /* + Adds a temporary clipped decal shader to the scene, centered at the given point with given orientation. Will be drawn by the next renderscene call, and freed by the next clearscene call. */ + +float(entity e, string skinfilename, optional string skindata) setcustomskin = #376; /* + Sets an entity's skin overrides. These are custom per-entity surface->shader lookups. The skinfilename/data should be in .skin format: + surfacename,shadername - makes the named surface use the named shader + replace "surfacename" "shadername" - same. + compose "surfacename" "shader" "imagename@x,y:w,h?r,g,b,a" - compose a skin texture from multiple images. The texture is determined to be sufficient to hold the first named image, additional images can be named as extra tokens on the same line. Use a + at the end of the line to continue reading image tokens from the next line also, the named shader must use 'map $diffuse' to read the composed texture (compatible with the defaultskin shader). */ + +__variant*(int size) memalloc = #384; /* Part of FTE_MEMALLOC + Allocate an arbitary block of memory */ + +void(__variant *ptr) memfree = #385; /* Part of FTE_MEMALLOC + Frees a block of memory that was allocated with memfree */ + +void(__variant *dst, __variant *src, int size) memcpy = #386; /* Part of FTE_MEMALLOC + Copys memory from one location to another */ + +void(__variant *dst, int val, int size) memfill8 = #387; /* Part of FTE_MEMALLOC + Sets an entire block of memory to a specified value. Pretty much always 0. */ + +__variant(__variant *dst, float ofs) memgetval = #388; /* + Looks up the 32bit value stored at a pointer-with-offset. */ + +void(__variant *dst, float ofs, __variant val) memsetval = #389; /* + Changes the 32bit value stored at the specified pointer-with-offset. */ + +__variant*(__variant *base, float ofs) memptradd = #390; /* + Perform some pointer maths. Woo. */ + +string(string conname, string field, optional string newvalue) con_getset = #391; /* Part of FTE_CSQC_ALTCONSOLES_WIP + Reads or sets a property from a console object. The old value is returned. Iterrate through consoles with the 'next' field. Valid properties: title, name, next, unseen, markup, forceutf8, close, clear, hidden, linecount */ + +void(string conname, string messagefmt, ...) con_printf = #392; /* Part of FTE_CSQC_ALTCONSOLES_WIP + Prints onto a named console. */ + +void(string conname, vector pos, vector size, float fontsize) con_draw = #393; /* Part of FTE_CSQC_ALTCONSOLES_WIP + Draws the named console. */ + +float(string conname, float inevtype, float parama, float paramb, float paramc) con_input = #394; /* Part of FTE_CSQC_ALTCONSOLES_WIP + Forwards input events to the named console. Mouse updates should be absolute only. */ + void(entity from, entity to) copyentity = #400; /* Part of DP_QC_COPYENTITY*/ entity(.string field, string match) findchain = #402; /* Part of DP_QC_FINDCHAIN*/ entity(.float fld, float match) findchainfloat = #403; /* Part of DP_QC_FINDCHAINFLOAT*/ -void(vector org, string modelname, float startframe, float endframe, float framerate) effect = #404; /* Part of DP_SV_EFFECT*/ +void(vector org, string modelname, float startframe, float endframe, float framerate) effect = #404; /* Part of DP_SV_EFFECT + Spawns a self-animating sprite */ + void(vector org, vector dir, float count) te_blood = #405; /* Part of DP_TE_BLOOD*/ void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower = #406; /* Part of DP_TE_BLOODSHOWER*/ void(vector org, vector color) te_explosionrgb = #407; /* Part of DP_TE_EXPLOSIONRGB*/ @@ -527,7 +1115,7 @@ void(vector org) te_spikequad = #413; /* Part of _DP_TE_QUADEFFECTS1*/ void(vector org) te_superspikequad = #414; /* Part of _DP_TE_QUADEFFECTS1*/ void(vector org) te_explosionquad = #415; /* Part of _DP_TE_QUADEFFECTS1*/ void(vector org) te_smallflash = #416; /* Part of DP_TE_SMALLFLASH*/ -void(vector org, float radius, float lifetime, vector color) te_customflash = #417; /* Part of _DP_TE_CUSTOMFLASH*/ +void(vector org, float radius, float lifetime, vector color) te_customflash = #417; /* Part of DP_TE_CUSTOMFLASH*/ void(vector org, optional float count) te_gunshot = #418; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ void(vector org) te_spike = #419; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ void(vector org) te_superspike = #420; /* Part of DP_TE_STANDARDEFFECTBUILTINS, FTE_TE_STANDARDEFFECTBUILTINS*/ @@ -549,23 +1137,33 @@ vector(entity e, float s, float n) getsurfacepoint = #435; /* Part of DP_QC_GETS vector(entity e, float s) getsurfacenormal = #436; /* Part of DP_QC_GETSURFACE*/ string(entity e, float s) getsurfacetexture = #437; /* Part of DP_QC_GETSURFACE*/ float(entity e, vector p) getsurfacenearpoint = #438; /* Part of DP_QC_GETSURFACE*/ +vector(entity e, float s, vector p) getsurfaceclippedpoint = #439; /* Part of DP_QC_GETSURFACE*/ float(string s) tokenize = #441; /* Part of KRIMZON_SV_PARSECLIENTCOMMAND*/ string(float n) argv = #442; /* Part of KRIMZON_SV_PARSECLIENTCOMMAND*/ -float(string pattern, float caseinsensitive, float quiet) search_begin = #444; /* Part of DP_QC_FS_SEARCH*/ +void(entity e, entity tagentity, string tagname) setattachment = #443; /* Part of DP_GFX_QUAKE3MODELTAGS*/ +float(string pattern, float caseinsensitive, float quiet) search_begin = #444; /* Part of DP_QC_FS_SEARCH + initiate a filesystem scan based upon filenames. Be sure to call search_end on the returned handle. */ + void(float handle) search_end = #445; /* Part of DP_QC_FS_SEARCH*/ -float(float handle) search_getsize = #446; /* Part of DP_QC_FS_SEARCH*/ -string(float handle, float num) search_getfilename = #447; /* Part of DP_QC_FS_SEARCH*/ +float(float handle) search_getsize = #446; /* Part of DP_QC_FS_SEARCH + Retrieves the number of files that were found. */ + +string(float handle, float num) search_getfilename = #447; /* Part of DP_QC_FS_SEARCH + Retrieves name of one of the files that was found by the initial search. */ + string(string cvarname) cvar_string = #448; /* Part of DP_QC_CVAR_STRING*/ entity(entity start, .float fld, float match) findflags = #449; /* Part of DP_QC_FINDFLAGS*/ entity(.float fld, float match) findchainflags = #450; /* Part of DP_QC_FINDCHAINFLAGS*/ float(entity ent, string tagname) gettagindex = #451; /* Part of DP_MD3_TAGSINFO*/ -vector(entity ent, float tagindex) gettaginfo = #452; /* Part of DP_MD3_TAGSINFO*/ +vector(entity ent, float tagindex) gettaginfo = #452; /* Part of DP_MD3_TAGSINFO + Obtains the current worldspace position+orientation of the bone or tag from the given entity. The return value is the world coord, v_forward, v_right, v_up are also set according to the bone/tag's orientation. */ + entity(float entnum) edict_num = #459; /* Part of DP_QC_EDICT_NUM*/ float() buf_create = #460; /* Part of DP_QC_STRINGBUFFERS*/ void(float bufhandle) buf_del = #461; /* Part of DP_QC_STRINGBUFFERS*/ float(float bufhandle) buf_getsize = #462; /* Part of DP_QC_STRINGBUFFERS*/ void(float bufhandle_from, float bufhandle_to) buf_copy = #463; /* Part of DP_QC_STRINGBUFFERS*/ -void(float bufhandle, float sortpower, float backward) buf_sort = #464; /* Part of DP_QC_STRINGBUFFERS*/ +void(float bufhandle, float sortprefixlen, float backward) buf_sort = #464; /* Part of DP_QC_STRINGBUFFERS*/ string(float bufhandle, string glue) buf_implode = #465; /* Part of DP_QC_STRINGBUFFERS*/ string(float bufhandle, float string_index) bufstr_get = #466; /* Part of DP_QC_STRINGBUFFERS*/ void(float bufhandle, float string_index, string str) bufstr_set = #467; /* Part of DP_QC_STRINGBUFFERS*/ @@ -583,13 +1181,10 @@ float(string s, string separator1, ...) tokenizebyseparator = #479; /* Part of D string(string s) strtolower = #480; /* Part of DP_QC_STRING_CASE_FUNCTIONS*/ string(string s) strtoupper = #481; /* Part of DP_QC_STRING_CASE_FUNCTIONS*/ string(string s) cvar_defstring = #482; /* Part of DP_QC_CVAR_DEFSTRING*/ -#ifdef CSQC void(vector origin, string sample, float volume, float attenuation) pointsound = #483; /* Part of DP_SV_POINTSOUND*/ -#endif string(string search, string replace, string subject) strreplace = #484; /* Part of DP_QC_STRREPLACE*/ string(string search, string replace, string subject) strireplace = #485; /* Part of DP_QC_STRREPLACE*/ vector(entity e, float s, float n, float a) getsurfacepointattribute = #486; /* Part of DP_QC_GETSURFACEPOINTATTRIBUTE*/ -#ifdef CSQC float(string name) gecko_create = #487; /* Part of DP_GECKO_SUPPORT*/ void(string name) gecko_destroy = #488; /* Part of DP_GECKO_SUPPORT*/ void(string name, string URI) gecko_navigate = #489; /* Part of DP_GECKO_SUPPORT*/ @@ -597,7 +1192,6 @@ float(string name, float key, float eventtype) gecko_keyevent = #490; /* Part of void(string name, float x, float y) gecko_mousemove = #491; /* Part of DP_GECKO_SUPPORT*/ void(string name, float w, float h) gecko_resize = #492; /* Part of DP_GECKO_SUPPORT*/ vector(string name) gecko_get_texture_extent = #493; /* Part of DP_GECKO_SUPPORT*/ -#endif float(float caseinsensitive, string s, ...) crc16 = #494; /* Part of DP_QC_CRC16*/ float(string name) cvar_type = #495; /* Part of DP_QC_CVAR_TYPE*/ float() numentityfields = #496; /* Part of DP_QC_ENTITYDATA*/ @@ -605,29 +1199,194 @@ string(float fieldnum) entityfieldname = #497; /* Part of DP_QC_ENTITYDATA*/ float(float fieldnum) entityfieldtype = #498; /* Part of DP_QC_ENTITYDATA*/ string(float fieldnum, entity ent) getentityfieldstring = #499; /* Part of DP_QC_ENTITYDATA*/ float(float fieldnum, entity ent, string s) putentityfieldstring = #500; /* Part of DP_QC_ENTITYDATA*/ -//void(float to, string s, float sz) WritePicture = #501; /* Part of DP_SV_WRITEPICTURE*/ -//string() ReadPicture = #501; -string(string filename) whichpack = #503; /* Part of DP_QC_WHICHPACK*/ -#ifdef CSQC -__variant(float entnum, float fieldnum) getentity = #504; -#endif +void(float effectindex, entity own, vector org_from, vector org_to, vector dir_from, vector dir_to, float countmultiplier, optional float flags) boxparticles = #502; +string(string filename, optional float makereferenced) whichpack = #503; /* Part of DP_QC_WHICHPACK + Returns the pak file name that contains the file specified. progs/player.mdl will generally return something like 'pak0.pak'. If makereferenced is true, clients will automatically be told that the returned package should be pre-downloaded and used, even if allow_download_refpackages is not set. */ + +__variant(float entnum, float fieldnum) getentity = #504; /* + Looks up fields from non-csqc-visible entities. The entity will need to be within the player's pvs. fieldnum should be one of the GE_ constants. */ + string(string in) uri_escape = #510; /* Part of DP_QC_URI_ESCAPE*/ string(string in) uri_unescape = #511; /* Part of DP_QC_URI_ESCAPE*/ float(entity ent) num_for_edict = #512; +float(string uril, float id, optional string postmimetype, optional string postdata) uri_get = #513; /* Part of DP_QC_URI_GET + uri_get() gets content from an URL and calls a callback "uri_get_callback" with it set as string; an unique ID of the transfer is returned + returns 1 on success, and then calls the callback with the ID, 0 or the HTTP status code, and the received data in a string */ + float(string str) tokenize_console = #514; float(float idx) argv_start_index = #515; float(float idx) argv_end_index = #516; +void(float strbuf) buf_cvarlist = #517; string(string cvarname) cvar_description = #518; -#ifdef CSQC float(optional float timetype) gettime = #519; -#endif -void(string s) loadfromdata = #529; -void(string s) loadfromfile = #530; -void(.../*, string funcname*/) callfunction = #605; -void(float fh, entity e) writetofile = #606; +string(float keynum) keynumtostring_omgwtf = #520; +string(string command, optional float bindmap) findkeysforcommand = #521; +void(string s) loadfromdata = #529; /* + Reads a set of entities from the given string. This string should have the same format as a .ent file or a saved game. Entities will be spawned as required. If you need to see the entities that were created, you should use parseentitydata instead. */ + +void(string s) loadfromfile = #530; /* + Reads a set of entities from the named file. This file should have the same format as a .ent file or a saved game. Entities will be spawned as required. If you need to see the entities that were created, you should use parseentitydata instead. */ + +float(entity e, float channel) getsoundtime = #533; +float(string sample) soundlength = #534; +float(string filename, float bufhandle) buf_loadfile = #535; +float(float filehandle, float bufhandle, optional float startpos, optional float numstrings) buf_writefile = #536; +void(entity e, float physics_enabled) physics_enable = #540; /* + Enable or disable the physics attached to a MOVETYPE_PHYSICS entity. Entities which have been disabled in this way will stop taking so much cpu time. */ + +void(entity e, vector force, vector relative_ofs) physics_addforce = #541; /* + Apply some impulse directional force upon a MOVETYPE_PHYSICS entity. */ + +void(entity e, vector torque) physics_addtorque = #542; /* + Apply some impulse rotational force upon a MOVETYPE_PHYSICS entity. */ + +void(float trg) setmousetarget = #603; +float() getmousetarget = #604; +void(.../*, string funcname*/) callfunction = #605; /* + Invokes the named function. The function name is always passed as the last parameter and must always be present. The others are passed to the named function as-is */ + +void(float fh, entity e) writetofile = #606; /* + Writes an entity's fields to the named frik_file file handle. */ + float(string s) isfunction = #607; -void(entity e, string s) parseentitydata = #608; +vector(float vidmode, optional float forfullscreen) getresolution = #608; +string(float keynum) keynumtostring_menu = #609; +string(string command, optional float bindmap) findkeysforcommand_dp = #610; +float(float type) gethostcachevalue = #611; /* Part of FTE_CSQC_SERVERBROWSER*/ +string(float type, float hostnr) gethostcachestring = #612; /* Part of FTE_CSQC_SERVERBROWSER*/ +void(entity e, string s) parseentitydata = #613; /* + Reads a single entity's fields into an already-spawned entity. s should contain field pairs like in a saved game: {"foo1" "bar" "foo2" "5"} */ + +float(string key) stringtokeynum_menu = #614; +void() resethostcachemasks = #615; /* Part of FTE_CSQC_SERVERBROWSER*/ +void(float mask, float fld, string str, float op) sethostcachemaskstring = #616; /* Part of FTE_CSQC_SERVERBROWSER*/ +void(float mask, float fld, float num, float op) sethostcachemasknumber = #617; /* Part of FTE_CSQC_SERVERBROWSER*/ +void() resorthostcache = #618; /* Part of FTE_CSQC_SERVERBROWSER*/ +void(float fld, float descending) sethostcachesort = #619; /* Part of FTE_CSQC_SERVERBROWSER*/ +void() refreshhostcache = #620; /* Part of FTE_CSQC_SERVERBROWSER*/ +float(float fld, float hostnr) gethostcachenumber = #621; /* Part of FTE_CSQC_SERVERBROWSER*/ +float(string key) gethostcacheindexforkey = #622; /* Part of FTE_CSQC_SERVERBROWSER*/ +void(string key) addwantedhostcachekey = #623; /* Part of FTE_CSQC_SERVERBROWSER*/ +string() getextresponse = #624; /* Part of FTE_CSQC_SERVERBROWSER*/ +string(string dnsname, optional float defport) netaddress_resolve = #625; string(string fmt, ...) sprintf = #627; float(entity e, float s) getsurfacenumtriangles = #628; vector(entity e, float s, float n) getsurfacetriangle = #629; +string(string digest, string data, ...) digest_hex = #639; +#if defined(CSQC) || defined(MENU) +#define K_TAB 9 +#define K_ENTER 13 +#define K_ESCAPE 27 +#define K_SPACE 32 +#define K_BACKSPACE 127 +#define K_UPARROW 128 +#define K_DOWNARROW 129 +#define K_LEFTARROW 130 +#define K_RIGHTARROW 131 +#define K_LALT 132 +#define K_RALT -245 +#define K_LCTRL 133 +#define K_RCTRL -246 +#define K_LSHIFT 134 +#define K_RSHIFT -247 +#define K_F1 135 +#define K_F2 136 +#define K_F3 137 +#define K_F4 138 +#define K_F5 139 +#define K_F6 140 +#define K_F7 141 +#define K_F8 142 +#define K_F9 143 +#define K_F10 144 +#define K_F11 145 +#define K_F12 146 +#define K_INS 147 +#define K_DEL 148 +#define K_PGDN 149 +#define K_PGUP 150 +#define K_HOME 151 +#define K_END 152 +#define K_KP_HOME 164 +#define K_KP_UPARROW 165 +#define K_KP_PGUP 166 +#define K_KP_LEFTARROW 161 +#define K_KP_5 162 +#define K_KP_RIGHTARROW 163 +#define K_KP_END 158 +#define K_KP_DOWNARROW 159 +#define K_KP_PGDN 160 +#define K_KP_ENTER 172 +#define K_KP_INS 157 +#define K_KP_DEL 167 +#define K_KP_SLASH 168 +#define K_KP_MINUS 170 +#define K_KP_PLUS 171 +#define K_KP_NUMLOCK 154 +#define K_KP_STAR 169 +#define K_KP_EQUALS 173 +#define K_MOUSE1 512 +#define K_MOUSE2 513 +#define K_MOUSE3 514 +#define K_MOUSE4 517 +#define K_MOUSE5 518 +#define K_MOUSE6 519 +#define K_MOUSE7 520 +#define K_MOUSE8 521 +#define K_MOUSE9 522 +#define K_MOUSE10 523 +#define K_LWIN 239 +#define K_RWIN 240 +#define K_APP -241 +#define K_SEARCH -242 +#define K_POWER 130 +#define K_VOLUP -243 +#define K_VOLDOWN -244 +#define K_JOY1 768 +#define K_JOY2 769 +#define K_JOY3 770 +#define K_JOY4 771 +#define K_AUX1 784 +#define K_AUX2 785 +#define K_AUX3 786 +#define K_AUX4 787 +#define K_AUX5 788 +#define K_AUX6 789 +#define K_AUX7 790 +#define K_AUX8 791 +#define K_AUX9 792 +#define K_AUX10 793 +#define K_AUX11 794 +#define K_AUX12 795 +#define K_AUX13 796 +#define K_AUX14 797 +#define K_AUX15 798 +#define K_AUX16 799 +#define K_AUX17 800 +#define K_AUX18 801 +#define K_AUX19 802 +#define K_AUX20 803 +#define K_AUX21 804 +#define K_AUX22 805 +#define K_AUX23 806 +#define K_AUX24 807 +#define K_AUX25 808 +#define K_AUX26 809 +#define K_AUX27 810 +#define K_AUX28 811 +#define K_AUX29 812 +#define K_AUX30 813 +#define K_AUX31 814 +#define K_AUX32 815 +#define K_PAUSE 153 +#define K_MWHEELUP 515 +#define K_MWHEELDOWN 516 +#define K_PRINTSCREEN 174 +#define K_CAPSLOCK 155 +#define K_SCROLLLOCK 156 +#define K_SEMICOLON 59 +#define K_TILDE 126 +#define K_BACKQUOTE 96 +#define K_BACKSLASH 92 +#endif #pragma noref 0 diff --git a/quakec/csaddon/src/editor_terrain.qc b/quakec/csaddon/src/editor_terrain.qc index cedf233be..ce05b85ac 100644 --- a/quakec/csaddon/src/editor_terrain.qc +++ b/quakec/csaddon/src/editor_terrain.qc @@ -1,3 +1,14 @@ +/* +a) +b) Make a version of Mix Paint that just draws the texture onto tiles and replaces any other texture there instead of mixing, call it Tex Paint Single +b2) Rename Mix Paint to Tex Paint Mix +c) Add 2 buttons to incr/decrease Percentage setting +d) Add option to switch from circular selection reticle to square +e) Make reticle follow mouse properly (I can see it moving on the sonar map up above, but it's definitely not where I'm pointing the mouse) +f) Make Tex Kill choose the circular or square reticle you selected (suggestion D), right now it only uses square +g) Possibly an option to manually shrink the world bounds from the outside in (for eliminating unwanted space) +*/ + enum { ter_reload, //reload the entire thing @@ -11,14 +22,17 @@ enum ter_height_lower, //lower the terrain in a bell (negative value to raise) ter_tex_kill, //set section texture ter_tex_get, //get section texture - ter_mixpaint, //paint a specific texture + ter_tex_paint, //paint a specific texture with gracefulish blending. + ter_tex_paint_single, //paint a texture with 100% opacity and no attenuation (other than radius) ter_mixconcentrate, //figure out which is the strongest mixed texture and make it stronger ter_mixnoise, //add random noise to the affected samples ter_mixblur, //blur the texture mixture ter_water_set, //lower the terrain in a bell (negative value to raise) ter_mesh_add, //add a mesh ter_mesh_kill, //remove meshes within the radius - ter_tint, //pants new colour modifiers/tints + ter_tint, //paints new colour modifiers/tints + ter_reset, //destroy's the entire section completely, resetting it to default. + ter_reloadsect, //reload a section, reverting changes. ter_blank, ter_radius, ter_quant, @@ -26,15 +40,18 @@ enum ter_mesh, ter_tintval, ter_tex, + ter_roundpegsquarehole, ter_count }; static var float eradius = 256; static var float equant = 8; static var float epercent = 40; +static var float squaretool = 0; static string tex[8]; static var string tint[8] = {"1 1 1", "1.2 0.9 0.9", "0 1 0"}; static string meshname; static var float curtool = ter_blank; +static var float lasttool = ter_blank; static int painttex; static float mautorepeattime; static entity tempent; @@ -60,14 +77,17 @@ static string toolname[ter_count] = "height lower", "tex kill", "tex get", - "mix paint", - "mix concentrate", - "mix noise", - "mix blur", + "tex paint blend", + "tex paint single", + "tex concentrate", + "tex noise", + "tex blur", "water set", "mesh add", "mesh kill", - "mesh tint", + "tex tint", + "revert to default", + "reload single section", "", "rad", "quant", @@ -82,8 +102,8 @@ __variant(float action, ...) terrain_edit = #278; void(vector m) editor_do = { - vector t = unproject(m + '0 0 8192'); - vector o = unproject(m); + vector t = mousefar; + vector o = mousenear; if (vlen(o - t) > 8192) t = o + normalize(t)*8192; traceline(o, t, TRUE, world); @@ -163,11 +183,18 @@ void(vector m) editor_do = // case ter_mixset: // terrain_edit(curtool, trace_endpos, eradius, equant, emix); // break; - case ter_mixpaint: + case ter_tex_paint: if (autocvar_mod_terrain_networked && !isserver()) - sendevent("teredit", "fvffs", TEREDIT_MIX_PAINT, trace_endpos, eradius, epercent/100.0, tex[painttex]); + sendevent("teredit", "fvffs", TEREDIT_TEX_BLEND, trace_endpos, eradius, epercent/100.0, tex[painttex]); else - terrain_edit(TEREDIT_MIX_PAINT, trace_endpos, eradius, epercent/100.0, tex[painttex]); + terrain_edit(TEREDIT_TEX_BLEND, trace_endpos, eradius, epercent/100.0, tex[painttex]); + break; + case ter_tex_paint_single: + if (autocvar_mod_terrain_networked && !isserver()) + sendevent("teredit", "fvfs", TEREDIT_TEX_REPLACE, trace_endpos, eradius, tex[painttex]); + else + terrain_edit(TEREDIT_TEX_REPLACE, trace_endpos, eradius, tex[painttex]); + break; break; case ter_tex_kill: if (autocvar_mod_terrain_networked && !isserver()) @@ -175,23 +202,35 @@ void(vector m) editor_do = else terrain_edit(TEREDIT_TEX_KILL, trace_endpos, eradius, equant, tex[painttex]); break; + case ter_reset: + if (autocvar_mod_terrain_networked && !isserver()) + sendevent("teredit", "fvf", TEREDIT_RESET_SECT, trace_endpos, eradius); + else + terrain_edit(TEREDIT_RESET_SECT, trace_endpos, eradius); + break; + case ter_reloadsect: + if (autocvar_mod_terrain_networked && !isserver()) + sendevent("teredit", "fvf", TEREDIT_RELOAD_SECT, trace_endpos, eradius); + else + terrain_edit(TEREDIT_RELOAD_SECT, trace_endpos, eradius); + break; case ter_mixconcentrate: if (autocvar_mod_terrain_networked && !isserver()) - sendevent("teredit", "fvff", TEREDIT_MIX_UNIFY, trace_endpos, eradius, equant); + sendevent("teredit", "fvff", TEREDIT_TEX_UNIFY, trace_endpos, eradius, equant); else - terrain_edit(TEREDIT_MIX_UNIFY, trace_endpos, eradius, equant); + terrain_edit(TEREDIT_TEX_UNIFY, trace_endpos, eradius, equant); break; case ter_mixnoise: if (autocvar_mod_terrain_networked && !isserver()) - sendevent("teredit", "fvff", TEREDIT_MIX_NOISE, trace_endpos, eradius, equant); + sendevent("teredit", "fvff", TEREDIT_TEX_NOISE, trace_endpos, eradius, equant); else - terrain_edit(TEREDIT_MIX_NOISE, trace_endpos, eradius, equant); + terrain_edit(TEREDIT_TEX_NOISE, trace_endpos, eradius, equant); break; case ter_mixblur: if (autocvar_mod_terrain_networked && !isserver()) - sendevent("teredit", "fvff", TEREDIT_MIX_BLUR, trace_endpos, eradius, equant); + sendevent("teredit", "fvff", TEREDIT_TEX_BLUR, trace_endpos, eradius, equant); else - terrain_edit(TEREDIT_MIX_BLUR, trace_endpos, eradius, equant); + terrain_edit(TEREDIT_TEX_BLUR, trace_endpos, eradius, equant); break; case ter_tint: @@ -215,16 +254,17 @@ void(vector m) editor_do = float(float keyc, float unic, vector m) editor_terrain_key = { + float nt; if (curtool >= ter_radius && curtool <= ter_tex) { string txt = ""; - float nt = curtool; + nt = curtool; if (curtool == ter_tex) { if (keyc == 512 && m_x > 128) { txt = texturesearchhighlighted; - nt = ter_mixpaint; + nt = ter_tex_paint; } if (keyc == 515) texturesearchfirst += floor((vidsize_x)/128) - 1; @@ -233,7 +273,7 @@ float(float keyc, float unic, vector m) editor_terrain_key = } if (curtool == ter_radius) - txt = itos((int)eradius); + txt = itos((int)fabs(eradius)); if (curtool == ter_quant) txt = itos((int)equant); if (curtool == ter_strength) @@ -246,14 +286,7 @@ float(float keyc, float unic, vector m) editor_terrain_key = txt = tex[painttex]; if (keyc == 10 || keyc == 13) - { - if (curtool == ter_mesh) - nt = ter_mesh_add; - else if (curtool == ter_tintval) - nt = ter_tint; - else - nt = ter_mixpaint; - } + nt = lasttool; else if (keyc == 127) txt = substring(txt, 0, -2); else if (keyc == 8) @@ -262,7 +295,11 @@ float(float keyc, float unic, vector m) editor_terrain_key = txt = strcat(txt, chr2str(unic)); if (curtool == ter_radius) - eradius = stof(txt); + { + eradius = fabs(stof(txt)); + if (squaretool) + eradius *= -1; + } if (curtool == ter_quant) equant = stof(txt); if (curtool == ter_strength) @@ -286,21 +323,46 @@ float(float keyc, float unic, vector m) editor_terrain_key = tint[painttex] = txt; } - curtool = nt; + if (curtool != nt) + { + lasttool = curtool; + curtool = nt; + } } else if (keyc == 13 || (keyc == 512 && m_x < 128)) { if (m_x < 128) - curtool = floor((m_y-16) / 8); + { + nt = floor((m_y-16) / 8); + if (nt != curtool) + { + if (nt == ter_roundpegsquarehole) + { + squaretool = !squaretool; + eradius = fabs(eradius); + if (squaretool) eradius *= -1; + } + else + { + lasttool = curtool; + curtool = nt; + } + } + } else if (keyc == 13) { editor_do(m); } } else if (unic == '+' || unic == '=') - eradius += 16; + eradius += squaretool?-16:16; else if (unic == '-') - eradius -= 16; + { + eradius = fabs(eradius) - 16; + if (eradius < 0) + eradius = 0; + if (squaretool) eradius *= -1; + } else if (curtool == ter_mesh_add && tempent) { if (unic == '[') @@ -330,6 +392,10 @@ float(float keyc, float unic, vector m) editor_terrain_key = else return FALSE; } + else if (unic == '(') + epercent -= 10; + else if (unic == ')') + epercent += 10; else if (unic == '[') equant -= 1; else if (unic == ']') @@ -374,8 +440,8 @@ void(vector mousepos) editor_terrain_add = if (mousepos_x < 128) return; - vector t = unproject(mousepos + '0 0 8192'); - vector o = unproject(mousepos); + vector t = mousefar; + vector o = mousenear; if (vlen(o - t) > 8192) t = o + normalize(t)*8192; traceline(o, t, TRUE, world); @@ -466,13 +532,15 @@ void(vector mousepos) editor_terrain_overlay = colour = '1 1 1'; if (i == ter_radius) - drawstring(pos, sprintf("radius: %g", eradius), '8 8 0', colour, 1, 0); + drawstring(pos, sprintf("radius: %g", fabs(eradius)), '8 8 0', colour, 1, 0); else if (i == ter_quant) drawstring(pos, sprintf("quantity: %g", equant), '8 8 0', colour, 1, 0); else if (i == ter_strength) drawstring(pos, sprintf("percent: %g%%", epercent), '8 8 0', colour, 1, 0); else if (i == ter_mesh) drawstring(pos, sprintf("mesh: %s", meshname), '8 8 0', colour, 1, 0); + else if (i == ter_roundpegsquarehole) + drawstring(pos, sprintf("shape: %s", (squaretool?"square peg":"round")), '8 8 0', colour, 1, 0); else if (i == ter_tex) { if (curtool == ter_tex_get)