header file for world

master
Daniel Kolesa 2020-04-28 04:02:15 +02:00
parent 376dfcd550
commit e58ef89426
16 changed files with 184 additions and 187 deletions

View File

@ -6,7 +6,6 @@
#ifndef STANDALONE
#include "octa.hh"
#include "light.hh"
#include "texture.hh"
#include "bih.hh"
@ -30,8 +29,6 @@ extern bool inbetweenframes, renderedframe;
extern SDL_Window *screen;
extern int screenw, screenh, renderw, renderh, hudw, hudh;
extern vector<int> entgroup;
// rendertext
struct font
{
@ -364,13 +361,6 @@ extern bool useavatarmask();
extern void enableavatarmask();
extern void disableavatarmask();
// 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);
@ -604,19 +594,6 @@ extern bool overlapsdynent(const vec &o, float radius);
extern void rotatebb(vec &center, vec &radius, int yaw, int pitch, int roll = 0);
extern float shadowray(const vec &o, const vec &ray, float radius, int mode, extentity *t = NULL);
// world
extern vector<int> outsideents;
extern void entcancel();
extern void entitiesinoctanodes();
extern void attachentities();
extern void freeoctaentities(cube &c);
extern bool pointinsel(const selinfo &sel, const vec &o);
extern void resetmap();
extern void startmap(const char *name);
// rendermodel
struct mapmodelinfo { string name; model *m, *collide; };

View File

@ -1,6 +1,7 @@
// main.cpp: initialisation & main loop
#include "blend.hh"
#include "world.hh"
#include "engine.hh"

View File

@ -1,5 +1,7 @@
// core world management routines
#include "world.hh"
#include "engine.hh"
static struct emptycube : cube

View File

@ -1,3 +1,6 @@
#ifndef ENGINE_OCTA_HH
#define ENGINE_OCTA_HH
// 6-directional octree heightfield map format
struct elementset
@ -335,3 +338,4 @@ enum
GENFACEVERTSXY(x0,x1, y0,y1, z0,z1, c0,c1, r0,r1, d0,d1) \
GENFACEVERTSZ(x0,x1, y0,y1, z0,z1, c0,c1, r0,r1, d0,d1)
#endif

View File

@ -1,4 +1,5 @@
#include "blend.hh"
#include "world.hh"
#include "engine.hh"
@ -346,9 +347,6 @@ bool editmoveplane(const vec &o, const vec &ray, int d, float off, vec &handle,
}
namespace hmap { inline bool isheightmap(int orient, int d, bool empty, cube *c); }
extern void entdrag(const vec &ray);
extern bool hoveringonent(int ent, int orient);
extern void renderentselection(const vec &o, const vec &ray, bool entmoving);
extern float rayent(const vec &o, const vec &ray, float radius, int mode, int size, int &orient, int &ent);
VAR(gridlookup, 0, 0, 1);

View File

@ -1,6 +1,7 @@
// octarender.cpp: fill vertex arrays with different cube surfaces.
#include "blend.hh"
#include "world.hh"
#include "engine.hh"

View File

@ -3,6 +3,8 @@
// they "felt right", and have no basis in reality. Collision detection is simplistic but
// very robust (uses discrete steps at fixed fps).
#include "world.hh"
#include "engine.hh"
#include "mpr.hh"
@ -124,7 +126,6 @@ static inline bool raycubeintersect(const clipplanes &p, const cube &c, const ve
return true;
}
extern void entselectionbox(const entity &e, vec &eo, vec &es);
float hitentdist;
int hitent, hitorient;

View File

@ -1,4 +1,5 @@
#include "aa.hh"
#include "world.hh"
#include "engine.hh"

View File

@ -1,5 +1,7 @@
// renderparticles.cpp
#include "world.hh"
#include "engine.hh"
Shader *particleshader = NULL, *particlenotextureshader = NULL, *particlesoftshader = NULL, *particletextshader = NULL;
@ -1429,13 +1431,13 @@ void updateparticles()
loopv(entgroup)
{
entity &e = *ents[entgroup[i]];
particle_textcopy(e.o, entname(e), PART_TEXT, 1, 0xFF4B19, 2.0f);
particle_textcopy(e.o, entities::entname(e.type), PART_TEXT, 1, 0xFF4B19, 2.0f);
}
loopv(ents)
{
entity &e = *ents[i];
if(e.type==ET_EMPTY) continue;
particle_textcopy(e.o, entname(e), PART_TEXT, 1, 0x1EC850, 2.0f);
particle_textcopy(e.o, entities::entname(e.type), PART_TEXT, 1, 0x1EC850, 2.0f);
regular_particle_splash(PART_EDIT, 2, 40, e.o, 0x3232FF, 0.32f*particlesize/100.0f);
}
}

