gCycleMovement Class Reference

class handling lightcycle movement aspects ( not networking beyond construction, no rendering, no wall building ) More...

#include <gCycleMovement.h>

Inheritance diagram for gCycleMovement:

Inheritance graph
[legend]
Collaboration diagram for gCycleMovement:

Collaboration graph
[legend]

List of all members.

Public Member Functions

int WindingNumber () const
 returns the current winding number
void SetWindingNumberWrapped (int newWindingNumberWrapped)
 sets the new wrapped winding number
virtual eCoord Direction () const
 returns the current driving direction
virtual eCoord LastDirection () const
 returns the last driving direction
virtual REAL Speed () const
 returns the current speed
virtual bool Alive () const
 returns whether the cycle is still alive
virtual bool Vulnerable () const
 returns whether the cycle can be killed
virtual eCoord SpawnDirection () const
 returns the driving direction when the cycle was last spawned
bool CanMakeTurn (int direction) const
 returns whether a turn is currently possible
bool CanMakeTurn (REAL time, int direction) const
 returns whether a turn is possible at the given time
REAL GetDistanceSinceLastTurn () const
 returns the distance since the last turn
REAL GetTurnDelay () const
 returns the time between turns in different directions
REAL GetTurnDelayDb () const
 returns the time between turns in the same direcion
REAL GetNextTurn (int direction) const
 returns the time of the next turn
void AddDestination ()
 adds current position as destination
void AdvanceDestination ()
 proceeds to the next destination
void AddDestination (gDestination *dest)
 adds given destination
gDestinationGetCurrentDestination () const
 returns the current destination
