RailroadGuideAIUpdate.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. /*
  2. ** Command & Conquer Generals Zero Hour(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: RailroadBehavior.h ////////////////////////////////////////////////////////////////
  24. // Author: Mark Lorenzen, September 2002
  25. // Desc: Railroad Train AI
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. #pragma once
  28. #ifndef __RAILROADGUIDE_AI_UPDATE_H_
  29. #define __RAILROADGUIDE_AI_UPDATE_H_
  30. // USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
  31. #include "GameLogic/Module/AIUpdate.h"
  32. #include "GameLogic/Module/PhysicsUpdate.h"
  33. // FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
  34. class Waypoint;
  35. typedef std::vector<AsciiString> TemplateNameList;
  36. // ------------------------------------------------------------------------------------------------
  37. // ------------------------------------------------------------------------------------------------
  38. class RailroadBehaviorModuleData : public PhysicsBehaviorModuleData
  39. {
  40. public:
  41. RailroadBehaviorModuleData( void );
  42. static void buildFieldParse( MultiIniFieldParse &p )
  43. {
  44. PhysicsBehaviorModuleData::buildFieldParse( p );
  45. static const FieldParse dataFieldParse[] =
  46. {
  47. { "PathPrefixName", INI::parseAsciiString, NULL, offsetof( RailroadBehaviorModuleData, m_pathPrefixName ) },
  48. { "CrashFXTemplateName", INI::parseAsciiString, NULL, offsetof( RailroadBehaviorModuleData, m_CrashFXTemplateName ) },
  49. { "IsLocomotive", INI::parseBool, NULL, offsetof( RailroadBehaviorModuleData, m_isLocomotive ) },
  50. { "CarriageTemplateName", INI::parseAsciiStringVectorAppend, NULL, offsetof(RailroadBehaviorModuleData, m_carriageTemplateNameData) },
  51. { "BigMetalBounceSound", INI::parseAudioEventRTS, NULL, offsetof( RailroadBehaviorModuleData, m_bigMetalImpactDefaultSound) },
  52. { "SmallMetalBounceSound", INI::parseAudioEventRTS, NULL, offsetof( RailroadBehaviorModuleData, m_smallMetalImpactDefaultSound) },
  53. { "MeatyBounceSound", INI::parseAudioEventRTS, NULL, offsetof( RailroadBehaviorModuleData, m_meatyImpactDefaultSound) },
  54. { "RunningGarrisonSpeedMax", INI::parseReal, NULL, offsetof( RailroadBehaviorModuleData, m_runningGarrisonSpeedMax) },
  55. { "KillSpeedMin", INI::parseReal, NULL, offsetof( RailroadBehaviorModuleData, m_killSpeedMin) },
  56. { "SpeedMax", INI::parseReal, NULL, offsetof( RailroadBehaviorModuleData, m_speedMax) },
  57. { "Acceleration", INI::parseReal, NULL, offsetof( RailroadBehaviorModuleData, m_acceleration) },
  58. { "Braking", INI::parseReal, NULL, offsetof( RailroadBehaviorModuleData, m_braking) },
  59. { "WaitAtStationTime", INI::parseDurationUnsignedInt, NULL, offsetof( RailroadBehaviorModuleData, m_waitAtStationTime) },
  60. { "RunningSound", INI::parseAudioEventRTS, NULL, offsetof( RailroadBehaviorModuleData, m_runningSound) },
  61. { "ClicketyClackSound", INI::parseAudioEventRTS, NULL, offsetof( RailroadBehaviorModuleData, m_clicketyClackSound) },
  62. { "WhistleSound", INI::parseAudioEventRTS, NULL, offsetof( RailroadBehaviorModuleData, m_whistleSound) },
  63. { "Friction", INI::parseReal, NULL, offsetof( RailroadBehaviorModuleData, m_friction) },
  64. { 0, 0, 0, 0 }
  65. };
  66. p.add( dataFieldParse );
  67. } // end buildFieldParse
  68. TemplateNameList m_carriageTemplateNameData;
  69. AsciiString m_pathPrefixName; ///< prefix to use for waypont start and end points we'll look for
  70. AsciiString m_CrashFXTemplateName;
  71. Bool m_isLocomotive;
  72. Real m_runningGarrisonSpeedMax;
  73. Real m_killSpeedMin;
  74. Real m_speedMax;
  75. Real m_acceleration;
  76. Real m_braking;
  77. Real m_friction;
  78. UnsignedInt m_waitAtStationTime;
  79. AudioEventRTS m_runningSound;
  80. AudioEventRTS m_clicketyClackSound;
  81. AudioEventRTS m_bigMetalImpactDefaultSound;
  82. AudioEventRTS m_smallMetalImpactDefaultSound;
  83. AudioEventRTS m_meatyImpactDefaultSound;
  84. AudioEventRTS m_whistleSound;
  85. };
  86. //-------------------------------------------------------------------------------------------------
  87. //-------------------------------------------------------------------------------------------------
  88. struct TrackPoint
  89. {
  90. TrackPoint( void )
  91. {
  92. clear();
  93. };
  94. void clear( void )
  95. {
  96. m_position.set(0,0,0);
  97. m_distanceFromPrev = 0;
  98. m_distanceFromFirst = 0;
  99. m_handle = 0xfacade;
  100. m_isFirstPoint = FALSE;
  101. m_isLastPoint = FALSE;
  102. m_isTunnelOrBridge = FALSE;
  103. m_isStation = FALSE;
  104. m_isDisembark = FALSE;
  105. m_isPingPong = FALSE;
  106. };
  107. const Int getHandle( void )
  108. {
  109. return m_handle;
  110. };
  111. Coord3D m_position;
  112. Real m_distanceFromPrev;
  113. Real m_distanceFromFirst;
  114. Int m_handle;
  115. Bool m_isFirstPoint;
  116. Bool m_isLastPoint;
  117. Bool m_isTunnelOrBridge;
  118. Bool m_isStation;
  119. Bool m_isDisembark;
  120. Bool m_isPingPong;
  121. };
  122. typedef std::list<TrackPoint> TrackPointList;
  123. struct TrainTrack
  124. {
  125. TrainTrack( void ) // a constructor 4 u
  126. {
  127. clear();
  128. incReference();
  129. };
  130. void clear( void )
  131. {
  132. m_pointList.clear();
  133. m_isLooping = FALSE;
  134. m_isValid = FALSE;
  135. m_refCount = 0;
  136. m_length = 0.0f;
  137. };
  138. Bool m_isLooping;
  139. Bool m_isValid;
  140. Real m_length;
  141. void incReference();
  142. Bool releaseReference();
  143. // To protect the track form ever going out of sync between cars on the same train...
  144. // I restrict write access to the first referencer, before a second one is added (the locomotive)
  145. TrackPointList* getWritablePointList( void ) { return m_refCount == 1 ? &m_pointList : NULL; };
  146. const TrackPointList* getPointList( void ) { return &m_pointList; };
  147. private:
  148. TrackPointList m_pointList;
  149. UnsignedInt m_refCount;
  150. };
  151. //-------------------------------------------------------------------------------------------------
  152. class RailroadBehavior : public PhysicsBehavior
  153. {
  154. MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( RailroadBehavior, "RailroadBehavior" )
  155. MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( RailroadBehavior, RailroadBehaviorModuleData )
  156. public:
  157. RailroadBehavior( Thing *thing, const ModuleData *moduleData );
  158. // virtual destructor prototype provided by memory pool declaration
  159. static Int getInterfaceMask() { return PhysicsBehavior::getInterfaceMask(); }
  160. struct PullInfo
  161. {
  162. Real m_direction; ///< 1 = forward, -1 = backward
  163. Real speed;
  164. Real trackDistance;
  165. Coord3D towHitchPosition;
  166. Int m_mostRecentSpecialPointHandle;
  167. UnsignedInt previousWaypoint;
  168. UnsignedInt currentWaypoint;
  169. void xferPullInfo( Xfer *xfer );
  170. };
  171. typedef std::vector<AsciiString> TemplateNameVector;
  172. typedef TemplateNameVector::const_iterator TemplateNameIterator;;
  173. //UpdateModule methods
  174. // virtual SleepyUpdatePhase getUpdatePhase() const { return PHASE_FINAL; }
  175. // PhysicsBehavior methods
  176. virtual void onCollide( Object *other, const Coord3D *loc, const Coord3D *normal );
  177. virtual Bool isRailroad() const ;
  178. virtual UpdateSleepTime update( void );
  179. // TRAINY METHODS
  180. void getPulled( PullInfo *info );
  181. void destroyTheWholeTrainNow( void );
  182. void hitchNewCarriagebyTemplate( ObjectID parentID, const TemplateNameVector& list, TemplateNameIterator& iter, TrainTrack *trackPointList );
  183. void hitchNewCarriagebyProximity( ObjectID parentID, TrainTrack *trackPointList );
  184. void disembark( void );
  185. Bool hasEverBeenHitched( void ) { return m_hasEverBeenHitched; };
  186. void setHeld( Bool held ) {m_held = held;};
  187. void makeAWallOutOfThisTrain( Bool on );
  188. protected:
  189. //definitions
  190. enum ConductorState
  191. {
  192. APPLY_BRAKES,
  193. WAIT_AT_STATION,
  194. ACCELERATE,
  195. COAST
  196. };
  197. enum StationTask
  198. {
  199. DO_NOTHING,
  200. DISEMBARK
  201. };
  202. // our methods
  203. void updatePositionTrackDistance( PullInfo *pullerInfo, PullInfo *myInfo );
  204. void loadTrackData( void );
  205. void createCarriages( void );
  206. void FindPosByPathDistance( Coord3D *pos, const Real dist, const Real length, Bool setState = FALSE );
  207. void playImpactSound(Object *victim, const Coord3D *impactPosition);
  208. TemplateNameIterator m_carriageTemplateNameIterator;
  209. StationTask m_nextStationTask;
  210. ObjectID m_trailerID; ///< the ID of the object I am directly pulling
  211. PullInfo conductorPullInfo;
  212. PullInfo m_pullInfo;
  213. AudioEventRTS m_whistleSound;
  214. AudioEventRTS m_clicketyClackSound;
  215. AudioEventRTS m_runningSound;
  216. AudioHandle m_runningSoundHandle;
  217. TrainTrack *m_track;
  218. Int m_currentPointHandle;
  219. Int m_waitAtStationTimer;
  220. //Flags
  221. Bool m_carriagesCreated; ///< TRUE once we have made all the cars in the train
  222. Bool m_hasEverBeenHitched; /// has somebody ever hitched me? Remains true, even after puller dies.
  223. Bool m_trackDataLoaded; ///< have I TRIED to load track data, yet? I only try once!
  224. Bool m_waitingInWings; /// I have not entered the real track yet, so leave me alone
  225. Bool m_endOfLine; /// I have reached the end of a non looping track
  226. Bool m_isLocomotive; ///< Am I a locomotive,
  227. Bool m_isLeadCarraige; ///< Am the carraige in front,
  228. Int m_wantsToBeLeadCarraige; ///< Am the carraige in front,
  229. Bool m_disembark; ///< If I wait at a station, I should also evacuate everybody when I get theres
  230. Bool m_inTunnel; ///< Am I in a tunnel, so I wil not snap to ground height, until the next waypoint,
  231. // i.e. do I provide the movement and scheduling AI for m_trailerID
  232. // And therefore for his and his and his..........
  233. Bool m_held; ///< This will prevent a loco from departing a station
  234. ConductorState m_conductorState;
  235. WaypointID m_anchorWaypointID;
  236. };
  237. #endif // end __RAILROAD_GUIDE_AI_UPDATE_H_