summaryrefslogtreecommitdiff
path: root/src/engine
diff options
context:
space:
mode:
authorxolatile2025-08-07 08:30:30 +0200
committerxolatile2025-08-07 08:30:30 +0200
commitb2c89d7060e99a36c8c7ac897b7386686c74deac (patch)
treef5e526378859cd1a86421efd25d3d6e6cb1d8bcc /src/engine
parent4c8dfb375b4b30dbb6079f9d68024980d81ffa20 (diff)
downloadxolatile-badassbug-b2c89d7060e99a36c8c7ac897b7386686c74deac.tar.xz
xolatile-badassbug-b2c89d7060e99a36c8c7ac897b7386686c74deac.tar.zst
Removed undo and prefab...
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/3dgui.cpp40
-rw-r--r--src/engine/engine.h8
-rw-r--r--src/engine/main.cpp2
-rw-r--r--src/engine/menus.cpp16
-rw-r--r--src/engine/octa.h12
-rw-r--r--src/engine/octaedit.cpp508
-rw-r--r--src/engine/world.cpp63
7 files changed, 5 insertions, 644 deletions
diff --git a/src/engine/3dgui.cpp b/src/engine/3dgui.cpp
index 201f9e3..19eed54 100644
--- a/src/engine/3dgui.cpp
+++ b/src/engine/3dgui.cpp
@@ -342,46 +342,6 @@ struct gui : g3d_gui {
}
return layout(size+SHADOW, size+SHADOW);
}
- int prefabpreview(const char *prefab, const vec &color, float sizescale, const char *overlaid, bool throttle) {
- autotab();
- if(sizescale==0) sizescale = 1;
- int size = (int)(sizescale*2*FONTH)-SHADOW;
- if(prefab[0] && visible() && (!throttle || throttlepreview(prefabloaded(prefab)))) {
- bool hit = ishit(size+SHADOW, size+SHADOW);
- float xs = size, ys = size, xi = curx, yi = cury;
- if(overlaid && hit && actionon) {
- hudnotextureshader->set();
- gle::colorf(0, 0, 0, 0.75f);
- rect_(xi+SHADOW, yi+SHADOW, xs, ys);
- hudshader->set();
- }
- int x1 = int(floor(screenw*(xi*scale.x+origin.x))), y1 = int(floor(screenh*(1 - ((yi+ys)*scale.y+origin.y)))),
- x2 = int(ceil(screenw*((xi+xs)*scale.x+origin.x))), y2 = int(ceil(screenh*(1 - (yi*scale.y+origin.y))));
- glDisable(GL_BLEND);
- modelpreview::start(x1, y1, x2-x1, y2-y1, overlaid!=NULL);
- previewprefab(prefab, color);
- modelpreview::end();
- hudshader->set();
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- if(overlaid) {
- if(hit) {
- hudnotextureshader->set();
- glBlendFunc(GL_ZERO, GL_SRC_COLOR);
- gle::colorf(1, 0.5f, 0.5f);
- rect_(xi, yi, xs, ys);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- hudshader->set();
- }
- if(overlaid[0]) text_(overlaid, xi + FONTH/2, yi + FONTH/2, hit ? 0xFF0000 : 0xFFFFFF, hit, hit);
- if(!overlaytex) overlaytex = textureload("data/guioverlay.png", 3);
- gle::color(light);
- glBindTexture(GL_TEXTURE_2D, overlaytex->id);
- rect_(xi, yi, xs, ys, 0);
- }
- }
- return layout(size+SHADOW, size+SHADOW);
- }
void slider(int &val, int vmin, int vmax, int color, const char *label) {
autotab();
int x = curx;
diff --git a/src/engine/engine.h b/src/engine/engine.h
index f50a558..5d3fec3 100644
--- a/src/engine/engine.h
+++ b/src/engine/engine.h
@@ -196,22 +196,14 @@ static inline cubeext &ext(cube &c) {
// ents
extern char *entname(entity &e);
extern bool haveselent();
-extern undoblock *copyundoents(undoblock *u);
-extern void pasteundoent(int idx, const entity &ue);
-extern void pasteundoents(undoblock *u);
// octaedit
extern void cancelsel();
extern void rendertexturepanel(int w, int h);
-extern void addundo(undoblock *u);
extern void commitchanges(bool force = false);
extern void rendereditcursor();
extern void tryedit();
-extern bool prefabloaded(const char *name);
-extern void renderprefab(const char *name, const vec &o, float yaw, float pitch, float roll, float size = 1, const vec &color = vec(1, 1, 1));
-extern void previewprefab(const char *name, const vec &color);
-
// octarender
extern vector<tjoint> tjoints;
extern vector<vtxarray *> varoot, valist;
diff --git a/src/engine/main.cpp b/src/engine/main.cpp
index 5e3b1c8..aa9b2fe 100644
--- a/src/engine/main.cpp
+++ b/src/engine/main.cpp
@@ -592,14 +592,12 @@ void resetgl() {
extern void cleanupparticles();
extern void cleanupdecals();
extern void cleanupmodels();
- extern void cleanupprefabs();
extern void cleanuplightmaps();
extern void cleanshadowmap();
cleanupva();
cleanupparticles();
cleanupdecals();
cleanupmodels();
- cleanupprefabs();
cleanuptextures();
cleanuplightmaps();
cleanshadowmap();
diff --git a/src/engine/menus.cpp b/src/engine/menus.cpp
index e91c6a2..da9e5ec 100644
--- a/src/engine/menus.cpp
+++ b/src/engine/menus.cpp
@@ -554,22 +554,6 @@ void guimodelpreview(char *model, char *animspec, char *action, float *scale, in
}
COMMAND(guimodelpreview, "sssfisi");
-void guiprefabpreview(char *prefab, int *color, char *action, float *scale, int *overlaid, char *title, int *throttle) {
- if(!cgui) return;
- int ret = cgui->prefabpreview(prefab, vec::hexcolor(*color), *scale, *overlaid!=0 ? title : NULL, *throttle!=0);
- if(ret&G3D_UP) {
- if(*action) {
- updatelater.add().schedule(action);
- if(shouldclearmenu) clearlater = true;
- }
- }
- else if(ret&G3D_ROLLOVER) {
- alias("guirolloverpreviewname", prefab);
- alias("guirolloverpreviewaction", action);
- }
-}
-COMMAND(guiprefabpreview, "sisfisi");
-
struct change {
int type;
const char *desc;
diff --git a/src/engine/octa.h b/src/engine/octa.h
index d8a2c45..60cc507 100644
--- a/src/engine/octa.h
+++ b/src/engine/octa.h
@@ -176,18 +176,6 @@ struct editinfo {
editinfo() : copy(NULL) {}
};
-struct undoent { int i; entity e; };
-struct undoblock { // undo header, all data sits in payload {
- undoblock *prev, *next;
- int size, timestamp, numents; // if numents is 0, is a cube undo record, otherwise an entity undo record
- block3 *block() { return (block3 *)(this + 1); }
- uchar *gridmap() {
- block3 *ub = block();
- return (uchar *)(ub->c() + ub->size());
- }
- undoent *ents() { return (undoent *)(this + 1); }
-};
-
extern cube *worldroot; // the world data. only a ptr to 8 cubes (ie: like cube.children above)
extern int wtris, wverts, vtris, vverts, glde, gbatches;
extern int allocnodes, allocva, selchildcount, selchildmat;
diff --git a/src/engine/octaedit.cpp b/src/engine/octaedit.cpp
index 7947e67..80e2b03 100644
--- a/src/engine/octaedit.cpp
+++ b/src/engine/octaedit.cpp
@@ -116,12 +116,9 @@ VAR(passthroughsel, 0, 0, 1);
VAR(editing, 1, 0, 0);
VAR(selectcorners, 0, 0, 1);
-void forcenextundo() { lastsel.orient = -1; }
-
void cubecancel() {
havesel = false;
moving = dragging = passthroughsel = 0;
- forcenextundo();
}
void cancelsel() {
@@ -234,7 +231,7 @@ cube &blockcube(int x, int y, int z, const block3 &b, int rgrid) { // looks up a
#define loopxy(b) loop(y,(b).s[C[dimension((b).orient)]]) loop(x,(b).s[R[dimension((b).orient)]])
#define loopxyz(b, r, f) { loop(z,(b).s[D[dimension((b).orient)]]) loopxy((b)) { cube &c = blockcube(x,y,z,b,r); f; } }
-#define loopselxyz(f) { if(local) makeundo(); loopxyz(sel, sel.grid, f); changed(sel); }
+#define loopselxyz(f) { loopxyz(sel, sel.grid, f); changed(sel); }
#define selcube(x, y, z) blockcube(x, y, z, sel, sel.grid)
////////////// cursor ///////////////
@@ -498,7 +495,6 @@ void changed(const block3 &sel, bool commit = true) {
if(commit) commitchanges();
}
-//////////// copy and undo /////////////
static inline void copycube(const cube &src, cube &dst) {
dst = src;
dst.visible = 0;
@@ -539,119 +535,8 @@ void selgridmap(selinfo &sel, uchar *g) { // generates a map of the cube
loopxyz(sel, -sel.grid, (*g++ = bitscan(lusize), (void)c));
}
-void freeundo(undoblock *u) {
- if(!u->numents) freeblock(u->block(), false);
- delete[] (uchar *)u;
-}
-
-void pasteundoblock(block3 *b, uchar *g) {
- cube *s = b->c();
- loopxyz(*b, 1<<min(int(*g++), worldscale-1), pastecube(*s++, c));
-}
-
-void pasteundo(undoblock *u) {
- if(u->numents) pasteundoents(u);
- else pasteundoblock(u->block(), u->gridmap());
-}
-
-static inline int undosize(undoblock *u) {
- if(u->numents) return u->numents*sizeof(undoent);
- else {
- block3 *b = u->block();
- cube *q = b->c();
- int size = b->size(), total = size;
- loopj(size) total += familysize(*q++)*sizeof(cube);
- return total;
- }
-}
-
-struct undolist {
- undoblock *first, *last;
- undolist() : first(NULL), last(NULL) {}
- bool empty() { return !first; }
- void add(undoblock *u) {
- u->next = NULL;
- u->prev = last;
- if(!first) first = last = u;
- else {
- last->next = u;
- last = u;
- }
- }
- undoblock *popfirst() {
- undoblock *u = first;
- first = first->next;
- if(first) first->prev = NULL;
- else last = NULL;
- return u;
- }
- undoblock *poplast() {
- undoblock *u = last;
- last = last->prev;
- if(last) last->next = NULL;
- else first = NULL;
- return u;
- }
-};
-
-undolist undos, redos;
-VARP(undomegs, 0, 8, 100); // bounded by n megs
-int totalundos = 0;
-
-void pruneundos(int maxremain) { // bound memory {
- while(totalundos > maxremain && !undos.empty()) {
- undoblock *u = undos.popfirst();
- totalundos -= u->size;
- freeundo(u);
- }
- //conoutf(CON_DEBUG, "undo: %d of %d(%%%d)", totalundos, undomegs<<20, totalundos*100/(undomegs<<20));
- while(!redos.empty()) {
- undoblock *u = redos.popfirst();
- totalundos -= u->size;
- freeundo(u);
- }
-}
-
-void clearundos() { pruneundos(0); }
-
-COMMAND(clearundos, "");
-
-undoblock *newundocube(selinfo &s) {
- int ssize = s.size(),
- selgridsize = ssize,
- blocksize = sizeof(block3)+ssize*sizeof(cube);
- if(blocksize <= 0 || blocksize > (undomegs<<20)) return NULL;
- undoblock *u = (undoblock *)new (false) uchar[sizeof(undoblock) + blocksize + selgridsize];
- if(!u) return NULL;
- u->numents = 0;
- block3 *b = u->block();
- blockcopy(s, -s.grid, b);
- uchar *g = u->gridmap();
- selgridmap(s, g);
- return u;
-}
-
-void addundo(undoblock *u) {
- u->size = undosize(u);
- u->timestamp = totalmillis;
- undos.add(u);
- totalundos += u->size;
- pruneundos(undomegs<<20);
-}
-
VARP(nompedit, 0, 1, 1);
-void makeundo(selinfo &s) {
- undoblock *u = newundocube(s);
- if(u) addundo(u);
-}
-
-void makeundo() { // stores state of selected cubes before editing {
- if(lastsel==sel || sel.s.iszero()) return;
- lastsel=sel;
- makeundo(sel);
-}
-
static inline int countblock(cube *c, int n = 8) {
int r = 0;
loopi(n) if(c[i].children) r += countblock(c[i].children); else ++r;
@@ -660,57 +545,6 @@ static inline int countblock(cube *c, int n = 8) {
static int countblock(block3 *b) { return countblock(b->c(), b->size()); }
-void swapundo(undolist &a, undolist &b, int op) {
- if(noedit()) return;
- if(a.empty()) { conoutf(CON_WARN, "nothing more to %s", op == EDIT_REDO ? "redo" : "undo"); return; }
- int ts = a.last->timestamp;
- if(multiplayer(false)) {
- int n = 0, ops = 0;
- for(undoblock *u = a.last; u && ts==u->timestamp; u = u->prev) {
- ++ops;
- n += u->numents ? u->numents : countblock(u->block());
- if(ops > 10 || n > 2500) {
- conoutf(CON_WARN, "undo too big for multiplayer");
- if(nompedit) { multiplayer(); return; }
- op = -1;
- break;
- }
- }
- }
- selinfo l = sel;
- while(!a.empty() && ts==a.last->timestamp) {
- if(op >= 0) game::edittrigger(sel, op);
- undoblock *u = a.poplast(), *r;
- if(u->numents) r = copyundoents(u);
- else {
- block3 *ub = u->block();
- l.o = ub->o;
- l.s = ub->s;
- l.grid = ub->grid;
- l.orient = ub->orient;
- r = newundocube(l);
- }
- if(r) {
- r->size = u->size;
- r->timestamp = totalmillis;
- b.add(r);
- }
- pasteundo(u);
- if(!u->numents) changed(*u->block(), false);
- freeundo(u);
- }
- commitchanges();
- sel = l;
- reorient();
- forcenextundo();
-}
-
-void editundo() { swapundo(undos, redos, EDIT_UNDO); }
-void editredo() { swapundo(redos, undos, EDIT_REDO); }
-
-// guard against subdivision
-#define protectsel(f) { undoblock *_u = newundocube(sel); f; if(_u) { pasteundo(_u); freeundo(_u); } }
-
vector<editinfo *> editinfos;
editinfo *localedit = NULL;
@@ -900,138 +734,6 @@ void freeeditinfo(editinfo *&e) {
e = NULL;
}
-bool packundo(undoblock *u, int &inlen, uchar *&outbuf, int &outlen) {
- vector<uchar> buf;
- buf.reserve(512);
- *(ushort *)buf.pad(2) = lilswap(ushort(u->numents));
- if(u->numents) {
- undoent *ue = u->ents();
- loopi(u->numents) {
- *(ushort *)buf.pad(2) = lilswap(ushort(ue[i].i));
- entity &e = *(entity *)buf.pad(sizeof(entity));
- e = ue[i].e;
- lilswap(&e.o.x, 3);
- lilswap(&e.attr1, 5);
- }
- }
- else {
- block3 &b = *u->block();
- if(!packblock(b, buf)) return false;
- buf.put(u->gridmap(), b.size());
- packvslots(b, buf);
- }
- inlen = buf.length();
- return compresseditinfo(buf.getbuf(), buf.length(), outbuf, outlen);
-}
-
-bool unpackundo(const uchar *inbuf, int inlen, int outlen) {
- uchar *outbuf = NULL;
- if(!uncompresseditinfo(inbuf, inlen, outbuf, outlen)) return false;
- ucharbuf buf(outbuf, outlen);
- if(buf.remaining() < 2) {
- delete[] outbuf;
- return false;
- }
- int numents = lilswap(*(const ushort *)buf.pad(2));
- if(numents) {
- if(buf.remaining() < numents*int(2 + sizeof(entity))) {
- delete[] outbuf;
- return false;
- }
- loopi(numents) {
- int idx = lilswap(*(const ushort *)buf.pad(2));
- entity &e = *(entity *)buf.pad(sizeof(entity));
- lilswap(&e.o.x, 3);
- lilswap(&e.attr1, 5);
- pasteundoent(idx, e);
- }
- }
- else {
- block3 *b = NULL;
- if(!unpackblock(b, buf) || b->grid >= worldsize || buf.remaining() < b->size()) {
- freeblock(b);
- delete[] outbuf;
- return false;
- }
- uchar *g = buf.pad(b->size());
- unpackvslots(*b, buf);
- pasteundoblock(b, g);
- changed(*b, false);
- freeblock(b);
- }
- delete[] outbuf;
- commitchanges();
- return true;
-}
-
-bool packundo(int op, int &inlen, uchar *&outbuf, int &outlen) {
- switch(op) {
- case EDIT_UNDO: return !undos.empty() && packundo(undos.last, inlen, outbuf, outlen);
- case EDIT_REDO: return !redos.empty() && packundo(redos.last, inlen, outbuf, outlen);
- default: return false;
- }
-}
-
-struct prefabheader {
- char magic[4];
- int version;
-};
-
-struct prefab : editinfo {
- char *name;
- GLuint ebo, vbo;
- int numtris, numverts;
- prefab() : name(NULL), ebo(0), vbo(0), numtris(0), numverts(0) {}
- ~prefab() { DELETEA(name); if(copy) freeblock(copy); }
- void cleanup() {
- if(ebo) { glDeleteBuffers_(1, &ebo); ebo = 0; }
- if(vbo) { glDeleteBuffers_(1, &vbo); vbo = 0; }
- numtris = numverts = 0;
- }
-};
-
-static hashnameset<prefab> prefabs;
-
-void cleanupprefabs() {
- enumerate(prefabs, prefab, p, p.cleanup());
-}
-
-void delprefab(char *name) {
- prefab *p = prefabs.access(name);
- if(p) {
- p->cleanup();
- prefabs.remove(name);
- conoutf("deleted prefab %s", name);
- }
-}
-COMMAND(delprefab, "s");
-
-void saveprefab(char *name) {
- if(!name[0] || noedit(true) || (nompedit && multiplayer())) return;
- prefab *b = prefabs.access(name);
- if(!b) {
- b = &prefabs[name];
- b->name = newstring(name);
- }
- if(b->copy) freeblock(b->copy);
- protectsel(b->copy = blockcopy(block3(sel), sel.grid));
- changed(sel);
- defformatstring(filename, strpbrk(name, "/\\") ? "packages/%s.obr" : "packages/prefab/%s.obr", name);
- path(filename);
- stream *f = opengzfile(filename, "wb");
- if(!f) { conoutf(CON_ERROR, "could not write prefab to %s", filename); return; }
- prefabheader hdr;
- memcpy(hdr.magic, "OEBR", 4);
- hdr.version = 0;
- lilswap(&hdr.version, 1);
- f->write(&hdr, sizeof(hdr));
- streambuf<uchar> s(f);
- if(!packblock(*b->copy, s)) { delete f; conoutf(CON_ERROR, "could not pack prefab %s", filename); return; }
- delete f;
- conoutf("wrote prefab file %s", filename);
-}
-COMMAND(saveprefab, "s");
-
void pasteblock(block3 &b, selinfo &sel, bool local) {
sel.s = b.s;
int o = sel.orient;
@@ -1041,211 +743,13 @@ void pasteblock(block3 &b, selinfo &sel, bool local) {
sel.orient = o;
}
-bool prefabloaded(const char *name) {
- return prefabs.access(name) != NULL;
-}
-
-prefab *loadprefab(const char *name, bool msg = true) {
- prefab *b = prefabs.access(name);
- if(b) return b;
-
- defformatstring(filename, strpbrk(name, "/\\") ? "packages/%s.obr" : "packages/prefab/%s.obr", name);
- path(filename);
- stream *f = opengzfile(filename, "rb");
- if(!f) { if(msg) conoutf(CON_ERROR, "could not read prefab %s", filename); return NULL; }
- prefabheader hdr;
- if(f->read(&hdr, sizeof(hdr)) != sizeof(prefabheader) || memcmp(hdr.magic, "OEBR", 4)) { delete f; if(msg) conoutf(CON_ERROR, "prefab %s has malformatted header", filename); return NULL; }
- lilswap(&hdr.version, 1);
- if(hdr.version != 0) { delete f; if(msg) conoutf(CON_ERROR, "prefab %s uses unsupported version", filename); return NULL; }
- streambuf<uchar> s(f);
- block3 *copy = NULL;
- if(!unpackblock(copy, s)) { delete f; if(msg) conoutf(CON_ERROR, "could not unpack prefab %s", filename); return NULL; }
- delete f;
-
- b = &prefabs[name];
- b->name = newstring(name);
- b->copy = copy;
-
- return b;
-}
-
-void pasteprefab(char *name) {
- if(!name[0] || noedit() || (nompedit && multiplayer())) return;
- prefab *b = loadprefab(name, true);
- if(b) pasteblock(*b->copy, sel, true);
-}
-COMMAND(pasteprefab, "s");
-
-struct prefabmesh {
- struct vertex { vec pos; bvec4 norm; };
- static const int SIZE = 1<<9;
- int table[SIZE];
- vector<vertex> verts;
- vector<int> chain;
- vector<ushort> tris;
- prefabmesh() { memset(table, -1, sizeof(table)); }
- int addvert(const vertex &v) {
- uint h = hthash(v.pos)&(SIZE-1);
- for(int i = table[h]; i>=0; i = chain[i]) {
- const vertex &c = verts[i];
- if(c.pos==v.pos && c.norm==v.norm) return i;
- }
- if(verts.length() >= USHRT_MAX) return -1;
- verts.add(v);
- chain.add(table[h]);
- return table[h] = verts.length()-1;
- }
- int addvert(const vec &pos, const bvec &norm) {
- vertex vtx;
- vtx.pos = pos;
- vtx.norm = norm;
- return addvert(vtx);
- }
- void setup(prefab &p) {
- if(tris.empty()) return;
- p.cleanup();
- loopv(verts) verts[i].norm.flip();
- if(!p.vbo) glGenBuffers_(1, &p.vbo);
- gle::bindvbo(p.vbo);
- glBufferData_(GL_ARRAY_BUFFER, verts.length()*sizeof(vertex), verts.getbuf(), GL_STATIC_DRAW);
- gle::clearvbo();
- p.numverts = verts.length();
- if(!p.ebo) glGenBuffers_(1, &p.ebo);
- gle::bindebo(p.ebo);
- glBufferData_(GL_ELEMENT_ARRAY_BUFFER, tris.length()*sizeof(ushort), tris.getbuf(), GL_STATIC_DRAW);
- gle::clearebo();
- p.numtris = tris.length()/3;
- }
-
-};
-
-static void genprefabmesh(prefabmesh &r, cube &c, const ivec &co, int size) {
- if(c.children) {
- neighbourstack[++neighbourdepth] = c.children;
- loopi(8) {
- ivec o(i, co, size/2);
- genprefabmesh(r, c.children[i], o, size/2);
- }
- --neighbourdepth;
- }
- else if(!isempty(c)) {
- int vis;
- loopi(6) if((vis = visibletris(c, i, co, size))) {
- ivec v[4];
- genfaceverts(c, i, v);
- int convex = 0;
- if(!flataxisface(c, i)) convex = faceconvexity(v);
- int order = vis&4 || convex < 0 ? 1 : 0, numverts = 0;
- vec vo(co), pos[4], norm[4];
- pos[numverts++] = vec(v[order]).mul(size/8.0f).add(vo);
- if(vis&1) pos[numverts++] = vec(v[order+1]).mul(size/8.0f).add(vo);
- pos[numverts++] = vec(v[order+2]).mul(size/8.0f).add(vo);
- if(vis&2) pos[numverts++] = vec(v[(order+3)&3]).mul(size/8.0f).add(vo);
- guessnormals(pos, numverts, norm);
- int index[4];
- loopj(numverts) index[j] = r.addvert(pos[j], bvec(norm[j]));
- loopj(numverts-2) if(index[0]!=index[j+1] && index[j+1]!=index[j+2] && index[j+2]!=index[0]) {
- r.tris.add(index[0]);
- r.tris.add(index[j+1]);
- r.tris.add(index[j+2]);
- }
- }
- }
-}
-
-void genprefabmesh(prefab &p) {
- block3 b = *p.copy;
- b.o = ivec(0, 0, 0);
- cube *oldworldroot = worldroot;
- int oldworldscale = worldscale, oldworldsize = worldsize;
- worldroot = newcubes();
- worldscale = 1;
- worldsize = 2;
- while(worldsize < max(max(b.s.x, b.s.y), b.s.z)*b.grid) {
- worldscale++;
- worldsize *= 2;
- }
- cube *s = p.copy->c();
- loopxyz(b, b.grid, if(!isempty(*s) || s->children) pastecube(*s, c); s++);
- prefabmesh r;
- neighbourstack[++neighbourdepth] = worldroot;
- loopi(8) genprefabmesh(r, worldroot[i], ivec(i, ivec(0, 0, 0), worldsize/2), worldsize/2);
- --neighbourdepth;
- r.setup(p);
- freeocta(worldroot);
- worldroot = oldworldroot;
- worldscale = oldworldscale;
- worldsize = oldworldsize;
- useshaderbyname("prefab");
-}
-
extern int outlinecolour;
-static void renderprefab(prefab &p, const vec &o, float yaw, float pitch, float roll, float size, const vec &color) {
- if(!p.numtris) {
- genprefabmesh(p);
- if(!p.numtris) return;
- }
- block3 &b = *p.copy;
- matrix4 m;
- m.identity();
- m.settranslation(o);
- if(yaw) m.rotate_around_z(yaw*RAD);
- if(pitch) m.rotate_around_x(pitch*RAD);
- if(roll) m.rotate_around_y(-roll*RAD);
- matrix3 w(m);
- if(size > 0 && size != 1) m.scale(size);
- m.translate(vec(b.s).mul(-b.grid*0.5f));
- gle::bindvbo(p.vbo);
- gle::bindebo(p.ebo);
- gle::enablevertex();
- gle::enablenormal();
- prefabmesh::vertex *v = (prefabmesh::vertex *)0;
- gle::vertexpointer(sizeof(prefabmesh::vertex), v->pos.v);
- gle::normalpointer(sizeof(prefabmesh::vertex), v->norm.v, GL_BYTE);
- matrix4 pm;
- pm.mul(camprojmatrix, m);
- GLOBALPARAM(prefabmatrix, pm);
- GLOBALPARAM(prefabworld, w);
- SETSHADER(prefab);
- gle::color(color);
- glDrawRangeElements_(GL_TRIANGLES, 0, p.numverts-1, p.numtris*3, GL_UNSIGNED_SHORT, (ushort *)0);
- glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
- enablepolygonoffset(GL_POLYGON_OFFSET_LINE);
- pm.mul(camprojmatrix, m);
- GLOBALPARAM(prefabmatrix, pm);
- SETSHADER(prefab);
- gle::color(vec::hexcolor(outlinecolour));
- glDrawRangeElements_(GL_TRIANGLES, 0, p.numverts-1, p.numtris*3, GL_UNSIGNED_SHORT, (ushort *)0);
- disablepolygonoffset(GL_POLYGON_OFFSET_LINE);
- glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
- gle::disablevertex();
- gle::disablenormal();
- gle::clearebo();
- gle::clearvbo();
-}
-
-void renderprefab(const char *name, const vec &o, float yaw, float pitch, float roll, float size, const vec &color) {
- prefab *p = loadprefab(name, false);
- if(p) renderprefab(*p, o, yaw, pitch, roll, size, color);
-}
-
-void previewprefab(const char *name, const vec &color) {
- prefab *p = loadprefab(name, false);
- if(p) {
- block3 &b = *p->copy;
- float yaw;
- vec o = calcmodelpreviewpos(vec(b.s).mul(b.grid*0.5f), yaw);
- renderprefab(*p, o, yaw, 0, 0, 1, color);
- }
-}
-
void mpcopy(editinfo *&e, selinfo &sel, bool local) {
if(local) game::edittrigger(sel, EDIT_COPY);
if(e==NULL) e = editinfos.add(new editinfo);
if(e->copy) freeblock(e->copy);
e->copy = NULL;
- protectsel(e->copy = blockcopy(block3(sel), sel.grid));
changed(sel);
}
@@ -1275,8 +779,6 @@ void paste() {
COMMAND(copy, "");
COMMAND(pastehilite, "");
COMMAND(paste, "");
-COMMANDN(undo, editundo, "");
-COMMANDN(redo, editredo, "");
static vector<int *> editingvslots;
struct vslotref {
@@ -1292,12 +794,6 @@ void compacteditvslots() {
editinfo *e = editinfos[i];
compactvslots(e->copy->c(), e->copy->size());
}
- for(undoblock *u = undos.first; u; u = u->next)
- if(!u->numents)
- compactvslots(u->block()->c(), u->block()->size());
- for(undoblock *u = redos.first; u; u = u->next)
- if(!u->numents)
- compactvslots(u->block()->c(), u->block()->size());
}
///////////// main cube edit ////////////////
@@ -1895,7 +1391,6 @@ void rotatecube(cube &c, int d) { // rotates cube clockwise. see pics in cvs f
void mpflip(selinfo &sel, bool local) {
if(local) {
game::edittrigger(sel, EDIT_FLIP);
- makeundo();
}
int zs = sel.s[dimension(sel.orient)];
loopxy(sel) {
@@ -1920,7 +1415,6 @@ void mprotate(int cw, selinfo &sel, bool local) {
if(!dimcoord(sel.orient)) cw = -cw;
int m = sel.s[C[d]] < sel.s[R[d]] ? C[d] : R[d];
int ss = sel.s[m] = max(sel.s[R[d]], sel.s[C[d]]);
- if(local) makeundo();
loop(z,sel.s[D[d]]) loopi(cw>0 ? 1 : 3) {
loopxy(sel) rotatecube(selcube(x,y,z), d);
loop(y,ss/2) loop(x,ss-1-y*2) rotatequad
diff --git a/src/engine/world.cpp b/src/engine/world.cpp
index f58886f..cbe3fad 100644
--- a/src/engine/world.cpp
+++ b/src/engine/world.cpp
@@ -226,7 +226,6 @@ extern selinfo sel;
extern bool havesel;
int entlooplevel = 0;
int efocus = -1, enthover = -1, entorient = -1, oldhover = -1;
-bool undonext = true;
VARF(entediting, 0, 0, 1, { if(!entediting) { entcancel(); efocus = enthover = -1; } });
@@ -255,36 +254,13 @@ void entcancel() {
}
void entadd(int 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;
-}
-
-void makeundoent() {
- if(!undonext) return;
- undonext = false;
- oldhover = enthover;
- undoblock *u = newundoent();
- if(u) addundo(u);
-}
-
// 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; }
+#define addimplicit(f) { if(entgroup.empty() && enthover>=0) { entadd(enthover); f; entgroup.drop(); } else f; }
#define entfocusv(i, f, v){ int n = efocus = (i); if(n>=0) { extentity &e = *v[n]; f; (void) e; } }
#define entfocus(i, f) entfocusv(i, f, entities::getents())
#define enteditv(i, f, v) { entfocusv(i, { int a = 0; (void) a; }, v); }
@@ -293,8 +269,7 @@ void makeundoent() {
#define setgroup(exp) { entcancel(); addgroup(exp); }
#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(groupeditpure(f)); }
vec getselpos() {
vector<extentity *> &ents = entities::getents();
@@ -303,36 +278,11 @@ vec getselpos() {
return vec(sel.o);
}
-undoblock *copyundoents(undoblock *u) {
- 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;
-}
-
-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);
-}
-
-void pasteundoents(undoblock *u) {
- 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);
+ groupeditpure(e.o[d] -= (e.o[d]-mid)*2);
}
void entrotate(int *cw) {
@@ -341,7 +291,7 @@ void entrotate(int *cw) {
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(
+ groupeditpure(
e.o[dd] -= (e.o[dd]-mid)*2;
e.o.sub(s);
swap(e.o[R[d]], e.o[C[d]]);
@@ -401,7 +351,6 @@ void entdrag(const vec &ray) {
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;
}
@@ -550,7 +499,6 @@ void renderentselection(const vec &o, bool entmoving) {
}
bool enttoggle(int id) {
- undonext = true;
int i = entgroup.find(id);
if(i < 0)
entadd(id);
@@ -738,7 +686,6 @@ void newentity(int type, int a1, int a2, int a3, int a4, int a5) {
dropentity(*t);
t->type = ET_EMPTY;
enttoggle(idx);
- makeundoent();
entedit(idx, e.type = type);
}
@@ -777,7 +724,6 @@ void entpaste() {
}
keepents = 0;
int j = 0;
- groupeditundo(e.type = entcopybuf[j++].type;);
}
COMMAND(newent, "siiiii");
@@ -941,7 +887,6 @@ void resetmap() {
cleardecals();
clearsleep();
cancelsel();
- pruneundos();
clearmapcrc();
entities::clearents();
outsideents.setsize(0);