From 35e6793287a0881333f6018ac2046fc4cd7177d1 Mon Sep 17 00:00:00 2001
From: Tim Angus <tim@ngus.net>
Date: Tue, 2 Sep 2003 04:19:44 +0000
Subject: * Ladders. Use "surfaceParm ladder" in ladder shaders

---
 src/game/bg_local.h     |  1 +
 src/game/bg_misc.c      |  5 ++-
 src/game/bg_pmove.c     | 97 +++++++++++++++++++++++++++++++++++++++++++------
 src/game/bg_public.h    |  1 +
 src/game/surfaceflags.h | 88 ++++++++++++++++++++++----------------------
 5 files changed, 135 insertions(+), 57 deletions(-)

(limited to 'src')

diff --git a/src/game/bg_local.h b/src/game/bg_local.h
index 8a6d99b3..778bebba 100644
--- a/src/game/bg_local.h
+++ b/src/game/bg_local.h
@@ -39,6 +39,7 @@ typedef struct
 
   qboolean  walking;
   qboolean  groundPlane;
+  qboolean  ladder;
   trace_t   groundTrace;
 
   float     impactSpeed;
diff --git a/src/game/bg_misc.c b/src/game/bg_misc.c
index 7676c2cf..73d56c12 100644
--- a/src/game/bg_misc.c
+++ b/src/game/bg_misc.c
@@ -1538,7 +1538,7 @@ classAttributes_t bg_classList[ ] =
     BMOFO_REGEN,                                    //int     regenRate;
     SCA_CANJUMP|SCA_NOWEAPONDRIFT|
       SCA_FOVWARPS|SCA_ALIENSENSE|SCA_NOFOOTSTEPS,  //int     abilities;
-    WP_CHARGE,                                //weapon_t  startWeapon
+    WP_CHARGE,                                      //weapon_t  startWeapon
     0.0f,                                           //float   buildDist;
     90,                                             //int     fov;
     0.001f,                                         //float   bob;
@@ -1569,7 +1569,8 @@ classAttributes_t bg_classList[ ] =
     100,                                            //int     health;
     1.0f,                                           //float   fallDamage;
     0,                                              //int     regenRate;
-    SCA_TAKESFALLDAMAGE|SCA_CANJUMP,                //int     abilities;
+    SCA_TAKESFALLDAMAGE|SCA_CANJUMP|
+      SCA_CANUSELADDERS,                            //int     abilities;
     WP_NONE, //special-cased in g_client.c          //weapon_t  startWeapon
     110.0f,                                         //float   buildDist;
     90,                                             //int     fov;
diff --git a/src/game/bg_pmove.c b/src/game/bg_pmove.c
index df2f7c7e..74ab3be2 100644
--- a/src/game/bg_pmove.c
+++ b/src/game/bg_pmove.c
@@ -246,7 +246,7 @@ static void PM_Friction( void )
   // apply ground friction
   if( pm->waterlevel <= 1 )
   {
-    if( pml.walking && !( pml.groundTrace.surfaceFlags & SURF_SLICK ) )
+    if( ( pml.walking || pml.ladder ) && !( pml.groundTrace.surfaceFlags & SURF_SLICK ) )
     {
       // if getting knocked back, no friction
       if( !( pm->ps->pm_flags & PMF_TIME_KNOCKBACK ) )
@@ -916,16 +916,6 @@ static void PM_AirMove( void )
     PM_ClipVelocity( pm->ps->velocity, pml.groundTrace.plane.normal,
       pm->ps->velocity, OVERCLIP );
 
-#if 0
-  //ZOID:  If we are on the grapple, try stair-stepping
-  //this allows a player to use the grapple to pull himself
-  //over a ledge
-  if (pm->ps->pm_flags & PMF_GRAPPLE_PULL)
-    PM_StepSlideMove ( qtrue );
-  else
-    PM_SlideMove ( qtrue );
-#endif
-
   PM_StepSlideMove( qtrue, qfalse );
 }
 
@@ -1201,6 +1191,86 @@ static void PM_WalkMove( void )
 }
 
 
