summaryrefslogtreecommitdiff
path: root/src/engine/world.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/world.cpp')
-rw-r--r--src/engine/world.cpp1895
1 files changed, 947 insertions, 948 deletions
diff --git a/src/engine/world.cpp b/src/engine/world.cpp
index 7f5baed..af998c3 100644
--- a/src/engine/world.cpp
+++ b/src/engine/world.cpp
@@ -12,261 +12,261 @@ VAR(entselradius, 0, 2, 10);
static inline void mmboundbox(const entity &e, model *m, vec &center, vec &radius)
{
- m->boundbox(center, radius);
- rotatebb(center, radius, e.attr1);
+ m->boundbox(center, radius);
+ rotatebb(center, radius, e.attr1);
}
static inline void mmcollisionbox(const entity &e, model *m, vec &center, vec &radius)
{
- m->collisionbox(center, radius);
- rotatebb(center, radius, e.attr1);
+ m->collisionbox(center, radius);
+ rotatebb(center, radius, e.attr1);
}
bool getentboundingbox(const extentity &e, ivec &o, ivec &r)
{
- switch(e.type)
- {
- case ET_EMPTY:
- return false;
- case ET_MAPMODEL:
- {
- model *m = loadmapmodel(e.attr2);
- if(m)
- {
- vec center, radius;
- mmboundbox(e, m, center, radius);
- center.add(e.o);
- radius.max(entselradius);
- o = ivec(vec(center).sub(radius));
- r = ivec(vec(center).add(radius).add(1));
- break;
- }
- }
- [[fallthrough]];
- // invisible mapmodels use entselradius
- default:
- o = ivec(vec(e.o).sub(entselradius));
- r = ivec(vec(e.o).add(entselradius+1));
- break;
- }
- return true;
+ switch(e.type)
+ {
+ case ET_EMPTY:
+ return false;
+ case ET_MAPMODEL:
+ {
+ model *m = loadmapmodel(e.attr2);
+ if(m)
+ {
+ vec center, radius;
+ mmboundbox(e, m, center, radius);
+ center.add(e.o);
+ radius.max(entselradius);
+ o = ivec(vec(center).sub(radius));
+ r = ivec(vec(center).add(radius).add(1));
+ break;
+ }
+ }
+ [[fallthrough]];
+ // invisible mapmodels use entselradius
+ default:
+ o = ivec(vec(e.o).sub(entselradius));
+ r = ivec(vec(e.o).add(entselradius+1));
+ break;
+ }
+ return true;
}
enum
{
- MODOE_ADD = 1<<0,
- MODOE_UPDATEBB = 1<<1,
- MODOE_LIGHTENT = 1<<2
+ MODOE_ADD = 1<<0,
+ MODOE_UPDATEBB = 1<<1,
+ MODOE_LIGHTENT = 1<<2
};
void modifyoctaentity(int flags, int id, extentity &e, cube *c, const ivec &cor, int size, const ivec &bo, const ivec &br, int leafsize, vtxarray *lastva = NULL)
{
- loopoctabox(cor, size, bo, br)
- {
- ivec o(i, cor, size);
- vtxarray *va = c[i].ext && c[i].ext->va ? c[i].ext->va : lastva;
- if(c[i].children != NULL && size > leafsize)
- modifyoctaentity(flags, id, e, c[i].children, o, size>>1, bo, br, leafsize, va);
- else if(flags&MODOE_ADD)
- {
- if(!c[i].ext || !c[i].ext->ents) ext(c[i]).ents = new octaentities(o, size);
- octaentities &oe = *c[i].ext->ents;
- switch(e.type)
- {
- case ET_MAPMODEL:
- if(loadmapmodel(e.attr2))
- {
- if(va)
- {
- va->bbmin.x = -1;
- if(oe.mapmodels.empty()) va->mapmodels.add(&oe);
- }
- oe.mapmodels.add(id);
- oe.bbmin.min(bo).max(oe.o);
- oe.bbmax.max(br).min(ivec(oe.o).add(oe.size));
- break;
- }
- // invisible mapmodel
- [[fallthrough]];
- default:
- oe.other.add(id);
- break;
- }
-
- }
- else if(c[i].ext && c[i].ext->ents)
- {
- octaentities &oe = *c[i].ext->ents;
- switch(e.type)
- {
- case ET_MAPMODEL:
- if(loadmapmodel(e.attr2))
- {
- oe.mapmodels.removeobj(id);
- if(va)
- {
- va->bbmin.x = -1;
- if(oe.mapmodels.empty()) va->mapmodels.removeobj(&oe);
- }
- oe.bbmin = oe.bbmax = oe.o;
- oe.bbmin.add(oe.size);
- loopvj(oe.mapmodels)
- {
- extentity &e = *entities::getents()[oe.mapmodels[j]];
- ivec eo, er;
- if(getentboundingbox(e, eo, er))
- {
- oe.bbmin.min(eo);
- oe.bbmax.max(er);
- }
- }
- oe.bbmin.max(oe.o);
- oe.bbmax.min(ivec(oe.o).add(oe.size));
- break;
- }
- [[fallthrough]];
- // invisible mapmodel
- default:
- oe.other.removeobj(id);
- break;
- }
- if(oe.mapmodels.empty() && oe.other.empty())
- freeoctaentities(c[i]);
- }
- if(c[i].ext && c[i].ext->ents) c[i].ext->ents->query = NULL;
- if(va && va!=lastva)
- {
- if(lastva)
- {
- if(va->bbmin.x < 0) lastva->bbmin.x = -1;
- }
- else if(flags&MODOE_UPDATEBB) updatevabb(va);
- }
- }
+ loopoctabox(cor, size, bo, br)
+ {
+ ivec o(i, cor, size);
+ vtxarray *va = c[i].ext && c[i].ext->va ? c[i].ext->va : lastva;
+ if(c[i].children != NULL && size > leafsize)
+ modifyoctaentity(flags, id, e, c[i].children, o, size>>1, bo, br, leafsize, va);
+ else if(flags&MODOE_ADD)
+ {
+ if(!c[i].ext || !c[i].ext->ents) ext(c[i]).ents = new octaentities(o, size);
+ octaentities &oe = *c[i].ext->ents;
+ switch(e.type)
+ {
+ case ET_MAPMODEL:
+ if(loadmapmodel(e.attr2))
+ {
+ if(va)
+ {
+ va->bbmin.x = -1;
+ if(oe.mapmodels.empty()) va->mapmodels.add(&oe);
+ }
+ oe.mapmodels.add(id);
+ oe.bbmin.min(bo).max(oe.o);
+ oe.bbmax.max(br).min(ivec(oe.o).add(oe.size));
+ break;
+ }
+ // invisible mapmodel
+ [[fallthrough]];
+ default:
+ oe.other.add(id);
+ break;
+ }
+
+ }
+ else if(c[i].ext && c[i].ext->ents)
+ {
+ octaentities &oe = *c[i].ext->ents;
+ switch(e.type)
+ {
+ case ET_MAPMODEL:
+ if(loadmapmodel(e.attr2))
+ {
+ oe.mapmodels.removeobj(id);
+ if(va)
+ {
+ va->bbmin.x = -1;
+ if(oe.mapmodels.empty()) va->mapmodels.removeobj(&oe);
+ }
+ oe.bbmin = oe.bbmax = oe.o;
+ oe.bbmin.add(oe.size);
+ loopvj(oe.mapmodels)
+ {
+ extentity &e = *entities::getents()[oe.mapmodels[j]];
+ ivec eo, er;
+ if(getentboundingbox(e, eo, er))
+ {
+ oe.bbmin.min(eo);
+ oe.bbmax.max(er);
+ }
+ }
+ oe.bbmin.max(oe.o);
+ oe.bbmax.min(ivec(oe.o).add(oe.size));
+ break;
+ }
+ [[fallthrough]];
+ // invisible mapmodel
+ default:
+ oe.other.removeobj(id);
+ break;
+ }
+ if(oe.mapmodels.empty() && oe.other.empty())
+ freeoctaentities(c[i]);
+ }
+ if(c[i].ext && c[i].ext->ents) c[i].ext->ents->query = NULL;
+ if(va && va!=lastva)
+ {
+ if(lastva)
+ {
+ if(va->bbmin.x < 0) lastva->bbmin.x = -1;
+ }
+ else if(flags&MODOE_UPDATEBB) updatevabb(va);
+ }
+ }
}
vector<int> outsideents;
static bool modifyoctaent(int flags, int id, extentity &e)
{
- if(flags&MODOE_ADD ? e.flags&EF_OCTA : !(e.flags&EF_OCTA)) return false;
-
- ivec o, r;
- if(!getentboundingbox(e, o, r)) return false;
-
- if(!insideworld(e.o))
- {
- int idx = outsideents.find(id);
- if(flags&MODOE_ADD)
- {
- if(idx < 0) outsideents.add(id);
- }
- else if(idx >= 0) outsideents.removeunordered(idx);
- }
- else
- {
- int leafsize = octaentsize, limit = max(r.x - o.x, max(r.y - o.y, r.z - o.z));
- while(leafsize < limit) leafsize *= 2;
- int diff = ~(leafsize-1) & ((o.x^r.x)|(o.y^r.y)|(o.z^r.z));
- if(diff && (limit > octaentsize/2 || diff < leafsize*2)) leafsize *= 2;
- modifyoctaentity(flags, id, e, worldroot, ivec(0, 0, 0), worldsize>>1, o, r, leafsize);
- }
- e.flags ^= EF_OCTA;
- if(e.type == ET_LIGHT) clearlightcache(id);
- else if(e.type == ET_PARTICLES) clearparticleemitters();
- else if(flags&MODOE_LIGHTENT) lightent(e);
- return true;
+ if(flags&MODOE_ADD ? e.flags&EF_OCTA : !(e.flags&EF_OCTA)) return false;
+
+ ivec o, r;
+ if(!getentboundingbox(e, o, r)) return false;
+
+ if(!insideworld(e.o))
+ {
+ int idx = outsideents.find(id);
+ if(flags&MODOE_ADD)
+ {
+ if(idx < 0) outsideents.add(id);
+ }
+ else if(idx >= 0) outsideents.removeunordered(idx);
+ }
+ else
+ {
+ int leafsize = octaentsize, limit = max(r.x - o.x, max(r.y - o.y, r.z - o.z));
+ while(leafsize < limit) leafsize *= 2;
+ int diff = ~(leafsize-1) & ((o.x^r.x)|(o.y^r.y)|(o.z^r.z));
+ if(diff && (limit > octaentsize/2 || diff < leafsize*2)) leafsize *= 2;
+ modifyoctaentity(flags, id, e, worldroot, ivec(0, 0, 0), worldsize>>1, o, r, leafsize);
+ }
+ e.flags ^= EF_OCTA;
+ if(e.type == ET_LIGHT) clearlightcache(id);
+ else if(e.type == ET_PARTICLES) clearparticleemitters();
+ else if(flags&MODOE_LIGHTENT) lightent(e);
+ return true;
}
static inline bool modifyoctaent(int flags, int id)
{
- vector<extentity *> &ents = entities::getents();
- return ents.inrange(id) && modifyoctaent(flags, id, *ents[id]);
+ vector<extentity *> &ents = entities::getents();
+ return ents.inrange(id) && modifyoctaent(flags, id, *ents[id]);
}
-static inline void addentity(int id) { modifyoctaent(MODOE_ADD|MODOE_UPDATEBB|MODOE_LIGHTENT, id); }
+static inline void addentity(int id) { modifyoctaent(MODOE_ADD|MODOE_UPDATEBB|MODOE_LIGHTENT, id); }
static inline void removeentity(int id) { modifyoctaent(MODOE_UPDATEBB, id); }
void freeoctaentities(cube &c)
{
- if(!c.ext) return;
- if(entities::getents().length())
- {
- while(c.ext->ents && !c.ext->ents->mapmodels.empty()) removeentity(c.ext->ents->mapmodels.pop());
- while(c.ext->ents && !c.ext->ents->other.empty()) removeentity(c.ext->ents->other.pop());
- }
- if(c.ext->ents)
- {
- delete c.ext->ents;
- c.ext->ents = NULL;
- }
+ if(!c.ext) return;
+ if(entities::getents().length())
+ {
+ while(c.ext->ents && !c.ext->ents->mapmodels.empty()) removeentity(c.ext->ents->mapmodels.pop());
+ while(c.ext->ents && !c.ext->ents->other.empty()) removeentity(c.ext->ents->other.pop());
+ }
+ if(c.ext->ents)
+ {
+ delete c.ext->ents;
+ c.ext->ents = NULL;
+ }
}
void entitiesinoctanodes()
{
- vector<extentity *> &ents = entities::getents();
- loopv(ents) modifyoctaent(MODOE_ADD, i, *ents[i]);
+ vector<extentity *> &ents = entities::getents();
+ loopv(ents) modifyoctaent(MODOE_ADD, i, *ents[i]);
}
static inline void findents(octaentities &oe, int low, int high, bool notspawned, const vec &pos, const vec &invradius, vector<int> &found)
{
- vector<extentity *> &ents = entities::getents();
- loopv(oe.other)
- {
- int id = oe.other[i];
- extentity &e = *ents[id];
- if(e.type >= low && e.type <= high && (e.spawned() || notspawned) && vec(e.o).sub(pos).mul(invradius).squaredlen() <= 1) found.add(id);
- }
+ vector<extentity *> &ents = entities::getents();
+ loopv(oe.other)
+ {
+ int id = oe.other[i];
+ extentity &e = *ents[id];
+ if(e.type >= low && e.type <= high && (e.spawned() || notspawned) && vec(e.o).sub(pos).mul(invradius).squaredlen() <= 1) found.add(id);
+ }
}
static inline void findents(cube *c, const ivec &o, int size, const ivec &bo, const ivec &br, int low, int high, bool notspawned, const vec &pos, const vec &invradius, vector<int> &found)
{
- loopoctabox(o, size, bo, br)
- {
- if(c[i].ext && c[i].ext->ents) findents(*c[i].ext->ents, low, high, notspawned, pos, invradius, found);
- if(c[i].children && size > octaentsize)
- {
- ivec co(i, o, size);
- findents(c[i].children, co, size>>1, bo, br, low, high, notspawned, pos, invradius, found);
- }
- }
+ loopoctabox(o, size, bo, br)
+ {
+ if(c[i].ext && c[i].ext->ents) findents(*c[i].ext->ents, low, high, notspawned, pos, invradius, found);
+ if(c[i].children && size > octaentsize)
+ {
+ ivec co(i, o, size);
+ findents(c[i].children, co, size>>1, bo, br, low, high, notspawned, pos, invradius, found);
+ }
+ }
}
void findents(int low, int high, bool notspawned, const vec &pos, const vec &radius, vector<int> &found)
{
- vec invradius(1/radius.x, 1/radius.y, 1/radius.z);
- ivec bo(vec(pos).sub(radius).sub(1)),
- br(vec(pos).add(radius).add(1));
- int diff = (bo.x^br.x) | (bo.y^br.y) | (bo.z^br.z) | octaentsize,
- scale = worldscale-1;
- if(diff&~((1<<scale)-1) || uint(bo.x|bo.y|bo.z|br.x|br.y|br.z) >= uint(worldsize))
- {
- findents(worldroot, ivec(0, 0, 0), 1<<scale, bo, br, low, high, notspawned, pos, invradius, found);
- return;
- }
- cube *c = &worldroot[octastep(bo.x, bo.y, bo.z, scale)];
- if(c->ext && c->ext->ents) findents(*c->ext->ents, low, high, notspawned, pos, invradius, found);
- scale--;
- while(c->children && !(diff&(1<<scale)))
- {
- c = &c->children[octastep(bo.x, bo.y, bo.z, scale)];
- if(c->ext && c->ext->ents) findents(*c->ext->ents, low, high, notspawned, pos, invradius, found);
- scale--;
- }
- if(c->children && 1<<scale >= octaentsize) findents(c->children, ivec(bo).mask(~((2<<scale)-1)), 1<<scale, bo, br, low, high, notspawned, pos, invradius, found);
+ vec invradius(1/radius.x, 1/radius.y, 1/radius.z);
+ ivec bo(vec(pos).sub(radius).sub(1)),
+ br(vec(pos).add(radius).add(1));
+ int diff = (bo.x^br.x) | (bo.y^br.y) | (bo.z^br.z) | octaentsize,
+ scale = worldscale-1;
+ if(diff&~((1<<scale)-1) || uint(bo.x|bo.y|bo.z|br.x|br.y|br.z) >= uint(worldsize))
+ {
+ findents(worldroot, ivec(0, 0, 0), 1<<scale, bo, br, low, high, notspawned, pos, invradius, found);
+ return;
+ }
+ cube *c = &worldroot[octastep(bo.x, bo.y, bo.z, scale)];
+ if(c->ext && c->ext->ents) findents(*c->ext->ents, low, high, notspawned, pos, invradius, found);
+ scale--;
+ while(c->children && !(diff&(1<<scale)))
+ {
+ c = &c->children[octastep(bo.x, bo.y, bo.z, scale)];
+ if(c->ext && c->ext->ents) findents(*c->ext->ents, low, high, notspawned, pos, invradius, found);
+ scale--;
+ }
+ if(c->children && 1<<scale >= octaentsize) findents(c->children, ivec(bo).mask(~((2<<scale)-1)), 1<<scale, bo, br, low, high, notspawned, pos, invradius, found);
}
char *entname(entity &e)
{
- static string fullentname;
- copystring(fullentname, entities::entname(e.type));
- const char *einfo = entities::entnameinfo(e);
- if(*einfo)
- {
- concatstring(fullentname, ": ");
- concatstring(fullentname, einfo);
- }
- return fullentname;
+ static string fullentname;
+ copystring(fullentname, entities::entname(e.type));
+ const char *einfo = entities::entnameinfo(e);
+ if(*einfo)
+ {
+ concatstring(fullentname, ": ");
+ concatstring(fullentname, einfo);
+ }
+ return fullentname;
}
extern selinfo sel;
@@ -279,138 +279,138 @@ VARF(entediting, 0, 0, 1, { if(!entediting) { entcancel(); efocus = enthover = -
bool noentedit()
{
- if(!editmode) { conoutf(CON_ERROR, "operation only allowed in edit mode"); return true; }
- return !entediting;
+ if(!editmode) { conoutf(CON_ERROR, "operation only allowed in edit mode"); return true; }
+ return !entediting;
}
bool pointinsel(const selinfo &sel, const vec &o)
{
- return(o.x <= sel.o.x+sel.s.x*sel.grid
- && o.x >= sel.o.x
- && o.y <= sel.o.y+sel.s.y*sel.grid
- && o.y >= sel.o.y
- && o.z <= sel.o.z+sel.s.z*sel.grid
- && o.z >= sel.o.z);
+ return(o.x <= sel.o.x+sel.s.x*sel.grid
+ && o.x >= sel.o.x
+ && o.y <= sel.o.y+sel.s.y*sel.grid
+ && o.y >= sel.o.y
+ && o.z <= sel.o.z+sel.s.z*sel.grid
+ && o.z >= sel.o.z);
}
vector<int> entgroup;
bool haveselent()
{
- return entgroup.length() > 0;
+ return entgroup.length() > 0;
}
void entcancel()
{
- entgroup.shrink(0);
+ entgroup.shrink(0);
}
void entadd(int id)
{
- undonext = true;
- entgroup.add(id);
+ undonext = true;
+ entgroup.add(id);
}
undoblock *newundoent()
{
- int numents = entgroup.length();
- if(numents <= 0) return NULL;
- undoblock *u = (undoblock *)new uchar[sizeof(undoblock) + numents*sizeof(undoent)];
- u->numents = numents;
- undoent *e = (undoent *)(u + 1);
- loopv(entgroup)
- {
- e->i = entgroup[i];
- e->e = *entities::getents()[entgroup[i]];
- e++;
- }
- return u;
+ int numents = entgroup.length();
+ if(numents <= 0) return NULL;
+ undoblock *u = (undoblock *)new uchar[sizeof(undoblock) + numents*sizeof(undoent)];
+ u->numents = numents;
+ undoent *e = (undoent *)(u + 1);
+ loopv(entgroup)
+ {
+ e->i = entgroup[i];
+ e->e = *entities::getents()[entgroup[i]];
+ e++;
+ }
+ return u;
}
void makeundoent()
{
- if(!undonext) return;
- undonext = false;
- oldhover = enthover;
- undoblock *u = newundoent();
- if(u) addundo(u);
+ if(!undonext) return;
+ undonext = false;
+ oldhover = enthover;
+ undoblock *u = newundoent();
+ if(u) addundo(u);
}
void detachentity(extentity &e)
{
- if(!e.attached) return;
- e.attached->attached = NULL;
- e.attached = NULL;
+ if(!e.attached) return;
+ e.attached->attached = NULL;
+ e.attached = NULL;
}
VAR(attachradius, 1, 100, 1000);
void attachentity(extentity &e)
{
- switch(e.type)
- {
- case ET_SPOTLIGHT:
- break;
-
- default:
- if(e.type<ET_GAMESPECIFIC || !entities::mayattach(e)) return;
- break;
- }
-
- detachentity(e);
-
- vector<extentity *> &ents = entities::getents();
- int closest = -1;
- float closedist = 1e10f;
- loopv(ents)
- {
- extentity *a = ents[i];
- if(a->attached) continue;
- switch(e.type)
- {
- case ET_SPOTLIGHT:
- if(a->type!=ET_LIGHT) continue;
- break;
-
- default:
- if(e.type<ET_GAMESPECIFIC || !entities::attachent(e, *a)) continue;
- break;
- }
- float dist = e.o.dist(a->o);
- if(dist < closedist)
- {
- closest = i;
- closedist = dist;
- }
- }
- if(closedist>attachradius) return;
- e.attached = ents[closest];
- ents[closest]->attached = &e;
+ switch(e.type)
+ {
+ case ET_SPOTLIGHT:
+ break;
+
+ default:
+ if(e.type<ET_GAMESPECIFIC || !entities::mayattach(e)) return;
+ break;
+ }
+
+ detachentity(e);
+
+ vector<extentity *> &ents = entities::getents();
+ int closest = -1;
+ float closedist = 1e10f;
+ loopv(ents)
+ {
+ extentity *a = ents[i];
+ if(a->attached) continue;
+ switch(e.type)
+ {
+ case ET_SPOTLIGHT:
+ if(a->type!=ET_LIGHT) continue;
+ break;
+
+ default:
+ if(e.type<ET_GAMESPECIFIC || !entities::attachent(e, *a)) continue;
+ break;
+ }
+ float dist = e.o.dist(a->o);
+ if(dist < closedist)
+ {
+ closest = i;
+ closedist = dist;
+ }
+ }
+ if(closedist>attachradius) return;
+ e.attached = ents[closest];
+ ents[closest]->attached = &e;
}
void attachentities()
{
- vector<extentity *> &ents = entities::getents();
- loopv(ents) attachentity(*ents[i]);
+ vector<extentity *> &ents = entities::getents();
+ loopv(ents) attachentity(*ents[i]);
}
// convenience macros implicitly define:
-// e entity, currently edited ent
-// n int, index to currently edited ent
-#define addimplicit(f) { if(entgroup.empty() && enthover>=0) { entadd(enthover); undonext = (enthover != oldhover); f; entgroup.drop(); } else f; }
+// e entity, currently edited ent
+// n int, index to currently edited ent
+#define addimplicit(f) { if(entgroup.empty() && enthover>=0) { entadd(enthover); undonext = (enthover != oldhover); f; entgroup.drop(); } else f; }
#define entfocusv(i, f, v){ int n = efocus = (i); if(n>=0) { extentity &e = *v[n]; f; } }
-#define entfocus(i, f) entfocusv(i, f, entities::getents())
+#define entfocus(i, f) entfocusv(i, f, entities::getents())
#define enteditv(i, f, v) \
{ \
- entfocusv(i, \
- { \
- int oldtype = e.type; \
- removeentity(n); \
- f; \
- if(oldtype!=e.type) detachentity(e); \
- if(e.type!=ET_EMPTY) { addentity(n); if(oldtype!=e.type) attachentity(e); } \
- entities::editent(n, true); \
- }, v); \
+ entfocusv(i, \
+ { \
+ int oldtype = e.type; \
+ removeentity(n); \
+ f; \
+ if(oldtype!=e.type) detachentity(e); \
+ if(e.type!=ET_EMPTY) { addentity(n); if(oldtype!=e.type) attachentity(e); } \
+ entities::editent(n, true); \
+ }, v); \
}
#define entedit(i, f) enteditv(i, f, entities::getents())
#define addgroup(exp) { vector<extentity *> &ents = entities::getents(); loopv(ents) entfocusv(i, if(exp) entadd(n), ents); }
@@ -418,93 +418,93 @@ void attachentities()
#define groupeditloop(f){ vector<extentity *> &ents = entities::getents(); entlooplevel++; int _ = efocus; loopv(entgroup) enteditv(entgroup[i], f, ents); efocus = _; entlooplevel--; }
#define groupeditpure(f){ if(entlooplevel>0) { entedit(efocus, f); } else groupeditloop(f); }
#define groupeditundo(f){ makeundoent(); groupeditpure(f); }
-#define groupedit(f) { addimplicit(groupeditundo(f)); }
+#define groupedit(f) { addimplicit(groupeditundo(f)); }
vec getselpos()
{
- vector<extentity *> &ents = entities::getents();
- if(entgroup.length() && ents.inrange(entgroup[0])) return ents[entgroup[0]]->o;
- if(ents.inrange(enthover)) return ents[enthover]->o;
- return vec(sel.o);
+ vector<extentity *> &ents = entities::getents();
+ if(entgroup.length() && ents.inrange(entgroup[0])) return ents[entgroup[0]]->o;
+ if(ents.inrange(enthover)) return ents[enthover]->o;
+ return vec(sel.o);
}
undoblock *copyundoents(undoblock *u)
{
- entcancel();
- undoent *e = u->ents();
- loopi(u->numents)
- entadd(e[i].i);
- undoblock *c = newundoent();
+ entcancel();
+ undoent *e = u->ents();
+ loopi(u->numents)
+ entadd(e[i].i);
+ undoblock *c = newundoent();
loopi(u->numents) if(e[i].e.type==ET_EMPTY)
entgroup.removeobj(e[i].i);
- return c;
+ return c;
}
void pasteundoent(int idx, const entity &ue)
{
- if(idx < 0 || idx >= MAXENTS) return;
- vector<extentity *> &ents = entities::getents();
- while(ents.length() < idx) ents.add(entities::newentity())->type = ET_EMPTY;
- int efocus = -1;
- entedit(idx, (entity &)e = ue);
+ if(idx < 0 || idx >= MAXENTS) return;
+ vector<extentity *> &ents = entities::getents();
+ while(ents.length() < idx) ents.add(entities::newentity())->type = ET_EMPTY;
+ int efocus = -1;
+ entedit(idx, (entity &)e = ue);
}
void pasteundoents(undoblock *u)
{
- undoent *ue = u->ents();
- loopi(u->numents)
- entedit(ue[i].i, (entity &)e = ue[i].e);
+ undoent *ue = u->ents();
+ loopi(u->numents)
+ entedit(ue[i].i, (entity &)e = ue[i].e);
}
void entflip()
{
- if(noentedit()) return;
- int d = dimension(sel.orient);
- float mid = sel.s[d]*sel.grid/2+sel.o[d];
- groupeditundo(e.o[d] -= (e.o[d]-mid)*2);
+ if(noentedit()) return;
+ int d = dimension(sel.orient);
+ float mid = sel.s[d]*sel.grid/2+sel.o[d];
+ groupeditundo(e.o[d] -= (e.o[d]-mid)*2);
}
void entrotate(int *cw)
{
- if(noentedit()) return;
- int d = dimension(sel.orient);
- int dd = (*cw<0) == dimcoord(sel.orient) ? R[d] : C[d];
- float mid = sel.s[dd]*sel.grid/2+sel.o[dd];
- vec s(sel.o.v);
- groupeditundo(
- e.o[dd] -= (e.o[dd]-mid)*2;
- e.o.sub(s);
- swap(e.o[R[d]], e.o[C[d]]);
- e.o.add(s);
- );
+ if(noentedit()) return;
+ int d = dimension(sel.orient);
+ int dd = (*cw<0) == dimcoord(sel.orient) ? R[d] : C[d];
+ float mid = sel.s[dd]*sel.grid/2+sel.o[dd];
+ vec s(sel.o.v);
+ groupeditundo(
+ e.o[dd] -= (e.o[dd]-mid)*2;
+ e.o.sub(s);
+ swap(e.o[R[d]], e.o[C[d]]);
+ e.o.add(s);
+ );
}
void entselectionbox(const entity &e, vec &eo, vec &es)
{
- model *m = NULL;
- const char *mname = entities::entmodel(e);
- if(mname && (m = loadmodel(mname)))
- {
- m->collisionbox(eo, es);
- if(es.x > es.y) es.y = es.x; else es.x = es.y; // square
- es.z = (es.z + eo.z + 1 + entselradius)/2; // enclose ent radius box and model box
- eo.x += e.o.x;
- eo.y += e.o.y;
- eo.z = e.o.z - entselradius + es.z;
- }
- else if(e.type == ET_MAPMODEL && (m = loadmapmodel(e.attr2)))
- {
- mmcollisionbox(e, m, eo, es);
- es.max(entselradius);
- eo.add(e.o);
- }
- else
- {
- es = vec(entselradius);
- eo = e.o;
- }
- eo.sub(es);
- es.mul(2);
+ model *m = NULL;
+ const char *mname = entities::entmodel(e);
+ if(mname && (m = loadmodel(mname)))
+ {
+ m->collisionbox(eo, es);
+ if(es.x > es.y) es.y = es.x; else es.x = es.y; // square
+ es.z = (es.z + eo.z + 1 + entselradius)/2; // enclose ent radius box and model box
+ eo.x += e.o.x;
+ eo.y += e.o.y;
+ eo.z = e.o.z - entselradius + es.z;
+ }
+ else if(e.type == ET_MAPMODEL && (m = loadmapmodel(e.attr2)))
+ {
+ mmcollisionbox(e, m, eo, es);
+ es.max(entselradius);
+ eo.add(e.o);
+ }
+ else
+ {
+ es = vec(entselradius);
+ eo = e.o;
+ }
+ eo.sub(es);
+ es.mul(2);
}
VAR(entselsnap, 0, 0, 1);
@@ -519,327 +519,327 @@ int entmoving = 0;
void entdrag(const vec &ray)
{
- if(noentedit() || !haveselent()) return;
+ if(noentedit() || !haveselent()) return;
- float r = 0, c = 0;
- static vec v, handle;
- vec eo, es;
- int d = dimension(entorient),
- dc= dimcoord(entorient);
+ float r = 0, c = 0;
+ static vec v, handle;
+ vec eo, es;
+ int d = dimension(entorient),
+ dc= dimcoord(entorient);
- entfocus(entgroup.last(),
- entselectionbox(e, eo, es);
+ entfocus(entgroup.last(),
+ entselectionbox(e, eo, es);
- if(!editmoveplane(e.o, ray, d, eo[d] + (dc ? es[d] : 0), handle, v, entmoving==1))
- return;
+ if(!editmoveplane(e.o, ray, d, eo[d] + (dc ? es[d] : 0), handle, v, entmoving==1))
+ return;
- ivec g(v);
- int z = g[d]&(~(sel.grid-1));
- g.add(sel.grid/2).mask(~(sel.grid-1));
- g[d] = z;
+ ivec g(v);
+ int z = g[d]&(~(sel.grid-1));
+ g.add(sel.grid/2).mask(~(sel.grid-1));
+ g[d] = z;
- r = (entselsnap ? g[R[d]] : v[R[d]]) - e.o[R[d]];
- c = (entselsnap ? g[C[d]] : v[C[d]]) - e.o[C[d]];
- );
+ r = (entselsnap ? g[R[d]] : v[R[d]]) - e.o[R[d]];
+ c = (entselsnap ? g[C[d]] : v[C[d]]) - e.o[C[d]];
+ );
- if(entmoving==1) makeundoent();
- groupeditpure(e.o[R[d]] += r; e.o[C[d]] += c);
- entmoving = 2;
+ if(entmoving==1) makeundoent();
+ groupeditpure(e.o[R[d]] += r; e.o[C[d]] += c);
+ entmoving = 2;
}
VAR(showentradius, 0, 1, 1);
void renderentring(const extentity &e, float radius, int axis)
{
- if(radius <= 0) return;
- gle::defvertex();
- gle::begin(GL_LINE_LOOP);
- loopi(15)
- {
- vec p(e.o);
- const vec2 &sc = sincos360[i*(360/15)];
- p[axis>=2 ? 1 : 0] += radius*sc.x;
- p[axis>=1 ? 2 : 1] += radius*sc.y;
- gle::attrib(p);
- }
- xtraverts += gle::end();
+ if(radius <= 0) return;
+ gle::defvertex();
+ gle::begin(GL_LINE_LOOP);
+ loopi(15)
+ {
+ vec p(e.o);
+ const vec2 &sc = sincos360[i*(360/15)];
+ p[axis>=2 ? 1 : 0] += radius*sc.x;
+ p[axis>=1 ? 2 : 1] += radius*sc.y;
+ gle::attrib(p);
+ }
+ xtraverts += gle::end();
}
void renderentsphere(const extentity &e, float radius)
{
- if(radius <= 0) return;
- loopk(3) renderentring(e, radius, k);
+ if(radius <= 0) return;
+ loopk(3) renderentring(e, radius, k);
}
void renderentattachment(const extentity &e)
{
- if(!e.attached) return;
- gle::defvertex();
- gle::begin(GL_LINES);
- gle::attrib(e.o);
- gle::attrib(e.attached->o);
- xtraverts += gle::end();
+ if(!e.attached) return;
+ gle::defvertex();
+ gle::begin(GL_LINES);
+ gle::attrib(e.o);
+ gle::attrib(e.attached->o);
+ xtraverts += gle::end();
}
void renderentarrow(const extentity &e, const vec &dir, float radius)
{
- if(radius <= 0) return;
- float arrowsize = min(radius/8, 0.5f);
- vec target = vec(dir).mul(radius).add(e.o), arrowbase = vec(dir).mul(radius - arrowsize).add(e.o), spoke;
- spoke.orthogonal(dir);
- spoke.normalize();
- spoke.mul(arrowsize);
+ if(radius <= 0) return;
+ float arrowsize = min(radius/8, 0.5f);
+ vec target = vec(dir).mul(radius).add(e.o), arrowbase = vec(dir).mul(radius - arrowsize).add(e.o), spoke;
+ spoke.orthogonal(dir);
+ spoke.normalize();
+ spoke.mul(arrowsize);
- gle::defvertex();
+ gle::defvertex();
- gle::begin(GL_LINES);
- gle::attrib(e.o);
- gle::attrib(target);
- xtraverts += gle::end();
+ gle::begin(GL_LINES);
+ gle::attrib(e.o);
+ gle::attrib(target);
+ xtraverts += gle::end();
- gle::begin(GL_TRIANGLE_FAN);
- gle::attrib(target);
- loopi(5) gle::attrib(vec(spoke).rotate(2*M_PI*i/4.0f, dir).add(arrowbase));
- xtraverts += gle::end();
+ gle::begin(GL_TRIANGLE_FAN);
+ gle::attrib(target);
+ loopi(5) gle::attrib(vec(spoke).rotate(2*M_PI*i/4.0f, dir).add(arrowbase));
+ xtraverts += gle::end();
}
void renderentcone(const extentity &e, const vec &dir, float radius, float angle)
{
- if(radius <= 0) return;
- vec spot = vec(dir).mul(radius*cosf(angle*RAD)).add(e.o), spoke;
- spoke.orthogonal(dir);
- spoke.normalize();
- spoke.mul(radius*sinf(angle*RAD));
+ if(radius <= 0) return;
+ vec spot = vec(dir).mul(radius*cosf(angle*RAD)).add(e.o), spoke;
+ spoke.orthogonal(dir);
+ spoke.normalize();
+ spoke.mul(radius*sinf(angle*RAD));
- gle::defvertex();
+ gle::defvertex();
- gle::begin(GL_LINES);
- loopi(8)
- {
- gle::attrib(e.o);
- gle::attrib(vec(spoke).rotate(2*M_PI*i/8.0f, dir).add(spot));
- }
- xtraverts += gle::end();
+ gle::begin(GL_LINES);
+ loopi(8)
+ {
+ gle::attrib(e.o);
+ gle::attrib(vec(spoke).rotate(2*M_PI*i/8.0f, dir).add(spot));
+ }
+ xtraverts += gle::end();
- gle::begin(GL_LINE_LOOP);
- loopi(8) gle::attrib(vec(spoke).rotate(2*M_PI*i/8.0f, dir).add(spot));
- xtraverts += gle::end();
+ gle::begin(GL_LINE_LOOP);
+ loopi(8) gle::attrib(vec(spoke).rotate(2*M_PI*i/8.0f, dir).add(spot));
+ xtraverts += gle::end();
}
void renderentradius(extentity &e, bool color)
{
- switch(e.type)
- {
- case ET_LIGHT:
- if(color) gle::colorf(e.attr2/255.0f, e.attr3/255.0f, e.attr4/255.0f);
- renderentsphere(e, e.attr1);
- break;
-
- case ET_SPOTLIGHT:
- if(e.attached)
- {
- if(color) gle::colorf(0, 1, 1);
- float radius = e.attached->attr1;
- if(!radius) radius = 2*e.o.dist(e.attached->o);
- vec dir = vec(e.o).sub(e.attached->o).normalize();
- float angle = clamp(int(e.attr1), 1, 89);
- renderentattachment(e);
- renderentcone(*e.attached, dir, radius, angle);
- }
- break;
-
- case ET_SOUND:
- if(color) gle::colorf(0, 1, 1);
- renderentsphere(e, e.attr2);
- break;
-
- case ET_ENVMAP:
- {
- extern int envmapradius;
- if(color) gle::colorf(0, 1, 1);
- renderentsphere(e, e.attr1 ? max(0, min(10000, int(e.attr1))) : envmapradius);
- break;
- }
-
- case ET_MAPMODEL:
- case ET_PLAYERSTART:
- {
- if(color) gle::colorf(0, 1, 1);
- entities::entradius(e, color);
- vec dir;
- vecfromyawpitch(e.attr1, 0, 1, 0, dir);
- renderentarrow(e, dir, 4);
- break;
- }
-
- default:
- if(e.type>=ET_GAMESPECIFIC)
- {
- if(color) gle::colorf(0, 1, 1);
- entities::entradius(e, color);
- }
- break;
- }
+ switch(e.type)
+ {
+ case ET_LIGHT:
+ if(color) gle::colorf(e.attr2/255.0f, e.attr3/255.0f, e.attr4/255.0f);
+ renderentsphere(e, e.attr1);
+ break;
+
+ case ET_SPOTLIGHT:
+ if(e.attached)
+ {
+ if(color) gle::colorf(0, 1, 1);
+ float radius = e.attached->attr1;
+ if(!radius) radius = 2*e.o.dist(e.attached->o);
+ vec dir = vec(e.o).sub(e.attached->o).normalize();
+ float angle = clamp(int(e.attr1), 1, 89);
+ renderentattachment(e);
+ renderentcone(*e.attached, dir, radius, angle);
+ }
+ break;
+
+ case ET_SOUND:
+ if(color) gle::colorf(0, 1, 1);
+ renderentsphere(e, e.attr2);
+ break;
+
+ case ET_ENVMAP:
+ {
+ extern int envmapradius;
+ if(color) gle::colorf(0, 1, 1);
+ renderentsphere(e, e.attr1 ? max(0, min(10000, int(e.attr1))) : envmapradius);
+ break;
+ }
+
+ case ET_MAPMODEL:
+ case ET_PLAYERSTART:
+ {
+ if(color) gle::colorf(0, 1, 1);
+ entities::entradius(e, color);
+ vec dir;
+ vecfromyawpitch(e.attr1, 0, 1, 0, dir);
+ renderentarrow(e, dir, 4);
+ break;
+ }
+
+ default:
+ if(e.type>=ET_GAMESPECIFIC)
+ {
+ if(color) gle::colorf(0, 1, 1);
+ entities::entradius(e, color);
+ }
+ break;
+ }
}
static void renderentbox(const vec &eo, vec es)
{
- es.add(eo);
+ es.add(eo);
- // bottom quad
- gle::attrib(eo.x, eo.y, eo.z); gle::attrib(es.x, eo.y, eo.z);
- gle::attrib(es.x, eo.y, eo.z); gle::attrib(es.x, es.y, eo.z);
- gle::attrib(es.x, es.y, eo.z); gle::attrib(eo.x, es.y, eo.z);
- gle::attrib(eo.x, es.y, eo.z); gle::attrib(eo.x, eo.y, eo.z);
+ // bottom quad
+ gle::attrib(eo.x, eo.y, eo.z); gle::attrib(es.x, eo.y, eo.z);
+ gle::attrib(es.x, eo.y, eo.z); gle::attrib(es.x, es.y, eo.z);
+ gle::attrib(es.x, es.y, eo.z); gle::attrib(eo.x, es.y, eo.z);
+ gle::attrib(eo.x, es.y, eo.z); gle::attrib(eo.x, eo.y, eo.z);
- // top quad
- gle::attrib(eo.x, eo.y, es.z); gle::attrib(es.x, eo.y, es.z);
- gle::attrib(es.x, eo.y, es.z); gle::attrib(es.x, es.y, es.z);
- gle::attrib(es.x, es.y, es.z); gle::attrib(eo.x, es.y, es.z);
- gle::attrib(eo.x, es.y, es.z); gle::attrib(eo.x, eo.y, es.z);
+ // top quad
+ gle::attrib(eo.x, eo.y, es.z); gle::attrib(es.x, eo.y, es.z);
+ gle::attrib(es.x, eo.y, es.z); gle::attrib(es.x, es.y, es.z);
+ gle::attrib(es.x, es.y, es.z); gle::attrib(eo.x, es.y, es.z);
+ gle::attrib(eo.x, es.y, es.z); gle::attrib(eo.x, eo.y, es.z);
- // sides
- gle::attrib(eo.x, eo.y, eo.z); gle::attrib(eo.x, eo.y, es.z);
- gle::attrib(es.x, eo.y, eo.z); gle::attrib(es.x, eo.y, es.z);
- gle::attrib(es.x, es.y, eo.z); gle::attrib(es.x, es.y, es.z);
- gle::attrib(eo.x, es.y, eo.z); gle::attrib(eo.x, es.y, es.z);
+ // sides
+ gle::attrib(eo.x, eo.y, eo.z); gle::attrib(eo.x, eo.y, es.z);
+ gle::attrib(es.x, eo.y, eo.z); gle::attrib(es.x, eo.y, es.z);
+ gle::attrib(es.x, es.y, eo.z); gle::attrib(es.x, es.y, es.z);
+ gle::attrib(eo.x, es.y, eo.z); gle::attrib(eo.x, es.y, es.z);
}
void renderentselection(const vec &o, const vec &ray, bool entmoving)
{
- if(noentedit()) return;
- vec eo, es;
-
- if(entgroup.length())
- {
- gle::colorub(0, 40, 0);
- gle::defvertex();
- gle::begin(GL_LINES, entgroup.length()*24);
- loopv(entgroup) entfocus(entgroup[i],
- entselectionbox(e, eo, es);
- renderentbox(eo, es);
- );
- xtraverts += gle::end();
- }
-
- if(enthover >= 0)
- {
- gle::colorub(0, 40, 0);
- entfocus(enthover, entselectionbox(e, eo, es)); // also ensures enthover is back in focus
- boxs3D(eo, es, 1);
- if(entmoving && entmovingshadow==1)
- {
- vec a, b;
- gle::colorub(20, 20, 20);
- (a = eo).x = eo.x - fmod(eo.x, worldsize); (b = es).x = a.x + worldsize; boxs3D(a, b, 1);
- (a = eo).y = eo.y - fmod(eo.y, worldsize); (b = es).y = a.x + worldsize; boxs3D(a, b, 1);
- (a = eo).z = eo.z - fmod(eo.z, worldsize); (b = es).z = a.x + worldsize; boxs3D(a, b, 1);
- }
- gle::colorub(150,0,0);
- boxs(entorient, eo, es);
- boxs(entorient, eo, es, clamp(0.015f*camera1->o.dist(eo)*tan(fovy*0.5f*RAD), 0.1f, 1.0f));
- }
-
- if(showentradius && (entgroup.length() || enthover >= 0))
- {
- glDepthFunc(GL_GREATER);
- gle::colorf(0.25f, 0.25f, 0.25f);
- loopv(entgroup) entfocus(entgroup[i], renderentradius(e, false));
- if(enthover>=0) entfocus(enthover, renderentradius(e, false));
- glDepthFunc(GL_LESS);
- loopv(entgroup) entfocus(entgroup[i], renderentradius(e, true));
- if(enthover>=0) entfocus(enthover, renderentradius(e, true));
- }
+ if(noentedit()) return;
+ vec eo, es;
+
+ if(entgroup.length())
+ {
+ gle::colorub(0, 40, 0);
+ gle::defvertex();
+ gle::begin(GL_LINES, entgroup.length()*24);
+ loopv(entgroup) entfocus(entgroup[i],
+ entselectionbox(e, eo, es);
+ renderentbox(eo, es);
+ );
+ xtraverts += gle::end();
+ }
+
+ if(enthover >= 0)
+ {
+ gle::colorub(0, 40, 0);
+ entfocus(enthover, entselectionbox(e, eo, es)); // also ensures enthover is back in focus
+ boxs3D(eo, es, 1);
+ if(entmoving && entmovingshadow==1)
+ {
+ vec a, b;
+ gle::colorub(20, 20, 20);
+ (a = eo).x = eo.x - fmod(eo.x, worldsize); (b = es).x = a.x + worldsize; boxs3D(a, b, 1);
+ (a = eo).y = eo.y - fmod(eo.y, worldsize); (b = es).y = a.x + worldsize; boxs3D(a, b, 1);
+ (a = eo).z = eo.z - fmod(eo.z, worldsize); (b = es).z = a.x + worldsize; boxs3D(a, b, 1);
+ }
+ gle::colorub(150,0,0);
+ boxs(entorient, eo, es);
+ boxs(entorient, eo, es, clamp(0.015f*camera1->o.dist(eo)*tan(fovy*0.5f*RAD), 0.1f, 1.0f));
+ }
+
+ if(showentradius && (entgroup.length() || enthover >= 0))
+ {
+ glDepthFunc(GL_GREATER);
+ gle::colorf(0.25f, 0.25f, 0.25f);
+ loopv(entgroup) entfocus(entgroup[i], renderentradius(e, false));
+ if(enthover>=0) entfocus(enthover, renderentradius(e, false));
+ glDepthFunc(GL_LESS);
+ loopv(entgroup) entfocus(entgroup[i], renderentradius(e, true));
+ if(enthover>=0) entfocus(enthover, renderentradius(e, true));
+ }
}
bool enttoggle(int id)
{
- undonext = true;
- int i = entgroup.find(id);
- if(i < 0)
- entadd(id);
- else
- entgroup.remove(i);
- return i < 0;
+ undonext = true;
+ int i = entgroup.find(id);
+ if(i < 0)
+ entadd(id);
+ else
+ entgroup.remove(i);
+ return i < 0;
}
bool hoveringonent(int ent, int orient)
{
- if(noentedit()) return false;
- entorient = orient;
- if((efocus = enthover = ent) >= 0)
- return true;
- efocus = entgroup.empty() ? -1 : entgroup.last();
- enthover = -1;
- return false;
+ if(noentedit()) return false;
+ entorient = orient;
+ if((efocus = enthover = ent) >= 0)
+ return true;
+ efocus = entgroup.empty() ? -1 : entgroup.last();
+ enthover = -1;
+ return false;
}
VAR(entitysurf, 0, 0, 1);
ICOMMAND(entadd, "", (),
{
- if(enthover >= 0 && !noentedit())
- {
- if(entgroup.find(enthover) < 0) entadd(enthover);
- if(entmoving > 1) entmoving = 1;
- }
+ if(enthover >= 0 && !noentedit())
+ {
+ if(entgroup.find(enthover) < 0) entadd(enthover);
+ if(entmoving > 1) entmoving = 1;
+ }
});
ICOMMAND(enttoggle, "", (),
{
- if(enthover < 0 || noentedit() || !enttoggle(enthover)) { entmoving = 0; intret(0); }
- else { if(entmoving > 1) entmoving = 1; intret(1); }
+ if(enthover < 0 || noentedit() || !enttoggle(enthover)) { entmoving = 0; intret(0); }
+ else { if(entmoving > 1) entmoving = 1; intret(1); }
});
ICOMMAND(entmoving, "b", (int *n),
{
- if(*n >= 0)
- {
- if(!*n || enthover < 0 || noentedit()) entmoving = 0;
- else
- {
- if(entgroup.find(enthover) < 0) { entadd(enthover); entmoving = 1; }
- else if(!entmoving) entmoving = 1;
- }
- }
- intret(entmoving);
+ if(*n >= 0)
+ {
+ if(!*n || enthover < 0 || noentedit()) entmoving = 0;
+ else
+ {
+ if(entgroup.find(enthover) < 0) { entadd(enthover); entmoving = 1; }
+ else if(!entmoving) entmoving = 1;
+ }
+ }
+ intret(entmoving);
});
void entpush(int *dir)
{
- if(noentedit()) return;
- int d = dimension(entorient);
- int s = dimcoord(entorient) ? -*dir : *dir;
- if(entmoving)
- {
- groupeditpure(e.o[d] += float(s*sel.grid)); // editdrag supplies the undo
- }
- else
- groupedit(e.o[d] += float(s*sel.grid));
- if(entitysurf==1)
- {
- player->o[d] += float(s*sel.grid);
- player->resetinterp();
- }
+ if(noentedit()) return;
+ int d = dimension(entorient);
+ int s = dimcoord(entorient) ? -*dir : *dir;
+ if(entmoving)
+ {
+ groupeditpure(e.o[d] += float(s*sel.grid)); // editdrag supplies the undo
+ }
+ else
+ groupedit(e.o[d] += float(s*sel.grid));
+ if(entitysurf==1)
+ {
+ player->o[d] += float(s*sel.grid);
+ player->resetinterp();
+ }
}
VAR(entautoviewdist, 0, 25, 100);
void entautoview(int *dir)
{
- if(!haveselent()) return;
- static int s = 0;
- vec v(player->o);
- v.sub(worldpos);
- v.normalize();
- v.mul(entautoviewdist);
- int t = s + *dir;
- s = abs(t) % entgroup.length();
- if(t<0 && s>0) s = entgroup.length() - s;
- entfocus(entgroup[s],
- v.add(e.o);
- player->o = v;
- player->resetinterp();
- );
+ if(!haveselent()) return;
+ static int s = 0;
+ vec v(player->o);
+ v.sub(worldpos);
+ v.normalize();
+ v.mul(entautoviewdist);
+ int t = s + *dir;
+ s = abs(t) % entgroup.length();
+ if(t<0 && s>0) s = entgroup.length() - s;
+ entfocus(entgroup[s],
+ v.add(e.o);
+ player->o = v;
+ player->resetinterp();
+ );
}
COMMAND(entautoview, "i");
@@ -849,76 +849,76 @@ COMMAND(entpush, "i");
void delent()
{
- if(noentedit()) return;
- groupedit(e.type = ET_EMPTY;);
- entcancel();
+ if(noentedit()) return;
+ groupedit(e.type = ET_EMPTY;);
+ entcancel();
}
int findtype(char *what)
{
- for(int i = 0; *entities::entname(i); i++) if(strcmp(what, entities::entname(i))==0) return i;
- conoutf(CON_ERROR, "unknown entity type \"%s\"", what);
- return ET_EMPTY;
+ for(int i = 0; *entities::entname(i); i++) if(strcmp(what, entities::entname(i))==0) return i;
+ conoutf(CON_ERROR, "unknown entity type \"%s\"", what);
+ return ET_EMPTY;
}
VAR(entdrop, 0, 2, 3);
bool dropentity(entity &e, int drop = -1)
{
- vec radius(4.0f, 4.0f, 4.0f);
- if(drop<0) drop = entdrop;
- if(e.type == ET_MAPMODEL)
- {
- model *m = loadmapmodel(e.attr2);
- if(m)
- {
- vec center;
- mmboundbox(e, m, center, radius);
- radius.x += fabs(center.x);
- radius.y += fabs(center.y);
- }
- radius.z = 0.0f;
- }
- switch(drop)
- {
- case 1:
- if(e.type != ET_LIGHT && e.type != ET_SPOTLIGHT)
- dropenttofloor(&e);
- break;
- case 2:
- case 3:
- int cx = 0, cy = 0;
- if(sel.cxs == 1 && sel.cys == 1)
- {
- cx = (sel.cx ? 1 : -1) * sel.grid / 2;
- cy = (sel.cy ? 1 : -1) * sel.grid / 2;
- }
- e.o = vec(sel.o);
- int d = dimension(sel.orient), dc = dimcoord(sel.orient);
- e.o[R[d]] += sel.grid / 2 + cx;
- e.o[C[d]] += sel.grid / 2 + cy;
- if(!dc)
- e.o[D[d]] -= radius[D[d]];
- else
- e.o[D[d]] += sel.grid + radius[D[d]];
-
- if(drop == 3)
- dropenttofloor(&e);
- break;
- }
- return true;
+ vec radius(4.0f, 4.0f, 4.0f);
+ if(drop<0) drop = entdrop;
+ if(e.type == ET_MAPMODEL)
+ {
+ model *m = loadmapmodel(e.attr2);
+ if(m)
+ {
+ vec center;
+ mmboundbox(e, m, center, radius);
+ radius.x += fabs(center.x);
+ radius.y += fabs(center.y);
+ }
+ radius.z = 0.0f;
+ }
+ switch(drop)
+ {
+ case 1:
+ if(e.type != ET_LIGHT && e.type != ET_SPOTLIGHT)
+ dropenttofloor(&e);
+ break;
+ case 2:
+ case 3:
+ int cx = 0, cy = 0;
+ if(sel.cxs == 1 && sel.cys == 1)
+ {
+ cx = (sel.cx ? 1 : -1) * sel.grid / 2;
+ cy = (sel.cy ? 1 : -1) * sel.grid / 2;
+ }
+ e.o = vec(sel.o);
+ int d = dimension(sel.orient), dc = dimcoord(sel.orient);
+ e.o[R[d]] += sel.grid / 2 + cx;
+ e.o[C[d]] += sel.grid / 2 + cy;
+ if(!dc)
+ e.o[D[d]] -= radius[D[d]];
+ else
+ e.o[D[d]] += sel.grid + radius[D[d]];
+
+ if(drop == 3)
+ dropenttofloor(&e);
+ break;
+ }
+ return true;
}
void dropent()
{
- if(noentedit()) return;
- groupedit(dropentity(e));
+ if(noentedit()) return;
+ groupedit(dropentity(e));
}
void attachent()
{
- if(noentedit()) return;
- groupedit(attachentity(e));
+ if(noentedit()) return;
+ groupedit(attachentity(e));
}
COMMAND(attachent, "");
@@ -929,63 +929,63 @@ static int keepents = 0;
extentity *newentity(bool local, const vec &o, int type, int v1, int v2, int v3, int v4, int v5, int &idx)
{
- vector<extentity *> &ents = entities::getents();
- if(local)
- {
- idx = -1;
- for(int i = keepents; i < ents.length(); i++) if(ents[i]->type == ET_EMPTY) { idx = i; break; }
- if(idx < 0 && ents.length() >= MAXENTS) { conoutf(CON_ERROR, "too many entities"); return NULL; }
- }
- else while(ents.length() < idx) ents.add(entities::newentity())->type = ET_EMPTY;
- extentity &e = *entities::newentity();
- e.o = o;
- e.attr1 = v1;
- e.attr2 = v2;
- e.attr3 = v3;
- e.attr4 = v4;
- e.attr5 = v5;
- e.type = type;
- e.reserved = 0;
- e.light.color = vec(1, 1, 1);
- e.light.dir = vec(0, 0, 1);
- if(local)
- {
- if(entcamdir) switch(type)
- {
- case ET_MAPMODEL:
- case ET_PLAYERSTART:
- e.attr5 = e.attr4;
- e.attr4 = e.attr3;
- e.attr3 = e.attr2;
- e.attr2 = e.attr1;
- e.attr1 = (int)camera1->yaw;
- break;
- }
- entities::fixentity(e);
- }
- if(ents.inrange(idx)) { entities::deleteentity(ents[idx]); ents[idx] = &e; }
- else { idx = ents.length(); ents.add(&e); }
- return &e;
+ vector<extentity *> &ents = entities::getents();
+ if(local)
+ {
+ idx = -1;
+ for(int i = keepents; i < ents.length(); i++) if(ents[i]->type == ET_EMPTY) { idx = i; break; }
+ if(idx < 0 && ents.length() >= MAXENTS) { conoutf(CON_ERROR, "too many entities"); return NULL; }
+ }
+ else while(ents.length() < idx) ents.add(entities::newentity())->type = ET_EMPTY;
+ extentity &e = *entities::newentity();
+ e.o = o;
+ e.attr1 = v1;
+ e.attr2 = v2;
+ e.attr3 = v3;
+ e.attr4 = v4;
+ e.attr5 = v5;
+ e.type = type;
+ e.reserved = 0;
+ e.light.color = vec(1, 1, 1);
+ e.light.dir = vec(0, 0, 1);
+ if(local)
+ {
+ if(entcamdir) switch(type)
+ {
+ case ET_MAPMODEL:
+ case ET_PLAYERSTART:
+ e.attr5 = e.attr4;
+ e.attr4 = e.attr3;
+ e.attr3 = e.attr2;
+ e.attr2 = e.attr1;
+ e.attr1 = (int)camera1->yaw;
+ break;
+ }
+ entities::fixentity(e);
+ }
+ if(ents.inrange(idx)) { entities::deleteentity(ents[idx]); ents[idx] = &e; }
+ else { idx = ents.length(); ents.add(&e); }
+ return &e;
}
void newentity(int type, int a1, int a2, int a3, int a4, int a5)
{
- int idx;
- extentity *t = newentity(true, player->o, type, a1, a2, a3, a4, a5, idx);
- if(!t) return;
- dropentity(*t);
- t->type = ET_EMPTY;
- enttoggle(idx);
- makeundoent();
- entedit(idx, e.type = type);
+ int idx;
+ extentity *t = newentity(true, player->o, type, a1, a2, a3, a4, a5, idx);
+ if(!t) return;
+ dropentity(*t);
+ t->type = ET_EMPTY;
+ enttoggle(idx);
+ makeundoent();
+ entedit(idx, e.type = type);
}
void newent(char *what, int *a1, int *a2, int *a3, int *a4, int *a5)
{
- if(noentedit()) return;
- int type = findtype(what);
- if(type != ET_EMPTY)
- newentity(type, *a1, *a2, *a3, *a4, *a5);
+ if(noentedit()) return;
+ int type = findtype(what);
+ if(type != ET_EMPTY)
+ newentity(type, *a1, *a2, *a3, *a4, *a5);
}
int entcopygrid;
@@ -993,33 +993,33 @@ vector<entity> entcopybuf;
void entcopy()
{
- if(noentedit()) return;
- entcopygrid = sel.grid;
- entcopybuf.shrink(0);
- loopv(entgroup)
- entfocus(entgroup[i], entcopybuf.add(e).o.sub(vec(sel.o)));
+ if(noentedit()) return;
+ entcopygrid = sel.grid;
+ entcopybuf.shrink(0);
+ loopv(entgroup)
+ entfocus(entgroup[i], entcopybuf.add(e).o.sub(vec(sel.o)));
}
void entpaste()
{
- if(noentedit()) return;
- if(entcopybuf.length()==0) return;
- entcancel();
- float m = float(sel.grid)/float(entcopygrid);
- loopv(entcopybuf)
- {
- entity &c = entcopybuf[i];
- vec o(c.o);
- o.mul(m).add(vec(sel.o));
- int idx;
- extentity *e = newentity(true, o, ET_EMPTY, c.attr1, c.attr2, c.attr3, c.attr4, c.attr5, idx);
- if(!e) continue;
- entadd(idx);
- keepents = max(keepents, idx+1);
- }
- keepents = 0;
- int j = 0;
- groupeditundo(e.type = entcopybuf[j++].type;);
+ if(noentedit()) return;
+ if(entcopybuf.length()==0) return;
+ entcancel();
+ float m = float(sel.grid)/float(entcopygrid);
+ loopv(entcopybuf)
+ {
+ entity &c = entcopybuf[i];
+ vec o(c.o);
+ o.mul(m).add(vec(sel.o));
+ int idx;
+ extentity *e = newentity(true, o, ET_EMPTY, c.attr1, c.attr2, c.attr3, c.attr4, c.attr5, idx);
+ if(!e) continue;
+ entadd(idx);
+ keepents = max(keepents, idx+1);
+ }
+ keepents = 0;
+ int j = 0;
+ groupeditundo(e.type = entcopybuf[j++].type;);
}
COMMAND(newent, "siiiii");
@@ -1030,101 +1030,101 @@ COMMAND(entpaste, "");
void entset(char *what, int *a1, int *a2, int *a3, int *a4, int *a5)
{
- if(noentedit()) return;
- int type = findtype(what);
- if(type != ET_EMPTY)
- groupedit(e.type=type;
- e.attr1=*a1;
- e.attr2=*a2;
- e.attr3=*a3;
- e.attr4=*a4;
- e.attr5=*a5);
+ if(noentedit()) return;
+ int type = findtype(what);
+ if(type != ET_EMPTY)
+ groupedit(e.type=type;
+ e.attr1=*a1;
+ e.attr2=*a2;
+ e.attr3=*a3;
+ e.attr4=*a4;
+ e.attr5=*a5);
}
void printent(extentity &e, char *buf, int len)
{
- switch(e.type)
- {
- case ET_PARTICLES:
- if(printparticles(e, buf, len)) return;
- break;
+ switch(e.type)
+ {
+ case ET_PARTICLES:
+ if(printparticles(e, buf, len)) return;
+ break;
- default:
- if(e.type >= ET_GAMESPECIFIC && entities::printent(e, buf, len)) return;
- break;
- }
- nformatstring(buf, len, "%s %d %d %d %d %d", entities::entname(e.type), e.attr1, e.attr2, e.attr3, e.attr4, e.attr5);
+ default:
+ if(e.type >= ET_GAMESPECIFIC && entities::printent(e, buf, len)) return;
+ break;
+ }
+ nformatstring(buf, len, "%s %d %d %d %d %d", entities::entname(e.type), e.attr1, e.attr2, e.attr3, e.attr4, e.attr5);
}
void nearestent()
{
- if(noentedit()) return;
- int closest = -1;
- float closedist = 1e16f;
- vector<extentity *> &ents = entities::getents();
- loopv(ents)
- {
- extentity &e = *ents[i];
- if(e.type == ET_EMPTY) continue;
- float dist = e.o.dist(player->o);
- if(dist < closedist)
- {
- closest = i;
- closedist = dist;
- }
- }
- if(closest >= 0 && entgroup.find(closest) < 0) entadd(closest);
+ if(noentedit()) return;
+ int closest = -1;
+ float closedist = 1e16f;
+ vector<extentity *> &ents = entities::getents();
+ loopv(ents)
+ {
+ extentity &e = *ents[i];
+ if(e.type == ET_EMPTY) continue;
+ float dist = e.o.dist(player->o);
+ if(dist < closedist)
+ {
+ closest = i;
+ closedist = dist;
+ }
+ }
+ if(closest >= 0 && entgroup.find(closest) < 0) entadd(closest);
}
ICOMMAND(enthavesel,"", (), addimplicit(intret(entgroup.length())));
ICOMMAND(entselect, "e", (uint *body), if(!noentedit()) addgroup(e.type != ET_EMPTY && entgroup.find(n)<0 && executebool(body)));
ICOMMAND(entloop, "e", (uint *body), if(!noentedit()) addimplicit(groupeditloop(((void)e, execute(body)))));
-ICOMMAND(insel, "", (), entfocus(efocus, intret(pointinsel(sel, e.o))));
-ICOMMAND(entget, "", (), entfocus(efocus, string s; printent(e, s, sizeof(s)); result(s)));
+ICOMMAND(insel, "", (), entfocus(efocus, intret(pointinsel(sel, e.o))));
+ICOMMAND(entget, "", (), entfocus(efocus, string s; printent(e, s, sizeof(s)); result(s)));
ICOMMAND(entindex, "", (), intret(efocus));
COMMAND(entset, "siiiii");
COMMAND(nearestent, "");
void enttype(char *type, int *numargs)
{
- if(*numargs >= 1)
- {
- int typeidx = findtype(type);
- if(typeidx != ET_EMPTY) groupedit(e.type = typeidx);
- }
- else entfocus(efocus,
- {
- result(entities::entname(e.type));
- })
+ if(*numargs >= 1)
+ {
+ int typeidx = findtype(type);
+ if(typeidx != ET_EMPTY) groupedit(e.type = typeidx);
+ }
+ else entfocus(efocus,
+ {
+ result(entities::entname(e.type));
+ })
}
void entattr(int *attr, int *val, int *numargs)
{
- if(*numargs >= 2)
- {
- if(*attr >= 0 && *attr <= 4)
- groupedit(
- switch(*attr)
- {
- case 0: e.attr1 = *val; break;
- case 1: e.attr2 = *val; break;
- case 2: e.attr3 = *val; break;
- case 3: e.attr4 = *val; break;
- case 4: e.attr5 = *val; break;
- }
- );
- }
- else entfocus(efocus,
- {
- switch(*attr)
- {
- case 0: intret(e.attr1); break;
- case 1: intret(e.attr2); break;
- case 2: intret(e.attr3); break;
- case 3: intret(e.attr4); break;
- case 4: intret(e.attr5); break;
- }
- });
+ if(*numargs >= 2)
+ {
+ if(*attr >= 0 && *attr <= 4)
+ groupedit(
+ switch(*attr)
+ {
+ case 0: e.attr1 = *val; break;
+ case 1: e.attr2 = *val; break;
+ case 2: e.attr3 = *val; break;
+ case 3: e.attr4 = *val; break;
+ case 4: e.attr5 = *val; break;
+ }
+ );
+ }
+ else entfocus(efocus,
+ {
+ switch(*attr)
+ {
+ case 0: intret(e.attr1); break;
+ case 1: intret(e.attr2); break;
+ case 2: intret(e.attr3); break;
+ case 3: intret(e.attr4); break;
+ case 4: intret(e.attr5); break;
+ }
+ });
}
COMMAND(enttype, "sN");
@@ -1132,21 +1132,21 @@ COMMAND(entattr, "iiN");
int findentity(int type, int index, int attr1, int attr2)
{
- const vector<extentity *> &ents = entities::getents();
- if(index > ents.length()) index = ents.length();
- else for(int i = index; i<ents.length(); i++)
- {
- extentity &e = *ents[i];
- if(e.type==type && (attr1<0 || e.attr1==attr1) && (attr2<0 || e.attr2==attr2))
- return i;
- }
- loopj(index)
- {
- extentity &e = *ents[j];
- if(e.type==type && (attr1<0 || e.attr1==attr1) && (attr2<0 || e.attr2==attr2))
- return j;
- }
- return -1;
+ const vector<extentity *> &ents = entities::getents();
+ if(index > ents.length()) index = ents.length();
+ else for(int i = index; i<ents.length(); i++)
+ {
+ extentity &e = *ents[i];
+ if(e.type==type && (attr1<0 || e.attr1==attr1) && (attr2<0 || e.attr2==attr2))
+ return i;
+ }
+ loopj(index)
+ {
+ extentity &e = *ents[j];
+ if(e.type==type && (attr1<0 || e.attr1==attr1) && (attr2<0 || e.attr2==attr2))
+ return j;
+ }
+ return -1;
}
struct spawninfo { const extentity *e; float weight; };
@@ -1155,18 +1155,18 @@ struct spawninfo { const extentity *e; float weight; };
// which serves as a measure of its desirability for a spawning player.
float gatherspawninfos(dynent *d, int tag, vector<spawninfo> &spawninfos)
{
- const vector<extentity *> &ents = entities::getents();
- float total = 0.0f;
- loopv(ents)
- {
- const extentity &e = *ents[i];
- if(e.type != ET_PLAYERSTART || e.attr2 != tag) continue;
- spawninfo &s = spawninfos.add();
- s.e = &e;
- s.weight = game::ratespawn(d, e);
- total += s.weight;
- }
- return total;
+ const vector<extentity *> &ents = entities::getents();
+ float total = 0.0f;
+ loopv(ents)
+ {
+ const extentity &e = *ents[i];
+ if(e.type != ET_PLAYERSTART || e.attr2 != tag) continue;
+ spawninfo &s = spawninfos.add();
+ s.e = &e;
+ s.weight = game::ratespawn(d, e);
+ total += s.weight;
+ }
+ return total;
}
// Randomly picks a weighted spawn from the provided vector and removes it.
@@ -1174,179 +1174,178 @@ float gatherspawninfos(dynent *d, int tag, vector<spawninfo> &spawninfos)
// If all weights are zero, the index is picked uniformly.
static const extentity *poprandomspawn(vector<spawninfo> &spawninfos, float &total)
{
- if(spawninfos.empty()) return NULL;
- int index = 0;
- if(total > 0.0f)
- {
- float x = rndscale(total);
- do x -= spawninfos[index].weight; while(x > 0 && ++index < spawninfos.length()-1);
- }
- else index = rnd(spawninfos.length());
- spawninfo s = spawninfos.removeunordered(index);
- total -= s.weight;
- return s.e;
+ if(spawninfos.empty()) return NULL;
+ int index = 0;
+ if(total > 0.0f)
+ {
+ float x = rndscale(total);
+ do x -= spawninfos[index].weight; while(x > 0 && ++index < spawninfos.length()-1);
+ }
+ else index = rnd(spawninfos.length());
+ spawninfo s = spawninfos.removeunordered(index);
+ total -= s.weight;
+ return s.e;
}
static inline bool tryspawn(dynent *d, const extentity &e)
{
- d->o = e.o;
- d->yaw = e.attr1;
- return entinmap(d, true);
+ d->o = e.o;
+ d->yaw = e.attr1;
+ return entinmap(d, true);
}
void findplayerspawn(dynent *d, int forceent, int tag)
{
- const vector<extentity *> &ents = entities::getents();
- d->pitch = 0;
- d->roll = 0;
- if(ents.inrange(forceent) && tryspawn(d, *ents[forceent])) return;
- vector<spawninfo> spawninfos;
- float total = gatherspawninfos(d, tag, spawninfos);
- while(const extentity *e = poprandomspawn(spawninfos, total)) if(tryspawn(d, *e)) return;
- d->o = vec(0.5f * worldsize).addz(1);
- d->yaw = 0;
- entinmap(d);
+ const vector<extentity *> &ents = entities::getents();
+ d->pitch = 0;
+ d->roll = 0;
+ if(ents.inrange(forceent) && tryspawn(d, *ents[forceent])) return;
+ vector<spawninfo> spawninfos;
+ float total = gatherspawninfos(d, tag, spawninfos);
+ while(const extentity *e = poprandomspawn(spawninfos, total)) if(tryspawn(d, *e)) return;
+ d->o = vec(0.5f * worldsize).addz(1);
+ d->yaw = 0;
+ entinmap(d);
}
void splitocta(cube *c, int size)
{
- if(size <= 0x1000) return;
- loopi(8)
- {
- if(!c[i].children) c[i].children = newcubes(isempty(c[i]) ? F_EMPTY : F_SOLID);
- splitocta(c[i].children, size>>1);
- }
+ if(size <= 0x1000) return;
+ loopi(8)
+ {
+ if(!c[i].children) c[i].children = newcubes(isempty(c[i]) ? F_EMPTY : F_SOLID);
+ splitocta(c[i].children, size>>1);
+ }
}
void resetmap()
{
- clearoverrides();
- clearmapsounds();
- cleanreflections();
- resetblendmap();
- resetlightmaps();
- clearslots();
- clearparticles();
- cleardecals();
- cleardamagescreen();
- clearsleep();
- cancelsel();
- pruneundos();
- clearmapcrc();
+ clearoverrides();
+ clearmapsounds();
+ cleanreflections();
+ resetblendmap();
+ resetlightmaps();
+ clearslots();
+ clearparticles();
+ cleardecals();
+ clearsleep();
+ cancelsel();
+ pruneundos();
+ clearmapcrc();
- entities::clearents();
- outsideents.setsize(0);
+ entities::clearents();
+ outsideents.setsize(0);
}
void startmap(const char *name)
{
- game::startmap(name);
+ game::startmap(name);
}
-bool emptymap(int scale, bool force, const char *mname, bool usecfg) // main empty world creation routine
+bool emptymap(int scale, bool force, const char *mname, bool usecfg) // main empty world creation routine
{
- if(!force && !editmode)
- {
- conoutf(CON_ERROR, "newmap only allowed in edit mode");
- return false;
- }
+ if(!force && !editmode)
+ {
+ conoutf(CON_ERROR, "newmap only allowed in edit mode");
+ return false;
+ }
- resetmap();
+ resetmap();
- setvar("mapscale", scale<10 ? 10 : (scale>16 ? 16 : scale), true, false);
- setvar("mapsize", 1<<worldscale, true, false);
+ setvar("mapscale", scale<10 ? 10 : (scale>16 ? 16 : scale), true, false);
+ setvar("mapsize", 1<<worldscale, true, false);
- texmru.shrink(0);
- freeocta(worldroot);
- worldroot = newcubes(F_EMPTY);
- loopi(4) solidfaces(worldroot[i]);
+ texmru.shrink(0);
+ freeocta(worldroot);
+ worldroot = newcubes(F_EMPTY);
+ loopi(4) solidfaces(worldroot[i]);
- if(worldsize > 0x1000) splitocta(worldroot, worldsize>>1);
+ if(worldsize > 0x1000) splitocta(worldroot, worldsize>>1);
- clearmainmenu();
+ clearmainmenu();
- if(usecfg)
- {
- identflags |= IDF_OVERRIDDEN;
- execfile("data/default_map.cfg", false);
- identflags &= ~IDF_OVERRIDDEN;
- }
+ if(usecfg)
+ {
+ identflags |= IDF_OVERRIDDEN;
+ execfile("data/default_map.cfg", false);
+ identflags &= ~IDF_OVERRIDDEN;
+ }
- initlights();
- allchanged(true);
+ initlights();
+ allchanged(true);
- startmap(mname);
+ startmap(mname);
- return true;
+ return true;
}
bool enlargemap(bool force)
{
- if(!force && !editmode)
- {
- conoutf(CON_ERROR, "mapenlarge only allowed in edit mode");
- return false;
- }
- if(worldsize >= 1<<16) return false;
+ if(!force && !editmode)
+ {
+ conoutf(CON_ERROR, "mapenlarge only allowed in edit mode");
+ return false;
+ }
+ if(worldsize >= 1<<16) return false;
- while(outsideents.length()) removeentity(outsideents.pop());
+ while(outsideents.length()) removeentity(outsideents.pop());
- worldscale++;
- worldsize *= 2;
- cube *c = newcubes(F_EMPTY);
- c[0].children = worldroot;
- loopi(3) solidfaces(c[i+1]);
- worldroot = c;
+ worldscale++;
+ worldsize *= 2;
+ cube *c = newcubes(F_EMPTY);
+ c[0].children = worldroot;
+ loopi(3) solidfaces(c[i+1]);
+ worldroot = c;
- if(worldsize > 0x1000) splitocta(worldroot, worldsize>>1);
+ if(worldsize > 0x1000) splitocta(worldroot, worldsize>>1);
- enlargeblendmap();
+ enlargeblendmap();
- allchanged();
+ allchanged();
- return true;
+ return true;
}
static bool isallempty(cube &c)
{
- if(!c.children) return isempty(c);
- loopi(8) if(!isallempty(c.children[i])) return false;
- return true;
+ if(!c.children) return isempty(c);
+ loopi(8) if(!isallempty(c.children[i])) return false;
+ return true;
}
void shrinkmap()
{
- extern int nompedit;
- if(noedit(true) || (nompedit && multiplayer())) return;
- if(worldsize <= 1<<10) return;
+ extern int nompedit;
+ if(noedit(true) || (nompedit && multiplayer())) return;
+ if(worldsize <= 1<<10) return;
- int octant = -1;
- loopi(8) if(!isallempty(worldroot[i]))
- {
- if(octant >= 0) return;
- octant = i;
- }
- if(octant < 0) return;
+ int octant = -1;
+ loopi(8) if(!isallempty(worldroot[i]))
+ {
+ if(octant >= 0) return;
+ octant = i;
+ }
+ if(octant < 0) return;
- while(outsideents.length()) removeentity(outsideents.pop());
+ while(outsideents.length()) removeentity(outsideents.pop());
- if(!worldroot[octant].children) subdividecube(worldroot[octant], false, false);
- cube *root = worldroot[octant].children;
- worldroot[octant].children = NULL;
- freeocta(worldroot);
- worldroot = root;
- worldscale--;
- worldsize /= 2;
+ if(!worldroot[octant].children) subdividecube(worldroot[octant], false, false);
+ cube *root = worldroot[octant].children;
+ worldroot[octant].children = NULL;
+ freeocta(worldroot);
+ worldroot = root;
+ worldscale--;
+ worldsize /= 2;
- ivec offset(octant, ivec(0, 0, 0), worldsize);
- vector<extentity *> &ents = entities::getents();
- loopv(ents) ents[i]->o.sub(vec(offset));
+ ivec offset(octant, ivec(0, 0, 0), worldsize);
+ vector<extentity *> &ents = entities::getents();
+ loopv(ents) ents[i]->o.sub(vec(offset));
- shrinkblendmap(octant);
+ shrinkblendmap(octant);
- allchanged();
+ allchanged();
- conoutf("shrunk map to size %d", worldscale);
+ conoutf("shrunk map to size %d", worldscale);
}
void newmap(int *i) { bool force = !isconnected(); if(force) game::forceedit(""); if(emptymap(*i, force, NULL)) game::newmap(max(*i, 0)); }
@@ -1357,35 +1356,35 @@ COMMAND(shrinkmap, "");
void mapname()
{
- result(game::getclientmap());
+ result(game::getclientmap());
}
COMMAND(mapname, "");
void mpeditent(int i, const vec &o, int type, int attr1, int attr2, int attr3, int attr4, int attr5, bool local)
{
- if(i < 0 || i >= MAXENTS) return;
- vector<extentity *> &ents = entities::getents();
- if(ents.length()<=i)
- {
- extentity *e = newentity(local, o, type, attr1, attr2, attr3, attr4, attr5, i);
- if(!e) return;
- addentity(i);
- attachentity(*e);
- }
- else
- {
- extentity &e = *ents[i];
- removeentity(i);
- int oldtype = e.type;
- if(oldtype!=type) detachentity(e);
- e.type = type;
- e.o = o;
- e.attr1 = attr1; e.attr2 = attr2; e.attr3 = attr3; e.attr4 = attr4; e.attr5 = attr5;
- addentity(i);
- if(oldtype!=type) attachentity(e);
- }
- entities::editent(i, local);
+ if(i < 0 || i >= MAXENTS) return;
+ vector<extentity *> &ents = entities::getents();
+ if(ents.length()<=i)
+ {
+ extentity *e = newentity(local, o, type, attr1, attr2, attr3, attr4, attr5, i);
+ if(!e) return;
+ addentity(i);
+ attachentity(*e);
+ }
+ else
+ {
+ extentity &e = *ents[i];
+ removeentity(i);
+ int oldtype = e.type;
+ if(oldtype!=type) detachentity(e);
+ e.type = type;
+ e.o = o;
+ e.attr1 = attr1; e.attr2 = attr2; e.attr3 = attr3; e.attr4 = attr4; e.attr5 = attr5;
+ addentity(i);
+ if(oldtype!=type) attachentity(e);
+ }
+ entities::editent(i, local);
}
int getworldsize() { return worldsize; }