00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #include "eGameObject.h"
00029 #include "uInputQueue.h"
00030 #include "eTimer.h"
00031 #include "eTess2.h"
00032 #include "eWall.h"
00033 #include "tConsole.h"
00034 #include "rScreen.h"
00035 #include "rGL.h"
00036
00037 #include "eSoundMixer.h"
00038
00039 #include "eAdvWall.h"
00040 #include "eGrid.h"
00041 #include "uInput.h"
00042 #include "tMath.h"
00043 #include "nConfig.h"
00044 #include "eTeam.h"
00045
00046 #include <map>
00047
00048 uActionPlayer eGameObject::se_turnRight("CYCLE_TURN_RIGHT", -10);
00049
00050 uActionPlayer eGameObject::se_turnLeft("CYCLE_TURN_LEFT", -10);
00051
00052
00053
00054 void eGameObject::AddToList(){
00055 if ( id < 0 )
00056 AddRef();
00057
00058 grid->gameObjectsInactive.Remove(this,inactiveID);
00059 grid->gameObjects.Add(this,id);
00060 }
00061 void eGameObject::RemoveFromList(){
00062 int oldID = id;
00063
00064 currentFace = 0;
00065
00066 grid->gameObjects.Remove(this,id);
00067 grid->gameObjectsInactive.Add(this,inactiveID);
00068
00069 if ( oldID >= 0 )
00070 Release();
00071 }
00072
00073 void eGameObject::RemoveFromListsAll(){
00074 int oldID = id;
00075
00076 currentFace = 0;
00077
00078 grid->gameObjects.Remove(this,id);
00079 grid->gameObjectsInactive.Remove(this,inactiveID);
00080 grid->gameObjectsInteresting.Remove(this,interestingID);
00081
00082 if ( oldID >= 0 )
00083 Release();
00084
00085 }
00086
00087 void eGameObject::RemoveFromGame()
00088 {
00089 tJUST_CONTROLLED_PTR< eGameObject > keepAlive;
00090 if ( id >= 0 )
00091 keepAlive = this;
00092
00093 OnRemoveFromGame();
00094 DoRemoveFromGame();
00095 }
00096
00097
00098
00099 void eGameObject::OnRemoveFromGame()
00100 {
00101
00102 currentFace = 0;
00103
00104
00105 RemoveFromListsAll();
00106 }
00107
00108
00109
00110 void eGameObject::DoRemoveFromGame()
00111 {
00112
00113 delete this;
00114 }
00115
00116
00117 eGameObject::eGameObject(eGrid *g,const eCoord &p,const eCoord &d,eFace *currentface,bool autodel)
00118 :autodelete(autodel),pos(p),dir(d),z(0),grid(g){
00119 tASSERT(g);
00120 currentFace=currentface;
00121 lastTime=se_GameTime();
00122 id=-1;
00123 interestingID=-1;
00124 inactiveID=-1;
00125 if ( lastTime < 0 )
00126 lastTime=0;
00127 team = 0;
00128 }
00129
00130 eGameObject::~eGameObject(){
00131 currentFace = 0;
00132 RemoveFromListsAll();
00133 tCHECK_DEST;
00134 }
00135
00136
00137
00138
00139
00140
00141 void eGameObject::InteractWith(eGameObject *,REAL,int){}
00142
00143
00144 void eGameObject::PassEdge(const eWall *w,REAL,REAL,int){
00145 if (w) Kill();
00146 }
00147
00148 static int se_moveTimeout = 100;
00149 static tSettingItem<int> se_moveTimeoutC("GAMEOBJECT_MOVE_TIMEOUT", se_moveTimeout);
00150
00151
00152 struct eTempEdgePassing
00153 {
00154 eWall *wall;
00155 REAL ratio;
00156 };
00157 typedef std::multimap< REAL, eTempEdgePassing > eTempEdgeMap;
00158
00159
00160
00161 void eGameObject::Move( const eCoord &dest, REAL startTime, REAL endTime, bool useTempWalls )
00162 {
00163 #ifdef DEBUG
00164 grid->Check();
00165 #endif
00166 if (!finite(dest.x) || !finite(dest.y))
00167 {
00168 st_Breakpoint();
00169 return;
00170 }
00171
00172 tStackObject< ePoint > start(pos),stop(dest);
00173 ePoint* pstart = &start;
00174 ePoint* pstop = &stop;
00175
00176
00177 REAL clip = eWallRim::Clip(start,stop,-10);
00178 endTime = startTime + ( endTime - startTime ) * clip;
00179
00180 grid->Range(stop.NormSquared());
00181
00182 #ifdef DEBUG
00183 if (!finite(stop.x) || !finite(stop.y))
00184 {
00185 st_Breakpoint();
00186
00187 static_cast<eCoord&>(stop) = dest;
00188 eWallRim::Bound(stop,-10);
00189
00190 return;
00191 }
00192 #endif
00193
00194
00195 eTempEdgeMap tempCollisions;
00196
00197 tStackObject< eTempEdge > te( pstart, pstop );
00198 eHalfEdge &e=*te.Edge(0);
00199
00200
00201 if ( useTempWalls )
00202 {
00203 for(int i=grid->wallsNotYetInserted.Len()-1;i>=0;i--){
00204 const eHalfEdge *other_e=grid->wallsNotYetInserted[i]->Edge();
00205 if (
00206 other_e->Point() && other_e->Other() && other_e->Other()->Point()){
00207 tJUST_CONTROLLED_PTR< ePoint > new_cross_p=e.IntersectWith(other_e);
00208 if (new_cross_p){
00209 REAL e_ratio =e.Ratio(*new_cross_p);
00210 REAL o_ratio =other_e->Ratio(*new_cross_p);
00211 if (0<=e_ratio && 1>=e_ratio &&
00212 0<=o_ratio && 1>=o_ratio)
00213 {
00214 eWall *w = other_e->GetWall();
00215 if (!w)
00216 {
00217 w = other_e->Other()->GetWall();
00218 o_ratio = 1-o_ratio;
00219 }
00220 if (w)
00221 {
00222
00223 eTempEdgePassing passing;
00224 passing.wall = w;
00225 passing.ratio = o_ratio;
00226 tempCollisions.insert( std::pair< REAL, eTempEdgePassing >( e_ratio, passing) );
00227 }
00228 }
00229 }
00230 }
00231 }
00232 }
00233
00234
00235 FindCurrentFace();
00236
00237
00238 REAL totalDistance = ( stop - pos ).Norm();
00239
00240 if (currentFace){
00241
00242 eTempEdgeMap::const_iterator currentTempCollision = tempCollisions.begin();
00243
00244
00245
00246
00247 REAL goneRatio = 0;
00248
00249 int timeout = se_moveTimeout;
00250
00251 REAL lastDistance = 1E+30;
00252 eHalfEdge *in = NULL;
00253
00254 while (currentFace && timeout >0 && !currentFace->IsInside(stop)){
00255
00256 eCoord vec=stop - pos;
00257
00258
00259 REAL distance = vec.Norm();
00260 if ( distance >= lastDistance )
00261 {
00262 timeout--;
00263 }
00264 else
00265 {
00266 timeout = se_moveTimeout;
00267 if ( lastDistance > 1E+29 )
00268 lastDistance = distance * 1.1;
00269 lastDistance = .1 * lastDistance + distance * (.9 - EPS);
00270
00271
00272
00273 if ( distance <= EPS * totalDistance )
00274 {
00275
00276 break;
00277 }
00278 }
00279 #ifdef DEBUG_X
00280 rerun:
00281 #endif
00282
00283 eHalfEdge *run = currentFace->Edge();
00284 eHalfEdge *best = NULL;
00285 eHalfEdge *end = run;
00286 REAL bestScore = -1000;
00287 REAL bestERatio = .5;
00288 REAL bestRRatio = .5;
00289 eCoord bestCross (0,0);
00290
00291
00292 do
00293 {
00294 run = run->Next();
00295
00296 if (run == in)
00297 continue;
00298
00299 eCoord runVec = run->Vec();
00300
00301 REAL score = runVec * vec / ( se_EstimatedRangeOfMult( runVec, vec ) + EPS );
00302 static const REAL smallBias = .01;
00303
00304
00305
00306 if ( score > smallBias || ( score > 0 && !run->GetWall() ) )
00307 score = smallBias;
00308
00309 eCoord cross = e.IntersectWithCareless(run);
00310
00311
00312 REAL run_ratio = run->Ratio(cross);
00313 if ( !good( run_ratio ) )
00314 {
00315
00316 run_ratio = .5;
00317 }
00318
00319 if (run_ratio < 0)
00320 {
00321
00322 run_ratio = 0;
00323 }
00324 else if (run_ratio > 1)
00325 {
00326
00327 run_ratio = 1;
00328 }
00329 cross = *run->Point() + run->Vec() * run_ratio;
00330
00331
00332 REAL e_side = vec * ( cross - pos ) / distance;
00333 score -= fabs( e_side );
00334
00335
00336 REAL e_ratio = e.Ratio(cross);
00337
00338
00339 if ( !good( e_ratio ) )
00340 {
00341 score -= 100;
00342 e_ratio = .5;
00343 }
00344
00345 if (e_ratio < 0)
00346 {
00347 score += e_ratio;
00348 e_ratio = 0;
00349 }
00350 else if (e_ratio > 1)
00351 {
00352 score += (1-e_ratio);
00353 e_ratio = 1;
00354 }
00355
00356 if (!best || score > bestScore)
00357 {
00358 best = run;
00359 bestScore = score;
00360 bestERatio = e_ratio;
00361 bestRRatio = run_ratio;
00362 bestCross = cross;
00363 }
00364
00365 }
00366 while (run != end);
00367
00368 #ifdef DEBUG_X
00369 if ( !good( bestScore ) || bestScore < -50 )
00370 {
00371 st_Breakpoint();
00372 goto rerun;
00373 }
00374 #endif
00375
00376 #define TIME( ratio ) ( startTime+(endTime-startTime)*( ratio ) )
00377
00378 if (best)
00379 {
00380
00381 goneRatio = goneRatio + ( 1 - goneRatio ) * bestERatio;
00382
00383
00384 while ( currentTempCollision != tempCollisions.end() && (*currentTempCollision).first < goneRatio )
00385 {
00386 eTempEdgePassing const & passing = (*currentTempCollision).second;
00387 PassEdge( passing.wall, TIME( (*currentTempCollision).first ), passing.ratio, 0 );
00388 ++ currentTempCollision;
00389 }
00390
00391 REAL time=TIME( bestERatio );
00392
00393
00394 pos = bestCross;
00395
00396
00397 eWall* w = best->GetWall();
00398 if (w)
00399 PassEdge(w,time,bestRRatio,0);
00400
00401
00402 tASSERT(best->Other());
00403 in = best->Other();
00404
00405
00406 if (in)
00407 {
00408 bestRRatio = 1-bestRRatio;
00409 w = in->GetWall();
00410
00411 if (w)
00412 PassEdge(w,time,bestRRatio,0);
00413 }
00414
00415
00416 if (in)
00417 currentFace=in->Face();
00418 else
00419 currentFace=NULL;
00420 }
00421 else
00422 {
00423 timeout = 0;
00424 st_Breakpoint();
00425 }
00426 }
00427
00428 if (timeout <= 0)
00429 grid->requestCleanup = true;
00430 else
00431 pos=stop;
00432
00433
00434 while ( currentTempCollision != tempCollisions.end() )
00435 {
00436 eTempEdgePassing const & passing = (*currentTempCollision).second;
00437 PassEdge( passing.wall, TIME( (*currentTempCollision).first ), passing.ratio, 0 );
00438 ++ currentTempCollision;
00439 }
00440 }
00441 else
00442 {
00443
00444 pos = dest;
00445 }
00446
00447
00448
00449
00450
00451 FindCurrentFace();
00452
00453
00454
00455
00456
00457
00458
00459
00460 lastTime = endTime;
00461 }
00462
00463
00464 static short se_bugTunnel = false;
00465 static nSettingItem<short> se_bugTunnelConfig("BUG_TUNNEL",
00466 se_bugTunnel );
00467
00468 class eFaceFindFilter: public tConsoleFilter
00469 {
00470 virtual void DoFilterLine( tString& line )
00471 {
00472 line = tString( "FindCurrentFace() is running, so this message probably means there is a BUG: " ) + line;
00473 }
00474 };
00475
00476 void eGameObject::FindCurrentFace(){
00477
00478 if ( currentFace && !currentFace->IsInGrid() )
00479 {
00480 if ( !se_bugTunnel )
00481 {
00482 currentFace = currentFace->FindReplacement( pos, Direction(), LastDirection() );
00483 if ( !currentFace && sn_GetNetState() != nCLIENT )
00484 {
00485 static bool warn = true;
00486 if (warn)
00487 {
00488 tERR_WARN("Possible phase bug!\n");
00489 }
00490
00491 warn = false;
00492 }
00493 }
00494 else
00495 {
00496
00497 currentFace = NULL;
00498 }
00499 }
00500
00501
00502 if ( !currentFace && GOID() < 0 )
00503 {
00504 #ifdef DEBUG
00505 con << "Attempting to get a current face, but object is not in game.\n";
00506 st_Breakpoint();
00507 return;
00508 #endif
00509 }
00510
00511
00512 if ( !currentFace )
00513 currentFace = grid->FindSurroundingFace(pos);
00514
00515 if ( currentFace )
00516 {
00517
00518 REAL insideness = currentFace->Insideness(pos);
00519 if ( insideness < 0 )
00520 {
00521 eFaceFindFilter filter;
00522
00523
00524
00525
00526 int i;
00527 eCoord center;
00528 eHalfEdge * run = currentFace->Edge();
00529 for ( i = 2; i >= 0; --i )
00530 {
00531 run = run->Next();
00532 center = center + ( *run->Point() - pos );
00533 }
00534 eCoord centerToPos = -center*(1/3.0);
00535 center = pos - centerToPos;
00536
00537 static bool recurse = true;
00538 if ( recurse )
00539 {
00540 class RecursionGuard
00541 {
00542 public:
00543 RecursionGuard( bool& recursion )
00544 :recursion_( recursion )
00545 {
00546 recursion = false;
00547 }
00548
00549 ~RecursionGuard()
00550 {
00551 recursion_ = true;
00552 }
00553
00554 private:
00555 bool& recursion_;
00556 };
00557
00558 RecursionGuard guard( recurse );
00559
00560
00561
00562 eCoord oldPos = pos;
00563 pos = center;
00564 #ifdef DEBUG
00565 eFace * lastFace = currentFace;
00566 #endif
00567 try
00568 {
00569 Move( oldPos, lastTime, lastTime, false );
00570 }
00571 catch( eDeath & )
00572 {
00573 #ifdef DEBUG
00574
00575 try
00576 {
00577 pos = center;
00578 currentFace = lastFace;
00579 Move( oldPos, lastTime, lastTime, false );
00580 }
00581 catch( eDeath & ){}
00582 #endif
00583 }
00584
00585 recurse = true;
00586 }
00587 else
00588 {
00589
00590
00591 run = currentFace->Edge();
00592 for ( i = 2; i >= 0; --i )
00593 {
00594 run = run->Next();
00595 eCoord centerToPoint = *run->Point() - center;
00596 eCoord runVec = run->Vec();
00597 REAL prod = centerToPoint * runVec;
00598 if (prod < 0)
00599 {
00600 REAL toClamp = (centerToPos * runVec) / prod;
00601 if ( toClamp > 1 )
00602 {
00603 centerToPos = centerToPos * (1/toClamp);
00604 }
00605 }
00606 }
00607 pos = center + centerToPos;
00608 }
00609 }
00610 }
00611 }
00612
00613
00614 bool eGameObject::Timestep(REAL t){
00615 lastTime = t;
00616 return 0;
00617 }
00618
00619
00620 void eGameObject::OnRoundBegin(){}
00621 void eGameObject::OnRoundEnd(){}
00622
00623 void eGameObject::Kill(){}
00624
00625
00626 void eGameObject::Render(const eCamera *){}
00627 void eGameObject::Render2D(tCoord scale) const {}
00628
00629
00630
00631
00632
00633
00637
00638 bool eGameObject::RendersAlpha() const{return false;}
00639
00640
00641 bool eGameObject::RenderCockpitFixedBefore(bool){return true;}
00642
00643
00644
00645 void eGameObject::RenderCockpitFixedAfter(bool){}
00646
00647 void eGameObject::RenderCockpitVirtual(bool){}
00648
00649
00650 #ifdef POWERPAK_DEB
00651 void eGameObject::PPDisplay(){
00652 PD_PutPixel(DoubleBuffer,
00653 se_X_ToScreen(pos.x),
00654 se_Y_ToScreen(pos.y),
00655 PD_CreateColor(DoubleBuffer,255,0,100));
00656 PD_PutPixel(DoubleBuffer,
00657 se_X_ToScreen(pos.x+1),
00658 se_Y_ToScreen(pos.y),
00659 PD_CreateColor(DoubleBuffer,255,0,100));
00660 PD_PutPixel(DoubleBuffer,
00661 se_X_ToScreen(pos.x-1),
00662 se_Y_ToScreen(pos.y),
00663 PD_CreateColor(DoubleBuffer,255,0,100));
00664 PD_PutPixel(DoubleBuffer,
00665 se_X_ToScreen(pos.x),
00666 se_Y_ToScreen(pos.y+1),
00667 PD_CreateColor(DoubleBuffer,255,0,100));
00668 PD_PutPixel(DoubleBuffer,
00669 se_X_ToScreen(pos.x),
00670 se_Y_ToScreen(pos.y-1),
00671 PD_CreateColor(DoubleBuffer,255,0,100));
00672
00673 }
00674 #endif
00675
00676
00677 bool eGameObject::Act(uActionPlayer *,REAL){return false;}
00678
00679
00680 bool eGameObject::TimestepThis(REAL currentTime,eGameObject *c){
00681 #ifdef DEBUG
00682 c->grid->Check();
00683 #endif
00684
00685 tJUST_CONTROLLED_PTR< eGameObject > keep( c );
00686
00687 REAL maxstep=.2;
00688
00689
00690 if (fabs(currentTime - c->lastTime) < .001)
00691 return false;
00692
00693
00694 if (currentTime<c->lastTime)
00695 maxstep=.1;
00696
00697 int number_of_steps=int(fabs((currentTime-c->lastTime)/maxstep));
00698 if (number_of_steps<1)
00699 number_of_steps=1;
00700 if ( number_of_steps > 10 )
00701 {
00702 number_of_steps = 10;
00703 }
00704
00705 REAL lastTime=c->lastTime;
00706
00707 bool ret=false;
00708
00709 for(int i=1;i<=number_of_steps;i++)
00710 {
00711
00712 c->FindCurrentFace();
00713
00714 if (sn_GetNetState()!=nCLIENT)
00715 for(int j=c->grid->gameObjectsInteresting.Len()-1;j>=0;j--)
00716 c->InteractWith(c->grid->gameObjectsInteresting(j),currentTime,0);
00717
00718 REAL timeThisStep = lastTime+i*(currentTime-lastTime)/number_of_steps;
00719 ret = ret || c->Timestep(timeThisStep);
00720 c->FindCurrentFace();
00721
00722
00723 if ( 2 * c->lastTime < timeThisStep + lastTime )
00724 break;
00725 }
00726 #ifdef DEBUG
00727 c->grid->Check();
00728 #endif
00729
00730 return ret;
00731 }
00732
00733 #ifdef DEDICATED
00734 static REAL se_maxSimulateAhead = .01f;
00735 static tSettingItem<REAL> se_maxSimulateAheadConf( "MAX_SIMULATE_AHEAD", se_maxSimulateAhead );
00736 #endif
00737
00738
00739 static REAL se_maxSimulateAheadLeft = 0.0f;
00740 REAL eGameObject::MaxSimulateAhead()
00741 {
00742 return se_maxSimulateAheadLeft;
00743 }
00744
00745 static REAL se_lazyLag = 0;
00747 REAL eGameObject::GetMaxLazyLag()
00748 {
00749 return se_lazyLag;
00750 }
00751
00753 void eGameObject::SetMaxLazyLag( REAL lag )
00754 {
00755 se_lazyLag = lag;
00756 }
00757
00758 void eGameObject::TimestepThisWrapper(eGrid * grid, REAL currentTime, eGameObject *c, REAL minTimestep )
00759 {
00760 su_FetchAndStoreSDLInput();
00761
00762 REAL simTime=currentTime;
00763
00764 #ifndef DEDICATED
00765 if (sn_GetNetState()==nCLIENT && !sr_predictObjects)
00766 #endif
00767 simTime -= c->Lag();
00768
00769 #ifdef DEDICATED
00770 REAL nextTime = c->NextInterestingTime();
00771
00772
00773 se_maxSimulateAheadLeft = simTime + se_maxSimulateAhead - nextTime;
00774 if ( se_maxSimulateAheadLeft < 0 )
00775 se_maxSimulateAheadLeft = 0;
00776
00777 REAL lagThreshold = c->LagThreshold();
00778 if ( simTime - lagThreshold < nextTime && nextTime < simTime + se_maxSimulateAhead )
00779 {
00780
00781 simTime = nextTime;
00782 }
00783 else
00784 {
00785
00786 simTime -= lagThreshold;
00787
00788 if ( simTime < c->LastTime() + minTimestep )
00789 {
00790
00791 return;
00792 }
00793 }
00794 #endif
00795
00796
00797 if (!eWallRim::IsBound(c->pos,-20))
00798 {
00799 se_maxSimulateAheadLeft = 0;
00800
00801 c->Kill();
00802 return;
00803 }
00804
00805
00806 if ( simTime > c->lastTime )
00807 {
00808 if (TimestepThis(simTime,c))
00809 {
00810 if (c->autodelete)
00811 c->RemoveFromGame();
00812 else
00813 {
00814 c->currentFace=NULL;
00815 c->RemoveFromList();
00816 }
00817 }
00818 }
00819
00820 se_maxSimulateAheadLeft = 0.0;
00821 }
00822
00823
00824 void eGameObject::s_Timestep(eGrid *grid, REAL currentTime, REAL minTimestep)
00825 {
00826 #ifdef DEBUG
00827 grid->Check();
00828 #endif
00829
00830
00831 for(int i=grid->gameObjects.Len()-1;i>=0;i--)
00832 {
00833 eGameObject * c = grid->gameObjects(i);
00834 TimestepThisWrapper( grid, currentTime, c, minTimestep );
00835 }
00836
00837 #ifdef DEBUG
00838 grid->Check();
00839 #endif
00840 }
00841
00842 #ifdef DEBUG
00843 eGameObject *displayed_gameobject = 0;
00844 #endif
00845
00846 void eGameObject::RenderAll(eGrid *grid, const eCamera *cam){
00847
00848
00849
00850
00851
00852
00853 eGameObject * firstAlpha = NULL;
00854 for(int i=grid->gameObjects.Len()-1;i>=0;i--){
00855 su_FetchAndStoreSDLInput();
00856 if (sr_glOut){
00857 eGameObject * object = grid->gameObjects(i);
00858 #ifdef DEBUG
00859 displayed_gameobject = object;
00860 #endif
00861
00862 sr_CheckGLError();
00863
00864 object->Render(cam);
00865
00866 bool thisAlpha = object->RendersAlpha();
00867 if ( !thisAlpha && firstAlpha )
00868 {
00869
00870
00871
00872
00873 int firstAlphaID = firstAlpha->id;
00874 grid->gameObjects.Remove(firstAlpha,firstAlpha->id);
00875 grid->gameObjects.Add(firstAlpha,firstAlpha->id);
00876 grid->gameObjects.Remove(object,object->id);
00877 grid->gameObjects.Add(object,object->id);
00878
00879
00880
00881 firstAlpha = 0;
00882 if ( firstAlphaID > 0 )
00883 {
00884 firstAlpha = grid->gameObjects(firstAlphaID - 1);
00885 tASSERT( firstAlpha->RendersAlpha() );
00886 }
00887 }
00888 if ( thisAlpha && !firstAlpha )
00889 {
00890
00891 firstAlpha = object;
00892 }
00893 sr_CheckGLError();
00894
00895 #ifdef DEBUG
00896 displayed_gameobject = 0;
00897 #endif
00898 }
00899 }
00900 }
00901
00902 #ifdef POWERPAK_DEB
00903 void eGameObject::PPDisplayAll(){
00904 for(int i=gameObjects.Len()-1;i>=0;i--){
00905 if (pp_out) gameObjects(i)->PPDisplay();
00906 }
00907 }
00908 #endif
00909
00910
00911 void eGameObject::DeleteAll(eGrid *grid){
00912 int i;
00913 for(i=grid->gameObjects.Len()-1;i>=0;i--)
00914 {
00915 eGameObject* o = grid->gameObjects(i);
00916 o->RemoveFromGame();
00917 #ifdef POWERPAK_DEB
00918 if (pp_out) o->PPDisplay();
00919 #endif
00920 }
00921 }
00922
00923 eReferencableGameObject::eReferencableGameObject(eGrid *grid, const eCoord &p,const eCoord &d, eFace *currentface, bool autodelete)
00924 : eGameObject( grid, p, d, currentface, autodelete )
00925 {
00926 }
00927
00928
00929 void eReferencableGameObject::AddRef()
00930 {
00931 tReferencable< eReferencableGameObject >::AddRef();
00932 }
00933
00934 void eReferencableGameObject::Release()
00935 {
00936 tReferencable< eReferencableGameObject >::Release();
00937 }
00938
00939 void eReferencableGameObject::DoRemoveFromGame()
00940 {
00941
00942 }
00943
00944 eStackGameObject::eStackGameObject(eGrid *grid, const eCoord &p,const eCoord &d, eFace *currentface)
00945 : eGameObject( grid, p, d, currentface, false )
00946 {
00947 }
00948
00949 void eStackGameObject::AddRef()
00950 {
00951 }
00952
00953 void eStackGameObject::Release()
00954 {
00955 }
00956
00957 void eStackGameObject::DoRemoveFromGame()
00958 {
00959
00960 tERR_ERROR("Stack game object removed from game.");
00961 }
00962
00963