finish attr5..7 and highres entity attributes
* some cleanups in editing.cpp (putting COMMAND to the function, removing unnecessary COMMANDF) * upgrade transformclipentities for floating point clip entities * changed some entity commands to float attributes entproperty <attribute index> <attribute increment> [<unscaled flag>] index and increment work like before, but increment is now a float for some attributes. If unscaled is "1", increment is applied as unscaled integer, which means, it will change float attributes at their highest resolution. getentattr <attribute index> [<unscaled flag>] Works like before, but returns float values for some attributes. If unscaled is "1", raw integer values (representing the highest resolution) are returned. entset <type> <attr1> <attr2> <attr3> <attr4> Works like before, but some attributes may be specified as floats. editentity <...> Now uses float values for some attributes. Return values also may be float. DOCREF newent entproperty getentattr entset editentity
This commit is contained in:
+74
-66
@@ -107,7 +107,7 @@ char *editinfo()
|
||||
entity &c = ents[e];
|
||||
int t = c.type < MAXENTTYPES ? c.type : 0;
|
||||
#define AA(x) floatstr(float(c.attr##x) / entscale[t][x - 1], true)
|
||||
formatstring(info)("closest entity = %s (%s, %s, %s, %s, %s, %s, %s)", entnames[t], AA(1), AA(2), AA(3), AA(4), AA(5), AA(6), AA(7));
|
||||
formatstring(info)("closest entity: %s (%s, %s, %s, %s, %s, %s, %s)", entnames[t], AA(1), AA(2), AA(3), AA(4), AA(5), AA(6), AA(7));
|
||||
#undef AA
|
||||
const char *slotinfo = "unassigned slot";
|
||||
if(t == MAPMODEL)
|
||||
@@ -154,6 +154,10 @@ void resetselections()
|
||||
sels.shrink(0);
|
||||
}
|
||||
|
||||
COMMANDF(select, "iiii", (int *x, int *y, int *xs, int *ys) { resetselections(); addselection(*x, *y, *xs, *ys, 0); });
|
||||
COMMANDF(addselection, "iiii", (int *x, int *y, int *xs, int *ys) { addselection(*x, *y, *xs, *ys, 0); });
|
||||
COMMAND(resetselections, "");
|
||||
|
||||
// reset all invalid selections
|
||||
void checkselections()
|
||||
{
|
||||
@@ -429,6 +433,7 @@ void editundo()
|
||||
freeblock(p);
|
||||
unsavededits++;
|
||||
}
|
||||
COMMANDN(undo, editundo, "");
|
||||
|
||||
void editredo()
|
||||
{
|
||||
@@ -441,6 +446,7 @@ void editredo()
|
||||
freeblock(p);
|
||||
unsavededits++;
|
||||
}
|
||||
COMMANDN(redo, editredo, "");
|
||||
|
||||
extern int worldiodebug;
|
||||
|
||||
@@ -545,6 +551,7 @@ void copy()
|
||||
}
|
||||
|
||||
}
|
||||
COMMAND(copy, "");
|
||||
|
||||
void paste()
|
||||
{
|
||||
@@ -572,6 +579,7 @@ void paste()
|
||||
}
|
||||
}
|
||||
}
|
||||
COMMAND(paste, "");
|
||||
|
||||
// Count the walls of type "type" contained in the current selection
|
||||
void countwalls(int *type)
|
||||
@@ -586,6 +594,7 @@ void countwalls(int *type)
|
||||
loopselsxy(if(s->type==*type) counter++)
|
||||
intret(counter);
|
||||
}
|
||||
COMMAND(countwalls, "i");
|
||||
|
||||
void tofronttex() // maintain most recently used of the texture lists when applying texture
|
||||
{
|
||||
@@ -671,47 +680,49 @@ void edittexxy(int type, int t, block &sel)
|
||||
});
|
||||
}
|
||||
|
||||
void edittex(int type, int dir)
|
||||
void edittex(int *type, int *dir)
|
||||
{
|
||||
EDITSEL;
|
||||
if(type<0 || type>3) return;
|
||||
if(type!=lasttype) { tofronttex(); lasttype = type; }
|
||||
int atype = type==3 ? 1 : type;
|
||||
if(*type < 0 || *type > 3) return;
|
||||
if(*type != lasttype) { tofronttex(); lasttype = *type; }
|
||||
int atype = *type == 3 ? 1 : *type;
|
||||
int i = curedittex[atype];
|
||||
i = i<0 ? 0 : i+dir;
|
||||
i = i < 0 ? 0 : i + *dir;
|
||||
curedittex[atype] = i = min(max(i, 0), 255);
|
||||
int t = lasttex = hdr.texlists[atype][i];
|
||||
loopv(sels)
|
||||
{
|
||||
edittexxy(type, t, sels[i]);
|
||||
addmsg(SV_EDITT, "ri6", sels[i].x, sels[i].y, sels[i].xs, sels[i].ys, type, t);
|
||||
edittexxy(*type, t, sels[i]);
|
||||
addmsg(SV_EDITT, "ri6", sels[i].x, sels[i].y, sels[i].xs, sels[i].ys, *type, t);
|
||||
}
|
||||
unsavededits++;
|
||||
}
|
||||
COMMAND(edittex, "ii");
|
||||
|
||||
void settex(int texture, int type)
|
||||
void settex(int *texture, int *type)
|
||||
{
|
||||
EDITSEL;
|
||||
if(type<0 || type>3) return;
|
||||
int atype = type==3 ? 1 : type;
|
||||
if(*type < 0 || *type > 3) return;
|
||||
int atype = *type == 3 ? 1 : *type;
|
||||
int t = -1;
|
||||
loopi(256) if(texture == (int)hdr.texlists[atype][i])
|
||||
loopi(256) if(*texture == (int)hdr.texlists[atype][i])
|
||||
{
|
||||
t = (int)hdr.texlists[atype][i];
|
||||
break;
|
||||
}
|
||||
if(t<0)
|
||||
if(t < 0)
|
||||
{
|
||||
conoutf("invalid/unavaible texture");
|
||||
return;
|
||||
}
|
||||
loopv(sels)
|
||||
{
|
||||
edittexxy(type, t, sels[i]);
|
||||
addmsg(SV_EDITT, "ri6", sels[i].x, sels[i].y, sels[i].xs, sels[i].ys, type, t);
|
||||
edittexxy(*type, t, sels[i]);
|
||||
addmsg(SV_EDITT, "ri6", sels[i].x, sels[i].y, sels[i].xs, sels[i].ys, *type, t);
|
||||
}
|
||||
unsavededits++;
|
||||
}
|
||||
COMMAND(settex, "ii");
|
||||
|
||||
void replace()
|
||||
{
|
||||
@@ -731,6 +742,7 @@ void replace()
|
||||
remip(b);
|
||||
unsavededits++;
|
||||
}
|
||||
COMMAND(replace, "");
|
||||
|
||||
void edittypexy(int type, block &sel)
|
||||
{
|
||||
@@ -787,7 +799,6 @@ void equalize(int *flr)
|
||||
addmsg(SV_EDITE, "ri5", sel.x, sel.y, sel.xs, sel.ys, isfloor);
|
||||
}
|
||||
}
|
||||
|
||||
COMMAND(equalize, "i");
|
||||
|
||||
void setvdeltaxy(int delta, block &sel)
|
||||
@@ -796,15 +807,16 @@ void setvdeltaxy(int delta, block &sel)
|
||||
remipmore(sel);
|
||||
}
|
||||
|
||||
void setvdelta(int delta)
|
||||
void setvdelta(int *delta)
|
||||
{
|
||||
EDITSEL;
|
||||
loopv(sels)
|
||||
{
|
||||
setvdeltaxy(delta, sels[i]);
|
||||
addmsg(SV_EDITD, "ri5", sels[i].x, sels[i].y, sels[i].xs, sels[i].ys, delta);
|
||||
setvdeltaxy(*delta, sels[i]);
|
||||
addmsg(SV_EDITD, "ri5", sels[i].x, sels[i].y, sels[i].xs, sels[i].ys, *delta);
|
||||
}
|
||||
}
|
||||
COMMANDN(vdelta, setvdelta, "i");
|
||||
|
||||
const int MAXARCHVERT = 50;
|
||||
int archverts[MAXARCHVERT][MAXARCHVERT];
|
||||
@@ -820,6 +832,7 @@ void archvertex(int *span, int *vert, int *delta)
|
||||
if(*span>=MAXARCHVERT || *vert>=MAXARCHVERT || *span<0 || *vert<0) return;
|
||||
archverts[*span][*vert] = *delta;
|
||||
}
|
||||
COMMAND(archvertex, "iii");
|
||||
|
||||
void arch(int *sidedelta)
|
||||
{
|
||||
@@ -838,24 +851,26 @@ void arch(int *sidedelta)
|
||||
remipmore(sel);
|
||||
}
|
||||
}
|
||||
COMMAND(arch, "i");
|
||||
|
||||
void slope(int xd, int yd)
|
||||
void slope(int *xd, int *yd)
|
||||
{
|
||||
EDITSELMP;
|
||||
loopv(sels)
|
||||
{
|
||||
block &sel = sels[i];
|
||||
int off = 0;
|
||||
if(xd<0) off -= xd*sel.xs;
|
||||
if(yd<0) off -= yd*sel.ys;
|
||||
if(*xd < 0) off -= *xd * sel.xs;
|
||||
if(*yd < 0) off -= *yd * sel.ys;
|
||||
sel.xs++;
|
||||
sel.ys++;
|
||||
loopselxy(sel, s->vdelta = xd*x+yd*y+off);
|
||||
loopselxy(sel, s->vdelta = *xd * x + *yd * y + off);
|
||||
remipmore(sel);
|
||||
}
|
||||
}
|
||||
COMMAND(slope, "ii");
|
||||
|
||||
void perlin(int scale, int seed, int psize)
|
||||
void perlin(int *scale, int *seed, int *psize)
|
||||
{
|
||||
EDITSELMP;
|
||||
loopv(sels)
|
||||
@@ -866,12 +881,13 @@ void perlin(int scale, int seed, int psize)
|
||||
makeundo(sel);
|
||||
sel.xs--;
|
||||
sel.ys--;
|
||||
perlinarea(sel, scale, seed, psize);
|
||||
perlinarea(sel, *scale, *seed, *psize);
|
||||
sel.xs++;
|
||||
sel.ys++;
|
||||
remipmore(sel);
|
||||
}
|
||||
}
|
||||
COMMAND(perlin, "iii");
|
||||
|
||||
VARF(fullbright, 0, 0, 1,
|
||||
if(fullbright)
|
||||
@@ -887,16 +903,19 @@ void edittag(int *tag)
|
||||
EDITSELMP;
|
||||
loopselsxy(s->tag = *tag);
|
||||
}
|
||||
COMMAND(edittag, "i");
|
||||
|
||||
void newent(char *what, int *a1, int *a2, int *a3, int *a4)
|
||||
void newent(char *what, float *a1, float *a2, float *a3, float *a4)
|
||||
{
|
||||
EDITSEL;
|
||||
loopv(sels) newentity(-1, sels[i].x, sels[i].y, (int)camera1->o.z, what, *a1, *a2, *a3, *a4);
|
||||
}
|
||||
COMMAND(newent, "sffff");
|
||||
|
||||
void movemap(int xo, int yo, int zo) // move whole map
|
||||
void movemap(int *xop, int *yop, int *zop) // move whole map
|
||||
{
|
||||
EDITMP;
|
||||
int xo = *xop, yo = *yop, zo = *zop;
|
||||
if(!worldbordercheck(MINBORD + max(-xo, 0), MINBORD + max(xo, 0), MINBORD + max(-yo, 0), MINBORD + max(yo, 0), max(zo, 0), max(-zo, 0)))
|
||||
{
|
||||
conoutf("not enough space to move the map");
|
||||
@@ -933,6 +952,7 @@ void movemap(int xo, int yo, int zo) // move whole map
|
||||
resetmap(false);
|
||||
unsavededits++;
|
||||
}
|
||||
COMMAND(movemap, "iii");
|
||||
|
||||
void selfliprotate(block &sel, int dir)
|
||||
{
|
||||
@@ -962,17 +982,18 @@ void selfliprotate(block &sel, int dir)
|
||||
freeblock(org);
|
||||
}
|
||||
|
||||
void selectionrotate(int dir)
|
||||
void selectionrotate(int *dir)
|
||||
{
|
||||
EDITSELMP;
|
||||
dir &= 3;
|
||||
if(!dir) return;
|
||||
*dir &= 3;
|
||||
if(!*dir) return;
|
||||
loopv(sels)
|
||||
{
|
||||
block &sel = sels[i];
|
||||
if(sel.xs == sel.ys || dir == 2) selfliprotate(sel, dir);
|
||||
if(sel.xs == sel.ys || *dir == 2) selfliprotate(sel, *dir);
|
||||
}
|
||||
}
|
||||
COMMAND(selectionrotate, "i");
|
||||
|
||||
void selectionflip(char *axis)
|
||||
{
|
||||
@@ -981,74 +1002,61 @@ void selectionflip(char *axis)
|
||||
if(c != 'X' && c != 'Y') return;
|
||||
loopv(sels) selfliprotate(sels[i], c == 'X' ? 11 : 12);
|
||||
}
|
||||
|
||||
COMMANDF(select, "iiii", (int *x, int *y, int *xs, int *ys) { resetselections(); addselection(*x, *y, *xs, *ys, 0); });
|
||||
COMMANDF(addselection, "iiii", (int *x, int *y, int *xs, int *ys) { addselection(*x, *y, *xs, *ys, 0); });
|
||||
COMMAND(resetselections, "");
|
||||
COMMAND(edittag, "i");
|
||||
COMMAND(replace, "");
|
||||
COMMAND(archvertex, "iii");
|
||||
COMMAND(arch, "i");
|
||||
COMMANDF(slope, "ii", (int *xd, int *yd) { slope(*xd, *yd); });
|
||||
COMMANDF(vdelta, "i", (int *d) { setvdelta(*d); });
|
||||
COMMANDN(undo, editundo, "");
|
||||
COMMANDN(redo, editredo, "");
|
||||
COMMAND(copy, "");
|
||||
COMMAND(paste, "");
|
||||
COMMANDF(edittex, "ii", (int *type, int *dir) { edittex(*type, *dir); });
|
||||
COMMAND(newent, "siiii");
|
||||
COMMANDF(perlin, "iii", (int *sc, int *se, int *ps) { perlin(*sc, *se, *ps); });
|
||||
COMMANDF(movemap, "iii", (int *x, int *y, int *z) { movemap(*x, *y, *z); });
|
||||
COMMANDF(selectionrotate, "i", (int *d) { selectionrotate(*d); });
|
||||
COMMAND(selectionflip, "s");
|
||||
COMMAND(countwalls, "i");
|
||||
COMMANDF(settex, "ii", (int *texture, int *type) { settex(*texture, *type); });
|
||||
#if 0 // fix clip scaling
|
||||
|
||||
void transformclipentities() // transforms all clip entities to tag clips, if they are big enough (so, that no player could be above or below them)
|
||||
{
|
||||
{ // (hardcoded factor ENTSCALE10 for attr1 and ENTSCALE5 for attr2-4)
|
||||
EDITMP;
|
||||
int total = 0, thisrun;
|
||||
int total = 0, thisrun, bonus = 5;
|
||||
do
|
||||
{
|
||||
thisrun = 0;
|
||||
loopv(ents)
|
||||
{
|
||||
entity &e = ents[i];
|
||||
if((e.type == CLIP || e.type == PLCLIP) && e.attr2 && e.attr3 && e.attr4)
|
||||
if((e.type == CLIP || e.type == PLCLIP) && e.attr2 / ENTSCALE5 && e.attr3 / ENTSCALE5 && e.attr4 / ENTSCALE5)
|
||||
{
|
||||
int allowedspace = e.type == CLIP ? 1 : 4;
|
||||
int clipmask = e.type == CLIP ? TAGCLIP : TAGPLCLIP;
|
||||
int x1 = e.x - e.attr2, x2 = e.x + e.attr2 - 1, y1 = e.y - e.attr3, y2 = e.y + e.attr3 - 1;
|
||||
int z1 = S(e.x, e.y)->floor + e.attr1, z2 = z1 + e.attr4;
|
||||
bool bigenough = true;
|
||||
for(int xx = x1; xx <= x2; xx++) for(int yy = y1; yy <= y2; yy++)
|
||||
int i2 = e.attr2 / ENTSCALE5, i3 = e.attr3 / ENTSCALE5; // floor values
|
||||
int r2 = (e.attr2 % ENTSCALE5) > 0, r3 = (e.attr3 % ENTSCALE5) > 0; // fractions
|
||||
int x1i = e.x - i2, x2i = e.x + i2 - 1, y1i = e.y - i3, y2i = e.y + i3 - 1; // inner rectangle (fully covered cubes)
|
||||
int x1o = x1i - r2, x2o = x2i + r2, y1o = y1i - r3, y2o = y2i + r3; // outer rectangle (partially covered cubes)
|
||||
float z1 = S(e.x, e.y)->floor + float(e.attr1) / ENTSCALE10, z2 = z1 + float(e.attr4) / ENTSCALE5;
|
||||
bool bigenough = true, nodelete = false;
|
||||
for(int xx = x1o; xx <= x2o; xx++) for(int yy = y1o; yy <= y2o; yy++) // loop over outer rectangle to check, if a clip has the required height
|
||||
{
|
||||
if(OUTBORD(xx,yy) || SOLID(S(xx,yy))) continue;
|
||||
bool inner = xx >= x1i && xx <= x2i && yy >= y1i && yy <= y2i; // flag: xx|yy is inner rectangle
|
||||
sqr *s[4] = { S(xx, yy), S(xx + 1, yy), S(xx, yy + 1), S(xx + 1, yy + 1) };
|
||||
int vdeltamax = 0;
|
||||
loopj(4) if(s[j]->vdelta > vdeltamax) vdeltamax = s[j]->vdelta;
|
||||
int floor = s[0]->floor - (s[0]->type == FHF ? (vdeltamax + 3) / 4 : 0),
|
||||
ceil = s[0]->ceil - (s[0]->type == CHF ? (vdeltamax + 3) / 4 : 0);
|
||||
if((z1 - floor > allowedspace || ceil - z2 > allowedspace) && !(s[0]->tag & (TAGCLIP | clipmask))) bigenough = false;
|
||||
bool alreadytagged = (s[0]->tag & (TAGCLIP | clipmask)) != 0;
|
||||
if((z1 - floor > allowedspace || ceil - z2 > allowedspace) && !alreadytagged) bigenough = false;
|
||||
if(!inner && !alreadytagged) nodelete = true; // fractional part of the clip would not be covered: entity can not be deleted
|
||||
}
|
||||
if(bigenough)
|
||||
{
|
||||
for(int xx = x1; xx <= x2; xx++) for(int yy = y1; yy <= y2; yy++)
|
||||
for(int xx = x1i; xx <= x2i; xx++) for(int yy = y1i; yy <= y2i; yy++) // only convert inner rectangle to tag clips
|
||||
{
|
||||
if(!OUTBORD(xx,yy) && !SOLID(S(xx,yy))) S(xx, yy)->tag |= clipmask;
|
||||
}
|
||||
e.type = NOTUSED;
|
||||
thisrun++;
|
||||
if(!nodelete)
|
||||
{
|
||||
e.type = NOTUSED; // only delete entity, if it is now fully covered in tag clips
|
||||
thisrun++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
total += thisrun;
|
||||
}
|
||||
while(thisrun);
|
||||
while(thisrun || bonus-- > 0);
|
||||
loopi(ssize) loopj(ssize) { sqr *s = S(i,j); if(s->tag & TAGCLIP) s->tag &= ~TAGPLCLIP; }
|
||||
conoutf("changed %d clip entities to tagged clip areas", total);
|
||||
if(total) unsavededits++;
|
||||
}
|
||||
|
||||
COMMAND(transformclipentities, "");
|
||||
#endif
|
||||
|
||||
+1
-1
@@ -489,7 +489,7 @@ extern void deletesoundentity(entity &e);
|
||||
extern int findtype(char *what);
|
||||
extern int findentity(int type, int index = 0);
|
||||
extern int findentity(int type, int index, uchar attr2);
|
||||
extern entity *newentity(int index, int x, int y, int z, char *what, int v1, int v2, int v3, int v4);
|
||||
extern void newentity(int index, int x, int y, int z, char *what, float v1, float v2, float v3, float v4);
|
||||
extern void mapmrproper(bool manual);
|
||||
|
||||
// worldlight
|
||||
|
||||
+60
-47
@@ -166,13 +166,16 @@ int closestent() // used for delent and edit mode ent display
|
||||
return best;
|
||||
}
|
||||
|
||||
void entproperty(int prop, int amount)
|
||||
void entproperty(int *prop, float *famount, int *unscaled)
|
||||
{
|
||||
int n = closestent();
|
||||
if(n<0) return;
|
||||
if(n < 0) return;
|
||||
entity &e = ents[n];
|
||||
int old_a1 = e.attr1;
|
||||
switch(prop)
|
||||
int t = e.type < MAXENTTYPES ? e.type : 0;
|
||||
int amount = int(*famount * (*prop >= 0 && *prop < 7 && !*unscaled ? entscale[t][*prop] : 1));
|
||||
|
||||
switch(*prop)
|
||||
{
|
||||
case 0: e.attr1 += amount; break;
|
||||
case 1: e.attr2 += amount; break;
|
||||
@@ -199,6 +202,7 @@ void entproperty(int prop, int amount)
|
||||
if(changedents.find(n) == -1) changedents.add(n); // apply ent changes later (reduces network traffic)
|
||||
unsavededits++;
|
||||
}
|
||||
COMMAND(entproperty, "ifi");
|
||||
|
||||
hashtable<char *, enet_uint32> mapinfo, &resdata = mapinfo;
|
||||
|
||||
@@ -210,22 +214,33 @@ void getenttype()
|
||||
if(type < 0 || type >= MAXENTTYPES) return;
|
||||
result(entnames[type]);
|
||||
}
|
||||
|
||||
void getentattr(int *attr)
|
||||
{
|
||||
int e = closestent();
|
||||
if(e>=0) switch(*attr)
|
||||
{
|
||||
case 0: intret(ents[e].attr1); return;
|
||||
case 1: intret(ents[e].attr2); return;
|
||||
case 2: intret(ents[e].attr3); return;
|
||||
case 3: intret(ents[e].attr4); return;
|
||||
}
|
||||
intret(0);
|
||||
}
|
||||
|
||||
COMMAND(getenttype, "");
|
||||
COMMAND(getentattr, "i");
|
||||
|
||||
void getentattr(int *attr, int *unscaled)
|
||||
{
|
||||
int n = closestent();
|
||||
const char *res = "0";
|
||||
if(n >= 0)
|
||||
{
|
||||
entity &e = ents[n];
|
||||
int t = e.type < MAXENTTYPES ? e.type : 0;
|
||||
int scale = *attr >= 0 && *attr < 7 && !*unscaled ? entscale[t][*attr] : 1;
|
||||
switch(*attr)
|
||||
{
|
||||
#define CHKATTR(x) case x - 1: res = floatstr(float(e.attr##x) / scale, true); break
|
||||
CHKATTR(1);
|
||||
CHKATTR(2);
|
||||
CHKATTR(3);
|
||||
CHKATTR(4);
|
||||
CHKATTR(5);
|
||||
CHKATTR(6);
|
||||
CHKATTR(7);
|
||||
#undef CHKATTR
|
||||
}
|
||||
}
|
||||
result(res);
|
||||
}
|
||||
COMMAND(getentattr, "ii");
|
||||
|
||||
void deletesoundentity(entity &e)
|
||||
{
|
||||
@@ -266,41 +281,35 @@ int findtype(char *what)
|
||||
return t;
|
||||
}
|
||||
|
||||
entity *newentity(int index, int x, int y, int z, char *what, int v1, int v2, int v3, int v4)
|
||||
void newentity(int index, int x, int y, int z, char *what, float v1f, float v2f, float v3f, float v4f) // add an entity or overwrite an existing one
|
||||
{
|
||||
int type = findtype(what);
|
||||
if(type==NOTUSED) return NULL;
|
||||
|
||||
if (type == SOUND && index >= 0)
|
||||
{
|
||||
entity &o = ents[index];
|
||||
|
||||
entityreference entref(&o);
|
||||
location *loc = audiomgr.locations.find(o.attr1, &entref, mapsounds);
|
||||
|
||||
if(loc)
|
||||
loc->drop();
|
||||
if(type == NOTUSED) return;
|
||||
if (index >= 0 && ents[index].type == SOUND) deletesoundentity(ents[index]); // overwriting sound entity
|
||||
switch(type)
|
||||
{ // MAPMODEL, PLAYERSTART and CTF-FLAG use the current camera direction as value for attr1, so attr234 need to be moved
|
||||
case MAPMODEL:
|
||||
v4f = v3f;
|
||||
v3f = v2f;
|
||||
case PLAYERSTART:
|
||||
case CTF_FLAG:
|
||||
v2f = v1f;
|
||||
int y = camera1->yaw;
|
||||
if(type != PLAYERSTART) y = y + 7 - (y + 7) % 15;
|
||||
v1f = y;
|
||||
break;
|
||||
}
|
||||
|
||||
int v1 = v1f * entscale[type][0], v2 = v2f * entscale[type][1], v3 = v3f * entscale[type][2], v4 = v4f * entscale[type][3];
|
||||
entity e(x, y, z, type, v1, v2, v3, v4);
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case LIGHT:
|
||||
if(v1>64) e.attr1 = 64;
|
||||
if(v1 > 64) e.attr1 = 64;
|
||||
if(!v1) e.attr1 = 16;
|
||||
if(!v2 && !v3 && !v4) e.attr2 = 255;
|
||||
break;
|
||||
|
||||
case MAPMODEL:
|
||||
e.attr4 = e.attr3;
|
||||
e.attr3 = e.attr2;
|
||||
case PLAYERSTART:
|
||||
case CTF_FLAG:
|
||||
e.attr2 = v1;
|
||||
e.attr1 = int(camera1->yaw * ENTSCALE10);
|
||||
if(type != PLAYERSTART) e.attr1 = e.attr1 + 70 - (e.attr1 + 70) % 150;
|
||||
break;
|
||||
}
|
||||
clampentityattributes(e);
|
||||
syncentchanges(true);
|
||||
@@ -323,10 +332,9 @@ entity *newentity(int index, int x, int y, int z, char *what, int v1, int v2, in
|
||||
case SOUND: audiomgr.preloadmapsound(e); break;
|
||||
}
|
||||
unsavededits++;
|
||||
return index<0 ? &ents.last() : &ents[index];
|
||||
}
|
||||
|
||||
void entset(char *what, int *a1, int *a2, int *a3, int *a4)
|
||||
void entset(char *what, float *a1, float *a2, float *a3, float *a4)
|
||||
{
|
||||
int n = closestent();
|
||||
if(n>=0)
|
||||
@@ -336,7 +344,7 @@ void entset(char *what, int *a1, int *a2, int *a3, int *a4)
|
||||
}
|
||||
}
|
||||
|
||||
COMMAND(entset, "siiii");
|
||||
COMMAND(entset, "sffff");
|
||||
|
||||
void clearents(char *name)
|
||||
{
|
||||
@@ -384,6 +392,7 @@ void editentity(char **args, int numargs) // index x y z a1 a2 a3 a4 ...
|
||||
entity &e = ents[n];
|
||||
bool edit = false;
|
||||
for(int i = 1; i < numargs; i++) if(*args[i]) edit = true; // only arguments other than empty strings can edit anything - otherwise we're just browsing
|
||||
int t = e.type < MAXENTTYPES ? e.type : NOTUSED;
|
||||
if(edit)
|
||||
{
|
||||
if(e.type == SOUND)
|
||||
@@ -394,7 +403,7 @@ void editentity(char **args, int numargs) // index x y z a1 a2 a3 a4 ...
|
||||
}
|
||||
for(int i = 1; i < numargs; i++) if(*args[i])
|
||||
{
|
||||
int v = ATOI(args[i]);
|
||||
int v = atof(args[i]) * (i < 4 || i > 10 ? 1 : entscale[t][i - 4]);
|
||||
switch(i)
|
||||
{
|
||||
case 1: e.x = v; break;
|
||||
@@ -404,6 +413,9 @@ void editentity(char **args, int numargs) // index x y z a1 a2 a3 a4 ...
|
||||
case 5: e.attr2 = v; break;
|
||||
case 6: e.attr3 = v; break;
|
||||
case 7: e.attr4 = v; break;
|
||||
case 8: e.attr5 = v; break;
|
||||
case 9: e.attr6 = v; break;
|
||||
case 10: e.attr7 = v; break;
|
||||
}
|
||||
}
|
||||
clampentityattributes(e);
|
||||
@@ -415,7 +427,9 @@ void editentity(char **args, int numargs) // index x y z a1 a2 a3 a4 ...
|
||||
unsavededits++;
|
||||
}
|
||||
// give back unchanged or new entity properties
|
||||
formatstring(res)("%s %d %d %d %d %d %d %d", entnames[e.type], e.x, e.y, e.z, e.attr1, e.attr2, e.attr3, e.attr4);
|
||||
#define AA(x) floatstr(float(e.attr##x) / entscale[t][x - 1], true)
|
||||
formatstring(res)("%s %d %d %d %s %s %s %s %s %s %s", entnames[e.type], e.x, e.y, e.z, AA(1), AA(2), AA(3), AA(4), AA(5), AA(6), AA(7));
|
||||
#undef AA
|
||||
}
|
||||
result(res);
|
||||
}
|
||||
@@ -675,7 +689,6 @@ COMMAND(mapshrink, "");
|
||||
COMMAND(newmap, "i");
|
||||
COMMANDN(recalc, calclight, "");
|
||||
COMMAND(delent, "");
|
||||
COMMANDF(entproperty, "ii", (int *p, int *a) { entproperty(*p, *a); });
|
||||
|
||||
void countperfectmips(int mip, int xx, int yy, int bs, int *stats)
|
||||
{
|
||||
|
||||
@@ -708,7 +708,7 @@ bool load_world(char *mname) // still supports all map formats that have
|
||||
if(e.type == LIGHT && e.attr1 >= 0)
|
||||
{
|
||||
if(!e.attr2) e.attr2 = 255; // needed for MAPVERSION<=2
|
||||
if(e.attr1>32) e.attr1 = 32; // 12_03 and below
|
||||
if(e.attr1 > 32) e.attr1 = 32; // 12_03 and below (but applied to _all_ files!)
|
||||
}
|
||||
transformoldentitytypes(hdr.version, e.type);
|
||||
if(oldentityformat && e.type < MAXENTTYPES)
|
||||
|
||||
Reference in New Issue
Block a user