1 /*
2 
3 *************************************************************************
4 
5 ArmageTron -- Just another Tron Lightcycle Game in 3D.
6 Copyright (C) 2000  Manuel Moos (manuel@moosnet.de)
7 
8 **************************************************************************
9 
10 This program is free software; you can redistribute it and/or
11 modify it under the terms of the GNU General Public License
12 as published by the Free Software Foundation; either version 2
13 of the License, or (at your option) any later version.
14 
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 GNU General Public License for more details.
19 
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
23 
24 ***************************************************************************
25 
26 */
27 
28 #ifndef ArmageTron_CYCLE_H
29 #define ArmageTron_CYCLE_H
30 
31 //#define USE_HEADLIGHT
32 
33 #include "gStuff.h"
34 //#include "eSound.h"
35 //#include "rTexture.h"
36 //#include "rModel.h"
37 #include "eNetGameObject.h"
38 #include "tList.h"
39 #include "nObserver.h"
40 #include "rDisplayList.h"
41 
42 #include "gCycleMovement.h"
43 
44 class rModel;
45 class gTextureCycle;
46 class eSoundPlayer;
47 class gSensor;
48 class gNetPlayerWall;
49 class gPlayerWall;
50 class eTempEdge;
51 struct gPredictPositionData;
52 
53 // minimum time between two cycle turns
54 extern REAL sg_delayCycle;
55 
56 // Render the headlight effect?
57 extern bool headlights;
58 
59 // steering help
60 extern REAL sg_rubberCycle;
61 
62 
63 // this class set is responsible for remembering which walls are too
64 // close together to pass through safely. The AI uses this information,
65 // so the real declaration of gCylceMemoryEntry can be found in gAIBase.cpp.
66 class gCycleMemoryEntry;
67 
68 class gCycleMemory{
69     friend class gCycleMemoryEntry;
70 
71     tList<gCycleMemoryEntry>     memory;  // memory about other cylces
72 
73 public:
74     // memory functions: access the memory for a cylce
75     gCycleMemoryEntry* Remember(const gCycle *cycle);
Len()76     int Len() const {return memory.Len();}
77     gCycleMemoryEntry* operator() (int i)  const;
78     gCycleMemoryEntry* Latest   (int side)  const;
79     gCycleMemoryEntry* Earliest (int side)  const;
80 
81     void Clear();
82 
83     gCycleMemory();
84     ~gCycleMemory();
85 };
86 
87 // class used to extrapolate the movement of a lightcycle
88 class gCycleExtrapolator: public gCycleMovement
89 {
90 public:
91     void CopyFrom( const gCycleMovement& other );							// copies relevant info from other cylce
92     void CopyFrom( const SyncData& sync, const gCycle& other );	        	// copies relevant info from sync data and everything else from other cycle
93 
94     gCycleExtrapolator(eGrid *grid, const eCoord &pos,const eCoord &dir,ePlayerNetID *p=NULL,bool autodelete=1);
95     // gCycleExtrapolator(nMessage &m);
96     virtual ~gCycleExtrapolator();
97 
98     // virtual gDestination* GetCurrentDestination() const;			// returns the current destination
99 
100     virtual bool EdgeIsDangerous(const eWall *w, REAL time, REAL a) const;
101 
102     virtual void PassEdge(const eWall *w,REAL time,REAL a,int recursion=1);
103 
104     virtual bool TimestepCore(REAL currentTime, bool calculateAcceleration = true );
105 
106     // virtual bool DoTurn(int dir);
107 
108     REAL			  trueDistance_;										// distance predicted as best as we can
109 private:
110     // virtual REAL            DoGetDistanceSinceLastTurn  (                               ) const     ;   //!< returns the distance since the last turn
111 
112     virtual nDescriptor& CreatorDescriptor() const;
113 
114     const gCycleMovement* parent_;												// the cycle that is extrapolated
115 };
116 
117 class gCycleChatBot;
118 
119 #ifndef DEDICATED
120 class gCycleWallsDisplayListManager
121 {
122     friend class gNetPlayerWall;
123 
124 public:
125     gCycleWallsDisplayListManager();
126 
127     //! checks whether a wall at a certain distance can have a display list
128     static bool CannotHaveList( REAL distance, gCycle const * cycle );
129 
130     void RenderAll( eCamera const * camera, gCycle * cycle );
Walls()131     bool Walls() const
132     {
133         return wallList_ || wallsWithDisplayList_;
134     }
135 
136     void Clear( int inhibit = 0 )
137     {
138         displayList_.Clear( inhibit );
139     }
140 private:
141     gNetPlayerWall *                wallList_;                      //!< linked list of all walls
142     gNetPlayerWall *                wallsWithDisplayList_;          //!< linked list of all walls with display list
143     rDisplayList                    displayList_;                   //!< combined display list
144     REAL                            wallsWithDisplayListMinDistance_; //!< minimal distance of the walls with display list
145     int                             wallsInDisplayList_;            //!< number of walls in the current display list
146 };
147 #endif
148 
149 // a complete lightcycle
150 class gCycle: public gCycleMovement
151 {
152     friend class gPlayerWall;
153     friend class gNetPlayerWall;
154     friend class gDestination;
155     friend class gCycleWallRenderer;
156 
157     eSoundPlayer *engine;
158     eSoundPlayer *turning;
159     eSoundPlayer *spark;
160 
161     REAL spawnTime_;    //!< time the cycle spawned at
162     REAL lastTimeAnim;  //!< last time animation was simulated at
163     REAL timeCameIntoView;
164 
165     friend class gCycleChatBot;
166     std::auto_ptr< gCycleChatBot > chatBot_;
167 
168     bool dropWallRequested_; //!< flag indicating that someone requested a wall drop
169 public:
170     eCoord            lastGoodPosition_;    // the location of the last known good position
171 
172     REAL skew,skewDot;						// leaning to the side
173 
174     bool 				mp; 				// use moviepack or not?
175 
176     rModel *body,*front,*rear,
177     *customModel;
178 
179     gTextureCycle  *wheelTex,*bodyTex;
180     gTextureCycle  *customTexture;
181 
182     eCoord rotationFrontWheel,rotationRearWheel; 	// wheel position (rotation)
183     REAL   heightFrontWheel,heightRearWheel;  		// wheel (suspension)
184 public:
185     //REAL	brakingReservoir; // reservoir for braking. 1 means full, 0 is empty
186 
187     static uActionPlayer s_brake;
188     gCycleMemory memory;
189 
190     gRealColor color_;
191     gRealColor trailColor_;
192 
193     // smooth corrections
194     // pos is always the correct simulated position; the displayed position is calculated as pos + correctPosSmooth
195     // and correctPosSmooth decays with time.
196     eCoord correctPosSmooth;
197     eCoord predictPosition_; //!< the best guess of where the cycle is at at display time
198 
199     // every frame, a bit of this variable is taken away and added to the step the cycle makes.
200     REAL correctDistanceSmooth;
201 
202 private:
203     void TransferPositionCorrectionToDistanceCorrection();
204 
205 #ifndef DEDICATED
206     gCycleWallsDisplayListManager displayList_;                     //!< display list manager
207 #endif
208 
209     tCHECKED_PTR(gNetPlayerWall)	currentWall;                    //!< the wall that currenly is attached to the cycle
210     tCHECKED_PTR(gNetPlayerWall)	lastWall;                       //!< the last wall that was attached to this cycle
211     tCHECKED_PTR(gNetPlayerWall)	lastNetWall;                    //!< the last wall received over the network
212 
213     // for network prediction
214     SyncData									lastSyncMessage_;	// the last sync message the cycle received
215     tJUST_CONTROLLED_PTR<gCycleExtrapolator>	extrapolator_;		// the cycle copy used for extrapolation
216     bool										resimulate_;		// flag indicating that a new extrapolation should be started
217 
218     void	ResetExtrapolator();							// resets the extrapolator to the last known state
219     bool	Extrapolate( REAL dt );							// simulate the extrapolator at higher speed
220     void	SyncFromExtrapolator();							// take over the extrapolator's data
221 
222     virtual void OnNotifyNewDestination(gDestination *dest);   //!< called when a destination is successfully inserted into the destination list
223     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.
224 
225     //	unsigned short currentWallID;
226 
227     nTimeRolling nextSync, nextSyncOwner;
228     REAL lastSyncOwnerGameTime_;    //!< time of the last sync to the owner in game time
229 
230     void MyInitAfterCreation();
231 
232     void SetCurrentWall(gNetPlayerWall *w);
233 
234     void PreparePredictPosition( gPredictPositionData & data ); //!< prepares CalculatePredictPosition() call, requesting a raycast to the front
235     REAL CalculatePredictPosition( gPredictPositionData & data ); //!< Calculates predictPosition_
236 protected:
237     virtual ~gCycle();
238 
239     virtual void OnRemoveFromGame(); // called when the cycle is physically removed from the game
240 
241     virtual void OnRoundEnd();    //!< called when the round ends
242 
243     // virtual REAL            DoGetDistanceSinceLastTurn  (                               ) const     ;   //!< returns the distance since the last turn
244 public:
245     virtual void Die ( REAL time )  ;  //!< dies at the specified time
246     void KillAt( const eCoord& pos );  //!< kill this cycle at the given position and take care of scoring
247 
WindingNumber()248     int WindingNumber() const {return windingNumber_;}
249 
250     virtual bool            Vulnerable              ()                                    const     ;   //!< returns whether the cycle can be killed
251 
252     // bool CanMakeTurn() const { return pendingTurns <= 0 && lastTime >= nextTurn; }
253 
254     virtual void InitAfterCreation();
255     gCycle(eGrid *grid, const eCoord &pos,const eCoord &dir,ePlayerNetID *p=NULL);
256 
257     static	void 	SetWallsStayUpDelay		( REAL delay );				//!< the time the cycle walls stay up ( negative values: they stay up forever )
258     static	void 	SetWallsLength			( REAL length);				//!< the maximum total length of the walls
259     static	void 	SetExplosionRadius		( REAL radius);				//!< the radius of the holes blewn in by an explosion
260 
WallsStayUpDelay()261     static	REAL 	WallsStayUpDelay()	 { return wallsStayUpDelay;	}	//!< the time the cycle walls stay up ( negative values: they stay up forever )
WallsLength()262     static	REAL	WallsLength()	 	 { return wallsLength;		}	//!< the default total length of the walls
263     REAL	        MaxWallsLength() const;                             //!< the maximum total length of the walls (including max effect of rubber growth)
264     REAL	        ThisWallsLength() const;                            //!< the maximum total length of this cycle's wall (including rubber shrink)
265     REAL	        WallEndSpeed() const;                               //!< the speed the end of the trail is receeding with right now
ExplosionRadius()266     static	REAL	ExplosionRadius()	 { return explosionRadius;	}	//!< the radius of the holes blewn in by an explosion
267 
268     bool    IsMe( eGameObject const * other ) const;              //!< checks whether the passed pointer is logically identical with this cycle
269 
270     // the network routines:
271     gCycle(nMessage &m);
272     virtual void WriteCreate(nMessage &m);
273     virtual void WriteSync(nMessage &m);
274     virtual void ReadSync(nMessage &m);
275     virtual void RequestSyncOwner(); //!< requests special syncs to the owner on important points (just passed an enemy trail end safely...)
276     virtual void RequestSyncAll(); //!< requests special syncs to everyone on important points (just passed an enemy trail end safely...)
277 
278     virtual void SyncEnemy ( const eCoord& begWall );    //!< handle sync message for enemy cycles
279     // virtual void SyncFriend( const eCoord& begWall );    //!< handle sync message for enemy cycles
280 
281     virtual void ReceiveControl(REAL time,uActionPlayer *Act,REAL x);
282     virtual void PrintName(tString &s) const;
283     virtual bool ActionOnQuit();
284 
285     virtual nDescriptor &CreatorDescriptor() const;
286     virtual bool SyncIsNew(nMessage &m);
287     //virtual bool ClearToTransmit(int user) const;
288 
289     virtual bool Timestep(REAL currentTime);
290     virtual bool TimestepCore(REAL currentTime,bool calculateAcceleration = true);
291 
292     virtual void InteractWith(eGameObject *target,REAL time,int recursion=1);
293 
294     virtual bool EdgeIsDangerous(const eWall *w, REAL time, REAL a) const;
295 
296     virtual void PassEdge(const eWall *w,REAL time,REAL a,int recursion=1);
297 
298     virtual REAL PathfindingModifier( const eWall *w ) const;
299 
300     virtual bool Act(uActionPlayer *Act,REAL x);
301 
302     virtual bool DoTurn(int dir);
303     void DropWall( bool buildNew=true );                                    //!< Drops the current wall and builds a new one
304 
305     // void Turbo(bool turbo);
306 
307     virtual void Kill();
308 
309     const eTempEdge* Edge();
310     const gPlayerWall* CurrentWall();
311     // const gPlayerWall* LastWall();
312 
313 #ifndef DEDICATED
314     virtual void Render(const eCamera *cam);
315 
316     virtual void RenderName( const eCamera *cam );
317 
318     virtual bool RenderCockpitFixedBefore(bool primary=true);
319 
320     virtual void SoundMix(unsigned char *dest,unsigned int len,
321                           int viewer,REAL rvol,REAL lvol);
322 #endif
323 
324     virtual eCoord CamPos() const;
325     virtual eCoord PredictPosition() const;
326     virtual eCoord  CamTop() const;
327 
328     virtual void RightBeforeDeath( int numTries );
329 
330 #ifdef POWERPAK_DEB
331     virtual void PPDisplay();
332 #endif
333 
334     static 	void	PrivateSettings();									// initiate private setting items
335 
336     //	virtual void AddRef();
337     //	virtual void Release();
338 
339 private:
340     static	REAL	wallsStayUpDelay;			//!< the time the cycle walls stay up ( negative values: they stay up forever )
341     static	REAL	wallsLength;				//!< the maximum total length of the walls
342     static	REAL	explosionRadius;			//!< the radius of the holes blewn in by an explosion
343 
344 protected:
345     virtual 	bool 			DoIsDestinationUsed		( const gDestination *	dest		) const		;	//!< returns whether the given destination is in active use
346 };
347 
348 #endif
349 
350