/*
===================
PM_Toggle_Gear

===================
*/
void PM_Toggle_HeloGear()
{
	if( !(availableVehicles[pm->vehicle].caps & HC_GEAR) ) {
		return;
	}

	if( pm->ps->ONOFF & OO_LANDED ) {
		return;
	}

	if( pm->cmd.serverTime < pm->ps->timers[TIMER_GEAR] && pm->ps->timers[TIMER_GEARANIM] ) {
		return;
	}

	if( pm->ps->speed > availableVehicles[pm->vehicle].stallspeed * 10 * SPEED_GREEN_ARC ) {
		pm->ps->timers[TIMER_GEAR] = pm->cmd.serverTime + availableVehicles[pm->vehicle].gearTime + 100;
		return;
	}

	if( pm->ps->ONOFF & OO_GEAR ) {
		PM_AddEvent( EV_GEAR_UP );
		pm->ps->timers[TIMER_GEARANIM] = pm->cmd.serverTime + availableVehicles[pm->vehicle].gearTime;
//		pm->ps->ONOFF &= ~OO_GEAR;
	}
	else {
		PM_AddEvent( EV_GEAR_DOWN );
		pm->ps->timers[TIMER_GEARANIM] = pm->cmd.serverTime + availableVehicles[pm->vehicle].gearTime;
//		pm->ps->ONOFF |= OO_GEAR;
	}
	pm->ps->timers[TIMER_GEAR] = pm->cmd.serverTime + availableVehicles[pm->vehicle].gearTime + 100;
}
Example #2
0
/*
==============
PM_WaterEvents

Generate sound events for entering and leaving water
==============
*/
static void PM_WaterEvents( void ) {		// FIXME?
	//
	// if just entered a water volume, play a sound
	//
	if (!pml.previous_waterlevel && pm->waterlevel) {
		PM_AddEvent( EV_WATER_TOUCH );
	}

	//
	// if just completely exited a water volume, play a sound
	//
	if (pml.previous_waterlevel && !pm->waterlevel) {
		PM_AddEvent( EV_WATER_LEAVE );
	}

	//
	// check for head just going under water
	//
	if (pml.previous_waterlevel != 3 && pm->waterlevel == 3) {
		PM_AddEvent( EV_WATER_UNDER );
	}

	//
	// check for head just coming out of water
	//
	if (pml.previous_waterlevel == 3 && pm->waterlevel != 3) {
		PM_AddEvent( EV_WATER_CLEAR );
	}
}
Example #3
0
/*
=============
PM_CheckJump
=============
*/
static qboolean PM_CheckJump( void ) {
	if ( pm->ps->pm_flags & PMF_RESPAWNED ) {
		return qfalse;		// don't allow jump until all buttons are up
	}

	if ( pm->cmd.upmove < 10 ) {
		// not holding jump
		return qfalse;
	}

	// must wait for jump to be released
	if ( pm->ps->pm_flags & PMF_JUMP_HELD ) {
		// clear upmove so cmdscale doesn't lower running speed
		pm->cmd.upmove = 0;
		return qfalse;
	}

	pml.groundPlane = qfalse;		// jumping away
	pml.walking = qfalse;
	pm->ps->pm_flags |= PMF_JUMP_HELD;

	pm->ps->groundEntityNum = ENTITYNUM_NONE;
	pm->ps->velocity[2] = JUMP_VELOCITY;
	PM_AddEvent( EV_JUMP );

	if ( pm->cmd.forwardmove >= 0 ) {
		PM_ForceLegsAnim( LEGS_JUMP );
		pm->ps->pm_flags &= ~PMF_BACKWARDS_JUMP;
	} else {
		PM_ForceLegsAnim( LEGS_JUMPB );
		pm->ps->pm_flags |= PMF_BACKWARDS_JUMP;
	}

	return qtrue;
}
Example #4
0
static void PM_Animate( void ) {
	if ( pm->cmd.buttons & BUTTON_GESTURE ) {
		if ( pm->ps->torsoTimer == 0 ) {
			PM_StartTorsoAnim( TORSO_GESTURE );
			pm->ps->torsoTimer = TIMER_GESTURE;
			PM_AddEvent( EV_TAUNT );
		}
	}
}
Example #5
0
static void PM_BeginWeaponReload() { //works for kar98 sniper? rest not? mmhm
	
	pmove_t *xm = *(pmove_t**)(int)pm;
	
	int clientNum = *(int*)((int)xm->ps + 172);
	xclient_t *xcl = &xclients[clientNum];
	
	int *weapons = *(int**)((int)xm->ps + 796);
	int weapon = *(int*)((int)xm->ps + 176);
	int *weaponTime = (int*)((int)xm->ps + 44);
	int *weaponDelay = (int*)((int)xm->ps + 48);
	
	int weaponinfo = BG_GetInfoForWeapon(weapon);
	
	int *weaponstate = (int*)((int)xm->ps + 180);
	
	if(*weaponstate == WEAPON_READY || *weaponstate == WEAPON_FIRING || *weaponstate == WEAPON_RECHAMBERING) {
		int weapon = *(int*)((int)xm->ps + 176);
		if(weapon) {
			if(weapon <= BG_GetNumWeapons()) {
				
				int weaponinfo = BG_GetInfoForWeapon(weapon);
				
				if(!*(int*)(weaponinfo + 724))
					BG_AnimScriptEvent(xm->ps, 10, 0, 1);
				
				int v2 = *(int*)((int)pml + 132);
				
				if(*(int*)(v2 + 748) && *(int*)(v2 + 500)) {
					if(xm->ps->pm_type <= 5) {
						if(*(unsigned char*)((int)xm + 10)) {
							int v4 = *(int*)((int)xm->ps + 980) & 0x200;
							BYTE1(v4) ^= 2u;
							LOBYTE(v4) = 13;
							*(int*)((int)xm->ps + 980) = v4;
						}
					}
					if(xcl->perks[PERK_QUICK_RELOAD])
						*weaponTime = (int)(*(int*)(v2 + 500) / QUICK_RELOAD_FRACTION);
					else
						*weaponTime = *(int*)(v2 + 500);
					*weaponstate = WEAPON_RELOAD_START; //7
					
					PM_AddEvent(EV_RELOAD_START);
					PM_SetWeaponReloadAddAmmoDelay();//sub_377B8
					if(xcl->perks[PERK_QUICK_RELOAD])
						*weaponDelay = (int)(*weaponDelay / QUICK_RELOAD_FRACTION);
				} else {
					PM_SetReloadingState();//sub_378BC
				}
			}
		}
	}
}
Example #6
0
static void PM_SetReloadingState() {
	pmove_t *xm = *(pmove_t**)(int)pm;
	
	int clientNum = *(int*)((int)xm->ps + 172);
	xclient_t *xcl = &xclients[clientNum];
	
	int *weaponstate = (int*)((int)xm->ps + 180);
	int *weapons = *(int**)((int)xm->ps + 796);
	int weapon = *(int*)((int)xm->ps + 176);
	int *weaponTime = (int*)((int)xm->ps + 44);
	int *weaponDelay = (int*)((int)xm->ps + 48);
	
	int weaponinfo = BG_GetInfoForWeapon(weapon);
	
	int v2 = *(int*)((int)pml + 132);
	int event = EV_RELOAD_FROM_EMPTY, v3;
	if (*(int *)(4 * *(int *)(weaponinfo + 424) + (int)xm->ps + 524) || *(int *)(v2 + 112)) {
		if ( xm->ps->pm_type <= 5 ) {
			if (xm->cmd.wbuttons ) {
				v3 = *(int *)((int)xm->ps + 980) & 0x200;
				BYTE1(v3) ^= 2u;
				LOBYTE(v3) = 11;
				*(int *)((int)xm->ps + 980) = v3;
			}
		}
		if(!xcl->perks[PERK_QUICK_RELOAD])
		*weaponTime = *(int *)(v2 + 488);
		else
		*weaponTime = (int)(*(int *)(v2 + 488) / QUICK_RELOAD_FRACTION);
		event = EV_RELOAD;
	} else {
		if ( xm->ps->pm_type <= 5 ) {
			if (xm->cmd.wbuttons ) {
				v3 = *(int *)((int)xm->ps + 980) & 0x200;
				BYTE1(v3) ^= 2u;
				LOBYTE(v3) = 12;
				*(int *)((int)xm->ps + 980) = v3;
			}
		}
		if(!xcl->perks[PERK_QUICK_RELOAD])
		*weaponTime = *(int *)(v2 + 492);
		else
		*weaponTime = (int)(*(int *)(v2 + 492) / QUICK_RELOAD_FRACTION);
	}
	PM_AddEvent(event);
	if ( *weaponstate == 8 )
		*weaponstate = 6; //WEAPON_RELOADING_INTERRUPT??
	else
		*weaponstate = 5; //WEAPON_RELOADING
	//if(!reloadtime->integer)
	PM_SetWeaponReloadAddAmmoDelay();
	if(xcl->perks[PERK_QUICK_RELOAD])
		*weaponDelay = (int)(*weaponDelay / QUICK_RELOAD_FRACTION);
}
/*
==================
PM_StepEvent
==================
*/
void PM_StepEvent( vec3_t from, vec3_t to, vec3_t normal )
{
  float   size;
  vec3_t  delta, dNormal;

  VectorSubtract( from, to, delta );
  VectorCopy( delta, dNormal );
  VectorNormalize( dNormal );

  size = DotProduct( normal, dNormal ) * VectorLength( delta );

  if( size > 0.0f )
  {
    if( size > 2.0f )
    {
      if( size < 7.0f )
        PM_AddEvent( EV_STEPDN_4 );
      else if( size < 11.0f )
        PM_AddEvent( EV_STEPDN_8 );
      else if( size < 15.0f )
        PM_AddEvent( EV_STEPDN_12 );
      else
        PM_AddEvent( EV_STEPDN_16 );
    }
  }
  else
  {
    size = fabs( size );

    if( size > 2.0f )
    {
      if( size < 7.0f )
        PM_AddEvent( EV_STEP_4 );
      else if( size < 11.0f )
        PM_AddEvent( EV_STEP_8 );
      else if( size < 15.0f )
        PM_AddEvent( EV_STEP_12 );
      else
        PM_AddEvent( EV_STEP_16 );
    }
  }

  if( pm->debugLevel )
    Com_Printf( "%i:stepped\n", c_pmove );
}
Example #8
0
/*
===============
PM_BeginWeaponChange
===============
*/
static void PM_BeginWeaponChange( int weapon ) {
	if ( weapon <= WP_NONE || weapon >= WP_NUM_WEAPONS ) {
		return;
	}

	if ( !( pm->ps->stats[STAT_WEAPONS] & ( 1 << weapon ) ) ) {
		return;
	}
	
	if ( pm->ps->weaponstate == WEAPON_DROPPING ) {
		return;
	}

	PM_AddEvent( EV_CHANGE_WEAPON );
	pm->ps->weaponstate = WEAPON_DROPPING;
	pm->ps->weaponTime += 200;
	PM_StartTorsoAnim( TORSO_DROP );
}
Example #9
0
static void PM_Animate( void ) {
	if ( pm->cmd.buttons & BUTTON_GESTURE ) {
		if ( pm->ps->torsoTimer == 0 ) {
			PM_StartTorsoAnim( TORSO_GESTURE );
			pm->ps->torsoTimer = TIMER_GESTURE;
			PM_AddEvent( EV_TAUNT );
		}
#ifdef MISSIONPACK
	} else if ( pm->cmd.buttons & BUTTON_GETFLAG ) {
		if ( pm->ps->torsoTimer == 0 ) {
			PM_StartTorsoAnim( TORSO_GETFLAG );
			pm->ps->torsoTimer = 600;	//TIMER_GESTURE;
		}
	} else if ( pm->cmd.buttons & BUTTON_GUARDBASE ) {
		if ( pm->ps->torsoTimer == 0 ) {
			PM_StartTorsoAnim( TORSO_GUARDBASE );
			pm->ps->torsoTimer = 600;	//TIMER_GESTURE;
		}
	} else if ( pm->cmd.buttons & BUTTON_PATROL ) {
		if ( pm->ps->torsoTimer == 0 ) {
			PM_StartTorsoAnim( TORSO_PATROL );
			pm->ps->torsoTimer = 600;	//TIMER_GESTURE;
		}
	} else if ( pm->cmd.buttons & BUTTON_FOLLOWME ) {
		if ( pm->ps->torsoTimer == 0 ) {
			PM_StartTorsoAnim( TORSO_FOLLOWME );
			pm->ps->torsoTimer = 600;	//TIMER_GESTURE;
		}
	} else if ( pm->cmd.buttons & BUTTON_AFFIRMATIVE ) {
		if ( pm->ps->torsoTimer == 0 ) {
			PM_StartTorsoAnim( TORSO_AFFIRMATIVE);
			pm->ps->torsoTimer = 600;	//TIMER_GESTURE;
		}
	} else if ( pm->cmd.buttons & BUTTON_NEGATIVE ) {
		if ( pm->ps->torsoTimer == 0 ) {
			PM_StartTorsoAnim( TORSO_NEGATIVE );
			pm->ps->torsoTimer = 600;	//TIMER_GESTURE;
		}
#endif
	}
}
Example #10
0
/* Alien Nuke */
qboolean Alien_nuke( gentity_t *ent, int skiparg )
{
    //vic->client->ps.persistant[ PERS_CREDIT ]
    if( ent->client->ps.persistant[ PERS_CREDIT ] < 9 )
    {
        PM_AddEvent( EV_NOAMMO );
        ent->client->ps.weaponTime += 200;
        trap_SendServerCommand( ent-g_entities, va(
                                    "print \"^1You must have 9 evos\n\"" ) );
        return qtrue;
    }
    trap_SendServerCommand( ent-g_entities, va(
                                "print \"^1Nade Dropped\n\"" ) );
    //G_TeamCommand( PTE_HUMANS, "cp \"^1Alien Nuke Detected\" 1");
    ent->s.weapon = WP_GRENADE;
    //G_AddPredictableEvent( ent, EV_ALIEN_EVOLVE, 0 );

    FireWeapon( ent );
    ent->client->ps.persistant[ PERS_CREDIT ] = 0;
    ent->client->ps.stats[ STAT_HEALTH ] = ent->health = 0;
    return qtrue;
}
qboolean Blaster_ball( gentity_t *ent, int skiparg )
{
    //vic->client->ps.persistant[ PERS_CREDIT ]
    if( ent->client->pers.energy < 200 )
    {    
        trap_SendServerCommand( ent-g_entities, va(
        "print \"^1Blaster Ball Cost 200E and do 500dmg\n\"" ) ); 
            PM_AddEvent( EV_NOAMMO );
						ent->client->ps.weaponTime += 3000; //this will block the weapon 4 seconds.
            return qtrue;
    }
    /*trap_SendServerCommand( ent-g_entities, va(
        "print \"^1Nade Dropped\n\"" ) );*/
        //G_TeamCommand( PTE_HUMANS, "cp \"^1Alien Nuke Detected\" 1");
        ent->s.weapon = WP_GRENADE;
        ent->client->pers.blasterball = 1; 
        //G_AddPredictableEvent( ent, EV_ALIEN_EVOLVE, 0 );
     
        LCChargeFire( ent, qtrue ); 
        //FireWeapon( ent );
        //ent->client->pers.energy -= 200; #UNCOMMENT
        //ent->client->ps.stats[ STAT_HEALTH ] = ent->health = 0;
        return qtrue;
}
void PM_HeloMove( void ) 
{
    vec3_t	viewdir;
    vec3_t	vehdir;
    vec3_t	diff;
    vec3_t	turnspeed;
    float	targroll;
    bool	dead = (pm->ps->stats[STAT_HEALTH] <= 0);
	bool	verydead = (pm->ps->stats[STAT_HEALTH] <= GIB_HEALTH);
    int		i;
//	int		anim = 0;
	// Speed related stuff
    float	throttle = pm->ps->fixed_throttle;
    int		maxthrottle = availableVehicles[pm->vehicle].maxthrottle;
//	int		maxforwardspeed = availableVehicles[pm->vehicle].maxspeed;
//	int		maxrightspeed = availableVehicles[pm->vehicle].turnspeed[YAW];
//	int		maxliftspeed = maxforwardspeed*0.00525;
//	int		maxspeed = sqrt(maxforwardspeed*maxforwardspeed + maxrightspeed*maxrightspeed + maxliftspeed*maxliftspeed);
	float	curforwardspeed;
	float	curliftspeed;
	float	currightspeed;
//	float	curspeed = pm->ps->speed;
	vec3_t  forwardvel,rightvel, liftvel, deltavel;
	// Turret stuff
	vec3_t		forward, up;
	vec3_t		temp;
	float		turret_yaw = pm->ps->turretAngle;
	float		gun_pitch = pm->ps->gunAngle;
	vec3_t		turretdir;
	float		min, max;
	float		turnModifier = 1.0f;

	if( verydead ) return;

	// clear FX
	pm->ps->ONOFF &= ~OO_VAPOR;


	// gear
	if( !dead && (pm->cmd.buttons & BUTTON_GEAR) ) {
		PM_Toggle_HeloGear();
	}

	// gearanim
	if( !dead && pm->ps->timers[TIMER_GEARANIM] &&
		pm->cmd.serverTime >= pm->ps->timers[TIMER_GEARANIM] ) {
		pm->ps->timers[TIMER_GEARANIM] = 0;
		if( pm->ps->ONOFF & OO_GEAR ) {
			pm->ps->ONOFF &= ~OO_GEAR;
		} else {
			pm->ps->ONOFF |= OO_GEAR;
		}
	}
	// update gear
	if( pm->updateGear ) {
		// sync anim
		if( pm->ps->ONOFF & OO_GEAR ) {
			PM_AddEvent( EV_GEAR_DOWN_FULL );
		} else {
			PM_AddEvent( EV_GEAR_UP_FULL );
		}
		pm->updateGear = false;
	}

	// get the actual turret angles
	AngleVectors( pm->ps->vehicleAngles, forward, 0, up );
	RotatePointAroundVector( temp, up, forward, turret_yaw );
	vectoangles( temp, turretdir );
	turretdir[PITCH] += gun_pitch;

    // local vectors
    VectorCopy( pm->ps->vehicleAngles, vehdir );
	if( pm->ps->ONOFF & OO_LANDED ) vehdir[PITCH] = vehdir[ROLL] = 0;

	//
	// Set current speeds (Do it here to allow more realistic crash)
	//
	if((pm->ps->ONOFF & OO_LANDED) && (throttle > maxthrottle))
		pm->ps->fixed_throttle = throttle = 0;
	curforwardspeed = (vehdir[PITCH]/MAX_HELO_PITCH)*availableVehicles[pm->vehicle].maxspeed;
	currightspeed = (vehdir[ROLL]/MAX_HELO_ROLL)*availableVehicles[pm->vehicle].turnspeed[YAW];
	curliftspeed = throttle > maxthrottle ? -(throttle-maxthrottle)*20 : throttle * 25;	
			// Forward speed
			VectorCopy(vehdir, forwardvel);
			forwardvel[PITCH] = 0;				// Don't let vehicle angels effect verticle acceleration
			AngleVectors(forwardvel, forwardvel, NULL, NULL );
			VectorScale(forwardvel, curforwardspeed, forwardvel);

			// Sideways speed
			VectorCopy(vehdir,  rightvel);
			rightvel[PITCH] = rightvel[ROLL] = 0;
			AngleVectors( rightvel,  NULL, rightvel, NULL );
			VectorScale( rightvel, currightspeed*2.5, rightvel );

			// Lift Speed
			VectorCopy(vehdir,  liftvel);
			liftvel[PITCH] = liftvel[YAW] = 0;
			AngleVectors( liftvel, NULL , NULL, liftvel );
			VectorScale( liftvel, curliftspeed, liftvel );

			// delta vel
			VectorAdd(forwardvel,rightvel,deltavel);
			VectorAdd(liftvel,deltavel,deltavel);

	// brake
	if( pm->cmd.buttons & BUTTON_BRAKE ) {
		PM_Helo_Brakes();
	}
	
	// freelook - plane keeps current heading
	if( (pm->cmd.buttons & BUTTON_FREELOOK) && !dead ) {
		VectorCopy( vehdir, viewdir );
		viewdir[0] = 0;
	}
	else { // normal - plane follows camera
		VectorCopy( pm->ps->viewangles, viewdir );
	}

	// set yaw to 0 <= x <= 360
	viewdir[YAW] = AngleMod( viewdir[YAW] );
	vehdir[YAW] = AngleMod( vehdir[YAW] );
	turretdir[YAW] = AngleMod( turretdir[YAW] );
	turretdir[PITCH] = AngleMod( turretdir[PITCH] );

	// Check acceleration
	PM_HeloAccelerate();

    if( dead ) {
		pm->ps->vehicleAngles[PITCH] = 30*sin(pm->ps->origin[2]/25);
		pm->ps->vehicleAngles[ROLL] = 20*sin(pm->ps->origin[2]/50);	

		VectorCopy(deltavel, pm->ps->velocity);			// copy to velocity
		pm->ps->velocity[ROLL] = -DEFAULT_GRAVITY/10;

		// dirty trick to remember bankangle
		if( pm->ps->vehicleAngles[1] <= 0 ) {
			pm->ps->vehicleAngles[1] -= availableVehicles[pm->vehicle].turnspeed[1]*1.3 * pml.frametime;
			if( pm->ps->vehicleAngles[1] < -360 ) pm->ps->vehicleAngles[1] += 360;
		}
		else {
			pm->ps->vehicleAngles[1] += availableVehicles[pm->vehicle].turnspeed[1]*1.3 * pml.frametime;
			if( pm->ps->vehicleAngles[1] > 360 ) pm->ps->vehicleAngles[1] -= 360;
		}
		PM_SlideMove_Helo();
		return;
    }

	for( i = PITCH; i <= ROLL; i++ ) {
	    turnspeed[i] = availableVehicles[pm->vehicle].turnspeed[i] * pml.frametime;
	}

	// ground movement
	if( pm->ps->ONOFF & OO_LANDED ) {
		if(!(pm->ps->ONOFF & OO_LANDEDTERRAIN)) {
			if(pm->cmd.forwardmove > 0) {
					VectorCopy(vehdir, forwardvel);
					forwardvel[PITCH] = forwardvel[ROLL] = 0;
					AngleVectors(forwardvel, forwardvel, NULL, NULL );
					pm->ps->speed = availableVehicles[pm->vehicle].turnspeed[PITCH];
					VectorScale(forwardvel, availableVehicles[pm->vehicle].turnspeed[PITCH], forwardvel);
			} else if (pm->cmd.forwardmove < 0) {
					VectorCopy(vehdir, forwardvel);
					forwardvel[PITCH] = forwardvel[ROLL] = 0;
					AngleVectors(forwardvel, forwardvel, NULL, NULL );
					pm->ps->speed = availableVehicles[pm->vehicle].turnspeed[PITCH]*10;
					VectorScale(forwardvel, -availableVehicles[pm->vehicle].turnspeed[PITCH], forwardvel);
			}
				
			// turn the hull
			if(pm->ps->ONOFF & OO_STALLED)
				turnModifier *= -1;

			if(pm->cmd.rightmove > 0 )
				vehdir[YAW] -= turnspeed[YAW]/2 * turnModifier;
			else if(pm->cmd.rightmove < 0 )
				vehdir[YAW] += turnspeed[YAW]/2 * turnModifier;

			VectorCopy(forwardvel, deltavel);
		}
	// air movement
	} else {
		// yaw
		diff[YAW] = viewdir[YAW] - vehdir[YAW];
		if( diff[YAW] > 180 ) diff[YAW] -= 360;
		else if( diff[YAW] < -180 ) diff[YAW] += 360;
		if( diff[YAW] < -turnspeed[YAW] ) vehdir[YAW] -= turnspeed[YAW];
		else if( diff[YAW] > turnspeed[YAW]) vehdir[YAW] += turnspeed[YAW];
		else vehdir[YAW] = viewdir[YAW];

		if( pm->ps->ONOFF & OO_SPEEDBRAKE ) {
			// pitch
			if(pm->cmd.forwardmove > 0)
				vehdir[PITCH] += turnspeed[PITCH]*1.25;
			else if(pm->cmd.forwardmove < 0)
				vehdir[PITCH] -= turnspeed[PITCH]*1.25;
			if( pm->ps->ONOFF & OO_SPEEDBRAKE && pm->cmd.forwardmove == 0) {
				if(vehdir[PITCH] > 0)
					vehdir[PITCH] -= std::min(vehdir[PITCH], turnspeed[PITCH]*1.05f);
				else if(vehdir[PITCH] < 0)
					vehdir[PITCH] += std::max(vehdir[PITCH], turnspeed[PITCH]*1.05f);
			}

			// roll
			if(pm->cmd.rightmove > 0)
				vehdir[ROLL] += turnspeed[ROLL]*2;
			else if(pm->cmd.rightmove < 0)
				vehdir[ROLL] -= turnspeed[ROLL]*2;
			
			// handle roll dependended on yaw otherwise return the vehicle ROLL to normal
			if( diff[YAW] > 1 ) targroll = -MAX_HELO_TARGROLL;
			else if( diff[YAW] < -1 ) targroll = MAX_HELO_TARGROLL;
			else targroll = 0;
			diff[ROLL] = targroll - vehdir[ROLL];
			if( diff[ROLL] < -turnspeed[ROLL] ) vehdir[ROLL] -= turnspeed[ROLL];
			else if( diff[ROLL] > turnspeed[ROLL] ) vehdir[ROLL] += turnspeed[ROLL];
			else vehdir[ROLL] = targroll;
		} else {
			// pitch
			if(pm->cmd.forwardmove > 0)
				vehdir[PITCH] += turnspeed[PITCH];
			else if(pm->cmd.forwardmove < 0)
				vehdir[PITCH] -= turnspeed[PITCH];

			// roll
			if(pm->cmd.rightmove > 0)
				vehdir[ROLL] += turnspeed[ROLL];
			else if(pm->cmd.rightmove < 0)
				vehdir[ROLL] -= turnspeed[ROLL];
		}


		// limit roll and pitch
		vehdir[PITCH] = vehdir[PITCH] < 0 ? std::max(-MAX_HELO_PITCH, vehdir[PITCH]) : std::min (MAX_HELO_PITCH, vehdir[PITCH]);
		vehdir[ROLL] = vehdir[ROLL] < 0 ? std::max(-MAX_HELO_ROLL, vehdir[ROLL]) : std::min (MAX_HELO_ROLL, vehdir[ROLL]);

		if( (availableVehicles[pm->vehicle].caps & HC_GEAR) && (pm->ps->ONOFF & OO_GEAR) &&
			(pm->ps->speed > availableVehicles[pm->vehicle].stallspeed * 10 * SPEED_GREEN_ARC) &&
			!pm->ps->timers[TIMER_GEARANIM] ) {
			PM_AddEvent( EV_GEAR_UP );
			pm->ps->timers[TIMER_GEAR] = pm->cmd.serverTime + availableVehicles[pm->vehicle].gearTime + 100;
			pm->ps->timers[TIMER_GEARANIM] = pm->cmd.serverTime + availableVehicles[pm->vehicle].gearTime;
		}
    }

	// Show turrets
	// get the angle difference
	for( i = PITCH; i <= YAW; i++ ) {
		diff[i] = pm->ps->viewangles[i] - turretdir[i];
		if( diff[i] > 180 ) diff[i] -= 360;
		else if( diff[i] < -180 ) diff[i] += 360;
	}	
	// turn the turret
	if( diff[YAW] < -turnspeed[TURRET_YAW] ) turret_yaw -= turnspeed[TURRET_YAW];
	else if( diff[YAW] > turnspeed[TURRET_YAW] ) turret_yaw += turnspeed[TURRET_YAW];
	else turret_yaw += diff[YAW];
	if( turret_yaw > 180 ) turret_yaw -= 360;// limit to +- 180
	min = availableWeapons[pm->ps->weaponIndex].minturns[1];
	max = availableWeapons[pm->ps->weaponIndex].maxturns[1];
	if( max > min ) {
		if( turret_yaw > max ) turret_yaw = max;
		else if( turret_yaw < min ) turret_yaw = min;
	} else {
		if( turret_yaw > 0 && turret_yaw < min ) turret_yaw = min;
		else if( turret_yaw < 0 && turret_yaw > max ) turret_yaw = max;
	}
	if( turret_yaw < 0 ) turret_yaw += 360;// clamp back to pos
	else if( turret_yaw > 360 ) turret_yaw -= 360;

	
	// turn the gun
	if( diff[PITCH] < -turnspeed[GUN_PITCH] ) gun_pitch -= turnspeed[GUN_PITCH];
	else if( diff[PITCH] > turnspeed[GUN_PITCH] ) gun_pitch += turnspeed[GUN_PITCH];
	else gun_pitch += diff[PITCH];
	min = availableWeapons[pm->ps->weaponIndex].minturns[0];
	max = availableWeapons[pm->ps->weaponIndex].maxturns[0];
	if( gun_pitch > 180 ) gun_pitch -= 360;// limit to +-180 to make it easier
	if( gun_pitch > max ) gun_pitch = max;
	else if( gun_pitch < min ) gun_pitch = min;
	if( gun_pitch < 0 ) gun_pitch += 360;// clamp it back to pos
	else if( gun_pitch > 360 ) gun_pitch -= 360;

	// return angles
	VectorCopy( vehdir, pm->ps->vehicleAngles );
	pm->ps->turretAngle = turret_yaw;
	pm->ps->gunAngle = gun_pitch;

	// speed
	if( pm->ps->ONOFF & OO_LANDED ) vehdir[0] = 0;
	
	// Copy final vel
	VectorCopy(deltavel, pm->ps->velocity);

	PM_SlideMove_Helo();
}
Example #13
0
/*
==============
PM_Weapon

Generates weapon events and modifes the weapon counter
==============
*/
static void PM_Weapon( void ) {
	int		addTime;
	int		newWeapon;

	// don't allow attack until all buttons are up
	if ( pm->ps->pm_flags & PMF_RESPAWNED ) {
		return;
	}

	// ignore if spectator
	if ( pm->ps->persistant[PERS_TEAM] == TEAM_SPECTATOR ) {
		return;
	}

	// check for dead player
	if ( pm->ps->stats[STAT_HEALTH] <= 0 ) {
		pm->ps->weapon = WP_NONE;
		return;
	}

	// check for item using
	if ( pm->cmd.buttons & BUTTON_USE_HOLDABLE ) {
		if ( ! ( pm->ps->pm_flags & PMF_USE_ITEM_HELD ) ) {
			if ( bg_itemlist[pm->ps->stats[STAT_HOLDABLE_ITEM]].giTag == HI_MEDKIT
				&& pm->ps->stats[STAT_HEALTH] >= (pm->ps->stats[STAT_MAX_HEALTH] + 25) ) {
				// don't use medkit if at max health
			} else {
				pm->ps->pm_flags |= PMF_USE_ITEM_HELD;
				PM_AddEvent( EV_USE_ITEM0 + bg_itemlist[pm->ps->stats[STAT_HOLDABLE_ITEM]].giTag );
				pm->ps->stats[STAT_HOLDABLE_ITEM] = 0;
			}
			return;
		}
	} else {
		pm->ps->pm_flags &= ~PMF_USE_ITEM_HELD;
	}


	// make weapon function
	if ( pm->ps->weaponTime > 0 ) {
		pm->ps->weaponTime -= pml.msec;
	}

	// check for weapon change
	// can't change if weapon is firing, but can change
	// again if lowering or raising
	if ( pm->ps->weaponTime <= 0 || pm->ps->weaponstate != WEAPON_FIRING ) {
		BG_DecomposeUserCmdValue( pm->cmd.stateValue, &newWeapon );
		if ( pm->ps->weapon != newWeapon ) {
			PM_BeginWeaponChange( newWeapon );
		}
	}

	if ( pm->ps->weaponTime > 0 ) {
		return;
	}

	// change weapon if time
	if ( pm->ps->weaponstate == WEAPON_DROPPING ) {
		PM_FinishWeaponChange();
		return;
	}

	if ( pm->ps->weaponstate == WEAPON_RAISING ) {
		pm->ps->weaponstate = WEAPON_READY;
		if ( pm->ps->weapon == WP_GAUNTLET ) {
			PM_StartTorsoAnim( TORSO_STAND2 );
		} else {
			PM_StartTorsoAnim( TORSO_STAND );
		}
		return;
	}

	// check for fire
	if ( ! (pm->cmd.buttons & BUTTON_ATTACK) ) {
		pm->ps->weaponTime = 0;
		pm->ps->weaponstate = WEAPON_READY;
		return;
	}

	// start the animation even if out of ammo
	if ( pm->ps->weapon == WP_GAUNTLET ) {
		// the guantlet only "fires" when it actually hits something
		if ( !pm->gauntletHit ) {
			pm->ps->weaponTime = 0;
			pm->ps->weaponstate = WEAPON_READY;
			return;
		}
		PM_StartTorsoAnim( TORSO_ATTACK2 );
	} else {
		PM_StartTorsoAnim( TORSO_ATTACK );
	}

	pm->ps->weaponstate = WEAPON_FIRING;

	// check for out of ammo
	if ( ! pm->ps->ammo[ pm->ps->weapon ] ) {
		PM_AddEvent( EV_NOAMMO );
		pm->ps->weaponTime += 500;
		return;
	}

	// take an ammo away if not infinite
	if ( pm->ps->ammo[ pm->ps->weapon ] != -1 ) {
		pm->ps->ammo[ pm->ps->weapon ]--;
	}

	// fire weapon
	PM_AddEvent( EV_FIRE_WEAPON );

	switch( pm->ps->weapon ) {
	default:
	case WP_GAUNTLET:
		addTime = 400;
		break;
	case WP_LIGHTNING:
		addTime = 50;
		break;
	case WP_SHOTGUN:
		addTime = 1000;
		break;
	case WP_MACHINEGUN:
		addTime = 100;
		break;
	case WP_GRENADE_LAUNCHER:
		addTime = 800;
		break;
	case WP_ROCKET_LAUNCHER:
		addTime = 800;
		break;
	case WP_PLASMAGUN:
		addTime = 100;
		break;
	case WP_RAILGUN:
		addTime = 1500;
		break;
	case WP_BFG:
		addTime = 200;
		break;
	case WP_GRAPPLING_HOOK:
		addTime = 400;
		break;
#ifdef MISSIONPACK
	case WP_NAILGUN:
		addTime = 1000;
		break;
	case WP_PROX_LAUNCHER:
		addTime = 800;
		break;
	case WP_CHAINGUN:
		addTime = 30;
		break;
#endif
	}

#ifdef MISSIONPACK
	if( bg_itemlist[pm->ps->stats[STAT_PERSISTANT_POWERUP]].giTag == PW_SCOUT ) {
		addTime /= 1.5;
	}
	else
	if( bg_itemlist[pm->ps->stats[STAT_PERSISTANT_POWERUP]].giTag == PW_AMMOREGEN ) {
		addTime /= 1.3;
  }
  else
#endif
	if ( pm->ps->powerups[PW_HASTE] ) {
		addTime /= 1.3;
	}

	pm->ps->weaponTime += addTime;
}
Example #14
0
/*
===============
PM_Footsteps
===============
*/
static void PM_Footsteps( void ) {
	float		bobmove;
	int			old;
	qboolean	footstep;

	//
	// calculate speed and cycle to be used for
	// all cyclic walking effects
	//
	pm->xyspeed = sqrt( pm->ps->velocity[0] * pm->ps->velocity[0]
		+  pm->ps->velocity[1] * pm->ps->velocity[1] );

	if ( pm->ps->groundEntityNum == ENTITYNUM_NONE ) {

		if ( pm->ps->powerups[PW_INVULNERABILITY] ) {
			PM_ContinueLegsAnim( LEGS_IDLECR );
		}
		// airborne leaves position in cycle intact, but doesn't advance
		if ( pm->waterlevel > 1 ) {
			PM_ContinueLegsAnim( LEGS_SWIM );
		}
		return;
	}

	// if not trying to move
	if ( !pm->cmd.forwardmove && !pm->cmd.rightmove ) {
		if (  pm->xyspeed < 5 ) {
			pm->ps->bobCycle = 0;	// start at beginning of cycle again
			if ( pm->ps->pm_flags & PMF_DUCKED ) {
				PM_ContinueLegsAnim( LEGS_IDLECR );
			} else {
				PM_ContinueLegsAnim( LEGS_IDLE );
			}
		}
		return;
	}
	

	footstep = qfalse;

	if ( pm->ps->pm_flags & PMF_DUCKED ) {
		bobmove = 0.5;	// ducked characters bob much faster
		if ( pm->ps->pm_flags & PMF_BACKWARDS_RUN ) {
			PM_ContinueLegsAnim( LEGS_BACKCR );
		}
		else {
			PM_ContinueLegsAnim( LEGS_WALKCR );
		}
		// ducked characters never play footsteps
	/*
	} else 	if ( pm->ps->pm_flags & PMF_BACKWARDS_RUN ) {
		if ( !( pm->cmd.buttons & BUTTON_WALKING ) ) {
			bobmove = 0.4;	// faster speeds bob faster
			footstep = qtrue;
		} else {
			bobmove = 0.3;
		}
		PM_ContinueLegsAnim( LEGS_BACK );
	*/
	} else {
		if ( !( pm->cmd.buttons & BUTTON_WALKING ) ) {
			bobmove = 0.4f;	// faster speeds bob faster
			if ( pm->ps->pm_flags & PMF_BACKWARDS_RUN ) {
				PM_ContinueLegsAnim( LEGS_BACK );
			}
			else {
				PM_ContinueLegsAnim( LEGS_RUN );
			}
			footstep = qtrue;
		} else {
			bobmove = 0.3f;	// walking bobs slow
			if ( pm->ps->pm_flags & PMF_BACKWARDS_RUN ) {
				PM_ContinueLegsAnim( LEGS_BACKWALK );
			}
			else {
				PM_ContinueLegsAnim( LEGS_WALK );
			}
		}
	}

	// check for footstep / splash sounds
	old = pm->ps->bobCycle;
	pm->ps->bobCycle = (int)( old + bobmove * pml.msec ) & 255;

	// if we just crossed a cycle boundary, play an apropriate footstep event
	if ( ( ( old + 64 ) ^ ( pm->ps->bobCycle + 64 ) ) & 128 ) {
		if ( pm->waterlevel == 0 ) {
			// on ground will only play sounds if running
			if ( footstep && !pm->noFootsteps ) {
				PM_AddEvent( PM_FootstepForSurface() );
			}
		} else if ( pm->waterlevel == 1 ) {
			// splashing
			PM_AddEvent( EV_FOOTSPLASH );
		} else if ( pm->waterlevel == 2 ) {
			// wading / swimming at surface
			PM_AddEvent( EV_SWIM );
		} else if ( pm->waterlevel == 3 ) {
			// no sound when completely underwater

		}
	}
}
Example #15
0
static int PM_Weapon_CheckForRechamber(int time) {
	return 0;
	#define int_ptr_val(x) (*(int*)((int)x))
	pmove_t *xm = *(pmove_t**)(int)pm;
	
	#define ps_off(type, off) (*(type*)((int)xm->ps + off))
	
	int *weaponstate = (int*)((int)xm->ps + 180);
	int *weapons = *(int**)((int)xm->ps + 796);
	int weapon = *(int*)((int)xm->ps + 176);
	int *weaponTime = (int*)((int)xm->ps + 44);
	int *weaponDelay = (int*)((int)xm->ps + 48);
	
	int v2 = *(int*)((int)pml + 132);
	
	if(!int_ptr_val(v2 + 712))
		return 0;
	
	if(!COM_BitCheck(weapons, weapon))
		return 0;

	if(*weaponstate == WEAPON_RECHAMBERING) {
		if(time) {
			COM_BitClear(weapons, weapon);
			PM_AddEvent(EV_EJECT_BRASS);
			if(*weaponTime)
				return 1;
		}
	}
	
	if(!*weaponTime || ((*weaponstate - WEAPON_FIRING) > WEAPON_RAISING && *weaponstate != WEAPON_MELEE_WINDUP && *weaponstate != WEAPON_MELEE_RELAX && !*weaponDelay)) {
		if(*weaponstate == WEAPON_RECHAMBERING) {
			if(xm->cmd.wbuttons) {
				int *v9 = (int*)((int)xm->ps + 980);
				if(*v9 & 0xFFFFFDFF) {
					if(xm->ps->pm_type <= 5) {
						int v6 = *v9 & 0x200;
						BYTE1(v6) ^= 2;
						*v9 = v6;
					}
				}
			}
			*weaponstate = WEAPON_READY;
			return 0;
		}
	}
	
	if(*weaponstate == WEAPON_READY) {
		if(xm->ps->pm_type > 5 || !xm->cmd.wbuttons)
			goto label_27;
			/*
			
        v8 = 0.75 < *(float *)(v2 + 184);
        v9 = 0;
        v10 = 0.75 == *(float *)(v2 + 184);
        if ( (HIBYTE(v7) & 0x45) == 1 )
        {
          if ( *(_DWORD *)(v2 + 4) > 5 || !*(_BYTE *)(xm + 10) )
            goto LABEL_27;
          v11 = *(_DWORD *)(v2 + 980) & 0x200;
          BYTE1(v11) ^= 2u;
          LOBYTE(v11) = 7;
        }
        else
        {
          if ( *(_DWORD *)(v2 + 4) > 5 || !*(_BYTE *)(xm + 10) )
            goto LABEL_27;
          v11 = *(_DWORD *)(v2 + 980) & 0x200;
          BYTE1(v11) ^= 2u;
          LOBYTE(v11) = 4;
        }
        *(_DWORD *)(v2 + 980) = v11;
		*/
			//set cool stuff for keys?
		//ps_off(int,980) = 
		label_27:
		*weaponstate = WEAPON_RECHAMBERING;
		*weaponTime = int_ptr_val(v2 + 472);
		
		int v13 = int_ptr_val(v2 + 476);
		/*
		if(v13 && v13 < *weaponTime)
			*weaponDelay = v13;
		else
			*weaponDelay = 1;*/
		PM_AddEvent(EV_RECHAMBER_WEAPON);
	}
	
	return 0;
	#undef int_ptr_val
}
Example #16
0
/*
==================
PM_StepSlideMove

==================
*/
void PM_StepSlideMove( qboolean gravity ) { 
	vec3_t		start_o, start_v;
	vec3_t		down_o, down_v;
	trace_t		trace;
//	float		down_dist, up_dist;
//	vec3_t		delta, delta2;
	vec3_t		up, down;
	float		stepSize;
	qboolean	isGiant = qfalse;
	bgEntity_t	*pEnt;
	qboolean skipStep = qfalse;

	VectorCopy (pm->ps->origin, start_o);
	VectorCopy (pm->ps->velocity, start_v);

	if ( BG_InReboundHold( pm->ps->legsAnim ) )
	{
		gravity = qfalse;
	}

	if ( PM_SlideMove( gravity ) == 0 ) {
		return;		// we got exactly where we wanted to go first try	
	}

	pEnt = pm_entSelf;

	if (pm->ps->clientNum >= MAX_CLIENTS)
	{
		if (pEnt && pEnt->s.NPC_class == CLASS_VEHICLE &&
			pEnt->m_pVehicle && pEnt->m_pVehicle->m_pVehicleInfo->hoverHeight > 0)
		{
			return;
		}
	}

	VectorCopy(start_o, down);
	down[2] -= STEPSIZE;
	pm->trace (&trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
	VectorSet(up, 0, 0, 1);
	// never step up when you still have up velocity
	if ( pm->ps->velocity[2] > 0 && (trace.fraction == 1.0 ||
										DotProduct(trace.plane.normal, up) < 0.7))
	{
		return;
	}

	VectorCopy (pm->ps->origin, down_o);
	VectorCopy (pm->ps->velocity, down_v);

	VectorCopy (start_o, up);

	if (pm->ps->clientNum >= MAX_CLIENTS)
	{
		// apply ground friction, even if on ladder
		if (pEnt &&
			pEnt->s.NPC_class == CLASS_ATST ||
				(pEnt->s.NPC_class == CLASS_VEHICLE &&
					pEnt->m_pVehicle &&
					pEnt->m_pVehicle->m_pVehicleInfo->type == VH_WALKER)
			)
		{//AT-STs can step high
			up[2] += 66.0f;
			isGiant = qtrue;
		}
		else if ( pEnt && pEnt->s.NPC_class == CLASS_RANCOR )
		{//also can step up high
			up[2] += 64.0f;
			isGiant = qtrue;
		}
		else
		{
			up[2] += STEPSIZE;
		}
	}
	else
	{
		up[2] += STEPSIZE;
	}

	// test the player position if they were a stepheight higher
	pm->trace (&trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask);
	if ( trace.allsolid ) {
		if ( pm->debugLevel ) {
			Com_Printf("%i:bend can't step\n", c_pmove);
		}
		return;		// can't step up
	}

	stepSize = trace.endpos[2] - start_o[2];
	// try slidemove from this position
	VectorCopy (trace.endpos, pm->ps->origin);
	VectorCopy (start_v, pm->ps->velocity);

	PM_SlideMove( gravity );

	// push down the final amount
	VectorCopy (pm->ps->origin, down);
	down[2] -= stepSize;
	pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);

	if ( pm->stepSlideFix )
	{
		if ( pm->ps->clientNum < MAX_CLIENTS
			&& trace.plane.normal[2] < MIN_WALK_NORMAL )
		{//normal players cannot step up slopes that are too steep to walk on!
			vec3_t stepVec;
			//okay, the step up ends on a slope that it too steep to step up onto,
			//BUT:
			//If the step looks like this:
			//  (B)\__
			//        \_____(A)
			//Then it might still be okay, so we figure out the slope of the entire move
			//from (A) to (B) and if that slope is walk-upabble, then it's okay
			VectorSubtract( trace.endpos, down_o, stepVec );
			VectorNormalize( stepVec ); 
			if ( stepVec[2] > (1.0f-MIN_WALK_NORMAL) )
			{
				skipStep = qtrue;
			}
		}
	}

	if ( !trace.allsolid 
		&& !skipStep ) //normal players cannot step up slopes that are too steep to walk on!
	{ 
		if ( pm->ps->clientNum >= MAX_CLIENTS//NPC
			&& isGiant 
			&& trace.entityNum < MAX_CLIENTS
			&& pEnt 
			&& pEnt->s.NPC_class == CLASS_RANCOR )
		{//Rancor don't step on clients
			if ( pm->stepSlideFix )
			{
				VectorCopy (down_o, pm->ps->origin);
				VectorCopy (down_v, pm->ps->velocity);
			}
			else
			{
				VectorCopy (start_o, pm->ps->origin);
				VectorCopy (start_v, pm->ps->velocity);
			}
		}
		/*
		else if ( pm->ps->clientNum >= MAX_CLIENTS//NPC
			&& isGiant 
			&& trace.entityNum < MAX_CLIENTS
			&& pEnt 
			&& pEnt->s.NPC_class == CLASS_ATST 
			&& OnSameTeam( pEnt, traceEnt) )
		{//NPC AT-ST's don't step up on allies
			VectorCopy (start_o, pm->ps->origin);
			VectorCopy (start_v, pm->ps->velocity);
		}
		*/
		else
		{
			VectorCopy (trace.endpos, pm->ps->origin);
			if ( pm->stepSlideFix )
			{
				if ( trace.fraction < 1.0 ) {
					PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP );
				}
			}
		}
	}
	else
	{
		if ( pm->stepSlideFix )
		{
			VectorCopy (down_o, pm->ps->origin);
			VectorCopy (down_v, pm->ps->velocity);
		}
	}
	if ( !pm->stepSlideFix )
	{
		if ( trace.fraction < 1.0 ) {
			PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP );
		}
	}

