experimental crouching and remove forward/jumping speed bonus

master
Lee Salzman 2013-05-28 02:37:08 +03:00
parent 38161cf1df
commit b008294557
9 changed files with 82 additions and 6 deletions

View File

@ -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"

View File

@ -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

View File

@ -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);

View File

@ -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))
{

View File

@ -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;

View File

@ -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;
}
};

View File

@ -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()

View File

@ -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);

View File

@ -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);