Added a particle effect editor. A few issues still to fix (like being unable to add a new effect).

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3966 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2012-01-28 10:31:55 +00:00
parent 4496bb6ea0
commit 03f3cc738f
7 changed files with 1518 additions and 47 deletions

View File

@ -7,9 +7,11 @@ enum
MODE_INITIAL=0,
MODE_LIGHTEDIT=1,
MODE_SPLINEEDIT=2
MODE_SPLINEEDIT=2,
MODE_PARTICLEEDIT=3
};
var vector vidsize = '640 480 0';
vector curmousepos;
float mousedown;
@ -106,10 +108,20 @@ void() wrap_renderscene =
col = '1 1 1';
drawrawstring('64 0 0'*(MODE_SPLINEEDIT-1), "SPLINES", '8 8 0', col, 1);
if (autocvar_ca_editormode == MODE_PARTICLEEDIT)
col = '1 0 0';
else if (curmousepos_y < 8 && curmousepos_x >= 64*(MODE_PARTICLEEDIT-1) && curmousepos_x < 64*MODE_PARTICLEEDIT)
col = '0 0 1';
else
col = '1 1 1';
drawrawstring('64 0 0'*(MODE_PARTICLEEDIT-1), "PARTICLES", '8 8 0', col, 1);
if (autocvar_ca_editormode == MODE_LIGHTEDIT)
editor_lights_overlay(curmousepos);
else if (autocvar_ca_editormode == MODE_SPLINEEDIT)
editor_spline_overlay(curmousepos);
else if (autocvar_ca_editormode == MODE_PARTICLEEDIT)
editor_particles_overlay(curmousepos);
drawcharacter(curmousepos - '4 4', '+', '8 8', '1 1 1', 1);
};
@ -136,6 +148,11 @@ float (float event, float parama, float paramb) wrap_InputEvent =
if (editor_spline_key(parama, paramb, curmousepos))
return TRUE;
}
else if (autocvar_ca_editormode == MODE_PARTICLEEDIT)
{
if (editor_particles_key(parama, paramb, curmousepos))
return TRUE;
}
if (parama == 512)
{
mousedown = 1;
@ -162,10 +179,10 @@ float (float event, float parama, float paramb) wrap_InputEvent =
curmousepos_x = 0;
if (curmousepos_y < 0)
curmousepos_y = 0;
if (curmousepos_x > 640)
curmousepos_x = 640;
if (curmousepos_y > 480)
curmousepos_y = 480;
if (curmousepos_x > vidsize_x)
curmousepos_x = vidsize_x;
if (curmousepos_y > vidsize_y)
curmousepos_y = vidsize_y;
return TRUE;
}
else if (event == 3)
@ -188,6 +205,9 @@ float (float event, float parama, float paramb) wrap_InputEvent =
/*this is a fallback function, in case the main progs does not have one*/
void(float width, float height, float do2d) CSQC_UpdateView =
{
vidsize_x = width;
vidsize_y = height;
vidsize_z = 0;
clearscene();
setproperty(VF_DRAWENGINESBAR, 1);
setproperty(VF_DRAWCROSSHAIR, 1);

View File

@ -1,7 +1,10 @@
../csaddon.dat
//pr_dumpplatform -FFTE -Fdefines -TCS -O csplat
opts.qc
csplat.qc
editor_lights.qc
textfield.qc
editor_particles.qc
cam.qc
csaddon.qc

View File

@ -0,0 +1,679 @@
/*
This file was automatically generated by FTE QuakeWorld v1.01
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
*/
#pragma noref 1
#pragma target FTE
#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;
float intermission;
vector v_forward, v_up, v_right;
vector view_angles;
float trace_allsolid, trace_startsolid, trace_fraction;
vector trace_endpos, trace_plane_normal;
float trace_plane_dist;
entity trace_ent;
float trace_inopen;
float trace_inwater;
float input_timelength;
vector input_angles;
vector input_movevalues;
float input_buttons;
float input_impulse;
void end_sys_globals;
.float modelindex;
.vector absmin, absmax;
.float entnum;
.float drawmask;
.void() predraw;
.float movetype;
.float solid;
.vector origin;
.vector oldorigin;
.vector velocity;
.vector angles;
.vector avelocity;
.float pmove_flags;
.string classname;
.float renderflags;
.string model;
.float frame;
.float frame1time;
.float frame2;
.float frame2time;
.float lerpfrac;
.float skin;
.float effects;
.vector mins, maxs;
.vector size;
.void() touch;
.void() think;
.void() blocked;
.float nextthink;
.entity chain;
.entity enemy;
.float flags;
.float colormap;
.entity owner;
void end_sys_fields;
.vector punchangle;
.float gravity;
.float hull;
.entity movechain;
.void() chainmoved;
.float dimension_solid;
.float dimension_hit;
.float scale;
.float fatness;
.float alpha;
.entity tag_entity;
.float skeletonindex;
.vector colormod;
.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;
.vector glowmod;
.float ideal_pitch;
.float pitch_speed;
var float physics_mode = 2;
#define TRUE 1
#define FALSE 0
#define MOVETYPE_NONE 0
#define MOVETYPE_WALK 3
#define MOVETYPE_STEP 4
#define MOVETYPE_FLY 5
#define MOVETYPE_TOSS 6
#define MOVETYPE_PUSH 7
#define MOVETYPE_NOCLIP 8
#define MOVETYPE_FLYMISSILE 9
#define MOVETYPE_BOUNCE 10
#define MOVETYPE_BOUNCEMISSILE 11
#define MOVETYPE_FOLLOW 12
#define MOVETYPE_PHYSICS 32
#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_PHYSICS_BOX 32
#define SOLID_PHYSICS_SPHERE 33
#define SOLID_PHYSICS_CAPSULE 34
#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 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 CHAN_WEAPON 1
#define CHAN_VOICE 2
#define CHAN_ITEM 3
#define CHAN_BODY 4
#define ATTN_NONE 0
#define ATTN_NORM 1
#define FL_FLY 1
#define FL_SWIM 2
#define FL_CLIENT 8
#define FL_INWATER 16
#define FL_MONSTER 32
#define FL_ITEM 256
#define FL_ONGROUND 512
#define FL_PARTIALGROUND 1024
#define FL_WATERJUMP 2048
#define FL_FINDABLE_NONSOLID 16384
#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 EF_BRIGHTFIELD 1
#define EF_MUZZLEFLASH 2
#define EF_BRIGHTLIGHT 4
#define EF_DIMLIGHT 8
#define EF_ADDITIVE 32
#define EF_BLUE 64
#define EF_RED 128
#define EF_FULLBRIGHT 512
#define EF_NODEPTHTEST 8192
#define STAT_HEALTH 0
#define STAT_WEAPON 2
#define STAT_AMMO 3
#define STAT_ARMOR 4
#define STAT_WEAPONFRAME 5
#define STAT_SHELLS 6
#define STAT_NAILS 7
#define STAT_ROCKETS 8
#define STAT_CELLS 9
#define STAT_ACTIVEWEAPON 10
#define STAT_TOTALSECRETS 11
#define STAT_TOTALMONSTERS 12
#define STAT_SECRETS 13
#define STAT_MONSTERS 14
#define STAT_ITEMS 15
#define STAT_VIEWHEIGHT 16
#define STAT_VIEW2 20
#define STAT_VIEWZOOM 21
#define VF_MIN 1
#define VF_MIN_X 2
#define VF_MIN_Y 3
#define VF_SIZE 4
#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_ORIGIN_X 12
#define VF_ORIGIN_Y 13
#define VF_ORIGIN_Z 14
#define VF_ANGLES 15
#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_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 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 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 LFIELD_ORIGIN 0
#define LFIELD_COLOUR 1
#define LFIELD_RADIUS 2
#define LFIELD_FLAGS 3
#define LFIELD_STYLE 4
#define LFIELD_ANGLES 5
#define LFIELD_FOV 6
#define LFIELD_CORONA 7
#define LFIELD_CORONASCALE 8
#define LFIELD_CUBEMAPNAME 9
#define LFIELD_AMBIENTSCALE 10
#define LFIELD_DIFFUSESCALE 11
#define LFIELD_SPECULARSCALE 12
#define LFLAG_NORMALMODE 1
#define LFLAG_REALTIMEMODE 2
#define LFLAG_LIGHTMAP 4
#define LFLAG_FLASHBLEND 8
#define LFLAG_NOSHADOWS 256
#define LFLAG_SHADOWMAP 512
#define LFLAG_CREPUSCULAR 1024
void(vector) 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;
#ifdef SSQC
void(float style, float val) lightstylestatic = #5;
void() break = #6;
#endif
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;
#ifdef SSQC
entity() checkclient = #17;
#endif
entity(entity start, .string fld, string match) find = #18;
void(string s) precache_sound = #19;
void(string s) precache_model = #20;
#ifdef SSQC
void(entity client, string s) stuffcmd = #21;
#endif
entity(vector org, float rad) findradius = #22;
#ifdef SSQC
void(string s) bprint = #23;
void(entity client, string s) sprint = #24;
#endif
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;
#ifdef SSQC
vector(entity player, float missilespeed) aim = #44;
#endif
float(string) cvar = #45;
void(string, ...) localcmd = #46;
entity(entity) nextent = #47;
void(vector pos, vector dir, float colour, float count) particle = #48;
#define ChangeYaw changeyaw
void() changeyaw = #49;
vector(vector fwd, optional vector up) vectoangles = #51;
#ifdef SSQC
void(float to, float val) WriteByte = #52;
void(float to, float val) WriteChar = #53;
void(float to, float val) WriteShort = #54;
void(float to, float val) WriteLong = #55;
void(float to, float val) WriteCoord = #56;
void(float to, float val) WriteAngle = #57;
void(float to, string val) WriteString = #58;
void(float to, entity val) WriteEntity = #59;
#endif
float(float angle) sin = #60;
float(float angle) cos = #61;
float(float value) sqrt = #62;
void(entity ent) changepitch = #63;
void(entity ent, entity ignore) tracetoss = #64;
string(entity ent) etos = #65;
void(float step) movetogoal = #67;
#ifdef SSQC
void(string s) precache_file = #68;
#endif
void(entity e) makestatic = #69;
#ifdef SSQC
void(string mapname) changelevel = #70;
#endif
void(string cvarname, string valuetoset) cvar_set = #72;
#ifdef SSQC
void(entity ent, string text, ...) centerprint = #73;
#endif
void (vector pos, string samp, float vol, float atten) ambientsound = #74;
void(string str) precache_model2 = #75;
void(string str) precache_sound2 = #76;
#ifdef SSQC
void(string str) precache_file2 = #77;
void() setspawnparms = #78;
void(entity killer, entity killee) logfrag = #79;
string(entity e, string key) infokey = #80;
#endif
float(string) stof = #81;
#ifdef SSQC
void(vector where, float set) multicast = #82;
#endif
void(vector start, vector mins, vector maxs, vector end, float nomonsters, entity ent) tracebox = #90;
vector() randomvec = #91;
vector(vector org) getlight = #92;
void(string cvarname, string defaultvalue) registercvar = #93;
float(float a, float b, ...) min = #94;
float(float a, float b, ...) max = #95;
float(float minimum, float val, float maximum) bound = #96;
float(float value, float exp) pow = #97;
entity(entity start, .float fld, float match) findfloat = #98;
float(string extname) checkextension = #99;
#ifdef SSQC
float(string builtinname) builtin_find = #100;
float(float value) anglemod = #102;
void(string slot, string picname, float x, float y, float zone, optional entity player) showpic = #104;
void(string slot, optional entity player) hidepic = #105;
void(string slot, float x, float y, float zone, optional entity player) movepic = #106;
void(string slot, string picname, optional entity player) changepic = #107;
#endif
float(string filename, float mode, optional float mmapminsize) fopen = #110;
void(float fhandle) fclose = #111;
string(float fhandle) fgets = #112;
void(float fhandle, string s) fputs = #113;
float(string s) strlen = #114;
string(string s1, optional string s2, ...) strcat = #115;
string(string s, float start, float length) substring = #116;
vector(string s) stov = #117;
string(string s) strzone = #118;
void(string s) strunzone = #119;
#ifdef SSQC
void(string cvar, float val) cvar_setf = #176;
#endif
float(string modelname, optional float queryonly) getmodelindex = #200;
__variant(float prnum, string funcname, ...) externcall = #201;
float(string progsname) addprogs = #202;
__variant(float prnum, string varname) externvalue = #203;
void(float prnum, __variant newval, string varname) externset = #204;
float(string input, string token) instr = #206;
void(float portal, float state) openportal = #207;
#ifdef SSQC
float(float attributes, string effectname, ...) RegisterTempEnt = #208;
void(float type, vector pos, ...) CustomTempEnt = #209;
float(optional float sleeptime) fork = #210;
#endif
void(optional __variant ret) abort = #211;
#ifdef SSQC
void(float sleeptime) sleep = #212;
void(entity player, string key, string value) forceinfokey = #213;
void(string filename, float starttag, entity edict) chat = #214;
#endif
void(vector org, vector dmin, vector dmax, float colour, float effect, float count) particle2 = #215;
void(vector org, vector box, float colour, float effect, float count) particle3 = #216;
void(vector org, float radius, float colour, float effect, float count) particle4 = #217;
float(float number, float quantity) bitshift = #218;
void(vector pos) te_lightningblood = #219;
float(string s1, string sub, optional float startidx) strstrofs = #221;
float(string str, float index) str2chr = #222;
string(float chr, ...) chr2str = #223;
string(float ccase, float redalpha, float redchars, string str, ...) strconv = #224;
string(float pad, string str1, ...) strpad = #225;
string(string old, string key, string value) infoadd = #226;
string(string info, string key) infoget = #227;
float(string s1, string s2, float len) strncmp = #228;
float(string s1, string s2) strcasecmp = #229;
float(string s1, string s2, float len) strncasecmp = #230;
void() calltimeofday = #231;
#ifdef SSQC
void(float num, float type, .void fld) clientstat = #232;
void(float num, float type, string name) globalstat = #233;
void(entity player) isbackbuffered = #234;
#endif
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
void(vector org, optional float count) te_bloodqw = #239;
#ifdef SSQC
float(vector viewpos, entity entity) checkpvs = #240;
entity(string match, optional float matchnum) matchclientname = #241;
void(string dest, string content) sendpacket = #242;
#endif
#ifdef CSQC
vector(entity ent, float tagnum) rotatevectorsbytag = #244;
#endif
int(string) stoi = #259;
string(int) itos = #260;
int(string) stoh = #261;
string(int) htos = #262;
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;
void(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;
#ifdef SSQC
void(float buf, float fl) writefloat = #280;
#endif
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;
#ifdef CSQC
void() clearscene = #300;
void(float mask) addentities = #301;
void(entity ent) addentity = #302;
#define setviewprop setproperty
float(float property, ...) setproperty = #303;
void() renderscene = #304;
float(vector org, float radius, vector lightcolours) dynamiclight_add = #305;
void(string texturename) R_BeginPolygon = #306;
void(vector org, vector texcoords, vector rgb, float alpha) R_PolygonVertex = #307;
void() R_EndPolygon = #308;
#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;
float() readbyte = #360;
float() readchar = #361;
float() readshort = #362;
float() readlong = #363;
float() readcoord = #364;
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(entity from, entity to) copyentity = #400;
#ifdef SSQC
void(entity from, entity to) setcolors = #401;
#endif
entity(string field, string match) findchain = #402;
entity(float fld, float match) findchainfloat = #403;
void(vector org, string modelname, float startframe, float endframe, float framerate) effect = #404;
void(vector org, vector dir, float count) te_blood = #405;
void(vector mincorner, vector maxcorner, float explosionspeed, float howmany) te_bloodshower = #406;
void(vector org, vector color) te_explosionrgb = #407;
void(vector mincorner, vector maxcorner, vector vel, float howmany, float color, float gravityflag, float randomveljitter) te_particlecube = #408;
void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlerain = #409;
void(vector mincorner, vector maxcorner, vector vel, float howmany, float color) te_particlesnow = #410;
void(vector org, vector vel, float howmany) te_spark = #411;
void(vector org) te_gunshotquad = #412;
void(vector org) te_spikequad = #413;
void(vector org) te_superspikequad = #414;
void(vector org) te_explosionquad = #415;
void(vector org) te_smallflash = #416;
void(vector org, float radius, float lifetime, vector color) te_customflash = #417;
void(vector org) te_gunshot = #418;
void(vector org) te_spike = #419;
void(vector org) te_superspike = #420;
void(vector org) te_explosion = #421;
void(vector org) te_tarexplosion = #422;
void(vector org) te_wizspike = #423;
void(vector org) te_knightspike = #424;
void(vector org) te_lavasplash = #425;
void(vector org) te_teleport = #426;
void(vector org, float color, float colorlength) te_explosion2 = #427;
void(entity own, vector start, vector end) te_lightning1 = #428;
void(entity own, vector start, vector end) te_lightning2 = #429;
void(entity own, vector start, vector end) te_lightning3 = #430;
void(entity own, vector start, vector end) te_beam = #431;
void(vector dir) vectorvectors = #432;
void(vector org) te_plasmaburn = #433;
float(entity e, float s) getsurfacenumpoints = #434;
vector(entity e, float s, float n) getsurfacepoint = #435;
vector(entity e, float s) getsurfacenormal = #436;
string(entity e, float s) getsurfacetexture = #437;
float(entity e, vector p) getsurfacenearpoint = #438;
#ifdef SSQC
void(entity e, string s) clientcommand = #440;
#endif
float(string s) tokenize = #441;
string(float n) argv = #442;
#ifdef SSQC
void(entity e, entity tagentity, string tagname) setattachment = #443;
#endif
float(string pattern, float caseinsensitive, float quiet) search_begin = #444;
void(float handle) search_end = #445;
float(float handle) search_getsize = #446;
string(float handle, float num) search_getfilename = #447;
string(string cvarname) cvar_string = #448;
entity(entity start, .entity fld, float match) findflags = #449;
entity(.float fld, float match) findchainflags = #450;
float(entity ent, string tagname) gettagindex = #451;
vector(entity ent, float tagindex) gettaginfo = #452;
#ifdef SSQC
void(entity player) dropclient = #453;
entity() spawnclient = #454;
float(entity client) clienttype = #455;
void(float target, string str) WriteUnterminatedString = #456;
#endif
entity(float entnum) edict_num = #459;
float() buf_create = #460;
void(float bufhandle) buf_del = #461;
float(float bufhandle) buf_getsize = #462;
void(float bufhandle_from, float bufhandle_to) buf_copy = #463;
void(float bufhandle, float sortpower, float backward) buf_sort = #464;
string(float bufhandle, string glue) buf_implode = #465;
string(float bufhandle, float string_index) bufstr_get = #466;
void(float bufhandle, float string_index, string str) bufstr_set = #467;
float(float bufhandle, string str, float order) bufstr_add = #468;
void(float bufhandle, float string_index) bufstr_free = #469;
float(float s) asin = #471;
float(float c) acos = #472;
float(float t) atan = #473;
float(float c, float s) atan2 = #474;
float(float a) tan = #475;
float(string s) strlennocol = #476;
string(string s) strdecolorize = #477;
string(float uselocaltime, string format, ...) strftime = #478;
float(string s, string separator1, ...) tokenizebyseparator = #479;
string(string s) strtolower = #480;
string(string s) strtoupper = #481;
string(string s) cvar_defstring = #482;
#ifdef CSQC
void(vector origin, string sample, float volume, float attenuation) pointsound = #483;
#endif
string(string search, string replace, string subject) strreplace = #484;
string(string search, string replace, string subject) strireplace = #485;
//vector(entity e, float s, float n, float a) getsurfacepointattribute = #486;
#ifdef CSQC
float(string name) gecko_create = #487;
void(string name) gecko_destroy = #488;
void(string name, string URI) gecko_navigate = #489;
float(string name, float key, float eventtype) gecko_keyevent = #490;
void(string name, float x, float y) gecko_mousemove = #491;
void(string name, float w, float h) gecko_resize = #492;
vector(string name) gecko_get_texture_extent = #493;
#endif
float(float caseinsensitive, string s, ...) crc16 = #494;
float(string name) cvar_type = #495;
//float() numentityfields = #496;
//string(float fieldnum) entityfieldname = #497;
//float(float fieldnum) entityfieldtype = #498;
//string(float fieldnum, entity ent) getentityfieldstring = #499;
//float(float fieldnum, entity ent, string s) putentityfieldstring = #500;
//void(float to, string s, float sz) WritePicture = #501;
string(string filename) whichpack = #503;
string(string in) uri_escape = #510;
string(string in) uri_unescape = #511;
float(entity ent) num_for_edict = #512;
void(string str) tokenize_console = #514;
float(float idx) argv_start_index = #515;
float(float idx) argv_end_index = #516;
string(string cvarname) cvar_description = #518;
#ifdef CSQC
float(optional float timetype) gettime = #519;
#endif
#ifdef SSQC
float(string mname) precache_vwep_model = #532;
#endif
#pragma noref 0

View File

@ -18,15 +18,15 @@ void() editor_lights_add =
setmodel(tempent, autocvar_cg_editor_lightmodel);
while(l > 0)
{
l = l-1;
l = l-1.0;
if (l == selectedlight)
{
if (gettime(0)*5 & 1)
if (gettime(0)*5f & 1)
continue;
tempent.effects |= 8192;
tempent.effects |= 8192f;
}
else
tempent.effects &~= 8192;
tempent.effects &~= 8192f;
if (!(float)dynamiclight_get(l, LFIELD_RADIUS))
continue;
setorigin(tempent, dynamiclight_get(l, LFIELD_ORIGIN));
@ -34,28 +34,31 @@ void() editor_lights_add =
}
};
#define NUMLFIELDS 11
#define NUMLFIELDS 14
static string fldname[NUMLFIELDS+1] = { "bad",
"num",
"org",
"rgb",
"rad",
"flg",
"sty",
"ang",
"fov",
"cmp",
"cor",
"csc"
" num",
" org",
" rgb",
" rad",
" flg",
" sty",
" ang",
" fov",
" cmp",
" cor",
" csc",
" amb",
" dif",
" spc"
};
static string(float fld, float foredit) readfield =
static string(int fld, float foredit) readfield =
{
switch(fld)
{
case 1:
if (foredit)
return ftos(selectedlight);
return strcat(ftos(selectedlight), " / ", ftos(dynamiclight_get(-1, -1)));
return strcat(ftos(selectedlight), " / ", ftos(dynamiclight_get(-1f, -1f)));
case 2:
return vtos(dynamiclight_get(selectedlight, LFIELD_ORIGIN));
case 3:
@ -85,6 +88,12 @@ static string(float fld, float foredit) readfield =
return ftos(dynamiclight_get(selectedlight, LFIELD_CORONA));
case 11:
return ftos(dynamiclight_get(selectedlight, LFIELD_CORONASCALE));
case 12:
return ftos(dynamiclight_get(selectedlight, LFIELD_AMBIENTSCALE));
case 13:
return ftos(dynamiclight_get(selectedlight, LFIELD_DIFFUSESCALE));
case 14:
return ftos(dynamiclight_get(selectedlight, LFIELD_SPECULARSCALE));
default:
return "";
}
@ -115,7 +124,7 @@ static void(float fld, string newval) writefield =
if (strstrofs(newval, "c")>=0) fl |= LFLAG_NOSHADOWS;
if (strstrofs(newval, "s")>=0) fl |= LFLAG_SHADOWMAP;
if (strstrofs(newval, "r")>=0) fl |= LFLAG_CREPUSCULAR;
dynamiclight_set(selectedlight, LFIELD_FLAGS, fl);
dynamiclight_set(selectedlight, LFIELD_FLAGS, (float)fl);
return;
case 6:
dynamiclight_set(selectedlight, LFIELD_STYLE, stof(newval));
@ -135,6 +144,15 @@ static void(float fld, string newval) writefield =
case 11:
dynamiclight_set(selectedlight, LFIELD_CORONASCALE, stof(newval));
return;
case 12:
dynamiclight_set(selectedlight, LFIELD_AMBIENTSCALE, stof(newval));
return;
case 13:
dynamiclight_set(selectedlight, LFIELD_DIFFUSESCALE, stof(newval));
return;
case 14:
dynamiclight_set(selectedlight, LFIELD_SPECULARSCALE, stof(newval));
return;
default:
return;
}
@ -142,13 +160,13 @@ static void(float fld, string newval) writefield =
void(vector m) editor_lights_overlay =
{
float i;
int i;
string s;
vector col;
m_y = floor((m_y - 32) / 8);
m_y = floor((m_y - 32f) / 8f);
for (i = 1; i <= NUMLFIELDS; i++)
for (i = 1f; i <= NUMLFIELDS; i++)
{
if (editfield == i)
s = editvalue;
@ -163,30 +181,30 @@ void(vector m) editor_lights_overlay =
else
col = '1 1 1';
drawrawstring('0 32 0' + '0 8 0' * i, s, '8 8 0', col, 1);
drawrawstring('0 32 0' + '0 8 0' * (float)i, s, '8 8 0', col, 1);
}
i+=1;
if (editfield == 5)
{
drawrawstring('0 32 0' + '0 8 0' * i, "d: dynamic mode\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * i, "w: realtime world lights mode\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * i, "l: lightmap hack (not valid above index 32)\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * i, "f: flashblend coronas\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * i, "c: does not cast shadows\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * i, "s: shadowmapped light\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * i, "r: crepuscular rays\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "d: dynamic mode\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "w: realtime world lights mode\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "l: lightmap hack (not valid above index 32)\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "f: flashblend coronas\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "c: does not cast shadows\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "s: shadowmapped light\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "r: crepuscular rays\n", '8 8 0', '1 1 1', 1); i+=1;
}
else
{
drawrawstring('0 32 0' + '0 8 0' * i, "+/- change selected light\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * i, "mouse also selects lights\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * i, "m moves the light to the crosshair\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * i, "i inserts new light\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * i, "p points the light to aim at the crosshair\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * i, "[ and ] move the light towards/away from indicated plane\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * i, "don't forget to save\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "+/- change selected light\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "mouse also selects lights\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "m moves the light to the crosshair\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "i inserts new light\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "p points the light to aim at the crosshair\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "[ and ] move the light towards/away from indicated plane\n", '8 8 0', '1 1 1', 1); i+=1;
drawrawstring('0 32 0' + '0 8 0' * (float)i, "don't forget to save\n", '8 8 0', '1 1 1', 1); i+=1;
}
};
@ -194,7 +212,7 @@ static void(vector fwd, vector vorg) selectbestlight =
{
float l, b=selectedlight, d, bd;
vector ldir;
l = dynamiclight_get(-1, -1);
l = dynamiclight_get(-1f, -1f);
while(l > 0)
{
l--;
@ -223,7 +241,7 @@ float(float keyc, float unic, vector m) editor_lights_key =
strunzone(editvalue);
editfield = 0;
}
editfield = floor((m_y - 32) / 8);
editfield = floor((m_y - 32f) / 8f);
if (editfield <= 0 || editfield > NUMLFIELDS || m_x >= 64)
{
editfield = 0;
@ -282,8 +300,8 @@ float(float keyc, float unic, vector m) editor_lights_key =
else if (keyc == 'p')
{
traceline(o, t, TRUE, world);
vector ang = vectoangles((trace_endpos + trace_plane_normal*4) - (vector)dynamiclight_get(selectedlight, LFIELD_ORIGIN));
ang_x *= -1;
vector ang = vectoangles((trace_endpos + trace_plane_normal*4f) - (vector)dynamiclight_get(selectedlight, LFIELD_ORIGIN));
ang_x *= -1f;
dynamiclight_set(selectedlight, LFIELD_ANGLES, ang);
/*if we're pointing the light at something, it should probably have a fov*/
@ -306,7 +324,7 @@ float(float keyc, float unic, vector m) editor_lights_key =
/*place it at the pointed location*/
traceline(o, t, TRUE, world);
dynamiclight_set(selectedlight, LFIELD_ORIGIN, trace_endpos + trace_plane_normal*4);
dynamiclight_set(selectedlight, LFIELD_ORIGIN, trace_endpos + trace_plane_normal*4f);
break;
}
}

View File

@ -0,0 +1,410 @@
static float cureffect;
static float curmodified;
textfield_linedesc_t fields[100] =
{
{"shader", "shader <shadername>\\n{\\nshaderbody\\n}"},
{"texture", "texture <shadername>"},
{"tcoords", "tcoords <s1> <t1> <s2> <t2> [coordscale] [randcount] [randsinc]\ncoordscale is an optional divisor for more readable numbers.\nrandcount is a the number of images used in particlefont image.\nrandsinc is the amount to add to s coords to display each sequential randomized image."},
{"rotationstart", "rotationstart <minangle> [maxangle]\nan angle of 45 will give you a particle aligned to screen coords"},
{"rotationspeed", "rotationspeed <min> <max>\nspecifies a range of rotational speeds. You probably want to set the min value as negative."},
{"beamtexstep", "beamtexstep <documentme>"},
{"scale", "scale <min> [max]\nValues are 4 times higher than quake units"},
{"scalerand", "use scale instead"},
{"scalefactor", "scalefactor <factor>\nHow much the particle shrinks with distance.\n1=true scaling"},
{"scaledelta", "scaledelta <changepersecond>\nHow much the particle's scale changes per second"},
{"step", "step <dist>\nworld distance between each particle within a particle trail."},
{"count", "count <multiplier>\nProvides a multiplier value independant from the particle() builtin or other mechanisms"},
{"alpha", "alpha <val>\nInitial opacity of particle. 0 is invisible, 1 is fully visible."},
{"alphachange", "depricated. use alphadelta"},
{"alphadelta", "alphadelta <alphapersecond>\n How much the alpha value changes per second"},
{"die", "die <min> [max]\nHow long the particle lives for"},
{"diesubrand", "depricated. use die"},
{"randomvel", "<documentme>"},
{"veladd", "<documentme>"},
{"orgadd", "<documentme>"},
{"friction", "<documentme>"},
{"gravity", "gravity <grav>\nParticle's downwards velocity will be increased by this much per second"},
{"clipbounce", "<documentme>"},
{"assoc", "assoc <othereffectname>\nWhen the effect is spawned, the associated effect will also be spawned. Can chain."},
{"inwater", "inwater <othereffectname>\nIf the particle effect is spawned underwater, the named effect will be used instead."},
{"model", "model <modelname> <firstframe> <lastframe> <framerate> <alpha>\nSpawns a the sprite/model when the effect is spawned.\nCan be specified multiple times and a random model line will be used.\nModels with only 1 frame will animate skins instead."},
{"colorindex", "colourindex <min> <max>\nIf set, the particle's colour will be set to this palette index instead of the particle's rgb field."},
{"colorrand", "depricated"},
{"citracer", "citracer\nFlag that syncronizes colorindex-based palette indexes with spawn ordering ala quake."},
{"red", "depricated, use rgb."},
{"green", "depricated, use rgb."},
{"blue", "depricated, use rgb."},
{"rgb", "rgb <red> <green> <blue>\nInitial colour of particle, in a scale of 0 to 255."},
{"reddelta", "depricated, use rgbdelta."},
{"greendelta", "depricated, use rgbdelta."},
{"bluedelta", "depricated, use rgbdelta."},
{"rgbdelta", "rgbdelta <red> <green> <blue>\nSpecifies the change in particle colours over a second of time. The effective range is 0 to 255, but larger values might be needed for short-lived effects."},
{"rgbdeltatime", "rgbdeltatime <age>\nOnce the particle reaches this age, its rgb values will stop changing."},
{"redrand", "depricated"},
{"greenrand", "depricated"},
{"bluerand", "depricated"},
{"rgbrand", "rgbrand <red> <green> <blue>\nThis rgb value will be multiplied by a random value between 0 and 1 and added to the particle's initial rgb value. All three channels channels are scaled independantly."},
{"rgbrandsync", "rgbrandsync <red> <green> <blue>\nThis rgb value will be multiplied by a random value between 0 and 1 and added to the particle's initial rgb value. All three channels will be scaled the same."},
{"redrandsync", "depricated"},
{"greenrandsync", "depricated"},
{"bluerandsync", "depricated"},
{"stains", "stains <radius>\nSpecifies a multiplier for the radius of a stain if the particle impacts upon a wall"},
{"blend", "blend <blendmode>\nOne of add, subtract, blendcolour, or blendalpha. Particles with additive blend modes will render fastest due to no depth sorting requirement."},
{"spawnmode", "<documentme>"},
{"type", "type <rendertype>\nOne of:\nbeam - quads generated between particles\nspark - a single line drawn in direction of motion\nsparkfan - triangle fan oriented in direction of motion\ntexturedspark - quads extruded along line of motion\ndecal - motionless effect that attaches to surfaces around the center of the effect\nnormal - simple screen-facing quad"},
{"isbeam", "depricated, use type."},
{"spawntime", "<documentme>"},
{"spawnchance", "<documentme>"},
{"cliptype", "<documentme>"},
{"clipcount", "<documentme>"},
{"emit", "<documentme>"},
{"emitinterval", "<documentme>"},
{"emitintervalrand", "<documentme>"},
{"emitstart", "<documentme>"},
{"areaspread", "<documentme>"},
{"areaspreadvert", "<documentme>"},
{"offsetspread", "<documentme>"},
{"offsetspreadvert", "<documentme>"},
{"spawnorg", "<documentme>"},
{"spawnvel", "<documentme>"},
{"spawnparm1", "<documentme>"},
{"spawnparm2", "<documentme>"},
{"up", "<documentme>"},
{"rampmode", "<documentme>"},
{"rampindexlist", "<documentme>"},
{"rampindex", "<documentme>"},
{"ramp", "<documentme>"},
{"perframe", "<documentme>"},
{"averageout", "<documentme>"},
{"nostate", "<documentme>"},
{"nospreadfirst", "<documentme>"},
{"nospreadlast", "<documentme>"},
{"lightradius", "<documentme>"},
{"lightradiusfade", "<documentme>"},
{"lightradiusrgb", "<documentme>"},
{"lightradiusrgbfade", "<documentme>"},
{"lighttime", "<documentme>"},
{__NULL__}
};
static textfield_t tf_particle;
#define MAXPARTICLETYPES 200
typedef struct
{
string efname;
int start;
int end;
} particledesc_t;
particledesc_t pdesc[MAXPARTICLETYPES];
int numptypes;
string particlesfile;
static entity ptrailent;
float mousedown;
static void(string descname) saveparticle;
static void(float newef) selecteffect =
{
if (newef == cureffect)
return;
if (curmodified)
saveparticle(cvar_string("ca_particleset"));
curmodified = FALSE;
cureffect = floor(newef);
if (cureffect < 0)
cureffect = 0;
textfield_fill(&tf_particle, substring(particlesfile, pdesc[cureffect].start, pdesc[cureffect].end - pdesc[cureffect].start));
if (ptrailent)
remove(ptrailent);
ptrailent = world;
};
static int(string src, int *start) skipblock =
{
string line;
int ls = *start, le;
int level = 0;
/*parse a string from the start of one { to its closing }*/
while(1)
{
le = strstrofs(particlesfile, "\n", ls);
if (le < 0)
break;
line = substring(particlesfile, ls, le - ls);
tokenize_console(line);
line = argv(0);
if (line == "{")
{
if (!level)
*start = le+1;
++level;
}
else if (line == "}")
{
if (level == 1)
return ls;
--level;
}
else if (!level)
return le+1;
ls = le+1;
}
return ls;
};
static void() updateloadedparticles =
{
string line;
int ls, le;
int ce = cureffect;
while(numptypes>0)
{
--numptypes;
strunzone(pdesc[numptypes].efname);
}
ls = 0;
while(1)
{
le = strstrofs(particlesfile, "\n", ls);
if (le < 0)
break;
// print("line: ", substring(particlesfile, ls, le - ls), "\n");
if (le - ls > 7)
if (substring(particlesfile, ls, 6) == "r_part")
{
line = substring(particlesfile, ls, le - ls);
tokenize_console(line);
if (argv(0) == "r_part")
{
pdesc[numptypes].efname = strzone(argv(1));
pdesc[numptypes].start = le+1;
le = skipblock(particlesfile, &pdesc[numptypes].start);
pdesc[numptypes].end = le;
// print("particle: ", pdesc[numptypes].efname, "\n", substring(particlesfile, pdesc[numptypes].start, pdesc[numptypes].end - pdesc[numptypes].start), "\n");
++numptypes;
}
}
ls = le+1;
}
cureffect = -1;
selecteffect(ce);
};
static void(string descname) loadparticles =
{
float f;
/*kill old string*/
if (particlesfile)
strunzone(particlesfile);
particlesfile = (string)0;
/*load new string*/
f = fopen(strcat("particles/", descname, ".cfg"), FILE_READNL);
if (f >= 0)
{
particlesfile = strzone(fgets(f));
fclose(f);
}
/*and find out where the particles are*/
updateloadedparticles();
localcmd(particlesfile);
localcmd("\n");
};
static void(string descname) saveparticle =
{
float f;
string newfile;
/*only do this if there's something to save*/
if (cureffect < 0)
return;
newfile = textfield_strcat(&tf_particle);
newfile = strcat(substring(particlesfile, 0, pdesc[cureffect].start), newfile, substring(particlesfile, pdesc[cureffect].end, -1));
strunzone(particlesfile);
particlesfile = "";
particlesfile = strzone(newfile);
if (descname != "")
{
f = fopen(strcat("particles/", descname, ".cfg"), FILE_WRITE);
if (f >= 0)
{
fputs(f, particlesfile);
fclose(f);
}
}
/*and recalculate where the particles are*/
updateloadedparticles();
};
static void() applyparticles =
{
if (tf_particle.dirty)
{
string sln;
int i;
if (cureffect >= numptypes)
return;
localcmd("r_part \"");
localcmd(pdesc[cureffect].efname);
localcmd("\"\n{\n");
textfield_localcmd(&tf_particle);
localcmd("}\n");
sln = strcat("+", pdesc[cureffect].efname);
for (i = cureffect + 1; i < numptypes; i++)
{
if (pdesc[i].efname == sln)
{
localcmd("r_part \"");
localcmd(pdesc[i].efname);
localcmd("\"\n{\n");
localcmd(substring(particlesfile, pdesc[i].start, pdesc[i].end - pdesc[i].start));
localcmd("}\n");
}
}
tf_particle.dirty = FALSE;
curmodified = TRUE;
}
};
float(float keyc, float unic, vector m) editor_particles_key =
{
if (m_y > 16 && m_y < 24 && m_x < 128)
{
string oval = strcat(cvar_string("ca_particleset"));
if (keyc == 127)
cvar_set("ca_particleset", substring(oval, 0, -2));
else if (unic)
cvar_set("ca_particleset", strcat(oval, chr2str(unic)));
else
return FALSE;
applyparticles();
if (curmodified)
saveparticle(oval);
curmodified = FALSE;
oval = cvar_string("ca_particleset");
loadparticles(oval);
return TRUE;
}
if (m_y < 32)
return FALSE;
/*middle mouse*/
if (keyc == 514)
{
mousedown = 3;
applyparticles();
}
else if (m_x < 128)
{
if (keyc == 512)
{
float ef, y;
ef = cureffect - 10;
if (ef < 0)
ef = 0;
y = 32;
selecteffect(ef + (m_y - y)/8);
}
return TRUE;
}
else
{
return textfield_key(&tf_particle, keyc, unic, m - '128 32 0');
}
return FALSE;
};
void(vector mousepos) editor_particles_overlay =
{
string n;
float ef;
vector y;
vector col;
string setname = cvar_string("ca_particleset");
if (!numptypes)
{
loadparticles(setname);
}
if (mousedown == 3 && cureffect >= 0 && cureffect < numptypes)
{
vector t = unproject(mousepos + '0 0 8192');
vector o = unproject(mousepos);
traceline(o, t, TRUE, world);
trace_endpos += trace_plane_normal * 4;
if (!ptrailent)
{
ptrailent = spawn();
ptrailent.origin = trace_endpos;
pointparticles(particleeffectnum(pdesc[cureffect].efname), trace_endpos, '0 0 -1', 1);
}
trailparticles(particleeffectnum(pdesc[cureffect].efname), ptrailent, ptrailent.origin, trace_endpos);
ptrailent.origin = trace_endpos;
}
else if (ptrailent)
{
remove(ptrailent);
ptrailent = world;
}
if (mousepos_y > 16 && mousepos_y < 24 && mousepos_x < 128)
drawstring('0 16 0', strcat(setname, ((time*4)&1)?"^1\x0b":""), '8 8 0', '1 1 1', 1, 0);
else
drawstring('0 16 0', ((setname=="")?"NO SET LOADED":setname), '8 8 0', '1 1 1', 1, 0);
ef = cureffect - 10;
if (ef < 0)
ef = 0;
y = '0 32 0';
for (; ; ef++)
{
if (ef >= numptypes)
break;
n = pdesc[ef].efname;
col = '1 1 1';
if (ef == cureffect)
col = '1 0 0';
drawrawstring(y, n, '8 8 0', col, 1, 0);
y_y += 8;
}
textfield_draw('128 32 0', &tf_particle, &fields);
};

View File

@ -0,0 +1,2 @@
//#pragma flag enable assumeint
//#pragma flag enable typeexplicit

View File

@ -0,0 +1,339 @@
/*reusable code to draw/edit/etc some generic text object*/
/*consult the brief blurb above each function to see what it does*/
/*this file deals with textfield_t pointers. allocate your textfield somewhere yourself (probably as a global, this is QC after all), before invoking this code with a pointer to it*/
#define TEXTFIELD_LINES 200i
typedef struct
{
string lines[TEXTFIELD_LINES];
int cursorline;
int cursorcol;
int linecount;
int dirty;
} textfield_t;
/*this is a text description thing*/
typedef struct
{
string name;
string desc;
} textfield_linedesc_t;
/*destroys the contents of a text field, releasing strings to the system (and clears ready for reuse)*/
void(textfield_t *fld) textfield_clean =
{
while(fld->linecount)
{
fld->linecount = fld->linecount - 1i;
strunzone(fld->lines[fld->linecount]);
fld->lines[fld->linecount] = (string)__NULL__;
}
fld->cursorline = 0i;
fld->cursorcol = 0i;
fld->dirty = TRUE; //because its changed
};
#pragma wrasm 1
/*fill a text field with data from a string. new lines are supported, but leading tabs and spaces will be stripped*/
void(textfield_t *fld, string text) textfield_fill =
{
string line;
float start, end, term;
while(fld->linecount)
{
fld->linecount = fld->linecount - 1i;
strunzone(fld->lines[fld->linecount]);
fld->lines[fld->linecount] = (string)__NULL__;
}
fld->cursorline = -1i;
fld->cursorcol = -1i;
start = 0;
for(;;)
{
end = strstrofs(text, "\n", start);
if (end < 0)
break;
while(text[start] == '\t')
++start;
term = end;
if (term) if (text[term-1] == '\r') term--;
line = substring(text, start, term - start);
end += 1;
if (fld->linecount == TEXTFIELD_LINES)
break;
fld->lines[fld->linecount] = strzone(line);
fld->linecount = fld->linecount + 1i;
start = end;
}
fld->dirty = TRUE;
};
#pragma wrasm 0
/*draws the text field on the screen at a given position.
there's no size argument, so make sure data doesn't cause the display to overflow intended area (personally I'm just going to put it at the bottom+right of the screen)*/
void(vector pos, textfield_t *fld, textfield_linedesc_t *fields) textfield_draw =
{
string t;
int l;
int nummatches;
int lastmatch;
for (l = 0i; l < fld->linecount; l+=1i, pos_y += 8)
{
if (l == fld->cursorline && ((cltime * 4) & 1))
{
t = substring(fld->lines[l], 0, fld->cursorcol);
drawrawstring(pos, t, '8 8 0', '1 1 1', 1, 0);
drawrawstring(pos + (0+fld->cursorcol) * '8 0 0', "\x0b", '8 8 0', '1 0 0', 1, 0);
t = substring(fld->lines[l], fld->cursorcol+1, -1);
drawrawstring(pos + (1+fld->cursorcol) * '8 0 0', t, '8 8 0', '1 1 1', 1, 0);
}
else
drawrawstring(pos, fld->lines[l], '8 8 0', '1 1 1', 1, 0);
}
if (fld->cursorline < 0)
return;
pos_y += 8;
pos_x += 64;
string cmd = fld->lines[fld->cursorline];
float llen = strstrofs(cmd, " ");
if (llen < 0f)
llen = strlen(cmd);
cmd = substring(cmd, 0, llen);
/*show command completion box*/
for (l = 0; fields[l].name; l++)
{
if (!strncmp(fields[l].name, cmd, llen))
{
nummatches++;
lastmatch = l;
/*if its an exact match, then stop here*/
if (cmd == fields[l].name)
{
nummatches = 1;
break;
}
}
}
if (nummatches == 1 && strlen(fields[lastmatch].name) == llen)
{
drawrawstring(pos, fields[lastmatch].desc, '8 8 0', '0 1 1', 1, 0);
}
else
{
/*show command completion box*/
for (l = 0; fields[l].name; l++)
{
if (!strncmp(fields[l].name, cmd, llen))
{
drawrawstring(pos, fields[l].name, '8 8 0', '0 1 1', 1, 0);
pos_y += 8;
}
}
}
};
/*send the entire text field into the localcmd builtin, newlines and all*/
void(textfield_t *fld) textfield_localcmd =
{
int l;
for (l = 0i; l < fld->linecount; l+=1i)
{
localcmd(fld->lines[l]);
localcmd("\n");
}
};
/*returns the current contents of the text field as a single tempstring (strcat, woo)*/
string(textfield_t *fld) textfield_strcat =
{
int l;
string res;
for (l = 0i; l < fld->linecount; l+=1i)
{
res = strcat(res, fld->lines[l], "\n");
}
return res;
};
/*if the user clicks+presses+etc upon the text field, do the magic here
the caller will need to track selected wigit themselves.*/
float(textfield_t *fld, float keyc, float unic, vector m) textfield_key
{
int i;
string l,r;
/*mouse*/
if (keyc == 512)
{
fld->cursorline = floor(m_y / 8);
fld->cursorcol = floor(m_x / 8);
if (fld->cursorline > fld->linecount && fld->linecount)
fld->cursorline = -1i;
return TRUE;
}
else if (fld->cursorline == -1i)
{
/*if its not active, do nothing*/
return FALSE;
}
/*escape*/
else if (keyc == 27)
{
fld->cursorline = -1i;
return TRUE;
}
/*backspace*/
else if (keyc == 127)
{
if (fld->cursorline >= fld->linecount)
{
/*we're beyond the bounds of the buffer*/
if (fld->cursorline)
fld->cursorline = fld->cursorline - 1i;
}
else if (fld->cursorcol)
{
/*simple delete*/
l = substring(fld->lines[fld->cursorline], 0, fld->cursorcol-1);
r = substring(fld->lines[fld->cursorline], fld->cursorcol, -1);
strunzone(fld->lines[fld->cursorline]);
fld->lines[fld->cursorline] = strzone(strcat(l, r));
fld->cursorcol = fld->cursorcol - 1i;
}
else if (fld->cursorline)
{
/*at the start of the line, merge the line with thee previous*/
l = fld->lines[(fld->cursorline - 1i)];
r = fld->lines[fld->cursorline];
fld->cursorcol = strlen(l);
l = strcat(l, r);
strunzone(fld->lines[fld->cursorline - 1i]);
fld->lines[fld->cursorline - 1i] = strzone(l);
for (i = fld->cursorline; i < fld->linecount - 1i; i++)
{
fld->lines[i] = fld->lines[i + 1i];
}
fld->cursorline = fld->cursorline - 1i;
fld->linecount = fld->linecount - 1i;
}
}
/*delete*/
else if (keyc == 8)
{
if (fld->cursorline >= fld->linecount)
{
/*we're beyond the bounds of the buffer*/
if (fld->cursorline)
fld->cursorline = fld->cursorline - 1i;
}
else if (fld->cursorcol >= strlen(fld->lines[fld->cursorline]))
{
/*we're at the end of the line, merge next line in to this one*/
l = fld->lines[(fld->cursorline)];
r = fld->lines[fld->cursorline + 1i];
fld->cursorcol = strlen(l);
l = strcat(l, r);
strunzone(fld->lines[fld->cursorline]);
fld->lines[fld->cursorline] = strzone(l);
for (i = fld->cursorline + 1i; i < fld->linecount - 1i; i++)
{
fld->lines[i] = fld->lines[i + 1i];
}
fld->linecount = fld->linecount - 1i;
}
else
{
/*simple delete*/
l = substring(fld->lines[fld->cursorline], 0, fld->cursorcol);
r = substring(fld->lines[fld->cursorline], fld->cursorcol + 1, -1);
strunzone(fld->lines[fld->cursorline]);
fld->lines[fld->cursorline] = strzone(strcat(l, r));
fld->cursorcol = fld->cursorcol - 1i;
}
}
/*home*/
else if (keyc == 151)
{
fld->cursorcol = 0;
}
/*end*/
else if (keyc == 152)
{
fld->cursorcol = strlen(fld->lines[fld->cursorline]);
}
/*leftarrow*/
else if (keyc == 130)
{
if (fld->cursorcol)
fld->cursorcol = fld->cursorcol - 1i;
}
/*rightarrow*/
else if (keyc == 131)
{
fld->cursorcol = fld->cursorcol + 1i;
}
/*uparrow*/
else if (keyc == 128)
{
if (fld->cursorline)
fld->cursorline = fld->cursorline - 1i;
}
/*downarrow*/
else if (keyc == 129)
{
if (fld->cursorline < fld->linecount)
fld->cursorline = fld->cursorline + 1i;
}
/*return*/
else if (keyc == 13)
{
if (fld->linecount < TEXTFIELD_LINES)
{
/*shift trailing lines down*/
fld->linecount = fld->linecount + 1i;
for (i = fld->linecount - 1i; i > fld->cursorline; i--)
{
fld->lines[i] = fld->lines[i - 1i];
}
/*set the new line to the second half of the current line*/
fld->lines[fld->cursorline + 1i] = strzone(substring(fld->lines[fld->cursorline], fld->cursorcol, -1));
/*update the old line to be the first half only*/
r = strzone(substring(fld->lines[fld->cursorline], 0, fld->cursorcol));
strunzone(fld->lines[fld->cursorline]);
fld->lines[fld->cursorline] = r;
/*and set the cursor properly*/
fld->cursorline = fld->cursorline + 1i;
fld->cursorcol = 0;
}
}
/*printable char*/
else if (unic)
{
if (fld->cursorline >= fld->linecount)
{
fld->cursorline = fld->linecount;
fld->linecount += 1i;
fld->lines[fld->cursorline] = strzone(chr2str(unic));
fld->cursorcol = 1i;
}
else
{
l = substring(fld->lines[fld->cursorline], 0, fld->cursorcol);
r = substring(fld->lines[fld->cursorline], fld->cursorcol, -1);
strunzone(fld->lines[fld->cursorline]);
fld->lines[fld->cursorline] = strzone(strcat(l, chr2str(unic), r));
fld->cursorcol = fld->cursorcol+1i;
}
}
else
return FALSE;
fld->dirty = TRUE;
return TRUE;
}