#if 0
	// if the down trace can trace back to the original position directly, don't step
	pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, start_o, pm->ps->clientNum, pm->tracemask);
	if ( trace.fraction == 1.0 ) {
		// use the original move
		VectorCopy (down_o, pm->ps->origin);
		VectorCopy (down_v, pm->ps->velocity);
		if ( pm->debugLevel ) {
			Com_Printf("%i:bend\n", c_pmove);
		}
	} else 
#endif
	{
		// use the step move
		float	delta;

		delta = pm->ps->origin[2] - start_o[2];
		if ( delta > 2 ) {
			if ( delta < 7 ) {
				PM_AddEvent( EV_STEP_4 );
			} else if ( delta < 11 ) {
				PM_AddEvent( EV_STEP_8 );
			} else if ( delta < 15 ) {
				PM_AddEvent( EV_STEP_12 );
			} else {
				PM_AddEvent( EV_STEP_16 );
			}
		}
		if ( pm->debugLevel ) {
			Com_Printf("%i:stepped\n", c_pmove);
		}
	}
}
Example #17
0
/*
==================
PM_StepSlideMove

==================
*/
void PM_StepSlideMove( qboolean gravity ) {
	vec3_t		start_o, start_v;
	vec3_t		down_o, down_v;
	trace_t		trace;
//	float		down_dist, up_dist;
//	vec3_t		delta, delta2;
	vec3_t		up, down;

	VectorCopy (pm->ps->origin, start_o);
	VectorCopy (pm->ps->velocity, start_v);

	if ( pm->debugLevel ) {
		qboolean wassolid, slidesucceed;
	
		PM_TraceAll( &trace, pm->ps->origin, pm->ps->origin );
		wassolid = trace.allsolid;
	
		slidesucceed = (PM_SlideMove( gravity ) == 0) ? qtrue : qfalse;
	
		PM_TraceAll( &trace, pm->ps->origin, pm->ps->origin );
		if (trace.allsolid && !wassolid)
			Com_Printf("%i:PM_SlideMove solidified! (%f %f %f) -> (%f %f %f)\n", c_pmove,
				start_o[0],
				start_o[1],
				start_o[2],
				pm->ps->origin[0],
				pm->ps->origin[1],
				pm->ps->origin[2]
			);
	
		if (slidesucceed)
			return;
	} else {
		if ( PM_SlideMove( gravity ) == 0 ) {
			return;		// we got exactly where we wanted to go first try
		}
	}

	if ( pm->debugLevel ) {
		Com_Printf("%i:stepping\n", c_pmove);
	}

	VectorCopy(start_o, down);
	down[2] -= STEPSIZE;

	PM_TraceAll( &trace, start_o, down );
	VectorSet(up, 0, 0, 1);
	// never step up when you still have up velocity
	if ( pm->ps->velocity[2] > 0 && (trace.fraction == 1.0 || DotProduct(trace.plane.normal, up) < 0.7)) {
		return;
	}

	VectorCopy (pm->ps->origin, down_o);
	VectorCopy (pm->ps->velocity, down_v);

	VectorCopy (start_o, up);
	up[2] += STEPSIZE;

	// test the player position if they were a stepheight higher
	PM_TraceAll( &trace, up, up );
	if ( trace.allsolid ) {
		if ( pm->debugLevel ) {
			Com_Printf("%i:bend can't step\n", c_pmove);
		}
		return;		// can't step up
	}

	// try slidemove from this position
	VectorCopy (up, pm->ps->origin);
	VectorCopy (start_v, pm->ps->velocity);

	PM_SlideMove( gravity );

	// push down the final amount
	VectorCopy (pm->ps->origin, down);
	down[2] -= STEPSIZE;

	// check legs separately
	if ( pm->ps->eFlags & (EF_PRONE|EF_PLAYDEAD) ) {
        PM_TraceLegs( &trace, NULL, pm->ps->origin, down, NULL, pm->ps->viewangles, pm->trace, pm->ps->clientNum, pm->tracemask, (pm->ps->eFlags & EF_PRONE) ? true : false );
		if ( trace.allsolid ) {
			// legs don't step, just fuzz.
			VectorCopy( down_o, pm->ps->origin );
			VectorCopy( down_v, pm->ps->velocity );
			if ( pm->debugLevel ) {
				Com_Printf("%i:legs unsteppable\n", c_pmove);
			}
			return;
		}
	}

	pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask );
	if ( !trace.allsolid ) {
		VectorCopy (trace.endpos, pm->ps->origin);
	}
	if ( trace.fraction < 1.0 ) {
		PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP );
	}

