experimental crouching and remove forward/jumping speed bonus
parent
38161cf1df
commit
b008294557
|
@ -56,6 +56,7 @@ bind 6 "setweapon PI"
|
|||
bind 7 "setweapon FI"
|
||||
|
||||
bind SPACE "jump"
|
||||
bind LSHIFT "crouch"
|
||||
bind MOUSERIGHT "jump"
|
||||
bind MOUSELEFT "attack"
|
||||
bind MOUSEMIDDLE "weapon"
|
||||
|
|
|
@ -1500,6 +1500,47 @@ bool move(physent *d, vec &dir)
|
|||
return !collided;
|
||||
}
|
||||
|
||||
void crouchplayer(physent *pl, int moveres, bool local, float speed, float minheight, float maxheight)
|
||||
{
|
||||
if(!curtime) return;
|
||||
speed = (maxheight - minheight) * (curtime / speed);
|
||||
if(pl->crouching < 0)
|
||||
{
|
||||
if(pl->eyeheight > minheight)
|
||||
{
|
||||
float diff = min(pl->eyeheight - minheight, speed);
|
||||
pl->eyeheight -= diff;
|
||||
if(pl->physstate > PHYS_FALL)
|
||||
{
|
||||
pl->o.z -= diff;
|
||||
pl->newpos.z -= diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(pl->eyeheight < maxheight)
|
||||
{
|
||||
float diff = min(maxheight - pl->eyeheight, speed), step = diff/moveres;
|
||||
pl->eyeheight += diff;
|
||||
if(pl->physstate > PHYS_FALL)
|
||||
{
|
||||
pl->o.z += diff;
|
||||
pl->newpos.z += diff;
|
||||
}
|
||||
pl->crouching = 0;
|
||||
loopi(moveres)
|
||||
{
|
||||
if(collide(pl, vec(0, 0, pl->physstate <= PHYS_FALL ? -1 : 1), 0, true)) break;
|
||||
pl->crouching = 1;
|
||||
pl->eyeheight -= step;
|
||||
if(pl->physstate > PHYS_FALL)
|
||||
{
|
||||
pl->o.z -= step;
|
||||
pl->newpos.z -= step;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool bounce(physent *d, float secs, float elasticity, float waterfric, float grav)
|
||||
{
|
||||
// make sure bouncers don't start inside geometry
|
||||
|
@ -1734,7 +1775,7 @@ void modifyvelocity(physent *pl, bool local, bool water, bool floating, int curt
|
|||
{
|
||||
if(pl==player) d.mul(floatspeed/100.0f);
|
||||
}
|
||||
else if(!water && game::allowmove(pl)) d.mul((pl->move && !pl->strafe ? 1.3f : 1.0f) * (pl->physstate < PHYS_SLOPE ? 1.3f : 1.0f));
|
||||
else if(pl->physstate >= PHYS_SLOPE && pl->crouching) d.mul(0.35f);
|
||||
}
|
||||
float fric = water && !floating ? 20.0f : (pl->physstate >= PHYS_SLOPE || floating ? 6.0f : 30.0f);
|
||||
pl->vel.lerp(d, pl->vel, pow(1 - 1/fric, curtime/20.0f));
|
||||
|
@ -1955,6 +1996,7 @@ dir(left, strafe, 1, k_left, k_right);
|
|||
dir(right, strafe, -1, k_right, k_left);
|
||||
|
||||
ICOMMAND(jump, "D", (int *down), { if(!*down || game::canjump()) player->jumping = *down!=0; });
|
||||
ICOMMAND(crouch, "D", (int *down), { if(!*down) player->crouching = abs(player->crouching); else if(game::cancrouch()) player->crouching = -1; });
|
||||
ICOMMAND(attack, "D", (int *down), { game::doattack(*down!=0); });
|
||||
|
||||
bool entinmap(dynent *d, bool avoidplayers) // brute force but effective way to find a free spawn spot in the map
|
||||
|
|
|
@ -1148,7 +1148,19 @@ void renderclient(dynent *d, const char *mdlname, modelattach *attachments, int
|
|||
else if(d->strafe) anim |= ((d->strafe>0 ? ANIM_LEFT : ANIM_RIGHT)|ANIM_LOOP)<<ANIM_SECONDARY;
|
||||
else if(d->move<0) anim |= (ANIM_BACKWARD|ANIM_LOOP)<<ANIM_SECONDARY;
|
||||
}
|
||||
|
||||
|
||||
if(d->crouching) switch((anim>>ANIM_SECONDARY)&ANIM_INDEX)
|
||||
{
|
||||
case ANIM_IDLE: anim &= ~(ANIM_INDEX<<ANIM_SECONDARY); anim |= ANIM_CROUCH<<ANIM_SECONDARY; break;
|
||||
case ANIM_JUMP: anim &= ~(ANIM_INDEX<<ANIM_SECONDARY); anim |= ANIM_CROUCH_JUMP<<ANIM_SECONDARY; break;
|
||||
case ANIM_SWIM: anim &= ~(ANIM_INDEX<<ANIM_SECONDARY); anim |= ANIM_CROUCH_SWIM<<ANIM_SECONDARY; break;
|
||||
case ANIM_SINK: anim &= ~(ANIM_INDEX<<ANIM_SECONDARY); anim |= ANIM_CROUCH_SINK<<ANIM_SECONDARY; break;
|
||||
case 0: anim |= (ANIM_CROUCH|ANIM_LOOP)<<ANIM_SECONDARY; break;
|
||||
case ANIM_FORWARD: case ANIM_BACKWARD: case ANIM_LEFT: case ANIM_RIGHT:
|
||||
anim += (ANIM_CROUCH_FORWARD - ANIM_FORWARD)<<ANIM_SECONDARY;
|
||||
break;
|
||||
}
|
||||
|
||||
if((anim&ANIM_INDEX)==ANIM_IDLE && (anim>>ANIM_SECONDARY)&ANIM_INDEX) anim >>= ANIM_SECONDARY;
|
||||
}
|
||||
if(d->ragdoll && (!ragdoll || (anim&ANIM_INDEX)!=ANIM_DYING)) DELETEP(d->ragdoll);
|
||||
|
|
|
@ -858,7 +858,7 @@ namespace game
|
|||
q.put(physstate);
|
||||
ivec o = ivec(vec(d->o.x, d->o.y, d->o.z-d->eyeheight).mul(DMF));
|
||||
uint vel = min(int(d->vel.magnitude()*DVELF), 0xFFFF), fall = min(int(d->falling.magnitude()*DVELF), 0xFFFF);
|
||||
// 3 bits position, 1 bit velocity, 3 bits falling, 1 bit material
|
||||
// 3 bits position, 1 bit velocity, 3 bits falling, 1 bit material, 1 bit crouching
|
||||
uint flags = 0;
|
||||
if(o.x < 0 || o.x > 0xFFFF) flags |= 1<<0;
|
||||
if(o.y < 0 || o.y > 0xFFFF) flags |= 1<<1;
|
||||
|
@ -871,6 +871,7 @@ namespace game
|
|||
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;
|
||||
if(d->crouching < 0) flags |= 1<<8;
|
||||
putuint(q, flags);
|
||||
loopk(3)
|
||||
{
|
||||
|
@ -1077,6 +1078,7 @@ namespace game
|
|||
d->roll = roll;
|
||||
d->move = (physstate>>4)&2 ? -1 : (physstate>>4)&1;
|
||||
d->strafe = (physstate>>6)&2 ? -1 : (physstate>>6)&1;
|
||||
d->crouching = (flags&(1<<8))!=0 ? -1 : abs(d->crouching);
|
||||
vec oldpos(d->o);
|
||||
if(allowmove(d))
|
||||
{
|
||||
|
|
|
@ -204,6 +204,7 @@ namespace game
|
|||
}
|
||||
if(d->state==CS_ALIVE || d->state==CS_EDITING)
|
||||
{
|
||||
crouchplayer(d, 10, false, CROUCHTIME, CROUCHMINHEIGHT, CROUCHMAXHEIGHT);
|
||||
if(smoothmove && d->smoothmillis>0) predictplayer(d, true);
|
||||
else moveplayer(d, 1, false);
|
||||
}
|
||||
|
@ -239,6 +240,7 @@ namespace game
|
|||
else if(!intermission)
|
||||
{
|
||||
if(player1->ragdoll) cleanragdoll(player1);
|
||||
crouchplayer(player1, 10, true, CROUCHTIME, CROUCHMINHEIGHT, CROUCHMAXHEIGHT);
|
||||
moveplayer(player1, 10, true);
|
||||
swayhudgun(curtime);
|
||||
entities::checkitems(player1);
|
||||
|
@ -293,6 +295,11 @@ namespace game
|
|||
return player1->state!=CS_DEAD && !intermission;
|
||||
}
|
||||
|
||||
bool cancrouch()
|
||||
{
|
||||
return player1->state!=CS_DEAD && !intermission;
|
||||
}
|
||||
|
||||
bool allowmove(physent *d)
|
||||
{
|
||||
if(d->type!=ENT_PLAYER) return true;
|
||||
|
|
|
@ -345,6 +345,10 @@ static const struct guninfo { int sound, attackdelay, damage, spread, projspeed,
|
|||
|
||||
#include "ai.h"
|
||||
|
||||
#define CROUCHTIME 150
|
||||
#define CROUCHMAXHEIGHT 14
|
||||
#define CROUCHMINHEIGHT 10
|
||||
|
||||
// inherited by fpsent and server clients
|
||||
struct fpsstate
|
||||
{
|
||||
|
@ -576,6 +580,7 @@ struct fpsent : dynent, fpsstate
|
|||
lastcollect = vec(-1e10f, -1e10f, -1e10f);
|
||||
stopattacksound();
|
||||
lastnode = -1;
|
||||
eyeheight = CROUCHMAXHEIGHT;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ struct physent // base entity type, can be affe
|
|||
|
||||
int inwater;
|
||||
bool jumping;
|
||||
char move, strafe;
|
||||
char move, strafe, crouching;
|
||||
|
||||
uchar physstate; // one of PHYS_* above
|
||||
uchar state, editstate; // one of CS_* above
|
||||
|
@ -80,7 +80,7 @@ struct physent // base entity type, can be affe
|
|||
{
|
||||
inwater = 0;
|
||||
timeinair = 0;
|
||||
strafe = move = 0;
|
||||
strafe = move = crouching = 0;
|
||||
physstate = PHYS_FALL;
|
||||
vel = falling = vec(0, 0, 0);
|
||||
floor = vec(0, 0, 1);
|
||||
|
@ -96,10 +96,13 @@ enum
|
|||
{
|
||||
ANIM_DEAD = 0, ANIM_DYING, ANIM_IDLE,
|
||||
ANIM_FORWARD, ANIM_BACKWARD, ANIM_LEFT, ANIM_RIGHT,
|
||||
ANIM_CROUCH, ANIM_CROUCH_FORWARD, ANIM_CROUCH_BACKWARD, ANIM_CROUCH_LEFT, ANIM_CROUCH_RIGHT,
|
||||
|
||||
ANIM_HOLD1, ANIM_HOLD2, ANIM_HOLD3, ANIM_HOLD4, ANIM_HOLD5, ANIM_HOLD6, ANIM_HOLD7,
|
||||
ANIM_ATTACK1, ANIM_ATTACK2, ANIM_ATTACK3, ANIM_ATTACK4, ANIM_ATTACK5, ANIM_ATTACK6, ANIM_ATTACK7,
|
||||
ANIM_PAIN,
|
||||
ANIM_JUMP, ANIM_SINK, ANIM_SWIM,
|
||||
ANIM_CROUCH_JUMP, ANIM_CROUCH_SINK, ANIM_CROUCH_SWIM,
|
||||
ANIM_EDIT, ANIM_LAG, ANIM_TAUNT, ANIM_WIN, ANIM_LOSE,
|
||||
ANIM_GUN_IDLE, ANIM_GUN_SHOOT,
|
||||
ANIM_VWEP_IDLE, ANIM_VWEP_SHOOT, ANIM_SHIELD, ANIM_POWERUP,
|
||||
|
@ -111,10 +114,12 @@ static const char * const animnames[] =
|
|||
{
|
||||
"dead", "dying", "idle",
|
||||
"forward", "backward", "left", "right",
|
||||
"crouch", "crouch forward", "crouch backward", "crouch left", "crouch right",
|
||||
"hold 1", "hold 2", "hold 3", "hold 4", "hold 5", "hold 6", "hold 7",
|
||||
"attack 1", "attack 2", "attack 3", "attack 4", "attack 5", "attack 6", "attack 7",
|
||||
"pain",
|
||||
"jump", "sink", "swim",
|
||||
"crouch jump", "crouch sink", "crouch swim",
|
||||
"edit", "lag", "taunt", "win", "lose",
|
||||
"gun idle", "gun shoot",
|
||||
"vwep idle", "vwep shoot", "shield", "powerup",
|
||||
|
@ -193,7 +198,7 @@ struct dynent : physent // animated characters, or chara
|
|||
void stopmoving()
|
||||
{
|
||||
k_left = k_right = k_up = k_down = jumping = false;
|
||||
move = strafe = 0;
|
||||
move = strafe = crouching = 0;
|
||||
}
|
||||
|
||||
void reset()
|
||||
|
|
|
@ -336,6 +336,7 @@ extern bool loadents(const char *fname, vector<entity> &ents, uint *crc = NULL);
|
|||
// physics
|
||||
extern void moveplayer(physent *pl, int moveres, bool local);
|
||||
extern bool moveplayer(physent *pl, int moveres, bool local, int curtime);
|
||||
extern void crouchplayer(physent *pl, int moveres, bool local, float speed, float minheight, float maxheight);
|
||||
extern bool collide(physent *d, const vec &dir = vec(0, 0, 0), float cutoff = 0.0f, bool playercol = true);
|
||||
extern bool bounce(physent *d, float secs, float elasticity, float waterfric, float grav);
|
||||
extern bool bounce(physent *d, float elasticity, float waterfric, float grav);
|
||||
|
|
|
@ -67,6 +67,7 @@ namespace game
|
|||
extern float abovegameplayhud(int w, int h);
|
||||
extern void gameplayhud(int w, int h);
|
||||
extern bool canjump();
|
||||
extern bool cancrouch();
|
||||
extern bool allowmove(physent *d);
|
||||
extern void doattack(bool on);
|
||||
extern dynent *iterdynents(int i);
|
||||
|
|
Loading…
Reference in New Issue