#include <gCycleMovement.h>
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 | |
gDestination * | GetCurrentDestination () 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. | |
gCycleMovement & | SetRubber (REAL rubber) |
Sets the amount rubber used up by the cycle. | |
gCycleMovement & | SetBrakingReservoir (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 | |
gCycleMovement & | SetLastTurnPos (eCoord const &lastTurnPos) |
Sets the location of the last turn. | |
gCycleMovement & | SetLastTurnTime (REAL const &lastTurnTime) |
Sets the time of the last turn. | |
Static Protected Member Functions | |
static gDestination * | GetDestinationBefore (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 | |
gDestination * | destinationList |
the list of destinations that belong to this cycle ( for memory management ) | |
gDestination * | currentDestination |
the destination this cycle aims for now | |
gDestination * | lastDestination |
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 | |
gMaxSpaceAheadHitInfo * | maxSpaceHit_ |
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 | |
gCycleMovement & | operator= (gCycleMovement const &other) |
copy operator | |
gCycleMovement & | SetDistance (REAL distance) |
Sets the distance traveled so far. | |
gCycleMovement & | SetTurns (unsigned short turns) |
Sets the number of turns taken so far. | |
gCycleMovement & | SetBraking (unsigned short braking) |
Sets flag indicating status of brakes ( on/off ). | |
gCycleMovement & | SetRubberMalus (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... |
Definition at line 76 of file gCycleMovement.h.
gCycleMovement::gCycleMovement | ( | eGrid * | grid, | |
const eCoord & | pos, | |||
const eCoord & | dir, | |||
ePlayerNetID * | player = NULL , |
|||
bool | autodelete = 1 | |||
) |
local constructor
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_.
02491 :eNetGameObject(grid, pos,dir,player,autodelete), 02492 destinationList(NULL),currentDestination(NULL),lastDestination(NULL), 02493 dirDrive(dir), 02494 acceleration(0), 02495 totalZoneAcceleration(0), 02496 lastTimestep_(0), 02497 verletSpeed_(sg_speedCycleStart * SpeedMultiplier()), 02498 pendingTurns() 02499 { 02500 windingNumberWrapped_ = windingNumber_ = Grid()->DirectionWinding(dir); 02501 02502 MyInitAfterCreation();
gCycleMovement::gCycleMovement | ( | nMessage & | message | ) |
remote constructor
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
float gCycleMovement::RubberSpeed | ( | ) | [static] |
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;
float gCycleMovement::SpeedMultiplier | ( | void | ) | [static] |
returns the current speed multiplier
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;
void gCycleMovement::SetSpeedMultiplier | ( | REAL | mul | ) | [static] |
sets the current speed multiplier
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 );
float gCycleMovement::MaximalSpeed | ( | void | ) | [static] |
returns the maximal speed a cycle can reach on its own
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;
int gCycleMovement::WindingNumber | ( | void | ) | const |
returns the current winding number
Reimplemented in gCycle.
Definition at line 878 of file gCycleMovement.cpp.
References windingNumber_.
Referenced by blocks(), SetWindingNumberWrapped(), and gJoystick::Turn().
00880 { 00881 return windingNumber_;
void gCycleMovement::SetWindingNumberWrapped | ( | int | newWindingNumberWrapped | ) |
sets the new wrapped winding number
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;
eCoord gCycleMovement::Direction | ( | void | ) | const [virtual] |
returns the current 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;
eCoord gCycleMovement::LastDirection | ( | void | ) | const [virtual] |
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;
REAL gCycleMovement::Speed | ( | void | ) | const [virtual] |
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;
bool gCycleMovement::Alive | ( | ) | const [virtual] |
returns whether 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;
bool gCycleMovement::Vulnerable | ( | ) | const [virtual] |
returns whether the cycle can be killed
Reimplemented in gCycle.
Definition at line 986 of file gCycleMovement.cpp.
Referenced by TimestepCore().
eCoord gCycleMovement::SpawnDirection | ( | ) | const [virtual] |
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;
bool gCycleMovement::CanMakeTurn | ( | int | direction | ) | const |
returns whether a turn is currently possible
direction | the direction of the planned turn |
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 );
bool gCycleMovement::CanMakeTurn | ( | REAL | time, | |
int | direction | |||
) | const |
returns whether a turn is possible at the given time
time | the time to check | |
direction | the direction of the planned turn |
Definition at line 1019 of file gCycleMovement.cpp.
References GetNextTurn().
01021 { 01022 return time >= GetNextTurn(direction);
REAL gCycleMovement::GetDistanceSinceLastTurn | ( | void | ) | const [inline] |
returns the distance 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 }
REAL gCycleMovement::GetTurnDelay | ( | void | ) | const |
returns the time between turns in different directions
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 );
REAL gCycleMovement::GetTurnDelayDb | ( | void | ) | const |
returns the time between turns in the same direcion
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 );
REAL gCycleMovement::GetNextTurn | ( | int | direction | ) | const |
returns the time of the next 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;
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 }
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
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);
gDestination * gCycleMovement::GetCurrentDestination | ( | void | ) | const |
returns the current destination
Definition at line 1149 of file gCycleMovement.cpp.
References currentDestination.
Referenced by gCycleExtrapolator::TimestepCore().
01151 { 01152 return currentDestination;
void gCycleMovement::NotifyNewDestination | ( | gDestination * | dest | ) |
notifies cycle of the insertion of a new destination ( don't call manually )
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 );
bool gCycleMovement::IsDestinationUsed | ( | const gDestination * | dest | ) | const [inline] |
returns whether the given destination is in active use
dest | the destination to test |
Definition at line 384 of file gCycleMovement.h.
References DoIsDestinationUsed().
Referenced by Timestep().
00385 { 00386 // delegate to virtual function 00387 return DoIsDestinationUsed( dest ); 00388 }
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.
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 }
returns whether a given wall is dangerous to this cycle
wall | the wall to check for danger | |
time | the time of the possible collision | |
alpha | the local wall coordinate of the collision |
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.
bool gCycleMovement::Turn | ( | REAL | dir | ) |
Turn left for positive argument, right for negative argument.
dir | negative for left turns, positive for right turns |
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;
bool gCycleMovement::Turn | ( | int | dir | ) |
Turn left for positive argument, right for negative argument.
dir | +1 for right turns, -1 for left turns |
Definition at line 1453 of file gCycleMovement.cpp.
References DoTurn().
move without throwing exceptions on passing a wall
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 }
bool gCycleMovement::Timestep | ( | REAL | currentTime | ) | [virtual] |
advance to the given time
currentTime | the time to simulate up to |
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;
REAL gCycleMovement::NextInterestingTime | ( | void | ) | const [virtual] |
the next time something interesting is going to happen with this object
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;
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 }
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();
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 );
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 );
void gCycleMovement::CopyFrom | ( | const gCycleMovement & | other | ) | [protected] |
copies relevant info from other cylce
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;
void gCycleMovement::CopyFrom | ( | const SyncData & | sync, | |
const gCycleMovement & | other | |||
) | [protected] |
copies relevant info from sync data and everything else from other cycle
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;
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();
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;
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 );
void gCycleMovement::ApplyAcceleration | ( | REAL | dt | ) | [protected, virtual] |
apply acceleration calculated earlier
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 );
REAL gCycleMovement::DistanceToDestination | ( | gDestination & | dest | ) | const [protected] |
calculates the distance to the given destination
dest | the destination to measure the distance to |
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;
void gCycleMovement::OnNotifyNewDestination | ( | gDestination * | dest | ) | [protected, virtual] |
notifies cycle of the insertion of a new destination
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 }
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.
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().
bool gCycleMovement::DoIsDestinationUsed | ( | const gDestination * | dest | ) | const [protected, virtual] |
returns whether the given destination is in active use
dest | the destination to test |
Reimplemented in gCycle.
Definition at line 1195 of file gCycleMovement.cpp.
References currentDestination, destinationList, and lastDestination.
Referenced by gCycle::DoIsDestinationUsed(), and IsDestinationUsed().
01197 { 01198 return ( destinationList == currentDestination || destinationList == lastDestination );
gDestination * gCycleMovement::GetDestinationBefore | ( | const SyncData & | sync, | |
gDestination * | first | |||
) | [static, protected] |
determine the destination from before the sync message
sync | the sync data received from the server | |
first | the first candidate for the return value |
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 }
bool gCycleMovement::DoTurn | ( | int | dir | ) | [protected, virtual] |
turns the cycle in the given direction
dir | +1 for right turns, -1 for left turns |
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;
REAL gCycleMovement::DoGetDistanceSinceLastTurn | ( | void | ) | const [protected, virtual] |
returns the distance since the last turn
other | ||
other |
other |
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();
void gCycleMovement::RightBeforeDeath | ( | int | numTries | ) | [protected, virtual] |
called when the cycle is very close to a wall and about to crash
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().
void gCycleMovement::Die | ( | REAL | time | ) | [protected, virtual] |
dies at the specified time
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 }
bool gCycleMovement::TimestepCore | ( | REAL | currentTime, | |
bool | calculateAcceleration = true | |||
) | [protected, virtual] |
core physics simulation routine
currentTime | time to simulate up to |
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);
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
gCycleMovement & gCycleMovement::operator= | ( | gCycleMovement const & | other | ) | [private] |
copy operator
other | the source to copy from | |
other | the source to copy from |
Definition at line 684 of file gCycleMovement.cpp.
References CopyFrom().
00686 { 00687 this->CopyFrom( other ); 00688 return *this;
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.
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 |
maxReport | maximal distance to report |
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;
REAL gCycleMovement::GetDistance | ( | void | ) | const [inline] |
Gets 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 }
gCycleMovement const & gCycleMovement::GetDistance | ( | REAL & | distance | ) | const [inline] |
Gets the distance traveled so far.
distance | the distance traveled so far to fill |
Definition at line 433 of file gCycleMovement.h.
REAL gCycleMovement::GetRubber | ( | void | ) | const [inline] |
Gets 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 }
gCycleMovement const & gCycleMovement::GetRubber | ( | REAL & | rubber | ) | const [inline] |
Gets the amount rubber used up by the cycle.
rubber | the amount rubber used up by the cycle to fill |
Definition at line 482 of file gCycleMovement.h.
unsigned short gCycleMovement::GetTurns | ( | void | ) | const [inline] |
Gets 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 }
gCycleMovement const & gCycleMovement::GetTurns | ( | unsigned short & | turns | ) | const [inline] |
Gets the number of turns taken so far.
turns | the number of turns taken so far to fill |
Definition at line 531 of file gCycleMovement.h.
unsigned short gCycleMovement::GetBraking | ( | void | ) | const [inline] |
Gets 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 }
gCycleMovement const & gCycleMovement::GetBraking | ( | unsigned short & | braking | ) | const [inline] |
Gets flag indicating status of brakes ( on/off ).
braking | flag indicating status of brakes ( on/off ) to fill |
Definition at line 580 of file gCycleMovement.h.
REAL gCycleMovement::GetBrakingReservoir | ( | void | ) | const [inline] |
Gets 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.
brakingReservoir | the reservoir for braking. 1 means full, 0 is empty to fill |
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.
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.
rubberMalus | additional rubber usage factor to fill |
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.
Definition at line 4057 of file gCycleMovement.cpp.
References sg_rubberCycleMalusTurn.
Referenced by _wrap_GCycleMovement_rubber_malus_active().
04059 { 04060 return sg_rubberCycleMalusTurn > 0;
eCoord const & gCycleMovement::GetLastTurnPos | ( | void | ) | const [inline] |
Gets 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 }
gCycleMovement const & gCycleMovement::GetLastTurnPos | ( | eCoord & | lastTurnPos | ) | const [inline] |
Gets the location of the last turn.
lastTurnPos | the location of the last turn to fill |
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.
Definition at line 775 of file gCycleMovement.h.
References lastTurnTimeLeft_, and lastTurnTimeRight_.
Referenced by gEnemyInfluence::AddWall(), GetLastTurnTime(), and GetMaxSpaceAhead().
00776 { 00777 return lastTurnTimeRight_ > lastTurnTimeLeft_ ? lastTurnTimeRight_ : lastTurnTimeLeft_; 00778 }
gCycleMovement const & gCycleMovement::GetLastTurnTime | ( | REAL & | lastTurnTime | ) | const [inline] |
Gets the time of the last turn.
lastTurnTime | the time of the last turn to fill |
Definition at line 791 of file gCycleMovement.h.
References GetLastTurnTime().
00792 { 00793 lastTurnTime = GetLastTurnTime(); 00794 return *this; 00795 }
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.
lastTurnPos | the location of the last turn to set |
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.
lastTurnTime | the time of the last turn to set |
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.
distance | the distance traveled so far to set |
Definition at line 450 of file gCycleMovement.h.
gCycleMovement & gCycleMovement::SetRubber | ( | REAL | rubber | ) | [inline] |
Sets the amount rubber used up by the cycle.
rubber | the amount rubber used up by the cycle to set |
Definition at line 499 of file gCycleMovement.h.
gCycleMovement & gCycleMovement::SetTurns | ( | unsigned short | turns | ) | [inline, private] |
Sets the number of turns taken so far.
turns | the number of turns taken so far to set |
Definition at line 548 of file gCycleMovement.h.
gCycleMovement & gCycleMovement::SetBraking | ( | unsigned short | braking | ) | [inline, private] |
Sets flag indicating status of brakes ( on/off ).
braking | flag indicating status of brakes ( on/off ) to set |
Definition at line 597 of file gCycleMovement.h.
gCycleMovement & gCycleMovement::SetBrakingReservoir | ( | REAL | brakingReservoir | ) | [inline] |
Sets the reservoir for braking. 1 means full, 0 is empty.
brakingReservoir | the reservoir for braking. 1 means full, 0 is empty to set |
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.
rubberMalus | additional rubber usage factor to set |
Definition at line 710 of file gCycleMovement.h.
00711 { 00712 this->rubberMalus = rubberMalus; 00713 return *this; 00714 }
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().