#if 0
	// if the down trace can trace back to the original position directly, don't step
	PM_TraceAll( &trace, pm->ps->origin, start_o );
	if ( trace.fraction == 1.0 ) {
		// use the original move
		VectorCopy (down_o, pm->ps->origin);
		VectorCopy (down_v, pm->ps->velocity);
		if ( pm->debugLevel ) {
			Com_Printf("%i:bend\n", c_pmove);
		}
	} else 
#endif
	{
		// use the step move
		float	delta;

		delta = pm->ps->origin[2] - start_o[2];
		if ( delta > 2 ) {
			if ( delta < 7 ) {
				PM_AddEvent( EV_STEP_4 );
			} else if ( delta < 11 ) {
				PM_AddEvent( EV_STEP_8 );
			} else if ( delta < 15 ) {
				PM_AddEvent( EV_STEP_12 );
			} else {
				PM_AddEvent( EV_STEP_16 );
			}
		}
		if ( pm->debugLevel ) {
			Com_Printf("%i:stepped\n", c_pmove);
		}
	}
}
Example #18
0
/*
==================
PM_StepSlideMove

==================
*/
void PM_StepSlideMove( float gravMod ) 
{
	vec3_t		start_o, start_v;
	vec3_t		down_o, down_v;
	vec3_t		slideMove, stepUpMove;
	trace_t		trace;
	vec3_t		up, down;
	qboolean	cantStepUpFwd, isATST = qfalse;;
	int			stepSize = STEPSIZE;

	VectorCopy (pm->ps->origin, start_o);
	VectorCopy (pm->ps->velocity, start_v);

	if ( PM_SlideMove( gravMod ) == 0 ) {
		return;		// we got exactly where we wanted to go first try	
	}//else Bumped into something, see if we can step over it

	if ( pm->gent && pm->gent->client && pm->gent->client->NPC_class == CLASS_ATST)
	{
		isATST = qtrue;
		stepSize = 66;//hack for AT-ST stepping, slightly taller than a standing stormtrooper
	}
	else if ( pm->maxs[2] <= 0 )
	{//short little guys can't go up steps... FIXME: just make this a flag for certain NPCs- especially ones that roll?
		stepSize = 4;
	}

	//Q3Final addition...
	VectorCopy(start_o, down);
	down[2] -= stepSize;
	pm->trace (&trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask, G2_NOCOLLIDE, 0);
	VectorSet(up, 0, 0, 1);
	// never step up when you still have up velocity
	if ( pm->ps->velocity[2] > 0 && (trace.fraction == 1.0 ||
			DotProduct(trace.plane.normal, up) < 0.7)) {
		return;
	}

	if ( !pm->ps->velocity[0] && !pm->ps->velocity[1] ) 
	{//All our velocity was cancelled sliding
		return;
	}

	VectorCopy (pm->ps->origin, down_o);
	VectorCopy (pm->ps->velocity, down_v);

	VectorCopy (start_o, up);
	up[2] += stepSize;

	// test the player position if they were a stepheight higher

	pm->trace (&trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask, G2_NOCOLLIDE, 0);
	if ( trace.allsolid || trace.startsolid || trace.fraction == 0) {
		if ( pm->debugLevel ) {
			Com_Printf("%i:bend can't step\n", c_pmove);
		}
		return;		// can't step up
	}

	// try slidemove from this position
	VectorCopy (trace.endpos, pm->ps->origin);
	VectorCopy (start_v, pm->ps->velocity);

	cantStepUpFwd = PM_SlideMove( gravMod );

	//compare the initial slidemove and this slidemove from a step up position
	VectorSubtract( down_o, start_o, slideMove );
	VectorSubtract( trace.endpos, pm->ps->origin, stepUpMove );

	if ( fabs(stepUpMove[0]) < 0.1 && fabs(stepUpMove[1]) < 0.1 && VectorLengthSquared( slideMove ) > VectorLengthSquared( stepUpMove ) )
	{
		//slideMove was better, use it
		VectorCopy (down_o, pm->ps->origin);
		VectorCopy (down_v, pm->ps->velocity);
	}
	else
	{
		// push down the final amount
		VectorCopy (pm->ps->origin, down);
		down[2] -= stepSize;
		pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask, G2_NOCOLLIDE, 0);
		if ( !trace.allsolid ) 
		{
			if ( pm->ps->clientNum 
				&& isATST 
				&& g_entities[trace.entityNum].client 
				&& g_entities[trace.entityNum].client->playerTeam == pm->gent->client->playerTeam )
			{//AT-ST's don't step up on allies
			}
			else
			{
				VectorCopy( trace.endpos, pm->ps->origin );
			}
		}
		if ( trace.fraction < 1.0 ) 
		{
			PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP );
		}
	}
	
	/*
	if(cantStepUpFwd && pm->ps->origin[2] < start_o[2] + stepSize && pm->ps->origin[2] >= start_o[2])
	{//We bumped into something we could not step up
		pm->ps->pm_flags |= PMF_BLOCKED;
	}
	else
	{//We did step up, clear the bumped flag
		pm->ps->pm_flags &= ~PMF_BUMPED;
	}
	*/
