summaryrefslogtreecommitdiff
path: root/src/engine/physics.cpp
diff options
context:
space:
mode:
authorxolatile2025-08-06 22:54:55 +0200
committerxolatile2025-08-06 22:54:55 +0200
commit0a1172b75f571685c264a8b9d8ee224bbf11381f (patch)
treed041fdc68a60f0ebb48a3852bbcce6d9432f83d5 /src/engine/physics.cpp
parentaffde05dc07a94643f1fd2751b2b441f57f73d7d (diff)
downloadxolatile-badassbug-0a1172b75f571685c264a8b9d8ee224bbf11381f.tar.xz
xolatile-badassbug-0a1172b75f571685c264a8b9d8ee224bbf11381f.tar.zst
Please do not hate me, it makes sense...
Diffstat (limited to 'src/engine/physics.cpp')
-rw-r--r--src/engine/physics.cpp773
1 files changed, 245 insertions, 528 deletions
diff --git a/src/engine/physics.cpp b/src/engine/physics.cpp
index b1b800a..a43e8b4 100644
--- a/src/engine/physics.cpp
+++ b/src/engine/physics.cpp
@@ -10,11 +10,9 @@ const int MAXCLIPPLANES = 1024;
static clipplanes clipcache[MAXCLIPPLANES];
static int clipcacheversion = -2;
-static inline clipplanes &getclipplanes(const cube &c, const ivec &o, int size, bool collide = true, int offset = 0)
-{
+static inline clipplanes &getclipplanes(const cube &c, const ivec &o, int size, bool collide = true, int offset = 0) {
clipplanes &p = clipcache[int(&c - worldroot)&(MAXCLIPPLANES-1)];
- if(p.owner != &c || p.version != clipcacheversion+offset)
- {
+ if(p.owner != &c || p.version != clipcacheversion+offset) {
p.owner = &c;
p.version = clipcacheversion+offset;
genclipplanes(c, o, size, p, collide);
@@ -22,11 +20,9 @@ static inline clipplanes &getclipplanes(const cube &c, const ivec &o, int size,
return p;
}
-void resetclipplanes()
-{
+void resetclipplanes() {
clipcacheversion += 2;
- if(!clipcacheversion)
- {
+ if(!clipcacheversion) {
memclear(clipcache);
clipcacheversion = 2;
}
@@ -36,24 +32,24 @@ void resetclipplanes()
#define INTERSECTPLANES(setentry, exit) \
float enterdist = -1e16f, exitdist = 1e16f; \
- loopi(p.size) \
- { \
+ loopi(p.size) { \
+ \
float pdist = p.p[i].dist(v), facing = ray.dot(p.p[i]); \
- if(facing < 0) \
- { \
+ if(facing < 0) { \
+ \
pdist /= -facing; \
- if(pdist > enterdist) \
- { \
+ if(pdist > enterdist) { \
+ \
if(pdist > exitdist) exit; \
enterdist = pdist; \
setentry; \
} \
} \
- else if(facing > 0) \
- { \
+ else if(facing > 0) { \
+ \
pdist /= -facing; \
- if(pdist < exitdist) \
- { \
+ if(pdist < exitdist) { \
+ \
if(pdist < enterdist) exit; \
exitdist = pdist; \
} \
@@ -62,19 +58,19 @@ void resetclipplanes()
}
#define INTERSECTBOX(setentry, exit) \
- loop(i, 3) \
- { \
- if(ray[i]) \
- { \
+ loop(i, 3) { \
+ \
+ if(ray[i]) { \
+ \
float prad = fabs(p.r[i] * invray[i]), pdist = (p.o[i] - v[i]) * invray[i], pmin = pdist - prad, pmax = pdist + prad; \
- if(pmin > enterdist) \
- { \
+ if(pmin > enterdist) { \
+ \
if(pmin > exitdist) exit; \
enterdist = pmin; \
setentry; \
} \
- if(pmax < exitdist) \
- { \
+ if(pmax < exitdist) { \
+ \
if(pmax < enterdist) exit; \
exitdist = pmax; \
} \
@@ -84,8 +80,7 @@ void resetclipplanes()
vec hitsurface;
-static inline bool raycubeintersect(const clipplanes &p, const cube &c, const vec &v, const vec &ray, const vec &invray, float &dist)
-{
+static inline bool raycubeintersect(const clipplanes &p, const cube &c, const vec &v, const vec &ray, const vec &invray, float &dist) {
int entry = -1, bbentry = -1;
INTERSECTPLANES(entry = i, return false);
INTERSECTBOX(bbentry = i, return false);
@@ -100,59 +95,50 @@ extern void entselectionbox(const entity &e, vec &eo, vec &es);
float hitentdist;
int hitent, hitorient;
-static float disttoent(octaentities *oc, const vec &o, const vec &ray, float radius, int mode, extentity *t)
-{
+static float disttoent(octaentities *oc, const vec &o, const vec &ray, float radius, int mode, extentity *t) {
vec eo, es;
int orient = -1;
float dist = radius, f = 0.0f;
const vector<extentity *> &ents = entities::getents();
-
#define entintersect(mask, type, func) {\
- if((mode&(mask))==(mask)) loopv(oc->type) \
- { \
+ if((mode&(mask))==(mask)) loopv(oc->type) { \
+ \
extentity &e = *ents[oc->type[i]]; \
if(!(e.flags&EF_OCTA) || &e==t) continue; \
func; \
- if(f<dist && f>0 && vec(ray).mul(f).add(o).insidebb(oc->o, oc->size)) \
- { \
+ if(f<dist && f>0 && vec(ray).mul(f).add(o).insidebb(oc->o, oc->size)) { \
+ \
hitentdist = dist = f; \
hitent = oc->type[i]; \
hitorient = orient; \
} \
} \
}
-
entintersect(RAY_POLY, mapmodels,
if(!mmintersect(e, o, ray, radius, mode, f)) continue;
);
-
entintersect(RAY_ENTS, other,
entselectionbox(e, eo, es);
if(!rayboxintersect(eo, es, o, ray, f, orient)) continue;
);
-
entintersect(RAY_ENTS, mapmodels,
entselectionbox(e, eo, es);
if(!rayboxintersect(eo, es, o, ray, f, orient)) continue;
);
-
return dist;
}
-static float disttooutsideent(const vec &o, const vec &ray, float radius, int mode, extentity *t)
-{
+static float disttooutsideent(const vec &o, const vec &ray, float radius, int mode, extentity *t) {
vec eo, es;
int orient;
float dist = radius, f = 0.0f;
const vector<extentity *> &ents = entities::getents();
- loopv(outsideents)
- {
+ loopv(outsideents) {
extentity &e = *ents[outsideents[i]];
if(!(e.flags&EF_OCTA) || &e==t) continue;
entselectionbox(e, eo, es);
if(!rayboxintersect(eo, es, o, ray, f, orient)) continue;
- if(f<dist && f>0)
- {
+ if(f<dist && f>0) {
hitentdist = dist = f;
hitent = outsideents[i];
hitorient = orient;
@@ -162,12 +148,10 @@ static float disttooutsideent(const vec &o, const vec &ray, float radius, int mo
}
// optimized shadow version
-static float shadowent(octaentities *oc, const vec &o, const vec &ray, float radius, int mode, extentity *t)
-{
+static float shadowent(octaentities *oc, const vec &o, const vec &ray, float radius, int mode, extentity *t) {
float dist = radius, f = 0.0f;
const vector<extentity *> &ents = entities::getents();
- loopv(oc->mapmodels)
- {
+ loopv(oc->mapmodels) {
extentity &e = *ents[oc->mapmodels[i]];
if(!(e.flags&EF_OCTA) || &e==t) continue;
if(!mmintersect(e, o, ray, radius, mode, f)) continue;
@@ -185,14 +169,14 @@ static float shadowent(octaentities *oc, const vec &o, const vec &ray, float rad
ivec lsizemask(invray.x>0 ? 1 : 0, invray.y>0 ? 1 : 0, invray.z>0 ? 1 : 0); \
#define CHECKINSIDEWORLD \
- if(!insideworld(o)) \
- { \
+ if(!insideworld(o)) { \
+ \
float disttoworld = 0, exitworld = 1e16f; \
- loopi(3) \
- { \
+ loopi(3) { \
+ \
float c = v[i]; \
- if(c<0 || c>=worldsize) \
- { \
+ if(c<0 || c>=worldsize) { \
+ \
float d = ((invray[i]>0?0:worldsize)-c)*invray[i]; \
if(d<0) return (radius>0?radius:-1); \
disttoworld = max(disttoworld, 0.1f + d); \
@@ -207,15 +191,15 @@ static float shadowent(octaentities *oc, const vec &o, const vec &ray, float rad
#define DOWNOCTREE(disttoent, earlyexit) \
cube *lc = levels[lshift]; \
- for(;;) \
- { \
+ for(;;) { \
+ \
lshift--; \
lc += octastep(x, y, z, lshift); \
- if(lc->ext && lc->ext->ents && lshift < elvl) \
- { \
+ if(lc->ext && lc->ext->ents && lshift < elvl) { \
+ \
float edist = disttoent(lc->ext->ents, o, ray, dent, mode, t); \
- if(edist < dent) \
- { \
+ if(edist < dent) { \
+ \
earlyexit return min(edist, dist); \
elvl = lshift; \
dent = min(dent, edist); \
@@ -246,103 +230,76 @@ static float shadowent(octaentities *oc, const vec &o, const vec &ray, float rad
if(diff >= uint(worldsize)) exitworld; \
diff >>= lshift; \
if(!diff) exitworld; \
- do \
- { \
+ do { \
+ \
lshift++; \
diff >>= 1; \
} while(diff);
-float raycube(const vec &o, const vec &ray, float radius, int mode, int size, extentity *t)
-{
+float raycube(const vec &o, const vec &ray, float radius, int mode, int size, extentity *t) {
if(ray.iszero()) return 0;
-
INITRAYCUBE;
CHECKINSIDEWORLD;
-
int closest = -1, x = int(v.x), y = int(v.y), z = int(v.z);
- for(;;)
- {
+ for(;;) {
DOWNOCTREE(disttoent, if(mode&RAY_SHADOW));
-
int lsize = 1<<lshift;
-
cube &c = *lc;
if((dist>0 || !(mode&RAY_SKIPFIRST)) &&
(((mode&RAY_EDITMAT) && c.material != MAT_AIR) ||
(!(mode&RAY_PASS) && lsize==size && !isempty(c)) ||
isentirelysolid(c) ||
- dent < dist))
- {
+ dent < dist)) {
if(closest >= 0) { hitsurface = vec(0, 0, 0); hitsurface[closest] = ray[closest]>0 ? -1 : 1; }
return min(dent, dist);
}
-
ivec lo(x&(~0U<<lshift), y&(~0U<<lshift), z&(~0U<<lshift));
-
- if(!isempty(c))
- {
+ if(!isempty(c)) {
const clipplanes &p = getclipplanes(c, lo, lsize, false, 1);
float f = 0;
if(raycubeintersect(p, c, v, ray, invray, f) && (dist+f>0 || !(mode&RAY_SKIPFIRST)))
return min(dent, dist+f);
}
-
FINDCLOSEST(closest = 0, closest = 1, closest = 2);
-
if(radius>0 && dist>=radius) return min(dent, dist);
-
UPOCTREE(return min(dent, radius>0 ? radius : dist));
}
}
// optimized version for lightmap shadowing... every cycle here counts!!!
-float shadowray(const vec &o, const vec &ray, float radius, int mode, extentity *t)
-{
+float shadowray(const vec &o, const vec &ray, float radius, int mode, extentity *t) {
INITRAYCUBE;
CHECKINSIDEWORLD;
-
- int side = O_BOTTOM, x = int(v.x), y = int(v.y), z = int(v.z);
- for(;;)
- {
+ int side = O_BOTTOM, x = int(v.x), y = int(v.y), z = int(v.z); (void) side;
+ for(;;) {
DOWNOCTREE(shadowent, );
-
cube &c = *lc;
ivec lo(x&(~0U<<lshift), y&(~0U<<lshift), z&(~0U<<lshift));
-
- if(!isempty(c) && !(c.material&MAT_ALPHA))
- {
- if(isentirelysolid(c))
- {
+ if(!isempty(c) && !(c.material&MAT_ALPHA)) {
+ if(isentirelysolid(c)) {
return dist;
}
- else
- {
+ else {
const clipplanes &p = getclipplanes(c, lo, 1<<lshift, false, 1);
INTERSECTPLANES(side = p.side[i], goto nextcube);
INTERSECTBOX(side = (i<<1) + 1 - lsizemask[i], goto nextcube);
- if(exitdist >= 0)
- {
+ if(exitdist >= 0) {
return dist+max(enterdist+0.1f, 0.0f);
}
}
}
-
nextcube:
FINDCLOSEST(side = O_RIGHT - lsizemask.x, side = O_FRONT - lsizemask.y, side = O_TOP - lsizemask.z);
-
if(dist>=radius) return dist;
-
UPOCTREE(return radius);
}
}
// thread safe version
-struct ShadowRayCache
-{
+struct ShadowRayCache {
clipplanes clipcache[MAXCLIPPLANES];
int version;
-
ShadowRayCache() : version(-1) {}
};
@@ -350,65 +307,49 @@ ShadowRayCache *newshadowraycache() { return new ShadowRayCache; }
void freeshadowraycache(ShadowRayCache *&cache) { delete cache; cache = NULL; }
-void resetshadowraycache(ShadowRayCache *cache)
-{
+void resetshadowraycache(ShadowRayCache *cache) {
cache->version++;
- if(!cache->version)
- {
+ if(!cache->version) {
memclear(cache->clipcache);
cache->version = 1;
}
}
-float shadowray(ShadowRayCache *cache, const vec &o, const vec &ray, float radius, int mode, extentity *t)
-{
+float shadowray(ShadowRayCache *cache, const vec &o, const vec &ray, float radius, int mode, extentity *t) {
INITRAYCUBE;
CHECKINSIDEWORLD;
-
- int side = O_BOTTOM, x = int(v.x), y = int(v.y), z = int(v.z);
- for(;;)
- {
+ int side = O_BOTTOM, x = int(v.x), y = int(v.y), z = int(v.z); (void) side;
+ for(;;) {
DOWNOCTREE(shadowent, );
-
cube &c = *lc;
ivec lo(x&(~0U<<lshift), y&(~0U<<lshift), z&(~0U<<lshift));
-
- if(!isempty(c) && !(c.material&MAT_ALPHA))
- {
- if(isentirelysolid(c))
- {
+ if(!isempty(c) && !(c.material&MAT_ALPHA)) {
+ if(isentirelysolid(c)) {
return dist;
}
- else
- {
+ else {
clipplanes &p = cache->clipcache[int(&c - worldroot)&(MAXCLIPPLANES-1)];
if(p.owner != &c || p.version != cache->version) { p.owner = &c; p.version = cache->version; genclipplanes(c, lo, 1<<lshift, p, false); }
INTERSECTPLANES(side = p.side[i], goto nextcube);
INTERSECTBOX(side = (i<<1) + 1 - lsizemask[i], goto nextcube);
- if(exitdist >= 0)
- {
+ if(exitdist >= 0) {
return dist+max(enterdist+0.1f, 0.0f);
}
}
}
-
nextcube:
FINDCLOSEST(side = O_RIGHT - lsizemask.x, side = O_FRONT - lsizemask.y, side = O_TOP - lsizemask.z);
-
if(dist>=radius) return dist;
-
UPOCTREE(return radius);
}
}
-float rayent(const vec &o, const vec &ray, float radius, int mode, int size, int &orient, int &ent)
-{
+float rayent(const vec &o, const vec &ray, float radius, int mode, int size, int &orient, int &ent) {
hitent = -1;
hitentdist = radius;
hitorient = -1;
float dist = raycube(o, ray, radius, mode, size);
- if((mode&RAY_ENTS) == RAY_ENTS)
- {
+ if((mode&RAY_ENTS) == RAY_ENTS) {
float dent = disttooutsideent(o, ray, dist < 0 ? 1e16f : dist, mode, NULL);
if(dent < 1e15f && (dist < 0 || dent < dist)) dist = dent;
}
@@ -417,8 +358,7 @@ float rayent(const vec &o, const vec &ray, float radius, int mode, int size, int
return dist;
}
-float raycubepos(const vec &o, const vec &ray, vec &hitpos, float radius, int mode, int size)
-{
+float raycubepos(const vec &o, const vec &ray, vec &hitpos, float radius, int mode, int size) {
hitpos = ray;
float dist = raycube(o, ray, radius, mode, size);
if(radius>0 && dist>=radius) dist = radius;
@@ -426,8 +366,7 @@ float raycubepos(const vec &o, const vec &ray, vec &hitpos, float radius, int mo
return dist;
}
-bool raycubelos(const vec &o, const vec &dest, vec &hitpos)
-{
+bool raycubelos(const vec &o, const vec &dest, vec &hitpos) {
vec ray(dest);
ray.sub(o);
float mag = ray.magnitude();
@@ -436,8 +375,7 @@ bool raycubelos(const vec &o, const vec &dest, vec &hitpos)
return distance >= mag;
}
-float rayfloor(const vec &o, vec &floor, int mode, float radius)
-{
+float rayfloor(const vec &o, vec &floor, int mode, float radius) {
if(o.z<=0) return -1;
hitsurface = vec(0, 0, 1);
float dist = raycube(o, vec(0, 0, -1), radius, mode);
@@ -460,53 +398,42 @@ const float WALLZ = 0.2f;
extern const float JUMPVEL = 125.0f;
extern const float GRAVITY = 200.0f;
-bool ellipseboxcollide(physent *d, const vec &dir, const vec &o, const vec &center, float yaw, float xr, float yr, float hi, float lo)
-{
+bool ellipseboxcollide(physent *d, const vec &dir, const vec &o, const vec &center, float yaw, float xr, float yr, float hi, float lo) {
float below = (o.z+center.z-lo) - (d->o.z+d->aboveeye),
above = (d->o.z-d->eyeheight) - (o.z+center.z+hi);
if(below>=0 || above>=0) return false;
-
vec yo(d->o);
yo.sub(o);
yo.rotate_around_z(-yaw*RAD);
yo.sub(center);
-
float dx = clamp(yo.x, -xr, xr) - yo.x, dy = clamp(yo.y, -yr, yr) - yo.y,
dist = sqrtf(dx*dx + dy*dy) - d->radius;
- if(dist < 0)
- {
+ if(dist < 0) {
int sx = yo.x <= -xr ? -1 : (yo.x >= xr ? 1 : 0),
sy = yo.y <= -yr ? -1 : (yo.y >= yr ? 1 : 0);
- if(dist > (yo.z < 0 ? below : above) && (sx || sy))
- {
+ if(dist > (yo.z < 0 ? below : above) && (sx || sy)) {
vec ydir(dir);
ydir.rotate_around_z(-yaw*RAD);
- if(sx*yo.x - xr > sy*yo.y - yr)
- {
- if(dir.iszero() || sx*ydir.x < -1e-6f)
- {
+ if(sx*yo.x - xr > sy*yo.y - yr) {
+ if(dir.iszero() || sx*ydir.x < -1e-6f) {
collidewall = vec(sx, 0, 0);
collidewall.rotate_around_z(yaw*RAD);
return true;
}
}
- else if(dir.iszero() || sy*ydir.y < -1e-6f)
- {
+ else if(dir.iszero() || sy*ydir.y < -1e-6f) {
collidewall = vec(0, sy, 0);
collidewall.rotate_around_z(yaw*RAD);
return true;
}
}
- if(yo.z < 0)
- {
- if(dir.iszero() || (dir.z > 0 && (d->type>=ENT_INANIMATE || below >= d->zmargin-(d->eyeheight+d->aboveeye)/4.0f)))
- {
+ if(yo.z < 0) {
+ if(dir.iszero() || (dir.z > 0 && (d->type>=ENT_INANIMATE || below >= d->zmargin-(d->eyeheight+d->aboveeye)/4.0f))) {
collidewall = vec(0, 0, -1);
return true;
}
}
- else if(dir.iszero() || (dir.z < 0 && (d->type>=ENT_INANIMATE || above >= d->zmargin-(d->eyeheight+d->aboveeye)/3.0f)))
- {
+ else if(dir.iszero() || (dir.z < 0 && (d->type>=ENT_INANIMATE || above >= d->zmargin-(d->eyeheight+d->aboveeye)/3.0f))) {
collidewall = vec(0, 0, 1);
return true;
}
@@ -515,8 +442,7 @@ bool ellipseboxcollide(physent *d, const vec &dir, const vec &o, const vec &cent
return false;
}
-bool ellipsecollide(physent *d, const vec &dir, const vec &o, const vec &center, float yaw, float xr, float yr, float hi, float lo)
-{
+bool ellipsecollide(physent *d, const vec &dir, const vec &o, const vec &center, float yaw, float xr, float yr, float hi, float lo) {
float below = (o.z+center.z-lo) - (d->o.z+d->aboveeye),
above = (d->o.z-d->eyeheight) - (o.z+center.z+hi);
if(below>=0 || above>=0) return false;
@@ -528,24 +454,19 @@ bool ellipsecollide(physent *d, const vec &dir, const vec &o, const vec &center,
float dx = d->xradius*cosf(dangle), dy = d->yradius*sinf(dangle);
float ex = xr*cosf(eangle), ey = yr*sinf(eangle);
float dist = sqrtf(x*x + y*y) - sqrtf(dx*dx + dy*dy) - sqrtf(ex*ex + ey*ey);
- if(dist < 0)
- {
- if(dist > (d->o.z < yo.z ? below : above) && (dir.iszero() || x*dir.x + y*dir.y > 0))
- {
+ if(dist < 0) {
+ if(dist > (d->o.z < yo.z ? below : above) && (dir.iszero() || x*dir.x + y*dir.y > 0)) {
collidewall = vec(-x, -y, 0);
if(!collidewall.iszero()) collidewall.normalize();
return true;
}
- if(d->o.z < yo.z)
- {
- if(dir.iszero() || (dir.z > 0 && (d->type>=ENT_INANIMATE || below >= d->zmargin-(d->eyeheight+d->aboveeye)/4.0f)))
- {
+ if(d->o.z < yo.z) {
+ if(dir.iszero() || (dir.z > 0 && (d->type>=ENT_INANIMATE || below >= d->zmargin-(d->eyeheight+d->aboveeye)/4.0f))) {
collidewall = vec(0, 0, -1);
return true;
}
}
- else if(dir.iszero() || (dir.z < 0 && (d->type>=ENT_INANIMATE || above >= d->zmargin-(d->eyeheight+d->aboveeye)/3.0f)))
- {
+ else if(dir.iszero() || (dir.z < 0 && (d->type>=ENT_INANIMATE || above >= d->zmargin-(d->eyeheight+d->aboveeye)/3.0f))) {
collidewall = vec(0, 0, 1);
return true;
}
@@ -558,15 +479,13 @@ bool ellipsecollide(physent *d, const vec &dir, const vec &o, const vec &center,
static uint dynentframe = 0;
-static struct dynentcacheentry
-{
+static struct dynentcacheentry {
int x, y;
uint frame;
vector<physent *> dynents;
} dynentcache[DYNENTCACHESIZE];
-void cleardynentcache()
-{
+void cleardynentcache() {
dynentframe++;
if(!dynentframe || dynentframe == 1) loopi(DYNENTCACHESIZE) dynentcache[i].frame = 0;
if(!dynentframe) dynentframe = 1;
@@ -576,8 +495,7 @@ VARF(dynentsize, 4, 7, 12, cleardynentcache());
#define DYNENTHASH(x, y) (((((x)^(y))<<5) + (((x)^(y))>>5)) & (DYNENTCACHESIZE - 1))
-const vector<physent *> &checkdynentcache(int x, int y)
-{
+const vector<physent *> &checkdynentcache(int x, int y) {
dynentcacheentry &dec = dynentcache[DYNENTHASH(x, y)];
if(dec.x == x && dec.y == y && dec.frame == dynentframe) return dec.dynents;
dec.x = x;
@@ -585,8 +503,7 @@ const vector<physent *> &checkdynentcache(int x, int y)
dec.frame = dynentframe;
dec.dynents.shrink(0);
int numdyns = game::numdynents(), dsize = 1<<dynentsize, dx = x<<dynentsize, dy = y<<dynentsize;
- loopi(numdyns)
- {
+ loopi(numdyns) {
dynent *d = game::iterdynents(i);
if(d->state != CS_ALIVE ||
d->o.x+d->radius <= dx || d->o.x-d->radius >= dx+dsize ||
@@ -601,23 +518,18 @@ const vector<physent *> &checkdynentcache(int x, int y)
for(int curx = max(int(o.x-radius), 0)>>dynentsize, endx = min(int(o.x+radius), worldsize-1)>>dynentsize; curx <= endx; curx++) \
for(int cury = max(int(o.y-radius), 0)>>dynentsize, endy = min(int(o.y+radius), worldsize-1)>>dynentsize; cury <= endy; cury++)
-void updatedynentcache(physent *d)
-{
- loopdynentcache(x, y, d->o, d->radius)
- {
+void updatedynentcache(physent *d) {
+ loopdynentcache(x, y, d->o, d->radius) {
dynentcacheentry &dec = dynentcache[DYNENTHASH(x, y)];
if(dec.x != x || dec.y != y || dec.frame != dynentframe || dec.dynents.find(d) >= 0) continue;
dec.dynents.add(d);
}
}
-bool overlapsdynent(const vec &o, float radius)
-{
- loopdynentcache(x, y, o, radius)
- {
+bool overlapsdynent(const vec &o, float radius) {
+ loopdynentcache(x, y, o, radius) {
const vector<physent *> &dynents = checkdynentcache(x, y);
- loopv(dynents)
- {
+ loopv(dynents) {
physent *d = dynents[i];
if(o.dist(d->o)-d->radius < radius) return true;
}
@@ -626,13 +538,11 @@ bool overlapsdynent(const vec &o, float radius)
}
template<class E, class O>
-static inline bool plcollide(physent *d, const vec &dir, physent *o)
-{
+static inline bool plcollide(physent *d, const vec &dir, physent *o) {
E entvol(d);
O obvol(o);
vec cp;
- if(mpr::collide(entvol, obvol, NULL, NULL, &cp))
- {
+ if(mpr::collide(entvol, obvol, NULL, NULL, &cp)) {
vec wn = vec(cp).sub(obvol.center());
collidewall = obvol.contactface(wn, dir.iszero() ? vec(wn).neg() : dir);
if(!collidewall.iszero()) return true;
@@ -641,10 +551,8 @@ static inline bool plcollide(physent *d, const vec &dir, physent *o)
return false;
}
-static inline bool plcollide(physent *d, const vec &dir, physent *o)
-{
- switch(d->collidetype)
- {
+static inline bool plcollide(physent *d, const vec &dir, physent *o) {
+ switch(d->collidetype) {
case COLLIDE_ELLIPSE:
case COLLIDE_ELLIPSE_PRECISE:
if(o->collidetype == COLLIDE_OBB) return ellipseboxcollide(d, dir, o->o, vec(0, 0, 0), o->yaw, o->xradius, o->yradius, o->aboveeye, o->eyeheight);
@@ -656,33 +564,27 @@ static inline bool plcollide(physent *d, const vec &dir, physent *o)
}
}
-bool plcollide(physent *d, const vec &dir, bool insideplayercol) // collide with player or monster
-{
+bool plcollide(physent *d, const vec &dir, bool insideplayercol) { // collide with player or monster {
if(d->type==ENT_CAMERA || d->state!=CS_ALIVE) return false;
int lastinside = collideinside;
physent *insideplayer = NULL;
- loopdynentcache(x, y, d->o, d->radius)
- {
+ loopdynentcache(x, y, d->o, d->radius) {
const vector<physent *> &dynents = checkdynentcache(x, y);
- loopv(dynents)
- {
+ loopv(dynents) {
physent *o = dynents[i];
if(o==d || d->o.reject(o->o, d->radius+o->radius)) continue;
- if(plcollide(d, dir, o))
- {
+ if(plcollide(d, dir, o)) {
collideplayer = o;
game::dynentcollide(d, o, collidewall);
return true;
}
- if(collideinside > lastinside)
- {
+ if(collideinside > lastinside) {
lastinside = collideinside;
insideplayer = o;
}
}
}
- if(insideplayer && insideplayercol)
- {
+ if(insideplayer && insideplayercol) {
collideplayer = insideplayer;
game::dynentcollide(d, insideplayer, vec(0, 0, 0));
return true;
@@ -690,8 +592,7 @@ bool plcollide(physent *d, const vec &dir, bool insideplayercol) // collide with
return false;
}
-void rotatebb(vec &center, vec &radius, int yaw)
-{
+void rotatebb(vec &center, vec &radius, int yaw) {
if(yaw < 0) yaw = 360 + yaw%360;
else if(yaw >= 360) yaw %= 360;
const vec2 &rot = sincos360[yaw];
@@ -703,13 +604,11 @@ void rotatebb(vec &center, vec &radius, int yaw)
}
template<class E, class M>
-static inline bool mmcollide(physent *d, const vec &dir, const extentity &e, const vec &center, const vec &radius, float yaw)
-{
+static inline bool mmcollide(physent *d, const vec &dir, const extentity &e, const vec &center, const vec &radius, float yaw) {
E entvol(d);
M mdlvol(e.o, center, radius, yaw);
vec cp;
- if(mpr::collide(entvol, mdlvol, NULL, NULL, &cp))
- {
+ if(mpr::collide(entvol, mdlvol, NULL, NULL, &cp)) {
vec wn = vec(cp).sub(mdlvol.center());
collidewall = mdlvol.contactface(wn, dir.iszero() ? vec(wn).neg() : dir);
if(!collidewall.iszero()) return true;
@@ -718,34 +617,27 @@ static inline bool mmcollide(physent *d, const vec &dir, const extentity &e, con
return false;
}
-bool mmcollide(physent *d, const vec &dir, octaentities &oc) // collide with a mapmodel
-{
+bool mmcollide(physent *d, const vec &dir, octaentities &oc) { // collide with a mapmodel {
const vector<extentity *> &ents = entities::getents();
- loopv(oc.mapmodels)
- {
+ loopv(oc.mapmodels) {
extentity &e = *ents[oc.mapmodels[i]];
if(e.flags&EF_NOCOLLIDE) continue;
model *m = loadmapmodel(e.attr2);
if(!m || !m->collide) continue;
-
vec center, radius;
float rejectradius = m->collisionbox(center, radius);
if(d->o.reject(e.o, d->radius + rejectradius)) continue;
-
float yaw = e.attr1;
- switch(d->collidetype)
- {
+ switch(d->collidetype) {
case COLLIDE_ELLIPSE:
case COLLIDE_ELLIPSE_PRECISE:
- if(m->ellipsecollide)
- {
+ if(m->ellipsecollide) {
if(ellipsecollide(d, dir, e.o, center, yaw, radius.x, radius.y, radius.z, radius.z)) return true;
}
else if(ellipseboxcollide(d, dir, e.o, center, yaw, radius.x, radius.y, radius.z, radius.z)) return true;
break;
case COLLIDE_OBB:
- if(m->ellipsecollide)
- {
+ if(m->ellipsecollide) {
if(mmcollide<mpr::EntOBB, mpr::ModelEllipse>(d, dir, e, center, radius, yaw)) return true;
}
else if(mmcollide<mpr::EntOBB, mpr::ModelOBB>(d, dir, e, center, radius, yaw)) return true;
@@ -757,24 +649,22 @@ bool mmcollide(physent *d, const vec &dir, octaentities &oc) // collide wit
}
template<class E>
-static bool fuzzycollidesolid(physent *d, const vec &dir, float cutoff, const cube &c, const ivec &co, int size) // collide with solid cube geometry
-{
+static bool fuzzycollidesolid(physent *d, const vec &dir, float cutoff, const cube &c, const ivec &co, int size) { // collide with solid cube geometry {
int crad = size/2;
if(fabs(d->o.x - co.x - crad) > d->radius + crad || fabs(d->o.y - co.y - crad) > d->radius + crad ||
d->o.z + d->aboveeye < co.z || d->o.z - d->eyeheight > co.z + size)
return false;
-
E entvol(d);
collidewall = vec(0, 0, 0);
float bestdist = -1e10f;
int visible = isentirelysolid(c) ? c.visible : 0xFF;
- #define CHECKSIDE(side, distval, dotval, margin, normal) if(visible&(1<<side)) do \
- { \
+ #define CHECKSIDE(side, distval, dotval, margin, normal) if(visible&(1<<side)) do { \
+ \
float dist = distval; \
if(dist > 0) return false; \
if(dist <= bestdist) continue; \
- if(!dir.iszero()) \
- { \
+ if(!dir.iszero()) { \
+ \
if(dotval >= -cutoff*dir.magnitude()) continue; \
if(d->type<ENT_CAMERA && dotval < 0 && dist < margin) continue; \
} \
@@ -787,9 +677,7 @@ static bool fuzzycollidesolid(physent *d, const vec &dir, float cutoff, const cu
CHECKSIDE(O_FRONT, d->o.y - d->radius - (co.y + size), dir.y, -d->radius, vec(0, 1, 0));
CHECKSIDE(O_BOTTOM, co.z - (d->o.z + d->aboveeye), -dir.z, d->zmargin-(d->eyeheight+d->aboveeye)/4.0f, vec(0, 0, -1));
CHECKSIDE(O_TOP, d->o.z - d->eyeheight - (co.z + size), dir.z, d->zmargin-(d->eyeheight+d->aboveeye)/3.0f, vec(0, 0, 1));
-
- if(collidewall.iszero())
- {
+ if(collidewall.iszero()) {
collideinside++;
return false;
}
@@ -797,24 +685,20 @@ static bool fuzzycollidesolid(physent *d, const vec &dir, float cutoff, const cu
}
template<class E>
-static inline bool clampcollide(const clipplanes &p, const E &entvol, const plane &w, const vec &pw)
-{
- if(w.x && (w.y || w.z) && fabs(pw.x - p.o.x) > p.r.x)
- {
+static inline bool clampcollide(const clipplanes &p, const E &entvol, const plane &w, const vec &pw) {
+ if(w.x && (w.y || w.z) && fabs(pw.x - p.o.x) > p.r.x) {
vec c = entvol.center();
float fv = pw.x < p.o.x ? p.o.x-p.r.x : p.o.x+p.r.x, fdist = (w.x*fv + w.y*c.y + w.z*c.z + w.offset) / (w.y*w.y + w.z*w.z);
vec fdir(fv - c.x, -w.y*fdist, -w.z*fdist);
if((pw.y-c.y-fdir.y)*w.y + (pw.z-c.z-fdir.z)*w.z >= 0 && entvol.supportpoint(fdir).squaredist(c) < fdir.squaredlen()) return true;
}
- if(w.y && (w.x || w.z) && fabs(pw.y - p.o.y) > p.r.y)
- {
+ if(w.y && (w.x || w.z) && fabs(pw.y - p.o.y) > p.r.y) {
vec c = entvol.center();
float fv = pw.y < p.o.y ? p.o.y-p.r.y : p.o.y+p.r.y, fdist = (w.x*c.x + w.y*fv + w.z*c.z + w.offset) / (w.x*w.x + w.z*w.z);
vec fdir(-w.x*fdist, fv - c.y, -w.z*fdist);
if((pw.x-c.x-fdir.x)*w.x + (pw.z-c.z-fdir.z)*w.z >= 0 && entvol.supportpoint(fdir).squaredist(c) < fdir.squaredlen()) return true;
}
- if(w.z && (w.x || w.y) && fabs(pw.z - p.o.z) > p.r.z)
- {
+ if(w.z && (w.x || w.y) && fabs(pw.z - p.o.z) > p.r.z) {
vec c = entvol.center();
float fv = pw.z < p.o.z ? p.o.z-p.r.z : p.o.z+p.r.z, fdist = (w.x*c.x + w.y*c.y + w.z*fv + w.offset) / (w.x*w.x + w.y*w.y);
vec fdir(-w.x*fdist, -w.y*fdist, fv - c.z);
@@ -824,14 +708,11 @@ static inline bool clampcollide(const clipplanes &p, const E &entvol, const plan
}
template<class E>
-static bool fuzzycollideplanes(physent *d, const vec &dir, float cutoff, const cube &c, const ivec &co, int size) // collide with deformed cube geometry
-{
+static bool fuzzycollideplanes(physent *d, const vec &dir, float cutoff, const cube &c, const ivec &co, int size) { // collide with deformed cube geometry {
const clipplanes &p = getclipplanes(c, co, size);
-
if(fabs(d->o.x - p.o.x) > p.r.x + d->radius || fabs(d->o.y - p.o.y) > p.r.y + d->radius ||
d->o.z + d->aboveeye < p.o.z - p.r.z || d->o.z - d->eyeheight > p.o.z + p.r.z)
return false;
-
collidewall = vec(0, 0, 0);
float bestdist = -1e10f;
int visible = p.visible;
@@ -841,11 +722,9 @@ static bool fuzzycollideplanes(physent *d, const vec &dir, float cutoff, const c
CHECKSIDE(O_FRONT, d->o.y - d->radius - (p.o.y + p.r.y), dir.y, -d->radius, vec(0, 1, 0));
CHECKSIDE(O_BOTTOM, p.o.z - p.r.z - (d->o.z + d->aboveeye), -dir.z, d->zmargin-(d->eyeheight+d->aboveeye)/4.0f, vec(0, 0, -1));
CHECKSIDE(O_TOP, d->o.z - d->eyeheight - (p.o.z + p.r.z), dir.z, d->zmargin-(d->eyeheight+d->aboveeye)/3.0f, vec(0, 0, 1));
-
E entvol(d);
int bestplane = -1;
- loopi(p.size)
- {
+ loopi(p.size) {
const plane &w = p.p[i];
vec pw = entvol.supportpoint(vec(w).neg());
float dist = w.dist(pw);
@@ -853,8 +732,7 @@ static bool fuzzycollideplanes(physent *d, const vec &dir, float cutoff, const c
if(dist <= bestdist) continue;
bestplane = -1;
bestdist = dist;
- if(!dir.iszero())
- {
+ if(!dir.iszero()) {
if(w.dot(dir) >= -cutoff*dir.magnitude()) continue;
if(d->type<ENT_CAMERA &&
dist < (dir.z*w.z < 0 ?
@@ -866,8 +744,7 @@ static bool fuzzycollideplanes(physent *d, const vec &dir, float cutoff, const c
bestplane = i;
}
if(bestplane >= 0) collidewall = p.p[bestplane];
- else if(collidewall.iszero())
- {
+ else if(collidewall.iszero()) {
collideinside++;
return false;
}
@@ -875,17 +752,14 @@ static bool fuzzycollideplanes(physent *d, const vec &dir, float cutoff, const c
}
template<class E>
-static bool cubecollidesolid(physent *d, const vec &dir, float cutoff, const cube &c, const ivec &co, int size) // collide with solid cube geometry
-{
+static bool cubecollidesolid(physent *d, const vec &dir, float cutoff, const cube &c, const ivec &co, int size) { // collide with solid cube geometry {
int crad = size/2;
if(fabs(d->o.x - co.x - crad) > d->radius + crad || fabs(d->o.y - co.y - crad) > d->radius + crad ||
d->o.z + d->aboveeye < co.z || d->o.z - d->eyeheight > co.z + size)
return false;
-
E entvol(d);
bool collided = mpr::collide(mpr::SolidCube(co, size), entvol);
if(!collided) return false;
-
collidewall = vec(0, 0, 0);
float bestdist = -1e10f;
int visible = isentirelysolid(c) ? c.visible : 0xFF;
@@ -895,9 +769,7 @@ static bool cubecollidesolid(physent *d, const vec &dir, float cutoff, const cub
CHECKSIDE(O_FRONT, entvol.back() - (co.y + size), dir.y, -d->radius, vec(0, 1, 0));
CHECKSIDE(O_BOTTOM, co.z - entvol.top(), -dir.z, d->zmargin-(d->eyeheight+d->aboveeye)/4.0f, vec(0, 0, -1));
CHECKSIDE(O_TOP, entvol.bottom() - (co.z + size), dir.z, d->zmargin-(d->eyeheight+d->aboveeye)/3.0f, vec(0, 0, 1));
-
- if(collidewall.iszero())
- {
+ if(collidewall.iszero()) {
collideinside++;
return false;
}
@@ -905,18 +777,14 @@ static bool cubecollidesolid(physent *d, const vec &dir, float cutoff, const cub
}
template<class E>
-static bool cubecollideplanes(physent *d, const vec &dir, float cutoff, const cube &c, const ivec &co, int size) // collide with deformed cube geometry
-{
+static bool cubecollideplanes(physent *d, const vec &dir, float cutoff, const cube &c, const ivec &co, int size) { // collide with deformed cube geometry {
const clipplanes &p = getclipplanes(c, co, size);
-
if(fabs(d->o.x - p.o.x) > p.r.x + d->radius || fabs(d->o.y - p.o.y) > p.r.y + d->radius ||
d->o.z + d->aboveeye < p.o.z - p.r.z || d->o.z - d->eyeheight > p.o.z + p.r.z)
return false;
-
E entvol(d);
bool collided = mpr::collide(mpr::CubePlanes(p), entvol);
if(!collided) return false;
-
collidewall = vec(0, 0, 0);
float bestdist = -1e10f;
int visible = p.visible;
@@ -926,18 +794,15 @@ static bool cubecollideplanes(physent *d, const vec &dir, float cutoff, const cu
CHECKSIDE(O_FRONT, entvol.back() - (p.o.y + p.r.y), dir.y, -d->radius, vec(0, 1, 0));
CHECKSIDE(O_BOTTOM, p.o.z - p.r.z - entvol.top(), -dir.z, d->zmargin-(d->eyeheight+d->aboveeye)/4.0f, vec(0, 0, -1));
CHECKSIDE(O_TOP, entvol.bottom() - (p.o.z + p.r.z), dir.z, d->zmargin-(d->eyeheight+d->aboveeye)/3.0f, vec(0, 0, 1));
-
int bestplane = -1;
- loopi(p.size)
- {
+ loopi(p.size) {
const plane &w = p.p[i];
vec pw = entvol.supportpoint(vec(w).neg());
float dist = w.dist(pw);
if(dist <= bestdist) continue;
bestplane = -1;
bestdist = dist;
- if(!dir.iszero())
- {
+ if(!dir.iszero()) {
if(w.dot(dir) >= -cutoff*dir.magnitude()) continue;
if(d->type<ENT_CAMERA &&
dist < (dir.z*w.z < 0 ?
@@ -949,18 +814,15 @@ static bool cubecollideplanes(physent *d, const vec &dir, float cutoff, const cu
bestplane = i;
}
if(bestplane >= 0) collidewall = p.p[bestplane];
- else if(collidewall.iszero())
- {
+ else if(collidewall.iszero()) {
collideinside++;
return false;
}
return true;
}
-static inline bool cubecollide(physent *d, const vec &dir, float cutoff, const cube &c, const ivec &co, int size, bool solid)
-{
- switch(d->collidetype)
- {
+static inline bool cubecollide(physent *d, const vec &dir, float cutoff, const cube &c, const ivec &co, int size, bool solid) {
+ switch(d->collidetype) {
case COLLIDE_OBB:
if(isentirelysolid(c) || solid) return cubecollidesolid<mpr::EntOBB>(d, dir, cutoff, c, co, size);
else return cubecollideplanes<mpr::EntOBB>(d, dir, cutoff, c, co, size);
@@ -974,21 +836,16 @@ static inline bool cubecollide(physent *d, const vec &dir, float cutoff, const c
}
}
-static inline bool octacollide(physent *d, const vec &dir, float cutoff, const ivec &bo, const ivec &bs, const cube *c, const ivec &cor, int size) // collide with octants
-{
- loopoctabox(cor, size, bo, bs)
- {
+static inline bool octacollide(physent *d, const vec &dir, float cutoff, const ivec &bo, const ivec &bs, const cube *c, const ivec &cor, int size) { // collide with octants {
+ loopoctabox(cor, size, bo, bs) {
if(c[i].ext && c[i].ext->ents) if(mmcollide(d, dir, *c[i].ext->ents)) return true;
ivec o(i, cor, size);
- if(c[i].children)
- {
+ if(c[i].children) {
if(octacollide(d, dir, cutoff, bo, bs, c[i].children, o, size>>1)) return true;
}
- else
- {
+ else {
bool solid = false;
- switch(c[i].material&MATF_CLIP)
- {
+ switch(c[i].material&MATF_CLIP) {
case MAT_NOCLIP: continue;
case MAT_GAMECLIP: if(d->type==ENT_AI) solid = true; break;
case MAT_CLIP: if(d->type<ENT_CAMERA) solid = true; break;
@@ -1000,8 +857,7 @@ static inline bool octacollide(physent *d, const vec &dir, float cutoff, const i
return false;
}
-static inline bool octacollide(physent *d, const vec &dir, float cutoff, const ivec &bo, const ivec &bs)
-{
+static inline bool octacollide(physent *d, const vec &dir, float cutoff, const ivec &bo, const ivec &bs) {
int diff = (bo.x^bs.x) | (bo.y^bs.y) | (bo.z^bs.z),
scale = worldscale-1;
if(diff&~((1<<scale)-1) || uint(bo.x|bo.y|bo.z|bs.x|bs.y|bs.z) >= uint(worldsize))
@@ -1009,16 +865,14 @@ static inline bool octacollide(physent *d, const vec &dir, float cutoff, const i
const cube *c = &worldroot[octastep(bo.x, bo.y, bo.z, scale)];
if(c->ext && c->ext->ents && mmcollide(d, dir, *c->ext->ents)) return true;
scale--;
- while(c->children && !(diff&(1<<scale)))
- {
+ while(c->children && !(diff&(1<<scale))) {
c = &c->children[octastep(bo.x, bo.y, bo.z, scale)];
if(c->ext && c->ext->ents && mmcollide(d, dir, *c->ext->ents)) return true;
scale--;
}
if(c->children) return octacollide(d, dir, cutoff, bo, bs, c->children, ivec(bo).mask(~((2<<scale)-1)), 1<<scale);
bool solid = false;
- switch(c->material&MATF_CLIP)
- {
+ switch(c->material&MATF_CLIP) {
case MAT_NOCLIP: return false;
case MAT_GAMECLIP: if(d->type==ENT_AI) solid = true; break;
case MAT_CLIP: if(d->type<ENT_CAMERA) solid = true; break;
@@ -1029,8 +883,7 @@ static inline bool octacollide(physent *d, const vec &dir, float cutoff, const i
}
// all collision happens here
-bool collide(physent *d, const vec &dir, float cutoff, bool playercol, bool insideplayercol)
-{
+bool collide(physent *d, const vec &dir, float cutoff, bool playercol, bool insideplayercol) {
collideinside = 0;
collideplayer = NULL;
collidewall = vec(0, 0, 0);
@@ -1040,11 +893,9 @@ bool collide(physent *d, const vec &dir, float cutoff, bool playercol, bool insi
return octacollide(d, dir, cutoff, bo, bs) || (playercol && plcollide(d, dir, insideplayercol));
}
-void recalcdir(physent *d, const vec &oldvel, vec &dir)
-{
+void recalcdir(physent *d, const vec &oldvel, vec &dir) {
float speed = oldvel.magnitude();
- if(speed > 1e-6f)
- {
+ if(speed > 1e-6f) {
float step = dir.magnitude();
dir = d->vel;
dir.add(d->falling);
@@ -1052,11 +903,9 @@ void recalcdir(physent *d, const vec &oldvel, vec &dir)
}
}
-void slideagainst(physent *d, vec &dir, const vec &obstacle, bool foundfloor, bool slidecollide)
-{
+void slideagainst(physent *d, vec &dir, const vec &obstacle, bool foundfloor, bool slidecollide) {
vec wall(obstacle);
- if(foundfloor ? wall.z > 0 : slidecollide)
- {
+ if(foundfloor ? wall.z > 0 : slidecollide) {
wall.z = 0;
if(!wall.iszero()) wall.normalize();
}
@@ -1067,14 +916,11 @@ void slideagainst(physent *d, vec &dir, const vec &obstacle, bool foundfloor, bo
recalcdir(d, oldvel, dir);
}
-void switchfloor(physent *d, vec &dir, const vec &floor)
-{
+void switchfloor(physent *d, vec &dir, const vec &floor) {
if(floor.z >= FLOORZ) d->falling = vec(0, 0, 0);
-
vec oldvel(d->vel);
oldvel.add(d->falling);
- if(dir.dot(floor) >= 0)
- {
+ if(dir.dot(floor) >= 0) {
if(d->physstate < PHYS_SLIDE || fabs(dir.dot(d->floor)) > 0.01f*dir.magnitude()) return;
d->vel.projectxy(floor, 0.0f);
}
@@ -1083,57 +929,46 @@ void switchfloor(physent *d, vec &dir, const vec &floor)
recalcdir(d, oldvel, dir);
}
-bool trystepup(physent *d, vec &dir, const vec &obstacle, float maxstep, const vec &floor)
-{
+bool trystepup(physent *d, vec &dir, const vec &obstacle, float maxstep, const vec &floor) {
vec old(d->o), stairdir = (obstacle.z >= 0 && obstacle.z < SLOPEZ ? vec(-obstacle.x, -obstacle.y, 0) : vec(dir.x, dir.y, 0)).rescale(1);
bool cansmooth = true;
/* check if there is space atop the stair to move to */
- if(d->physstate != PHYS_STEP_UP)
- {
+ if(d->physstate != PHYS_STEP_UP) {
vec checkdir = stairdir;
checkdir.mul(0.1f);
checkdir.z += maxstep + 0.1f;
d->o.add(checkdir);
- if(collide(d))
- {
+ if(collide(d)) {
d->o = old;
if(!collide(d, vec(0, 0, -1), SLOPEZ)) return false;
cansmooth = false;
}
}
-
- if(cansmooth)
- {
+ if(cansmooth) {
vec checkdir = stairdir;
checkdir.z += 1;
checkdir.mul(maxstep);
d->o = old;
d->o.add(checkdir);
int scale = 2;
- if(collide(d, checkdir))
- {
- if(!collide(d, vec(0, 0, -1), SLOPEZ))
- {
+ if(collide(d, checkdir)) {
+ if(!collide(d, vec(0, 0, -1), SLOPEZ)) {
d->o = old;
return false;
}
d->o.add(checkdir);
if(collide(d, vec(0, 0, -1), SLOPEZ)) scale = 1;
}
- if(scale != 1)
- {
+ if(scale != 1) {
d->o = old;
d->o.sub(checkdir.mul(vec(2, 2, 1)));
if(!collide(d, vec(0, 0, -1), SLOPEZ)) scale = 1;
}
-
d->o = old;
vec smoothdir(dir.x, dir.y, 0);
float magxy = smoothdir.magnitude();
- if(magxy > 1e-9f)
- {
- if(magxy > scale*dir.z)
- {
+ if(magxy > 1e-9f) {
+ if(magxy > scale*dir.z) {
smoothdir.mul(1/magxy);
smoothdir.z = 1.0f/scale;
smoothdir.mul(dir.magnitude()/smoothdir.magnitude());
@@ -1141,11 +976,9 @@ bool trystepup(physent *d, vec &dir, const vec &obstacle, float maxstep, const v
else smoothdir.z = dir.z;
d->o.add(smoothdir);
d->o.z += maxstep + 0.1f;
- if(!collide(d, smoothdir))
- {
+ if(!collide(d, smoothdir)) {
d->o.z -= maxstep + 0.1f;
- if(d->physstate == PHYS_FALL || d->floor != floor)
- {
+ if(d->physstate == PHYS_FALL || d->floor != floor) {
d->timeinair = 0;
d->floor = floor;
switchfloor(d, dir, d->floor);
@@ -1155,14 +988,11 @@ bool trystepup(physent *d, vec &dir, const vec &obstacle, float maxstep, const v
}
}
}
-
/* try stepping up */
d->o = old;
d->o.z += dir.magnitude();
- if(!collide(d, vec(0, 0, 1)))
- {
- if(d->physstate == PHYS_FALL || d->floor != floor)
- {
+ if(!collide(d, vec(0, 0, 1))) {
+ if(d->physstate == PHYS_FALL || d->floor != floor) {
d->timeinair = 0;
d->floor = floor;
switchfloor(d, dir, d->floor);
@@ -1174,34 +1004,28 @@ bool trystepup(physent *d, vec &dir, const vec &obstacle, float maxstep, const v
return false;
}
-bool trystepdown(physent *d, vec &dir, float step, float xy, float z, bool init = false)
-{
+bool trystepdown(physent *d, vec &dir, float step, float xy, float z, bool init = false) {
vec stepdir(dir.x, dir.y, 0);
stepdir.z = -stepdir.magnitude2()*z/xy;
if(!stepdir.z) return false;
stepdir.normalize();
-
vec old(d->o);
d->o.add(vec(stepdir).mul(STAIRHEIGHT/fabs(stepdir.z))).z -= STAIRHEIGHT;
d->zmargin = -STAIRHEIGHT;
- if(collide(d, vec(0, 0, -1), SLOPEZ))
- {
+ if(collide(d, vec(0, 0, -1), SLOPEZ)) {
d->o = old;
d->o.add(vec(stepdir).mul(step));
d->zmargin = 0;
- if(!collide(d, vec(0, 0, -1)))
- {
+ if(!collide(d, vec(0, 0, -1))) {
vec stepfloor(stepdir);
stepfloor.mul(-stepfloor.z).z += 1;
stepfloor.normalize();
- if(d->physstate >= PHYS_SLOPE && d->floor != stepfloor)
- {
+ if(d->physstate >= PHYS_SLOPE && d->floor != stepfloor) {
// prevent alternating step-down/step-up states if player would keep bumping into the same floor
vec stepped(d->o);
d->o.z -= 0.5f;
d->zmargin = -0.5f;
- if(collide(d, stepdir) && collidewall == d->floor)
- {
+ if(collide(d, stepdir) && collidewall == d->floor) {
d->o = old;
if(!init) { d->o.x += dir.x; d->o.y += dir.y; if(dir.z <= 0 || collide(d, dir)) d->o.z += dir.z; }
d->zmargin = 0;
@@ -1225,14 +1049,12 @@ bool trystepdown(physent *d, vec &dir, float step, float xy, float z, bool init
return false;
}
-bool trystepdown(physent *d, vec &dir, bool init = false)
-{
+bool trystepdown(physent *d, vec &dir, bool init = false) {
if((!d->move && !d->strafe) || !game::allowmove(d)) return false;
vec old(d->o);
d->o.z -= STAIRHEIGHT;
d->zmargin = -STAIRHEIGHT;
- if(!collide(d, vec(0, 0, -1), SLOPEZ))
- {
+ if(!collide(d, vec(0, 0, -1), SLOPEZ)) {
d->o = old;
d->zmargin = 0;
return false;
@@ -1251,10 +1073,8 @@ bool trystepdown(physent *d, vec &dir, bool init = false)
return false;
}
-void falling(physent *d, vec &dir, const vec &floor)
-{
- if(floor.z > 0.0f && floor.z < SLOPEZ)
- {
+void falling(physent *d, vec &dir, const vec &floor) {
+ if(floor.z > 0.0f && floor.z < SLOPEZ) {
if(floor.z >= WALLZ) switchfloor(d, dir, floor);
d->timeinair = 0;
d->physstate = PHYS_SLIDE;
@@ -1264,11 +1084,9 @@ void falling(physent *d, vec &dir, const vec &floor)
d->physstate = PHYS_FALL;
}
-void landing(physent *d, vec &dir, const vec &floor, bool collided)
-{
+void landing(physent *d, vec &dir, const vec &floor, bool collided) {
#if 0
- if(d->physstate == PHYS_FALL)
- {
+ if(d->physstate == PHYS_FALL) {
d->timeinair = 0;
if(dir.z < 0.0f) dir.z = d->vel.z = 0.0f;
}
@@ -1280,40 +1098,32 @@ void landing(physent *d, vec &dir, const vec &floor, bool collided)
d->floor = floor;
}
-bool findfloor(physent *d, bool collided, const vec &obstacle, bool &slide, vec &floor)
-{
+bool findfloor(physent *d, bool collided, const vec &obstacle, bool &slide, vec &floor) {
bool found = false;
vec moved(d->o);
d->o.z -= 0.1f;
- if(collide(d, vec(0, 0, -1), d->physstate == PHYS_SLOPE || d->physstate == PHYS_STEP_DOWN ? SLOPEZ : FLOORZ))
- {
+ if(collide(d, vec(0, 0, -1), d->physstate == PHYS_SLOPE || d->physstate == PHYS_STEP_DOWN ? SLOPEZ : FLOORZ)) {
floor = collidewall;
found = true;
}
- else if(collided && obstacle.z >= SLOPEZ)
- {
+ else if(collided && obstacle.z >= SLOPEZ) {
floor = obstacle;
found = true;
slide = false;
}
- else if(d->physstate == PHYS_STEP_UP || d->physstate == PHYS_SLIDE)
- {
- if(collide(d, vec(0, 0, -1)) && collidewall.z > 0.0f)
- {
+ else if(d->physstate == PHYS_STEP_UP || d->physstate == PHYS_SLIDE) {
+ if(collide(d, vec(0, 0, -1)) && collidewall.z > 0.0f) {
floor = collidewall;
if(floor.z >= SLOPEZ) found = true;
}
}
- else if(d->physstate >= PHYS_SLOPE && d->floor.z < 1.0f)
- {
- if(collide(d, vec(d->floor).neg(), 0.95f) || collide(d, vec(0, 0, -1)))
- {
+ else if(d->physstate >= PHYS_SLOPE && d->floor.z < 1.0f) {
+ if(collide(d, vec(d->floor).neg(), 0.95f) || collide(d, vec(0, 0, -1))) {
floor = collidewall;
if(floor.z >= SLOPEZ && floor.z < 1.0f) found = true;
}
}
- if(collided && (!found || obstacle.z > floor.z))
- {
+ if(collided && (!found || obstacle.z > floor.z)) {
floor = obstacle;
slide = !found && (floor.z < WALLZ || floor.z >= SLOPEZ);
}
@@ -1321,49 +1131,41 @@ bool findfloor(physent *d, bool collided, const vec &obstacle, bool &slide, vec
return found;
}
-bool move(physent *d, vec &dir)
-{
+bool move(physent *d, vec &dir) {
vec old(d->o);
bool collided = false, slidecollide = false;
vec obstacle = vec(0, 0, 0);
d->o.add(dir);
- if(collide(d, dir) || ((d->type==ENT_AI || d->type==ENT_INANIMATE) && collide(d, vec(0, 0, 0), 0, false)))
- {
+ if(collide(d, dir) || ((d->type==ENT_AI || d->type==ENT_INANIMATE) && collide(d, vec(0, 0, 0), 0, false))) {
obstacle = collidewall;
/* check to see if there is an obstacle that would prevent this one from being used as a floor (or ceiling bump) */
- if(d->type==ENT_PLAYER && ((collidewall.z>=SLOPEZ && dir.z<0) || (collidewall.z<=-SLOPEZ && dir.z>0)) && (dir.x || dir.y) && collide(d, vec(dir.x, dir.y, 0)))
- {
+ if(d->type==ENT_PLAYER && ((collidewall.z>=SLOPEZ && dir.z<0) || (collidewall.z<=-SLOPEZ && dir.z>0)) && (dir.x || dir.y) && collide(d, vec(dir.x, dir.y, 0))) {
if(collidewall.dot(dir) >= 0) slidecollide = true;
obstacle = collidewall;
}
d->o = old;
d->o.z -= STAIRHEIGHT;
d->zmargin = -STAIRHEIGHT;
- if(d->physstate == PHYS_SLOPE || d->physstate == PHYS_FLOOR || (collide(d, vec(0, 0, -1), SLOPEZ) && (d->physstate==PHYS_STEP_UP || d->physstate==PHYS_STEP_DOWN || collidewall.z>=FLOORZ)))
- {
+ if(d->physstate == PHYS_SLOPE || d->physstate == PHYS_FLOOR || (collide(d, vec(0, 0, -1), SLOPEZ) && (d->physstate==PHYS_STEP_UP || d->physstate==PHYS_STEP_DOWN || collidewall.z>=FLOORZ))) {
d->o = old;
d->zmargin = 0;
if(trystepup(d, dir, obstacle, STAIRHEIGHT, d->physstate == PHYS_SLOPE || d->physstate == PHYS_FLOOR ? d->floor : vec(collidewall))) return true;
}
- else
- {
+ else {
d->o = old;
d->zmargin = 0;
}
/* can't step over the obstacle, so just slide against it */
collided = true;
}
- else if(d->physstate == PHYS_STEP_UP)
- {
- if(collide(d, vec(0, 0, -1), SLOPEZ))
- {
+ else if(d->physstate == PHYS_STEP_UP) {
+ if(collide(d, vec(0, 0, -1), SLOPEZ)) {
d->o = old;
if(trystepup(d, dir, vec(0, 0, 1), STAIRHEIGHT, vec(collidewall))) return true;
d->o.add(dir);
}
}
- else if(d->physstate == PHYS_STEP_DOWN && dir.dot(d->floor) <= 1e-6f)
- {
+ else if(d->physstate == PHYS_STEP_DOWN && dir.dot(d->floor) <= 1e-6f) {
vec moved(d->o);
d->o = old;
if(trystepdown(d, dir)) return true;
@@ -1372,8 +1174,7 @@ bool move(physent *d, vec &dir)
vec floor(0, 0, 0);
bool slide = collided,
found = findfloor(d, collided, obstacle, slide, floor);
- if(slide || (!collided && floor.z > 0 && floor.z < WALLZ))
- {
+ if(slide || (!collided && floor.z > 0 && floor.z < WALLZ)) {
slideagainst(d, dir, slide ? obstacle : floor, found, slidecollide);
//if(d->type == ENT_AI || d->type == ENT_INANIMATE)
d->blocked = true;
@@ -1383,21 +1184,17 @@ bool move(physent *d, vec &dir)
return !collided;
}
-bool bounce(physent *d, float secs, float elasticity, float grav)
-{
+bool bounce(physent *d, float secs, float elasticity, float grav) {
// make sure bouncers don't start inside geometry
if(d->physstate!=PHYS_BOUNCE && collide(d, vec(0, 0, 0), 0, false)) return true;
d->vel.z -= grav*GRAVITY*secs;
vec old(d->o);
- loopi(2)
- {
+ loopi(2) {
vec dir(d->vel);
dir.mul(secs);
d->o.add(dir);
- if(!collide(d, dir, 0, true, true))
- {
- if(collideinside)
- {
+ if(!collide(d, dir, 0, true, true)) {
+ if(collideinside) {
d->o = old;
d->vel.mul(-elasticity);
}
@@ -1411,8 +1208,7 @@ bool bounce(physent *d, float secs, float elasticity, float grav)
d->vel.mul(k);
d->vel.sub(vec(collidewall).mul(elasticity*2.0f*c));
}
- if(d->physstate!=PHYS_BOUNCE)
- {
+ if(d->physstate!=PHYS_BOUNCE) {
// make sure bouncers don't start inside geometry
if(d->o == old) return !collideplayer;
d->physstate = PHYS_BOUNCE;
@@ -1420,8 +1216,7 @@ bool bounce(physent *d, float secs, float elasticity, float grav)
return collideplayer!=NULL;
}
-void avoidcollision(physent *d, const vec &dir, physent *obstacle, float space)
-{
+void avoidcollision(physent *d, const vec &dir, physent *obstacle, float space) {
float rad = obstacle->radius+d->radius;
vec bbmin(obstacle->o);
bbmin.x -= rad;
@@ -1433,31 +1228,24 @@ void avoidcollision(physent *d, const vec &dir, physent *obstacle, float space)
bbmax.y += rad;
bbmax.z += obstacle->aboveeye+d->eyeheight;
bbmax.add(space);
-
loopi(3) if(d->o[i] <= bbmin[i] || d->o[i] >= bbmax[i]) return;
-
float mindist = 1e16f;
- loopi(3) if(dir[i] != 0)
- {
+ loopi(3) if(dir[i] != 0) {
float dist = ((dir[i] > 0 ? bbmax[i] : bbmin[i]) - d->o[i]) / dir[i];
mindist = min(mindist, dist);
}
if(mindist >= 0.0f && mindist < 1e15f) d->o.add(vec(dir).mul(mindist));
}
-bool movecamera(physent *pl, const vec &dir, float dist, float stepdist)
-{
+bool movecamera(physent *pl, const vec &dir, float dist, float stepdist) {
int steps = (int)ceil(dist/stepdist);
if(steps <= 0) return true;
-
vec d(dir);
d.mul(dist/steps);
- loopi(steps)
- {
+ loopi(steps) {
vec oldpos(pl->o);
pl->o.add(d);
- if(collide(pl, vec(0, 0, 0), 0, false))
- {
+ if(collide(pl, vec(0, 0, 0), 0, false)) {
pl->o = oldpos;
return false;
}
@@ -1465,22 +1253,18 @@ bool movecamera(physent *pl, const vec &dir, float dist, float stepdist)
return true;
}
-void dropenttofloor(entity *e)
-{
+void dropenttofloor(entity *e) {
float radius = 1.0f;
float height = 4.0f;
vec o = e->o;
- static struct dropent : physent
- {
- dropent()
- {
+ static struct dropent : physent {
+ dropent() {
type = ENT_BOUNCE;
vel = vec(0, 0, -1);
}
} d;
d.o = o;
- if(!insideworld(d.o))
- {
+ if(!insideworld(d.o)) {
if(d.o.z < worldsize) return;
d.o.z = worldsize - 1e-3f;
if(!insideworld(d.o)) return;
@@ -1495,35 +1279,27 @@ void dropenttofloor(entity *e)
o = d.o;
}
-void vecfromyawpitch(float yaw, float pitch, int move, int strafe, vec &m)
-{
- if(move)
- {
+void vecfromyawpitch(float yaw, float pitch, int move, int strafe, vec &m) {
+ if(move) {
m.x = move*-sinf(RAD*yaw);
m.y = move*cosf(RAD*yaw);
}
else m.x = m.y = 0;
-
- if(pitch)
- {
+ if(pitch) {
m.x *= cosf(RAD*pitch);
m.y *= cosf(RAD*pitch);
m.z = move*sinf(RAD*pitch);
}
else m.z = 0;
-
- if(strafe)
- {
+ if(strafe) {
m.x += strafe*cosf(RAD*yaw);
m.y += strafe*sinf(RAD*yaw);
}
}
-void vectoyawpitch(const vec &v, float &yaw, float &pitch)
-{
+void vectoyawpitch(const vec &v, float &yaw, float &pitch) {
if(v.iszero()) yaw = pitch = 0;
- else
- {
+ else {
yaw = -atan2(v.x, v.y)/RAD;
pitch = asin(v.z/v.magnitude())/RAD;
}
@@ -1536,51 +1312,36 @@ FVAR(straferoll, 0, 0.033f, 90);
FVAR(faderoll, 0, 0.95f, 1);
VAR(floatspeed, 1, 100, 10000);
-void modifyvelocity(physent *pl, bool local, bool floating, int curtime)
-{
+void modifyvelocity(physent *pl, bool local, bool floating, int curtime) {
bool allowmove = game::allowmove(pl);
- if(floating)
- {
- if(pl->jumping && allowmove)
- {
+ if(floating) {
+ if(pl->jumping && allowmove) {
pl->jumping = false;
pl->vel.z = max(pl->vel.z, JUMPVEL);
}
}
- else if(pl->physstate >= PHYS_SLOPE)
- {
+ else if(pl->physstate >= PHYS_SLOPE) {
if(!pl->inwater) pl->vel.div(8);
- if(pl->jumping && allowmove)
- {
+ if(pl->jumping && allowmove) {
pl->jumping = false;
-
pl->vel.z = max(pl->vel.z, JUMPVEL); // physics impulse upwards
-
game::physicstrigger(pl, local, 1);
}
}
if(!floating && pl->physstate == PHYS_FALL) pl->timeinair = min(pl->timeinair + curtime, 1000);
-
vec m(0.0f, 0.0f, 0.0f);
- if((pl->move || pl->strafe) && allowmove)
- {
+ if((pl->move || pl->strafe) && allowmove) {
vecfromyawpitch(pl->yaw, floating || pl->type==ENT_CAMERA ? pl->pitch : 0, pl->move, pl->strafe, m);
-
if(!floating && pl->physstate >= PHYS_SLOPE)
m.z = -(m.x*pl->floor.x + m.y*pl->floor.y)/pl->floor.z; // move up or down slopes in air
-
m.normalize();
}
-
vec d(m);
speedmodifier*=(pl->physstate!=PHYS_FLOOR)*(speedmodifier>0);
speedmodifier=(speedmodifier>100.0f)?100.0f:speedmodifier;
d.mul(pl->maxspeed + speedmodifier);
-
- if(pl->type==ENT_PLAYER)
- {
- if(floating)
- {
+ if(pl->type==ENT_PLAYER) {
+ if(floating) {
if(pl==player) d.mul(floatspeed/100.0f);
}
else if(allowmove) d.mul((pl->move && !pl->strafe ? 1.3f : 1.0f) * (pl->physstate < PHYS_SLOPE ? 1.3f : 1.0f));
@@ -1589,22 +1350,18 @@ void modifyvelocity(physent *pl, bool local, bool floating, int curtime)
pl->vel.lerp(d, pl->vel, pow(1 - 1/fric, curtime/20.0f));
}
-void modifygravity(physent *pl, int curtime)
-{
+void modifygravity(physent *pl, int curtime) {
float secs = curtime/1000.0f;
vec g(0, 0, 0);
if(pl->physstate == PHYS_FALL) g.z -= GRAVITY*secs;
- else if(pl->floor.z > 0 && pl->floor.z < FLOORZ)
- {
+ else if(pl->floor.z > 0 && pl->floor.z < FLOORZ) {
g.z = -1;
g.project(pl->floor);
g.normalize();
g.mul(GRAVITY*secs);
}
if(!game::allowmove(pl) || (!pl->move && !pl->strafe)) pl->falling.add(g);
-
- if(pl->physstate >= PHYS_SLOPE)
- {
+ if(pl->physstate >= PHYS_SLOPE) {
float fric = 6.0f,
c = clamp((pl->floor.z - SLOPEZ)/(FLOORZ-SLOPEZ), 0.0f, 1.0f);
pl->falling.mul(pow(1 - c/fric, curtime/20.0f));
@@ -1615,71 +1372,53 @@ void modifygravity(physent *pl, int curtime)
// moveres indicated the physics precision (which is lower for monsters and multiplayer prediction)
// local is false for multiplayer prediction
-bool moveplayer(physent *pl, int moveres, bool local, int curtime)
-{
+bool moveplayer(physent *pl, int moveres, bool local, int curtime) {
int material = lookupmaterial(vec(pl->o.x, pl->o.y, pl->o.z + (3*pl->aboveeye - pl->eyeheight)/4));
bool floating = pl->type==ENT_PLAYER && (pl->state==CS_EDITING || pl->state==CS_SPECTATOR);
float secs = curtime/1000.f;
-
// apply gravity
if(!floating) modifygravity(pl, curtime);
// apply any player generated changes in velocity
modifyvelocity(pl, local, floating, curtime);
-
vec d(pl->vel);
if(!floating) d.mul(0.5f);
d.add(pl->falling);
d.mul(secs);
-
pl->blocked = false;
-
- if(floating) // just apply velocity
- {
- if(pl->physstate != PHYS_FLOAT)
- {
+ if(floating) { // just apply velocity {
+ if(pl->physstate != PHYS_FLOAT) {
pl->physstate = PHYS_FLOAT;
pl->timeinair = 0;
pl->falling = vec(0, 0, 0);
}
pl->o.add(d);
}
- else // apply velocity with collision
- {
+ else { // apply velocity with collision {
const float f = 1.0f/moveres;
const int timeinair = pl->timeinair;
int collisions = 0;
-
d.mul(f);
loopi(moveres) if(!move(pl, d) && ++collisions<5) i--; // discrete steps collision detection & sliding
- if(timeinair > 800 && !pl->timeinair) // if we land after long time must have been a high jump, make thud sound
- {
+ if(timeinair > 800 && !pl->timeinair) { // if we land after long time must have been a high jump, make thud sound {
game::physicstrigger(pl, local, -1);
}
}
-
if(pl->state==CS_ALIVE) updatedynentcache(pl);
-
// automatically apply smooth roll when strafing
-
if(pl->strafe && maxroll) pl->roll = clamp(pl->roll - pow(clamp(1.0f + pl->strafe*pl->roll/maxroll, 0.0f, 1.0f), 0.33f)*pl->strafe*curtime*straferoll, -maxroll, maxroll);
else pl->roll *= curtime == PHYSFRAMETIME ? faderoll : pow(faderoll, curtime/float(PHYSFRAMETIME));
-
if(pl->inwater) game::physicstrigger(pl, local, 0, pl->inwater);
pl->inwater = MAT_AIR;
-
if(pl->state==CS_ALIVE && (pl->o.z < 0 || material&MAT_DEATH)) game::suicide(pl);
-
return true;
}
int physsteps = 0, physframetime = PHYSFRAMETIME, lastphysframe = 0;
-void physicsframe() // optimally schedule physics frames inside the graphics frames
-{
+void physicsframe() { // optimally schedule physics frames inside the graphics frames {
int diff = lastmillis - lastphysframe;
if(diff <= 0) physsteps = 0;
- else
- {
+ else {
physframetime = clamp(game::scaletime(PHYSFRAMETIME)/100, 1, PHYSFRAMETIME);
physsteps = (diff + physframetime - 1)/physframetime;
lastphysframe += physsteps * physframetime;
@@ -1689,50 +1428,39 @@ void physicsframe() // optimally schedule physics frames inside the graphics
VAR(physinterp, 0, 1, 1);
-void interppos(physent *pl)
-{
+void interppos(physent *pl) {
pl->o = pl->newpos;
-
int diff = lastphysframe - lastmillis;
if(diff <= 0 || !physinterp) return;
-
vec deltapos(pl->deltapos);
deltapos.mul(min(diff, physframetime)/float(physframetime));
pl->o.add(deltapos);
}
-void moveplayer(physent *pl, int moveres, bool local)
-{
- if(physsteps <= 0)
- {
+void moveplayer(physent *pl, int moveres, bool local) {
+ if(physsteps <= 0) {
if(local) interppos(pl);
return;
}
-
if(local) pl->o = pl->newpos;
loopi(physsteps-1) moveplayer(pl, moveres, local, physframetime);
if(local) pl->deltapos = pl->o;
moveplayer(pl, moveres, local, physframetime);
- if(local)
- {
+ if(local) {
pl->newpos = pl->o;
pl->deltapos.sub(pl->newpos);
interppos(pl);
}
}
-bool bounce(physent *d, float elasticity, float grav)
-{
- if(physsteps <= 0)
- {
+bool bounce(physent *d, float elasticity, float grav) {
+ if(physsteps <= 0) {
interppos(d);
return false;
}
-
d->o = d->newpos;
bool hitplayer = false;
- loopi(physsteps-1)
- {
+ loopi(physsteps-1) {
if(bounce(d, physframetime/1000.0f, elasticity, grav)) hitplayer = true;
}
d->deltapos = d->o;
@@ -1743,8 +1471,7 @@ bool bounce(physent *d, float elasticity, float grav)
return hitplayer;
}
-void updatephysstate(physent *d)
-{
+void updatephysstate(physent *d) {
if(d->physstate == PHYS_FALL) return;
d->timeinair = 0;
vec old(d->o);
@@ -1752,8 +1479,7 @@ void updatephysstate(physent *d)
* May be inaccurate since movement collisions are not considered.
* If good floor is not found, just keep the old floor and hope it's correct enough.
*/
- switch(d->physstate)
- {
+ switch(d->physstate) {
case PHYS_SLOPE:
case PHYS_FLOOR:
case PHYS_STEP_DOWN:
@@ -1761,13 +1487,11 @@ void updatephysstate(physent *d)
if(collide(d, vec(0, 0, -1), d->physstate == PHYS_SLOPE || d->physstate == PHYS_STEP_DOWN ? SLOPEZ : FLOORZ))
d->floor = collidewall;
break;
-
case PHYS_STEP_UP:
d->o.z -= STAIRHEIGHT+0.15f;
if(collide(d, vec(0, 0, -1), SLOPEZ))
d->floor = collidewall;
break;
-
case PHYS_SLIDE:
d->o.z -= 0.15f;
if(collide(d, vec(0, 0, -1)) && collidewall.z < SLOPEZ)
@@ -1788,30 +1512,23 @@ dir(right, strafe, -1, k_right, k_left);
ICOMMAND(jump, "D", (int *down), { if(!*down || game::canjump()) player->jumping = *down!=0; });
ICOMMAND(attack, "D", (int *down), { game::doattack(*down!=0); });
-bool entinmap(dynent *d, bool avoidplayers) // brute force but effective way to find a free spawn spot in the map
-{
+bool entinmap(dynent *d, bool avoidplayers) { // brute force but effective way to find a free spawn spot in the map {
d->o.z += d->eyeheight; // pos specified is at feet
vec orig = d->o;
- loopi(100) // try max 100 times
- {
- if(i)
- {
+ loopi(100) { // try max 100 times {
+ if(i) {
d->o = orig;
d->o.x += (rnd(21)-10)*i/5; // increasing distance
d->o.y += (rnd(21)-10)*i/5;
d->o.z += (rnd(21)-10)*i/5;
}
-
- if(!collide(d) && !collideinside)
- {
- if(collideplayer)
- {
+ if(!collide(d) && !collideinside) {
+ if(collideplayer) {
if(!avoidplayers) continue;
d->o = orig;
d->resetinterp();
return false;
}
-
d->resetinterp();
return true;
}