#include <gCycle.h>
Public Member Functions | |
virtual void | Die (REAL time) |
dies at the specified time | |
void | KillAt (const eCoord &pos) |
kill this cycle at the given position and take care of scoring | |
int | WindingNumber () const |
returns the current winding number | |
virtual bool | Vulnerable () const |
returns whether the cycle can be killed | |
virtual void | InitAfterCreation () |
shared initialization routine | |
gCycle (eGrid *grid, const eCoord &pos, const eCoord &dir, ePlayerNetID *p=NULL) | |
REAL | MaxWallsLength () const |
the maximum total length of the walls (including max effect of rubber growth) | |
REAL | ThisWallsLength () const |
the maximum total length of this cycle's wall (including rubber shrink) | |
REAL | WallEndSpeed () const |
the speed the end of the trail is receeding with right now | |
bool | IsMe (eGameObject const *other) const |
checks whether the passed pointer is logically identical with this cycle | |
gCycle (nMessage &m) | |
virtual void | WriteCreate (nMessage &m) |
virtual void | WriteSync (nMessage &m) |
virtual void | ReadSync (nMessage &m) |
virtual void | RequestSyncOwner () |
requests special syncs to the owner on important points (just passed an enemy trail end safely...) | |
virtual void | RequestSyncAll () |
requests special syncs to everyone on important points (just passed an enemy trail end safely...) | |
virtual void | SyncEnemy (const eCoord &begWall) |
handle sync message for enemy cycles | |
virtual void | ReceiveControl (REAL time, uActionPlayer *Act, REAL x) |
virtual void | PrintName (tString &s) const |
virtual bool | ActionOnQuit () |
virtual nDescriptor & | CreatorDescriptor () const |
virtual bool | SyncIsNew (nMessage &m) |
virtual bool | Timestep (REAL currentTime) |
advance to the given time | |
virtual bool | TimestepCore (REAL currentTime, bool calculateAcceleration=true) |
core physics simulation routine | |
virtual void | InteractWith (eGameObject *target, REAL time, int recursion=1) |
virtual bool | EdgeIsDangerous (const eWall *w, REAL time, REAL a) const |
returns whether a given wall is dangerous to this cycle | |
virtual void | PassEdge (const eWall *w, REAL time, REAL a, int recursion=1) |
virtual REAL | PathfindingModifier (const eWall *w) const |
virtual bool | Act (uActionPlayer *Act, REAL x) |
virtual bool | DoTurn (int dir) |
turns the cycle in the given direction | |
void | DropWall (bool buildNew=true) |
Drops the current wall and builds a new one. | |
virtual void | Kill () |
destroys the gameobject (in the game) | |
const eTempEdge * | Edge () |
const gPlayerWall * | CurrentWall () |
virtual void | Render (const eCamera *cam) |
draws object to the screen using OpenGL | |
virtual void | Render2D (tCoord scale) const |
virtual void | RenderName (const eCamera *cam) |
virtual bool | RenderCockpitFixedBefore (bool primary=true) |
virtual eCoord | CamPos () const |
virtual eCoord | PredictPosition () const |
virtual eCoord | CamTop () const |
virtual eCoord | CamDir () const |
virtual eCoord | Direction () const |
returns the current driving direction | |
virtual void | RightBeforeDeath (int numTries) |
called when the cycle is very close to a wall and about to crash | |
Static Public Member Functions | |
static void | SetWallsStayUpDelay (REAL delay) |
the time the cycle walls stay up ( negative values: they stay up forever ) | |
static void | SetWallsLength (REAL length) |
the maximum total length of the walls | |
static void | SetExplosionRadius (REAL radius) |
the radius of the holes blewn in by an explosion | |
static REAL | WallsStayUpDelay () |
the time the cycle walls stay up ( negative values: they stay up forever ) | |
static REAL | WallsLength () |
the default total length of the walls | |
static REAL | ExplosionRadius () |
the radius of the holes blewn in by an explosion | |
static void | PrivateSettings () |
Public Attributes | |
eCoord | lastGoodPosition_ |
REAL | skew |
REAL | skewDot |
bool | mp |
rModel * | body |
rModel * | front |
rModel * | rear |
rModel * | customModel |
gTextureCycle * | wheelTex |
gTextureCycle * | bodyTex |
gTextureCycle * | customTexture |
eCoord | rotationFrontWheel |
eCoord | rotationRearWheel |
REAL | heightFrontWheel |
REAL | heightRearWheel |
gCycleMemory | memory |
gRealColor | color_ |
gRealColor | trailColor_ |
eCoord | correctPosSmooth |
eCoord | predictPosition_ |
the best guess of where the cycle is at at display time | |
REAL | correctDistanceSmooth |
Static Public Attributes | |
static uActionPlayer | s_brake |
Protected Member Functions | |
virtual | ~gCycle () |
virtual void | OnRemoveFromGame () |
called on RemoveFromGame(). Call base class implementation, too, in your implementation. Must keep the object alive. | |
virtual void | OnRoundEnd () |
called when the round ends | |
virtual bool | DoIsDestinationUsed (const gDestination *dest) const |
returns whether the given destination is in active use | |
Private Member Functions | |
void | TransferPositionCorrectionToDistanceCorrection () |
tCHECKED_PTR (gNetPlayerWall) currentWall | |
the wall that currenly is attached to the cycle | |
tCHECKED_PTR (gNetPlayerWall) lastWall | |
the last wall that was attached to this cycle | |
tCHECKED_PTR (gNetPlayerWall) lastNetWall | |
the last wall received over the network | |
void | ResetExtrapolator () |
bool | Extrapolate (REAL dt) |
void | SyncFromExtrapolator () |
virtual void | OnNotifyNewDestination (gDestination *dest) |
called when a destination is successfully inserted into the destination list | |
virtual void | OnDropTempWall (gPlayerWall *wall, eCoord const &position, eCoord const &direction) |
called when another cycle grinds a wall; this cycle should then drop its current wall if the grinding is too close. | |
void | MyInitAfterCreation () |
private shared initialization code | |
void | SetCurrentWall (gNetPlayerWall *w) |
void | PreparePredictPosition (gPredictPositionData &data) |
prepares CalculatePredictPosition() call, requesting a raycast to the front | |
REAL | CalculatePredictPosition (gPredictPositionData &data) |
Calculates predictPosition_. | |
Private Attributes | |
REAL | spawnTime_ |
time the cycle spawned at | |
REAL | lastTimeAnim |
last time animation was simulated at | |
REAL | timeCameIntoView |
std::auto_ptr< gCycleChatBot > | chatBot_ |
bool | dropWallRequested_ |
flag indicating that someone requested a wall drop | |
gCycleWallsDisplayListManager | displayList_ |
display list manager | |
SyncData | lastSyncMessage_ |
tJUST_CONTROLLED_PTR < gCycleExtrapolator > | extrapolator_ |
bool | resimulate_ |
nTimeRolling | nextSync |
nTimeRolling | nextSyncOwner |
gJoystick * | joystick_ |
joystick control | |
Static Private Attributes | |
static REAL | wallsStayUpDelay = 8.0f |
the time the cycle walls stay up ( negative values: they stay up forever ) | |
static REAL | wallsLength = -1.0f |
the maximum total length of the walls | |
static REAL | explosionRadius = 4.0f |
the radius of the holes blewn in by an explosion | |
Friends | |
class | gPlayerWall |
class | gNetPlayerWall |
class | gDestination |
class | gCycleWallRenderer |
class | gCycleChatBot |
Definition at line 149 of file gCycle.h.
gCycle::~gCycle | ( | ) | [protected, virtual] |
Definition at line 2331 of file gCycle.cpp.
References body, bodyTex, customModel, customTexture, CYCLE_MOTOR, front, eSoundMixer::GetMixer(), mp, rear, eSoundMixer::RemoveContinuous(), eGameObject::RemoveFromGame(), and wheelTex.
02332 { 02333 #ifdef DEBUG 02334 // con << "deleting cylce...\n"; 02335 #endif 02336 // clear the destination list 02337 02338 eSoundMixer* mixer = eSoundMixer::GetMixer(); 02339 mixer->RemoveContinuous(CYCLE_MOTOR, this); 02340 02341 this->RemoveFromGame(); 02342 02343 if (mp){ 02344 delete customModel; 02345 delete customTexture; 02346 } 02347 else{ 02348 delete body; 02349 delete front; 02350 delete rear; 02351 delete wheelTex; 02352 delete bodyTex; 02353 } 02354 #ifdef DEBUG 02355 //con << "Deleted cycle.\n"; 02356 #endif 02357 /* 02358 delete currentPos; 02359 delete last_turn; 02360 */
gCycle::gCycle | ( | eGrid * | grid, | |
const eCoord & | pos, | |||
const eCoord & | dir, | |||
ePlayerNetID * | p = NULL | |||
) |
Definition at line 2308 of file gCycle.cpp.
References eGameObject::deathTime, eGameObject::dir, gCycleMovement::dirDrive, eGrid::DirectionWinding(), eGrid::GetDirection(), eGameObject::Grid(), MyInitAfterCreation(), NULL, sg_ArchiveCoord(), sg_ArchiveReal(), gCycleMovement::windingNumber_, and gCycleMovement::windingNumberWrapped_.
02310 :gCycleMovement(grid, pos,d,p,false), 02311 skew(0),skewDot(0), 02312 rotationFrontWheel(1,0),rotationRearWheel(1,0),heightFrontWheel(0),heightRearWheel(0), 02313 currentWall(NULL), 02314 lastWall(NULL) 02315 { 02316 windingNumberWrapped_ = windingNumber_ = Grid()->DirectionWinding(dirDrive); 02317 dirDrive = Grid()->GetDirection(windingNumberWrapped_); 02318 dir = dirDrive; 02319 02320 deathTime=0; 02321 02322 lastNetWall=lastWall=currentWall=NULL; 02323 02324 MyInitAfterCreation(); 02325 02326 sg_ArchiveCoord( this->dirDrive, 1 ); 02327 sg_ArchiveCoord( this->dir, 1 ); 02328 sg_ArchiveCoord( this->pos, 1 ); 02329 sg_ArchiveReal( this->verletSpeed_, 1 );
gCycle::gCycle | ( | nMessage & | m | ) |
Definition at line 4878 of file gCycle.cpp.
References gRealColor::b, color_, correctDistanceSmooth, eGameObject::deathTime, eGameObject::dir, gCycleMovement::dirDrive, eGrid::DirectionWinding(), gCycleMovement::dirSpawn, EPS, gRealColor::g, eGrid::GetDirection(), eGameObject::Grid(), eGameObject::lastTime, lastTimeAnim, nextSync, nextSyncOwner, NULL, gRealColor::r, gCycleMovement::rubber, se_GameTime(), se_MakeColorValid(), spawnTime_, trailColor_, gCycleMovement::windingNumber_, and gCycleMovement::windingNumberWrapped_.
04878 : 04879 gCycle::gCycle(nMessage &m) 04880 :gCycleMovement(m), 04881 skew(0),skewDot(0), 04882 rotationFrontWheel(1,0),rotationRearWheel(1,0),heightFrontWheel(0),heightRearWheel(0), 04883 currentWall(NULL), 04884 lastWall(NULL) 04885 { 04886 deathTime=0; 04887 lastNetWall=lastWall=currentWall=NULL; 04888 windingNumberWrapped_ = windingNumber_ = Grid()->DirectionWinding(dirDrive); 04889 dirDrive = Grid()->GetDirection(windingNumberWrapped_); 04890 dir = dirDrive; 04891 04892 rubber=0; 04893 //correctTimeSmooth =0; 04894 correctDistanceSmooth =0; 04895 //correctSpeedSmooth =0; 04896 04897 deathTime = 0; 04898 spawnTime_ = se_GameTime() + 100; 04899 dirSpawn = dirDrive; 04900 04901 04902 m >> color_.r; 04903 m >> color_.g; 04904 m >> color_.b; 04905 04906 trailColor_ = color_; 04907 04908 se_MakeColorValid( color_.r, color_.g, color_.b, 1.0f ); 04909 se_MakeColorValid( trailColor_.r, trailColor_.g, trailColor_.b, .5f ); 04910 04911 // set last time so that the first read_sync will not think this is old 04912 lastTimeAnim = lastTime = -EPS; 04913 04914 nextSync = nextSyncOwner = -1; }
void gCycle::TransferPositionCorrectionToDistanceCorrection | ( | ) | [private] |
Definition at line 5158 of file gCycle.cpp.
References correctDistanceSmooth, correctPosSmooth, gCycleMovement::dirDrive, gCycleMovement::distance, and REAL.
Referenced by Die(), SyncFromExtrapolator(), and TimestepCore().
05160 { 05161 REAL newCorrectDist = eCoord::F( correctPosSmooth, dirDrive ); 05162 distance += newCorrectDist - correctDistanceSmooth; 05163 correctDistanceSmooth = newCorrectDist;
gCycle::tCHECKED_PTR | ( | gNetPlayerWall | ) | [private] |
the wall that currenly is attached to the cycle
gCycle::tCHECKED_PTR | ( | gNetPlayerWall | ) | [private] |
the last wall that was attached to this cycle
gCycle::tCHECKED_PTR | ( | gNetPlayerWall | ) | [private] |
the last wall received over the network
void gCycle::ResetExtrapolator | ( | ) | [private] |
Definition at line 5055 of file gCycle.cpp.
References eGameObject::dir, extrapolator_, lastSyncMessage_, eGameObject::pos, resimulate_, and tNEW.
Referenced by PassEdge(), and Timestep().
05057 { 05058 resimulate_ = false; 05059 if (!extrapolator_) 05060 { 05061 extrapolator_ = tNEW( gCycleExtrapolator )(grid, pos, dir ); 05062 } 05063 05064 extrapolator_->CopyFrom( lastSyncMessage_, *this ); 05065 05066 // simulate a bit, only to get current rubberSpeedFactor and acceleration 05067 extrapolator_->TimestepCore( extrapolator_->LastTime(), true );
bool gCycle::Extrapolate | ( | REAL | dt | ) | [private] |
Definition at line 5070 of file gCycle.cpp.
References eCoord, extrapolator_, eGameObject::lastTime, gDestination::list, REAL, tASSERT, and eGameObject::TimestepThis().
Referenced by PassEdge(), and Timestep().
05072 { 05073 tASSERT( extrapolator_ ); 05074 05075 eCoord posBefore = extrapolator_->Position(); 05076 05077 // calculate target time 05078 REAL newTime = extrapolator_->LastTime() + dt; 05079 05080 bool ret = false; 05081 05082 // clamp: don't simulate further than our current time 05083 if ( newTime >= lastTime ) 05084 { 05085 // simulate extrapolator until now 05086 eGameObject::TimestepThis( lastTime, extrapolator_ ); 05087 05088 // test if there are real (the check for list does that) destinations left; we cannot call it finished if there are. 05089 gDestination* unhandledDestination = extrapolator_->GetCurrentDestination(); 05090 ret = !unhandledDestination || !unhandledDestination->list; 05091 05092 newTime = lastTime; 05093 } 05094 else 05095 { 05096 // simulate extrapolator as requested 05097 eGameObject::TimestepThis( newTime, extrapolator_ ); 05098 } 05099 05100 //eCoord posAfter = extrapolator_->Position(); 05101 //eDebugLine::SetTimeout( 1.0 ); 05102 //eDebugLine::SetColor( 1,0,0 ); 05103 //eDebugLine::Draw( posBefore, 8, posAfter, 4 ); 05104 //eDebugLine::Draw( posBefore, 4, posAfter, 4 ); 05105 05106 return ret;
void gCycle::SyncFromExtrapolator | ( | ) | [private] |
Definition at line 5166 of file gCycle.cpp.
References gCycleMovement::CopyFrom(), correctDistanceSmooth, correctPosSmooth, gCycleMovement::distance, dt, eCoord, extrapolator_, eGameObject::LastTime(), gCycleMovement::lastTurnPos_, gPlayerWallCoord::Pos, eGameObject::pos, REAL, resimulate_, sg_cycleWallTime, spawnTime_, tASSERT, and TransferPositionCorrectionToDistanceCorrection().
Referenced by Timestep().
05168 { 05169 // store old position 05170 eCoord oldPos = pos; 05171 05172 // con << "Copy: " << LastTime() << ", " << extrapolator_->LastTime() << ", " << extrapolator_->Position() << ", " << pos << "\n"; 05173 05174 tASSERT( extrapolator_ ); 05175 05176 // delegate 05177 CopyFrom( *extrapolator_ ); 05178 05179 // adjust current wall (not essential, don't do it for the first wall) 05180 if ( currentWall && currentWall->tBeg > spawnTime_ + sg_cycleWallTime + .01f ) 05181 { 05182 // update start position 05183 currentWall->beg = extrapolator_->GetLastTurnPos(); 05184 05185 // set begin distance as well 05186 REAL dBeg = extrapolator_->GetDistance() - eCoord::F( extrapolator_->Direction(), extrapolator_->Position() - extrapolator_->GetLastTurnPos() ); 05187 05188 currentWall->dbegin = dBeg; 05189 currentWall->coords_[0].Pos = dBeg; 05190 05191 // and care for consistency 05192 int i; 05193 for ( i = currentWall->coords_.Len() -1 ; i>=0; --i ) 05194 { 05195 gPlayerWallCoord & coord = currentWall->coords_( i ); 05196 if ( coord.Pos <= dBeg ) 05197 coord.Pos = dBeg; 05198 } 05199 } 05200 05201 // transfer last turn position 05202 lastTurnPos_ = extrapolator_->GetLastTurnPos(); 05203 05204 // smooth position correction 05205 correctPosSmooth = correctPosSmooth + oldPos - pos; 05206 05207 #ifdef DEBUG 05208 if ( correctPosSmooth.NormSquared() > .1f ) 05209 { 05210 std::cout << "Lag slide! " << correctPosSmooth << "\n"; 05211 resimulate_ = true; 05212 } 05213 #endif 05214 05215 // calculate time difference between this cycle and extrapolator 05216 REAL dt = this->LastTime() - extrapolator_->LastTime(); 05217 05218 // extrapolate true distance ( the best estimate we have for the distance on the server ) 05219 REAL trueDistance = extrapolator_->trueDistance_ + extrapolator_->Speed() * dt; 05220 05221 // update distance correction 05222 // con << correctDistanceSmooth << "," << trueDistance << "," << distance << "\n"; 05223 // correctDistanceSmooth = trueDistance - distance; 05224 distance = trueDistance; 05225 correctDistanceSmooth=0; 05226 05227 // split away part in driving direction 05228 TransferPositionCorrectionToDistanceCorrection(); 05229 05230 // make sure correction does not bring us to the wrong side of a wall 05231 // se_SanifyDisplacement( this, correctPosSmooth ); 05232 05233 //eDebugLine::SetTimeout( 1.0 ); 05234 //eDebugLine::SetColor( 0,1,0 ); 05235 //eDebugLine::Draw( pos, 4, pos + dirDrive * 10, 14 ); 05236 05237 // delete extrapolator 05238 extrapolator_ = 0;
void gCycle::OnNotifyNewDestination | ( | gDestination * | dest | ) | [private, virtual] |
called when a destination is successfully inserted into the destination list
Reimplemented from gCycleMovement.
Definition at line 1428 of file gCycle.cpp.
References gCycleMovement::acceleration, BroadCastNewDestination(), gCycleMovement::dirDrive, gDestination::distance, gCycleMovement::distance, EPS, extrapolator_, gDestination::gameTime, eNetGameObject::Lag(), eGameObject::lastTime, nCLIENT, nSERVER, gCycleMovement::OnNotifyNewDestination(), nNetObject::Owner(), eNetGameObject::Player(), eGameObject::pos, gDestination::position, REAL, eLag::Report(), gCycleMovement::rubber, gCycleMovement::rubberSpeedFactor, se_GameTime(), sg_gnuplotDebug, sg_RubberValues(), sn_GetNetState(), sn_myNetID, st_Breakpoint(), eLag::TakeCredit(), TimestepCore(), tSysTimeFloat(), and gCycleMovement::verletSpeed_.
01429 { 01430 #ifdef DELAYEDTURN_DEBUG 01431 sg_turnReceivedTime = tSysTimeFloat(); 01432 #endif 01433 01434 #ifdef GNUPLOT_DEBUG 01435 if ( sg_gnuplotDebug && Player() ) 01436 { 01437 std::ofstream f( Player()->GetUserName() + "_sync", std::ios::app ); 01438 f << dest->position.x << " " << dest->position.y << "\n"; 01439 } 01440 #endif 01441 01442 gCycleMovement::OnNotifyNewDestination( dest ); 01443 01444 // if (sn_GetNetState()==nSERVER || ::sn_myNetID == owner) 01445 if (sn_GetNetState()==nCLIENT && ::sn_myNetID == Owner()) 01446 BroadCastNewDestination(this,dest); 01447 01448 if ( extrapolator_ ) 01449 { 01450 // add destination and try to squeeze it into the schedule. 01451 extrapolator_->NotifyNewDestination( dest ); 01452 } 01453 01454 // start a new simulation in any case. The server may simulate the movement a bit differently at the turn. 01455 // resimulate_ = ( sn_GetNetState() == nCLIENT ); 01456 01457 // detect lag slides 01458 if( sn_GetNetState() == nSERVER ) 01459 { 01460 // see how far we should be simulated in an ideal world 01461 REAL simTime=se_GameTime() - Lag(); 01462 01463 REAL lag = simTime - dest->gameTime; // the real lag 01464 REAL lagOffset = simTime - lastTime; // difference between real lag and practical lag (what we need to compensate) 01465 if ( lag > 0 && sn_GetNetState() == nSERVER ) 01466 { 01467 eLag::Report( Owner(), lag ); 01468 if ( currentWall && currentWall->Wall() && rubberSpeedFactor >= 1-EPS ) 01469 { 01470 lag -= lagOffset; // switch to practical lag 01471 01472 // no compensation? Just quit. 01473 if ( lag < 0 ) 01474 return; 01475 01476 // see how much we can go back 01477 REAL minDist = currentWall->Wall()->Pos(0); 01478 REAL maxGoBack = ( distance - minDist ) * .8; 01479 01480 // see how much we should go back 01481 REAL stepBack = distance - dest->distance; 01482 01483 if ( rubberSpeedFactor < 1-EPS ) 01484 { 01485 // make the correction distance based so we don't loosen a grind 01486 maxGoBack = stepBack; 01487 } 01488 01489 // clamp so we don't go back too far 01490 if ( stepBack > maxGoBack ) 01491 { 01492 stepBack = maxGoBack; 01493 lag = rubberSpeedFactor*stepBack/verletSpeed_; 01494 } 01495 01496 // ask lag compensation how much we are allowed to go back; switch to real lag 01497 // for the credit 01498 lag = eLag::TakeCredit( Owner(), lag + lagOffset ) - lagOffset; 01499 01500 // no compensation? Just quit. 01501 if ( lag < 0 ) 01502 return; 01503 01504 // go back in time 01505 if ( rubberSpeedFactor >= 1-EPS ) 01506 { 01507 // rubber is inactive, basic timestep is enough 01508 TimestepCore( lastTime - lag ); 01509 } 01510 else if ( 0 ) 01511 { 01512 // rubber is active. Take care! 01513 01514 // just extrapolate the movement backwards 01515 REAL step = lag * verletSpeed_; 01516 lastTime -= lag; 01517 01518 // rubber is a bit tricker, we need the effectiveness 01519 REAL rubberGranted, rubberEffectiveness; 01520 sg_RubberValues( player, verletSpeed_, rubberGranted, rubberEffectiveness ); 01521 if ( rubberEffectiveness > 0 ) 01522 rubber -= step/rubberEffectiveness; 01523 01524 if ( rubber < 0 ) 01525 rubber = 0; 01526 01527 // position and distance are easy 01528 step *= rubberSpeedFactor; 01529 distance -= step; 01530 pos = pos - dirDrive * step; 01531 01532 // undo acceleration 01533 verletSpeed_ -= acceleration * lag; 01534 } 01535 01536 // see if we went back too far (should almost never happen) 01537 if ( distance < minDist ) 01538 { 01539 st_Breakpoint(); 01540 TimestepCore( lastTime + ( minDist - distance )/verletSpeed_ ); 01541 } 01542 } 01543 } 01544 } 01545 }
void gCycle::OnDropTempWall | ( | gPlayerWall * | wall, | |
eCoord const & | position, | |||
eCoord const & | dir | |||
) | [private, 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 from gCycleMovement.
Definition at line 1560 of file gCycle.cpp.
References tRecorderSync< DATA >::Archive(), dropWallRequested_, nNetObject::ID(), gCycleMovement::lastDirDrive, gPlayerWall::NetWall(), REAL, sg_minDropInterval, tASSERT, and gCycleMovement::verletSpeed_.
01561 { 01562 tASSERT( wall ); 01563 01564 unsigned short idrec = ID(); 01565 tRecorderSync< unsigned short >::Archive( "_ON_DROP_WALL", 8, idrec ); 01566 01567 // determine if the grinded wall is current enough 01568 bool wallRight = ( currentWall && ( wall->NetWall() == currentWall || wall->NetWall() == currentWall ) ); 01569 01570 // don't drop if we already dropped a short time ago 01571 if ( wallRight && currentWall->Edge()->Vec().NormSquared() < verletSpeed_ * verletSpeed_ * sg_minDropInterval * sg_minDropInterval ) 01572 wallRight = false; 01573 01574 tRecorderSync< bool >::Archive( "_ON_DROP_WALL_RIGHT", 8, wallRight ); 01575 01576 // drop the current wall if eiter this or the last wall is grinded 01577 // gNetPlayerWall * nw = wall->NetWall(); 01578 if ( wallRight ) 01579 { 01580 // calculate relative position of grinding in wall; if alpha is positive, it's already too late 01581 REAL alpha = currentWall->Edge()->Edge(0)->Ratio( position ); 01582 tRecorderSync< REAL >::Archive( "_ON_DROP_WALL_ALPHA", 8, alpha ); 01583 if ( alpha > -.5 ) 01584 { 01585 unsigned short idrec = ID(); 01586 tRecorderSync< unsigned short >::Archive( "_ON_DROP_WALL_DROP", 8, idrec ); 01587 01588 // just request the drop, Timestep() will execute it later 01589 dropWallRequested_ = true; 01590 01591 // bend last driving direction to -dir. That way, should the grinder overtake this cycle, 01592 // it will end up on the right side of his wall. 01593 lastDirDrive = -dir; 01594 } 01595 } 01596 }
void gCycle::MyInitAfterCreation | ( | void | ) | [private] |
private shared initialization code
Reimplemented from gCycleMovement.
Definition at line 2114 of file gCycle.cpp.
References eGameObject::AddToList(), gRealColor::b, body, gCycleVisuals::bodyModel, bodyTex, gCycleVisuals::bodyTexture, color_, con, correctDistanceSmooth, correctPosSmooth, gCycleVisuals::customModel, customModel, gCycleVisuals::customTexture, customTexture, CYCLE_MOTOR, eGameObject::dir, gCycleMovement::dirDrive, gCycleMovement::dirSpawn, dropWallRequested_, eCoord, front, gCycleVisuals::frontModel, gRealColor::g, gCycleWallRenderer, eSoundMixer::GetMixer(), joystick_, lastGoodPosition_, eGameObject::lastTime, lastTimeAnim, gCycleVisuals::LoadModel(), mp, gCycleVisuals::mpType, nCLIENT, nextSync, nextSyncOwner, NULL, eSoundMixer::PlayContinuous(), eNetGameObject::Player(), eGameObject::pos, predictPosition_, gRealColor::r, REAL, rear, gCycleVisuals::rearModel, gCycleMovement::RequestSync(), resimulate_, rotationFrontWheel, rotationRearWheel, se_MakeColorValid(), sg_cycleFirstSpawnProtection, sg_gnuplotDebug, sg_MoviePack(), skew, skewDot, sn_GetNetState(), spawnTime_, sqrt(), tASSERT, tERR_ERROR, timeCameIntoView, tNEW, trailColor_, tSysTimeFloat(), wheelTex, and gCycleVisuals::wheelTexture.
Referenced by gCycle(), and InitAfterCreation().
02114 { 02115 #ifndef DEDICATED 02116 joystick_ = tNEW( gJoystick( this ) ); 02117 #else 02118 joystick_ = NULL; 02119 #endif 02120 02121 // create wall renderer 02122 #ifndef DEDICATED 02123 new gCycleWallRenderer( this ); 02124 #endif 02125 02126 dropWallRequested_ = false; 02127 lastGoodPosition_ = pos; 02128 02129 #ifdef DEBUG 02130 // con << "creating cycle.\n"; 02131 #endif 02132 eSoundMixer* mixer = eSoundMixer::GetMixer(); 02133 mixer->PlayContinuous(CYCLE_MOTOR, this); 02134 02135 //correctDistSmooth=correctTimeSmooth=correctSpeedSmooth=0; 02136 correctDistanceSmooth = 0; 02137 02138 resimulate_ = false; 02139 02140 mp=sg_MoviePack(); 02141 02142 lastTimeAnim = 0; 02143 timeCameIntoView = 0; 02144 02145 customModel = NULL; 02146 body = NULL; 02147 front = NULL; 02148 rear = NULL; 02149 wheelTex = NULL; 02150 bodyTex = NULL; 02151 customTexture = NULL; 02152 02153 correctPosSmooth=eCoord(0,0); 02154 02155 rotationFrontWheel=rotationRearWheel=eCoord(1,0); 02156 02157 skew=skewDot=0; 02158 02159 { 02160 dir=dirDrive; 02161 REAL dirLen=dir.NormSquared(); 02162 if ( dirLen > 0 ) 02163 { 02164 dir = dir * (1/sqrt( dirLen )); 02165 } 02166 } 02167 02168 if (sn_GetNetState()!=nCLIENT){ 02169 if(!player) 02170 { // distribute AI colors 02171 // con << current_ai << ':' << take_ai << ':' << maxmindist << "\n\n\n"; 02172 color_.r=1; 02173 color_.g=1; 02174 color_.b=1; 02175 02176 trailColor_.r=1; 02177 trailColor_.g=1; 02178 trailColor_.b=1; 02179 } 02180 else 02181 { 02182 player->Color(color_.r,color_.g,color_.b); 02183 player->TrailColor(trailColor_.r,trailColor_.g,trailColor_.b); 02184 } 02185 02186 se_MakeColorValid( color_.r, color_.g, color_.b, 1.0f ); 02187 se_MakeColorValid( trailColor_.r, trailColor_.g, trailColor_.b, .5f ); 02188 } 02189 02190 // load model and texture 02191 #ifndef DEDICATED 02192 gCycleVisuals visuals( color_ ); 02193 if ( !visuals.LoadModel( mp ) ) 02194 { 02195 tERR_ERROR( "Neither classic style nor moviepack style model and textures found. " 02196 "The folders \"textures\" and \"moviepack\" need to contain either " 02197 "cycle.ase and bike.png or body.mod, front.mod, rear.mod, cycle_body.png and cycle_wheel.png." ); 02198 } 02199 02200 mp = visuals.mpType; 02201 02202 // transfer models and textures 02203 if ( mp ) 02204 { 02205 // use moviepack style body and texture 02206 customModel = visuals.customModel; 02207 visuals.customModel = 0; 02208 customTexture = visuals.customTexture; 02209 visuals.customTexture = 0; 02210 } 02211 else 02212 { 02213 // use classic style body and texture 02214 body = visuals.bodyModel; 02215 visuals.bodyModel = 0; 02216 front = visuals.frontModel; 02217 visuals.frontModel = 0; 02218 rear = visuals.rearModel; 02219 visuals.rearModel = 0; 02220 bodyTex = visuals.bodyTexture; 02221 visuals.bodyTexture = 0; 02222 wheelTex = visuals.wheelTexture; 02223 visuals.wheelTexture = 0; 02224 02225 tASSERT ( body && front && rear && bodyTex && wheelTex ); 02226 02227 mp = false; 02228 } 02229 #endif // DEDICATED 02230 02231 /* 02232 the old, less flexible, loading code 02233 02234 if (mp) 02235 { 02236 customModel=new rModel("moviepack/cycle.ASE","moviepack/cycle.ase"); 02237 } 02238 else{ 02239 body=new rModel("models/cycle_body.mod"); 02240 front=new rModel("models/cycle_front.mod"); 02241 rear=new rModel("models/cycle_rear.mod"); 02242 } 02243 02244 if (mp) 02245 { 02246 // static rSurface bike(lala_bikeTexture); 02247 static rSurface bike("moviepack/bike.png"); 02248 customTexture=new gTextureCycle(bike,color_,0,0); 02249 } 02250 else{ 02251 static rSurface body("textures/cycle_body.png"); 02252 static rSurface wheel("textures/cycle_wheel.png"); 02253 //static rSurface body((const char*) lala_bodyTexture); 02254 //static rSurface wheel((const char*) lala_wheelTexture); 02255 wheelTex=new gTextureCycle(wheel,color_,0,0,true); 02256 bodyTex=new gTextureCycle(body,color_,0,0); 02257 } 02258 */ 02259 02260 #ifdef DEBUG 02261 con << "Created cycle.\n"; 02262 #endif 02263 nextSyncOwner=nextSync=tSysTimeFloat()-1; 02264 02265 if (sn_GetNetState()!=nCLIENT) 02266 RequestSync(); 02267 02268 grid->AddGameObjectInteresting(this); 02269 02270 spawnTime_=lastTimeAnim=lastTime; 02271 // set spawn time to infinite past if this is the first spawn 02272 if ( !sg_cycleFirstSpawnProtection && spawnTime_ <= 1.0 ) 02273 { 02274 spawnTime_ = -1E+20; 02275 } 02276 dirSpawn = dirDrive; 02277 02278 // add to game grid 02279 this->AddToList(); 02280 02281 predictPosition_ = pos; 02282 02283 #ifdef GNUPLOT_DEBUG 02284 if ( sg_gnuplotDebug && Player() ) 02285 { 02286 std::ofstream f( Player()->GetUserName() + "_step" ); 02287 f << pos.x << " " << pos.y << "\n"; 02288 std::ofstream g( Player()->GetUserName() + "_sync" ); 02289 g << pos.x << " " << pos.y << "\n"; 02290 std::ofstream h( Player()->GetUserName() + "_turn" ); 02291 h << pos.x << " " << pos.y << "\n"; 02292 } 02293 #endif
void gCycle::SetCurrentWall | ( | gNetPlayerWall * | w | ) | [private] |
void gCycle::PreparePredictPosition | ( | gPredictPositionData & | data | ) | [private] |
prepares CalculatePredictPosition() call, requesting a raycast to the front
data | data to be passed to CalculatePredictPosition() later |
Definition at line 2442 of file gCycle.cpp.
References eGameObject::GetMaxLazyLag(), eGameObject::lastTime, eGameObject::MaxSimulateAhead(), gCycleMovement::maxSpaceMaxCast_, gPredictPositionData::maxSpaceReport, REAL, gCycleMovement::RubberSpeed(), gCycleMovement::rubberSpeedFactor, se_PredictTime(), sg_predictWalls, and gCycleMovement::verletSpeed_.
Referenced by Timestep().
02444 { 02445 // don't cast a ray by default 02446 data.maxSpaceReport = 0; 02447 #ifdef DEDICATED 02448 if ( sg_predictWalls ) 02449 { 02450 // predict to the maximum time anyone else may be simulated up to 02451 REAL maxTime = lastTime + MaxSimulateAhead() + GetMaxLazyLag(); 02452 REAL predictDT = maxTime - lastTime; 02453 REAL lookAhead = predictDT * verletSpeed_; 02454 02455 // see how far we can go before rubber kicks in 02456 data.rubberStart = verletSpeed_ / RubberSpeed(); 02457 02458 // store max lookahead plus rubber safety 02459 data.maxSpaceReport = lookAhead + data.rubberStart; 02460 } 02461 #else 02462 data.maxSpaceReport = verletSpeed_ * se_PredictTime() * rubberSpeedFactor; 02463 #endif 02464 02465 // request a raycast of the right length 02466 maxSpaceMaxCast_ = data.maxSpaceReport;
REAL gCycle::CalculatePredictPosition | ( | gPredictPositionData & | data | ) | [private] |
Calculates predictPosition_.
data | data from PreparePredictPosition() |
Definition at line 2479 of file gCycle.cpp.
References correctPosSmooth, gCycleMovement::dirDrive, gCycleMovement::GetMaxSpaceAhead(), eGameObject::lastTime, gPredictPositionData::maxSpaceReport, eGameObject::pos, predictPosition_, REAL, se_PredictTime(), sg_predictWalls, and gCycleMovement::verletSpeed_.
Referenced by Timestep().
02481 { 02482 // predict position 02483 REAL predictTime = lastTime; 02484 { 02485 #ifdef DEDICATED 02486 predictPosition_ = pos; 02487 02488 if ( sg_predictWalls ) 02489 { 02490 REAL spaceAhead = GetMaxSpaceAhead( data.maxSpaceReport ); 02491 spaceAhead -= data.rubberStart; 02492 02493 if ( spaceAhead > 0 ) 02494 { 02495 // store consistent prediction position and time 02496 predictPosition_ = pos + dirDrive * spaceAhead; 02497 predictTime = lastTime + spaceAhead/verletSpeed_; 02498 } 02499 } 02500 #else 02501 // predict half a frame time 02502 predictTime += se_PredictTime(); 02503 predictPosition_ = pos+correctPosSmooth + dirDrive * GetMaxSpaceAhead( data.maxSpaceReport ); 02504 #endif 02505 } 02506 02507 return predictTime;
void gCycle::OnRemoveFromGame | ( | ) | [protected, virtual] |
called on RemoveFromGame(). Call base class implementation, too, in your implementation. Must keep the object alive.
Reimplemented from gCycleMovement.
Definition at line 2362 of file gCycle.cpp.
References gCycleMovement::Alive(), Die(), joystick_, eGameObject::lastTime, nSERVER, NULL, gCycleMovement::OnRemoveFromGame(), gCycleMovement::RequestSync(), sn_GetNetState(), and gCycleMovement::Turn().
02364 { 02365 // keep this cycle alive during this function 02366 tJUST_CONTROLLED_PTR< gCycle > keep; 02367 02368 if ( this->GetRefcount() > 0 ) 02369 { 02370 keep = this; 02371 02372 this->Turn(0); 02373 02374 if ( sn_GetNetState() == nSERVER ) 02375 RequestSync(); 02376 } 02377 02378 // make sure we're dead, so our walls know they need to time out. 02379 if ( Alive() ) 02380 { 02381 Die( lastTime ); 02382 } 02383 02384 if (currentWall) 02385 currentWall->CopyIntoGrid(0); 02386 currentWall=NULL; 02387 lastWall=NULL; 02388 02389 gCycleMovement::OnRemoveFromGame(); 02390 02391 delete joystick_; 02392 joystick_ = NULL;
void gCycle::OnRoundEnd | ( | ) | [protected, virtual] |
called when the round ends
Reimplemented from eGameObject.
Definition at line 2395 of file gCycle.cpp.
References ePlayerNetID::AddScore(), gCycleMovement::Alive(), eNetGameObject::Player(), and score_survive.
02397 { 02398 // give survival bonus 02399 if ( Alive() && player ) 02400 { 02401 Player()->AddScore( score_survive, tOutput("$player_win_survive"), tOutput() ); 02402 }
void gCycle::Die | ( | REAL | time | ) | [virtual] |
dies at the specified time
time | the time of death |
Reimplemented from gCycleMovement.
Definition at line 3097 of file gCycle.cpp.
References correctPosSmooth, gNetPlayerWall::Cycle(), gCycleMovement::Die(), eCoord, nSERVER, eGameObject::pos, predictPosition_, gNetPlayerWall::Preliminary(), gNetPlayerWall::real_CopyIntoGrid(), gCycleMovement::RequestSync(), sg_netPlayerWalls, sn_GetNetState(), and TransferPositionCorrectionToDistanceCorrection().
Referenced by Kill(), OnRemoveFromGame(), ReadSync(), Timestep(), and TimestepCore().
03099 { 03100 if ( sn_GetNetState() == nSERVER ) 03101 { 03102 // request one last sync 03103 RequestSync( true ); 03104 } 03105 03106 gCycleMovement::Die( time ); 03107 03108 // reset smoothing 03109 correctPosSmooth = eCoord(); 03110 TransferPositionCorrectionToDistanceCorrection(); 03111 predictPosition_ = pos; 03112 03113 // delete all temporary walls of this cycle 03114 for ( int i = sg_netPlayerWalls.Len()-1; i >= 0; --i ) 03115 { 03116 gNetPlayerWall * wall = sg_netPlayerWalls(i); 03117 if ( wall->Cycle() == this && wall->Preliminary() ) 03118 { 03119 wall->real_CopyIntoGrid(grid); 03120 } 03121 }
void gCycle::KillAt | ( | const eCoord & | pos | ) |
kill this cycle at the given position and take care of scoring
Definition at line 3123 of file gCycle.cpp.
References gStatList::add(), ePlayerNetID::AddScore(), gCycleMovement::Alive(), tColoredString::ColorString(), ePlayerNetID::CurrentTeam(), gStatistics::deaths, gCycleMovement::enemyInfluence, gEnemyInfluence::GetEnemy(), ePlayerNetID::GetName(), gEnemyInfluence::GetTime(), ePlayerNetID::GetUserName(), gStats, ePlayerNetID::IsHuman(), Kill(), gStatistics::kills, eGameObject::LastTime(), eGameObject::lastTime, gCycleMovement::MoveSafely(), nCLIENT, NULL, ePlayerNetID::Object(), eNetGameObject::Player(), eGameObject::pos, score_die, score_kill, score_suicide, se_SaveToLadderLog(), se_sendEventNotification(), tOutput::SetTemplateParameter(), sg_suicideTimeout, sn_ConsoleOut(), sn_GetNetState(), and Vulnerable().
Referenced by PassEdge(), sg_TopologyPoliceCheck(), Timestep(), and TimestepCore().
03124 { 03125 // don't kill invulnerable cycles 03126 if ( !Vulnerable() ) 03127 { 03128 MoveSafely( deathPos, lastTime, lastTime ); 03129 return; 03130 } 03131 03132 // find the killer from the enemy influence storage 03133 ePlayerNetID const * constHunter = enemyInfluence.GetEnemy(); 03134 ePlayerNetID * hunter = Player(); 03135 03136 // cast away const the safe way 03137 if ( constHunter && constHunter->Object() ) 03138 hunter = constHunter->Object()->Player(); 03139 03140 // only take it if it is not too old 03141 if ( LastTime() - enemyInfluence.GetTime() > sg_suicideTimeout ) 03142 hunter = NULL; 03143 03144 // suicide? 03145 if ( !hunter ) 03146 hunter = Player(); 03147 03148 03149 if (!Alive() || sn_GetNetState()==nCLIENT) 03150 return; 03151 03152 #ifdef KRAWALL_SERVER_LEAGUE 03153 if ( hunter && Player() && 03154 !dynamic_cast<gAIPlayer*>(hunter) && 03155 !dynamic_cast<gAIPlayer*>(Player()) && 03156 hunter->IsAuth() && Player()->IsAuth()) 03157 nKrawall::ServerFrag(hunter->GetUserName(), Player()->GetUserName()); 03158 #endif 03159 03160 if (hunter==Player()) 03161 { 03162 if (hunter) 03163 { 03164 tString ladderLog; 03165 ladderLog << "DEATH_SUICIDE " << hunter->GetUserName() << "\n"; 03166 se_SaveToLadderLog( ladderLog ); 03167 tString notificationMessage(hunter->GetUserName()); 03168 notificationMessage << " commited suicide"; 03169 se_sendEventNotification(tString("Death suicide"), notificationMessage); 03170 03171 if ( score_suicide ) 03172 hunter->AddScore(score_suicide, tOutput(), "$player_lose_suicide" ); 03173 else 03174 { 03175 tColoredString hunterName; 03176 hunterName << *hunter << tColoredString::ColorString(1,1,1); 03177 sn_ConsoleOut( tOutput( "$player_free_suicide", hunterName ) ); 03178 } 03179 } 03180 } 03181 else{ 03182 if (hunter) 03183 { 03184 tOutput lose; 03185 tOutput win; 03186 if (Player()) 03187 { 03188 tColoredString preyName; 03189 preyName << *Player(); 03190 preyName << tColoredString::ColorString(1,1,1); 03191 if (Player()->CurrentTeam() != hunter->CurrentTeam()) { 03192 tString ladderLog; 03193 ladderLog << "DEATH_FRAG " << Player()->GetUserName() << " " << hunter->GetUserName() << "\n"; 03194 se_SaveToLadderLog( ladderLog ); 03195 tString notificationMessage(hunter->GetUserName()); 03196 notificationMessage << " core dumped " << Player()->GetUserName(); 03197 se_sendEventNotification(tString("Death frag"), notificationMessage); 03198 03199 win.SetTemplateParameter(3, preyName); 03200 win << "$player_win_frag"; 03201 if ( score_kill != 0 ) 03202 hunter->AddScore(score_kill, win, lose ); 03203 else 03204 { 03205 tColoredString hunterName; 03206 hunterName << *hunter << tColoredString::ColorString(1,1,1); 03207 sn_ConsoleOut( tOutput( "$player_free_frag", hunterName, preyName ) ); 03208 } 03209 } 03210 else { 03211 tString ladderLog; 03212 ladderLog << "DEATH_TEAMKILL " << Player()->GetUserName() << " " << hunter->GetUserName() << "\n"; 03213 se_SaveToLadderLog( ladderLog ); 03214 tString notificationMessage(hunter->GetUserName()); 03215 notificationMessage << " teamkilled " << Player()->GetUserName(); 03216 se_sendEventNotification(tString("Death teamkill"), notificationMessage); 03217 03218 tColoredString hunterName; 03219 hunterName << *hunter << tColoredString::ColorString(1,1,1); 03220 sn_ConsoleOut( tOutput( "$player_teamkill", hunterName, preyName ) ); 03221 } 03222 } 03223 else 03224 { 03225 win << "$player_win_frag_ai"; 03226 hunter->AddScore(score_kill, win, lose); 03227 } 03228 } 03229 // if (prey->player && (prey->player->CurrentTeam() != hunter->player->CurrentTeam())) 03230 if (Player()) 03231 Player()->AddScore(score_die,tOutput(),"$player_lose_frag"); 03232 } 03233 03234 //collect stats! huzzah! 03235 if (Player() && hunter && gStats) 03236 { 03237 //always a death 03238 if (Player()->IsHuman()) 03239 { 03240 gStats->deaths->add(Player()->GetName(), 1); 03241 } 03242 if (hunter != Player() && hunter->IsHuman()) //but a kill too? 03243 { 03244 gStats->kills->add(hunter->GetName(), 1); 03245 } 03246 } 03247 03248 // set position to death position so the explosion is at the right place (I dimly remember this caused problems in an earlier attempt) 03249 this->pos = deathPos; 03250 03251 Kill();
int gCycle::WindingNumber | ( | void | ) | const [inline] |
returns the current winding number
Reimplemented from gCycleMovement.
Definition at line 243 of file gCycle.h.
References gCycleMovement::windingNumber_.
Referenced by gAIPlayer::EmergencySurvive().
00243 {return windingNumber_;}
bool gCycle::Vulnerable | ( | ) | const [virtual] |
returns whether the cycle can be killed
the distance driven since the last turn
true if the cycle is vulnerable
Reimplemented from gCycleMovement.
Definition at line 6076 of file gCycle.cpp.
References gCycleMovement::Alive(), eGameObject::lastTime, sg_cycleInvulnerableTime, and spawnTime_.
Referenced by EdgeIsDangerous(), KillAt(), PassEdge(), and Render().
06078 { 06079 return Alive() && lastTime > spawnTime_ + sg_cycleInvulnerableTime;
void gCycle::InitAfterCreation | ( | void | ) | [virtual] |
shared initialization routine
Reimplemented from gCycleMovement.
Definition at line 2295 of file gCycle.cpp.
References gCycleMovement::InitAfterCreation(), MyInitAfterCreation(), gCycleMovement::Speed(), and st_Breakpoint().
02296 { 02297 #ifdef DEBUG 02298 if (!finite(Speed())) 02299 st_Breakpoint(); 02300 #endif 02301 gCycleMovement::InitAfterCreation(); 02302 #ifdef DEBUG 02303 if (!finite(Speed())) 02304 st_Breakpoint(); 02305 #endif 02306 MyInitAfterCreation();
void gCycle::SetWallsStayUpDelay | ( | REAL | delay | ) | [static] |
the time the cycle walls stay up ( negative values: they stay up forever )
Definition at line 1607 of file gCycle.cpp.
References nConfItem< T >::Set().
Referenced by _wrap_GCycle_set_walls_stay_up_delay(), and sg_copySettings().
01608 { 01609 c_pwsud->Set( delay ); 01610 }
void gCycle::SetWallsLength | ( | REAL | length | ) | [static] |
the maximum total length of the walls
Definition at line 1700 of file gCycle.cpp.
References c_pwl.
Referenced by _wrap_GCycle_set_walls_length(), and sg_copySettings().
01701 { 01702 c_pwl->Set( length ); 01703 }
void gCycle::SetExplosionRadius | ( | REAL | radius | ) | [static] |
the radius of the holes blewn in by an explosion
Definition at line 1706 of file gCycle.cpp.
References c_per.
Referenced by _wrap_GCycle_set_explosion_radius(), and sg_copySettings().
01707 { 01708 c_per->Set( radius ); 01709 }
static REAL gCycle::WallsStayUpDelay | ( | ) | [inline, static] |
the time the cycle walls stay up ( negative values: they stay up forever )
Definition at line 256 of file gCycle.h.
References wallsStayUpDelay.
Referenced by _wrap_GCycle_walls_stay_up_delay(), gCycleWallsDisplayListManager::CannotHaveList(), cWidget::Map::DrawWalls(), gNetPlayerWall::IsDangerousAnywhere(), gNetPlayerWall::IsDangerousApartFromHoles(), gNetPlayerWall::RenderBegin(), and gNetPlayerWall::RenderNormal().
static REAL gCycle::WallsLength | ( | ) | [inline, static] |
the default total length of the walls
Definition at line 257 of file gCycle.h.
References wallsLength.
Referenced by _wrap_GCycle_walls_length(), cWidget::Map::DrawWalls(), gNetPlayerWall::IsDangerousAnywhere(), gNetPlayerWall::IsDangerousApartFromHoles(), gNetPlayerWall::RenderList(), and sg_CycleWallLengthFromDist().
REAL gCycle::MaxWallsLength | ( | ) | const |
the maximum total length of the walls (including max effect of rubber growth)
Definition at line 1681 of file gCycle.cpp.
References gCycleMovement::distance, REAL, sg_cycleDistWallShrink, sg_cycleRubberWallShrink, sg_CycleWallLengthFromDist(), sg_rubberCycle, and wallsLength.
Referenced by gCycleWallsDisplayListManager::RenderAll().
01682 { 01683 REAL len = sg_CycleWallLengthFromDist( distance ); 01684 01685 // exception: if the wall grows faster than it receeds, take the maximum, because the wall will 01686 // grow backwards 01687 if ( sg_cycleDistWallShrink > 1 ) 01688 { 01689 len = wallsLength; 01690 } 01691 01692 // if the wall grows from rubber use, add the maximal growth 01693 if ( sg_cycleRubberWallShrink >= 0 || sg_rubberCycle < 0 ) 01694 return len; 01695 else 01696 return len - sg_cycleRubberWallShrink * sg_rubberCycle; 01697 }
REAL gCycle::ThisWallsLength | ( | ) | const |
the maximum total length of this cycle's wall (including rubber shrink)
Definition at line 1649 of file gCycle.cpp.
References gCycleMovement::distance, gCycleMovement::GetRubber(), REAL, sg_cycleRubberWallShrink, and sg_CycleWallLengthFromDist().
Referenced by gCycleWallsDisplayListManager::CannotHaveList(), cWidget::Map::DrawWalls(), PassEdge(), and gCycleWallsDisplayListManager::RenderAll().
01650 { 01651 // get distance influence 01652 REAL len = sg_CycleWallLengthFromDist( distance ); 01653 01654 // apply rubber shortening 01655 return len - GetRubber() * sg_cycleRubberWallShrink; 01656 }
REAL gCycle::WallEndSpeed | ( | ) | const |
the speed the end of the trail is receeding with right now
Definition at line 1660 of file gCycle.cpp.
References d, gCycleMovement::distance, REAL, gCycleMovement::rubberSpeedFactor, sg_cycleDistWallShrink, sg_cycleDistWallShrinkOffset, sg_cycleRubberWallShrink, sg_RubberValues(), and gCycleMovement::Speed().
01661 { 01662 REAL rubberMax, rubberEffectiveness; 01663 sg_RubberValues( player, Speed(), rubberMax, rubberEffectiveness ); 01664 01665 // basic speed from cycle movement 01666 REAL speed = rubberSpeedFactor * Speed(); 01667 01668 // take distance shrinking into account 01669 REAL d = sg_cycleDistWallShrinkOffset - distance; 01670 if ( d > 0 ) 01671 speed *= ( 1 - sg_cycleDistWallShrink ); 01672 01673 // speed from rubber usage and shringing 01674 if ( rubberEffectiveness > 0 ) 01675 speed += Speed() * ( 1 - rubberSpeedFactor ) * sg_cycleRubberWallShrink / rubberEffectiveness; 01676 01677 return speed; 01678 }
static REAL gCycle::ExplosionRadius | ( | ) | [inline, static] |
the radius of the holes blewn in by an explosion
Definition at line 261 of file gCycle.h.
References explosionRadius.
Referenced by _wrap_GCycle_explosion_radius(), gExplosion::OnNewWall(), and gExplosion::Timestep().
bool gCycle::IsMe | ( | eGameObject const * | other | ) | const |
checks whether the passed pointer is logically identical with this cycle
Definition at line 1419 of file gCycle.cpp.
References extrapolator_.
Referenced by gSensor::PassEdge().
01420 { 01421 return other == this || other == extrapolator_; 01422 }
void gCycle::WriteCreate | ( | nMessage & | m | ) | [virtual] |
Reimplemented from eNetGameObject.
Definition at line 4917 of file gCycle.cpp.
References gRealColor::b, color_, gRealColor::g, gRealColor::r, and eNetGameObject::WriteCreate().
04918 { 04919 eNetGameObject::WriteCreate(m); 04920 m << color_.r; 04921 m << color_.g; 04922 m << color_.b;
void gCycle::WriteSync | ( | nMessage & | m | ) | [virtual] |
Reimplemented from eNetGameObject.
Definition at line 4926 of file gCycle.cpp.
References gCycleMovement::Alive(), gCycleMovement::braking, gCycleMovement::brakingReservoir, compressZeroOne, eGameObject::deathTime, Direction(), gCycleMovement::distance, gCycleMovement::GetLastTurnPos(), gCycleMovement::lastDestination, eGameObject::lastTime, gDestination::messageID, eGameObject::Position(), REAL, gCycleMovement::rubber, gCycleMovement::rubberMalus, sg_rubberCycle, sg_verletIntegration, gCycleMovement::Speed(), nVersionFeature::Supported(), gCycleMovement::turns, gCycleMovement::verletSpeed_, gFloatCompressor::Write(), nMessage::Write(), and x.
04927 { 04928 // eNetGameObject::WriteSync(m); 04929 04930 if ( Alive() ) 04931 { 04932 m << lastTime; 04933 } 04934 else 04935 { 04936 m << deathTime; 04937 } 04938 m << Direction(); 04939 m << Position(); 04940 04941 REAL speed = verletSpeed_; 04942 // if the clients understand it, send them the real current speed 04943 if ( sg_verletIntegration.Supported() ) 04944 speed = Speed(); 04945 04946 if ( speed > 15 ) 04947 { 04948 int x; 04949 x = 0; 04950 } 04951 04952 m << speed; 04953 m << short( Alive() ? 1 : 0 ); 04954 m << distance; 04955 if (!currentWall || currentWall->preliminary) 04956 m.Write(0); 04957 else 04958 m.Write(currentWall->ID()); 04959 04960 m.Write(turns); 04961 m.Write(braking); 04962 04963 // write last turn position 04964 m << GetLastTurnPos(); 04965 04966 // write rubber 04967 compressZeroOne.Write( m, rubber/( sg_rubberCycle + .1 ) ); 04968 compressZeroOne.Write( m, 1/( 1 + rubberMalus ) ); 04969 04970 // write last clientside sync message ID 04971 unsigned short lastMessageID = 0; 04972 if ( lastDestination ) 04973 lastMessageID = lastDestination->messageID; 04974 m.Write(lastMessageID); 04975 04976 // write brake 04977 compressZeroOne.Write( m, brakingReservoir ); 04978 04979 // set new sync times 04980 // nextSync=tSysTimeFloat()+sg_syncIntervalEnemy; 04981 // nextSyncOwner=tSysTimeFloat()+sg_GetSyncIntervalSelf( this );
void gCycle::ReadSync | ( | nMessage & | m | ) | [virtual] |
Reimplemented from eNetGameObject.
Definition at line 5254 of file gCycle.cpp.
References gCycleMovement::AccelerationDiscontinuity(), gCycleMovement::Alive(), eSensor::before_hit, gCycleMovement::braking, gCycleMovement::SyncData::braking, gCycleMovement::brakingReservoir, gCycleMovement::SyncData::brakingReservoir, ClampForward(), color_, compressZeroOne, con, correctDistanceSmooth, correctPosSmooth, eGameObject::deathTime, gCycleMovement::destinationList, eSensor::detect(), Die(), eGameObject::dir, gCycleMovement::SyncData::dir, gCycleMovement::dirDrive, Direction(), gCycleMovement::dirSpawn, gDestination::distance, gCycleMovement::distance, gCycleMovement::SyncData::distance, DropWall(), eCoord, nMessage::End(), extrapolator_, eGameObject::FindCurrentFace(), gDestination::gameTime, gCycleMovement::GetDestinationBefore(), eGrid::GetDirection(), eGameObject::GOID(), eGameObject::Grid(), gCycleMovement::lastDirDrive, lastGoodPosition_, lastSyncMessage_, eGameObject::lastTime, gCycleMovement::SyncData::lastTurn, gCycleMovement::lastTurnPos_, gCycleMovement::SyncData::messageID, gCycleMovement::MoveSafely(), gDestination::next, NULL, nNetObject::Owner(), gCycleMovement::SyncData::pos, eGameObject::pos, gDestination::position, predictPosition_, gFloatCompressor::Read(), nMessage::Read(), REAL, resimulate_, gCycleMovement::rubber, gCycleMovement::SyncData::rubber, gCycleMovement::SyncData::rubberMalus, gCycleMovement::SetWindingNumberWrapped(), sg_cycleFirstSpawnProtection, sg_rubberCycle, skew, skewDot, sn_myNetID, sn_Update(), spawnTime_, gCycleMovement::Speed(), gCycleMovement::SyncData::speed, sqrt(), SyncEnemy(), gCycleMovement::SyncData::time, tNEW, gCycleMovement::turns, gCycleMovement::SyncData::turns, gCycleMovement::verletSpeed_, gCycleMovement::windingNumberWrapped_, and x.
05256 { 05257 // data from sync message 05258 SyncData sync; 05259 05260 short sync_alive; // is this cycle alive? 05261 unsigned short sync_wall=0; // ID of wall 05262 05263 eCoord new_pos = pos; // the extrapolated position 05264 05265 // warning: depends on the implementation of eNetGameObject::WriteSync 05266 // since we don't call eNetGameObject::ReadSync. 05267 m >> sync.time; 05268 05269 // reset values not sent with old protocol messages 05270 sync.rubber = rubber; 05271 sync.turns = turns; 05272 sync.braking = braking; 05273 sync.messageID = 1; 05274 05275 m >> sync.dir; 05276 m >> sync.pos; 05277 05278 //eDebugLine::SetTimeout( 1.0 ); 05279 //eDebugLine::SetColor( 1,1,1 ); 05280 //eDebugLine::Draw( lastSyncMessage_.pos, 0, lastSyncMessage_.pos, 20 ); 05281 05282 m >> sync.speed; 05283 m >> sync_alive; 05284 m >> sync.distance; 05285 m.Read(sync_wall); 05286 if (!m.End()) 05287 m.Read(sync.turns); 05288 if (!m.End()) 05289 m.Read(sync.braking); 05290 05291 if ( !m.End() ) 05292 { 05293 m >> sync.lastTurn; 05294 } 05295 else if ( currentWall ) 05296 { 05297 sync.lastTurn = currentWall->beg; 05298 } 05299 05300 bool canUseExtrapolatorMethod = false; 05301 05302 bool rubberSent = false; 05303 if ( !m.End() ) 05304 { 05305 rubberSent = true; 05306 05307 // read rubber 05308 REAL preRubber, preRubberMalus; 05309 preRubber = compressZeroOne.Read( m ); 05310 preRubberMalus = compressZeroOne.Read( m ); 05311 05312 // read last message ID 05313 m.Read(sync.messageID); 05314 05315 // read braking reservoir 05316 sync.brakingReservoir = compressZeroOne.Read( m ); 05317 // std::cout << "sync: " << sync.brakingReservoir << ":" << sync.braking << "\n"; 05318 05319 // undo skewing 05320 sync.rubber = preRubber * ( sg_rubberCycle + .1 ); 05321 sync.rubberMalus = 1/preRubberMalus - 1; 05322 05323 // extrapolation is probably safe 05324 canUseExtrapolatorMethod = sg_useExtrapolatorSync && lastTime > 0; 05325 } 05326 else 05327 { 05328 // try to extrapolate brake status backwards in time 05329 sync.brakingReservoir = brakingReservoir; 05330 if ( brakingReservoir > 0 && sync.braking ) 05331 sync.brakingReservoir += ( lastTime - sync.time ) * sg_cycleBrakeDeplete; 05332 else if ( brakingReservoir < 1 && !sync.braking ) 05333 sync.brakingReservoir -= ( lastTime - sync.time ) * sg_cycleBrakeRefill; 05334 05335 if ( sync.brakingReservoir < 0 ) 05336 sync.brakingReservoir = 0; 05337 else if ( sync.brakingReservoir > 1 ) 05338 sync.brakingReservoir = 1; 05339 } 05340 05341 // abort if sync is not new 05342 if ( lastSyncMessage_.time >= sync.time && lastSyncMessage_.turns >= sync.turns && sync_alive > 0 ) 05343 { 05344 //eDebugLine::SetTimeout( 5 ); 05345 //eDebugLine::SetColor( 1,1,0); 05346 //eDebugLine::Draw( lastSyncMessage_.pos, 1.5, lastSyncMessage_.pos, 5.0 ); 05347 return; 05348 } 05349 lastSyncMessage_ = sync; 05350 05351 // store last known good position: a bit before the last position confirmed by the server 05352 lastGoodPosition_ = sync.pos + ( sync.lastTurn - sync.pos ) *.01; 05353 // offset it a tiny bit by our last driving direction 05354 if ( eCoord::F( dirDrive, sync.dir ) > .99f*dirDrive.NormSquared() ) 05355 lastGoodPosition_ = lastGoodPosition_ - this->lastDirDrive * .0001; 05356 05357 //eDebugLine::SetTimeout( 2 ); 05358 //eDebugLine::SetColor( 0,1,0); 05359 //eDebugLine::Draw( lastSyncMessage_.pos, 1.5, lastSyncMessage_.pos, 5.0 ); 05360 05361 // con << "Sync: " << lastTime << ", " << lastSyncMessage_.time << ", " << lastSyncMessage_.pos << ", " << pos << "\n"; 05362 05363 if ( canUseExtrapolatorMethod ) 05364 { 05365 // reset extrapolator if information from server is more up to date 05366 if ( extrapolator_ && extrapolator_->LastTime() < lastSyncMessage_.time ) 05367 { 05368 extrapolator_ = 0; 05369 } 05370 } 05371 05372 // killed? 05373 if (Alive() && sync_alive!=1 && GOID() >= 0 && grid ) 05374 { 05375 Die( lastSyncMessage_.time ); 05376 MoveSafely( lastSyncMessage_.pos, lastTime, deathTime ); 05377 distance=lastSyncMessage_.distance; 05378 correctDistanceSmooth=0; 05379 DropWall( false ); 05380 05381 tNEW(gExplosion)( grid, lastSyncMessage_.pos, lastSyncMessage_.time ,color_, this ); 05382 05383 return; 05384 } 05385 05386 // no point going on if you're not alive 05387 if (!Alive()) 05388 { 05389 #ifdef DEBUG 05390 con << "Received duplicate death sync message; those things confuse old clients!\n"; 05391 #endif 05392 return; 05393 } 05394 05395 gDestination emergency_aft(*this); 05396 05397 // all the data was read. check where it fits in our destination list: 05398 gDestination *bef= GetDestinationBefore( lastSyncMessage_, destinationList ); 05399 gDestination *aft=NULL; 05400 if (bef){ 05401 aft=bef->next; 05402 if (!aft) 05403 aft=&emergency_aft; 05404 05405 //eDebugLine::SetTimeout(1); 05406 //eDebugLine::SetColor( 1,0,0 ); 05407 //eDebugLine::Draw( bef->position, 1.5, lastSyncMessage_.pos, 3.0 ); 05408 //eDebugLine::SetColor( 0,1,0 ); 05409 //eDebugLine::Draw( lastSyncMessage_.pos, 3.0, aft->position, 5.0 ); 05410 05411 } 05412 05413 05414 // detect local tunneling by casting a ray from the server certified position 05415 // to the next known client position 05416 if ( lastTime > 0 ) 05417 { 05418 eCoord position = pos; 05419 if ( bef ) 05420 position = bef->position; 05421 eSensor tunnel( this, lastSyncMessage_.pos, position - lastSyncMessage_.pos ); 05422 tunnel.detect( 1 ); 05423 05424 // use extrapolation to undo local tunneling 05425 if ( tunnel.ehit ) 05426 { 05427 canUseExtrapolatorMethod = true; 05428 if ( 0 ) 05429 { 05430 con << "possible local tunneling detected\n"; 05431 eSensor tunnel( this, lastSyncMessage_.pos, position - lastSyncMessage_.pos ); 05432 tunnel.detect( 1 ); 05433 } 05434 } 05435 } 05436 else 05437 { 05438 // first sync. Accept the position without questioning it. 05439 pos = sync.pos; 05440 FindCurrentFace(); 05441 } 05442 05443 // determine whether we can use the distance based interpolating sync method here 05444 bool distanceBased = aft && aft != &emergency_aft && Owner() == sn_myNetID; 05445 05446 if ( canUseExtrapolatorMethod && Owner()==sn_myNetID ) 05447 { 05448 // exactlu resimulate from sync position for cycles controlled by this client 05449 resimulate_ = true; 05450 05451 return; 05452 } 05453 05454 rubber = lastSyncMessage_.rubber; 05455 05456 // bool fullSync = false; 05457 05458 // try to get a distance value closer to the client's data by calculating the distance from the sync position to the next destination 05459 REAL interpolatedDistance = lastSyncMessage_.distance; 05460 if ( aft ) 05461 { 05462 interpolatedDistance = aft->distance - sqrt((lastSyncMessage_.pos-aft->position).NormSquared()); 05463 } 05464 05465 // determine true lag 05466 // REAL lag = 1; 05467 //if ( player ) 05468 // lag = player->ping; 05469 05470 if ( distanceBased ) 05471 { 05472 // new way: correct our time and speed 05473 05474 #ifdef DEBUG 05475 // destination *save = bef; 05476 #endif 05477 05478 REAL ratio = (interpolatedDistance - bef->distance)/ 05479 (aft->distance - bef->distance); 05480 05481 if (!finite(ratio)) 05482 ratio = 0; 05483 05484 // interpolate when the cycle was at the position the sync message was sent 05485 REAL interpolatedTime = bef->gameTime * (1-ratio) + aft->gameTime * ratio; 05486 // REAL interpolatedSpeed = bef->speed * (1-ratio) + aft->speed * ratio; 05487 05488 // calculate deltas 05489 REAL correctTime = ( lastSyncMessage_.time - interpolatedTime ); 05490 // REAL correctSpeed = ( lastSyncMessage_.speed - interpolatedSpeed ); 05491 REAL correctDist = ( lastSyncMessage_.distance - interpolatedDistance ); 05492 05493 // don't trust high ratios too much; they may be skewed by rubber application 05494 { 05495 REAL factor = (1 - ratio) * 5; 05496 if ( factor < 1 ) 05497 { 05498 if ( factor < 0 ) 05499 factor = 0; 05500 correctTime *= factor; 05501 correctDist *= factor; 05502 } 05503 } 05504 05505 //if (correctTime > 0) 05506 //{ 05507 // correctTime*=.5; 05508 // correctSpeed*=.5; 05509 // correctDist*=.5; 05510 //} 05511 05512 //correctTimeSmooth += correctTime; 05513 //correctSpeedSmooth += correctSpeed; 05514 // correctDistanceSmooth += correctDist; 05515 05516 // correctDistanceSmooth += correctDist; 05517 05518 // con << ratio << ", " << correctDist << ", " << correctTime << "\n"; 05519 05520 // correct distances according to sync 05521 { 05522 distance += correctDist; 05523 gDestination * run = bef; 05524 while ( run ) 05525 { 05526 run->distance += correctDist; 05527 run = run->next; 05528 } 05529 } 05530 05531 // correct time by adapting position and distance 05532 eCoord newPos = pos - Direction() * Speed() * correctTime; 05533 if ( currentWall ) 05534 { 05535 ClampForward( newPos, currentWall->beg, Direction() ); 05536 } 05537 05538 // don't tunnel through walls 05539 { 05540 const eCoord & safePos = pos; // aft->position 05541 gSensor test( this, safePos , newPos - safePos ); 05542 test.detect(1); 05543 if ( test.ehit ) 05544 { 05545 newPos = test.before_hit; 05546 05547 // something bad must be going on, better recheck with accurate extrapolation 05548 resimulate_ = true; 05549 } 05550 } 05551 05552 correctPosSmooth = correctPosSmooth + pos - newPos; 05553 distance += eCoord::F( newPos - pos, Direction() )/Direction().NormSquared(); 05554 05555 MoveSafely( newPos, lastTime, lastTime ); 05556 05557 /* 05558 REAL ts = lastSyncMessage_.time - lastTime; 05559 05560 // eCoord intPos = pos + dirDrive * (ts * speed + .5 * ts*ts*acceleration); 05561 eCoord intPos = pos + dirDrive * ( ts * ( speed + lastSyncMessage_.speed ) * .5 ); 05562 REAL int_speed = speed + acceleration*ts; 05563 05564 dirDrive = lastSyncMessage_.dir; 05565 05566 correctPosSmooth = lastSyncMessage_.pos - intPos; 05567 05568 distance = lastSyncMessage_.distance - speed * ts - acceleration * ts*ts*.5; 05569 05570 //correctTimeSmooth = 0; 05571 */ 05572 } 05573 else 05574 { 05575 // direct sync 05576 if ( Owner() != sn_myNetID ) 05577 { 05578 // direct extrapolation for cycles of other clients or if no turn is newer than the sync 05579 SyncEnemy( lastSyncMessage_.lastTurn ); 05580 05581 // update beginning of current wall 05582 if ( currentWall ) 05583 { 05584 currentWall->beg = lastSyncMessage_.lastTurn; 05585 } 05586 05587 // update brake status 05588 AccelerationDiscontinuity(); 05589 braking = lastSyncMessage_.braking; 05590 05591 // store last turn 05592 lastTurnPos_ = lastSyncMessage_.lastTurn; 05593 } 05594 else 05595 { 05596 // same algorithm, but update smooth position correction so that there is no immediate visual change 05597 eCoord oldPos = pos + correctPosSmooth; 05598 SyncEnemy( lastSyncMessage_.lastTurn ); 05599 correctPosSmooth = oldPos - pos; 05600 } 05601 05602 // restore rubber meter 05603 if ( !rubberSent ) 05604 { 05605 rubber = lastSyncMessage_.rubber; 05606 } 05607 } 05608 05609 // if this happens during creation, ignore position correction 05610 if ( this->ID() == 0 ) 05611 { 05612 correctPosSmooth = eCoord(); 05613 05614 // some other stuff that should happen on the first sync 05615 05616 // estimate time of spawning (HACK) 05617 spawnTime_=lastTime; 05618 if ( verletSpeed_ > 0 ) 05619 spawnTime_ -= distance/verletSpeed_; 05620 05621 // set spawn time to infinite past if this is the first spawn 05622 if ( !sg_cycleFirstSpawnProtection && spawnTime_ <= 1.0 ) 05623 { 05624 spawnTime_ = -1E+20; 05625 } 05626 dirSpawn = dirDrive; 05627 05628 // reset position and direction 05629 predictPosition_ = pos; 05630 dir = dirDrive; 05631 skew = skewDot = 0; 05632 lastDirDrive=dirDrive; 05633 lastTurnPos_=pos; 05634 } 05635 #ifdef DEBUG 05636 else 05637 if ( correctPosSmooth.NormSquared() > .1f && lastTime > 0.0 ) 05638 { 05639 std::cout << "Lag slide! " << correctPosSmooth << "\n"; 05640 int x; 05641 x = 0; 05642 } 05643 #endif 05644 05645 sn_Update(turns,lastSyncMessage_.turns); 05646 05647 //if (fabs(correctTimeSmooth > 5)) 05648 // st_Breakpoint(); 05649 05650 // calculate new winding number. Try to change it as little as possible. 05651 this->SetWindingNumberWrapped( Grid()->DirectionWinding(dirDrive) ); 05652 05653 // Resnap to the axis 05654 dirDrive = Grid()->GetDirection(windingNumberWrapped_);
void gCycle::RequestSyncOwner | ( | ) | [virtual] |
requests special syncs to the owner on important points (just passed an enemy trail end safely...)
Definition at line 5012 of file gCycle.cpp.
References gCycleMovement::Alive(), nextSyncOwner, nSERVER, nNetObject::Owner(), REAL, gCycleMovement::RequestSync(), sg_GetSyncIntervalSelf(), sn_GetNetState(), and tSysTimeFloat().
Referenced by PassEdge(), and TimestepCore().
05014 { 05015 // no more syncs when you're dead 05016 if ( !Alive() ) 05017 { 05018 return; 05019 } 05020 05021 // nothing to do on the client or if the cycle belongs to an AI 05022 if ( sn_GetNetState() != nSERVER || Owner() == 0 ) 05023 return; 05024 05025 REAL syncInterval = sg_GetSyncIntervalSelf( this ); 05026 if ( nextSyncOwner < tSysTimeFloat() + syncInterval * 2.0 ) 05027 { 05028 // postpone next sync so the notal number of syncs stays the same 05029 RequestSync( Owner(), false ); 05030 nextSyncOwner += syncInterval; 05031 }
void gCycle::RequestSyncAll | ( | ) | [virtual] |
requests special syncs to everyone on important points (just passed an enemy trail end safely...)
Definition at line 5033 of file gCycle.cpp.
References gCycleMovement::Alive(), nextSync, nSERVER, nNetObject::Owner(), REAL, gCycleMovement::RequestSync(), sg_syncIntervalEnemy, sn_GetNetState(), and tSysTimeFloat().
Referenced by PassEdge().
05035 { 05036 // no more syncs when you're dead 05037 if ( !Alive() ) 05038 { 05039 return; 05040 } 05041 05042 // nothing to do on the client or if the cycle belongs to an AI 05043 if ( sn_GetNetState() != nSERVER || Owner() == 0 ) 05044 return; 05045 05046 REAL syncInterval = sg_syncIntervalEnemy; 05047 if ( nextSync < tSysTimeFloat() + syncInterval * 2.0 ) 05048 { 05049 // postpone next sync so the notal number of syncs stays the same 05050 RequestSync( false ); 05051 nextSync += syncInterval; 05052 }
void gCycle::SyncEnemy | ( | const eCoord & | begWall | ) | [virtual] |
handle sync message for enemy cycles
Definition at line 5656 of file gCycle.cpp.
References b, gCycleMovement::SyncData::brakingReservoir, gCycleMovement::brakingReservoir, eNetGameObject::clientside_action(), correctDistanceSmooth, CYCLE_TURN, gCycleMovement::SyncData::dir, gCycleMovement::dirDrive, gCycleMovement::SyncData::distance, gCycleMovement::distance, eDebugLine::Draw(), eCoord, EPS, eSoundMixer::GetMixer(), gNetPlayerWall, eNetGameObject::laggometer, eNetGameObject::laggometerSmooth, gCycleMovement::lastDirDrive, lastSyncMessage_, eGameObject::lastTime, lastTimeAnim, gCycleMovement::lastTimestep_, gCycleMovement::MoveSafely(), nCLIENT, NULL, nNetObject::Owner(), eGameObject::pos, gCycleMovement::SyncData::pos, eSoundMixer::PushButton(), REAL, resimulate_, gCycleMovement::SyncData::rubber, gCycleMovement::rubber, se_GameTime(), eDebugLine::SetColor(), eDebugLine::SetTimeout(), sg_cycleWallTime, skewDot, sn_GetNetState(), sn_myNetID, spawnTime_, gCycleMovement::SyncData::speed, tASSERT, gCycleMovement::SyncData::time, eGameObject::TimestepThis(), gCycleMovement::SyncData::turns, gCycleMovement::turns, and gCycleMovement::verletSpeed_.
Referenced by ReadSync().
05658 { 05659 // keep this cycle alive 05660 tJUST_CONTROLLED_PTR< gCycle > keep( this->GetRefcount()>0 ? this : 0 ); 05661 05662 resimulate_ = false; 05663 05664 // calculate turning 05665 bool turned = false; 05666 REAL turnDirection=( dirDrive*lastSyncMessage_.dir ); 05667 REAL notTurned=eCoord::F( dirDrive, lastSyncMessage_.dir )/dirDrive.NormSquared(); 05668 05669 // the last known time 05670 REAL lastKnownTime = lastTime; 05671 05672 // calculate the position of the last turn from the sync data 05673 if ( distance > 0 && ( notTurned < .99 || this->turns < lastSyncMessage_.turns ) ) 05674 { 05675 // update old wall as good as we can 05676 eCoord crossPos = lastSyncMessage_.pos; 05677 REAL crossDist = lastSyncMessage_.distance; 05678 REAL crossTime = lastSyncMessage_.time; 05679 05680 // calculate intersection of old and new trajectory (if only one turn was made) 05681 // the second condition is for old servers that don't send the turn count; they 05682 // don't support multiple axes, so we can possibly detect missed turns if 05683 // the dot product of the current and last direction is negative. 05684 if (this->turns+1 >= lastSyncMessage_.turns && ( lastSyncMessage_.turns > 0 || notTurned > -.5 ) ) 05685 { 05686 if ( fabs( turnDirection ) > .01 ) 05687 { 05688 REAL b = ( crossPos - pos ) * dirDrive; 05689 REAL distplace = b/turnDirection; 05690 crossPos = crossPos + lastSyncMessage_.dir * distplace; 05691 crossDist += distplace; 05692 if ( lastSyncMessage_.speed > 0 ) 05693 crossTime += distplace / lastSyncMessage_.speed; 05694 05695 tASSERT( fabs ( ( crossPos - pos ) * dirDrive ) < 1 ); 05696 tASSERT( fabs ( ( crossPos - lastSyncMessage_.pos ) * lastSyncMessage_.dir ) < 1 ); 05697 05698 // update the old wall 05699 if (currentWall) { 05700 currentWall->Update(crossTime,crossPos); 05701 05702 eSoundMixer* mixer = eSoundMixer::GetMixer(); 05703 mixer->PushButton(CYCLE_TURN, crossPos); 05704 } 05705 } 05706 } 05707 else 05708 { 05709 // a turn sync was dropped for whatever reason. The last wall is not reliable. 05710 // make it disappear immediately. 05711 if (currentWall) 05712 { 05713 currentWall->real_CopyIntoGrid(grid); 05714 } 05715 } 05716 05717 eDebugLine::SetTimeout(5); 05718 eDebugLine::SetColor( 1,0,0 ); 05719 eDebugLine::Draw( crossPos, 0, crossPos, 8 ); 05720 05721 // drop old wall 05722 if(currentWall){ 05723 lastWall=currentWall; 05724 currentWall->CopyIntoGrid( grid ); 05725 tControlledPTR< gNetPlayerWall > bounce( currentWall ); 05726 currentWall=NULL; 05727 } 05728 05729 // create new wall at sync location 05730 distance = lastSyncMessage_.distance; 05731 correctDistanceSmooth=0; 05732 05733 REAL startBuildWallAt = spawnTime_ + sg_cycleWallTime; 05734 if ( crossTime > startBuildWallAt ) 05735 currentWall=new gNetPlayerWall 05736 (this,crossPos,lastSyncMessage_.dir,crossTime,crossDist); 05737 05738 turned = true; 05739 05740 // save last driving direction 05741 lastDirDrive = dirDrive; 05742 05743 // move to cross position 05744 MoveSafely( crossPos, lastTime, crossTime ); 05745 lastKnownTime = crossTime; 05746 } 05747 05748 // side bending 05749 skewDot+=4*turnDirection; 05750 05751 // calculate timestep 05752 // REAL ts = lastSyncMessage_.time - lastTime; 05753 05754 // backup current time 05755 REAL oldTime = lastTime; 05756 05757 // update position, speed, distance and direction 05758 MoveSafely( lastSyncMessage_.pos, lastKnownTime, lastSyncMessage_.time ); 05759 verletSpeed_ = lastSyncMessage_.speed; 05760 lastTimestep_ = 0; 05761 distance = lastSyncMessage_.distance; 05762 correctDistanceSmooth=0; 05763 dirDrive = lastSyncMessage_.dir; 05764 rubber = lastSyncMessage_.rubber; 05765 brakingReservoir = lastSyncMessage_.brakingReservoir; 05766 05767 // update time to values from sync 05768 lastTime = lastSyncMessage_.time; 05769 if ( oldTime < 0 ) 05770 oldTime = lastTime; 05771 clientside_action(); 05772 05773 // bend last driving direction if it is antiparallel to the current one 05774 if ( lastDirDrive * dirDrive < EPS && eCoord::F( lastDirDrive, dirDrive ) < 0 ) 05775 { 05776 lastDirDrive = dirDrive.Turn(0,1); 05777 } 05778 05779 // correct laggometer to actual facts 05780 if (Owner() != sn_myNetID ) 05781 { 05782 // calculate lag from sync delay 05783 REAL lag = se_GameTime() - lastSyncMessage_.time; 05784 if ( lag < 0 ) 05785 lag = 0; 05786 05787 // try not to let the lag jump 05788 REAL maxLag = laggometer * 1.2; 05789 REAL minLag = laggometer * .8; 05790 05791 // store it 05792 laggometer = lag; 05793 05794 // clamp smooth laggometer to it (or set it if a turn was made) 05795 //if ( laggometerSmooth > lag ) 05796 // laggometerSmooth = lag; 05797 05798 // For the client and without prediction: 05799 // do not simulate if a turn was made, just accept sync as it is 05800 // (so turns don't look awkward) 05801 if ( 05802 sn_GetNetState()==nCLIENT && turned ) 05803 { 05804 laggometerSmooth = lag; 05805 05806 // but at least update the current wall 05807 if ( currentWall ) 05808 currentWall->Update(lastTime,pos); 05809 05810 // and reset the animation time 05811 lastTimeAnim=lastTime; 05812 05813 return; 05814 } 05815 else 05816 { 05817 // sanity check: the lag should not jump up suddenly 05818 // (and if it does, we'll catch up at the next turn) 05819 // REAL maxLag = 1.2 * laggometerSmooth; 05820 if ( laggometer > maxLag ) 05821 laggometer = maxLag; 05822 if ( laggometer < minLag ) 05823 laggometer = minLag; 05824 } 05825 } 05826 05827 // simulate to extrapolate, but don't touch the smooth laggometer 05828 { 05829 REAL laggometerSmoothBackup = this->laggometerSmooth; 05830 TimestepThis(oldTime, this); 05831 this->laggometerSmooth = laggometerSmoothBackup; 05832 }
void gCycle::ReceiveControl | ( | REAL | time, | |
uActionPlayer * | Act, | |||
REAL | x | |||
) | [virtual] |
Reimplemented from eNetGameObject.
Definition at line 5931 of file gCycle.cpp.
References Act(), and eGameObject::TimestepThis().
05932 { 05933 //forceTime=true; 05934 TimestepThis(time,this); 05935 Act(act,x); 05936 //forceTime=false;
void gCycle::PrintName | ( | tString & | s | ) | const [virtual] |
Reimplemented from nNetObject.
Definition at line 5938 of file gCycle.cpp.
References nNetObject::ID().
Referenced by sg_TopologyPoliceKill().
05940 { 05941 s << "gCycle nr. " << ID(); 05942 if ( this->player ) 05943 { 05944 s << " owned by "; 05945 this->player->PrintName( s ); 05946 }
bool gCycle::ActionOnQuit | ( | ) | [virtual] |
Reimplemented from eNetGameObject.
Definition at line 5948 of file gCycle.cpp.
References Kill(), nSERVER, sn_GetNetState(), and nNetObject::TakeOwnership().
Referenced by _wrap_GCycle_action_on_quit().
05950 { 05951 // currentWall = NULL; 05952 // lastWall = NULL; 05953 if ( sn_GetNetState() == nSERVER ) 05954 { 05955 TakeOwnership(); 05956 Kill(); 05957 return false; 05958 } 05959 else 05960 { 05961 return true; 05962 }
nDescriptor & gCycle::CreatorDescriptor | ( | void | ) | const [virtual] |
Implements nNetObject.
Definition at line 5965 of file gCycle.cpp.
References cycle_init.
Referenced by _wrap_GCycle_creator_descriptor().
05966 { 05967 return cycle_init;
bool gCycle::SyncIsNew | ( | nMessage & | m | ) | [virtual] |
Reimplemented from eNetGameObject.
Definition at line 4983 of file gCycle.cpp.
References con, nMessage::Read(), REAL, and eNetGameObject::SyncIsNew().
04984 { 04985 bool ret=eNetGameObject::SyncIsNew(m); 04986 04987 04988 REAL dummy2; 04989 short al; 04990 unsigned short Turns; 04991 04992 m >> dummy2; 04993 m >> al; 04994 m >> dummy2; 04995 m.Read(Turns); 04996 04997 #ifdef DEBUG_X 04998 con << "received sync for player " << player->GetName() << " "; 04999 if (ret || al!=1){ 05000 con << "accepting..\n"; 05001 return true; 05002 } 05003 else 05004 { 05005 con << "rejecting..\n"; 05006 return false; 05007 } 05008 #endif 05009 05010 return ret || al!=1;
bool gCycle::Timestep | ( | REAL | currentTime | ) | [virtual] |
advance to the given time
currentTime | the time to simulate up to |
Reimplemented from gCycleMovement.
Definition at line 2509 of file gCycle.cpp.
References gCycleChatBot::Activate(), gCycleMovement::Alive(), tRecorderSync< DATA >::Archive(), CalculatePredictPosition(), chatBot_, gCycleMovement::currentDestination, gCycleMovement::destinationList, Die(), gDestination::distance, dropWallRequested_, dt, Extrapolate(), extrapolator_, gCycleChatBot::Get(), nNetObject::ID(), gDestination::InsertIntoList(), KillAt(), eGameObject::lastTime, gCycleMovement::maxSpaceHit_, gDestination::messageID, nCLIENT, gCycleMovement::pendingTurns, eNetGameObject::Player(), eGameObject::pos, gCycleDeath::pos_, PredictPosition(), PreparePredictPosition(), REAL, ResetExtrapolator(), resimulate_, sg_ArchiveCoord(), sg_ArchiveReal(), sg_chatBotAlwaysActive, sg_gnuplotDebug, sg_minDropInterval, sg_syncFF, sg_syncFFSteps, sn_GetNetState(), sn_myNetID, SyncFromExtrapolator(), gCycleMovement::Timestep(), tNEW, tSysTimeFloat(), and gCycleMovement::verletSpeed_.
Referenced by sg_CreateWinDeathZone().
02510 { 02511 // clear out dangerous info when we're done 02512 gMaxSpaceAheadHitInfoClearer hitInfoClearer( maxSpaceHit_ ); 02513 02514 // if ( Owner() == sn_myNetID ) 02515 // con << pos << ',' << distance << ',' << eCoord::F( dirDrive, pos ) - distance << '\n'; 02516 02517 // request the right space ahead for wall extrapolation 02518 gPredictPositionData predictPositionData; 02519 PreparePredictPosition( predictPositionData ); 02520 02521 // drop current wall if it was requested 02522 if ( dropWallRequested_ ) 02523 { 02524 // but don't do so too often globally (performance) 02525 static double nextDrop = 0; 02526 double time = tSysTimeFloat(); 02527 if ( time >= nextDrop ) 02528 { 02529 unsigned short idrec = ID(); 02530 tRecorderSync< unsigned short >::Archive( "_PARTIAL_COPY_GRID", 8, idrec ); 02531 02532 nextDrop = time + sg_minDropInterval; 02533 if ( currentWall ) 02534 { 02535 currentWall->Update(lastTime,pos); 02536 currentWall->PartialCopyIntoGrid( grid ); 02537 } 02538 dropWallRequested_ = false; 02539 } 02540 } 02541 02542 #ifdef GNUPLOT_DEBUG 02543 if ( sg_gnuplotDebug && Player() ) 02544 { 02545 std::ofstream f( Player()->GetUserName() + "_step", std::ios::app ); 02546 f << pos.x << " " << pos.y << "\n"; 02547 } 02548 #endif 02549 // timewarp test debug code 02550 //if ( Player() && Player()->IsHuman() ) 02551 // currentTime -= .1; 02552 02553 // don't timestep when you're dead 02554 if ( !Alive() ) 02555 { 02556 // die completely 02557 Die( lastTime ); 02558 02559 // and let yourself be removed from the lists so we don't have to go 02560 // through this again. 02561 return true; 02562 } 02563 02564 // Debug archive position and speed 02565 sg_ArchiveCoord( pos, 7 ); 02566 sg_ArchiveReal( verletSpeed_, 7 ); 02567 02568 if ( !destinationList && sn_GetNetState() == nCLIENT ) 02569 { 02570 // insert emergency first destination without broadcasting it 02571 gDestination* dest = tNEW(gDestination)(*this); 02572 dest->messageID = 0; 02573 dest->distance = -.001; 02574 dest->InsertIntoList(&destinationList); 02575 } 02576 02577 // start new extrapolation 02578 if ( !extrapolator_ && resimulate_ ) 02579 ResetExtrapolator(); 02580 02581 // extrapolate state from server and copy state when finished 02582 if ( extrapolator_ ) 02583 { 02584 REAL dt = ( currentTime - lastTime ) * sg_syncFF / sg_syncFFSteps; 02585 #ifdef DEBUG 02586 // dt *= 10.101; 02587 //if ( !resimulate_ ) 02588 // dt *= .1; 02589 #endif 02590 for ( int i = sg_syncFFSteps - 1; i>= 0; --i ) 02591 { 02592 if ( Extrapolate( dt ) ) 02593 { 02594 SyncFromExtrapolator(); 02595 break; 02596 } 02597 } 02598 } 02599 02600 bool ret = false; 02601 02602 // nothing special if simulating backwards 02603 if (currentTime < lastTime) 02604 { 02605 ret = gCycleMovement::Timestep(currentTime); 02606 } 02607 // no targets are given 02608 else if ( !currentDestination && pendingTurns.empty() ) 02609 { 02610 // chatting? activate chatbot 02611 if ( bool(player) && 02612 player->IsHuman() && 02613 ( sg_chatBotAlwaysActive || player->IsChatting() ) && 02614 player->Owner() == sn_myNetID ) 02615 { 02616 gCycleChatBot & bot = gCycleChatBot::Get( this ); 02617 bot.Activate( currentTime ); 02618 } 02619 else if ( &(*chatBot_) ) 02620 { 02621 chatBot_->nextChatAI_ = 0; 02622 } 02623 02624 bool simulate=Alive(); 02625 02626 if ( !pendingTurns.empty() || currentDestination ) 02627 simulate=true; 02628 02629 if (simulate) 02630 { 02631 try 02632 { 02633 ret = gCycleMovement::Timestep(currentTime); 02634 } 02635 catch ( gCycleDeath const & death ) 02636 { 02637 KillAt( death.pos_ ); 02638 return false; 02639 } 02640 } 02641 else 02642 ret = !Alive(); 02643 } 02644 else 02645 { 02646 // just basic movement to do: let base class handle that. 02647 try 02648 { 02649 gCycleMovement::Timestep(currentTime); 02650 } 02651 catch ( gCycleDeath const & death ) 02652 { 02653 KillAt( death.pos_ ); 02654 return false; 02655 } 02656 } 02657 02658 // do the rest of the timestep 02659 try 02660 { 02661 if ( currentTime > lastTime ) 02662 ret = gCycleMovement::Timestep(currentTime); 02663 } 02664 catch ( gCycleDeath const & death ) 02665 { 02666 KillAt( death.pos_ ); 02667 return false; 02668 } 02669 02670 REAL predictTime = CalculatePredictPosition( predictPositionData ); 02671 02672 if ( Alive() && currentWall ) 02673 { 02674 // z-man: the next two lines are a very bad idea. This lets walls stick out on the other side while you're using up your rubber. 02675 //if ( sn_GetNetState() != nSERVER ) 02676 // wallEndPos = pos + dirDrive * ( verletSpeed_ * se_PredictTime() ); 02677 02678 // but using the predicted position which halts at walls may work 02679 currentWall->Update(predictTime, PredictPosition() ); 02680 } 02681 02682 return ret;
bool gCycle::TimestepCore | ( | REAL | currentTime, | |
bool | calculateAcceleration = true | |||
) | [virtual] |
core physics simulation routine
currentTime | time to simulate up to |
Reimplemented from gCycleMovement.
Definition at line 2738 of file gCycle.cpp.
References gCycleMovement::Alive(), gRealColor::b, clamp(), ClampDisplacement(), color_, correctDistanceSmooth, correctPosSmooth, crash_sparks, gPlayerWall::Cycle(), DecaySmooth(), Die(), eGameObject::dir, gCycleMovement::dirDrive, gCycleMovement::dirSpawn, DropWall(), eCoord, EPS, fr, gRealColor::g, gCycleMovement::GetMaxSpaceAhead(), joystick_, KillAt(), eGameObject::lastTime, lastTimeAnim, gCycleMovement::lastTurnPos_, gCycleMovement::MoveSafely(), nextSync, nextSyncOwner, nSERVER, nNetObject::Owner(), eGameObject::pos, gCycleDeath::pos_, gRealColor::r, REAL, gCycleMovement::RequestSync(), RequestSyncOwner(), rotate(), rotationFrontWheel, rotationRearWheel, gCycleMovement::rubberSpeedFactor, sg_ArchiveCoord(), sg_ArchiveReal(), sg_avoidBadOldClientSync, sg_cycleSyncSmoothMinSpeed, sg_cycleSyncSmoothThreshold, sg_cycleSyncSmoothTime, sg_cycleWallTime, sg_GetSparksDistance(), sg_GetSyncIntervalSelf(), sg_NoLocalTunnelOnSync, sg_syncIntervalEnemy, skew, skewDot, sn_Connections, sn_GetNetState(), spawnTime_, gCycleMovement::Speed(), sqrt(), nVersionFeature::Supported(), gCycleMovement::TimestepCore(), TransferPositionCorrectionToDistanceCorrection(), ts, tSysTimeFloat(), gJoystick::Turn(), nBandwidthControl::Usage_Planning, and gCycleMovement::verletSpeed_.
Referenced by OnNotifyNewDestination().
02739 { 02740 if (!finite(skew)) 02741 skew=0; 02742 if (!finite(skewDot)) 02743 skewDot=0; 02744 02745 eCoord oldpos=pos; 02746 02747 // let the joystick execute delayed turns 02748 if ( joystick_ ) 02749 { 02750 joystick_->Turn(); 02751 } 02752 02753 // archive rubber speed for later comparison 02754 REAL rubberSpeedFactorBack = rubberSpeedFactor; 02755 02756 REAL ts=(currentTime-lastTime); 02757 02758 clamp(ts, -10, 10); 02759 //clamp(correctTimeSmooth, -100, 100); 02760 clamp(correctDistanceSmooth, -100, 100); 02761 //clamp(correctSpeedSmooth, -100, 100); 02762 02763 // scale factor for smoothing. It is always used as 02764 // value += smooth * smooth_correction; 02765 // smooth_correction -= smooth * smooth_correction; 02766 02767 REAL smooth = 0; 02768 02769 if ( ts > 0 ) 02770 { 02771 // go a bit of the way 02772 smooth = 1 - 1/( 1 + ts / sg_cycleSyncSmoothTime ); 02773 } 02774 02775 //if ( smooth > 0) 02776 //{ 02777 // REAL scd = correctDistanceSmooth * smooth; 02778 // distance += scd; 02779 // correctDistanceSmooth -= scd; 02780 // } 02781 02782 // handle distance correction 02783 TransferPositionCorrectionToDistanceCorrection(); 02784 02785 // apply smooth position correction 02786 // smooth = .5f; 02787 //correctPosSmooth = eCoord(0,0); 02788 02789 // correctPosSmooth = correctPosSmooth * ( 1 - smooth ); 02790 02791 //if ( 0 ) 02792 02793 REAL animts=currentTime-lastTimeAnim; 02794 if (animts<0 || !finite(animts)) 02795 animts=0; 02796 else 02797 lastTimeAnim=currentTime; 02798 02799 // handle decaying of smooth position correction 02800 { 02801 // let components of smooth position correction decay 02802 REAL minSpeed = sg_cycleSyncSmoothMinSpeed * Speed() * animts; 02803 REAL clamp = sg_cycleSyncSmoothThreshold * Speed(); 02804 02805 DecaySmooth( correctPosSmooth.x, smooth, minSpeed, clamp ); 02806 DecaySmooth( correctPosSmooth.y, smooth, minSpeed, clamp ); 02807 02808 // do sanity checks 02809 if ( correctPosSmooth.NormSquared() > EPS ) 02810 { 02811 // cast ray to make sure corrected position lies on the right side of walls 02812 ClampDisplacement( this, correctPosSmooth, correctPosSmooth * 2, pos ); 02813 02814 // same for negative direction, players should see it when they are close to a wall 02815 ClampDisplacement( this, correctPosSmooth, -correctPosSmooth, pos ); 02816 02817 // cast another some rays into the future 02818 eCoord lookahead = dirDrive * ( 2 * correctPosSmooth.Norm() ); 02819 ClampDisplacement( this, correctPosSmooth, lookahead, pos ); 02820 } 02821 } 02822 02823 if (animts>.2) 02824 animts=.2; 02825 02826 rotate(rotationFrontWheel,2*verletSpeed_*animts/.43); 02827 rotate(rotationRearWheel,2*verletSpeed_*animts/.73); 02828 02829 REAL sparksDistance = sg_GetSparksDistance(); 02830 REAL extension = .25; 02831 if ( extension < sparksDistance ) 02832 extension = sparksDistance; 02833 02834 // REAL step=speed*ts; // +.5*acceleration*ts*ts; 02835 02836 // animate cycle direction 02837 { 02838 // move it a bit closer to dirDrive 02839 dir=dir+dirDrive*animts*verletSpeed_*3; 02840 02841 // if it's too far away from dirDrive, clamp it 02842 eCoord dirDistance = dir - dirDrive; 02843 REAL dist = dirDistance.NormSquared(); 02844 const REAL maxDist = .8; 02845 if (dirDistance.NormSquared() > maxDist) 02846 dir = dirDrive + dirDistance* (1/sqrt(dist/maxDist)); 02847 02848 // normalize 02849 dir=dir*(1/sqrt(dir.NormSquared())); 02850 } 02851 02852 { 02853 eCoord oldPos = pos; 02854 02855 if ( Alive() ){ 02856 // delegate core work to base class 02857 try 02858 { 02859 // start building wall 02860 REAL startBuildWallAt = spawnTime_ + sg_cycleWallTime; 02861 if ( !currentWall && currentTime > startBuildWallAt ) 02862 { 02863 // simulate right to the spot where the wall should begin 02864 if ( currentTime < startBuildWallAt ) 02865 if ( gCycleMovement::TimestepCore( startBuildWallAt, calculateAcceleration ) ) 02866 return true; 02867 calculateAcceleration = true; 02868 02869 // build the wall, modifying the spawn time to make sure it happens 02870 REAL lastSpawn = spawnTime_; 02871 spawnTime_ += -1E+20; 02872 DropWall(); 02873 spawnTime_ = lastSpawn; 02874 dirSpawn = dirDrive; 02875 lastTurnPos_ = pos; // hack last turn position to generate good wall 02876 } 02877 02878 // simulate rest of frame 02879 if ( gCycleMovement::TimestepCore( currentTime, calculateAcceleration ) ) 02880 return true; 02881 } 02882 catch ( gCycleDeath const & death ) 02883 { 02884 KillAt( death.pos_ ); 02885 02886 // death exceptions are precise; we can safely take over the position from it 02887 oldPos = death.pos_; 02888 } 02889 } 02890 02891 // die where you started 02892 if ( !Alive() ) 02893 { 02894 MoveSafely(oldPos,currentTime,currentTime); 02895 Die( currentTime ); 02896 } 02897 } 02898 02899 // Debug archive position and speed 02900 sg_ArchiveCoord( pos, 7 ); 02901 sg_ArchiveReal( verletSpeed_, 7 ); 02902 02903 if (Alive()){ 02904 #ifndef DEDICATED 02905 // animate skew 02906 gSensor fl(this,pos,dirDrive.Turn(1,1)); 02907 gSensor fr(this,pos,dirDrive.Turn(1,-1)); 02908 02909 fl.detect(extension*4); 02910 fr.detect(extension*4); 02911 02912 if (fl.hit > extension) 02913 fl.hit = extension; 02914 02915 if (fr.hit > extension) 02916 fr.hit = extension; 02917 02918 REAL lr=(fl.hit-fr.hit)/extension; 02919 02920 // ODE for skew 02921 const REAL skewrelax=24; 02922 skewDot-=128*(skew+lr/2)*animts; 02923 skewDot/=1+skewrelax*animts; 02924 if (skew*skewDot>4) skewDot=4/skew; 02925 skew+=skewDot*animts; 02926 02927 REAL fac = 0.5f; 02928 if ( skew > fr.hit * fac ) 02929 { 02930 skew = fr.hit * fac; 02931 } 02932 if ( skew < -fl.hit * fac ) 02933 { 02934 skew = -fl.hit * fac; 02935 } 02936 02937 // generate sparks 02938 eCoord sparkpos,sparkdir; 02939 02940 if (fl.ehit && fl.hit<=sparksDistance){ 02941 sparkpos=pos+dirDrive.Turn(1,1)*fl.hit; 02942 sparkdir=dirDrive.Turn(0,-1); 02943 } 02944 if (fr.ehit && fr.hit<=sparksDistance){ 02945 sparkpos=pos+dirDrive.Turn(1,-1)*fr.hit; 02946 sparkdir=dirDrive.Turn(0,1); 02947 } 02948 02949 if (fabs(skew)<fabs(lr*.8) ){ 02950 skewDot-=lr*1000*animts; 02951 if (crash_sparks && animts>0) 02952 { 02953 gPlayerWall *tmpplayerWall=0; 02954 02955 if(fl.ehit) tmpplayerWall=dynamic_cast<gPlayerWall*>(fl.ehit->GetWall()); 02956 if(fr.ehit) tmpplayerWall=dynamic_cast<gPlayerWall*>(fr.ehit->GetWall()); 02957 02958 if(tmpplayerWall) { 02959 gCycle *tmpcycle = tmpplayerWall->Cycle(); 02960 02961 if( tmpcycle ) 02962 new gSpark(grid, sparkpos-dirDrive*.1,sparkdir,currentTime,color_.r,color_.g,color_.b,tmpcycle->color_.r,tmpcycle->color_.g,tmpcycle->color_.b); 02963 } 02964 else 02965 new gSpark(grid, sparkpos-dirDrive*.1,sparkdir,currentTime,color_.r,color_.g,color_.b,1,1,1); 02966 } 02967 } 02968 02969 if (fabs(skew)<fabs(lr*.9) ){ 02970 skewDot-=lr*100*animts; 02971 if (crash_sparks && animts>0) 02972 { 02973 gPlayerWall *tmpplayerWall=0; 02974 02975 if(fl.ehit) tmpplayerWall=dynamic_cast<gPlayerWall*>(fl.ehit->GetWall()); 02976 if(fr.ehit) tmpplayerWall=dynamic_cast<gPlayerWall*>(fr.ehit->GetWall()); 02977 02978 if(tmpplayerWall) { 02979 gCycle *tmpcycle = tmpplayerWall->Cycle(); 02980 02981 if( tmpcycle ) 02982 new gSpark(grid, sparkpos-dirDrive*.1,sparkdir,currentTime,color_.r,color_.g,color_.b,tmpcycle->color_.r,tmpcycle->color_.g,tmpcycle->color_.b); 02983 } 02984 else 02985 new gSpark(grid, sparkpos-dirDrive*.1,sparkdir,currentTime,color_.r,color_.g,color_.b,1,1,1); 02986 } 02987 } 02988 #endif 02989 /* 02990 if (fl.hit+fr.hit<extension*.4) 02991 Kill(); 02992 */ 02993 } 02994 02995 // clamp skew 02996 if (skew>.5){ 02997 skew=.5; 02998 skewDot=0; 02999 } 03000 03001 if (skew<-.5){ 03002 skew=-.5; 03003 skewDot=0; 03004 } 03005 03006 // checkpoint wall when rubber starts to get used 03007 if ( currentWall ) 03008 { 03009 if ( rubberSpeedFactor >= .99 && rubberSpeedFactorBack < .99 ) 03010 { 03011 currentWall->Checkpoint(); 03012 } 03013 03014 if ( rubberSpeedFactor < .99 && rubberSpeedFactorBack >= .99 ) 03015 { 03016 currentWall->Checkpoint(); 03017 } 03018 03019 if ( rubberSpeedFactor < .1 && rubberSpeedFactorBack >= .1 ) 03020 { 03021 currentWall->Checkpoint(); 03022 } 03023 03024 if ( rubberSpeedFactor < .01 && rubberSpeedFactorBack >= .01 ) 03025 { 03026 currentWall->Checkpoint(); 03027 } 03028 } 03029 03030 03031 if ( sn_GetNetState()==nSERVER ) 03032 { 03033 // do an emergency sync when rubber starts to get used, it may come unexpected to clients 03034 if ( rubberSpeedFactor < .99 && rubberSpeedFactorBack >= .99 ) 03035 { 03036 RequestSyncOwner(); 03037 } 03038 03039 if (nextSync < tSysTimeFloat() ) 03040 { 03041 // delay syncs for old clients when there is a wall ahead; they would tunnel locally 03042 REAL lookahead = Speed() * sg_syncIntervalEnemy*.5; 03043 if ( !sg_avoidBadOldClientSync || sg_NoLocalTunnelOnSync.Supported( Owner() ) || GetMaxSpaceAhead( lookahead ) >= lookahead ) 03044 { 03045 RequestSync(false); 03046 03047 // checkpoint wall for better collision accuracy, only required on the server 03048 if ( currentWall ) 03049 currentWall->Checkpoint(); 03050 } 03051 03052 nextSync=tSysTimeFloat()+sg_syncIntervalEnemy; 03053 nextSyncOwner=tSysTimeFloat()+sg_GetSyncIntervalSelf( this ); 03054 } 03055 else if ( nextSyncOwner < tSysTimeFloat() && 03056 Owner() != 0 && 03057 sn_Connections[Owner()].bandwidthControl_.Control( nBandwidthControl::Usage_Planning ) > 200 ) 03058 { 03059 // sync only to the owner (provided there is enough bandwidth available) 03060 RequestSyncOwner(); 03061 } 03062 } 03063 03064 return (!Alive());
void gCycle::InteractWith | ( | eGameObject * | target, | |
REAL | time, | |||
int | recursion = 1 | |||
) | [virtual] |
Reimplemented from eGameObject.
Definition at line 3067 of file gCycle.cpp.
03068 { 03069 /* 03070 if (alive && target->type()==ArmageTron_CYCLE){ 03071 gCycle *c=(gCycle *)target; 03072 if (c->alive){ 03073 const eEdge *current_eEdge=Edge(); 03074 const eEdge *other_eEdge=c->Edge(); 03075 if(current_eEdge && other_eEdge){ 03076 ePoint *meet=current_eEdge->IntersectWith(other_eEdge); 03077 if (meet){ // somebody is going to die! 03078 REAL ratio=current_eEdge->Ratio(*meet); 03079 REAL time=CurrentWall()->Time(ratio); 03080 PassEdge(other_eEdge,time,other_eEdge->Ratio(*meet),0); 03081 } 03082 } 03083 } 03084 } 03085 */
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 gCycleMovement.
Definition at line 3264 of file gCycle.cpp.
References gPlayerWall::Cycle(), gPlayerWall::CycleMovement(), gCycleMovement::EdgeIsDangerous(), gJustChecking::justChecking, gPlayerWall::NetWall(), nNetObject::Owner(), sn_myNetID, eGameObject::Team(), gPlayerWall::Time(), and Vulnerable().
Referenced by PassEdge().
03265 { 03266 gPlayerWall const * w = dynamic_cast< gPlayerWall const * >( ww ); 03267 if ( w ) 03268 { 03269 if ( !Vulnerable() ) 03270 return false; 03271 03272 gNetPlayerWall *nw = w->NetWall(); 03273 03274 // check whether the wall is one of the walls no real collision is 03275 // possible with. The lastNetWall is only checked for enemy cycles, 03276 // because it can be an arbitrary wall for your own cycle. But for 03277 // enemy cycles, it may be what lastWall should be, and the test 03278 // prevents enemy cycles from getting stuck right after a turn. 03279 if( nw == currentWall || nw == lastWall || ( nw == lastNetWall && Owner() != sn_myNetID ) ) 03280 return false; 03281 03282 // see if the wall is from another player and from the future. 03283 // if it is, it's not dangerous, this cycle was here first. 03284 // on passing the wall later, the other cycle will be pushed back 03285 // to the collision point or killed if that is no longer possible. 03286 // z-man notes: I've got the vaque feeling something like this was 03287 // here before, but got thrown out again for making problems. 03288 if ( gJustChecking::justChecking && w->CycleMovement() != static_cast< const gCycleMovement * >( this ) && w->Time(a) > time ) 03289 { 03290 // One problem with this is that you kill teammates if they can't 03291 // be pushed back, whereas we'd just use our rubber to survive. 03292 // So we should first check whether the other player should be 03293 // protected. 03294 gCycle const * otherPlayer = w->Cycle(); 03295 if ( !otherPlayer || // valididy 03296 otherPlayer->Team() != this->Team() || // team protection 03297 !otherPlayer->currentWall || w == otherPlayer->currentWall->Wall() // pushback protection, if the other player can be pushed back, it's all right as well 03298 ) 03299 return false; 03300 } 03301 } 03302 03303 return gCycleMovement::EdgeIsDangerous( ww, time, a );
Reimplemented from eGameObject.
Definition at line 3338 of file gCycle.cpp.
References gExplosion::AccountForHole(), gEnemyInfluence::AddWall(), gCycleMovement::Alive(), ePlayerNetID::CurrentTeam(), gPlayerWall::Cycle(), d, gCycleMovement::dirDrive, gCycleMovement::distance, DropWall(), dropWallRequested_, dt, eCoord, EdgeIsDangerous(), gCycleMovement::enemyInfluence, EPS, Extrapolate(), extrapolator_, gCycleMovement::GetDistanceSinceLastTurn(), gCycleMovement::GetLastTurnPos(), eGameObject::GetMaxLazyLag(), gExplosion::GetOwner(), ePlayerNetID::GetUserName(), gPlayerWall::Holer(), KillAt(), eNetGameObject::Lag(), eGameObject::LastTime(), eGameObject::lastTime, max(), gCycleMovement::MoveSafely(), nCLIENT, eNetGameObject::Player(), eWall::Point(), eGameObject::pos, gPlayerWall::Pos(), REAL, RequestSyncAll(), RequestSyncOwner(), ResetExtrapolator(), gCycleMovement::rubber, score_hole, se_GameTime(), se_SaveToLadderLog(), sg_HoleScore(), sg_KillFutureWalls(), sg_RubberValues(), sn_GetNetState(), gCycleMovement::Speed(), ThisWallsLength(), gPlayerWall::Time(), gCycleMovement::verletSpeed_, and Vulnerable().
Referenced by sg_TopologyPoliceCheck().
03339 { 03340 { 03341 // deactivate time check 03342 gJustChecking thisIsSerious; 03343 03344 if (!EdgeIsDangerous(ww,time,a) || !Alive() ) 03345 { 03346 // request a sync for everyone if this is a non-bogus wall passage, maybe not all clients know the wall is passable 03347 if ( ( !currentWall || ww != currentWall->Wall() ) && ( !lastWall || ww != lastWall->Wall() ) ) 03348 RequestSyncAll(); 03349 03350 // check whether we drove through a hole in an enemy wall made by a teammate 03351 gPlayerWall const * w = dynamic_cast< gPlayerWall const * >( ww ); 03352 if ( w && score_hole ) 03353 { 03354 gExplosion * explosion = w->Holer( a, time ); 03355 if ( explosion ) 03356 { 03357 gCycle * holer = explosion->GetOwner(); 03358 if ( holer && holer->Player() && 03359 Player() && 03360 w->Cycle() && w->Cycle()->Player() && 03361 holer->Player()->CurrentTeam() == Player()->CurrentTeam() && // holer must have been a teammate 03362 w->Cycle()->Player()->CurrentTeam() != Player()->CurrentTeam() // wall must have been an enemy 03363 ) 03364 { 03365 // this test must come last, it resets the flag. 03366 if ( explosion->AccountForHole() ) 03367 { 03368 tString ladderLog; 03369 ladderLog << "SACRIFICE " << Player()->GetUserName() << " " << holer->Player()->GetUserName() << " " << w->Cycle()->Player()->GetUserName() << "\n"; 03370 se_SaveToLadderLog( ladderLog ); 03371 if ( score_hole > 0 ) 03372 { 03373 // positive hole score goes to the holer 03374 sg_HoleScore( *holer ); 03375 } 03376 else 03377 { 03378 // negative hole score to the driver 03379 sg_HoleScore( *this ); 03380 03381 } 03382 } 03383 } 03384 } 03385 } 03386 03387 return; 03388 } 03389 03390 #ifdef DEBUG 03391 if (!EdgeIsDangerous(ww,time,a) || !Alive() ) 03392 return; 03393 #endif 03394 } 03395 03396 // request a sync to bring everyone up to date about the cycle passing/getting stuck on this wall 03397 RequestSyncOwner(); 03398 03399 #ifdef DEBUG_X 03400 // keep other cycle around 03401 tJUST_CONTROLLED_PTR<gCycleExtrapolator> keepOther( extrapolator_ ); 03402 03403 ResetExtrapolator(); 03404 03405 // extrapolate state from server and copy state when finished 03406 REAL dt = 1; 03407 for ( int i = 9; i>= 0; --i ) 03408 { 03409 Extrapolate( dt ); 03410 } 03411 03412 extrapolator_ = keepOther; 03413 #endif 03414 03415 eCoord collPos = ww->Point( a ); 03416 03417 const gPlayerWall *w = dynamic_cast<const gPlayerWall*>(ww); 03418 03419 enemyInfluence.AddWall( ww, collPos, 0, this ); 03420 03421 if (w) 03422 { 03423 gCycle *otherPlayer=w->Cycle(); 03424 03425 REAL otherTime = w->Time(a); 03426 if(otherPlayer && time < otherTime*(1-EPS) ) 03427 { 03428 // also send updates about the other cylce 03429 otherPlayer->RequestSyncOwner(); 03430 03431 // get the distance of the wall 03432 REAL wallDist = w->Pos(a); 03433 // get the distance the cycle is simulated up to 03434 REAL cycleDist = w->Cycle()->distance; 03435 // comparing these two gives an accurate criterion whether the wall is extrapolated 03436 if ( wallDist > cycleDist * (1 + EPS ) ) 03437 { 03438 static bool fix = false; 03439 // it's an extrapolation wall, don't simulate further. 03440 if ( fix && lastTime > se_GameTime() - 2 * Lag() - GetMaxLazyLag() ) 03441 throw gCycleStop(); 03442 else 03443 return; 03444 } 03445 03446 // we were first! 03447 if ( otherPlayer->Vulnerable() ) 03448 { 03449 static bool tryToSaveFutureWallOwner = true; 03450 bool saved = false; 03451 03452 if ( tryToSaveFutureWallOwner && otherPlayer->currentWall && w == otherPlayer->currentWall->Wall() ) 03453 { 03454 // teleport the other cycle back to the point before the collision; its next timestep 03455 // will simulate the collision again from the right viewpoint 03456 // determine the distance of the pushback 03457 REAL d = otherPlayer->GetDistanceSinceLastTurn() * .001; 03458 if ( d < .01 ) 03459 d = .01; 03460 REAL maxd = eCoord::F( otherPlayer->dirDrive, collPos - otherPlayer->GetLastTurnPos() ) * .5/otherPlayer->dirDrive.NormSquared(); 03461 if ( d > maxd ) 03462 d = maxd; 03463 if ( d > 0 ) 03464 { 03465 saved = true; 03466 03467 // do the move 03468 otherPlayer->MoveSafely( collPos-otherPlayer->dirDrive*d, otherPlayer->LastTime(), otherTime - d/otherPlayer->Speed() ); 03469 otherPlayer->currentWall->Update( otherPlayer->lastTime, otherPlayer->pos ); 03470 otherPlayer->dropWallRequested_ = false; 03471 03472 // drop our wall so collisions are more accurate 03473 dropWallRequested_ = true; 03474 } 03475 } 03476 03477 // another possibility: if the walls are very short compared to rubber, we could 03478 // get away with just accounding for some rubber on the cycle that we'd need to kill 03479 // otherwise. 03480 if ( !saved && verletSpeed_ >= 0 ) 03481 { 03482 REAL dt = otherTime - time; 03483 03484 // this long would the other cycle have to sit in front of our wall 03485 // before he's released by the end 03486 REAL wallTimeLeft = this->ThisWallsLength()/verletSpeed_ - dt; 03487 03488 if ( wallTimeLeft < 0 ) 03489 { 03490 // isn't hit at all 03491 return; 03492 } 03493 03494 // check how much rubber would be used 03495 REAL max, effectiveness; 03496 sg_RubberValues( otherPlayer->Player(), otherPlayer->verletSpeed_, max, effectiveness ); 03497 if ( effectiveness > 0 ) 03498 { 03499 REAL rubberToEat = wallTimeLeft * otherPlayer->Speed()/effectiveness; 03500 03501 otherPlayer->rubber += rubberToEat; 03502 if ( otherPlayer->rubber > max ) 03503 otherPlayer->rubber = max; // too much rubber used 03504 else 03505 saved = true; // within bounds, he may survive 03506 } 03507 } 03508 03509 if ( !saved && sn_GetNetState() != nCLIENT ) 03510 { 03511 // err, trouble. Can't push the other guy back far enough. Better kill him. 03512 if ( currentWall ) 03513 otherPlayer->enemyInfluence.AddWall( currentWall->Wall(), lastTime, otherPlayer ); 03514 otherPlayer->distance = wallDist; 03515 otherPlayer->DropWall(); 03516 otherPlayer->KillAt( collPos ); 03517 03518 // get rid of future walls 03519 sg_KillFutureWalls( otherPlayer ); 03520 } 03521 } 03522 } 03523 else // sad but true 03524 { 03525 // this cycle has to die here unless it has rubber left or is invulnerable (checked on catching the exception, and besides, this code path isn't called for invulnerable cycles) 03526 throw gCycleDeath( collPos ); 03527 03528 // REAL dist = w->Pos( a ); 03529 // const_cast<gPlayerWall*>(w)->BlowHole( dist - explosionRadius, dist + explosionRadius ); 03530 } 03531 } 03532 else 03533 { 03534 if (bool(player) && sn_GetNetState()!=nCLIENT && Alive() ) 03535 { 03536 throw gCycleDeath( collPos ); 03537 } 03538 03539 }
Reimplemented from eGameObject.
Definition at line 3541 of file gCycle.cpp.
03543 { 03544 if (!w) 03545 return 1; 03546 if (dynamic_cast<const gPlayerWall*>(w)) 03547 return .9f; 03548 else 03549 return 1;
bool gCycle::Act | ( | uActionPlayer * | Act, | |
REAL | x | |||
) | [virtual] |
Reimplemented from eGameObject.
Definition at line 3552 of file gCycle.cpp.
References gCycleMovement::AccelerationDiscontinuity(), gJoystick::Act(), gCycleMovement::AddDestination(), gCycleMovement::Alive(), gCycleMovement::braking, joystick_, nSERVER, gCycleMovement::RequestSync(), s_brake, s_brakeToggle, se_mainGameTimer, eGameObject::se_turnLeft, eGameObject::se_turnRight, sn_GetNetState(), eTimer::speed, eTimer::Time(), and gCycleMovement::Turn().
Referenced by ReceiveControl().
03553 { 03554 // delegate to joystick 03555 if ( joystick_ && joystick_->Act( Act, x ) ) 03556 { 03557 return true; 03558 } 03559 03560 // don't accept premature input 03561 if (se_mainGameTimer && ( se_mainGameTimer->speed <= 0 || se_mainGameTimer->Time() < -1 ) ) 03562 return false; 03563 03564 if (!Alive() && sn_GetNetState()==nSERVER) 03565 RequestSync(false); 03566 03567 if(se_turnLeft==*Act && x>.5){ 03568 //SendControl(lastTime,&se_turnLeft,1); 03569 Turn(-1); 03570 return true; 03571 } 03572 else if(se_turnRight==*Act && x>.5){ 03573 //SendControl(lastTime,&se_turnRight,1); 03574 Turn(1); 03575 return true; 03576 } 03577 else if(s_brake==*Act){ 03578 //SendControl(lastTime,&brake,x); 03579 unsigned short newBraking=(x>0); 03580 if ( braking != newBraking ) 03581 { 03582 AccelerationDiscontinuity(); 03583 braking = newBraking; 03584 AddDestination(); 03585 } 03586 return true; 03587 } 03588 else if(s_brakeToggle==*Act){ 03589 if ( x > 0 ) 03590 { 03591 AccelerationDiscontinuity(); 03592 braking = !braking; 03593 AddDestination(); 03594 } 03595 return true; 03596 } 03597 return false;
bool gCycle::DoTurn | ( | int | dir | ) | [virtual] |
turns the cycle in the given direction
dir | +1 for right turns, -1 for left turns |
Reimplemented from gCycleMovement.
Definition at line 3621 of file gCycle.cpp.
References gCycleMovement::AddDestination(), gCycleMovement::Alive(), eNetGameObject::clientside_action(), con, CYCLE_TURN, gCycleMovement::dirDrive, gCycleMovement::DoTurn(), DropWall(), eCoord, EPS, eGameObject::FindCurrentFace(), eSoundMixer::GetMixer(), gCycleMovement::lastDirDrive, nCLIENT, nSERVER, nNetObject::Owner(), eNetGameObject::Player(), eGameObject::pos, eGameObject::Position(), eSoundMixer::PushButton(), REAL, gCycleMovement::RequestSync(), sg_ArchiveCoord(), sg_gnuplotDebug, skewDot, sn_GetNetState(), sn_myNetID, tSysTimeFloat(), and gCycleMovement::turns.
03623 { 03624 #ifdef DELAYEDTURN_DEBUG 03625 REAL delay = tSysTimeFloat() - sg_turnReceivedTime; 03626 if ( delay > EPS && sn_GetNetState() == nSERVER && Owner() != 0 ) 03627 { 03628 con << "Delayed turn execution! " << turns << "\n"; 03629 } 03630 #endif 03631 03632 #ifdef GNUPLOT_DEBUG 03633 if ( sg_gnuplotDebug && Player() ) 03634 { 03635 std::ofstream f( Player()->GetUserName() + "_turn", std::ios::app ); 03636 f << pos.x << " " << pos.y << "\n"; 03637 } 03638 #endif 03639 03640 if (d > 1) d = 1; 03641 if (d < -1) d = -1; 03642 03643 if (Alive()){ 03644 eSoundMixer* mixer = eSoundMixer::GetMixer(); 03645 mixer->PushButton(CYCLE_TURN, Position()); 03646 03647 clientside_action(); 03648 03649 if ( gCycleMovement::DoTurn( d ) ) 03650 { 03651 sg_ArchiveCoord( pos, 1 ); 03652 03653 skewDot+=4*d; 03654 03655 if (sn_GetNetState() == nCLIENT && Owner() == ::sn_myNetID) 03656 AddDestination(); 03657 03658 if (sn_GetNetState()!=nCLIENT) 03659 { 03660 RequestSync(); 03661 } 03662 03663 // hack: while dropping the wall, turn around dirDrive. 03664 // this makes FindCurrentFace work better. 03665 { 03666 FindCurrentFace(); 03667 REAL factor = -16; 03668 eCoord dirDriveFake = dirDrive * factor; 03669 eCoord lastDirDriveBack = lastDirDrive; 03670 lastDirDrive = lastDirDrive * factor; 03671 gFakeDirDriveSetter fakeSetter( dirDriveFake ); 03672 DropWall(); 03673 lastDirDrive = lastDirDriveBack; 03674 } 03675 03676 return true; 03677 } 03678 } 03679 03680 return false;
void gCycle::DropWall | ( | bool | buildNew = true |
) |
Drops the current wall and builds a new one.
Definition at line 3682 of file gCycle.cpp.
References c, eGameObject::CurrentFace(), gCycleMovement::dirDrive, gCycleMovement::distance, dropWallRequested_, eCoord, eGameObject::FindCurrentFace(), gNetPlayerWall, eDual::IsInGrid(), eGameObject::lastTime, NULL, eGameObject::pos, sg_cycleWallTime, sg_fakeDirDrive, and spawnTime_.
Referenced by DoTurn(), PassEdge(), ReadSync(), and TimestepCore().
03684 { 03685 // keep this cycle alive 03686 tJUST_CONTROLLED_PTR< gCycle > keep( this->GetRefcount()>0 ? this : 0 ); 03687 03688 // drop last net wall if it is outdated 03689 if ( lastWall && lastNetWall && lastWall->Time(.5) > lastNetWall->Time(0) ) 03690 lastNetWall = 0; 03691 03692 // update and drop current wall 03693 if(currentWall) 03694 { 03695 lastWall=currentWall; 03696 currentWall->Update(lastTime,pos); 03697 currentWall->CopyIntoGrid( grid ); 03698 currentWall=NULL; 03699 } 03700 03701 if ( buildNew && lastTime >= spawnTime_ + sg_cycleWallTime ) 03702 currentWall=new gNetPlayerWall(this,pos,dirDrive,lastTime,distance); 03703 03704 // grid datastructures change on inserting a wall, better recheck 03705 // all game objects. Temporarily override this cycle's driving direction. 03706 eCoord dirDriveBack = dirDrive; 03707 if ( sg_fakeDirDrive ) 03708 dirDrive = *sg_fakeDirDrive; 03709 03710 if ( grid ) 03711 { 03712 for(int i=grid->GameObjects().Len()-1;i>=0;i--) 03713 { 03714 eGameObject * c = grid->GameObjects()(i); 03715 if (c->CurrentFace() && !c->CurrentFace()->IsInGrid() ) 03716 c->FindCurrentFace(); 03717 } 03718 } 03719 dirDrive = dirDriveBack; 03720 03721 // reset flag 03722 dropWallRequested_ = false;
void gCycle::Kill | ( | ) | [virtual] |
destroys the gameobject (in the game)
Reimplemented from eGameObject.
Definition at line 3724 of file gCycle.cpp.
References gCycleMovement::Alive(), color_, Die(), gCycleMovement::distance, eGameObject::GOID(), eGameObject::lastTime, nCLIENT, NULL, eGameObject::pos, gCycleMovement::RequestSync(), sn_GetNetState(), and tNEW.
Referenced by ActionOnQuit(), gGame::Analysis(), KillAt(), gDeathZoneHack::OnEnter(), and sg_TopologyPoliceKill().
03725 { 03726 // keep this cycle alive 03727 tJUST_CONTROLLED_PTR< gCycle > keep( this->GetRefcount()>0 ? this : 0 ); 03728 03729 if (sn_GetNetState()!=nCLIENT){ 03730 RequestSync(true); 03731 if (Alive() && grid && GOID() >= 0 ){ 03732 Die( lastTime ); 03733 tNEW(gExplosion)(grid, pos,lastTime, color_, this ); 03734 // eEdge::SeethroughHasChanged(); 03735 03736 if ( currentWall ) 03737 { 03738 // z-man: updating the wall so it reflects exactly the position of death looks like 03739 // a good idea, but unfortunately, the collision position reported from above 03740 // is inaccurate. It's better not to use it at all, or the cycle's wall will stick out 03741 // a bit on the other side of the wall it crashed into. 03742 03743 // but if prediction was active, do it anyway 03744 if ( currentWall->Pos(1) > distance || currentWall->Time(1) > lastTime ) 03745 currentWall->Update( lastTime, pos ); 03746 03747 // copy the wall into the grid, but not directly; the grid datastructures are probably currently traversed. Kill() is called from eGameObject::Move(). 03748 currentWall->CopyIntoGrid( 0 ); 03749 03750 currentWall = NULL; 03751 } 03752 } 03753 } 03754 // z-man: another stupid idea. Why would we need a destination when we're dead? 03755 // else if (Owner() == ::sn_myNetID) 03756 // AddDestination(); 03757 /* 03758 else if (owner!=::sn_myNetID) 03759 speed=-.01; 03760 */
const eTempEdge * gCycle::Edge | ( | ) |
Definition at line 1889 of file gCycle.cpp.
References eTempEdge::Edge(), and NULL.
01889 { 01890 if (currentWall) 01891 return currentWall->Edge(); 01892 else 01893 return NULL; 01894 }
const gPlayerWall * gCycle::CurrentWall | ( | ) |
Definition at line 1896 of file gCycle.cpp.
References NULL.
01896 { 01897 if (currentWall) 01898 return currentWall->Wall(); 01899 else 01900 return NULL; 01901 }
void gCycle::Render | ( | const eCamera * | cam | ) | [virtual] |
draws object to the screen using OpenGL
Reimplemented from eGameObject.
Definition at line 4141 of file gCycle.cpp.
References gCycleMovement::Alive(), gRealColor::b, BeginLineLoop(), BeginQuads(), BeginTriangles(), body, bodyTex, c, eCamera::CameraZ(), eCamera::Center(), color_, cos(), customModel, customTexture, cycle_shad, cycleprograminited, eGameObject::dir, eCoord, front, gRealColor::g, gCycleMovement::GetTurnDelay(), glMatrixMode, headlights, IdentityMatrix(), eNetGameObject::Lag(), eGameObject::lastTime, M_PI, ModelMatrix(), mp, nSERVER, nSTANDALONE, eGameObject::pos, PredictPosition(), gRealColor::r, REAL, rear, rModel::Render(), RenderEnd(), RenderName(), rFLOOR_GRID, rotationFrontWheel, rotationRearWheel, se_GameTime(), rITexture::Select(), sg_axesIndicator, sg_blinkFrequency, sg_laggometerScale, sg_laggometerThreshold, sin(), gArena::SizeMultiplier(), skew, sn_GetNetState(), spawnTime_, sqrt(), sr_alphaBlend, sr_DepthOffset(), sr_floorDetail, sr_laggometer, sr_predictObjects, st_Breakpoint(), rTextureGroups::TEX_FLOOR, TexMatrix(), rTextureGroups::TextureMode, tSysTimeFloat(), gCycleMovement::verletSpeed_, void(), Vulnerable(), wheelTex, x, and eGameObject::z.
04142 { 04143 // are we blinking from invulnerability? 04144 bool blinking = false; 04145 if ( lastTime > spawnTime_ && !Vulnerable() ) 04146 { 04147 double time = tSysTimeFloat(); 04148 double wrap = time - floor(time); 04149 int pulse = int ( 2 * wrap * sg_blinkFrequency ); 04150 blinking = pulse & 1; 04151 } 04152 04153 #ifdef USE_HEADLIGHT 04154 #ifdef LINUX 04155 typedef void (*glProgramStringARB_Func)(GLenum, GLenum, GLsizei, const void*); 04156 glProgramStringARB_Func glProgramStringARB_ptr = 0; 04157 04158 typedef void (*glProgramLocalParameter4fARB_Func)(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); 04159 glProgramLocalParameter4fARB_Func glProgramLocalParameter4fARB_ptr = 0; 04160 04161 glProgramStringARB_ptr = (glProgramStringARB_Func) SDL_GL_GetProcAddress("glProgramStringARB"); 04162 glProgramLocalParameter4fARB_ptr = (glProgramLocalParameter4fARB_Func) SDL_GL_GetProcAddress("glProgramLocalParameter4fARB"); 04163 #endif 04164 #endif 04165 if (!finite(z) || !finite(pos.x) ||!finite(pos.y)||!finite(dir.x)||!finite(dir.y) 04166 || !finite(skew)) 04167 st_Breakpoint(); 04168 if (Alive()){ 04169 //con << "Drawing cycle at " << pos << '\n'; 04170 04171 #ifdef DEBUG 04172 /* { 04173 gDestination *l = destinationList; 04174 glDisable(GL_LIGHTING); 04175 glColor3f(1,1,1); 04176 while(l){ 04177 if (l == currentDestination) 04178 glColor3f(0,1,0); 04179 04180 glBegin(GL_LINES); 04181 glVertex3f(l->position.x, l->position.y, 0); 04182 glVertex3f(l->position.x, l->position.y, 100); 04183 glEnd(); 04184 04185 if (l == currentDestination) 04186 glColor3f(0,1,1); 04187 04188 l=l->next; 04189 } 04190 } */ 04191 #endif 04192 04193 GLfloat color[4]={1,1,1,1}; 04194 static GLfloat lposa[4] = { 320, 240, 200,0}; 04195 static GLfloat lposb[4] = { -240, -100, 200,0}; 04196 static GLfloat lighta[4] = { 1, .7, .7, 1 }; 04197 static GLfloat lightb[4] = { .7, .7, 1, 1 }; 04198 04199 glMaterialfv(GL_FRONT_AND_BACK,GL_SPECULAR,color); 04200 glMaterialfv(GL_FRONT_AND_BACK,GL_DIFFUSE,color); 04201 04202 glLightfv(GL_LIGHT0, GL_DIFFUSE, lighta); 04203 glLightfv(GL_LIGHT0, GL_SPECULAR, lighta); 04204 glLightfv(GL_LIGHT0, GL_POSITION, lposa); 04205 glLightfv(GL_LIGHT1, GL_DIFFUSE, lightb); 04206 glLightfv(GL_LIGHT1, GL_SPECULAR, lightb); 04207 glLightfv(GL_LIGHT1, GL_POSITION, lposb); 04208 04209 04210 ModelMatrix(); 04211 glPushMatrix(); 04212 eCoord p = PredictPosition(); 04213 glTranslatef(p.x,p.y,0); 04214 glScalef(.5f,.5f,.5f); 04215 04216 04217 eCoord ske(1,skew); 04218 ske=ske*(1/sqrt(ske.NormSquared())); 04219 04220 GLfloat m[4][4]={{dir.x,dir.y,0,0}, 04221 {-dir.y,dir.x,0,0}, 04222 {0,0,1,0}, 04223 {0,0,0,1}}; 04224 glMultMatrixf(&m[0][0]); 04225 04226 glPushMatrix(); 04227 //glTranslatef(-1.84,0,0); 04228 if (!mp) 04229 glTranslatef(-1.5,0,0); 04230 04231 glPushMatrix(); 04232 04233 GLfloat sk[4][4]={{1,0,0,0}, 04234 {0,ske.x,ske.y,0}, 04235 {0,-ske.y,ske.x,0}, 04236 {0,0,0,1}}; 04237 04238 glMultMatrixf(&sk[0][0]); 04239 04240 04241 glEnable(GL_LIGHT0); 04242 glEnable(GL_LIGHT1); 04243 glEnable(GL_LIGHTING); 04244 04245 04246 04247 TexMatrix(); 04248 IdentityMatrix(); 04249 04250 if (mp){ 04251 04252 ModelMatrix(); 04253 if ( !blinking ) 04254 { 04255 glPushMatrix(); 04256 customTexture->Select(); 04257 glColor3f(1,1,1); 04258 customModel->Render(); 04259 glPopMatrix(); 04260 } 04261 04262 glPopMatrix(); 04263 glTranslatef(-1.5,0,0); 04264 } 04265 else{ 04266 glEnable(GL_TEXTURE_2D); 04267 04268 ModelMatrix(); 04269 04270 if ( !blinking ) 04271 { 04272 bodyTex->Select(); 04273 body->Render(); 04274 04275 wheelTex->Select(); 04276 04277 glPushMatrix(); 04278 glTranslatef(0,0,.73); 04279 04280 GLfloat mr[4][4]={{rotationRearWheel.x,0,rotationRearWheel.y,0}, 04281 {0,1,0,0}, 04282 {-rotationRearWheel.y,0,rotationRearWheel.x,0}, 04283 {0,0,0,1}}; 04284 04285 04286 glMultMatrixf(&mr[0][0]); 04287 04288 rear->Render(); 04289 glPopMatrix(); 04290 04291 glPushMatrix(); 04292 glTranslatef(1.84,0,.43); 04293 04294 GLfloat mf[4][4]={{rotationFrontWheel.x,0,rotationFrontWheel.y,0}, 04295 {0,1,0,0}, 04296 {-rotationFrontWheel.y,0,rotationFrontWheel.x,0}, 04297 {0,0,0,1}}; 04298 04299 glMultMatrixf(&mf[0][0]); 04300 04301 front->Render(); 04302 glPopMatrix(); 04303 } 04304 04305 glPopMatrix(); 04306 } 04307 04308 04309 // TexMatrix(); 04310 // IdentityMatrix(); 04311 ModelMatrix(); 04312 04313 /* 04314 glDisable(GL_TEXTURE_GEN_S); 04315 glDisable(GL_TEXTURE_GEN_T); 04316 glDisable(GL_TEXTURE_GEN_Q); 04317 glDisable(GL_TEXTURE_GEN_R); 04318 */ 04319 04320 glDisable(GL_LIGHT0); 04321 glDisable(GL_LIGHT1); 04322 glDisable(GL_LIGHTING); 04323 04324 //glDisable(GL_TEXTURE); 04325 glDisable(GL_TEXTURE_2D); 04326 glColor3f(1,1,1); 04327 04328 { 04329 bool renderPyramid = false; 04330 gRealColor colorPyramid; 04331 REAL alpha = 1; 04332 const REAL timeout = .5f; 04333 04334 if ( bool(player) ) 04335 { 04336 if ( player->IsChatting() ) 04337 { 04338 renderPyramid = true; 04339 colorPyramid.b = 0.0f; 04340 } 04341 else if ( !player->IsActive() ) 04342 { 04343 renderPyramid = true; 04344 colorPyramid.b = 0.0f; 04345 colorPyramid.g = 0.0f; 04346 } 04347 else if ( cam && cam->Center() == this && se_GameTime() < timeout && player->CurrentTeam() && player->CurrentTeam()->NumPlayers() > 1 ) 04348 { 04349 renderPyramid = true; 04350 alpha = timeout - se_GameTime(); 04351 } 04352 } 04353 04354 if ( renderPyramid ) 04355 { 04356 GLfloat s=sin(lastTime); 04357 GLfloat c=cos(lastTime); 04358 04359 GLfloat m[4][4]={{c,s,0,0}, 04360 {-s,c,0,0}, 04361 {0,0,1,0}, 04362 {0,0,1,1}}; 04363 04364 glPushMatrix(); 04365 04366 glMultMatrixf(&m[0][0]); 04367 glScalef(.5,.5,.5); 04368 04369 04370 BeginTriangles(); 04371 04372 glColor4f( colorPyramid.r,colorPyramid.g,colorPyramid.b, alpha ); 04373 glVertex3f(0,0,3); 04374 glVertex3f(0,1,4.5); 04375 glVertex3f(0,-1,4.5); 04376 04377 glColor4f( colorPyramid.r * .7f,colorPyramid.g * .7f,colorPyramid.b * .7f, alpha ); 04378 glVertex3f(0,0,3); 04379 glVertex3f(1,0,4.5); 04380 glVertex3f(-1,0,4.5); 04381 04382 RenderEnd(); 04383 04384 glPopMatrix(); 04385 } 04386 } 04387 04388 #ifdef USE_HEADLIGHT 04389 // Headlight contributed by Jonathan 04390 if(headlights) { 04391 if(!cycleprograminited) { // set to false on every sr_InitDisplay, without it I lost my program when I switched to windowed 04392 const char *program = 04393 "!!ARBfp1.0\ 04394 \ 04395 PARAM normal = program.local[0];\ 04396 ATTRIB texcoord = fragment.texcoord;\ 04397 TEMP final, diffuse, distance;\ 04398 \ 04399 DP3 distance, texcoord, texcoord;\ 04400 RSQ diffuse, distance.w;\ 04401 RCP distance, distance.w;\ 04402 MUL diffuse, texcoord, diffuse;\ 04403 DP3 diffuse, diffuse, normal;\ 04404 MUL final, diffuse, distance;\ 04405 MOV result.color.w, fragment.color;\ 04406 MUL result.color.xyz, fragment.color, final;\ 04407 \ 04408 END"; 04409 #ifdef LINUX 04410 glProgramStringARB_ptr(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(program), program); 04411 #else 04412 glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, strlen(program), program); 04413 #endif 04414 cycleprograminited = true; 04415 } 04416 #ifdef LINUX 04417 glProgramLocalParameter4fARB_ptr(GL_FRAGMENT_PROGRAM_ARB, 0, 0, 0, verletSpeed_ * verletSpeed_, 0); 04418 #else 04419 glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, 0, 0, verletSpeed_ * verletSpeed_, 0); 04420 #endif 04421 glPushAttrib(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // blend func and depth mask. Efficient or not, glPushAttrib/glPopAttrib is a quick way to manage state. 04422 glEnable(GL_FRAGMENT_PROGRAM_ARB); // doesn't check if it exists... 04423 04424 const unsigned sensors = 32; // actually one more 04425 const double mul = 0.25 * M_PI / sensors; 04426 const double add = -0.125 * M_PI; 04427 04428 double size = gArena::SizeMultiplier() * 500 * M_SQRT2; // is M_SQRT2 in your math.h? 04429 GLfloat array[sensors+2][5]; 04430 04431 array[0][0] = 0; 04432 array[0][1] = 0; 04433 array[0][2] = p.x; 04434 array[0][3] = p.y; 04435 array[0][4] = 0.125; 04436 04437 for(unsigned i=0; i<=sensors; i++) { 04438 gSensor sensor(this, p, dir.Turn(cos(i * mul + add), sin(i * mul + add))); 04439 sensor.detect(size); 04440 array[i][5] = sensor.before_hit.x - p.x; 04441 array[i][6] = sensor.before_hit.y - p.y; 04442 array[i][7] = sensor.before_hit.x; 04443 array[i][8] = sensor.before_hit.y; 04444 array[i][9] = 0.125; 04445 } 04446 04447 glPushMatrix(); 04448 glLoadIdentity(); 04449 04450 glMatrixMode(GL_TEXTURE); 04451 glPushMatrix(); 04452 glTranslatef(0, 0, 1); 04453 04454 glBlendFunc(GL_ONE, GL_ONE); 04455 glDepthMask(GL_FALSE); 04456 04457 glColor3fv(reinterpret_cast<GLfloat *>(&color_)); // 8-) 04458 glEnableClientState(GL_VERTEX_ARRAY); 04459 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 04460 04461 glInterleavedArrays(GL_T2F_V3F, 0, array); 04462 glDrawArrays(GL_TRIANGLE_FAN, 0, sensors+2); 04463 04464 glDisableClientState(GL_VERTEX_ARRAY); 04465 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 04466 04467 glDisable(GL_FRAGMENT_PROGRAM_ARB); 04468 04469 glPopMatrix(); 04470 glMatrixMode(GL_MODELVIEW); 04471 04472 glPopMatrix(); 04473 glPopAttrib(); 04474 } 04475 #endif // USE_HEADLIGHT 04476 // Name 04477 RenderName( cam ); 04478 04479 04480 // shadow: 04481 04482 sr_DepthOffset(true); 04483 04484 04485 REAL h=0;//se_cameraZ*.005+.03; 04486 04487 glEnable(GL_CULL_FACE); 04488 04489 if(!blinking && sr_floorDetail>rFLOOR_GRID && rTextureGroups::TextureMode[rTextureGroups::TEX_FLOOR]>0 && sr_alphaBlend){ 04490 glColor3f(0,0,0); 04491 cycle_shad.Select(); 04492 BeginQuads(); 04493 glTexCoord2f(0,1); 04494 glVertex3f(-.6,.4,h); 04495 04496 glTexCoord2f(1,1); 04497 glVertex3f(-.6,-.4,h); 04498 04499 glTexCoord2f(1,0); 04500 glVertex3f(2.1,-.4,h); 04501 04502 glTexCoord2f(0,0); 04503 glVertex3f(2.1,.4,h); 04504 04505 RenderEnd(); 04506 } 04507 04508 glDisable(GL_CULL_FACE); 04509 04510 // sr_laggometer; 04511 04512 04513 REAL f=verletSpeed_; 04514 04515 REAL l=Lag(); 04516 04517 glPopMatrix(); 04518 04519 h=cam->CameraZ()*.005+.03; 04520 04521 #ifdef ENABLE_OLD_LAG_O_METER 04522 if(sg_laggometerUseOld) { 04523 if (sn_GetNetState() != nSTANDALONE && sr_laggometer && f*l>.5) { 04524 //&& owner!=::sn_myNetID){ 04525 glPushMatrix(); 04526 04527 glColor3f(1,1,1); 04528 //glDisable(GL_TEXTURE); 04529 glDisable(GL_TEXTURE_2D); 04530 04531 glTranslatef(0,0,h); 04532 //glScalef(.5*f,.5*f,.5*f); 04533 04534 // compensate for the .5 scaling further up 04535 f *= 2 * sg_laggometerScale; 04536 04537 glScalef(f,f,f); 04538 04539 // move the sr_laggometer ahead a bit 04540 if (!sr_predictObjects || sn_GetNetState()==nSERVER) 04541 glTranslatef(l,0,0); 04542 04543 04544 BeginLineLoop(); 04545 04546 04547 glVertex2f(-l,-l); 04548 glVertex2f(0,0); 04549 glVertex2f(-l,l); 04550 REAL delay = GetTurnDelay(); 04551 if(l> 2*delay){ 04552 glVertex2f(-2*l+delay,delay); 04553 glVertex2f(-2*l+2*delay,0); 04554 glVertex2f(-2*l+delay,-delay); 04555 } 04556 else if (l>delay){ 04557 glVertex2f(-2*l+delay,delay); 04558 glVertex2f(-l,2*delay-l); 04559 glVertex2f(-l,-(2*delay-l)); 04560 glVertex2f(-2*l+delay,-delay); 04561 } 04562 04563 RenderEnd(); 04564 glPopMatrix(); 04565 } 04566 } else 04567 #endif 04568 { 04569 glPushMatrix(); 04570 04571 //glDisable(GL_TEXTURE); 04572 glDisable(GL_TEXTURE_2D); 04573 04574 glTranslatef(0,0,h); 04575 //glScalef(.5*f,.5*f,.5*f); 04576 04577 // compensate for the .5 scaling further up 04578 f *= 2 * sg_laggometerScale; 04579 04580 glScalef(f,f,f); 04581 04582 // move the sr_laggometer back a bit 04583 if (sr_predictObjects || sn_GetNetState()==nSERVER) { 04584 glTranslatef(-l,0,0); 04585 } 04586 04587 if (f*l>sg_laggometerThreshold) { 04588 if (sr_laggometer) { 04589 gLaggometer::LagOMeterRenderer(this).render(l); 04590 } 04591 } else if(sg_axesIndicator) { 04592 gLaggometer::AxesIndicator(this).render(); 04593 } 04594 04595 glPopMatrix(); 04596 } 04597 sr_DepthOffset(false); 04598 04599 glPopMatrix(); 04600 04601 }
void gCycle::Render2D | ( | tCoord | scale | ) | const [virtual] |
Reimplemented from eGameObject.
Definition at line 4603 of file gCycle.cpp.
References gCycleMovement::Alive(), gRealColor::b, color_, eGameObject::DeathTime(), eGameObject::dir, Direction(), eCoord, gRealColor::g, glBegin, glEnd, eGameObject::pos, PredictPosition(), gRealColor::r, se_GameTime(), tCoord::x, and tCoord::y.
04604 { 04605 double alpha = 1; 04606 if(!Alive()) { 04607 alpha -= 2 * (se_GameTime() - DeathTime()); 04608 if(alpha <= 0) return; 04609 } 04610 glColor4f(color_.r, color_.g, color_.b, alpha); 04611 eCoord pos = PredictPosition(), dir = Direction(); 04612 tCoord p = pos; 04613 glPushMatrix(); 04614 GLfloat m[16] = { 04615 scale.x * dir.x, scale.y * dir.y, 0, 0, 04616 -scale.x * dir.y, scale.y * dir.x, 0, 0, 04617 0, 0, 1, 0, 04618 pos.x, pos.y, 0, 1 04619 }; 04620 glMultMatrixf(m); 04621 glBegin(GL_TRIANGLES); 04622 glVertex2f(.5, 0); 04623 glVertex2f(-.5, .5); 04624 glVertex2f(-.5, -.5); 04625 glEnd(); 04626 glPopMatrix();
void gCycle::RenderName | ( | const eCamera * | cam | ) | [virtual] |
Definition at line 4641 of file gCycle.cpp.
References DisplayText(), ModelMatrix(), eCamera::Player(), ProjMatrix(), rCHEIGHT_NORMAL, REAL, cCockpit::Render(), eCamera::RenderingMain(), cCockpit::SetCycle(), sr_fontCycleLabel, timeCameIntoView, tSysTimeFloat(), cCockpit::VIEWPORT_CYCLE, x, and eGameObject::z.
Referenced by Render().
04642 { 04643 if ( !this->Player() ) 04644 return; 04645 04646 float modelviewMatrix[16], projectionMatrix[16]; 04647 float x, y, z, w; 04648 float xp, yp, wp; 04649 float alpha = 0.75; 04650 04651 if (fadeOutNameAfter == 0) return; /* XXX put that in ::Render() */ 04652 if ( !cam->RenderingMain() ) return; // no name in mirrored image 04653 if ( !showOwnName && cam->Player() == this->player ) return; // don't show own name 04654 04655 glPushMatrix(); 04656 /* position sign above center of cycle */ 04657 glTranslatef(0.8, 0, 2.0); 04658 glGetFloatv(GL_MODELVIEW_MATRIX, modelviewMatrix); 04659 glGetFloatv(GL_PROJECTION_MATRIX, projectionMatrix); 04660 glPopMatrix(); 04661 04662 /* get coordinates of sign */ 04663 x = modelviewMatrix[12]; 04664 y = modelviewMatrix[13]; 04665 z = modelviewMatrix[14]; 04666 w = modelviewMatrix[15]; 04667 04668 /* multiply by projection matrix */ 04669 xp = projectionMatrix[0] * x + projectionMatrix[4] * y + 04670 projectionMatrix[8] * z + projectionMatrix[12] * w; 04671 yp = projectionMatrix[1] * x + projectionMatrix[5] * y + 04672 projectionMatrix[9] * z + projectionMatrix[13] * w; 04673 wp = projectionMatrix[3] * x + projectionMatrix[7] * y + 04674 projectionMatrix[11] * z + projectionMatrix[15] * w; 04675 04676 if (wp <= 0) { 04677 /* behind camera */ 04678 timeCameIntoView = 0; 04679 return; 04680 } 04681 04682 xp /= wp; 04683 yp /= wp; 04684 yp += rCHEIGHT_NORMAL;// * 2.0; 04685 04686 if (xp <= -1 || xp >= 1 || yp <= -1 || yp >= 1) { 04687 /* out of screen */ 04688 timeCameIntoView = 0; 04689 return; 04690 } 04691 04692 /* it is visible */ 04693 04694 bool doname = true; 04695 if (fadeOutNameAfter > 0) { 04696 REAL now = tSysTimeFloat(); 04697 if (timeCameIntoView == 0) 04698 timeCameIntoView = now; 04699 04700 if (now - timeCameIntoView > fadeOutNameAfter) { 04701 doname = false; 04702 } else if (now - timeCameIntoView > fadeOutNameAfter - 1) { 04703 /* start to fade out */ 04704 alpha = 0.75 - (now - timeCameIntoView - 04705 (fadeOutNameAfter - 1)) * 0.75; 04706 } 04707 } 04708 04709 ModelMatrix(); 04710 glPushMatrix(); 04711 glLoadIdentity(); 04712 04713 ProjMatrix(); 04714 glPushMatrix(); 04715 glLoadIdentity(); 04716 04717 glTranslatef(xp, yp, 0.); 04718 if(doname) { 04719 glColor4f(1, 1, 1, alpha); 04720 tColoredString name; 04721 if(sg_displayColoredNameOverCycles) 04722 name << *this->player; 04723 else 04724 name << this->player->GetName(); 04725 DisplayText(0, 0, rCHEIGHT_NORMAL, name, sr_fontCycleLabel, 0, 0); 04726 } 04727 static cCockpit cycleCockpit(cCockpit::VIEWPORT_CYCLE); 04728 cycleCockpit.SetCycle(*this); 04729 cycleCockpit.Render(); 04730 04731 ProjMatrix(); 04732 glPopMatrix(); 04733 04734 ModelMatrix(); 04735 glPopMatrix();
bool gCycle::RenderCockpitFixedBefore | ( | bool | primary = true |
) | [virtual] |
Reimplemented from eGameObject.
Definition at line 4738 of file gCycle.cpp.
04739 { 04740 /* 04741 if (alive) 04742 return true; 04743 else{ 04744 REAL rd=se_GameTime()-deathTime; 04745 if (rd<1) 04746 return true; 04747 else{ 04748 REAL d=1.25-rd; 04749 d*=8; 04750 if (d<0) d=0; 04751 glColor3f(d,d/2,d/4); 04752 glDisable(GL_TEXTURE_2D); 04753 glDisable(GL_TEXTURE); 04754 glDisable(GL_DEPTH_TEST); 04755 glRectf(-1,-1,1,1); 04756 glColor4f(1,1,1,rd*(2-rd/2)); 04757 DisplayText(0,0,.05,.15,"You have been deleted."); 04758 return false; 04759 } 04760 } 04761 */ 04762 return true;
eCoord gCycle::CamPos | ( | ) | const [virtual] |
Reimplemented from eGameObject.
Definition at line 4800 of file gCycle.cpp.
References eGameObject::dir, PredictPosition(), skew, and eGameObject::z.
Referenced by _wrap_GCycle_cam_pos().
04802 { 04803 return PredictPosition() + dir.Turn(0 ,-skew*z); 04804 04805 // gSensor s(this,pos, PredictPosition() - pos ); 04806 // s.detect(1); 04807 04808 // return s.before_hit + dir.Turn(0 ,-skew*z); 04809 04810 // return pos + dir.Turn(0 ,-skew*z);
eCoord gCycle::PredictPosition | ( | ) | const [virtual] |
Reimplemented from eGameObject.
Definition at line 4793 of file gCycle.cpp.
References predictPosition_.
Referenced by _wrap_GCycle_predict_position(), CamPos(), Render(), Render2D(), and Timestep().
04794 { 04795 return predictPosition_; 04796 04797 // eCoord p = pos + dir * (speed * se_PredictTime()); 04798 // return p + correctPosSmooth;
eCoord gCycle::CamTop | ( | ) | const [virtual] |
Reimplemented from eGameObject.
Definition at line 4812 of file gCycle.cpp.
References eGameObject::dir, and skew.
Referenced by _wrap_GCycle_cam_top().
eCoord gCycle::CamDir | ( | ) | const [virtual] |
Reimplemented from eGameObject.
Definition at line 4817 of file gCycle.cpp.
References gJoystick::cameraDirection_, eGameObject::dir, joystick_, and tCoord::NormSquared().
Referenced by gCamera::CenterCycleDir().
04819 { 04820 if ( joystick_ && joystick_->cameraDirection_.NormSquared() > .25 ) 04821 { 04822 return joystick_->cameraDirection_; 04823 } 04824 else 04825 { 04826 return dir; 04827 }
eCoord gCycle::Direction | ( | void | ) | const [virtual] |
returns the current driving direction
Reimplemented from gCycleMovement.
Definition at line 4829 of file gCycle.cpp.
References gJoystick::cameraDirection_, gCycleMovement::dirDrive, gCycleMovement::Direction(), joystick_, and tCoord::NormSquared().
Referenced by cCockpit::cb_TimeToImpactFront(), cWidget::Map::DrawMap(), gAIPlayer::EmergencySurvive(), ReadSync(), Render2D(), gAIPlayer::RightBeforeDeath(), gAIPlayer::Think(), gAIPlayer::ThinkCloseCombat(), gAIPlayer::ThinkPath(), and WriteSync().
04831 { 04832 return gCycleMovement::Direction(); 04833 04834 if ( joystick_ && joystick_->cameraDirection_.NormSquared() > .25 ) 04835 { 04836 return joystick_->cameraDirection_; 04837 } 04838 else 04839 { 04840 return dirDrive; 04841 }
void gCycle::RightBeforeDeath | ( | int | numTries | ) | [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 from gCycleMovement.
Definition at line 5994 of file gCycle.cpp.
References correctPosSmooth, nextSync, nextSyncOwner, nNetObject::Owner(), sg_avoidBadOldClientSync, sg_GetSyncIntervalSelf(), sg_NoLocalTunnelOnSync, sg_syncIntervalEnemy, nVersionFeature::Supported(), and tSysTimeFloat().
05996 { 05997 if ( player ) 05998 { 05999 player->RightBeforeDeath( numTries ); 06000 } 06001 06002 // delay syncs for old clients; they would tunnel locally 06003 if ( sg_avoidBadOldClientSync && !sg_NoLocalTunnelOnSync.Supported( Owner() ) ) 06004 { 06005 nextSync=tSysTimeFloat()+sg_syncIntervalEnemy; 06006 nextSyncOwner=tSysTimeFloat()+sg_GetSyncIntervalSelf( this ); 06007 } 06008 06009 correctPosSmooth = correctPosSmooth * .5;
void gCycle::PrivateSettings | ( | ) | [static] |
Definition at line 122 of file gCycle.cpp.
References c_per, c_pwl, explosionRadius, wallsLength, and wallsStayUpDelay.
Referenced by _wrap_GCycle_private_settings(), and main().
00123 { 00124 static nSettingItem<REAL> c_wsud("CYCLE_WALLS_STAY_UP_DELAY",wallsStayUpDelay); 00125 static nSettingItem<REAL> c_wl("CYCLE_WALLS_LENGTH",wallsLength); 00126 static nSettingItem<REAL> c_er("CYCLE_EXPLOSION_RADIUS",explosionRadius); 00127 00128 c_pwsud=&c_wsud; 00129 c_pwl =&c_wl; 00130 c_per =&c_er; 00131 }
bool gCycle::DoIsDestinationUsed | ( | const gDestination * | dest | ) | const [protected, virtual] |
returns whether the given destination is in active use
dest | the destination to test |
Reimplemented from gCycleMovement.
Definition at line 6022 of file gCycle.cpp.
References gCycleMovement::DoIsDestinationUsed(), and extrapolator_.
06024 { 06025 return ( extrapolator_ && extrapolator_->IsDestinationUsed( dest ) ) || gCycleMovement::DoIsDestinationUsed( dest );
friend class gPlayerWall [friend] |
friend class gNetPlayerWall [friend] |
friend class gDestination [friend] |
friend class gCycleWallRenderer [friend] |
friend class gCycleChatBot [friend] |
REAL gCycle::spawnTime_ [private] |
time the cycle spawned at
Definition at line 156 of file gCycle.h.
Referenced by DropWall(), gCycle(), MyInitAfterCreation(), ReadSync(), Render(), SyncEnemy(), SyncFromExtrapolator(), TimestepCore(), and Vulnerable().
REAL gCycle::lastTimeAnim [private] |
last time animation was simulated at
Definition at line 157 of file gCycle.h.
Referenced by gCycle(), MyInitAfterCreation(), SyncEnemy(), and TimestepCore().
REAL gCycle::timeCameIntoView [private] |
std::auto_ptr< gCycleChatBot > gCycle::chatBot_ [private] |
bool gCycle::dropWallRequested_ [private] |
flag indicating that someone requested a wall drop
Definition at line 164 of file gCycle.h.
Referenced by DropWall(), MyInitAfterCreation(), OnDropTempWall(), PassEdge(), and Timestep().
eCoord gCycle::lastGoodPosition_ |
Definition at line 166 of file gCycle.h.
Referenced by gCycleExtrapolator::CopyFrom(), MyInitAfterCreation(), and ReadSync().
Definition at line 168 of file gCycle.h.
Referenced by CamPos(), CamTop(), MyInitAfterCreation(), ReadSync(), Render(), and TimestepCore().
Definition at line 168 of file gCycle.h.
Referenced by DoTurn(), MyInitAfterCreation(), ReadSync(), SyncEnemy(), and TimestepCore().
bool gCycle::mp |
Definition at line 170 of file gCycle.h.
Referenced by MyInitAfterCreation(), Render(), and ~gCycle().
Definition at line 172 of file gCycle.h.
Referenced by MyInitAfterCreation(), Render(), and ~gCycle().
Definition at line 172 of file gCycle.h.
Referenced by MyInitAfterCreation(), Render(), and ~gCycle().
Definition at line 172 of file gCycle.h.
Referenced by MyInitAfterCreation(), Render(), and ~gCycle().
Definition at line 172 of file gCycle.h.
Referenced by gCycleVisuals::gCycleVisuals(), gCycleVisuals::LoadModel(), MyInitAfterCreation(), Render(), ~gCycle(), and gCycleVisuals::~gCycleVisuals().
Definition at line 175 of file gCycle.h.
Referenced by MyInitAfterCreation(), Render(), and ~gCycle().
Definition at line 175 of file gCycle.h.
Referenced by MyInitAfterCreation(), Render(), and ~gCycle().
Definition at line 176 of file gCycle.h.
Referenced by gCycleVisuals::gCycleVisuals(), gCycleVisuals::LoadTextures(), MyInitAfterCreation(), Render(), ~gCycle(), and gCycleVisuals::~gCycleVisuals().
eCoord gCycle::rotationFrontWheel |
Definition at line 178 of file gCycle.h.
Referenced by MyInitAfterCreation(), Render(), and TimestepCore().
eCoord gCycle::rotationRearWheel |
Definition at line 178 of file gCycle.h.
Referenced by MyInitAfterCreation(), Render(), and TimestepCore().
uActionPlayer gCycle::s_brake [static] |
Definition at line 186 of file gCycle.h.
Referenced by cWidget::Map::DrawWalls(), gCycle(), Kill(), MyInitAfterCreation(), ReadSync(), Render(), Render2D(), TimestepCore(), and WriteCreate().
eCoord gCycle::correctPosSmooth |
Definition at line 192 of file gCycle.h.
Referenced by CalculatePredictPosition(), Die(), MyInitAfterCreation(), ReadSync(), RightBeforeDeath(), SyncFromExtrapolator(), TimestepCore(), and TransferPositionCorrectionToDistanceCorrection().
eCoord gCycle::predictPosition_ |
the best guess of where the cycle is at at display time
Definition at line 193 of file gCycle.h.
Referenced by CalculatePredictPosition(), Die(), MyInitAfterCreation(), PredictPosition(), and ReadSync().
Definition at line 196 of file gCycle.h.
Referenced by gDestination::CopyFrom(), gCycle(), MyInitAfterCreation(), ReadSync(), SyncEnemy(), SyncFromExtrapolator(), TimestepCore(), and TransferPositionCorrectionToDistanceCorrection().
display list manager
Definition at line 202 of file gCycle.h.
Referenced by gNetPlayerWall::CanHaveDisplayList(), and gNetPlayerWall::HasDisplayList().
SyncData gCycle::lastSyncMessage_ [private] |
Definition at line 210 of file gCycle.h.
Referenced by ReadSync(), ResetExtrapolator(), and SyncEnemy().
Definition at line 211 of file gCycle.h.
Referenced by DoIsDestinationUsed(), Extrapolate(), IsMe(), OnNotifyNewDestination(), PassEdge(), ReadSync(), ResetExtrapolator(), SyncFromExtrapolator(), and Timestep().
bool gCycle::resimulate_ [private] |
Definition at line 212 of file gCycle.h.
Referenced by MyInitAfterCreation(), ReadSync(), ResetExtrapolator(), SyncEnemy(), SyncFromExtrapolator(), and Timestep().
nTimeRolling gCycle::nextSync [private] |
Definition at line 223 of file gCycle.h.
Referenced by gCycle(), MyInitAfterCreation(), RequestSyncAll(), RightBeforeDeath(), and TimestepCore().
nTimeRolling gCycle::nextSyncOwner [private] |
Definition at line 223 of file gCycle.h.
Referenced by gCycle(), MyInitAfterCreation(), RequestSyncOwner(), RightBeforeDeath(), and TimestepCore().
REAL gCycle::wallsStayUpDelay = 8.0f [static, private] |
the time the cycle walls stay up ( negative values: they stay up forever )
Definition at line 338 of file gCycle.h.
Referenced by PrivateSettings(), and WallsStayUpDelay().
REAL gCycle::wallsLength = -1.0f [static, private] |
the maximum total length of the walls
Definition at line 339 of file gCycle.h.
Referenced by MaxWallsLength(), PrivateSettings(), and WallsLength().
REAL gCycle::explosionRadius = 4.0f [static, private] |
the radius of the holes blewn in by an explosion
Definition at line 340 of file gCycle.h.
Referenced by ExplosionRadius(), and PrivateSettings().
gJoystick* gCycle::joystick_ [private] |
joystick control
Definition at line 341 of file gCycle.h.
Referenced by Act(), CamDir(), Direction(), MyInitAfterCreation(), OnRemoveFromGame(), and TimestepCore().