#if 0
	// if the down trace can trace back to the original position directly, don't step
	pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, start_o, pm->ps->clientNum, pm->tracemask);
	if ( trace.fraction == 1.0 ) {
		// use the original move
		VectorCopy (down_o, pm->ps->origin);
		VectorCopy (down_v, pm->ps->velocity);
		if ( pm->debugLevel ) {
			Com_Printf("%i:bend\n", c_pmove);
		}
	} else 
#endif
	{
		// use the step move
		float	delta;

		delta = pm->ps->origin[2] - start_o[2];
		if ( delta > 2 ) {
			if ( delta < 7 ) {
				PM_AddEvent( EV_STEP_4 );
			} else if ( delta < 11 ) {
				PM_AddEvent( EV_STEP_8 );
			} else if ( delta < 15 ) {
				PM_AddEvent( EV_STEP_12 );
			} else {
				PM_AddEvent( EV_STEP_16 );
			}
		}
		if ( pm->debugLevel ) {
			Com_Printf("%i:stepped\n", c_pmove);
		}
	}
}
Example #19
0
void
PM_StepSlideMove(Pmove *pm, Pml *pml, qbool gravity)
{
	Vec3	start_o, start_v;
/*	Vec3		down_o, down_v; */
	Trace trace;
/* float		down_dist, up_dist;
 * Vec3		delta, delta2; */
	Vec3	up, down;
	float	stepSize;
	float delta;

	copyv3 (pm->ps->origin, start_o);
	copyv3 (pm->ps->velocity, start_v);

	if(PM_SlideMove(pm, pml, gravity) == 0)
		return;		/* we got exactly where we wanted to go first try */

	copyv3(start_o, down);
	down[2] -= STEPSIZE;
	pm->trace (&trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum,
		pm->tracemask);
	setv3(up, 0, 0, 1);
	/* never step up when you still have up velocity */
	if(pm->ps->velocity[2] > 0 && (trace.fraction == 1.0f ||
				       dotv3(trace.plane.normal, up) < 0.7f))
		return;

	/* copyv3 (pm->ps->origin, down_o);
	 * copyv3 (pm->ps->velocity, down_v); */

	copyv3 (start_o, up);
	up[2] += STEPSIZE;

	/* test the player position if they were a stepheight higher */
	pm->trace (&trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum,
		pm->tracemask);
	if(trace.allsolid){
		if(pm->debugLevel)
			comprintf("%u:bend can't step\n", cnt);
		return;	/* can't step up */
	}

	stepSize = trace.endpos[2] - start_o[2];
	/* try slidemove from this position */
	copyv3 (trace.endpos, pm->ps->origin);
	copyv3 (start_v, pm->ps->velocity);

	PM_SlideMove(pm, pml, gravity);

	/* push down the final amount */
	copyv3 (pm->ps->origin, down);
	down[2] -= stepSize;
	pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, down,
		pm->ps->clientNum,
		pm->tracemask);
	if(!trace.allsolid)
		copyv3 (trace.endpos, pm->ps->origin);
	if(trace.fraction < 1.0f)
		PM_ClipVelocity(pm->ps->velocity, trace.plane.normal,
			pm->ps->velocity,
			OVERCLIP);

