terrain editor update, to implement some of the things epicenter asked for.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4687 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2014-06-16 20:45:44 +00:00
parent b026bbacfe
commit 84888e3ff2
8 changed files with 1301 additions and 384 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -18,3 +18,6 @@ void() csfixups =
ptr_self = (entity*)externvalue(0, "&self");
};
vector mousenear;
vector mousefar;

File diff suppressed because it is too large Load Diff

View File

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