/* ************************************************************************* ArmageTron -- Just another Tron Lightcycle Game in 3D. Copyright (C) 2000 Manuel Moos (manuel@moosnet.de) ************************************************************************** This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *************************************************************************** */ #ifndef ArmageTron_CYCLE_H #define ArmageTron_CYCLE_H #include "gStuff.h" //#include "eSound.h" //#include "rTexture.h" //#include "rModel.h" #include "eNetGameObject.h" #include "tList.h" #include "nObserver.h" class rModel; class gTextureCycle; class eSoundPlayer; class gSensor; class gCycle; class gPlayerWall; class gNetPlayerWall; class gDestination; // minimum time between two cycle turns extern REAL sg_delayCycle; // steering help extern REAL sg_rubberCycle; // this class describes a point on the map the cycle on another // computer of the game IS at. The copies of the cycle on the // other computers try to reach this position by making the right // turns. class gDestination{ friend class gCycle; eCoord position; // position of turn/brake command eCoord direction; // driving direction after the command REAL gameTime; // game time of the command REAL distance; // distance travelled so far REAL speed; // speed at the time of the command bool braking; // flag telling whether the brake was active bool chatting; // flag indicating chat status bool hasBeenUsed; // flag indicating whether the sync code has already used this command unsigned short messageID; // ID of the message this command came from gDestination *next; // so they can form a list gDestination **list; // the list we are in public: // take pos,dir and time from a cycle gDestination(const gCycle &takeitfrom); // or from a message gDestination(nMessage &m); // write all the data into a nMessage void WriteCreate(nMessage &m); // insert yourself into a list ordered by distance void InsertIntoList(gDestination **list); // find the latest entry in a list before the given distance static gDestination *RightBefore(gDestination *list, REAL dist); // remove yourself again void RemoveFromList(); bool Chatting(){ return chatting; } ~gDestination(){RemoveFromList();} gDestination & SetGameTime( REAL gameTime ); //!< Sets game time of the command REAL GetGameTime( void ) const; //!< Gets game time of the command gDestination const & GetGameTime( REAL & gameTime ) const; //!< Gets game time of the command }; // this class set is responsible for remembering which walls are too // close together to pass through safely. The AI uses this information, // so the real declaration of gCylceMemoryEntry can be found in gAIBase.cpp. class gCycleMemoryEntry; class gCycleMemory{ friend class gCycleMemoryEntry; tList memory; // memory about other cylces public: // memory functions: access the memory for a cylce gCycleMemoryEntry* Remember(const gCycle *cycle); int Len() const {return memory.Len();} gCycleMemoryEntry* operator() (int i) const; gCycleMemoryEntry* Latest (int side) const; gCycleMemoryEntry* Earliest (int side) const; void Clear(); gCycleMemory(); ~gCycleMemory(); }; class gEnemyInfluence{ private: nObserverPtr< ePlayerNetID > lastEnemyInfluence; // the last enemy wall we encountered REAL lastTime; // the time it was drawn at public: gEnemyInfluence(); const ePlayerNetID* GetEnemy(); // the last enemy possibly responsible for our death void AddSensor( const gSensor& sensor, REAL timePenalty ); // add the result of the sensor scan to our data }; struct gRealColor { REAL r,g,b; gRealColor():r(1), g(1), b(1){} }; class gCycle: public eNetGameObject{ // a lightcycle friend class gPlayerWall; friend class gNetPlayerWall; friend class gDestination; eSoundPlayer *engine; eSoundPlayer *turning; eSoundPlayer *spark; REAL lastTimeAnim; REAL timeCameIntoView; REAL nextChatAI; eCoord correctPosSmooth; gDestination *destinationList; gDestination *currentDestination; public: eCoord dirDrive; // the direction we are facing in reality REAL skew,skewDot,speed,acceleration; // leaning to the side and velocity REAL rubber; // allows stopping shortly if there's a eWall ahead static REAL wallsStayUpDelay; // the time the cycle walls stay up ( negative values: they stay up forever ) static REAL wallsLength; // the maximum total length of the walls static REAL explosionRadius; // the radius of the holes blewn in by an explosion bool mp; // use moviepack or not? rModel *body,*front,*rear, *customModel; gTextureCycle *wheelTex,*bodyTex; gTextureCycle *customTexture; eCoord rotationFrontWheel,rotationRearWheel; // wheel position (rotation) REAL heightFrontWheel,heightRearWheel; // wheel (suspension) REAL nextTurn; int pendingTurns; unsigned short turns; // how many turns did we make up to now? unsigned short braking; bool localTunnel_; // flag set in network mode to indicate this cycle tunneled locally int windingNumber; public: REAL brakingReservoir; // reservoir for braking. 1 means full, 0 is empty static uActionPlayer s_brake; short alive; // are we still there? gCycleMemory memory; gRealColor color_; gRealColor trailColor_; REAL distance; //distance travveled so far REAL wallContDistance; // distance at wich the walls will start to build up ( negative if the wall is already building ) // smooth corrections for space-based network control REAL correctTimeSmooth,correctSpeedSmooth,correctDistSmooth; private: gEnemyInfluence enemyInfluence; tCHECKED_PTR(gNetPlayerWall) currentWall; // the eWall we are currently making tCHECKED_PTR(gNetPlayerWall) lastWall; // unsigned short currentWallID; REAL nextSync, nextSyncOwner; void MyInitAfterCreation(); static void Hunt( gCycle *hunter, gCycle *prey, const eCoord& pos ); void SetCurrentWall(gNetPlayerWall *w); protected: virtual ~gCycle(); virtual void RemoveFromGame(); // call this instead of the destructor public: virtual void AddRef(); int WindingNumber() const {return windingNumber;} bool CanMakeTurn() const { return pendingTurns <= 0 && lastTime >= nextTurn; } virtual bool EdgeIsDangerous(const eWall *w, REAL time, REAL a) const; virtual void InitAfterCreation(); gCycle(eGrid *grid, const eCoord &pos,const eCoord &dir,ePlayerNetID *p=NULL,bool autodelete=1); // the network routines: gCycle(nMessage &m); virtual void WriteCreate(nMessage &m); virtual void WriteSync(nMessage &m); virtual void ReadSync(nMessage &m); virtual void ReceiveControl(REAL time,uActionPlayer *Act,REAL x); virtual void PrintName(tString &s) const; virtual bool ActionOnQuit(); void AddDestination(gDestination *dest); void AddDestination(); virtual nDescriptor &CreatorDescriptor() const; virtual bool SyncIsNew(nMessage &m); //virtual bool ClearToTransmit(int user) const; virtual eCoord Direction()const{return dirDrive;} virtual REAL Speed()const{return speed;} // virtual gameobject_type type(); virtual bool Timestep(REAL currentTime); bool TimestepCore(REAL currentTime); virtual void InteractWith(eGameObject *target,REAL time,int recursion=1); 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); void Turn(REAL dir); void Turn(int dir); void Turbo(bool turbo); virtual void Kill(); virtual bool Alive()const {return alive>=1;} const eTempEdge* Edge(); const gPlayerWall* CurrentWall(); const gPlayerWall* LastWall(); #ifndef DEDICATED virtual void Render(const eCamera *cam); virtual void RenderName( const eCamera *cam ); virtual bool RenderCockpitFixedBefore(bool primary=true); virtual void SoundMix(unsigned char *dest,unsigned int len, int viewer,REAL rvol,REAL lvol); #endif virtual eCoord CamPos(); virtual eCoord PredictPosition(); virtual eCoord CamTop(); #ifdef POWERPAK_DEB virtual void PPDisplay(); #endif // access the speed multiplier static float SpeedMultiplier(); static void SetSpeedMultiplier(float mult); 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() { return wallsStayUpDelay; } // the time the cycle walls stay up ( negative values: they stay up forever ) static REAL WallsLength() { return wallsLength; } // the maximum total length of the walls static REAL ExplosionRadius() { return explosionRadius; } // the radius of the holes blewn in by an explosion static void PrivateSettings(); // initiate private setting items // virtual void AddRef(); // virtual void Release(); }; #endif