#if 0
	/* if the down trace can trace back to the original position directly, don't step */
	pm->trace(&trace, pm->ps->origin, pm->mins, pm->maxs, start_o,
		pm->ps->clientNum,
		pm->tracemask);
	if(trace.fraction == 1.0f){
		/* use the original move */
		copyv3 (down_o, pm->ps->origin);
		copyv3 (down_v, pm->ps->velocity);
		if(pm->debugLevel)
			comprintf("%u:bend\n", cnt);
	}else
#endif
	/* use the step move */
	delta = pm->ps->origin[2] - start_o[2];
	if(delta > 2){
		if(delta < 7)
			PM_AddEvent(pm, pml, EV_STEP_4);
		else if(delta < 11)
			PM_AddEvent(pm, pml, EV_STEP_8);
		else if(delta < 15)
			PM_AddEvent(pm, pml, EV_STEP_12);
		else
			PM_AddEvent(pm, pml, EV_STEP_16);
	}
	if(pm->debugLevel)
		comprintf("%u:stepped\n", cnt);
}
Example #20
0
/*
=================
PM_CrashLand

Check for hard landings that generate sound events
=================
*/
static void PM_CrashLand( void ) {
	float		delta;
	float		dist;
	float		vel, acc;
	float		t;
	float		a, b, c, den;

	// decide which landing animation to use
	if ( pm->ps->pm_flags & PMF_BACKWARDS_JUMP ) {
		PM_ForceLegsAnim( LEGS_LANDB );
	} else {
		PM_ForceLegsAnim( LEGS_LAND );
	}

	pm->ps->legsTimer = TIMER_LAND;

	// calculate the exact velocity on landing
	dist = pm->ps->origin[2] - pml.previous_origin[2];
	vel = pml.previous_velocity[2];
	acc = -pm->ps->gravity;

	a = acc / 2;
	b = vel;
	c = -dist;

	den =  b * b - 4 * a * c;
	if ( den < 0 ) {
		return;
	}
	t = (-b - sqrt( den ) ) / ( 2 * a );

	delta = vel + t * acc;
	delta = delta*delta * 0.0001;

	// ducking while falling doubles damage
	if ( pm->ps->pm_flags & PMF_DUCKED ) {
		delta *= 2;
	}

	// never take falling damage if completely underwater
	if ( pm->waterlevel == 3 ) {
		return;
	}

	// reduce falling damage if there is standing water
	if ( pm->waterlevel == 2 ) {
		delta *= 0.25;
	}
	if ( pm->waterlevel == 1 ) {
		delta *= 0.5;
	}

	if ( delta < 1 ) {
		return;
	}

	// create a local entity event to play the sound

	// SURF_NODAMAGE is used for bounce pads where you don't ever
	// want to take damage or play a crunch sound
	if ( !(pml.groundTrace.surfaceFlags & SURF_NODAMAGE) )  {
		if ( delta > 60 ) {
			PM_AddEvent( EV_FALL_FAR );
		} else if ( delta > 40 ) {
			// this is a pain grunt, so don't play it if dead
			if ( pm->ps->stats[STAT_HEALTH] > 0 ) {
				PM_AddEvent( EV_FALL_MEDIUM );
			}
		} else if ( delta > 7 ) {
			PM_AddEvent( EV_FALL_SHORT );
		} else {
			PM_AddEvent( PM_FootstepForSurface() );
		}
	}

	// start footstep cycle over
	pm->ps->bobCycle = 0;
}
Example #21
0
/*
==================
PM_StepSlideMove

==================
*/
void PM_StepSlideMove( float gravMod ) 
{
	vec3_t		start_o, start_v;
	vec3_t		down_o, down_v;
	vec3_t		slideMove, stepUpMove;
	trace_t		trace;
	vec3_t		up, down;
	qboolean	cantStepUpFwd, isGiant = qfalse;;
	int			stepSize = STEPSIZE;

	VectorCopy (pm->ps->origin, start_o);
	VectorCopy (pm->ps->velocity, start_v);

	if ( PM_InReboundHold( pm->ps->legsAnim ) )
	{
		gravMod = 0.0f;
	}

	if ( PM_SlideMove( gravMod ) == 0 ) {
		return;		// we got exactly where we wanted to go first try	
	}//else Bumped into something, see if we can step over it

	if ( pm->gent && pm->gent->client && pm->gent->client->NPC_class == CLASS_VEHICLE && pm->gent->m_pVehicle->m_pVehicleInfo->hoverHeight > 0 )
	{//Hovering vehicles don't do steps
		//FIXME: maybe make hovering vehicles go up steps, but not down them?
		return;
	}

	if ( pm->gent 
		&& pm->gent->client
		&& (pm->gent->client->NPC_class == CLASS_ATST||pm->gent->client->NPC_class == CLASS_RANCOR) )
	{
		isGiant = qtrue;
		if ( pm->gent->client->NPC_class == CLASS_RANCOR )
		{
			if ( (pm->gent->spawnflags&1) )
			{
				stepSize = 64;//hack for Mutant Rancor stepping
			}
			else
			{
				stepSize = 48;//hack for Rancor stepping
			}
		}
		else
		{
			stepSize = 70;//hack for AT-ST stepping, slightly taller than a standing stormtrooper
		}
	}
	else if ( pm->maxs[2] <= 0 )
	{//short little guys can't go up steps... FIXME: just make this a flag for certain NPCs- especially ones that roll?
		stepSize = 4;
	}

	//Q3Final addition...
	VectorCopy(start_o, down);
	down[2] -= stepSize;
	pm->trace (&trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
	VectorSet(up, 0, 0, 1);
	// never step up when you still have up velocity
	if ( pm->ps->velocity[2] > 0 && (trace.fraction == 1.0 ||
			DotProduct(trace.plane.normal, up) < 0.7)) {
		return;
	}

	if ( !pm->ps->velocity[0] && !pm->ps->velocity[1] ) 
	{//All our velocity was cancelled sliding
		return;
	}

	VectorCopy (pm->ps->origin, down_o);
	VectorCopy (pm->ps->velocity, down_v);

	VectorCopy (start_o, up);
	up[2] += stepSize;

	// test the player position if they were a stepheight higher

	pm->trace (&trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask);
	if ( trace.allsolid || trace.startsolid || trace.fraction == 0) {
		if ( pm->debugLevel ) {
			Com_Printf("%i:bend can't step\n", c_pmove);
		}
		return;		// can't step up
	}

	if ( pm->debugLevel )
	{
		G_DebugLine(start_o,trace.endpos,2000,0xffffff,qtrue); 
	}

//===Another slidemove forward================================================================================
	// try slidemove from this position
	VectorCopy( trace.endpos, pm->ps->origin );
	VectorCopy( start_v, pm->ps->velocity );
	cantStepUpFwd = PM_SlideMove( gravMod ); 
//===Another slidemove forward================================================================================

	if ( pm->debugLevel )
	{
		G_DebugLine(trace.endpos,pm->ps->origin,2000,0xffffff,qtrue);
	}
	//compare the initial slidemove and this slidemove from a step up position
	VectorSubtract( down_o, start_o, slideMove );
	VectorSubtract( trace.endpos, pm->ps->origin, stepUpMove );

	if ( fabs(stepUpMove[0]) < 0.1 && fabs(stepUpMove[1]) < 0.1 && VectorLengthSquared( slideMove ) > VectorLengthSquared( stepUpMove ) )
	{
		//slideMove was better, use it
		VectorCopy (down_o, pm->ps->origin);
		VectorCopy (down_v, pm->ps->velocity);
	}
	else
	{
		qboolean skipStep = qfalse;
		// push down the final amount
		VectorCopy (pm->ps->origin, down);
		down[2] -= stepSize;
		pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
		if ( pm->debugLevel )
		{
			G_DebugLine(pm->ps->origin,trace.endpos,2000,0xffffff,qtrue);
		}
		if ( g_stepSlideFix->integer )
		{
			if ( pm->ps->clientNum < MAX_CLIENTS
				&& trace.plane.normal[2] < MIN_WALK_NORMAL )
			{//normal players cannot step up slopes that are too steep to walk on!
				vec3_t stepVec;
				//okay, the step up ends on a slope that it too steep to step up onto,
				//BUT:
				//If the step looks like this:
				//  (B)\__
				//        \_____(A)
				//Then it might still be okay, so we figure out the slope of the entire move
				//from (A) to (B) and if that slope is walk-upabble, then it's okay
				VectorSubtract( trace.endpos, down_o, stepVec );
				VectorNormalize( stepVec ); 
				if ( stepVec[2] > (1.0f-MIN_WALK_NORMAL) )
				{
					if ( pm->debugLevel )
					{
						G_DebugLine(down_o,trace.endpos,2000,0x0000ff,qtrue);
					}
					skipStep = qtrue;
				}
			}
		}

		if ( !trace.allsolid
			&& !skipStep ) //normal players cannot step up slopes that are too steep to walk on!
		{
			if ( pm->ps->clientNum 
				&& isGiant 
				&& g_entities[trace.entityNum].client
				&& pm->gent
				&& pm->gent->client
				&& pm->gent->client->NPC_class == CLASS_RANCOR )
			{//Rancor don't step on clients
				if ( g_stepSlideFix->integer )
				{
					VectorCopy (down_o, pm->ps->origin);
					VectorCopy (down_v, pm->ps->velocity);
				}
				else
				{
					VectorCopy (start_o, pm->ps->origin);
					VectorCopy (start_v, pm->ps->velocity);
				}
			}
			else if ( pm->ps->clientNum 
				&& isGiant 
				&& g_entities[trace.entityNum].client
				&& g_entities[trace.entityNum].client->playerTeam == pm->gent->client->playerTeam )
			{//AT-ST's don't step up on allies
				if ( g_stepSlideFix->integer )
				{
					VectorCopy (down_o, pm->ps->origin);
					VectorCopy (down_v, pm->ps->velocity);
				}
				else
				{
					VectorCopy (start_o, pm->ps->origin);
					VectorCopy (start_v, pm->ps->velocity);
				}
			}
			else
			{
				VectorCopy( trace.endpos, pm->ps->origin );
				if ( g_stepSlideFix->integer )
				{
					if ( trace.fraction < 1.0 ) 
					{
						PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP );
					}
				}
			}
		}
		else
		{
			if ( g_stepSlideFix->integer )
			{
				VectorCopy (down_o, pm->ps->origin);
				VectorCopy (down_v, pm->ps->velocity);
			}
		}
		if ( !g_stepSlideFix->integer )
		{
			if ( trace.fraction < 1.0 ) 
			{
				PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP );
			}
		}
	}

	/*
	if(cantStepUpFwd && pm->ps->origin[2] < start_o[2] + stepSize && pm->ps->origin[2] >= start_o[2])
	{//We bumped into something we could not step up
		pm->ps->pm_flags |= PMF_BLOCKED;
	}
	else
	{//We did step up, clear the bumped flag
	}
	*/
