Skip to content

Instantly share code, notes, and snippets.

@sauerbraten
Created September 7, 2021 18:13
Show Gist options
  • Save sauerbraten/dc2421836c7f8f38caaf5f903a6fd1ec to your computer and use it in GitHub Desktop.
Save sauerbraten/dc2421836c7f8f38caaf5f903a6fd1ec to your computer and use it in GitHub Desktop.
up/down/hover floating movement patch
Index: src/engine/physics.cpp
===================================================================
--- src/engine/physics.cpp (revision 6518)
+++ src/engine/physics.cpp (working copy)
@@ -1545,30 +1545,18 @@
COMMAND(phystest, "");
-void vecfromyawpitch(float yaw, float pitch, int move, int strafe, vec &m)
+void vecfromyawpitch(float yaw, float pitch, int move, int strafe, int vertical, vec &m)
{
- if(move)
- {
- m.x = move*-sinf(RAD*yaw);
- m.y = move*cosf(RAD*yaw);
+ m.x = move*-sinf(RAD*yaw)*cosf(RAD*pitch) + vertical*-sinf(RAD*pitch)*-sinf(RAD*yaw) + strafe*cosf(RAD*yaw);
+ m.y = move* cosf(RAD*yaw)*cosf(RAD*pitch) + vertical*-sinf(RAD*pitch)* cosf(RAD*yaw) + strafe*sinf(RAD*yaw);
+ m.z = move* sinf(RAD*pitch) + vertical* cosf(RAD*pitch);
}
- else m.x = m.y = 0;
- if(pitch)
+void vecfromyawpitch(float yaw, float pitch, int move, int strafe, vec &m)
{
- m.x *= cosf(RAD*pitch);
- m.y *= cosf(RAD*pitch);
- m.z = move*sinf(RAD*pitch);
+ vecfromyawpitch(yaw, pitch, move, strafe, 0, m);
}
- else m.z = 0;
- if(strafe)
- {
- m.x += strafe*cosf(RAD*yaw);
- m.y += strafe*sinf(RAD*yaw);
- }
-}
-
void vectoyawpitch(const vec &v, float &yaw, float &pitch)
{
if(v.iszero()) yaw = pitch = 0;
@@ -1613,9 +1601,10 @@
if(!floating && pl->physstate == PHYS_FALL) pl->timeinair = min(pl->timeinair + curtime, 1000);
vec m(0.0f, 0.0f, 0.0f);
- if((pl->move || pl->strafe) && allowmove)
+ if((pl->move || pl->strafe || pl->vertical) && allowmove)
{
- vecfromyawpitch(pl->yaw, floating || water || pl->type==ENT_CAMERA ? pl->pitch : 0, pl->move, pl->strafe, m);
+ bool allowvertical = !pl->hovering && (floating || water || pl->type==ENT_CAMERA);
+ vecfromyawpitch(pl->yaw, allowvertical ? pl->pitch : 0, pl->move, pl->strafe, pl->vertical, m);
if(!floating && pl->physstate >= PHYS_SLOPE)
{
@@ -1686,7 +1675,7 @@
float secs = curtime/1000.f;
// apply gravity
- if(!floating) modifygravity(pl, water, curtime);
+ if(!floating) { pl->vertical = 0; modifygravity(pl, water, curtime); }
// apply any player generated changes in velocity
modifyvelocity(pl, local, water, floating, curtime);
@@ -2011,12 +2000,15 @@
#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);
-dir(forward, move, 1, k_up, k_down);
+dir(forward, move, 1, k_forward, k_backward);
+dir(backward, move, -1, k_backward, k_forward);
dir(left, strafe, 1, k_left, k_right);
dir(right, strafe, -1, k_right, k_left);
+dir(up, vertical, 1, k_up, k_down);
+dir(down, vertical, -1, k_down, k_up);
ICOMMAND(jump, "D", (int *down), { if(!*down || game::canjump()) player->jumping = *down!=0; });
+ICOMMAND(hover, "D", (int *down), { if(!*down || game::canhover()) player->hovering = *down!=0; });
ICOMMAND(attack, "D", (int *down), { game::doattack(*down!=0); });
bool entinmap(dynent *d, bool avoidplayers) // brute force but effective way to find a free spawn spot in the map
Index: src/fpsgame/fps.cpp
===================================================================
--- src/fpsgame/fps.cpp (revision 6518)
+++ src/fpsgame/fps.cpp (working copy)
@@ -385,6 +385,11 @@
return player1->state!=CS_DEAD;
}
+ bool canhover()
+ {
+ return player1->state==CS_SPECTATOR || player1->state==CS_EDITING;
+ }
+
bool allowmove(physent *d)
{
if(d->type!=ENT_PLAYER) return true;
Index: src/rpggame/rpg.cpp
===================================================================
--- src/rpggame/rpg.cpp (revision 6518)
+++ src/rpggame/rpg.cpp (working copy)
@@ -204,6 +204,7 @@
}
bool canjump() { return true; }
+ bool canhover() { return false; }
bool allowmove(physent *d) { return d->type!=ENT_AI || ((rpgent *)d)->allowmove(); }
void doattack(bool on) { player1->attacking = on; }
dynent *iterdynents(int i) { return i ? objects[i-1]->ent : player1; }
Index: src/shared/ents.h
===================================================================
--- src/shared/ents.h (revision 6518)
+++ src/shared/ents.h (working copy)
@@ -77,8 +77,8 @@
ushort timeinair;
uchar inwater;
- bool jumping;
- schar move, strafe;
+ bool jumping, hovering;
+ schar move, strafe, vertical;
uchar physstate; // one of PHYS_* above
uchar state, editstate; // one of CS_* above
@@ -105,6 +105,7 @@
inwater = 0;
timeinair = 0;
jumping = false;
+ hovering = false;
strafe = move = 0;
physstate = PHYS_FALL;
vel = falling = vec(0, 0, 0);
@@ -196,7 +197,7 @@
struct dynent : physent // animated characters, or characters that can receive input
{
- bool k_left, k_right, k_up, k_down; // see input code
+ bool k_left, k_right, k_forward, k_backward, k_up, k_down; // see input code
entitylight light;
animinterpinfo animinterp[MAXANIMPARTS];
@@ -220,7 +221,7 @@
void stopmoving()
{
- k_left = k_right = k_up = k_down = jumping = false;
+ k_left = k_right = k_forward = k_backward = k_up = k_down = jumping = hovering = false;
move = strafe = 0;
}
Index: src/shared/igame.h
===================================================================
--- src/shared/igame.h (revision 6518)
+++ src/shared/igame.h (working copy)
@@ -69,6 +69,7 @@
extern float abovegameplayhud(int w, int h);
extern void gameplayhud(int w, int h);
extern bool canjump();
+ extern bool canhover();
extern bool allowmove(physent *d);
extern void doattack(bool on);
extern dynent *iterdynents(int i);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment