cull away unused SP stuff
parent
562bca8646
commit
2b2ee32725
|
@ -13,28 +13,13 @@ loop i (listlen $modenames) [
|
|||
mapcomplete $mname
|
||||
]
|
||||
|
||||
spmodenames = "sp dmsp"
|
||||
loop i (listlen $spmodenames) [
|
||||
mname = (at $spmodenames $i)
|
||||
alias $mname [ if (mode (- @i 3)) [if (> $numargs 0) [map $arg1] [map]] ]
|
||||
mapcomplete $mname
|
||||
]
|
||||
|
||||
complete importcube packages/cube cgz
|
||||
|
||||
demo = [ stopdemo; if (mode -1) [if (> $numargs 0) [map $arg1] [map]] ]
|
||||
complete demo . dmo
|
||||
|
||||
speditlock = 1
|
||||
allowspedit = [ speditlock = 0; onrelease [speditlock = 1] ]
|
||||
|
||||
allowedittoggle = [
|
||||
if (&& (m_sp (getmode)) $speditlock) [
|
||||
error "you must hold" (prettylist (searchbinds "allowspedit") "or") "to toggle editing in single player modes"
|
||||
result 0
|
||||
] [
|
||||
result 1
|
||||
]
|
||||
result 1
|
||||
]
|
||||
|
||||
playermodelnum = 5
|
||||
|
|
|
@ -38,7 +38,6 @@ newgui main [
|
|||
guibutton "disconnect" "disconnect" "exit"
|
||||
] [
|
||||
guibutton "bot match.." "showgui botmatch"
|
||||
guibutton "campaign.." "showgui campaign"
|
||||
guibar
|
||||
guibutton "options.." "showgui options"
|
||||
guibutton "about.." "showgui about"
|
||||
|
@ -301,41 +300,6 @@ newgui botmatch [
|
|||
guibutton "start match.." [guionclear [startbotmatch]; showgui gamemode]
|
||||
] "bot match"
|
||||
|
||||
newgui campaign [
|
||||
guibutton "start Private Stan Sauer" "showgui privatestansauer"
|
||||
guibutton "start An Army Of One" "showgui armyofone"
|
||||
guibutton "start Lost" "sp lost" "cube"
|
||||
guibutton "start Level 9" "sp level9" "cube"
|
||||
guibar
|
||||
guibutton "start DMSP map.." "mode -2; showgui maps"
|
||||
guicheckbox "slow motion" "slowmosp"
|
||||
guitext "skill (default: 3)"
|
||||
guislider skill
|
||||
]
|
||||
|
||||
newgui armyofone [
|
||||
guilist [
|
||||
guilist [
|
||||
guibutton "Part I" "sp mpsp6a" "cube"
|
||||
guibutton "Part II" "sp mpsp6b" "cube"
|
||||
guibutton "Part III" "sp mpsp6c" "cube"
|
||||
]
|
||||
showmapshot (substr $guirolloveraction 3)
|
||||
]
|
||||
] "An Army Of One"
|
||||
|
||||
newgui privatestansauer [
|
||||
guilist [
|
||||
guilist [
|
||||
guibutton "Run N' Gun Part I" "sp mpsp9a" "cube"
|
||||
guibutton "Run N' Gun Part II" "sp mpsp9b" "cube"
|
||||
guibutton "Run N' Gun Part III" "sp mpsp9c" "cube"
|
||||
guibutton "THE SERIOUSLY BIG VALLEY" "sp mpsp10" "cube"
|
||||
]
|
||||
showmapshot (substr $guirolloveraction 3)
|
||||
]
|
||||
] "Private Stan Sauer"
|
||||
|
||||
newgui servers [
|
||||
guistayopen [
|
||||
guiservers [
|
||||
|
@ -495,8 +459,6 @@ newgui editing [
|
|||
]
|
||||
guilist [
|
||||
guibutton "teleport.." "showgui newteleport"
|
||||
guibutton "monster.." "showgui monsters"
|
||||
guibutton "trigger.." "showgui triggers"
|
||||
|
||||
guibutton "newent cartridges"
|
||||
guibutton "newent health"
|
||||
|
@ -685,45 +647,6 @@ newgui dropent [
|
|||
guicheckbox "entity selection" setting_entediting 1 0 [ entediting $setting_entediting ]
|
||||
]
|
||||
|
||||
newgui triggers [
|
||||
guibutton [invisible] [BTmm = -1; showgui trigger2]
|
||||
guibutton [a carrot] [BTmm = 23; showgui trigger2]
|
||||
guibutton [switch #1] [BTmm = 24; showgui trigger2]
|
||||
guibutton [switch #2] [BTmm = 25; showgui trigger2]
|
||||
guibutton [door #1] [BTmm = 26; showgui trigger2]
|
||||
guibutton [door #2] [BTmm = 27; showgui trigger2]
|
||||
guibutton [door #3] [BTmm = 28; showgui trigger2]
|
||||
]
|
||||
|
||||
newgui trigger2 [
|
||||
guibutton [animation loop] [BTtt = 0; showgui trigger3]
|
||||
guibutton [trigger once (popback)] [BTtt = 1; showgui trigger3]
|
||||
guibutton [trigger once (popback & rumble)] [BTtt = 2; showgui trigger3]
|
||||
guibutton [trigger once] [BTtt = 3; showgui trigger3]
|
||||
guibutton [trigger once (rumble)] [BTtt = 4; showgui trigger3]
|
||||
guibutton [trigger multiple (popback)] [BTtt = 5; showgui trigger3]
|
||||
guibutton [trigger multiple (popback & rumble)] [BTtt = 6; showgui trigger3]
|
||||
guibutton [trigger multiple] [BTtt = 7; showgui trigger3]
|
||||
guibutton [trigger multiple (rumble)] [BTtt = 8; showgui trigger3]
|
||||
guibutton [door (open once)] [BTtt = 9; showgui trigger3]
|
||||
guibutton [door (auto close)] [BTtt = 10; showgui trigger3]
|
||||
guibutton [door (locked)] [BTtt = 11; showgui trigger3]
|
||||
guibutton [vanishing trigger] [BTtt = 12; showgui trigger3]
|
||||
guibutton [vanishing trigger (rumble)] [BTtt = 13; showgui trigger3]
|
||||
guibutton [End Of Level Trigger] [BTtt = 29; showgui trigger3]
|
||||
]
|
||||
|
||||
build_trigger = [newent mapmodel $BTmm $BTtt $BTti]
|
||||
|
||||
newgui trigger3 [
|
||||
loop i 9 [
|
||||
tjt = (concat tag (concatword # $i))
|
||||
tjc = (concat BTti "=" $i ";" "build_trigger")
|
||||
guibutton $tjt $tjc
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
resetlight = [
|
||||
lightcolour = 0
|
||||
lightbright = 1
|
||||
|
@ -799,18 +722,6 @@ newgui mapmodels [
|
|||
]
|
||||
]
|
||||
|
||||
newgui monsters [
|
||||
guibutton "ogro / fireball" "newent monster 0"
|
||||
guibutton "rhino / chaingun" "newent monster 1"
|
||||
guibutton "ratamahatta / shotgun" "newent monster 2"
|
||||
guibutton "slith / rifle" "newent monster 3"
|
||||
guibutton "bauul / RL" "newent monster 4"
|
||||
guibutton "hellpig / bite" "newent monster 5"
|
||||
guibutton "knight / iceball" "newent monster 6"
|
||||
guibutton "goblin / slimeball" "newent monster 7"
|
||||
guibutton "spider / grenade" "newent monster 8"
|
||||
]
|
||||
|
||||
newgui postfx [
|
||||
guibutton "(effect OFF)" "clearpostfx"
|
||||
guibutton "rotoscope" "rotoscope 1"
|
||||
|
@ -1346,7 +1257,6 @@ newentgui spotlight "radius" "0 200"
|
|||
newentgui playerstart "direction" "0 360"
|
||||
newentgui teleport "tag" "0 20"
|
||||
newentgui teledest "direction tag" "0 360 0 20"
|
||||
newentgui monster "direction type" "0 360 0 7"
|
||||
newentgui mapmodel "direction model" "0 360 0 100"
|
||||
newentgui envmap "radius" "0 400"
|
||||
newentgui jumppad "Z Y X" "0 200 0 200 0 200"
|
||||
|
|
|
@ -50,10 +50,9 @@ enttypelist = [
|
|||
shells bullets rockets riflerounds grenades cartridges
|
||||
health healthboost greenarmour yellowarmour quaddamage
|
||||
teleport teledest
|
||||
monster carrot jumppad
|
||||
base respawnpoint
|
||||
jumppad
|
||||
base
|
||||
spotlight
|
||||
box barrel platform elevator
|
||||
flag
|
||||
]
|
||||
|
||||
|
@ -73,7 +72,6 @@ ent_action_mapmodel = [ entproperty 1 ( * $arg1 1 ) ]
|
|||
ent_action_spotlight = [ entproperty 0 ( * $arg1 5 ) ]
|
||||
ent_action_light = [ entproperty 0 ( * $arg1 5 ) ]
|
||||
ent_action_jumppad = [ entproperty 0 ( * $arg1 5 ) ]
|
||||
ent_action_respawnpoint = [ entproperty 0 ( * $arg1 15 ) ]
|
||||
ent_action_playerstart = [ entproperty 0 ( * $arg1 15 ) ]
|
||||
ent_action_envmap = [ entproperty 0 ( * $arg1 5 ) ]
|
||||
ent_action_particles = [ entproperty 0 ( * $arg1 1 ) ]
|
||||
|
@ -90,10 +88,6 @@ ent_action_health = [ ent_action_cycle $arg1 healthboost yellowarmour ]
|
|||
ent_action_healthboost = [ ent_action_cycle $arg1 greenarmour health ]
|
||||
ent_action_greenarmour = [ ent_action_cycle $arg1 yellowarmour healthboost ]
|
||||
ent_action_yellowarmour = [ ent_action_cycle $arg1 health greenarmour ]
|
||||
ent_action_box = [ entproperty 1 ( * $arg1 1 ) ]
|
||||
ent_action_barrel = [ entproperty 1 ( * $arg1 1 ) ]
|
||||
ent_action_platform = [ entproperty 1 ( * $arg1 1 ) ]
|
||||
ent_action_elevator = [ entproperty 1 ( * $arg1 1 ) ]
|
||||
|
||||
//////// Copy and Paste //////////////
|
||||
|
||||
|
@ -221,7 +215,7 @@ editfacewentpush = [
|
|||
]
|
||||
]
|
||||
|
||||
entswithdirection = "playerstart teledest mapmodel monster box barrel platform elevator"
|
||||
entswithdirection = "playerstart teledest mapmodel"
|
||||
|
||||
entdirection = [
|
||||
if ( && [enthavesel] [ = (havesel) 0 ] ) [
|
||||
|
|
|
@ -88,8 +88,6 @@ CLIENT_OBJS= \
|
|||
fpsgame/client.o \
|
||||
fpsgame/entities.o \
|
||||
fpsgame/fps.o \
|
||||
fpsgame/monster.o \
|
||||
fpsgame/movable.o \
|
||||
fpsgame/render.o \
|
||||
fpsgame/scoreboard.o \
|
||||
fpsgame/server.o \
|
||||
|
@ -401,12 +399,6 @@ fpsgame/entities.o: shared/igame.h fpsgame/ai.h
|
|||
fpsgame/fps.o: fpsgame/game.h shared/cube.h shared/tools.h shared/geom.h
|
||||
fpsgame/fps.o: shared/ents.h shared/command.h shared/iengine.h shared/igame.h
|
||||
fpsgame/fps.o: fpsgame/ai.h
|
||||
fpsgame/monster.o: fpsgame/game.h shared/cube.h shared/tools.h shared/geom.h
|
||||
fpsgame/monster.o: shared/ents.h shared/command.h shared/iengine.h
|
||||
fpsgame/monster.o: shared/igame.h fpsgame/ai.h
|
||||
fpsgame/movable.o: fpsgame/game.h shared/cube.h shared/tools.h shared/geom.h
|
||||
fpsgame/movable.o: shared/ents.h shared/command.h shared/iengine.h
|
||||
fpsgame/movable.o: shared/igame.h fpsgame/ai.h
|
||||
fpsgame/render.o: fpsgame/game.h shared/cube.h shared/tools.h shared/geom.h
|
||||
fpsgame/render.o: shared/ents.h shared/command.h shared/iengine.h
|
||||
fpsgame/render.o: shared/igame.h fpsgame/ai.h
|
||||
|
|
|
@ -497,13 +497,13 @@ bool ellipserectcollide(physent *d, const vec &dir, const vec &o, const vec &cen
|
|||
}
|
||||
if(yo.z < 0)
|
||||
{
|
||||
if(dir.iszero() || (dir.z > 0 && (d->type>=ENT_INANIMATE || below >= d->zmargin-(d->eyeheight+d->aboveeye)/4.0f)))
|
||||
if(dir.iszero() || (dir.z > 0 && (d->type>=ENT_CAMERA || below >= d->zmargin-(d->eyeheight+d->aboveeye)/4.0f)))
|
||||
{
|
||||
wall = vec(0, 0, -1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if(dir.iszero() || (dir.z < 0 && (d->type>=ENT_INANIMATE || above >= d->zmargin-(d->eyeheight+d->aboveeye)/3.0f)))
|
||||
else if(dir.iszero() || (dir.z < 0 && (d->type>=ENT_CAMERA || above >= d->zmargin-(d->eyeheight+d->aboveeye)/3.0f)))
|
||||
{
|
||||
wall = vec(0, 0, 1);
|
||||
return false;
|
||||
|
@ -536,13 +536,13 @@ bool ellipsecollide(physent *d, const vec &dir, const vec &o, const vec ¢er,
|
|||
}
|
||||
if(d->o.z < yo.z)
|
||||
{
|
||||
if(dir.iszero() || (dir.z > 0 && (d->type>=ENT_INANIMATE || below >= d->zmargin-(d->eyeheight+d->aboveeye)/4.0f)))
|
||||
if(dir.iszero() || (dir.z > 0 && (d->type>=ENT_CAMERA || below >= d->zmargin-(d->eyeheight+d->aboveeye)/4.0f)))
|
||||
{
|
||||
wall = vec(0, 0, -1);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if(dir.iszero() || (dir.z < 0 && (d->type>=ENT_INANIMATE || above >= d->zmargin-(d->eyeheight+d->aboveeye)/3.0f)))
|
||||
else if(dir.iszero() || (dir.z < 0 && (d->type>=ENT_CAMERA || above >= d->zmargin-(d->eyeheight+d->aboveeye)/3.0f)))
|
||||
{
|
||||
wall = vec(0, 0, 1);
|
||||
return false;
|
||||
|
@ -567,8 +567,8 @@ bool rectcollide(physent *d, const vec &dir, const vec &o, float xr, float yr,
|
|||
wall.x = wall.y = wall.z = 0;
|
||||
#define TRYCOLLIDE(dim, ON, OP, N, P) \
|
||||
{ \
|
||||
if(s.dim<0) { if(visible&(1<<ON) && (dir.iszero() || (dir.dim>0 && (d->type>=ENT_INANIMATE || (N))))) { wall.dim = -1; return false; } } \
|
||||
else if(visible&(1<<OP) && (dir.iszero() || (dir.dim<0 && (d->type>=ENT_INANIMATE || (P))))) { wall.dim = 1; return false; } \
|
||||
if(s.dim<0) { if(visible&(1<<ON) && (dir.iszero() || (dir.dim>0 && (d->type>=ENT_CAMERA || (N))))) { wall.dim = -1; return false; } } \
|
||||
else if(visible&(1<<OP) && (dir.iszero() || (dir.dim<0 && (d->type>=ENT_CAMERA || (P))))) { wall.dim = 1; return false; } \
|
||||
}
|
||||
if(ax>ay && ax>az) TRYCOLLIDE(x, O_LEFT, O_RIGHT, ax > -dxr, ax > -dxr);
|
||||
if(ay>az) TRYCOLLIDE(y, O_BACK, O_FRONT, ay > -dyr, ay > -dyr);
|
||||
|
@ -1075,7 +1075,6 @@ static inline bool octacollide(physent *d, const vec &dir, float cutoff, const i
|
|||
switch(c[i].material&MATF_CLIP)
|
||||
{
|
||||
case MAT_NOCLIP: continue;
|
||||
case MAT_GAMECLIP: if(d->type==ENT_AI) solid = true; break;
|
||||
case MAT_CLIP: if(isclipped(c[i].material&MATF_VOLUME) || d->type<ENT_CAMERA) solid = true; break;
|
||||
}
|
||||
if(!solid && isempty(c[i])) continue;
|
||||
|
@ -1105,7 +1104,6 @@ static inline bool octacollide(physent *d, const vec &dir, float cutoff, const i
|
|||
switch(c->material&MATF_CLIP)
|
||||
{
|
||||
case MAT_NOCLIP: return true;
|
||||
case MAT_GAMECLIP: if(d->type==ENT_AI) solid = true; break;
|
||||
case MAT_CLIP: if(isclipped(c->material&MATF_VOLUME) || d->type<ENT_CAMERA) solid = true; break;
|
||||
}
|
||||
if(!solid && isempty(*c)) return true;
|
||||
|
@ -1413,7 +1411,7 @@ bool move(physent *d, vec &dir)
|
|||
bool collided = false, slidecollide = false;
|
||||
vec obstacle;
|
||||
d->o.add(dir);
|
||||
if(!collide(d, dir) || ((d->type==ENT_AI || d->type==ENT_INANIMATE) && !collide(d, vec(0, 0, 0), 0, false)))
|
||||
if(!collide(d, dir))
|
||||
{
|
||||
obstacle = wall;
|
||||
/* check to see if there is an obstacle that would prevent this one from being used as a floor (or ceiling bump) */
|
||||
|
@ -1461,7 +1459,6 @@ bool move(physent *d, vec &dir)
|
|||
if(slide || (!collided && floor.z > 0 && floor.z < WALLZ))
|
||||
{
|
||||
slideagainst(d, dir, slide ? obstacle : floor, found, slidecollide);
|
||||
//if(d->type == ENT_AI || d->type == ENT_INANIMATE)
|
||||
d->blocked = true;
|
||||
}
|
||||
if(found) landing(d, dir, floor, collided);
|
||||
|
@ -1917,164 +1914,6 @@ void updatephysstate(physent *d)
|
|||
d->o = old;
|
||||
}
|
||||
|
||||
const float PLATFORMMARGIN = 0.2f;
|
||||
const float PLATFORMBORDER = 10.0f;
|
||||
|
||||
struct platforment
|
||||
{
|
||||
physent *d;
|
||||
int stacks, chains;
|
||||
|
||||
platforment() {}
|
||||
platforment(physent *d) : d(d), stacks(-1), chains(-1) {}
|
||||
|
||||
bool operator==(const physent *o) const { return d == o; }
|
||||
};
|
||||
|
||||
struct platformcollision
|
||||
{
|
||||
platforment *ent;
|
||||
int next;
|
||||
|
||||
platformcollision() {}
|
||||
platformcollision(platforment *ent, int next) : ent(ent), next(next) {}
|
||||
};
|
||||
|
||||
template<class E, class O>
|
||||
static inline bool platformcollide(physent *d, const vec &dir, physent *o, float margin)
|
||||
{
|
||||
E entvol(d);
|
||||
O obvol(o, margin);
|
||||
vec cp;
|
||||
if(mpr::collide(entvol, obvol, NULL, NULL, &cp))
|
||||
{
|
||||
vec wn = vec(cp).sub(obvol.center());
|
||||
return obvol.contactface(wn, dir.iszero() ? vec(wn).neg() : dir).iszero();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool platformcollide(physent *d, physent *o, const vec &dir, float margin = 0)
|
||||
{
|
||||
if(d->collidetype == COLLIDE_ELLIPSE)
|
||||
{
|
||||
if(o->collidetype == COLLIDE_ELLIPSE) return ellipsecollide(d, dir, o->o, vec(0, 0, 0), o->yaw, o->xradius, o->yradius, o->aboveeye, o->eyeheight + margin);
|
||||
else return ellipserectcollide(d, dir, o->o, vec(0, 0, 0), o->yaw, o->xradius, o->yradius, o->aboveeye, o->eyeheight + margin);
|
||||
}
|
||||
else if(o->collidetype == COLLIDE_ELLIPSE) return platformcollide<mpr::EntOBB, mpr::EntCylinder>(d, dir, o, margin);
|
||||
else return platformcollide<mpr::EntOBB, mpr::EntOBB>(d, dir, o, margin);
|
||||
}
|
||||
|
||||
bool moveplatform(physent *p, const vec &dir)
|
||||
{
|
||||
if(!insideworld(p->newpos)) return false;
|
||||
|
||||
vec oldpos(p->o);
|
||||
(p->o = p->newpos).add(dir);
|
||||
if(!collide(p, dir, 0, dir.z<=0))
|
||||
{
|
||||
p->o = oldpos;
|
||||
return false;
|
||||
}
|
||||
p->o = oldpos;
|
||||
|
||||
static vector<platforment> ents;
|
||||
ents.setsize(0);
|
||||
for(int x = int(max(p->o.x-p->radius-PLATFORMBORDER, 0.0f))>>dynentsize, ex = int(min(p->o.x+p->radius+PLATFORMBORDER, worldsize-1.0f))>>dynentsize; x <= ex; x++)
|
||||
for(int y = int(max(p->o.y-p->radius-PLATFORMBORDER, 0.0f))>>dynentsize, ey = int(min(p->o.y+p->radius+PLATFORMBORDER, worldsize-1.0f))>>dynentsize; y <= ey; y++)
|
||||
{
|
||||
const vector<physent *> &dynents = checkdynentcache(x, y);
|
||||
loopv(dynents)
|
||||
{
|
||||
physent *d = dynents[i];
|
||||
if(p==d || d->o.z-d->eyeheight < p->o.z+p->aboveeye || p->o.reject(d->o, p->radius+PLATFORMBORDER+d->radius) || ents.find(d) >= 0) continue;
|
||||
ents.add(d);
|
||||
}
|
||||
}
|
||||
static vector<platforment *> passengers, colliders;
|
||||
passengers.setsize(0);
|
||||
colliders.setsize(0);
|
||||
static vector<platformcollision> collisions;
|
||||
collisions.setsize(0);
|
||||
// build up collision DAG of colliders to be pushed off, and DAG of stacked passengers
|
||||
loopv(ents)
|
||||
{
|
||||
platforment &ent = ents[i];
|
||||
physent *d = ent.d;
|
||||
// check if the dynent is on top of the platform
|
||||
if(!platformcollide(p, d, vec(0, 0, 1), PLATFORMMARGIN)) passengers.add(&ent);
|
||||
vec doldpos(d->o);
|
||||
(d->o = d->newpos).add(dir);
|
||||
if(!collide(d, dir, 0, false)) colliders.add(&ent);
|
||||
d->o = doldpos;
|
||||
loopvj(ents)
|
||||
{
|
||||
platforment &o = ents[j];
|
||||
if(!platformcollide(d, o.d, dir))
|
||||
{
|
||||
collisions.add(platformcollision(&ent, o.chains));
|
||||
o.chains = collisions.length() - 1;
|
||||
}
|
||||
if(d->o.z < o.d->o.z && !platformcollide(d, o.d, vec(0, 0, 1), PLATFORMMARGIN))
|
||||
{
|
||||
collisions.add(platformcollision(&o, ent.stacks));
|
||||
ent.stacks = collisions.length() - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
loopv(colliders) // propagate collisions
|
||||
{
|
||||
platforment *ent = colliders[i];
|
||||
for(int n = ent->chains; n>=0; n = collisions[n].next)
|
||||
{
|
||||
platforment *o = collisions[n].ent;
|
||||
if(colliders.find(o)<0) colliders.add(o);
|
||||
}
|
||||
}
|
||||
if(dir.z>0)
|
||||
{
|
||||
loopv(passengers) // if any stacked passengers collide, stop the platform
|
||||
{
|
||||
platforment *ent = passengers[i];
|
||||
if(colliders.find(ent)>=0) return false;
|
||||
for(int n = ent->stacks; n>=0; n = collisions[n].next)
|
||||
{
|
||||
platforment *o = collisions[n].ent;
|
||||
if(passengers.find(o)<0) passengers.add(o);
|
||||
}
|
||||
}
|
||||
loopv(passengers)
|
||||
{
|
||||
physent *d = passengers[i]->d;
|
||||
d->o.add(dir);
|
||||
d->newpos.add(dir);
|
||||
if(dir.x || dir.y) updatedynentcache(d);
|
||||
}
|
||||
}
|
||||
else loopv(passengers) // move any stacked passengers who aren't colliding with non-passengers
|
||||
{
|
||||
platforment *ent = passengers[i];
|
||||
if(colliders.find(ent)>=0) continue;
|
||||
|
||||
physent *d = ent->d;
|
||||
d->o.add(dir);
|
||||
d->newpos.add(dir);
|
||||
if(dir.x || dir.y) updatedynentcache(d);
|
||||
|
||||
for(int n = ent->stacks; n>=0; n = collisions[n].next)
|
||||
{
|
||||
platforment *o = collisions[n].ent;
|
||||
if(passengers.find(o)<0) passengers.add(o);
|
||||
}
|
||||
}
|
||||
|
||||
p->o.add(dir);
|
||||
p->newpos.add(dir);
|
||||
if(dir.x || dir.y) updatedynentcache(p);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define dir(name,v,d,s,os) ICOMMAND(name, "D", (int *down), { player->s = *down!=0; player->v = player->s ? d : (player->os ? -(d) : 0); });
|
||||
|
||||
dir(backward, move, -1, k_down, k_up);
|
||||
|
|
|
@ -1016,7 +1016,7 @@ void renderclient(dynent *d, const char *mdlname, modelattach *attachments, int
|
|||
anim = ANIM_PAIN;
|
||||
basetime = lastpain;
|
||||
}
|
||||
else if(lastpain < lastaction && (attack < 0 || (d->type != ENT_AI && lastmillis-lastaction < attackdelay)))
|
||||
else if(lastpain < lastaction && (attack < 0 || lastmillis-lastaction < attackdelay))
|
||||
{
|
||||
anim = attack < 0 ? -attack : attack;
|
||||
basetime = lastaction;
|
||||
|
@ -1049,7 +1049,7 @@ void setbbfrommodel(dynent *d, const char *mdl)
|
|||
if(!m) return;
|
||||
vec center, radius;
|
||||
m->collisionbox(center, radius);
|
||||
if(d->type==ENT_INANIMATE && !m->ellipsecollide)
|
||||
if(!m->ellipsecollide)
|
||||
{
|
||||
d->collidetype = COLLIDE_OBB;
|
||||
//d->collidetype = COLLIDE_AABB;
|
||||
|
|
|
@ -483,9 +483,6 @@ 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); });
|
||||
ICOMMANDS("m_sp", "i", (int *mode), { int gamemode = *mode; intret(m_sp); });
|
||||
ICOMMANDS("m_dmsp", "i", (int *mode), { int gamemode = *mode; intret(m_dmsp); });
|
||||
ICOMMANDS("m_classicsp", "i", (int *mode), { int gamemode = *mode; intret(m_classicsp); });
|
||||
|
||||
void changemap(const char *name, int mode) // request map change, server may ignore
|
||||
{
|
||||
|
|
|
@ -15,26 +15,10 @@ namespace entities
|
|||
if(ver <= 30) switch(e.type)
|
||||
{
|
||||
case FLAG:
|
||||
case MONSTER:
|
||||
case TELEDEST:
|
||||
case RESPAWNPOINT:
|
||||
case BOX:
|
||||
case BARREL:
|
||||
case PLATFORM:
|
||||
case ELEVATOR:
|
||||
e.attr1 = (int(e.attr1)+180)%360;
|
||||
break;
|
||||
}
|
||||
if(ver <= 31) switch(e.type)
|
||||
{
|
||||
case BOX:
|
||||
case BARREL:
|
||||
case PLATFORM:
|
||||
case ELEVATOR:
|
||||
int yaw = (int(e.attr1)%360 + 360)%360 + 7;
|
||||
e.attr1 = yaw - yaw%15;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef STANDALONE
|
||||
|
@ -99,9 +83,6 @@ namespace entities
|
|||
case I_HEALTH: case I_BOOST: case I_GREENARMOUR: case I_YELLOWARMOUR: case I_QUAD:
|
||||
if(m_noitems) continue;
|
||||
break;
|
||||
case CARROT: case RESPAWNPOINT:
|
||||
if(!m_classicsp) continue;
|
||||
break;
|
||||
}
|
||||
const char *mdl = entmdlname(i);
|
||||
if(!mdl) continue;
|
||||
|
@ -117,15 +98,12 @@ namespace entities
|
|||
int revs = 10;
|
||||
switch(e.type)
|
||||
{
|
||||
case CARROT:
|
||||
case RESPAWNPOINT:
|
||||
if(e.attr2) revs = 1;
|
||||
break;
|
||||
case TELEPORT:
|
||||
if(e.attr2 < 0) continue;
|
||||
break;
|
||||
default:
|
||||
if(!e.spawned || e.type < I_SHELLS || e.type > I_QUAD) continue;
|
||||
break;
|
||||
}
|
||||
const char *mdlname = entmodel(e);
|
||||
if(mdlname)
|
||||
|
@ -277,14 +255,6 @@ namespace entities
|
|||
break;
|
||||
}
|
||||
|
||||
case RESPAWNPOINT:
|
||||
if(d!=player1) break;
|
||||
if(n==respawnent) break;
|
||||
respawnent = n;
|
||||
conoutf(CON_GAMEINFO, "\f2respawn point set!");
|
||||
playsound(S_V_RESPAWNPOINT);
|
||||
break;
|
||||
|
||||
case JUMPPAD:
|
||||
{
|
||||
if(d->lastpickup==ents[n]->type && lastmillis-d->lastpickupmillis<300) break;
|
||||
|
@ -310,7 +280,7 @@ namespace entities
|
|||
{
|
||||
extentity &e = *ents[i];
|
||||
if(e.type==NOTUSED) continue;
|
||||
if(!e.spawned && e.type!=TELEPORT && e.type!=JUMPPAD && e.type!=RESPAWNPOINT) continue;
|
||||
if(!e.spawned && e.type!=TELEPORT && e.type!=JUMPPAD) continue;
|
||||
float dist = e.o.dist(o);
|
||||
if(dist<(e.type==TELEPORT ? 16 : 12)) trypickup(i, d);
|
||||
}
|
||||
|
@ -344,7 +314,7 @@ namespace entities
|
|||
if(m_noitems) return;
|
||||
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))
|
||||
{
|
||||
ents[i]->spawned = force || m_sp || !server::delayspawn(ents[i]->type);
|
||||
ents[i]->spawned = force || !server::delayspawn(ents[i]->type);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,209 +328,9 @@ namespace entities
|
|||
while(ents.length()) deleteentity(ents.pop());
|
||||
}
|
||||
|
||||
enum
|
||||
{
|
||||
TRIG_COLLIDE = 1<<0,
|
||||
TRIG_TOGGLE = 1<<1,
|
||||
TRIG_ONCE = 0<<2,
|
||||
TRIG_MANY = 1<<2,
|
||||
TRIG_DISAPPEAR = 1<<3,
|
||||
TRIG_AUTO_RESET = 1<<4,
|
||||
TRIG_RUMBLE = 1<<5,
|
||||
TRIG_LOCKED = 1<<6,
|
||||
TRIG_ENDSP = 1<<7
|
||||
};
|
||||
|
||||
static const int NUMTRIGGERTYPES = 32;
|
||||
|
||||
static const int triggertypes[NUMTRIGGERTYPES] =
|
||||
{
|
||||
-1,
|
||||
TRIG_ONCE, // 1
|
||||
TRIG_RUMBLE, // 2
|
||||
TRIG_TOGGLE, // 3
|
||||
TRIG_TOGGLE | TRIG_RUMBLE, // 4
|
||||
TRIG_MANY, // 5
|
||||
TRIG_MANY | TRIG_RUMBLE, // 6
|
||||
TRIG_MANY | TRIG_TOGGLE, // 7
|
||||
TRIG_MANY | TRIG_TOGGLE | TRIG_RUMBLE, // 8
|
||||
TRIG_COLLIDE | TRIG_TOGGLE | TRIG_RUMBLE, // 9
|
||||
TRIG_COLLIDE | TRIG_TOGGLE | TRIG_AUTO_RESET | TRIG_RUMBLE, // 10
|
||||
TRIG_COLLIDE | TRIG_TOGGLE | TRIG_LOCKED | TRIG_RUMBLE, // 11
|
||||
TRIG_DISAPPEAR, // 12
|
||||
TRIG_DISAPPEAR | TRIG_RUMBLE, // 13
|
||||
TRIG_DISAPPEAR | TRIG_COLLIDE | TRIG_LOCKED, // 14
|
||||
-1 /* reserved 15 */,
|
||||
-1 /* reserved 16 */,
|
||||
-1 /* reserved 17 */,
|
||||
-1 /* reserved 18 */,
|
||||
-1 /* reserved 19 */,
|
||||
-1 /* reserved 20 */,
|
||||
-1 /* reserved 21 */,
|
||||
-1 /* reserved 22 */,
|
||||
-1 /* reserved 23 */,
|
||||
-1 /* reserved 24 */,
|
||||
-1 /* reserved 25 */,
|
||||
-1 /* reserved 26 */,
|
||||
-1 /* reserved 27 */,
|
||||
-1 /* reserved 28 */,
|
||||
TRIG_DISAPPEAR | TRIG_RUMBLE | TRIG_ENDSP, // 29
|
||||
-1 /* reserved 30 */,
|
||||
-1 /* reserved 31 */,
|
||||
};
|
||||
|
||||
#define validtrigger(type) (triggertypes[(type) & (NUMTRIGGERTYPES-1)]>=0)
|
||||
#define checktriggertype(type, flag) (triggertypes[(type) & (NUMTRIGGERTYPES-1)] & (flag))
|
||||
|
||||
static inline void setuptriggerflags(fpsentity &e)
|
||||
{
|
||||
e.flags = extentity::F_ANIM;
|
||||
if(checktriggertype(e.attr3, TRIG_COLLIDE|TRIG_DISAPPEAR)) e.flags |= extentity::F_NOSHADOW;
|
||||
if(!checktriggertype(e.attr3, TRIG_COLLIDE)) e.flags |= extentity::F_NOCOLLIDE;
|
||||
switch(e.triggerstate)
|
||||
{
|
||||
case TRIGGERING:
|
||||
if(checktriggertype(e.attr3, TRIG_COLLIDE) && lastmillis-e.lasttrigger >= 500) e.flags |= extentity::F_NOCOLLIDE;
|
||||
break;
|
||||
case TRIGGERED:
|
||||
if(checktriggertype(e.attr3, TRIG_COLLIDE)) e.flags |= extentity::F_NOCOLLIDE;
|
||||
break;
|
||||
case TRIGGER_DISAPPEARED:
|
||||
e.flags |= extentity::F_NOVIS | extentity::F_NOCOLLIDE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void resettriggers()
|
||||
{
|
||||
loopv(ents)
|
||||
{
|
||||
fpsentity &e = *(fpsentity *)ents[i];
|
||||
if(e.type != ET_MAPMODEL || !validtrigger(e.attr3)) continue;
|
||||
e.triggerstate = TRIGGER_RESET;
|
||||
e.lasttrigger = 0;
|
||||
setuptriggerflags(e);
|
||||
}
|
||||
}
|
||||
|
||||
void unlocktriggers(int tag, int oldstate = TRIGGER_RESET, int newstate = TRIGGERING)
|
||||
{
|
||||
loopv(ents)
|
||||
{
|
||||
fpsentity &e = *(fpsentity *)ents[i];
|
||||
if(e.type != ET_MAPMODEL || !validtrigger(e.attr3)) continue;
|
||||
if(e.attr4 == tag && e.triggerstate == oldstate && checktriggertype(e.attr3, TRIG_LOCKED))
|
||||
{
|
||||
if(newstate == TRIGGER_RESETTING && checktriggertype(e.attr3, TRIG_COLLIDE) && overlapsdynent(e.o, 20)) continue;
|
||||
e.triggerstate = newstate;
|
||||
e.lasttrigger = lastmillis;
|
||||
if(checktriggertype(e.attr3, TRIG_RUMBLE)) playsound(S_RUMBLE, &e.o);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ICOMMAND(trigger, "ii", (int *tag, int *state),
|
||||
{
|
||||
if(*state) unlocktriggers(*tag);
|
||||
else unlocktriggers(*tag, TRIGGERED, TRIGGER_RESETTING);
|
||||
});
|
||||
|
||||
VAR(triggerstate, -1, 0, 1);
|
||||
|
||||
void doleveltrigger(int trigger, int state)
|
||||
{
|
||||
defformatstring(aliasname)("level_trigger_%d", trigger);
|
||||
if(identexists(aliasname))
|
||||
{
|
||||
triggerstate = state;
|
||||
execute(aliasname);
|
||||
}
|
||||
}
|
||||
|
||||
void checktriggers()
|
||||
{
|
||||
if(player1->state != CS_ALIVE) return;
|
||||
vec o = player1->feetpos();
|
||||
loopv(ents)
|
||||
{
|
||||
fpsentity &e = *(fpsentity *)ents[i];
|
||||
if(e.type != ET_MAPMODEL || !validtrigger(e.attr3)) continue;
|
||||
switch(e.triggerstate)
|
||||
{
|
||||
case TRIGGERING:
|
||||
case TRIGGER_RESETTING:
|
||||
if(lastmillis-e.lasttrigger>=1000)
|
||||
{
|
||||
if(e.attr4)
|
||||
{
|
||||
if(e.triggerstate == TRIGGERING) unlocktriggers(e.attr4);
|
||||
else unlocktriggers(e.attr4, TRIGGERED, TRIGGER_RESETTING);
|
||||
}
|
||||
if(checktriggertype(e.attr3, TRIG_DISAPPEAR)) e.triggerstate = TRIGGER_DISAPPEARED;
|
||||
else if(e.triggerstate==TRIGGERING && checktriggertype(e.attr3, TRIG_TOGGLE)) e.triggerstate = TRIGGERED;
|
||||
else e.triggerstate = TRIGGER_RESET;
|
||||
}
|
||||
setuptriggerflags(e);
|
||||
break;
|
||||
case TRIGGER_RESET:
|
||||
if(e.lasttrigger)
|
||||
{
|
||||
if(checktriggertype(e.attr3, TRIG_AUTO_RESET|TRIG_MANY|TRIG_LOCKED) && e.o.dist(o)-player1->radius>=(checktriggertype(e.attr3, TRIG_COLLIDE) ? 20 : 12))
|
||||
e.lasttrigger = 0;
|
||||
break;
|
||||
}
|
||||
else if(e.o.dist(o)-player1->radius>=(checktriggertype(e.attr3, TRIG_COLLIDE) ? 20 : 12)) break;
|
||||
else if(checktriggertype(e.attr3, TRIG_LOCKED))
|
||||
{
|
||||
if(!e.attr4) break;
|
||||
doleveltrigger(e.attr4, -1);
|
||||
e.lasttrigger = lastmillis;
|
||||
break;
|
||||
}
|
||||
e.triggerstate = TRIGGERING;
|
||||
e.lasttrigger = lastmillis;
|
||||
setuptriggerflags(e);
|
||||
if(checktriggertype(e.attr3, TRIG_RUMBLE)) playsound(S_RUMBLE, &e.o);
|
||||
if(checktriggertype(e.attr3, TRIG_ENDSP)) endsp(false);
|
||||
if(e.attr4) doleveltrigger(e.attr4, 1);
|
||||
break;
|
||||
case TRIGGERED:
|
||||
if(e.o.dist(o)-player1->radius<(checktriggertype(e.attr3, TRIG_COLLIDE) ? 20 : 12))
|
||||
{
|
||||
if(e.lasttrigger) break;
|
||||
}
|
||||
else if(checktriggertype(e.attr3, TRIG_AUTO_RESET))
|
||||
{
|
||||
if(lastmillis-e.lasttrigger<6000) break;
|
||||
}
|
||||
else if(checktriggertype(e.attr3, TRIG_MANY))
|
||||
{
|
||||
e.lasttrigger = 0;
|
||||
break;
|
||||
}
|
||||
else break;
|
||||
if(checktriggertype(e.attr3, TRIG_COLLIDE) && overlapsdynent(e.o, 20)) break;
|
||||
e.triggerstate = TRIGGER_RESETTING;
|
||||
e.lasttrigger = lastmillis;
|
||||
setuptriggerflags(e);
|
||||
if(checktriggertype(e.attr3, TRIG_RUMBLE)) playsound(S_RUMBLE, &e.o);
|
||||
if(checktriggertype(e.attr3, TRIG_ENDSP)) endsp(false);
|
||||
if(e.attr4) doleveltrigger(e.attr4, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void animatemapmodel(const extentity &e, int &anim, int &basetime)
|
||||
{
|
||||
const fpsentity &f = (const fpsentity &)e;
|
||||
if(validtrigger(f.attr3)) switch(f.triggerstate)
|
||||
{
|
||||
case TRIGGER_RESET: anim = ANIM_TRIGGER|ANIM_START; break;
|
||||
case TRIGGERING: anim = ANIM_TRIGGER; basetime = f.lasttrigger; break;
|
||||
case TRIGGERED: anim = ANIM_TRIGGER|ANIM_END; break;
|
||||
case TRIGGER_RESETTING: anim = ANIM_TRIGGER|ANIM_REVERSE; basetime = f.lasttrigger; break;
|
||||
}
|
||||
//const fpsentity &f = (const fpsentity &)e;
|
||||
}
|
||||
|
||||
void fixentity(extentity &e)
|
||||
|
@ -568,17 +338,11 @@ namespace entities
|
|||
switch(e.type)
|
||||
{
|
||||
case FLAG:
|
||||
case BOX:
|
||||
case BARREL:
|
||||
case PLATFORM:
|
||||
case ELEVATOR:
|
||||
e.attr5 = e.attr4;
|
||||
e.attr4 = e.attr3;
|
||||
case TELEDEST:
|
||||
e.attr3 = e.attr2;
|
||||
case MONSTER:
|
||||
e.attr2 = e.attr1;
|
||||
case RESPAWNPOINT:
|
||||
e.attr1 = (int)player1->yaw;
|
||||
break;
|
||||
}
|
||||
|
@ -601,22 +365,13 @@ namespace entities
|
|||
break;
|
||||
|
||||
case FLAG:
|
||||
case MONSTER:
|
||||
case TELEDEST:
|
||||
case RESPAWNPOINT:
|
||||
case BOX:
|
||||
case BARREL:
|
||||
case PLATFORM:
|
||||
case ELEVATOR:
|
||||
{
|
||||
vec dir;
|
||||
vecfromyawpitch(e.attr1, 0, 1, 0, dir);
|
||||
renderentarrow(e, dir, 4);
|
||||
break;
|
||||
}
|
||||
case MAPMODEL:
|
||||
if(validtrigger(e.attr3)) renderentring(e, checktriggertype(e.attr3, TRIG_COLLIDE) ? 20 : 12);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -647,14 +402,7 @@ namespace entities
|
|||
void editent(int i, bool local)
|
||||
{
|
||||
extentity &e = *ents[i];
|
||||
if(e.type == ET_MAPMODEL && validtrigger(e.attr3))
|
||||
{
|
||||
fpsentity &f = (fpsentity &)e;
|
||||
f.triggerstate = TRIGGER_RESET;
|
||||
f.lasttrigger = 0;
|
||||
setuptriggerflags(f);
|
||||
}
|
||||
else e.flags = 0;
|
||||
//e.flags = 0;
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -70,12 +70,6 @@ namespace game
|
|||
|
||||
void resetgamestate()
|
||||
{
|
||||
if(m_classicsp)
|
||||
{
|
||||
clearmovables();
|
||||
clearmonsters(); // all monsters back at their spawns for editing
|
||||
entities::resettriggers();
|
||||
}
|
||||
clearprojectiles();
|
||||
clearbouncers();
|
||||
}
|
||||
|
@ -220,22 +214,6 @@ namespace game
|
|||
}
|
||||
}
|
||||
|
||||
VARFP(slowmosp, 0, 0, 1,
|
||||
{
|
||||
if(m_sp && !slowmosp) setvar("gamespeed", 100);
|
||||
});
|
||||
|
||||
void checkslowmo()
|
||||
{
|
||||
static int lastslowmohealth = 0;
|
||||
setvar("gamespeed", intermission ? 100 : clamp(player1->health, 25, 200), true, false);
|
||||
if(player1->health<player1->maxhealth && lastmillis-max(maptime, lastslowmohealth)>player1->health*player1->health/2)
|
||||
{
|
||||
lastslowmohealth = lastmillis;
|
||||
player1->health++;
|
||||
}
|
||||
}
|
||||
|
||||
void updateworld() // main game update loop
|
||||
{
|
||||
if(!maptime) { maptime = lastmillis; maprealtime = totalmillis; return; }
|
||||
|
@ -252,8 +230,6 @@ namespace game
|
|||
ai::update();
|
||||
moveragdolls();
|
||||
gets2c();
|
||||
updatemovables(curtime);
|
||||
updatemonsters(curtime);
|
||||
if(player1->state == CS_DEAD)
|
||||
{
|
||||
if(player1->ragdoll) moveragdoll(player1);
|
||||
|
@ -269,12 +245,7 @@ namespace game
|
|||
moveplayer(player1, 10, true);
|
||||
swayhudgun(curtime);
|
||||
entities::checkitems(player1);
|
||||
if(m_sp)
|
||||
{
|
||||
if(slowmosp) checkslowmo();
|
||||
if(m_classicsp) entities::checktriggers();
|
||||
}
|
||||
else if(cmode) cmode->checkitems(player1);
|
||||
if(cmode) cmode->checkitems(player1);
|
||||
}
|
||||
if(player1->clientnum>=0) c2sinfo(); // do this last, to reduce the effective frame lag
|
||||
}
|
||||
|
@ -307,13 +278,7 @@ namespace game
|
|||
return;
|
||||
}
|
||||
if(lastmillis < player1->lastpain + spawnwait) return;
|
||||
if(m_dmsp) { changemap(clientmap, gamemode); return; } // if we die in SP we try the same map again
|
||||
respawnself();
|
||||
if(m_classicsp)
|
||||
{
|
||||
conoutf(CON_GAMEINFO, "\f2You wasted another life! The monsters stole your armour and some ammo...");
|
||||
loopi(NUMGUNS) if(i!=GUN_PISTOL && (player1->ammo[i] = savedammo[i]) > 5) player1->ammo[i] = max(player1->ammo[i]/3, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -361,8 +326,6 @@ namespace game
|
|||
|
||||
ai::damaged(d, actor);
|
||||
|
||||
if(m_sp && slowmosp && d==player1 && d->health < 1) d->health = 1;
|
||||
|
||||
if(d->health<=0) { if(local) killed(d, actor); }
|
||||
else if(d==h) playsound(S_PAIN6);
|
||||
else playsound(S_PAIN1+rnd(5), &d->o);
|
||||
|
@ -412,9 +375,7 @@ namespace game
|
|||
string dname, aname;
|
||||
copystring(dname, d==player1 ? "you" : colorname(d));
|
||||
copystring(aname, actor==player1 ? "you" : colorname(actor));
|
||||
if(actor->type==ENT_AI)
|
||||
conoutf(contype, "\f2%s got killed by %s!", dname, aname);
|
||||
else if(d==actor || actor->type==ENT_INANIMATE)
|
||||
if(d==actor)
|
||||
conoutf(contype, "\f2%s suicided%s", dname, d==player1 ? "!" : "");
|
||||
else if(isteam(d->team, actor->team))
|
||||
{
|
||||
|
@ -450,7 +411,6 @@ namespace game
|
|||
else 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);
|
||||
if(m_sp) spsummary(accuracy);
|
||||
|
||||
showscores(true);
|
||||
disablezoom();
|
||||
|
@ -531,9 +491,6 @@ namespace game
|
|||
|
||||
void startgame()
|
||||
{
|
||||
clearmovables();
|
||||
clearmonsters();
|
||||
|
||||
clearprojectiles();
|
||||
clearbouncers();
|
||||
clearragdolls();
|
||||
|
@ -565,17 +522,8 @@ namespace game
|
|||
|
||||
conoutf(CON_GAMEINFO, "\f2game mode is %s", server::modename(gamemode));
|
||||
|
||||
if(m_sp)
|
||||
{
|
||||
defformatstring(scorename)("bestscore_%s", getclientmap());
|
||||
const char *best = getalias(scorename);
|
||||
if(*best) conoutf(CON_GAMEINFO, "\f2try to beat your best score so far: %s", best);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *info = m_valid(gamemode) ? gamemodes[gamemode - STARTGAMEMODE].info : NULL;
|
||||
if(showmodeinfo && info) conoutf(CON_GAMEINFO, "\f0%s", info);
|
||||
}
|
||||
const char *info = m_valid(gamemode) ? gamemodes[gamemode - STARTGAMEMODE].info : NULL;
|
||||
if(showmodeinfo && info) conoutf(CON_GAMEINFO, "\f0%s", info);
|
||||
|
||||
if(player1->playermodel != playermodel) switchplayermodel(playermodel);
|
||||
|
||||
|
@ -607,7 +555,6 @@ namespace game
|
|||
|
||||
void physicstrigger(physent *d, bool local, int floorlevel, int waterlevel, int material)
|
||||
{
|
||||
if(d->type==ENT_INANIMATE) return;
|
||||
if (waterlevel>0) { if(material!=MAT_LAVA) playsound(S_SPLASH1, d==player1 ? NULL : &d->o); }
|
||||
else if(waterlevel<0) playsound(material==MAT_LAVA ? S_BURN : S_SPLASH2, d==player1 ? NULL : &d->o);
|
||||
if (floorlevel>0) { if(d==player1 || d->type!=ENT_PLAYER || ((fpsent *)d)->ai) msgsound(S_JUMP, d); }
|
||||
|
@ -616,11 +563,6 @@ namespace game
|
|||
|
||||
void dynentcollide(physent *d, physent *o, const vec &dir)
|
||||
{
|
||||
switch(d->type)
|
||||
{
|
||||
case ENT_AI: if(dir.z > 0) stackmonster((monster *)d, o); break;
|
||||
case ENT_INANIMATE: if(dir.z > 0) stackmovable((movable *)d, o); break;
|
||||
}
|
||||
}
|
||||
|
||||
void msgsound(int n, physent *d)
|
||||
|
@ -638,15 +580,11 @@ namespace game
|
|||
}
|
||||
}
|
||||
|
||||
int numdynents() { return players.length()+monsters.length()+movables.length(); }
|
||||
int numdynents() { return players.length(); }
|
||||
|
||||
dynent *iterdynents(int i)
|
||||
{
|
||||
if(i<players.length()) return players[i];
|
||||
i -= players.length();
|
||||
if(i<monsters.length()) return (dynent *)monsters[i];
|
||||
i -= monsters.length();
|
||||
if(i<movables.length()) return (dynent *)movables[i];
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -681,8 +619,6 @@ namespace game
|
|||
pl->suicided = pl->lifesequence;
|
||||
}
|
||||
}
|
||||
else if(d->type==ENT_AI) suicidemonster((monster *)d);
|
||||
else if(d->type==ENT_INANIMATE) suicidemovable((movable *)d);
|
||||
}
|
||||
ICOMMAND(kill, "", (), suicide(player1));
|
||||
|
||||
|
|
|
@ -60,9 +60,6 @@ enum
|
|||
|
||||
struct fpsentity : extentity
|
||||
{
|
||||
int triggerstate, lasttrigger;
|
||||
|
||||
fpsentity() : triggerstate(TRIGGER_RESET), lasttrigger(0) {}
|
||||
};
|
||||
|
||||
enum { GUN_FIST = 0, GUN_SG, GUN_CG, GUN_RL, GUN_RIFLE, GUN_GL, GUN_PISTOL, GUN_FIREBALL, GUN_ICEBALL, GUN_SLIMEBALL, GUN_BITE, GUN_BARREL, NUMGUNS };
|
||||
|
@ -158,10 +155,6 @@ static struct gamemodeinfo
|
|||
#define m_botmode (m_checknot(gamemode, M_DEMO|M_LOCAL))
|
||||
#define m_mp(mode) (m_checknot(mode, M_LOCAL))
|
||||
|
||||
#define m_sp (m_check(gamemode, M_DMSP | M_CLASSICSP))
|
||||
#define m_dmsp (m_check(gamemode, M_DMSP))
|
||||
#define m_classicsp (m_check(gamemode, M_CLASSICSP))
|
||||
|
||||
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" };
|
||||
|
@ -491,7 +484,7 @@ struct fpsstate
|
|||
}
|
||||
else
|
||||
{
|
||||
ammo[GUN_PISTOL] = m_sp ? 80 : 40;
|
||||
ammo[GUN_PISTOL] = 40;
|
||||
ammo[GUN_GL] = 1;
|
||||
}
|
||||
}
|
||||
|
@ -555,7 +548,7 @@ struct fpsent : dynent, fpsstate
|
|||
{
|
||||
vec push(dir);
|
||||
push.mul(80*damage/weight);
|
||||
if(gun==GUN_RL || gun==GUN_GL) push.mul(actor==this ? 5 : (type==ENT_AI ? 3 : 2));
|
||||
if(gun==GUN_RL || gun==GUN_GL) push.mul(actor==this ? 5 : 2);
|
||||
vel.add(push);
|
||||
}
|
||||
|
||||
|
@ -616,8 +609,6 @@ namespace entities
|
|||
|
||||
extern void preloadentities();
|
||||
extern void renderentities();
|
||||
extern void resettriggers();
|
||||
extern void checktriggers();
|
||||
extern void checkitems(fpsent *d);
|
||||
extern void checkquad(int time, fpsent *d);
|
||||
extern void resetspawns();
|
||||
|
@ -714,32 +705,6 @@ namespace game
|
|||
extern void c2sinfo(bool force = false);
|
||||
extern void sendposition(fpsent *d, bool reliable = false);
|
||||
|
||||
// monster
|
||||
struct monster;
|
||||
extern vector<monster *> monsters;
|
||||
|
||||
extern void clearmonsters();
|
||||
extern void preloadmonsters();
|
||||
extern void stackmonster(monster *d, physent *o);
|
||||
extern void updatemonsters(int curtime);
|
||||
extern void rendermonsters();
|
||||
extern void suicidemonster(monster *m);
|
||||
extern void hitmonster(int damage, monster *m, fpsent *at, const vec &vel, int gun);
|
||||
extern void monsterkilled();
|
||||
extern void endsp(bool allkilled);
|
||||
extern void spsummary(int accuracy);
|
||||
|
||||
// movable
|
||||
struct movable;
|
||||
extern vector<movable *> movables;
|
||||
|
||||
extern void clearmovables();
|
||||
extern void stackmovable(movable *d, physent *o);
|
||||
extern void updatemovables(int curtime);
|
||||
extern void rendermovables();
|
||||
extern void suicidemovable(movable *m);
|
||||
extern void hitmovable(int damage, movable *m, fpsent *at, const vec &vel, int gun);
|
||||
|
||||
// weapon
|
||||
extern int getweapon(const char *name);
|
||||
extern void shoot(fpsent *d, const vec &targ);
|
||||
|
|
|
@ -1,430 +0,0 @@
|
|||
// monster.h: implements AI for single player monsters, currently client only
|
||||
#include "game.h"
|
||||
|
||||
extern int physsteps;
|
||||
|
||||
namespace game
|
||||
{
|
||||
static vector<int> teleports;
|
||||
|
||||
static const int TOTMFREQ = 14;
|
||||
static const int NUMMONSTERTYPES = 9;
|
||||
|
||||
struct monstertype // see docs for how these values modify behaviour
|
||||
{
|
||||
short gun, speed, health, freq, lag, rate, pain, loyalty, bscale, weight;
|
||||
short painsound, diesound;
|
||||
const char *name, *mdlname, *vwepname;
|
||||
};
|
||||
|
||||
static const monstertype monstertypes[NUMMONSTERTYPES] =
|
||||
{
|
||||
{ GUN_FIREBALL, 15, 100, 3, 0, 100, 800, 1, 10, 90, S_PAINO, S_DIE1, "an ogro", "ogro", "ogro/vwep"},
|
||||
{ GUN_CG, 18, 70, 2, 70, 10, 400, 2, 10, 50, S_PAINR, S_DEATHR, "a rhino", "monster/rhino", NULL},
|
||||
{ GUN_SG, 13, 120, 1, 100, 300, 400, 4, 14, 115, S_PAINE, S_DEATHE, "ratamahatta", "monster/rat", "monster/rat/vwep"},
|
||||
{ GUN_RIFLE, 14, 200, 1, 80, 400, 300, 4, 18, 145, S_PAINS, S_DEATHS, "a slith", "monster/slith", "monster/slith/vwep"},
|
||||
{ GUN_RL, 12, 500, 1, 0, 200, 200, 6, 24, 210, S_PAINB, S_DEATHB, "bauul", "monster/bauul", "monster/bauul/vwep"},
|
||||
{ GUN_BITE, 24, 50, 3, 0, 100, 400, 1, 15, 75, S_PAINP, S_PIGGR2, "a hellpig", "monster/hellpig", NULL},
|
||||
{ GUN_ICEBALL, 11, 250, 1, 0, 10, 400, 6, 18, 160, S_PAINH, S_DEATHH, "a knight", "monster/knight", "monster/knight/vwep"},
|
||||
{ GUN_SLIMEBALL, 15, 100, 1, 0, 200, 400, 2, 10, 60, S_PAIND, S_DEATHD, "a goblin", "monster/goblin", "monster/goblin/vwep"},
|
||||
{ GUN_GL, 22, 50, 1, 0, 200, 400, 1, 10, 40, S_PAIND, S_DEATHD, "a spider", "monster/spider", NULL },
|
||||
};
|
||||
|
||||
VAR(skill, 1, 3, 10);
|
||||
VAR(killsendsp, 0, 1, 1);
|
||||
|
||||
bool monsterhurt;
|
||||
vec monsterhurtpos;
|
||||
|
||||
struct monster : fpsent
|
||||
{
|
||||
int monsterstate; // one of M_*, M_NONE means human
|
||||
|
||||
int mtype, tag; // see monstertypes table
|
||||
fpsent *enemy; // monster wants to kill this entity
|
||||
float targetyaw; // monster wants to look in this direction
|
||||
int trigger; // millis at which transition to another monsterstate takes place
|
||||
vec attacktarget; // delayed attacks
|
||||
int anger; // how many times already hit by fellow monster
|
||||
physent *stacked;
|
||||
vec stackpos;
|
||||
|
||||
monster(int _type, int _yaw, int _tag, int _state, int _trigger, int _move) :
|
||||
monsterstate(_state), tag(_tag),
|
||||
stacked(NULL),
|
||||
stackpos(0, 0, 0)
|
||||
{
|
||||
type = ENT_AI;
|
||||
respawn();
|
||||
if(_type>=NUMMONSTERTYPES || _type < 0)
|
||||
{
|
||||
conoutf(CON_WARN, "warning: unknown monster in spawn: %d", _type);
|
||||
_type = 0;
|
||||
}
|
||||
mtype = _type;
|
||||
const monstertype &t = monstertypes[mtype];
|
||||
eyeheight = 8.0f;
|
||||
aboveeye = 7.0f;
|
||||
radius *= t.bscale/10.0f;
|
||||
xradius = yradius = radius;
|
||||
eyeheight *= t.bscale/10.0f;
|
||||
aboveeye *= t.bscale/10.0f;
|
||||
weight = t.weight;
|
||||
if(_state!=M_SLEEP) spawnplayer(this);
|
||||
trigger = lastmillis+_trigger;
|
||||
targetyaw = yaw = (float)_yaw;
|
||||
move = _move;
|
||||
enemy = player1;
|
||||
gunselect = t.gun;
|
||||
maxspeed = (float)t.speed*4;
|
||||
health = t.health;
|
||||
armour = 0;
|
||||
loopi(NUMGUNS) ammo[i] = 10000;
|
||||
pitch = 0;
|
||||
roll = 0;
|
||||
state = CS_ALIVE;
|
||||
anger = 0;
|
||||
copystring(name, t.name);
|
||||
}
|
||||
|
||||
void normalize_yaw(float angle)
|
||||
{
|
||||
while(yaw<angle-180.0f) yaw += 360.0f;
|
||||
while(yaw>angle+180.0f) yaw -= 360.0f;
|
||||
}
|
||||
|
||||
// monster AI is sequenced using transitions: they are in a particular state where
|
||||
// they execute a particular behaviour until the trigger time is hit, and then they
|
||||
// reevaluate their situation based on the current state, the environment etc., and
|
||||
// transition to the next state. Transition timeframes are parametrized by difficulty
|
||||
// level (skill), faster transitions means quicker decision making means tougher AI.
|
||||
|
||||
void transition(int _state, int _moving, int n, int r) // n = at skill 0, n/2 = at skill 10, r = added random factor
|
||||
{
|
||||
monsterstate = _state;
|
||||
move = _moving;
|
||||
n = n*130/100;
|
||||
trigger = lastmillis+n-skill*(n/16)+rnd(r+1);
|
||||
}
|
||||
|
||||
void monsteraction(int curtime) // main AI thinking routine, called every frame for every monster
|
||||
{
|
||||
if(enemy->state==CS_DEAD) { enemy = player1; anger = 0; }
|
||||
normalize_yaw(targetyaw);
|
||||
if(targetyaw>yaw) // slowly turn monster towards his target
|
||||
{
|
||||
yaw += curtime*0.5f;
|
||||
if(targetyaw<yaw) yaw = targetyaw;
|
||||
}
|
||||
else
|
||||
{
|
||||
yaw -= curtime*0.5f;
|
||||
if(targetyaw>yaw) yaw = targetyaw;
|
||||
}
|
||||
float dist = enemy->o.dist(o);
|
||||
if(monsterstate!=M_SLEEP) pitch = asin((enemy->o.z - o.z) / dist) / RAD;
|
||||
|
||||
if(blocked) // special case: if we run into scenery
|
||||
{
|
||||
blocked = false;
|
||||
if(!rnd(20000/monstertypes[mtype].speed)) // try to jump over obstackle (rare)
|
||||
{
|
||||
jumping = true;
|
||||
}
|
||||
else if(trigger<lastmillis && (monsterstate!=M_HOME || !rnd(5))) // search for a way around (common)
|
||||
{
|
||||
targetyaw += 90+rnd(180); // patented "random walk" AI pathfinding (tm) ;)
|
||||
transition(M_SEARCH, 1, 100, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
float enemyyaw = -atan2(enemy->o.x - o.x, enemy->o.y - o.y)/RAD;
|
||||
|
||||
switch(monsterstate)
|
||||
{
|
||||
case M_PAIN:
|
||||
case M_ATTACKING:
|
||||
case M_SEARCH:
|
||||
if(trigger<lastmillis) transition(M_HOME, 1, 100, 200);
|
||||
break;
|
||||
|
||||
case M_SLEEP: // state classic sp monster start in, wait for visual contact
|
||||
{
|
||||
if(editmode) break;
|
||||
normalize_yaw(enemyyaw);
|
||||
float angle = (float)fabs(enemyyaw-yaw);
|
||||
if(dist<32 // the better the angle to the player, the further the monster can see/hear
|
||||
||(dist<64 && angle<135)
|
||||
||(dist<128 && angle<90)
|
||||
||(dist<256 && angle<45)
|
||||
|| angle<10
|
||||
|| (monsterhurt && o.dist(monsterhurtpos)<128))
|
||||
{
|
||||
vec target;
|
||||
if(raycubelos(o, enemy->o, target))
|
||||
{
|
||||
transition(M_HOME, 1, 500, 200);
|
||||
playsound(S_GRUNT1+rnd(2), &o);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case M_AIMING: // this state is the delay between wanting to shoot and actually firing
|
||||
if(trigger<lastmillis)
|
||||
{
|
||||
lastaction = 0;
|
||||
attacking = true;
|
||||
shoot(this, attacktarget);
|
||||
transition(M_ATTACKING, 0, 600, 0);
|
||||
}
|
||||
break;
|
||||
|
||||
case M_HOME: // monster has visual contact, heads straight for player and may want to shoot at any time
|
||||
targetyaw = enemyyaw;
|
||||
if(trigger<lastmillis)
|
||||
{
|
||||
vec target;
|
||||
if(!raycubelos(o, enemy->o, target)) // no visual contact anymore, let monster get as close as possible then search for player
|
||||
{
|
||||
transition(M_HOME, 1, 800, 500);
|
||||
}
|
||||
else
|
||||
{
|
||||
bool melee = false, longrange = false;
|
||||
switch(monstertypes[mtype].gun)
|
||||
{
|
||||
case GUN_BITE:
|
||||
case GUN_FIST: melee = true; break;
|
||||
case GUN_RIFLE: longrange = true; break;
|
||||
}
|
||||
// the closer the monster is the more likely he wants to shoot,
|
||||
if((!melee || dist<20) && !rnd(longrange ? (int)dist/12+1 : min((int)dist/12+1,6)) && enemy->state==CS_ALIVE) // get ready to fire
|
||||
{
|
||||
attacktarget = target;
|
||||
transition(M_AIMING, 0, monstertypes[mtype].lag, 10);
|
||||
}
|
||||
else // track player some more
|
||||
{
|
||||
transition(M_HOME, 1, monstertypes[mtype].rate, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
if(move || maymove() || (stacked && (stacked->state!=CS_ALIVE || stackpos != stacked->o)))
|
||||
{
|
||||
vec pos = feetpos();
|
||||
loopv(teleports) // equivalent of player entity touch, but only teleports are used
|
||||
{
|
||||
entity &e = *entities::ents[teleports[i]];
|
||||
float dist = e.o.dist(pos);
|
||||
if(dist<16) entities::teleport(teleports[i], this);
|
||||
}
|
||||
|
||||
if(physsteps > 0) stacked = NULL;
|
||||
moveplayer(this, 1, true); // use physics to move monster
|
||||
}
|
||||
}
|
||||
|
||||
void monsterpain(int damage, fpsent *d)
|
||||
{
|
||||
if(d->type==ENT_AI) // a monster hit us
|
||||
{
|
||||
if(this!=d) // guard for RL guys shooting themselves :)
|
||||
{
|
||||
anger++; // don't attack straight away, first get angry
|
||||
int _anger = d->type==ENT_AI && mtype==((monster *)d)->mtype ? anger/2 : anger;
|
||||
if(_anger>=monstertypes[mtype].loyalty) enemy = d; // monster infight if very angry
|
||||
}
|
||||
}
|
||||
else if(d->type==ENT_PLAYER) // player hit us
|
||||
{
|
||||
anger = 0;
|
||||
enemy = d;
|
||||
monsterhurt = true;
|
||||
monsterhurtpos = o;
|
||||
}
|
||||
damageeffect(damage, this);
|
||||
if((health -= damage)<=0)
|
||||
{
|
||||
state = CS_DEAD;
|
||||
lastpain = lastmillis;
|
||||
playsound(monstertypes[mtype].diesound, &o);
|
||||
monsterkilled();
|
||||
gibeffect(max(-health, 0), vel, this);
|
||||
|
||||
defformatstring(id)("monster_dead_%d", tag);
|
||||
if(identexists(id)) execute(id);
|
||||
}
|
||||
else
|
||||
{
|
||||
transition(M_PAIN, 0, monstertypes[mtype].pain, 200); // in this state monster won't attack
|
||||
playsound(monstertypes[mtype].painsound, &o);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void stackmonster(monster *d, physent *o)
|
||||
{
|
||||
d->stacked = o;
|
||||
d->stackpos = o->o;
|
||||
}
|
||||
|
||||
int nummonsters(int tag, int state)
|
||||
{
|
||||
int n = 0;
|
||||
loopv(monsters) if(monsters[i]->tag==tag && (monsters[i]->state==CS_ALIVE ? state!=1 : state>=1)) n++;
|
||||
return n;
|
||||
}
|
||||
ICOMMAND(nummonsters, "ii", (int *tag, int *state), intret(nummonsters(*tag, *state)));
|
||||
|
||||
void preloadmonsters()
|
||||
{
|
||||
loopi(NUMMONSTERTYPES) preloadmodel(monstertypes[i].mdlname);
|
||||
}
|
||||
|
||||
vector<monster *> monsters;
|
||||
|
||||
int nextmonster, spawnremain, numkilled, monstertotal, mtimestart, remain;
|
||||
|
||||
void spawnmonster() // spawn a random monster according to freq distribution in DMSP
|
||||
{
|
||||
int n = rnd(TOTMFREQ), type;
|
||||
for(int i = 0; ; i++) if((n -= monstertypes[i].freq)<0) { type = i; break; }
|
||||
monsters.add(new monster(type, rnd(360), 0, M_SEARCH, 1000, 1));
|
||||
}
|
||||
|
||||
void clearmonsters() // called after map start or when toggling edit mode to reset/spawn all monsters to initial state
|
||||
{
|
||||
removetrackedparticles();
|
||||
removetrackeddynlights();
|
||||
loopv(monsters) delete monsters[i];
|
||||
cleardynentcache();
|
||||
monsters.shrink(0);
|
||||
numkilled = 0;
|
||||
monstertotal = 0;
|
||||
spawnremain = 0;
|
||||
remain = 0;
|
||||
monsterhurt = false;
|
||||
if(m_dmsp)
|
||||
{
|
||||
nextmonster = mtimestart = lastmillis+10000;
|
||||
monstertotal = spawnremain = skill*10;
|
||||
}
|
||||
else if(m_classicsp)
|
||||
{
|
||||
mtimestart = lastmillis;
|
||||
loopv(entities::ents)
|
||||
{
|
||||
extentity &e = *entities::ents[i];
|
||||
if(e.type!=MONSTER) continue;
|
||||
monster *m = new monster(e.attr2, e.attr1, e.attr3, M_SLEEP, 100, 0);
|
||||
monsters.add(m);
|
||||
m->o = e.o;
|
||||
entinmap(m);
|
||||
updatedynentcache(m);
|
||||
monstertotal++;
|
||||
}
|
||||
}
|
||||
teleports.setsize(0);
|
||||
if(m_dmsp || m_classicsp)
|
||||
{
|
||||
loopv(entities::ents) if(entities::ents[i]->type==TELEPORT) teleports.add(i);
|
||||
}
|
||||
}
|
||||
|
||||
void endsp(bool allkilled)
|
||||
{
|
||||
conoutf(CON_GAMEINFO, allkilled ? "\f2you have cleared the map!" : "\f2you reached the exit!");
|
||||
monstertotal = 0;
|
||||
game::addmsg(N_FORCEINTERMISSION, "r");
|
||||
}
|
||||
ICOMMAND(endsp, "", (), endsp(false));
|
||||
|
||||
|
||||
void monsterkilled()
|
||||
{
|
||||
numkilled++;
|
||||
player1->frags = numkilled;
|
||||
remain = monstertotal-numkilled;
|
||||
if(remain>0 && remain<=5) conoutf(CON_GAMEINFO, "\f2only %d monster(s) remaining", remain);
|
||||
}
|
||||
|
||||
void updatemonsters(int curtime)
|
||||
{
|
||||
if(m_dmsp && spawnremain && lastmillis>nextmonster)
|
||||
{
|
||||
if(spawnremain--==monstertotal) { conoutf(CON_GAMEINFO, "\f2The invasion has begun!"); playsound(S_V_FIGHT); }
|
||||
nextmonster = lastmillis+1000;
|
||||
spawnmonster();
|
||||
}
|
||||
|
||||
if(killsendsp && monstertotal && !spawnremain && numkilled==monstertotal) endsp(true);
|
||||
|
||||
bool monsterwashurt = monsterhurt;
|
||||
|
||||
loopv(monsters)
|
||||
{
|
||||
if(monsters[i]->state==CS_ALIVE) monsters[i]->monsteraction(curtime);
|
||||
else if(monsters[i]->state==CS_DEAD)
|
||||
{
|
||||
if(lastmillis-monsters[i]->lastpain<2000)
|
||||
{
|
||||
//monsters[i]->move = 0;
|
||||
monsters[i]->move = monsters[i]->strafe = 0;
|
||||
moveplayer(monsters[i], 1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(monsterwashurt) monsterhurt = false;
|
||||
}
|
||||
|
||||
void rendermonsters()
|
||||
{
|
||||
loopv(monsters)
|
||||
{
|
||||
monster &m = *monsters[i];
|
||||
if(m.state!=CS_DEAD || lastmillis-m.lastpain<10000)
|
||||
{
|
||||
modelattach vwep[2];
|
||||
vwep[0] = modelattach("tag_weapon", monstertypes[m.mtype].vwepname, ANIM_VWEP_IDLE|ANIM_LOOP, 0);
|
||||
float fade = 1;
|
||||
if(m.state==CS_DEAD) fade -= clamp(float(lastmillis - (m.lastpain + 9000))/1000, 0.0f, 1.0f);
|
||||
renderclient(&m, monstertypes[m.mtype].mdlname, vwep, 0, m.monsterstate==M_ATTACKING ? -ANIM_ATTACK1 : 0, 300, m.lastaction, m.lastpain, fade);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void suicidemonster(monster *m)
|
||||
{
|
||||
m->monsterpain(400, player1);
|
||||
}
|
||||
|
||||
void hitmonster(int damage, monster *m, fpsent *at, const vec &vel, int gun)
|
||||
{
|
||||
m->monsterpain(damage, at);
|
||||
}
|
||||
|
||||
void spsummary(int accuracy)
|
||||
{
|
||||
conoutf(CON_GAMEINFO, "\f2--- single player time score: ---");
|
||||
int pen, score = 0;
|
||||
pen = ((lastmillis-maptime)*100)/(1000*getvar("gamespeed")); score += pen; if(pen) conoutf(CON_GAMEINFO, "\f2time taken: %d seconds (%d simulated seconds)", pen, (lastmillis-maptime)/1000);
|
||||
pen = player1->deaths*60; score += pen; if(pen) conoutf(CON_GAMEINFO, "\f2time penalty for %d deaths (1 minute each): %d seconds", player1->deaths, pen);
|
||||
pen = remain*10; score += pen; if(pen) conoutf(CON_GAMEINFO, "\f2time penalty for %d monsters remaining (10 seconds each): %d seconds", remain, pen);
|
||||
pen = (10-skill)*20; score += pen; if(pen) conoutf(CON_GAMEINFO, "\f2time penalty for lower skill level (20 seconds each): %d seconds", pen);
|
||||
pen = 100-accuracy; score += pen; if(pen) conoutf(CON_GAMEINFO, "\f2time penalty for missed shots (1 second each %%): %d seconds", pen);
|
||||
defformatstring(aname)("bestscore_%s", getclientmap());
|
||||
const char *bestsc = getalias(aname);
|
||||
int bestscore = *bestsc ? parseint(bestsc) : score;
|
||||
if(score<bestscore) bestscore = score;
|
||||
defformatstring(nscore)("%d", bestscore);
|
||||
alias(aname, nscore);
|
||||
conoutf(CON_GAMEINFO, "\f2TOTAL SCORE (time + time penalties): %d seconds (best so far: %d seconds)", score, bestscore);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,188 +0,0 @@
|
|||
// movable.cpp: implements physics for inanimate models
|
||||
#include "game.h"
|
||||
|
||||
extern int physsteps;
|
||||
|
||||
namespace game
|
||||
{
|
||||
enum
|
||||
{
|
||||
BOXWEIGHT = 25,
|
||||
BARRELHEALTH = 50,
|
||||
BARRELWEIGHT = 25,
|
||||
PLATFORMWEIGHT = 1000,
|
||||
PLATFORMSPEED = 8,
|
||||
EXPLODEDELAY = 200
|
||||
};
|
||||
|
||||
struct movable : dynent
|
||||
{
|
||||
int etype, mapmodel, health, weight, exploding, tag, dir;
|
||||
physent *stacked;
|
||||
vec stackpos;
|
||||
|
||||
movable(const entity &e) :
|
||||
etype(e.type),
|
||||
mapmodel(e.attr2),
|
||||
health(e.type==BARREL ? (e.attr4 ? e.attr4 : BARRELHEALTH) : 0),
|
||||
weight(e.type==PLATFORM || e.type==ELEVATOR ? PLATFORMWEIGHT : (e.attr3 ? e.attr3 : (e.type==BARREL ? BARRELWEIGHT : BOXWEIGHT))),
|
||||
exploding(0),
|
||||
tag(e.type==PLATFORM || e.type==ELEVATOR ? e.attr3 : 0),
|
||||
dir(e.type==PLATFORM || e.type==ELEVATOR ? (e.attr4 < 0 ? -1 : 1) : 0),
|
||||
stacked(NULL),
|
||||
stackpos(0, 0, 0)
|
||||
{
|
||||
state = CS_ALIVE;
|
||||
type = ENT_INANIMATE;
|
||||
yaw = e.attr1;
|
||||
if(e.type==PLATFORM || e.type==ELEVATOR)
|
||||
{
|
||||
maxspeed = e.attr4 ? fabs(float(e.attr4)) : PLATFORMSPEED;
|
||||
if(tag) vel = vec(0, 0, 0);
|
||||
else if(e.type==PLATFORM) { vecfromyawpitch(yaw, 0, 1, 0, vel); vel.mul(dir*maxspeed); }
|
||||
else vel = vec(0, 0, dir*maxspeed);
|
||||
}
|
||||
|
||||
const char *mdlname = mapmodelname(e.attr2);
|
||||
if(mdlname) setbbfrommodel(this, mdlname);
|
||||
}
|
||||
|
||||
void hitpush(int damage, const vec &dir, fpsent *actor, int gun)
|
||||
{
|
||||
if(etype!=BOX && etype!=BARREL) return;
|
||||
vec push(dir);
|
||||
push.mul(80*damage/weight);
|
||||
vel.add(push);
|
||||
}
|
||||
|
||||
void explode(dynent *at)
|
||||
{
|
||||
state = CS_DEAD;
|
||||
exploding = 0;
|
||||
game::explode(true, (fpsent *)at, o, this, guns[GUN_BARREL].damage, GUN_BARREL);
|
||||
}
|
||||
|
||||
void damaged(int damage, fpsent *at, int gun = -1)
|
||||
{
|
||||
if(etype!=BARREL || state!=CS_ALIVE || exploding) return;
|
||||
health -= damage;
|
||||
if(health>0) return;
|
||||
if(gun==GUN_BARREL) exploding = lastmillis + EXPLODEDELAY;
|
||||
else explode(at);
|
||||
}
|
||||
|
||||
void suicide()
|
||||
{
|
||||
state = CS_DEAD;
|
||||
if(etype==BARREL) explode(player1);
|
||||
}
|
||||
};
|
||||
|
||||
vector<movable *> movables;
|
||||
|
||||
void clearmovables()
|
||||
{
|
||||
if(movables.length())
|
||||
{
|
||||
cleardynentcache();
|
||||
movables.deletecontents();
|
||||
}
|
||||
if(!m_dmsp && !m_classicsp) return;
|
||||
loopv(entities::ents)
|
||||
{
|
||||
const entity &e = *entities::ents[i];
|
||||
if(e.type!=BOX && e.type!=BARREL && e.type!=PLATFORM && e.type!=ELEVATOR) continue;
|
||||
movable *m = new movable(e);
|
||||
movables.add(m);
|
||||
m->o = e.o;
|
||||
entinmap(m);
|
||||
updatedynentcache(m);
|
||||
}
|
||||
}
|
||||
|
||||
void triggerplatform(int tag, int newdir)
|
||||
{
|
||||
newdir = max(-1, min(1, newdir));
|
||||
loopv(movables)
|
||||
{
|
||||
movable *m = movables[i];
|
||||
if(m->state!=CS_ALIVE || (m->etype!=PLATFORM && m->etype!=ELEVATOR) || m->tag!=tag) continue;
|
||||
if(!newdir)
|
||||
{
|
||||
if(m->tag) m->vel = vec(0, 0, 0);
|
||||
else m->vel.neg();
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m->etype==PLATFORM) { vecfromyawpitch(m->yaw, 0, 1, 0, m->vel); m->vel.mul(newdir*m->dir*m->maxspeed); }
|
||||
else m->vel = vec(0, 0, newdir*m->dir*m->maxspeed);
|
||||
}
|
||||
}
|
||||
}
|
||||
ICOMMAND(platform, "ii", (int *tag, int *newdir), triggerplatform(*tag, *newdir));
|
||||
|
||||
void stackmovable(movable *d, physent *o)
|
||||
{
|
||||
d->stacked = o;
|
||||
d->stackpos = o->o;
|
||||
}
|
||||
|
||||
void updatemovables(int curtime)
|
||||
{
|
||||
if(!curtime) return;
|
||||
loopv(movables)
|
||||
{
|
||||
movable *m = movables[i];
|
||||
if(m->state!=CS_ALIVE) continue;
|
||||
if(m->etype==PLATFORM || m->etype==ELEVATOR)
|
||||
{
|
||||
if(m->vel.iszero()) continue;
|
||||
for(int remaining = curtime; remaining>0;)
|
||||
{
|
||||
int step = min(remaining, 20);
|
||||
remaining -= step;
|
||||
if(!moveplatform(m, vec(m->vel).mul(step/1000.0f)))
|
||||
{
|
||||
if(m->tag) { m->vel = vec(0, 0, 0); break; }
|
||||
else m->vel.neg();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(m->exploding && lastmillis >= m->exploding)
|
||||
{
|
||||
m->explode(m);
|
||||
adddecal(DECAL_SCORCH, m->o, vec(0, 0, 1), RL_DAMRAD/2);
|
||||
}
|
||||
else if(m->maymove() || (m->stacked && (m->stacked->state!=CS_ALIVE || m->stackpos != m->stacked->o)))
|
||||
{
|
||||
if(physsteps > 0) m->stacked = NULL;
|
||||
moveplayer(m, 1, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rendermovables()
|
||||
{
|
||||
loopv(movables)
|
||||
{
|
||||
movable &m = *movables[i];
|
||||
if(m.state!=CS_ALIVE) continue;
|
||||
vec o = m.feetpos();
|
||||
const char *mdlname = mapmodelname(m.mapmodel);
|
||||
if(!mdlname) continue;
|
||||
rendermodel(mdlname, ANIM_MAPMODEL|ANIM_LOOP, o, m.yaw, 0, MDL_CULL_VFC | MDL_CULL_DIST | MDL_CULL_OCCLUDED, &m);
|
||||
}
|
||||
}
|
||||
|
||||
void suicidemovable(movable *m)
|
||||
{
|
||||
m->suicide();
|
||||
}
|
||||
|
||||
void hitmovable(int damage, movable *m, fpsent *at, const vec &vel, int gun)
|
||||
{
|
||||
m->hitpush(damage, vel, at, gun);
|
||||
m->damaged(damage, at, gun);
|
||||
}
|
||||
}
|
||||
|
|
@ -220,8 +220,6 @@ namespace game
|
|||
renderplayer(d, getplayermodelinfo(d), team, fade);
|
||||
}
|
||||
if(isthirdperson() && !followingplayer() && (player1->state!=CS_DEAD || !hidedead)) renderplayer(player1, getplayermodelinfo(player1), teamskins || m_teammode ? 1 : 0, 1);
|
||||
rendermonsters();
|
||||
rendermovables();
|
||||
entities::renderentities();
|
||||
renderbouncers();
|
||||
renderprojectiles();
|
||||
|
@ -348,13 +346,10 @@ namespace game
|
|||
vec front, right;
|
||||
vecfromyawpitch(d->yaw, d->pitch, 1, 0, front);
|
||||
offset.add(front.mul(d->radius));
|
||||
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));
|
||||
offset.add(front);
|
||||
}
|
||||
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));
|
||||
offset.add(front);
|
||||
return offset;
|
||||
}
|
||||
offset.add(vec(to).sub(from).normalize().mul(2));
|
||||
|
@ -396,7 +391,6 @@ namespace game
|
|||
preloadbouncers();
|
||||
preloadplayermodel();
|
||||
entities::preloadentities();
|
||||
if(m_sp) preloadmonsters();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -803,7 +803,6 @@ namespace server
|
|||
|
||||
int spawntime(int type)
|
||||
{
|
||||
if(m_classicsp) return INT_MAX;
|
||||
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;
|
||||
|
@ -830,7 +829,7 @@ namespace server
|
|||
{
|
||||
case I_GREENARMOUR:
|
||||
case I_YELLOWARMOUR:
|
||||
return !m_classicsp;
|
||||
return true;
|
||||
case I_BOOST:
|
||||
case I_QUAD:
|
||||
return true;
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
namespace game
|
||||
{
|
||||
static const int MONSTERDAMAGEFACTOR = 4;
|
||||
static const int OFFSETMILLIS = 500;
|
||||
vec sg[SGRAYS];
|
||||
|
||||
|
@ -333,21 +332,14 @@ namespace game
|
|||
lasthit = lastmillis;
|
||||
}
|
||||
|
||||
if(d->type==ENT_INANIMATE)
|
||||
{
|
||||
hitmovable(damage, (movable *)d, at, vel, gun);
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
if(!m_mp(gamemode) || f==at) f->hitpush(damage, vel, at, gun);
|
||||
|
||||
if(f->type==ENT_AI) hitmonster(damage, (monster *)f, at, vel, gun);
|
||||
else if(!m_mp(gamemode)) damaged(damage, f, at);
|
||||
if(!m_mp(gamemode)) damaged(damage, f, at);
|
||||
else
|
||||
{
|
||||
hitmsg &h = hits.add();
|
||||
|
@ -499,7 +491,6 @@ namespace game
|
|||
projectile &p = projs[i];
|
||||
p.offsetmillis = max(p.offsetmillis-time, 0);
|
||||
int qdam = guns[p.gun].damage*(p.owner->quadmillis ? 4 : 1);
|
||||
if(p.owner->type==ENT_AI) qdam /= MONSTERDAMAGEFACTOR;
|
||||
vec v;
|
||||
float dist = p.to.dist(p.o, v);
|
||||
float dtime = dist*1000/p.speed;
|
||||
|
@ -604,7 +595,6 @@ namespace game
|
|||
case GUN_ICEBALL:
|
||||
case GUN_SLIMEBALL:
|
||||
pspeed = guns[gun].projspeed*4;
|
||||
if(d->type==ENT_AI) pspeed /= 2;
|
||||
newprojectile(from, to, (float)pspeed, local, id, d, gun);
|
||||
break;
|
||||
|
||||
|
@ -649,7 +639,7 @@ namespace game
|
|||
|
||||
void particletrack(physent *owner, vec &o, vec &d)
|
||||
{
|
||||
if(owner->type!=ENT_PLAYER && owner->type!=ENT_AI) return;
|
||||
if(owner->type!=ENT_PLAYER) return;
|
||||
fpsent *pl = (fpsent *)owner;
|
||||
if(pl->muzzle.x < 0 || pl->lastattackgun != pl->gunselect) return;
|
||||
float dist = o.dist(d);
|
||||
|
@ -665,7 +655,7 @@ namespace game
|
|||
|
||||
void dynlighttrack(physent *owner, vec &o, vec &hud)
|
||||
{
|
||||
if(owner->type!=ENT_PLAYER && owner->type!=ENT_AI) return;
|
||||
if(owner->type!=ENT_PLAYER) return;
|
||||
fpsent *pl = (fpsent *)owner;
|
||||
if(pl->muzzle.x < 0 || pl->lastattackgun != pl->gunselect) return;
|
||||
o = pl->muzzle;
|
||||
|
@ -710,7 +700,6 @@ namespace game
|
|||
{
|
||||
int qdam = guns[d->gunselect].damage;
|
||||
if(d->quadmillis) qdam *= 4;
|
||||
if(d->type==ENT_AI) qdam /= MONSTERDAMAGEFACTOR;
|
||||
dynent *o;
|
||||
float dist;
|
||||
if(d->gunselect==GUN_SG)
|
||||
|
|
|
@ -37,7 +37,7 @@ enum { CS_ALIVE = 0, CS_DEAD, CS_SPAWNING, CS_LAGGED, CS_EDITING, CS_SPECTATOR }
|
|||
|
||||
enum { PHYS_FLOAT = 0, PHYS_FALL, PHYS_SLIDE, PHYS_SLOPE, PHYS_FLOOR, PHYS_STEP_UP, PHYS_STEP_DOWN, PHYS_BOUNCE };
|
||||
|
||||
enum { ENT_PLAYER = 0, ENT_AI, ENT_INANIMATE, ENT_CAMERA, ENT_BOUNCE };
|
||||
enum { ENT_PLAYER = 0, ENT_CAMERA, ENT_BOUNCE };
|
||||
|
||||
enum { COLLIDE_AABB = 0, COLLIDE_OBB, COLLIDE_ELLIPSE };
|
||||
|
||||
|
|
|
@ -336,7 +336,6 @@ extern bool droptofloor(vec &o, float radius, float height);
|
|||
|
||||
extern void vecfromyawpitch(float yaw, float pitch, int move, int strafe, vec &m);
|
||||
extern void vectoyawpitch(const vec &v, float &yaw, float &pitch);
|
||||
extern bool moveplatform(physent *p, const vec &dir);
|
||||
extern void updatephysstate(physent *d);
|
||||
extern void cleardynentcache();
|
||||
extern void updatedynentcache(physent *d);
|
||||
|
|
|
@ -176,8 +176,6 @@
|
|||
<Option compile="1" />
|
||||
<Option weight="0" />
|
||||
</Unit>
|
||||
<Unit filename="..\fpsgame\monster.cpp" />
|
||||
<Unit filename="..\fpsgame\movable.cpp" />
|
||||
<Unit filename="..\fpsgame\render.cpp" />
|
||||
<Unit filename="..\fpsgame\scoreboard.cpp" />
|
||||
<Unit filename="..\fpsgame\server.cpp" />
|
||||
|
|
|
@ -1049,34 +1049,6 @@
|
|||
<PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)game.pch</PrecompiledHeaderOutputFile>
|
||||
<PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)game.pch</PrecompiledHeaderOutputFile>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\fpsgame\monster.cpp">
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">game.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">game.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)game.pch</PrecompiledHeaderOutputFile>
|
||||
<PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)game.pch</PrecompiledHeaderOutputFile>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">game.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">game.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">$(IntDir)game.pch</PrecompiledHeaderOutputFile>
|
||||
<PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">$(IntDir)game.pch</PrecompiledHeaderOutputFile>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">game.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">game.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)game.pch</PrecompiledHeaderOutputFile>
|
||||
<PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)game.pch</PrecompiledHeaderOutputFile>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\fpsgame\movable.cpp">
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">game.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">game.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)game.pch</PrecompiledHeaderOutputFile>
|
||||
<PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)game.pch</PrecompiledHeaderOutputFile>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">game.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">game.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Profile|Win32'">$(IntDir)game.pch</PrecompiledHeaderOutputFile>
|
||||
<PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Profile|x64'">$(IntDir)game.pch</PrecompiledHeaderOutputFile>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">game.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">game.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)game.pch</PrecompiledHeaderOutputFile>
|
||||
<PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)game.pch</PrecompiledHeaderOutputFile>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\fpsgame\pch.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
|
|
|
@ -70,8 +70,6 @@
|
|||
D1D040DA0F830C350043BA95 /* movie.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D1D040D90F830C350043BA95 /* movie.cpp */; };
|
||||
D1D07EFE0F645590007098A8 /* client.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D1D07EF60F645590007098A8 /* client.cpp */; };
|
||||
D1D07EFF0F645590007098A8 /* entities.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D1D07EF70F645590007098A8 /* entities.cpp */; };
|
||||
D1D07F000F645590007098A8 /* monster.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D1D07EF80F645590007098A8 /* monster.cpp */; };
|
||||
D1D07F010F645590007098A8 /* movable.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D1D07EF90F645590007098A8 /* movable.cpp */; };
|
||||
D1D07F020F645590007098A8 /* render.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D1D07EFA0F645590007098A8 /* render.cpp */; };
|
||||
D1D07F030F645590007098A8 /* scoreboard.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D1D07EFB0F645590007098A8 /* scoreboard.cpp */; };
|
||||
D1D07F040F645590007098A8 /* server.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D1D07EFC0F645590007098A8 /* server.cpp */; };
|
||||
|
@ -209,8 +207,6 @@
|
|||
D1D040D90F830C350043BA95 /* movie.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = movie.cpp; sourceTree = "<group>"; };
|
||||
D1D07EF60F645590007098A8 /* client.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = client.cpp; sourceTree = "<group>"; };
|
||||
D1D07EF70F645590007098A8 /* entities.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = entities.cpp; sourceTree = "<group>"; };
|
||||
D1D07EF80F645590007098A8 /* monster.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = monster.cpp; sourceTree = "<group>"; };
|
||||
D1D07EF90F645590007098A8 /* movable.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = movable.cpp; sourceTree = "<group>"; };
|
||||
D1D07EFA0F645590007098A8 /* render.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = render.cpp; sourceTree = "<group>"; };
|
||||
D1D07EFB0F645590007098A8 /* scoreboard.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = scoreboard.cpp; sourceTree = "<group>"; };
|
||||
D1D07EFC0F645590007098A8 /* server.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = server.cpp; sourceTree = "<group>"; };
|
||||
|
@ -415,8 +411,6 @@
|
|||
D11B024A0F830BA400334D69 /* ai.cpp */,
|
||||
D1D07EF60F645590007098A8 /* client.cpp */,
|
||||
D1D07EF70F645590007098A8 /* entities.cpp */,
|
||||
D1D07EF80F645590007098A8 /* monster.cpp */,
|
||||
D1D07EF90F645590007098A8 /* movable.cpp */,
|
||||
D1D07EFA0F645590007098A8 /* render.cpp */,
|
||||
D1D07EFB0F645590007098A8 /* scoreboard.cpp */,
|
||||
D1D07EFC0F645590007098A8 /* server.cpp */,
|
||||
|
@ -589,8 +583,6 @@
|
|||
D16E4E140ED107C300C401A2 /* blend.cpp in Sources */,
|
||||
D1D07EFE0F645590007098A8 /* client.cpp in Sources */,
|
||||
D1D07EFF0F645590007098A8 /* entities.cpp in Sources */,
|
||||
D1D07F000F645590007098A8 /* monster.cpp in Sources */,
|
||||
D1D07F010F645590007098A8 /* movable.cpp in Sources */,
|
||||
D1D07F020F645590007098A8 /* render.cpp in Sources */,
|
||||
D1D07F030F645590007098A8 /* scoreboard.cpp in Sources */,
|
||||
D1D07F040F645590007098A8 /* server.cpp in Sources */,
|
||||
|
|
Loading…
Reference in New Issue