#if 0
	// if the down trace can trace back to the original position directly, don't step
	pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, start_o, pm->ps->clientNum, pm->tracemask);
	if ( trace.fraction == 1.0 ) {
		// use the original move
		VectorCopy (down_o, pm->ps->origin);
		VectorCopy (down_v, pm->ps->velocity);
		if ( pm->debugLevel ) {
			Com_Printf("%i:bend\n", c_pmove);
		}
	} else 
#endif
	{
		// use the step move
		float	delta;

		delta = pm->ps->origin[2] - start_o[2];
		if ( delta > 2 ) {
			if ( delta < 7 ) {
				PM_AddEvent( EV_STEP_4 );
			} else if ( delta < 11 ) {
				PM_AddEvent( EV_STEP_8 );
			} else if ( delta < 15 ) {
				PM_AddEvent( EV_STEP_12 );
			} else {
				PM_AddEvent( EV_STEP_16 );
			}
		}
		if ( pm->debugLevel ) {
			Com_Printf("%i:stepped\n", c_pmove);
		}
	}
}
Example #22
0
void PM_StepSlideMove( qboolean gravity ) { 
	vec3_t		start_o, start_v;
	vec3_t		down_o, down_v;
	trace_t		trace;
//	float		down_dist, up_dist;
//	vec3_t		delta, delta2;
	vec3_t		up, down;
	float		stepSize;
	qboolean	isGiant = qfalse;
	bgEntity_t	*pEnt;
	qboolean skipStep = qfalse;
	int NEW_STEPSIZE = STEPSIZE;
	const int moveStyle = PM_GetMovePhysics();

	if (moveStyle == MV_CPM || moveStyle == MV_Q3 || moveStyle == MV_WSW || moveStyle == MV_RJQ3 || moveStyle == MV_RJCPM || moveStyle == MV_SLICK || moveStyle == MV_BOTCPM) {
		if (pm->ps->velocity[2] > 0 && pm->cmd.upmove > 0) {
			int jumpHeight = pm->ps->origin[2] - pm->ps->fd.forceJumpZStart;

			if (jumpHeight > 48)
				jumpHeight = 48;
			else if (jumpHeight < 22)
				jumpHeight = 22;

			NEW_STEPSIZE = 48 - jumpHeight + 22;

			//trap->SendServerCommand(-1, va("print \"new stepsize: %i, expected max end height: %i\n\"", NEW_STEPSIZE, NEW_STEPSIZE + (int)(pm->ps->origin[2] - pm->ps->fd.forceJumpZStart)));
			
			//This means that we can always clip things up to 48 units tall, if we are moving up when we hit it and from a bhop..
			//It means we can sometimes clip things up to 70 units tall, if we hit it in right part of jump
			//Should it be higher..? some of the things in q3 are 56 units tall..

			//NEW_STEPSIZE = 46;
			//Make stepsize equal to.. our current 48 - our current jumpheight ?
		}
		else 
			NEW_STEPSIZE = 22;
	}

	VectorCopy (pm->ps->origin, start_o);
	VectorCopy (pm->ps->velocity, start_v);

	if ( BG_InReboundHold( pm->ps->legsAnim ) )
	{
		gravity = qfalse;
	}

	if ( PM_SlideMove( gravity ) == 0 ) {
		return;		// we got exactly where we wanted to go first try, nospeed ramp returns here maybe	
	}

	pEnt = pm_entSelf;

	if (pm->ps->clientNum >= MAX_CLIENTS)
	{
		if (pEnt && pEnt->s.NPC_class == CLASS_VEHICLE &&
			pEnt->m_pVehicle && pEnt->m_pVehicle->m_pVehicleInfo->hoverHeight > 0)
		{
			return;
		}
	}

	VectorCopy(start_o, down);
	down[2] -= NEW_STEPSIZE;
	pm->trace (&trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
	VectorSet(up, 0, 0, 1);
	// never step up when you still have up velocity
	if ( pm->ps->velocity[2] > 0 && (trace.fraction == 1.0 ||
										DotProduct(trace.plane.normal, up) < 0.7))
	{
		return;
	}

	VectorCopy (pm->ps->origin, down_o);
	VectorCopy (pm->ps->velocity, down_v);

	VectorCopy (start_o, up);

	if (pm->ps->clientNum >= MAX_CLIENTS)
	{
		// apply ground friction, even if on ladder
		if (pEnt &&
			(pEnt->s.NPC_class == CLASS_ATST ||
			(pEnt->s.NPC_class == CLASS_VEHICLE && pEnt->m_pVehicle && pEnt->m_pVehicle->m_pVehicleInfo->type == VH_WALKER) ) )
		{//AT-STs can step high
			up[2] += 66.0f;
			isGiant = qtrue;
		}
		else if ( pEnt && pEnt->s.NPC_class == CLASS_RANCOR )
		{//also can step up high
			up[2] += 64.0f;
			isGiant = qtrue;
		}
		else
		{
			up[2] += NEW_STEPSIZE;
		}
	}
	else
	{
		up[2] += NEW_STEPSIZE;
	}

	// test the player position if they were a stepheight higher
	pm->trace (&trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask);
	if ( trace.allsolid ) {
		if ( pm->debugLevel ) {
			Com_Printf("%i:bend can't step\n", c_pmove);
		}
		return;		// can't step up, nospeed ramp returns here maybe
	}

	stepSize = trace.endpos[2] - start_o[2];
	// try slidemove from this position
	VectorCopy (trace.endpos, pm->ps->origin);
	VectorCopy (start_v, pm->ps->velocity);

	PM_SlideMove( gravity );

	pml.clipped = qtrue; //nospeed ramp fix, if we made it to this point there wont be a nospeed ramp

	// push down the final amount
	VectorCopy (pm->ps->origin, down);
	down[2] -= stepSize;
	pm->trace (&trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);

	if ( pm->stepSlideFix )
	{
		if ( pm->ps->clientNum < MAX_CLIENTS
			&& trace.plane.normal[2] < MIN_WALK_NORMAL )
		{//normal players cannot step up slopes that are too steep to walk on!
			vec3_t stepVec;
			//okay, the step up ends on a slope that it too steep to step up onto,
			//BUT:
			//If the step looks like this:
			//  (B)\__
			//        \_____(A)
			//Then it might still be okay, so we figure out the slope of the entire move
			//from (A) to (B) and if that slope is walk-upabble, then it's okay
			VectorSubtract( trace.endpos, down_o, stepVec );
			VectorNormalize( stepVec ); 
			if ( stepVec[2] > (1.0f-MIN_WALK_NORMAL) )
			{
				skipStep = qtrue;
			}
		}
	}

	if ( !trace.allsolid 
		&& !skipStep ) //normal players cannot step up slopes that are too steep to walk on!
	{ 
		if ( pm->ps->clientNum >= MAX_CLIENTS//NPC
			&& isGiant 
			&& trace.entityNum < MAX_CLIENTS
			&& pEnt 
			&& pEnt->s.NPC_class == CLASS_RANCOR )
		{//Rancor don't step on clients
			if ( pm->stepSlideFix )
			{
				VectorCopy (down_o, pm->ps->origin);
				VectorCopy (down_v, pm->ps->velocity);
			}
			else
			{
				VectorCopy (start_o, pm->ps->origin);
				VectorCopy (start_v, pm->ps->velocity);
			}
		}
		/*
		else if ( pm->ps->clientNum >= MAX_CLIENTS//NPC
			&& isGiant 
			&& trace.entityNum < MAX_CLIENTS
			&& pEnt 
			&& pEnt->s.NPC_class == CLASS_ATST 
			&& OnSameTeam( pEnt, traceEnt) )
		{//NPC AT-ST's don't step up on allies
			VectorCopy (start_o, pm->ps->origin);
			VectorCopy (start_v, pm->ps->velocity);
		}
		*/
		else
		{
			VectorCopy (trace.endpos, pm->ps->origin);
			if (pm->stepSlideFix)
			{
				if (trace.fraction < 1.0) {
					if (moveStyle == MV_WSW || moveStyle == MV_SLICK) { //Make Warsow Rampjump not slow down your XY speed
						vec3_t oldVel, clipped_velocity, newVel;
						float oldSpeed, newSpeed;

						VectorCopy(pm->ps->velocity, oldVel);
						oldSpeed = oldVel[0] * oldVel[0] + oldVel[1] * oldVel[1]; 

						PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, clipped_velocity, OVERCLIP ); //WSW RAMPJUMP 3

						VectorCopy(clipped_velocity, newVel);
						newVel[2] = 0;
						newSpeed = newVel[0] * newVel[0] + newVel[1] * newVel[1]; 

						if (newSpeed > oldSpeed)
							VectorCopy(clipped_velocity, pm->ps->velocity);
					}
					else {
						PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP );
					}
				}
			}
		}
	}
	else
	{
		if ( pm->stepSlideFix )
		{
			VectorCopy (down_o, pm->ps->origin);
			VectorCopy (down_v, pm->ps->velocity);
		}
	}
	if ( !pm->stepSlideFix )
	{
		if ( trace.fraction < 1.0 ) {
			if (moveStyle == MV_WSW || moveStyle == MV_SLICK) {
				vec3_t oldVel, clipped_velocity, newVel;
				float oldSpeed, newSpeed;

				VectorCopy(pm->ps->velocity, oldVel);
				oldSpeed = oldVel[0] * oldVel[0] + oldVel[1] * oldVel[1]; 

				PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, clipped_velocity, OVERCLIP ); //WSW RAMPJUMP 2

				VectorCopy(clipped_velocity, newVel);
				newVel[2] = 0;
				newSpeed = newVel[0] * newVel[0] + newVel[1] * newVel[1]; 

				if (newSpeed > oldSpeed)
					VectorCopy(clipped_velocity, pm->ps->velocity);
			}
			else {
				PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP );
			}
		}
	}

