summaryrefslogtreecommitdiff
path: root/src/fpsgame
diff options
context:
space:
mode:
authorxolatile2025-08-06 22:54:55 +0200
committerxolatile2025-08-06 22:54:55 +0200
commit0a1172b75f571685c264a8b9d8ee224bbf11381f (patch)
treed041fdc68a60f0ebb48a3852bbcce6d9432f83d5 /src/fpsgame
parentaffde05dc07a94643f1fd2751b2b441f57f73d7d (diff)
downloadxolatile-badassbug-0a1172b75f571685c264a8b9d8ee224bbf11381f.tar.xz
xolatile-badassbug-0a1172b75f571685c264a8b9d8ee224bbf11381f.tar.zst
Please do not hate me, it makes sense...
Diffstat (limited to 'src/fpsgame')
-rw-r--r--src/fpsgame/ai.cpp828
-rw-r--r--src/fpsgame/ai.h160
-rw-r--r--src/fpsgame/aiman.h147
-rw-r--r--src/fpsgame/client.cpp874
-rw-r--r--src/fpsgame/entities.cpp211
-rw-r--r--src/fpsgame/extinfo.h57
-rw-r--r--src/fpsgame/fps.cpp654
-rw-r--r--src/fpsgame/game.h216
-rw-r--r--src/fpsgame/render.cpp224
-rw-r--r--src/fpsgame/scoreboard.cpp263
-rw-r--r--src/fpsgame/server.cpp1779
-rw-r--r--src/fpsgame/waypoint.cpp424
-rw-r--r--src/fpsgame/weapon.cpp460
13 files changed, 1719 insertions, 4578 deletions
diff --git a/src/fpsgame/ai.cpp b/src/fpsgame/ai.cpp
index 0886245..b4e631b 100644
--- a/src/fpsgame/ai.cpp
+++ b/src/fpsgame/ai.cpp
@@ -1,100 +1,68 @@
#include "game.h"
-namespace ai
-{
+namespace ai {
using namespace game;
-
avoidset obstacles;
int updatemillis = 0, iteration = 0, itermillis = 0, forcegun = -1;
vec aitarget(0, 0, 0);
-
VAR(aidebug, 0, 0, 6);
VAR(aiforcegun, -1, -1, NUMGUNS-1);
-
ICOMMAND(addbot, "s", (char *s), addmsg(N_ADDBOT, "ri", *s ? clamp(parseint(s), 1, 101) : -1));
ICOMMAND(delbot, "", (), addmsg(N_DELBOT, "r"));
ICOMMAND(botlimit, "i", (int *n), addmsg(N_BOTLIMIT, "ri", *n));
ICOMMAND(botbalance, "i", (int *n), addmsg(N_BOTBALANCE, "ri", *n));
-
- float viewdist(int x)
- {
+ float viewdist(int x) {
return x <= 100 ? clamp((SIGHTMIN+(SIGHTMAX-SIGHTMIN))/100.f*float(x), float(SIGHTMIN), 10000.0f) : 10000.0f;
}
-
- float viewfieldx(int x)
- {
+ float viewfieldx(int x) {
return x <= 100 ? clamp((VIEWMIN+(VIEWMAX-VIEWMIN))/100.f*float(x), float(VIEWMIN), float(VIEWMAX)) : float(VIEWMAX);
}
-
- float viewfieldy(int x)
- {
+ float viewfieldy(int x) {
return viewfieldx(x)*3.f/4.f;
}
-
- bool canmove(fpsent *d)
- {
+ bool canmove(fpsent *d) {
return d->state != CS_DEAD && !intermission;
}
-
- float weapmindist(int weap)
- {
+ float weapmindist(int weap) {
return max(int(guns[weap].exprad), 2);
}
-
- float weapmaxdist(int weap)
- {
+ float weapmaxdist(int weap) {
return guns[weap].range + 4;
}
-
- bool weaprange(fpsent *d, int weap, float dist)
- {
+ bool weaprange(fpsent *d, int weap, float dist) {
float mindist = weapmindist(weap), maxdist = weapmaxdist(weap);
return dist >= mindist*mindist && dist <= maxdist*maxdist;
}
-
- bool targetable(fpsent *d, fpsent *e)
- {
+ bool targetable(fpsent *d, fpsent *e) {
if(d == e || !canmove(d)) return false;
return e->state == CS_ALIVE && !isteam(d->team, e->team);
}
-
- bool getsight(vec &o, float yaw, float pitch, vec &q, vec &v, float mdist, float fovx, float fovy)
- {
+ bool getsight(vec &o, float yaw, float pitch, vec &q, vec &v, float mdist, float fovx, float fovy) {
float dist = o.dist(q);
-
- if(dist <= mdist)
- {
+ if(dist <= mdist) {
float x = fmod(fabs(asin((q.z-o.z)/dist)/RAD-pitch), 360);
float y = fmod(fabs(-atan2(q.x-o.x, q.y-o.y)/RAD-yaw), 360);
if(min(x, 360-x) <= fovx && min(y, 360-y) <= fovy) return raycubelos(o, q, v);
}
return false;
}
-
- bool cansee(fpsent *d, vec &x, vec &y, vec &targ)
- {
+ bool cansee(fpsent *d, vec &x, vec &y, vec &targ) {
aistate &b = d->ai->getstate();
if(canmove(d) && b.type != AI_S_WAIT)
return getsight(x, d->yaw, d->pitch, y, targ, d->ai->views[2], d->ai->views[0], d->ai->views[1]);
return false;
}
-
- bool canshoot(fpsent *d, fpsent *e)
- {
+ bool canshoot(fpsent *d, fpsent *e) {
if(weaprange(d, d->gunselect, e->o.squaredist(d->o)) && targetable(d, e))
return d->ammo[d->gunselect] > 0 && lastmillis - d->lastaction >= d->gunwait;
return false;
}
-
- bool canshoot(fpsent *d)
- {
+ bool canshoot(fpsent *d) {
return !d->ai->becareful && d->ammo[d->gunselect] > 0 && lastmillis - d->lastaction >= d->gunwait;
}
-
- bool hastarget(fpsent *d, aistate &b, fpsent *e, float yaw, float pitch, float dist)
- { // add margins of error
- if(weaprange(d, d->gunselect, dist) || (d->skill <= 100 && !rnd(d->skill)))
- {
+ bool hastarget(fpsent *d, aistate &b, fpsent *e, float yaw, float pitch, float dist) {
+ // add margins of error
+ if(weaprange(d, d->gunselect, dist) || (d->skill <= 100 && !rnd(d->skill))) {
if(d->gunselect == GUN_FIST) return true;
float skew = clamp(float(lastmillis-d->ai->enemymillis)/float((d->skill*guns[d->gunselect].attackdelay/200.f)), 0.f, guns[d->gunselect].projspeed ? 0.25f : 1e16f),
offy = yaw-d->yaw, offp = pitch-d->pitch;
@@ -104,16 +72,12 @@ namespace ai
}
return false;
}
-
- vec getaimpos(fpsent *d, fpsent *e)
- {
+ vec getaimpos(fpsent *d, fpsent *e) {
vec o = e->o;
if(d->gunselect == GUN_RL) o.z += (e->aboveeye*0.2f)-(0.8f*d->eyeheight);
else if(d->gunselect != GUN_GL) o.z += (e->aboveeye-e->eyeheight)*0.5f;
- if(d->skill <= 100)
- {
- if(lastmillis >= d->ai->lastaimrnd)
- {
+ if(d->skill <= 100) {
+ if(lastmillis >= d->ai->lastaimrnd) {
const int aiskew[NUMGUNS] = { 1, 10, 50, 5, 20, 1, 100 };
#define rndaioffset(r) ((rnd(int(r*aiskew[d->gunselect]*2)+1)-(r*aiskew[d->gunselect]))*(1.f/float(max(d->skill, 1))))
loopk(3) d->ai->aimrnd[k] = rndaioffset(e->radius);
@@ -124,55 +88,39 @@ namespace ai
}
return o;
}
-
- void create(fpsent *d)
- {
+ void create(fpsent *d) {
if(!d->ai) d->ai = new aiinfo;
}
-
- void destroy(fpsent *d)
- {
+ void destroy(fpsent *d) {
if(d->ai) DELETEP(d->ai);
}
-
- void init(fpsent *d, int at, int ocn, int sk, int bn, int pm, const char *name, const char *team)
- {
+ void init(fpsent *d, int at, int ocn, int sk, int bn, int pm, const char *name, const char *team) {
loadwaypoints();
-
fpsent *o = newclient(ocn);
-
d->aitype = at;
-
bool resetthisguy = false;
- if(!d->name[0])
- {
+ if(!d->name[0]) {
if(aidebug) conoutf(CON_DEBUG, "%s assigned to %s at skill %d", colorname(d, name), o ? colorname(o) : "?", sk);
else conoutf("\f0join:\f7 %s", colorname(d, name));
resetthisguy = true;
}
- else
- {
- if(d->ownernum != ocn)
- {
+ else {
+ if(d->ownernum != ocn) {
if(aidebug) conoutf(CON_DEBUG, "%s reassigned to %s", colorname(d, name), o ? colorname(o) : "?");
resetthisguy = true;
}
if(d->skill != sk && aidebug) conoutf(CON_DEBUG, "%s changed skill to %d", colorname(d, name), sk);
}
-
copystring(d->name, name, MAXNAMELEN+1);
copystring(d->team, team, MAXTEAMLEN+1);
d->ownernum = ocn;
d->plag = 0;
d->skill = sk;
d->playermodel = 0;
-
if(resetthisguy) removeweapons(d);
- if(d->ownernum >= 0 && player1->clientnum == d->ownernum)
- {
+ if(d->ownernum >= 0 && player1->clientnum == d->ownernum) {
create(d);
- if(d->ai)
- {
+ if(d->ai) {
d->ai->views[0] = viewfieldx(d->skill);
d->ai->views[1] = viewfieldy(d->skill);
d->ai->views[2] = viewdist(d->skill);
@@ -180,20 +128,15 @@ namespace ai
}
else if(d->ai) destroy(d);
}
-
- void update()
- {
+ void update() {
if(intermission) { loopv(players) if(players[i]->ai) players[i]->stopmoving(); }
- else // fixed rate logic done out-of-sequence at 1 frame per second for each ai
- {
- if(totalmillis-updatemillis > 1000)
- {
+ else { // fixed rate logic done out-of-sequence at 1 frame per second for each ai {
+ if(totalmillis-updatemillis > 1000) {
avoid();
forcegun = multiplayer(false) ? -1 : aiforcegun;
updatemillis = totalmillis;
}
- if(!iteration && totalmillis-itermillis > 1000)
- {
+ if(!iteration && totalmillis-itermillis > 1000) {
iteration = 1;
itermillis = totalmillis;
}
@@ -202,12 +145,10 @@ namespace ai
if(++iteration > count) iteration = 0;
}
}
-
- bool checkothers(vector<int> &targets, fpsent *d, int state, int targtype, int target, bool teams, int *members)
- { // checks the states of other ai for a match
+ bool checkothers(vector<int> &targets, fpsent *d, int state, int targtype, int target, bool teams, int *members) {
+ // checks the states of other ai for a match
targets.setsize(0);
- loopv(players)
- {
+ loopv(players) {
fpsent *e = players[i];
if(targets.find(e->clientnum) >= 0) continue;
if(teams && d && !isteam(d->team, e->team)) continue;
@@ -221,13 +162,10 @@ namespace ai
}
return !targets.empty();
}
-
- bool makeroute(fpsent *d, aistate &b, int node, bool changed, int retries)
- {
+ bool makeroute(fpsent *d, aistate &b, int node, bool changed, int retries) {
if(!iswaypoint(d->lastnode)) return false;
if(changed && d->ai->route.length() > 1 && d->ai->route[0] == node) return true;
- if(route(d, d->lastnode, node, d->ai->route, obstacles, retries))
- {
+ if(route(d, d->lastnode, node, d->ai->route, obstacles, retries)) {
b.override = false;
return true;
}
@@ -235,51 +173,37 @@ namespace ai
if(retries <= 1) return makeroute(d, b, node, false, retries+1);
return false;
}
-
- bool makeroute(fpsent *d, aistate &b, const vec &pos, bool changed, int retries)
- {
+ bool makeroute(fpsent *d, aistate &b, const vec &pos, bool changed, int retries) {
int node = closestwaypoint(pos, SIGHTMIN, true);
return makeroute(d, b, node, changed, retries);
}
-
- bool randomnode(fpsent *d, aistate &b, const vec &pos, float guard, float wander)
- {
+ bool randomnode(fpsent *d, aistate &b, const vec &pos, float guard, float wander) {
static vector<int> candidates;
candidates.setsize(0);
findwaypointswithin(pos, guard, wander, candidates);
-
- while(!candidates.empty())
- {
+ while(!candidates.empty()) {
int w = rnd(candidates.length()), n = candidates.removeunordered(w);
if(n != d->lastnode && !d->ai->hasprevnode(n) && !obstacles.find(n, d) && makeroute(d, b, n)) return true;
}
return false;
}
-
- bool randomnode(fpsent *d, aistate &b, float guard, float wander)
- {
+ bool randomnode(fpsent *d, aistate &b, float guard, float wander) {
return randomnode(d, b, d->feetpos(), guard, wander);
}
-
- bool badhealth(fpsent *d)
- {
+ bool badhealth(fpsent *d) {
if(d->skill <= 100) return d->health <= (111-d->skill)/4;
return false;
}
-
- bool enemy(fpsent *d, aistate &b, const vec &pos, float guard = SIGHTMIN, int pursue = 0)
- {
+ bool enemy(fpsent *d, aistate &b, const vec &pos, float guard = SIGHTMIN, int pursue = 0) {
fpsent *t = NULL;
vec dp = d->headpos();
float mindist = guard*guard, bestdist = 1e16f;
- loopv(players)
- {
+ loopv(players) {
fpsent *e = players[i];
if(e == d || !targetable(d, e)) continue;
vec ep = getaimpos(d, e);
float dist = ep.squaredist(dp);
- if(dist < bestdist && (cansee(d, dp, ep) || dist <= mindist))
- {
+ if(dist < bestdist && (cansee(d, dp, ep) || dist <= mindist)) {
t = e;
bestdist = dist;
}
@@ -287,21 +211,16 @@ namespace ai
if(t && violence(d, b, t, pursue)) return true;
return false;
}
-
- bool patrol(fpsent *d, aistate &b, const vec &pos, float guard, float wander, int walk, bool retry)
- {
+ bool patrol(fpsent *d, aistate &b, const vec &pos, float guard, float wander, int walk, bool retry) {
vec feet = d->feetpos();
- if(walk == 2 || b.override || (walk && feet.squaredist(pos) <= guard*guard) || !makeroute(d, b, pos))
- { // run away and back to keep ourselves busy
- if(!b.override && randomnode(d, b, pos, guard, wander))
- {
+ if(walk == 2 || b.override || (walk && feet.squaredist(pos) <= guard*guard) || !makeroute(d, b, pos)) {
+ // run away and back to keep ourselves busy
+ if(!b.override && randomnode(d, b, pos, guard, wander)) {
b.override = true;
return true;
}
- else if(d->ai->route.empty())
- {
- if(!retry)
- {
+ else if(d->ai->route.empty()) {
+ if(!retry) {
b.override = false;
return patrol(d, b, pos, guard, wander, walk, true);
}
@@ -312,14 +231,10 @@ namespace ai
b.override = false;
return true;
}
-
- bool defend(fpsent *d, aistate &b, const vec &pos, float guard, float wander, int walk)
- {
+ bool defend(fpsent *d, aistate &b, const vec &pos, float guard, float wander, int walk) {
bool hasenemy = enemy(d, b, pos, wander, d->gunselect == GUN_FIST ? 1 : 0);
- if(!walk)
- {
- if(d->feetpos().squaredist(pos) <= guard*guard)
- {
+ if(!walk) {
+ if(d->feetpos().squaredist(pos) <= guard*guard) {
b.idle = hasenemy ? 2 : 1;
return true;
}
@@ -327,19 +242,14 @@ namespace ai
}
return patrol(d, b, pos, guard, wander, walk);
}
-
- bool violence(fpsent *d, aistate &b, fpsent *e, int pursue)
- {
- if(e && targetable(d, e))
- {
- if(pursue)
- {
+ bool violence(fpsent *d, aistate &b, fpsent *e, int pursue) {
+ if(e && targetable(d, e)) {
+ if(pursue) {
if((b.targtype != AI_T_AFFINITY || !(pursue%2)) && makeroute(d, b, e->lastnode))
d->ai->switchstate(b, AI_S_PURSUE, AI_T_PLAYER, e->clientnum);
else if(pursue >= 3) return false; // can't pursue
}
- if(d->ai->enemy != e->clientnum)
- {
+ if(d->ai->enemy != e->clientnum) {
d->ai->enemyseen = d->ai->enemymillis = lastmillis;
d->ai->enemy = e->clientnum;
}
@@ -347,29 +257,23 @@ namespace ai
}
return false;
}
-
- bool target(fpsent *d, aistate &b, int pursue = 0, bool force = false, float mindist = 0.f)
- {
+ bool target(fpsent *d, aistate &b, int pursue = 0, bool force = false, float mindist = 0.f) {
static vector<fpsent *> hastried; hastried.setsize(0);
vec dp = d->headpos();
- while(true)
- {
+ while(true) {
float dist = 1e16f;
fpsent *t = NULL;
- loopv(players)
- {
+ loopv(players) {
fpsent *e = players[i];
if(e == d || hastried.find(e) >= 0 || !targetable(d, e)) continue;
vec ep = getaimpos(d, e);
float v = ep.squaredist(dp);
- if((!t || v < dist) && (mindist <= 0 || v <= mindist) && (force || cansee(d, dp, ep)))
- {
+ if((!t || v < dist) && (mindist <= 0 || v <= mindist) && (force || cansee(d, dp, ep))) {
t = e;
dist = v;
}
}
- if(t)
- {
+ if(t) {
if(violence(d, b, t, pursue)) return true;
hastried.add(t);
}
@@ -377,21 +281,15 @@ namespace ai
}
return false;
}
-
int isgoodammo(int gun) { return gun >= GUN_SG && gun <= GUN_GL; }
-
- bool hasgoodammo(fpsent *d)
- {
+ bool hasgoodammo(fpsent *d) {
static const int goodguns[] = { GUN_CG, GUN_RL, GUN_SG, GUN_RIFLE };
loopi(sizeof(goodguns)/sizeof(goodguns[0])) if(d->hasammo(goodguns[0])) return true;
if(d->ammo[GUN_GL] > 5) return true;
return false;
}
-
- void assist(fpsent *d, aistate &b, vector<interest> &interests, bool all, bool force)
- {
- loopv(players)
- {
+ void assist(fpsent *d, aistate &b, vector<interest> &interests, bool all, bool force) {
+ loopv(players) {
fpsent *e = players[i];
if(e == d || (!all && e->aitype != AI_NONE) || !isteam(d->team, e->team)) continue;
interest &n = interests.add();
@@ -402,28 +300,22 @@ namespace ai
n.score = e->o.squaredist(d->o)/(hasgoodammo(d) ? 1e8f : (force ? 1e4f : 1e2f));
}
}
-
- static void tryitem(fpsent *d, extentity &e, int id, aistate &b, vector<interest> &interests, bool force = false)
- {
+ static void tryitem(fpsent *d, extentity &e, int id, aistate &b, vector<interest> &interests, bool force = false) {
float score = 0;
- switch(e.type)
- {
+ switch(e.type) {
case I_HEALTH:
if(d->health < min(d->skill, 75)) score = 1e3f;
break;
case I_QUAD: score = 1e3f; break;
case I_BOOST: score = 1e2f; break;
- case I_GREENARMOUR: case I_YELLOWARMOUR:
- {
+ case I_GREENARMOUR: case I_YELLOWARMOUR: {
int atype = A_GREEN + e.type - I_GREENARMOUR;
if(atype > d->armourtype) score = atype == A_YELLOW ? 1e2f : 1e1f;
else if(d->armour < 50) score = 1e1f;
break;
}
- default:
- {
- if(e.type >= I_SHELLS && e.type <= I_CARTRIDGES && !d->hasmaxammo(e.type))
- {
+ default: {
+ if(e.type >= I_SHELLS && e.type <= I_CARTRIDGES && !d->hasmaxammo(e.type)) {
int gun = e.type - I_SHELLS + GUN_SG;
// go get a weapon upgrade
if(gun == d->ai->weappref) score = 1e8f;
@@ -432,8 +324,7 @@ namespace ai
break;
}
}
- if(score != 0)
- {
+ if(score != 0) {
interest &n = interests.add();
n.state = AI_S_INTEREST;
n.node = closestwaypoint(e.o, SIGHTMIN, true);
@@ -442,61 +333,46 @@ namespace ai
n.score = d->feetpos().squaredist(e.o)/(force ? -1 : score);
}
}
-
- void items(fpsent *d, aistate &b, vector<interest> &interests, bool force = false)
- {
- loopv(entities::ents)
- {
+ void items(fpsent *d, aistate &b, vector<interest> &interests, bool force = false) {
+ loopv(entities::ents) {
extentity &e = *(extentity *)entities::ents[i];
if(!e.spawned() || e.nopickup() || !d->canpickup(e.type)) continue;
tryitem(d, e, i, b, interests, force);
}
}
-
static vector<int> targets;
-
- bool parseinterests(fpsent *d, aistate &b, vector<interest> &interests, bool override, bool ignore)
- {
- while(!interests.empty())
- {
+ bool parseinterests(fpsent *d, aistate &b, vector<interest> &interests, bool override, bool ignore) {
+ while(!interests.empty()) {
int q = interests.length()-1;
loopi(interests.length()-1) if(interests[i].score < interests[q].score) q = i;
interest n = interests.removeunordered(q);
bool proceed = true;
- if(!ignore) switch(n.state)
- {
- case AI_S_DEFEND: // don't get into herds
- {
+ if(!ignore) switch(n.state) {
+ case AI_S_DEFEND: { // don't get into herds {
int members = 0;
proceed = !checkothers(targets, d, n.state, n.targtype, n.target, true, &members) && members > 1;
break;
}
default: break;
}
- if(proceed && makeroute(d, b, n.node))
- {
+ if(proceed && makeroute(d, b, n.node)) {
d->ai->switchstate(b, n.state, n.targtype, n.target);
return true;
}
}
return false;
}
-
- bool find(fpsent *d, aistate &b, bool override = false)
- {
+ bool find(fpsent *d, aistate &b, bool override = false) {
static vector<interest> interests;
interests.setsize(0);
- if(!m_noitems)
- {
+ if(!m_noitems) {
if((!m_noammo && !hasgoodammo(d)) || d->health < min(d->skill - 15, 75))
items(d, b, interests);
- else
- {
+ else {
static vector<int> nearby;
nearby.setsize(0);
findents(I_SHELLS, I_QUAD, false, d->feetpos(), vec(32, 32, 24), nearby);
- loopv(nearby)
- {
+ loopv(nearby) {
int id = nearby[i];
extentity &e = *(extentity *)entities::ents[id];
if(d->canpickup(e.type)) tryitem(d, e, id, b, interests);
@@ -506,48 +382,37 @@ namespace ai
if(m_teammode) assist(d, b, interests);
return parseinterests(d, b, interests, override);
}
-
- bool findassist(fpsent *d, aistate &b, bool override = false)
- {
+ bool findassist(fpsent *d, aistate &b, bool override = false) {
static vector<interest> interests;
interests.setsize(0);
assist(d, b, interests);
- while(!interests.empty())
- {
+ while(!interests.empty()) {
int q = interests.length()-1;
loopi(interests.length()-1) if(interests[i].score < interests[q].score) q = i;
interest n = interests.removeunordered(q);
bool proceed = true;
- switch(n.state)
- {
- case AI_S_DEFEND: // don't get into herds
- {
+ switch(n.state) {
+ case AI_S_DEFEND: { // don't get into herds {
int members = 0;
proceed = !checkothers(targets, d, n.state, n.targtype, n.target, true, &members) && members > 1;
break;
}
default: break;
}
- if(proceed && makeroute(d, b, n.node))
- {
+ if(proceed && makeroute(d, b, n.node)) {
d->ai->switchstate(b, n.state, n.targtype, n.target);
return true;
}
}
return false;
}
-
- void damaged(fpsent *d, fpsent *e)
- {
- if(d->ai && canmove(d) && targetable(d, e)) // see if this ai is interested in a grudge
- {
+ void damaged(fpsent *d, fpsent *e) {
+ if(d->ai && canmove(d) && targetable(d, e)) { // see if this ai is interested in a grudge {
aistate &b = d->ai->getstate();
if(violence(d, b, e, d->gunselect == GUN_FIST ? 1 : 0)) return;
}
- if(checkothers(targets, d, AI_S_DEFEND, AI_T_PLAYER, d->clientnum, true))
- {
- loopv(targets)
- {
+ if(checkothers(targets, d, AI_S_DEFEND, AI_T_PLAYER, d->clientnum, true)) {
+ loopv(targets) {
fpsent *t = getclient(targets[i]);
if(!t->ai || !canmove(t) || !targetable(t, e)) continue;
aistate &c = t->ai->getstate();
@@ -555,23 +420,18 @@ namespace ai
}
}
}
-
- void findorientation(vec &o, float yaw, float pitch, vec &pos)
- {
+ void findorientation(vec &o, float yaw, float pitch, vec &pos) {
vec dir;
vecfromyawpitch(yaw, pitch, 1, 0, dir);
if(raycubepos(o, dir, pos, 0, RAY_CLIPMAT|RAY_SKIPFIRST) == -1)
pos = dir.mul(2*getworldsize()).add(o);
}
-
- void setup(fpsent *d)
- {
+ void setup(fpsent *d) {
d->ai->clearsetup();
d->ai->reset(true);
d->ai->lastrun = lastmillis;
if(m_insta) d->ai->weappref = GUN_RIFLE;
- else
- {
+ else {
if(forcegun >= 0 && forcegun < NUMGUNS) d->ai->weappref = forcegun;
else if(m_noammo) d->ai->weappref = -1;
else d->ai->weappref = rnd(GUN_GL-GUN_SG+1)+GUN_SG;
@@ -579,50 +439,34 @@ namespace ai
vec dp = d->headpos();
findorientation(dp, d->yaw, d->pitch, d->ai->target);
}
-
- void spawned(fpsent *d)
- {
+ void spawned(fpsent *d) {
if(d->ai) setup(d);
}
-
- void killed(fpsent *d, fpsent *e)
- {
+ void killed(fpsent *d, fpsent *e) {
if(d->ai) d->ai->reset();
}
-
- void itemspawned(int ent)
- {
- if(entities::ents.inrange(ent) && entities::ents[ent]->type >= I_SHELLS && entities::ents[ent]->type <= I_QUAD)
- {
- loopv(players) if(players[i] && players[i]->ai && players[i]->aitype == AI_BOT && players[i]->canpickup(entities::ents[ent]->type))
- {
+ void itemspawned(int ent) {
+ if(entities::ents.inrange(ent) && entities::ents[ent]->type >= I_SHELLS && entities::ents[ent]->type <= I_QUAD) {
+ loopv(players) if(players[i] && players[i]->ai && players[i]->aitype == AI_BOT && players[i]->canpickup(entities::ents[ent]->type)) {
fpsent *d = players[i];
bool wantsitem = false;
- switch(entities::ents[ent]->type)
- {
+ switch(entities::ents[ent]->type) {
case I_BOOST:
-
case I_HEALTH: wantsitem = badhealth(d); break;
case I_GREENARMOUR:
-
case I_YELLOWARMOUR:
-
case I_QUAD: break;
- default:
- {
+ default: {
itemstat &is = itemstats[entities::ents[ent]->type-I_SHELLS];
wantsitem = isgoodammo(is.info) && d->ammo[is.info] <= (d->ai->weappref == is.info ? is.add : is.add/2);
break;
}
}
- if(wantsitem)
- {
+ if(wantsitem) {
aistate &b = d->ai->getstate();
if(b.targtype == AI_T_AFFINITY) continue;
- if(b.type == AI_S_INTEREST && b.targtype == AI_T_ENTITY)
- {
- if(entities::ents.inrange(b.target))
- {
+ if(b.type == AI_S_INTEREST && b.targtype == AI_T_ENTITY) {
+ if(entities::ents.inrange(b.target)) {
if(d->o.squaredist(entities::ents[ent]->o) < d->o.squaredist(entities::ents[b.target]->o))
d->ai->switchstate(b, AI_S_INTEREST, AI_T_ENTITY, ent);
}
@@ -633,35 +477,27 @@ namespace ai
}
}
}
-
- int dowait(fpsent *d, aistate &b)
- {
+ int dowait(fpsent *d, aistate &b) {
d->ai->clear(true); // ensure they're clean
if(find(d, b)) return 1;
if(target(d, b, 4, false)) return 1;
if(target(d, b, 4, true)) return 1;
- if(randomnode(d, b, SIGHTMIN, 1e16f))
- {
+ if(randomnode(d, b, SIGHTMIN, 1e16f)) {
d->ai->switchstate(b, AI_S_INTEREST, AI_T_NODE, d->ai->route[0]);
return 1;
}
return 0; // but don't pop the state
}
-
- int dodefend(fpsent *d, aistate &b)
- {
- if(d->state == CS_ALIVE)
- {
- switch(b.targtype)
- {
+ int dodefend(fpsent *d, aistate &b) {
+ if(d->state == CS_ALIVE) {
+ switch(b.targtype) {
case AI_T_NODE:
if(iswaypoint(b.target)) return defend(d, b, waypoints[b.target].o) ? 1 : 0;
break;
case AI_T_ENTITY:
if(entities::ents.inrange(b.target)) return defend(d, b, entities::ents[b.target]->o) ? 1 : 0;
break;
- case AI_T_PLAYER:
- {
+ case AI_T_PLAYER: {
fpsent *e = getclient(b.target);
if(e && e->state == CS_ALIVE) return defend(d, b, e->feetpos()) ? 1 : 0;
break;
@@ -671,12 +507,9 @@ namespace ai
}
return 0;
}
-
- int dointerest(fpsent *d, aistate &b)
- {
+ int dointerest(fpsent *d, aistate &b) {
if(d->state != CS_ALIVE) return 0;
- switch(b.targtype)
- {
+ switch(b.targtype) {
case AI_T_NODE: // this is like a wait state without sitting still..
if(find(d, b)) return 1;
if(target(d, b, 4, true)) return 1;
@@ -684,8 +517,7 @@ namespace ai
return makeroute(d, b, waypoints[b.target].o) ? 1 : 0;
break;
case AI_T_ENTITY:
- if(entities::ents.inrange(b.target))
- {
+ if(entities::ents.inrange(b.target)) {
extentity &e = *(extentity *)entities::ents[b.target];
if(!e.spawned() || e.nopickup() || e.type < I_SHELLS || e.type > I_CARTRIDGES || d->hasmaxammo(e.type)) return 0;
//if(d->feetpos().squaredist(e.o) <= CLOSEDIST*CLOSEDIST)
@@ -699,25 +531,17 @@ namespace ai
}
return 0;
}
-
- int dopursue(fpsent *d, aistate &b)
- {
- if(d->state == CS_ALIVE)
- {
- switch(b.targtype)
- {
- case AI_T_NODE:
- {
+ int dopursue(fpsent *d, aistate &b) {
+ if(d->state == CS_ALIVE) {
+ switch(b.targtype) {
+ case AI_T_NODE: {
if(iswaypoint(b.target))
return defend(d, b, waypoints[b.target].o) ? 1 : 0;
break;
}
-
- case AI_T_PLAYER:
- {
+ case AI_T_PLAYER: {
fpsent *e = getclient(b.target);
- if(e && e->state == CS_ALIVE)
- {
+ if(e && e->state == CS_ALIVE) {
float guard = SIGHTMIN, wander = guns[d->gunselect].range;
if(d->gunselect == GUN_FIST) guard = 0.f;
return patrol(d, b, e->feetpos(), guard, wander) ? 1 : 0;
@@ -729,20 +553,16 @@ namespace ai
}
return 0;
}
-
- int closenode(fpsent *d)
- {
+ int closenode(fpsent *d) {
vec pos = d->feetpos();
int node1 = -1, node2 = -1;
float mindist1 = CLOSEDIST*CLOSEDIST, mindist2 = CLOSEDIST*CLOSEDIST;
- loopv(d->ai->route) if(iswaypoint(d->ai->route[i]))
- {
+ loopv(d->ai->route) if(iswaypoint(d->ai->route[i])) {
vec epos = waypoints[d->ai->route[i]].o;
float dist = epos.squaredist(pos);
if(dist > FARDIST*FARDIST) continue;
int entid = obstacles.remap(d, d->ai->route[i], epos);
- if(entid >= 0)
- {
+ if(entid >= 0) {
if(entid != i) dist = epos.squaredist(pos);
if(dist < mindist1) { node1 = i; mindist1 = dist; }
}
@@ -750,15 +570,11 @@ namespace ai
}
return node1 >= 0 ? node1 : node2;
}
-
- int wpspot(fpsent *d, int n, bool check = false)
- {
- if(iswaypoint(n)) loopk(2)
- {
+ int wpspot(fpsent *d, int n, bool check = false) {
+ if(iswaypoint(n)) loopk(2) {
vec epos = waypoints[n].o;
int entid = obstacles.remap(d, n, epos, k!=0);
- if(iswaypoint(entid))
- {
+ if(iswaypoint(entid)) {
d->ai->spot = epos;
d->ai->targnode = entid;
return !check || d->feetpos().squaredist(epos) > MINWPDIST*MINWPDIST ? 1 : 2;
@@ -766,15 +582,11 @@ namespace ai
}
return 0;
}
-
- int randomlink(fpsent *d, int n)
- {
- if(iswaypoint(n) && waypoints[n].haslinks())
- {
+ int randomlink(fpsent *d, int n) {
+ if(iswaypoint(n) && waypoints[n].haslinks()) {
waypoint &w = waypoints[n];
static vector<int> linkmap; linkmap.setsize(0);
- loopi(MAXWAYPOINTLINKS)
- {
+ loopi(MAXWAYPOINTLINKS) {
if(!w.links[i]) break;
if(iswaypoint(w.links[i]) && !d->ai->hasprevnode(w.links[i]) && d->ai->route.find(w.links[i]) < 0)
linkmap.add(w.links[i]);
@@ -783,19 +595,14 @@ namespace ai
}
return -1;
}
-
- bool anynode(fpsent *d, aistate &b, int len = NUMPREVNODES)
- {
- if(iswaypoint(d->lastnode)) loopk(2)
- {
+ bool anynode(fpsent *d, aistate &b, int len = NUMPREVNODES) {
+ if(iswaypoint(d->lastnode)) loopk(2) {
d->ai->clear(k ? true : false);
int n = randomlink(d, d->lastnode);
- if(wpspot(d, n))
- {
+ if(wpspot(d, n)) {
d->ai->route.add(n);
d->ai->route.add(d->lastnode);
- loopi(len)
- {
+ loopi(len) {
n = randomlink(d, n);
if(iswaypoint(n)) d->ai->route.insert(0, n);
else break;
@@ -805,29 +612,23 @@ namespace ai
}
return false;
}
-
- bool checkroute(fpsent *d, int n)
- {
+ bool checkroute(fpsent *d, int n) {
if(d->ai->route.empty() || !d->ai->route.inrange(n)) return false;
int last = d->ai->lastcheck ? lastmillis-d->ai->lastcheck : 0;
if(last < 500 || n < 3) return false; // route length is too short
d->ai->lastcheck = lastmillis;
int w = iswaypoint(d->lastnode) ? d->lastnode : d->ai->route[n], c = min(n-1, NUMPREVNODES);
- loopj(c) // check ahead to see if we need to go around something
- {
+ loopj(c) { // check ahead to see if we need to go around something {
int p = n-j-1, v = d->ai->route[p];
- if(d->ai->hasprevnode(v) || obstacles.find(v, d)) // something is in the way, try to remap around it
- {
+ if(d->ai->hasprevnode(v) || obstacles.find(v, d)) { // something is in the way, try to remap around it {
int m = p-1;
if(m < 3) return false; // route length is too short from this point
- loopirev(m)
- {
+ loopirev(m) {
int t = d->ai->route[i];
- if(!d->ai->hasprevnode(t) && !obstacles.find(t, d))
- {
+ if(!d->ai->hasprevnode(t) && !obstacles.find(t, d)) {
static vector<int> remap; remap.setsize(0);
- if(route(d, w, t, remap, obstacles))
- { // kill what we don't want and put the remap in
+ if(route(d, w, t, remap, obstacles)) {
+ // kill what we don't want and put the remap in
while(d->ai->route.length() > i) d->ai->route.pop();
loopvk(remap) d->ai->route.add(remap[k]);
return true;
@@ -840,28 +641,20 @@ namespace ai
}
return false;
}
-
- bool hunt(fpsent *d, aistate &b)
- {
- if(!d->ai->route.empty())
- {
+ bool hunt(fpsent *d, aistate &b) {
+ if(!d->ai->route.empty()) {
int n = closenode(d);
if(d->ai->route.inrange(n) && checkroute(d, n)) n = closenode(d);
- if(d->ai->route.inrange(n))
- {
- if(!n)
- {
- switch(wpspot(d, d->ai->route[n], true))
- {
+ if(d->ai->route.inrange(n)) {
+ if(!n) {
+ switch(wpspot(d, d->ai->route[n], true)) {
case 2: d->ai->clear(false);
[[fallthrough]];
-
case 1: return true; // not close enough to pop it yet
default: break;
}
}
- else
- {
+ else {
while(d->ai->route.length() > n+1) d->ai->route.pop(); // waka-waka-waka-waka
int m = n-1; // next, please!
if(d->ai->route.inrange(m) && wpspot(d, d->ai->route[m])) return true;
@@ -871,30 +664,24 @@ namespace ai
b.override = false;
return anynode(d, b);
}
-
- void jumpto(fpsent *d, aistate &b, const vec &pos)
- {
+ void jumpto(fpsent *d, aistate &b, const vec &pos) {
vec off = vec(pos).sub(d->feetpos()), dir(off.x, off.y, 0);
bool sequenced = d->ai->blockseq || d->ai->targseq, offground = d->timeinair && !d->inwater,
jump = !offground && lastmillis >= d->ai->jumpseed && (sequenced || off.z >= JUMPMIN || lastmillis >= d->ai->jumprand);
- if(jump)
- {
+ if(jump) {
vec old = d->o;
d->o = vec(pos).add(vec(0, 0, d->eyeheight));
if(collide(d, vec(0, 0, 1))) jump = false;
d->o = old;
- if(jump)
- {
+ if(jump) {
float radius = 18*18;
- loopv(entities::ents) if(entities::ents[i]->type == JUMPPAD)
- {
+ loopv(entities::ents) if(entities::ents[i]->type == JUMPPAD) {
extentity &e = *(extentity *)entities::ents[i];
if(e.o.squaredist(pos) <= radius) { jump = false; break; }
}
}
}
- if(jump)
- {
+ if(jump) {
d->jumping = true;
int seed = (111-d->skill)*(d->inwater ? 3 : 5);
d->ai->jumpseed = lastmillis+seed+rnd(seed);
@@ -902,18 +689,14 @@ namespace ai
d->ai->jumprand = lastmillis+seed+rnd(seed);
}
}
-
- void fixfullrange(float &yaw, float &pitch, float &roll, bool full)
- {
- if(full)
- {
+ void fixfullrange(float &yaw, float &pitch, float &roll, bool full) {
+ if(full) {
while(pitch < -180.0f) pitch += 360.0f;
while(pitch >= 180.0f) pitch -= 360.0f;
while(roll < -180.0f) roll += 360.0f;
while(roll >= 180.0f) roll -= 360.0f;
}
- else
- {
+ else {
if(pitch > 89.9f) pitch = 89.9f;
if(pitch < -89.9f) pitch = -89.9f;
if(roll > 89.9f) roll = 89.9f;
@@ -922,95 +705,71 @@ namespace ai
while(yaw < 0.0f) yaw += 360.0f;
while(yaw >= 360.0f) yaw -= 360.0f;
}
-
- void fixrange(float &yaw, float &pitch)
- {
+ void fixrange(float &yaw, float &pitch) {
float r = 0.f;
fixfullrange(yaw, pitch, r, false);
}
-
- void getyawpitch(const vec &from, const vec &pos, float &yaw, float &pitch)
- {
+ void getyawpitch(const vec &from, const vec &pos, float &yaw, float &pitch) {
float dist = from.dist(pos);
yaw = -atan2(pos.x-from.x, pos.y-from.y)/RAD;
pitch = asin((pos.z-from.z)/dist)/RAD;
}
-
- void scaleyawpitch(float &yaw, float &pitch, float targyaw, float targpitch, float frame, float scale)
- {
+ void scaleyawpitch(float &yaw, float &pitch, float targyaw, float targpitch, float frame, float scale) {
if(yaw < targyaw-180.0f) yaw += 360.0f;
if(yaw > targyaw+180.0f) yaw -= 360.0f;
float offyaw = fabs(targyaw-yaw)*frame, offpitch = fabs(targpitch-pitch)*frame*scale;
- if(targyaw > yaw)
- {
+ if(targyaw > yaw) {
yaw += offyaw;
if(targyaw < yaw) yaw = targyaw;
}
- else if(targyaw < yaw)
- {
+ else if(targyaw < yaw) {
yaw -= offyaw;
if(targyaw > yaw) yaw = targyaw;
}
- if(targpitch > pitch)
- {
+ if(targpitch > pitch) {
pitch += offpitch;
if(targpitch < pitch) pitch = targpitch;
}
- else if(targpitch < pitch)
- {
+ else if(targpitch < pitch) {
pitch -= offpitch;
if(targpitch > pitch) pitch = targpitch;
}
fixrange(yaw, pitch);
}
-
- bool lockon(fpsent *d, fpsent *e, float maxdist)
- {
- if(d->gunselect == GUN_FIST && !d->blocked && !d->timeinair)
- {
+ bool lockon(fpsent *d, fpsent *e, float maxdist) {
+ if(d->gunselect == GUN_FIST && !d->blocked && !d->timeinair) {
vec dir = vec(e->o).sub(d->o);
float xydist = dir.x*dir.x+dir.y*dir.y, zdist = dir.z*dir.z, mdist = maxdist*maxdist, ddist = d->radius*d->radius+e->radius*e->radius;
if(zdist <= ddist && xydist >= ddist+4 && xydist <= mdist+ddist) return true;
}
return false;
}
-
- int process(fpsent *d, aistate &b)
- {
+ int process(fpsent *d, aistate &b) {
int result = 0, stupify = d->skill <= 10+rnd(15) ? rnd(d->skill*1000) : 0, skmod = 101-d->skill;
float frame = d->skill <= 100 ? float(lastmillis-d->ai->lastrun)/float(max(skmod,1)*10) : 1;
vec dp = d->headpos();
-
bool idle = b.idle == 1 || (stupify && stupify <= skmod);
d->ai->dontmove = false;
- if(idle)
- {
+ if(idle) {
d->ai->lastaction = d->ai->lasthunt = lastmillis;
d->ai->dontmove = true;
d->ai->spot = vec(0, 0, 0);
}
- else if(hunt(d, b))
- {
+ else if(hunt(d, b)) {
getyawpitch(dp, vec(d->ai->spot).add(vec(0, 0, d->eyeheight)), d->ai->targyaw, d->ai->targpitch);
d->ai->lasthunt = lastmillis;
}
- else
- {
+ else {
idle = d->ai->dontmove = true;
d->ai->spot = vec(0, 0, 0);
}
-
if(!d->ai->dontmove) jumpto(d, b, d->ai->spot);
-
fpsent *e = getclient(d->ai->enemy);
bool enemyok = e && targetable(d, e);
- if(!enemyok || d->skill >= 50)
- {
+ if(!enemyok || d->skill >= 50) {
fpsent *f = (fpsent *)intersectclosest(dp, d->ai->target, d);
- if(f)
- {
- if(targetable(d, f))
- {
+ if(f) {
+ if(targetable(d, f)) {
if(!enemyok) violence(d, b, f, d->gunselect == GUN_FIST ? 1 : 0);
enemyok = true;
e = f;
@@ -1020,8 +779,7 @@ namespace ai
else if(!enemyok && target(d, b, d->gunselect == GUN_FIST ? 1 : 0, false, SIGHTMIN))
enemyok = (e = getclient(d->ai->enemy)) != NULL;
}
- if(enemyok)
- {
+ if(enemyok) {
vec ep = getaimpos(d, e);
float yaw, pitch;
getyawpitch(dp, ep, yaw, pitch);
@@ -1029,21 +787,17 @@ namespace ai
bool insight = cansee(d, dp, ep), hasseen = d->ai->enemyseen && lastmillis-d->ai->enemyseen <= (d->skill*10)+3000,
quick = d->ai->enemyseen && lastmillis-d->ai->enemyseen <= (d->gunselect == GUN_CG ? 300 : skmod)+30;
if(insight) d->ai->enemyseen = lastmillis;
- if(idle || insight || hasseen || quick)
- {
+ if(idle || insight || hasseen || quick) {
float sskew = insight || d->skill > 100 ? 1.5f : (hasseen ? 1.f : 0.5f);
- if(insight && lockon(d, e, 16))
- {
+ if(insight && lockon(d, e, 16)) {
d->ai->targyaw = yaw;
d->ai->targpitch = pitch;
if(!idle) frame *= 2;
d->ai->becareful = false;
}
scaleyawpitch(d->yaw, d->pitch, yaw, pitch, frame, sskew);
- if(insight || quick)
- {
- if(canshoot(d, e) && hastarget(d, b, e, yaw, pitch, dp.squaredist(ep)))
- {
+ if(insight || quick) {
+ if(canshoot(d, e) && hastarget(d, b, e, yaw, pitch, dp.squaredist(ep))) {
d->attacking = true;
d->ai->lastaction = lastmillis;
result = 3;
@@ -1052,10 +806,8 @@ namespace ai
}
else result = 1;
}
- else
- {
- if(!d->ai->enemyseen || lastmillis-d->ai->enemyseen > (d->skill*50)+3000)
- {
+ else {
+ if(!d->ai->enemyseen || lastmillis-d->ai->enemyseen > (d->skill*50)+3000) {
d->ai->enemy = -1;
d->ai->enemyseen = d->ai->enemymillis = 0;
}
@@ -1063,22 +815,17 @@ namespace ai
result = 0;
}
}
- else
- {
- if(!enemyok)
- {
+ else {
+ if(!enemyok) {
d->ai->enemy = -1;
d->ai->enemyseen = d->ai->enemymillis = 0;
}
enemyok = false;
result = 0;
}
-
fixrange(d->ai->targyaw, d->ai->targpitch);
if(!result) scaleyawpitch(d->yaw, d->pitch, d->ai->targyaw, d->ai->targpitch, frame*0.25f, 1.f);
-
- if(d->ai->becareful && d->physstate == PHYS_FALL)
- {
+ if(d->ai->becareful && d->physstate == PHYS_FALL) {
float offyaw, offpitch;
vectoyawpitch(d->vel, offyaw, offpitch);
offyaw -= d->yaw; offpitch -= d->pitch;
@@ -1086,20 +833,18 @@ namespace ai
else if(d->ai->becareful) d->ai->dontmove = true;
}
else d->ai->becareful = false;
-
if(d->ai->dontmove) d->move = d->strafe = 0;
- else
- { // our guys move one way.. but turn another?! :)
- const struct aimdir { int move, strafe, offset; } aimdirs[8] =
- {
+ else {
+ // our guys move one way.. but turn another?! :)
+ const struct aimdir { int move, strafe, offset; } aimdirs[8] = {
{ 1, 0, 0 },
- { 1, -1, 45 },
- { 0, -1, 90 },
- { -1, -1, 135 },
+ { 1, -1, 45 },
+ { 0, -1, 90 },
+ { -1, -1, 135 },
{ -1, 0, 180 },
- { -1, 1, 225 },
- { 0, 1, 270 },
- { 1, 1, 315 }
+ { -1, 1, 225 },
+ { 0, 1, 270 },
+ { 1, 1, 315 }
};
float yaw = d->ai->targyaw-d->yaw;
while(yaw < 0.0f) yaw += 360.0f;
@@ -1112,31 +857,23 @@ namespace ai
findorientation(dp, d->yaw, d->pitch, d->ai->target);
return result;
}
-
- bool hasrange(fpsent *d, fpsent *e, int weap)
- {
+ bool hasrange(fpsent *d, fpsent *e, int weap) {
if(!e) return true;
- if(targetable(d, e))
- {
+ if(targetable(d, e)) {
vec ep = getaimpos(d, e);
float dist = ep.squaredist(d->headpos());
if(weaprange(d, weap, dist)) return true;
}
return false;
}
-
- bool request(fpsent *d, aistate &b)
- {
+ bool request(fpsent *d, aistate &b) {
fpsent *e = getclient(d->ai->enemy);
- if(!d->hasammo(d->gunselect) || !hasrange(d, e, d->gunselect) || (d->gunselect != d->ai->weappref && (!isgoodammo(d->gunselect) || d->hasammo(d->ai->weappref))))
- {
+ if(!d->hasammo(d->gunselect) || !hasrange(d, e, d->gunselect) || (d->gunselect != d->ai->weappref && (!isgoodammo(d->gunselect) || d->hasammo(d->ai->weappref)))) {
static const int gunprefs[] = { GUN_CG, GUN_RL, GUN_SG, GUN_RIFLE, GUN_GL, GUN_PISTOL, GUN_FIST };
int gun = -1;
if(d->hasammo(d->ai->weappref) && hasrange(d, e, d->ai->weappref)) gun = d->ai->weappref;
- else
- {
- loopi(sizeof(gunprefs)/sizeof(gunprefs[0])) if(d->hasammo(gunprefs[i]) && hasrange(d, e, gunprefs[i]))
- {
+ else {
+ loopi(sizeof(gunprefs)/sizeof(gunprefs[0])) if(d->hasammo(gunprefs[i]) && hasrange(d, e, gunprefs[i])) {
gun = gunprefs[i];
break;
}
@@ -1145,17 +882,12 @@ namespace ai
}
return process(d, b) >= 2;
}
-
- void timeouts(fpsent *d, aistate &b)
- {
- if(d->blocked)
- {
+ void timeouts(fpsent *d, aistate &b) {
+ if(d->blocked) {
d->ai->blocktime += lastmillis-d->ai->lastrun;
- if(d->ai->blocktime > (d->ai->blockseq+1)*1000)
- {
+ if(d->ai->blocktime > (d->ai->blockseq+1)*1000) {
d->ai->blockseq++;
- switch(d->ai->blockseq)
- {
+ switch(d->ai->blockseq) {
case 1: case 2: case 3:
if(entities::ents.inrange(d->ai->targnode)) d->ai->addprevnode(d->ai->targnode);
d->ai->clear(false);
@@ -1167,15 +899,11 @@ namespace ai
}
}
else d->ai->blocktime = d->ai->blockseq = 0;
-
- if(d->ai->targnode == d->ai->targlast)
- {
+ if(d->ai->targnode == d->ai->targlast) {
d->ai->targtime += lastmillis-d->ai->lastrun;
- if(d->ai->targtime > (d->ai->targseq+1)*1000)
- {
+ if(d->ai->targtime > (d->ai->targseq+1)*1000) {
d->ai->targseq++;
- switch(d->ai->targseq)
- {
+ switch(d->ai->targseq) {
case 1: case 2: case 3:
if(entities::ents.inrange(d->ai->targnode)) d->ai->addprevnode(d->ai->targnode);
d->ai->clear(false);
@@ -1186,21 +914,16 @@ namespace ai
}
}
}
- else
- {
+ else {
d->ai->targtime = d->ai->targseq = 0;
d->ai->targlast = d->ai->targnode;
}
-
- if(d->ai->lasthunt)
- {
+ if(d->ai->lasthunt) {
int millis = lastmillis-d->ai->lasthunt;
if(millis <= 1000) { d->ai->tryreset = false; d->ai->huntseq = 0; }
- else if(millis > (d->ai->huntseq+1)*1000)
- {
+ else if(millis > (d->ai->huntseq+1)*1000) {
d->ai->huntseq++;
- switch(d->ai->huntseq)
- {
+ switch(d->ai->huntseq) {
case 1: d->ai->reset(true); break;
case 2: d->ai->reset(false); break;
case 3: default: suicide(d); return; break; // this is our last resort..
@@ -1208,20 +931,15 @@ namespace ai
}
}
}
-
- void logic(fpsent *d, aistate &b, bool run)
- {
+ void logic(fpsent *d, aistate &b, bool run) {
bool allowmove = canmove(d) && b.type != AI_S_WAIT;
if(d->state != CS_ALIVE || !allowmove) d->stopmoving();
- if(d->state == CS_ALIVE)
- {
- if(allowmove)
- {
+ if(d->state == CS_ALIVE) {
+ if(allowmove) {
if(!request(d, b)) target(d, b, d->gunselect == GUN_FIST ? 1 : 0, b.idle ? true : false);
shoot(d, d->ai->target);
}
- if(!intermission)
- {
+ if(!intermission) {
if(d->ragdoll) cleanragdoll(d);
moveplayer(d, 10, true);
if(allowmove && !b.idle) timeouts(d, b);
@@ -1229,25 +947,20 @@ namespace ai
entities::checkitems(d);
}
}
- else if(d->state == CS_DEAD)
- {
+ else if(d->state == CS_DEAD) {
if(d->ragdoll) moveragdoll(d);
- else if(lastmillis-d->lastpain<2000)
- {
+ else if(lastmillis-d->lastpain<2000) {
d->move = d->strafe = 0;
moveplayer(d, 10, false);
}
}
d->attacking = d->jumping = false;
}
-
- void avoid()
- {
+ void avoid() {
// guess as to the radius of ai and other critters relying on the avoid set for now
float guessradius = player1->radius;
obstacles.clear();
- loopv(players)
- {
+ loopv(players) {
dynent *d = players[i];
if(d->state != CS_ALIVE) continue;
obstacles.avoidnear(d, d->o.z + d->aboveeye + 1, d->feetpos(), guessradius + d->radius);
@@ -1256,46 +969,36 @@ namespace ai
obstacles.add(wpavoid);
avoidweapons(obstacles, guessradius);
}
-
- void think(fpsent *d, bool run)
- {
+ void think(fpsent *d, bool run) {
// the state stack works like a chain of commands, certain commands simply replace each other
// others spawn new commands to the stack the ai reads the top command from the stack and executes
// it or pops the stack and goes back along the history until it finds a suitable command to execute
bool cleannext = false;
if(d->ai->state.empty()) d->ai->addstate(AI_S_WAIT);
- loopvrev(d->ai->state)
- {
+ loopvrev(d->ai->state) {
aistate &c = d->ai->state[i];
- if(cleannext)
- {
+ if(cleannext) {
c.millis = lastmillis;
c.override = false;
cleannext = false;
}
- if(d->state == CS_DEAD && d->respawned!=d->lifesequence && lastmillis - d->lastpain >= 500)
- {
+ if(d->state == CS_DEAD && d->respawned!=d->lifesequence && lastmillis - d->lastpain >= 500) {
addmsg(N_TRYSPAWN, "rc", d);
d->respawned = d->lifesequence;
}
- else if(d->state == CS_ALIVE && run)
- {
+ else if(d->state == CS_ALIVE && run) {
int result = 0;
c.idle = 0;
- switch(c.type)
- {
+ switch(c.type) {
case AI_S_WAIT: result = dowait(d, c); break;
case AI_S_DEFEND: result = dodefend(d, c); break;
case AI_S_PURSUE: result = dopursue(d, c); break;
case AI_S_INTEREST: result = dointerest(d, c); break;
default: result = 0; break;
}
- if(result <= 0)
- {
- if(c.type != AI_S_WAIT)
- {
- switch(result)
- {
+ if(result <= 0) {
+ if(c.type != AI_S_WAIT) {
+ switch(result) {
case 0: default: d->ai->removestate(i); cleannext = true; break;
case -1: i = d->ai->state.length()-1; break;
}
@@ -1309,17 +1012,12 @@ namespace ai
if(d->ai->trywipe) d->ai->wipe();
d->ai->lastrun = lastmillis;
}
-
- void drawroute(fpsent *d, float amt = 1.f)
- {
+ void drawroute(fpsent *d, float amt = 1.f) {
int last = -1;
- loopvrev(d->ai->route)
- {
- if(d->ai->route.inrange(last))
- {
+ loopvrev(d->ai->route) {
+ if(d->ai->route.inrange(last)) {
int index = d->ai->route[i], prev = d->ai->route[last];
- if(iswaypoint(index) && iswaypoint(prev))
- {
+ if(iswaypoint(index) && iswaypoint(prev)) {
waypoint &e = waypoints[index], &f = waypoints[prev];
vec fr = f.o, dr = e.o;
fr.z += amt; dr.z += amt;
@@ -1328,45 +1026,22 @@ namespace ai
}
last = i;
}
- if(aidebug >= 5)
- {
- vec pos = d->feetpos();
- if(d->ai->spot != vec(0, 0, 0)) particle_flare(pos, d->ai->spot, 1, PART_LIGHTNING, 0x00FFFF);
- if(iswaypoint(d->ai->targnode))
- particle_flare(pos, waypoints[d->ai->targnode].o, 1, PART_LIGHTNING, 0xFF00FF);
- if(iswaypoint(d->lastnode))
- particle_flare(pos, waypoints[d->lastnode].o, 1, PART_LIGHTNING, 0xFFFF00);
- loopi(NUMPREVNODES) if(iswaypoint(d->ai->prevnodes[i]))
- {
- particle_flare(pos, waypoints[d->ai->prevnodes[i]].o, 1, PART_LIGHTNING, 0x884400);
- pos = waypoints[d->ai->prevnodes[i]].o;
- }
- }
}
-
VAR(showwaypoints, 0, 0, 1);
VAR(showwaypointsradius, 0, 200, 10000);
-
- const char *stnames[AI_S_MAX] = {
- "wait", "defend", "pursue", "interest"
- }, *sttypes[AI_T_MAX+1] = {
- "none", "node", "player", "affinity", "entity"
- };
- void render()
- {
- if(aidebug > 1)
- {
+ const char *stnames[AI_S_MAX] = { "wait", "defend", "pursue", "interest" },
+ *sttypes[AI_T_MAX+1] = { "none", "node", "player", "affinity", "entity" };
+ void render() {
+ if(aidebug > 1) {
int total = 0, alive = 0;
loopv(players) if(players[i]->ai) total++;
- loopv(players) if(players[i]->state == CS_ALIVE && players[i]->ai)
- {
+ loopv(players) if(players[i]->state == CS_ALIVE && players[i]->ai) {
fpsent *d = players[i];
vec pos = d->abovehead();
pos.z += 3;
alive++;
if(aidebug >= 4) drawroute(d, 4.f*(float(alive)/float(total)));
- if(aidebug >= 3)
- {
+ if(aidebug >= 3) {
defformatstring(q, "node: %d route: %d (%d)",
d->lastnode,
!d->ai->route.empty() ? d->ai->route[0] : -1,
@@ -1376,8 +1051,7 @@ namespace ai
pos.z += 2;
}
bool top = true;
- loopvrev(d->ai->state)
- {
+ loopvrev(d->ai->state) {
aistate &b = d->ai->state[i];
defformatstring(s, "%s%s (%d ms) %s:%d",
top ? "\fg" : "\fy",
@@ -1387,36 +1061,29 @@ namespace ai
);
particle_textcopy(pos, s, PART_TEXT, 1);
pos.z += 2;
- if(top)
- {
+ if(top) {
if(aidebug >= 3) top = false;
else break;
}
}
- if(aidebug >= 3)
- {
- if(d->ai->weappref >= 0 && d->ai->weappref < NUMGUNS)
- {
+ if(aidebug >= 3) {
+ if(d->ai->weappref >= 0 && d->ai->weappref < NUMGUNS) {
particle_textcopy(pos, guns[d->ai->weappref].name, PART_TEXT, 1);
pos.z += 2;
}
fpsent *e = getclient(d->ai->enemy);
- if(e)
- {
+ if(e) {
particle_textcopy(pos, colorname(e), PART_TEXT, 1);
pos.z += 2;
}
}
}
- if(aidebug >= 4)
- {
+ if(aidebug >= 4) {
int cur = 0;
- loopv(obstacles.obstacles)
- {
+ loopv(obstacles.obstacles) {
const avoidset::obstacle &ob = obstacles.obstacles[i];
int next = cur + ob.numwaypoints;
- for(; cur < next; cur++)
- {
+ for(; cur < next; cur++) {
int ent = obstacles.waypoints[cur];
if(iswaypoint(ent))
regular_particle_splash(PART_EDIT, 2, 40, waypoints[ent].o, 0xFF6600, 1.5f);
@@ -1425,26 +1092,21 @@ namespace ai
}
}
}
- if(showwaypoints || aidebug >= 6)
- {
+ if(showwaypoints || aidebug >= 6) {
vector<int> close;
int len = waypoints.length();
- if(showwaypointsradius)
- {
+ if(showwaypointsradius) {
findwaypointswithin(camera1->o, 0, showwaypointsradius, close);
len = close.length();
}
- loopi(len)
- {
+ loopi(len) {
waypoint &w = waypoints[showwaypointsradius ? close[i] : i];
- loopj(MAXWAYPOINTLINKS)
- {
+ loopj(MAXWAYPOINTLINKS) {
int link = w.links[j];
if(!link) break;
particle_flare(w.o, waypoints[link].o, 1, PART_STREAK, 0x0000FF);
}
}
-
}
}
}
diff --git a/src/fpsgame/ai.h b/src/fpsgame/ai.h
index 9ea7e41..b6db1fc 100644
--- a/src/fpsgame/ai.h
+++ b/src/fpsgame/ai.h
@@ -5,12 +5,10 @@ struct fpsent;
enum { AI_NONE = 0, AI_BOT, AI_MAX };
#define isaitype(a) (a >= 0 && a <= AI_MAX-1)
-namespace ai
-{
+namespace ai {
const int MAXWAYPOINTS = USHRT_MAX - 2;
const int MAXWAYPOINTLINKS = 6;
const int WAYPOINTRADIUS = 16;
-
const float MINWPDIST = 4.f; // is on top of
const float CLOSEDIST = 32.f; // is close
const float FARDIST = 128.f; // too far to remap close
@@ -20,97 +18,71 @@ namespace ai
const float SIGHTMAX = 1024.f; // maximum line of sight
const float VIEWMIN = 90.f; // minimum field of view
const float VIEWMAX = 180.f; // maximum field of view
-
- struct waypoint
- {
+ struct waypoint {
vec o;
float curscore, estscore;
int weight;
ushort route, prev;
ushort links[MAXWAYPOINTLINKS];
-
waypoint() {}
waypoint(const vec &o, int weight = 0) : o(o), weight(weight), route(0) { memset(links, 0, sizeof(links)); }
-
int score() const { return int(curscore) + int(estscore); }
-
- int find(int wp)
- {
+ int find(int wp) {
loopi(MAXWAYPOINTLINKS) if(links[i] == wp) return i;
return -1;
}
-
bool haslinks() { return links[0]!=0; }
};
extern vector<waypoint> waypoints;
-
- static inline bool iswaypoint(int n)
- {
+ static inline bool iswaypoint(int n) {
return n > 0 && n < waypoints.length();
}
-
extern int showwaypoints, dropwaypoints;
- extern int closestwaypoint(const vec &pos, float mindist, bool links, fpsent *d = NULL);
+ extern int closestwaypoint(const vec &pos, float mindist, bool links);
extern void findwaypointswithin(const vec &pos, float mindist, float maxdist, vector<int> &results);
extern void inferwaypoints(fpsent *d, const vec &o, const vec &v, float mindist = ai::CLOSEDIST);
-
- struct avoidset
- {
- struct obstacle
- {
+ struct avoidset {
+ struct obstacle {
void *owner;
int numwaypoints;
float above;
-
obstacle(void *owner, float above = -1) : owner(owner), numwaypoints(0), above(above) {}
};
-
vector<obstacle> obstacles;
vector<int> waypoints;
-
- void clear()
- {
+ void clear() {
obstacles.setsize(0);
waypoints.setsize(0);
}
-
- void add(void *owner, float above)
- {
+ void add(void *owner, float above) {
obstacles.add(obstacle(owner, above));
}
-
- void add(void *owner, float above, int wp)
- {
+ void add(void *owner, float above, int wp) {
if(obstacles.empty() || owner != obstacles.last().owner) add(owner, above);
obstacles.last().numwaypoints++;
waypoints.add(wp);
}
-
- void add(avoidset &avoid)
- {
+ void add(avoidset &avoid) {
waypoints.put(avoid.waypoints.getbuf(), avoid.waypoints.length());
- loopv(avoid.obstacles)
- {
+ loopv(avoid.obstacles) {
obstacle &o = avoid.obstacles[i];
if(obstacles.empty() || o.owner != obstacles.last().owner) add(o.owner, o.above);
obstacles.last().numwaypoints += o.numwaypoints;
}
}
-
void avoidnear(void *owner, float above, const vec &pos, float limit);
-
#define loopavoid(v, d, body) \
- if(!(v).obstacles.empty()) \
- { \
+ if(!(v).obstacles.empty()) { \
+ \
int cur = 0; \
- loopv((v).obstacles) \
- { \
+ loopv((v).obstacles) { \
+ \
const ai::avoidset::obstacle &ob = (v).obstacles[i]; \
int next = cur + ob.numwaypoints; \
- if(ob.owner != d) \
- { \
- for(; cur < next; cur++) \
- { \
+ if(ob.owner != d) { \
+ \
+ for(; cur < next; cur++) { \
+ \
int wp = (v).waypoints[cur]; \
body; \
} \
@@ -118,72 +90,53 @@ namespace ai
cur = next; \
} \
}
-
- bool find(int n, fpsent *d) const
- {
+ bool find(int n, fpsent *d) const {
loopavoid(*this, d, { if(wp == n) return true; });
return false;
}
-
int remap(fpsent *d, int n, vec &pos, bool retry = false);
};
-
extern bool route(fpsent *d, int node, int goal, vector<int> &route, const avoidset &obstacles, int retries = 0);
extern void navigate();
extern void clearwaypoints(bool full = false);
extern void seedwaypoints();
extern void loadwaypoints(bool force = false, const char *mname = NULL);
extern void savewaypoints(bool force = false, const char *mname = NULL);
-
// ai state information for the owner client
- enum
- {
+ enum {
AI_S_WAIT = 0, // waiting for next command
AI_S_DEFEND, // defend goal target
AI_S_PURSUE, // pursue goal target
AI_S_INTEREST, // interest in goal entity
AI_S_MAX
};
-
- enum
- {
+ enum {
AI_T_NODE,
AI_T_PLAYER,
AI_T_AFFINITY,
AI_T_ENTITY,
AI_T_MAX
};
-
- struct interest
- {
+ struct interest {
int state, node, target, targtype;
float score;
interest() : state(-1), node(-1), target(-1), targtype(-1), score(0.f) {}
~interest() {}
};
-
- struct aistate
- {
+ struct aistate {
int type, millis, targtype, target, idle;
bool override;
-
- aistate(int m, int t, int r = -1, int v = -1) : type(t), millis(m), targtype(r), target(v)
- {
+ aistate(int m, int t, int r = -1, int v = -1) : type(t), millis(m), targtype(r), target(v) {
reset();
}
~aistate() {}
-
- void reset()
- {
+ void reset() {
idle = 0;
override = false;
}
};
-
const int NUMPREVNODES = 6;
-
- struct aiinfo
- {
+ struct aiinfo {
vector<aistate> state;
vector<int> route;
vec target, spot;
@@ -191,17 +144,13 @@ namespace ai
lastrun, lasthunt, lastaction, lastcheck, jumpseed, jumprand, blocktime, huntseq, blockseq, lastaimrnd;
float targyaw, targpitch, views[3], aimrnd[3];
bool dontmove, becareful, tryreset, trywipe;
-
- aiinfo()
- {
+ aiinfo() {
clearsetup();
reset();
loopk(3) views[k] = 0.f;
}
~aiinfo() {}
-
- void clearsetup()
- {
+ void clearsetup() {
weappref = GUN_PISTOL;
spot = target = vec(0, 0, 0);
lastaction = lasthunt = lastcheck = enemyseen = enemymillis = blocktime = huntseq = blockseq = targtime = targseq = lastaimrnd = 0;
@@ -209,68 +158,47 @@ namespace ai
jumprand = lastmillis+5000;
targnode = targlast = enemy = -1;
}
-
- void clear(bool prev = false)
- {
+ void clear(bool prev = false) {
if(prev) memset(prevnodes, -1, sizeof(prevnodes));
route.setsize(0);
}
-
- void wipe(bool prev = false)
- {
+ void wipe(bool prev = false) {
clear(prev);
state.setsize(0);
addstate(AI_S_WAIT);
trywipe = false;
}
-
- void clean(bool tryit = false)
- {
+ void clean(bool tryit = false) {
if(!tryit) becareful = dontmove = false;
targyaw = rnd(360);
targpitch = 0.f;
tryreset = tryit;
}
-
void reset(bool tryit = false) { wipe(); clean(tryit); }
-
- bool hasprevnode(int n) const
- {
+ bool hasprevnode(int n) const {
loopi(NUMPREVNODES) if(prevnodes[i] == n) return true;
return false;
}
-
- void addprevnode(int n)
- {
- if(prevnodes[0] != n)
- {
+ void addprevnode(int n) {
+ if(prevnodes[0] != n) {
memmove(&prevnodes[1], prevnodes, sizeof(prevnodes) - sizeof(prevnodes[0]));
prevnodes[0] = n;
}
}
-
- aistate &addstate(int t, int r = -1, int v = -1)
- {
+ aistate &addstate(int t, int r = -1, int v = -1) {
return state.add(aistate(lastmillis, t, r, v));
}
-
- void removestate(int index = -1)
- {
+ void removestate(int index = -1) {
if(index < 0) state.pop();
else if(state.inrange(index)) state.remove(index);
if(!state.length()) addstate(AI_S_WAIT);
}
-
- aistate &getstate(int idx = -1)
- {
+ aistate &getstate(int idx = -1) {
if(state.inrange(idx)) return state[idx];
return state.last();
}
-
- aistate &switchstate(aistate &b, int t, int r = -1, int v = -1)
- {
- if((b.type == t && b.targtype == r) || (b.type == AI_S_INTEREST && b.targtype == AI_T_NODE))
- {
+ aistate &switchstate(aistate &b, int t, int r = -1, int v = -1) {
+ if((b.type == t && b.targtype == r) || (b.type == AI_S_INTEREST && b.targtype == AI_T_NODE)) {
b.millis = lastmillis;
b.target = v;
b.reset();
@@ -279,21 +207,17 @@ namespace ai
return addstate(t, r, v);
}
};
-
extern avoidset obstacles;
extern vec aitarget;
-
extern float viewdist(int x = 101);
extern float viewfieldx(int x = 101);
extern float viewfieldy(int x = 101);
extern bool targetable(fpsent *d, fpsent *e);
extern bool cansee(fpsent *d, vec &x, vec &y, vec &targ = aitarget);
-
extern void init(fpsent *d, int at, int on, int sk, int bn, int pm, const char *name, const char *team);
extern void update();
extern void avoid();
extern void think(fpsent *d, bool run);
-
extern bool badhealth(fpsent *d);
extern bool checkothers(vector<int> &targets, fpsent *d = NULL, int state = -1, int targtype = -1, int target = -1, bool teams = false, int *members = NULL);
extern bool makeroute(fpsent *d, aistate &b, int node, bool changed = true, int retries = 0);
@@ -305,12 +229,10 @@ namespace ai
extern bool defend(fpsent *d, aistate &b, const vec &pos, float guard = SIGHTMIN, float wander = SIGHTMAX, int walk = 1);
extern void assist(fpsent *d, aistate &b, vector<interest> &interests, bool all = false, bool force = false);
extern bool parseinterests(fpsent *d, aistate &b, vector<interest> &interests, bool override = false, bool ignore = false);
-
extern void spawned(fpsent *d);
extern void damaged(fpsent *d, fpsent *e);
extern void killed(fpsent *d, fpsent *e);
extern void itemspawned(int ent);
-
extern void render();
}
diff --git a/src/fpsgame/aiman.h b/src/fpsgame/aiman.h
index 940f13e..f926d44 100644
--- a/src/fpsgame/aiman.h
+++ b/src/fpsgame/aiman.h
@@ -1,15 +1,11 @@
// server-side ai manager
-namespace aiman
-{
+namespace aiman {
bool dorefresh = false, botbalance = true;
VARN(serverbotlimit, botlimit, 0, 8, MAXBOTS);
VAR(serverbotbalance, 0, 1, 1);
-
- void calcteams(vector<teamscore> &teams)
- {
+ void calcteams(vector<teamscore> &teams) {
static const char * const defaults[2] = { "good", "evil" };
- loopv(clients)
- {
+ loopv(clients) {
clientinfo *ci = clients[i];
if(ci->state.state==CS_SPECTATOR || !ci->team[0]) continue;
teamscore *t = NULL;
@@ -18,83 +14,64 @@ namespace aiman
else teams.add(teamscore(ci->team, 1));
}
teams.sort(teamscore::compare);
- if(teams.length() < int(sizeof(defaults)/sizeof(defaults[0])))
- {
+ if(teams.length() < int(sizeof(defaults)/sizeof(defaults[0]))) {
loopi(sizeof(defaults)/sizeof(defaults[0])) if(teams.htfind(defaults[i]) < 0) teams.add(teamscore(defaults[i], 0));
}
}
-
- void balanceteams()
- {
+ void balanceteams() {
vector<teamscore> teams;
calcteams(teams);
vector<clientinfo *> reassign;
loopv(bots) if(bots[i]) reassign.add(bots[i]);
- while(reassign.length() && teams.length() && teams[0].score > teams.last().score + 1)
- {
+ while(reassign.length() && teams.length() && teams[0].score > teams.last().score + 1) {
teamscore &t = teams.last();
clientinfo *bot = NULL;
- loopv(reassign) if(reassign[i] && !strcmp(reassign[i]->team, teams[0].team))
- {
+ loopv(reassign) if(reassign[i] && !strcmp(reassign[i]->team, teams[0].team)) {
bot = reassign.removeunordered(i);
teams[0].score--;
t.score++;
- for(int j = teams.length() - 2; j >= 0; j--)
- {
+ for(int j = teams.length() - 2; j >= 0; j--) {
if(teams[j].score >= teams[j+1].score) break;
swap(teams[j], teams[j+1]);
}
break;
}
- if(bot)
- {
+ if(bot) {
copystring(bot->team, t.team, MAXTEAMLEN+1);
sendf(-1, 1, "riisi", N_SETTEAM, bot->clientnum, bot->team, 0);
}
else teams.remove(0, 1);
}
}
-
- const char *chooseteam()
- {
+ const char *chooseteam() {
vector<teamscore> teams;
calcteams(teams);
return teams.length() ? teams.last().team : "";
}
-
- static inline bool validaiclient(clientinfo *ci)
- {
+ static inline bool validaiclient(clientinfo *ci) {
return ci->clientnum >= 0 && ci->state.aitype == AI_NONE && (ci->state.state!=CS_SPECTATOR || ci->local || (ci->privilege && !ci->warned));
}
-
- clientinfo *findaiclient(clientinfo *exclude = NULL)
- {
+ clientinfo *findaiclient(clientinfo *exclude = NULL) {
clientinfo *least = NULL;
- loopv(clients)
- {
+ loopv(clients) {
clientinfo *ci = clients[i];
if(!validaiclient(ci) || ci==exclude) continue;
if(!least || ci->bots.length() < least->bots.length()) least = ci;
}
return least;
}
-
- bool addai(int skill, int limit)
- {
+ bool addai(int skill, int limit) {
int numai = 0, cn = -1, maxai = limit >= 0 ? min(limit, MAXBOTS) : MAXBOTS;
- loopv(bots)
- {
+ loopv(bots) {
clientinfo *ci = bots[i];
if(!ci || ci->ownernum < 0) { if(cn < 0) cn = i; continue; }
numai++;
}
if(numai >= maxai) return false;
- if(bots.inrange(cn))
- {
+ if(bots.inrange(cn)) {
clientinfo *ci = bots[cn];
- if(ci)
- { // reuse a slot that was going to removed
-
+ if(ci) {
+ // reuse a slot that was going to removed
clientinfo *owner = findaiclient();
ci->ownernum = owner ? owner->clientnum : -1;
if(owner) owner->bots.add(ci);
@@ -124,9 +101,7 @@ namespace aiman
dorefresh = true;
return true;
}
-
- void deleteai(clientinfo *ci)
- {
+ void deleteai(clientinfo *ci) {
int cn = ci->clientnum - MAXCLIENTS;
if(!bots.inrange(cn)) return;
sendf(-1, 1, "ri2", N_CDIS, ci->clientnum);
@@ -136,25 +111,18 @@ namespace aiman
DELETEP(bots[cn]);
dorefresh = true;
}
-
- bool deleteai()
- {
- loopvrev(bots) if(bots[i] && bots[i]->ownernum >= 0)
- {
+ bool deleteai() {
+ loopvrev(bots) if(bots[i] && bots[i]->ownernum >= 0) {
deleteai(bots[i]);
return true;
}
return false;
}
-
- void reinitai(clientinfo *ci)
- {
+ void reinitai(clientinfo *ci) {
if(ci->ownernum < 0) deleteai(ci);
- else if(ci->aireinit >= 1)
- {
+ else if(ci->aireinit >= 1) {
sendf(-1, 1, "ri6ss", N_INITAI, ci->clientnum, ci->ownernum, ci->state.aitype, ci->state.skill, ci->playermodel, ci->name, ci->team);
- if(ci->aireinit == 2)
- {
+ if(ci->aireinit == 2) {
ci->reassign();
if(ci->state.state==CS_ALIVE) sendspawn(ci);
else sendresume(ci);
@@ -162,36 +130,27 @@ namespace aiman
ci->aireinit = 0;
}
}
-
- void shiftai(clientinfo *ci, clientinfo *owner = NULL)
- {
+ void shiftai(clientinfo *ci, clientinfo *owner = NULL) {
clientinfo *prevowner = (clientinfo *)getclientinfo(ci->ownernum);
if(prevowner) prevowner->bots.removeobj(ci);
if(!owner) { ci->aireinit = 0; ci->ownernum = -1; }
else if(ci->ownernum != owner->clientnum) { ci->aireinit = 2; ci->ownernum = owner->clientnum; owner->bots.add(ci); }
dorefresh = true;
}
-
- void removeai(clientinfo *ci)
- { // either schedules a removal, or someone else to assign to
-
+ void removeai(clientinfo *ci) {
+ // either schedules a removal, or someone else to assign to
loopvrev(ci->bots) shiftai(ci->bots[i], findaiclient(ci));
}
-
- bool reassignai()
- {
+ bool reassignai() {
clientinfo *hi = NULL, *lo = NULL;
- loopv(clients)
- {
+ loopv(clients) {
clientinfo *ci = clients[i];
if(!validaiclient(ci)) continue;
if(!lo || ci->bots.length() < lo->bots.length()) lo = ci;
if(!hi || ci->bots.length() > hi->bots.length()) hi = ci;
}
- if(hi && lo && hi->bots.length() - lo->bots.length() > 1)
- {
- loopvrev(hi->bots)
- {
+ if(hi && lo && hi->bots.length() - lo->bots.length() > 1) {
+ loopvrev(hi->bots) {
shiftai(hi->bots[i], lo);
return true;
}
@@ -199,53 +158,39 @@ namespace aiman
return false;
}
-
- void checksetup()
- {
+ void checksetup() {
if(m_teammode && botbalance) balanceteams();
loopvrev(bots) if(bots[i]) reinitai(bots[i]);
}
-
- void clearai()
- { // clear and remove all ai immediately
+ void clearai() {
+ // clear and remove all ai immediately
loopvrev(bots) if(bots[i]) deleteai(bots[i]);
}
-
- void checkai()
- {
+ void checkai() {
if(!dorefresh) return;
dorefresh = false;
- if(m_botmode && numclients(-1, false, true))
- {
+ if(m_botmode && numclients(-1, false, true)) {
checksetup();
while(reassignai());
}
else clearai();
}
-
- void reqadd(clientinfo *ci, int skill)
- {
+ void reqadd(clientinfo *ci, int skill) {
if(!ci->local && !ci->privilege) return;
if(!addai(skill, !ci->local && ci->privilege < PRIV_ADMIN ? botlimit : -1)) sendf(ci->clientnum, 1, "ris", N_SERVMSG, "failed to create or assign bot");
}
-
- void reqdel(clientinfo *ci)
- {
+ void reqdel(clientinfo *ci) {
if(!ci->local && !ci->privilege) return;
if(!deleteai()) sendf(ci->clientnum, 1, "ris", N_SERVMSG, "failed to remove any bots");
}
-
- void setbotlimit(clientinfo *ci, int limit)
- {
+ void setbotlimit(clientinfo *ci, int limit) {
if(ci && !ci->local && ci->privilege < PRIV_ADMIN) return;
botlimit = clamp(limit, 0, MAXBOTS);
dorefresh = true;
defformatstring(msg, "bot limit is now %d", botlimit);
sendservmsg(msg);
}
-
- void setbotbalance(clientinfo *ci, bool balance)
- {
+ void setbotbalance(clientinfo *ci, bool balance) {
if(ci && !ci->local && !ci->privilege) return;
botbalance = balance ? 1 : 0;
dorefresh = true;
@@ -253,21 +198,15 @@ namespace aiman
sendservmsg(msg);
}
-
- void changemap()
- {
+ void changemap() {
dorefresh = true;
loopv(clients) if(clients[i]->local || clients[i]->privilege) return;
if(botbalance != (serverbotbalance != 0)) setbotbalance(NULL, serverbotbalance != 0);
}
-
- void addclient(clientinfo *ci)
- {
+ void addclient(clientinfo *ci) {
if(ci->state.aitype == AI_NONE) dorefresh = true;
}
-
- void changeteam(clientinfo *ci)
- {
+ void changeteam(clientinfo *ci) {
if(ci->state.aitype == AI_NONE) dorefresh = true;
}
}
diff --git a/src/fpsgame/client.cpp b/src/fpsgame/client.cpp
index 7155c00..2ad6a6f 100644
--- a/src/fpsgame/client.cpp
+++ b/src/fpsgame/client.cpp
@@ -1,98 +1,71 @@
#include "game.h"
-namespace game
-{
+namespace game {
bool senditemstoserver = false, sendcrc = false; // after a map change, since server doesn't have map data
int lastping = 0;
-
bool connected = false, remote = false, demoplayback = false, gamepaused = false;
int sessionid = 0, mastermode = MM_OPEN, gamespeed = 100;
string servinfo = "", servauth = "", connectpass = "";
-
VARP(deadpush, 1, 2, 20);
-
- void switchname(const char *name)
- {
+ void switchname(const char *name) {
filtertext(player1->name, name, false, false, MAXNAMELEN);
if(!player1->name[0]) copystring(player1->name, "Anonymous");
addmsg(N_SWITCHNAME, "rs", player1->name);
}
- void printname()
- {
+ void printname() {
conoutf("your name is: %s", colorname(player1));
}
- ICOMMAND(name, "sN", (char *s, int *numargs),
- {
+ ICOMMAND(name, "sN", (char *s, int *numargs), {
if(*numargs > 0) switchname(s);
else if(!*numargs) printname();
else result(colorname(player1));
});
ICOMMAND(getname, "", (), result(player1->name));
-
- void switchteam(const char *team)
- {
+ void switchteam(const char *team) {
if(player1->clientnum < 0) filtertext(player1->team, team, false, false, MAXTEAMLEN);
else addmsg(N_SWITCHTEAM, "rs", team);
}
- void printteam()
- {
+ void printteam() {
conoutf("your team is: %s", player1->team);
}
- ICOMMAND(team, "sN", (char *s, int *numargs),
- {
+ ICOMMAND(team, "sN", (char *s, int *numargs), {
if(*numargs > 0) switchteam(s);
else if(!*numargs) printteam();
else result(player1->team);
});
ICOMMAND(getteam, "", (), result(player1->team));
-
- struct authkey
- {
+ struct authkey {
char *name, *key, *desc;
int lastauth;
-
authkey(const char *name, const char *key, const char *desc)
: name(newstring(name)), key(newstring(key)), desc(newstring(desc)),
- lastauth(0)
- {
+ lastauth(0) {
}
-
- ~authkey()
- {
+ ~authkey() {
DELETEA(name);
DELETEA(key);
DELETEA(desc);
}
};
vector<authkey *> authkeys;
-
- authkey *findauthkey(const char *desc = "")
- {
+ authkey *findauthkey(const char *desc = "") {
loopv(authkeys) if(!strcmp(authkeys[i]->desc, desc) && !strcasecmp(authkeys[i]->name, player1->name)) return authkeys[i];
loopv(authkeys) if(!strcmp(authkeys[i]->desc, desc)) return authkeys[i];
return NULL;
}
-
VARP(autoauth, 0, 1, 1);
-
- void addauthkey(const char *name, const char *key, const char *desc)
- {
+ void addauthkey(const char *name, const char *key, const char *desc) {
loopvrev(authkeys) if(!strcmp(authkeys[i]->desc, desc) && !strcmp(authkeys[i]->name, name)) delete authkeys.remove(i);
if(name[0] && key[0]) authkeys.add(new authkey(name, key, desc));
}
ICOMMAND(authkey, "sss", (char *name, char *key, char *desc), addauthkey(name, key, desc));
-
- bool hasauthkey(const char *name, const char *desc)
- {
+ bool hasauthkey(const char *name, const char *desc) {
if(!name[0] && !desc[0]) return authkeys.length() > 0;
loopvrev(authkeys) if(!strcmp(authkeys[i]->desc, desc) && !strcmp(authkeys[i]->name, name)) return true;
return false;
}
-
ICOMMAND(hasauthkey, "ss", (char *name, char *desc), intret(hasauthkey(name, desc) ? 1 : 0));
-
- void genauthkey(const char *secret)
- {
+ void genauthkey(const char *secret) {
if(!secret[0]) { conoutf(CON_ERROR, "you must specify a secret password"); return; }
vector<char> privkey, pubkey;
genprivkey(secret, privkey, pubkey);
@@ -101,9 +74,7 @@ namespace game
result(privkey.getbuf());
}
COMMAND(genauthkey, "s");
-
- void getpubkey(const char *desc)
- {
+ void getpubkey(const char *desc) {
authkey *k = findauthkey(desc);
if(!k) { if(desc[0]) conoutf(CON_ERROR, "no authkey found: %s", desc); else conoutf(CON_ERROR, "no global authkey found"); return; }
vector<char> pubkey;
@@ -111,13 +82,10 @@ namespace game
result(pubkey.getbuf());
}
COMMAND(getpubkey, "s");
-
- void saveauthkeys()
- {
+ void saveauthkeys() {
stream *f = openfile("auth.cfg", "w");
if(!f) { conoutf(CON_ERROR, "failed to open auth.cfg for writing"); return; }
- loopv(authkeys)
- {
+ loopv(authkeys) {
authkey *a = authkeys[i];
f->printf("authkey %s %s %s\n", escapestring(a->name), escapestring(a->key), escapestring(a->desc));
}
@@ -125,139 +93,104 @@ namespace game
delete f;
}
COMMAND(saveauthkeys, "");
-
- void sendmapinfo()
- {
+ void sendmapinfo() {
if(!connected) return;
sendcrc = true;
if(player1->state!=CS_SPECTATOR || player1->privilege || !remote) senditemstoserver = true;
}
-
- void writeclientinfo(stream *f)
- {
+ void writeclientinfo(stream *f) {
f->printf("name %s\n", escapestring(player1->name));
}
-
- bool allowedittoggle()
- {
+ bool allowedittoggle() {
if(editmode) return true;
- if(isconnected() && multiplayer(false) && !m_edit)
- {
+ if(isconnected() && multiplayer(false) && !m_edit) {
conoutf(CON_ERROR, "editing in multiplayer requires coop edit mode (1)");
return false;
}
return execidentbool("allowedittoggle", true);
}
-
- void edittoggled(bool on)
- {
+ void edittoggled(bool on) {
addmsg(N_EDITMODE, "ri", on ? 1 : 0);
if(player1->state==CS_DEAD) deathstate(player1, true);
else if(player1->state==CS_EDITING && player1->editstate==CS_DEAD) showscores(false);
disablezoom();
player1->suicided = player1->respawned = -2;
}
-
- const char *getclientname(int cn)
- {
+ const char *getclientname(int cn) {
fpsent *d = getclient(cn);
return d ? d->name : "";
}
ICOMMAND(getclientname, "i", (int *cn), result(getclientname(*cn)));
-
- const char *getclientteam(int cn)
- {
+ const char *getclientteam(int cn) {
fpsent *d = getclient(cn);
return d ? d->team : "";
}
ICOMMAND(getclientteam, "i", (int *cn), result(getclientteam(*cn)));
-
- const char *getclienticon(int cn)
- {
+ const char *getclienticon(int cn) {
fpsent *d = getclient(cn);
if(!d || d->state==CS_SPECTATOR) return "spectator";
const playermodelinfo &mdl = getplayermodelinfo(d);
return m_teammode ? (isteam(player1->team, d->team) ? mdl.blueicon : mdl.redicon) : mdl.ffaicon;
}
ICOMMAND(getclienticon, "i", (int *cn), result(getclienticon(*cn)));
-
- bool ismaster(int cn)
- {
+ bool ismaster(int cn) {
fpsent *d = getclient(cn);
return d && d->privilege >= PRIV_MASTER;
}
ICOMMAND(ismaster, "i", (int *cn), intret(ismaster(*cn) ? 1 : 0));
-
- bool isauth(int cn)
- {
+ bool isauth(int cn) {
fpsent *d = getclient(cn);
return d && d->privilege >= PRIV_AUTH;
}
ICOMMAND(isauth, "i", (int *cn), intret(isauth(*cn) ? 1 : 0));
-
- bool isadmin(int cn)
- {
+ bool isadmin(int cn) {
fpsent *d = getclient(cn);
return d && d->privilege >= PRIV_ADMIN;
}
ICOMMAND(isadmin, "i", (int *cn), intret(isadmin(*cn) ? 1 : 0));
-
ICOMMAND(getmastermode, "", (), intret(mastermode));
ICOMMAND(mastermodename, "i", (int *mm), result(server::mastermodename(*mm, "")));
-
- bool isspectator(int cn)
- {
+ bool isspectator(int cn) {
fpsent *d = getclient(cn);
return d && d->state==CS_SPECTATOR;
}
ICOMMAND(isspectator, "i", (int *cn), intret(isspectator(*cn) ? 1 : 0));
-
- bool isai(int cn, int type)
- {
+ bool isai(int cn, int type) {
fpsent *d = getclient(cn);
int aitype = type > 0 && type < AI_MAX ? type : AI_BOT;
return d && d->aitype==aitype;
}
ICOMMAND(isai, "ii", (int *cn, int *type), intret(isai(*cn, *type) ? 1 : 0));
-
- int parseplayer(const char *arg)
- {
+ int parseplayer(const char *arg) {
char *end;
int n = strtol(arg, &end, 10);
- if(*arg && !*end)
- {
+ if(*arg && !*end) {
if(n!=player1->clientnum && !clients.inrange(n)) return -1;
return n;
}
// try case sensitive first
- loopv(players)
- {
+ loopv(players) {
fpsent *o = players[i];
if(!strcmp(arg, o->name)) return o->clientnum;
}
// nothing found, try case insensitive
- loopv(players)
- {
+ loopv(players) {
fpsent *o = players[i];
if(!strcasecmp(arg, o->name)) return o->clientnum;
}
return -1;
}
ICOMMAND(getclientnum, "s", (char *name), intret(name[0] ? parseplayer(name) : player1->clientnum));
-
- void listclients(bool local, bool bots)
- {
+ void listclients(bool local, bool bots) {
vector<char> buf;
string cn;
int numclients = 0;
- if(local && connected)
- {
+ if(local && connected) {
formatstring(cn, "%d", player1->clientnum);
buf.put(cn, strlen(cn));
numclients++;
}
- loopv(clients) if(clients[i] && (bots || clients[i]->aitype == AI_NONE))
- {
+ loopv(clients) if(clients[i] && (bots || clients[i]->aitype == AI_NONE)) {
formatstring(cn, "%d", clients[i]->clientnum);
if(numclients++) buf.add(' ');
buf.put(cn, strlen(cn));
@@ -266,26 +199,19 @@ namespace game
result(buf.getbuf());
}
ICOMMAND(listclients, "bb", (int *local, int *bots), listclients(*local>0, *bots!=0));
-
- void clearbans()
- {
+ void clearbans() {
addmsg(N_CLEARBANS, "r");
}
COMMAND(clearbans, "");
-
- void kick(const char *victim, const char *reason)
- {
+ void kick(const char *victim, const char *reason) {
int vn = parseplayer(victim);
if(vn>=0 && vn!=player1->clientnum) addmsg(N_KICK, "ris", vn, reason);
}
COMMAND(kick, "ss");
-
- void authkick(const char *desc, const char *victim, const char *reason)
- {
+ void authkick(const char *desc, const char *victim, const char *reason) {
authkey *a = findauthkey(desc);
int vn = parseplayer(victim);
- if(a && vn>=0 && vn!=player1->clientnum)
- {
+ if(a && vn>=0 && vn!=player1->clientnum) {
a->lastauth = lastmillis;
addmsg(N_AUTHKICK, "rssis", a->desc, a->name, vn, reason);
}
@@ -293,60 +219,45 @@ namespace game
ICOMMAND(authkick, "ss", (const char *victim, const char *reason), authkick("", victim, reason));
ICOMMAND(sauthkick, "ss", (const char *victim, const char *reason), if(servauth[0]) authkick(servauth, victim, reason));
ICOMMAND(dauthkick, "sss", (const char *desc, const char *victim, const char *reason), if(desc[0]) authkick(desc, victim, reason));
-
vector<int> ignores;
-
- void ignore(int cn)
- {
+ void ignore(int cn) {
fpsent *d = getclient(cn);
if(!d || d == player1) return;
conoutf("ignoring %s", d->name);
if(ignores.find(cn) < 0) ignores.add(cn);
}
-
- void unignore(int cn)
- {
+ void unignore(int cn) {
if(ignores.find(cn) < 0) return;
fpsent *d = getclient(cn);
if(d) conoutf("stopped ignoring %s", d->name);
ignores.removeobj(cn);
}
-
bool isignored(int cn) { return ignores.find(cn) >= 0; }
-
ICOMMAND(ignore, "s", (char *arg), ignore(parseplayer(arg)));
ICOMMAND(unignore, "s", (char *arg), unignore(parseplayer(arg)));
ICOMMAND(isignored, "s", (char *arg), intret(isignored(parseplayer(arg)) ? 1 : 0));
-
- void setteam(const char *arg1, const char *arg2)
- {
+ void setteam(const char *arg1, const char *arg2) {
int i = parseplayer(arg1);
if(i>=0) addmsg(N_SETTEAM, "ris", i, arg2);
}
COMMAND(setteam, "ss");
-
- void hashpwd(const char *pwd)
- {
+ void hashpwd(const char *pwd) {
if(player1->clientnum<0) return;
string hash;
server::hashpassword(player1->clientnum, sessionid, pwd, hash);
result(hash);
}
COMMAND(hashpwd, "s");
-
- void setmaster(const char *arg, const char *who)
- {
+ void setmaster(const char *arg, const char *who) {
if(!arg[0]) return;
int val = 1, cn = player1->clientnum;
- if(who[0])
- {
+ if(who[0]) {
cn = parseplayer(who);
if(cn < 0) return;
}
string hash = "";
if(!arg[1] && isdigit(arg[0])) val = parseint(arg);
- else
- {
+ else {
if(cn != player1->clientnum) return;
server::hashpassword(player1->clientnum, sessionid, arg, hash);
}
@@ -354,9 +265,7 @@ namespace game
}
COMMAND(setmaster, "ss");
ICOMMAND(mastermode, "i", (int *val), addmsg(N_MASTERMODE, "ri", *val));
-
- bool tryauth(const char *desc)
- {
+ bool tryauth(const char *desc) {
authkey *a = findauthkey(desc);
if(!a) return false;
a->lastauth = lastmillis;
@@ -366,45 +275,32 @@ namespace game
ICOMMAND(auth, "s", (char *desc), tryauth(desc));
ICOMMAND(sauth, "", (), if(servauth[0]) tryauth(servauth));
ICOMMAND(dauth, "s", (char *desc), if(desc[0]) tryauth(desc));
-
ICOMMAND(getservauth, "", (), result(servauth));
-
- void togglespectator(int val, const char *who)
- {
+ void togglespectator(int val, const char *who) {
int i = who[0] ? parseplayer(who) : player1->clientnum;
if(i>=0) addmsg(N_SPECTATOR, "rii", i, val);
}
ICOMMAND(spectator, "is", (int *val, char *who), togglespectator(*val, who));
-
ICOMMAND(checkmaps, "", (), addmsg(N_CHECKMAPS, "r"));
-
int gamemode = INT_MAX, nextmode = INT_MAX;
string clientmap = "";
-
- void changemapserv(const char *name, int mode) // forced map change from the server
- {
- if(multiplayer(false) && !m_mp(mode))
- {
+ void changemapserv(const char *name, int mode) { // forced map change from the server {
+ if(multiplayer(false) && !m_mp(mode)) {
conoutf(CON_ERROR, "mode %s (%d) not supported in multiplayer", server::modename(gamemode), gamemode);
loopi(NUMGAMEMODES) if(m_mp(STARTGAMEMODE + i)) { mode = STARTGAMEMODE + i; break; }
}
-
gamemode = mode;
nextmode = mode;
if(editmode) toggleedit();
if(m_demo) { entities::resetspawns(); return; }
- if((m_edit && !name[0]) || !load_world(name))
- {
+ if((m_edit && !name[0]) || !load_world(name)) {
emptymap(0, true, name);
senditemstoserver = false;
}
startgame();
}
-
- void setmode(int mode)
- {
- if(multiplayer(false) && !m_mp(mode))
- {
+ void setmode(int mode) {
+ if(multiplayer(false) && !m_mp(mode)) {
conoutf(CON_ERROR, "mode %s (%d) not supported in multiplayer", server::modename(mode), mode);
intret(0);
return;
@@ -414,11 +310,9 @@ namespace game
}
ICOMMAND(mode, "i", (int *val), setmode(*val));
ICOMMAND(getmode, "", (), intret(gamemode));
- ICOMMAND(timeremaining, "i", (int *formatted),
- {
+ ICOMMAND(timeremaining, "i", (int *formatted), {
int val = max(maplimit - lastmillis + 999, 0)/1000;
- if(*formatted)
- {
+ if(*formatted) {
defformatstring(str, "%d:%02d", val/60, val%60);
result(str);
}
@@ -432,46 +326,32 @@ namespace game
ICOMMANDS("m_demo", "i", (int *mode), { int gamemode = *mode; intret(m_demo); });
ICOMMANDS("m_edit", "i", (int *mode), { int gamemode = *mode; intret(m_edit); });
ICOMMANDS("m_lobby", "i", (int *mode), { int gamemode = *mode; intret(m_lobby); });
-
- void changemap(const char *name, int mode) // request map change, server may ignore
- {
- if(!remote)
- {
+ void changemap(const char *name, int mode) { // request map change, server may ignore {
+ if(!remote) {
server::forcemap(name, mode);
if(!isconnected()) localconnect();
}
else if(player1->state!=CS_SPECTATOR || player1->privilege) addmsg(N_MAPVOTE, "rsi", name, mode);
}
- void changemap(const char *name)
- {
+ void changemap(const char *name) {
changemap(name, m_valid(nextmode) ? nextmode : (remote ? 0 : 1));
}
ICOMMAND(map, "s", (char *name), changemap(name));
-
- void forceintermission()
- {
+ void forceintermission() {
if(!remote && !hasnonlocalclients()) server::startintermission();
else addmsg(N_FORCEINTERMISSION, "r");
}
-
- void forceedit(const char *name)
- {
+ void forceedit(const char *name) {
changemap(name, 1);
}
-
- void newmap(int size)
- {
+ void newmap(int size) {
addmsg(N_NEWMAP, "ri", size);
}
-
int needclipboard = -1;
-
- void sendclipboard()
- {
+ void sendclipboard() {
uchar *outbuf = NULL;
int inlen = 0, outlen = 0;
- if(!packeditinfo(localedit, inlen, outbuf, outlen))
- {
+ if(!packeditinfo(localedit, inlen, outbuf, outlen)) {
outbuf = NULL;
inlen = outlen = 0;
}
@@ -483,22 +363,16 @@ namespace game
sendclientpacket(p.finalize(), 1);
needclipboard = -1;
}
-
- void edittrigger(const selinfo &sel, int op, int arg1, int arg2, int arg3, const VSlot *vs)
- {
- if(m_edit) switch(op)
- {
+ void edittrigger(const selinfo &sel, int op, int arg1, int arg2, int arg3, const VSlot *vs) {
+ if(m_edit) switch(op) {
case EDIT_FLIP:
case EDIT_COPY:
case EDIT_PASTE:
- case EDIT_DELCUBE:
- {
- switch(op)
- {
+ case EDIT_DELCUBE: {
+ switch(op) {
case EDIT_COPY: needclipboard = 0; break;
case EDIT_PASTE:
- if(needclipboard > 0)
- {
+ if(needclipboard > 0) {
c2sinfo(true);
sendclipboard();
}
@@ -509,8 +383,7 @@ namespace game
sel.cx, sel.cxs, sel.cy, sel.cys, sel.corner);
break;
}
- case EDIT_ROTATE:
- {
+ case EDIT_ROTATE: {
addmsg(N_EDITF + op, "ri9i5",
sel.o.x, sel.o.y, sel.o.z, sel.s.x, sel.s.y, sel.s.z, sel.grid, sel.orient,
sel.cx, sel.cxs, sel.cy, sel.cys, sel.corner,
@@ -518,22 +391,19 @@ namespace game
break;
}
case EDIT_MAT:
- case EDIT_FACE:
- {
+ case EDIT_FACE: {
addmsg(N_EDITF + op, "ri9i6",
sel.o.x, sel.o.y, sel.o.z, sel.s.x, sel.s.y, sel.s.z, sel.grid, sel.orient,
sel.cx, sel.cxs, sel.cy, sel.cys, sel.corner,
arg1, arg2);
break;
}
- case EDIT_TEX:
- {
+ case EDIT_TEX: {
int tex1 = shouldpacktex(arg1);
if(addmsg(N_EDITF + op, "ri9i6",
sel.o.x, sel.o.y, sel.o.z, sel.s.x, sel.s.y, sel.s.z, sel.grid, sel.orient,
sel.cx, sel.cxs, sel.cy, sel.cys, sel.corner,
- tex1 ? tex1 : arg1, arg2))
- {
+ tex1 ? tex1 : arg1, arg2)) {
messages.pad(2);
int offset = messages.length();
if(tex1) packvslot(messages, arg1);
@@ -541,14 +411,12 @@ namespace game
}
break;
}
- case EDIT_REPLACE:
- {
+ case EDIT_REPLACE: {
int tex1 = shouldpacktex(arg1), tex2 = shouldpacktex(arg2);
if(addmsg(N_EDITF + op, "ri9i7",
sel.o.x, sel.o.y, sel.o.z, sel.s.x, sel.s.y, sel.s.z, sel.grid, sel.orient,
sel.cx, sel.cxs, sel.cy, sel.cys, sel.corner,
- tex1 ? tex1 : arg1, tex2 ? tex2 : arg2, arg3))
- {
+ tex1 ? tex1 : arg1, tex2 ? tex2 : arg2, arg3)) {
messages.pad(2);
int offset = messages.length();
if(tex1) packvslot(messages, arg1);
@@ -557,18 +425,15 @@ namespace game
}
break;
}
- case EDIT_REMIP:
- {
+ case EDIT_REMIP: {
addmsg(N_EDITF + op, "r");
break;
}
- case EDIT_VSLOT:
- {
+ case EDIT_VSLOT: {
if(addmsg(N_EDITF + op, "ri9i6",
sel.o.x, sel.o.y, sel.o.z, sel.s.x, sel.s.y, sel.s.z, sel.grid, sel.orient,
sel.cx, sel.cxs, sel.cy, sel.cys, sel.corner,
- arg1, arg2))
- {
+ arg1, arg2)) {
messages.pad(2);
int offset = messages.length();
packvslot(messages, vs);
@@ -577,12 +442,10 @@ namespace game
break;
}
case EDIT_UNDO:
- case EDIT_REDO:
- {
+ case EDIT_REDO: {
uchar *outbuf = NULL;
int inlen = 0, outlen = 0;
- if(packundo(op, inlen, outbuf, outlen))
- {
+ if(packundo(op, inlen, outbuf, outlen)) {
if(addmsg(N_EDITF + op, "ri2", inlen, outlen)) messages.put(outbuf, outlen);
delete[] outbuf;
}
@@ -590,13 +453,9 @@ namespace game
}
}
}
-
- void printvar(fpsent *d, ident *id)
- {
- if(id) switch(id->type)
- {
- case ID_VAR:
- {
+ void printvar(fpsent *d, ident *id) {
+ if(id) switch(id->type) {
+ case ID_VAR: {
int val = *id->storage.i;
string str;
if(val < 0)
@@ -616,20 +475,15 @@ namespace game
break;
}
}
-
- void vartrigger(ident *id)
- {
+ void vartrigger(ident *id) {
if(!m_edit) return;
- switch(id->type)
- {
+ switch(id->type) {
case ID_VAR:
addmsg(N_EDITVAR, "risi", ID_VAR, id->name, *id->storage.i);
break;
-
case ID_FVAR:
addmsg(N_EDITVAR, "risf", ID_FVAR, id->name, *id->storage.f);
break;
-
case ID_SVAR:
addmsg(N_EDITVAR, "riss", ID_SVAR, id->name, *id->storage.s);
break;
@@ -637,83 +491,64 @@ namespace game
}
printvar(player1, id);
}
-
- void pausegame(bool val)
- {
+ void pausegame(bool val) {
if(!connected) return;
if(!remote) server::forcepaused(val);
else addmsg(N_PAUSEGAME, "ri", val ? 1 : 0);
}
ICOMMAND(pausegame, "i", (int *val), pausegame(*val > 0));
- ICOMMAND(paused, "iN$", (int *val, int *numargs, ident *id),
- {
+ ICOMMAND(paused, "iN$", (int *val, int *numargs, ident *id), {
if(*numargs > 0) pausegame(clampvar(id, *val, 0, 1) > 0);
else if(*numargs < 0) intret(gamepaused ? 1 : 0);
else printvar(id, gamepaused ? 1 : 0);
});
-
bool ispaused() { return gamepaused; }
-
bool allowmouselook() { return !gamepaused || !remote || m_edit; }
-
- void changegamespeed(int val)
- {
+ void changegamespeed(int val) {
if(!connected) return;
if(!remote) server::forcegamespeed(val);
else addmsg(N_GAMESPEED, "ri", val);
}
- ICOMMAND(gamespeed, "iN$", (int *val, int *numargs, ident *id),
- {
+ ICOMMAND(gamespeed, "iN$", (int *val, int *numargs, ident *id), {
if(*numargs > 0) changegamespeed(clampvar(id, *val, 10, 1000));
else if(*numargs < 0) intret(gamespeed);
else printvar(id, gamespeed);
});
-
int scaletime(int t) { return t*gamespeed; }
-
// collect c2s messages conveniently
vector<uchar> messages;
int messagecn = -1, messagereliable = false;
-
- bool addmsg(int type, const char *fmt, ...)
- {
+ bool addmsg(int type, const char *fmt, ...) {
if(!connected) return false;
static uchar buf[MAXTRANS];
ucharbuf p(buf, sizeof(buf));
putint(p, type);
int numi = 1, numf = 0, nums = 0, mcn = -1;
bool reliable = false;
- if(fmt)
- {
+ if(fmt) {
va_list args;
va_start(args, fmt);
- while(*fmt) switch(*fmt++)
- {
+ while(*fmt) switch(*fmt++) {
case 'r': reliable = true; break;
- case 'c':
- {
+ case 'c': {
fpsent *d = va_arg(args, fpsent *);
mcn = !d || d == player1 ? -1 : d->clientnum;
break;
}
- case 'v':
- {
+ case 'v': {
int n = va_arg(args, int);
int *v = va_arg(args, int *);
loopi(n) putint(p, v[i]);
numi += n;
break;
}
-
- case 'i':
- {
+ case 'i': {
int n = isdigit(*fmt) ? *fmt++-'0' : 1;
loopi(n) putint(p, va_arg(args, int));
numi += n;
break;
}
- case 'f':
- {
+ case 'f': {
int n = isdigit(*fmt) ? *fmt++-'0' : 1;
loopi(n) putfloat(p, (float)va_arg(args, double));
numf += n;
@@ -726,8 +561,7 @@ namespace game
int num = nums || numf ? 0 : numi, msgsize = server::msgsizelookup(type);
if(msgsize && num!=msgsize) { fatal("inconsistent msg size for %d (%d != %d)", type, num, msgsize); }
if(reliable) messagereliable = true;
- if(mcn != messagecn)
- {
+ if(mcn != messagecn) {
static uchar mbuf[16];
ucharbuf m(mbuf, sizeof(mbuf));
putint(m, N_FROMAI);
@@ -738,25 +572,17 @@ namespace game
messages.put(buf, p.length());
return true;
}
-
- void connectattempt(const char *name, const char *password, const ENetAddress &address)
- {
+ void connectattempt(const char *name, const char *password, const ENetAddress &address) {
copystring(connectpass, password);
}
-
- void connectfail()
- {
+ void connectfail() {
memset(connectpass, 0, sizeof(connectpass));
}
-
- void gameconnect(bool _remote)
- {
+ void gameconnect(bool _remote) {
remote = _remote;
if(editmode) toggleedit();
}
-
- void gamedisconnect(bool cleanup)
- {
+ void gamedisconnect(bool cleanup) {
if(remote) stopfollowing();
ignores.setsize(0);
connected = remote = false;
@@ -775,26 +601,19 @@ namespace game
gamepaused = false;
gamespeed = 100;
clearclients(false);
- if(cleanup)
- {
+ if(cleanup) {
nextmode = gamemode = INT_MAX;
clientmap[0] = '\0';
}
}
-
VARP(teamcolorchat, 0, 1, 1);
const char *chatcolorname(fpsent *d) { return teamcolorchat ? teamcolorname(d, NULL) : colorname(d); }
-
void toserver(char *text) { conoutf(CON_CHAT, "%s:\f0 %s", chatcolorname(player1), text); addmsg(N_TEXT, "rcs", player1, text); }
COMMANDN(say, toserver, "C");
-
void sayteam(char *text) { conoutf(CON_TEAMCHAT, "\fs\f8[team]\fr %s: \f8%s", chatcolorname(player1), text); addmsg(N_SAYTEAM, "rcs", player1, text); }
COMMAND(sayteam, "C");
-
ICOMMAND(servcmd, "C", (char *cmd), addmsg(N_SERVCMD, "rs", cmd));
-
- static void sendposition(fpsent *d, packetbuf &q)
- {
+ static void sendposition(fpsent *d, packetbuf &q) {
putint(q, N_POS);
putuint(q, d->clientnum);
// 3 bits phys state, 1 bit life sequence, 2 bits move, 2 bits strafe
@@ -808,16 +627,14 @@ namespace game
if(o.y < 0 || o.y > 0xFFFF) flags |= 1<<1;
if(o.z < 0 || o.z > 0xFFFF) flags |= 1<<2;
if(vel > 0xFF) flags |= 1<<3;
- if(fall > 0)
- {
+ if(fall > 0) {
flags |= 1<<4;
if(fall > 0xFF) flags |= 1<<5;
if(d->falling.x || d->falling.y || d->falling.z > 0) flags |= 1<<6;
}
if((lookupmaterial(d->feetpos())&MATF_CLIP) == MAT_GAMECLIP) flags |= 1<<7;
putuint(q, flags);
- loopk(3)
- {
+ loopk(3) {
q.put(o[k]&0xFF);
q.put((o[k]>>8)&0xFF);
if(o[k] < 0 || o[k] > 0xFFFF) q.put((o[k]>>16)&0xFF);
@@ -833,12 +650,10 @@ namespace game
uint veldir = (velyaw < 0 ? 360 + int(velyaw)%360 : int(velyaw)%360) + clamp(int(velpitch+90), 0, 180)*360;
q.put(veldir&0xFF);
q.put((veldir>>8)&0xFF);
- if(fall > 0)
- {
+ if(fall > 0) {
q.put(fall&0xFF);
if(fall > 0xFF) q.put((fall>>8)&0xFF);
- if(d->falling.x || d->falling.y || d->falling.z > 0)
- {
+ if(d->falling.x || d->falling.y || d->falling.z > 0) {
float fallyaw, fallpitch;
vectoyawpitch(d->falling, fallyaw, fallpitch);
uint falldir = (fallyaw < 0 ? 360 + int(fallyaw)%360 : int(fallyaw)%360) + clamp(int(fallpitch+90), 0, 180)*360;
@@ -847,26 +662,19 @@ namespace game
}
}
}
-
- void sendposition(fpsent *d, bool reliable)
- {
+ void sendposition(fpsent *d, bool reliable) {
if(d->state != CS_ALIVE && d->state != CS_EDITING) return;
packetbuf q(100, reliable ? ENET_PACKET_FLAG_RELIABLE : 0);
sendposition(d, q);
sendclientpacket(q.finalize(), 0);
}
-
- void sendpositions()
- {
- loopv(players)
- {
+ void sendpositions() {
+ loopv(players) {
fpsent *d = players[i];
- if((d == player1 || d->ai) && (d->state == CS_ALIVE || d->state == CS_EDITING))
- {
+ if((d == player1 || d->ai) && (d->state == CS_ALIVE || d->state == CS_EDITING)) {
packetbuf q(100);
sendposition(d, q);
- for(int j = i+1; j < players.length(); j++)
- {
+ for(int j = i+1; j < players.length(); j++) {
fpsent *d = players[j];
if((d == player1 || d->ai) && (d->state == CS_ALIVE || d->state == CS_EDITING))
sendposition(d, q);
@@ -876,12 +684,9 @@ namespace game
}
}
}
-
- void sendmessages()
- {
+ void sendmessages() {
packetbuf p(MAXTRANS);
- if(sendcrc)
- {
+ if(sendcrc) {
p.reliable();
sendcrc = false;
const char *mname = getclientmap();
@@ -889,31 +694,26 @@ namespace game
sendstring(mname, p);
putint(p, mname[0] ? getmapcrc() : 0);
}
- if(senditemstoserver)
- {
+ if(senditemstoserver) {
if(!m_noitems) p.reliable();
if(!m_noitems) entities::putitems(p);
senditemstoserver = false;
}
- if(messages.length())
- {
+ if(messages.length()) {
p.put(messages.getbuf(), messages.length());
messages.setsize(0);
if(messagereliable) p.reliable();
messagereliable = false;
messagecn = -1;
}
- if(totalmillis-lastping>250)
- {
+ if(totalmillis-lastping>250) {
putint(p, N_PING);
putint(p, totalmillis);
lastping = totalmillis;
}
sendclientpacket(p.finalize(), 1);
}
-
- void c2sinfo(bool force) // send update to the server
- {
+ void c2sinfo(bool force) { // send update to the server {
static int lastupdate = -1000;
if(totalmillis - lastupdate < 33 && !force) return; // don't update faster than 30fps
lastupdate = totalmillis;
@@ -921,73 +721,58 @@ namespace game
sendmessages();
flushclient();
}
-
- void sendintro()
- {
+ void sendintro() {
packetbuf p(MAXTRANS, ENET_PACKET_FLAG_RELIABLE);
putint(p, N_CONNECT);
sendstring(player1->name, p);
putint(p, player1->playermodel);
string hash = "";
- if(connectpass[0])
- {
+ if(connectpass[0]) {
server::hashpassword(player1->clientnum, sessionid, connectpass, hash);
memset(connectpass, 0, sizeof(connectpass));
}
sendstring(hash, p);
authkey *a = servauth[0] && autoauth ? findauthkey(servauth) : NULL;
- if(a)
- {
+ if(a) {
a->lastauth = lastmillis;
sendstring(a->desc, p);
sendstring(a->name, p);
}
- else
- {
+ else {
sendstring("", p);
sendstring("", p);
}
sendclientpacket(p.finalize(), 1);
}
-
- void updatepos(fpsent *d)
- {
+ void updatepos(fpsent *d) {
// update the position of other clients in the game in our world
// don't care if he's in the scenery or other players,
// just don't overlap with our client
-
const float r = player1->radius+d->radius;
const float dx = player1->o.x-d->o.x;
const float dy = player1->o.y-d->o.y;
const float dz = player1->o.z-d->o.z;
const float rz = player1->aboveeye+d->eyeheight;
const float fx = (float)fabs(dx), fy = (float)fabs(dy), fz = (float)fabs(dz);
- if(fx<r && fy<r && fz<rz && player1->state!=CS_SPECTATOR && d->state!=CS_DEAD)
- {
+ if(fx<r && fy<r && fz<rz && player1->state!=CS_SPECTATOR && d->state!=CS_DEAD) {
if(fx<fy) d->o.y += dy<0 ? r-fy : -(r-fy); // push aside
else d->o.x += dx<0 ? r-fx : -(r-fx);
}
int lagtime = totalmillis-d->lastupdate;
- if(lagtime)
- {
+ if(lagtime) {
if(d->state!=CS_SPAWNING && d->lastupdate) d->plag = (d->plag*5+lagtime)/6;
d->lastupdate = totalmillis;
}
}
-
- void parsepositions(ucharbuf &p)
- {
+ void parsepositions(ucharbuf &p) {
int type;
- while(p.remaining()) switch(type = getint(p))
- {
+ while(p.remaining()) switch(type = getint(p)) {
case N_DEMOPACKET: break;
- case N_POS: // position of another client
- {
+ case N_POS: { // position of another client {
int cn = getuint(p), physstate = p.get(), flags = getuint(p);
vec o, vel, falling;
float yaw, pitch, roll;
- loopk(3)
- {
+ loopk(3) {
int n = p.get(); n |= p.get()<<8; if(flags&(1<<k)) { n |= p.get()<<16; if(n&0x800000) n |= ~0U<<24; }
o[k] = n/DMF;
}
@@ -999,11 +784,9 @@ namespace game
dir = p.get(); dir |= p.get()<<8;
vecfromyawpitch(dir%360, clamp(dir/360, 0, 180)-90, 1, 0, vel);
vel.mul(mag/DVELF);
- if(flags&(1<<4))
- {
+ if(flags&(1<<4)) {
mag = p.get(); if(flags&(1<<5)) mag |= p.get()<<8;
- if(flags&(1<<6))
- {
+ if(flags&(1<<6)) {
dir = p.get(); dir |= p.get()<<8;
vecfromyawpitch(dir%360, clamp(dir/360, 0, 180)-90, 1, 0, falling);
}
@@ -1028,8 +811,7 @@ namespace game
d->physstate = physstate&7;
updatephysstate(d);
updatepos(d);
- if(smoothmove && d->smoothmillis>=0 && oldpos.dist(d->o) < smoothdist)
- {
+ if(smoothmove && d->smoothmillis>=0 && oldpos.dist(d->o) < smoothdist) {
d->newpos = d->o;
d->newyaw = d->yaw;
d->newpitch = d->pitch;
@@ -1050,36 +832,28 @@ namespace game
if(d->state==CS_LAGGED || d->state==CS_SPAWNING) d->state = CS_ALIVE;
break;
}
-
- case N_TELEPORT:
- {
+ case N_TELEPORT: {
int cn = getint(p), tp = getint(p), td = getint(p);
fpsent *d = getclient(cn);
if(!d || d->lifesequence < 0 || d->state==CS_DEAD) continue;
entities::teleporteffects(d, tp, td, false);
break;
}
-
- case N_JUMPPAD:
- {
+ case N_JUMPPAD: {
int cn = getint(p), jp = getint(p);
fpsent *d = getclient(cn);
if(!d || d->lifesequence < 0 || d->state==CS_DEAD) continue;
entities::jumppadeffects(d, jp, false);
break;
}
-
default:
neterr("type");
return;
}
}
-
- void parsestate(fpsent *d, ucharbuf &p, bool resume = false)
- {
+ void parsestate(fpsent *d, ucharbuf &p, bool resume = false) {
if(!d) { static fpsent dummy; d = &dummy; }
- if(resume)
- {
+ if(resume) {
if(d==player1) getint(p);
else d->state = getint(p);
d->frags = getint(p);
@@ -1094,36 +868,26 @@ namespace game
d->armour = getint(p);
d->maxarmour = getint(p);
d->armourtype = getint(p);
- if(resume && d==player1)
- {
+ if(resume && d==player1) {
getint(p);
loopi(GUN_PISTOL-GUN_SG+1) getint(p);
}
- else
- {
+ else {
int gun = getint(p);
d->gunselect = clamp(gun, int(GUN_FIST), int(GUN_PISTOL));
loopi(GUN_PISTOL-GUN_SG+1) d->ammo[GUN_SG+i] = getint(p);
}
}
-
extern int deathscore;
-
- void parsemessages(int cn, fpsent *d, ucharbuf &p)
- {
+ void parsemessages(int cn, fpsent *d, ucharbuf &p) {
static char text[MAXTRANS];
int type;
bool mapchanged = false, demopacket = false;
-
- while(p.remaining()) switch(type = getint(p))
- {
+ while(p.remaining()) switch(type = getint(p)) {
case N_DEMOPACKET: demopacket = true; break;
-
- case N_SERVINFO: // welcome messsage from the server
- {
+ case N_SERVINFO: { // welcome messsage from the server {
int mycn = getint(p), prot = getint(p);
- if(prot!=PROTOCOL_VERSION)
- {
+ if(prot!=PROTOCOL_VERSION) {
conoutf(CON_ERROR, "you are using a different game protocol (you: %d, server: %d)", PROTOCOL_VERSION, prot);
disconnect();
return;
@@ -1136,21 +900,16 @@ namespace game
sendintro();
break;
}
-
- case N_WELCOME:
- {
+ case N_WELCOME: {
connected = true;
notifywelcome();
break;
}
-
- case N_PAUSEGAME:
- {
+ case N_PAUSEGAME: {
bool val = getint(p) > 0;
int cn = getint(p);
fpsent *a = cn >= 0 ? getclient(cn) : NULL;
- if(!demopacket)
- {
+ if(!demopacket) {
gamepaused = val;
player1->attacking = false;
}
@@ -1158,9 +917,7 @@ namespace game
else conoutf("game is %s", val ? "paused" : "resumed");
break;
}
-
- case N_GAMESPEED:
- {
+ case N_GAMESPEED: {
int val = clamp(getint(p), 10, 1000), cn = getint(p);
fpsent *a = cn >= 0 ? getclient(cn) : NULL;
if(!demopacket) gamespeed = val;
@@ -1168,22 +925,17 @@ namespace game
else conoutf("gamespeed is %d", val);
break;
}
-
- case N_CLIENT:
- {
+ case N_CLIENT: {
int cn = getint(p), len = getuint(p);
ucharbuf q = p.subbuf(len);
parsemessages(cn, getclient(cn), q);
break;
}
-
case N_SOUND:
if(!d) return;
playsound(getint(p), &d->o);
break;
-
- case N_TEXT:
- {
+ case N_TEXT: {
if(!d) return;
getstring(text, p);
filtertext(text, text, true, true);
@@ -1193,9 +945,7 @@ namespace game
conoutf(CON_CHAT, "%s:\f0 %s", chatcolorname(d), text);
break;
}
-
- case N_SAYTEAM:
- {
+ case N_SAYTEAM: {
int tcn = getint(p);
fpsent *t = getclient(tcn);
getstring(text, p);
@@ -1206,7 +956,6 @@ namespace game
conoutf(CON_TEAMCHAT, "\fs\f8[team]\fr %s: \f8%s", chatcolorname(t), text);
break;
}
-
case N_MAPCHANGE:
getstring(text, p);
filtertext(text, text, false);
@@ -1216,14 +965,11 @@ namespace game
if(getint(p)) entities::spawnitems();
else senditemstoserver = false;
break;
-
- case N_FORCEDEATH:
- {
+ case N_FORCEDEATH: {
int cn = getint(p);
fpsent *d = cn==player1->clientnum ? player1 : newclient(cn);
if(!d) break;
- if(d==player1)
- {
+ if(d==player1) {
if(editmode) toggleedit();
stopfollowing();
if(deathscore) showscores(true);
@@ -1232,24 +978,18 @@ namespace game
d->state = CS_DEAD;
break;
}
-
- case N_ITEMLIST:
- {
+ case N_ITEMLIST: {
int n;
- while((n = getint(p))>=0 && !p.overread())
- {
+ while((n = getint(p))>=0 && !p.overread()) {
if(mapchanged) entities::setspawn(n, true);
getint(p); // type
}
break;
}
-
- case N_INITCLIENT: // another client either connected or changed name/team
- {
+ case N_INITCLIENT: { // another client either connected or changed name/team {
int cn = getint(p);
fpsent *d = newclient(cn);
- if(!d)
- {
+ if(!d) {
getstring(text, p);
getstring(text, p);
getint(p);
@@ -1258,13 +998,11 @@ namespace game
getstring(text, p);
filtertext(text, text, false, false, MAXNAMELEN);
if(!text[0]) copystring(text, "Anonymous");
- if(d->name[0]) // already connected
- {
+ if(d->name[0]) { // already connected {
if(strcmp(d->name, text) && !isignored(d->clientnum))
conoutf("%s is now known as %s", colorname(d), colorname(d, text));
}
- else // new client
- {
+ else { // new client {
conoutf("\f0join:\f7 %s", colorname(d, text));
if(needclipboard >= 0) needclipboard++;
}
@@ -1275,32 +1013,24 @@ namespace game
d->playermodel = 0;
break;
}
-
case N_SWITCHNAME:
getstring(text, p);
- if(d)
- {
+ if(d) {
filtertext(text, text, false, false, MAXNAMELEN);
if(!text[0]) copystring(text, "Anonymous");
- if(strcmp(text, d->name))
- {
+ if(strcmp(text, d->name)) {
if(!isignored(d->clientnum)) conoutf("%s is now known as %s", colorname(d), colorname(d, text));
copystring(d->name, text, MAXNAMELEN+1);
}
}
break;
-
case N_SWITCHMODEL:
break;
-
case N_CDIS:
clientdisconnected(getint(p));
break;
-
- case N_SPAWN:
- {
- if(d)
- {
+ case N_SPAWN: {
+ if(d) {
if(d->state==CS_DEAD && d->lastpain) saveragdoll(d);
d->respawn();
}
@@ -1311,15 +1041,12 @@ namespace game
lasthit = 0;
break;
}
-
- case N_SPAWNSTATE:
- {
+ case N_SPAWNSTATE: {
int scn = getint(p);
fpsent *s = getclient(scn);
if(!s) { parsestate(NULL, p); break; }
if(s->state==CS_DEAD && s->lastpain) saveragdoll(s);
- if(s==player1)
- {
+ if(s==player1) {
if(editmode) toggleedit();
stopfollowing();
}
@@ -1327,8 +1054,7 @@ namespace game
parsestate(s, p);
s->state = CS_ALIVE;
pickgamespawn(s);
- if(s == player1)
- {
+ if(s == player1) {
showscores(false);
lasthit = 0;
}
@@ -1336,9 +1062,7 @@ namespace game
addmsg(N_SPAWN, "rcii", s, s->lifesequence, s->gunselect);
break;
}
-
- case N_SHOTFX:
- {
+ case N_SHOTFX: {
int scn = getint(p), gun = getint(p), id = getint(p);
vec from, to;
loopk(3) from[k] = getint(p)/DMF;
@@ -1354,17 +1078,14 @@ namespace game
shoteffects(s->gunselect, from, to, s, false, id, prevaction);
break;
}
-
- case N_EXPLODEFX:
- {
+ case N_EXPLODEFX: {
int ecn = getint(p), gun = getint(p), id = getint(p);
fpsent *e = getclient(ecn);
if(!e) break;
explodeeffects(gun, e, false, id);
break;
}
- case N_DAMAGE:
- {
+ case N_DAMAGE: {
int tcn = getint(p),
acn = getint(p),
damage = getint(p),
@@ -1379,9 +1100,7 @@ namespace game
damaged(damage, target, actor, false);
break;
}
-
- case N_HITPUSH:
- {
+ case N_HITPUSH: {
int tcn = getint(p), gun = getint(p), damage = getint(p);
fpsent *target = getclient(tcn);
vec dir;
@@ -1389,9 +1108,7 @@ namespace game
if(target) target->hitpush(damage * (target->health<=0 ? deadpush : 1), dir, NULL, gun);
break;
}
-
- case N_DIED:
- {
+ case N_DIED: {
int vcn = getint(p), acn = getint(p), frags = getint(p), tfrags = getint(p);
fpsent *victim = getclient(vcn),
*actor = getclient(acn);
@@ -1399,8 +1116,7 @@ namespace game
actor->frags = frags;
if(m_teammode) setteaminfo(actor->team, tfrags);
extern int hidefrags;
- if(actor!=player1 && (!hidefrags))
- {
+ if(actor!=player1 && (!hidefrags)) {
defformatstring(ds, "%d", actor->frags);
particle_textcopy(actor->abovehead(), ds, PART_TEXT, 2000, 0x32FF64, 4.0f, -8);
}
@@ -1408,10 +1124,8 @@ namespace game
killed(victim, actor);
break;
}
-
case N_TEAMINFO:
- for(;;)
- {
+ for(;;) {
getstring(text, p);
if(p.overread() || !text[0]) break;
int frags = getint(p);
@@ -1419,27 +1133,20 @@ namespace game
if(m_teammode) setteaminfo(text, frags);
}
break;
-
- case N_GUNSELECT:
- {
+ case N_GUNSELECT: {
if(!d) return;
int gun = getint(p);
d->gunselect = clamp(gun, int(GUN_FIST), int(GUN_PISTOL));
playsound(S_WEAPLOAD, &d->o);
break;
}
-
- case N_TAUNT:
- {
+ case N_TAUNT: {
if(!d) return;
d->lasttaunt = lastmillis;
break;
}
-
- case N_RESUME:
- {
- for(;;)
- {
+ case N_RESUME: {
+ for(;;) {
int cn = getint(p);
if(p.overread() || cn<0) break;
fpsent *d = (cn == player1->clientnum ? player1 : newclient(cn));
@@ -1447,9 +1154,7 @@ namespace game
}
break;
}
-
- case N_ITEMSPAWN:
- {
+ case N_ITEMSPAWN: {
int i = getint(p);
if(!entities::ents.inrange(i)) break;
entities::setspawn(i, true);
@@ -1463,21 +1168,16 @@ namespace game
if(icon >= 0) particle_icon(vec(0.0f, 0.0f, 4.0f).add(entities::ents[i]->o), icon%4, icon/4, PART_HUD_ICON, 2000, 0xFFFFFF, 2.0f, -8);
break;
}
-
- case N_ITEMACC: // server acknowledges that I picked up this item
- {
+ case N_ITEMACC: { // server acknowledges that I picked up this item {
int i = getint(p), cn = getint(p);
- if(cn >= 0)
- {
+ if(cn >= 0) {
fpsent *d = getclient(cn);
entities::pickupeffects(i, d);
}
else entities::setspawn(i, true);
break;
}
-
- case N_CLIPBOARD:
- {
+ case N_CLIPBOARD: {
int cn = getint(p), unpacklen = getint(p), packlen = getint(p);
fpsent *d = getclient(cn);
ucharbuf q = p.subbuf(max(packlen, 0));
@@ -1485,15 +1185,13 @@ namespace game
break;
}
case N_UNDO:
- case N_REDO:
- {
+ case N_REDO: {
int cn = getint(p), unpacklen = getint(p), packlen = getint(p);
fpsent *d = getclient(cn);
ucharbuf q = p.subbuf(max(packlen, 0));
if(d) unpackundo(q.buf, q.maxlen, unpacklen);
break;
}
-
case N_EDITF: // coop editing messages
case N_EDITT:
case N_EDITM:
@@ -1503,8 +1201,7 @@ namespace game
case N_ROTATE:
case N_REPLACE:
case N_DELCUBE:
- case N_EDITVSLOT:
- {
+ case N_EDITVSLOT: {
if(!d) return;
selinfo sel;
sel.o.x = getint(p); sel.o.y = getint(p); sel.o.z = getint(p);
@@ -1512,11 +1209,9 @@ namespace game
sel.grid = getint(p); sel.orient = getint(p);
sel.cx = getint(p); sel.cxs = getint(p); sel.cy = getint(p), sel.cys = getint(p);
sel.corner = getint(p);
- switch(type)
- {
+ switch(type) {
case N_EDITF: { int dir = getint(p), mode = getint(p); if(sel.validate()) mpeditface(dir, mode, sel, false); break; }
- case N_EDITT:
- {
+ case N_EDITT: {
int tex = getint(p),
allfaces = getint(p);
if(p.remaining() < 2) return;
@@ -1531,8 +1226,7 @@ namespace game
case N_COPY: if(d && sel.validate()) mpcopy(d->edit, sel, false); break;
case N_PASTE: if(d && sel.validate()) mppaste(d->edit, sel, false); break;
case N_ROTATE: { int dir = getint(p); if(sel.validate()) mprotate(dir, sel, false); break; }
- case N_REPLACE:
- {
+ case N_REPLACE: {
int oldtex = getint(p),
newtex = getint(p),
insel = getint(p);
@@ -1544,8 +1238,7 @@ namespace game
break;
}
case N_DELCUBE: if(sel.validate()) mpdelcube(sel, false); break;
- case N_EDITVSLOT:
- {
+ case N_EDITVSLOT: {
int delta = getint(p),
allfaces = getint(p);
if(p.remaining() < 2) return;
@@ -1558,48 +1251,40 @@ namespace game
}
break;
}
- case N_REMIP:
- {
+ case N_REMIP: {
if(!d) return;
conoutf("%s remipped", colorname(d));
mpremip(false);
break;
}
- case N_EDITENT: // coop edit of ent
- {
+ case N_EDITENT: { // coop edit of ent {
if(!d) return;
int i = getint(p);
float x = getint(p)/DMF, y = getint(p)/DMF, z = getint(p)/DMF;
int type = getint(p);
int attr1 = getint(p), attr2 = getint(p), attr3 = getint(p), attr4 = getint(p), attr5 = getint(p);
-
mpeditent(i, vec(x, y, z), type, attr1, attr2, attr3, attr4, attr5, false);
break;
}
- case N_EDITVAR:
- {
+ case N_EDITVAR: {
if(!d) return;
int type = getint(p);
getstring(text, p);
string name;
filtertext(name, text, false);
ident *id = getident(name);
- switch(type)
- {
- case ID_VAR:
- {
+ switch(type) {
+ case ID_VAR: {
int val = getint(p);
if(id && id->flags&IDF_OVERRIDE && !(id->flags&IDF_READONLY)) setvar(name, val);
break;
}
- case ID_FVAR:
- {
+ case ID_FVAR: {
float val = getfloat(p);
if(id && id->flags&IDF_OVERRIDE && !(id->flags&IDF_READONLY)) setfvar(name, val);
break;
}
- case ID_SVAR:
- {
+ case ID_SVAR: {
getstring(text, p);
if(id && id->flags&IDF_OVERRIDE && !(id->flags&IDF_READONLY)) setsvar(name, text);
break;
@@ -1608,40 +1293,31 @@ namespace game
printvar(d, id);
break;
}
-
case N_PONG:
addmsg(N_CLIENTPING, "i", player1->ping = (player1->ping*5+totalmillis-getint(p))/6);
break;
-
case N_CLIENTPING:
if(!d) return;
d->ping = getint(p);
break;
-
case N_TIMEUP:
timeupdate(getint(p));
break;
-
case N_SERVMSG:
getstring(text, p);
conoutf("%s", text);
break;
-
- case N_SENDDEMOLIST:
- {
+ case N_SENDDEMOLIST: {
int demos = getint(p);
if(demos <= 0) conoutf("no demos available");
- else loopi(demos)
- {
+ else loopi(demos) {
getstring(text, p);
if(p.overread()) break;
conoutf("%d. %s", i+1, text);
}
break;
}
-
- case N_DEMOPLAYBACK:
- {
+ case N_DEMOPLAYBACK: {
int on = getint(p);
if(on) player1->state = CS_SPECTATOR;
else clearclients();
@@ -1651,80 +1327,62 @@ namespace game
execident(on ? "demostart" : "demoend");
break;
}
-
- case N_CURRENTMASTER:
- {
+ case N_CURRENTMASTER: {
int mm = getint(p), mn;
loopv(players) players[i]->privilege = PRIV_NONE;
- while((mn = getint(p))>=0 && !p.overread())
- {
+ while((mn = getint(p))>=0 && !p.overread()) {
fpsent *m = mn==player1->clientnum ? player1 : newclient(mn);
int priv = getint(p);
if(m) m->privilege = priv;
}
- if(mm != mastermode)
- {
+ if(mm != mastermode) {
mastermode = mm;
conoutf("mastermode is %s (%d)", server::mastermodename(mastermode), mastermode);
}
break;
}
-
- case N_MASTERMODE:
- {
+ case N_MASTERMODE: {
mastermode = getint(p);
conoutf("mastermode is %s (%d)", server::mastermodename(mastermode), mastermode);
break;
}
-
- case N_EDITMODE:
- {
+ case N_EDITMODE: {
int val = getint(p);
if(!d) break;
- if(val)
- {
+ if(val) {
d->editstate = d->state;
d->state = CS_EDITING;
}
- else
- {
+ else {
d->state = d->editstate;
if(d->state==CS_DEAD) deathstate(d, true);
}
break;
}
-
- case N_SPECTATOR:
- {
+ case N_SPECTATOR: {
int sn = getint(p), val = getint(p);
fpsent *s;
- if(sn==player1->clientnum)
- {
+ if(sn==player1->clientnum) {
s = player1;
if(val && remote && !player1->privilege) senditemstoserver = false;
}
else s = newclient(sn);
if(!s) return;
- if(val)
- {
- if(s==player1)
- {
+ if(val) {
+ if(s==player1) {
if(editmode) toggleedit();
if(s->state==CS_DEAD) showscores(false);
disablezoom();
}
s->state = CS_SPECTATOR;
}
- else if(s->state==CS_SPECTATOR)
- {
+ else if(s->state==CS_SPECTATOR) {
if(s==player1) stopfollowing();
deathstate(s, true);
}
break;
}
-
- case N_SETTEAM:
- {
+ case N_SETTEAM: {
int wn = getint(p);
getstring(text, p);
int reason = getint(p);
@@ -1736,44 +1394,34 @@ namespace game
conoutf(fmt[reason], colorname(w), w->team);
break;
}
-
- case N_ANNOUNCE:
- {
+ case N_ANNOUNCE: {
int t = getint(p);
- if (t==I_QUAD) { playsound(S_V_QUAD10, NULL, NULL, 0, 0, 0, -1, 0, 3000); conoutf(CON_GAMEINFO, "\f2quad damage will spawn in 10 seconds!"); }
+ if (t==I_QUAD) { playsound(S_V_QUAD10, NULL, NULL, 0, 0, 0, -1, 0, 3000); conoutf(CON_GAMEINFO, "\f2quad damage will spawn in 10 seconds!"); }
else if(t==I_BOOST) { playsound(S_V_BOOST10, NULL, NULL, 0, 0, 0, -1, 0, 3000); conoutf(CON_GAMEINFO, "\f2health boost will spawn in 10 seconds!"); }
break;
}
-
- case N_NEWMAP:
- {
+ case N_NEWMAP: {
int size = getint(p);
if(size>=0) emptymap(size, true, NULL);
else enlargemap(true);
- if(d && d!=player1)
- {
+ if(d && d!=player1) {
int newsize = 0;
while(1<<newsize < getworldsize()) newsize++;
conoutf(size>=0 ? "%s started a new map of size %d" : "%s enlarged the map to size %d", colorname(d), newsize);
}
break;
}
-
- case N_REQAUTH:
- {
+ case N_REQAUTH: {
getstring(text, p);
if(autoauth && text[0] && tryauth(text)) conoutf("server requested authkey \"%s\"", text);
break;
}
-
- case N_AUTHCHAL:
- {
+ case N_AUTHCHAL: {
getstring(text, p);
authkey *a = findauthkey(text);
uint id = (uint)getint(p);
getstring(text, p);
- if(a && a->lastauth && lastmillis - a->lastauth < 60*1000)
- {
+ if(a && a->lastauth && lastmillis - a->lastauth < 60*1000) {
vector<char> buf;
answerchallenge(a->key, text, buf);
//conoutf(CON_DEBUG, "answering %u, challenge %s with %s", id, text, buf.getbuf());
@@ -1786,9 +1434,7 @@ namespace game
}
break;
}
-
- case N_INITAI:
- {
+ case N_INITAI: {
int bn = getint(p), on = getint(p), at = getint(p), sk = clamp(getint(p), 1, 101), pm = getint(p);
string name, team;
getstring(text, p);
@@ -1800,45 +1446,35 @@ namespace game
ai::init(b, at, on, sk, bn, pm, name, team);
break;
}
-
case N_SERVCMD:
getstring(text, p);
break;
-
default:
neterr("type", cn < 0);
return;
}
}
-
- struct demoreq
- {
+ struct demoreq {
int tag;
string name;
};
vector<demoreq> demoreqs;
enum { MAXDEMOREQS = 7 };
static int lastdemoreq = 0;
-
- void receivefile(packetbuf &p)
- {
+ void receivefile(packetbuf &p) {
int type;
- while(p.remaining()) switch(type = getint(p))
- {
+ while(p.remaining()) switch(type = getint(p)) {
case N_DEMOPACKET: return;
- case N_SENDDEMO:
- {
+ case N_SENDDEMO: {
string fname;
fname[0] = '\0';
int tag = getint(p);
- loopv(demoreqs) if(demoreqs[i].tag == tag)
- {
+ loopv(demoreqs) if(demoreqs[i].tag == tag) {
copystring(fname, demoreqs[i].name);
demoreqs.remove(i);
break;
}
- if(!fname[0])
- {
+ if(!fname[0]) {
time_t t = time(NULL);
size_t len = strftime(fname, sizeof(fname), "%Y-%m-%d_%H.%M.%S", localtime(&t));
fname[min(len, sizeof(fname)-1)] = '\0';
@@ -1855,9 +1491,7 @@ namespace game
delete demo;
break;
}
-
- case N_SENDMAP:
- {
+ case N_SENDMAP: {
if(!m_edit) return;
string oldname;
copystring(oldname, getclientmap());
@@ -1876,69 +1510,52 @@ namespace game
}
}
}
-
- void parsepacketclient(int chan, packetbuf &p) // processes any updates from the server
- {
+ void parsepacketclient(int chan, packetbuf &p) { // processes any updates from the server {
if(p.packet->flags&ENET_PACKET_FLAG_UNSEQUENCED) return;
- switch(chan)
- {
+ switch(chan) {
case 0:
parsepositions(p);
break;
-
case 1:
parsemessages(-1, NULL, p);
break;
-
case 2:
receivefile(p);
break;
}
}
-
- void getmap()
- {
+ void getmap() {
if(!m_edit) { conoutf(CON_ERROR, "\"getmap\" only works in coop edit mode"); return; }
conoutf("getting map...");
addmsg(N_GETMAP, "r");
}
COMMAND(getmap, "");
-
- void stopdemo()
- {
- if(remote)
- {
+ void stopdemo() {
+ if(remote) {
if(player1->privilege<PRIV_MASTER) return;
addmsg(N_STOPDEMO, "r");
}
else server::stopdemo();
}
COMMAND(stopdemo, "");
-
- void recorddemo(int val)
- {
+ void recorddemo(int val) {
if(remote && player1->privilege<PRIV_MASTER) return;
addmsg(N_RECORDDEMO, "ri", val);
}
ICOMMAND(recorddemo, "i", (int *val), recorddemo(*val));
-
- void cleardemos(int val)
- {
+ void cleardemos(int val) {
if(remote && player1->privilege<PRIV_MASTER) return;
addmsg(N_CLEARDEMOS, "ri", val);
}
ICOMMAND(cleardemos, "i", (int *val), cleardemos(*val));
-
- void getdemo(char *val, char *name)
- {
+ void getdemo(char *val, char *name) {
int i = 0;
if(isdigit(val[0]) || name[0]) i = parseint(val);
else name = val;
if(i<=0) conoutf("getting demo...");
else conoutf("getting demo %d...", i);
++lastdemoreq;
- if(name[0])
- {
+ if(name[0]) {
if(demoreqs.length() >= MAXDEMOREQS) demoreqs.remove(0);
demoreq &r = demoreqs.add();
r.tag = lastdemoreq;
@@ -1947,29 +1564,23 @@ namespace game
addmsg(N_GETDEMO, "rii", i, lastdemoreq);
}
ICOMMAND(getdemo, "ss", (char *val, char *name), getdemo(val, name));
-
- void listdemos()
- {
+ void listdemos() {
conoutf("listing demos...");
addmsg(N_LISTDEMOS, "r");
}
COMMAND(listdemos, "");
-
- void sendmap()
- {
+ void sendmap() {
if(!m_edit || (player1->state==CS_SPECTATOR && remote && !player1->privilege)) { conoutf(CON_ERROR, "\"sendmap\" only works in coop edit mode"); return; }
conoutf("sending map...");
defformatstring(mname, "sendmap_%d", lastmillis);
save_world(mname, true);
defformatstring(fname, "packages/maps/%s.ogz", mname);
stream *map = openrawfile(path(fname), "rb");
- if(map)
- {
+ if(map) {
stream::offset len = map->size();
if(len > 4*1024*1024) conoutf(CON_ERROR, "map is too large");
else if(len <= 0) conoutf(CON_ERROR, "could not read map");
- else
- {
+ else {
sendfile(-1, 2, map);
if(needclipboard >= 0) needclipboard++;
}
@@ -1979,13 +1590,10 @@ namespace game
remove(findfile(fname, "rb"));
}
COMMAND(sendmap, "");
-
- void gotoplayer(const char *arg)
- {
+ void gotoplayer(const char *arg) {
if(player1->state!=CS_SPECTATOR && player1->state!=CS_EDITING) return;
int i = parseplayer(arg);
- if(i>=0)
- {
+ if(i>=0) {
fpsent *d = getclient(i);
if(!d || d==player1) return;
player1->o = d->o;
@@ -1996,9 +1604,7 @@ namespace game
}
}
COMMANDN(goto, gotoplayer, "s");
-
- void gotosel()
- {
+ void gotosel() {
if(player1->state!=CS_EDITING) return;
player1->o = getselpos();
vec dir;
diff --git a/src/fpsgame/entities.cpp b/src/fpsgame/entities.cpp
index 93e3dc9..9336c4e 100644
--- a/src/fpsgame/entities.cpp
+++ b/src/fpsgame/entities.cpp
@@ -2,38 +2,27 @@
int pwitemspicked[7] = { 0 };
-namespace entities
-{
+namespace entities {
using namespace game;
-
int extraentinfosize() { return 0; } // size in bytes of what the 2 methods below read/write... so it can be skipped by other games
#ifndef STANDALONE
vector<extentity *> ents;
-
vector<extentity *> &getents() { return ents; }
-
bool mayattach(extentity &e) { return false; }
bool attachent(extentity &e, extentity &a) { return false; }
-
- const char *itemname(int i)
- {
+ const char *itemname(int i) {
int t = ents[i]->type;
if(t<I_SHELLS || t>I_QUAD) return NULL;
return itemstats[t-I_SHELLS].name;
}
-
- int itemicon(int i)
- {
+ int itemicon(int i) {
int t = ents[i]->type;
if(t<I_SHELLS || t>I_QUAD) return -1;
return itemstats[t-I_SHELLS].icon;
}
-
- const char *entmdlname(int type)
- {
- static const char * const entmdlnames[] =
- {
+ const char *entmdlname(int type) {
+ static const char * const entmdlnames[] = {
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"ammo/shells", "ammo/bullets", "ammo/rockets", "ammo/rrounds", "ammo/grenades", "ammo/cartridges",
"health", "boost", "tinyhealth", "tinyarmour", "armor/green", "armor/yellow", "quad", "teleporter",
@@ -47,23 +36,16 @@ namespace entities
};
return entmdlnames[type];
}
-
- const char *entmodel(const entity &e)
- {
- if(e.type == TELEPORT)
- {
+ const char *entmodel(const entity &e) {
+ if(e.type == TELEPORT) {
if(e.attr2 > 0) return mapmodelname(e.attr2);
if(e.attr2 < 0) return NULL;
}
return e.type < MAXENTTYPES ? entmdlname(e.type) : NULL;
}
-
- void preloadentities()
- {
- loopi(MAXENTTYPES)
- {
- switch(i)
- {
+ void preloadentities() {
+ loopi(MAXENTTYPES) {
+ switch(i) {
case I_SHELLS:
[[fallthrough]];
case I_BULLETS:
@@ -97,30 +79,23 @@ namespace entities
if(!mdl) continue;
preloadmodel(mdl);
}
- loopv(ents)
- {
+ loopv(ents) {
extentity &e = *ents[i];
- switch(e.type)
- {
+ switch(e.type) {
case TELEPORT:
if(e.attr2 > 0) preloadmodel(mapmodelname(e.attr2));
[[fallthrough]];
-
case JUMPPAD:
if(e.attr4 > 0) preloadmapsound(e.attr4);
break;
}
}
}
-
- void renderentities()
- {
- loopv(ents)
- {
+ void renderentities() {
+ loopv(ents) {
extentity &e = *ents[i];
int revs = 10;
- switch(e.type)
- {
+ switch(e.type) {
case TELEPORT:
if(e.attr2 < 0) continue;
break;
@@ -128,33 +103,25 @@ namespace entities
if(!e.spawned() || e.type < I_SHELLS || e.type > I_QUAD) continue;
}
const char *mdlname = entmodel(e);
- if(mdlname)
- {
+ if(mdlname) {
vec p = e.o;
p.z += 1+sinf(lastmillis/100.0+e.o.x+e.o.y)/20;
rendermodel(&e.light, mdlname, ANIM_MAPMODEL|ANIM_LOOP, p, lastmillis/(float)revs, 0, MDL_SHADOW | MDL_CULL_VFC | MDL_CULL_DIST | MDL_CULL_OCCLUDED);
}
}
}
-
- void addammo(int type, int &v, bool local)
- {
+ void addammo(int type, int &v, bool local) {
itemstat &is = itemstats[type-I_SHELLS];
v += is.add;
if(v>is.max) v = is.max;
if(local) msgsound(is.sound);
}
-
- void repammo(fpsent *d, int type, bool local)
- {
+ void repammo(fpsent *d, int type, bool local) {
addammo(type, d->ammo[type-I_SHELLS+GUN_SG], local);
}
-
// these two functions are called when the server acknowledges that you really
// picked up the item (in multiplayer someone may grab it before you).
-
- void pickupeffects(int n, fpsent *d)
- {
+ void pickupeffects(int n, fpsent *d) {
if(!ents.inrange(n)) return;
extentity *e = ents[n];
int type = e->type;
@@ -164,8 +131,7 @@ namespace entities
if(!d) return;
itemstat &is = itemstats[type-I_SHELLS];
fpsent *h = followingplayer(player1);
- if(d!=h || isthirdperson())
- {
+ if(d!=h || isthirdperson()) {
//particle_text(d->abovehead(), is.name, PART_TEXT, 2000, 0xFFC864, 4.0f, -8);
particle_icon(d->abovehead(), is.icon%4, is.icon/4, PART_HUD_ICON_GREY, 2000, 0xFFFFFF, 2.0f, -8);
}
@@ -180,29 +146,22 @@ namespace entities
case I_BOOST: pwitemspicked[5]++; break;
case I_QUAD: pwitemspicked[6]++; break;
}
- if(d==h) switch(type)
- {
+ if(d==h) switch(type) {
case I_BOOST:
conoutf(CON_GAMEINFO, "\f2you got the health boost!");
playsound(S_V_BOOST, NULL, NULL, 0, 0, 0, -1, 0, 3000);
break;
-
case I_QUAD:
conoutf(CON_GAMEINFO, "\f2you got the quad!");
playsound(S_V_QUAD, NULL, NULL, 0, 0, 0, -1, 0, 3000);
break;
}
}
-
// these functions are called when the client touches the item
-
- void teleporteffects(fpsent *d, int tp, int td, bool local)
- {
- if(ents.inrange(tp) && ents[tp]->type == TELEPORT)
- {
+ void teleporteffects(fpsent *d, int tp, int td, bool local) {
+ if(ents.inrange(tp) && ents[tp]->type == TELEPORT) {
extentity &e = *ents[tp];
- if(e.attr4 >= 0)
- {
+ if(e.attr4 >= 0) {
int snd = S_TELEPORT, flags = 0;
if(e.attr4 > 0) { snd = e.attr4; flags = SND_MAP; }
fpsent *h = followingplayer(player1);
@@ -210,8 +169,7 @@ namespace entities
if(d!=h && ents.inrange(td) && ents[td]->type == TELEDEST) playsound(snd, &ents[td]->o, NULL, flags);
}
}
- if(local && d->clientnum >= 0)
- {
+ if(local && d->clientnum >= 0) {
sendposition(d);
packetbuf p(32, ENET_PACKET_FLAG_RELIABLE);
putint(p, N_TELEPORT);
@@ -222,21 +180,16 @@ namespace entities
flushclient();
}
}
-
- void jumppadeffects(fpsent *d, int jp, bool local)
- {
- if(ents.inrange(jp) && ents[jp]->type == JUMPPAD)
- {
+ void jumppadeffects(fpsent *d, int jp, bool local) {
+ if(ents.inrange(jp) && ents[jp]->type == JUMPPAD) {
extentity &e = *ents[jp];
- if(e.attr4 >= 0)
- {
+ if(e.attr4 >= 0) {
int snd = S_JUMPPAD, flags = 0;
if(e.attr4 > 0) { snd = e.attr4; flags = SND_MAP; }
playsound(snd, d == followingplayer(player1) ? NULL : &e.o, NULL, flags);
}
}
- if(local && d->clientnum >= 0)
- {
+ if(local && d->clientnum >= 0) {
sendposition(d);
packetbuf p(16, ENET_PACKET_FLAG_RELIABLE);
putint(p, N_JUMPPAD);
@@ -246,22 +199,17 @@ namespace entities
flushclient();
}
}
-
- void teleport(int n, fpsent *d) // also used by monsters
- {
+ void teleport(int n, fpsent *d) { // also used by monsters {
int e = -1, tag = ents[n]->attr1, beenhere = -1;
- for(;;)
- {
+ for(;;) {
e = findentity(TELEDEST, e+1);
if(e==beenhere || e<0) { conoutf(CON_WARN, "no teleport destination for tag %d", tag); return; }
if(beenhere<0) beenhere = e;
- if(ents[e]->attr2==tag)
- {
+ if(ents[e]->attr2==tag) {
teleporteffects(d, n, e, true);
d->o = ents[e]->o;
d->yaw = ents[e]->attr1;
- if(ents[e]->attr3 > 0)
- {
+ if(ents[e]->attr3 > 0) {
vec dir;
vecfromyawpitch(d->yaw, 0, 1, 0, dir);
float speed = d->vel.magnitude2();
@@ -276,25 +224,18 @@ namespace entities
}
}
}
-
- void trypickup(int n, fpsent *d)
- {
+ void trypickup(int n, fpsent *d) {
extentity *e = ents[n];
- switch(e->type)
- {
+ switch(e->type) {
default:
- if(d->canpickup(e->type))
- {
+ if(d->canpickup(e->type)) {
addmsg(N_ITEMPICKUP, "rci", d, n);
e->setnopickup(); // even if someone else gets it first
}
break;
-
- case TELEPORT:
- {
+ case TELEPORT: {
if(d->lastpickup==e->type && lastmillis-d->lastpickupmillis<500) break;
- if(e->attr3 > 0)
- {
+ if(e->attr3 > 0) {
defformatstring(hookname, "can_teleport_%d", e->attr3);
if(!execidentbool(hookname, true)) break;
}
@@ -303,9 +244,7 @@ namespace entities
teleport(n, d);
break;
}
-
- case JUMPPAD:
- {
+ case JUMPPAD: {
if(d->lastpickup==e->type && lastmillis-d->lastpickupmillis<300) break;
d->lastpickup = e->type;
d->lastpickupmillis = lastmillis;
@@ -320,13 +259,10 @@ namespace entities
}
}
}
-
- void checkitems(fpsent *d)
- {
+ void checkitems(fpsent *d) {
if(d->state!=CS_ALIVE) return;
vec o = d->feetpos();
- loopv(ents)
- {
+ loopv(ents) {
extentity &e = *ents[i];
if(e.type==NOTUSED) continue;
if((!e.spawned() || e.nopickup()) && e.type!=TELEPORT && e.type!=JUMPPAD) continue;
@@ -334,97 +270,68 @@ namespace entities
if(dist<(e.type==TELEPORT ? 16 : 12)) trypickup(i, d);
}
}
-
- void checkquad(int time, fpsent *d)
- {
- if(d->quadmillis && (d->quadmillis -= time)<=0)
- {
+ void checkquad(int time, fpsent *d) {
+ if(d->quadmillis && (d->quadmillis -= time)<=0) {
d->quadmillis = 0;
fpsent *h = followingplayer(player1);
playsound(S_PUPOUT, d==h ? NULL : &d->o);
if(d==h) conoutf(CON_GAMEINFO, "\f2quad damage is over");
}
}
-
- void putitems(packetbuf &p) // puts items in network stream and also spawns them locally
- {
+ void putitems(packetbuf &p) { // puts items in network stream and also spawns them locally {
putint(p, N_ITEMLIST);
- loopv(ents) if(ents[i]->type>=I_SHELLS && ents[i]->type<=I_QUAD && (!m_noammo || ents[i]->type<I_SHELLS || ents[i]->type>I_CARTRIDGES))
- {
+ loopv(ents) if(ents[i]->type>=I_SHELLS && ents[i]->type<=I_QUAD && (!m_noammo || ents[i]->type<I_SHELLS || ents[i]->type>I_CARTRIDGES)) {
putint(p, i);
putint(p, ents[i]->type);
}
putint(p, -1);
}
-
void resetspawns() { loopv(ents) { extentity *e = ents[i]; e->clearspawned(); e->clearnopickup(); } }
-
- void spawnitems(bool force)
- {
+ void spawnitems(bool force) {
if(m_noitems) return;
- loopv(ents)
- {
+ loopv(ents) {
extentity *e = ents[i];
- if(e->type>=I_SHELLS && e->type<=I_QUAD && (!m_noammo || e->type<I_SHELLS || e->type>I_CARTRIDGES))
- {
+ if(e->type>=I_SHELLS && e->type<=I_QUAD && (!m_noammo || e->type<I_SHELLS || e->type>I_CARTRIDGES)) {
e->setspawned(force || !server::delayspawn(e->type));
e->clearnopickup();
}
}
}
-
void setspawn(int i, bool on) { if(ents.inrange(i)) { extentity *e = ents[i]; e->setspawned(on); e->clearnopickup(); } }
-
extentity *newentity() { return new extentity(); }
void deleteentity(extentity *e) { delete e; }
-
- void clearents()
- {
+ void clearents() {
while(ents.length()) deleteentity(ents.pop());
}
-
- void fixentity(extentity &e)
- {
+ void fixentity(extentity &e) {
if(e.type == TELEDEST) e.attr3 = e.attr2;
}
-
- void entradius(extentity &e, bool color)
- {
- switch(e.type)
- {
- case TELEDEST:
- {
+ void entradius(extentity &e, bool color) {
+ switch(e.type) {
+ case TELEDEST: {
vec dir;
vecfromyawpitch(e.attr1, 0, 1, 0, dir);
renderentarrow(e, dir, 4);
break;
}
case TELEPORT:
- loopv(ents) if(ents[i]->type == TELEDEST && e.attr1==ents[i]->attr2)
- {
+ loopv(ents) if(ents[i]->type == TELEDEST && e.attr1==ents[i]->attr2) {
renderentarrow(e, vec(ents[i]->o).sub(e.o).normalize(), e.o.dist(ents[i]->o));
break;
}
break;
-
case JUMPPAD:
renderentarrow(e, vec((int)(char)e.attr3*10.0f, (int)(char)e.attr2*10.0f, e.attr1*12.5f).normalize(), 4);
break;
-
default: break;
}
}
-
- bool printent(extentity &e, char *buf, int len)
- {
+ bool printent(extentity &e, char *buf, int len) {
return false;
}
-
const char *entnameinfo(entity &e) { return ""; }
- const char *entname(int i)
- {
- static const char * const entnames[] =
- {
+ const char *entname(int i) {
+ static const char * const entnames[] = {
"none?", "light", "mapmodel", "playerstart", "none?", "particles", "sound", "spotlight",
"shells", "bullets", "rockets", "riflerounds", "grenades", "cartridges",
"health", "healthboost", "tinyhealth", "tinyarmour", "greenarmour", "yellowarmour", "quaddamage",
@@ -434,9 +341,7 @@ namespace entities
};
return i>=0 && size_t(i)<sizeof(entnames)/sizeof(entnames[0]) ? entnames[i] : "";
}
-
- void editent(int i, bool local)
- {
+ void editent(int i, bool local) {
extentity &e = *ents[i];
if(local) addmsg(N_EDITENT, "rii3ii5", i, (int)(e.o.x*DMF), (int)(e.o.y*DMF), (int)(e.o.z*DMF), e.type, e.attr1, e.attr2, e.attr3, e.attr4, e.attr5);
}
diff --git a/src/fpsgame/extinfo.h b/src/fpsgame/extinfo.h
index 059ee27..b467a8c 100644
--- a/src/fpsgame/extinfo.h
+++ b/src/fpsgame/extinfo.h
@@ -15,7 +15,6 @@
A: 0 EXT_UPTIME
B: 0 EXT_PLAYERSTATS cn #a client number or -1 for all players#
C: 0 EXT_TEAMSCORE
-
Server:
--------
A: 0 EXT_UPTIME EXT_ACK EXT_VERSION uptime #in seconds#
@@ -23,16 +22,12 @@
EXT_PLAYERSTATS_RESP_IDS pid(s) #1 packet#
EXT_PLAYERSTATS_RESP_STATS pid playerdata #1 packet for each player#
C: 0 EXT_TEAMSCORE EXT_ACK EXT_VERSION 0 or 1 #error, no teammode# remaining_time gamemode loop(teamdata [numbases bases] or -1)
-
Errors:
--------------
B:C:default: 0 command EXT_ACK EXT_VERSION EXT_ERROR
*/
-
VAR(extinfoip, 0, 0, 1);
-
- void extinfoplayer(ucharbuf &p, clientinfo *ci)
- {
+ void extinfoplayer(ucharbuf &p, clientinfo *ci) {
ucharbuf q = p;
putint(q, EXT_PLAYERSTATS_RESP_STATS); // send player stats following
putint(q, ci->clientnum); //add player id
@@ -53,91 +48,65 @@
q.put((uchar*)&ip, 3);
sendserverinforeply(q);
}
-
- static inline void extinfoteamscore(ucharbuf &p, const char *team, int score)
- {
+ static inline void extinfoteamscore(ucharbuf &p, const char *team, int score) {
sendstring(team, p);
putint(p, score);
putint(p,-1); //no bases follow
}
-
- void extinfoteams(ucharbuf &p)
- {
+ void extinfoteams(ucharbuf &p) {
putint(p, m_teammode ? 0 : 1);
putint(p, gamemode);
putint(p, max((gamelimit - gamemillis)/1000, 0));
if(!m_teammode) return;
-
vector<teamscore> scores;
- loopv(clients)
- {
+ loopv(clients) {
clientinfo *ci = clients[i];
- if(ci->state.state!=CS_SPECTATOR && ci->team[0] && scores.htfind(ci->team) < 0)
- {
+ if(ci->state.state!=CS_SPECTATOR && ci->team[0] && scores.htfind(ci->team) < 0) {
teaminfo *ti = teaminfos.access(ci->team);
scores.add(teamscore(ci->team, ti ? ti->frags : 0));
}
}
loopv(scores) extinfoteamscore(p, scores[i].team, scores[i].score);
}
-
- void extserverinforeply(ucharbuf &req, ucharbuf &p)
- {
+ void extserverinforeply(ucharbuf &req, ucharbuf &p) {
int extcmd = getint(req); // extended commands
-
//Build a new packet
putint(p, EXT_ACK); //send ack
putint(p, EXT_VERSION); //send version of extended info
-
- switch(extcmd)
- {
- case EXT_UPTIME:
- {
+ switch(extcmd) {
+ case EXT_UPTIME: {
putint(p, totalsecs); //in seconds
break;
}
-
- case EXT_PLAYERSTATS:
- {
+ case EXT_PLAYERSTATS: {
int cn = getint(req); //a special player, -1 for all
-
clientinfo *ci = NULL;
- if(cn >= 0)
- {
+ if(cn >= 0) {
loopv(clients) if(clients[i]->clientnum == cn) { ci = clients[i]; break; }
- if(!ci)
- {
+ if(!ci) {
putint(p, EXT_ERROR); //client requested by id was not found
sendserverinforeply(p);
return;
}
}
-
putint(p, EXT_NO_ERROR); //so far no error can happen anymore
-
ucharbuf q = p; //remember buffer position
putint(q, EXT_PLAYERSTATS_RESP_IDS); //send player ids following
if(ci) putint(q, ci->clientnum);
else loopv(clients) putint(q, clients[i]->clientnum);
sendserverinforeply(q);
-
if(ci) extinfoplayer(p, ci);
else loopv(clients) extinfoplayer(p, clients[i]);
return;
}
-
- case EXT_TEAMSCORE:
- {
+ case EXT_TEAMSCORE: {
extinfoteams(p);
break;
}
-
- default:
- {
+ default: {
putint(p, EXT_ERROR);
break;
}
}
sendserverinforeply(p);
}
-
diff --git a/src/fpsgame/fps.cpp b/src/fpsgame/fps.cpp
index da678f6..c74f5f4 100644
--- a/src/fpsgame/fps.cpp
+++ b/src/fpsgame/fps.cpp
@@ -1,39 +1,28 @@
#include "game.h"
-namespace game
-{
+namespace game {
bool intermission = false;
int maptime = 0, maprealtime = 0, maplimit = -1;
int respawnent = -1;
int lasthit = 0, lastspawnattempt = 0;
-
int following = -1, followdir = 0;
-
fpsent *player1 = NULL; // our client
vector<fpsent *> players; // other clients
int savedammo[NUMGUNS];
-
bool clientoption(const char *arg) { return false; }
-
- void taunt()
- {
+ void taunt() {
if(player1->state!=CS_ALIVE || player1->physstate<PHYS_SLOPE) return;
if(lastmillis-player1->lasttaunt<1000) return;
player1->lasttaunt = lastmillis;
addmsg(N_TAUNT, "rc", player1);
}
COMMAND(taunt, "");
-
- ICOMMAND(getfollow, "", (),
- {
+ ICOMMAND(getfollow, "", (), {
fpsent *f = followingplayer();
intret(f ? f->clientnum : -1);
});
-
- void follow(char *arg)
- {
- if(arg[0] ? player1->state==CS_SPECTATOR : following>=0)
- {
+ void follow(char *arg) {
+ if(arg[0] ? player1->state==CS_SPECTATOR : following>=0) {
following = arg[0] ? parseplayer(arg) : -1;
if(following==player1->clientnum) following = -1;
followdir = 0;
@@ -41,20 +30,15 @@ namespace game
}
}
COMMAND(follow, "s");
-
- void nextfollow(int dir)
- {
- if(player1->state!=CS_SPECTATOR || clients.empty())
- {
+ void nextfollow(int dir) {
+ if(player1->state!=CS_SPECTATOR || clients.empty()) {
stopfollowing();
return;
}
int cur = following >= 0 ? following : (dir < 0 ? clients.length() - 1 : 0);
- loopv(clients)
- {
+ loopv(clients) {
cur = (cur + dir + clients.length()) % clients.length();
- if(clients[cur] && clients[cur]->state!=CS_SPECTATOR)
- {
+ if(clients[cur] && clients[cur]->state!=CS_SPECTATOR) {
if(following<0) conoutf("follow on");
following = cur;
followdir = dir;
@@ -65,117 +49,85 @@ namespace game
}
ICOMMAND(nextfollow, "i", (int *dir), nextfollow(*dir < 0 ? -1 : 1));
-
const char *getclientmap() { return clientmap; }
-
- void resetgamestate()
- {
+ void resetgamestate() {
clearprojectiles();
clearbouncers();
}
-
- fpsent *spawnstate(fpsent *d) // reset player state not persistent accross spawns
- {
+ fpsent *spawnstate(fpsent *d) { // reset player state not persistent accross spawns {
d->respawn();
d->spawnstate(gamemode);
return d;
}
-
- void respawnself()
- {
+ void respawnself() {
if(ispaused()) return;
- if(m_mp(gamemode))
- {
+ if(m_mp(gamemode)) {
int seq = (player1->lifesequence<<16)|((lastmillis/1000)&0xFFFF);
if(player1->respawned!=seq) { addmsg(N_TRYSPAWN, "rc", player1); player1->respawned = seq; }
}
- else
- {
+ else {
spawnplayer(player1);
showscores(false);
lasthit = 0;
}
}
-
- fpsent *pointatplayer()
- {
+ fpsent *pointatplayer() {
loopv(players) if(players[i] != player1 && intersect(players[i], player1->o, worldpos)) return players[i];
return NULL;
}
-
- void stopfollowing()
- {
+ void stopfollowing() {
if(following<0) return;
following = -1;
followdir = 0;
conoutf("follow off");
}
-
- fpsent *followingplayer(fpsent *fallback)
- {
+ fpsent *followingplayer(fpsent *fallback) {
if(player1->state!=CS_SPECTATOR || following<0) return fallback;
fpsent *target = getclient(following);
if(target && target->state!=CS_SPECTATOR) return target;
return fallback;
}
-
- fpsent *hudplayer()
- {
+ fpsent *hudplayer() {
if(thirdperson && allowthirdperson()) return player1;
return followingplayer(player1);
}
-
- void setupcamera()
- {
+ void setupcamera() {
fpsent *target = followingplayer();
- if(target)
- {
+ if(target) {
player1->yaw = target->yaw;
player1->pitch = target->state==CS_DEAD ? 0 : target->pitch;
player1->o = target->o;
player1->resetinterp();
}
}
-
- bool allowthirdperson(bool msg)
- {
+ bool allowthirdperson(bool msg) {
return player1->state==CS_SPECTATOR || player1->state==CS_EDITING || m_edit || !multiplayer(msg);
}
ICOMMAND(allowthirdperson, "b", (int *msg), intret(allowthirdperson(*msg!=0) ? 1 : 0));
-
- bool detachcamera()
- {
+ bool detachcamera() {
fpsent *d = hudplayer();
return d->state==CS_DEAD;
}
-
- bool collidecamera()
- {
- switch(player1->state)
- {
+ bool collidecamera() {
+ switch(player1->state) {
case CS_EDITING: return false;
case CS_SPECTATOR: return followingplayer()!=NULL;
}
return true;
}
-
VARP(smoothmove, 0, 75, 100);
VARP(smoothdist, 0, 32, 64);
-
- void predictplayer(fpsent *d, bool move)
- {
+ void predictplayer(fpsent *d, bool move) {
d->o = d->newpos;
d->yaw = d->newyaw;
d->pitch = d->newpitch;
d->roll = d->newroll;
- if(move)
- {
+ if(move) {
moveplayer(d, 1, false);
d->newpos = d->o;
}
float k = 1.0f - float(lastmillis - d->smoothmillis)/smoothmove;
- if(k>0)
- {
+ if(k>0) {
d->o.add(vec(d->deltapos).mul(k));
d->yaw += d->deltayaw*k;
if(d->yaw<0) d->yaw += 360;
@@ -184,57 +136,42 @@ namespace game
d->roll += d->deltaroll*k;
}
}
-
- void otherplayers(int curtime)
- {
- loopv(players)
- {
+ void otherplayers(int curtime) {
+ loopv(players) {
fpsent *d = players[i];
if(d == player1 || d->ai) continue;
-
if(d->state==CS_DEAD && d->ragdoll) moveragdoll(d);
- else if(!intermission)
- {
+ else if(!intermission) {
if(lastmillis - d->lastaction >= d->gunwait) d->gunwait = 0;
if(d->quadmillis) entities::checkquad(curtime, d);
}
-
const int lagtime = totalmillis-d->lastupdate;
if(!lagtime || intermission) continue;
- else if(lagtime>1000 && d->state==CS_ALIVE)
- {
+ else if(lagtime>1000 && d->state==CS_ALIVE) {
d->state = CS_LAGGED;
continue;
}
- if(d->state==CS_ALIVE || d->state==CS_EDITING)
- {
+ if(d->state==CS_ALIVE || d->state==CS_EDITING) {
if(smoothmove && d->smoothmillis>0) predictplayer(d, true);
else moveplayer(d, 1, false);
}
else if(d->state==CS_DEAD && !d->ragdoll && lastmillis-d->lastpain<2000) moveplayer(d, 1, true);
}
}
-
- void checkslowmo()
- {
+ void checkslowmo() {
static int lastslowmohealth = 0;
server::forcegamespeed(intermission ? 100 : clamp(player1->health, 25, 200));
- if(player1->health<player1->maxhealth && lastmillis-max(maptime, lastslowmohealth)>player1->health*player1->health/2)
- {
+ if(player1->health<player1->maxhealth && lastmillis-max(maptime, lastslowmohealth)>player1->health*player1->health/2) {
lastslowmohealth = lastmillis;
player1->health++;
}
}
-
- void updateworld() // main game update loop
- {
+ void updateworld() { // main game update loop {
if(!maptime) { maptime = lastmillis; maprealtime = totalmillis; return; }
if(!curtime) { gets2c(); if(player1->clientnum>=0) c2sinfo(); return; }
-
physicsframe();
ai::navigate();
- if(player1->state != CS_DEAD && !intermission)
- {
+ if(player1->state != CS_DEAD && !intermission) {
if(player1->quadmillis) entities::checkquad(curtime, player1);
}
updateweapons(curtime);
@@ -242,19 +179,15 @@ namespace game
ai::update();
moveragdolls();
gets2c();
- if(connected)
- {
- if(player1->state == CS_DEAD)
- {
+ if(connected) {
+ if(player1->state == CS_DEAD) {
if(player1->ragdoll) moveragdoll(player1);
- else if(lastmillis-player1->lastpain<2000)
- {
+ else if(lastmillis-player1->lastpain<2000) {
player1->move = player1->strafe = 0;
moveplayer(player1, 10, true);
}
}
- else if(!intermission)
- {
+ else if(!intermission) {
if(player1->ragdoll) cleanragdoll(player1);
moveplayer(player1, 10, true);
swayhudgun(curtime);
@@ -263,139 +196,98 @@ namespace game
}
if(player1->clientnum>=0) c2sinfo(); // do this last, to reduce the effective frame lag
}
-
- float proximityscore(float x, float lower, float upper)
- {
+ float proximityscore(float x, float lower, float upper) {
if(x <= lower) return 1.0f;
if(x >= upper) return 0.0f;
float a = x - lower, b = x - upper;
return (b * b) / (a * a + b * b);
}
-
static inline float harmonicmean(float a, float b) { return a + b > 0 ? 2 * a * b / (a + b) : 0.0f; }
-
// avoid spawning near other players
- float ratespawn(dynent *d, const extentity &e)
- {
+ float ratespawn(dynent *d, const extentity &e) {
fpsent *p = (fpsent *)d;
vec loc = vec(e.o).addz(p->eyeheight);
float maxrange = !m_noitems ? 400.0f : 110.0f;
float minplayerdist = maxrange;
- loopv(players)
- {
+ loopv(players) {
const fpsent *o = players[i];
- if(o == p)
- {
+ if(o == p) {
if(m_noitems || (o->state != CS_ALIVE && lastmillis - o->lastpain > 3000)) continue;
}
else if(o->state != CS_ALIVE || isteam(o->team, p->team)) continue;
-
vec dir = vec(o->o).sub(loc);
float dist = dir.squaredlen();
if(dist >= minplayerdist*minplayerdist) continue;
dist = sqrtf(dist);
dir.mul(1/dist);
-
// scale actual distance if not in line of sight
if(raycube(loc, dir, dist) < dist) dist *= 1.5f;
minplayerdist = min(minplayerdist, dist);
}
return 1.0f - proximityscore(minplayerdist, 80.0f, maxrange);
}
-
- void pickgamespawn(fpsent *d)
- {
+ void pickgamespawn(fpsent *d) {
int ent = d == player1 && respawnent >= 0 ? respawnent : -1;
findplayerspawn(d, ent, 0);
}
-
- void spawnplayer(fpsent *d) // place at random spawn
- {
+ void spawnplayer(fpsent *d) { // place at random spawn {
pickgamespawn(d);
spawnstate(d);
- if(d==player1)
- {
+ if(d==player1) {
if(editmode) d->state = CS_EDITING;
else if(d->state != CS_SPECTATOR) d->state = CS_ALIVE;
}
else d->state = CS_ALIVE;
}
-
VARP(spawnwait, 0, 0, 1000);
-
- void respawn()
- {
- if(player1->state==CS_DEAD)
- {
+ void respawn() {
+ if(player1->state==CS_DEAD) {
player1->attacking = false;
respawnself();
}
}
COMMAND(respawn, "");
-
// inputs
-
VARP(attackspawn, 0, 1, 1);
-
- void doattack(bool on)
- {
+ void doattack(bool on) {
if(!connected || intermission) return;
if((player1->attacking = on) && attackspawn) respawn();
}
-
VARP(jumpspawn, 0, 1, 1);
-
- bool canjump()
- {
+ bool canjump() {
if(!connected || intermission) return false;
if(jumpspawn) respawn();
return player1->state!=CS_DEAD;
}
-
- bool allowmove(physent *d)
- {
+ bool allowmove(physent *d) {
if(d->type!=ENT_PLAYER) return true;
return !((fpsent *)d)->lasttaunt || lastmillis-((fpsent *)d)->lasttaunt>=1000;
}
-
VARP(hitsound, 0, 0, 1);
-
- void damaged(int damage, fpsent *d, fpsent *actor, bool local)
- {
+ void damaged(int damage, fpsent *d, fpsent *actor, bool local) {
if((d->state!=CS_ALIVE && d->state != CS_LAGGED && d->state != CS_SPAWNING) || intermission) return;
-
if(local) damage = d->dodamage(damage);
else if(actor==player1) return;
-
fpsent *h = hudplayer();
- if(h!=player1 && actor==h && d!=actor)
- {
+ if(h!=player1 && actor==h && d!=actor) {
if(hitsound && lasthit != lastmillis) playsound(S_HIT);
lasthit = lastmillis;
}
- if(d==h)
- {
+ if(d==h) {
damagecompass(damage, actor->o);
}
damageeffect(damage, d, d!=h);
-
ai::damaged(d, actor);
-
if(d->health<=0) { if(local) killed(d, actor); }
else if(d==h) playsound(S_PAIN6);
else playsound(S_PAIN1+rnd(5), &d->o);
}
-
VARP(deathscore, 0, 1, 1);
-
- void deathstate(fpsent *d, bool restore)
- {
+ void deathstate(fpsent *d, bool restore) {
d->state = CS_DEAD;
d->lastpain = lastmillis;
if(!restore) d->deaths++;
-
- if(d==player1)
- {
+ if(d==player1) {
if(deathscore) showscores(true);
disablezoom();
if(!restore) loopi(NUMGUNS) savedammo[i] = player1->ammo[i];
@@ -403,53 +295,41 @@ namespace game
d->roll = 0;
playsound(S_DIE1+rnd(2));
}
- else
- {
+ else {
d->move = d->strafe = 0;
d->resetinterp();
d->smoothmillis = 0;
playsound(S_DIE1+rnd(2), &d->o);
}
}
-
VARP(teamcolorfrags, 0, 1, 1);
-
/// xolatile: HUD frag messages
#define fragmessageduration (2000)
-
string hudfragger, hudfragged;
int hudfraggun, hudfragmillis;
-
- void sethudfragdata(char *fragger, char *fragged, int gunid)
- {
+ void sethudfragdata(char *fragger, char *fragged, int gunid) {
copystring(hudfragger, fragger ? fragger : "");
copystring(hudfragged, fragged);
hudfraggun = gunid;
hudfragmillis = lastmillis;
}
-
- void killed(fpsent *d, fpsent *actor)
- {
- if(d->state==CS_EDITING)
- {
+ void killed(fpsent *d, fpsent *actor) {
+ if(d->state==CS_EDITING) {
d->editstate = CS_DEAD;
d->deaths++;
if(d!=player1) d->resetinterp();
return;
}
else if((d->state!=CS_ALIVE && d->state != CS_LAGGED && d->state != CS_SPAWNING) || intermission) return;
-
fpsent *h = followingplayer(player1);
int contype = d==h || actor==h ? CON_FRAG_SELF : CON_FRAG_OTHER;
const char *dname = "", *aname = "";
- if(m_teammode && teamcolorfrags)
- {
+ if(m_teammode && teamcolorfrags) {
dname = teamcolorname(d, "you");
aname = teamcolorname(actor, "you");
}
- else
- {
+ else {
dname = colorname(d, NULL, "", "", "you");
aname = colorname(actor, NULL, "", "", "you");
}
@@ -457,22 +337,18 @@ namespace game
conoutf(contype, "\f2%s got killed by %s!", dname, aname);
else if(d==actor || actor->type==ENT_INANIMATE)
conoutf(contype, "\f2%s suicided%s", dname, d==player1 ? "!" : "");
- else if(isteam(d->team, actor->team))
- {
+ else if(isteam(d->team, actor->team)) {
contype |= CON_TEAMKILL;
if(actor==player1) conoutf(contype, "\f6%s fragged a teammate (%s)", aname, dname);
else if(d==player1) conoutf(contype, "\f6%s got fragged by a teammate (%s)", dname, aname);
else conoutf(contype, "\f2%s fragged a teammate (%s)", aname, dname);
}
- else
- {
- if(d==player1)
- {
+ else {
+ if(d==player1) {
conoutf(contype, "\f2%s got fragged by %s", dname, aname);
sethudfragdata(actor->name, d->name, actor->gunselect);
}
- else
- {
+ else {
conoutf(contype, "\f2%s fragged %s", aname, dname);
sethudfragdata(actor->name, d->name, actor->gunselect);
}
@@ -480,16 +356,12 @@ namespace game
deathstate(d);
ai::killed(d, actor);
}
-
- void timeupdate(int secs)
- {
+ void timeupdate(int secs) {
server::timeupdate(secs);
- if(secs > 0)
- {
+ if(secs > 0) {
maplimit = lastmillis + secs*1000;
}
- else
- {
+ else {
intermission = true;
player1->attacking = false;
conoutf(CON_GAMEINFO, "\f2intermission:");
@@ -497,36 +369,26 @@ namespace game
conoutf(CON_GAMEINFO, "\f2player frags: %d, deaths: %d", player1->frags, player1->deaths);
int accuracy = (player1->totaldamage*100)/max(player1->totalshots, 1);
conoutf(CON_GAMEINFO, "\f2player total damage dealt: %d, damage wasted: %d, accuracy(%%): %d", player1->totaldamage, player1->totalshots-player1->totaldamage, accuracy);
-
showscores(true);
disablezoom();
-
execident("intermission");
}
}
-
ICOMMAND(getfrags, "", (), intret(player1->frags));
ICOMMAND(getflags, "", (), intret(player1->flags));
ICOMMAND(getdeaths, "", (), intret(player1->deaths));
ICOMMAND(getaccuracy, "", (), intret((player1->totaldamage*100)/max(player1->totalshots, 1)));
ICOMMAND(gettotaldamage, "", (), intret(player1->totaldamage));
ICOMMAND(gettotalshots, "", (), intret(player1->totalshots));
-
vector<fpsent *> clients;
-
- fpsent *newclient(int cn) // ensure valid entity
- {
- if(cn < 0 || cn > max(0xFF, MAXCLIENTS + MAXBOTS))
- {
+ fpsent *newclient(int cn) { // ensure valid entity {
+ if(cn < 0 || cn > max(0xFF, MAXCLIENTS + MAXBOTS)) {
neterr("clientnum", false);
return NULL;
}
-
if(cn == player1->clientnum) return player1;
-
while(cn >= clients.length()) clients.add(NULL);
- if(!clients[cn])
- {
+ if(!clients[cn]) {
fpsent *d = new fpsent;
d->clientnum = cn;
clients[cn] = d;
@@ -534,18 +396,13 @@ namespace game
}
return clients[cn];
}
-
- fpsent *getclient(int cn) // ensure valid entity
- {
+ fpsent *getclient(int cn) { // ensure valid entity {
if(cn == player1->clientnum) return player1;
return clients.inrange(cn) ? clients[cn] : NULL;
}
-
- void clientdisconnected(int cn, bool notify)
- {
+ void clientdisconnected(int cn, bool notify) {
if(!clients.inrange(cn)) return;
- if(following==cn)
- {
+ if(following==cn) {
if(followdir) nextfollow(followdir);
else stopfollowing();
}
@@ -560,32 +417,22 @@ namespace game
DELETEP(clients[cn]);
cleardynentcache();
}
-
- void clearclients(bool notify)
- {
+ void clearclients(bool notify) {
loopv(clients) if(clients[i]) clientdisconnected(i, notify);
}
-
- void initclient()
- {
+ void initclient() {
player1 = spawnstate(new fpsent);
filtertext(player1->name, "Anonymous", false, false, MAXNAMELEN);
players.add(player1);
}
-
VARP(showmodeinfo, 0, 1, 1);
-
- void startgame()
- {
+ void startgame() {
clearprojectiles();
clearbouncers();
clearragdolls();
-
clearteaminfo();
-
// reset perma-state
- loopv(players)
- {
+ loopv(players) {
fpsent *d = players[i];
d->frags = d->flags = 0;
d->deaths = 0;
@@ -596,106 +443,74 @@ namespace game
d->lifesequence = -1;
d->respawned = d->suicided = -2;
}
-
intermission = false;
maptime = maprealtime = 0;
maplimit = -1;
-
conoutf(CON_GAMEINFO, "\f2game mode is %s", server::modename(gamemode));
-
const char *info = m_valid(gamemode) ? gamemodes[gamemode - STARTGAMEMODE].info : NULL;
if(showmodeinfo && info) conoutf(CON_GAMEINFO, "\f0%s", info);
-
showscores(false);
disablezoom();
lasthit = 0;
-
execident("mapstart");
}
-
- void loadingmap(const char *name)
- {
+ void loadingmap(const char *name) {
execident("playsong");
}
-
- void startmap(const char *name) // called just after a map load
- {
+ void startmap(const char *name) { // called just after a map load {
pwreset();
ai::savewaypoints();
ai::clearwaypoints(true);
-
respawnent = -1; // so we don't respawn at an old spot
if(!m_mp(gamemode)) spawnplayer(player1);
else findplayerspawn(player1, -1);
entities::resetspawns();
copystring(clientmap, name ? name : "");
-
sendmapinfo();
}
-
- const char *getmapinfo()
- {
+ const char *getmapinfo() {
return showmodeinfo && m_valid(gamemode) ? gamemodes[gamemode - STARTGAMEMODE].info : NULL;
}
-
- const char *getscreenshotinfo()
- {
+ const char *getscreenshotinfo() {
return server::modename(gamemode, NULL);
}
-
- void physicstrigger(physent *d, bool local, int floorlevel, int material)
- {
+ void physicstrigger(physent *d, bool local, int floorlevel, int material) {
if(d->type==ENT_INANIMATE) return;
if (floorlevel>0) { if(d==player1 || d->type!=ENT_PLAYER || ((fpsent *)d)->ai) msgsound(S_JUMP, d); }
else if(floorlevel<0) { if(d==player1 || d->type!=ENT_PLAYER || ((fpsent *)d)->ai) msgsound(S_LAND, d); }
}
-
- void dynentcollide(physent *d, physent *o, const vec &dir)
- {
+ void dynentcollide(physent *d, physent *o, const vec &dir) {
return;
}
-
- void msgsound(int n, physent *d)
- {
- if(!d || d==player1)
- {
+ void msgsound(int n, physent *d) {
+ if(!d || d==player1) {
addmsg(N_SOUND, "ci", d, n);
playsound(n);
}
- else
- {
+ else {
if(d->type==ENT_PLAYER && ((fpsent *)d)->ai)
addmsg(N_SOUND, "ci", d, n);
playsound(n, &d->o);
}
}
-
int numdynents() { return players.length(); }
-
- dynent *iterdynents(int i)
- {
+ dynent *iterdynents(int i) {
if(i<players.length()) return players[i];
i -= players.length();
return NULL;
}
-
- bool duplicatename(fpsent *d, const char *name = NULL, const char *alt = NULL)
- {
+ bool duplicatename(fpsent *d, const char *name = NULL, const char *alt = NULL) {
if(!name) name = d->name;
if(alt && d != player1 && !strcmp(name, alt)) return true;
loopv(players) if(d!=players[i] && !strcmp(name, players[i]->name)) return true;
return false;
}
-
static string cname[3];
static int cidx = 0;
-
- const char *colorname(fpsent *d, const char *name, const char *prefix, const char *suffix, const char *alt)
- {
+ const char *colorname(fpsent *d, const char *name, const char *prefix, const char *suffix, const char *alt) {
if(!name) name = alt && d == player1 ? alt : d->name;
bool dup = !name[0] || duplicatename(d, name, alt) || d->aitype != AI_NONE;
- if(dup || prefix[0] || suffix[0])
- {
+ if(dup || prefix[0] || suffix[0]) {
cidx = (cidx+1)%3;
if(dup) formatstring(cname[cidx], d->aitype == AI_NONE ? "%s%s \fs\f5(%d)\fr%s" : "%s%s \fs\f5[%d]\fr%s", prefix, name, d->clientnum, suffix);
else formatstring(cname[cidx], "%s%s%s", prefix, name, suffix);
@@ -703,58 +518,40 @@ namespace game
}
return name;
}
-
VARP(teamcolortext, 0, 1, 1);
-
- const char *teamcolorname(fpsent *d, const char *alt)
- {
+ const char *teamcolorname(fpsent *d, const char *alt) {
if(!teamcolortext || !m_teammode || d->state==CS_SPECTATOR) return colorname(d, NULL, "", "", alt);
return colorname(d, NULL, isteam(d->team, player1->team) ? "\fs\f1" : "\fs\f3", "\fr", alt);
}
-
- const char *teamcolor(const char *name, bool sameteam, const char *alt)
- {
+ const char *teamcolor(const char *name, bool sameteam, const char *alt) {
if(!teamcolortext || !m_teammode) return sameteam || !alt ? name : alt;
cidx = (cidx+1)%3;
formatstring(cname[cidx], sameteam ? "\fs\f1%s\fr" : "\fs\f3%s\fr", sameteam || !alt ? name : alt);
return cname[cidx];
}
-
- const char *teamcolor(const char *name, const char *team, const char *alt)
- {
+ const char *teamcolor(const char *name, const char *team, const char *alt) {
return teamcolor(name, team && isteam(team, player1->team), alt);
}
-
VARP(teamsounds, 0, 1, 1);
-
- void teamsound(bool sameteam, int n, const vec *loc)
- {
+ void teamsound(bool sameteam, int n, const vec *loc) {
playsound(n, loc, NULL, teamsounds ? (m_teammode && sameteam ? SND_USE_ALT : SND_NO_ALT) : 0);
}
-
- void teamsound(fpsent *d, int n, const vec *loc)
- {
+ void teamsound(fpsent *d, int n, const vec *loc) {
teamsound(isteam(d->team, player1->team), n, loc);
}
-
- void suicide(physent *d)
- {
- if(d==player1 || (d->type==ENT_PLAYER && ((fpsent *)d)->ai))
- {
+ void suicide(physent *d) {
+ if(d==player1 || (d->type==ENT_PLAYER && ((fpsent *)d)->ai)) {
if(d->state!=CS_ALIVE) return;
fpsent *pl = (fpsent *)d;
if(!m_mp(gamemode)) killed(pl, pl);
- else
- {
+ else {
int seq = (pl->lifesequence<<16)|((lastmillis/1000)&0xFFFF);
if(pl->suicided!=seq) { addmsg(N_SUICIDE, "rc", pl); pl->suicided = seq; }
}
}
}
ICOMMAND(suicide, "", (), suicide(player1));
-
- void drawicon(int icon, float x, float y, float sz)
- {
+ void drawicon(int icon, float x, float y, float sz) {
settexture("packages/hud/items.png");
float tsz = 0.25f, tx = tsz*(icon%4), ty = tsz*(icon/4);
gle::defvertex(2);
@@ -766,11 +563,8 @@ namespace game
gle::attribf(x+sz, y+sz); gle::attribf(tx+tsz, ty+tsz);
gle::end();
}
-
- float abovegameplayhud(int w, int h)
- {
- switch(hudplayer()->state)
- {
+ float abovegameplayhud(int w, int h) {
+ switch(hudplayer()->state) {
case CS_EDITING:
case CS_SPECTATOR:
return 1;
@@ -778,61 +572,47 @@ namespace game
return 1650.0f/1800.0f;
}
}
-
int ammohudup[3] = { GUN_CG, GUN_RL, GUN_GL },
ammohuddown[3] = { GUN_RIFLE, GUN_SG, GUN_PISTOL },
ammohudcycle[7] = { -1, -1, -1, -1, -1, -1, -1 };
-
- ICOMMAND(ammohudup, "V", (tagval *args, int numargs),
- {
+ ICOMMAND(ammohudup, "V", (tagval *args, int numargs), {
loopi(3) ammohudup[i] = i < numargs ? getweapon(args[i].getstr()) : -1;
});
-
- ICOMMAND(ammohuddown, "V", (tagval *args, int numargs),
- {
+ ICOMMAND(ammohuddown, "V", (tagval *args, int numargs), {
loopi(3) ammohuddown[i] = i < numargs ? getweapon(args[i].getstr()) : -1;
});
-
- ICOMMAND(ammohudcycle, "V", (tagval *args, int numargs),
- {
+ ICOMMAND(ammohudcycle, "V", (tagval *args, int numargs), {
loopi(7) ammohudcycle[i] = i < numargs ? getweapon(args[i].getstr()) : -1;
});
-
VARP(ammohud, 0, 1, 1);
-
- void drawammohud(fpsent *d)
- {
+ void drawammohud(fpsent *d) {
float x = HICON_X + 2*HICON_STEP, y = HICON_Y, sz = HICON_SIZE;
pushhudmatrix();
hudmatrix.scale(1/3.2f, 1/3.2f, 1);
flushhudmatrix();
float xup = (x+sz)*3.2f, yup = y*3.2f + 0.1f*sz;
- loopi(3)
- {
+ loopi(3) {
int gun = ammohudup[i];
if(gun < GUN_FIST || gun > GUN_PISTOL || gun == d->gunselect || !d->ammo[gun]) continue;
drawicon(HICON_FIST+gun, xup, yup, sz);
yup += sz;
}
float xdown = x*3.2f - sz, ydown = (y+sz)*3.2f - 0.1f*sz;
- loopi(3)
- {
+ loopi(3) {
int gun = ammohuddown[3-i-1];
if(gun < GUN_FIST || gun > GUN_PISTOL || gun == d->gunselect || !d->ammo[gun]) continue;
ydown -= sz;
drawicon(HICON_FIST+gun, xdown, ydown, sz);
}
int offset = 0, num = 0;
- loopi(7)
- {
+ loopi(7) {
int gun = ammohudcycle[i];
if(gun < GUN_FIST || gun > GUN_PISTOL) continue;
if(gun == d->gunselect) offset = i + 1;
else if(d->ammo[gun]) num++;
}
float xcycle = (x+sz/2)*3.2f + 0.5f*num*sz, ycycle = y*3.2f-sz;
- loopi(7)
- {
+ loopi(7) {
int gun = ammohudcycle[(i + offset)%7];
if(gun < GUN_FIST || gun > GUN_PISTOL || gun == d->gunselect || !d->ammo[gun]) continue;
xcycle -= sz;
@@ -840,9 +620,7 @@ namespace game
}
pophudmatrix();
}
-
- void hudquad(float x, float y, float w, float h, float r = 1, float g = 1, float b = 1, float tx = 0, float ty = 0, float tw = 1, float th = 1)
- {
+ void hudquad(float x, float y, float w, float h, float r = 1, float g = 1, float b = 1, float tx = 0, float ty = 0, float tw = 1, float th = 1) {
gle::defvertex(2);
gle::deftexcoord0();
gle::colorf(r, g, b);
@@ -853,20 +631,15 @@ namespace game
gle::attribf(x+w, y+h); gle::attribf(tx + tw, ty + th);
gle::end();
}
-
VARP(healthcolors, 0, 1, 1);
-
VARP(hudhealth, 0, 1, 1);
FVARP(hudhealthx, 0, 0, 1);
FVARP(hudhealthy, 0, 1, 1);
FVARP(hudhealthscale, 0.1, 1.0, 1.0);
-
- void drawhudhealth(fpsent *d, int w, int h)
- {
+ void drawhudhealth(fpsent *d, int w, int h) {
pushhudmatrix();
hudmatrix.scale(hudhealthscale, hudhealthscale, 1);
flushhudmatrix();
-
bvec healthcolor = bvec::hexcolor(healthcolors && !m_insta ?
(d->state==CS_DEAD ? 0x808080 :
(d->health<=25 ? 0xc02020 :
@@ -889,21 +662,16 @@ namespace game
defformatstring(health, "%d", d->state==CS_DEAD ? 0 : d->health);
float tw=0, th=0; text_boundsf(health, tw, th);
draw_text(health, offset.x+(125*proportion-tw)/2, offset.y+(healthbarh-th)/2, healthcolor.r, healthcolor.g, healthcolor.b);
-
pophudmatrix();
}
-
VARP(hudmaxhealth, 0, 1, 1);
FVARP(hudmaxhealthx, 0, 0.207, 1);
FVARP(hudmaxhealthy, 0, 0.97, 1);
FVARP(hudmaxhealthscale, 0.1, 1.0, 1.0);
-
- void drawhudmaxhealth(fpsent *d, int w, int h)
- {
+ void drawhudmaxhealth(fpsent *d, int w, int h) {
pushhudmatrix();
hudmatrix.scale(hudmaxhealthscale, hudmaxhealthscale, 1);
flushhudmatrix();
-
const float proportion = (w/15.0f)/160.0f;
const float healthboostw = 160*proportion;
const float healthboosth = 78*proportion;
@@ -917,23 +685,17 @@ namespace game
settexture("packages/hud/health_boost_quad.png");
hudquad(offset.x, offset.y, healthboostw, healthboosth);
}
-
pophudmatrix();
}
-
VARP(armourcolors, 0, 1, 1);
-
VARP(hudarmour, 0, 1, 1);
FVARP(hudarmourx, 0, 1, 1);
FVARP(hudarmoury, 0, 1, 1);
FVARP(hudarmourscale, 0.1, 1.0, 1.0);
-
- void drawhudarmour(fpsent *d, int w, int h)
- {
+ void drawhudarmour(fpsent *d, int w, int h) {
pushhudmatrix();
hudmatrix.scale(hudarmourscale, hudarmourscale, 1);
flushhudmatrix();
-
bvec armourcolor = bvec::hexcolor(d->armourtype == A_BLUE ? 0x83ade5 : (d->armourtype == A_GREEN ? 0x77f29e : (d->armourtype == A_YELLOW ? 0xf5f19b : 0xffffff)));
const float proportion = (w/4.0f)/600.0f;
const float armourbarw = 600*proportion;
@@ -951,25 +713,19 @@ namespace game
defformatstring(armour, "%d", d->state==CS_DEAD ? 0 : d->armour);
float tw=0, th=0; text_boundsf(armour, tw, th);
draw_text(armour, offset.x+(2*(600-63)*proportion-tw)/2, offset.y+(armourbarh-th)/2, armourcolor.r, armourcolor.g, armourcolor.b);
-
pophudmatrix();
}
-
- void drawhudicons(fpsent *d, int w, int h)
- {
+ void drawhudicons(fpsent *d, int w, int h) {
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glEnable(GL_BLEND);
-
if(hudhealth) drawhudhealth(d, w, h);
if(hudmaxhealth) drawhudmaxhealth(d, w, h);
if(hudarmour) drawhudarmour(d, w, h);
-
if(d->state!=CS_DEAD) {
drawicon(HICON_FIST+d->gunselect, HICON_X + 2*HICON_STEP, HICON_Y);
if(ammohud) drawammohud(d);
}
}
-
VARP(gameclock, 0, 0, 1);
FVARP(gameclockscale, 1e-3f, 0.75f, 1e3f);
HVARP(gameclockcolour, 0, 0xFFFFFF, 0xFFFFFF);
@@ -978,34 +734,25 @@ namespace game
VARP(gameclockalign, -1, 0, 1);
FVARP(gameclockx, 0, 0.50f, 1);
FVARP(gameclocky, 0, 0.03f, 1);
-
- void drawgameclock(int w, int h)
- {
+ void drawgameclock(int w, int h) {
int secs = max(maplimit-lastmillis + 999, 0)/1000, mins = secs/60;
secs %= 60;
-
defformatstring(buf, "%d:%02d", mins, secs);
int tw = 0, th = 0;
text_bounds(buf, tw, th);
-
vec2 offset = vec2(gameclockx, gameclocky).mul(vec2(w, h).div(gameclockscale));
if(gameclockalign == 1) offset.x -= tw;
else if(gameclockalign == 0) offset.x -= tw/2.0f;
offset.y -= th/2.0f;
-
pushhudmatrix();
hudmatrix.scale(gameclockscale, gameclockscale, 1);
flushhudmatrix();
-
int color = mins < 1 ? gameclocklowcolour : gameclockcolour;
draw_text(buf, int(offset.x), int(offset.y), (color>>16)&0xFF, (color>>8)&0xFF, color&0xFF, gameclockalpha);
-
pophudmatrix();
}
-
extern int hudscore;
extern void drawhudscore(int w, int h);
-
VARP(ammobar, 0, 0, 1);
VARP(ammobaralign, -1, 0, 1);
VARP(ammobarhorizontal, 0, 0, 1);
@@ -1017,77 +764,58 @@ namespace game
FVARP(ammobarx, 0, 0.025f, 1.0f);
FVARP(ammobary, 0, 0.5f, 1.0f);
FVARP(ammobarscale, 0.1f, 0.5f, 1.0f);
-
- void drawammobarcounter(const vec2 &center, const fpsent *p, int gun)
- {
+ void drawammobarcounter(const vec2 &center, const fpsent *p, int gun) {
vec2 icondrawpos = vec2(center).sub(HICON_SIZE / 2);
int alpha = p->ammo[gun] ? 0xFF : 0x7F;
gle::color(bvec(0xFF, 0xFF, 0xFF), alpha);
drawicon(HICON_FIST + gun, icondrawpos.x, icondrawpos.y);
-
int fw, fh; text_bounds("000", fw, fh);
float labeloffset = HICON_SIZE / 2.0f + ammobarcountsep + ammobarcountscale * (ammobarhorizontal ? fh : fw) / 2.0f;
vec2 offsetdir = (ammobarhorizontal ? vec2(0, 1) : vec2(1, 0)).mul(ammobarflip ? -1 : 1);
vec2 labelorigin = vec2(offsetdir).mul(labeloffset).add(center);
-
pushhudmatrix();
hudmatrix.translate(labelorigin.x, labelorigin.y, 0);
hudmatrix.scale(ammobarcountscale, ammobarcountscale, 1);
flushhudmatrix();
-
defformatstring(label, "%d", p->ammo[gun]);
int tw, th; text_bounds(label, tw, th);
vec2 textdrawpos = vec2(-tw, -th).div(2);
float ammoratio = (float)p->ammo[gun] / itemstats[gun-GUN_SG].add;
bvec color = bvec::hexcolor(p->ammo[gun] == 0 || ammoratio >= 1.0f ? 0xFFFFFF : (ammoratio >= 0.5f ? 0xFFC040 : 0xFF0000));
draw_text(label, textdrawpos.x, textdrawpos.y, color.r, color.g, color.b, alpha);
-
pophudmatrix();
}
-
- static inline bool ammobargunvisible(const fpsent *d, int gun)
- {
+ static inline bool ammobargunvisible(const fpsent *d, int gun) {
return d->ammo[gun] > 0 || d->gunselect == gun;
}
-
- void drawammobar(int w, int h, fpsent *p)
- {
+ void drawammobar(int w, int h, fpsent *p) {
if(m_insta) return;
-
int NUMPLAYERGUNS = GUN_PISTOL - GUN_SG + 1;
int numvisibleguns = NUMPLAYERGUNS;
if(ammobarhideempty) loopi(NUMPLAYERGUNS) if(!ammobargunvisible(p, GUN_SG + i)) numvisibleguns--;
-
vec2 origin = vec2(ammobarx, ammobary).mul(vec2(w, h).div(ammobarscale));
vec2 offsetdir = ammobarhorizontal ? vec2(1, 0) : vec2(0, 1);
float stepsize = HICON_SIZE + ammobarsep;
float initialoffset = (ammobaralign - 1) * (numvisibleguns - 1) * stepsize / 2;
-
pushhudmatrix();
hudmatrix.scale(ammobarscale, ammobarscale, 1);
flushhudmatrix();
-
int numskippedguns = 0;
- loopi(NUMPLAYERGUNS) if(ammobargunvisible(p, GUN_SG + i) || !ammobarhideempty)
- {
+ loopi(NUMPLAYERGUNS) if(ammobargunvisible(p, GUN_SG + i) || !ammobarhideempty) {
float offset = initialoffset + (i - numskippedguns) * stepsize;
vec2 drawpos = vec2(offsetdir).mul(offset).add(origin);
drawammobarcounter(drawpos, p, GUN_SG + i);
}
else numskippedguns++;
-
pophudmatrix();
}
-
VARP(speedometer, 0, 1, 1);
FVARP(speedometerx, 0.0, 0.5, 1.0);
FVARP(speedometery, 0.0, 0.6, 1.0);
FVARP(speedometerscale, 0.1, 0.5, 1.0);
VARP(speedometercolor, 0, 1, 1);
FVARP(speedometeralpha, 0.0, 0.5, 1.0);
-
- void drawspeedometer(fpsent *d, int w, int h)
- {
+ void drawspeedometer(fpsent *d, int w, int h) {
int speedforreal = (int) (sqrtf(d->vel.squaredlen()) + 1.0f);
speedforreal = (speedforreal == 1) ? 0 : speedforreal;
vec colour = vec(255, 255, 255);
@@ -1101,35 +829,26 @@ namespace game
else if (speedforreal>180 && speedforreal<=240) colour = vec(90, 180, 60);
else colour = vec(30, 240, 30);
}
-
defformatstring(speedstring, "%d", speedforreal);
text_boundsf(speedstring, realw, realh);
vec2 offset = vec2(speedometerx, speedometery).mul(vec2(w, h).div(speedometerscale));
offset.x -= realw/2.0f;
offset.y -= realh/2.0f;
-
pushhudmatrix();
hudmatrix.scale(speedometerscale, speedometerscale, 1);
flushhudmatrix();
-
const int speedow = 220;
const int speedoh = 101;
settexture("packages/hud/speedometer.png");
hudquad(offset.x+realw/2.0f-speedow/2, offset.y+realh/2.0f-speedoh/2, speedow, speedoh);
-
draw_text(speedstring, int(offset.x), int(offset.y), colour.x, colour.y, colour.z, (int)(speedometeralpha*255.0f));
-
pophudmatrix();
}
-
- void gameplayhud(int w, int h)
- {
+ void gameplayhud(int w, int h) {
pushhudmatrix();
hudmatrix.scale(h/1800.0f, h/1800.0f, 1);
flushhudmatrix();
-
- if(player1->state==CS_SPECTATOR)
- {
+ if(player1->state==CS_SPECTATOR) {
int pw, ph, tw, th, fw, fh;
text_bounds(" ", pw, ph);
text_bounds("SPECTATOR", tw, th);
@@ -1138,36 +857,25 @@ namespace game
text_bounds(f ? colorname(f) : " ", fw, fh);
fh = max(fh, ph);
draw_text("SPECTATOR", w*1800/h - tw - pw, 1650 - th - fh);
- if(f)
- {
+ if(f) {
int color = statuscolor(f, 0xFFFFFF);
draw_text(colorname(f), w*1800/h - fw - pw, 1650 - fh, (color>>16)&0xFF, (color>>8)&0xFF, color&0xFF);
}
}
-
fpsent *d = hudplayer();
-
pophudmatrix();
-
if(d->state!=CS_EDITING && d->state!=CS_SPECTATOR) drawhudicons(d, w, h);
-
- if(d->state!=CS_EDITING && d->state!=CS_SPECTATOR && d->state!=CS_DEAD)
- {
+ if(d->state!=CS_EDITING && d->state!=CS_SPECTATOR && d->state!=CS_DEAD) {
if(ammobar) drawammobar(w, h, d);
if(speedometer) drawspeedometer(d, w, h);
}
-
- if(!m_edit)
- {
+ if(!m_edit) {
if(gameclock) drawgameclock(w, h);
if(hudscore) drawhudscore(w, h);
}
-
/// Frag message.
-
- if((hudfragmillis+fragmessageduration > lastmillis) && (lastmillis>fragmessageduration))
- {
+ if((hudfragmillis+fragmessageduration > lastmillis) && (lastmillis>fragmessageduration)) {
vec2 center = vec2(0.5*w, 0.2*h);
float width = 0, height = 0;
pushhudmatrix();
@@ -1180,69 +888,49 @@ namespace game
pophudmatrix();
}
}
-
- int clipconsole(int w, int h)
- {
+ int clipconsole(int w, int h) {
return 0;
}
-
VARP(teamcrosshair, 0, 1, 1);
VARP(hitcrosshair, 0, 425, 1000);
-
- const char *defaultcrosshair(int index)
- {
- switch(index)
- {
+ const char *defaultcrosshair(int index) {
+ switch(index) {
case 2: return "data/hit.png";
case 1: return "data/teammate.png";
default: return "data/crosshair.png";
}
}
-
- int selectcrosshair(vec &color)
- {
+ int selectcrosshair(vec &color) {
fpsent *d = hudplayer();
if(d->state==CS_SPECTATOR || d->state==CS_DEAD) return -1;
-
if(d->state!=CS_ALIVE) return 0;
-
int crosshair = 0;
if(lasthit && lastmillis - lasthit < hitcrosshair) crosshair = 2;
- else if(teamcrosshair)
- {
+ else if(teamcrosshair) {
dynent *o = intersectclosest(d->o, worldpos, d);
- if(o && o->type==ENT_PLAYER && isteam(((fpsent *)o)->team, d->team))
- {
+ if(o && o->type==ENT_PLAYER && isteam(((fpsent *)o)->team, d->team)) {
crosshair = 1;
color = vec(0, 0, 1);
}
}
-
- if(crosshair!=1 && !editmode && !m_insta)
- {
+ if(crosshair!=1 && !editmode && !m_insta) {
if(d->health<=25) color = vec(1, 0, 0);
else if(d->health<=50) color = vec(1, 0.5f, 0);
}
if(d->gunwait) color.mul(0.5f);
return crosshair;
}
-
- void lighteffects(dynent *e, vec &color, vec &dir)
- {
+ void lighteffects(dynent *e, vec &color, vec &dir) {
#if 0
fpsent *d = (fpsent *)e;
- if(d->state!=CS_DEAD && d->quadmillis)
- {
+ if(d->state!=CS_DEAD && d->quadmillis) {
float t = 0.5f + 0.5f*sinf(2*M_PI*lastmillis/1000.0f);
color.y = color.y*(1-t) + t;
}
#endif
}
-
- int maxsoundradius(int n)
- {
- switch(n)
- {
+ int maxsoundradius(int n) {
+ switch(n) {
case S_JUMP:
case S_LAND:
case S_WEAPLOAD:
@@ -1258,11 +946,9 @@ namespace game
return 500;
}
}
-
- bool serverinfostartcolumn(g3d_gui *g, int i)
- {
+ bool serverinfostartcolumn(g3d_gui *g, int i) {
static const char * const names[] = { "ping ", "players ", "mode ", "map ", "time ", "master ", "host ", "port ", "description " };
- static const float struts[] = { 7, 7, 12.5f, 14, 7, 8, 14, 7, 24.5f };
+ static const float struts[] = { 7, 7, 12.5f, 14, 7, 8, 14, 7, 24.5f };
if(size_t(i) >= sizeof(names)/sizeof(names[0])) return false;
g->pushlist();
g->text(names[i], 0xFFFF80, !i ? " " : NULL);
@@ -1270,34 +956,23 @@ namespace game
g->mergehits(true);
return true;
}
-
- void serverinfoendcolumn(g3d_gui *g, int i)
- {
+ void serverinfoendcolumn(g3d_gui *g, int i) {
g->mergehits(false);
g->column(i);
g->poplist();
}
-
- const char *mastermodecolor(int n, const char *unknown)
- {
+ const char *mastermodecolor(int n, const char *unknown) {
return (n>=MM_START && size_t(n-MM_START)<sizeof(mastermodecolors)/sizeof(mastermodecolors[0])) ? mastermodecolors[n-MM_START] : unknown;
}
-
- const char *mastermodeicon(int n, const char *unknown)
- {
+ const char *mastermodeicon(int n, const char *unknown) {
return (n>=MM_START && size_t(n-MM_START)<sizeof(mastermodeicons)/sizeof(mastermodeicons[0])) ? mastermodeicons[n-MM_START] : unknown;
}
-
- bool serverinfoentry(g3d_gui *g, int i, const char *name, int port, const char *sdesc, const char *map, int ping, const vector<int> &attr, int np)
- {
- if(ping < 0 || attr.empty() || attr[0]!=PROTOCOL_VERSION)
- {
- switch(i)
- {
+ bool serverinfoentry(g3d_gui *g, int i, const char *name, int port, const char *sdesc, const char *map, int ping, const vector<int> &attr, int np) {
+ if(ping < 0 || attr.empty() || attr[0]!=PROTOCOL_VERSION) {
+ switch(i) {
case 0:
if(g->button(" ", 0xFFFFDD, "serverunk")&G3D_UP) return true;
break;
-
case 1:
case 2:
case 3:
@@ -1305,18 +980,14 @@ namespace game
case 5:
if(g->button(" ", 0xFFFFDD)&G3D_UP) return true;
break;
-
case 6:
if(g->buttonf("%s ", 0xFFFFDD, NULL, name)&G3D_UP) return true;
break;
-
case 7:
if(g->buttonf("%d ", 0xFFFFDD, NULL, port)&G3D_UP) return true;
break;
-
case 8:
- if(ping < 0)
- {
+ if(ping < 0) {
if(g->button(sdesc, 0xFFFFDD)&G3D_UP) return true;
}
else if(g->buttonf("[%s protocol] ", 0xFFFFDD, NULL, attr.empty() ? "unknown" : (attr[0] < PROTOCOL_VERSION ? "older" : "newer"))&G3D_UP) return true;
@@ -1324,35 +995,26 @@ namespace game
}
return false;
}
-
- switch(i)
- {
- case 0:
- {
+ switch(i) {
+ case 0: {
const char *icon = attr.inrange(3) && np >= attr[3] ? "serverfull" : (attr.inrange(4) ? mastermodeicon(attr[4], "serverunk") : "serverunk");
if(g->buttonf("%d ", 0xFFFFDD, icon, ping)&G3D_UP) return true;
break;
}
-
case 1:
- if(attr.length()>=4)
- {
+ if(attr.length()>=4) {
if(g->buttonf(np >= attr[3] ? "\f3%d/%d " : "%d/%d ", 0xFFFFDD, NULL, np, attr[3])&G3D_UP) return true;
}
else if(g->buttonf("%d ", 0xFFFFDD, NULL, np)&G3D_UP) return true;
break;
-
case 2:
if(g->buttonf("%s ", 0xFFFFDD, NULL, attr.length()>=2 ? server::modename(attr[1], "") : "")&G3D_UP) return true;
break;
-
case 3:
if(g->buttonf("%.25s ", 0xFFFFDD, NULL, map)&G3D_UP) return true;
break;
-
case 4:
- if(attr.length()>=3 && attr[2] > 0)
- {
+ if(attr.length()>=3 && attr[2] > 0) {
int secs = clamp(attr[2], 0, 59*60+59),
mins = secs/60;
secs %= 60;
@@ -1363,36 +1025,28 @@ namespace game
case 5:
if(g->buttonf("%s%s ", 0xFFFFDD, NULL, attr.length()>=5 ? mastermodecolor(attr[4], "") : "", attr.length()>=5 ? server::mastermodename(attr[4], "") : "")&G3D_UP) return true;
break;
-
case 6:
if(g->buttonf("%s ", 0xFFFFDD, NULL, name)&G3D_UP) return true;
break;
-
case 7:
if(g->buttonf("%d ", 0xFFFFDD, NULL, port)&G3D_UP) return true;
break;
-
case 8:
if(g->buttonf("%.25s", 0xFFFFDD, NULL, sdesc)&G3D_UP) return true;
break;
}
return false;
}
-
// any data written into this vector will get saved with the map data. Must take care to do own versioning, and endianess if applicable. Will not get called when loading maps from other games, so provide defaults.
void writegamedata(vector<char> &extras) {}
void readgamedata(vector<char> &extras) {}
-
const char *savedconfig() { return "config.cfg"; }
const char *restoreconfig() { return "restore.cfg"; }
const char *defaultconfig() { return "data/defaults.cfg"; }
const char *autoexec() { return "autoexec.cfg"; }
const char *savedservers() { return "servers.cfg"; }
-
- void loadconfigs()
- {
+ void loadconfigs() {
execident("playsong");
-
execfile("auth.cfg", false);
}
}
diff --git a/src/fpsgame/game.h b/src/fpsgame/game.h
index 3cdbba3..974f1f3 100644
--- a/src/fpsgame/game.h
+++ b/src/fpsgame/game.h
@@ -5,8 +5,7 @@
// console message types
-enum
-{
+enum {
CON_CHAT = 1<<8,
CON_TEAMCHAT = 1<<9,
CON_GAMEINFO = 1<<10,
@@ -20,8 +19,7 @@ enum
#define DNF 100.0f // for normalized vectors
#define DVELF 1.0f // for playerspeed based velocity vectors
-enum // static entity types
-{
+enum { // static entity types {
NOTUSED = ET_EMPTY, // entity slot not in use in map
LIGHT = ET_LIGHT, // lightsource, attr1 = radius, attr2 = intensity
MAPMODEL = ET_MAPMODEL, // attr1 = angle, attr2 = idx
@@ -41,10 +39,9 @@ enum // static entity types
};
enum { GUN_FIST = 0, GUN_SG, GUN_CG, GUN_RL, GUN_RIFLE, GUN_GL, GUN_PISTOL, NUMGUNS };
-enum { A_BLUE, A_GREEN, A_YELLOW }; // armour types... take 20/40/60 % off
+enum { A_BLUE, A_GREEN, A_YELLOW }; // armour types... take 20/40/60 % off INCORRECT!
-enum
-{
+enum {
M_TEAM = 1<<0,
M_NOITEMS = 1<<1,
M_NOAMMO = 1<<2,
@@ -56,21 +53,20 @@ enum
M_LOBBY = 1<<15
};
-static struct gamemodeinfo
-{
+static struct gamemodeinfo {
const char *name;
int flags;
const char *info;
-} gamemodes[] =
-{
- { "demo", M_DEMO | M_LOCAL, NULL},
- { "ffa", M_LOBBY, "Free For All: Collect items for ammo. Frag everyone to score points." },
- { "coop edit", M_EDIT, "Cooperative Editing: Edit maps with multiple players simultaneously." },
- { "teamplay", M_TEAM, "Teamplay: Collect items for ammo. Frag \fs\f3the enemy team\fr to score points for \fs\f1your team\fr." },
- { "instagib", M_NOITEMS | M_INSTA, "Instagib: You spawn with full rifle ammo and die instantly from one shot. There are no items. Frag everyone to score points." },
- { "insta team", M_NOITEMS | M_INSTA | M_TEAM, "Instagib Team: You spawn with full rifle ammo and die instantly from one shot. There are no items. Frag \fs\f3the enemy team\fr to score points for \fs\f1your team\fr." },
- { "efficiency", M_NOITEMS | M_EFFICIENCY, "Efficiency: You spawn with all weapons and armour. There are no items. Frag everyone to score points." },
- { "effic team", M_NOITEMS | M_EFFICIENCY | M_TEAM, "Efficiency Team: You spawn with all weapons and armour. There are no items. Frag \fs\f3the enemy team\fr to score points for \fs\f1your team\fr." },
+} gamemodes[] = {
+ {
+ "demo", M_DEMO | M_LOCAL, NULL}, {
+ "ffa", M_LOBBY, "Free For All: Collect items for ammo. Frag everyone to score points." }, {
+ "coop edit", M_EDIT, "Cooperative Editing: Edit maps with multiple players simultaneously." }, {
+ "teamplay", M_TEAM, "Teamplay: Collect items for ammo. Frag \fs\f3the enemy team\fr to score points for \fs\f1your team\fr." }, {
+ "instagib", M_NOITEMS | M_INSTA, "Instagib: You spawn with full rifle ammo and die instantly from one shot. There are no items. Frag everyone to score points." }, {
+ "insta team", M_NOITEMS | M_INSTA | M_TEAM, "Instagib Team: You spawn with full rifle ammo and die instantly from one shot. There are no items. Frag \fs\f3the enemy team\fr to score points for \fs\f1your team\fr." }, {
+ "efficiency", M_NOITEMS | M_EFFICIENCY, "Efficiency: You spawn with all weapons and armour. There are no items. Frag everyone to score points." }, {
+ "effic team", M_NOITEMS | M_EFFICIENCY | M_TEAM, "Efficiency Team: You spawn with all weapons and armour. There are no items. Frag \fs\f3the enemy team\fr to score points for \fs\f1your team\fr." },
};
#define STARTGAMEMODE (-1)
@@ -98,13 +94,12 @@ static struct gamemodeinfo
enum { MM_AUTH = -1, MM_OPEN = 0, MM_VETO, MM_LOCKED, MM_PRIVATE, MM_PASSWORD, MM_START = MM_AUTH };
-static const char * const mastermodenames[] = { "auth", "open", "veto", "locked", "private", "password" };
+static const char * const mastermodenames[] = { "auth", "open", "veto", "locked", "private", "password" };
static const char * const mastermodecolors[] = { "", "\f0", "\f2", "\f2", "\f3", "\f3" };
-static const char * const mastermodeicons[] = { "server", "server", "serverlock", "serverlock", "serverpriv", "serverpriv" };
+static const char * const mastermodeicons[] = { "server", "server", "serverlock", "serverlock", "serverpriv", "serverpriv" };
// hardcoded sounds, defined in sounds.cfg
-enum
-{
+enum {
S_JUMP = 0, S_LAND, S_RIFLE, S_PUNCH1, S_SG, S_CG,
S_RLFIRE, S_RLHIT, S_WEAPLOAD, S_ITEMAMMO, S_ITEMHEALTH,
S_ITEMARMOUR, S_ITEMPUP, S_ITEMSPAWN, S_TELEPORT, S_NOAMMO, S_PUPOUT,
@@ -113,15 +108,12 @@ enum
S_FLAUNCH, S_FEXPLODE,
S_SPLASH1, S_SPLASH2,
S_JUMPPAD, S_PISTOL,
-
S_V_FIGHT,
S_V_BOOST, S_V_BOOST10,
S_V_QUAD, S_V_QUAD10,
-
S_BURN,
S_CHAINSAW_ATTACK,
S_CHAINSAW_IDLE,
-
S_HIT
};
@@ -129,8 +121,7 @@ enum
enum { PRIV_NONE = 0, PRIV_MASTER, PRIV_AUTH, PRIV_ADMIN };
-enum
-{
+enum {
N_CONNECT = 0, N_SERVINFO, N_WELCOME, N_INITCLIENT, N_POS, N_TEXT, N_SOUND, N_CDIS,
N_SHOOT, N_EXPLODE, N_SUICIDE,
N_DIED, N_DAMAGE, N_HITPUSH, N_SHOTFX, N_EXPLODEFX,
@@ -157,8 +148,7 @@ enum
NUMMSG
};
-static const int msgsizes[] = // size inclusive message token, 0 for variable or not-checked sizes
-{
+static const int msgsizes[] = { // size inclusive message token, 0 for variable or not-checked sizes {
N_CONNECT, 0, N_SERVINFO, 0, N_WELCOME, 1, N_INITCLIENT, 0, N_POS, 0, N_TEXT, 0, N_SOUND, 2, N_CDIS, 2,
N_SHOOT, 0, N_EXPLODE, 0, N_SUICIDE, 1,
N_DIED, 5, N_DAMAGE, 6, N_HITPUSH, 7, N_SHOTFX, 10, N_EXPLODEFX, 4,
@@ -193,8 +183,7 @@ static const int msgsizes[] = // size inclusive message token, 0 for variab
#define DEMO_VERSION 1 // bump when demo format changes
#define DEMO_MAGIC "SAUERBRATEN_DEMO"
-struct demoheader
-{
+struct demoheader {
char magic[16];
int version, protocol;
};
@@ -202,14 +191,11 @@ struct demoheader
#define MAXNAMELEN 15
#define MAXTEAMLEN 4
-enum
-{
+enum {
HICON_BLUE_ARMOUR = 0,
HICON_GREEN_ARMOUR,
HICON_YELLOW_ARMOUR,
-
HICON_HEALTH,
-
HICON_FIST,
HICON_SG,
HICON_CG,
@@ -217,11 +203,8 @@ enum
HICON_RIFLE,
HICON_GL,
HICON_PISTOL,
-
HICON_QUAD,
-
HICON_TOKEN,
-
HICON_X = 20,
HICON_Y = 1650,
HICON_TEXTY = 1644,
@@ -234,20 +217,20 @@ static struct itemstat {
int add, max, sound;
const char *name;
int icon, info;
-} itemstats[] = {
- {10, 30, S_ITEMAMMO, "SG", HICON_SG, GUN_SG},
- {20, 60, S_ITEMAMMO, "CG", HICON_CG, GUN_CG},
- {5, 15, S_ITEMAMMO, "RL", HICON_RL, GUN_RL},
- {5, 15, S_ITEMAMMO, "RI", HICON_RIFLE, GUN_RIFLE},
- {10, 30, S_ITEMAMMO, "GL", HICON_GL, GUN_GL},
- {30, 120, S_ITEMAMMO, "PI", HICON_PISTOL, GUN_PISTOL},
- {25, 100, S_ITEMHEALTH, "H", HICON_HEALTH, -1},
- {100, 200, S_ITEMHEALTH, "MH", HICON_HEALTH, 50},
- {5, 100, S_ITEMHEALTH, "TH", HICON_HEALTH, -1},
- {5, 50, S_ITEMARMOUR, "TA", HICON_BLUE_ARMOUR, A_BLUE},
- {50, 100, S_ITEMARMOUR, "GA", HICON_GREEN_ARMOUR, A_GREEN},
- {100, 200, S_ITEMARMOUR, "YA", HICON_YELLOW_ARMOUR, A_YELLOW},
- {20000, 30000, S_ITEMPUP, "Q", HICON_QUAD, -1},
+} itemstats[] = { {
+ 10, 30, S_ITEMAMMO, "SG", HICON_SG, GUN_SG}, {
+ 20, 60, S_ITEMAMMO, "CG", HICON_CG, GUN_CG}, {
+ 5, 15, S_ITEMAMMO, "RL", HICON_RL, GUN_RL}, {
+ 5, 15, S_ITEMAMMO, "RI", HICON_RIFLE, GUN_RIFLE}, {
+ 10, 30, S_ITEMAMMO, "GL", HICON_GL, GUN_GL}, {
+ 30, 120, S_ITEMAMMO, "PI", HICON_PISTOL, GUN_PISTOL}, {
+ 25, 100, S_ITEMHEALTH, "H", HICON_HEALTH, -1}, {
+ 100, 200, S_ITEMHEALTH, "MH", HICON_HEALTH, 50}, {
+ 5, 100, S_ITEMHEALTH, "TH", HICON_HEALTH, -1}, {
+ 5, 50, S_ITEMARMOUR, "TA", HICON_BLUE_ARMOUR, A_BLUE}, {
+ 50, 100, S_ITEMARMOUR, "GA", HICON_GREEN_ARMOUR, A_GREEN}, {
+ 100, 200, S_ITEMARMOUR, "YA", HICON_YELLOW_ARMOUR, A_YELLOW}, {
+ 20000, 30000, S_ITEMPUP, "Q", HICON_QUAD, -1},
};
#define MAXRAYS 12
@@ -260,7 +243,7 @@ static const struct guninfo {
const char *name, *file;
short part;
} guns[NUMGUNS] = {
- // delay| dmg| spr| spd| kck| rng| ray| pus| exp|
+ // delay| dmg| spr| spd| kck| rng| ray| pus| exp| {
{ S_PUNCH1, 100, 30, 0, 0, 0, 30, 1, 80, 0, 0, "fist", "fist", 0 },
{ S_SG, 1000, 20, 280, 0, 20, 1024, MAXRAYS, 100, 0, 0, "shotgun", "shotg", 0 },
{ S_CG, 100, 20, 70, 0, 10, 1024, 1, 80, 0, 0, "chaingun", "chaing", 0 },
@@ -287,61 +270,45 @@ extern void pwreset(void);
#include "ai.h"
// inherited by fpsent and server clients
-struct fpsstate
-{
+struct fpsstate {
int health, maxhealth;
int armour, maxarmour, armourtype;
int quadmillis;
int gunselect, gunwait;
int ammo[NUMGUNS];
int aitype, skill;
-
fpsstate() : maxhealth(100), maxarmour(50), aitype(AI_NONE), skill(0) {}
-
- void baseammo(int gun, int k = 2, int scale = 1)
- {
+ void baseammo(int gun, int k = 2, int scale = 1) {
ammo[gun] = (itemstats[gun-GUN_SG].add*k)/scale;
}
-
- void addammo(int gun, int k = 1, int scale = 1)
- {
+ void addammo(int gun, int k = 1, int scale = 1) {
itemstat &is = itemstats[gun-GUN_SG];
ammo[gun] = min(ammo[gun] + (is.add*k)/scale, is.max);
}
-
- bool hasmaxammo(int type)
- {
+ bool hasmaxammo(int type) {
const itemstat &is = itemstats[type-I_SHELLS];
return ammo[type-I_SHELLS+GUN_SG]>=is.max;
}
-
- bool canpickup(int type)
- {
+ bool canpickup(int type) {
if(type<I_SHELLS || type>I_QUAD) return false;
itemstat &is = itemstats[type-I_SHELLS];
- switch(type)
- {
+ switch(type) {
case I_BOOST: return maxhealth<is.max || health<maxhealth;
case I_TINYHEALTH: return health<maxhealth;
case I_HEALTH: return health<maxhealth;
-
case I_TINYARMOUR:
[[fallthrough]];
case I_GREENARMOUR:
[[fallthrough]];
case I_YELLOWARMOUR: return maxarmour<is.max || armour<maxarmour;
-
case I_QUAD: return quadmillis<is.max;
default: return ammo[is.info]<is.max;
}
}
-
- void pickup(int type)
- {
+ void pickup(int type) {
if(type<I_SHELLS || type>I_QUAD) return;
itemstat &is = itemstats[type-I_SHELLS];
- switch(type)
- {
+ switch(type) {
case I_TINYHEALTH:
health = min(health+is.add, maxhealth);
break;
@@ -368,9 +335,7 @@ struct fpsstate
break;
}
}
-
- void respawn()
- {
+ void respawn() {
maxhealth = 100;
health = maxhealth;
maxarmour = 50;
@@ -382,39 +347,31 @@ struct fpsstate
loopi(NUMGUNS) ammo[i] = 0;
ammo[GUN_FIST] = 1;
}
-
- void spawnstate(int gamemode)
- {
- if(m_demo)
- {
+ void spawnstate(int gamemode) {
+ if(m_demo) {
gunselect = GUN_FIST;
}
- else if(m_insta)
- {
+ else if(m_insta) {
armour = 0;
health = 1;
gunselect = GUN_RIFLE;
ammo[GUN_RIFLE] = 100;
}
- else if(m_efficiency)
- {
+ else if(m_efficiency) {
armourtype = A_GREEN;
armour = 100;
loopi(NUMGUNS-1) baseammo(i+1);
gunselect = GUN_CG;
ammo[GUN_CG] /= 2;
}
- else
- {
+ else {
armourtype = A_BLUE;
armour = 25;
ammo[GUN_PISTOL] = 40;
}
}
-
// just subtract damage here, can set death, etc. later in code calling this
- int dodamage(int damage)
- {
+ int dodamage(int damage) {
int ad = (damage*(armourtype+1)*30)/100; // let armour absorb when possible
if(ad>armour) ad = armour;
armour -= ad;
@@ -422,17 +379,14 @@ struct fpsstate
health -= damage;
return damage;
}
-
- int hasammo(int gun, int exclude = -1)
- {
+ int hasammo(int gun, int exclude = -1) {
return gun >= 0 && gun <= NUMGUNS && gun != exclude && ammo[gun] > 0;
}
};
extern int screenw, screenh;
-struct fpsent : dynent, fpsstate
-{
+struct fpsent : dynent, fpsstate {
int weight; // affects the effectiveness of hitpush
int clientnum, privilege, lastupdate, plag, ping;
int lifesequence; // sequence id for each respawn, used in damage test
@@ -448,48 +402,35 @@ struct fpsent : dynent, fpsstate
editinfo *edit;
float deltayaw, deltapitch, deltaroll, newyaw, newpitch, newroll;
int smoothmillis;
-
string name, team, info;
int playermodel;
ai::aiinfo *ai;
int ownernum, lastnode;
-
vec muzzle;
-
- fpsent() : weight(100), clientnum(-1), privilege(PRIV_NONE), lastupdate(0), plag(0), ping(0), lifesequence(0), respawned(-1), suicided(-1), lastpain(0), attacksound(-1), attackchan(-1), idlesound(-1), idlechan(-1), frags(0), flags(0), deaths(0), totaldamage(0), totalshots(0), edit(NULL), smoothmillis(-1), playermodel(-1), ai(NULL), ownernum(-1), muzzle(-1, -1, -1)
- {
+ fpsent() : weight(100), clientnum(-1), privilege(PRIV_NONE), lastupdate(0), plag(0), ping(0), lifesequence(0), respawned(-1), suicided(-1), lastpain(0), attacksound(-1), attackchan(-1), idlesound(-1), idlechan(-1), frags(0), flags(0), deaths(0), totaldamage(0), totalshots(0), edit(NULL), smoothmillis(-1), playermodel(-1), ai(NULL), ownernum(-1), muzzle(-1, -1, -1) {
name[0] = team[0] = info[0] = 0;
respawn();
}
- ~fpsent()
- {
+ ~fpsent() {
freeeditinfo(edit);
if(attackchan >= 0) stopsound(attacksound, attackchan);
if(idlechan >= 0) stopsound(idlesound, idlechan);
if(ai) delete ai;
}
-
- void hitpush(int damage, const vec &dir, fpsent *actor, int gun)
- {
+ void hitpush(int damage, const vec &dir, fpsent *actor, int gun) {
vec push(dir);
push.mul((actor==this && guns[gun].exprad ? EXP_SELFPUSH : 1.0f)*guns[gun].hitpush*damage/weight);
vel.add(push);
}
-
- void stopattacksound()
- {
+ void stopattacksound() {
if(attackchan >= 0) stopsound(attacksound, attackchan, 250);
attacksound = attackchan = -1;
}
-
- void stopidlesound()
- {
+ void stopidlesound() {
if(idlechan >= 0) stopsound(idlesound, idlechan, 100);
idlesound = idlechan = -1;
}
-
- void respawn()
- {
+ void respawn() {
dynent::reset();
fpsstate::respawn();
respawned = suicided = -1;
@@ -506,22 +447,17 @@ struct fpsent : dynent, fpsstate
stopattacksound();
lastnode = -1;
}
-
- int respawnwait(int secs, int delay = 0)
- {
+ int respawnwait(int secs, int delay = 0) {
return max(0, secs - (::lastmillis - lastpain - delay)/1000);
}
};
-struct teamscore
-{
+struct teamscore {
const char *team;
int score;
teamscore() {}
teamscore(const char *s, int n) : team(s), score(n) {}
-
- static bool compare(const teamscore &x, const teamscore &y)
- {
+ static bool compare(const teamscore &x, const teamscore &y) {
if(x.score > y.score) return true;
if(x.score < y.score) return false;
return strcmp(x.team, y.team) < 0;
@@ -533,8 +469,7 @@ static inline bool htcmp(const char *key, const teamscore &t) { return htcmp(key
#define MAXTEAMS 128
-struct teaminfo
-{
+struct teaminfo {
char team[MAXTEAMLEN+1];
int frags;
};
@@ -542,14 +477,11 @@ struct teaminfo
static inline uint hthash(const teaminfo &t) { return hthash(t.team); }
static inline bool htcmp(const char *team, const teaminfo &t) { return !strcmp(team, t.team); }
-namespace entities
-{
+namespace entities {
extern vector<extentity *> ents;
-
extern const char *entmdlname(int type);
extern const char *itemname(int i);
extern int itemicon(int i);
-
extern void preloadentities();
extern void renderentities();
extern void checkitems(fpsent *d);
@@ -562,12 +494,10 @@ namespace entities
extern void pickupeffects(int n, fpsent *d);
extern void teleporteffects(fpsent *d, int tp, int td, bool local = true);
extern void jumppadeffects(fpsent *d, int jp, bool local = true);
-
extern void repammo(fpsent *d, int type, bool local = true);
}
-namespace game
-{
+namespace game {
// fps
extern int gamemode, nextmode;
extern string clientmap;
@@ -580,7 +510,6 @@ namespace game
extern int respawnent;
extern int following;
extern int smoothmove, smoothdist;
-
extern bool clientoption(const char *arg);
extern fpsent *getclient(int cn);
extern fpsent *newclient(int cn);
@@ -608,12 +537,10 @@ namespace game
extern void drawicon(int icon, float x, float y, float sz = 120);
const char *mastermodecolor(int n, const char *unknown);
const char *mastermodeicon(int n, const char *unknown);
-
// client
extern bool connected, remote, demoplayback;
extern string servinfo;
extern vector<uchar> messages;
-
extern int parseplayer(const char *arg);
extern void ignore(int cn);
extern void unignore(int cn);
@@ -627,7 +554,6 @@ namespace game
extern void forceintermission();
extern void c2sinfo(bool force = false);
extern void sendposition(fpsent *d, bool reliable = false);
-
// weapon
extern int getweapon(const char *name);
extern void shoot(fpsent *d, const vec &targ);
@@ -652,7 +578,6 @@ namespace game
extern void gunselect(int gun, fpsent *d);
extern void weaponswitch(fpsent *d);
extern void avoidweapons(ai::avoidset &obstacles, float radius);
-
// scoreboard
extern void showscores(bool on);
extern void getbestplayers(vector<fpsent *> &best);
@@ -660,18 +585,14 @@ namespace game
extern void clearteaminfo();
extern void setteaminfo(const char *team, int frags);
extern int statuscolor(fpsent *d, int color);
-
// render
- struct playermodelinfo
- {
+ struct playermodelinfo {
const char *ffa, *blueteam, *redteam, *hudguns,
*vwep, *quad, *armour[3],
*ffaicon, *blueicon, *redicon;
bool ragdoll;
};
-
extern int playermodel, teamskins, testteam;
-
extern void saveragdoll(fpsent *d);
extern void clearragdolls();
extern void moveragdolls();
@@ -680,8 +601,7 @@ namespace game
extern vec hudgunorigin(int gun, const vec &from, const vec &to, fpsent *d);
}
-namespace server
-{
+namespace server {
extern const char *modename(int n, const char *unknown = "unknown");
extern const char *mastermodename(int n, const char *unknown = "unknown");
extern void startintermission();
diff --git a/src/fpsgame/render.cpp b/src/fpsgame/render.cpp
index f35daec..dacdcd9 100644
--- a/src/fpsgame/render.cpp
+++ b/src/fpsgame/render.cpp
@@ -3,21 +3,16 @@
struct spawninfo { const extentity *e; float weight; };
extern float gatherspawninfos(dynent *d, int tag, vector<spawninfo> &spawninfos);
-namespace game
-{
+namespace game {
vector<fpsent *> bestplayers;
vector<const char *> bestteams;
-
VARP(ragdoll, 0, 1, 1);
VARP(ragdollmillis, 0, 10000, 300000);
VARP(ragdollfade, 0, 1000, 300000);
VARP(playermodel, 0, 0, 0);
VARP(hidedead, 0, 0, 2);
-
vector<fpsent *> ragdolls;
-
- void saveragdoll(fpsent *d)
- {
+ void saveragdoll(fpsent *d) {
if(!d->ragdoll || !ragdollmillis || (!ragdollfade && lastmillis > d->lastpain + ragdollmillis)) return;
fpsent *r = new fpsent(*d);
r->lastupdate = ragdollfade && lastmillis > d->lastpain + max(ragdollmillis - ragdollfade, 0) ? lastmillis - max(ragdollmillis - ragdollfade, 0) : d->lastpain;
@@ -28,49 +23,38 @@ namespace game
ragdolls.add(r);
d->ragdoll = NULL;
}
-
- void clearragdolls()
- {
+ void clearragdolls() {
ragdolls.deletecontents();
}
-
- void moveragdolls()
- {
- loopv(ragdolls)
- {
+ void moveragdolls() {
+ loopv(ragdolls) {
fpsent *d = ragdolls[i];
- if(lastmillis > d->lastupdate + ragdollmillis)
- {
+ if(lastmillis > d->lastupdate + ragdollmillis) {
delete ragdolls.remove(i--);
continue;
}
moveragdoll(d);
}
}
-
- static const playermodelinfo playermodels[1] =
- {
- { "mrfixit", "mrfixit/blue", "mrfixit/red", "mrfixit/hudguns", NULL, "mrfixit/horns", { "mrfixit/armor/blue", "mrfixit/armor/green", "mrfixit/armor/yellow" }, "mrfixit", "mrfixit_blue", "mrfixit_red", true },
+ static const playermodelinfo playermodels[1] = {
+ {
+ "mrfixit", "mrfixit/blue", "mrfixit/red", "mrfixit/hudguns", NULL, "mrfixit/horns", {
+ "mrfixit/armor/blue", "mrfixit/armor/green", "mrfixit/armor/yellow" },
+ "mrfixit", "mrfixit_blue", "mrfixit_red", true },
};
-
- const playermodelinfo *getplayermodelinfo(int n)
- {
+ const playermodelinfo *getplayermodelinfo(int n) {
(void) n;
return &playermodels[0];
}
-
- const playermodelinfo &getplayermodelinfo(fpsent *d)
- {
+ const playermodelinfo &getplayermodelinfo(fpsent *d) {
+ (void) d;
const playermodelinfo *mdl = getplayermodelinfo(0);
if(!mdl) mdl = getplayermodelinfo(playermodel);
return *mdl;
}
-
- void preloadplayermodel()
- {
+ void preloadplayermodel() {
const playermodelinfo *mdl = getplayermodelinfo(0);
- if(m_teammode)
- {
+ if(m_teammode) {
preloadmodel(mdl->blueteam);
preloadmodel(mdl->redteam);
}
@@ -79,23 +63,18 @@ namespace game
if(mdl->quad) preloadmodel(mdl->quad);
loopj(3) if(mdl->armour[j]) preloadmodel(mdl->armour[j]);
}
-
VAR(testquad, 0, 0, 1);
VAR(testarmour, 0, 0, 1);
VAR(testteam, 0, 0, 3);
-
- void renderplayer(fpsent *d, const playermodelinfo &mdl, int team, float fade, bool mainpass)
- {
+ void renderplayer(fpsent *d, const playermodelinfo &mdl, int team, float fade, bool mainpass) {
int lastaction = d->lastaction, hold = mdl.vwep || d->gunselect==GUN_PISTOL ? 0 : (ANIM_HOLD1+d->gunselect)|ANIM_LOOP, attack = ANIM_ATTACK1+d->gunselect, delay = mdl.vwep ? 300 : guns[d->gunselect].attackdelay+50;
- if(intermission && d->state!=CS_DEAD)
- {
+ if(intermission && d->state!=CS_DEAD) {
lastaction = 0;
hold = attack = ANIM_LOSE|ANIM_LOOP;
delay = 0;
if(m_teammode ? bestteams.htfind(d->team)>=0 : bestplayers.find(d)>=0) hold = attack = ANIM_WIN|ANIM_LOOP;
}
- else if(d->state==CS_ALIVE && d->lasttaunt && lastmillis-d->lasttaunt<1000 && lastmillis-d->lastaction>delay)
- {
+ else if(d->state==CS_ALIVE && d->lasttaunt && lastmillis-d->lasttaunt<1000 && lastmillis-d->lastaction>delay) {
lastaction = d->lasttaunt;
hold = attack = ANIM_TAUNT;
delay = 1000;
@@ -103,94 +82,75 @@ namespace game
modelattach a[5];
static const char * const vweps[] = {"vwep/fist", "vwep/shotg", "vwep/chaing", "vwep/rocket", "vwep/rifle", "vwep/gl", "vwep/pistol"};
int ai = 0;
- if((!mdl.vwep || d->gunselect!=GUN_FIST) && d->gunselect<=GUN_PISTOL)
- {
+ if((!mdl.vwep || d->gunselect!=GUN_FIST) && d->gunselect<=GUN_PISTOL) {
int vanim = ANIM_VWEP_IDLE|ANIM_LOOP, vtime = 0;
- if(lastaction && d->lastattackgun==d->gunselect && lastmillis < lastaction + delay)
- {
+ if(lastaction && d->lastattackgun==d->gunselect && lastmillis < lastaction + delay) {
vanim = ANIM_VWEP_SHOOT;
vtime = lastaction;
}
a[ai++] = modelattach("tag_weapon", mdl.vwep ? mdl.vwep : vweps[d->gunselect], vanim, vtime);
}
- if(d->state==CS_ALIVE)
- {
+ if(d->state==CS_ALIVE) {
if((testquad || d->quadmillis) && mdl.quad)
a[ai++] = modelattach("tag_powerup", mdl.quad, ANIM_POWERUP|ANIM_LOOP, 0);
- if(testarmour || d->armour)
- {
+ if(testarmour || d->armour) {
int type = clamp(d->armourtype, (int)A_BLUE, (int)A_YELLOW);
if(mdl.armour[type])
a[ai++] = modelattach("tag_shield", mdl.armour[type], ANIM_SHIELD|ANIM_LOOP, 0);
}
}
- if(mainpass)
- {
+ if(mainpass) {
d->muzzle = vec(-1, -1, -1);
a[ai++] = modelattach("tag_muzzle", &d->muzzle);
}
const char *mdlname = mdl.ffa;
- switch(testteam ? testteam-1 : team)
- {
+ switch(testteam ? testteam-1 : team) {
case 1: mdlname = mdl.blueteam; break;
case 2: mdlname = mdl.redteam; break;
}
renderclient(d, mdlname, a[0].tag ? a : NULL, hold, attack, delay, lastaction, intermission && d->state!=CS_DEAD ? 0 : d->lastpain, fade, ragdoll && mdl.ragdoll);
}
-
VARP(teamskins, 0, 0, 1);
-
VARP(statusicons, 0, 1, 1);
-
- void renderstatusicons(fpsent *d, int team, float yoffset)///TODO
- {
+ void renderstatusicons(fpsent *d, int team, float yoffset) {///TODO {
vec p = d->abovehead().madd(camup, yoffset);
int icons = 0;
const itemstat &boost = itemstats[I_BOOST-I_SHELLS];
- if(statusicons && (d->state==CS_ALIVE || d->state==CS_LAGGED))
- {
+ if(statusicons && (d->state==CS_ALIVE || d->state==CS_LAGGED)) {
if(d->quadmillis) icons++;
if(d->maxhealth>100) icons += (min(d->maxhealth, boost.max) - 100 + boost.info-1) / boost.info;
if(d->armour>0 && d->armourtype>=A_GREEN && !m_noitems) icons++;
}
if(icons) concatstring(d->info, " ");
particle_text(p, d->info, PART_TEXT, 1, team ? (team==1 ? 0x6496FF : 0xFF4B19) : 0x1EC850, 2.0f, 0, icons);
- if(icons)
- {
+ if(icons) {
float tw, th;
text_boundsf(d->info, tw, th);
float offset = (tw - icons*th)/2;
- if(d->armour>0 && d->armourtype>=A_GREEN && !m_noitems)
- {
+ if(d->armour>0 && d->armourtype>=A_GREEN && !m_noitems) {
int icon = itemstats[(d->armourtype==A_YELLOW ? I_YELLOWARMOUR : I_GREENARMOUR)-I_SHELLS].icon;
particle_texticon(p, icon%4, icon/4, offset, PART_TEXT_ICON, 1, 0xFFFFFF, 2.0f);
offset += th;
}
- for(int i = 100; i < min(d->maxhealth, boost.max); i += boost.info)
- {
+ for(int i = 100; i < min(d->maxhealth, boost.max); i += boost.info) {
particle_texticon(p, boost.icon%4, boost.icon/4, offset, PART_TEXT_ICON, 1, 0xFFFFFF, 2.0f);
offset += th;
}
- if(d->quadmillis)
- {
+ if(d->quadmillis) {
int icon = itemstats[I_QUAD-I_SHELLS].icon;
particle_texticon(p, icon%4, icon/4, offset, PART_TEXT_ICON, 1, 0xFFFFFF, 2.0f);
offset += th;
}
}
}
-
VARP(statusbars, 0, 1, 2);
FVARP(statusbarscale, 0, 1, 2);
-
- float renderstatusbars(fpsent *d, int team)///TODO
- {
+ float renderstatusbars(fpsent *d, int team) {///TODO {
if(!statusbars || m_insta || (player1->state==CS_SPECTATOR ? statusbars <= 1 : team != 1) || (d->state!=CS_ALIVE && d->state!=CS_LAGGED)) return 0;
vec p = d->abovehead().msub(camdir, 50/80.0f).msub(camup, 2.0f);
float offset = 0;
float scale = statusbarscale;
- if(d->armour > 0)
- {
+ if(d->armour > 0) {
int limit = d->armourtype==A_YELLOW ? 200 : (d->armourtype==A_GREEN ? 100 : 50);
int color = d->armourtype==A_YELLOW ? 0xFFC040 : (d->armourtype==A_GREEN ? 0x008C00 : 0x0B5899);
float size = scale*sqrtf(max(d->armour, limit)/100.0f);
@@ -205,48 +165,36 @@ namespace game
particle_meter(vec(p).madd(camup, offset), fill, PART_METER, 1, color, 0, size);
return offset;
}
-
- void rendergame(bool mainpass)
- {
+ void rendergame(bool mainpass) {
if(mainpass) ai::render();
-
- if(intermission)
- {
+ if(intermission) {
bestteams.shrink(0);
bestplayers.shrink(0);
if(m_teammode) getbestteams(bestteams);
else getbestplayers(bestplayers);
}
-
startmodelbatches();
-
fpsent *exclude = isthirdperson() ? NULL : followingplayer();
- loopv(players)
- {
+ loopv(players) {
fpsent *d = players[i];
if(d == player1 || d->state==CS_SPECTATOR || d->state==CS_SPAWNING || d->lifesequence < 0 || d == exclude || (d->state==CS_DEAD && hidedead)) continue;
int team = 0;
if(teamskins || m_teammode) team = isteam(player1->team, d->team) ? 1 : 2;
renderplayer(d, getplayermodelinfo(d), team, 1, mainpass);
-
vec dir = vec(d->o).sub(camera1->o);
float dist = dir.magnitude();
dir.div(dist);
- if(d->state!=CS_EDITING && raycube(camera1->o, dir, dist, 0) < dist)
- {
+ if(d->state!=CS_EDITING && raycube(camera1->o, dir, dist, 0) < dist) {
d->info[0] = '\0';
continue;
}
-
copystring(d->info, colorname(d));
- if(d->state!=CS_DEAD)
- {
+ if(d->state!=CS_DEAD) {
float offset = renderstatusbars(d, team);
renderstatusicons(d, team, offset);
}
}
- loopv(ragdolls)
- {
+ loopv(ragdolls) {
fpsent *d = ragdolls[i];
int team = 0;
if(teamskins || m_teammode) team = isteam(player1->team, d->team) ? 1 : 2;
@@ -259,42 +207,32 @@ namespace game
entities::renderentities();
renderbouncers();
renderprojectiles();
-
endmodelbatches();
}
-
VARP(hudgun, 0, 1, 1);
VARP(hudgunsway, 0, 1, 1);
VARP(teamhudguns, 0, 1, 1);
VARP(chainsawhudgun, 0, 1, 1);
VAR(testhudgun, 0, 0, 1);
-
FVAR(swaystep, 1, 35.0f, 100);
FVAR(swayside, 0, 0.04f, 1);
FVAR(swayup, -1, 0.05f, 1);
-
float swayfade = 0, swayspeed = 0, swaydist = 0;
vec swaydir(0, 0, 0);
-
- void swayhudgun(int curtime)
- {
+ void swayhudgun(int curtime) {
fpsent *d = hudplayer();
- if(d->state != CS_SPECTATOR)
- {
- if(d->physstate >= PHYS_SLOPE)
- {
+ if(d->state != CS_SPECTATOR) {
+ if(d->physstate >= PHYS_SLOPE) {
swayspeed = min(sqrtf(d->vel.x*d->vel.x + d->vel.y*d->vel.y), d->maxspeed);
swaydist += swayspeed*curtime/1000.0f;
swaydist = fmod(swaydist, 2*swaystep);
swayfade = 1;
}
- else if(swayfade > 0)
- {
+ else if(swayfade > 0) {
swaydist += swayspeed*swayfade*curtime/1000.0f;
swaydist = fmod(swaydist, 2*swaystep);
swayfade -= 0.5f*(curtime*d->maxspeed)/(swaystep*1000.0f);
}
-
float k = pow(0.7f, curtime/10.0f);
swaydir.mul(k);
vec vel(d->vel);
@@ -302,18 +240,12 @@ namespace game
swaydir.add(vec(vel).mul((1-k)/(15*max(vel.magnitude(), d->maxspeed))));
}
}
-
- struct hudent : dynent
- {
+ struct hudent : dynent {
hudent() { type = ENT_CAMERA; }
} guninterp;
-
SVARP(hudgunsdir, "");
-
- void drawhudmodel(fpsent *d, int anim, float speed = 0, int base = 0)
- {
+ void drawhudmodel(fpsent *d, int anim, float speed = 0, int base = 0) {
if(d->gunselect>GUN_PISTOL) return;
-
vec sway;
vecfromyawpitch(d->yaw, 0, 0, 1, sway);
float steps = swaydist/swaystep*M_PI;
@@ -323,8 +255,7 @@ namespace game
if(!hudgunsway) sway = d->o;
#if 0
- if(player1->state!=CS_DEAD && player1->quadmillis)
- {
+ if(player1->state!=CS_DEAD && player1->quadmillis) {
float t = 0.5f + 0.5f*sinf(2*M_PI*lastmillis/1000.0f);
color.y = color.y*(1-t) + t;
}
@@ -339,8 +270,7 @@ namespace game
d->muzzle = vec(-1, -1, -1);
a[0] = modelattach("tag_muzzle", &d->muzzle);
dynent *interp = NULL;
- if(d->gunselect==GUN_FIST && chainsawhudgun)
- {
+ if(d->gunselect==GUN_FIST && chainsawhudgun) {
anim |= ANIM_LOOP;
base = 0;
interp = &guninterp;
@@ -348,37 +278,26 @@ namespace game
rendermodel(NULL, gunname, anim, sway, testhudgun ? 0 : d->yaw+90, testhudgun ? 0 : d->pitch, MDL_LIGHT|MDL_HUD, interp, a, base, (int)ceil(speed));
if(d->muzzle.x >= 0) d->muzzle = calcavatarpos(d->muzzle, 12);
}
-
- void drawhudgun()
- {
+ void drawhudgun() {
fpsent *d = hudplayer();
- if(d->state==CS_SPECTATOR || d->state==CS_EDITING || !hudgun || editmode)
- {
+ if(d->state==CS_SPECTATOR || d->state==CS_EDITING || !hudgun || editmode) {
d->muzzle = player1->muzzle = vec(-1, -1, -1);
return;
}
-
int rtime = guns[d->gunselect].attackdelay;
- if(d->lastaction && d->lastattackgun==d->gunselect && lastmillis-d->lastaction<rtime)
- {
+ if(d->lastaction && d->lastattackgun==d->gunselect && lastmillis-d->lastaction<rtime) {
drawhudmodel(d, ANIM_GUN_SHOOT|ANIM_SETSPEED, rtime/17.0f, d->lastaction);
}
- else
- {
+ else {
drawhudmodel(d, ANIM_GUN_IDLE|ANIM_LOOP);
}
}
-
- void renderavatar()
- {
+ void renderavatar() {
drawhudgun();
}
-
- void renderplayerpreview(int model, int team, int weap)
- {
+ void renderplayerpreview(int model, int team, int weap) {
static fpsent *previewent = NULL;
- if(!previewent)
- {
+ if(!previewent) {
previewent = new fpsent;
previewent->light.color = vec(1, 1, 1);
previewent->light.dir = vec(0, -1, 2).normalize();
@@ -394,18 +313,15 @@ namespace game
if(!mdlinfo) return;
renderplayer(previewent, *mdlinfo, team >= 0 && team <= 2 ? team : 0, 1, false);
}
-
- vec hudgunorigin(int gun, const vec &from, const vec &to, fpsent *d)
- {
+ vec hudgunorigin(int gun, const vec &from, const vec &to, fpsent *d) {
+ (void) gun;
if(d->muzzle.x >= 0) return d->muzzle;
vec offset(from);
- if(d!=hudplayer() || isthirdperson())
- {
+ if(d!=hudplayer() || isthirdperson()) {
vec front, right;
vecfromyawpitch(d->yaw, d->pitch, 1, 0, front);
offset.add(front.mul(d->radius));
- if(d->type!=ENT_AI)
- {
+ if(d->type!=ENT_AI) {
offset.z += (d->aboveeye + d->eyeheight)*0.75f - d->eyeheight;
vecfromyawpitch(d->yaw, 0, 0, -1, right);
offset.add(right.mul(0.5f*d->radius));
@@ -414,30 +330,24 @@ namespace game
return offset;
}
offset.add(vec(to).sub(from).normalize().mul(2));
- if(hudgun)
- {
+ if(hudgun) {
offset.sub(vec(camup).mul(1.0f));
offset.add(vec(camright).mul(0.8f));
}
else offset.sub(vec(camup).mul(0.8f));
return offset;
}
-
- void preloadweapons()
- {
+ void preloadweapons() {
const playermodelinfo &mdl = getplayermodelinfo(player1);
- loopi(NUMGUNS)
- {
+ loopi(NUMGUNS) {
const char *file = guns[i].file;
if(!file) continue;
string fname;
- if((m_teammode || teamskins) && teamhudguns)
- {
+ if((m_teammode || teamskins) && teamhudguns) {
formatstring(fname, "%s/%s/blue", hudgunsdir[0] ? hudgunsdir : mdl.hudguns, file);
preloadmodel(fname);
}
- else
- {
+ else {
formatstring(fname, "%s/%s", hudgunsdir[0] ? hudgunsdir : mdl.hudguns, file);
preloadmodel(fname);
}
@@ -445,14 +355,10 @@ namespace game
preloadmodel(fname);
}
}
-
- void preloadsounds()
- {
+ void preloadsounds() {
for(int i = S_JUMP; i <= S_HIT; i++) preloadsound(i);
}
-
- void preload()
- {
+ void preload() {
if(hudgun) preloadweapons();
preloadbouncers();
preloadplayermodel();
diff --git a/src/fpsgame/scoreboard.cpp b/src/fpsgame/scoreboard.cpp
index 96f8868..81f93a1 100644
--- a/src/fpsgame/scoreboard.cpp
+++ b/src/fpsgame/scoreboard.cpp
@@ -1,8 +1,7 @@
// creation of scoreboard
#include "game.h"
-namespace game
-{
+namespace game {
VARP(scoreboard2d, 0, 1, 1);
VARP(showservinfo, 0, 1, 1);
VARP(showclientnum, 0, 1, 1);
@@ -15,25 +14,17 @@ namespace game
VARP(hidefrags, 0, 0, 1);
VARP(showdeaths, 0, 1, 1);
VARP(showdamagedealt, 0, 1, 1);
-
static hashset<teaminfo> teaminfos;
-
- void clearteaminfo()
- {
+ void clearteaminfo() {
teaminfos.clear();
}
-
- void setteaminfo(const char *team, int frags)
- {
+ void setteaminfo(const char *team, int frags) {
teaminfo *t = teaminfos.access(team);
if(!t) { t = &teaminfos[team]; copystring(t->team, team, sizeof(t->team)); }
t->frags = frags;
}
-
- static inline bool playersort(const fpsent *a, const fpsent *b)
- {
- if(a->state==CS_SPECTATOR)
- {
+ static inline bool playersort(const fpsent *a, const fpsent *b) {
+ if(a->state==CS_SPECTATOR) {
if(b->state==CS_SPECTATOR) return strcmp(a->name, b->name) < 0;
else return false;
}
@@ -42,51 +33,38 @@ namespace game
if(a->frags < b->frags) return false;
return strcmp(a->name, b->name) < 0;
}
-
- void getbestplayers(vector<fpsent *> &best)
- {
- loopv(players)
- {
+ void getbestplayers(vector<fpsent *> &best) {
+ loopv(players) {
fpsent *o = players[i];
if(o->state!=CS_SPECTATOR) best.add(o);
}
best.sort(playersort);
while(best.length() > 1 && best.last()->frags < best[0]->frags) best.drop();
}
-
- void getbestteams(vector<const char *> &best)
- {
- if(!hidefrags)
- {
+ void getbestteams(vector<const char *> &best) {
+ if(!hidefrags) {
vector<teamscore> teamscores;
teamscores.sort(teamscore::compare);
while(teamscores.length() > 1 && teamscores.last().score < teamscores[0].score) teamscores.drop();
loopv(teamscores) best.add(teamscores[i].team);
}
- else
- {
+ else {
int bestfrags = INT_MIN;
enumerate(teaminfos, teaminfo, t, bestfrags = max(bestfrags, t.frags));
- if(bestfrags <= 0) loopv(players)
- {
+ if(bestfrags <= 0) loopv(players) {
fpsent *o = players[i];
if(o->state!=CS_SPECTATOR && !teaminfos.access(o->team) && best.htfind(o->team) < 0) { bestfrags = 0; best.add(o->team); }
}
enumerate(teaminfos, teaminfo, t, if(t.frags >= bestfrags) best.add(t.team));
}
}
-
- struct scoregroup : teamscore
- {
+ struct scoregroup : teamscore {
vector<fpsent *> players;
};
static vector<scoregroup *> groups;
static vector<fpsent *> spectators;
-
- static inline bool scoregroupcmp(const scoregroup *x, const scoregroup *y)
- {
- if(!x->team)
- {
+ static inline bool scoregroupcmp(const scoregroup *x, const scoregroup *y) {
+ if(!x->team) {
if(y->team) return false;
}
else if(!y->team) return true;
@@ -96,20 +74,16 @@ namespace game
if(x->players.length() < y->players.length()) return false;
return x->team && y->team && strcmp(x->team, y->team) < 0;
}
-
- static int groupplayers()
- {
+ static int groupplayers() {
int numgroups = 0;
spectators.setsize(0);
- loopv(players)
- {
+ loopv(players) {
fpsent *o = players[i];
if(!showconnecting && !o->name[0]) continue;
if(o->state==CS_SPECTATOR) { spectators.add(o); continue; }
const char *team = m_teammode && o->team[0] ? o->team : NULL;
bool found = false;
- loopj(numgroups)
- {
+ loopj(numgroups) {
scoregroup &g = *groups[j];
if(team!=g.team && (!team || !g.team || strcmp(team, g.team))) continue;
g.players.add(o);
@@ -129,31 +103,23 @@ namespace game
groups.sort(scoregroupcmp, 0, numgroups);
return numgroups;
}
-
- int statuscolor(fpsent *d, int color)
- {
- if(d->privilege)
- {
+ int statuscolor(fpsent *d, int color) {
+ if(d->privilege) {
color = d->privilege>=PRIV_ADMIN ? 0xFF8000 : (d->privilege>=PRIV_AUTH ? 0xC040C0 : 0x40FF80);
if(d->state==CS_DEAD) color = (color>>1)&0x7F7F7F;
}
else if(d->state==CS_DEAD) color = 0x606060;
return color;
}
-
- void renderscoreboard(g3d_gui &g, bool firstpass)
- {
+ void renderscoreboard(g3d_gui &g, bool firstpass) {
const ENetAddress *address = connectedpeer();
- if(showservinfo && address)
- {
+ if(showservinfo && address) {
string hostname;
- if(enet_address_get_host_ip(address, hostname, sizeof(hostname)) >= 0)
- {
+ if(enet_address_get_host_ip(address, hostname, sizeof(hostname)) >= 0) {
if(servinfo[0]) g.titlef("%.25s", 0xFFFF80, NULL, servinfo);
else g.titlef("%s:%d", 0xFFFF80, NULL, hostname, address->port);
}
}
-
g.pushlist();
g.spring();
g.text(server::modename(gamemode), 0xFFFF80);
@@ -162,12 +128,10 @@ namespace game
g.text(mname[0] ? mname : "[new map]", 0xFFFF80);
extern int gamespeed;
if(gamespeed != 100) { g.separator(); g.textf("%d.%02dx", 0xFFFF80, NULL, gamespeed/100, gamespeed%100); }
- if(m_timed && mname[0] && (maplimit >= 0 || intermission))
- {
+ if(m_timed && mname[0] && (maplimit >= 0 || intermission)) {
g.separator();
if(intermission) g.text("intermission", 0xFFFF80);
- else
- {
+ else {
int secs = max(maplimit-lastmillis+999, 0)/1000, mins = secs/60;
secs %= 60;
g.pushlist();
@@ -179,41 +143,31 @@ namespace game
if(ispaused()) { g.separator(); g.text("paused", 0xFFFF80); }
g.spring();
g.poplist();
-
g.separator();
-
int numgroups = groupplayers();
- loopk(numgroups)
- {
+ loopk(numgroups) {
if((k%2)==0) g.pushlist(); // horizontal
-
scoregroup &sg = *groups[k];
int bgcolor = sg.team && m_teammode ? (isteam(player1->team, sg.team) ? 0x3030C0 : 0xC03030) : 0,
fgcolor = 0xFFFF80;
-
g.pushlist(); // vertical
g.pushlist(); // horizontal
-
#define loopscoregroup(o, b) \
- loopv(sg.players) \
- { \
+ loopv(sg.players) { \
+ \
fpsent *o = sg.players[i]; \
b; \
}
-
g.pushlist();
- if(sg.team && m_teammode)
- {
+ if(sg.team && m_teammode) {
g.pushlist();
g.background(bgcolor, numgroups>1 ? 3 : 5);
g.strut(1);
g.poplist();
}
g.text("", 0, " ");
- loopscoregroup(o,
- {
- if(o==player1 && highlightscore && (multiplayer(false) || demoplayback || players.length() > 1))
- {
+ loopscoregroup(o, {
+ if(o==player1 && highlightscore && (multiplayer(false) || demoplayback || players.length() > 1)) {
g.pushlist();
g.background(0x808080, numgroups>1 ? 3 : 5);
}
@@ -223,104 +177,79 @@ namespace game
if(o==player1 && highlightscore && (multiplayer(false) || demoplayback || players.length() > 1)) g.poplist();
});
g.poplist();
-
- if(sg.team && m_teammode)
- {
+ if(sg.team && m_teammode) {
g.pushlist(); // vertical
-
if(sg.score>=10000) g.textf("%s: WIN", fgcolor, NULL, sg.team);
else g.textf("%s: %d", fgcolor, NULL, sg.team, sg.score);
-
g.pushlist(); // horizontal
}
-
- if(!hidefrags)
- {
+ if(!hidefrags) {
g.pushlist();
g.strut(6);
g.text("frags", fgcolor);
loopscoregroup(o, g.textf("%d", 0xFFFFDD, NULL, o->frags));
g.poplist();
}
-
- if(showdeaths)
- {
+ if(showdeaths) {
g.pushlist();
g.strut(6);
g.text("deaths", fgcolor);
loopscoregroup(o, g.textf("%d", 0xFFFFDD, NULL, o->deaths));
g.poplist();
}
-
- if(showdamagedealt)
- {
+ if(showdamagedealt) {
g.pushlist();
g.strut(7);
g.text("damage", fgcolor);
loopscoregroup(o, g.textf("%d", 0xFFFFDD, NULL, o->totaldamage));
g.poplist();
}
-
g.pushlist();
g.text("name", fgcolor);
g.strut(12);
loopscoregroup(o, { g.textf("%s ", statuscolor(o, 0xFFFFDD), NULL, colorname(o)); });
g.poplist();
-
- if(multiplayer(false) || demoplayback)
- {
+ if(multiplayer(false) || demoplayback) {
if(showpj || showping) g.space(1);
-
- if(showpj && showping <= 1)
- {
+ if(showpj && showping <= 1) {
g.pushlist();
g.strut(6);
g.text("pj", fgcolor);
- loopscoregroup(o,
- {
+ loopscoregroup(o, {
if(o->state==CS_LAGGED) g.text("LAG", 0xFFFFDD);
else g.textf("%d", 0xFFFFDD, NULL, o->plag);
});
g.poplist();
}
-
- if(showping > 1)
- {
+ if(showping > 1) {
g.pushlist();
g.strut(6);
-
g.pushlist();
g.text("ping", fgcolor);
g.space(1);
g.spring();
g.text("pj", fgcolor);
g.poplist();
-
- loopscoregroup(o,
- {
+ loopscoregroup(o, {
fpsent *p = o->ownernum >= 0 ? getclient(o->ownernum) : o;
if(!p) p = o;
g.pushlist();
if(p->state==CS_LAGGED) g.text("LAG", 0xFFFFDD);
- else
- {
+ else {
g.textf("%d", 0xFFFFDD, NULL, p->ping);
g.space(1);
g.spring();
g.textf("%d", 0xFFFFDD, NULL, o->plag);
}
g.poplist();
-
});
g.poplist();
}
- else if(showping)
- {
+ else if(showping) {
g.pushlist();
g.text("ping", fgcolor);
g.strut(6);
- loopscoregroup(o,
- {
+ loopscoregroup(o, {
fpsent *p = o->ownernum >= 0 ? getclient(o->ownernum) : o;
if(!p) p = o;
if(!showpj && p->state==CS_LAGGED) g.text("LAG", 0xFFFFDD);
@@ -329,43 +258,31 @@ namespace game
g.poplist();
}
}
-
- if(showclientnum || player1->privilege>=PRIV_MASTER)
- {
+ if(showclientnum || player1->privilege>=PRIV_MASTER) {
g.space(1);
g.pushlist();
g.text("cn", fgcolor);
loopscoregroup(o, g.textf("%d", 0xFFFFDD, NULL, o->clientnum));
g.poplist();
}
-
- if(sg.team && m_teammode)
- {
+ if(sg.team && m_teammode) {
g.poplist(); // horizontal
g.poplist(); // vertical
}
-
g.poplist(); // horizontal
g.poplist(); // vertical
-
if(k+1<numgroups && (k+1)%2) g.space(2);
else g.poplist(); // horizontal
}
-
- if(showspectators && spectators.length())
- {
- if(showclientnum || player1->privilege>=PRIV_MASTER)
- {
+ if(showspectators && spectators.length()) {
+ if(showclientnum || player1->privilege>=PRIV_MASTER) {
g.pushlist();
-
g.pushlist();
g.text("spectator", 0xFFFF80, " ");
g.strut(12);
- loopv(spectators)
- {
+ loopv(spectators) {
fpsent *o = spectators[i];
- if(o==player1 && highlightscore)
- {
+ if(o==player1 && highlightscore) {
g.pushlist();
g.background(0x808080, 3);
}
@@ -373,15 +290,12 @@ namespace game
if(o==player1 && highlightscore) g.poplist();
}
g.poplist();
-
- if((multiplayer(false) || demoplayback) && showspectatorping)
- {
+ if((multiplayer(false) || demoplayback) && showspectatorping) {
g.space(1);
g.pushlist();
g.text("ping", 0xFFFF80);
g.strut(6);
- loopv(spectators)
- {
+ loopv(spectators) {
fpsent *o = spectators[i];
fpsent *p = o->ownernum >= 0 ? getclient(o->ownernum) : o;
if(!p) p = o;
@@ -390,28 +304,22 @@ namespace game
}
g.poplist();
}
-
g.space(1);
g.pushlist();
g.text("cn", 0xFFFF80);
loopv(spectators) g.textf("%d", 0xFFFFDD, NULL, spectators[i]->clientnum);
g.poplist();
-
g.poplist();
}
- else
- {
+ else {
g.textf("%d spectator%s", 0xFFFF80, " ", spectators.length(), spectators.length()!=1 ? "s" : "");
- loopv(spectators)
- {
- if((i%3)==0)
- {
+ loopv(spectators) {
+ if((i%3)==0) {
g.pushlist();
g.text("", 0xFFFFDD, "spectator");
}
fpsent *o = spectators[i];
- if(o==player1 && highlightscore)
- {
+ if(o==player1 && highlightscore) {
g.pushlist();
g.background(0x808080);
}
@@ -422,7 +330,6 @@ namespace game
}
}
}
-
/// PW
g.separator();
g.pushlist();
@@ -445,53 +352,36 @@ namespace game
g.textf(" x %d ", 0xffffff, "quad_damage.png", pwitemspicked[6]);
g.poplist();
}
-
- struct scoreboardgui : g3d_callback
- {
+ struct scoreboardgui : g3d_callback {
bool showing;
vec menupos;
int menustart;
-
scoreboardgui() : showing(false) {}
-
- void show(bool on)
- {
- if(!showing && on)
- {
+ void show(bool on) {
+ if(!showing && on) {
menupos = menuinfrontofplayer();
menustart = starttime();
}
showing = on;
}
-
- void gui(g3d_gui &g, bool firstpass)
- {
+ void gui(g3d_gui &g, bool firstpass) {
g.start(menustart, 0.03f, NULL, false);
renderscoreboard(g, firstpass);
g.end();
}
-
- void render()
- {
+ void render() {
if(showing) g3d_addgui(this, menupos, (scoreboard2d ? GUI_FORCE_2D : GUI_2D | GUI_FOLLOW) | GUI_BOTTOM);
}
-
} scoreboard;
-
- void g3d_gamemenus()
- {
+ void g3d_gamemenus() {
scoreboard.render();
}
-
VARFN(scoreboard, showscoreboard, 0, 0, 1, scoreboard.show(showscoreboard!=0));
-
- void showscores(bool on)
- {
+ void showscores(bool on) {
showscoreboard = on ? 1 : 0;
scoreboard.show(on);
}
ICOMMAND(showscores, "D", (int *down), showscores(*down!=0));
-
VARP(hudscore, 0, 0, 1);
FVARP(hudscorescale, 1e-3f, 1.0f, 1e3f);
VARP(hudscorealign, -1, 0, 1);
@@ -501,61 +391,48 @@ namespace game
HVARP(hudscoreenemycolour, 0, 0xFF4040, 0xFFFFFF);
VARP(hudscorealpha, 0, 255, 255);
VARP(hudscoresep, 0, 200, 1000);
-
- void drawhudscore(int w, int h)
- {
+ void drawhudscore(int w, int h) {
int numgroups = groupplayers();
if(!numgroups) return;
-
scoregroup *g = groups[0];
int score = INT_MIN, score2 = INT_MIN;
bool best = false;
- if(m_teammode)
- {
+ if(m_teammode) {
score = g->score;
best = isteam(player1->team, g->team);
- if(numgroups > 1)
- {
+ if(numgroups > 1) {
if(best) score2 = groups[1]->score;
else for(int i = 1; i < groups.length(); ++i) if(isteam(player1->team, groups[i]->team)) { score2 = groups[i]->score; break; }
- if(score2 == INT_MIN)
- {
+ if(score2 == INT_MIN) {
fpsent *p = followingplayer(player1);
if(p->state==CS_SPECTATOR) score2 = groups[1]->score;
}
}
}
- else
- {
+ else {
fpsent *p = followingplayer(player1);
score = g->players[0]->frags;
best = p == g->players[0];
- if(g->players.length() > 1)
- {
+ if(g->players.length() > 1) {
if(best || p->state==CS_SPECTATOR) score2 = g->players[1]->frags;
else score2 = p->frags;
}
}
if(score == score2 && !best) best = true;
-
score = clamp(score, -999, 9999);
defformatstring(buf, "%d", score);
int tw = 0, th = 0;
text_bounds(buf, tw, th);
-
string buf2;
int tw2 = 0, th2 = 0;
- if(score2 > INT_MIN)
- {
+ if(score2 > INT_MIN) {
score2 = clamp(score2, -999, 9999);
formatstring(buf2, "%d", score2);
text_bounds(buf2, tw2, th2);
}
-
int fw = 0, fh = 0;
text_bounds("00", fw, fh);
fw = max(fw, max(tw, tw2));
-
vec2 offset = vec2(hudscorex, hudscorey).mul(vec2(w, h).div(hudscorescale));
if(hudscorealign == 1) offset.x -= 2*fw + hudscoresep;
else if(hudscorealign == 0) offset.x -= (2*fw + hudscoresep) / 2.0f;
@@ -564,17 +441,13 @@ namespace game
offset.y -= th/2.0f;
offset2.x += fw + hudscoresep + (fw-tw2)/2.0f;
offset2.y -= th2/2.0f;
-
pushhudmatrix();
hudmatrix.scale(hudscorescale, hudscorescale, 1);
flushhudmatrix();
-
int color = hudscoreplayercolour, color2 = hudscoreenemycolour;
if(!best) swap(color, color2);
-
draw_text(buf, int(offset.x), int(offset.y), (color>>16)&0xFF, (color>>8)&0xFF, color&0xFF, hudscorealpha);
if(score2 > INT_MIN) draw_text(buf2, int(offset2.x), int(offset2.y), (color2>>16)&0xFF, (color2>>8)&0xFF, color2&0xFF, hudscorealpha);
-
pophudmatrix();
}
}
diff --git a/src/fpsgame/server.cpp b/src/fpsgame/server.cpp
index ec781c6..2095dd1 100644
--- a/src/fpsgame/server.cpp
+++ b/src/fpsgame/server.cpp
@@ -1,9 +1,7 @@
#include "game.h"
-namespace game
-{
- void parseoptions(vector<const char *> &args)
- {
+namespace game {
+ void parseoptions(vector<const char *> &args) {
loopv(args)
#ifndef STANDALONE
if(!game::clientoption(args[i]))
@@ -11,7 +9,6 @@ namespace game
if(!server::serveroption(args[i]))
conoutf(CON_ERROR, "unknown command-line option: %s", args[i]);
}
-
const char *gameident() { return "fps"; }
}
@@ -19,105 +16,69 @@ VAR(regenbluearmour, 0, 1, 1);
extern ENetAddress masteraddress;
-namespace server
-{
- struct server_entity // server side version of "entity" type
- {
+namespace server {
+ struct server_entity { // server side version of "entity" type {
int type;
int spawntime;
bool spawned;
};
-
static const int DEATHMILLIS = 300;
-
struct clientinfo;
-
- struct gameevent
- {
+ struct gameevent {
virtual ~gameevent() {}
-
virtual bool flush(clientinfo *ci, int fmillis);
- virtual void process(clientinfo *ci) {}
-
+ virtual void process(clientinfo *) {}
virtual bool keepable() const { return false; }
};
-
- struct timedevent : gameevent
- {
+ struct timedevent : gameevent {
int millis;
-
bool flush(clientinfo *ci, int fmillis);
};
-
- struct hitinfo
- {
+ struct hitinfo {
int target;
int lifesequence;
int rays;
float dist;
vec dir;
};
-
- struct shotevent : timedevent
- {
+ struct shotevent : timedevent {
int id, gun;
vec from, to;
vector<hitinfo> hits;
-
void process(clientinfo *ci);
};
-
- struct explodeevent : timedevent
- {
+ struct explodeevent : timedevent {
int id, gun;
vector<hitinfo> hits;
-
bool keepable() const { return true; }
-
void process(clientinfo *ci);
};
-
- struct suicideevent : gameevent
- {
+ struct suicideevent : gameevent {
void process(clientinfo *ci);
};
-
- struct pickupevent : gameevent
- {
+ struct pickupevent : gameevent {
int ent;
-
void process(clientinfo *ci);
};
-
template <int N>
- struct projectilestate
- {
+ struct projectilestate {
int projs[N];
int numprojs;
-
projectilestate() : numprojs(0) {}
-
void reset() { numprojs = 0; }
-
- void add(int val)
- {
+ void add(int val) {
if(numprojs>=N) numprojs = 0;
projs[numprojs++] = val;
}
-
- bool remove(int val)
- {
- loopi(numprojs) if(projs[i]==val)
- {
+ bool remove(int val) {
+ loopi(numprojs) if(projs[i]==val) {
projs[i] = projs[--numprojs];
return true;
}
return false;
}
};
-
- struct gamestate : fpsstate
- {
+ struct gamestate : fpsstate {
vec o;
int state, editstate;
int lastdeath, deadflush, lastspawn, lifesequence;
@@ -126,38 +87,26 @@ namespace server
int frags, flags, deaths, teamkills, shotdamage, damage, tokens;
int lasttimeplayed, timeplayed;
float effectiveness;
-
gamestate() : state(CS_DEAD), editstate(CS_DEAD), lifesequence(0) {}
-
- bool isalive(int gamemillis)
- {
+ bool isalive(int gamemillis) {
return state==CS_ALIVE || (state==CS_DEAD && gamemillis - lastdeath <= DEATHMILLIS);
}
-
- bool waitexpired(int gamemillis)
- {
+ bool waitexpired(int gamemillis) {
return gamemillis - lastshot >= gunwait;
}
-
- void reset()
- {
+ void reset() {
if(state!=CS_SPECTATOR) state = editstate = CS_DEAD;
maxhealth = 100;
maxarmour = 50;
rockets.reset();
grenades.reset();
-
timeplayed = 0;
effectiveness = 0;
frags = flags = deaths = teamkills = shotdamage = damage = tokens = 0;
-
lastdeath = 0;
-
respawn();
}
-
- void respawn()
- {
+ void respawn() {
fpsstate::respawn();
o = vec(-1e10f, -1e10f, -1e10f);
deadflush = 0;
@@ -165,25 +114,19 @@ namespace server
lastshot = 0;
tokens = 0;
}
-
- void reassign()
- {
+ void reassign() {
respawn();
rockets.reset();
grenades.reset();
}
};
-
- struct savedscore
- {
+ struct savedscore {
uint ip;
string name;
int frags, flags, deaths, teamkills, shotdamage, damage;
int timeplayed;
float effectiveness;
-
- void save(gamestate &gs)
- {
+ void save(gamestate &gs) {
frags = gs.frags;
flags = gs.flags;
deaths = gs.deaths;
@@ -193,9 +136,7 @@ namespace server
timeplayed = gs.timeplayed;
effectiveness = gs.effectiveness;
}
-
- void restore(gamestate &gs)
- {
+ void restore(gamestate &gs) {
gs.frags = frags;
gs.flags = flags;
gs.deaths = deaths;
@@ -206,11 +147,8 @@ namespace server
gs.effectiveness = effectiveness;
}
};
-
extern int gamemillis, nextexceeded;
-
- struct clientinfo
- {
+ struct clientinfo {
int clientnum, ownernum, connectmillis, sessionid, overflow;
string name, team, mapvote;
int playermodel;
@@ -236,58 +174,39 @@ namespace server
void *authchallenge;
int authkickvictim;
char *authkickreason;
-
clientinfo() : getdemo(NULL), getmap(NULL), clipboard(NULL), authchallenge(NULL), authkickreason(NULL) { reset(); }
~clientinfo() { events.deletecontents(); cleanclipboard(); cleanauth(); }
-
- void addevent(gameevent *e)
- {
+ void addevent(gameevent *e) {
if(state.state==CS_SPECTATOR || events.length()>100) delete e;
else events.add(e);
}
-
- enum
- {
+ enum {
PUSHMILLIS = 3000
};
-
- int calcpushrange()
- {
+ int calcpushrange() {
ENetPeer *peer = getclientpeer(ownernum);
return PUSHMILLIS + ((peer) ? (int) (peer->roundTripTime + peer->roundTripTimeVariance) : (int) ENET_PEER_DEFAULT_ROUND_TRIP_TIME);
}
-
- bool checkpushed(int millis, int range)
- {
+ bool checkpushed(int millis, int range) {
return millis >= pushed - range && millis <= pushed + range;
}
-
- void scheduleexceeded()
- {
+ void scheduleexceeded() {
if(state.state!=CS_ALIVE || !exceeded) return;
int range = calcpushrange();
if(!nextexceeded || exceeded + range < nextexceeded) nextexceeded = exceeded + range;
}
-
- void setexceeded()
- {
+ void setexceeded() {
if(state.state==CS_ALIVE && !exceeded && !checkpushed(gamemillis, calcpushrange())) exceeded = gamemillis;
scheduleexceeded();
}
-
- void setpushed()
- {
+ void setpushed() {
pushed = max(pushed, gamemillis);
if(exceeded && checkpushed(exceeded, calcpushrange())) exceeded = 0;
}
-
- bool checkexceeded()
- {
+ bool checkexceeded() {
return state.state==CS_ALIVE && exceeded && gamemillis > exceeded + calcpushrange();
}
-
- void mapchange()
- {
+ void mapchange() {
mapvote[0] = 0;
modevote = INT_MAX;
state.reset();
@@ -302,36 +221,26 @@ namespace server
warned = false;
gameclip = false;
}
-
- void reassign()
- {
+ void reassign() {
state.reassign();
events.deletecontents();
timesync = false;
lastevent = 0;
}
-
- void cleanclipboard(bool fullclean = true)
- {
+ void cleanclipboard(bool fullclean = true) {
if(clipboard) { if(--clipboard->referenceCount <= 0) enet_packet_destroy(clipboard); clipboard = NULL; }
if(fullclean) lastclipboard = 0;
}
-
- void cleanauthkick()
- {
+ void cleanauthkick() {
authkickvictim = -1;
DELETEA(authkickreason);
}
-
- void cleanauth(bool full = true)
- {
+ void cleanauth(bool full = true) {
authreq = 0;
if(authchallenge) { freechallenge(authchallenge); authchallenge = NULL; }
if(full) cleanauthkick();
}
-
- void reset()
- {
+ void reset() {
name[0] = team[0] = 0;
playermodel = -1;
privilege = PRIV_NONE;
@@ -346,11 +255,8 @@ namespace server
cleanauth();
mapchange();
}
-
- int geteventmillis(int servmillis, int clientmillis)
- {
- if(!timesync || (events.empty() && state.waitexpired(servmillis)))
- {
+ int geteventmillis(int servmillis, int clientmillis) {
+ if(!timesync || (events.empty() && state.waitexpired(servmillis))) {
timesync = true;
gameoffset = servmillis - clientmillis;
return servmillis;
@@ -358,15 +264,11 @@ namespace server
else return gameoffset + clientmillis;
}
};
-
- struct ban
- {
+ struct ban {
int time, expire;
uint ip;
};
-
- namespace aiman
- {
+ namespace aiman {
extern void removeai(clientinfo *ci);
extern void clearai();
extern void checkai();
@@ -378,29 +280,23 @@ namespace server
extern void addclient(clientinfo *ci);
extern void changeteam(clientinfo *ci);
}
-
#define MM_MODE 0xF
#define MM_AUTOAPPROVE 0x1000
#define MM_PRIVSERV (MM_MODE | MM_AUTOAPPROVE)
#define MM_PUBSERV ((1<<MM_OPEN) | (1<<MM_VETO))
#define MM_COOPSERV (MM_AUTOAPPROVE | MM_PUBSERV | (1<<MM_LOCKED))
-
bool notgotitems = true; // true when map has changed and waiting for clients to send item
int gamemode = 0;
int gamemillis = 0, gamelimit = 0, nextexceeded = 0, gamespeed = 100;
bool gamepaused = false, shouldstep = true;
-
string smapname = "";
int interm = 0;
enet_uint32 lastsend = 0;
int mastermode = MM_OPEN, mastermask = MM_PRIVSERV;
stream *mapdata = NULL;
-
vector<uint> allowedips;
vector<ban> bannedips;
-
- void addban(uint ip, int expire)
- {
+ void addban(uint ip, int expire) {
allowedips.removeobj(ip);
ban b;
b.time = totalmillis;
@@ -409,71 +305,49 @@ namespace server
loopv(bannedips) if(bannedips[i].expire - b.expire > 0) { bannedips.insert(i, b); return; }
bannedips.add(b);
}
-
vector<clientinfo *> connects, clients, bots;
-
- void kickclients(uint ip, clientinfo *actor = NULL, int priv = PRIV_NONE)
- {
- loopvrev(clients)
- {
+ void kickclients(clientinfo *actor = NULL, int priv = PRIV_NONE) {
+ loopvrev(clients) {
clientinfo &c = *clients[i];
if(c.state.aitype != AI_NONE || c.privilege >= PRIV_ADMIN || c.local) continue;
if(actor && ((c.privilege > priv && !actor->local) || c.clientnum == actor->clientnum)) continue;
- //~if(getclientip(c.clientnum) == ip) disconnect_client(c.clientnum, DISC_KICK);
}
}
-
- struct maprotation
- {
+ struct maprotation {
static int exclude;
int modes;
string map;
-
int calcmodemask() const { return modes&(1<<NUMGAMEMODES) ? modes & ~exclude : modes; }
bool hasmode(int mode, int offset = STARTGAMEMODE) const { return (calcmodemask() & (1 << (mode-offset))) != 0; }
-
- int findmode(int mode) const
- {
+ int findmode(int mode) const {
if(!hasmode(mode)) loopi(NUMGAMEMODES) if(hasmode(i, 0)) return i+STARTGAMEMODE;
return mode;
}
-
- bool match(int reqmode, const char *reqmap) const
- {
+ bool match(int reqmode, const char *reqmap) const {
return hasmode(reqmode) && (!map[0] || !reqmap[0] || !strcmp(map, reqmap));
}
-
- bool includes(const maprotation &rot) const
- {
+ bool includes(const maprotation &rot) const {
return rot.modes == modes ? rot.map[0] && !map[0] : (rot.modes & modes) == rot.modes;
}
};
int maprotation::exclude = 0;
vector<maprotation> maprotations;
int curmaprotation = 0;
-
VAR(lockmaprotation, 0, 0, 2);
-
- void maprotationreset()
- {
+ void maprotationreset() {
maprotations.setsize(0);
curmaprotation = 0;
maprotation::exclude = 0;
}
-
- void nextmaprotation()
- {
+ void nextmaprotation() {
curmaprotation++;
if(maprotations.inrange(curmaprotation) && maprotations[curmaprotation].modes) return;
do curmaprotation--;
while(maprotations.inrange(curmaprotation) && maprotations[curmaprotation].modes);
curmaprotation++;
}
-
- int findmaprotation(int mode, const char *map)
- {
- for(int i = max(curmaprotation, 0); i < maprotations.length(); i++)
- {
+ int findmaprotation(int mode, const char *map) {
+ for(int i = max(curmaprotation, 0); i < maprotations.length(); i++) {
maprotation &rot = maprotations[i];
if(!rot.modes) break;
if(rot.match(mode, map)) return i;
@@ -481,35 +355,28 @@ namespace server
int start;
for(start = max(curmaprotation, 0) - 1; start >= 0; start--) if(!maprotations[start].modes) break;
start++;
- for(int i = start; i < curmaprotation; i++)
- {
+ for(int i = start; i < curmaprotation; i++) {
maprotation &rot = maprotations[i];
if(!rot.modes) break;
if(rot.match(mode, map)) return i;
}
int best = -1;
- loopv(maprotations)
- {
+ loopv(maprotations) {
maprotation &rot = maprotations[i];
if(rot.match(mode, map) && (best < 0 || maprotations[best].includes(rot))) best = i;
}
return best;
}
-
- bool searchmodename(const char *haystack, const char *needle)
- {
+ bool searchmodename(const char *haystack, const char *needle) {
if(!needle[0]) return true;
- do
- {
- if(needle[0] != '.')
- {
+ do {
+ if(needle[0] != '.') {
haystack = strchr(haystack, needle[0]);
if(!haystack) break;
haystack++;
}
const char *h = haystack, *n = needle+1;
- for(; *h && *n; h++)
- {
+ for(; *h && *n; h++) {
if(*h == *n) n++;
else if(*h != ' ') break;
}
@@ -518,16 +385,12 @@ namespace server
} while(needle[0] != '.');
return false;
}
-
- int genmodemask(vector<char *> &modes)
- {
+ int genmodemask(vector<char *> &modes) {
int modemask = 0;
- loopv(modes)
- {
+ loopv(modes) {
const char *mode = modes[i];
int op = mode[0];
- switch(mode[0])
- {
+ switch(mode[0]) {
case '*':
modemask |= 1<<NUMGAMEMODES;
loopk(NUMGAMEMODES) if(m_checknot(k+STARTGAMEMODE, M_DEMO|M_EDIT|M_LOCAL)) modemask |= 1<<k;
@@ -538,8 +401,7 @@ namespace server
[[fallthrough]];
case '?':
mode++;
- loopk(NUMGAMEMODES) if(searchmodename(gamemodes[k].name, mode))
- {
+ loopk(NUMGAMEMODES) if(searchmodename(gamemodes[k].name, mode)) {
if(op == '!') modemask &= ~(1<<k);
else modemask |= 1<<k;
}
@@ -549,17 +411,14 @@ namespace server
if(isdigit(mode[0])) modenum = atoi(mode);
else loopk(NUMGAMEMODES) if(searchmodename(gamemodes[k].name, mode)) { modenum = k+STARTGAMEMODE; break; }
if(!m_valid(modenum)) continue;
- switch(op)
- {
+ switch(op) {
case '!': modemask &= ~(1 << (modenum - STARTGAMEMODE)); break;
default: modemask |= 1 << (modenum - STARTGAMEMODE); break;
}
}
return modemask;
}
-
- bool addmaprotation(int modemask, const char *map)
- {
+ bool addmaprotation(int modemask, const char *map) {
if(!map[0]) loopk(NUMGAMEMODES) if(modemask&(1<<k) && !m_check(k+STARTGAMEMODE, M_EDIT)) modemask &= ~(1<<k);
if(!modemask) return false;
if(!(modemask&(1<<NUMGAMEMODES))) maprotation::exclude |= modemask;
@@ -568,12 +427,9 @@ namespace server
copystring(rot.map, map);
return true;
}
-
- void addmaprotations(tagval *args, int numargs)
- {
+ void addmaprotations(tagval *args, int numargs) {
vector<char *> modes, maps;
- for(int i = 0; i + 1 < numargs; i += 2)
- {
+ for(int i = 0; i + 1 < numargs; i += 2) {
explodelist(args[i].getstr(), modes);
explodelist(args[i+1].getstr(), maps);
int modemask = genmodemask(modes);
@@ -582,74 +438,54 @@ namespace server
modes.deletearrays();
maps.deletearrays();
}
- if(maprotations.length() && maprotations.last().modes)
- {
+ if(maprotations.length() && maprotations.last().modes) {
maprotation &rot = maprotations.add();
rot.modes = 0;
rot.map[0] = '\0';
}
}
-
COMMAND(maprotationreset, "");
COMMANDN(maprotation, addmaprotations, "ss2V");
-
- struct demofile
- {
+ struct demofile {
string info;
uchar *data;
int len;
};
-
vector<demofile> demos;
-
bool demonextmatch = false;
stream *demotmp = NULL, *demorecord = NULL, *demoplayback = NULL;
int nextplayback = 0;
-
VAR(maxdemos, 0, 5, 25);
VAR(maxdemosize, 0, 16, 31);
VAR(restrictdemos, 0, 1, 1);
VARF(autorecorddemo, 0, 0, 1, demonextmatch = autorecorddemo!=0);
-
VAR(restrictpausegame, 0, 1, 1);
VAR(restrictgamespeed, 0, 1, 1);
-
SVAR(serverdesc, "");
SVAR(serverpass, "");
SVAR(adminpass, "");
VARF(publicserver, 0, 0, 2, {
- switch(publicserver)
- {
+ switch(publicserver) {
case 0: default: mastermask = MM_PRIVSERV; break;
case 1: mastermask = MM_PUBSERV; break;
case 2: mastermask = MM_COOPSERV; break;
}
});
SVAR(servermotd, "");
-
- struct teamkillkick
- {
+ struct teamkillkick {
int modes, limit, ban;
-
- bool match(int mode) const
- {
+ bool match(int mode) const {
return (modes&(1<<(mode-STARTGAMEMODE)))!=0;
}
-
- bool includes(const teamkillkick &tk) const
- {
+ bool includes(const teamkillkick &tk) const {
return tk.modes != modes && (tk.modes & modes) == tk.modes;
}
};
vector<teamkillkick> teamkillkicks;
-
- void teamkillkickreset()
- {
+ void teamkillkickreset() {
teamkillkicks.setsize(0);
}
-
- void addteamkillkick(char *modestr, int *limit, int *ban)
- {
+ void addteamkillkick(char *modestr, int *limit, int *ban) {
vector<char *> modes;
explodelist(modestr, modes);
teamkillkick &kick = teamkillkicks.add();
@@ -658,25 +494,19 @@ namespace server
kick.ban = *ban > 0 ? *ban*60000 : (*ban < 0 ? 0 : 30*60000);
modes.deletearrays();
}
-
COMMAND(teamkillkickreset, "");
COMMANDN(teamkillkick, addteamkillkick, "sii");
-
- struct teamkillinfo
- {
+ struct teamkillinfo {
uint ip;
int teamkills;
};
vector<teamkillinfo> teamkills;
bool shouldcheckteamkills = false;
-
- void addteamkill(clientinfo *actor, clientinfo *victim, int n)
- {
+ void addteamkill(clientinfo *actor, clientinfo *victim, int n) {
if(!m_timed || actor->state.aitype != AI_NONE || actor->local || actor->privilege || (victim && victim->state.aitype != AI_NONE)) return;
shouldcheckteamkills = true;
uint ip = getclientip(actor->clientnum);
- loopv(teamkills) if(teamkills[i].ip == ip)
- {
+ loopv(teamkills) if(teamkills[i].ip == ip) {
teamkills[i].teamkills += n;
return;
}
@@ -684,92 +514,67 @@ namespace server
tk.ip = ip;
tk.teamkills = n;
}
-
- void checkteamkills()
- {
+ void checkteamkills() {
teamkillkick *kick = NULL;
if(m_timed) loopv(teamkillkicks) if(teamkillkicks[i].match(gamemode) && (!kick || kick->includes(teamkillkicks[i])))
kick = &teamkillkicks[i];
- if(kick) loopvrev(teamkills)
- {
+ if(kick) loopvrev(teamkills) {
teamkillinfo &tk = teamkills[i];
- if(tk.teamkills >= kick->limit)
- {
+ if(tk.teamkills >= kick->limit) {
if(kick->ban > 0) addban(tk.ip, kick->ban);
- kickclients(tk.ip);
+ kickclients();
teamkills.removeunordered(i);
}
}
shouldcheckteamkills = false;
}
-
void *newclientinfo() { return new clientinfo; }
void deleteclientinfo(void *ci) { delete (clientinfo *)ci; }
-
- clientinfo *getinfo(int n)
- {
+ clientinfo *getinfo(int n) {
if(n < MAXCLIENTS) return (clientinfo *)getclientinfo(n);
n -= MAXCLIENTS;
return bots.inrange(n) ? bots[n] : NULL;
}
-
uint mcrc = 0;
vector<entity> ments;
vector<server_entity> sents;
vector<savedscore> scores;
-
- int msgsizelookup(int msg)
- {
+ int msgsizelookup(int msg) {
static int sizetable[NUMMSG] = { -1 };
- if(sizetable[0] < 0)
- {
+ if(sizetable[0] < 0) {
memset(sizetable, -1, sizeof(sizetable));
for(const int *p = msgsizes; *p >= 0; p += 2) sizetable[p[0]] = p[1];
}
return msg >= 0 && msg < NUMMSG ? sizetable[msg] : -1;
}
-
- const char *modename(int n, const char *unknown)
- {
+ const char *modename(int n, const char *unknown) {
if(m_valid(n)) return gamemodes[n - STARTGAMEMODE].name;
return unknown;
}
-
- const char *mastermodename(int n, const char *unknown)
- {
+ const char *mastermodename(int n, const char *unknown) {
return (n>=MM_START && size_t(n-MM_START)<sizeof(mastermodenames)/sizeof(mastermodenames[0])) ? mastermodenames[n-MM_START] : unknown;
}
-
- const char *privname(int type)
- {
- switch(type)
- {
+ const char *privname(int type) {
+ switch(type) {
case PRIV_ADMIN: return "admin";
case PRIV_AUTH: return "auth";
case PRIV_MASTER: return "master";
default: return "unknown";
}
}
-
void sendservmsg(const char *s) { sendf(-1, 1, "ris", N_SERVMSG, s); }
- void sendservmsgf(const char *fmt, ...)
- {
+ void sendservmsgf(const char *fmt, ...) {
defvformatstring(s, fmt, fmt);
sendf(-1, 1, "ris", N_SERVMSG, s);
}
-
- void resetitems()
- {
+ void resetitems() {
mcrc = 0;
ments.setsize(0);
sents.setsize(0);
//cps.reset();
}
-
- bool serveroption(const char *arg)
- {
- if(arg[0]=='-') switch(arg[1])
- {
+ bool serveroption(const char *arg) {
+ if(arg[0]=='-') switch(arg[1]) {
case 'n': setsvar("serverdesc", &arg[2]); return true;
case 'y': setsvar("serverpass", &arg[2]); return true;
case 'p': setsvar("adminpass", &arg[2]); return true;
@@ -777,33 +582,24 @@ namespace server
}
return false;
}
-
- void serverinit()
- {
+ void serverinit() {
smapname[0] = '\0';
resetitems();
}
-
- int numclients(int exclude = -1, bool nospec = true, bool noai = true, bool priv = false)
- {
+ int numclients(int exclude = -1, bool nospec = true, bool noai = true, bool priv = false) {
int n = 0;
- loopv(clients)
- {
+ loopv(clients) {
clientinfo *ci = clients[i];
if(ci->clientnum!=exclude && (!nospec || ci->state.state!=CS_SPECTATOR || (priv && (ci->privilege || ci->local))) && (!noai || ci->state.aitype == AI_NONE)) n++;
}
return n;
}
-
- bool duplicatename(clientinfo *ci, const char *name)
- {
+ bool duplicatename(clientinfo *ci, const char *name) {
if(!name) name = ci->name;
loopv(clients) if(clients[i]!=ci && !strcmp(name, clients[i]->name)) return true;
return false;
}
-
- const char *colorname(clientinfo *ci, const char *name = NULL)
- {
+ const char *colorname(clientinfo *ci, const char *name = NULL) {
if(!name) name = ci->name;
if(name[0] && !duplicatename(ci, name) && ci->state.aitype == AI_NONE) return name;
static string cname[3];
@@ -812,16 +608,12 @@ namespace server
formatstring(cname[cidx], ci->state.aitype == AI_NONE ? "%s \fs\f5(%d)\fr" : "%s \fs\f5[%d]\fr", name, ci->clientnum);
return cname[cidx];
}
-
bool canspawnitem(int type) { return !m_noitems && (type>=I_SHELLS && type<=I_QUAD && (!m_noammo || type<I_SHELLS || type>I_CARTRIDGES)); }
-
- int spawntime(int type)
- {
+ int spawntime(int type) {
int np = numclients(-1, true, false);
np = np<3 ? 4 : (np>4 ? 2 : 3); // spawn times are dependent on number of players
int sec = 0;
- switch(type)
- {
+ switch(type) {
case I_SHELLS:
case I_BULLETS:
case I_ROCKETS:
@@ -838,11 +630,8 @@ namespace server
}
return sec*1000;
}
-
- bool delayspawn(int type)
- {
- switch(type)
- {
+ bool delayspawn(int type) {
+ switch(type) {
case I_GREENARMOUR:
case I_YELLOWARMOUR:
case I_BOOST:
@@ -852,14 +641,11 @@ namespace server
return false;
}
}
-
- bool pickup(int i, int sender) // server side item pickup, acknowledge first client that gets it
- {
+ bool pickup(int i, int sender) { // server side item pickup, acknowledge first client that gets it {
if((m_timed && gamemillis>=gamelimit) || !sents.inrange(i) || !sents[i].spawned) return false;
clientinfo *ci = getinfo(sender);
if(!ci) return false;
- if(!ci->local && !ci->state.canpickup(sents[i].type))
- {
+ if(!ci->local && !ci->state.canpickup(sents[i].type)) {
sendf(sender, 1, "ri3", N_ITEMACC, i, -1);
return false;
}
@@ -869,30 +655,21 @@ namespace server
ci->state.pickup(sents[i].type);
return true;
}
-
static hashset<teaminfo> teaminfos;
-
- void clearteaminfo()
- {
+ void clearteaminfo() {
teaminfos.clear();
}
-
bool teamhasplayers(const char *team) { loopv(clients) if(!strcmp(clients[i]->team, team)) return true; return false; }
-
- bool pruneteaminfo()
- {
+ bool pruneteaminfo() {
int oldteams = teaminfos.numelems;
enumerate(teaminfos, teaminfo, old,
if(!old.frags && !teamhasplayers(old.team)) teaminfos.remove(old.team);
);
return teaminfos.numelems < oldteams;
}
-
- teaminfo *addteaminfo(const char *team)
- {
+ teaminfo *addteaminfo(const char *team) {
teaminfo *t = teaminfos.access(team);
- if(!t)
- {
+ if(!t) {
if(teaminfos.numelems >= MAXTEAMS && !pruneteaminfo()) return NULL;
t = &teaminfos[team];
copystring(t->team, team, sizeof(t->team));
@@ -900,13 +677,10 @@ namespace server
}
return t;
}
-
- clientinfo *choosebestclient(float &bestrank)
- {
+ clientinfo *choosebestclient(float &bestrank) {
clientinfo *best = NULL;
bestrank = -1;
- loopv(clients)
- {
+ loopv(clients) {
clientinfo *ci = clients[i];
if(ci->state.timeplayed<0) continue;
float rank = ci->state.state!=CS_SPECTATOR ? ci->state.effectiveness/max(ci->state.timeplayed, 1) : -1;
@@ -914,19 +688,14 @@ namespace server
}
return best;
}
-
VAR(persistteams, 0, 0, 1);
-
- void autoteam()
- {
+ void autoteam() {
static const char * const teamnames[2] = {"good", "evil"};
vector<clientinfo *> team[2];
float teamrank[2] = {0, 0};
- for(int round = 0, remaining = clients.length(); remaining>=0; round++)
- {
+ for(int round = 0, remaining = clients.length(); remaining>=0; round++) {
int first = round&1, second = (round+1)&1, selected = 0;
- while(teamrank[first] <= teamrank[second])
- {
+ while(teamrank[first] <= teamrank[second]) {
float rank;
clientinfo *ci = choosebestclient(rank);
if(!ci) break;
@@ -940,15 +709,12 @@ namespace server
if(!selected) break;
remaining -= selected;
}
- loopi(sizeof(team)/sizeof(team[0]))
- {
+ loopi(sizeof(team)/sizeof(team[0])) {
addteaminfo(teamnames[i]);
- loopvj(team[i])
- {
+ loopvj(team[i]) {
clientinfo *ci = team[i][j];
if(!strcmp(ci->team, teamnames[i])) continue;
- if(persistteams && ci->team[0])
- {
+ if(persistteams && ci->team[0]) {
addteaminfo(ci->team);
continue;
}
@@ -957,29 +723,21 @@ namespace server
}
}
}
-
- struct teamrank
- {
+ struct teamrank {
const char *name;
float rank;
int clients;
-
teamrank(const char *name) : name(name), rank(0), clients(0) {}
};
-
- const char *chooseworstteam(const char *suggest = NULL, clientinfo *exclude = NULL)
- {
+ const char *chooseworstteam(clientinfo *exclude = NULL) {
teamrank teamranks[2] = { teamrank("good"), teamrank("evil") };
const int numteams = sizeof(teamranks)/sizeof(teamranks[0]);
- loopv(clients)
- {
+ loopv(clients) {
clientinfo *ci = clients[i];
if(ci==exclude || ci->state.aitype!=AI_NONE || ci->state.state==CS_SPECTATOR || !ci->team[0]) continue;
ci->state.timeplayed += lastmillis - ci->state.lasttimeplayed;
ci->state.lasttimeplayed = lastmillis;
-
- loopj(numteams) if(!strcmp(ci->team, teamranks[j].name))
- {
+ loopj(numteams) if(!strcmp(ci->team, teamranks[j].name)) {
teamrank &ts = teamranks[j];
ts.rank += ci->state.effectiveness/max(ci->state.timeplayed, 1);
ts.clients++;
@@ -987,24 +745,19 @@ namespace server
}
}
teamrank *worst = &teamranks[numteams-1];
- loopi(numteams-1)
- {
+ loopi(numteams-1) {
teamrank &ts = teamranks[i];
if(ts.rank < worst->rank || (ts.rank == worst->rank && ts.clients < worst->clients)) worst = &ts;
}
return worst->name;
}
-
- void prunedemos(int extra = 0)
- {
+ void prunedemos(int extra = 0) {
int n = clamp(demos.length() + extra - maxdemos, 0, demos.length());
if(n <= 0) return;
loopi(n) delete[] demos[i].data;
demos.remove(0, n);
}
-
- void adddemo()
- {
+ void adddemo() {
if(!demotmp) return;
int len = (int)min(demotmp->size(), stream::offset((maxdemosize<<20) + 0x10000));
demofile &d = demos.add();
@@ -1019,22 +772,15 @@ namespace server
demotmp->read(d.data, len);
DELETEP(demotmp);
}
-
- void enddemorecord()
- {
+ void enddemorecord() {
if(!demorecord) return;
-
DELETEP(demorecord);
-
if(!demotmp) return;
if(!maxdemos || !maxdemosize) { DELETEP(demotmp); return; }
-
prunedemos(1);
adddemo();
}
-
- void writedemo(int chan, void *data, int len)
- {
+ void writedemo(int chan, void *data, int len) {
if(!demorecord) return;
int stamp[3] = { gamemillis, chan, len };
lilswap(stamp, 3);
@@ -1042,86 +788,61 @@ namespace server
demorecord->write(data, len);
if(demorecord->rawtell() >= (maxdemosize<<20)) enddemorecord();
}
-
- void recordpacket(int chan, void *data, int len)
- {
+ void recordpacket(int chan, void *data, int len) {
writedemo(chan, data, len);
}
-
int welcomepacket(packetbuf &p, clientinfo *ci);
void sendwelcome(clientinfo *ci);
-
- void setupdemorecord()
- {
+ void setupdemorecord() {
if(!m_mp(gamemode) || m_edit) return;
-
demotmp = opentempfile("demorecord", "w+b");
if(!demotmp) return;
-
stream *f = opengzfile(NULL, "wb", demotmp);
if(!f) { DELETEP(demotmp); return; }
-
sendservmsg("recording demo");
-
demorecord = f;
-
demoheader hdr;
memcpy(hdr.magic, DEMO_MAGIC, sizeof(hdr.magic));
hdr.version = DEMO_VERSION;
hdr.protocol = PROTOCOL_VERSION;
lilswap(&hdr.version, 2);
demorecord->write(&hdr, sizeof(demoheader));
-
packetbuf p(MAXTRANS, ENET_PACKET_FLAG_RELIABLE);
welcomepacket(p, NULL);
writedemo(1, p.buf, p.len);
}
-
- void listdemos(int cn)
- {
+ void listdemos(int cn) {
packetbuf p(MAXTRANS, ENET_PACKET_FLAG_RELIABLE);
putint(p, N_SENDDEMOLIST);
putint(p, demos.length());
loopv(demos) sendstring(demos[i].info, p);
sendpacket(cn, 1, p.finalize());
}
-
- void cleardemos(int n)
- {
- if(!n)
- {
+ void cleardemos(int n) {
+ if(!n) {
loopv(demos) delete[] demos[i].data;
demos.shrink(0);
sendservmsg("cleared all demos");
}
- else if(demos.inrange(n-1))
- {
+ else if(demos.inrange(n-1)) {
delete[] demos[n-1].data;
demos.remove(n-1);
sendservmsgf("cleared demo %d", n);
}
}
-
- static void freegetmap(ENetPacket *packet)
- {
- loopv(clients)
- {
+ static void freegetmap(ENetPacket *packet) {
+ loopv(clients) {
clientinfo *ci = clients[i];
if(ci->getmap == packet) ci->getmap = NULL;
}
}
-
- static void freegetdemo(ENetPacket *packet)
- {
- loopv(clients)
- {
+ static void freegetdemo(ENetPacket *packet) {
+ loopv(clients) {
clientinfo *ci = clients[i];
if(ci->getdemo == packet) ci->getdemo = NULL;
}
}
-
- void senddemo(clientinfo *ci, int num, int tag)
- {
+ void senddemo(clientinfo *ci, int num, int tag) {
if(ci->getdemo) return;
if(!num) num = demos.length();
if(!demos.inrange(num-1)) return;
@@ -1129,39 +850,28 @@ namespace server
if((ci->getdemo = sendf(ci->clientnum, 2, "riim", N_SENDDEMO, tag, d.len, d.data)))
ci->getdemo->freeCallback = freegetdemo;
}
-
- void enddemoplayback()
- {
+ void enddemoplayback() {
if(!demoplayback) return;
DELETEP(demoplayback);
-
loopv(clients) sendf(clients[i]->clientnum, 1, "ri3", N_DEMOPLAYBACK, 0, clients[i]->clientnum);
-
sendservmsg("demo playback finished");
-
loopv(clients) sendwelcome(clients[i]);
}
-
SVARP(demodir, "demo");
-
- const char *getdemofile(const char *file, bool init)
- {
+ const char *getdemofile(const char *file, bool init) {
if(!demodir[0]) return NULL;
static string buf;
copystring(buf, demodir);
int dirlen = strlen(buf);
if(buf[dirlen] != '/' && buf[dirlen] != '\\' && dirlen+1 < (int)sizeof(buf)) { buf[dirlen++] = '/'; buf[dirlen] = '\0'; }
- if(init)
- {
+ if(init) {
const char *dir = findfile(buf, "w");
if(!fileexists(dir, "w")) createdir(dir);
}
concatstring(buf, file);
return buf;
}
-
- void setupdemoplayback()
- {
+ void setupdemoplayback() {
if(demoplayback) return;
demoheader hdr;
string msg;
@@ -1175,48 +885,37 @@ namespace server
if(!demoplayback) formatstring(msg, "could not read demo \"%s\"", file);
else if(demoplayback->read(&hdr, sizeof(demoheader))!=sizeof(demoheader) || memcmp(hdr.magic, DEMO_MAGIC, sizeof(hdr.magic)))
formatstring(msg, "\"%s\" is not a demo file", file);
- else
- {
+ else {
lilswap(&hdr.version, 2);
if(hdr.version!=DEMO_VERSION) formatstring(msg, "demo \"%s\" requires an %s version of Cube 2: Sauerbraten", file, hdr.version<DEMO_VERSION ? "older" : "newer");
else if(hdr.protocol!=PROTOCOL_VERSION) formatstring(msg, "demo \"%s\" requires an %s version of Cube 2: Sauerbraten", file, hdr.protocol<PROTOCOL_VERSION ? "older" : "newer");
}
- if(msg[0])
- {
+ if(msg[0]) {
DELETEP(demoplayback);
sendservmsg(msg);
return;
}
-
sendservmsgf("playing demo \"%s\"", file);
-
sendf(-1, 1, "ri3", N_DEMOPLAYBACK, 1, -1);
-
- if(demoplayback->read(&nextplayback, sizeof(nextplayback))!=sizeof(nextplayback))
- {
+ if(demoplayback->read(&nextplayback, sizeof(nextplayback))!=sizeof(nextplayback)) {
enddemoplayback();
return;
}
lilswap(&nextplayback, 1);
}
-
- void readdemo()
- {
+ void readdemo() {
if(!demoplayback) return;
- while(gamemillis>=nextplayback)
- {
+ while(gamemillis>=nextplayback) {
int chan, len;
if(demoplayback->read(&chan, sizeof(chan))!=sizeof(chan) ||
- demoplayback->read(&len, sizeof(len))!=sizeof(len))
- {
+ demoplayback->read(&len, sizeof(len))!=sizeof(len)) {
enddemoplayback();
return;
}
lilswap(&chan, 1);
lilswap(&len, 1);
ENetPacket *packet = enet_packet_create(NULL, len+1, 0);
- if(!packet || demoplayback->read(packet->data+1, len)!=size_t(len))
- {
+ if(!packet || demoplayback->read(packet->data+1, len)!=size_t(len)) {
if(packet) enet_packet_destroy(packet);
enddemoplayback();
return;
@@ -1225,24 +924,19 @@ namespace server
sendpacket(-1, chan, packet);
if(!packet->referenceCount) enet_packet_destroy(packet);
if(!demoplayback) break;
- if(demoplayback->read(&nextplayback, sizeof(nextplayback))!=sizeof(nextplayback))
- {
+ if(demoplayback->read(&nextplayback, sizeof(nextplayback))!=sizeof(nextplayback)) {
enddemoplayback();
return;
}
lilswap(&nextplayback, 1);
}
}
-
- void timeupdate(int secs)
- {
+ void timeupdate(int secs) {
if(!demoplayback) return;
if(secs <= 0) interm = -1;
else gamelimit = max(gamelimit, nextplayback + secs*1000);
}
-
- void seekdemo(char *t)
- {
+ void seekdemo(char *t) {
if(!demoplayback) return;
bool rev = *t == '-';
if(rev) t++;
@@ -1251,170 +945,123 @@ namespace server
else { secs = mins; mins = 0; }
if(*t == '.') millis = strtoul(t+1, &t, 10);
int offset = max(millis + (mins*60 + secs)*1000, 0), prevmillis = gamemillis;
- if(rev) while(gamelimit - offset > gamemillis)
- {
+ if(rev) while(gamelimit - offset > gamemillis) {
gamemillis = gamelimit - offset;
readdemo();
}
- else if(offset > gamemillis)
- {
+ else if(offset > gamemillis) {
gamemillis = offset;
readdemo();
}
- if(gamemillis > prevmillis)
- {
+ if(gamemillis > prevmillis) {
if(!interm) sendf(-1, 1, "ri2", N_TIMEUP, max((gamelimit - gamemillis)/1000, 1));
}
}
-
- ICOMMAND(seekdemo, "sN$", (char *t, int *numargs, ident *id),
- {
+ ICOMMAND(seekdemo, "sN$", (char *t, int *numargs, ident *id), {
if(*numargs > 0) seekdemo(t);
- else
- {
+ else {
int secs = gamemillis/1000;
defformatstring(str, "%d:%02d.%03d", secs/60, secs%60, gamemillis%1000);
if(*numargs < 0) result(str);
else printsvar(id, str);
}
});
-
- void stopdemo()
- {
+ void stopdemo() {
if(m_demo) enddemoplayback();
else enddemorecord();
}
-
- void pausegame(bool val, clientinfo *ci = NULL)
- {
+ void pausegame(bool val, clientinfo *ci = NULL) {
if(gamepaused==val) return;
gamepaused = val;
sendf(-1, 1, "riii", N_PAUSEGAME, gamepaused ? 1 : 0, ci ? ci->clientnum : -1);
}
-
- void checkpausegame()
- {
+ void checkpausegame() {
if(!gamepaused) return;
int admins = 0;
loopv(clients) if(clients[i]->privilege >= (restrictpausegame ? PRIV_ADMIN : PRIV_MASTER) || clients[i]->local) admins++;
if(!admins) pausegame(false);
}
-
- void forcepaused(bool paused)
- {
+ void forcepaused(bool paused) {
pausegame(paused);
}
-
bool ispaused() { return gamepaused; }
-
- void changegamespeed(int val, clientinfo *ci = NULL)
- {
+ void changegamespeed(int val, clientinfo *ci = NULL) {
val = clamp(val, 10, 1000);
if(gamespeed==val) return;
gamespeed = val;
sendf(-1, 1, "riii", N_GAMESPEED, gamespeed, ci ? ci->clientnum : -1);
}
-
- void forcegamespeed(int speed)
- {
+ void forcegamespeed(int speed) {
changegamespeed(speed);
}
-
int scaletime(int t) { return t*gamespeed; }
-
SVAR(serverauth, "");
-
- struct userkey
- {
+ struct userkey {
char *name;
char *desc;
-
userkey() : name(NULL), desc(NULL) {}
userkey(char *name, char *desc) : name(name), desc(desc) {}
};
-
static inline uint hthash(const userkey &k) { return ::hthash(k.name); }
static inline bool htcmp(const userkey &x, const userkey &y) { return !strcmp(x.name, y.name) && !strcmp(x.desc, y.desc); }
-
- struct userinfo : userkey
- {
+ struct userinfo : userkey {
void *pubkey;
int privilege;
-
userinfo() : pubkey(NULL), privilege(PRIV_NONE) {}
~userinfo() { delete[] name; delete[] desc; if(pubkey) freepubkey(pubkey); }
};
hashset<userinfo> users;
-
- void adduser(char *name, char *desc, char *pubkey, char *priv)
- {
+ void adduser(char *name, char *desc, char *pubkey, char *priv) {
userkey key(name, desc);
userinfo &u = users[key];
if(u.pubkey) { freepubkey(u.pubkey); u.pubkey = NULL; }
if(!u.name) u.name = newstring(name);
if(!u.desc) u.desc = newstring(desc);
u.pubkey = parsepubkey(pubkey);
- switch(priv[0])
- {
+ switch(priv[0]) {
case 'a': case 'A': u.privilege = PRIV_ADMIN; break;
case 'm': case 'M': default: u.privilege = PRIV_AUTH; break;
case 'n': case 'N': u.privilege = PRIV_NONE; break;
}
}
COMMAND(adduser, "ssss");
-
- void clearusers()
- {
+ void clearusers() {
users.clear();
}
COMMAND(clearusers, "");
-
- void hashpassword(int cn, int sessionid, const char *pwd, char *result, int maxlen)
- {
+ void hashpassword(int cn, int sessionid, const char *pwd, char *result, int maxlen) {
char buf[2*sizeof(string)];
formatstring(buf, "%d %d ", cn, sessionid);
concatstring(buf, pwd, sizeof(buf));
if(!hashstring(buf, result, maxlen)) *result = '\0';
}
-
- bool checkpassword(clientinfo *ci, const char *wanted, const char *given)
- {
+ bool checkpassword(clientinfo *ci, const char *wanted, const char *given) {
string hash;
hashpassword(ci->clientnum, ci->sessionid, wanted, hash, sizeof(hash));
return !strcmp(hash, given);
}
-
- void revokemaster(clientinfo *ci)
- {
+ void revokemaster(clientinfo *ci) {
ci->privilege = PRIV_NONE;
if(ci->state.state==CS_SPECTATOR && !ci->local) aiman::removeai(ci);
}
-
extern void connected(clientinfo *ci);
-
- bool setmaster(clientinfo *ci, bool val, const char *pass = "", const char *authname = NULL, const char *authdesc = NULL, int authpriv = PRIV_MASTER, bool force = false, bool trial = false)
- {
+ bool setmaster(clientinfo *ci, bool val, const char *pass = "", const char *authname = NULL, const char *authdesc = NULL, int authpriv = PRIV_MASTER, bool force = false, bool trial = false) {
if(authname && !val) return false;
const char *name = "";
- if(val)
- {
+ if(val) {
bool haspass = adminpass[0] && checkpassword(ci, adminpass, pass);
int wantpriv = ci->local || haspass ? PRIV_ADMIN : authpriv;
if(wantpriv <= ci->privilege) return true;
- else if(wantpriv <= PRIV_MASTER && !force)
- {
- if(ci->state.state==CS_SPECTATOR)
- {
+ else if(wantpriv <= PRIV_MASTER && !force) {
+ if(ci->state.state==CS_SPECTATOR) {
sendf(ci->clientnum, 1, "ris", N_SERVMSG, "Spectators may not claim master.");
return false;
}
- loopv(clients) if(ci!=clients[i] && clients[i]->privilege)
- {
+ loopv(clients) if(ci!=clients[i] && clients[i]->privilege) {
sendf(ci->clientnum, 1, "ris", N_SERVMSG, "Master is already claimed.");
return false;
}
- if(!authname && !(mastermask&MM_AUTOAPPROVE) && !ci->privilege && !ci->local)
- {
+ if(!authname && !(mastermask&MM_AUTOAPPROVE) && !ci->privilege && !ci->local) {
sendf(ci->clientnum, 1, "ris", N_SERVMSG, "This server requires you to use the \"/auth\" command to claim master.");
return false;
}
@@ -1423,8 +1070,7 @@ namespace server
ci->privilege = wantpriv;
name = privname(ci->privilege);
}
- else
- {
+ else {
if(!ci->privilege) return false;
if(trial) return true;
name = privname(ci->privilege);
@@ -1432,14 +1078,12 @@ namespace server
}
bool hasmaster = false;
loopv(clients) if(clients[i]->local || clients[i]->privilege >= PRIV_MASTER) hasmaster = true;
- if(!hasmaster)
- {
+ if(!hasmaster) {
mastermode = MM_OPEN;
allowedips.shrink(0);
}
string msg;
- if(val && authname)
- {
+ if(val && authname) {
if(authdesc && authdesc[0]) formatstring(msg, "%s claimed %s as '\fs\f5%s\fr' [\fs\f0%s\fr]", colorname(ci), name, authname, authdesc);
else formatstring(msg, "%s claimed %s as '\fs\f5%s\fr'", colorname(ci), name, authname);
}
@@ -1449,8 +1093,7 @@ namespace server
sendstring(msg, p);
putint(p, N_CURRENTMASTER);
putint(p, mastermode);
- loopv(clients) if(clients[i]->privilege >= PRIV_MASTER)
- {
+ loopv(clients) if(clients[i]->privilege >= PRIV_MASTER) {
putint(p, clients[i]->clientnum);
putint(p, clients[i]->privilege);
}
@@ -1459,24 +1102,18 @@ namespace server
checkpausegame();
return true;
}
-
- bool trykick(clientinfo *ci, int victim, const char *reason = NULL, const char *authname = NULL, const char *authdesc = NULL, int authpriv = PRIV_NONE, bool trial = false)
- {
+ bool trykick(clientinfo *ci, int victim, const char *reason = NULL, const char *authname = NULL, const char *authdesc = NULL, int authpriv = PRIV_NONE, bool trial = false) {
int priv = ci->privilege;
- if(authname)
- {
+ if(authname) {
if(priv >= authpriv || ci->local) authname = authdesc = NULL;
else priv = authpriv;
}
- if((priv || ci->local) && ci->clientnum!=victim)
- {
+ if((priv || ci->local) && ci->clientnum!=victim) {
clientinfo *vinfo = (clientinfo *)getclientinfo(victim);
- if(vinfo && vinfo->connected && (priv >= vinfo->privilege || ci->local) && vinfo->privilege < PRIV_ADMIN && !vinfo->local)
- {
+ if(vinfo && vinfo->connected && (priv >= vinfo->privilege || ci->local) && vinfo->privilege < PRIV_ADMIN && !vinfo->local) {
if(trial) return true;
string kicker;
- if(authname)
- {
+ if(authname) {
if(authdesc && authdesc[0]) formatstring(kicker, "%s as '\fs\f5%s\fr' [\fs\f0%s\fr]", colorname(ci), authname, authdesc);
else formatstring(kicker, "%s as '\fs\f5%s\fr'", colorname(ci), authname);
}
@@ -1485,23 +1122,18 @@ namespace server
else sendservmsgf("%s kicked %s", kicker, colorname(vinfo));
uint ip = getclientip(victim);
addban(ip, 4*60*60000);
- kickclients(ip, ci, priv);
+ kickclients(ci, priv);
}
}
return false;
}
-
- savedscore *findscore(clientinfo *ci, bool insert)
- {
+ savedscore *findscore(clientinfo *ci, bool insert) {
uint ip = getclientip(ci->clientnum);
if(!ip && !ci->local) return 0;
- if(!insert)
- {
- loopv(clients)
- {
+ if(!insert) {
+ loopv(clients) {
clientinfo *oi = clients[i];
- if(oi->clientnum != ci->clientnum && getclientip(oi->clientnum) == ip && !strcmp(oi->name, ci->name))
- {
+ if(oi->clientnum != ci->clientnum && getclientip(oi->clientnum) == ip && !strcmp(oi->name, ci->name)) {
oi->state.timeplayed += lastmillis - oi->state.lasttimeplayed;
oi->state.lasttimeplayed = lastmillis;
static savedscore curscore;
@@ -1510,8 +1142,7 @@ namespace server
}
}
}
- loopv(scores)
- {
+ loopv(scores) {
savedscore &sc = scores[i];
if(sc.ip == ip && !strcmp(sc.name, ci->name)) return &sc;
}
@@ -1521,30 +1152,22 @@ namespace server
copystring(sc.name, ci->name);
return &sc;
}
-
- void savescore(clientinfo *ci)
- {
+ void savescore(clientinfo *ci) {
savedscore *sc = findscore(ci, true);
if(sc) sc->save(ci->state);
}
-
- static struct msgfilter
- {
+ static struct msgfilter {
uchar msgmask[NUMMSG];
-
- msgfilter(int msg, ...)
- {
+ msgfilter(int msg, ...) {
memset(msgmask, 0, sizeof(msgmask));
va_list msgs;
va_start(msgs, msg);
- for(uchar val = 1; msg < NUMMSG; msg = va_arg(msgs, int))
- {
+ for(uchar val = 1; msg < NUMMSG; msg = va_arg(msgs, int)) {
if(msg < 0) val = uchar(-msg);
else msgmask[msg] = val;
}
va_end(msgs);
}
-
uchar operator[](int msg) const { return msg >= 0 && msg < NUMMSG ? msgmask[msg] : 0; }
} msgfilter(-1, N_CONNECT, N_SERVINFO, N_INITCLIENT, N_WELCOME, N_MAPCHANGE, N_SERVMSG, N_DAMAGE, N_HITPUSH, N_SHOTFX, N_EXPLODEFX, N_DIED,
N_SPAWNSTATE, N_FORCEDEATH, N_TEAMINFO, N_ITEMACC, N_ITEMSPAWN, N_TIMEUP, N_CDIS, N_CURRENTMASTER, N_PONG, N_RESUME,
@@ -1553,13 +1176,9 @@ namespace server
N_NEWMAP, N_GETMAP, N_SENDMAP, N_CLIPBOARD, -3, N_EDITENT, N_EDITF, N_EDITT, N_EDITM, N_FLIP, N_COPY, N_PASTE, N_ROTATE, N_REPLACE,
N_DELCUBE, N_EDITVAR, N_EDITVSLOT, N_UNDO, N_REDO, -4, N_POS, NUMMSG),
connectfilter(-1, N_CONNECT, -2, N_AUTHANS, -3, N_PING, NUMMSG);
-
- int checktype(int type, clientinfo *ci)
- {
- if(ci)
- {
- if(!ci->connected) switch(connectfilter[type])
- {
+ int checktype(int type, clientinfo *ci) {
+ if(ci) {
+ if(!ci->connected) switch(connectfilter[type]) {
// allow only before authconnect
case 1: return !ci->connectauth ? type : -1;
// allow only during authconnect
@@ -1571,8 +1190,7 @@ namespace server
}
if(ci->local) return type;
}
- switch(msgfilter[type])
- {
+ switch(msgfilter[type]) {
// server-only messages
case 1: return ci ? -1 : type;
// only allowed in coop-edit
@@ -1585,54 +1203,41 @@ namespace server
if(ci && ++ci->overflow >= 200) return -2;
return type;
}
-
- struct worldstate
- {
+ struct worldstate {
int uses, len;
uchar *data;
-
worldstate() : uses(0), len(0), data(NULL) {}
-
void setup(int n) { len = n; data = new uchar[n]; }
void cleanup() { DELETEA(data); len = 0; }
bool contains(const uchar *p) const { return p >= data && p < &data[len]; }
};
vector<worldstate> worldstates;
bool reliablemessages = false;
-
- void cleanworldstate(ENetPacket *packet)
- {
- loopv(worldstates)
- {
+ void cleanworldstate(ENetPacket *packet) {
+ loopv(worldstates) {
worldstate &ws = worldstates[i];
if(!ws.contains(packet->data)) continue;
ws.uses--;
- if(ws.uses <= 0)
- {
+ if(ws.uses <= 0) {
ws.cleanup();
worldstates.removeunordered(i);
}
break;
}
}
-
- void flushclientposition(clientinfo &ci)
- {
+ void flushclientposition(clientinfo &ci) {
if(ci.position.empty() || (!hasnonlocalclients() && !demorecord)) return;
packetbuf p(ci.position.length(), 0);
p.put(ci.position.getbuf(), ci.position.length());
ci.position.setsize(0);
sendpacket(-1, 0, p.finalize(), ci.ownernum);
}
-
- static void sendpositions(worldstate &ws, ucharbuf &wsbuf)
- {
+ static void sendpositions(worldstate &ws, ucharbuf &wsbuf) {
if(wsbuf.empty()) return;
int wslen = wsbuf.length();
recordpacket(0, wsbuf.buf, wslen);
wsbuf.put(wsbuf.buf, wslen);
- loopv(clients)
- {
+ loopv(clients) {
clientinfo &ci = *clients[i];
if(ci.state.aitype != AI_NONE) continue;
uchar *data = wsbuf.buf;
@@ -1646,9 +1251,7 @@ namespace server
}
wsbuf.offset(wsbuf.length());
}
-
- static inline void addposition(worldstate &ws, ucharbuf &wsbuf, int mtu, clientinfo &bi, clientinfo &ci)
- {
+ static inline void addposition(worldstate &ws, ucharbuf &wsbuf, int mtu, clientinfo &bi, clientinfo &ci) {
if(bi.position.empty()) return;
if(wsbuf.length() + bi.position.length() > mtu) sendpositions(ws, wsbuf);
int offset = wsbuf.length();
@@ -1658,15 +1261,12 @@ namespace server
if(ci.wsdata < wsbuf.buf) { ci.wsdata = &wsbuf.buf[offset]; ci.wslen = len; }
else ci.wslen += len;
}
-
- static void sendmessages(worldstate &ws, ucharbuf &wsbuf)
- {
+ static void sendmessages(worldstate &ws, ucharbuf &wsbuf) {
if(wsbuf.empty()) return;
int wslen = wsbuf.length();
recordpacket(1, wsbuf.buf, wslen);
wsbuf.put(wsbuf.buf, wslen);
- loopv(clients)
- {
+ loopv(clients) {
clientinfo &ci = *clients[i];
if(ci.state.aitype != AI_NONE) continue;
uchar *data = wsbuf.buf;
@@ -1680,9 +1280,7 @@ namespace server
}
wsbuf.offset(wsbuf.length());
}
-
- static inline void addmessages(worldstate &ws, ucharbuf &wsbuf, int mtu, clientinfo &bi, clientinfo &ci)
- {
+ static inline void addmessages(worldstate &ws, ucharbuf &wsbuf, int mtu, clientinfo &bi, clientinfo &ci) {
if(bi.messages.empty()) return;
if(wsbuf.length() + 10 + bi.messages.length() > mtu) sendmessages(ws, wsbuf);
int offset = wsbuf.length();
@@ -1695,20 +1293,16 @@ namespace server
if(ci.wsdata < wsbuf.buf) { ci.wsdata = &wsbuf.buf[offset]; ci.wslen = len; }
else ci.wslen += len;
}
-
- bool buildworldstate()
- {
+ bool buildworldstate() {
int wsmax = 0;
- loopv(clients)
- {
+ loopv(clients) {
clientinfo &ci = *clients[i];
ci.overflow = 0;
ci.wsdata = NULL;
wsmax += ci.position.length();
if(ci.messages.length()) wsmax += 10 + ci.messages.length();
}
- if(wsmax <= 0)
- {
+ if(wsmax <= 0) {
reliablemessages = false;
return false;
}
@@ -1717,16 +1311,14 @@ namespace server
int mtu = getservermtu() - 100;
if(mtu <= 0) mtu = ws.len;
ucharbuf wsbuf(ws.data, ws.len);
- loopv(clients)
- {
+ loopv(clients) {
clientinfo &ci = *clients[i];
if(ci.state.aitype != AI_NONE) continue;
addposition(ws, wsbuf, mtu, ci, ci);
loopvj(ci.bots) addposition(ws, wsbuf, mtu, *ci.bots[j], ci);
}
sendpositions(ws, wsbuf);
- loopv(clients)
- {
+ loopv(clients) {
clientinfo &ci = *clients[i];
if(ci.state.aitype != AI_NONE) continue;
addmessages(ws, wsbuf, mtu, ci, ci);
@@ -1739,9 +1331,7 @@ namespace server
worldstates.drop();
return false;
}
-
- bool sendpackets(bool force)
- {
+ bool sendpackets(bool force) {
if(clients.empty() || (!hasnonlocalclients() && !demorecord)) return false;
enet_uint32 curtime = enet_time_get()-lastsend;
if(curtime<33 && !force) return false;
@@ -1749,10 +1339,8 @@ namespace server
lastsend += curtime - (curtime%33);
return flush;
}
-
template<class T>
- void sendstate(gamestate &gs, T &p)
- {
+ void sendstate(gamestate &gs, T &p) {
putint(p, gs.lifesequence);
putint(p, gs.health);
putint(p, gs.maxhealth);
@@ -1762,16 +1350,12 @@ namespace server
putint(p, gs.gunselect);
loopi(GUN_PISTOL-GUN_SG+1) putint(p, gs.ammo[GUN_SG+i]);
}
-
- void spawnstate(clientinfo *ci)
- {
+ void spawnstate(clientinfo *ci) {
gamestate &gs = ci->state;
gs.spawnstate(gamemode);
gs.lifesequence = (gs.lifesequence + 1)&0x7F;
}
-
- void sendspawn(clientinfo *ci)
- {
+ void sendspawn(clientinfo *ci) {
gamestate &gs = ci->state;
spawnstate(ci);
sendf(ci->ownernum, 1, "rii8v", N_SPAWNSTATE, ci->clientnum, gs.lifesequence,
@@ -1780,18 +1364,13 @@ namespace server
gs.gunselect, GUN_PISTOL-GUN_SG+1, &gs.ammo[GUN_SG]);
gs.lastspawn = gamemillis;
}
-
- void sendwelcome(clientinfo *ci)
- {
+ void sendwelcome(clientinfo *ci) {
packetbuf p(MAXTRANS, ENET_PACKET_FLAG_RELIABLE);
int chan = welcomepacket(p, ci);
sendpacket(ci->clientnum, chan, p.finalize());
}
-
- void putinitclient(clientinfo *ci, packetbuf &p)
- {
- if(ci->state.aitype != AI_NONE)
- {
+ void putinitclient(clientinfo *ci, packetbuf &p) {
+ if(ci->state.aitype != AI_NONE) {
putint(p, N_INITAI);
putint(p, ci->clientnum);
putint(p, ci->ownernum);
@@ -1801,8 +1380,7 @@ namespace server
sendstring(ci->name, p);
sendstring(ci->team, p);
}
- else
- {
+ else {
putint(p, N_INITCLIENT);
putint(p, ci->clientnum);
sendstring(ci->name, p);
@@ -1810,57 +1388,43 @@ namespace server
putint(p, ci->playermodel);
}
}
-
- void welcomeinitclient(packetbuf &p, int exclude = -1)
- {
- loopv(clients)
- {
+ void welcomeinitclient(packetbuf &p, int exclude = -1) {
+ loopv(clients) {
clientinfo *ci = clients[i];
if(!ci->connected || ci->clientnum == exclude) continue;
-
putinitclient(ci, p);
}
}
-
- bool hasmap(clientinfo *ci)
- {
+ bool hasmap(clientinfo *ci) {
return (m_edit && (clients.length() > 0 || ci->local)) ||
(smapname[0] && (!m_timed || gamemillis < gamelimit || (ci->state.state==CS_SPECTATOR && !ci->privilege && !ci->local) || numclients(ci->clientnum, true, true, true)));
}
-
- int welcomepacket(packetbuf &p, clientinfo *ci)
- {
+ int welcomepacket(packetbuf &p, clientinfo *ci) {
putint(p, N_WELCOME);
putint(p, N_MAPCHANGE);
sendstring(smapname, p);
putint(p, gamemode);
putint(p, notgotitems ? 1 : 0);
- if(!ci || (m_timed && smapname[0]))
- {
+ if(!ci || (m_timed && smapname[0])) {
putint(p, N_TIMEUP);
putint(p, gamemillis < gamelimit && !interm ? max((gamelimit - gamemillis)/1000, 1) : 0);
}
- if(!notgotitems)
- {
+ if(!notgotitems) {
putint(p, N_ITEMLIST);
- loopv(sents) if(sents[i].spawned)
- {
+ loopv(sents) if(sents[i].spawned) {
putint(p, i);
putint(p, sents[i].type);
}
putint(p, -1);
}
bool hasmaster = false;
- if(mastermode != MM_OPEN)
- {
+ if(mastermode != MM_OPEN) {
putint(p, N_CURRENTMASTER);
putint(p, mastermode);
hasmaster = true;
}
- loopv(clients) if(clients[i]->privilege >= PRIV_MASTER)
- {
- if(!hasmaster)
- {
+ loopv(clients) if(clients[i]->privilege >= PRIV_MASTER) {
+ if(!hasmaster) {
putint(p, N_CURRENTMASTER);
putint(p, mastermode);
hasmaster = true;
@@ -1869,35 +1433,30 @@ namespace server
putint(p, clients[i]->privilege);
}
if(hasmaster) putint(p, -1);
- if(gamepaused)
- {
+ if(gamepaused) {
putint(p, N_PAUSEGAME);
putint(p, 1);
putint(p, -1);
}
- if(gamespeed != 100)
- {
+ if(gamespeed != 100) {
putint(p, N_GAMESPEED);
putint(p, gamespeed);
putint(p, -1);
}
- if(m_teammode)
- {
+ if(m_teammode) {
putint(p, N_TEAMINFO);
enumerate(teaminfos, teaminfo, t,
if(t.frags) { sendstring(t.team, p); putint(p, t.frags); }
);
sendstring("", p);
}
- if(ci)
- {
+ if(ci) {
putint(p, N_SETTEAM);
putint(p, ci->clientnum);
sendstring(ci->team, p);
putint(p, -1);
}
- if(ci && (m_demo || m_mp(gamemode)) && ci->state.state!=CS_SPECTATOR)
- {
+ if(ci && (m_demo || m_mp(gamemode)) && ci->state.state!=CS_SPECTATOR) {
gamestate &gs = ci->state;
spawnstate(ci);
putint(p, N_SPAWNSTATE);
@@ -1905,18 +1464,15 @@ namespace server
sendstate(gs, p);
gs.lastspawn = gamemillis;
}
- if(ci && ci->state.state==CS_SPECTATOR)
- {
+ if(ci && ci->state.state==CS_SPECTATOR) {
putint(p, N_SPECTATOR);
putint(p, ci->clientnum);
putint(p, 1);
sendf(-1, 1, "ri3x", N_SPECTATOR, ci->clientnum, 1, ci->clientnum);
}
- if(!ci || clients.length()>1)
- {
+ if(!ci || clients.length()>1) {
putint(p, N_RESUME);
- loopv(clients)
- {
+ loopv(clients) {
clientinfo *oi = clients[i];
if(ci && oi->clientnum==ci->clientnum) continue;
putint(p, oi->clientnum);
@@ -1932,21 +1488,16 @@ namespace server
}
return 1;
}
-
- bool restorescore(clientinfo *ci)
- {
+ bool restorescore(clientinfo *ci) {
//if(ci->local) return false;
savedscore *sc = findscore(ci, false);
- if(sc)
- {
+ if(sc) {
sc->restore(ci->state);
return true;
}
return false;
}
-
- void sendresume(clientinfo *ci)
- {
+ void sendresume(clientinfo *ci) {
gamestate &gs = ci->state;
sendf(-1, 1, "ri3i5i6vi", N_RESUME, ci->clientnum, gs.state,
gs.frags, gs.flags, gs.deaths, gs.quadmillis,
@@ -1955,22 +1506,17 @@ namespace server
gs.armour, gs.maxarmour, gs.armourtype,
gs.gunselect, GUN_PISTOL-GUN_SG+1, &gs.ammo[GUN_SG], -1);
}
-
- void sendinitclient(clientinfo *ci)
- {
+ void sendinitclient(clientinfo *ci) {
packetbuf p(MAXTRANS, ENET_PACKET_FLAG_RELIABLE);
putinitclient(ci, p);
sendpacket(-1, 1, p.finalize(), ci->clientnum);
}
-
- void loaditems()
- {
+ void loaditems() {
resetitems();
notgotitems = true;
if(m_edit || !loadents(smapname, ments, &mcrc))
return;
- loopv(ments) if(canspawnitem(ments[i].type))
- {
+ loopv(ments) if(canspawnitem(ments[i].type)) {
server_entity se = { NOTUSED, 0, false };
while(sents.length()<=i) sents.add(se);
sents[i].type = ments[i].type;
@@ -1979,14 +1525,11 @@ namespace server
}
notgotitems = false;
}
-
- void changemap(const char *s, int mode)
- {
+ void changemap(const char *s, int mode) {
stopdemo();
pausegame(false);
changegamespeed(100);
aiman::clearai();
-
gamemode = mode;
gamemillis = 0;
gamelimit = 10*60000;
@@ -1997,50 +1540,36 @@ namespace server
scores.shrink(0);
shouldcheckteamkills = false;
teamkills.shrink(0);
- loopv(clients)
- {
+ loopv(clients) {
clientinfo *ci = clients[i];
ci->state.timeplayed += lastmillis - ci->state.lasttimeplayed;
}
-
if(!m_mp(gamemode)) kicknonlocalclients(DISC_LOCAL);
-
sendf(-1, 1, "risii", N_MAPCHANGE, smapname, gamemode, 1);
-
clearteaminfo();
if(m_teammode) autoteam();
-
if(m_timed && smapname[0]) sendf(-1, 1, "ri2", N_TIMEUP, gamemillis < gamelimit && !interm ? max((gamelimit - gamemillis)/1000, 1) : 0);
- loopv(clients)
- {
+ loopv(clients) {
clientinfo *ci = clients[i];
ci->mapchange();
ci->state.lasttimeplayed = lastmillis;
if(m_mp(gamemode) && ci->state.state!=CS_SPECTATOR) sendspawn(ci);
}
-
aiman::changemap();
-
- if(m_demo)
- {
+ if(m_demo) {
if(clients.length()) setupdemoplayback();
}
- else
- {
+ else {
if(demonextmatch) setupdemorecord();
demonextmatch = autorecorddemo!=0;
}
}
-
- void rotatemap(bool next)
- {
- if(!maprotations.inrange(curmaprotation))
- {
+ void rotatemap(bool next) {
+ if(!maprotations.inrange(curmaprotation)) {
changemap("", 1);
return;
}
- if(next)
- {
+ if(next) {
curmaprotation = findmaprotation(gamemode, smapname);
if(curmaprotation >= 0) nextmaprotation();
else curmaprotation = smapname[0] ? max(findmaprotation(gamemode, ""), 0) : 0;
@@ -2048,29 +1577,23 @@ namespace server
maprotation &rot = maprotations[curmaprotation];
changemap(rot.map, rot.findmode(gamemode));
}
-
- struct votecount
- {
+ struct votecount {
char *map;
int mode, count;
votecount() {}
votecount(char *s, int n) : map(s), mode(n), count(0) {}
};
-
- void checkvotes(bool force = false)
- {
+ void checkvotes(bool force = false) {
vector<votecount> votes;
int maxvotes = 0;
- loopv(clients)
- {
+ loopv(clients) {
clientinfo *oi = clients[i];
if(oi->state.state==CS_SPECTATOR && !oi->privilege && !oi->local) continue;
if(oi->state.aitype!=AI_NONE) continue;
maxvotes++;
if(!m_valid(oi->modevote)) continue;
votecount *vc = NULL;
- loopvj(votes) if(!strcmp(oi->mapvote, votes[j].map) && oi->modevote==votes[j].mode)
- {
+ loopvj(votes) if(!strcmp(oi->mapvote, votes[j].map) && oi->modevote==votes[j].mode) {
vc = &votes[j];
break;
}
@@ -2079,24 +1602,19 @@ namespace server
}
votecount *best = NULL;
loopv(votes) if(!best || votes[i].count > best->count || (votes[i].count == best->count && rnd(2))) best = &votes[i];
- if(force || (best && best->count > maxvotes/2))
- {
+ if(force || (best && best->count > maxvotes/2)) {
sendpackets(true);
if(demorecord) enddemorecord();
- if(best && (best->count > (force ? 1 : maxvotes/2)))
- {
+ if(best && (best->count > (force ? 1 : maxvotes/2))) {
sendservmsg(force ? "vote passed by default" : "vote passed by majority");
changemap(best->map, best->mode);
}
else rotatemap(true);
}
}
-
- void forcemap(const char *map, int mode)
- {
+ void forcemap(const char *map, int mode) {
stopdemo();
- if(!map[0] && !m_check(mode, M_EDIT))
- {
+ if(!map[0] && !m_check(mode, M_EDIT)) {
int idx = findmaprotation(mode, smapname);
if(idx < 0 && smapname[0]) idx = findmaprotation(mode, "");
if(idx < 0) return;
@@ -2105,54 +1623,43 @@ namespace server
if(hasnonlocalclients()) sendservmsgf("local player forced %s on map %s", modename(mode), map[0] ? map : "[new map]");
changemap(map, mode);
}
-
- void vote(const char *map, int reqmode, int sender)
- {
+ void vote(const char *map, int reqmode, int sender) {
clientinfo *ci = getinfo(sender);
if(!ci || (ci->state.state==CS_SPECTATOR && !ci->privilege && !ci->local) || (!ci->local && !m_mp(reqmode))) return;
if(!m_valid(reqmode)) return;
- if(!map[0] && !m_check(reqmode, M_EDIT))
- {
+ if(!map[0] && !m_check(reqmode, M_EDIT)) {
int idx = findmaprotation(reqmode, smapname);
if(idx < 0 && smapname[0]) idx = findmaprotation(reqmode, "");
if(idx < 0) return;
map = maprotations[idx].map;
}
- if(lockmaprotation && !ci->local && ci->privilege < (lockmaprotation > 1 ? PRIV_ADMIN : PRIV_MASTER) && findmaprotation(reqmode, map) < 0)
- {
+ if(lockmaprotation && !ci->local && ci->privilege < (lockmaprotation > 1 ? PRIV_ADMIN : PRIV_MASTER) && findmaprotation(reqmode, map) < 0) {
sendf(sender, 1, "ris", N_SERVMSG, "This server has locked the map rotation.");
return;
}
copystring(ci->mapvote, map);
ci->modevote = reqmode;
- if(ci->local || (ci->privilege && mastermode>=MM_VETO))
- {
+ if(ci->local || (ci->privilege && mastermode>=MM_VETO)) {
sendpackets(true);
if(demorecord) enddemorecord();
if(!ci->local || hasnonlocalclients())
sendservmsgf("%s forced %s on map %s", colorname(ci), modename(ci->modevote), ci->mapvote[0] ? ci->mapvote : "[new map]");
changemap(ci->mapvote, ci->modevote);
}
- else
- {
+ else {
sendservmsgf("%s suggests %s on map %s (select map to vote)", colorname(ci), modename(reqmode), map[0] ? map : "[new map]");
checkvotes();
}
}
-
VAR(overtime, 0, 0, 1);
-
- bool checkovertime()
- {
+ bool checkovertime() {
if(!m_timed || !overtime) return false;
const char* topteam = NULL;
int topscore = INT_MIN;
bool tied = false;
- if(m_teammode)
- {
+ if(m_teammode) {
vector<teamscore> scores;
- loopv(clients)
- {
+ loopv(clients) {
clientinfo *ci = clients[i];
if(ci->state.state==CS_SPECTATOR || !ci->team[0]) continue;
int score = 0;
@@ -2161,10 +1668,8 @@ namespace server
else if(score == topscore && strcmp(ci->team, topteam)) tied = true;
}
}
- else
- {
- loopv(clients)
- {
+ else {
+ loopv(clients) {
clientinfo *ci = clients[i];
if(ci->state.state==CS_SPECTATOR) continue;
int score = ci->state.frags;
@@ -2178,39 +1683,30 @@ namespace server
sendf(-1, 1, "ri2", N_TIMEUP, max((gamelimit - gamemillis)/1000, 1));
return true;
}
-
- void checkintermission(bool force = false)
- {
- if(gamemillis >= gamelimit && !interm && (force || !checkovertime()))
- {
+ void checkintermission(bool force = false) {
+ if(gamemillis >= gamelimit && !interm && (force || !checkovertime())) {
sendf(-1, 1, "ri2", N_TIMEUP, 0);
changegamespeed(100);
interm = gamemillis + 10000;
}
}
-
void startintermission() { gamelimit = min(gamelimit, gamemillis); checkintermission(true); }
-
- void dodamage(clientinfo *target, clientinfo *actor, int damage, int gun, const vec &hitpush = vec(0, 0, 0))
- {
+ void dodamage(clientinfo *target, clientinfo *actor, int damage, int gun, const vec &hitpush = vec(0, 0, 0)) {
gamestate &ts = target->state;
ts.dodamage(damage);
if(target!=actor && !isteam(target->team, actor->team)) actor->state.damage += damage;
sendf(-1, 1, "ri6", N_DAMAGE, target->clientnum, actor->clientnum, damage, ts.armour, ts.health);
if(target==actor) target->setpushed();
- else if(!hitpush.iszero())
- {
+ else if(!hitpush.iszero()) {
ivec v(vec(hitpush).rescale(DNF));
sendf(ts.health<=0 ? -1 : target->ownernum, 1, "ri7", N_HITPUSH, target->clientnum, gun, damage, v.x, v.y, v.z);
target->setpushed();
}
- if(ts.health<=0)
- {
+ if(ts.health<=0) {
target->state.deaths++;
int fragvalue = (target==actor || isteam(target->team, actor->team) ? -1 : 1);
actor->state.frags += fragvalue;
- if(fragvalue>0)
- {
+ if(fragvalue>0) {
int friends = 0, enemies = 0; // note: friends also includes the fragger
if(m_teammode) loopv(clients) if(strcmp(clients[i]->team, actor->team)) enemies++; else friends++;
else { friends = 1; enemies = clients.length()-1; }
@@ -2222,8 +1718,7 @@ namespace server
target->position.setsize(0);
ts.state = CS_DEAD;
ts.lastdeath = gamemillis;
- if(actor!=target && isteam(actor->team, target->team))
- {
+ if(actor!=target && isteam(actor->team, target->team)) {
actor->state.teamkills++;
addteamkill(actor, target, 1);
}
@@ -2232,9 +1727,7 @@ namespace server
// ts.respawn();
}
}
-
- void suicide(clientinfo *ci)
- {
+ void suicide(clientinfo *ci) {
gamestate &gs = ci->state;
if(gs.state!=CS_ALIVE) return;
int fragvalue = -1;
@@ -2248,39 +1741,29 @@ namespace server
gs.lastdeath = gamemillis;
gs.respawn();
}
-
- void suicideevent::process(clientinfo *ci)
- {
+ void suicideevent::process(clientinfo *ci) {
suicide(ci);
}
-
- void explodeevent::process(clientinfo *ci)
- {
+ void explodeevent::process(clientinfo *ci) {
gamestate &gs = ci->state;
- switch(gun)
- {
+ switch(gun) {
case GUN_RL:
if(!gs.rockets.remove(id)) return;
break;
-
case GUN_GL:
if(!gs.grenades.remove(id)) return;
break;
-
default:
return;
}
sendf(-1, 1, "ri4x", N_EXPLODEFX, ci->clientnum, gun, id, ci->ownernum);
- loopv(hits)
- {
+ loopv(hits) {
hitinfo &h = hits[i];
clientinfo *target = getinfo(h.target);
if(!target || target->state.state!=CS_ALIVE || h.lifesequence!=target->state.lifesequence || h.dist<0 || h.dist>guns[gun].exprad) continue;
-
bool dup = false;
loopj(i) if(hits[j].target==h.target) { dup = true; break; }
if(dup) continue;
-
int damage = guns[gun].damage;
if(gs.quadmillis) damage *= 4;
damage = int(damage*(1-h.dist/EXP_DISTSCALE/guns[gun].exprad));
@@ -2288,9 +1771,7 @@ namespace server
dodamage(target, ci, damage, gun, h.dir);
}
}
-
- void shotevent::process(clientinfo *ci)
- {
+ void shotevent::process(clientinfo *ci) {
gamestate &gs = ci->state;
int wait = millis - gs.lastshot;
if(!gs.isalive(gamemillis) ||
@@ -2306,19 +1787,15 @@ namespace server
int(to.x*DMF), int(to.y*DMF), int(to.z*DMF),
ci->ownernum);
gs.shotdamage += guns[gun].damage*(gs.quadmillis ? 4 : 1)*guns[gun].rays;
- switch(gun)
- {
+ switch(gun) {
case GUN_RL: gs.rockets.add(id); break;
case GUN_GL: gs.grenades.add(id); break;
- default:
- {
+ default: {
int totalrays = 0, maxrays = guns[gun].rays;
- loopv(hits)
- {
+ loopv(hits) {
hitinfo &h = hits[i];
clientinfo *target = getinfo(h.target);
if(!target || target->state.state!=CS_ALIVE || h.lifesequence!=target->state.lifesequence || h.rays<1 || h.dist > guns[gun].range + 1) continue;
-
totalrays += h.rays;
if(totalrays>maxrays) continue;
int damage = h.rays*guns[gun].damage;
@@ -2329,65 +1806,46 @@ namespace server
}
}
}
-
- void pickupevent::process(clientinfo *ci)
- {
+ void pickupevent::process(clientinfo *ci) {
gamestate &gs = ci->state;
if(m_mp(gamemode) && !gs.isalive(gamemillis)) return;
pickup(ent, ci->clientnum);
}
-
- bool gameevent::flush(clientinfo *ci, int fmillis)
- {
+ bool gameevent::flush(clientinfo *ci, int fmillis) {
+ (void) fmillis;
process(ci);
return true;
}
-
- bool timedevent::flush(clientinfo *ci, int fmillis)
- {
+ bool timedevent::flush(clientinfo *ci, int fmillis) {
if(millis > fmillis) return false;
- else if(millis >= ci->lastevent)
- {
+ else if(millis >= ci->lastevent) {
ci->lastevent = millis;
process(ci);
}
return true;
}
-
- void clearevent(clientinfo *ci)
- {
+ void clearevent(clientinfo *ci) {
delete ci->events.remove(0);
}
-
- void flushevents(clientinfo *ci, int millis)
- {
- while(ci->events.length())
- {
+ void flushevents(clientinfo *ci, int millis) {
+ while(ci->events.length()) {
gameevent *ev = ci->events[0];
if(ev->flush(ci, millis)) clearevent(ci);
else break;
}
}
-
- void processevents()
- {
- loopv(clients)
- {
+ void processevents() {
+ loopv(clients) {
clientinfo *ci = clients[i];
if(curtime>0 && ci->state.quadmillis) ci->state.quadmillis = max(ci->state.quadmillis-curtime, 0);
flushevents(ci, gamemillis);
}
}
-
- void cleartimedevents(clientinfo *ci)
- {
+ void cleartimedevents(clientinfo *ci) {
int keep = 0;
- loopv(ci->events)
- {
- if(ci->events[i]->keepable())
- {
- if(keep < i)
- {
+ loopv(ci->events) {
+ if(ci->events[i]->keepable()) {
+ if(keep < i) {
for(int j = keep; j < i; j++) delete ci->events[j];
ci->events.remove(keep, i - keep);
i = keep;
@@ -2399,31 +1857,22 @@ namespace server
while(ci->events.length() > keep) delete ci->events.pop();
ci->timesync = false;
}
-
- void serverupdate()
- {
- if(shouldstep && !gamepaused)
- {
+ void serverupdate() {
+ if(shouldstep && !gamepaused) {
gamemillis += curtime;
-
if(m_demo) readdemo();
- else if(!m_timed || gamemillis < gamelimit)
- {
+ else if(!m_timed || gamemillis < gamelimit) {
processevents();
- if(curtime)
- {
- loopv(sents) if(sents[i].spawntime) // spawn entities when timer reached
- {
+ if(curtime) {
+ loopv(sents) if(sents[i].spawntime) { // spawn entities when timer reached {
int oldtime = sents[i].spawntime;
sents[i].spawntime -= curtime;
- if(sents[i].spawntime<=0)
- {
+ if(sents[i].spawntime<=0) {
sents[i].spawntime = 0;
sents[i].spawned = true;
sendf(-1, 1, "ri2", N_ITEMSPAWN, i);
}
- else if(sents[i].spawntime<=10000 && oldtime>10000 && (sents[i].type==I_QUAD || sents[i].type==I_BOOST))
- {
+ else if(sents[i].spawntime<=10000 && oldtime>10000 && (sents[i].type==I_QUAD || sents[i].type==I_BOOST)) {
sendf(-1, 1, "ri2", N_ANNOUNCE, sents[i].type);
}
}
@@ -2431,77 +1880,56 @@ namespace server
aiman::checkai();
}
}
-
while(bannedips.length() && bannedips[0].expire-totalmillis <= 0) bannedips.remove(0);
//~loopv(connects) if(totalmillis-connects[i]->connectmillis>15000) disconnect_client(connects[i]->clientnum, DISC_TIMEOUT);
-
- if(nextexceeded && gamemillis > nextexceeded && (!m_timed || gamemillis < gamelimit))
- {
+ if(nextexceeded && gamemillis > nextexceeded && (!m_timed || gamemillis < gamelimit)) {
nextexceeded = 0;
- loopvrev(clients)
- {
+ loopvrev(clients) {
clientinfo &c = *clients[i];
if(c.state.aitype != AI_NONE) continue;
//~if(c.checkexceeded()) disconnect_client(c.clientnum, DISC_MSGERR);
else c.scheduleexceeded();
}
}
-
if(shouldcheckteamkills) checkteamkills();
-
- if(shouldstep && !gamepaused)
- {
+ if(shouldstep && !gamepaused) {
if(m_timed && smapname[0] && gamemillis-curtime>0) checkintermission();
- if(interm > 0 && gamemillis>interm)
- {
+ if(interm > 0 && gamemillis>interm) {
if(demorecord) enddemorecord();
interm = -1;
checkvotes(true);
}
}
-
shouldstep = clients.length() > 0;
}
-
- void forcespectator(clientinfo *ci)
- {
+ void forcespectator(clientinfo *ci) {
if(ci->state.state==CS_ALIVE) suicide(ci);
ci->state.state = CS_SPECTATOR;
ci->state.timeplayed += lastmillis - ci->state.lasttimeplayed;
if(!ci->local && (!ci->privilege || ci->warned)) aiman::removeai(ci);
sendf(-1, 1, "ri3", N_SPECTATOR, ci->clientnum, 1);
}
-
- struct crcinfo
- {
+ struct crcinfo {
int crc, matches;
-
crcinfo() {}
crcinfo(int crc, int matches) : crc(crc), matches(matches) {}
-
static bool compare(const crcinfo &x, const crcinfo &y) { return x.matches > y.matches; }
};
-
VAR(modifiedmapspectator, 0, 1, 2);
-
- void checkmaps(int req = -1)
- {
+ void checkmaps(int req = -1) {
if(m_edit || !smapname[0]) return;
vector<crcinfo> crcs;
int total = 0, unsent = 0, invalid = 0;
if(mcrc) crcs.add(crcinfo(mcrc, clients.length() + 1));
- loopv(clients)
- {
+ loopv(clients) {
clientinfo *ci = clients[i];
if(ci->state.state==CS_SPECTATOR || ci->state.aitype != AI_NONE) continue;
total++;
- if(!ci->clientmap[0])
- {
+ if(!ci->clientmap[0]) {
if(ci->mapcrc < 0) invalid++;
else if(!ci->mapcrc) unsent++;
}
- else
- {
+ else {
crcinfo *match = NULL;
loopvj(crcs) if(crcs[j].crc == ci->mapcrc) { match = &crcs[j]; break; }
if(!match) crcs.add(crcinfo(ci->mapcrc, 1));
@@ -2511,19 +1939,16 @@ namespace server
if(!mcrc && total - unsent < min(total, 4)) return;
crcs.sort(crcinfo::compare);
string msg;
- loopv(clients)
- {
+ loopv(clients) {
clientinfo *ci = clients[i];
if(ci->state.state==CS_SPECTATOR || ci->state.aitype != AI_NONE || ci->clientmap[0] || ci->mapcrc >= 0 || (req < 0 && ci->warned)) continue;
formatstring(msg, "%s has modified map \"%s\"", colorname(ci), smapname);
sendf(req, 1, "ris", N_SERVMSG, msg);
if(req < 0) ci->warned = true;
}
- if(crcs.length() >= 2) loopv(crcs)
- {
+ if(crcs.length() >= 2) loopv(crcs) {
crcinfo &info = crcs[i];
- if(i || info.matches <= crcs[i+1].matches) loopvj(clients)
- {
+ if(i || info.matches <= crcs[i+1].matches) loopvj(clients) {
clientinfo *ci = clients[j];
if(ci->state.state==CS_SPECTATOR || ci->state.aitype != AI_NONE || !ci->clientmap[0] || ci->mapcrc != info.crc || (req < 0 && ci->warned)) continue;
formatstring(msg, "%s has modified map \"%s\"", colorname(ci), smapname);
@@ -2531,20 +1956,15 @@ namespace server
if(req < 0) ci->warned = true;
}
}
- if(req < 0 && modifiedmapspectator && (mcrc || modifiedmapspectator > 1)) loopv(clients)
- {
+ if(req < 0 && modifiedmapspectator && (mcrc || modifiedmapspectator > 1)) loopv(clients) {
clientinfo *ci = clients[i];
if(!ci->local && ci->warned && ci->state.state != CS_SPECTATOR) forcespectator(ci);
}
}
-
- bool shouldspectate(clientinfo *ci)
- {
+ bool shouldspectate(clientinfo *ci) {
return !ci->local && ci->warned && modifiedmapspectator && (mcrc || modifiedmapspectator > 1);
}
-
- void unspectate(clientinfo *ci)
- {
+ void unspectate(clientinfo *ci) {
if(shouldspectate(ci)) return;
ci->state.state = CS_DEAD;
ci->state.respawn();
@@ -2554,55 +1974,40 @@ namespace server
if(ci->clientmap[0] || ci->mapcrc) checkmaps();
if(!hasmap(ci)) rotatemap(true);
}
-
- void sendservinfo(clientinfo *ci)
- {
+ void sendservinfo(clientinfo *ci) {
sendf(ci->clientnum, 1, "ri5ss", N_SERVINFO, ci->clientnum, PROTOCOL_VERSION, ci->sessionid, serverpass[0] ? 1 : 0, serverdesc, serverauth);
}
-
- void noclients()
- {
+ void noclients() {
bannedips.shrink(0);
aiman::clearai();
}
-
- void localconnect(int n)
- {
+ void localconnect(int n) {
clientinfo *ci = getinfo(n);
ci->clientnum = ci->ownernum = n;
ci->connectmillis = totalmillis;
ci->sessionid = (rnd(0x1000000)*((totalmillis%10000)+1))&0xFFFFFF;
ci->local = true;
-
connects.add(ci);
sendservinfo(ci);
}
-
- void localdisconnect(int n)
- {
+ void localdisconnect(int n) {
if(m_demo) enddemoplayback();
clientdisconnect(n);
}
-
- int clientconnect(int n)
- {
+ int clientconnect(int n) {
clientinfo *ci = getinfo(n);
ci->clientnum = ci->ownernum = n;
ci->connectmillis = totalmillis;
ci->sessionid = (rnd(0x1000000)*((totalmillis%10000)+1))&0xFFFFFF;
-
connects.add(ci);
if(!m_mp(gamemode)) return DISC_LOCAL;
sendservinfo(ci);
return DISC_NONE;
}
-
- void clientdisconnect(int n)
- {
+ void clientdisconnect(int n) {
clientinfo *ci = getinfo(n);
loopv(clients) if(clients[i]->authkickvictim == ci->clientnum) clients[i]->cleanauth();
- if(ci->connected)
- {
+ if(ci->connected) {
if(ci->privilege) setmaster(ci, false);
ci->state.timeplayed += lastmillis - ci->state.lasttimeplayed;
savescore(ci);
@@ -2614,58 +2019,39 @@ namespace server
}
else connects.removeobj(ci);
}
-
int reserveclients() { return 3; }
-
extern void verifybans();
-
- struct banlist
- {
+ struct banlist {
vector<ipmask> bans;
-
void clear() { bans.shrink(0); }
-
- bool check(uint ip)
- {
+ bool check(uint ip) {
loopv(bans) if(bans[i].check(ip)) return true;
return false;
}
-
- void add(const char *ipname)
- {
+ void add(const char *ipname) {
ipmask ban;
ban.parse(ipname);
bans.add(ban);
-
verifybans();
}
} ipbans, gbans;
-
- bool checkbans(uint ip)
- {
+ bool checkbans(uint ip) {
loopv(bannedips) if(bannedips[i].ip==ip) return true;
return ipbans.check(ip) || gbans.check(ip);
}
-
- void verifybans()
- {
- loopvrev(clients)
- {
+ void verifybans() {
+ loopvrev(clients) {
clientinfo *ci = clients[i];
if(ci->state.aitype != AI_NONE || ci->local || ci->privilege >= PRIV_ADMIN) continue;
//~if(checkbans(getclientip(ci->clientnum))) disconnect_client(ci->clientnum, DISC_IPBAN);
}
}
-
ICOMMAND(clearipbans, "", (), ipbans.clear());
ICOMMAND(ipban, "s", (const char *ipname), ipbans.add(ipname));
-
- int allowconnect(clientinfo *ci, const char *pwd = "")
- {
+ int allowconnect(clientinfo *ci, const char *pwd = "") {
if(ci->local) return DISC_NONE;
if(!m_mp(gamemode)) return DISC_LOCAL;
- if(serverpass[0])
- {
+ if(serverpass[0]) {
if(!checkpassword(ci, serverpass, pwd)) return DISC_PASSWORD;
return DISC_NONE;
}
@@ -2676,68 +2062,50 @@ namespace server
if(mastermode>=MM_PRIVATE && allowedips.find(ip)<0) return DISC_PRIVATE;
return DISC_NONE;
}
-
- bool allowbroadcast(int n)
- {
+ bool allowbroadcast(int n) {
clientinfo *ci = getinfo(n);
return ci && ci->connected;
}
-
- clientinfo *findauth(uint id)
- {
+ clientinfo *findauth(uint id) {
loopv(clients) if(clients[i]->authreq == id) return clients[i];
return NULL;
}
-
- void authfailed(clientinfo *ci)
- {
+ void authfailed(clientinfo *ci) {
if(!ci) return;
ci->cleanauth();
//~if(ci->connectauth) disconnect_client(ci->clientnum, ci->connectauth);
}
-
- void authfailed(uint id)
- {
+ void authfailed(uint id) {
authfailed(findauth(id));
}
-
- void authsucceeded(uint id)
- {
+ void authsucceeded(uint id) {
clientinfo *ci = findauth(id);
if(!ci) return;
ci->cleanauth(ci->connectauth!=0);
if(ci->connectauth) connected(ci);
- if(ci->authkickvictim >= 0)
- {
+ if(ci->authkickvictim >= 0) {
if(setmaster(ci, true, "", ci->authname, NULL, PRIV_AUTH, false, true))
trykick(ci, ci->authkickvictim, ci->authkickreason, ci->authname, NULL, PRIV_AUTH);
ci->cleanauthkick();
}
else setmaster(ci, true, "", ci->authname, NULL, PRIV_AUTH);
}
-
- void authchallenged(uint id, const char *val, const char *desc = "")
- {
+ void authchallenged(uint id, const char *val, const char *desc = "") {
clientinfo *ci = findauth(id);
if(!ci) return;
sendf(ci->clientnum, 1, "risis", N_AUTHCHAL, desc, id, val);
}
-
uint nextauthreq = 0;
-
- bool tryauth(clientinfo *ci, const char *user, const char *desc)
- {
+ bool tryauth(clientinfo *ci, const char *user, const char *desc) {
ci->cleanauth();
if(!nextauthreq) nextauthreq = 1;
ci->authreq = nextauthreq++;
filtertext(ci->authname, user, false, false, 100);
copystring(ci->authdesc, desc);
- if(ci->authdesc[0])
- {
+ if(ci->authdesc[0]) {
userinfo *u = users.access(userkey(ci->authname, ci->authdesc));
- if(u)
- {
+ if(u) {
uint seed[3] = { ::hthash(serverauth) + detrnd(size_t(ci) + size_t(user) + size_t(desc), 0x10000), uint(totalmillis), randomMT() };
vector<char> buf;
ci->authchallenge = genchallenge(u->pubkey, seed, sizeof(seed), buf);
@@ -2745,8 +2113,7 @@ namespace server
}
else ci->cleanauth();
}
- else if(!requestmasterf("reqauth %u %s\n", ci->authreq, ci->authname))
- {
+ else if(!requestmasterf("reqauth %u %s\n", ci->authreq, ci->authname)) {
ci->cleanauth();
sendf(ci->clientnum, 1, "ris", N_SERVMSG, "not connected to authentication server");
}
@@ -2754,28 +2121,20 @@ namespace server
//~if(ci->connectauth) disconnect_client(ci->clientnum, ci->connectauth);
return false;
}
-
- bool answerchallenge(clientinfo *ci, uint id, char *val, const char *desc)
- {
- if(ci->authreq != id || strcmp(ci->authdesc, desc))
- {
+ bool answerchallenge(clientinfo *ci, uint id, char *val, const char *desc) {
+ if(ci->authreq != id || strcmp(ci->authdesc, desc)) {
ci->cleanauth();
return !ci->connectauth;
}
- for(char *s = val; *s; s++)
- {
+ for(char *s = val; *s; s++) {
if(!isxdigit(*s)) { *s = '\0'; break; }
}
- if(desc[0])
- {
- if(ci->authchallenge && checkchallenge(val, ci->authchallenge))
- {
+ if(desc[0]) {
+ if(ci->authchallenge && checkchallenge(val, ci->authchallenge)) {
userinfo *u = users.access(userkey(ci->authname, ci->authdesc));
- if(u)
- {
+ if(u) {
if(ci->connectauth) connected(ci);
- if(ci->authkickvictim >= 0)
- {
+ if(ci->authkickvictim >= 0) {
if(setmaster(ci, true, "", ci->authname, ci->authdesc, u->privilege, false, true))
trykick(ci, ci->authkickvictim, ci->authkickreason, ci->authname, ci->authdesc, u->privilege);
}
@@ -2784,29 +2143,21 @@ namespace server
}
ci->cleanauth();
}
- else if(!requestmasterf("confauth %u %s\n", id, val))
- {
+ else if(!requestmasterf("confauth %u %s\n", id, val)) {
ci->cleanauth();
sendf(ci->clientnum, 1, "ris", N_SERVMSG, "not connected to authentication server");
}
return ci->authreq || !ci->connectauth;
}
-
- void masterconnected()
- {
+ void masterconnected() {
}
-
- void masterdisconnected()
- {
- loopvrev(clients)
- {
+ void masterdisconnected() {
+ loopvrev(clients) {
clientinfo *ci = clients[i];
if(ci->authreq) authfailed(ci);
}
}
-
- void processmasterinput(const char *cmd, int cmdlen, const char *args)
- {
+ void processmasterinput(const char *cmd, int cmdlen) {
uint id;
string val;
if(sscanf(cmd, "failauth %u", &id) == 1)
@@ -2820,9 +2171,7 @@ namespace server
else if(sscanf(cmd, "addgban %100s", val) == 1)
gbans.add(val);
}
-
- void receivefile(int sender, uchar *data, int len)
- {
+ void receivefile(int sender, uchar *data, int len) {
if(!m_edit || len <= 0 || len > 4*1024*1024) return;
clientinfo *ci = getinfo(sender);
if(ci->state.state==CS_SPECTATOR && !ci->privilege && !ci->local) return;
@@ -2832,82 +2181,59 @@ namespace server
mapdata->write(data, len);
sendservmsgf("[%s sent a map to server, \"/getmap\" to receive it]", colorname(ci));
}
-
- void sendclipboard(clientinfo *ci)
- {
+ void sendclipboard(clientinfo *ci) {
if(!ci->lastclipboard || !ci->clipboard) return;
bool flushed = false;
- loopv(clients)
- {
+ loopv(clients) {
clientinfo &e = *clients[i];
- if(e.clientnum != ci->clientnum && e.needclipboard - ci->lastclipboard >= 0)
- {
+ if(e.clientnum != ci->clientnum && e.needclipboard - ci->lastclipboard >= 0) {
if(!flushed) { flushserver(true); flushed = true; }
sendpacket(e.clientnum, 1, ci->clipboard);
}
}
}
-
- void connected(clientinfo *ci)
- {
+ void connected(clientinfo *ci) {
if(m_demo) enddemoplayback();
-
if(!hasmap(ci)) rotatemap(false);
-
shouldstep = true;
-
connects.removeobj(ci);
clients.add(ci);
-
ci->connectauth = 0;
ci->connected = true;
ci->needclipboard = totalmillis ? totalmillis : 1;
if(mastermode>=MM_LOCKED) ci->state.state = CS_SPECTATOR;
ci->state.lasttimeplayed = lastmillis;
-
- const char *worst = m_teammode ? chooseworstteam(NULL, ci) : NULL;
+ const char *worst = m_teammode ? chooseworstteam(ci) : NULL;
copystring(ci->team, worst ? worst : "good", MAXTEAMLEN+1);
-
sendwelcome(ci);
if(restorescore(ci)) sendresume(ci);
sendinitclient(ci);
-
aiman::addclient(ci);
-
if(m_demo) setupdemoplayback();
-
if(servermotd[0]) sendf(ci->clientnum, 1, "ris", N_SERVMSG, servermotd);
}
-
- void parsepacket(int sender, int chan, packetbuf &p) // has to parse exactly each byte of the packet
- {
+ void parsepacket(int sender, int chan, packetbuf &p) { // has to parse exactly each byte of the packet {
if(sender<0 || p.packet->flags&ENET_PACKET_FLAG_UNSEQUENCED || chan > 2) return;
char text[MAXTRANS];
int type;
clientinfo *ci = sender>=0 ? getinfo(sender) : NULL, *cq = ci, *cm = ci;
- if(ci && !ci->connected)
- {
+ if(ci && !ci->connected) {
if(chan==0) return;
//~else if(chan!=1) { disconnect_client(sender, DISC_MSGERR); return; }
- else while(p.length() < p.maxlen) switch(checktype(getint(p), ci))
- {
- case N_CONNECT:
- {
+ else while(p.length() < p.maxlen) switch(checktype(getint(p), ci)) {
+ case N_CONNECT: {
getstring(text, p);
filtertext(text, text, false, false, MAXNAMELEN);
if(!text[0]) copystring(text, "Anonymous");
copystring(ci->name, text, MAXNAMELEN+1);
ci->playermodel = 0;
-
string password, authdesc, authname;
getstring(password, p, sizeof(password));
getstring(authdesc, p, sizeof(authdesc));
getstring(authname, p, sizeof(authname));
int disc = allowconnect(ci, password);
- if(disc)
- {
- if(disc == DISC_LOCAL || !serverauth[0] || strcmp(serverauth, authdesc) || !tryauth(ci, authname, authdesc))
- {
+ if(disc) {
+ if(disc == DISC_LOCAL || !serverauth[0] || strcmp(serverauth, authdesc) || !tryauth(ci, authname, authdesc)) {
//~disconnect_client(sender, disc);
return;
}
@@ -2916,63 +2242,53 @@ namespace server
else connected(ci);
break;
}
-
- case N_AUTHANS:
- {
+ case N_AUTHANS: {
string desc, ans;
getstring(desc, p, sizeof(desc));
uint id = (uint)getint(p);
getstring(ans, p, sizeof(ans));
- if(!answerchallenge(ci, id, ans, desc))
- {
+ if(!answerchallenge(ci, id, ans, desc)) {
//~disconnect_client(sender, ci->connectauth);
return;
}
break;
}
-
case N_PING:
getint(p);
break;
-
default:
//~disconnect_client(sender, DISC_MSGERR);
return;
}
return;
}
- else if(chan==2)
- {
+ else if(chan==2) {
receivefile(sender, p.buf, p.maxlen);
return;
}
-
if(p.packet->flags&ENET_PACKET_FLAG_RELIABLE) reliablemessages = true;
#define QUEUE_AI clientinfo *cm = cq;
#define QUEUE_MSG { if(cm && (!cm->local || demorecord || hasnonlocalclients())) while(curmsg<p.length()) cm->messages.add(p.buf[curmsg++]); }
#define QUEUE_BUF(body) { \
- if(cm && (!cm->local || demorecord || hasnonlocalclients())) \
- { \
- curmsg = p.length(); \
- { body; } \
+ if(cm && (!cm->local || demorecord || hasnonlocalclients())) { \
+ \
+ curmsg = p.length(); { \
+ body; } \
} \
}
#define QUEUE_INT(n) QUEUE_BUF(putint(cm->messages, n))
#define QUEUE_UINT(n) QUEUE_BUF(putuint(cm->messages, n))
#define QUEUE_STR(text) QUEUE_BUF(sendstring(text, cm->messages))
int curmsg;
- while((curmsg = p.length()) < p.maxlen) switch(type = checktype(getint(p), ci))
- {
- case N_POS:
- {
+ while((curmsg = p.length()) < p.maxlen) switch(type = checktype(getint(p), ci)) {
+ case N_POS: {
int pcn = getuint(p);
p.get();
uint flags = getuint(p);
clientinfo *cp = getinfo(pcn);
if(cp && pcn != sender && cp->ownernum != sender) cp = NULL;
vec pos;
- loopk(3)
- {
+ loopk(3) {
int n = p.get(); n |= p.get()<<8; if(flags&(1<<k)) { n |= p.get()<<16; if(n&0x800000) n |= ~0U<<24; }
pos[k] = n/DMF;
}
@@ -2980,15 +2296,12 @@ namespace server
int mag = p.get(); if(flags&(1<<3)) mag |= p.get()<<8;
int dir = p.get(); dir |= p.get()<<8;
vec vel = vec((dir%360)*RAD, (clamp(dir/360, 0, 180)-90)*RAD).mul(mag/DVELF);
- if(flags&(1<<4))
- {
+ if(flags&(1<<4)) {
p.get(); if(flags&(1<<5)) p.get();
if(flags&(1<<6)) loopk(2) p.get();
}
- if(cp)
- {
- if((!ci->local || demorecord || hasnonlocalclients()) && (cp->state.state==CS_ALIVE || cp->state.state==CS_EDITING))
- {
+ if(cp) {
+ if((!ci->local || demorecord || hasnonlocalclients()) && (cp->state.state==CS_ALIVE || cp->state.state==CS_EDITING)) {
if(!ci->local && !m_edit && max(vel.magnitude2(), (float)fabs(vel.z)) >= 180)
cp->setexceeded();
cp->position.setsize(0);
@@ -2999,53 +2312,41 @@ namespace server
}
break;
}
-
- case N_TELEPORT:
- {
+ case N_TELEPORT: {
int pcn = getint(p), teleport = getint(p), teledest = getint(p);
clientinfo *cp = getinfo(pcn);
if(cp && pcn != sender && cp->ownernum != sender) cp = NULL;
- if(cp && (!ci->local || demorecord || hasnonlocalclients()) && (cp->state.state==CS_ALIVE || cp->state.state==CS_EDITING))
- {
+ if(cp && (!ci->local || demorecord || hasnonlocalclients()) && (cp->state.state==CS_ALIVE || cp->state.state==CS_EDITING)) {
flushclientposition(*cp);
sendf(-1, 0, "ri4x", N_TELEPORT, pcn, teleport, teledest, cp->ownernum);
}
break;
}
-
- case N_JUMPPAD:
- {
+ case N_JUMPPAD: {
int pcn = getint(p), jumppad = getint(p);
clientinfo *cp = getinfo(pcn);
if(cp && pcn != sender && cp->ownernum != sender) cp = NULL;
- if(cp && (!ci->local || demorecord || hasnonlocalclients()) && (cp->state.state==CS_ALIVE || cp->state.state==CS_EDITING))
- {
+ if(cp && (!ci->local || demorecord || hasnonlocalclients()) && (cp->state.state==CS_ALIVE || cp->state.state==CS_EDITING)) {
cp->setpushed();
flushclientposition(*cp);
sendf(-1, 0, "ri3x", N_JUMPPAD, pcn, jumppad, cp->ownernum);
}
break;
}
-
- case N_FROMAI:
- {
+ case N_FROMAI: {
int qcn = getint(p);
if(qcn < 0) cq = ci;
- else
- {
+ else {
cq = getinfo(qcn);
if(cq && qcn != sender && cq->ownernum != sender) cq = NULL;
}
break;
}
-
- case N_EDITMODE:
- {
+ case N_EDITMODE: {
int val = getint(p);
if(!ci->local && !m_edit) break;
if(val ? ci->state.state!=CS_ALIVE && ci->state.state!=CS_DEAD : ci->state.state!=CS_EDITING) break;
- if(val)
- {
+ if(val) {
ci->state.editstate = ci->state.state;
ci->state.state = CS_EDITING;
ci->events.setsize(0);
@@ -3056,16 +2357,12 @@ namespace server
QUEUE_MSG;
break;
}
-
- case N_MAPCRC:
- {
+ case N_MAPCRC: {
getstring(text, p);
int crc = getint(p);
if(!ci) break;
- if(strcmp(text, smapname))
- {
- if(ci->clientmap[0])
- {
+ if(strcmp(text, smapname)) {
+ if(ci->clientmap[0]) {
ci->clientmap[0] = '\0';
ci->mapcrc = 0;
}
@@ -3078,31 +2375,25 @@ namespace server
if(cq && cq != ci && cq->ownernum != ci->clientnum) cq = NULL;
break;
}
-
case N_CHECKMAPS:
checkmaps(sender);
break;
-
case N_TRYSPAWN:
if(!ci || !cq || cq->state.state!=CS_DEAD || cq->state.lastspawn>=0) break;
- if(!ci->clientmap[0] && !ci->mapcrc)
- {
+ if(!ci->clientmap[0] && !ci->mapcrc) {
ci->mapcrc = -1;
checkmaps();
if(ci == cq) { if(ci->state.state != CS_DEAD) break; }
else if(cq->ownernum != ci->clientnum) { cq = NULL; break; }
}
- if(cq->state.deadflush)
- {
+ if(cq->state.deadflush) {
flushevents(cq, cq->state.deadflush);
cq->state.respawn();
}
cleartimedevents(cq);
sendspawn(cq);
break;
-
- case N_GUNSELECT:
- {
+ case N_GUNSELECT: {
int gunselect = getint(p);
if(!cq || cq->state.state!=CS_ALIVE) break;
cq->state.gunselect = gunselect >= GUN_FIST && gunselect <= GUN_PISTOL ? gunselect : GUN_FIST;
@@ -3110,9 +2401,7 @@ namespace server
QUEUE_MSG;
break;
}
-
- case N_SPAWN:
- {
+ case N_SPAWN: {
int ls = getint(p), gunselect = getint(p);
if(!cq || (cq->state.state!=CS_ALIVE && cq->state.state!=CS_DEAD && cq->state.state!=CS_EDITING) || ls!=cq->state.lifesequence || cq->state.lastspawn<0) break;
cq->state.lastspawn = -1;
@@ -3126,15 +2415,11 @@ namespace server
});
break;
}
-
- case N_SUICIDE:
- {
+ case N_SUICIDE: {
if(cq) cq->addevent(new suicideevent);
break;
}
-
- case N_SHOOT:
- {
+ case N_SHOOT: {
shotevent *shot = new shotevent;
shot->id = getint(p);
shot->millis = cq ? cq->geteventmillis(gamemillis, shot->id) : 0;
@@ -3142,8 +2427,7 @@ namespace server
loopk(3) shot->from[k] = getint(p)/DMF;
loopk(3) shot->to[k] = getint(p)/DMF;
int hits = getint(p);
- loopk(hits)
- {
+ loopk(hits) {
if(p.overread()) break;
hitinfo &hit = shot->hits.add();
hit.target = getint(p);
@@ -3152,25 +2436,21 @@ namespace server
hit.rays = getint(p);
loopk(3) hit.dir[k] = getint(p)/DNF;
}
- if(cq)
- {
+ if(cq) {
cq->addevent(shot);
cq->setpushed();
}
else delete shot;
break;
}
-
- case N_EXPLODE:
- {
+ case N_EXPLODE: {
explodeevent *exp = new explodeevent;
int cmillis = getint(p);
exp->millis = cq ? cq->geteventmillis(gamemillis, cmillis) : 0;
exp->gun = getint(p);
exp->id = getint(p);
int hits = getint(p);
- loopk(hits)
- {
+ loopk(hits) {
if(p.overread()) break;
hitinfo &hit = exp->hits.add();
hit.target = getint(p);
@@ -3183,9 +2463,7 @@ namespace server
else delete exp;
break;
}
-
- case N_ITEMPICKUP:
- {
+ case N_ITEMPICKUP: {
int n = getint(p);
if(!cq) break;
pickupevent *pickup = new pickupevent;
@@ -3193,9 +2471,7 @@ namespace server
cq->addevent(pickup);
break;
}
-
- case N_TEXT:
- {
+ case N_TEXT: {
QUEUE_AI;
QUEUE_MSG;
getstring(text, p);
@@ -3204,14 +2480,11 @@ namespace server
if(isdedicatedserver() && cq) logoutf("%s: %s", colorname(cq), text);
break;
}
-
- case N_SAYTEAM:
- {
+ case N_SAYTEAM: {
getstring(text, p);
if(!ci || !cq || (ci->state.state==CS_SPECTATOR && !ci->local && !ci->privilege) || !m_teammode || !cq->team[0]) break;
filtertext(text, text, true, true);
- loopv(clients)
- {
+ loopv(clients) {
clientinfo *t = clients[i];
if(t==cq || t->state.state==CS_SPECTATOR || t->state.aitype != AI_NONE || strcmp(cq->team, t->team)) continue;
sendf(t->clientnum, 1, "riis", N_SAYTEAM, cq->clientnum, text);
@@ -3219,9 +2492,7 @@ namespace server
if(isdedicatedserver() && cq) logoutf("%s <%s>: %s", colorname(cq), cq->team, text);
break;
}
-
- case N_SWITCHNAME:
- {
+ case N_SWITCHNAME: {
QUEUE_MSG;
getstring(text, p);
filtertext(ci->name, text, false, false, MAXNAMELEN);
@@ -3229,20 +2500,15 @@ namespace server
QUEUE_STR(ci->name);
break;
}
-
- case N_SWITCHMODEL:
- {
+ case N_SWITCHMODEL: {
ci->playermodel = 0;
QUEUE_MSG;
break;
}
-
- case N_SWITCHTEAM:
- {
+ case N_SWITCHTEAM: {
getstring(text, p);
filtertext(text, text, false, false, MAXTEAMLEN);
- if(m_teammode && text[0] && strcmp(ci->team, text) && addteaminfo(text))
- {
+ if(m_teammode && text[0] && strcmp(ci->team, text) && addteaminfo(text)) {
if(ci->state.state==CS_ALIVE) suicide(ci);
copystring(ci->team, text);
aiman::changeteam(ci);
@@ -3250,9 +2516,7 @@ namespace server
}
break;
}
-
- case N_MAPVOTE:
- {
+ case N_MAPVOTE: {
getstring(text, p);
filtertext(text, text, false);
fixmapname(text);
@@ -3260,18 +2524,14 @@ namespace server
vote(text, reqmode, sender);
break;
}
-
- case N_ITEMLIST:
- {
+ case N_ITEMLIST: {
if((ci->state.state==CS_SPECTATOR && !ci->privilege && !ci->local) || !notgotitems || strcmp(ci->clientmap, smapname)) { while(getint(p)>=0 && !p.overread()) getint(p); break; }
int n;
- while((n = getint(p))>=0 && n<MAXENTS && !p.overread())
- {
+ while((n = getint(p))>=0 && n<MAXENTS && !p.overread()) {
server_entity se = { NOTUSED, 0, false };
while(sents.length()<=n) sents.add(se);
sents[n].type = getint(p);
- if(canspawnitem(sents[n].type))
- {
+ if(canspawnitem(sents[n].type)) {
if(m_mp(gamemode) && delayspawn(sents[n].type)) sents[n].spawntime = spawntime(sents[n].type);
else sents[n].spawned = true;
}
@@ -3279,9 +2539,7 @@ namespace server
notgotitems = false;
break;
}
-
- case N_EDITENT:
- {
+ case N_EDITENT: {
int i = getint(p);
loopk(3) getint(p);
int type = getint(p);
@@ -3289,26 +2547,21 @@ namespace server
if(!ci || ci->state.state==CS_SPECTATOR) break;
QUEUE_MSG;
bool canspawn = canspawnitem(type);
- if(i<MAXENTS && (sents.inrange(i) || canspawnitem(type)))
- {
+ if(i<MAXENTS && (sents.inrange(i) || canspawnitem(type))) {
server_entity se = { NOTUSED, 0, false };
while(sents.length()<=i) sents.add(se);
sents[i].type = type;
- if(canspawn ? !sents[i].spawned : (sents[i].spawned || sents[i].spawntime))
- {
+ if(canspawn ? !sents[i].spawned : (sents[i].spawned || sents[i].spawntime)) {
sents[i].spawntime = canspawn ? 1 : 0;
sents[i].spawned = false;
}
}
break;
}
-
- case N_EDITVAR:
- {
+ case N_EDITVAR: {
int type = getint(p);
getstring(text, p);
- switch(type)
- {
+ switch(type) {
case ID_VAR: getint(p); break;
case ID_FVAR: getfloat(p); break;
case ID_SVAR: getstring(text, p);
@@ -3316,91 +2569,69 @@ namespace server
if(ci && ci->state.state!=CS_SPECTATOR) QUEUE_MSG;
break;
}
-
case N_PING:
sendf(sender, 1, "i2", N_PONG, getint(p));
break;
-
- case N_CLIENTPING:
- {
+ case N_CLIENTPING: {
int ping = getint(p);
- if(ci)
- {
+ if(ci) {
ci->ping = ping;
loopv(ci->bots) ci->bots[i]->ping = ping;
}
QUEUE_MSG;
break;
}
-
- case N_MASTERMODE:
- {
+ case N_MASTERMODE: {
int mm = getint(p);
- if((ci->privilege || ci->local) && mm>=MM_OPEN && mm<=MM_PRIVATE)
- {
- if((ci->privilege>=PRIV_ADMIN || ci->local) || (mastermask&(1<<mm)))
- {
+ if((ci->privilege || ci->local) && mm>=MM_OPEN && mm<=MM_PRIVATE) {
+ if((ci->privilege>=PRIV_ADMIN || ci->local) || (mastermask&(1<<mm))) {
mastermode = mm;
allowedips.shrink(0);
- if(mm>=MM_PRIVATE)
- {
+ if(mm>=MM_PRIVATE) {
loopv(clients) allowedips.add(getclientip(clients[i]->clientnum));
}
sendf(-1, 1, "rii", N_MASTERMODE, mastermode);
//sendservmsgf("mastermode is now %s (%d)", mastermodename(mastermode), mastermode);
}
- else
- {
+ else {
defformatstring(s, "mastermode %d is disabled on this server", mm);
sendf(sender, 1, "ris", N_SERVMSG, s);
}
}
break;
}
-
- case N_CLEARBANS:
- {
- if(ci->privilege || ci->local)
- {
+ case N_CLEARBANS: {
+ if(ci->privilege || ci->local) {
bannedips.shrink(0);
sendservmsg("cleared all bans");
}
break;
}
-
- case N_KICK:
- {
+ case N_KICK: {
int victim = getint(p);
getstring(text, p);
filtertext(text, text);
trykick(ci, victim, text);
break;
}
-
- case N_SPECTATOR:
- {
+ case N_SPECTATOR: {
int spectator = getint(p), val = getint(p);
if(!ci->privilege && !ci->local && (spectator!=sender || (ci->state.state==CS_SPECTATOR && mastermode>=MM_LOCKED))) break;
clientinfo *spinfo = (clientinfo *)getclientinfo(spectator); // no bots
if(!spinfo || !spinfo->connected || (spinfo->state.state==CS_SPECTATOR ? val : !val)) break;
-
if(spinfo->state.state!=CS_SPECTATOR && val) forcespectator(spinfo);
else if(spinfo->state.state==CS_SPECTATOR && !val) unspectate(spinfo);
-
if(cq && cq != ci && cq->ownernum != ci->clientnum) cq = NULL;
break;
}
-
- case N_SETTEAM:
- {
+ case N_SETTEAM: {
int who = getint(p);
getstring(text, p);
filtertext(text, text, false, false, MAXTEAMLEN);
if(!ci->privilege && !ci->local) break;
clientinfo *wi = getinfo(who);
if(!m_teammode || !text[0] || !wi || !wi->connected || !strcmp(wi->team, text)) break;
- if(addteaminfo(text))
- {
+ if(addteaminfo(text)) {
if(wi->state.state==CS_ALIVE) suicide(wi);
copystring(wi->team, text, MAXTEAMLEN+1);
}
@@ -3408,17 +2639,13 @@ namespace server
sendf(-1, 1, "riisi", N_SETTEAM, who, wi->team, 1);
break;
}
-
case N_FORCEINTERMISSION:
if(ci->local && !hasnonlocalclients()) startintermission();
break;
-
- case N_RECORDDEMO:
- {
+ case N_RECORDDEMO: {
int val = getint(p);
if(ci->privilege < (restrictdemos ? PRIV_ADMIN : PRIV_MASTER) && !ci->local) break;
- if(!maxdemos || !maxdemosize)
- {
+ if(!maxdemos || !maxdemosize) {
sendf(ci->clientnum, 1, "ris", N_SERVMSG, "the server has disabled demo recording");
break;
}
@@ -3426,53 +2653,41 @@ namespace server
sendservmsgf("demo recording is %s for next match", demonextmatch ? "enabled" : "disabled");
break;
}
-
- case N_STOPDEMO:
- {
+ case N_STOPDEMO: {
if(ci->privilege < (restrictdemos ? PRIV_ADMIN : PRIV_MASTER) && !ci->local) break;
stopdemo();
break;
}
-
- case N_CLEARDEMOS:
- {
+ case N_CLEARDEMOS: {
int demo = getint(p);
if(ci->privilege < (restrictdemos ? PRIV_ADMIN : PRIV_MASTER) && !ci->local) break;
cleardemos(demo);
break;
}
-
case N_LISTDEMOS:
if(!ci->privilege && !ci->local && ci->state.state==CS_SPECTATOR) break;
listdemos(sender);
break;
-
- case N_GETDEMO:
- {
+ case N_GETDEMO: {
int n = getint(p), tag = getint(p);
if(!ci->privilege && !ci->local && ci->state.state==CS_SPECTATOR) break;
senddemo(ci, n, tag);
break;
}
-
case N_GETMAP:
if(!mapdata) sendf(sender, 1, "ris", N_SERVMSG, "no map to send");
else if(ci->getmap) sendf(sender, 1, "ris", N_SERVMSG, "already sending map");
- else
- {
+ else {
sendservmsgf("[%s is getting the map]", colorname(ci));
if((ci->getmap = sendfile(sender, 2, mapdata, "ri", N_SENDMAP)))
ci->getmap->freeCallback = freegetmap;
ci->needclipboard = totalmillis ? totalmillis : 1;
}
break;
-
- case N_NEWMAP:
- {
+ case N_NEWMAP: {
int size = getint(p);
if(!ci->privilege && !ci->local && ci->state.state==CS_SPECTATOR) break;
- if(size>=0)
- {
+ if(size>=0) {
smapname[0] = '\0';
resetitems();
notgotitems = false;
@@ -3480,13 +2695,10 @@ namespace server
QUEUE_MSG;
break;
}
-
- case N_SETMASTER:
- {
+ case N_SETMASTER: {
int mn = getint(p), val = getint(p);
getstring(text, p);
- if(mn != ci->clientnum)
- {
+ if(mn != ci->clientnum) {
if(!ci->privilege && !ci->local) break;
clientinfo *minfo = (clientinfo *)getclientinfo(mn);
if(!minfo || !minfo->connected || (!ci->local && minfo->privilege >= ci->privilege) || (val && minfo->privilege)) break;
@@ -3496,44 +2708,32 @@ namespace server
// don't broadcast the master password
break;
}
-
- case N_ADDBOT:
- {
+ case N_ADDBOT: {
aiman::reqadd(ci, getint(p));
break;
}
-
- case N_DELBOT:
- {
+ case N_DELBOT: {
aiman::reqdel(ci);
break;
}
-
- case N_BOTLIMIT:
- {
+ case N_BOTLIMIT: {
int limit = getint(p);
if(ci) aiman::setbotlimit(ci, limit);
break;
}
-
- case N_BOTBALANCE:
- {
+ case N_BOTBALANCE: {
int balance = getint(p);
if(ci) aiman::setbotbalance(ci, balance!=0);
break;
}
-
- case N_AUTHTRY:
- {
+ case N_AUTHTRY: {
string desc, name;
getstring(desc, p, sizeof(desc));
getstring(name, p, sizeof(name));
tryauth(ci, name, desc);
break;
}
-
- case N_AUTHKICK:
- {
+ case N_AUTHKICK: {
string desc, name;
getstring(desc, p, sizeof(desc));
getstring(name, p, sizeof(name));
@@ -3541,22 +2741,18 @@ namespace server
getstring(text, p);
filtertext(text, text);
int authpriv = PRIV_AUTH;
- if(desc[0])
- {
+ if(desc[0]) {
userinfo *u = users.access(userkey(name, desc));
if(u) authpriv = u->privilege; else break;
}
if(ci->local || ci->privilege >= authpriv) trykick(ci, victim, text);
- else if(trykick(ci, victim, text, name, desc, authpriv, true) && tryauth(ci, name, desc))
- {
+ else if(trykick(ci, victim, text, name, desc, authpriv, true) && tryauth(ci, name, desc)) {
ci->authkickvictim = victim;
ci->authkickreason = newstring(text);
}
break;
}
-
- case N_AUTHANS:
- {
+ case N_AUTHANS: {
string desc, ans;
getstring(desc, p, sizeof(desc));
uint id = (uint)getint(p);
@@ -3564,43 +2760,33 @@ namespace server
answerchallenge(ci, id, ans, desc);
break;
}
-
- case N_PAUSEGAME:
- {
+ case N_PAUSEGAME: {
int val = getint(p);
if(ci->privilege < (restrictpausegame ? PRIV_ADMIN : PRIV_MASTER) && !ci->local) break;
pausegame(val > 0, ci);
break;
}
-
- case N_GAMESPEED:
- {
+ case N_GAMESPEED: {
int val = getint(p);
if(ci->privilege < (restrictgamespeed ? PRIV_ADMIN : PRIV_MASTER) && !ci->local) break;
changegamespeed(val, ci);
break;
}
-
case N_COPY:
ci->cleanclipboard();
ci->lastclipboard = totalmillis ? totalmillis : 1;
goto genericmsg;
-
case N_PASTE:
if(ci->state.state!=CS_SPECTATOR) sendclipboard(ci);
goto genericmsg;
-
- case N_CLIPBOARD:
- {
+ case N_CLIPBOARD: {
int unpacklen = getint(p), packlen = getint(p);
ci->cleanclipboard(false);
- if(ci->state.state==CS_SPECTATOR)
- {
+ if(ci->state.state==CS_SPECTATOR) {
if(packlen > 0) p.subbuf(packlen);
break;
}
- if(packlen <= 0 || packlen > (1<<16) || unpacklen <= 0)
- {
+ if(packlen <= 0 || packlen > (1<<16) || unpacklen <= 0) {
if(packlen > 0) p.subbuf(packlen);
packlen = unpacklen = 0;
}
@@ -3614,11 +2800,9 @@ namespace server
ci->clipboard->referenceCount++;
break;
}
-
case N_EDITT:
case N_REPLACE:
- case N_EDITVSLOT:
- {
+ case N_EDITVSLOT: {
int size = server::msgsizelookup(type);
//~if(size<=0) { disconnect_client(sender, DISC_MSGERR); return; }
loopi(size-1) getint(p);
@@ -3629,13 +2813,10 @@ namespace server
if(ci && ci->state.state!=CS_SPECTATOR) QUEUE_MSG;
break;
}
-
case N_UNDO:
- case N_REDO:
- {
+ case N_REDO: {
int unpacklen = getint(p), packlen = getint(p);
- if(!ci || ci->state.state==CS_SPECTATOR || packlen <= 0 || packlen > (1<<16) || unpacklen <= 0)
- {
+ if(!ci || ci->state.state==CS_SPECTATOR || packlen <= 0 || packlen > (1<<16) || unpacklen <= 0) {
if(packlen > 0) p.subbuf(packlen);
break;
}
@@ -3649,27 +2830,21 @@ namespace server
sendpacket(-1, 1, q.finalize(), ci->clientnum);
break;
}
-
case N_SERVCMD:
getstring(text, p);
break;
-
case -1:
//~disconnect_client(sender, DISC_MSGERR);
return;
-
case -2:
//~disconnect_client(sender, DISC_OVERFLOW);
return;
-
- default: genericmsg:
- {
+ default: genericmsg: {
int size = server::msgsizelookup(type);
//~if(size<=0) { disconnect_client(sender, DISC_MSGERR); return; }
loopi(size-1) getint(p);
- if(ci) switch(msgfilter[type])
- {
+ if(ci) switch(msgfilter[type]) {
case 2: case 3: if(ci->state.state != CS_SPECTATOR) QUEUE_MSG; break;
default: if(cq && (ci != cq || ci->state.state!=CS_SPECTATOR)) { QUEUE_AI; QUEUE_MSG; } break;
}
@@ -3677,24 +2852,18 @@ namespace server
}
}
}
-
int laninfoport() { return SAUERBRATEN_LANINFO_PORT; }
int serverinfoport(int servport) { return servport < 0 ? SAUERBRATEN_SERVINFO_PORT : servport+1; }
int serverport(int infoport) { return infoport < 0 ? SAUERBRATEN_SERVER_PORT : infoport-1; }
const char *defaultmaster() { return "master.sauerbraten.org"; }
int masterport() { return SAUERBRATEN_MASTER_PORT; }
int numchannels() { return 3; }
-
#include "extinfo.h"
-
- void serverinforeply(ucharbuf &req, ucharbuf &p)
- {
- if(req.remaining() && !getint(req))
- {
+ void serverinforeply(ucharbuf &req, ucharbuf &p) {
+ if(req.remaining() && !getint(req)) {
extserverinforeply(req, p);
return;
}
-
putint(p, numclients(-1, false, true));
putint(p, gamepaused || gamespeed != 100 ? 7 : 5); // number of attrs following
putint(p, PROTOCOL_VERSION); // generic attributes, passed back below
@@ -3702,8 +2871,7 @@ namespace server
putint(p, m_timed ? max((gamelimit - gamemillis)/1000, 0) : 0);
putint(p, maxclients);
putint(p, serverpass[0] ? MM_PASSWORD : (!m_mp(gamemode) ? MM_PRIVATE : (mastermode || mastermask&MM_AUTOAPPROVE ? mastermode : MM_AUTH)));
- if(gamepaused || gamespeed != 100)
- {
+ if(gamepaused || gamespeed != 100) {
putint(p, gamepaused ? 1 : 0);
putint(p, gamespeed);
}
@@ -3711,7 +2879,6 @@ namespace server
sendstring(serverdesc, p);
sendserverinforeply(p);
}
-
#include "aiman.h"
}
diff --git a/src/fpsgame/waypoint.cpp b/src/fpsgame/waypoint.cpp
index 30a1403..05afb6c 100644
--- a/src/fpsgame/waypoint.cpp
+++ b/src/fpsgame/waypoint.cpp
@@ -2,26 +2,19 @@
extern selinfo sel;
-namespace ai
-{
+namespace ai {
using namespace game;
-
vector<waypoint> waypoints;
-
- bool clipped(const vec &o)
- {
+ bool clipped(const vec &o) {
int material = lookupmaterial(o), clipmat = material&MATF_CLIP;
return clipmat == MAT_CLIP || material&MAT_DEATH;
}
-
- int getweight(const vec &o)
- {
+ int getweight(const vec &o) {
vec pos = o; pos.z += ai::JUMPMIN;
if(!insideworld(vec(pos.x, pos.y, min(pos.z, getworldsize() - 1e-3f)))) return -2;
float dist = raycube(pos, vec(0, 0, -1), 0, RAY_CLIPMAT);
int weight = 1;
- if(dist >= 0)
- {
+ if(dist >= 0) {
weight = int(dist/ai::JUMPMIN);
pos.z -= clamp(dist-8.0f, 0.0f, pos.z);
int trgmat = lookupmaterial(pos);
@@ -29,46 +22,33 @@ namespace ai
}
return weight;
}
-
- enum
- {
+ enum {
WPCACHE_STATIC = 0,
WPCACHE_DYNAMIC,
NUMWPCACHES
};
-
- struct wpcache
- {
- struct node
- {
+ struct wpcache {
+ struct node {
float split[2];
uint child[2];
-
int axis() const { return child[0]>>30; }
int childindex(int which) const { return child[which]&0x3FFFFFFF; }
bool isleaf(int which) const { return (child[1]&(1<<(30+which)))!=0; }
};
-
vector<node> nodes;
int firstwp, lastwp;
vec bbmin, bbmax;
-
wpcache() { clear(); }
-
- void clear()
- {
+ void clear() {
nodes.setsize(0);
firstwp = lastwp = -1;
bbmin = vec(1e16f, 1e16f, 1e16f);
bbmax = vec(-1e16f, -1e16f, -1e16f);
}
-
- void build(int first = 0, int last = -1)
- {
+ void build(int first = 0, int last = -1) {
if(last < 0) last = waypoints.length();
vector<int> indices;
- for(int i = first; i < last; i++)
- {
+ for(int i = first; i < last; i++) {
waypoint &w = waypoints[i];
indices.add(i);
if(firstwp < 0) firstwp = i;
@@ -77,34 +57,27 @@ namespace ai
bbmax.max(vec(w.o).add(radius));
}
if(first < last) lastwp = max(lastwp, last-1);
- if(indices.length())
- {
+ if(indices.length()) {
nodes.reserve(indices.length());
build(indices.getbuf(), indices.length(), bbmin, bbmax);
}
}
-
- void build(int *indices, int numindices, const vec &vmin, const vec &vmax)
- {
+ void build(int *indices, int numindices, const vec &vmin, const vec &vmax) {
int axis = 2;
loopk(2) if(vmax[k] - vmin[k] > vmax[axis] - vmin[axis]) axis = k;
-
vec leftmin(1e16f, 1e16f, 1e16f), leftmax(-1e16f, -1e16f, -1e16f), rightmin(1e16f, 1e16f, 1e16f), rightmax(-1e16f, -1e16f, -1e16f);
float split = 0.5f*(vmax[axis] + vmin[axis]), splitleft = -1e16f, splitright = 1e16f;
int left, right;
- for(left = 0, right = numindices; left < right;)
- {
+ for(left = 0, right = numindices; left < right;) {
waypoint &w = waypoints[indices[left]];
float radius = WAYPOINTRADIUS;
- if(max(split - (w.o[axis]-radius), 0.0f) > max((w.o[axis]+radius) - split, 0.0f))
- {
+ if(max(split - (w.o[axis]-radius), 0.0f) > max((w.o[axis]+radius) - split, 0.0f)) {
++left;
splitleft = max(splitleft, w.o[axis]+radius);
leftmin.min(vec(w.o).sub(radius));
leftmax.max(vec(w.o).add(radius));
}
- else
- {
+ else {
--right;
swap(indices[left], indices[right]);
splitright = min(splitright, w.o[axis]-radius);
@@ -112,111 +85,84 @@ namespace ai
rightmax.max(vec(w.o).add(radius));
}
}
-
- if(!left || right==numindices)
- {
+ if(!left || right==numindices) {
leftmin = rightmin = vec(1e16f, 1e16f, 1e16f);
leftmax = rightmax = vec(-1e16f, -1e16f, -1e16f);
left = right = numindices/2;
splitleft = -1e16f;
splitright = 1e16f;
- loopi(numindices)
- {
+ loopi(numindices) {
waypoint &w = waypoints[indices[i]];
float radius = WAYPOINTRADIUS;
- if(i < left)
- {
+ if(i < left) {
splitleft = max(splitleft, w.o[axis]+radius);
leftmin.min(vec(w.o).sub(radius));
leftmax.max(vec(w.o).add(radius));
}
- else
- {
+ else {
splitright = min(splitright, w.o[axis]-radius);
rightmin.min(vec(w.o).sub(radius));
rightmax.max(vec(w.o).add(radius));
}
}
}
-
int offset = nodes.length();
node &curnode = nodes.add();
curnode.split[0] = splitleft;
curnode.split[1] = splitright;
-
if(left<=1) curnode.child[0] = (axis<<30) | (left>0 ? indices[0] : 0x3FFFFFFF);
- else
- {
+ else {
curnode.child[0] = (axis<<30) | (nodes.length()-offset);
if(left) build(indices, left, leftmin, leftmax);
}
-
if(numindices-right<=1) curnode.child[1] = (1<<31) | (left<=1 ? 1<<30 : 0) | (numindices-right>0 ? indices[right] : 0x3FFFFFFF);
- else
- {
+ else {
curnode.child[1] = (left<=1 ? 1<<30 : 0) | (nodes.length()-offset);
if(numindices-right) build(&indices[right], numindices-right, rightmin, rightmax);
}
}
} wpcaches[NUMWPCACHES];
-
static int invalidatedwpcaches = 0, clearedwpcaches = (1<<NUMWPCACHES)-1, numinvalidatewpcaches = 0, lastwpcache = 0;
-
- static inline void invalidatewpcache(int wp)
- {
+ static inline void invalidatewpcache(int wp) {
if(++numinvalidatewpcaches >= 1000) { numinvalidatewpcaches = 0; invalidatedwpcaches = (1<<NUMWPCACHES)-1; }
- else
- {
+ else {
loopi(WPCACHE_DYNAMIC) if(wp >= wpcaches[i].firstwp && wp <= wpcaches[i].lastwp) { invalidatedwpcaches |= 1<<i; return; }
invalidatedwpcaches |= 1<<WPCACHE_DYNAMIC;
}
}
-
- void clearwpcache(bool full = true)
- {
+ void clearwpcache(bool full = true) {
loopi(NUMWPCACHES) if(full || invalidatedwpcaches&(1<<i)) { wpcaches[i].clear(); clearedwpcaches |= 1<<i; }
- if(full || invalidatedwpcaches == (1<<NUMWPCACHES)-1)
- {
+ if(full || invalidatedwpcaches == (1<<NUMWPCACHES)-1) {
numinvalidatewpcaches = 0;
lastwpcache = 0;
}
invalidatedwpcaches = 0;
}
ICOMMAND(clearwpcache, "", (), clearwpcache());
-
avoidset wpavoid;
-
- void buildwpcache()
- {
+ void buildwpcache() {
loopi(NUMWPCACHES) if(wpcaches[i].firstwp < 0)
wpcaches[i].build(i > 0 ? wpcaches[i-1].lastwp+1 : 1, i+1 >= NUMWPCACHES || wpcaches[i+1].firstwp < 0 ? -1 : wpcaches[i+1].firstwp);
clearedwpcaches = 0;
lastwpcache = waypoints.length();
-
wpavoid.clear();
loopv(waypoints) if(waypoints[i].weight < 0) wpavoid.avoidnear(NULL, waypoints[i].o.z + WAYPOINTRADIUS, waypoints[i].o, WAYPOINTRADIUS);
}
-
- struct wpcachestack
- {
+ struct wpcachestack {
wpcache::node *node;
float tmin, tmax;
};
-
vector<wpcache::node *> wpcachestack;
-
- int closestwaypoint(const vec &pos, float mindist, bool links, fpsent *d)
- {
+ int closestwaypoint(const vec &pos, float mindist, bool links) {
if(waypoints.empty()) return -1;
if(clearedwpcaches) buildwpcache();
-
#define CHECKCLOSEST(index) do { \
int n = (index); \
- if(n < waypoints.length()) \
- { \
+ if(n < waypoints.length()) { \
+ \
const waypoint &w = waypoints[n]; \
- if(!links || w.links[0]) \
- { \
+ if(!links || w.links[0]) { \
+ \
float dist = w.o.squaredist(pos); \
if(dist < mindist*mindist) { closest = n; mindist = sqrtf(dist); } \
} \
@@ -224,31 +170,24 @@ namespace ai
} while(0)
int closest = -1;
wpcache::node *curnode;
- loop(which, NUMWPCACHES) if(wpcaches[which].firstwp >= 0) for(curnode = &wpcaches[which].nodes[0], wpcachestack.setsize(0);;)
- {
+ loop(which, NUMWPCACHES) if(wpcaches[which].firstwp >= 0) for(curnode = &wpcaches[which].nodes[0], wpcachestack.setsize(0);;) {
int axis = curnode->axis();
float dist1 = pos[axis] - curnode->split[0], dist2 = curnode->split[1] - pos[axis];
- if(dist1 >= mindist)
- {
- if(dist2 < mindist)
- {
+ if(dist1 >= mindist) {
+ if(dist2 < mindist) {
if(!curnode->isleaf(1)) { curnode += curnode->childindex(1); continue; }
CHECKCLOSEST(curnode->childindex(1));
}
}
- else if(curnode->isleaf(0))
- {
+ else if(curnode->isleaf(0)) {
CHECKCLOSEST(curnode->childindex(0));
- if(dist2 < mindist)
- {
+ if(dist2 < mindist) {
if(!curnode->isleaf(1)) { curnode += curnode->childindex(1); continue; }
CHECKCLOSEST(curnode->childindex(1));
}
}
- else
- {
- if(dist2 < mindist)
- {
+ else {
+ if(dist2 < mindist) {
if(!curnode->isleaf(1)) wpcachestack.add(curnode + curnode->childindex(1));
else CHECKCLOSEST(curnode->childindex(1));
}
@@ -261,48 +200,38 @@ namespace ai
for(int i = lastwpcache; i < waypoints.length(); i++) { CHECKCLOSEST(i); }
return closest;
}
-
- void findwaypointswithin(const vec &pos, float mindist, float maxdist, vector<int> &results)
- {
+ void findwaypointswithin(const vec &pos, float mindist, float maxdist, vector<int> &results) {
if(waypoints.empty()) return;
if(clearedwpcaches) buildwpcache();
-
float mindist2 = mindist*mindist, maxdist2 = maxdist*maxdist;
#define CHECKWITHIN(index) do { \
int n = (index); \
- if(n < waypoints.length()) \
- { \
+ if(n < waypoints.length()) { \
+ \
const waypoint &w = waypoints[n]; \
float dist = w.o.squaredist(pos); \
if(dist > mindist2 && dist < maxdist2) results.add(n); \
} \
} while(0)
wpcache::node *curnode;
- loop(which, NUMWPCACHES) if(wpcaches[which].firstwp >= 0) for(curnode = &wpcaches[which].nodes[0], wpcachestack.setsize(0);;)
- {
+ loop(which, NUMWPCACHES) if(wpcaches[which].firstwp >= 0) for(curnode = &wpcaches[which].nodes[0], wpcachestack.setsize(0);;) {
int axis = curnode->axis();
float dist1 = pos[axis] - curnode->split[0], dist2 = curnode->split[1] - pos[axis];
- if(dist1 >= maxdist)
- {
- if(dist2 < maxdist)
- {
+ if(dist1 >= maxdist) {
+ if(dist2 < maxdist) {
if(!curnode->isleaf(1)) { curnode += curnode->childindex(1); continue; }
CHECKWITHIN(curnode->childindex(1));
}
}
- else if(curnode->isleaf(0))
- {
+ else if(curnode->isleaf(0)) {
CHECKWITHIN(curnode->childindex(0));
- if(dist2 < maxdist)
- {
+ if(dist2 < maxdist) {
if(!curnode->isleaf(1)) { curnode += curnode->childindex(1); continue; }
CHECKWITHIN(curnode->childindex(1));
}
}
- else
- {
- if(dist2 < maxdist)
- {
+ else {
+ if(dist2 < maxdist) {
if(!curnode->isleaf(1)) wpcachestack.add(curnode + curnode->childindex(1));
else CHECKWITHIN(curnode->childindex(1));
}
@@ -314,47 +243,37 @@ namespace ai
}
for(int i = lastwpcache; i < waypoints.length(); i++) { CHECKWITHIN(i); }
}
-
- void avoidset::avoidnear(void *owner, float above, const vec &pos, float limit)
- {
+ void avoidset::avoidnear(void *owner, float above, const vec &pos, float limit) {
if(ai::waypoints.empty()) return;
if(clearedwpcaches) buildwpcache();
-
float limit2 = limit*limit;
#define CHECKNEAR(index) do { \
int n = (index); \
- if(n < ai::waypoints.length()) \
- { \
+ if(n < ai::waypoints.length()) { \
+ \
const waypoint &w = ai::waypoints[n]; \
if(w.o.squaredist(pos) < limit2) add(owner, above, n); \
} \
} while(0)
wpcache::node *curnode;
- loop(which, NUMWPCACHES) if(wpcaches[which].firstwp >= 0) for(curnode = &wpcaches[which].nodes[0], wpcachestack.setsize(0);;)
- {
+ loop(which, NUMWPCACHES) if(wpcaches[which].firstwp >= 0) for(curnode = &wpcaches[which].nodes[0], wpcachestack.setsize(0);;) {
int axis = curnode->axis();
float dist1 = pos[axis] - curnode->split[0], dist2 = curnode->split[1] - pos[axis];
- if(dist1 >= limit)
- {
- if(dist2 < limit)
- {
+ if(dist1 >= limit) {
+ if(dist2 < limit) {
if(!curnode->isleaf(1)) { curnode += curnode->childindex(1); continue; }
CHECKNEAR(curnode->childindex(1));
}
}
- else if(curnode->isleaf(0))
- {
+ else if(curnode->isleaf(0)) {
CHECKNEAR(curnode->childindex(0));
- if(dist2 < limit)
- {
+ if(dist2 < limit) {
if(!curnode->isleaf(1)) { curnode += curnode->childindex(1); continue; }
CHECKNEAR(curnode->childindex(1));
}
}
- else
- {
- if(dist2 < limit)
- {
+ else {
+ if(dist2 < limit) {
if(!curnode->isleaf(1)) wpcachestack.add(curnode + curnode->childindex(1));
else CHECKNEAR(curnode->childindex(1));
}
@@ -366,27 +285,21 @@ namespace ai
}
for(int i = lastwpcache; i < waypoints.length(); i++) { CHECKNEAR(i); }
}
-
- int avoidset::remap(fpsent *d, int n, vec &pos, bool retry)
- {
- if(!obstacles.empty())
- {
+ int avoidset::remap(fpsent *d, int n, vec &pos, bool retry) {
+ if(!obstacles.empty()) {
int cur = 0;
- loopv(obstacles)
- {
+ loopv(obstacles) {
obstacle &ob = obstacles[i];
int next = cur + ob.numwaypoints;
- if(ob.owner != d)
- {
- for(; cur < next; cur++) if(waypoints[cur] == n)
- {
+ if(ob.owner != d) {
+ for(; cur < next; cur++) if(waypoints[cur] == n) {
if(ob.above < 0) return retry ? n : -1;
vec above(pos.x, pos.y, ob.above);
if(above.z-d->o.z >= ai::JUMPMAX)
return retry ? n : -1; // too much scotty
- int node = closestwaypoint(above, ai::SIGHTMIN, true, d);
- if(ai::iswaypoint(node) && node != n)
- { // try to reroute above their head?
+ int node = closestwaypoint(above, ai::SIGHTMIN, true);
+ if(ai::iswaypoint(node) && node != n) {
+ // try to reroute above their head?
if(!find(node, d))
{
pos = ai::waypoints[node].o;
@@ -394,8 +307,7 @@ namespace ai
}
else return retry ? n : -1;
}
- else
- {
+ else {
vec old = d->o;
d->o = vec(above).add(vec(0, 0, d->eyeheight));
bool col = collide(d, vec(0, 0, 1));
@@ -414,37 +326,25 @@ namespace ai
}
return n;
}
-
static inline float heapscore(waypoint *q) { return q->score(); }
-
- bool route(fpsent *d, int node, int goal, vector<int> &route, const avoidset &obstacles, int retries)
- {
+ bool route(fpsent *d, int node, int goal, vector<int> &route, const avoidset &obstacles, int retries) {
if(waypoints.empty() || !iswaypoint(node) || !iswaypoint(goal) || goal == node || !waypoints[node].links[0])
return false;
-
static ushort routeid = 1;
static vector<waypoint *> queue;
-
- if(!routeid)
- {
+ if(!routeid) {
loopv(waypoints) waypoints[i].route = 0;
routeid = 1;
}
-
- if(d)
- {
- if(retries <= 1 && d->ai) loopi(ai::NUMPREVNODES) if(d->ai->prevnodes[i] != node && iswaypoint(d->ai->prevnodes[i]))
- {
+ if(d) {
+ if(retries <= 1 && d->ai) loopi(ai::NUMPREVNODES) if(d->ai->prevnodes[i] != node && iswaypoint(d->ai->prevnodes[i])) {
waypoints[d->ai->prevnodes[i]].route = routeid;
waypoints[d->ai->prevnodes[i]].curscore = -1;
waypoints[d->ai->prevnodes[i]].estscore = 0;
}
- if(retries <= 0)
- {
- loopavoid(obstacles, d,
- {
- if(iswaypoint(wp) && wp != node && wp != goal && waypoints[node].find(wp) < 0 && waypoints[goal].find(wp) < 0)
- {
+ if(retries <= 0) {
+ loopavoid(obstacles, d, {
+ if(iswaypoint(wp) && wp != node && wp != goal && waypoints[node].find(wp) < 0 && waypoints[goal].find(wp) < 0) {
waypoints[wp].route = routeid;
waypoints[wp].curscore = -1;
waypoints[wp].estscore = 0;
@@ -452,34 +352,28 @@ namespace ai
});
}
}
-
waypoints[node].route = routeid;
waypoints[node].curscore = waypoints[node].estscore = 0;
waypoints[node].prev = 0;
queue.setsize(0);
queue.add(&waypoints[node]);
route.setsize(0);
-
int lowest = -1;
- while(!queue.empty())
- {
+ while(!queue.empty()) {
waypoint &m = *queue.removeheap();
float prevscore = m.curscore;
m.curscore = -1;
- loopi(MAXWAYPOINTLINKS)
- {
+ loopi(MAXWAYPOINTLINKS) {
int link = m.links[i];
if(!link) break;
- if(iswaypoint(link) && (link == node || link == goal || waypoints[link].links[0]))
- {
+ if(iswaypoint(link) && (link == node || link == goal || waypoints[link].links[0])) {
waypoint &n = waypoints[link];
int weight = max(n.weight, 1);
float curscore = prevscore + n.o.dist(m.o)*weight;
if(n.route == routeid && curscore >= n.curscore) continue;
n.curscore = curscore;
n.prev = ushort(&m - &waypoints[0]);
- if(n.route != routeid)
- {
+ if(n.route != routeid) {
n.estscore = n.o.dist(waypoints[goal].o)*weight;
if(n.estscore <= WAYPOINTRADIUS*4 && (lowest < 0 || n.estscore <= waypoints[lowest].estscore))
lowest = link;
@@ -492,92 +386,68 @@ namespace ai
}
}
foundgoal:
-
routeid++;
-
- if(lowest >= 0) // otherwise nothing got there
- {
+ if(lowest >= 0) { // otherwise nothing got there {
for(waypoint *m = &waypoints[lowest]; m > &waypoints[0]; m = &waypoints[m->prev])
route.add(m - &waypoints[0]); // just keep it stored backward
}
-
return !route.empty();
}
-
VARF(dropwaypoints, 0, 0, 1, { player1->lastnode = -1; });
-
- int addwaypoint(const vec &o, int weight = -1)
- {
+ int addwaypoint(const vec &o, int weight = -1) {
if(waypoints.length() > MAXWAYPOINTS) return -1;
int n = waypoints.length();
waypoints.add(waypoint(o, weight >= 0 ? weight : getweight(o)));
invalidatewpcache(n);
return n;
}
-
- void linkwaypoint(waypoint &a, int n)
- {
- loopi(MAXWAYPOINTLINKS)
- {
+ void linkwaypoint(waypoint &a, int n) {
+ loopi(MAXWAYPOINTLINKS) {
if(a.links[i] == n) return;
if(!a.links[i]) { a.links[i] = n; return; }
}
a.links[rnd(MAXWAYPOINTLINKS)] = n;
}
-
string loadedwaypoints = "";
-
- static inline bool shouldnavigate()
- {
+ static inline bool shouldnavigate() {
if(dropwaypoints) return true;
loopvrev(players) if(players[i]->aitype != AI_NONE) return true;
return false;
}
-
- static inline bool shoulddrop(fpsent *d)
- {
+ static inline bool shoulddrop(fpsent *d) {
return !d->ai && (dropwaypoints || !loadedwaypoints[0]);
}
-
- void inferwaypoints(fpsent *d, const vec &o, const vec &v, float mindist)
- {
+ void inferwaypoints(fpsent *d, const vec &o, const vec &v, float mindist) {
if(!shouldnavigate()) return;
- if(shoulddrop(d))
- {
+ if(shoulddrop(d)) {
if(waypoints.empty()) seedwaypoints();
int from = closestwaypoint(o, mindist, false), to = closestwaypoint(v, mindist, false);
if(!iswaypoint(from)) from = addwaypoint(o);
if(!iswaypoint(to)) to = addwaypoint(v);
if(d->lastnode != from && iswaypoint(d->lastnode) && iswaypoint(from))
linkwaypoint(waypoints[d->lastnode], from);
- if(iswaypoint(to))
- {
+ if(iswaypoint(to)) {
if(from != to && iswaypoint(from) && iswaypoint(to))
linkwaypoint(waypoints[from], to);
d->lastnode = to;
}
}
- else d->lastnode = closestwaypoint(v, WAYPOINTRADIUS*2, false, d);
+ else d->lastnode = closestwaypoint(v, WAYPOINTRADIUS*2, false);
}
-
- void navigate(fpsent *d)
- {
+ void navigate(fpsent *d) {
vec v(d->feetpos());
if(d->state != CS_ALIVE) { d->lastnode = -1; return; }
bool dropping = shoulddrop(d);
int mat = lookupmaterial(v);
if((mat&MATF_CLIP) == MAT_CLIP || mat&MAT_DEATH) dropping = false;
float dist = dropping ? WAYPOINTRADIUS : (d->ai ? WAYPOINTRADIUS : SIGHTMIN);
- int curnode = closestwaypoint(v, dist, false, d), prevnode = d->lastnode;
- if(!iswaypoint(curnode) && dropping)
- {
+ int curnode = closestwaypoint(v, dist, false), prevnode = d->lastnode;
+ if(!iswaypoint(curnode) && dropping) {
if(waypoints.empty()) seedwaypoints();
curnode = addwaypoint(v);
}
- if(iswaypoint(curnode))
- {
- if(dropping && d->lastnode != curnode && iswaypoint(d->lastnode))
- {
+ if(iswaypoint(curnode)) {
+ if(dropping && d->lastnode != curnode && iswaypoint(d->lastnode)) {
linkwaypoint(waypoints[d->lastnode], curnode);
if(!d->timeinair) linkwaypoint(waypoints[curnode], d->lastnode);
}
@@ -585,35 +455,26 @@ namespace ai
if(d->ai && iswaypoint(prevnode) && d->lastnode != prevnode) d->ai->addprevnode(prevnode);
}
else if(!iswaypoint(d->lastnode) || waypoints[d->lastnode].o.squaredist(v) > SIGHTMIN*SIGHTMIN)
- d->lastnode = closestwaypoint(v, SIGHTMAX, false, d);
+ d->lastnode = closestwaypoint(v, SIGHTMAX, false);
}
-
- void navigate()
- {
+ void navigate() {
if(shouldnavigate()) loopv(players) ai::navigate(players[i]);
if(invalidatedwpcaches) clearwpcache(false);
}
-
- void clearwaypoints(bool full)
- {
+ void clearwaypoints(bool full) {
waypoints.setsize(0);
clearwpcache();
- if(full)
- {
+ if(full) {
loadedwaypoints[0] = '\0';
dropwaypoints = 0;
}
}
ICOMMAND(clearwaypoints, "", (), clearwaypoints());
-
- void seedwaypoints()
- {
+ void seedwaypoints() {
if(waypoints.empty()) addwaypoint(vec(0, 0, 0));
- loopv(entities::ents)
- {
+ loopv(entities::ents) {
extentity &e = *entities::ents[i];
- switch(e.type)
- {
+ switch(e.type) {
case PLAYERSTART: case TELEPORT: case JUMPPAD:
addwaypoint(e.o);
break;
@@ -623,21 +484,17 @@ namespace ai
}
}
}
-
- void remapwaypoints()
- {
+ void remapwaypoints() {
vector<ushort> remap;
int total = 0;
loopv(waypoints) remap.add(waypoints[i].links[1] == 0xFFFF ? 0 : total++);
total = 0;
- loopvj(waypoints)
- {
+ loopvj(waypoints) {
if(waypoints[j].links[1] == 0xFFFF) continue;
waypoint &w = waypoints[total];
if(j != total) w = waypoints[j];
int k = 0;
- loopi(MAXWAYPOINTLINKS)
- {
+ loopi(MAXWAYPOINTLINKS) {
int link = w.links[i];
if(!link) break;
if((w.links[k] = remap[link])) k++;
@@ -647,22 +504,17 @@ namespace ai
}
waypoints.setsize(total);
}
-
- bool cleanwaypoints()
- {
+ bool cleanwaypoints() {
int cleared = 0;
- for(int i = 1; i < waypoints.length(); i++)
- {
+ for(int i = 1; i < waypoints.length(); i++) {
waypoint &w = waypoints[i];
- if(clipped(w.o))
- {
+ if(clipped(w.o)) {
w.links[0] = 0;
w.links[1] = 0xFFFF;
cleared++;
}
}
- if(cleared)
- {
+ if(cleared) {
player1->lastnode = -1;
loopv(players) if(players[i]) players[i]->lastnode = -1;
remapwaypoints();
@@ -671,37 +523,28 @@ namespace ai
}
return false;
}
-
- bool getwaypointfile(const char *mname, char *wptname)
- {
+ bool getwaypointfile(const char *mname, char *wptname) {
if(!mname || !*mname) mname = getclientmap();
if(!*mname) return false;
-
string pakname, mapname, cfgname;
getmapfilenames(mname, NULL, pakname, mapname, cfgname);
nformatstring(wptname, MAXSTRLEN, "packages/%s.wpt", mapname);
path(wptname);
return true;
}
-
- void loadwaypoints(bool force, const char *mname)
- {
+ void loadwaypoints(bool force, const char *mname) {
string wptname;
if(!getwaypointfile(mname, wptname)) return;
if(!force && (waypoints.length() || !strcmp(loadedwaypoints, wptname))) return;
-
stream *f = opengzfile(wptname, "rb");
if(!f) return;
char magic[4];
if(f->read(magic, 4) < 4 || memcmp(magic, "OWPT", 4)) { delete f; return; }
-
copystring(loadedwaypoints, wptname);
-
waypoints.setsize(0);
waypoints.add(vec(0, 0, 0));
ushort numwp = f->getlil<ushort>();
- loopi(numwp)
- {
+ loopi(numwp) {
if(f->end()) break;
vec o;
o.x = f->getlil<float>();
@@ -709,35 +552,26 @@ namespace ai
o.z = f->getlil<float>();
waypoint &w = waypoints.add(waypoint(o, getweight(o)));
int numlinks = f->getchar(), k = 0;
- loopi(numlinks)
- {
- if((w.links[k] = f->getlil<ushort>()))
- {
+ loopi(numlinks) {
+ if((w.links[k] = f->getlil<ushort>())) {
if(++k >= MAXWAYPOINTLINKS) break;
}
}
}
-
delete f;
conoutf("loaded %d waypoints from %s", numwp, wptname);
-
if(!cleanwaypoints()) clearwpcache();
}
ICOMMAND(loadwaypoints, "s", (char *mname), loadwaypoints(true, mname));
-
- void savewaypoints(bool force, const char *mname)
- {
+ void savewaypoints(bool force, const char *mname) {
if((!dropwaypoints && !force) || waypoints.empty()) return;
-
string wptname;
if(!getwaypointfile(mname, wptname)) return;
-
stream *f = opengzfile(wptname, "wb");
if(!f) return;
f->write("OWPT", 4);
f->putlil<ushort>(waypoints.length()-1);
- for(int i = 1; i < waypoints.length(); i++)
- {
+ for(int i = 1; i < waypoints.length(); i++) {
waypoint &w = waypoints[i];
f->putlil<float>(w.o.x);
f->putlil<float>(w.o.y);
@@ -747,55 +581,43 @@ namespace ai
f->putchar(numlinks);
loopj(numlinks) f->putlil<ushort>(w.links[j]);
}
-
delete f;
conoutf("saved %d waypoints to %s", waypoints.length()-1, wptname);
}
-
ICOMMAND(savewaypoints, "s", (char *mname), savewaypoints(true, mname));
-
- void delselwaypoints()
- {
+ void delselwaypoints() {
if(noedit(true)) return;
vec o = vec(sel.o).sub(0.1f), s = vec(sel.s).mul(sel.grid).add(o).add(0.1f);
int cleared = 0;
- for(int i = 1; i < waypoints.length(); i++)
- {
+ for(int i = 1; i < waypoints.length(); i++) {
waypoint &w = waypoints[i];
- if(w.o.x >= o.x && w.o.x <= s.x && w.o.y >= o.y && w.o.y <= s.y && w.o.z >= o.z && w.o.z <= s.z)
- {
+ if(w.o.x >= o.x && w.o.x <= s.x && w.o.y >= o.y && w.o.y <= s.y && w.o.z >= o.z && w.o.z <= s.z) {
w.links[0] = 0;
w.links[1] = 0xFFFF;
cleared++;
}
}
- if(cleared)
- {
+ if(cleared) {
player1->lastnode = -1;
remapwaypoints();
clearwpcache();
}
}
COMMAND(delselwaypoints, "");
-
- void movewaypoints(const vec &d)
- {
+ void movewaypoints(const vec &d) {
if(noedit(true)) return;
int worldsize = getworldsize();
- if(d.x < -worldsize || d.x > worldsize || d.y < -worldsize || d.y > worldsize || d.z < -worldsize || d.z > worldsize)
- {
+ if(d.x < -worldsize || d.x > worldsize || d.y < -worldsize || d.y > worldsize || d.z < -worldsize || d.z > worldsize) {
clearwaypoints();
return;
}
int cleared = 0;
- for(int i = 1; i < waypoints.length(); i++)
- {
+ for(int i = 1; i < waypoints.length(); i++) {
waypoint &w = waypoints[i];
w.o.add(d);
if(!insideworld(w.o)) { w.links[0] = 0; w.links[1] = 0xFFFF; cleared++; }
}
- if(cleared)
- {
+ if(cleared) {
player1->lastnode = -1;
remapwaypoints();
}
diff --git a/src/fpsgame/weapon.cpp b/src/fpsgame/weapon.cpp
index 1bdb302..c486110 100644
--- a/src/fpsgame/weapon.cpp
+++ b/src/fpsgame/weapon.cpp
@@ -1,37 +1,27 @@
// weapon.cpp: all shooting and effects code, projectile management
#include "game.h"
-namespace game
-{
+namespace game {
static const int OFFSETMILLIS = 500;
vec rays[MAXRAYS];
-
- struct hitmsg
- {
+ struct hitmsg {
int target, lifesequence, info1, info2;
ivec dir;
};
vector<hitmsg> hits;
-
ICOMMAND(getweapon, "", (), intret(player1->gunselect));
-
- void gunselect(int gun, fpsent *d)
- {
- if(gun!=d->gunselect)
- {
+ void gunselect(int gun, fpsent *d) {
+ if(gun!=d->gunselect) {
addmsg(N_GUNSELECT, "rci", d, gun);
playsound(S_WEAPLOAD, d == player1 ? NULL : &d->o);
}
d->gunselect = gun;
}
-
- void nextweapon(int dir, bool force = false)
- {
+ void nextweapon(int dir, bool force = false) {
if(player1->state!=CS_ALIVE) return;
dir = (dir < 0 ? NUMGUNS-1 : 1);
int gun = player1->gunselect;
- loopi(NUMGUNS)
- {
+ loopi(NUMGUNS) {
gun = (gun + dir)%NUMGUNS;
if(force || player1->ammo[gun]) break;
}
@@ -39,50 +29,39 @@ namespace game
else playsound(S_NOAMMO);
}
ICOMMAND(nextweapon, "ii", (int *dir, int *force), nextweapon(*dir, *force!=0));
-
- int getweapon(const char *name)
- {
+ int getweapon(const char *name) {
const char *abbrevs[] = { "FI", "SG", "CG", "RL", "RI", "GL", "PI" };
if(isdigit(name[0])) return parseint(name);
else loopi(sizeof(abbrevs)/sizeof(abbrevs[0])) if(!strcasecmp(abbrevs[i], name)) return i;
return -1;
}
-
- void setweapon(const char *name, bool force = false)
- {
+ void setweapon(const char *name, bool force = false) {
int gun = getweapon(name);
if(player1->state!=CS_ALIVE || gun<GUN_FIST || gun>GUN_PISTOL) return;
if(force || player1->ammo[gun]) gunselect(gun, player1);
else playsound(S_NOAMMO);
}
ICOMMAND(setweapon, "si", (char *name, int *force), setweapon(name, *force!=0));
-
- void cycleweapon(int numguns, int *guns, bool force = false)
- {
+ void cycleweapon(int numguns, int *guns, bool force = false) {
if(numguns<=0 || player1->state!=CS_ALIVE) return;
int offset = 0;
loopi(numguns) if(guns[i] == player1->gunselect) { offset = i+1; break; }
- loopi(numguns)
- {
+ loopi(numguns) {
int gun = guns[(i+offset)%numguns];
- if(gun>=0 && gun<NUMGUNS && (force || player1->ammo[gun]))
- {
+ if(gun>=0 && gun<NUMGUNS && (force || player1->ammo[gun])) {
gunselect(gun, player1);
return;
}
}
playsound(S_NOAMMO);
}
- ICOMMAND(cycleweapon, "V", (tagval *args, int numargs),
- {
+ ICOMMAND(cycleweapon, "V", (tagval *args, int numargs), {
int numguns = min(numargs, 7);
int guns[7];
loopi(numguns) guns[i] = getweapon(args[i].getstr());
cycleweapon(numguns, guns);
});
-
- void weaponswitch(fpsent *d)
- {
+ void weaponswitch(fpsent *d) {
if(d->state!=CS_ALIVE) return;
int s = d->gunselect;
if (s!=GUN_CG && d->ammo[GUN_CG]) s = GUN_CG;
@@ -92,49 +71,36 @@ namespace game
else if(s!=GUN_GL && d->ammo[GUN_GL]) s = GUN_GL;
else if(s!=GUN_PISTOL && d->ammo[GUN_PISTOL]) s = GUN_PISTOL;
else s = GUN_FIST;
-
gunselect(s, d);
}
-
- ICOMMAND(weapon, "V", (tagval *args, int numargs),
- {
+ ICOMMAND(weapon, "V", (tagval *args, int numargs), {
if(player1->state!=CS_ALIVE) return;
- loopi(7)
- {
+ loopi(7) {
const char *name = i < numargs ? args[i].getstr() : "";
- if(name[0])
- {
+ if(name[0]) {
int gun = getweapon(name);
if(gun >= GUN_FIST && gun <= GUN_PISTOL && gun != player1->gunselect && player1->ammo[gun]) { gunselect(gun, player1); return; }
} else { weaponswitch(player1); return; }
}
playsound(S_NOAMMO);
});
-
- void offsetray(const vec &from, const vec &to, int spread, float range, vec &dest)
- {
+ void offsetray(const vec &from, const vec &to, int spread, float range, vec &dest) {
vec offset;
do offset = vec(rndscale(1), rndscale(1), rndscale(1)).sub(0.5f);
while(offset.squaredlen() > 0.5f*0.5f);
offset.mul((to.dist(from)/1024)*spread);
offset.z /= 2;
dest = vec(offset).add(to);
- if(dest != from)
- {
+ if(dest != from) {
vec dir = vec(dest).sub(from).normalize();
raycubepos(from, dir, dest, range, RAY_CLIPMAT|RAY_ALPHAPOLY);
}
}
-
- void createrays(int gun, const vec &from, const vec &to) // create random spread of rays
- {
+ void createrays(int gun, const vec &from, const vec &to) { // create random spread of rays {
loopi(guns[gun].rays) offsetray(from, to, guns[gun].spread, guns[gun].range, rays[i]);
}
-
enum { BNC_GRENADE };
-
- struct bouncer : physent
- {
+ struct bouncer : physent {
int lifetime, bounces;
float lastyaw, roll;
bool local;
@@ -145,37 +111,26 @@ namespace game
float offsetheight;
int id;
entitylight light;
-
- bouncer() : bounces(0), roll(0), variant(0)
- {
+ bouncer() : bounces(0), roll(0), variant(0) {
type = ENT_BOUNCE;
}
-
- vec offsetpos()
- {
+ vec offsetpos() {
vec pos(o);
- if(offsetmillis > 0)
- {
+ if(offsetmillis > 0) {
pos.add(vec(offset).mul(offsetmillis/float(OFFSETMILLIS)));
if(offsetheight >= 0) pos.z = max(pos.z, o.z - max(offsetheight - eyeheight, 0.0f));
}
return pos;
}
-
- void limitoffset()
- {
+ void limitoffset() {
if(bouncetype == BNC_GRENADE && offsetmillis > 0 && offset.z < 0)
offsetheight = raycube(vec(o.x + offset.x, o.y + offset.y, o.z), vec(0, 0, -1), -offset.z);
else offsetheight = -1;
}
};
-
vector<bouncer *> bouncers;
-
vec hudgunorigin(int gun, const vec &from, const vec &to, fpsent *d);
-
- void newbouncer(const vec &from, const vec &to, bool local, int id, fpsent *owner, int type, int lifetime, int speed, entitylight *light = NULL)
- {
+ void newbouncer(const vec &from, const vec &to, bool local, int id, fpsent *owner, int type, int lifetime, int speed, entitylight *light = NULL) {
bouncer &bnc = *bouncers.add(new bouncer);
bnc.o = from;
bnc.radius = bnc.xradius = bnc.yradius = 1.5f;
@@ -187,18 +142,13 @@ namespace game
bnc.bouncetype = type;
bnc.id = local ? lastmillis : id;
if(light) bnc.light = *light;
-
bnc.collidetype = COLLIDE_ELLIPSE_PRECISE;
-
vec dir(to);
dir.sub(from).safenormalize();
bnc.vel = dir;
bnc.vel.mul(speed);
-
avoidcollision(&bnc, dir, owner, 0.1f);
-
- if(type==BNC_GRENADE)
- {
+ if(type==BNC_GRENADE) {
bnc.offset = hudgunorigin(GUN_GL, from, to, owner);
if(owner==followingplayer(player1) && !isthirdperson()) bnc.offset.sub(owner->o).rescale(16).add(owner->o);
}
@@ -206,37 +156,27 @@ namespace game
bnc.offset.sub(bnc.o);
bnc.offsetmillis = OFFSETMILLIS;
bnc.limitoffset();
-
bnc.resetinterp();
}
-
- void bounced(physent *d, const vec &surface)
- {
+ void bounced(physent *d, const vec &surface) {
if(d->type != ENT_BOUNCE) return;
bouncer *b = (bouncer *)d;
if(b->bounces >= 2) return;
b->bounces++;
adddecal(DECAL_BLOOD, vec(b->o).sub(vec(surface).mul(b->radius)), surface, 2.96f/b->bounces, bvec(0x60, 0xFF, 0xFF), rnd(4));
}
-
- void updatebouncers(int time)
- {
- loopv(bouncers)
- {
+ void updatebouncers(int time) {
+ loopv(bouncers) {
bouncer &bnc = *bouncers[i];
- if(bnc.bouncetype==BNC_GRENADE && bnc.vel.magnitude() > 50.0f)
- {
+ if(bnc.bouncetype==BNC_GRENADE && bnc.vel.magnitude() > 50.0f) {
vec pos = bnc.offsetpos();
regular_particle_splash(PART_SMOKE, 1, 150, pos, 0x404040, 2.4f, 50, -20);
}
vec old(bnc.o);
bool stopped = false;
if(bnc.bouncetype==BNC_GRENADE) stopped = bounce(&bnc, 0.6f, 0.5f, 0.8f) || (bnc.lifetime -= time)<0;
-
- if(stopped)
- {
- if(bnc.bouncetype==BNC_GRENADE)
- {
+ if(stopped) {
+ if(bnc.bouncetype==BNC_GRENADE) {
int qdam = guns[GUN_GL].damage*(bnc.owner->quadmillis ? 4 : 1);
hits.setsize(0);
explode(bnc.local, bnc.owner, bnc.o, NULL, qdam, GUN_GL);
@@ -247,24 +187,18 @@ namespace game
}
delete bouncers.remove(i--);
}
- else
- {
+ else {
bnc.roll += old.sub(bnc.o).magnitude()/(4*RAD);
bnc.offsetmillis = max(bnc.offsetmillis-time, 0);
bnc.limitoffset();
}
}
}
-
- void removebouncers(fpsent *owner)
- {
+ void removebouncers(fpsent *owner) {
loopv(bouncers) if(bouncers[i]->owner==owner) { delete bouncers[i]; bouncers.remove(i--); }
}
-
void clearbouncers() { bouncers.deletecontents(); }
-
- struct projectile
- {
+ struct projectile {
vec dir, o, to, offset;
float speed;
fpsent *owner;
@@ -275,11 +209,8 @@ namespace game
entitylight light;
};
vector<projectile> projs;
-
void clearprojectiles() { projs.shrink(0); }
-
- void newprojectile(const vec &from, const vec &to, float speed, bool local, int id, fpsent *owner, int gun)
- {
+ void newprojectile(const vec &from, const vec &to, float speed, bool local, int id, fpsent *owner, int gun) {
projectile &p = projs.add();
p.dir = vec(to).sub(from).safenormalize();
p.o = from;
@@ -293,69 +224,51 @@ namespace game
p.offsetmillis = OFFSETMILLIS;
p.id = local ? lastmillis : id;
}
-
- void removeprojectiles(fpsent *owner)
- {
+ void removeprojectiles(fpsent *owner) {
// can't use loopv here due to strange GCC optimizer bug
int len = projs.length();
loopi(len) if(projs[i].owner==owner) { projs.remove(i--); len--; }
}
-
VARP(blood, 0, 1, 1);
-
- void damageeffect(int damage, fpsent *d, bool thirdperson)
- {
+ void damageeffect(int damage, fpsent *d, bool thirdperson) {
vec p = d->o;
p.z += 0.6f*(d->eyeheight + d->aboveeye) - d->eyeheight;
if(blood) particle_splash(PART_BLOOD, damage/10, 1000, p, 0x60FFFF, 2.96f);
- if(thirdperson)
- {
+ if(thirdperson) {
defformatstring(ds, "%d", damage);
particle_textcopy(d->abovehead(), ds, PART_TEXT, 2000, 0xFF4B19, 4.0f, -8);
}
}
-
- void spawnbouncer(const vec &p, const vec &vel, fpsent *d, int type, entitylight *light = NULL)
- {
- vec to(rnd(100)-50, rnd(100)-50, rnd(100)-50);
- if(to.iszero()) to.z += 1;
- to.normalize();
- to.add(p);
- newbouncer(p, to, true, 0, d, type, rnd(1000)+1000, rnd(100)+20, light);
- }
-
- void hit(int damage, dynent *d, fpsent *at, const vec &vel, int gun, float info1, int info2 = 1)
- {
- if(at==player1 && d!=at)
- {
+ //~void spawnbouncer(const vec &p, const vec &vel, fpsent *d, int type, entitylight *light = NULL)
+ //~{
+ //~vec to(rnd(100)-50, rnd(100)-50, rnd(100)-50);
+ //~if(to.iszero()) to.z += 1;
+ //~to.normalize();
+ //~to.add(p);
+ //~newbouncer(p, to, true, 0, d, type, rnd(1000)+1000, rnd(100)+20, light);
+ //~}
+ void hit(int damage, dynent *d, fpsent *at, const vec &vel, int gun, float info1, int info2 = 1) {
+ if(at==player1 && d!=at) {
extern int hitsound;
if(hitsound && lasthit != lastmillis) playsound(S_HIT);
lasthit = lastmillis;
}
-
fpsent *f = (fpsent *)d;
-
f->lastpain = lastmillis;
if(at->type==ENT_PLAYER && !isteam(at->team, f->team)) at->totaldamage += damage;
-
if(f->type==ENT_AI || !m_mp(gamemode) || f==at) f->hitpush(damage, vel, at, gun);
-
pwhit(gun, damage);
-
if(!m_mp(gamemode)) damaged(damage, f, at);
- else
- {
+ else {
hitmsg &h = hits.add();
h.target = f->clientnum;
h.lifesequence = f->lifesequence;
h.info1 = int(info1*DMF);
h.info2 = info2;
h.dir = f==at ? ivec(0, 0, 0) : ivec(vec(vel).mul(DNF));
- if(at==player1)
- {
+ if(at==player1) {
damageeffect(damage, f);
- if(f==player1)
- {
+ if(f==player1) {
damagecompass(damage, at ? at->o : f->o);
playsound(S_PAIN6);
}
@@ -363,14 +276,10 @@ namespace game
}
}
}
-
- void hitpush(int damage, dynent *d, fpsent *at, vec &from, vec &to, int gun, int rays)
- {
+ void hitpush(int damage, dynent *d, fpsent *at, vec &from, vec &to, int gun, int rays) {
hit(damage, d, at, vec(to).sub(from).safenormalize(), gun, from.dist(to), rays);
}
-
- float projdist(dynent *o, vec &dir, const vec &v)
- {
+ float projdist(dynent *o, vec &dir, const vec &v) {
vec middle = o->o;
middle.z += (o->aboveeye-o->eyeheight)/2;
float dist = middle.dist(v, dir);
@@ -378,68 +287,53 @@ namespace game
if(dist<0) dist = 0;
return dist;
}
-
- void radialeffect(dynent *o, const vec &v, int qdam, fpsent *at, int gun)
- {
+ void radialeffect(dynent *o, const vec &v, int qdam, fpsent *at, int gun) {
if(o->state!=CS_ALIVE) return;
vec dir;
float dist = projdist(o, dir, v);
- if(dist<guns[gun].exprad)
- {
+ if(dist<guns[gun].exprad) {
int damage = (int)(qdam*(1-dist/EXP_DISTSCALE/guns[gun].exprad));
if(o==at) damage /= EXP_SELFDAMDIV;
hit(damage, o, at, dir, gun, dist);
}
}
-
FVARP(explodebright, 0, 1, 1);
-
- void explode(bool local, fpsent *owner, const vec &v, dynent *safe, int damage, int gun)
- {
+ void explode(bool local, fpsent *owner, const vec &v, dynent *safe, int damage, int gun) {
particle_splash(PART_SPARK, 200, 300, v, 0xB49B4B, 0.24f);
playsound(gun!=GUN_GL ? S_RLHIT : S_FEXPLODE, &v);
int color = gun!=GUN_GL ? 0xFF8080 : 0x80FFFF;
if((gun==GUN_RL || gun==GUN_GL) && explodebright < 1) color = vec::hexcolor(color).mul(explodebright).tohexcolor();
- particle_fireball(v, guns[gun].exprad, gun!=GUN_GL ? PART_EXPLOSION : PART_EXPLOSION_BLUE, gun!=GUN_GL ? -1 : int((guns[gun].exprad-4.0f)*15), color, 4.0f);
+ /// REPLACE THIS SHIT WITH SMOKE AND FIRE EFFECT LIKE IN XONOTIC
+ //~particle_fireball(v, guns[gun].exprad, gun!=GUN_GL ? PART_EXPLOSION : PART_EXPLOSION_BLUE, gun!=GUN_GL ? -1 : int((guns[gun].exprad-4.0f)*15), color, 4.0f);
if(gun==GUN_RL) adddynlight(v, 1.15f*guns[gun].exprad, vec(2, 1.5f, 1), 700, 100, 0, guns[gun].exprad/2, vec(1, 0.75f, 0.5f));
else if(gun==GUN_GL) adddynlight(v, 1.15f*guns[gun].exprad, vec(0.5f, 1.5f, 2), 600, 100, 0, 8, vec(0.25f, 1, 1));
else adddynlight(v, 1.15f*guns[gun].exprad, vec(2, 1.5f, 1), 700, 100);
if(!local) return;
int numdyn = numdynents();
- loopi(numdyn)
- {
+ loopi(numdyn) {
dynent *o = iterdynents(i);
if(o->o.reject(v, o->radius + guns[gun].exprad) || o==safe) continue;
radialeffect(o, v, damage, owner, gun);
}
}
-
- void projsplash(projectile &p, vec &v, dynent *safe, int damage)
- {
- if(guns[p.gun].part)
- {
+ void projsplash(projectile &p, vec &v, dynent *safe, int damage) {
+ if(guns[p.gun].part) {
particle_splash(PART_SPARK, 100, 200, v, 0xB49B4B, 0.24f);
playsound(S_FEXPLODE, &v);
// no push?
}
- else
- {
+ else {
explode(p.local, p.owner, v, safe, damage, GUN_RL);
adddecal(DECAL_SCORCH, v, vec(p.dir).neg(), guns[p.gun].exprad/2);
}
}
-
- void explodeeffects(int gun, fpsent *d, bool local, int id)
- {
+ void explodeeffects(int gun, fpsent *d, bool local, int id) {
if(local) return;
- switch(gun)
- {
+ switch(gun) {
case GUN_RL:
- loopv(projs)
- {
+ loopv(projs) {
projectile &p = projs[i];
- if(p.gun == gun && p.owner == d && p.id == id && !p.local)
- {
+ if(p.gun == gun && p.owner == d && p.id == id && !p.local) {
vec pos(p.o);
pos.add(vec(p.offset).mul(p.offsetmillis/float(OFFSETMILLIS)));
explode(p.local, p.owner, pos, NULL, 0, GUN_RL);
@@ -450,11 +344,9 @@ namespace game
}
break;
case GUN_GL:
- loopv(bouncers)
- {
+ loopv(bouncers) {
bouncer &b = *bouncers[i];
- if(b.bouncetype == BNC_GRENADE && b.owner == d && b.id == id && !b.local)
- {
+ if(b.bouncetype == BNC_GRENADE && b.owner == d && b.id == id && !b.local) {
vec pos = b.offsetpos();
explode(b.local, b.owner, pos, NULL, 0, GUN_GL);
adddecal(DECAL_SCORCH, pos, vec(0, 0, 1), guns[gun].exprad/2);
@@ -467,9 +359,7 @@ namespace game
break;
}
}
-
- bool projdamage(dynent *o, projectile &p, vec &v, int qdam)
- {
+ bool projdamage(dynent *o, projectile &p, vec &v, int qdam) {
if(o->state!=CS_ALIVE) return false;
if(!intersect(o, p.o, v)) return false;
projsplash(p, v, o, qdam);
@@ -478,11 +368,8 @@ namespace game
hit(qdam, o, p.owner, dir, p.gun, 0);
return true;
}
-
- void updateprojectiles(int time)
- {
- loopv(projs)
- {
+ void updateprojectiles(int time) {
+ loopv(projs) {
projectile &p = projs[i];
p.offsetmillis = max(p.offsetmillis-time, 0);
int qdam = guns[p.gun].damage*(p.owner->quadmillis ? 4 : 1);
@@ -492,37 +379,30 @@ namespace game
vec v = vec(p.o).add(dv);
bool exploded = false;
hits.setsize(0);
- if(p.local)
- {
+ if(p.local) {
vec halfdv = vec(dv).mul(0.5f), bo = vec(p.o).add(halfdv);
float br = max(fabs(halfdv.x), fabs(halfdv.y)) + 1;
- loopj(numdynents())
- {
+ loopj(numdynents()) {
dynent *o = iterdynents(j);
if(p.owner==o || o->o.reject(bo, o->radius + br)) continue;
if(projdamage(o, p, v, qdam)) { exploded = true; break; }
}
}
- if(!exploded)
- {
- if(dist<4)
- {
- if(p.o!=p.to) // if original target was moving, reevaluate endpoint
- {
+ if(!exploded) {
+ if(dist<4) {
+ if(p.o!=p.to) { // if original target was moving, reevaluate endpoint {
if(raycubepos(p.o, p.dir, p.to, 0, RAY_CLIPMAT|RAY_ALPHAPOLY)>=4) continue;
}
projsplash(p, v, NULL, qdam);
exploded = true;
}
- else
- {
+ else {
vec pos(v);
pos.add(vec(p.offset).mul(p.offsetmillis/float(OFFSETMILLIS)));
regular_particle_splash(PART_SMOKE, 2, 300, pos, 0x404040, 2.4f, 50, -20);
}
}
- if(exploded)
- {
+ if(exploded) {
if(p.local)
addmsg(N_EXPLODE, "rci3iv", p.owner, lastmillis-maptime, p.gun, p.id-maptime,
hits.length(), hits.length()*sizeof(hitmsg)/sizeof(int), hits.getbuf());
@@ -531,28 +411,20 @@ namespace game
else p.o = v;
}
}
-
extern int chainsawhudgun;
-
VARP(muzzleflash, 0, 1, 1);
VARP(muzzlelight, 0, 1, 1);
-
- void shoteffects(int gun, const vec &from, const vec &to, fpsent *d, bool local, int id, int prevaction) // create visual effect from a shot
- {
+ void shoteffects(int gun, const vec &from, const vec &to, fpsent *d, bool local, int id, int prevaction) { // create visual effect from a shot {
int sound = guns[gun].sound, pspeed = 25;
- switch(gun)
- {
+ switch(gun) {
case GUN_FIST:
if(d->type==ENT_PLAYER && chainsawhudgun) sound = S_CHAINSAW_ATTACK;
break;
-
- case GUN_SG:
- {
+ case GUN_SG: {
if(!local) createrays(gun, from, to);
if(muzzleflash && d->muzzle.x >= 0)
particle_flare(d->muzzle, d->muzzle, 200, PART_MUZZLE_FLASH3, 0xFFFFFF, 2.75f, d);
- loopi(guns[gun].rays)
- {
+ loopi(guns[gun].rays) {
if(d->quadmillis)
particle_trail(PART_FLAME, 400, hudgunorigin(gun, from, rays[i], d), rays[i], 0x802010, 0.6f, 36);
particle_splash(PART_SPARK, 20, 250, rays[i], 0xB49B4B, 0.24f);
@@ -562,10 +434,8 @@ namespace game
if(muzzlelight) adddynlight(hudgunorigin(gun, d->o, to, d), 30, vec(0.5f, 0.375f, 0.25f), 100, 100, DL_FLASH, 0, vec(0, 0, 0), d);
break;
}
-
case GUN_CG:
- case GUN_PISTOL:
- {
+ case GUN_PISTOL: {
particle_splash(PART_SPARK, 200, 250, to, 0xB49B4B, 0.24f);
if(d->quadmillis)
particle_trail(PART_FLAME, 400, hudgunorigin(gun, from, to, d), to, 0x802010, 0.6f, 36);
@@ -576,7 +446,6 @@ namespace game
if(muzzlelight) adddynlight(hudgunorigin(gun, d->o, to, d), gun==GUN_CG ? 30 : 15, vec(0.5f, 0.375f, 0.25f), gun==GUN_CG ? 50 : 100, gun==GUN_CG ? 50 : 100, DL_FLASH, 0, vec(0, 0, 0), d);
break;
}
-
case GUN_RL:
if(d->quadmillis)
particle_trail(PART_FLAME, 400, hudgunorigin(gun, from, to, d), to, 0x802010, 0.6f, 36);
@@ -585,9 +454,7 @@ namespace game
pspeed = guns[gun].projspeed;
newprojectile(from, to, (float)pspeed, local, id, d, gun);
break;
-
- case GUN_GL:
- {
+ case GUN_GL: {
float dist = from.dist(to);
vec up = to;
up.z += dist/8;
@@ -597,7 +464,6 @@ namespace game
newbouncer(from, up, local, id, d, BNC_GRENADE, guns[gun].ttl, guns[gun].projspeed);
break;
}
-
case GUN_RIFLE:
particle_splash(PART_SPARK, 200, 250, to, 0xB49B4B, 0.24f);
if(d->quadmillis)
@@ -609,13 +475,11 @@ namespace game
if(muzzlelight) adddynlight(hudgunorigin(gun, d->o, to, d), 25, vec(0.5f, 0.375f, 0.25f), 75, 75, DL_FLASH, 0, vec(0, 0, 0), d);
break;
}
-
bool looped = false;
if(d->attacksound >= 0 && d->attacksound != sound) d->stopattacksound();
if(d->idlesound >= 0) d->stopidlesound();
fpsent *h = followingplayer(player1);
- switch(sound)
- {
+ switch(sound) {
case S_CHAINSAW_ATTACK:
if(d->attacksound >= 0) looped = true;
d->attacksound = sound;
@@ -627,114 +491,89 @@ namespace game
}
if(d->quadmillis && lastmillis-prevaction>200 && !looped) playsound(S_ITEMPUP, d==h ? NULL : &d->o);
}
-
- void particletrack(physent *owner, vec &o, vec &d)
- {
+ void particletrack(physent *owner, vec &o, vec &d) {
if(owner->type!=ENT_PLAYER && owner->type!=ENT_AI) return;
fpsent *pl = (fpsent *)owner;
if(pl->muzzle.x < 0 || pl->lastattackgun != pl->gunselect) return;
float dist = o.dist(d);
o = pl->muzzle;
if(dist <= 0) d = o;
- else
- {
+ else {
vecfromyawpitch(owner->yaw, owner->pitch, 1, 0, d);
float newdist = raycube(owner->o, d, dist, RAY_CLIPMAT|RAY_ALPHAPOLY);
d.mul(min(newdist, dist)).add(owner->o);
}
}
-
- void dynlighttrack(physent *owner, vec &o, vec &hud)
- {
+ void dynlighttrack(physent *owner, vec &o, vec &hud) {
if(owner->type!=ENT_PLAYER && owner->type!=ENT_AI) return;
fpsent *pl = (fpsent *)owner;
if(pl->muzzle.x < 0 || pl->lastattackgun != pl->gunselect) return;
o = pl->muzzle;
hud = owner == followingplayer(player1) ? vec(pl->o).add(vec(0, 0, 2)) : pl->muzzle;
}
-
float intersectdist = 1e16f;
-
- bool intersect(dynent *d, const vec &from, const vec &to, float &dist) // if lineseg hits entity bounding box
- {
+ bool intersect(dynent *d, const vec &from, const vec &to, float &dist) { // if lineseg hits entity bounding box {
vec bottom(d->o), top(d->o);
bottom.z -= d->eyeheight;
top.z += d->aboveeye;
return linecylinderintersect(from, to, bottom, top, d->radius, dist);
}
-
- dynent *intersectclosest(const vec &from, const vec &to, fpsent *at, float &bestdist)
- {
+ dynent *intersectclosest(const vec &from, const vec &to, fpsent *at, float &bestdist) {
dynent *best = NULL;
bestdist = 1e16f;
- loopi(numdynents())
- {
+ loopi(numdynents()) {
dynent *o = iterdynents(i);
if(o==at || o->state!=CS_ALIVE) continue;
float dist;
if(!intersect(o, from, to, dist)) continue;
- if(dist<bestdist)
- {
+ if(dist<bestdist) {
best = o;
bestdist = dist;
}
}
return best;
}
-
- void shorten(vec &from, vec &target, float dist)
- {
+ void shorten(vec &from, vec &target, float dist) {
target.sub(from).mul(min(1.0f, dist)).add(from);
}
-
- void raydamage(vec &from, vec &to, fpsent *d)
- {
+ void raydamage(vec &from, vec &to, fpsent *d) {
int qdam = guns[d->gunselect].damage;
if(d->quadmillis) qdam *= 4;
dynent *o;
float dist;
- if(guns[d->gunselect].rays > 1)
- {
+ if(guns[d->gunselect].rays > 1) {
dynent *hits[MAXRAYS];
int maxrays = guns[d->gunselect].rays;
- loopi(maxrays)
- {
+ loopi(maxrays) {
if((hits[i] = intersectclosest(from, rays[i], d, dist))) shorten(from, rays[i], dist);
else adddecal(DECAL_BULLET, rays[i], vec(from).sub(rays[i]).safenormalize(), 2.0f);
}
- loopi(maxrays) if(hits[i])
- {
+ loopi(maxrays) if(hits[i]) {
o = hits[i];
hits[i] = NULL;
int numhits = 1;
- for(int j = i+1; j < maxrays; j++) if(hits[j] == o)
- {
+ for(int j = i+1; j < maxrays; j++) if(hits[j] == o) {
hits[j] = NULL;
numhits++;
}
hitpush(numhits*qdam, o, d, from, to, d->gunselect, numhits);
}
}
- else if((o = intersectclosest(from, to, d, dist)))
- {
+ else if((o = intersectclosest(from, to, d, dist))) {
shorten(from, to, dist);
hitpush(qdam, o, d, from, to, d->gunselect, 1);
}
else if(d->gunselect!=GUN_FIST) adddecal(DECAL_BULLET, to, vec(from).sub(to).safenormalize(), d->gunselect==GUN_RIFLE ? 3.0f : 2.0f);
}
-
- void shoot(fpsent *d, const vec &targ)
- {
+ void shoot(fpsent *d, const vec &targ) {
int prevaction = d->lastaction, attacktime = lastmillis-prevaction;
if(attacktime<d->gunwait) return;
d->gunwait = 0;
if((d==player1 || d->ai) && !d->attacking) return;
d->lastaction = lastmillis;
d->lastattackgun = d->gunselect;
- if(!d->ammo[d->gunselect])
- {
- if(d==player1)
- {
+ if(!d->ammo[d->gunselect]) {
+ if(d==player1) {
msgsound(S_NOAMMO, d);
d->gunwait = 600;
d->lastattackgun = -1;
@@ -743,9 +582,7 @@ namespace game
return;
}
if(d->gunselect) d->ammo[d->gunselect]--;
-
pwshot(d->gunselect); /// PW
-
vec from = d->o, to = targ, dir = vec(to).sub(from).safenormalize();
float dist = to.dist(from);
vec kickback = vec(dir).mul(guns[d->gunselect].kickamount*-2.5f);
@@ -757,65 +594,48 @@ namespace game
if(barrier > 0 && barrier < dist && (!shorten || barrier < shorten))
shorten = barrier;
if(shorten) to = vec(dir).mul(shorten).add(from);
-
if(guns[d->gunselect].rays > 1) createrays(d->gunselect, from, to);
else if(guns[d->gunselect].spread) offsetray(from, to, guns[d->gunselect].spread, guns[d->gunselect].range, to);
-
hits.setsize(0);
-
if(!guns[d->gunselect].projspeed) raydamage(from, to, d);
-
shoteffects(d->gunselect, from, to, d, true, 0, prevaction);
-
- if(d==player1 || d->ai)
- {
+ if(d==player1 || d->ai) {
addmsg(N_SHOOT, "rci2i6iv", d, lastmillis-maptime, d->gunselect,
(int)(from.x*DMF), (int)(from.y*DMF), (int)(from.z*DMF),
(int)(to.x*DMF), (int)(to.y*DMF), (int)(to.z*DMF),
hits.length(), hits.length()*sizeof(hitmsg)/sizeof(int), hits.getbuf());
}
-
d->gunwait = guns[d->gunselect].attackdelay;
if(d->gunselect == GUN_PISTOL && d->ai) d->gunwait += int(d->gunwait*(((101-d->skill)+rnd(111-d->skill))/100.f));
d->totalshots += guns[d->gunselect].damage*(d->quadmillis ? 4 : 1)*guns[d->gunselect].rays;
}
-
- void adddynlights()
- {
- loopv(projs)
- {
+ void adddynlights() {
+ loopv(projs) {
projectile &p = projs[i];
if(p.gun!=GUN_RL) continue;
vec pos(p.o);
pos.add(vec(p.offset).mul(p.offsetmillis/float(OFFSETMILLIS)));
adddynlight(pos, 20, vec(1, 0.75f, 0.5f));
}
- loopv(bouncers)
- {
+ loopv(bouncers) {
bouncer &bnc = *bouncers[i];
if(bnc.bouncetype!=BNC_GRENADE) continue;
vec pos = bnc.offsetpos();
adddynlight(pos, 8, vec(0.25f, 1, 1));
}
}
-
static const char * const projnames[2] = { "projectiles/grenade", "projectiles/rocket" };
-
void preloadbouncers() {
loopi(sizeof(projnames)/sizeof(projnames[0])) preloadmodel(projnames[i]);
}
-
- void renderbouncers()
- {
+ void renderbouncers() {
float yaw, pitch;
- loopv(bouncers)
- {
+ loopv(bouncers) {
bouncer &bnc = *bouncers[i];
vec pos = bnc.offsetpos();
vec vel(bnc.vel);
if(vel.magnitude() <= 25.0f) yaw = bnc.lastyaw;
- else
- {
+ else {
vectoyawpitch(vel, yaw, pitch);
yaw += 90;
bnc.lastyaw = yaw;
@@ -823,8 +643,7 @@ namespace game
pitch = -bnc.roll;
if(bnc.bouncetype==BNC_GRENADE)
rendermodel(&bnc.light, "projectiles/grenade", ANIM_MAPMODEL|ANIM_LOOP, pos, yaw, pitch, MDL_CULL_VFC|MDL_CULL_OCCLUDED|MDL_LIGHT|MDL_LIGHT_FAST|MDL_DYNSHADOW);
- else
- {
+ else {
const char *mdl = NULL;
int cull = MDL_CULL_VFC|MDL_CULL_DIST|MDL_CULL_OCCLUDED;
float fade = 1;
@@ -833,12 +652,9 @@ namespace game
}
}
}
-
- void renderprojectiles()
- {
+ void renderprojectiles() {
float yaw, pitch;
- loopv(projs)
- {
+ loopv(projs) {
projectile &p = projs[i];
if(p.gun!=GUN_RL) continue;
float dist = min(p.o.dist(p.to)/32.0f, 1.0f);
@@ -852,12 +668,9 @@ namespace game
rendermodel(&p.light, "projectiles/rocket", ANIM_MAPMODEL|ANIM_LOOP, v, yaw, pitch, MDL_CULL_VFC|MDL_CULL_OCCLUDED|MDL_LIGHT|MDL_LIGHT_FAST);
}
}
-
- void checkattacksound(fpsent *d, bool local)
- {
+ void checkattacksound(fpsent *d, bool local) {
int gun = -1;
- switch(d->attacksound)
- {
+ switch(d->attacksound) {
case S_CHAINSAW_ATTACK:
if(chainsawhudgun) gun = GUN_FIST;
break;
@@ -866,74 +679,57 @@ namespace game
}
if(gun >= 0 && gun < NUMGUNS &&
d->clientnum >= 0 && d->state == CS_ALIVE &&
- d->lastattackgun == gun && lastmillis - d->lastaction < guns[gun].attackdelay + 50)
- {
+ d->lastattackgun == gun && lastmillis - d->lastaction < guns[gun].attackdelay + 50) {
d->attackchan = playsound(d->attacksound, local ? NULL : &d->o, NULL, 0, -1, -1, d->attackchan);
if(d->attackchan < 0) d->attacksound = -1;
}
else d->stopattacksound();
}
-
- void checkidlesound(fpsent *d, bool local)
- {
+ void checkidlesound(fpsent *d, bool local) {
int sound = -1, radius = 0;
- if(d->clientnum >= 0 && d->state == CS_ALIVE) switch(d->gunselect)
- {
+ if(d->clientnum >= 0 && d->state == CS_ALIVE) switch(d->gunselect) {
case GUN_FIST:
- if(chainsawhudgun && d->attacksound < 0)
- {
+ if(chainsawhudgun && d->attacksound < 0) {
sound = S_CHAINSAW_IDLE;
radius = 50;
}
break;
}
- if(d->idlesound != sound)
- {
+ if(d->idlesound != sound) {
if(d->idlesound >= 0) d->stopidlesound();
- if(sound >= 0)
- {
+ if(sound >= 0) {
d->idlechan = playsound(sound, local ? NULL : &d->o, NULL, 0, -1, 100, d->idlechan, radius);
if(d->idlechan >= 0) d->idlesound = sound;
}
}
- else if(sound >= 0)
- {
+ else if(sound >= 0) {
d->idlechan = playsound(sound, local ? NULL : &d->o, NULL, 0, -1, -1, d->idlechan, radius);
if(d->idlechan < 0) d->idlesound = -1;
}
}
-
- void removeweapons(fpsent *d)
- {
+ void removeweapons(fpsent *d) {
removebouncers(d);
removeprojectiles(d);
}
-
- void updateweapons(int curtime)
- {
+ void updateweapons(int curtime) {
updateprojectiles(curtime);
pwcalcaccuracy();
if(player1->clientnum>=0 && player1->state==CS_ALIVE) shoot(player1, worldpos); // only shoot when connected to server
updatebouncers(curtime); // need to do this after the player shoots so grenades don't end up inside player's BB next frame
fpsent *following = followingplayer();
if(!following) following = player1;
- loopv(players)
- {
+ loopv(players) {
fpsent *d = players[i];
checkattacksound(d, d==following);
checkidlesound(d, d==following);
}
}
-
- void avoidweapons(ai::avoidset &obstacles, float radius)
- {
- loopv(projs)
- {
+ void avoidweapons(ai::avoidset &obstacles, float radius) {
+ loopv(projs) {
projectile &p = projs[i];
obstacles.avoidnear(NULL, p.o.z + guns[p.gun].exprad + 1, p.o, radius + guns[p.gun].exprad);
}
- loopv(bouncers)
- {
+ loopv(bouncers) {
bouncer &bnc = *bouncers[i];
if(bnc.bouncetype != BNC_GRENADE) continue;
obstacles.avoidnear(NULL, bnc.o.z + guns[GUN_GL].exprad + 1, bnc.o, radius + guns[GUN_GL].exprad);