void NotifyNewDestination (gDestination *dest)
 notifies cycle of the insertion of a new destination ( don't call manually )
bool IsDestinationUsed (const gDestination *dest) const
 returns whether the given destination is in active use
void DropTempWall (gPlayerWall *wall, eCoord const &pos, eCoord const &dir)
 called when another cycle grinds a wall; this cycle should then drop its current wall if the grinding is too close.
virtual bool EdgeIsDangerous (const eWall *wall, REAL time, REAL alpha) const
 returns whether a given wall is dangerous to this cycle
bool Turn (REAL dir)
 Turn left for positive argument, right for negative argument.
bool Turn (int dir)
 Turn left for positive argument, right for negative argument.
void MoveSafely (const eCoord &dest, REAL startTime, REAL endTime)
 move without throwing exceptions on passing a wall
virtual bool Timestep (REAL currentTime)
 advance to the given time
virtual REAL NextInterestingTime () const
 the next time something interesting is going to happen with this object
virtual void AddRef ()
 increase reference count
 gCycleMovement (eGrid *grid, const eCoord &pos, const eCoord &dir, ePlayerNetID *p=NULL, bool autodelete=1)
 local constructor
 gCycleMovement (nMessage &message)
 remote constructor
virtual ~gCycleMovement ()
 destructor
virtual void OnRemoveFromGame ()
 called on RemoveFromGame(). Call base class implementation, too, in your implementation. Must keep the object alive.
void RequestSync (bool ack=true)
 request a sync
void RequestSync (int user, bool ack)
 only for a single user
REAL GetMaxSpaceAhead (REAL maxReport) const
REAL GetDistance (void) const
 Gets the distance traveled so far.
gCycleMovement const & GetDistance (REAL &distance) const
 Gets the distance traveled so far.
REAL GetRubber (void) const
 Gets the amount rubber used up by the cycle.
gCycleMovement const & GetRubber (REAL &rubber) const
 Gets the amount rubber used up by the cycle.
unsigned short GetTurns (void) const
 Gets the number of turns taken so far.
gCycleMovement const & GetTurns (unsigned short &turns) const
 Gets the number of turns taken so far.
unsigned short GetBraking (void) const
 Gets flag indicating status of brakes ( on/off ).
gCycleMovement const & GetBraking (unsigned short &braking) const
 Gets flag indicating status of brakes ( on/off ).
REAL GetBrakingReservoir (void) const
 Gets the reservoir for braking. 1 means full, 0 is empty.
gCycleMovement const & GetBrakingReservoir (REAL &brakingReservoir) const
 Gets the reservoir for braking. 1 means full, 0 is empty.
REAL GetRubberMalus (void) const
 Gets additional rubber usage factor.
gCycleMovement const & GetRubberMalus (REAL &rubberMalus) const
 Gets additional rubber usage factor.
eCoord const & GetLastTurnPos (void) const
 Gets the location of the last turn.
gCycleMovement const & GetLastTurnPos (eCoord &lastTurnPos) const
 Gets the location of the last turn.
REAL const & GetLastTurnTime (void) const
 Gets the time of the last turn.
gCycleMovement const & GetLastTurnTime (REAL &lastTurnTime) const
 Gets the time of the last turn.
REAL GetAcceleration (void) const
virtual void AddZoneAcceleration (REAL zoneAcceleration)
 Gets the cycle's acceleration.
gCycleMovementSetRubber (REAL rubber)
 Sets the amount rubber used up by the cycle.
gCycleMovementSetBrakingReservoir (REAL brakingReservoir)
 Sets the reservoir for braking. 1 means full, 0 is empty.

Static Public Member Functions

static float RubberSpeed ()
 returns the rubber speed (decay rate of the distance to the wall in front)
static float SpeedMultiplier ()
 returns the current speed multiplier
static void SetSpeedMultiplier (REAL mult)
 sets the current speed multiplier
static float MaximalSpeed ()
 returns the maximal speed a cycle can reach on its own
static bool RubberMalusActive (void)
 Returns whether rubber malus code is active.

Protected Member Functions

void CopyFrom (const gCycleMovement &other)
 copies relevant info from other cylce
void CopyFrom (const SyncData &sync, const gCycleMovement &other)
 copies relevant info from sync data and everything else from other cycle
virtual void InitAfterCreation ()
 shared initialization routine
virtual void AccelerationDiscontinuity ()
 call when you know the acceleration makes a sharp jump now
virtual void CalculateAcceleration ()
 calculate acceleration to apply later
virtual void ApplyAcceleration (REAL dt)
 apply acceleration calculated earlier
REAL DistanceToDestination (gDestination &dest) const
 calculates the distance to the given destination
virtual void OnNotifyNewDestination (gDestination *dest)
 notifies cycle of the insertion of a new destination
virtual void OnDropTempWall (gPlayerWall *wall, eCoord const &pos, eCoord const &dir)
 called when another cycle grinds a wall; this cycle should then drop its current wall if the grinding is too close.
virtual bool DoIsDestinationUsed (const gDestination *dest) const
 returns whether the given destination is in active use
virtual bool DoTurn (int dir)
 turns the cycle in the given direction
virtual REAL DoGetDistanceSinceLastTurn () const
 returns the distance since the last turn
virtual void RightBeforeDeath (int numTries)
 called when the cycle is very close to a wall and about to crash
virtual void Die (REAL time)
 dies at the specified time
virtual bool TimestepCore (REAL currentTime, bool calculateAcceleration=true)
 core physics simulation routine
gCycleMovementSetLastTurnPos (eCoord const &lastTurnPos)
 Sets the location of the last turn.
gCycleMovementSetLastTurnTime (REAL const &lastTurnTime)
 Sets the time of the last turn.

Static Protected Member Functions

static gDestinationGetDestinationBefore (const SyncData &sync, gDestination *first)
 determine the destination from before the sync message

Protected Attributes

gEnemyInfluence enemyInfluence
 keeps track of enemies that influenced this cycle
gDestinationdestinationList
 the list of destinations that belong to this cycle ( for memory management )
gDestinationcurrentDestination
 the destination this cycle aims for now
gDestinationlastDestination
 the last destination that was passed
eCoord dirDrive
 the direction we are facing
eCoord dirSpawn
 the direction we were facing on the last spawn
eCoord lastDirDrive
 the direction we were facing before the last turn
REAL acceleration
 current acceleration
REAL totalZoneAcceleration
 current acceleration from the effect of zones and monitor
REAL lastTimestep_
 the length of the last timestep
REAL verletSpeed_
 object speed according to verlet (speed of half a frame ago)
REAL distance
 the distance traveled so far
bool refreshSpaceAhead_
 flag to set when maximum space in front of cycle should be recalculated
REAL maxSpaceMaxCast_
 the maximum raycast length to determine the above value
gMaxSpaceAheadHitInfomaxSpaceHit_
 detailed information about the wall in front
unsigned short turns
 the number of turns taken so far
unsigned short braking
 flag indicating status of brakes ( on/off )
int windingNumber_
 number that gets increased on every right turn and decreased on every left turn ( used by the AI )
int windingNumberWrapped_
 winding number wrapped to be used as an index to the axes code
REAL gap_ [2]
 when driving towards a wall, this is set to the maximal distance we need to approach it so that when the cycle turns, it can squeeze through any gaps
bool keepLookingForGap_ [2]
 flags telling the system whether it is worthwile to look for further, smaller, gaps
eCoord lastTurnPos_
 the location of the last turn
REAL lastTurnTimeRight_
 the time of the last turn right
REAL lastTurnTimeLeft_
 the time of the last turn left
REAL lastTimeAlive_
 the time of the last timestep where we would not have been killed
std::deque< int > pendingTurns
 stores turns ordered by the user, but not yet executed
REAL brakingReservoir
 the reservoir for braking. 1 means full, 0 is empty
REAL rubber
 the amount rubber used up by the cycle
REAL rubberMalus
 additional rubber usage factor
REAL rubberSpeedFactor
 the factor by which the speed is currently multiplied by rubber
REAL brakeUsage
 current brake usage
REAL rubberUsage
 current rubber usage (not from hitting a wall, but from tunneling. Without taking efficiency into account.)

Private Member Functions

void MyInitAfterCreation ()
 private shared initialization code
 gCycleMovement ()
 default constructor
 gCycleMovement (gCycleMovement const &other)
 copy constructor
gCycleMovementoperator= (gCycleMovement const &other)
 copy operator
gCycleMovementSetDistance (REAL distance)
 Sets the distance traveled so far.
gCycleMovementSetTurns (unsigned short turns)
 Sets the number of turns taken so far.
gCycleMovementSetBraking (unsigned short braking)
 Sets flag indicating status of brakes ( on/off ).
gCycleMovementSetRubberMalus (REAL rubberMalus)
 Sets additional rubber usage factor.

Private Attributes

short alive_
 status: 1: cycle is alive, -1: cycle just died, 0: cycle is dead

Classes

struct  SyncData
 data from sync message More...


Detailed Description

class handling lightcycle movement aspects ( not networking beyond construction, no rendering, no wall building )

Definition at line 76 of file gCycleMovement.h.


Constructor & Destructor Documentation

gCycleMovement::gCycleMovement ( eGrid grid,
const eCoord &  pos,
const eCoord &  dir,
ePlayerNetID player = NULL,
bool  autodelete = 1 
)

local constructor

Parameters:
grid the grid the cycle will live on
pos start position
dir start direction
player player owning this cycle
autodelete should the cycle get deleted when it gets killed?

Definition at line 2489 of file gCycleMovement.cpp.

References eGrid::DirectionWinding(), eGameObject::Grid(), MyInitAfterCreation(), windingNumber_, and windingNumberWrapped_.

Here is the call graph for this function:

gCycleMovement::gCycleMovement ( nMessage message  ) 

remote constructor

Parameters:
message network message to read everything from

Definition at line 2514 of file gCycleMovement.cpp.

References windingNumber_, and windingNumberWrapped_.

02516         :eNetGameObject(message),
02517         destinationList(NULL),currentDestination(NULL),lastDestination(NULL),
02518         dirDrive(1,0),
02519         acceleration(0),
02520         totalZoneAcceleration(0),
02521         lastTimestep_(0),
02522         verletSpeed_(5)
02523 {
02524     windingNumberWrapped_ = windingNumber_ = 2;
02525 
02526     // MyInitAfterCreation();

gCycleMovement::~gCycleMovement ( void   )  [virtual]

destructor

Definition at line 2537 of file gCycleMovement.cpp.

References currentDestination, destinationList, distance, lastDestination, maxSpaceHit_, NULL, and verletSpeed_.

02539 {
02540     lastDestination = NULL;
02541     currentDestination = NULL;
02542 
02543     while(destinationList)
02544     {
02545         gDestination* dest = destinationList;
02546         delete dest;
02547     }
02548 
02549     verletSpeed_=distance=0;
02550 
02551     delete maxSpaceHit_;
02552     maxSpaceHit_ = NULL;

gCycleMovement::gCycleMovement (  )  [private]

default constructor

gCycleMovement::gCycleMovement ( gCycleMovement const &  other  )  [private]

copy constructor


Member Function Documentation

float gCycleMovement::RubberSpeed (  )  [static]

returns the rubber speed (decay rate of the distance to the wall in front)

Returns:
the rubber speed (decay rate of the distance to the wall in front)

Definition at line 733 of file gCycleMovement.cpp.

References sg_rubberCycleSpeed.

Referenced by _wrap_GCycleMovement_rubber_speed(), and gCycle::PreparePredictPosition().

00735 {
00736     return sg_rubberCycleSpeed;

Here is the caller graph for this function:

float gCycleMovement::SpeedMultiplier ( void   )  [static]

returns the current speed multiplier

Returns:
the number all speed settings get multiplied by

Definition at line 748 of file gCycleMovement.cpp.

References sg_speedMultiplier.

Referenced by _wrap_GCycleMovement_speed_multiplier(), ApplyAcceleration(), CalculateAcceleration(), DoTurn(), gCycleExtrapolator::EdgeIsDangerous(), GetTurnDelay(), gAIPlayer::NewObject(), sg_RubberValues(), gSpawnPoint::Spawn(), gCamera::SpeedMultiplier(), and Timestep().

00750 {
00751     return sg_speedMultiplier;

Here is the caller graph for this function:

void gCycleMovement::SetSpeedMultiplier ( REAL  mul  )  [static]

sets the current speed multiplier

Parameters:
mul the number all speed settings get multiplied by

Definition at line 763 of file gCycleMovement.cpp.

References conf_mult.

Referenced by _wrap_GCycleMovement_set_speed_multiplier(), and sg_copySettings().

00765 {
00766     conf_mult.Set( mul );

Here is the caller graph for this function:

float gCycleMovement::MaximalSpeed ( void   )  [static]

returns the maximal speed a cycle can reach on its own

Returns:
the maximal speed a cycle can reach

Definition at line 787 of file gCycleMovement.cpp.

References REAL, sg_accelerationCycle, sg_accelerationCycleEnemy, sg_accelerationCycleOffs, sg_accelerationCycleRim, sg_accelerationCycleSelf, sg_accelerationCycleSlingshot, sg_accelerationCycleTeam, sg_accelerationCycleTunnel, sg_brakeCycle, sg_cycleBrakeDeplete, sg_cycleBrakeRefill, sg_MaxSpeed(), sg_nearCycle, sg_speedCycleStart, and sg_speedMultiplier.

Referenced by _wrap_GCycleMovement_maximal_speed().

00789 {
00790     // determine the maximal acceleration by walls
00791     REAL maxWallAcceleration = 0;
00792     REAL wallAcceleration = sg_accelerationCycleTeam * sg_accelerationCycle;
00793     if ( wallAcceleration > maxWallAcceleration )
00794         maxWallAcceleration = wallAcceleration;
00795     wallAcceleration = sg_accelerationCycleEnemy * sg_accelerationCycle;
00796     if ( wallAcceleration > maxWallAcceleration )
00797         maxWallAcceleration = wallAcceleration;
00798     wallAcceleration = sg_accelerationCycleRim * sg_accelerationCycle;
00799     if ( wallAcceleration > maxWallAcceleration )
00800         maxWallAcceleration = wallAcceleration;
00801 
00802     // self acceleration is tricky: slingshot countermeasures have to be taken into account
00803     REAL wallAccelerationSelf = sg_accelerationCycleSelf * sg_accelerationCycle;
00804 
00805     {
00806         // different combinations are now possible to get a maximum. It could be a single wall:
00807         REAL wallAccelerationSingle = maxWallAcceleration;
00808         if ( wallAccelerationSingle < wallAccelerationSelf )
00809             wallAccelerationSingle = wallAccelerationSelf;
00810 
00811         // it could be a slingshot, one arbitrary wall and one own wall:
00812         REAL wallAccelerationSlingshot = ( wallAccelerationSingle + wallAccelerationSelf ) * sg_accelerationCycleSlingshot;
00813 
00814         // or a tunnel, two foreign walls:
00815         REAL wallAccelerationTunnel = ( maxWallAcceleration ) * sg_accelerationCycleTunnel;
00816 
00817 
00818         // take the maximum
00819         if ( maxWallAcceleration < wallAccelerationSlingshot )
00820             maxWallAcceleration = wallAccelerationSlingshot;
00821         if ( maxWallAcceleration < wallAccelerationTunnel )
00822             maxWallAcceleration = wallAccelerationTunnel;
00823     }
00824 
00825     // use wall accel formula to take wall distance into account
00826     maxWallAcceleration *= ( 1/sg_accelerationCycleOffs - 1/(sg_accelerationCycleOffs+sg_nearCycle ) );
00827 
00828     // maximal sustainable speed from that
00829     REAL maxSpeed = sg_MaxSpeed( maxWallAcceleration );
00830 
00831     // what if the brake is a booster?
00832     if ( sg_brakeCycle < 0 )
00833     {
00834         // what if it can be applied infinitely?
00835         REAL maxSpeedBoost = sg_MaxSpeed( maxWallAcceleration - sg_brakeCycle );
00836 
00837         // but the boost can permanently only be applied at this efficiency
00838         REAL efficiency = 1;
00839         if ( sg_cycleBrakeRefill + sg_cycleBrakeDeplete > 0 )
00840             efficiency = sg_cycleBrakeRefill/(sg_cycleBrakeRefill + sg_cycleBrakeDeplete);
00841 
00842         // maximal permanent speed
00843         REAL maxSpeedPermanent = sg_MaxSpeed( maxWallAcceleration - sg_brakeCycle*efficiency );
00844 
00845         // if the boost is limited, don't let the result be larger than what you can achieve by
00846         // accelerating from the max speed attainable from walls
00847         if ( sg_cycleBrakeDeplete > 0 )
00848         {
00849             REAL boostTime = 1/sg_cycleBrakeDeplete;
00850             REAL maxSpeedBoost2 = maxSpeedPermanent - boostTime * sg_brakeCycle;
00851             if ( maxSpeedBoost2 < maxSpeedBoost )
00852                 maxSpeedBoost = maxSpeedBoost2;
00853         }
00854 
00855         // take over the result
00856         maxSpeed = maxSpeedBoost;
00857     }
00858 
00859     // start speed
00860     if ( sg_speedCycleStart > maxSpeed )
00861         maxSpeed = sg_speedCycleStart;
00862 
00863     // apply multiplier
00864     return sg_speedMultiplier * maxSpeed;

Here is the call graph for this function:

Here is the caller graph for this function:

int gCycleMovement::WindingNumber ( void   )  const

returns the current winding number

Returns:
number of right turns taken minus the number of left turns

Reimplemented in gCycle.

Definition at line 878 of file gCycleMovement.cpp.

References windingNumber_.

Referenced by blocks(), SetWindingNumberWrapped(), and gJoystick::Turn().

00880 {
00881     return windingNumber_;

Here is the caller graph for this function:

void gCycleMovement::SetWindingNumberWrapped ( int  newWindingNumberWrapped  ) 

sets the new wrapped winding number

Parameters:
newWindingNumberWrapped new wrapped winding number taken from the current driving direction

Definition at line 893 of file gCycleMovement.cpp.

References eGameObject::Grid(), eGrid::WindingNumber(), WindingNumber(), windingNumber_, and windingNumberWrapped_.

Referenced by CopyFrom(), DoTurn(), and gCycle::ReadSync().

00895 {
00896     // calculate the difference in the wrapped winding number
00897     int difference = newWindingNumberWrapped - windingNumberWrapped_;
00898 
00899     // wrap it into the interval [-WN/2,WN/2]
00900     if (2 * difference <= -Grid()->WindingNumber())
00901         difference += Grid()->WindingNumber();
00902     if (2 * difference >= Grid()->WindingNumber())
00903         difference -= Grid()->WindingNumber();
00904 
00905     // commit changes
00906     windingNumberWrapped_ = newWindingNumberWrapped;
00907     windingNumber_ += difference;

Here is the call graph for this function:

Here is the caller graph for this function:

eCoord gCycleMovement::Direction ( void   )  const [virtual]

returns the current driving direction

Returns:
the currend driving direction

Reimplemented from eGameObject.

Reimplemented in gCycle.

Definition at line 919 of file gCycleMovement.cpp.

References dirDrive.

Referenced by _wrap_GCycleMovement_direction(), gJoystick::Act(), gDestination::CopyFrom(), gCycle::Direction(), and GetMaxSpaceAhead().

00921 {
00922     return dirDrive;

Here is the caller graph for this function:

eCoord gCycleMovement::LastDirection ( void   )  const [virtual]

returns the last driving direction

Returns:
the last driving direction

Reimplemented from eGameObject.

Definition at line 940 of file gCycleMovement.cpp.

References lastDirDrive.

Referenced by _wrap_GCycleMovement_last_direction().

00942 {
00943     return lastDirDrive;

Here is the caller graph for this function:

REAL gCycleMovement::Speed ( void   )  const [virtual]

returns the current speed

Returns:
the current speed

Reimplemented from eGameObject.

Definition at line 955 of file gCycleMovement.cpp.

References acceleration, lastTimestep_, REAL, and verletSpeed_.

Referenced by AccelerationDiscontinuity(), gAIPlayer::ActOnData(), cCockpit::cb_TimeToImpactFront(), gDestination::CopyFrom(), gAIPlayer::CycleBlocksWay(), DoTurn(), cWidget::Map::DrawMap(), gCycleExtrapolator::EdgeIsDangerous(), gAIPlayer::EmergencySurvive(), GetMaxSpaceAhead(), gCycle::InitAfterCreation(), gCycle::PassEdge(), gCycle::ReadSync(), gAIPlayer::RightBeforeDeath(), gAIPlayer::Think(), gAIPlayer::ThinkCloseCombat(), gAIPlayer::ThinkPath(), gAIPlayer::ThinkTrace(), TimestepCore(), gCycle::TimestepCore(), gCycle::WallEndSpeed(), and gCycle::WriteSync().

00957 {
00958     REAL ret = verletSpeed_ + .5f * lastTimestep_ * acceleration;
00959     return ret > 0 ? ret : 0;

Here is the caller graph for this function:

bool gCycleMovement::Alive (  )  const [virtual]

returns whether the cycle is still alive

Returns:
true if the cycle is still alive

Reimplemented from eGameObject.

Definition at line 971 of file gCycleMovement.cpp.

References alive_.

Referenced by gCycle::Act(), AddRef(), gEnemyInfluence::AddWall(), gAIPlayer::Alive(), gGame::Analysis(), gCycleWallsDisplayListManager::CannotHaveList(), gCycle::DoTurn(), cWidget::Map::DrawWalls(), gAIPlayer::EmergencySurvive(), zZone::InteractWith(), gZone::InteractWith(), zShapePolygon::isInteracting(), zShapeCircle::isInteracting(), gCycle::Kill(), gCycle::KillAt(), gCycle::OnRemoveFromGame(), gCycle::OnRoundEnd(), gCycle::PassEdge(), gCycleExtrapolator::PassEdge(), gCycle::ReadSync(), gCycle::Render(), gCycle::Render2D(), RequestSync(), gCycle::RequestSyncAll(), gCycle::RequestSyncOwner(), sg_TopologyPoliceKill(), Timestep(), gCycle::Timestep(), gAIPlayer::Timestep(), gCycle::TimestepCore(), gCycle::Vulnerable(), and gCycle::WriteSync().

00973 {
00974     return alive_ > 0;

Here is the caller graph for this function:

bool gCycleMovement::Vulnerable (  )  const [virtual]

returns whether the cycle can be killed

Returns:
true if the cycle is vulnerable

Reimplemented in gCycle.

Definition at line 986 of file gCycleMovement.cpp.

Referenced by TimestepCore().

00988 {
00989     return true;

Here is the caller graph for this function:

eCoord gCycleMovement::SpawnDirection (  )  const [virtual]

returns the driving direction when the cycle was last spawned

Returns:
the driving direction when the cycle was last spawned

Definition at line 926 of file gCycleMovement.cpp.

References dirSpawn.

Referenced by _wrap_GCycleMovement_spawn_direction(), and cWidget::Map::DrawMap().

00927                                             {
00928     return dirSpawn;

Here is the caller graph for this function:

bool gCycleMovement::CanMakeTurn ( int  direction  )  const

returns whether a turn is currently possible

Parameters:
direction the direction of the planned turn
Returns:
true if a new turn is possible right now

Definition at line 1002 of file gCycleMovement.cpp.

References eGameObject::lastTime, and pendingTurns.

Referenced by DoTurn(), Timestep(), and gJoystick::Turn().

01004 {
01005     return pendingTurns.empty() && CanMakeTurn( lastTime, direction );

Here is the caller graph for this function:

bool gCycleMovement::CanMakeTurn ( REAL  time,
int  direction 
) const

returns whether a turn is possible at the given time

Parameters:
time the time to check
direction the direction of the planned turn
Returns:
true if a new turn is possible at the given time

Definition at line 1019 of file gCycleMovement.cpp.

References GetNextTurn().

01021 {
01022     return time >= GetNextTurn(direction);

Here is the call graph for this function:

REAL gCycleMovement::GetDistanceSinceLastTurn ( void   )  const [inline]

returns the distance since the last turn

Returns:
the distance driven since the last turn

Definition at line 662 of file gCycleMovement.h.

References DoGetDistanceSinceLastTurn().

Referenced by GetMaxSpaceAhead(), and gCycle::PassEdge().

00663 {
00664     return this->DoGetDistanceSinceLastTurn();
00665 }

Here is the call graph for this function:

Here is the caller graph for this function:

REAL gCycleMovement::GetTurnDelay ( void   )  const

returns the time between turns in different directions

Returns:
the delay between turns in seconds

Definition at line 1034 of file gCycleMovement.cpp.

References REAL, sg_delayCycle, sg_delayCycleBonus, sg_delayCycleTimeBased, sg_speedCycle, SpeedMultiplier(), and verletSpeed_.

Referenced by CopyFrom(), gCycleExtrapolator::EdgeIsDangerous(), GetNextTurn(), gCycle::Render(), Timestep(), and TimestepCore().

01036 {
01037     // the basic delay as it was before 0.2.8 looked like this:
01038     REAL baseDelay   = sg_delayCycle*sg_delayCycleBonus/SpeedMultiplier();
01039 
01040     // we're modifying it by a power law to make speed turns easier or harder:
01041     REAL speedFactor = verletSpeed_/(sg_speedCycle*SpeedMultiplier());
01042 
01043     return baseDelay * pow( speedFactor, sg_delayCycleTimeBased-1 );

Here is the call graph for this function:

Here is the caller graph for this function:

REAL gCycleMovement::GetTurnDelayDb ( void   )  const

returns the time between turns in the same direcion

Returns:
the delay between turns in seconds

Definition at line 1046 of file gCycleMovement.cpp.

Referenced by GetNextTurn().

01048 {
01049     // the basic delay as it was before 0.2.8 looked like this:
01050     REAL baseDelay   = sg_delayCycle*sg_delayCycleBonus/SpeedMultiplier()*sg_delayCycleDoublebindBonus;
01051 
01052     // we're modifying it by a power law to make speed turns easier or harder:
01053     REAL speedFactor = verletSpeed_/(sg_speedCycle*SpeedMultiplier());
01054 
01055     return baseDelay * pow( speedFactor, sg_delayCycleTimeBased-1 );

Here is the caller graph for this function:

REAL gCycleMovement::GetNextTurn ( int  direction  )  const

returns the time of the next turn

Returns:
the time of the next possible turn

Definition at line 1067 of file gCycleMovement.cpp.

References GetTurnDelay(), GetTurnDelayDb(), lastTurnTimeLeft_, and lastTurnTimeRight_.

Referenced by CanMakeTurn(), CopyFrom(), and Timestep().

01069 {
01070     float right,left;
01071 #ifdef DEBUG_X
01072     std::cerr << "GetNextTurn: " << direction << std::endl;
01073 #endif
01074     if(direction == 1) {
01075         right = lastTurnTimeRight_ + GetTurnDelayDb();
01076         left = lastTurnTimeLeft_ + GetTurnDelay();
01077     } else {
01078         right = lastTurnTimeLeft_ + GetTurnDelayDb();
01079         left = lastTurnTimeRight_ + GetTurnDelay();
01080     }
01081 #ifdef DEBUG_X
01082     std::cerr << "GetTurnDelay: " << GetTurnDelay() << std::endl;
01083     std::cerr << "GetTurnDelayDb: " << GetTurnDelayDb() << std::endl;
01084     std::cerr << "lastTurnTimeRight_: " << lastTurnTimeRight_ << std::endl;
01085     std::cerr << "lastTurnTimeLeft_: " << lastTurnTimeLeft_ << std::endl;
01086     std::cerr << "right: " << right << std::endl;
01087     std::cerr << "left: " << left << std::endl;
01088 #endif
01089     return left > right ? left : right;

Here is the call graph for this function:

Here is the caller graph for this function:

void gCycleMovement::AddDestination ( void   ) 

adds current position as destination

Definition at line 1100 of file gCycleMovement.cpp.

References nCLIENT, sn_GetNetState(), and tNEW.

Referenced by gCycle::Act(), gCycle::DoTurn(), and new_destination_handler().

01102 {
01103     if ( sn_GetNetState() == nCLIENT )
01104     {
01105         gDestination* dest = tNEW(gDestination)(*this);
01106         //      dest->position = dest->position + dest->direction.Turn( 0, 10.0f );
01107         AddDestination( dest );
01108     }

Here is the call graph for this function:

Here is the caller graph for this function:

void gCycleMovement::AdvanceDestination ( void   ) 

proceeds to the next destination

Definition at line 1163 of file gCycleMovement.cpp.

References tASSERT.

01165 {
01166     // not implemented
01167     tASSERT(0);

void gCycleMovement::AddDestination ( gDestination dest  ) 

adds given destination

Parameters:
dest the destination to add

Definition at line 1120 of file gCycleMovement.cpp.

References destinationList, gDestination::hasBeenUsed, gDestination::InsertIntoList(), gDestination::next, and NotifyNewDestination().

01122 {
01123     //  con << "got new dest " << dest->position << "," << dest->direction
01124     // << "," << dest->distance << "\n";
01125 
01126     dest->InsertIntoList(&destinationList);
01127 
01128     // if the next destination already has been used, this destination will never be used
01129     if (dest->next && dest->next->hasBeenUsed){
01130         delete dest;
01131         return;
01132     }
01133 
01134     this->NotifyNewDestination( dest );
01135 
01136     // repeat insertion: position may have changed
01137     dest->InsertIntoList(&destinationList);

Here is the call graph for this function:

gDestination * gCycleMovement::GetCurrentDestination ( void   )  const

returns the current destination

Returns:
the destination this cycle is driving towards right now

Definition at line 1149 of file gCycleMovement.cpp.

References currentDestination.

Referenced by gCycleExtrapolator::TimestepCore().

01151 {
01152     return currentDestination;

Here is the caller graph for this function:

void gCycleMovement::NotifyNewDestination ( gDestination dest  ) 

notifies cycle of the insertion of a new destination ( don't call manually )

Parameters:
dest the new destination the cycle is notified about

Definition at line 1179 of file gCycleMovement.cpp.

References OnNotifyNewDestination().

Referenced by AddDestination().

01181 {
01182     this->OnNotifyNewDestination( dest );

Here is the call graph for this function:

Here is the caller graph for this function:

bool gCycleMovement::IsDestinationUsed ( const gDestination dest  )  const [inline]

returns whether the given destination is in active use

Parameters:
dest the destination to test
Returns:
true if the destination is still in active use

Definition at line 384 of file gCycleMovement.h.

References DoIsDestinationUsed().

Referenced by Timestep().

00385 {
00386     // delegate to virtual function
00387     return DoIsDestinationUsed( dest );
00388 }

Here is the call graph for this function:

Here is the caller graph for this function:

void gCycleMovement::DropTempWall ( gPlayerWall wall,
eCoord const &  pos,
eCoord const &  dir 
) [inline]

called when another cycle grinds a wall; this cycle should then drop its current wall if the grinding is too close.

Parameters:
wall the wall the other cycle is grinding
pos the position of the grind
dir the direction the raycast triggering the gridding comes from

Definition at line 402 of file gCycleMovement.h.

References OnDropTempWall().

Referenced by sg_DropTempWall().

00403 {
00404     this->OnDropTempWall( wall, pos, dir );
00405 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool gCycleMovement::EdgeIsDangerous ( const eWall wall,
REAL  time,
REAL  alpha 
) const [virtual]

returns whether a given wall is dangerous to this cycle

Parameters:
wall the wall to check for danger
time the time of the possible collision
alpha the local wall coordinate of the collision
Returns:
true if the wall is dangerous

Reimplemented from eGameObject.

Reimplemented in gCycleExtrapolator, and gCycle.

Definition at line 1397 of file gCycleMovement.cpp.

References gPlayerWall::IsDangerous().

Referenced by gCycle::EdgeIsDangerous(), and gCycleExtrapolator::EdgeIsDangerous().

01399 {
01400     if (!wall)
01401         return false;
01402 
01403     const gPlayerWall *w = dynamic_cast<const gPlayerWall*>(wall);
01404     if (w)
01405     {
01406         // have we entered a hole? Is the wall breaking down? Have we passed behind the end?
01407         if ( !w->IsDangerous( alpha, time ) )
01408             return false;
01409 
01410         // get time the wall was built
01411         // REAL builtTime = w->Time(alpha);
01412 
01413         //gCycleMovement *otherPlayer=w->CycleMovement();
01414         //if (otherPlayer==this && time < builtTime+2.5*GetTurnDelay() )
01415         //    return false;        // impossible to make such a small circle
01416         // no, not impossible, just moderately unlikely.
01417     }
01418 
01419     return true; // it is a real eWall.

Here is the call graph for this function:

Here is the caller graph for this function:

bool gCycleMovement::Turn ( REAL  dir  ) 

Turn left for positive argument, right for negative argument.

Parameters:
dir negative for left turns, positive for right turns
Returns:
true if the turning was successful

Definition at line 1432 of file gCycleMovement.cpp.

Referenced by gCycle::Act(), gAIPlayer::ActOnData(), gCycle::OnRemoveFromGame(), gAIPlayer::RightBeforeDeath(), gAIPlayer::Think(), Timestep(), and gJoystick::Turn().

01434 {
01435     if (dir>0)
01436         return Turn(1);
01437     else if (dir<0)
01438         return Turn(-1);
01439     else
01440         return false;

Here is the caller graph for this function:

bool gCycleMovement::Turn ( int  dir  ) 

Turn left for positive argument, right for negative argument.

Parameters:
dir +1 for right turns, -1 for left turns
Returns:
true if the turning was successful

Definition at line 1453 of file gCycleMovement.cpp.

References DoTurn().

01455 {
01456     return DoTurn( dir );

Here is the call graph for this function:

void gCycleMovement::MoveSafely ( const eCoord &  dest,
REAL  startTime,
REAL  endTime 
)

move without throwing exceptions on passing a wall

Parameters:
dest the destination position
startTime the start time of the movement
endTime the end time of the movement

Definition at line 4074 of file gCycleMovement.cpp.

References alive_, and eGameObject::Move().

Referenced by CopyFrom(), gCycleExtrapolator::CopyFrom(), gCycle::KillAt(), gCycle::PassEdge(), gCycle::ReadSync(), gCycle::SyncEnemy(), and gCycle::TimestepCore().

04076 {
04077     static bool recursing = false;
04078     if ( !recursing )
04079     {
04080         recursing = true;
04081         try
04082         {
04083             // try a regular move
04084             Move( dest, startTime, endTime );
04085         }
04086         catch( eDeath & death )
04087         {
04088             // and play dead if that doesn't work right
04089             short lastAlive = alive_;
04090             alive_ = 0;
04091             Move( dest, startTime, endTime );
04092             alive_ = lastAlive;
04093         }
04094     }
04095     else
04096     {
04097         // play dead if another safe move is already in process. Sometimes,
04098         // crossing a wall of a live cycle causes that cycle to be moved with
04099         // this function, and "killing" it temporarily avoids an endless
04100         // recursion in that case.
04101         short lastAlive = alive_;
04102         alive_ = 0;
04103         Move( dest, startTime, endTime );
04104         alive_ = lastAlive;
04105     }

Here is the call graph for this function:

Here is the caller graph for this function:

bool gCycleMovement::Timestep ( REAL  currentTime  )  [virtual]

advance to the given time

Parameters:
currentTime the time to simulate up to
Returns:
true if the cycle is to be deleted

Reimplemented from eNetGameObject.

Reimplemented in gCycle.

Definition at line 1960 of file gCycleMovement.cpp.

References acceleration, AccelerationDiscontinuity(), Alive(), gDestination::braking, braking, CalculateAcceleration(), CanMakeTurn(), clamp(), con, currentDestination, eGameObject::deathTime, destinationList, dirDrive, gDestination::direction, DistanceToDestination(), dt, eCoord, EPS, eGrid::GetDirection(), gDestination::GetGameTime(), GetMaxSpaceAhead(), GetNextTurn(), GetTurnDelay(), ePlayerNetID::GetUserName(), eGameObject::Grid(), gDestination::hasBeenUsed, IsDestinationUsed(), eNetGameObject::Lag(), lastDestination, eGameObject::lastTime, eGameObject::MaxSimulateAhead(), maxSpaceHit_, gDestination::messageID, nCLIENT, gDestination::next, nSERVER, nNetObject::Owner(), pendingTurns, eNetGameObject::Player(), eGameObject::pos, gDestination::position, REAL, refreshSpaceAhead_, RequestSync(), rubber, rubberSpeedFactor, sg_ArchiveReal(), sg_CommandTime, sg_noRedundantBrakeCommands, sg_packetMissTolerance, sg_rubberCycle, sg_RubberValues(), sg_timeTolerance, sg_UseAntiLagSliding(), sn_GetNetState(), SpeedMultiplier(), st_Breakpoint(), nVersionFeature::Supported(), TimestepCore(), ts, Turn(), eGrid::Turn(), gDestination::turns, turns, verletSpeed_, and windingNumberWrapped_.

Referenced by gCycle::Timestep().

01962 {
01963     // request regeneration of maximum space
01964     refreshSpaceAhead_ = true;
01965 
01966     // clear out dangerous info when we're done
01967     gMaxSpaceAheadHitInfoClearer hitInfoClearer( maxSpaceHit_ );
01968 
01969     // clamp stuff to finite values
01970     clamp( rubber, 0, sg_rubberCycle );
01971 
01972     // keep this cycle alive
01973     tJUST_CONTROLLED_PTR< gCycleMovement > keep( this->GetRefcount()>0 ? this : 0 );
01974 
01975     // don't make a fuss about negative timesteps
01976     if ( currentTime < lastTime )
01977         return TimestepCore( currentTime );
01978 
01979     // remove old destinations
01980     //REAL lag = 1;
01981     //if ( player )
01982     //    lag = player->ping;
01983     // REAL lagDistance = lag * Speed() * 10;
01984 
01985     while(destinationList && destinationList->hasBeenUsed && !IsDestinationUsed( destinationList ) )
01986         delete destinationList;
01987 
01988     // calculate timestep
01989     REAL dt = currentTime - lastTime;
01990 
01991     sg_ArchiveReal( dt, 9 );
01992 
01993     // if (currentTime > lastTime)
01994     {
01995         int timeout=10;
01996         bool forceTurn = false; // force turning at the next iteration
01997         bool overrideTurnDelay=false; // override the turn delay system, turn immediately
01998 
01999         // only simulate forward in time
02000         while (pendingTurns.empty() && currentDestination && timeout > 0 )
02001         {
02002             timeout --;
02003 
02004             // the distance to the next destination
02005             REAL dist_to_dest = DistanceToDestination( *currentDestination );
02006             sg_ArchiveReal( dist_to_dest, 9 );
02007 
02008             REAL ts=currentTime - lastTime;
02009             sg_ArchiveReal( ts, 9 );
02010 
02011             sg_ArchiveReal( verletSpeed_, 9 );
02012             sg_ArchiveReal( acceleration, 9 );
02013 
02014             // our speed
02015             REAL avgspeed=verletSpeed_;
02016             CalculateAcceleration();
02017             if (acceleration > 0)
02018                 avgspeed += acceleration * SpeedMultiplier() * ts * .5;
02019 
02020             // will rubber slow the cycle down to a crawl, so that the command time will be
02021             // a better indication when to turn than the position?
02022             bool rubberActive = false;
02023 
02024             // check if the path to the destination is clear for the next timesteps
02025             sg_ArchiveReal( rubberSpeedFactor, 9 );
02026             REAL distToWall=1E+30;
02027             if ( rubberSpeedFactor < .999 )
02028             {
02029                 // take rubber activity into account
02030                 rubberActive = true;
02031                 avgspeed *= rubberSpeedFactor;
02032                 if ( avgspeed < EPS )
02033                     avgspeed = EPS;
02034 
02035                 sg_ArchiveReal( avgspeed, 9 );
02036 
02037                 // don't drive into a wall, turn before getting too close
02038                 REAL lookahead = ts * avgspeed * 2;
02039 
02040                 REAL dist_to_wall = GetMaxSpaceAhead( lookahead );
02041 
02042                 if ( dist_to_dest > dist_to_wall )
02043                     dist_to_dest = dist_to_wall;
02044             }
02045 
02046             static bool breakp = false;
02047 
02048             // the time left until the turn happened on the client
02049             // REAL timeLeft = currentDestination->GetGameTime() - lastTime;
02050 
02051             // the earliest and latest allowed time to turn
02052             REAL turnTime = currentDestination->GetGameTime();
02053             REAL earliestTurnTime = turnTime - sg_timeTolerance - 100;
02054             REAL latestTurnTime   = turnTime + sg_timeTolerance;
02055 
02056             // if rubber is active and anti lag sliding code should be enabled,
02057             // then allow no too early or late turns
02058             if ( sg_UseAntiLagSliding( this ) )
02059             {
02060                 if ( rubberActive )
02061                 {
02062                     // smoothly make the allowed time interval smaller with increased rubber use
02063                     earliestTurnTime = turnTime - sg_timeTolerance * rubberSpeedFactor;
02064                     latestTurnTime = turnTime + sg_timeTolerance * rubberSpeedFactor;
02065 
02066                     // clamp latest turn time so we don't drive into the wall
02067                     if ( verletSpeed_ > 0 )
02068                     {
02069                         REAL maxRubber, effectiveness;
02070                         sg_RubberValues( Player(), verletSpeed_, maxRubber, effectiveness );
02071 
02072                         // see when we'll die (be a little careful, the .9 is a fudge factor)
02073                         REAL rubberLeft = (maxRubber - rubber)*.9;
02074                         REAL stepLeft   = rubberLeft + distToWall;
02075                         REAL timeLeft   = stepLeft/verletSpeed_;
02076                         REAL deathTime  = lastTime + timeLeft;
02077 
02078                         // can't do a thing if the player wants to die
02079                         if ( deathTime < turnTime )
02080                             deathTime = turnTime;
02081 
02082                         // clamp latest possible time
02083                         if ( latestTurnTime > deathTime )
02084                             latestTurnTime = deathTime;
02085                     }
02086                 }
02087                 else
02088                 {
02089                     // just clamp the latest turn time
02090                     earliestTurnTime = turnTime - sg_timeTolerance;
02091                 }
02092             }
02093 
02094             sg_ArchiveReal( dist_to_dest, 9 );
02095 
02096             REAL simulateAhead = MaxSimulateAhead();
02097 
02098             if ( dist_to_dest > ( ts + simulateAhead ) * avgspeed && currentTime < latestTurnTime )
02099                 break; // no need to worry; we won't reach the next destination
02100 
02101             if ( currentTime < earliestTurnTime && sg_CommandTime.Supported( Owner() ) )
02102                 break; // the turn is too far in the future
02103 
02104             // if ( currentTime < turnTime + EPS )
02105             //    simulateAhead = 0;
02106 
02107             // determine whether to turn left or right (coping with weird axis settings)
02108             int turnTo=0;
02109             // and whether between the last and next destination, there was one missing that
02110             // we didn't receive.
02111             bool missed=false;
02112 
02113             {
02114                 REAL t = currentDestination->direction * dirDrive;
02115                 bool turn = true;
02116 
02117                 missed  = (fabs(t)<.01);
02118                 if (int(braking) != int(currentDestination->braking))
02119                 {
02120                     turn = false;
02121                     missed=!missed;
02122                 }
02123 
02124                 // detect false misses: if the last destination's message ID is just
02125                 // one below the current destination's message ID, it's a fake
02126                 if ( missed && lastDestination && lastDestination->messageID == currentDestination->messageID-1 )
02127                 {
02128                     missed = false;
02129                     if ( ( dirDrive - currentDestination->direction ).NormSquared() < EPS )
02130                     {
02131                         turn = false;
02132                         turnTo = 0;
02133                     }
02134                 }
02135 
02136                 // if the destination is dead ahead, it can't be a fake, either
02137                 if ( missed && sn_GetNetState() == nSERVER && !sg_noRedundantBrakeCommands.Supported( Owner() ) )
02138                 {
02139                     // calculate difference in expected position at the destination's time and the transmitted position
02140                     REAL timeToDest = currentDestination->GetGameTime() - lastTime;
02141                     eCoord posDelta = pos + dirDrive * ( timeToDest * ( verletSpeed_ + .5f * acceleration * timeToDest ) ) - currentDestination->position;
02142                     REAL deltaParallel = eCoord::F( posDelta, dirDrive );
02143                     REAL deltaOrthogonal = posDelta * dirDrive;
02144 
02145                     // if it's small, that's not a miss
02146                     REAL tolerance = verletSpeed_ * GetTurnDelay();
02147                     if ( fabs(deltaParallel) < tolerance && fabs(deltaOrthogonal) < tolerance * .5 )
02148                     {
02149                         missed = false;
02150                         if ( ( dirDrive - currentDestination->direction ).NormSquared() < EPS )
02151                         {
02152                             turn = false;
02153                         }
02154                     }
02155                 }
02156 
02157                 // see if we missed a turn by, say, just counting?
02158                 if ( turns < currentDestination->turns - 1 )
02159                     missed = true;
02160 
02161                 if ( turn )
02162                 {
02163                     // the direction we need to drive in
02164                     // see which direction we drive into after a left or right turn
02165                     int wn = windingNumberWrapped_;
02166                     Grid()->Turn(wn, 1);
02167                     eCoord dirPlus = Grid()->GetDirection(wn);
02168                     wn = windingNumberWrapped_;
02169                     Grid()->Turn(wn, -1);
02170                     eCoord dirMinus = Grid()->GetDirection(wn);
02171 
02172                     if ( missed )
02173                     {
02174                         eCoord dirTurn = (currentDestination->position - pos);
02175 
02176                         // see witch of the alternatives comes closer to the desired direction
02177                         turnTo = ( ( fabs( dirMinus * dirTurn ) - .1 * eCoord::F( dirMinus, dirTurn ) )/dirTurn.NormSquared() < ( fabs( dirPlus * dirTurn ) - .1 * eCoord::F( dirPlus, dirTurn ) )/dirTurn.NormSquared() ) ? -1 : +1;
02178                     }
02179                     else
02180                     {
02181                         // just see which axis gets closer
02182                         eCoord dirTurn = currentDestination->direction;
02183 
02184                         turnTo = ( ( dirMinus - dirTurn ).NormSquared() < ( dirPlus - dirTurn ).NormSquared() ) ? -1 : +1;
02185 
02186                     }
02187                 }
02188             }
02189 
02190             // can we turn already?
02191             bool canTurn = ( turnTo == 0 || CanMakeTurn(turnTo) || overrideTurnDelay );
02192 
02193             if ( lastTime >= earliestTurnTime && canTurn && ( forceTurn || dist_to_dest < 0.01 || timeout <= 0 || lastTime >= latestTurnTime ) ){
02194                 forceTurn = false;
02195 
02196 #ifdef DEBUG
02197                 if ( turnTo != 0 )
02198                 {
02199                     static REAL checkFactor = .9f;
02200                     gTurnDelayOverride check( checkFactor );
02201                     if ( !CanMakeTurn( turnTo ) )
02202                     {
02203                         con << "Early turn!\n";
02204                         st_Breakpoint();
02205                     }
02206                 }
02207 #endif
02208 
02209 
02210                 // con << timeLeft << ", " << earlyTurnTolerance << ", " << rubberActive << ", " << dist_to_dest << "\n";
02211 
02212                 // the destination is very close or we gave up. Now is the time to turn towards
02213                 // it or turn to the direction it gives us
02214 
02215                 // bring us to the exact location to avoid lag sliding due to
02216                 // disagreement between client and server.
02217                 // but only if we are reasonably close ( don't want cheating )
02218                 // and use a correct move that kills us if we cross a wall.
02219 
02220                 /*
02221                          if ( dist_to_dest < .1 && dist_to_dest > -.1 )
02222                          {
02223                              Move( pos + dirDrive * dist_to_dest, currentTime, currentTime );
02224                          }
02225                 #ifdef DEBUG
02226                          else
02227                          {
02228                              if ( breakp )
02229                              {
02230                                  int x;
02231                                  x = 0;
02232                              }
02233                              con << "gCycle::Timestep: Could not completely reach destination.\n";
02234                              breakp = true;
02235                          }
02236                 #endif                  
02237                 */
02238 
02239                 // con << "Turn: " << lastTime << ", " << dist_to_dest << ", " << currentDestination->position << ", " << pos << "\n";
02240 
02241                 //eDebugLine::SetTimeout(2);
02242                 //eDebugLine::SetColor( 0,1,1 );
02243                 //eDebugLine::Draw( currentDestination->position, 0, currentDestination->position, 8 );
02244                 //eDebugLine::SetColor( 0,0,1 );
02245                 //eDebugLine::Draw( pos, 0, pos, 8 );
02246 
02247                 bool used = false; // flag indicating whether the current destination has been used
02248 
02249                 if (!missed){ // then we did not miss a destination
02250                     used = true;
02251 
02252                     if (turnTo != 0)
02253                     {
02254 #ifdef DEBUG
02255 #ifdef DEDICATED
02256                         eCoord slide = this->pos - currentDestination->position;
02257                         if ( Player() && slide.NormSquared() > .01 )
02258                             con << "Lag slide for " << Player()->GetUserName() << ": "  << slide << ", rubberSpeedFactor " << rubberSpeedFactor << "\n";
02259 #endif
02260 #endif
02261                         gTurnDelayOverride override( overrideTurnDelay );
02262                         Turn(turnTo);
02263                     }
02264                     else{
02265                         AccelerationDiscontinuity();
02266                         braking = currentDestination->braking;
02267                         if (sn_GetNetState()!=nCLIENT)
02268                             RequestSync();
02269                     }
02270 
02271                     /*
02272                       con << "turning alon " << currentDestination->position << "," 
02273                       << currentDestination->direction << "," 
02274                       << currentDestination->distance << "\n";
02275                     */
02276                 }
02277                 else
02278                 {
02279 
02280                     // Uh oh. Turn commands are missing. We should wait as long as possible, it must
02281                     // already be on its way.
02282                     if ( lastTime > currentTime - Lag()*sg_packetMissTolerance )
02283                         return !Alive();
02284 
02285                     if ( turns >= currentDestination->turns - 1 )
02286                     {
02287                         // OK, we missed exactly one turn. Don't panic. Just turn
02288                         // towards the destination:
02289                         REAL side = (currentDestination->position - pos) * dirDrive;
02290                         if ( fabs(side)>verletSpeed_ * GetTurnDelay() * .2 )
02291                         {
02292                             gTurnDelayOverride override( overrideTurnDelay );
02293                             Turn(turnTo);
02294                         }
02295                         else
02296                             used = true;
02297                     }
02298                     /*
02299                       con << "turning to   " << currentDestination->position << "," 
02300                       << currentDestination->direction << "," 
02301                       << currentDestination->distance << "\n";
02302                     */
02303 
02304                 }
02305 
02306                 overrideTurnDelay = false;
02307 
02308                 if ( used )
02309                 {
02310                     // only the server marks destinations as used; the client has to reuse them sometimes.
02311                     currentDestination->hasBeenUsed = (sn_GetNetState()!=nCLIENT);
02312                     lastDestination = currentDestination;
02313 
02314                     // advance
02315                     currentDestination = currentDestination->next;
02316                 }
02317 
02318 
02319                 while (currentDestination && currentDestination->hasBeenUsed)
02320                 {
02321                     breakp = false;
02322                     currentDestination = currentDestination->next;
02323                 }
02324             }
02325             else
02326             {
02327                 // ok, the dest is right ahead, but not close enough.
02328                 // how long does it take at least
02329                 // (therefore the strange average speed) to get there?
02330                 sg_ArchiveReal( avgspeed, 9 );
02331                 REAL tsTodo = dist_to_dest/avgspeed;
02332                 /*
02333                          if ( tsTodo > timeLeft )
02334                          {
02335                              tsTodo = timeLeft;
02336                          }
02337                 */
02338                 sg_ArchiveReal( tsTodo, 9 );
02339 
02340                 // we can't turn now, simulate until we can
02341                 if ( !canTurn )
02342                 {
02343                     REAL nextTurn = GetNextTurn(turnTo);
02344                     REAL turnStep = nextTurn - lastTime;
02345 
02346                     // clamp timestep values
02347                     if ( turnTime < nextTurn )
02348                         turnTime = nextTurn;
02349                     if ( earliestTurnTime < nextTurn )
02350                         earliestTurnTime = nextTurn;
02351                     if ( latestTurnTime < nextTurn )
02352                         latestTurnTime = nextTurn;
02353 
02354                     if ( currentTime - lastTime > turnStep )
02355                     {
02356                         tsTodo = turnStep;
02357 
02358                         // if we can simulate to the turn in the next step, do so, overriding
02359                         // the turn delay then.
02360                         if ( tsTodo < ts + simulateAhead && tsTodo > 0 )
02361                         {
02362                             overrideTurnDelay = true;
02363                         }
02364                     }
02365                     else
02366                     {
02367                         // not enough time to simulate to turn possibility; skip out of loop
02368                         break;
02369                     }
02370                 }
02371                 else
02372                 {
02373                     sg_ArchiveReal( tsTodo, 9 );
02374                     // don't turn too late
02375                     REAL maxts = latestTurnTime - lastTime;
02376                     sg_ArchiveReal( maxts, 9 );
02377                     if ( tsTodo > maxts )
02378                     {
02379                         // force turn on next iteration, we'll be there
02380                         forceTurn = true;
02381                         tsTodo = maxts;
02382                     }
02383 
02384                     // don't turn too early
02385                     REAL mints = earliestTurnTime - lastTime;
02386                     // sg_ArchiveReal( mints, 9 );
02387                     if ( tsTodo < mints )
02388                     {
02389                         tsTodo = mints;
02390                     }
02391                 }
02392 
02393                 if ( tsTodo < 0 )
02394                 {
02395                     // should never happen
02396                     st_Breakpoint();
02397                     return !Alive();
02398                 }
02399                 if ( tsTodo > ts + simulateAhead )
02400                 {
02401                     tsTodo = ts + simulateAhead ;
02402                     forceTurn = false;
02403 
02404                     // quit from here if there is nothing to do
02405                     if ( tsTodo <= EPS )
02406                         break;
02407                 }
02408         #ifdef DEBUG
02409                 if ( tsTodo < 0 )
02410                     con << "Negative timestep!\n";
02411         #endif
02412                 sg_ArchiveReal( tsTodo, 9 );
02413 
02414                 // core simulation
02415                 if ( tsTodo > EPS )
02416                 {
02417                     REAL lastTimeBack = lastTime;
02418                     bool ret = TimestepCore( lastTime + tsTodo, false );
02419                     if ( lastTime <= lastTimeBack )
02420                         return ret;
02421                 }
02422                 else
02423                 {
02424                     // already nothing to do, turn on next iteration
02425                     forceTurn = true;
02426                 }
02427             }
02428         }
02429     }
02430 
02431     // simulate exactly to the time of the next turn if it is in reach
02432     if ( !pendingTurns.empty())
02433     {
02434         REAL nextTurn = GetNextTurn(pendingTurns.front());
02435         if(currentTime>nextTurn) {
02436             if ( nextTurn > lastTime )
02437                 TimestepCore( nextTurn );
02438 
02439             //con << "Executing delayed turn at time " << lastTime << "\n";
02440             Turn(pendingTurns.front());
02441             pendingTurns.pop_front();
02442         }
02443     }
02444 
02445     // do the rest of the timestep
02446     bool ret = false;
02447     if ( currentTime > lastTime )
02448         ret = TimestepCore( currentTime );
02449 
02450     return ret;

Here is the call graph for this function:

Here is the caller graph for this function:

REAL gCycleMovement::NextInterestingTime ( void   )  const [virtual]

the next time something interesting is going to happen with this object

Returns:

Reimplemented from eGameObject.

Definition at line 4121 of file gCycleMovement.cpp.

References currentDestination, gDestination::GetGameTime(), eGameObject::LastTime(), gDestination::next, and REAL.

04123 {
04124     // default to the last time
04125     REAL ret = LastTime();
04126 
04127     // look for a later destination
04128     gDestination * run = currentDestination;
04129     while ( run )
04130     {
04131         REAL time = run->GetGameTime();
04132         if ( time > ret )
04133             ret = time;
04134         run = run->next;
04135     }
04136 
04137     return ret;

Here is the call graph for this function:

void gCycleMovement::AddRef ( void   )  [virtual]

increase reference count

Reimplemented from eNetGameObject.

Definition at line 2461 of file gCycleMovement.cpp.

References eNetGameObject::AddRef(), Alive(), nNetObject::GetRefcount(), eGameObject::Kill(), and sg_cycleMaxRefCount.

02463 {
02464     eNetGameObject::AddRef();
02465     if ( GetRefcount() > sg_cycleMaxRefCount && Alive() )
02466     {
02467         // during the kill, further refcounts will be added, so we need to pump
02468         // up the limit
02469         int backup = sg_cycleMaxRefCount;
02470         sg_cycleMaxRefCount += 100;
02471         Kill();
02472         sg_cycleMaxRefCount = backup;
02473     }

Here is the call graph for this function:

void gCycleMovement::OnRemoveFromGame (  )  [virtual]

called on RemoveFromGame(). Call base class implementation, too, in your implementation. Must keep the object alive.

Reimplemented from eGameObject.

Reimplemented in gCycle.

Definition at line 2578 of file gCycleMovement.cpp.

References maxSpaceHit_, NULL, and eGameObject::OnRemoveFromGame().

Referenced by gCycle::OnRemoveFromGame().

02580 {
02581     delete maxSpaceHit_;
02582     maxSpaceHit_ = NULL;
02583 
02584     eNetGameObject::OnRemoveFromGame();

Here is the call graph for this function:

Here is the caller graph for this function:

void gCycleMovement::RequestSync ( bool  ack = true  ) 

request a sync

Reimplemented from nNetObject.

Definition at line 2554 of file gCycleMovement.cpp.

References Alive(), and nNetObject::RequestSync().

Referenced by gCycle::Act(), gCycle::Die(), gCycle::DoTurn(), gCycle::Kill(), gCycle::MyInitAfterCreation(), gCycle::OnRemoveFromGame(), gCycle::RequestSyncAll(), gCycle::RequestSyncOwner(), Timestep(), and gCycle::TimestepCore().

02556 {
02557     // no more syncs when you're dead
02558     if ( !Alive() )
02559     { 
02560        return;
02561     }
02562 
02563     // delegate
02564     eNetGameObject::RequestSync( ack );

Here is the call graph for this function:

Here is the caller graph for this function:

void gCycleMovement::RequestSync ( int  user,
bool  ack 
)

only for a single user

Reimplemented from nNetObject.

Definition at line 2566 of file gCycleMovement.cpp.

References Alive(), and nNetObject::RequestSync().

02568 {
02569     // no more syncs when you're dead
02570     if ( !Alive() )
02571     {
02572         return;
02573     }
02574 
02575     // delegate
02576     eNetGameObject::RequestSync( user, ack );

Here is the call graph for this function:

void gCycleMovement::CopyFrom ( const gCycleMovement other  )  [protected]

copies relevant info from other cylce

Parameters:
other the cycle to copy everything from

Reimplemented in gCycleExtrapolator.

Definition at line 2596 of file gCycleMovement.cpp.

References acceleration, brakingReservoir, con, gCycleExtrapolator::CopyFrom(), eGameObject::currentFace, eGameObject::dir, dirDrive, distance, eCoord, GetNextTurn(), GetTurnDelay(), eGameObject::LastTime(), eGameObject::lastTime, lastTimestep_, eGameObject::pos, eGameObject::Position(), REAL, rubber, rubberMalus, tASSERT, eGameObject::team, eGameObject::TimestepThis(), tNEW, turns, verletSpeed_, windingNumber_, and windingNumberWrapped_.

Referenced by gCycleExtrapolator::CopyFrom(), operator=(), and gCycle::SyncFromExtrapolator().

02598 {
02599     // calculate position update
02600     eCoord posUpdate = other.Position() - this->Position();
02601 
02602 #ifdef DEBUG_X
02603     // only update direction if the positions are out of sync
02604     REAL lag = 1;
02605     if ( player )
02606         lag = player->ping;
02607 
02608     REAL tol = this->speed * lag;
02609     if ( posUpdate.NormSquared() > tol*tol )// && eCoord::F( dirDrive, other.dirDrive ) < .5 )
02610     {
02611         con << "Out of sync!\n";
02612         //              dir                     = other.Direction();
02613 
02614         // get second opinion
02615         tJUST_CONTROLLED_PTR<gCycleExtrapolator> extrapolator = tNEW( gCycleExtrapolator )(grid, pos, dir );
02616         gCycleExtrapolator& secondOpinion = *extrapolator;
02617         secondOpinion.CopyFrom( sg_usedMessage, *this );
02618         eGameObject::TimestepThis( other.lastTime, &secondOpinion );
02619     }
02620 #endif
02621 
02622     dirDrive            = other.dirDrive;
02623 
02624     // transfer position and time
02625     currentFace = other.currentFace;
02626     pos = other.Position();
02627     lastTime = other.LastTime();
02628     // Move( other.Position(), LastTime(), other.LastTime() );
02629     // Move( other.Position() + other.Direction() * ( ( lastTime - other.LastTime() ) * other.Speed() ), LastTime(), other.LastTime() );
02630 
02631     // std::cout << "copy: " << brakingReservoir << ":" << braking << "\n";
02632 
02633     // transfer additional data
02634     team            = other.team;
02635     distance        = other.distance;
02636     lastTimestep_   = other.lastTimestep_;
02637     verletSpeed_    = other.verletSpeed_;
02638     acceleration    = other.acceleration;
02639     rubber              = other.rubber;
02640     rubberMalus     = other.rubberMalus;
02641     brakingReservoir= other.brakingReservoir;
02642     windingNumber_          = other.windingNumber_;
02643     windingNumberWrapped_   = other.windingNumberWrapped_;
02644 
02645     tASSERT(finite(distance));
02646 
02647     // std::cout << "copy: " << brakingReservoir << ":" << braking << "\n";
02648 
02649 #ifdef DEBUG_X
02650     if ( turns != other.turns )
02651     {
02652         con << "Client/Server turn mismatch:" << turns << " != " << other.turns << "\n";
02653     }
02654 #endif
02655 
02656     // update number of turns if the player is not turning wildly
02657     REAL right = GetNextTurn(1);
02658     REAL left  = GetNextTurn(-1);
02659     if ( lastTime > (right > left ? right : left) + 2 * GetTurnDelay() )
02660         turns                   = other.turns;

Here is the call graph for this function:

Here is the caller graph for this function:

void gCycleMovement::CopyFrom ( const SyncData sync,
const gCycleMovement other 
) [protected]

copies relevant info from sync data and everything else from other cycle

Parameters:
sync the network sync data to copy the most important data from
other the cycle to copy the rest of the information from

Definition at line 2675 of file gCycleMovement.cpp.

References acceleration, gDestination::braking, gCycleMovement::SyncData::braking, braking, gCycleMovement::SyncData::brakingReservoir, brakingReservoir, currentDestination, eGameObject::currentFace, destinationList, gCycleMovement::SyncData::dir, eGameObject::dir, dirDrive, gDestination::direction, gCycleMovement::SyncData::distance, distance, GetDestinationBefore(), eGameObject::Grid(), lastTimestep_, lastTurnTimeLeft_, lastTurnTimeRight_, MoveSafely(), nCLIENT, gDestination::next, eNetGameObject::Player(), gCycleMovement::SyncData::pos, gCycleMovement::SyncData::rubber, rubber, gCycleMovement::SyncData::rubberMalus, rubberMalus, eNetGameObject::SetPlayer(), SetWindingNumberWrapped(), sg_sendCorrectLastTurn, sn_GetNetState(), gCycleMovement::SyncData::speed, nVersionFeature::Supported(), tASSERT, gCycleMovement::SyncData::time, gCycleMovement::SyncData::turns, turns, and verletSpeed_.

02677 {
02678     // fetch values from sync
02679     dir = dirDrive      = sync.dir;
02680     lastTimestep_   = 0;
02681     verletSpeed_        = sync.speed;
02682     rubber                      = sync.rubber;
02683     rubberMalus     = sync.rubberMalus;
02684     braking                     = sync.braking;
02685     distance            = sync.distance;
02686     turns                       = sync.turns;
02687     brakingReservoir= sync.brakingReservoir;
02688     // std::cout << "fromsync: " << brakingReservoir << ":" << braking << "\n";
02689 
02690     tASSERT(finite(distance));
02691 
02692     // reset winding number and acceleration
02693     this->SetWindingNumberWrapped( Grid()->DirectionWinding(dirDrive) );
02694     acceleration        = 0;
02695 
02696     // fetch values from other
02697     // rubber = other.rubber;
02698     SetPlayer( other.Player() );
02699     currentFace         = other.currentFace;
02700 
02701     {
02702         //this->currentDestination = other.destinationList;
02703         //while ( currentDestination && currentDestination->messageID != sync.messageID )
02704         //    currentDestination = currentDestination->next;
02705 
02706         // deterimine last passed destination by the message ID
02707         this->currentDestination = GetDestinationBefore( sync, other.destinationList );
02708 
02709         bool trustDestination = true;
02710         if ( currentDestination && sn_GetNetState() == nCLIENT && !sg_sendCorrectLastTurn.Supported(0) )
02711         {
02712             // the server may send wrong information in the rare case that
02713             // our last turn command was not promptly executed. Sanity check:
02714             // if the relevant information from the alleged last destination
02715             // differs from the current state, it is already the next destination.
02716             if ( ( currentDestination->braking != (bool)braking ) || fabs( currentDestination->direction * dirDrive ) > .01 )
02717                 trustDestination = false;
02718         }
02719 
02720         // we only need the next one
02721         if ( trustDestination && currentDestination )
02722             currentDestination = currentDestination->next;
02723     }
02724 
02725     // let extrapolator find its face ( and set position and time )
02726     MoveSafely( sync.pos, sync.time, sync.time );
02727 
02728     // set last turn
02729     lastTurnTimeRight_ = lastTurnTimeLeft_ = -100;

Here is the call graph for this function:

void gCycleMovement::InitAfterCreation ( void   )  [protected, virtual]

shared initialization routine

Reimplemented from eNetGameObject.

Reimplemented in gCycle.

Definition at line 2740 of file gCycleMovement.cpp.

References eNetGameObject::InitAfterCreation(), MyInitAfterCreation(), st_Breakpoint(), and verletSpeed_.

Referenced by gCycle::InitAfterCreation().

02742 {
02743 #ifdef DEBUG
02744     if (!finite(verletSpeed_))
02745         st_Breakpoint();
02746 #endif
02747     eNetGameObject::InitAfterCreation();
02748 #ifdef DEBUG
02749     if (!finite(verletSpeed_))
02750         st_Breakpoint();
02751 #endif
02752     MyInitAfterCreation();

Here is the call graph for this function:

Here is the caller graph for this function:

void gCycleMovement::AccelerationDiscontinuity (  )  [protected, virtual]

call when you know the acceleration makes a sharp jump now

Definition at line 2792 of file gCycleMovement.cpp.

References lastTimestep_, Speed(), and verletSpeed_.

Referenced by gCycle::Act(), DoTurn(), gCycle::ReadSync(), Timestep(), and TimestepCore().

02794 {
02795     // make fake 0 timestep
02796     verletSpeed_ = Speed();
02797     lastTimestep_ = 0;

Here is the call graph for this function:

Here is the caller graph for this function:

void gCycleMovement::CalculateAcceleration (  )  [protected, virtual]

calculate acceleration to apply later

Definition at line 2808 of file gCycleMovement.cpp.

References acceleration, gEnemyInfluence::AddSensor(), blocks(), brakeUsage, braking, brakingReservoir, d, eSensor::detect(), dirDrive, eCoord, enemyInfluence, good(), gSENSOR_ENEMY, gSENSOR_NONE, gSENSOR_RIM, gSENSOR_SELF, gSENSOR_TEAMMATE, eSensor::hit, nCLIENT, eGameObject::pos, REAL, rubberUsage, sg_accelerationCycle, sg_accelerationCycleEnemy, sg_accelerationCycleOffs, sg_accelerationCycleRim, sg_accelerationCycleSelf, sg_accelerationCycleSlingshot, sg_accelerationCycleTeam, sg_accelerationCycleTunnel, sg_ArchiveReal(), sg_brakeCycle, sg_correctAccelerationScaling, sg_cycleBrakeDeplete, sg_cycleBrakeRefill, sg_cycleWidth, sg_cycleWidthRubberMax, sg_cycleWidthRubberMin, sg_cycleWidthSide, sg_DropTempWall(), sg_nearCycle, sg_speedCycle, sg_speedCycleDecayAbove, sg_speedCycleDecayBelow, sn_GetNetState(), SpeedMultiplier(), nVersionFeature::Supported(), tASSERT, totalZoneAcceleration, gSensor::type, and verletSpeed_.

Referenced by Timestep(), and TimestepCore().

02810 {
02811     // reset usage variables
02812     brakeUsage = 0.0f;
02813     rubberUsage = 0.0f;
02814 
02815     // calculate acceleration
02816     acceleration=0;
02817 
02818     // brake: it's only available since this version...
02819     static nVersionFeature brakeDepletion(2);
02820 
02821     // and servers starting from this version disable it my modifying config items
02822     static nVersionFeature brakeDepletionHandledWithConfig(10);
02823 
02824     // simply use the configured brake always on the server
02825     // and on the client if the server should have disabled it, but does not.
02826 
02827     if ( sn_GetNetState() != nCLIENT || brakeDepletion.Supported() || brakeDepletionHandledWithConfig.Supported(0) )
02828     {
02829         if(braking)
02830         {
02831             if ( brakingReservoir > 0.0 )
02832             {
02833                 brakeUsage = sg_cycleBrakeDeplete;
02834                 acceleration-=sg_brakeCycle * SpeedMultiplier();
02835             }
02836             else
02837                 brakingReservoir = 0.0f;
02838         }
02839         else
02840         {
02841             if ( brakingReservoir < 1.0 )
02842             {
02843                 brakeUsage = -sg_cycleBrakeRefill;
02844             }
02845             else
02846                 brakingReservoir = 1.0f;
02847         }
02848     }
02849     else
02850     {
02851         if(braking)
02852         {
02853             acceleration-=sg_brakeCycle * SpeedMultiplier();
02854         }
02855     }
02856 
02857     sg_ArchiveReal( acceleration, 9 );
02858 
02859     REAL baseSpeed = sg_speedCycle * SpeedMultiplier();
02860     if ( verletSpeed_ <= ( sg_correctAccelerationScaling.Supported() ? baseSpeed : sg_speedCycle ) )
02861         acceleration+=( baseSpeed - verletSpeed_) * sg_speedCycleDecayBelow;
02862     else
02863         acceleration+=( baseSpeed - verletSpeed_) * sg_speedCycleDecayAbove;
02864 
02865     tASSERT( good( acceleration ) );
02866     sg_ArchiveReal( acceleration, 9 );
02867 
02868     // sense near wall behind us, accelerate more
02869     REAL totalWallAcceleration = 0; // total acceleration by walls
02870     REAL tunnelWidth           = 0; // with of the tunnel the cycle is in
02871     REAL sideWidth             = sg_cycleWidthSide * 2; // minimal distance to wall
02872     bool slingshot  = true;         // flag indicating whether the cycle is between two walls
02873     bool oneOwnWall = false;        // flag indicating whether one of the walls is your own
02874     for(int d=1;d>=-1;d-=2){
02875         // the direction to cast the acceleration rays in
02876         eCoord dirCast = dirDrive.Turn(-1,d);
02877         gSensor rear(this,pos,dirCast);
02878         rear.detect(sg_nearCycle);
02879 
02880         enemyInfluence.AddSensor( rear, 0, this );
02881 
02882         if (rear.ehit && rear.hit < sg_cycleWidth + .1f )
02883             blocks(rear, this, -d);
02884 
02885         if ( 0 != rear.ehit )
02886         {
02887             sg_ArchiveReal( rear.hit, 9 );
02888 
02889             // update the minimal wall distance
02890             if ( sideWidth > rear.hit )
02891                 sideWidth = rear.hit;
02892 
02893             // drop walls that are grinded
02894             if ( rear.hit < verletSpeed_ * .01 )
02895                 ::sg_DropTempWall( dirCast, rear );
02896 
02897             // see if the wall is parallel to the driving direction, only then should it add speed
02898             eCoord wallVec = rear.ehit->Vec();
02899             if ( fabs( eCoord::F( wallVec, dirDrive  ) ) > .9 * dirDrive.NormSquared() )
02900             {
02901                 // enemyInfluence.AddSensor( rear, 1 );
02902                 REAL wallAcceleration=SpeedMultiplier() * sg_accelerationCycle * ((1/(rear.hit+sg_accelerationCycleOffs))
02903                                       -(1/(sg_nearCycle+sg_accelerationCycleOffs)));
02904 
02905                 tunnelWidth += rear.hit;
02906 
02907                 // apply modificators
02908                 switch (rear.type)
02909                 {
02910                 case gSENSOR_SELF:
02911                     wallAcceleration *= sg_accelerationCycleSelf;
02912                     oneOwnWall = true;
02913                     break;
02914                 case gSENSOR_TEAMMATE:
02915                     wallAcceleration *= sg_accelerationCycleTeam;
02916                     break;
02917                 case gSENSOR_ENEMY:
02918                     wallAcceleration *= sg_accelerationCycleEnemy;
02919                     break;
02920                 case gSENSOR_RIM:
02921                     wallAcceleration *= sg_accelerationCycleRim;
02922                     break;
02923                 case gSENSOR_NONE:
02924                     wallAcceleration = 0;
02925                     slingshot = false;
02926                     break;
02927 
02928                 }
02929 
02930                 sg_ArchiveReal( wallAcceleration, 9 );
02931                 totalWallAcceleration += wallAcceleration;
02932             }
02933             else
02934             {
02935                 slingshot = false;
02936             }
02937         }
02938         else
02939         {
02940             slingshot = false;
02941         }
02942 
02943         sg_ArchiveReal( totalWallAcceleration, 9 );
02944     }
02945 
02946     // kill cycle if it is inside a too narrow channel
02947     if ( slingshot && tunnelWidth < sg_cycleWidth || sideWidth < sg_cycleWidthSide )
02948     {
02949         tunnelWidth = 0;
02950         REAL sideWidth = sg_cycleWidthSide * 2;
02951 
02952         // check again with sensors to the front, both sensor pairs need
02953         // to see a narrow tunnel
02954         for(int d=1;d>=-1;d-=2)
02955         {
02956             // the direction to cast the acceleration rays in
02957             eCoord dirCast = dirDrive.Turn(1,d);
02958             gSensor front(this,pos,dirCast);
02959             front.detect(sg_nearCycle);
02960 
02961             if ( front.ehit && front.ehit->Other() )
02962             {
02963                 sg_ArchiveReal( front.hit, 9 );
02964 
02965                 // update the minimal wall distance
02966                 if ( sideWidth > front.hit )
02967                     sideWidth = front.hit;
02968 
02969                 tunnelWidth += front.hit;
02970             }
02971             else
02972             {
02973                 tunnelWidth += sg_cycleWidth;
02974             }
02975         }
02976 
02977         if ( tunnelWidth < sg_cycleWidth || sideWidth < sg_cycleWidthSide )
02978         {
02979             // determine the space available measured in the space allowed
02980             REAL available1 = 1;
02981             REAL available2 = 1;
02982             if ( sg_cycleWidth > 0 )
02983                 available1 = tunnelWidth/sg_cycleWidth;
02984             if ( sg_cycleWidthSide > 0 )
02985                 available2 = sideWidth/sg_cycleWidthSide;
02986             REAL available = available1 < available2 ? available1 : available2;
02987 
02988             // get rubber values
02989             // REAL rubberGranted, rubberEffectiveness;
02990             // sg_RubberValues( player, verletSpeed_, rubberGranted, rubberEffectiveness );
02991 
02992             // calculate rubber usage from squeezing
02993             rubberUsage = sg_cycleWidthRubberMax + ( sg_cycleWidthRubberMin - sg_cycleWidthRubberMax ) * available;
02994         }
02995     }
02996 
02997     // apply slingshot/tunnel multiplier
02998     if ( slingshot )
02999     {
03000         if ( oneOwnWall )
03001             totalWallAcceleration *= sg_accelerationCycleSlingshot;
03002         else
03003             totalWallAcceleration *= sg_accelerationCycleTunnel;
03004     }
03005 
03006     // apply wall acceleration
03007     acceleration += totalWallAcceleration;
03008     acceleration += totalZoneAcceleration;
03009     totalZoneAcceleration = 0.0; // This comes from external influence and should be applied only once per Timestep
03010 
03011     tASSERT( good( acceleration ) );
03012     sg_ArchiveReal( acceleration, 9 );

Here is the call graph for this function:

Here is the caller graph for this function:

void gCycleMovement::ApplyAcceleration ( REAL  dt  )  [protected, virtual]

apply acceleration calculated earlier

Parameters:
dt length of timestep

Definition at line 3024 of file gCycleMovement.cpp.

References acceleration, clamp(), EPS, exp(), good(), lastTimestep_, REAL, sg_ArchiveReal(), sg_correctAccelerationScaling, sg_speedCycle, sg_speedCycleDecayAbove, sg_speedCycleDecayBelow, sg_speedCycleMax, sg_speedCycleMin, sg_verletIntegration, SpeedMultiplier(), nVersionFeature::Supported(), tASSERT, and verletSpeed_.

03026 {
03027     sg_ArchiveReal( verletSpeed_, 9 );
03028     sg_ArchiveReal( dt, 9 );
03029     sg_ArchiveReal( acceleration, 9 );
03030 
03031     // the speed needs to be simulated for this half frame and half of the last frame
03032     REAL verletTimestep = sg_verletIntegration.Supported() ? .5 * ( dt + lastTimestep_ ) : dt;
03033     lastTimestep_ = dt;
03034 
03035     sg_ArchiveReal( verletTimestep, 9 );
03036 
03037     // don't use euler timesteps for large cycle speed decays
03038     bool properDecay = false;
03039     REAL maxTimestep = verletTimestep > dt ? verletTimestep : dt;
03040     if ( sg_speedCycleDecayBelow * maxTimestep > .1 || sg_speedCycleDecayAbove * maxTimestep > .1 )
03041     {
03042         REAL speedDecay = 0;
03043         REAL baseSpeed = sg_speedCycle * SpeedMultiplier();
03044         if ( verletSpeed_ < ( sg_correctAccelerationScaling.Supported() ? baseSpeed : sg_speedCycle ) )
03045             speedDecay = sg_speedCycleDecayBelow;
03046         else
03047             speedDecay = sg_speedCycleDecayAbove;
03048 
03049         if ( speedDecay * maxTimestep > .1 && dt > EPS )
03050         {
03051             // ok, really, a  better simulation is needed
03052             properDecay = true;
03053 
03054             // that's what CalculateAcceleration extrapolates
03055             REAL decayAcceleration = ( baseSpeed - verletSpeed_) * speedDecay;
03056             // throw it away
03057             acceleration -= decayAcceleration;
03058 
03059             tASSERT( good( acceleration ) );
03060 
03061             // adapt base speed as the limit speed with the current decay and acceleration
03062             baseSpeed += acceleration/speedDecay;
03063 
03064             // do a proper decay
03065             verletSpeed_ = baseSpeed + ( verletSpeed_ - baseSpeed ) * exp( -speedDecay * verletTimestep );
03066 
03067             // calculate new acceleration based purely on the decay, the external acceleration
03068             // is factored into baseSpeed now. Add extra decay factor so that
03069             // Speed() returns the most accurate current speed available.
03070             acceleration = ( baseSpeed - verletSpeed_) * ( 1 - exp( -speedDecay * dt * .5f ) ) / ( .5f * dt );
03071 
03072             tASSERT( good( acceleration ) );
03073         }
03074     }
03075 
03076     // if decay wasn't handled properly (because it didn't need to), use euler/verlet
03077     if ( !properDecay )
03078         verletSpeed_+=acceleration*verletTimestep;
03079 
03080     // clamp speed
03081     REAL minSpeed = sg_speedCycle*SpeedMultiplier()*sg_speedCycleMin;
03082     REAL maxSpeed = ( 100 + sg_speedCycle*SpeedMultiplier() )* 100000;
03083     if ( sg_speedCycleMax > 0 )
03084     {
03085         maxSpeed = sg_speedCycle*SpeedMultiplier()*sg_speedCycleMax;
03086     }
03087 
03088     sg_ArchiveReal( minSpeed, 9 );
03089     sg_ArchiveReal( maxSpeed, 9 );
03090     sg_ArchiveReal( acceleration, 9 );
03091 
03092     if ( clamp( verletSpeed_, minSpeed, maxSpeed ) )
03093         acceleration = 0;
03094 
03095     sg_ArchiveReal( acceleration, 9 );
03096 
03097     sg_ArchiveReal( verletSpeed_, 9 );

Here is the call graph for this function:

REAL gCycleMovement::DistanceToDestination ( gDestination dest  )  const [protected]

calculates the distance to the given destination

Parameters:
dest the destination to measure the distance to
Returns:
the distance to the destination

Definition at line 1211 of file gCycleMovement.cpp.

References gDestination::braking, braking, dirDrive, gDestination::direction, eCoord, EPS, F, eGrid::GetDirection(), eGameObject::Grid(), eGameObject::pos, gDestination::position, REAL, tASSERT, eGrid::Turn(), and windingNumberWrapped_.

Referenced by Timestep().

01213 {
01214     // read future direction from destination
01215     eCoord dirTurned = dest.direction;
01216 
01217     REAL divisor = ( dirDrive * dirTurned );
01218     if ( divisor < EPS && divisor > -EPS )
01219     {
01220         REAL F = eCoord::F( dirTurned, dirDrive );
01221         if ( F > 0 )
01222         {
01223             // destination direction and driving direction coincide; we have to
01224             // make up a new turned direction
01225 
01226             // no need to worry if brake status changed
01227             if ( ( braking != 0 ) != dest.braking )
01228             {
01229                 return eCoord::F( dest.position - pos, dirDrive )/dirDrive.NormSquared();
01230             }
01231 
01232             // we'd have to turn in this direction to reach the destination
01233             int side = (dest.position - pos) * dirDrive > 0 ? -1 : 1;
01234 
01235             // pretend to turn in that direction and fetch driving vector
01236             int w = windingNumberWrapped_;
01237             Grid()->Turn(w, side);
01238             dirTurned = Grid()->GetDirection( w );
01239 
01240             // recalculate divisor
01241             divisor = ( dirDrive * dirTurned );
01242             tASSERT( fabs( divisor ) > EPS );
01243         }
01244         else
01245         {
01246             // destination direction and driving direction are opposed. This must be a grave error,
01247             // so we'll make something up
01248             return eCoord::F( dest.position - pos, dirDrive )/dirDrive.NormSquared();
01249         }
01250     }
01251 
01252     // calculate when a turn would need to be made that aligns
01253     // this cycle with the destination
01254     return ( ( dest.position - pos ) * dirTurned ) / divisor;

Here is the call graph for this function:

Here is the caller graph for this function:

void gCycleMovement::OnNotifyNewDestination ( gDestination dest  )  [protected, virtual]

notifies cycle of the insertion of a new destination

Parameters:
dest the new destination

Reimplemented in gCycle.

Definition at line 1266 of file gCycleMovement.cpp.

References currentDestination, destinationList, gDestination::next, nSTANDALONE, nNetObject::Owner(), sn_GetNetState(), and sn_myNetID.

Referenced by NotifyNewDestination(), and gCycle::OnNotifyNewDestination().

01268 {
01269     // go back one destination if the new destination appears to be older than the current one
01270     if ((!currentDestination || currentDestination == dest->next ) &&
01271             sn_GetNetState()!=nSTANDALONE && ( Owner() != ::sn_myNetID || !destinationList ) )
01272     {
01273         currentDestination=dest;
01274         // con << "setting new cd\n";
01275     }

Here is the call graph for this function:

Here is the caller graph for this function:

void gCycleMovement::OnDropTempWall ( gPlayerWall wall,
eCoord const &  pos,
eCoord const &  dir 
) [protected, virtual]

called when another cycle grinds a wall; this cycle should then drop its current wall if the grinding is too close.

Parameters:
wall the wall the other cycle is grinding
pos the position of the grind
dir the direction the raycast triggering the gridding comes from

Reimplemented in gCycle.

Definition at line 1289 of file gCycleMovement.cpp.

Referenced by DropTempWall().

01291 {

Here is the caller graph for this function:

bool gCycleMovement::DoIsDestinationUsed ( const gDestination dest  )  const [protected, virtual]

returns whether the given destination is in active use

Parameters:
dest the destination to test
Returns:
true if the destination is still in active use

Reimplemented in gCycle.

Definition at line 1195 of file gCycleMovement.cpp.

References currentDestination, destinationList, and lastDestination.

Referenced by gCycle::DoIsDestinationUsed(), and IsDestinationUsed().

Here is the caller graph for this function:

gDestination * gCycleMovement::GetDestinationBefore ( const SyncData sync,
gDestination first 
) [static, protected]

determine the destination from before the sync message

Parameters:
sync the sync data received from the server
first the first candidate for the return value
Returns:
the destination entry that was last processed on the server

Definition at line 1305 of file gCycleMovement.cpp.

References gCycleMovement::SyncData::braking, gDestination::braking, braking, gCycleMovement::SyncData::dir, gDestination::direction, distance, gDestination::distance, gCycleMovement::SyncData::distance, gCycleMovement::SyncData::lastTurn, gDestination::messageID, gCycleMovement::SyncData::messageID, gDestination::next, NULL, gCycleMovement::SyncData::pos, and REAL.

Referenced by CopyFrom(), and gCycle::ReadSync().

01307 {
01308     // message IDs smaller than 16 don't exist
01309     if ( sync.messageID != 1 )
01310     {
01311         gDestination * ret = first;
01312 
01313         // deterimine last passed destination by the message ID
01314         while ( ret && ret->messageID != sync.messageID )
01315             ret = ret->next;
01316 
01317         // return match
01318         return ret;
01319     }
01320     else
01321     {
01322         // calculate the distance of the last turn of the sync
01323         REAL syncLastTurnDistance = sync.distance - ( sync.pos - sync.lastTurn ).Norm();
01324 
01325         // message ID not available; must use heuristics
01326         gDestination * run = first;         // destination iterator
01327         gDestination * bestMatch = NULL;    // the best message that fit the sync data and that lies before the sync
01328         REAL bestMatchDistance = 1E+20;     // the distance of the best message to the sync
01329         bool braking = false;               // braking causes trouble here. Activate extra checks if brakes are involved
01330         while ( run )
01331         {
01332             // calculate discrepancy of last turn distance of sync to the current message's distance
01333             REAL distanceBefore = syncLastTurnDistance - run->distance;
01334             REAL distanceAfter  = run->distance - sync.distance;
01335 
01336 
01337             // the allowed values for run->distance are inside the interval [ syncLastTurnDistance,sync.distance ]
01338             // distance is a metric that is positive outside of the interval and
01339             // negative inside it, with minimum in the center.
01340             REAL distance = distanceBefore < distanceAfter ? distanceBefore : distanceAfter;
01341 
01342             // activate brake trouble compensation
01343             if ( distance < 0 && ( run->braking || sync.braking ) )
01344             {
01345                 // void previous match
01346                 if ( !braking )
01347                     bestMatchDistance += 1;
01348                 braking = true;
01349             }
01350 
01351             // clamp distance to nonnegative values to give points inside the allowed interval
01352             // equal chances
01353             if ( distance < 0 )
01354                 distance = 0;
01355 
01356             // prefer destinations close to the end of the allowed interval if braking is involved, else destinations close to the beginning
01357             if ( braking )
01358             {
01359                 distance += fabs( distanceAfter + .01 * distanceBefore ) * .0001;
01360             }
01361             else
01362             {
01363                 distance += fabs( distanceBefore ) * .1;
01364             }
01365 
01366             // see if brake status and driving direction match; this is a must
01367             if ( eCoord::F( run->direction, sync.dir ) > .9*sync.dir.NormSquared() && run->braking == ( sync.braking != 0 ) )
01368             {
01369                 if ( !bestMatch || distance < bestMatchDistance )
01370                 {
01371                     bestMatch = run;
01372                     bestMatchDistance = distance;
01373                 }
01374             }
01375             run = run->next;
01376         }
01377 
01378         // con << bestMatchDistance << "\n";
01379 
01380         // return match
01381         return bestMatch;
01382     }

Here is the caller graph for this function:

bool gCycleMovement::DoTurn ( int  dir  )  [protected, virtual]

turns the cycle in the given direction

Parameters:
dir +1 for right turns, -1 for left turns
Returns:
true of the turn could be executed right now, false if it was queued

Reimplemented in gCycle.

Definition at line 3110 of file gCycleMovement.cpp.

References AccelerationDiscontinuity(), CanMakeTurn(), con, eSensor::detect(), dirDrive, eCoord, eGameObject::FindCurrentFace(), gap_, eGrid::GetDirection(), ePlayerNetID::GetName(), eGameObject::Grid(), gSENSOR_ENEMY, gSENSOR_NONE, gSENSOR_RIM, gSENSOR_SELF, gSENSOR_TEAMMATE, eSensor::hit, keepLookingForGap_, lastDirDrive, eGameObject::lastTime, lastTurnPos_, lastTurnTimeLeft_, lastTurnTimeRight_, pendingTurns, eNetGameObject::Player(), eGameObject::pos, eGameObject::Position(), REAL, refreshSpaceAhead_, rubberMalus, rubberSpeedFactor, SetWindingNumberWrapped(), sg_accelerationCycleOffs, sg_boostCycleEnemy, sg_boostCycleRim, sg_boostCycleSelf, sg_boostCycleTeam, sg_boostFactorCycleEnemy, sg_boostFactorCycleRim, sg_boostFactorCycleSelf, sg_boostFactorCycleTeam, sg_cycleTurnMemory, sg_cycleTurnSpeedFactor, sg_DropTempWall(), sg_nearCycle, sg_rubberCycleMalusTurn, Speed(), SpeedMultiplier(), tSysTimeFloat(), eGrid::Turn(), turns, gSensor::type, verletSpeed_, and windingNumberWrapped_.

Referenced by gCycle::DoTurn(), and Turn().

03112 {
03113     if ( turns == 0 )
03114         turns = 1;
03115 
03116     if (dir >  1) dir =  1;
03117     if (dir < -1) dir = -1;
03118 
03119     if ( CanMakeTurn( lastTime, dir ) )
03120     {
03121         // request regeneration of maximum space
03122         refreshSpaceAhead_ = true;
03123 
03124         // notify that no rubber is currently used (may be a lie, but a timestep correcting
03125         // it will surely follow)
03126         rubberSpeedFactor = 1;
03127 
03128         // store last postion
03129         lastTurnPos_ = pos;
03130 
03131         turns++;
03132 
03133         AccelerationDiscontinuity();
03134         verletSpeed_ *= sg_cycleTurnSpeedFactor;
03135         rubberMalus  += sg_rubberCycleMalusTurn;
03136 
03137         gap_[0] = gap_[1] = 1E+30;
03138         keepLookingForGap_[0] = keepLookingForGap_[1] = true;
03139 
03140         // turn winding numbers
03141         int wn = windingNumberWrapped_;
03142         Grid()->Turn(wn, dir);
03143         this->SetWindingNumberWrapped( wn );
03144 
03145         eCoord nextDirDrive = Grid()->GetDirection(windingNumberWrapped_);
03146 
03147         // send out a sensor a bit backwards and forwards into the turn direction to
03148         // copy all temporary walls into the grid
03149         {
03150             REAL range = .1 * Speed();
03151             eCoord dirCast = nextDirDrive;
03152             gSensor gridder1( this, Position(), dirCast );
03153             gridder1.detect( range );
03154             if ( gridder1.ehit )
03155                 ::sg_DropTempWall( nextDirDrive, gridder1 );
03156 
03157             gSensor gridder3( this, Position() - dirCast * (range*.5), dirCast );
03158             gridder3.detect( range );
03159             if ( gridder3.ehit )
03160                 ::sg_DropTempWall( nextDirDrive, gridder3 );
03161 
03162             // the ray backwards should detect walls that affected the acceleration;
03163             // they can also give a boost. Increase the range.
03164             if ( range < sg_nearCycle )
03165                 range = sg_nearCycle;
03166 
03167             gSensor gridder2( this, Position(), -dirCast );
03168             gridder2.detect( range );
03169             if ( gridder2.ehit )
03170             {
03171                 ::sg_DropTempWall( nextDirDrive, gridder2 );
03172 
03173                 // apply the boost. Calculate wall distance
03174                 REAL dist = gridder2.hit;
03175 
03176                 // calculate the factor acceleration would be multiplied with
03177                 REAL accellerationFactorOffset = 1/(sg_nearCycle+sg_accelerationCycleOffs);
03178                 REAL accelerationFactor = (1/(dist+sg_accelerationCycleOffs)) - accellerationFactorOffset;
03179                 // this would be the maximal acceleration factor
03180                 REAL accelerationFactorMax = (1/sg_accelerationCycleOffs) - accellerationFactorOffset;
03181 
03182                 // select boost settings according to wall type
03183                 // apply modificators
03184                 REAL boost = 0, boostFactor = 1;
03185                 switch (gridder2.type)
03186                 {
03187                 case gSENSOR_SELF:
03188                     boost = sg_boostCycleSelf;
03189                     boostFactor = sg_boostFactorCycleSelf;
03190                     break;
03191                 case gSENSOR_TEAMMATE:
03192                     boost = sg_boostCycleTeam;
03193                     boostFactor = sg_boostFactorCycleTeam;
03194                     break;
03195                 case gSENSOR_ENEMY:
03196                     boost = sg_boostCycleEnemy;
03197                     boostFactor = sg_boostFactorCycleEnemy;
03198                     break;
03199                 case gSENSOR_RIM:
03200                     boost = sg_boostCycleRim;
03201                     boostFactor = sg_boostFactorCycleRim;
03202                     break;
03203                 case gSENSOR_NONE:
03204                     break;
03205                 }
03206 
03207                 // apply acceleration factor to boost
03208                 boostFactor = 1 + ( boostFactor - 1 ) * accelerationFactor / accelerationFactorMax;
03209                 boost *= SpeedMultiplier() * accelerationFactor / accelerationFactorMax;
03210 
03211                 // apply boost to speed
03212                 verletSpeed_ = verletSpeed_ * boostFactor + boost;
03213             }
03214 
03215             // if edges have been inserted into the grid, find a new current face.
03216             FindCurrentFace();
03217         }
03218 
03219         // update driving directions
03220         lastDirDrive = dirDrive;
03221 
03222         if(dir == 1)
03223             lastTurnTimeRight_ = lastTime;
03224         else
03225             lastTurnTimeLeft_ = lastTime;
03226 
03227         dirDrive = nextDirDrive;
03228 
03229 #ifdef DEBUGOUTPUT
03230         if ( sg_cycleDebugPrintLevel > 0 )
03231             con << Player()->GetName() << " turned " << pos << "," << dirDrive << " " << tSysTimeFloat() << "\n";
03232 #endif
03233 
03234         return true;
03235     }
03236     else {
03237         int maxPendingTurns=sg_cycleTurnMemory;
03238         int size = pendingTurns.size();
03239         // std::cerr << "size of " << &pendingTurns << ": " << size << std::endl;
03240         if (size <= maxPendingTurns)
03241             pendingTurns.push_back(dir);
03242         else {
03243             if(pendingTurns.empty()) return false; //just to be sure
03244             if(pendingTurns.back() != dir) {
03245                 pendingTurns.pop_back(); //opposite turns cancel so the cycle still moves into the expected direction
03246             }
03247             else {
03248                 pendingTurns.push_back(dir); //add it anyways...
03249             }
03250         }
03251     }
03252 
03253     return false;

Here is the call graph for this function:

Here is the caller graph for this function:

REAL gCycleMovement::DoGetDistanceSinceLastTurn ( void   )  const [protected, virtual]

returns the distance since the last turn

Parameters:
other 
other 
Returns:
Parameters:
other 
Returns:
the distance driven since the last turn

Definition at line 4042 of file gCycleMovement.cpp.

References dirDrive, lastTurnPos_, and eGameObject::pos.

Referenced by GetDistanceSinceLastTurn().

04044 {
04045     return eCoord::F( dirDrive, pos - lastTurnPos_ )/dirDrive.NormSquared();

Here is the caller graph for this function:

void gCycleMovement::RightBeforeDeath ( int  numTries  )  [protected, virtual]

called when the cycle is very close to a wall and about to crash

Parameters:
numTries number of times this function will be called approximately before the cycle will be killed

Reimplemented in gCycle.

Definition at line 3265 of file gCycleMovement.cpp.

Referenced by TimestepCore().

03267 {

Here is the caller graph for this function:

void gCycleMovement::Die ( REAL  time  )  [protected, virtual]

dies at the specified time

Parameters:
time the time of death

Reimplemented in gCycle.

Definition at line 3279 of file gCycleMovement.cpp.

References alive_, and eGameObject::deathTime.

Referenced by gCycle::Die().

03281 {
03282     // only do something if you are alive
03283     if ( alive_ == 1 )
03284     {
03285         alive_ = -1;
03286         deathTime = time;
03287     }
03288 
03289     // or complete death if you died only recently
03290     if ( alive_ == -1 )
03291     {
03292         alive_ = 0;
03293     }

Here is the caller graph for this function:

bool gCycleMovement::TimestepCore ( REAL  currentTime,
bool  calculateAcceleration = true 
) [protected, virtual]

core physics simulation routine

Parameters:
currentTime time to simulate up to
Returns:
true if the cycle is to be killed

Reimplemented in gCycleExtrapolator, and gCycle.

Definition at line 3322 of file gCycleMovement.cpp.

References acceleration, AccelerationDiscontinuity(), brakeUsage, brakingReservoir, CalculateAcceleration(), clamp(), con, eLag::Credit(), currentDestination, eGameObject::currentFace, gPlayerWall::CycleMovement(), dirDrive, distance, eCoord, emergency, EPS, exp(), nAverager::GetDataVariance(), GetMaxSpaceAhead(), ePlayerNetID::GetName(), nPingAverager::GetSnailAverager(), GetTurnDelay(), gPlayerWall::IsDangerous(), eNetGameObject::Lag(), eNetGameObject::LagThreshold(), eGameObject::lastTime, lastTimeAlive_, lastTurnTimeLeft_, lastTurnTimeRight_, maxSpaceHit_, eGameObject::Move(), nCLIENT, nSERVER, nNetObject::Owner(), nConnectionInfo::ping, eNetGameObject::Player(), gMaxSpaceAheadHitInfo::playerWall, gPlayerWall::Pos(), eGameObject::pos, REAL, RightBeforeDeath(), rubber, rubberMalus, rubberSpeedFactor, rubberUsage, se_GameTime(), sg_ArchiveCoord(), sg_ArchiveReal(), sg_cycleWidthRubberMax, sg_cycleWidthRubberMin, sg_nonRippable, sg_packetLossTolerance, sg_rubberCycleDelay, sg_rubberCycleDelayBonus, sg_rubberCycleLegacy, sg_rubberCycleMalusTime, sg_rubberCycleMinDistance, sg_rubberCycleSpeed, sg_rubberCycleTime, sg_RubberValues(), sg_verletIntegration, sn_Connections, sn_GetNetState(), Speed(), sqrtf(), st_Breakpoint(), nVersionFeature::Supported(), tASSERT, eNetGameObject::Timestep(), ts, tSysTimeFloat(), verletSpeed_, Vulnerable(), gMaxSpaceAheadHitInfo::wallAlpha, and x.

Referenced by Timestep(), gCycle::TimestepCore(), and gCycleExtrapolator::TimestepCore().

03324 {
03325     eCoord oldpos=pos;
03326     REAL lastSpeed=verletSpeed_;
03327 
03328     REAL ts=(currentTime-lastTime);
03329 
03330     // calculate acceleration
03331     if ( calculateAcceleration )
03332         this->CalculateAcceleration();
03333 
03334     // ApplyAcceleration modifies the acceleration, so we need to back it up
03335     REAL lastAcceleration=acceleration;
03336 
03337     // calculate when the braking reservoir will run dry and simulate to that point
03338     {
03339         static bool recurse = true;
03340         if (recurse && brakingReservoir > 0 && brakeUsage > 0 && brakingReservoir - ts * brakeUsage < 0 )
03341         {
03342             gRecursionGuard guard( recurse );
03343 
03344             // calculate the time the brake will run out
03345             REAL brakeTime = lastTime + brakingReservoir/brakeUsage;
03346             if ( TimestepCore( brakeTime, false ) )
03347                 return true;
03348             AccelerationDiscontinuity();
03349             brakingReservoir = -EPS;
03350             return TimestepCore( currentTime );
03351         }
03352     }
03353 
03354     // apply acceleration
03355     if ( sg_verletIntegration.Supported() )
03356         this->ApplyAcceleration( ts );
03357 
03358     //eDebugLine::SetTimeout( 2 );
03359     //eDebugLine::SetColor(1,1,0);
03360     //eDebugLine::Draw(pos, 4, pos, 4 + 20 * ts);
03361 
03362     sg_ArchiveCoord( pos, 9 );
03363     sg_ArchiveReal( ts, 9 );
03364     sg_ArchiveReal( verletSpeed_, 9 );
03365 
03366 #ifdef DEBUG
03367     if ( ts > 2.0f )
03368     {
03369         int x;
03370         x = 0;
03371     }
03372 
03373     if ( verletSpeed_ > 30.0f )
03374     {
03375         int x;
03376         x = 0;
03377     }
03378 
03379     if ( acceleration > 100.0f )
03380     {
03381         int x;
03382         x = 0;
03383     }
03384 #endif
03385 
03386     clamp(ts, -10, 10);
03387 
03388     REAL step=verletSpeed_*ts;
03389     tASSERT(finite(step));
03390 
03391     int numTries = 0;
03392     bool emergency = false;
03393 
03394     rubberSpeedFactor = 1;
03395 
03396     // be a little nice and don't drive into the wall
03397     REAL rubber_granted, rubberEffectiveness;
03398 
03399     // get rubber values
03400     sg_RubberValues( player, verletSpeed_, rubber_granted, rubberEffectiveness );
03401 
03402     // rubber effectiveness right now
03403     rubberEffectiveness /= (1 + rubberMalus );
03404 
03405     // reduce it further if cycle turned recently
03406     {
03407         REAL delayTime = (lastTurnTimeRight_ > lastTurnTimeLeft_ ? lastTurnTimeRight_ : lastTurnTimeLeft_) + GetTurnDelay() * sg_rubberCycleDelay;
03408         if ( lastTime < delayTime )
03409         {
03410             rubberEffectiveness *= sg_rubberCycleDelayBonus;
03411 
03412             // if the target time is after the rubber delay ends...
03413             if( currentTime > delayTime )
03414             {
03415                 static bool recurse = true;
03416                 if (recurse)
03417                 {
03418                     gRecursionGuard guard( recurse );
03419 
03420                     verletSpeed_=lastSpeed;
03421                     acceleration=lastAcceleration;
03422                     // do two small timesteps
03423                     return TimestepCore( delayTime, false ) || TimestepCore( currentTime );
03424                 }
03425             }
03426         }
03427     }
03428 
03429     sg_ArchiveReal( rubberEffectiveness, 9 );
03430 
03431     tASSERT( rubber >= 0 );
03432 
03433     // TODO: solve smooth position correction trouble with rubber
03434     if ( player && ( rubber_granted > rubber || sn_GetNetState() == nCLIENT || !Vulnerable() ) && sg_rubberCycleSpeed > 0 && step > -EPS && ( sn_GetNetState() == nCLIENT || rubberEffectiveness > 0 ) )
03435     {
03436         // ignore zero effectiveness, this happens only on the client
03437         if ( rubberEffectiveness <= 0 )
03438             rubberEffectiveness = 1E+20;
03439 
03440         // formerly: rubberFactor = .5
03441         REAL beta = ts * sg_rubberCycleSpeed;
03442         REAL neededSpace = 0;
03443         REAL rubberFactor;
03444         if ( beta > .001 )
03445         {
03446             rubberFactor = 1 - exp( -beta );
03447             neededSpace = step/rubberFactor;
03448         }
03449         else
03450         {
03451             rubberFactor = beta;        // better accuracy than the full formula
03452 
03453             // a lot of factors can be cut out of this one (avoiding a division by zero for ts=0)
03454             neededSpace = verletSpeed_/sg_rubberCycleSpeed;
03455         }
03456 
03457         // rubberFactor must not be too close to 1, otherwise we get precision trouble
03458         if ( rubberFactor > .999 )
03459             rubberFactor = .999;
03460 
03461         // revert to old rubber logic if old clients are connected
03462         if ( sg_rubberCycleLegacy && !sg_nonRippable.Supported() && rubberFactor < .5f )
03463             rubberFactor = .5f;
03464 
03465         // space we need to look ahead
03466         if ( neededSpace < step*3 || ts < -EPS )
03467             neededSpace = step*3;
03468 
03469         // determine how long we can drive on
03470         // REAL space = GetMaxSpaceAhead( this, neededSpace, ts * step * rubberFactor / rubberEffectiveness, &hitInfo );
03471         REAL space = GetMaxSpaceAhead( neededSpace );
03472 
03473 #ifdef DEBUG_RUBBER
03474         if ( Player() && space < 1E+15)
03475         {
03476             std::ofstream f( Player()->GetUserName() + "_rubber", std::ios::app );
03477             f << lastTime << " " << space << "\n";
03478         }
03479 #endif
03480 
03481         // if the available space in front is less than the space needed to slow down via
03482         // the rubber brake, activate rubber and slow down
03483         if ( space < neededSpace )
03484         {
03485             // the minimal space rubber gets active at
03486             REAL rubberStartSpace = verletSpeed_/sg_rubberCycleSpeed;
03487             static bool recurse = true;
03488             if ( space > rubberStartSpace && recurse )
03489             {
03490                 // rubber will not be active immediately, simulate to the time it will
03491                 gRecursionGuard guard( recurse );
03492 
03493                 // calculate the time rubber will get active at
03494                 REAL ratio = ( space - rubberStartSpace )/step;
03495                 if ( ratio > EPS && ratio < 1 - EPS )
03496                 {
03497                     REAL rubberGetsActiveTime = lastTime + ( currentTime - lastTime ) * ratio;
03498 
03499                     verletSpeed_=lastSpeed;
03500                     acceleration=lastAcceleration;
03501                     return TimestepCore( rubberGetsActiveTime, false ) || TimestepCore( currentTime );
03502                 }
03503             }
03504 #ifdef DEDICATED
03505             else
03506             {
03507                 // see if the wall we're about to hit comes from its cycle's future. If so,
03508                 // it is a prediction wall and we shouldn't actually use rubber before we
03509                 // have to.
03510                 if ( maxSpaceHit_ && maxSpaceHit_->playerWall )
03511                 {
03512                     gPlayerWall * wall = maxSpaceHit_->playerWall;
03513 
03514                     // get the position of the hit
03515                     REAL alpha = maxSpaceHit_->wallAlpha;
03516 
03517                     // get the distance of the wall
03518                     REAL wallDist = wall->Pos( alpha );
03519                     // get the distance the cycle is simulated up to
03520                     REAL cycleDist = wall->CycleMovement()->distance;
03521                     // comparing these two gives an accurate criterion whether the wall is extrapolated
03522 
03523                     REAL minLag = se_GameTime() - lastTime - LagThreshold();
03524                     if ( cycleDist < wallDist && ( minLag < Lag() || minLag < wall->CycleMovement()->Lag() ) )
03525                     {
03526                         // it is an extrapolation wall and we are allowed to delay simulation a bit.
03527                         // so let's abort here.
03528                         verletSpeed_=lastSpeed;
03529                         acceleration=lastAcceleration;
03530 
03531                         return false;
03532                     }
03533                 }
03534             }
03535 #endif
03536 
03537             // see if the obstacle will go away during this timestep.
03538             // if it does, simulate in two steps to make the simulation more accurate.
03539             {
03540                 // get the wall
03541                 if ( maxSpaceHit_ && maxSpaceHit_->playerWall )
03542                 {
03543                     gPlayerWall * wall = maxSpaceHit_->playerWall;
03544 
03545                     // get the position of the hit
03546                     REAL alpha = maxSpaceHit_->wallAlpha;
03547 
03548                     // use binary search to find the time the wall goes away. Not
03549                     // the fastest way, but it doesn't depend on wall internals, and
03550                     // it shouldn't be called often anyway.
03551                     REAL tolerance = 0.001;
03552                     if ( !wall->IsDangerous( alpha, currentTime ) && currentTime > lastTime + tolerance )
03553                     {
03554                         // take movement speed into account, we won't hit the wall for
03555                         // another distanceOffset seconds
03556                         REAL distanceOffset = 0;
03557                         {
03558                             REAL speed = Speed();
03559                             if ( speed > 0 )
03560                                 distanceOffset = space/speed;
03561                         }
03562 
03563                         REAL minTime = lastTime + distanceOffset;
03564                         REAL maxTime = currentTime + distanceOffset;
03565                         while ( minTime + tolerance < maxTime )
03566                         {
03567                             REAL midTime = .5 * ( minTime + maxTime );
03568                             if ( wall->IsDangerous( alpha, midTime ) )
03569                                 minTime = midTime;
03570                             else
03571                                 maxTime = midTime;
03572                         }
03573 
03574                         maxTime -= distanceOffset;
03575                         // minTime -= distanceOffset;
03576 
03577                         // split simulation into two parts, one up to the point the wall turns harmless
03578                         {
03579                             static bool recurse = true;
03580                             if (recurse)
03581                             {
03582                                 gRecursionGuard guard( recurse );
03583 
03584                                 verletSpeed_=lastSpeed;
03585                                 acceleration=lastAcceleration;
03586                                 return TimestepCore( maxTime, false ) || TimestepCore( currentTime );
03587                             }
03588                         }
03589                     }
03590                 }
03591             }
03592 
03593             /*
03594             // debug output for sensitive space/time diagrams
03595             static REAL lastTimePrinted = 0;
03596             if ( currentTime > lastTimePrinted && Player() )
03597             {
03598                 lastTimePrinted = currentTime;
03599                 std::ofstream f( Player()->GetUserName() + "_space", std::ios::app );
03600                 f << lastTime << " " << log(space) << "\n";
03601             }
03602             */
03603 
03604             // notify AIs of it
03605             emergency = true;
03606 
03607             // calculate the step the rubber code should do based on the decay factor
03608             // calculated earler
03609             REAL rubberStep = space * rubberFactor;
03610             if ( rubberStep > step )
03611                 rubberStep = step;
03612 
03613             // clamp the step
03614             if (step<0)
03615                 step=0;
03616 
03617             // calculate the amount of rubber needed for the desired brake effect
03618             REAL rubberneeded = step - rubberStep;
03619             if (rubberneeded < 0)
03620                 rubberneeded = 0;
03621 
03622             // clamp rubberneeded to the amout of rubber available
03623             REAL rubberAvailable = ( rubber_granted - rubber ) * rubberEffectiveness;
03624             if ( sn_GetNetState() != nCLIENT && rubberneeded > rubberAvailable && Vulnerable() )
03625             {
03626                 // rubber will run out this frame.
03627                 // split simulation into two parts, one up to the point rubber runs out
03628                 {
03629                     REAL ratio = rubberAvailable/rubberneeded;
03630 
03631                     if ( ratio > .01 && ratio < .99 && currentTime - lastTime > .001 )
03632                     {
03633                         REAL runOutTime = lastTime + ( currentTime - lastTime ) * ratio;
03634                         static bool recurse = true;
03635                         if (recurse)
03636                         {
03637                             gRecursionGuard guard( recurse );
03638                             // need many attempts
03639                             verletSpeed_=lastSpeed;
03640                             acceleration=lastAcceleration;
03641                             return TimestepCore( runOutTime, false ) || TimestepCore( currentTime );
03642                         }
03643                     }
03644                 }
03645 
03646                 rubberneeded = rubberAvailable;
03647             }
03648 
03649             // update rubber usage
03650             rubber += rubberneeded / rubberEffectiveness;
03651 
03652             numTries = int((sg_rubberCycleTime * ( rubber_granted - rubber ) - 1 )/(sg_rubberCycleTime * step*1.5 + 1));
03653             int numTriesSpace = int(space*10/verletSpeed_);
03654             if ( numTriesSpace < numTries )
03655                 numTriesSpace = 0;
03656 
03657             if ( step > 0 )
03658                 rubberSpeedFactor = 1 - rubberneeded/step;
03659             else
03660                 // better algorithm for zero steps
03661                 rubberSpeedFactor = space / neededSpace;
03662 
03663             // clamp
03664             if ( rubberSpeedFactor < 0 )
03665                 rubberSpeedFactor = 0;
03666 
03667             // correct the step to take, don't go backwards.
03668             step -= rubberneeded;
03669             if (step<0)
03670                 step=0;
03671 
03672             //{
03673             //    rubber+=step;
03674             //    step=0;
03675             //}
03676         }
03677     }
03678 
03679     tASSERT( rubber >= 0 );
03680 
03681     sg_ArchiveReal( step, 9 );
03682 
03683     // move forward
03684     eCoord nextpos;
03685     if ( verletSpeed_ >0 )
03686         nextpos=pos+dirDrive*step;
03687     else
03688         nextpos=pos;
03689 
03690     eCoord lastPos = pos;
03691     tJUST_CONTROLLED_PTR< eFace > lastFace = currentFace;
03692     try
03693     {
03694 #ifdef DEBUG
03695         static int run = 0;
03696         run++;
03697         if ( run == -1 )
03698         {
03699             st_Breakpoint();
03700         }
03701 #endif
03702         Move(nextpos,lastTime,currentTime);
03703 #ifdef DEBUG
03704         {
03705             if ( step > 0 && ( nextpos - pos ).NormSquared() > 1 )
03706             {
03707                 con << "Wrong move! run = " << run << ", nextpos = " << nextpos << ", pos = " << pos << "\n";
03708             }
03709         }
03710 #endif
03711 
03712         tASSERT(finite(distance));
03713         tASSERT(finite(step));
03714         distance += step;
03715         lastTimeAlive_ = currentTime;
03716     }
03717     catch ( gCycleStop const & )
03718     {
03719         // undo simulation done so far and stop
03720         pos = lastPos;
03721         verletSpeed_ = lastSpeed;
03722         acceleration = lastAcceleration;
03723         currentFace = lastFace;
03724         numTries = 0;
03725 
03726         // don't simulate further
03727         return false;
03728     }
03729     catch ( gCycleDeath const & )
03730     {
03731         rubberSpeedFactor = 0;
03732 
03733         // the cycle should die in this movement. Prevent it if there is rubber left.
03734         // if RUBBER_MINDISTANCE is negative and the player is not an AI, the cycle dies anyway.
03735         if ( rubberEffectiveness <= 0 || step >= (rubber_granted-rubber)*rubberEffectiveness || ( sg_rubberCycleMinDistance < 0 && Player() && Player()->IsHuman() ) )
03736         {
03737             // last survival chance: packet loss protection. Determine whether it should be in effect..
03738             bool toleratePacketLoss = false;
03739             if (!currentDestination)
03740             {
03741                 // calculate time tolerance to capture packet loss...
03742                 REAL tolerance = Lag() * sg_packetLossTolerance;
03743 
03744                 // add lag credit on top of that
03745                 if ( Owner() > 0 )
03746                     tolerance += eLag::Credit( Owner() );
03747 
03748                 // add lag fluctuation to the mix
03749                 if ( sn_GetNetState() == nSERVER && player && player->Owner() != 0 )
03750                 {
03751                     REAL varianceTolerance = 2 * sqrtf( sn_Connections[ player->Owner() ].ping.GetSnailAverager().GetDataVariance() );
03752                     // clamp it, high fluctuations are the player's own problem
03753                     if ( varianceTolerance > tolerance )
03754                         varianceTolerance = tolerance;
03755                     tolerance += varianceTolerance;
03756                 }
03757 
03758                 // if time has not progressed beyond tolerance, protection may be in effect
03759                 toleratePacketLoss = ( se_GameTime() - Lag() - lastTimeAlive_ < tolerance );
03760             }
03761 
03762             // ... and apply it.
03763             if ( toleratePacketLoss )
03764             {
03765                 pos = lastPos;
03766                 verletSpeed_ = lastSpeed;
03767                 acceleration = lastAcceleration;
03768                 currentFace = lastFace;
03769                 numTries = 0;
03770                 emergency = true;
03771 
03772                 // don't simulate further
03773                 return false;
03774             }
03775             else
03776             {
03777                 // no, no straw left. Rethrow and get killed.
03778                 rubber = rubber_granted;
03779 
03780                 // update distance to include the really covered space
03781                 tASSERT(finite(distance));
03782                 distance += eCoord::F( dirDrive, pos - lastPos )/dirDrive.NormSquared();
03783                 tASSERT(finite(distance));
03784 
03785                 throw;
03786             }
03787         }
03788         else
03789         {
03790             pos = lastPos;
03791             currentFace = lastFace;
03792             rubber += step/rubberEffectiveness;
03793             if ( rubber < 0 )
03794                 rubber = 0;
03795 
03796             numTries = 0;
03797             emergency = true;
03798         }
03799     }
03800 
03801     tASSERT( rubber >= 0 );
03802 
03803     // use up rubber from tunneling (calculated by CalculateAcceleration
03804     if ( rubberEffectiveness > 0 )
03805     {
03806         rubber += rubberUsage * ts * verletSpeed_ / rubberEffectiveness;            }
03807     else if ( rubberUsage > 0 )
03808     {
03809         rubber = rubber_granted + 10;
03810     }
03811     rubberUsage = 0;
03812 
03813     // decide over kill
03814     if ( rubber > rubber_granted || ( sg_cycleWidthRubberMax == 0 && sg_cycleWidthRubberMin == 0 ) )
03815     {
03816         if ( sn_GetNetState() != nCLIENT )
03817         {
03818             throw gCycleDeath( pos );
03819         }
03820         else
03821             rubber = rubber_granted;
03822     }
03823 
03824     // use up brake
03825     brakingReservoir -= brakeUsage * ts;
03826     clamp( brakingReservoir, 0, 1 );
03827 
03828     // let rubber decay
03829     if ( sg_rubberCycleTime > 0 )
03830         rubber /= (1+ts/sg_rubberCycleTime);
03831     else
03832         rubber = 0;
03833 
03834     // let rubber decay
03835     if ( sg_rubberCycleMalusTime > 0 )
03836         rubberMalus /= (1+ts/sg_rubberCycleMalusTime);
03837     else
03838         rubberMalus = 0;
03839 
03840 
03841     // clamp rubber ( mostly for client side HUD display )
03842     if ( rubber > rubber_granted )
03843         rubber = rubber_granted;
03844 
03845 
03846     lastTime=currentTime;
03847 
03848     // give the AI a chance to evade just in time
03849     if (emergency)
03850     {
03851         RightBeforeDeath(numTries);
03852     }
03853 
03854 #ifdef DEBUGOUTPUT
03855     if ( sg_cycleDebugPrintLevel > 1 )
03856         con << Player()->GetName() << " moved " << pos << "," << dirDrive << " " << tSysTimeFloat() << "\n";
03857 #endif
03858 
03859     /*
03860     // debug output for sensitive rubber/time diagrams
03861     static REAL lastTimePrinted = 0;
03862     if ( currentTime > lastTimePrinted && Player() )
03863     {
03864         lastTimePrinted = currentTime;
03865         std::ofstream f( Player()->GetUserName() + "_rubber", std::ios::app );
03866         f << currentTime << " " << rubber << "\n";
03867     }
03868     */
03869 
03870     // apply acceleration
03871     if ( !sg_verletIntegration.Supported() )
03872         this->ApplyAcceleration( ts );
03873 
03874     tASSERT(finite(distance));
03875 
03876     tASSERT( rubber >= 0 );
03877 
03878     // call base timestep
03879     return eNetGameObject::Timestep(currentTime);

Here is the call graph for this function:

Here is the caller graph for this function:

void gCycleMovement::MyInitAfterCreation ( void   )  [private]

private shared initialization code

Reimplemented from eNetGameObject.

Reimplemented in gCycle.

Definition at line 3890 of file gCycleMovement.cpp.

References acceleration, alive_, braking, brakingReservoir, con, eGameObject::dir, dirDrive, distance, gap_, ePlayerNetID::GetName(), keepLookingForGap_, lastDirDrive, eGameObject::lastTime, lastTimeAlive_, lastTurnPos_, lastTurnTimeLeft_, lastTurnTimeRight_, maxSpaceHit_, maxSpaceMaxCast_, NULL, pendingTurns, eNetGameObject::Player(), eGameObject::pos, refreshSpaceAhead_, rubber, rubberMalus, rubberSpeedFactor, st_Breakpoint(), tSysTimeFloat(), turns, verletSpeed_, and eGameObject::z.

Referenced by gCycleMovement(), and InitAfterCreation().

03892 {
03893 #ifdef DEBUG
03894     // con << "creating cycle.\n";
03895 #endif
03896     brakingReservoir = 1.0f;
03897 
03898     braking = false;
03899 
03900     acceleration = 0;
03901 
03902     refreshSpaceAhead_ = true;
03903     maxSpaceMaxCast_ = 0.0;
03904     maxSpaceHit_ = NULL;
03905 
03906     dir=dirDrive;
03907     lastDirDrive=dirDrive;
03908     lastTurnPos_=pos;
03909 
03910     distance=0;
03911     // wallContDistance = 5;
03912     rubber=0.0f;
03913     rubberMalus=0.0f;
03914     rubberSpeedFactor=1.0f;
03915 
03916     gap_[0] = gap_[1] = 1E+30;
03917     keepLookingForGap_[0] = keepLookingForGap_[1] = true;
03918 
03919     alive_ = 1;
03920 
03921     z=.75;
03922 
03923     turns=1;
03924 
03925     pendingTurns.clear();
03926     lastTurnTimeRight_ = lastTurnTimeLeft_=lastTime-10;
03927 
03928     lastTimeAlive_ = lastTime;
03929 
03930     if (!finite(verletSpeed_)){
03931         st_Breakpoint();
03932         verletSpeed_ = 1;
03933     }
03934 
03935     if (verletSpeed_ < .1)
03936         verletSpeed_=.1;
03937 
03938 #ifdef DEBUGOUTPUT
03939     if ( sg_cycleDebugPrintLevel > 0 )
03940         con << Player()->GetName() << " created " << pos << "," << dirDrive << " " << tSysTimeFloat() << "\n";
03941 #endif

Here is the call graph for this function:

Here is the caller graph for this function:

gCycleMovement & gCycleMovement::operator= ( gCycleMovement const &  other  )  [private]

copy operator

Parameters:
other the source to copy from
other the source to copy from
Returns:
a reference to this

Definition at line 684 of file gCycleMovement.cpp.

References CopyFrom().

00686 {
00687     this->CopyFrom( other );
00688     return *this;

Here is the call graph for this function:

REAL gCycleMovement::GetMaxSpaceAhead ( REAL  maxReport  )  const

determines how much a given cycle is allowed to drive ahead without getting too close to the next wall. Looks exactly lookAhead into the future.

Parameters:
cycle the cycle to investigate
lookAhead minimum distance to look ahead
rubber expected to be used up until we hit the wall
extra info storage space
Returns:
distance from the cycle to the next wall determines how much this cycle is allowed to drive ahead without getting too close to the next wall. Looks exactly lookAhead into the future.
Parameters:
maxReport maximal distance to report
Returns:
distance from the cycle to the next wall

Definition at line 1586 of file gCycleMovement.cpp.

References gPlayerWall::Cycle(), eSensor::detect(), eGameObject::dir, dirDrive, Direction(), eCoord, gMaxSpaceAheadHitInfo::edge, EPS, fr, gap_, eGrid::GetDirection(), GetDistanceSinceLastTurn(), GetLastTurnTime(), GetRubber(), eGameObject::Grid(), eSensor::hit, keepLookingForGap_, eGameObject::LastTime(), lastTimestep_, maxSpaceHit_, maxSpaceMaxCast_, NULL, gMaxSpaceAheadHitInfo::offset, gMaxSpaceAheadHitInfo::playerWall, eGameObject::pos, gMaxSpaceAheadHitInfo::pos, eGameObject::Position(), REAL, refreshSpaceAhead_, rubberSpeedFactor, sg_ArchiveReal(), sg_DropTempWall(), sg_Gap(), sg_nonRippable, sg_rubberCycleLegacy, sg_rubberCycleMinAdjust, sg_rubberCycleMinDistance, sg_rubberCycleMinDistanceGap, sg_rubberCycleMinDistanceGapSide, sg_rubberCycleMinDistanceLegacy, sg_rubberCycleMinDistancePreparation, sg_rubberCycleMinDistanceRatio, sg_rubberCycleMinDistanceReservoir, sg_rubberCycleMinDistanceUnprepared, sg_RubberValues(), Speed(), nVersionFeature::Supported(), tNEW, eGrid::Turn(), verletSpeed_, gMaxSpaceAheadHitInfo::wallAlpha, and windingNumberWrapped_.

Referenced by gCycle::CalculatePredictPosition(), Timestep(), TimestepCore(), and gCycle::TimestepCore().

01588 {
01589     // refresh hit info if required
01590     if ( refreshSpaceAhead_ )
01591     {
01592         refreshSpaceAhead_ = false;
01593 
01594         // make sure the raycast is long enoigh
01595         REAL lookAhead = maxSpaceMaxCast_;
01596         if ( maxReport > lookAhead )
01597         {
01598             lookAhead = maxReport;
01599         }
01600 
01601         sg_ArchiveReal( lookAhead, 9 );
01602 
01603         // store data here for later
01604         gMaxSpaceAheadHitInfo info;
01605 
01606         // calculate the relevant minimal distance
01607         REAL mindistance = sg_rubberCycleMinDistance;
01608         {
01609             // get rubber values
01610             REAL rubber_granted, rubberEffectiveness;
01611             sg_RubberValues( player, verletSpeed_, rubber_granted, rubberEffectiveness );
01612 
01613             // add the reservoir dependant term
01614             if ( rubber_granted > 0 )
01615             {
01616                 // rubber usage speed
01617                 REAL rubberUsageSpeed = verletSpeed_ * ( 1 - rubberSpeedFactor ) / rubberEffectiveness;
01618                 // rubber used till end of frame
01619                 REAL rubberUsed = rubberUsageSpeed * lastTimestep_;
01620 
01621                 // fill ratio of rubber at the end of the next frame
01622                 REAL filling = ( GetRubber() + rubberUsed )/rubber_granted;
01623                 if ( filling > 1 )
01624                     filling = 1;
01625                 mindistance += sg_rubberCycleMinDistanceReservoir * (1-filling);
01626             }
01627 
01628             // add the bad preparation dependant term
01629             if ( sg_rubberCycleMinDistancePreparation > 0 )
01630             {
01631                 REAL badPreparation = sg_rubberCycleMinDistancePreparation/( sg_rubberCycleMinDistancePreparation + ( this->LastTime() - this->GetLastTurnTime() ) );
01632                 mindistance += sg_rubberCycleMinDistanceUnprepared * badPreparation;
01633             }
01634         }
01635         sg_ArchiveReal( mindistance, 9 );
01636 
01637         // since we are going to subtract the rubber min distance from the found hit, we'll still have to llok a bit further:
01638         lookAhead += mindistance * sg_rubberCycleMinDistanceLegacy * 2;
01639 
01640         // be a little nice and don't drive into the eWall if turning is allowed
01641         gSensor fr( const_cast< gCycleMovement* >(this), this->Position(), this->Direction() );
01642         {
01643             REAL speed = this->Speed();
01644             if ( speed > 0 )
01645                 fr.SetInverseSpeed( 1 / speed );
01646         }
01647         fr.detect( lookAhead );
01648 
01649         info.edge = fr.ehit;
01650         info.pos  = fr.before_hit;
01651 
01652         if ( fr.ehit )
01653         {
01654             {
01655                 // get the wall of the hit
01656                 eWall * w = info.edge->GetWall();
01657                 if ( !w && info.edge->Other() )
01658                 {
01659                     info.edge = info.edge->Other();
01660                     w = info.edge->GetWall();
01661                 }
01662 
01663                 gPlayerWall * wall = dynamic_cast< gPlayerWall * >( w );
01664                 if ( wall && wall->Cycle() )
01665                 {
01666                     // get the position of the hit and store everything
01667                     info.wallAlpha = info.edge->Ratio( info.pos );
01668                     info.playerWall = wall;
01669                 }
01670             }
01671 
01672 #ifdef DEBUG
01673             {
01674                 gSensor fr2( const_cast< gCycleMovement* >( this ), this->Position(), this->Direction() );
01675                 fr2.detect( lookAhead );
01676             }
01677 #endif
01678 
01679             REAL stopDistance = 0.1;
01680             if ( fr.ehit )
01681             {
01682                 REAL norm = fr.ehit->Vec().Norm();
01683                 stopDistance = mindistance + sg_rubberCycleMinDistanceRatio * norm;
01684 
01685                 ::sg_DropTempWall( this->Direction(), fr );
01686 
01687                 // enforce "open" play: every successive grind to a wall can get closer and closer.
01688 
01689                 REAL rubberCycleMinDistanceGapDistance = sg_rubberCycleMinDistanceGapSide * Speed();
01690 
01691 
01692                 if ( sg_rubberCycleMinDistanceGap > 0 )
01693                 {
01694                     // determine the width of the gap previous grinders left
01695                     for ( int dir = -1; dir < 2; dir += 2 )
01696                     {
01697                         // see if cached value is still good
01698                         REAL & gapCache = gap_[(dir+1)/2];
01699                         bool & keepLooking = keepLookingForGap_[(dir+1)/2];
01700 
01701                         if ( gapCache > fr.hit && keepLooking )
01702                         {
01703                             // determine next direction when turning into dir
01704                             int wn = windingNumberWrapped_;
01705                             Grid()->Turn(wn, dir);
01706                             eCoord dirCast = Grid()->GetDirection(wn);
01707 
01708                             bool gapFound = false;
01709                             for ( int back = -1; back <= 2; ++back )
01710                             {
01711                                 // determine next direction when turning into dir
01712                                 int wn2 = wn;
01713                                 Grid()->Turn(wn2, back);
01714                                 eCoord dirCast2 = Grid()->GetDirection(wn2);
01715 
01716                                 // send out a side sensor
01717                                 gSensor side( const_cast< gCycleMovement * >( this ),
01718                                               this->Position(),
01719                                               ( dirCast + dirCast2 ) * .5 );
01720 
01721                                 side.detect( rubberCycleMinDistanceGapDistance );
01722 
01723                                 // only allow non-hit default search for the ray that goes straight to the side
01724                                 if ( back != 0 && !side.ehit )
01725                                     continue;
01726 
01727                                 REAL tolerance;
01728                                 REAL minGap = sg_Gap( fr, side, dirDrive, norm, fr.hit * .5, tolerance );
01729 
01730                                 while ( minGap > tolerance )
01731                                 {
01732                                     // last test: see if there really is a gap after that wall ends
01733                                     gSensor side2( const_cast< gCycleMovement * >( this ),
01734                                                    this->Position() + this->Direction() * ( fr.hit - minGap * .9 ),
01735                                                    dirCast );
01736                                     side2.detect( rubberCycleMinDistanceGapDistance );
01737 
01738                                     // if this sensor did not hit or hit farther than the first sensor, the gap is real
01739                                     if ( fabs(side2.hit - side.hit) < tolerance )
01740                                     {
01741                                         // true gap not found yet
01742                                         REAL dumpTolerance;
01743                                         REAL lastMinGap = minGap;
01744                                         minGap = sg_Gap( fr, side2, dirDrive, norm, minGap * .5, dumpTolerance );
01745                                         // no improvement? give up.
01746                                         if ( minGap >= lastMinGap * .9 )
01747                                             break;
01748                                     }
01749                                     else
01750                                     {
01751                                         gapFound = true;
01752 
01753                                         // true gap found, is it smaller than the last one?
01754                                         if ( minGap < gapCache )
01755                                         {
01756                                             gapCache = minGap;
01757 
01758                                             // bail out of outer loop
01759                                             back = 100;
01760                                         }
01761 
01762                                         // bail out of inner loop
01763                                         break;
01764                                     }
01765                                 }
01766                             }
01767 
01768                             // no gap to see anywhere
01769                             if ( ! gapFound )
01770                             {
01771                                 // don't waste time looking from now on
01772                                 keepLooking = false;
01773 
01774                                 // if there was no gap detected so far, there is no gap.
01775                                 if ( gapCache > 5E+19 )
01776                                     gapCache = 0;
01777                             }
01778                         }
01779                     }
01780 
01781                     // fetch cache, ignoring zeroes
01782                     REAL gap = ( ( gap_[0] > 0 ? gap_[0] : 1E+30 ) < ( gap_[1] > 0 ? gap_[1] : 1E+30 ) ) ? gap_[0] : gap_[1];
01783                     if ( gap > 0 )
01784                     {
01785                         REAL minDistanceGap = gap * sg_rubberCycleMinDistanceGap;
01786                         if ( stopDistance > minDistanceGap )
01787                             stopDistance = minDistanceGap;
01788                     }
01789                 }
01790             }
01791             sg_ArchiveReal( stopDistance, 9 );
01792 
01793 
01794             // revert to almost old rubber logic if old clients are connected. This may cause rips, but we don't care.
01795             if ( sg_rubberCycleLegacy && !sg_nonRippable.Supported() && stopDistance > .001 )
01796                 stopDistance = .001;
01797 
01798             // if there is a rippable peer connected and the wall is the rim wall, add extra distance
01799             //if ( fr.type == gSENSOR_RIM && !sg_nonRippable.Supported() )
01800             //    stopDistance *= sg_rubberCycleMinDistanceLegacy;
01801 
01802             REAL space = fr.hit;
01803             sg_ArchiveReal( space, 9 );
01804 
01805             // see if we just did a turn
01806             REAL distSinceLastTurn = this->GetDistanceSinceLastTurn();
01807 
01808             // we want to get closer to the wall by at least some percentage
01809             REAL maxStop = ( distSinceLastTurn + space ) * ( 1 - sg_rubberCycleMinAdjust );
01810             if ( maxStop < stopDistance )
01811             {
01812                 stopDistance = maxStop;
01813             }
01814 
01815             sg_ArchiveReal( stopDistance, 9 );
01816 
01817             // add safety
01818             REAL safety = this->Position().Norm() * 2 * EPS;
01819 
01820             info.offset = stopDistance + safety;
01821 
01822             sg_ArchiveReal( space, 9 );
01823 
01824             // create new hit info
01825             if ( !maxSpaceHit_ )
01826                 maxSpaceHit_ = tNEW( gMaxSpaceAheadHitInfo );
01827 
01828             // store information
01829             *maxSpaceHit_ = info;
01830         }
01831         else
01832         {
01833             // delete information
01834             delete maxSpaceHit_;
01835             maxSpaceHit_ = NULL;
01836         }
01837     }
01838 
01839     // information up to date? Good, just take the distance to the collision point.
01840     REAL ret = 1E+30;
01841     if ( maxSpaceHit_ )
01842     {
01843         ret = eCoord::F( dirDrive, maxSpaceHit_->pos - pos ) - maxSpaceHit_->offset;
01844     }
01845 
01846     // clamp it and return.
01847     if ( ret > maxReport )
01848         ret = maxReport;
01849     return ret;

Here is the call graph for this function:

Here is the caller graph for this function:

REAL gCycleMovement::GetDistance ( void   )  const [inline]

Gets the distance traveled so far.

Returns:
the distance traveled so far

Definition at line 417 of file gCycleMovement.h.

References distance.

Referenced by gCycleWallsDisplayListManager::CannotHaveList(), CheckLoop(), gCycleExtrapolator::CopyFrom(), gDestination::CopyFrom(), gAIPlayer::CycleBlocksWay(), cWidget::Map::DrawWalls(), gCycleExtrapolator::EdgeIsDangerous(), IsTrapped(), gCycleWallsDisplayListManager::RenderAll(), gCycleChatBot::Sensor::Sensor(), and sg_KillFutureWall().

00418 {
00419     return this->distance;
00420 }

Here is the caller graph for this function:

gCycleMovement const & gCycleMovement::GetDistance ( REAL distance  )  const [inline]

Gets the distance traveled so far.

Parameters:
distance the distance traveled so far to fill
Returns:
A reference to this to allow chaining

Definition at line 433 of file gCycleMovement.h.

00434 {
00435     distance = this->distance;
00436     return *this;
00437 }

REAL gCycleMovement::GetRubber ( void   )  const [inline]

Gets the amount rubber used up by the cycle.

Returns:
the amount rubber used up by the cycle

Definition at line 466 of file gCycleMovement.h.

References rubber.

Referenced by cCockpit::cb_CurrentRubber(), GetMaxSpaceAhead(), and gCycle::ThisWallsLength().

00467 {
00468     return this->rubber;
00469 }

Here is the caller graph for this function:

gCycleMovement const & gCycleMovement::GetRubber ( REAL rubber  )  const [inline]

Gets the amount rubber used up by the cycle.

Parameters:
rubber the amount rubber used up by the cycle to fill
Returns:
A reference to this to allow chaining

Definition at line 482 of file gCycleMovement.h.

00483 {
00484     rubber = this->rubber;
00485     return *this;
00486 }

unsigned short gCycleMovement::GetTurns ( void   )  const [inline]

Gets the number of turns taken so far.

Returns:
the number of turns taken so far

Definition at line 515 of file gCycleMovement.h.

References turns.

Referenced by gDestination::CopyFrom().

00516 {
00517     return this->turns;
00518 }

Here is the caller graph for this function:

gCycleMovement const & gCycleMovement::GetTurns ( unsigned short &  turns  )  const [inline]

Gets the number of turns taken so far.

Parameters:
turns the number of turns taken so far to fill
Returns:
A reference to this to allow chaining

Definition at line 531 of file gCycleMovement.h.

00532 {
00533     turns = this->turns;
00534     return *this;
00535 }

unsigned short gCycleMovement::GetBraking ( void   )  const [inline]

Gets flag indicating status of brakes ( on/off ).

Returns:
flag indicating status of brakes ( on/off )

Definition at line 564 of file gCycleMovement.h.

References braking.

Referenced by gDestination::CopyFrom().

00565 {
00566     return this->braking;
00567 }

Here is the caller graph for this function:

gCycleMovement const & gCycleMovement::GetBraking ( unsigned short &  braking  )  const [inline]

Gets flag indicating status of brakes ( on/off ).

Parameters:
braking flag indicating status of brakes ( on/off ) to fill
Returns:
A reference to this to allow chaining

Definition at line 580 of file gCycleMovement.h.

00581 {
00582     braking = this->braking;
00583     return *this;
00584 }

REAL gCycleMovement::GetBrakingReservoir ( void   )  const [inline]

Gets the reservoir for braking. 1 means full, 0 is empty.

Returns:
the reservoir for braking. 1 means full, 0 is empty

Definition at line 613 of file gCycleMovement.h.

References brakingReservoir.

00614 {
00615     return this->brakingReservoir;
00616 }

gCycleMovement const & gCycleMovement::GetBrakingReservoir ( REAL brakingReservoir  )  const [inline]

Gets the reservoir for braking. 1 means full, 0 is empty.

Parameters:
brakingReservoir the reservoir for braking. 1 means full, 0 is empty to fill
Returns:
A reference to this to allow chaining

Definition at line 629 of file gCycleMovement.h.

00630 {
00631     brakingReservoir = this->brakingReservoir;
00632     return *this;
00633 }

REAL gCycleMovement::GetRubberMalus ( void   )  const [inline]

Gets additional rubber usage factor.

Returns:
additional rubber usage factor

Definition at line 677 of file gCycleMovement.h.

References rubberMalus.

00678 {
00679     return this->rubberMalus;
00680 }

gCycleMovement const & gCycleMovement::GetRubberMalus ( REAL rubberMalus  )  const [inline]

Gets additional rubber usage factor.

Parameters:
rubberMalus additional rubber usage factor to fill
Returns:
A reference to this to allow chaining

Definition at line 693 of file gCycleMovement.h.

00694 {
00695     rubberMalus = this->rubberMalus;
00696     return *this;
00697 }

bool gCycleMovement::RubberMalusActive ( void   )  [static]

Returns whether rubber malus code is active.

Returns:

Definition at line 4057 of file gCycleMovement.cpp.

References sg_rubberCycleMalusTurn.

Referenced by _wrap_GCycleMovement_rubber_malus_active().

04059 {
04060     return sg_rubberCycleMalusTurn > 0;

Here is the caller graph for this function:

eCoord const & gCycleMovement::GetLastTurnPos ( void   )  const [inline]

Gets the location of the last turn.

Returns:
the location of the last turn

Definition at line 726 of file gCycleMovement.h.

References lastTurnPos_.

Referenced by gCycle::PassEdge(), and gCycle::WriteSync().

00727 {
00728     return this->lastTurnPos_;
00729 }

Here is the caller graph for this function:

gCycleMovement const & gCycleMovement::GetLastTurnPos ( eCoord &  lastTurnPos  )  const [inline]

Gets the location of the last turn.

Parameters:
lastTurnPos the location of the last turn to fill
Returns:
A reference to this to allow chaining

Definition at line 742 of file gCycleMovement.h.

References lastTurnPos_.

00743 {
00744     lastTurnPos = this->lastTurnPos_;
00745     return *this;
00746 }

REAL const & gCycleMovement::GetLastTurnTime ( void   )  const [inline]

Gets the time of the last turn.

Returns:
the time of the last turn

Definition at line 775 of file gCycleMovement.h.

References lastTurnTimeLeft_, and lastTurnTimeRight_.

Referenced by gEnemyInfluence::AddWall(), GetLastTurnTime(), and GetMaxSpaceAhead().

Here is the caller graph for this function:

gCycleMovement const & gCycleMovement::GetLastTurnTime ( REAL lastTurnTime  )  const [inline]

Gets the time of the last turn.

Parameters:
lastTurnTime the time of the last turn to fill
Returns:
A reference to this to allow chaining

Definition at line 791 of file gCycleMovement.h.

References GetLastTurnTime().

00792 {
00793     lastTurnTime = GetLastTurnTime();
00794     return *this;
00795 }

Here is the call graph for this function:

REAL gCycleMovement::GetAcceleration ( void   )  const [inline]

Definition at line 270 of file gCycleMovement.h.

References acceleration.

00270 { return acceleration; };  

void gCycleMovement::AddZoneAcceleration ( REAL  zoneAcceleration  )  [virtual]

Gets the cycle's acceleration.

Definition at line 4139 of file gCycleMovement.cpp.

References totalZoneAcceleration.

04141 {
04142     totalZoneAcceleration += zoneAcceleration;

gCycleMovement & gCycleMovement::SetLastTurnPos ( eCoord const &  lastTurnPos  )  [inline, protected]

Sets the location of the last turn.

Parameters:
lastTurnPos the location of the last turn to set
Returns:
A reference to this to allow chaining

Definition at line 759 of file gCycleMovement.h.

References lastTurnPos_.

00760 {
00761     this->lastTurnPos_ = lastTurnPos;
00762     return *this;
00763 }

gCycleMovement & gCycleMovement::SetLastTurnTime ( REAL const &  lastTurnTime  )  [inline, protected]

Sets the time of the last turn.

Parameters:
lastTurnTime the time of the last turn to set
Returns:
A reference to this to allow chaining

Definition at line 808 of file gCycleMovement.h.

References lastTurnTimeLeft_, and lastTurnTimeRight_.

00809 {
00810     lastTurnTimeRight_ = lastTurnTimeLeft_ = lastTurnTime;
00811     return *this;
00812 }

gCycleMovement & gCycleMovement::SetDistance ( REAL  distance  )  [inline, private]

Sets the distance traveled so far.

Parameters:
distance the distance traveled so far to set
Returns:
A reference to this to allow chaining

Definition at line 450 of file gCycleMovement.h.

00451 {
00452     this->distance = distance;
00453     return *this;
00454 }

gCycleMovement & gCycleMovement::SetRubber ( REAL  rubber  )  [inline]

Sets the amount rubber used up by the cycle.

Parameters:
rubber the amount rubber used up by the cycle to set
Returns:
A reference to this to allow chaining

Definition at line 499 of file gCycleMovement.h.

00500 {
00501     this->rubber = rubber;
00502     return *this;
00503 }

gCycleMovement & gCycleMovement::SetTurns ( unsigned short  turns  )  [inline, private]

Sets the number of turns taken so far.

Parameters:
turns the number of turns taken so far to set
Returns:
A reference to this to allow chaining

Definition at line 548 of file gCycleMovement.h.

00549 {
00550     this->turns = turns;
00551     return *this;
00552 }

gCycleMovement & gCycleMovement::SetBraking ( unsigned short  braking  )  [inline, private]

Sets flag indicating status of brakes ( on/off ).

Parameters:
braking flag indicating status of brakes ( on/off ) to set
Returns:
A reference to this to allow chaining

Definition at line 597 of file gCycleMovement.h.

00598 {
00599     this->braking = braking;
00600     return *this;
00601 }

gCycleMovement & gCycleMovement::SetBrakingReservoir ( REAL  brakingReservoir  )  [inline]

Sets the reservoir for braking. 1 means full, 0 is empty.

Parameters:
brakingReservoir the reservoir for braking. 1 means full, 0 is empty to set
Returns:
A reference to this to allow chaining

Definition at line 646 of file gCycleMovement.h.

00647 {
00648     this->brakingReservoir = brakingReservoir;
00649     return *this;
00650 }

gCycleMovement & gCycleMovement::SetRubberMalus ( REAL  rubberMalus  )  [inline, private]

Sets additional rubber usage factor.

Parameters:
rubberMalus additional rubber usage factor to set
Returns:
A reference to this to allow chaining

Definition at line 710 of file gCycleMovement.h.

00711 {
00712     this->rubberMalus = rubberMalus;
00713     return *this;
00714 }


Member Data Documentation

short gCycleMovement::alive_ [private]

status: 1: cycle is alive, -1: cycle just died, 0: cycle is dead

Definition at line 201 of file gCycleMovement.h.

Referenced by Alive(), Die(), MoveSafely(), and MyInitAfterCreation().

gEnemyInfluence gCycleMovement::enemyInfluence [protected]

keeps track of enemies that influenced this cycle

Definition at line 204 of file gCycleMovement.h.

Referenced by CalculateAcceleration(), gCycle::KillAt(), and gCycle::PassEdge().

gDestination* gCycleMovement::destinationList [protected]

the list of destinations that belong to this cycle ( for memory management )

Definition at line 206 of file gCycleMovement.h.

Referenced by AddDestination(), CopyFrom(), DoIsDestinationUsed(), OnNotifyNewDestination(), gCycle::ReadSync(), Timestep(), gCycle::Timestep(), and ~gCycleMovement().

gDestination* gCycleMovement::currentDestination [protected]

the destination this cycle aims for now

Definition at line 207 of file gCycleMovement.h.

Referenced by CopyFrom(), DoIsDestinationUsed(), GetCurrentDestination(), NextInterestingTime(), OnNotifyNewDestination(), Timestep(), gCycle::Timestep(), TimestepCore(), and ~gCycleMovement().

gDestination* gCycleMovement::lastDestination [protected]

the last destination that was passed

Definition at line 208 of file gCycleMovement.h.

Referenced by DoIsDestinationUsed(), Timestep(), gCycle::WriteSync(), and ~gCycleMovement().

eCoord gCycleMovement::dirDrive [protected]

the direction we are facing

Definition at line 210 of file gCycleMovement.h.

Referenced by CalculateAcceleration(), gCycle::CalculatePredictPosition(), CopyFrom(), Direction(), gCycle::Direction(), DistanceToDestination(), DoGetDistanceSinceLastTurn(), DoTurn(), gCycle::DoTurn(), gCycle::DropWall(), gCycleExtrapolator::EdgeIsDangerous(), gCycle::gCycle(), GetMaxSpaceAhead(), MyInitAfterCreation(), gCycle::MyInitAfterCreation(), gCycle::OnNotifyNewDestination(), gCycle::PassEdge(), gCycle::ReadSync(), gCycle::SyncEnemy(), Timestep(), TimestepCore(), gCycle::TimestepCore(), and gCycle::TransferPositionCorrectionToDistanceCorrection().

eCoord gCycleMovement::dirSpawn [protected]

the direction we were facing on the last spawn

Definition at line 211 of file gCycleMovement.h.

Referenced by gCycle::gCycle(), gCycle::MyInitAfterCreation(), gCycle::ReadSync(), SpawnDirection(), and gCycle::TimestepCore().

eCoord gCycleMovement::lastDirDrive [protected]

the direction we were facing before the last turn

Definition at line 212 of file gCycleMovement.h.

Referenced by DoTurn(), gCycle::DoTurn(), LastDirection(), MyInitAfterCreation(), gCycle::OnDropTempWall(), gCycle::ReadSync(), and gCycle::SyncEnemy().

REAL gCycleMovement::acceleration [protected]

current acceleration

Definition at line 213 of file gCycleMovement.h.

Referenced by ApplyAcceleration(), CalculateAcceleration(), CopyFrom(), GetAcceleration(), MyInitAfterCreation(), gCycle::OnNotifyNewDestination(), Speed(), Timestep(), and TimestepCore().

REAL gCycleMovement::totalZoneAcceleration [protected]

current acceleration from the effect of zones and monitor

Definition at line 214 of file gCycleMovement.h.

Referenced by AddZoneAcceleration(), and CalculateAcceleration().

REAL gCycleMovement::lastTimestep_ [protected]

the length of the last timestep

Definition at line 216 of file gCycleMovement.h.

Referenced by AccelerationDiscontinuity(), ApplyAcceleration(), CopyFrom(), GetMaxSpaceAhead(), Speed(), and gCycle::SyncEnemy().

REAL gCycleMovement::verletSpeed_ [protected]

object speed according to verlet (speed of half a frame ago)

Definition at line 217 of file gCycleMovement.h.

Referenced by AccelerationDiscontinuity(), ApplyAcceleration(), CalculateAcceleration(), gCycle::CalculatePredictPosition(), CopyFrom(), DoTurn(), GetMaxSpaceAhead(), GetTurnDelay(), InitAfterCreation(), MyInitAfterCreation(), gCycle::OnDropTempWall(), gCycle::OnNotifyNewDestination(), gCycle::PassEdge(), gCycle::PreparePredictPosition(), gCycle::ReadSync(), gCycle::Render(), Speed(), gCycle::SyncEnemy(), Timestep(), gCycle::Timestep(), TimestepCore(), gCycle::TimestepCore(), gCycle::WriteSync(), and ~gCycleMovement().

REAL gCycleMovement::distance [protected]

the distance traveled so far

Definition at line 219 of file gCycleMovement.h.

Referenced by CopyFrom(), gCycle::DropWall(), GetDestinationBefore(), GetDistance(), gCycle::Kill(), gCycle::MaxWallsLength(), MyInitAfterCreation(), gCycle::OnNotifyNewDestination(), gBaseZoneHack::OnVanish(), gCycle::PassEdge(), gCycle::ReadSync(), gCycle::SyncEnemy(), gCycle::SyncFromExtrapolator(), gCycle::ThisWallsLength(), gBaseZoneHack::Timestep(), TimestepCore(), gCycleExtrapolator::TimestepCore(), gCycle::TransferPositionCorrectionToDistanceCorrection(), gCycle::WallEndSpeed(), gCycle::WriteSync(), and ~gCycleMovement().

bool gCycleMovement::refreshSpaceAhead_ [mutable, protected]

flag to set when maximum space in front of cycle should be recalculated

Definition at line 222 of file gCycleMovement.h.

Referenced by DoTurn(), GetMaxSpaceAhead(), MyInitAfterCreation(), and Timestep().

REAL gCycleMovement::maxSpaceMaxCast_ [protected]

the maximum raycast length to determine the above value

Definition at line 223 of file gCycleMovement.h.

Referenced by GetMaxSpaceAhead(), MyInitAfterCreation(), and gCycle::PreparePredictPosition().

gMaxSpaceAheadHitInfo* gCycleMovement::maxSpaceHit_ [mutable, protected]

detailed information about the wall in front

Definition at line 224 of file gCycleMovement.h.

Referenced by GetMaxSpaceAhead(), MyInitAfterCreation(), OnRemoveFromGame(), Timestep(), gCycle::Timestep(), TimestepCore(), and ~gCycleMovement().

unsigned short gCycleMovement::turns [protected]

the number of turns taken so far

Definition at line 226 of file gCycleMovement.h.

Referenced by CopyFrom(), DoTurn(), gCycle::DoTurn(), GetTurns(), MyInitAfterCreation(), gCycle::ReadSync(), gCycle::SyncEnemy(), Timestep(), and gCycle::WriteSync().

unsigned short gCycleMovement::braking [protected]

flag indicating status of brakes ( on/off )

Definition at line 227 of file gCycleMovement.h.

Referenced by gCycle::Act(), CalculateAcceleration(), CopyFrom(), DistanceToDestination(), GetBraking(), GetDestinationBefore(), MyInitAfterCreation(), gCycle::ReadSync(), Timestep(), and gCycle::WriteSync().

int gCycleMovement::windingNumber_ [protected]

number that gets increased on every right turn and decreased on every left turn ( used by the AI )

Definition at line 229 of file gCycleMovement.h.

Referenced by CopyFrom(), gCycle::gCycle(), gCycleMovement(), SetWindingNumberWrapped(), WindingNumber(), and gCycle::WindingNumber().

int gCycleMovement::windingNumberWrapped_ [protected]

winding number wrapped to be used as an index to the axes code

Definition at line 230 of file gCycleMovement.h.

Referenced by CopyFrom(), DistanceToDestination(), DoTurn(), gCycle::gCycle(), gCycleMovement(), GetMaxSpaceAhead(), gCycle::ReadSync(), SetWindingNumberWrapped(), and Timestep().

REAL gCycleMovement::gap_[2] [mutable, protected]

when driving towards a wall, this is set to the maximal distance we need to approach it so that when the cycle turns, it can squeeze through any gaps

Definition at line 232 of file gCycleMovement.h.

Referenced by DoTurn(), GetMaxSpaceAhead(), and MyInitAfterCreation().

bool gCycleMovement::keepLookingForGap_[2] [mutable, protected]

flags telling the system whether it is worthwile to look for further, smaller, gaps

Definition at line 233 of file gCycleMovement.h.

Referenced by DoTurn(), GetMaxSpaceAhead(), and MyInitAfterCreation().

eCoord gCycleMovement::lastTurnPos_ [protected]

the location of the last turn

Definition at line 235 of file gCycleMovement.h.

Referenced by gCycleExtrapolator::CopyFrom(), DoGetDistanceSinceLastTurn(), DoTurn(), GetLastTurnPos(), MyInitAfterCreation(), gCycle::ReadSync(), SetLastTurnPos(), gCycle::SyncFromExtrapolator(), and gCycle::TimestepCore().

REAL gCycleMovement::lastTurnTimeRight_ [protected]

the time of the last turn right

Definition at line 236 of file gCycleMovement.h.

Referenced by CopyFrom(), DoTurn(), GetLastTurnTime(), GetNextTurn(), MyInitAfterCreation(), SetLastTurnTime(), and TimestepCore().

REAL gCycleMovement::lastTurnTimeLeft_ [protected]

the time of the last turn left

Definition at line 237 of file gCycleMovement.h.

Referenced by CopyFrom(), DoTurn(), GetLastTurnTime(), GetNextTurn(), MyInitAfterCreation(), SetLastTurnTime(), and TimestepCore().

REAL gCycleMovement::lastTimeAlive_ [protected]

the time of the last timestep where we would not have been killed

Definition at line 238 of file gCycleMovement.h.

Referenced by MyInitAfterCreation(), and TimestepCore().

std::deque<int> gCycleMovement::pendingTurns [protected]

stores turns ordered by the user, but not yet executed

Definition at line 239 of file gCycleMovement.h.

Referenced by CanMakeTurn(), DoTurn(), MyInitAfterCreation(), Timestep(), and gCycle::Timestep().

REAL gCycleMovement::brakingReservoir [protected]

the reservoir for braking. 1 means full, 0 is empty

Definition at line 241 of file gCycleMovement.h.

Referenced by CalculateAcceleration(), CopyFrom(), GetBrakingReservoir(), MyInitAfterCreation(), gCycle::ReadSync(), gCycle::SyncEnemy(), TimestepCore(), and gCycle::WriteSync().

REAL gCycleMovement::rubber [protected]

the amount rubber used up by the cycle

Definition at line 242 of file gCycleMovement.h.

Referenced by CopyFrom(), gCycle::gCycle(), GetRubber(), MyInitAfterCreation(), gCycle::OnNotifyNewDestination(), gCycle::PassEdge(), gCycle::ReadSync(), gCycle::SyncEnemy(), Timestep(), TimestepCore(), and gCycle::WriteSync().

REAL gCycleMovement::rubberMalus [protected]

additional rubber usage factor

Definition at line 243 of file gCycleMovement.h.

Referenced by CopyFrom(), DoTurn(), GetRubberMalus(), MyInitAfterCreation(), TimestepCore(), and gCycle::WriteSync().

REAL gCycleMovement::rubberSpeedFactor [protected]

the factor by which the speed is currently multiplied by rubber

Definition at line 244 of file gCycleMovement.h.

Referenced by DoTurn(), GetMaxSpaceAhead(), MyInitAfterCreation(), gCycle::OnNotifyNewDestination(), gCycle::PreparePredictPosition(), Timestep(), TimestepCore(), gCycle::TimestepCore(), and gCycle::WallEndSpeed().

REAL gCycleMovement::brakeUsage [protected]

current brake usage

Definition at line 246 of file gCycleMovement.h.

Referenced by CalculateAcceleration(), and TimestepCore().

REAL gCycleMovement::rubberUsage [protected]

current rubber usage (not from hitting a wall, but from tunneling. Without taking efficiency into account.)

Definition at line 247 of file gCycleMovement.h.

Referenced by CalculateAcceleration(), and TimestepCore().


The documentation for this class was generated from the following files:
Generated on Sat Mar 15 23:38:38 2008 for Armagetron Advanced by  doxygen 1.5.4