View File

@ -2,10 +2,10 @@
#include "blend.hh"
#include "worldio.hh"
#include "world.hh"
#include "engine.hh"
VARR(mapversion, 1, MAPVERSION, 0);
VARNR(mapscale, worldscale, 1, 0, 0);
VARNR(mapsize, worldsize, 1, 0, 0);
SVARR(maptitle, "Untitled Map by Unknown");
@ -40,7 +40,7 @@ static inline void decalboundbox(const entity &e, DecalSlot &s, vec &center, vec
rotatebb(center, radius, e.attr2, e.attr3, e.attr4);
}
bool getentboundingbox(const extentity &e, ivec &o, ivec &r)
static bool getentboundingbox(const extentity &e, ivec &o, ivec &r)
{
switch(e.type)
{
@ -84,7 +84,7 @@ enum
MODOE_CHANGED = 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)
static 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)
{
@ -299,6 +299,7 @@ static inline void findents(cube *c, const ivec &o, int size, const ivec &bo, co
}
}
#if 0
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);
@ -322,19 +323,7 @@ void findents(int low, int high, bool notspawned, const vec &pos, const vec &rad
}
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;
}
#endif
extern selinfo sel;
extern bool havesel;
@ -344,7 +333,7 @@ bool undonext = true;
VARF(entediting, 0, 0, 1, { if(!entediting) { entcancel(); efocus = enthover = -1; } });
bool noentedit()
static bool noentedit()
{
if(!editmode) { conoutf(CON_ERROR, "operation only allowed in edit mode"); return true; }
return !entediting;
@ -372,13 +361,13 @@ void entcancel()
entgroup.shrink(0);
}
void entadd(int id)
static void entadd(int id)
{
undonext = true;
entgroup.add(id);
}
undoblock *newundoent()
static undoblock *newundoent()
{
int numents = entgroup.length();
if(numents <= 0) return NULL;
@ -394,7 +383,7 @@ undoblock *newundoent()
return u;
}
void makeundoent()
static void makeundoent()
{
if(!undonext) return;
undonext = false;
@ -403,7 +392,7 @@ void makeundoent()
if(u) addundo(u);
}
void detachentity(extentity &e)
static void detachentity(extentity &e)
{
if(!e.attached) return;
e.attached->attached = NULL;
@ -412,7 +401,7 @@ void detachentity(extentity &e)
VAR(attachradius, 1, 100, 1000);
void attachentity(extentity &e)
static void attachentity(extentity &e)
{
switch(e.type)
{
@ -523,7 +512,7 @@ void pasteundoents(undoblock *u)
loopi(u->numents) pasteundoent(ue[i].i, ue[i].e);
}
void entflip()
static void entflip()
{
if(noentedit()) return;
int d = dimension(sel.orient);
@ -531,7 +520,7 @@ void entflip()
groupeditundo(e.o[d] -= (e.o[d]-mid)*2);
}
void entrotate(int *cw)
static void entrotate(int *cw)
{
if(noentedit()) return;
int d = dimension(sel.orient);
@ -623,7 +612,7 @@ void entdrag(const vec &ray)
VAR(showentradius, 0, 1, 1);
void renderentring(const extentity &e, float radius, int axis)
static void renderentring(const extentity &e, float radius, int axis)
{
if(radius <= 0) return;
gle::defvertex();
@ -639,13 +628,13 @@ void renderentring(const extentity &e, float radius, int axis)
xtraverts += gle::end();
}
void renderentsphere(const extentity &e, float radius)
static void renderentsphere(const extentity &e, float radius)
{
if(radius <= 0) return;
loopk(3) renderentring(e, radius, k);
}
void renderentattachment(const extentity &e)
static void renderentattachment(const extentity &e)
{
if(!e.attached) return;
gle::defvertex();
@ -655,7 +644,7 @@ void renderentattachment(const extentity &e)
xtraverts += gle::end();
}
void renderentarrow(const extentity &e, const vec &dir, float radius)
static void renderentarrow(const extentity &e, const vec &dir, float radius)
{
if(radius <= 0) return;
float arrowsize = min(radius/8, 0.5f);
@ -677,7 +666,7 @@ void renderentarrow(const extentity &e, const vec &dir, float radius)
xtraverts += gle::end();
}
void renderentcone(const extentity &e, const vec &dir, float radius, float angle)
static 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;
@ -700,7 +689,7 @@ void renderentcone(const extentity &e, const vec &dir, float radius, float angle
xtraverts += gle::end();
}
void renderentbox(const extentity &e, const vec &center, const vec &radius, int yaw, int pitch, int roll)
static void renderentbox(const extentity &e, const vec &center, const vec &radius, int yaw, int pitch, int roll)
{
matrix4x3 orient;
orient.identity();
@ -741,7 +730,7 @@ void renderentbox(const extentity &e, const vec &center, const vec &radius, int
xtraverts += gle::end();
}
void renderentradius(extentity &e, bool color)
static void renderentradius(extentity &e, bool color)
{
switch(e.type)
{
@ -886,7 +875,7 @@ void renderentselection(const vec &o, const vec &ray, bool entmoving)
}
}
bool enttoggle(int id)
static bool enttoggle(int id)
{
undonext = true;
int i = entgroup.find(id);
@ -939,7 +928,7 @@ ICOMMAND(entmoving, "b", (int *n),
intret(entmoving);
});
void entpush(int *dir)
static void entpush(int *dir)
{
if(noentedit()) return;
int d = dimension(entorient);
@ -958,7 +947,7 @@ void entpush(int *dir)
}
VAR(entautoviewdist, 0, 25, 100);
void entautoview(int *dir)
static void entautoview(int *dir)
{
if(!haveselent()) return;
static int s = 0;
@ -981,14 +970,14 @@ COMMAND(entflip, "");
COMMAND(entrotate, "i");
COMMAND(entpush, "i");
void delent()
static void delent()
{
if(noentedit()) return;
groupedit(e.type = ET_EMPTY;);
entcancel();
}
int findtype(char *what)
static 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);
@ -997,7 +986,7 @@ int findtype(char *what)
VAR(entdrop, 0, 2, 3);
bool dropentity(entity &e, int drop = -1)
static bool dropentity(entity &e, int drop = -1)
{
vec radius(4.0f, 4.0f, 4.0f);
if(drop<0) drop = entdrop;
@ -1043,13 +1032,13 @@ bool dropentity(entity &e, int drop = -1)
return true;
}
void dropent()
static void dropent()
{
if(noentedit()) return;
groupedit(dropentity(e));
}
void attachent()
static void attachent()
{
if(noentedit()) return;
groupedit(attachentity(e));
@ -1059,7 +1048,7 @@ COMMAND(attachent, "");
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, bool fix = true)
static extentity *newentity(bool local, const vec &o, int type, int v1, int v2, int v3, int v4, int v5, int &idx, bool fix = true)
{
vector<extentity *> &ents = entities::getents();
if(local)
@ -1108,7 +1097,7 @@ extentity *newentity(bool local, const vec &o, int type, int v1, int v2, int v3,
return &e;
}
void newentity(int type, int a1, int a2, int a3, int a4, int a5, bool fix = true)
static void newentity(int type, int a1, int a2, int a3, int a4, int a5, bool fix = true)
{
int idx;
extentity *t = newentity(true, player->o, type, a1, a2, a3, a4, a5, idx, fix);
@ -1121,7 +1110,7 @@ void newentity(int type, int a1, int a2, int a3, int a4, int a5, bool fix = true
commitchanges();
}
void newent(char *what, int *a1, int *a2, int *a3, int *a4, int *a5)
static void newent(char *what, int *a1, int *a2, int *a3, int *a4, int *a5)
{
if(noentedit()) return;
int type = findtype(what);
@ -1129,10 +1118,10 @@ void newent(char *what, int *a1, int *a2, int *a3, int *a4, int *a5)
newentity(type, *a1, *a2, *a3, *a4, *a5);
}
int entcopygrid;
vector<entity> entcopybuf;
static int entcopygrid;
static vector<entity> entcopybuf;
void entcopy()
static void entcopy()
{
if(noentedit()) return;
entcopygrid = sel.grid;
@ -1142,7 +1131,7 @@ void entcopy()
});
}
void entpaste()
static void entpaste()
{
if(noentedit() || entcopybuf.empty()) return;
entcancel();
@ -1162,7 +1151,7 @@ void entpaste()
groupeditundo(e.type = entcopybuf[j++].type;);
}
void entreplace()
static void entreplace()
{
if(noentedit() || entcopybuf.empty()) return;
const entity &c = entcopybuf[0];
@ -1190,7 +1179,7 @@ COMMAND(entcopy, "");
COMMAND(entpaste, "");
COMMAND(entreplace, "");
void entset(char *what, int *a1, int *a2, int *a3, int *a4, int *a5)
static void entset(char *what, int *a1, int *a2, int *a3, int *a4, int *a5)
{
if(noentedit()) return;
int type = findtype(what);
@ -1203,7 +1192,7 @@ void entset(char *what, int *a1, int *a2, int *a3, int *a4, int *a5)
e.attr5=*a5);
}
void printent(extentity &e, char *buf, int len)
static void printent(extentity &e, char *buf, int len)
{
switch(e.type)
{
@ -1218,7 +1207,7 @@ void printent(extentity &e, char *buf, int len)
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()
static void nearestent()
{
if(noentedit()) return;
int closest = -1;
@ -1247,7 +1236,7 @@ ICOMMAND(entindex, "", (), intret(efocus));
COMMAND(entset, "siiiii");
COMMAND(nearestent, "");
void enttype(char *type, int *numargs)
static void enttype(char *type, int *numargs)
{
if(*numargs >= 1)
{
@ -1260,7 +1249,7 @@ void enttype(char *type, int *numargs)
})
}
void entattr(int *attr, int *val, int *numargs)
static void entattr(int *attr, int *val, int *numargs)
{
if(*numargs >= 2)
{
@ -1292,7 +1281,7 @@ void entattr(int *attr, int *val, int *numargs)
COMMAND(enttype, "sN");
COMMAND(entattr, "iiN");
void splitocta(cube *c, int size)
static void splitocta(cube *c, int size)
{
if(size <= 0x1000) return;
loopi(8)
@ -1400,7 +1389,7 @@ static bool isallempty(cube &c)
return true;
}
void shrinkmap()
static void shrinkmap()
{
extern int nompedit;
if(noedit(true) || (nompedit && multiplayer())) return;
@ -1435,40 +1424,10 @@ void shrinkmap()
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)); }
void mapenlarge() { if(enlargemap(false)) game::newmap(-1); }
static void newmap(int *i) { bool force = !isconnected(); if(force) game::forceedit(""); if(emptymap(*i, force, NULL)) game::newmap(max(*i, 0)); }
static void mapenlarge() { if(enlargemap(false)) game::newmap(-1); }
COMMAND(newmap, "i");
COMMAND(mapenlarge, "");
COMMAND(shrinkmap, "");
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;
addentityedit(i);
attachentity(*e);
}
else
{
extentity &e = *ents[i];
removeentityedit(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;
addentityedit(i);
if(oldtype!=type) attachentity(e);
}
entities::editent(i, local);
clearshadowcache();
commitchanges();
}
int getworldsize() { return worldsize; }
int getmapversion() { return mapversion; }

View File

@ -1,3 +1,12 @@
#ifndef ENGINE_WORLD_HH
#define ENGINE_WORLD_HH
#include <shared/tools.hh>
#include <shared/geom.hh>
#include <shared/ents.hh>
/* FIXME: move these defines/enums */
enum // hardcoded texture numbers
{
@ -6,37 +15,6 @@ enum // hardcoded texture numbers
NUMDEFAULTSLOTS
};
#define OCTAVERSION 33
struct octaheader
{
char magic[4]; // "OCTA"
int version; // any >8bit quantity is little endian
int headersize; // sizeof(header)
int worldsize;
int numents;
int numpvs;
int lightmaps;
int blendmap;
int numvars;
int numvslots;
};
#define MAPVERSION 1 // bump if map format changes, see worldio.cpp
struct mapheader
{
char magic[4]; // "TMAP"
int version; // any >8bit quantity is little endian
int headersize; // sizeof(header)
int worldsize;
int numents;
int numpvs;
int blendmap;
int numvars;
int numvslots;
};
#define WATER_AMPLITUDE 0.4f
#define WATER_OFFSET 1.1f
@ -51,3 +29,69 @@ enum
struct vertex { vec pos; bvec4 norm; vec tc; bvec4 tangent; };
struct selinfo
{
int corner;
int cx, cxs, cy, cys;
ivec o, s;
int grid, orient;
selinfo() : corner(0), cx(0), cxs(0), cy(0), cys(0), o(0, 0, 0), s(0, 0, 0), grid(8), orient(0) {}
int size() const { return s.x*s.y*s.z; }
int us(int d) const { return s[d]*grid; }
bool operator==(const selinfo &sel) const { return o==sel.o && s==sel.s && grid==sel.grid && orient==sel.orient; }
bool validate()
{
extern int worldsize;
if(grid <= 0 || grid >= worldsize) return false;
if(o.x >= worldsize || o.y >= worldsize || o.z >= worldsize) return false;
if(o.x < 0) { s.x -= (grid - 1 - o.x)/grid; o.x = 0; }
if(o.y < 0) { s.y -= (grid - 1 - o.y)/grid; o.y = 0; }
if(o.z < 0) { s.z -= (grid - 1 - o.z)/grid; o.z = 0; }
s.x = clamp(s.x, 0, (worldsize - o.x)/grid);
s.y = clamp(s.y, 0, (worldsize - o.y)/grid);
s.z = clamp(s.z, 0, (worldsize - o.z)/grid);
return s.x > 0 && s.y > 0 && s.z > 0;
}
};
#include "octa.hh"
extern vector<int> outsideents;
extern vector<int> entgroup;
extern int spotlights;
extern int volumetriclights;
extern int nospeclights;
void freeoctaentities(cube &c);
void entitiesinoctanodes();
bool pointinsel(const selinfo &sel, const vec &o);
bool haveselent();
void entcancel();
void attachentities();
vec getselpos();
undoblock *copyundoents(undoblock *u);
void pasteundoent(int idx, const entity &ue);
void pasteundoents(undoblock *u);
void entselectionbox(const entity &e, vec &eo, vec &es);
void entdrag(const vec &ray);
void renderentselection(const vec &o, const vec &ray, bool entmoving);
bool hoveringonent(int ent, int orient);
void resetmap();
void startmap(const char *name);
bool emptymap(int factor, bool force, const char *mname = "", bool usecfg = true);
bool enlargemap(bool force);
int getworldsize();
#endif

View File

@ -1,10 +1,44 @@
// worldio.cpp: loading & saving of maps and savegames
#include "blend.hh"
#include "world.hh"
#include "worldio.hh"
#include "engine.hh"
#define OCTAVERSION 33
struct octaheader
{
char magic[4]; // "OCTA"
int version; // any >8bit quantity is little endian
int headersize; // sizeof(header)
int worldsize;
int numents;
int numpvs;
int lightmaps;
int blendmap;
int numvars;
int numvslots;
};
#define MAPVERSION 1 // bump if map format changes, see worldio.cpp
struct mapheader
{
char magic[4]; // "TMAP"
int version; // any >8bit quantity is little endian
int headersize; // sizeof(header)
int worldsize;
int numents;
int numpvs;
int blendmap;
int numvars;
int numvslots;
};
VARR(mapversion, 1, MAPVERSION, 0);
static void validmapname(char *dst, const char *src, const char *prefix = NULL, const char *alt = "untitled", size_t maxlen = 100)
{
if(prefix) while(*prefix) *dst++ = *prefix++;

View File

@ -0,0 +1,8 @@
#ifndef ENGINE_WORLDIO_HH
#define ENGINE_WORLDIO_HH
uint getmapcrc();
void clearmapcrc();
bool load_world(const char *mname, const char *cname = NULL);
#endif

View File

@ -1,6 +1,7 @@
#include "cube.hh"
#include <engine/worldio.hh>
#include <engine/world.hh>
extern void clearmainmenu();

View File

@ -1,3 +1,6 @@
#ifndef SHARED_ENTS_HH
#define SHARED_ENTS_HH
// this file defines static map entities ("entity") and dynamic entities (players/monsters, "dynent")
// the gamecode extends these types to add game specific functionality
@ -204,4 +207,4 @@ struct dynent : physent // animated characters, or chara
vec abovehead() { return vec(o).addz(aboveeye+4); }
};
#endif

View File

@ -58,31 +58,7 @@ extern bool settexture(const char *name, int clamp = 0);
enum { EDIT_FACE = 0, EDIT_TEX, EDIT_MAT, EDIT_FLIP, EDIT_COPY, EDIT_PASTE, EDIT_ROTATE, EDIT_REPLACE, EDIT_DELCUBE, EDIT_CALCLIGHT, EDIT_REMIP, EDIT_VSLOT, EDIT_UNDO, EDIT_REDO };
struct selinfo
{
int corner;
int cx, cxs, cy, cys;
ivec o, s;
int grid, orient;
selinfo() : corner(0), cx(0), cxs(0), cy(0), cys(0), o(0, 0, 0), s(0, 0, 0), grid(8), orient(0) {}
int size() const { return s.x*s.y*s.z; }
int us(int d) const { return s[d]*grid; }
bool operator==(const selinfo &sel) const { return o==sel.o && s==sel.s && grid==sel.grid && orient==sel.orient; }
bool validate()
{
extern int worldsize;
if(grid <= 0 || grid >= worldsize) return false;
if(o.x >= worldsize || o.y >= worldsize || o.z >= worldsize) return false;
if(o.x < 0) { s.x -= (grid - 1 - o.x)/grid; o.x = 0; }
if(o.y < 0) { s.y -= (grid - 1 - o.y)/grid; o.y = 0; }
if(o.z < 0) { s.z -= (grid - 1 - o.z)/grid; o.z = 0; }
s.x = clamp(s.x, 0, (worldsize - o.x)/grid);
s.y = clamp(s.y, 0, (worldsize - o.y)/grid);
s.z = clamp(s.z, 0, (worldsize - o.z)/grid);
return s.x > 0 && s.y > 0 && s.z > 0;
}
};
struct selinfo;
struct editinfo;
extern editinfo *localedit;
@ -210,21 +186,6 @@ static inline bool insideworld(const ivec &o)
return uint(o.x)<uint(worldsize) && uint(o.y)<uint(worldsize) && uint(o.z)<uint(worldsize);
}
// world
extern bool emptymap(int factor, bool force, const char *mname = "", bool usecfg = true);
extern bool enlargemap(bool force);
extern int findentity(int type, int index = 0, int attr1 = -1, int attr2 = -1);
extern void findents(int low, int high, bool notspawned, const vec &pos, const vec &radius, vector<int> &found);
extern void mpeditent(int i, const vec &o, int type, int attr1, int attr2, int attr3, int attr4, int attr5, bool local);
extern vec getselpos();
extern int getworldsize();
extern int getmapversion();
extern void renderentcone(const extentity &e, const vec &dir, float radius, float angle);
extern void renderentarrow(const extentity &e, const vec &dir, float radius);
extern void renderentattachment(const extentity &e);
extern void renderentsphere(const extentity &e, float radius);
extern void renderentring(const extentity &e, float radius, int axis = 0);
// main
extern void fatal(const char *s, ...) PRINTFARGS(1, 2);