#if 0
	// if the down trace can trace back to the original position directly, don't step
	pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, start_o, pm->ps->clientNum, pm->tracemask);
	if ( trace.fraction == 1.0 ) {
		// use the original move
		VectorCopy (down_o, pm->ps->origin);
		VectorCopy (down_v, pm->ps->velocity);
		if ( pm->debugLevel ) {
			Com_Printf("%i:bend\n", c_pmove);
		}
	} else 
#endif
	{
		// use the step move
		float	delta;

		delta = pm->ps->origin[2] - start_o[2];
		if ( delta > 2 ) {
			if ( delta < 7 ) {
				PM_AddEvent( EV_STEP_4 );
			} else if ( delta < 11 ) {
				PM_AddEvent( EV_STEP_8 );
			} else if ( delta < 15 ) {
				PM_AddEvent( EV_STEP_12 );
			} else {
				PM_AddEvent( EV_STEP_16 );
			}
		}
		if ( pm->debugLevel ) {
			Com_Printf("%i:stepped\n", c_pmove);
		}
	}
}
Example #23
0
/*
==================
PM_StepSlideMove

==================
*/
void PM_StepSlideMove(qboolean gravity) {
    vec3_t      start_o, start_v;
    //  vec3_t      down_o, down_v;
    trace_t     trace;
    //  float       down_dist, up_dist;
    //  vec3_t      delta, delta2;
    vec3_t      up, down;
    float       stepSize;

    VectorCopy(pm->ps->origin, start_o);
    VectorCopy(pm->ps->velocity, start_v);

    if (PM_SlideMove(gravity) == 0) {
        return;     // we got exactly where we wanted to go first try
    }

    VectorCopy(start_o, down);
    down[2] -= STEPSIZE;
    pm->trace(&trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
    VectorSet(up, 0, 0, 1);
    // never step up when you still have up velocity
    if (pm->ps->velocity[2] > 0 && (trace.fraction == 1.0 ||
                                    DotProduct(trace.plane.normal, up) < 0.7)) {
        return;
    }

    //VectorCopy (pm->ps->origin, down_o);
    //VectorCopy (pm->ps->velocity, down_v);

    VectorCopy(start_o, up);
    up[2] += STEPSIZE;

    // test the player position if they were a stepheight higher
    pm->trace(&trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask);
    if (trace.allsolid) {
        if (pm->debugLevel) {
            Com_Printf("%i:bend can't step\n", c_pmove);
        }
        return;     // can't step up
    }

    stepSize = trace.endpos[2] - start_o[2];
    // try slidemove from this position
    VectorCopy(trace.endpos, pm->ps->origin);
    VectorCopy(start_v, pm->ps->velocity);

    PM_SlideMove(gravity);

    // push down the final amount
    VectorCopy(pm->ps->origin, down);
    down[2] -= stepSize;
    pm->trace(&trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask);
    if (!trace.allsolid) {
        VectorCopy(trace.endpos, pm->ps->origin);
    }
    if (trace.fraction < 1.0) {
        PM_ClipVelocity(pm->ps->velocity, trace.plane.normal, pm->ps->velocity, OVERCLIP);
    }

#if 0
    // if the down trace can trace back to the original position directly, don't step
    pm->trace(&trace, pm->ps->origin, pm->mins, pm->maxs, start_o, pm->ps->clientNum, pm->tracemask);
    if (trace.fraction == 1.0) {
        // use the original move
        VectorCopy(down_o, pm->ps->origin);
        VectorCopy(down_v, pm->ps->velocity);
        if (pm->debugLevel) {
            Com_Printf("%i:bend\n", c_pmove);
        }
    } else
#endif
    {
        // use the step move
        float   delta;

        delta = pm->ps->origin[2] - start_o[2];
        if (delta > 2) {
            if (delta < 7) {
                PM_AddEvent(EV_STEP_4);
            } else if (delta < 11) {
                PM_AddEvent(EV_STEP_8);
            } else if (delta < 15) {
                PM_AddEvent(EV_STEP_12);
            } else {
                PM_AddEvent(EV_STEP_16);
            }
        }
        if (pm->debugLevel) {
            Com_Printf("%i:stepped\n", c_pmove);
        }
    }
}
Example #24
0
/*
==================
PM_StepSlideMove
==================
*/
bool PM_StepSlideMove( bool gravity, bool predictive )
{
	vec3_t   start_o, start_v;
#ifndef UNREALARENA
	vec3_t   down_o, down_v;
#endif
	trace_t  trace;
#ifndef UNREALARENA
	vec3_t   normal;
	vec3_t   step_v, step_vNormal;
#endif
	vec3_t   up, down;
	float    stepSize;
	bool stepped = false;

#ifndef UNREALARENA
	BG_GetClientNormal( pm->ps, normal );
#endif

	VectorCopy( pm->ps->origin, start_o );
	VectorCopy( pm->ps->velocity, start_v );

	if ( !PM_SlideMove( gravity ) )
	{
#ifdef UNREALARENA
		return stepped; // we got exactly where we wanted to go first try
#else
		VectorCopy( start_o, down );
		VectorMA( down, -STEPSIZE, normal, down );
		pm->trace( &trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask, 0 );

		//we can step down
		if ( trace.fraction > 0.01f && trace.fraction < 1.0f &&
		     !trace.allsolid && pml.groundPlane )
		{
			if ( pm->debugLevel > 1 )
			{
				Log::Notice( "%d: step down\n", c_pmove );
			}

			stepped = true;
		}
#endif
	}
	else
	{
		VectorCopy( start_o, down );
#ifdef UNREALARENA
		down[ 2 ] -= STEPSIZE;
#else
		VectorMA( down, -STEPSIZE, normal, down );
#endif
		pm->trace( &trace, start_o, pm->mins, pm->maxs, down, pm->ps->clientNum, pm->tracemask, 0 );
#ifdef UNREALARENA
		VectorSet( up, 0.0f, 0.0f, 1.0f );
#endif

		// never step up when you still have up velocity
#ifdef UNREALARENA
		if ( pm->ps->velocity[ 2 ] > 0.0f && ( trace.fraction == 1.0f || DotProduct( trace.plane.normal, up ) < 0.7f ) )
#else
		if ( DotProduct( trace.plane.normal, pm->ps->velocity ) > 0.0f &&
		     ( trace.fraction == 1.0f || DotProduct( trace.plane.normal, normal ) < 0.7f ) )
#endif
		{
			return stepped;
		}

#ifndef UNREALARENA
		// never step up when flying upwards with the jetpack
		if ( pm->ps->velocity[ 2 ] > 0.0f && ( pm->ps->stats[ STAT_STATE2 ] & SS2_JETPACK_ACTIVE ) )
		{
			return stepped;
		}

		VectorCopy( pm->ps->origin, down_o );
		VectorCopy( pm->ps->velocity, down_v );
#endif

		VectorCopy( start_o, up );
#ifdef UNREALARENA
		up[ 2 ] += STEPSIZE;
#else
		VectorMA( up, STEPSIZE, normal, up );
#endif

		// test the player position if they were a stepheight higher
		pm->trace( &trace, start_o, pm->mins, pm->maxs, up, pm->ps->clientNum, pm->tracemask, 0 );

		if ( trace.allsolid )
		{
			if ( pm->debugLevel > 1 )
			{
				Log::Notice( "%i:bend can't step\n", c_pmove );
			}

			return stepped; // can't step up
		}

#ifdef UNREALARENA
		stepSize = trace.endpos[ 2 ] - start_o[ 2 ];

		// if the new position is falling then do nothing
		if ( PM_CheckFallingFromLedge( trace.endpos ) )
		{
			VectorCopy( start_o, pm->ps->origin );

			return stepped;
		}
#else
		VectorSubtract( trace.endpos, start_o, step_v );
		VectorCopy( step_v, step_vNormal );
		VectorNormalize( step_vNormal );

		stepSize = DotProduct( normal, step_vNormal ) * VectorLength( step_v );
#endif
		// try slidemove from this position
		VectorCopy( trace.endpos, pm->ps->origin );
		VectorCopy( start_v, pm->ps->velocity );

#ifdef UNREALARENA
		PM_SlideMove( gravity, stepSize );
#else
		if ( PM_SlideMove( gravity ) == 0 )
		{
			if ( pm->debugLevel > 1 )
			{
				Log::Notice( "%d: step up\n", c_pmove );
			}

			stepped = true;
		}
#endif

		// push down the final amount
		VectorCopy( pm->ps->origin, down );
#ifdef UNREALARENA
		down[ 2 ] -= stepSize;
#else
		VectorMA( down, -stepSize, normal, down );
#endif
		pm->trace( &trace, pm->ps->origin, pm->mins, pm->maxs, down, pm->ps->clientNum,
		           pm->tracemask, 0 );

		if ( !trace.allsolid )
		{
#ifdef UNREALARENA
			// if the new position is falling then do nothing
			if ( PM_CheckFallingFromLedge( trace.endpos ) )
			{
				VectorCopy( start_o, pm->ps->origin );

				return stepped;
			}
#endif
			VectorCopy( trace.endpos, pm->ps->origin );
		}

		if ( trace.fraction < 1.0f )
		{
			PM_ClipVelocity( pm->ps->velocity, trace.plane.normal, pm->ps->velocity );
		}
	}

#ifdef UNREALARENA
	if ( !predictive )
	{
		stepped = true;

		// use the step move
		float	delta;

		delta = pm->ps->origin[ 2 ] - start_o[ 2 ];

		if ( delta > 2.0f )
		{
			if ( delta < 7.0f )
			{
				PM_AddEvent( EV_STEP_4 );
			}
			else if ( delta < 11.0f )
			{
				PM_AddEvent( EV_STEP_8 );
			}
			else if ( delta < 15.0f )
			{
				PM_AddEvent( EV_STEP_12 );
			}
			else
			{
				PM_AddEvent( EV_STEP_16 );
			}
		}

		if ( pm->debugLevel > 1 )
		{
			Log::Notice( "%i:stepped\n", c_pmove );
		}
	}
#else
	if ( !predictive && stepped )
	{
		PM_StepEvent( start_o, pm->ps->origin, normal );
	}
#endif

	return stepped;
}