+/*
+===================
+PM_LadderMove
+
+Basically a rip of PM_WaterMove with a few changes
+===================
+*/
+static void PM_LadderMove( void )
+{
+  int     i;
+  vec3_t  wishvel;
+  float   wishspeed;
+  vec3_t  wishdir;
+  float   scale;
+  float   vel;
+
+  PM_Friction( );
+
+  scale = PM_CmdScale( &pm->cmd );
+  
+  for( i = 0; i < 3; i++ )
+    wishvel[ i ] = scale * pml.forward[ i ] * pm->cmd.forwardmove + scale * pml.right[ i ] * pm->cmd.rightmove;
+
+  wishvel[ 2 ] += scale * pm->cmd.upmove;
+
+  VectorCopy( wishvel, wishdir );
+  wishspeed = VectorNormalize( wishdir );
+
+  if( wishspeed > pm->ps->speed * pm_swimScale )
+    wishspeed = pm->ps->speed * pm_swimScale;
+
+  PM_Accelerate( wishdir, wishspeed, pm_accelerate );
+
+  //slanty ladders
+  if( pml.groundPlane && DotProduct( pm->ps->velocity, pml.groundTrace.plane.normal ) < 0.0f )
+  {
+    vel = VectorLength( pm->ps->velocity );
+
+    // slide along the ground plane
+    PM_ClipVelocity( pm->ps->velocity, pml.groundTrace.plane.normal,
+      pm->ps->velocity, OVERCLIP );
+
+    VectorNormalize( pm->ps->velocity );
+    VectorScale( pm->ps->velocity, vel, pm->ps->velocity );
+  }
+
+  PM_SlideMove( qfalse );
+}
+
+
+/*
+=============
+PM_CheckLadder
+
+Check to see if the player is on a ladder or not
+=============
+*/
+static void PM_CheckLadder( void )
+{
+  vec3_t  forward, end;
+  trace_t trace;
+  
+  //test if class can use ladders
+  if( !BG_ClassHasAbility( pm->ps->stats[ STAT_PCLASS ], SCA_CANUSELADDERS ) )
+    pml.ladder = qfalse;
+  
+  VectorCopy( pml.forward, forward );
+  forward[ 2 ] = 0.0f;
+  
+  VectorMA( pm->ps->origin, 1.0f, forward, end );
+  
+  pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, end, pm->ps->clientNum, MASK_PLAYERSOLID );
+  
+  if( ( trace.fraction < 1.0f ) && ( trace.surfaceFlags & SURF_LADDER ) )
+    pml.ladder = qtrue;
+  else
+    pml.ladder = qfalse;
+}
+          
+          
 /*
 ==============
 PM_DeadMove
@@ -3040,8 +3110,11 @@ void PmoveSingle (pmove_t *pmove)
   // set mins, maxs, and viewheight
   PM_CheckDuck( );
 
+  PM_CheckLadder( );
+  
   // set groundentity
   PM_GroundTrace( );
+  
   // update the viewangles
   PM_UpdateViewAngles( pm->ps, &pm->cmd );
 
@@ -3062,6 +3135,8 @@ void PmoveSingle (pmove_t *pmove)
     PM_WaterJumpMove( );
   else if ( pm->waterlevel > 1 )
     PM_WaterMove( );
+  else if ( pml.ladder )
+    PM_LadderMove( );
   else if ( pml.walking )
   {
     if( BG_ClassHasAbility( pm->ps->stats[ STAT_PCLASS ], SCA_WALLCLIMBER ) &&
diff --git a/src/game/bg_public.h b/src/game/bg_public.h
index 48fd2157..748c5ba1 100644
--- a/src/game/bg_public.h
+++ b/src/game/bg_public.h
@@ -218,6 +218,7 @@ typedef enum
 #define SCA_FOVWARPS            0x00000020
 #define SCA_ALIENSENSE          0x00000040
 #define SCA_NOFOOTSTEPS         0x00000080
+#define SCA_CANUSELADDERS       0x00000100
 
 #define SS_WALLCLIMBING         0x00000001
 #define SS_WALLCLIMBINGCEILING  0x00000002
diff --git a/src/game/surfaceflags.h b/src/game/surfaceflags.h
index 455a1054..2a31631e 100644
--- a/src/game/surfaceflags.h
+++ b/src/game/surfaceflags.h
@@ -20,55 +20,55 @@
 
 // these definitions also need to be in q_shared.h!
 
-#define	CONTENTS_SOLID			1		// an eye is never valid in a solid
-#define	CONTENTS_LAVA			8
-#define	CONTENTS_SLIME			16
-#define	CONTENTS_WATER			32
-#define	CONTENTS_FOG			64
+#define CONTENTS_SOLID          1   // an eye is never valid in a solid
+#define CONTENTS_LAVA           8
+#define CONTENTS_SLIME          16
+#define CONTENTS_WATER          32
+#define CONTENTS_FOG            64
 
-#define CONTENTS_NOTTEAM1   0x0080
-#define CONTENTS_NOTTEAM2   0x0100
-#define CONTENTS_NOBOTCLIP    0x0200
+#define CONTENTS_NOTTEAM1       0x0080
+#define CONTENTS_NOTTEAM2       0x0100
+#define CONTENTS_NOBOTCLIP      0x0200
 
-#define	CONTENTS_AREAPORTAL		0x8000
+#define CONTENTS_AREAPORTAL     0x8000
 
-#define	CONTENTS_PLAYERCLIP		0x10000
-#define	CONTENTS_MONSTERCLIP	0x20000
+#define CONTENTS_PLAYERCLIP     0x10000
+#define CONTENTS_MONSTERCLIP    0x20000
 //bot specific contents types
-#define	CONTENTS_TELEPORTER		0x40000
-#define	CONTENTS_JUMPPAD		0x80000
-#define CONTENTS_CLUSTERPORTAL	0x100000
-#define CONTENTS_DONOTENTER		0x200000
-#define CONTENTS_BOTCLIP    0x400000
-#define CONTENTS_MOVER      0x800000
+#define CONTENTS_TELEPORTER     0x40000
+#define CONTENTS_JUMPPAD        0x80000
+#define CONTENTS_CLUSTERPORTAL  0x100000
+#define CONTENTS_DONOTENTER     0x200000
+#define CONTENTS_BOTCLIP        0x400000
+#define CONTENTS_MOVER          0x800000
 
-#define	CONTENTS_ORIGIN			0x1000000	// removed before bsping an entity
+#define CONTENTS_ORIGIN         0x1000000 // removed before bsping an entity
 
-#define	CONTENTS_BODY			0x2000000	// should never be on a brush, only in game
-#define	CONTENTS_CORPSE			0x4000000
-#define	CONTENTS_DETAIL			0x8000000	// brushes not used for the bsp
-#define	CONTENTS_STRUCTURAL		0x10000000	// brushes used for the bsp
-#define	CONTENTS_TRANSLUCENT	0x20000000	// don't consume surface fragments inside
-#define	CONTENTS_TRIGGER		0x40000000
-#define	CONTENTS_NODROP			0x80000000	// don't leave bodies or items (death fog, lava)
+#define CONTENTS_BODY           0x2000000 // should never be on a brush, only in game
+#define CONTENTS_CORPSE         0x4000000
+#define CONTENTS_DETAIL         0x8000000 // brushes not used for the bsp
+#define CONTENTS_STRUCTURAL     0x10000000  // brushes used for the bsp
+#define CONTENTS_TRANSLUCENT    0x20000000  // don't consume surface fragments inside
+#define CONTENTS_TRIGGER        0x40000000
+#define CONTENTS_NODROP         0x80000000  // don't leave bodies or items (death fog, lava)
 
-#define	SURF_NODAMAGE			0x1		// never give falling damage
-#define	SURF_SLICK				0x2		// effects game physics
-#define	SURF_SKY				0x4		// lighting from environment map
-#define	SURF_LADDER				0x8
-#define	SURF_NOIMPACT			0x10	// don't make missile explosions
-#define	SURF_NOMARKS			0x20	// don't leave missile marks
-#define	SURF_FLESH				0x40	// make flesh sounds and effects
-#define	SURF_NODRAW				0x80	// don't generate a drawsurface at all
-#define	SURF_HINT				0x100	// make a primary bsp splitter
-#define	SURF_SKIP				0x200	// completely ignore, allowing non-closed brushes
-#define	SURF_NOLIGHTMAP			0x400	// surface doesn't need a lightmap
-#define	SURF_POINTLIGHT			0x800	// generate lighting info at vertexes
-#define	SURF_METALSTEPS			0x1000	// clanking footsteps
-#define	SURF_NOSTEPS			0x2000	// no footstep sounds
-#define	SURF_NONSOLID			0x4000	// don't collide against curves with this set
-#define SURF_LIGHTFILTER		0x8000	// act as a light filter during q3map -light
-#define	SURF_ALPHASHADOW		0x10000	// do per-pixel light shadow casting in q3map
-#define	SURF_NODLIGHT			0x20000	// don't dlight even if solid (solid lava, skies)
-#define SURF_DUST         0x40000 // leave a dust trail when walking on this surface
+#define SURF_NODAMAGE           0x1   // never give falling damage
+#define SURF_SLICK              0x2   // effects game physics
+#define SURF_SKY                0x4   // lighting from environment map
+#define SURF_LADDER             0x8
+#define SURF_NOIMPACT           0x10  // don't make missile explosions
+#define SURF_NOMARKS            0x20  // don't leave missile marks
+#define SURF_FLESH              0x40  // make flesh sounds and effects
+#define SURF_NODRAW             0x80  // don't generate a drawsurface at all
+#define SURF_HINT               0x100 // make a primary bsp splitter
+#define SURF_SKIP               0x200 // completely ignore, allowing non-closed brushes
+#define SURF_NOLIGHTMAP         0x400 // surface doesn't need a lightmap
+#define SURF_POINTLIGHT         0x800 // generate lighting info at vertexes
+#define SURF_METALSTEPS         0x1000  // clanking footsteps
+#define SURF_NOSTEPS            0x2000  // no footstep sounds
+#define SURF_NONSOLID           0x4000  // don't collide against curves with this set
+#define SURF_LIGHTFILTER        0x8000  // act as a light filter during q3map -light
+#define SURF_ALPHASHADOW        0x10000 // do per-pixel light shadow casting in q3map
+#define SURF_NODLIGHT           0x20000 // don't dlight even if solid (solid lava, skies)
+#define SURF_DUST               0x40000 // leave a dust trail when walking on this surface
 
-- 
cgit