diff --git a/Generals/Code/GameEngine/Include/Common/ArchiveFileSystem.h b/Generals/Code/GameEngine/Include/Common/ArchiveFileSystem.h index e9695e0c17..b1f75e7411 100644 --- a/Generals/Code/GameEngine/Include/Common/ArchiveFileSystem.h +++ b/Generals/Code/GameEngine/Include/Common/ArchiveFileSystem.h @@ -172,11 +172,10 @@ class ArchiveFileSystem : public SubsystemInterface // Unprotected this for copy-protection routines AsciiString getArchiveFilenameForFile(const AsciiString& filename) const; - void loadMods( void ); protected: - virtual void loadIntoDirectoryTree(const ArchiveFile *archiveFile, const AsciiString& archiveFilename, Bool overwrite = FALSE); ///< load the archive file's header information and apply it to the global archive directory tree. + virtual void loadIntoDirectoryTree(const ArchiveFile *archiveFile, const AsciiString& archiveFilename, Bool overwrite = FALSE ); ///< load the archive file's header information and apply it to the global archive directory tree. ArchiveFileMap m_archiveFileMap; ArchivedDirectoryInfo m_rootDirectory; diff --git a/Generals/Code/GameEngine/Include/Common/BitFlagsIO.h b/Generals/Code/GameEngine/Include/Common/BitFlagsIO.h index da4a1e3cb1..5911362b0a 100644 --- a/Generals/Code/GameEngine/Include/Common/BitFlagsIO.h +++ b/Generals/Code/GameEngine/Include/Common/BitFlagsIO.h @@ -138,6 +138,18 @@ template ((BitFlags*)store)->parse(ini, NULL); } +//------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------------- +template +/*static*/ void BitFlags::parseSingleBitFromINI(INI* ini, void* /*instance*/, void *store, const void* /*userData*/) +{ + const char *token = ini->getNextToken(); + Int bitIndex = INI::scanIndexList(token, s_bitNameList); // this throws if the token is not found + + Int *storeAsInt = (Int*)store; + *storeAsInt = bitIndex; +} + //------------------------------------------------------------------------------------------------- /** Xfer method * Version Info: diff --git a/Generals/Code/GameEngine/Include/Common/DataChunk.h b/Generals/Code/GameEngine/Include/Common/DataChunk.h index 3fe923efda..a1130f184c 100644 --- a/Generals/Code/GameEngine/Include/Common/DataChunk.h +++ b/Generals/Code/GameEngine/Include/Common/DataChunk.h @@ -136,6 +136,7 @@ class DataChunkOutput void writeUnicodeString(UnicodeString string); void writeArrayOfBytes(char *ptr, Int len); void writeDict(const Dict& d); + void writeNameKey(const NameKeyType key); }; //---------------------------------------------------------------------- @@ -228,6 +229,8 @@ class DataChunkInput UnicodeString readUnicodeString(void); Dict readDict(void); void readArrayOfBytes(char *ptr, Int len); + + NameKeyType readNameKey(void); }; diff --git a/Generals/Code/GameEngine/Include/Common/DisabledTypes.h b/Generals/Code/GameEngine/Include/Common/DisabledTypes.h index 89ecb6aa32..28b2fd8b55 100644 --- a/Generals/Code/GameEngine/Include/Common/DisabledTypes.h +++ b/Generals/Code/GameEngine/Include/Common/DisabledTypes.h @@ -35,6 +35,7 @@ // INCLUDES /////////////////////////////////////////////////////////////////////////////////////// #include "Lib/BaseType.h" #include "Common/BitFlags.h" +#include "Common/BitFlagsIO.h" //------------------------------------------------------------------------------------------------- /** Kind of flags for determining groups of things that belong together @@ -56,6 +57,8 @@ enum DisabledType CPP_11(: Int) DISABLED_SCRIPT_UNDERPOWERED, DISABLED_COUNT, + + DISABLED_ANY = 65535 ///< Do not use this value for setting disabled types (read-only) }; typedef BitFlags DisabledMaskType; diff --git a/Generals/Code/GameEngine/Include/Common/Energy.h b/Generals/Code/GameEngine/Include/Common/Energy.h index a6faacd27c..aea2740367 100644 --- a/Generals/Code/GameEngine/Include/Common/Energy.h +++ b/Generals/Code/GameEngine/Include/Common/Energy.h @@ -66,7 +66,7 @@ class Energy : public Snapshot public: - inline Energy() : m_energyProduction(0), m_energyConsumption(0), m_owner(NULL) { } + Energy(); // reset energy information to base values. void init( Player *owner) @@ -77,7 +77,7 @@ class Energy : public Snapshot } /// return current energy production in kilowatts - Int getProduction() const { return m_energyProduction; } + Int getProduction() const; /// return current energy consumption in kilowatts Int getConsumption() const { return m_energyConsumption; } diff --git a/Generals/Code/GameEngine/Include/Common/FileSystem.h b/Generals/Code/GameEngine/Include/Common/FileSystem.h index a7513a994a..26c1fea41e 100644 --- a/Generals/Code/GameEngine/Include/Common/FileSystem.h +++ b/Generals/Code/GameEngine/Include/Common/FileSystem.h @@ -116,9 +116,13 @@ struct FileInfo { * created when FileSystem::Open() gets called. */ //=============================== +#include class FileSystem : public SubsystemInterface { + FileSystem(const FileSystem&); + FileSystem& operator=(const FileSystem&); + public: FileSystem(); virtual ~FileSystem(); @@ -138,8 +142,7 @@ class FileSystem : public SubsystemInterface void loadMusicFilesFromCD(); void unloadMusicFilesFromCD(); protected: - - + mutable std::map m_fileExist; }; extern FileSystem* TheFileSystem; diff --git a/Generals/Code/GameEngine/Include/Common/GameMemory.h b/Generals/Code/GameEngine/Include/Common/GameMemory.h index 2c222407e9..822ee7baab 100644 --- a/Generals/Code/GameEngine/Include/Common/GameMemory.h +++ b/Generals/Code/GameEngine/Include/Common/GameMemory.h @@ -730,7 +730,6 @@ private: \ public: /* include this line at the end to reset visibility to 'public' */ - // ---------------------------------------------------------------------------- /** This class is provided as a simple and safe way to integrate C++ object allocation @@ -768,7 +767,6 @@ class MemoryPoolObject }; - // INLINING /////////////////////////////////////////////////////////////////// // ---------------------------------------------------------------------------- @@ -893,7 +891,6 @@ class STLSpecialAlloc #endif //DISABLE_GAMEMEMORY -// ---------------------------------------------------------------------------- /** A simple utility class to ensure exception safety; this holds a MemoryPoolObject and deletes it in its destructor. Especially useful for iterators! @@ -910,7 +907,6 @@ class MemoryPoolObjectHolder }; -// ---------------------------------------------------------------------------- /** Sometimes you want to make a class's destructor protected so that it can only be destroyed under special circumstances. MemoryPoolObject short-circuits this @@ -924,4 +920,5 @@ ARGVIS: void deleteInstance() { MemoryPoolObject::deleteInstance(); } public: #define EMPTY_DTOR(CLASS) inline CLASS::~CLASS() { } + #endif // _GAME_MEMORY_H_ diff --git a/Generals/Code/GameEngine/Include/Common/GameType.h b/Generals/Code/GameEngine/Include/Common/GameType.h index 566f560f7c..b793738073 100644 --- a/Generals/Code/GameEngine/Include/Common/GameType.h +++ b/Generals/Code/GameEngine/Include/Common/GameType.h @@ -58,6 +58,8 @@ enum FormationID CPP_11(: Int) FORCE_FORMATIONID_TO_LONG_SIZE = 0x7ffffff }; +#define INVALID_ANGLE -100.0f + class INI; //------------------------------------------------------------------------------------------------- diff --git a/Generals/Code/GameEngine/Include/Common/GlobalData.h b/Generals/Code/GameEngine/Include/Common/GlobalData.h index 7840845813..282232c2bc 100644 --- a/Generals/Code/GameEngine/Include/Common/GlobalData.h +++ b/Generals/Code/GameEngine/Include/Common/GlobalData.h @@ -391,6 +391,9 @@ class GlobalData : public SubsystemInterface Color m_hotKeyTextColor; ///< standard color for all hotkeys. + //THis is put on ice until later - M Lorenzen + // Int m_cheaterHasBeenSpiedIfMyLowestBitIsTrue; ///< says it all.. this lives near other "colors" cause it is masquerading as one + AsciiString m_specialPowerViewObjectName; ///< Created when certain special powers are fired so players can watch. std::vector m_standardPublicBones; @@ -492,10 +495,13 @@ class GlobalData : public SubsystemInterface Bool m_isBreakableMovie; ///< if we enter a breakable movie, set this flag Bool m_breakTheMovie; ///< The user has hit escape! - AsciiString m_modDir; AsciiString m_modBIG; + //-allAdvice feature + //Bool m_allAdvice; + + // the trailing '\' is included! AsciiString getPath_UserData() const; diff --git a/Generals/Code/GameEngine/Include/Common/KindOf.h b/Generals/Code/GameEngine/Include/Common/KindOf.h index 6a47f33c77..845070bec4 100644 --- a/Generals/Code/GameEngine/Include/Common/KindOf.h +++ b/Generals/Code/GameEngine/Include/Common/KindOf.h @@ -35,6 +35,7 @@ // INCLUDES /////////////////////////////////////////////////////////////////////////////////////// #include "Lib/BaseType.h" #include "Common/BitFlags.h" +#include "Common/BitFlagsIO.h" //------------------------------------------------------------------------------------------------- /** Kind of flags for determining groups of things that belong together diff --git a/Generals/Code/GameEngine/Include/Common/MapObject.h b/Generals/Code/GameEngine/Include/Common/MapObject.h index 7c68eb2516..7e1b3784b8 100644 --- a/Generals/Code/GameEngine/Include/Common/MapObject.h +++ b/Generals/Code/GameEngine/Include/Common/MapObject.h @@ -36,6 +36,19 @@ #include "Common/GameMemory.h" #include "GameClient/TerrainRoads.h" + + +class WorldHeightMapInterfaceClass +{ +public: + + virtual Int getBorderSize() = 0; + virtual Real getSeismicZVelocity(Int xIndex, Int yIndex) const = 0; + virtual void setSeismicZVelocity(Int xIndex, Int yIndex, Real value) = 0; + virtual Real getBilinearSampleSeismicZVelocity( Int x, Int y) = 0; + +}; + /** MapObject class Not ref counted. Do not store pointers to this class. */ class WorldHeightMap; diff --git a/Generals/Code/GameEngine/Include/Common/MessageStream.h b/Generals/Code/GameEngine/Include/Common/MessageStream.h index 1edb0c70c2..8024c65af5 100644 --- a/Generals/Code/GameEngine/Include/Common/MessageStream.h +++ b/Generals/Code/GameEngine/Include/Common/MessageStream.h @@ -567,6 +567,8 @@ class GameMessage : public MemoryPoolObject MSG_DEBUG_KILL_OBJECT, #endif + + //********************************************************************************************************* MSG_END_NETWORK_MESSAGES = 1999, ///< MARKER TO DELINEATE MESSAGES THAT GO OVER THE NETWORK //********************************************************************************************************* diff --git a/Generals/Code/GameEngine/Include/Common/MiscAudio.h b/Generals/Code/GameEngine/Include/Common/MiscAudio.h index 69b09a0564..5f690e100b 100644 --- a/Generals/Code/GameEngine/Include/Common/MiscAudio.h +++ b/Generals/Code/GameEngine/Include/Common/MiscAudio.h @@ -73,4 +73,5 @@ struct MiscAudio }; -#endif /* _MISCAUDIO_H_ */ \ No newline at end of file +#endif /* _MISCAUDIO_H_ */ + diff --git a/Generals/Code/GameEngine/Include/Common/ModelState.h b/Generals/Code/GameEngine/Include/Common/ModelState.h index 9ca76f0f97..536282efff 100644 --- a/Generals/Code/GameEngine/Include/Common/ModelState.h +++ b/Generals/Code/GameEngine/Include/Common/ModelState.h @@ -34,6 +34,7 @@ #include "Lib/BaseType.h" #include "Common/INI.h" #include "Common/BitFlags.h" +#include "Common/BitFlagsIO.h" //------------------------------------------------------------------------------------------------- @@ -83,6 +84,8 @@ */ +#define NUM_MODELCONDITION_DOOR_STATES 4 + //------------------------------------------------------------------------------------------------- // IMPORTANT NOTE: you should endeavor to set up states such that the most "normal" // state is defined by the bit being off. That is, the typical "normal" condition diff --git a/Generals/Code/GameEngine/Include/Common/Module.h b/Generals/Code/GameEngine/Include/Common/Module.h index a291cfed56..7ea6491a12 100644 --- a/Generals/Code/GameEngine/Include/Common/Module.h +++ b/Generals/Code/GameEngine/Include/Common/Module.h @@ -48,6 +48,7 @@ class Object; class Player; class Thing; class W3DModelDrawModuleData; // ugh, hack (srj) +class W3DTreeDrawModuleData; // ugh, hack (srj) struct FieldParse; // TYPES ////////////////////////////////////////////////////////////////////////////////////////// @@ -112,6 +113,8 @@ class ModuleData : public Snapshot // ugh, hack virtual const W3DModelDrawModuleData* getAsW3DModelDrawModuleData() const { return NULL; } + // ugh, hack + virtual const W3DTreeDrawModuleData* getAsW3DTreeDrawModuleData() const { return NULL; } virtual StaticGameLODLevel getMinimumRequiredGameLOD() const { return (StaticGameLODLevel)0;} static void buildFieldParse(MultiIniFieldParse& p) diff --git a/Generals/Code/GameEngine/Include/Common/MultiplayerSettings.h b/Generals/Code/GameEngine/Include/Common/MultiplayerSettings.h index 1d93377754..8cc00ebb40 100644 --- a/Generals/Code/GameEngine/Include/Common/MultiplayerSettings.h +++ b/Generals/Code/GameEngine/Include/Common/MultiplayerSettings.h @@ -79,9 +79,9 @@ class MultiplayerSettings : public SubsystemInterface MultiplayerSettings( void ); - void init() { } - void update() { } - void reset() { } + virtual void init() { } + virtual void update() { } + virtual void reset() { } //----------------------------------------------------------------------------------------------- static const FieldParse m_multiplayerSettingsFieldParseTable[]; ///< the parse table for INI definition diff --git a/Generals/Code/GameEngine/Include/Common/NameKeyGenerator.h b/Generals/Code/GameEngine/Include/Common/NameKeyGenerator.h index 1363a4b5b6..583f42d658 100644 --- a/Generals/Code/GameEngine/Include/Common/NameKeyGenerator.h +++ b/Generals/Code/GameEngine/Include/Common/NameKeyGenerator.h @@ -96,9 +96,11 @@ class NameKeyGenerator : public SubsystemInterface /// Given a string, convert into a unique integer key. NameKeyType nameToKey(const AsciiString& name) { return nameToKey(name.str()); } + NameKeyType nameToLowercaseKey(const AsciiString& name) { return nameToLowercaseKey(name.str()); } /// Given a string, convert into a unique integer key. NameKeyType nameToKey(const char* name); + NameKeyType nameToLowercaseKey(const char *name); /** given a key, return the name. this is almost never needed, @@ -108,6 +110,9 @@ class NameKeyGenerator : public SubsystemInterface */ AsciiString keyToName(NameKeyType key); + // Get a string out of the INI. Store it into a NameKeyType + static void parseStringAsNameKeyType( INI *ini, void *instance, void *store, const void* userData ); + private: enum diff --git a/Generals/Code/GameEngine/Include/Common/Player.h b/Generals/Code/GameEngine/Include/Common/Player.h index e074b926b4..6dba29393d 100644 --- a/Generals/Code/GameEngine/Include/Common/Player.h +++ b/Generals/Code/GameEngine/Include/Common/Player.h @@ -316,6 +316,9 @@ class Player : public Snapshot void toggleFreeBuild(){ m_DEMO_freeBuild = !m_DEMO_freeBuild; } Bool buildsForFree() const { return m_DEMO_freeBuild; } +#endif + +#if defined(_DEBUG) || defined(_INTERNAL) || defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE) /// No time building cheat key void toggleInstantBuild(){ m_DEMO_instantBuild = !m_DEMO_instantBuild; } Bool buildsInstantly() const { return m_DEMO_instantBuild; } @@ -770,6 +773,9 @@ class Player : public Snapshot #if defined(_DEBUG) || defined(_INTERNAL) Bool m_DEMO_ignorePrereqs; ///< Can I ignore prereq checks? Bool m_DEMO_freeBuild; ///< Can I build everything for no money? +#endif + +#if defined(_DEBUG) || defined(_INTERNAL) || defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE) Bool m_DEMO_instantBuild; ///< Can I build anything in one frame? #endif diff --git a/Generals/Code/GameEngine/Include/Common/Radar.h b/Generals/Code/GameEngine/Include/Common/Radar.h index 33d61a0069..fb1b65547a 100644 --- a/Generals/Code/GameEngine/Include/Common/Radar.h +++ b/Generals/Code/GameEngine/Include/Common/Radar.h @@ -169,6 +169,7 @@ class Radar : public Snapshot, Bool isRadarWindow( GameWindow *window ) { return (m_radarWindow == window) && (m_radarWindow != NULL); } Bool radarToWorld( const ICoord2D *radar, Coord3D *world ); ///< radar point to world point on terrain + Bool radarToWorld2D( const ICoord2D *radar, Coord3D *world ); ///< radar point to world point (x,y only!) Bool worldToRadar( const Coord3D *world, ICoord2D *radar ); ///< translate world point to radar (x,y) Bool localPixelToRadar( const ICoord2D *pixel, ICoord2D *radar ); ///< translate pixel (with UL of radar being (0,0)) to logical radar coords Bool screenPixelToWorld( const ICoord2D *pixel, Coord3D *world ); ///< translate pixel (with UL of the screen being (0,0)) to world position in the world diff --git a/Generals/Code/GameEngine/Include/Common/SparseMatchFinder.h b/Generals/Code/GameEngine/Include/Common/SparseMatchFinder.h index 7ea1c91cb3..4630c31f9b 100644 --- a/Generals/Code/GameEngine/Include/Common/SparseMatchFinder.h +++ b/Generals/Code/GameEngine/Include/Common/SparseMatchFinder.h @@ -72,6 +72,26 @@ class SparseMatchFinder } }; + struct MapHelper + { + bool operator()(const BITSET& a, const BITSET& b) const + { + int i; + if (a.size() < b.size()) { + return true; + } + for (i = 0; i < a.size(); ++i) { + bool aVal = a.test(i); + bool bVal = b.test(i); + if (aVal && bVal) continue; + if (!aVal && !bVal) continue; + if (!aVal) return true; + return false; + } + return false; // all bits match. + } + }; + //------------------------------------------------------------------------------------------------- typedef std::hash_map< BITSET, const MATCHABLE*, HashMapHelper, HashMapHelper > MatchMap; @@ -80,6 +100,7 @@ class SparseMatchFinder //------------------------------------------------------------------------------------------------- mutable MatchMap m_bestMatches; + //mutable HashMatchMap m_bestHashMatches; //------------------------------------------------------------------------------------------------- // METHODS diff --git a/Generals/Code/GameEngine/Include/Common/SpecialPowerMaskType.h b/Generals/Code/GameEngine/Include/Common/SpecialPowerMaskType.h index f350a2ea45..ffabd68f9c 100644 --- a/Generals/Code/GameEngine/Include/Common/SpecialPowerMaskType.h +++ b/Generals/Code/GameEngine/Include/Common/SpecialPowerMaskType.h @@ -31,6 +31,7 @@ #define __SPECIALPOWERMASKTYPE_H__ #include "Common/BitFlags.h" +#include "Common/BitFlagsIO.h" #include "Common/SpecialPowerType.h" typedef BitFlags SpecialPowerMaskType; diff --git a/Generals/Code/GameEngine/Include/Common/StackDump.h b/Generals/Code/GameEngine/Include/Common/StackDump.h index d0f7a1ff4f..1493129c85 100644 --- a/Generals/Code/GameEngine/Include/Common/StackDump.h +++ b/Generals/Code/GameEngine/Include/Common/StackDump.h @@ -29,8 +29,7 @@ #ifndef IG_DEGBUG_STACKTRACE #define IG_DEBUG_STACKTRACE 1 -#endif - +#endif // Unsure about this one -ML 3/25/03 #if defined(_DEBUG) || defined(_INTERNAL) || defined(IG_DEBUG_STACKTRACE) // Writes a stackdump (provide a callback : gets called per line) @@ -70,6 +69,4 @@ __inline void DumpExceptionInfo( unsigned int u, EXCEPTION_POINTERS* e_info ) {} #endif extern AsciiString g_LastErrorDump; - - #endif // __STACKDUMP_H_ diff --git a/Generals/Code/GameEngine/Include/Common/Team.h b/Generals/Code/GameEngine/Include/Common/Team.h index f27e3a46d1..4caeb537b7 100644 --- a/Generals/Code/GameEngine/Include/Common/Team.h +++ b/Generals/Code/GameEngine/Include/Common/Team.h @@ -474,7 +474,7 @@ class Team : public MemoryPoolObject, a convenience routine used to estimate the team's position by just returning the position of the first member of the team */ - const Coord3D* getEstimateTeamPosition(void); + const Coord3D* getEstimateTeamPosition(void) const; /** a convenience routine to move a team's units to another team. diff --git a/Generals/Code/GameEngine/Include/Common/ThingFactory.h b/Generals/Code/GameEngine/Include/Common/ThingFactory.h index cb9f2c2fac..2dbf537a49 100644 --- a/Generals/Code/GameEngine/Include/Common/ThingFactory.h +++ b/Generals/Code/GameEngine/Include/Common/ThingFactory.h @@ -76,7 +76,7 @@ class ThingFactory : public SubsystemInterface get a template given template database name. return null if not found. note, this is now substantially faster (does a hash-table lookup) */ - const ThingTemplate *findTemplate( const AsciiString& name ) { return findTemplateInternal(name); } + const ThingTemplate *findTemplate( const AsciiString& name, Bool check = TRUE ) { return findTemplateInternal( name, check ); } /** get a template given ID. return null if not found. @@ -123,7 +123,7 @@ class ThingFactory : public SubsystemInterface NOTE: this is protected since it returns a NON-CONST template, and folks outside of the template system itself shouldn't get access... */ - ThingTemplate *findTemplateInternal( const AsciiString& name ); + ThingTemplate *findTemplateInternal( const AsciiString& name, Bool check = TRUE ); ThingTemplate *m_firstTemplate; ///< head of linked list UnsignedShort m_nextTemplateID; ///< next available ID for templates diff --git a/Generals/Code/GameEngine/Include/Common/ThingTemplate.h b/Generals/Code/GameEngine/Include/Common/ThingTemplate.h index d6ef1ee3f5..4de6697fb6 100644 --- a/Generals/Code/GameEngine/Include/Common/ThingTemplate.h +++ b/Generals/Code/GameEngine/Include/Common/ThingTemplate.h @@ -431,8 +431,8 @@ class ThingTemplate : public Overridable Bool isBridge() const { return m_isBridge; } // return fence offset // Only Object can ask this. Everyone else should ask the Object. In fact, you really should ask the Object everything. - Real friend_getVisionRange() const { return m_visionRange; } ///< get vision range - Real friend_getShroudClearingRange() const { return m_shroudClearingRange; } ///< get vision range for Shroud ONLY (Design requested split) + Real friend_calcVisionRange() const { return m_visionRange; } ///< get vision range + Real friend_calcShroudClearingRange() const { return m_shroudClearingRange; } ///< get vision range for Shroud ONLY (Design requested split) // This function is only for use by the AIUpdateModuleData::parseLocomotorSet function. AIUpdateModuleData *friend_getAIModuleInfo(void); diff --git a/Generals/Code/GameEngine/Include/Common/Xfer.h b/Generals/Code/GameEngine/Include/Common/Xfer.h index 7b0eabd307..cdfa7c0f16 100644 --- a/Generals/Code/GameEngine/Include/Common/Xfer.h +++ b/Generals/Code/GameEngine/Include/Common/Xfer.h @@ -43,7 +43,6 @@ #define __XFER_H_ // INCLUDES /////////////////////////////////////////////////////////////////////////////////////// -#include "Common/ModelState.h" #include "Common/Science.h" #include "Common/Upgrade.h" @@ -171,6 +170,7 @@ class Xfer virtual void xferRGBAColorInt( RGBAColorInt *rgbaColorInt ); virtual void xferObjectID( ObjectID *objectID ); virtual void xferDrawableID( DrawableID *drawableID ); + virtual void xferSTLObjectIDVector( std::vector *objectIDVectorData ); virtual void xferSTLObjectIDList( std::list< ObjectID > *objectIDListData ); virtual void xferSTLIntList( std::list< Int > *intListData ); virtual void xferScienceType( ScienceType *science ); diff --git a/Generals/Code/GameEngine/Include/Common/crc.h b/Generals/Code/GameEngine/Include/Common/crc.h index 8547351f09..855dc2d520 100644 --- a/Generals/Code/GameEngine/Include/Common/crc.h +++ b/Generals/Code/GameEngine/Include/Common/crc.h @@ -32,6 +32,9 @@ #define _CRC_H_ #include "Lib/BaseType.h" + +#ifdef _DEBUG + //#include "winsock2.h" // for htonl class CRC @@ -50,4 +53,77 @@ class CRC UnsignedInt crc; }; +#else + +// optimized inline only version +class CRC +{ +public: + CRC(void) { crc=0; } + + /// Compute the CRC for a buffer, added into current CRC + __forceinline void computeCRC( const void *buf, Int len ) + { + if (!buf||len<1) + return; + +#if !(defined(_MSC_VER) && _MSC_VER < 1300) + // C++ version left in for reference purposes + for (UnsignedByte *uintPtr=(UnsignedByte *)buf;len>0;len--,uintPtr++) + { + int hibit; + if (crc & 0x80000000) + { + hibit = 1; + } + else + { + hibit = 0; + } + + crc <<= 1; + crc += *uintPtr; + crc += hibit; + } +#else + // ASM version, verified by comparing resulting data with C++ version data + unsigned *crcPtr=&crc; + _asm + { + mov esi,[buf] + mov ecx,[len] + dec ecx + mov edi,[crcPtr] + mov ebx,dword ptr [edi] + xor eax,eax + lp: + mov al,byte ptr [esi] + shl ebx,1 + inc esi + adc ebx,eax + dec ecx + jns lp + mov dword ptr [edi],ebx + }; +#endif + } + + /// Clears the CRC to 0 + void clear( void ) + { + crc = 0; + } + + ///< Get the combined CRC + UnsignedInt get( void ) const + { + return crc; + } + +private: + UnsignedInt crc; +}; + +#endif + #endif // _CRC_H_ diff --git a/Generals/Code/GameEngine/Include/GameClient/Color.h b/Generals/Code/GameEngine/Include/GameClient/Color.h index 2c512e7986..94d952790c 100644 --- a/Generals/Code/GameEngine/Include/GameClient/Color.h +++ b/Generals/Code/GameEngine/Include/GameClient/Color.h @@ -76,6 +76,15 @@ extern void GameGetColorComponents( Color color, UnsignedByte *green, UnsignedByte *blue, UnsignedByte *alpha ); + +// Put on ice until later - M Lorenzen +//extern void GameGetColorComponentsWithCheatSpy( Color color, +// UnsignedByte *red, +// UnsignedByte *green, +// UnsignedByte *blue, +// UnsignedByte *alpha ); + + extern void GameGetColorComponentsReal( Color color, Real *red, Real *green, Real *blue, Real *alpha ); extern Color GameDarkenColor( Color color, Int percent = 10 ); diff --git a/Generals/Code/GameEngine/Include/GameClient/ControlBar.h b/Generals/Code/GameEngine/Include/GameClient/ControlBar.h index c25dd7fccf..7d2536c434 100644 --- a/Generals/Code/GameEngine/Include/GameClient/ControlBar.h +++ b/Generals/Code/GameEngine/Include/GameClient/ControlBar.h @@ -359,8 +359,11 @@ class CommandButton : public Overridable RadiusCursorType m_radiusCursor; ///< radius cursor, if any AsciiString m_cursorName; ///< cursor name for placement (NEED_TARGET_POS) or valid version (CONTEXTMODE_COMMAND) AsciiString m_invalidCursorName; ///< cursor name for invalid version - AsciiString m_textLabel; ///< string manager text label - AsciiString m_descriptionLabel; ///< The description of the current command, read in from the ini + + // bleah. shouldn't be mutable, but is. sue me. (Kris) -snork! + mutable AsciiString m_textLabel; ///< string manager text label + mutable AsciiString m_descriptionLabel; ///< The description of the current command, read in from the ini + AsciiString m_purchasedLabel; ///< Description for the current command if it has already been purchased. AsciiString m_conflictingLabel; ///< Description for the current command if it can't be selected due to multually-exclusive choice. WeaponSlotType m_weaponSlot; ///< for commands that refer to a weapon slot diff --git a/Generals/Code/GameEngine/Include/GameClient/Eva.h b/Generals/Code/GameEngine/Include/GameClient/Eva.h index ecf7c85276..1d2b1af36d 100644 --- a/Generals/Code/GameEngine/Include/GameClient/Eva.h +++ b/Generals/Code/GameEngine/Include/GameClient/Eva.h @@ -39,6 +39,8 @@ class Player; // Keep in sync with TheEvaMessageNames AND Eva::s_shouldPlayFuncs enum EvaMessage CPP_11(: Int) { + EVA_Invalid = -1, + EVA_FIRST = 0, EVA_LowPower = EVA_FIRST, EVA_InsufficientFunds, @@ -176,4 +178,4 @@ class Eva : public SubsystemInterface extern Eva *TheEva; -#endif /* __EVA_H__ */ \ No newline at end of file +#endif /* __EVA_H__ */ diff --git a/Generals/Code/GameEngine/Include/GameClient/GadgetCheckBox.h b/Generals/Code/GameEngine/Include/GameClient/GadgetCheckBox.h index 0545f14e47..f801752f62 100644 --- a/Generals/Code/GameEngine/Include/GameClient/GadgetCheckBox.h +++ b/Generals/Code/GameEngine/Include/GameClient/GadgetCheckBox.h @@ -80,6 +80,7 @@ extern void GadgetCheckBoxSetText( GameWindow *g, UnicodeString text ); extern Bool GadgetCheckBoxIsChecked( GameWindow *g ); extern void GadgetCheckBoxSetChecked( GameWindow *g, Bool isChecked); +extern void GadgetCheckBoxToggle( GameWindow *g); inline void GadgetCheckBoxSetEnabledImage( GameWindow *g, const Image *image ) { g->winSetEnabledImage( 0, image ); } inline void GadgetCheckBoxSetEnabledColor( GameWindow *g, Color color ) { g->winSetEnabledColor( 0, color ); } diff --git a/Generals/Code/GameEngine/Include/GameClient/GameWindow.h b/Generals/Code/GameEngine/Include/GameClient/GameWindow.h index e5c427436b..c1204631d5 100644 --- a/Generals/Code/GameEngine/Include/GameClient/GameWindow.h +++ b/Generals/Code/GameEngine/Include/GameClient/GameWindow.h @@ -248,6 +248,7 @@ friend class GameWindowManager; Int winBringToTop( void ); ///< bring this window to the top of the win list Int winEnable( Bool enable ); /**< enable/disable a window, a disbled window can be seen but accepts no input */ + Bool winGetEnabled( void ); ///< Is window enabled? Int winHide( Bool hide ); ///< hide/unhide a window Bool winIsHidden( void ); ///< is this window hidden/ UnsignedInt winSetStatus( UnsignedInt status ); ///< set status bits diff --git a/Generals/Code/GameEngine/Include/GameClient/InGameUI.h b/Generals/Code/GameEngine/Include/GameClient/InGameUI.h index 80c4a11a16..89390bea85 100644 --- a/Generals/Code/GameEngine/Include/GameClient/InGameUI.h +++ b/Generals/Code/GameEngine/Include/GameClient/InGameUI.h @@ -37,6 +37,7 @@ #include "Common/GameType.h" #include "Common/MessageStream.h" // for GameMessageTranslator #include "Common/SpecialPowerType.h" +#include "Common/Snapshot.h" #include "Common/STLTypedefs.h" #include "Common/SubsystemInterface.h" #include "Common/UnicodeString.h" @@ -44,7 +45,6 @@ #include "GameClient/Mouse.h" #include "GameClient/RadiusDecal.h" #include "GameClient/View.h" -#include "Common/Snapshot.h" // FORWARD DECLARATIONS /////////////////////////////////////////////////////////////////////////// class Drawable; diff --git a/Generals/Code/GameEngine/Include/GameClient/View.h b/Generals/Code/GameEngine/Include/GameClient/View.h index 474bd879af..a76a7542c0 100644 --- a/Generals/Code/GameEngine/Include/GameClient/View.h +++ b/Generals/Code/GameEngine/Include/GameClient/View.h @@ -83,6 +83,16 @@ class View : public Snapshot SHAKE_COUNT }; + // Return values for worldToScreenTriReturn + enum WorldToScreenReturn CPP_11(: Int) + { + WTS_INSIDE_FRUSTUM = 0, // On the screen (inside frustum of camera) + WTS_OUTSIDE_FRUSTUM, // Return is valid but off the screen (outside frustum of camera) + WTS_INVALID, // No transform possible + + WTS_COUNT + }; + public: View( void ); diff --git a/Generals/Code/GameEngine/Include/GameLogic/AI.h b/Generals/Code/GameEngine/Include/GameLogic/AI.h index 894f22b144..053cbe87bf 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/AI.h +++ b/Generals/Code/GameEngine/Include/GameLogic/AI.h @@ -307,7 +307,8 @@ class Weapon; // TheSuperHackers @compile xezon 22/03/2025 Renames AI_PASSIVE to not conflict with macro in ws2def.h // Note - written out in save/load xfer and .map files, don't change these numbers. -enum AttitudeType CPP_11(: Int) { +enum AttitudeType CPP_11(: Int) +{ ATTITUDE_SLEEP = -2, ATTITUDE_PASSIVE=-1, ATTITUDE_NORMAL=0, @@ -335,6 +336,7 @@ static const char *TheCommandSourceMaskNames[] = enum AICommandType CPP_11(: Int) // Stored in save file, do not reorder/renumber. jba. { + AICMD_NO_COMMAND = -1, AICMD_MOVE_TO_POSITION = 0, AICMD_MOVE_TO_OBJECT, AICMD_TIGHTEN_TO_POSITION, @@ -435,6 +437,7 @@ class AICommandParmsStorage void store(const AICommandParms& parms); void reconstitute(AICommandParms& parms) const; void doXfer(Xfer *xfer); + AICommandType getCommandType() const { return m_cmd; } }; /** diff --git a/Generals/Code/GameEngine/Include/GameLogic/Damage.h b/Generals/Code/GameEngine/Include/GameLogic/Damage.h index 5bbc50fd9b..088fa6adc8 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Damage.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Damage.h @@ -36,6 +36,7 @@ #include "Common/GameType.h" #include "Common/Snapshot.h" + // FORWARD REFERENCES ///////////////////////////////////////////////////////////////////////////// class Object; class INI; @@ -215,7 +216,6 @@ static const char *TheDeathNames[] = "DETONATED", "SPLATTED", "POISONED_BETA", - "EXTRA_2", "EXTRA_3", "EXTRA_4", diff --git a/Generals/Code/GameEngine/Include/GameLogic/GameLogic.h b/Generals/Code/GameEngine/Include/GameLogic/GameLogic.h index 1dbb89b655..b23b88bb7f 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/GameLogic.h +++ b/Generals/Code/GameEngine/Include/GameLogic/GameLogic.h @@ -68,6 +68,7 @@ class GhostObjectManager; class CommandButton; enum BuildableStatus CPP_11(: Int); + typedef const CommandButton* ConstCommandButtonPtr; // What kind of game we're in. @@ -88,6 +89,7 @@ enum CRC_RECALC }; + /// Function pointers for use by GameLogic callback functions. typedef void (*GameLogicFuncPtr)( Object *obj, void *userData ); typedef std::hash_map, rts::equal_to > ObjectPtrHash; diff --git a/Generals/Code/GameEngine/Include/GameLogic/Module/FireWeaponWhenDeadBehavior.h b/Generals/Code/GameEngine/Include/GameLogic/Module/FireWeaponWhenDeadBehavior.h index 6e217de962..965430994c 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Module/FireWeaponWhenDeadBehavior.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Module/FireWeaponWhenDeadBehavior.h @@ -33,6 +33,7 @@ #define __FireWeaponWhenDeadBehavior_H_ // INCLUDES /////////////////////////////////////////////////////////////////////////////////////// + #include "GameLogic/Module/BehaviorModule.h" #include "GameLogic/Module/DieModule.h" #include "GameLogic/Module/UpgradeModule.h" diff --git a/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h b/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h index ee61d39eb4..e146c61d10 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Module/JetAIUpdate.h @@ -103,6 +103,7 @@ class JetAIUpdate : public AIUpdateInterface virtual Bool isTemporarilyPreventingAimSuccess() const; virtual Bool isDoingGroundMovement() const; virtual void notifyVictimIsDead(); + virtual Bool isOutOfSpecialReloadAmmo() const; const Coord3D* friend_getProducerLocation() const { return &m_producerLocation; } Real friend_getOutOfAmmoDamagePerSecond() const { return getJetAIUpdateModuleData()->m_outOfAmmoDamagePerSecond; } @@ -172,8 +173,8 @@ class JetAIUpdate : public AIUpdateInterface void getProducerLocation(); void buildLockonDrawableIfNecessary(); void doLandingCommand(Object *airfield, CommandSourceType cmdSource); - inline Bool getFlag(FlagType f) const { return (m_flags & (1< getQMMaps(void) = 0; @@ -73,7 +73,6 @@ class GameSpyConfigInterface // Custom match virtual Bool restrictGamesToLobby() = 0; - static GameSpyConfigInterface* create(AsciiString config); }; diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PeerDefsImplementation.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PeerDefsImplementation.h index f086b48b93..d4c0d83f7e 100644 --- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PeerDefsImplementation.h +++ b/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PeerDefsImplementation.h @@ -64,7 +64,6 @@ class GameSpyInfo : public GameSpyInfoInterface virtual void setLocalPassword( AsciiString passwd ) { m_localPasswd = passwd; } virtual void setLocalBaseName( AsciiString name ) { m_localBaseName = name; } virtual AsciiString getLocalBaseName( void ){ return m_localBaseName; } - virtual void setCachedLocalPlayerStats( PSPlayerStats stats ) {m_cachedLocalPlayerStats = stats; } virtual PSPlayerStats getCachedLocalPlayerStats( void ){ return m_cachedLocalPlayerStats; } @@ -177,7 +176,6 @@ class GameSpyInfo : public GameSpyInfoInterface std::set m_textWindows; std::set m_preorderPlayers; - Int m_additionalDisconnects; }; diff --git a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PersistentStorageThread.h b/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PersistentStorageThread.h index 430f5e0cd7..01fcc98242 100644 --- a/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PersistentStorageThread.h +++ b/Generals/Code/GameEngine/Include/GameNetwork/GameSpy/PersistentStorageThread.h @@ -47,7 +47,7 @@ class PSPlayerStats Int id; PerGeneralMap wins; PerGeneralMap losses; - PerGeneralMap games; + PerGeneralMap games; //first: playerTemplate #, second: #games played (see also gamesAsRandom) PerGeneralMap duration; PerGeneralMap unitsKilled; PerGeneralMap unitsLost; diff --git a/Generals/Code/GameEngine/Include/GameNetwork/networkutil.h b/Generals/Code/GameEngine/Include/GameNetwork/networkutil.h index 760a6f640a..9272705623 100644 --- a/Generals/Code/GameEngine/Include/GameNetwork/networkutil.h +++ b/Generals/Code/GameEngine/Include/GameNetwork/networkutil.h @@ -39,7 +39,9 @@ Bool IsCommandSynchronized(NetCommandType type); AsciiString GetAsciiNetCommandType(NetCommandType type); #ifdef DEBUG_LOGGING +extern "C" { void dumpBufferToLog(const void *vBuf, Int len, const char *fname, Int line); +}; #define LOGBUFFER(buf, len) dumpBufferToLog(buf, len, __FILE__, __LINE__) #else #define LOGBUFFER(buf, len) {} diff --git a/Generals/Code/GameEngine/Include/Precompiled/PreRTS.h b/Generals/Code/GameEngine/Include/Precompiled/PreRTS.h index fe5bfde473..1a03c5d049 100644 --- a/Generals/Code/GameEngine/Include/Precompiled/PreRTS.h +++ b/Generals/Code/GameEngine/Include/Precompiled/PreRTS.h @@ -123,6 +123,7 @@ class STLSpecialAlloc; #include "Common/NameKeyGenerator.h" #include "GameClient/ClientRandomValue.h" #include "GameLogic/LogicRandomValue.h" +#include "Common/ObjectStatusTypes.h" #include "Common/Thing.h" #include "Common/UnicodeString.h" diff --git a/Generals/Code/GameEngine/Source/Common/Audio/GameMusic.cpp b/Generals/Code/GameEngine/Source/Common/Audio/GameMusic.cpp index 28159bff6d..7f6abd3a66 100644 --- a/Generals/Code/GameEngine/Source/Common/Audio/GameMusic.cpp +++ b/Generals/Code/GameEngine/Source/Common/Audio/GameMusic.cpp @@ -52,6 +52,11 @@ #include "Common/GameAudio.h" #include "Common/INI.h" +#ifdef _INTERNAL +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif + //---------------------------------------------------------------------------- // Externals //---------------------------------------------------------------------------- diff --git a/Generals/Code/GameEngine/Source/Common/INI/INIMapCache.cpp b/Generals/Code/GameEngine/Source/Common/INI/INIMapCache.cpp index f294a5b0bc..557a220fd3 100644 --- a/Generals/Code/GameEngine/Source/Common/INI/INIMapCache.cpp +++ b/Generals/Code/GameEngine/Source/Common/INI/INIMapCache.cpp @@ -38,6 +38,12 @@ #include "Common/WellKnownKeys.h" #include "Common/QuotedPrintable.h" +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif + class MapMetaDataReader { public: diff --git a/Generals/Code/GameEngine/Source/Common/MessageStream.cpp b/Generals/Code/GameEngine/Source/Common/MessageStream.cpp index f1dcfecb07..729dd40000 100644 --- a/Generals/Code/GameEngine/Source/Common/MessageStream.cpp +++ b/Generals/Code/GameEngine/Source/Common/MessageStream.cpp @@ -41,6 +41,15 @@ MessageStream *TheMessageStream = NULL; CommandList *TheCommandList = NULL; + +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif + + + //------------------------------------------------------------------------------------------------ // GameMessage // diff --git a/Generals/Code/GameEngine/Source/Common/MultiplayerSettings.cpp b/Generals/Code/GameEngine/Source/Common/MultiplayerSettings.cpp index d13d8f2180..7065d5f209 100644 --- a/Generals/Code/GameEngine/Source/Common/MultiplayerSettings.cpp +++ b/Generals/Code/GameEngine/Source/Common/MultiplayerSettings.cpp @@ -166,3 +166,4 @@ void MultiplayerColorDefinition::setNightColor( RGBColor rgb ) { m_colorNight = rgb.getAsInt() | 0xFF << 24; } + diff --git a/Generals/Code/GameEngine/Source/Common/NameKeyGenerator.cpp b/Generals/Code/GameEngine/Source/Common/NameKeyGenerator.cpp index dca57a0e6f..506b55714a 100644 --- a/Generals/Code/GameEngine/Source/Common/NameKeyGenerator.cpp +++ b/Generals/Code/GameEngine/Source/Common/NameKeyGenerator.cpp @@ -98,6 +98,16 @@ inline UnsignedInt calcHashForString(const char* p) return result; } +/* ------------------------------------------------------------------------ */ +inline UnsignedInt calcHashForLowercaseString(const char* p) +{ + UnsignedInt result = 0; + Byte *pp = (Byte*)p; + while (*pp) + result = (result << 5) + result + tolower(*pp++); + return result; +} + //------------------------------------------------------------------------------------------------- AsciiString NameKeyGenerator::keyToName(NameKeyType key) { @@ -160,6 +170,63 @@ NameKeyType NameKeyGenerator::nameToKey(const char* nameString) } // end nameToKey +//------------------------------------------------------------------------------------------------- +NameKeyType NameKeyGenerator::nameToLowercaseKey(const char* nameString) +{ + Bucket *b; + + UnsignedInt hash = calcHashForLowercaseString(nameString) % SOCKET_COUNT; + + // hmm, do we have it already? + for (b = m_sockets[hash]; b; b = b->m_nextInSocket) + { + if (_stricmp(nameString, b->m_nameString.str()) == 0) + return b->m_key; + } + + // nope, guess not. let's allocate it. + b = newInstance(Bucket); + b->m_key = (NameKeyType)m_nextID++; + b->m_nameString = nameString; + b->m_nextInSocket = m_sockets[hash]; + m_sockets[hash] = b; + + NameKeyType result = b->m_key; + +#if defined(_DEBUG) || defined(_INTERNAL) + // reality-check to be sure our hasher isn't going bad. + const Int maxThresh = 3; + Int numOverThresh = 0; + for (Int i = 0; i < SOCKET_COUNT; ++i) + { + Int numInThisSocket = 0; + for (b = m_sockets[i]; b; b = b->m_nextInSocket) + ++numInThisSocket; + + if (numInThisSocket > maxThresh) + ++numOverThresh; + } + + // if more than a small percent of the sockets are getting deep, probably want to increase the socket count. + if (numOverThresh > SOCKET_COUNT/20) + { + DEBUG_CRASH(("hmm, might need to increase the number of bucket-sockets for NameKeyGenerator (numOverThresh %d = %f%%)\n",numOverThresh,(Real)numOverThresh/(Real)(SOCKET_COUNT/20))); + } +#endif + + return result; + +} // end nameToLowercaseKey + +//------------------------------------------------------------------------------------------------- +// Get a string out of the INI. Store it into a NameKeyType +//------------------------------------------------------------------------------------------------- +void NameKeyGenerator::parseStringAsNameKeyType( INI *ini, void *instance, void *store, const void* userData ) +{ + *(NameKeyType *)store = TheNameKeyGenerator->nameToKey( ini->getNextToken() ); +} + + //------------------------------------------------------------------------------------------------- NameKeyType StaticNameKey::key() const { diff --git a/Generals/Code/GameEngine/Source/Common/RTS/Energy.cpp b/Generals/Code/GameEngine/Source/Common/RTS/Energy.cpp index bacf681997..d089c2dd2b 100644 --- a/Generals/Code/GameEngine/Source/Common/RTS/Energy.cpp +++ b/Generals/Code/GameEngine/Source/Common/RTS/Energy.cpp @@ -51,6 +51,26 @@ #include "Common/Xfer.h" #include "GameLogic/Object.h" +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif + +//----------------------------------------------------------------------------- +Energy::Energy() +{ + m_energyProduction = 0; + m_energyConsumption = 0; + m_owner = NULL; +} + +//----------------------------------------------------------------------------- +Int Energy::getProduction() const +{ + return m_energyProduction; +} + //----------------------------------------------------------------------------- Real Energy::getEnergySupplyRatio() const { diff --git a/Generals/Code/GameEngine/Source/Common/RTS/Player.cpp b/Generals/Code/GameEngine/Source/Common/RTS/Player.cpp index 744532f99a..d5c0936238 100644 --- a/Generals/Code/GameEngine/Source/Common/RTS/Player.cpp +++ b/Generals/Code/GameEngine/Source/Common/RTS/Player.cpp @@ -433,6 +433,9 @@ void Player::init(const PlayerTemplate* pt) #if defined(_DEBUG) || defined(_INTERNAL) m_DEMO_ignorePrereqs = FALSE; m_DEMO_freeBuild = FALSE; +#endif + +#if defined(_DEBUG) || defined(_INTERNAL) || defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE) m_DEMO_instantBuild = FALSE; #endif @@ -686,14 +689,15 @@ void Player::update() m_ai->update(); // Allow the teams this player owns to update themselves. - - for (PlayerTeamList::iterator it = m_playerTeamPrototypes.begin(); it != m_playerTeamPrototypes.end(); ++it) { - for (DLINK_ITERATOR iter = (*it)->iterate_TeamInstanceList(); !iter.done(); iter.advance()) { + for( PlayerTeamList::iterator it = m_playerTeamPrototypes.begin(); it != m_playerTeamPrototypes.end(); ++it ) + { + for( DLINK_ITERATOR iter = (*it)->iterate_TeamInstanceList(); !iter.done(); iter.advance() ) + { Team *team = iter.cur(); - if (!team) { + if( !team ) + { continue; } - team->updateGenericScripts(); } } @@ -859,14 +863,17 @@ void Player::initFromDict(const Dict* d) } Int diffInt = d->getInt(TheKey_skirmishDifficulty, &exists); GameDifficulty difficulty = TheScriptEngine->getGlobalDifficulty(); - if (exists) { + if (exists) + { difficulty = (GameDifficulty) diffInt; } - if (m_ai) { + if (m_ai) + { m_ai->setAIDifficulty(difficulty); } - if (!found) { + if (!found) + { DEBUG_CRASH(("Could not find skirmish player for side %s", mySide.str())); } else { m_playerName = qualTemplatePlayerName; @@ -3882,11 +3889,6 @@ void Player::xfer( Xfer *xfer ) // score keeper xfer->xferSnapshot( &m_scoreKeeper ); - - - - - // size of and data for kindof percent production change list UnsignedShort percentProductionChangeCount = m_kindOfPercentProductionChangeList.size(); xfer->xferUnsignedShort( &percentProductionChangeCount ); diff --git a/Generals/Code/GameEngine/Source/Common/RTS/ProductionPrerequisite.cpp b/Generals/Code/GameEngine/Source/Common/RTS/ProductionPrerequisite.cpp index ba54998549..d98bd28d3f 100644 --- a/Generals/Code/GameEngine/Source/Common/RTS/ProductionPrerequisite.cpp +++ b/Generals/Code/GameEngine/Source/Common/RTS/ProductionPrerequisite.cpp @@ -88,14 +88,17 @@ void ProductionPrerequisite::resolveNames() // sub-temlates), which is what we want ... we conceptually only have one // template for any given thing, it's only the *data* that is overridden // - m_prereqUnits[i].unit = TheThingFactory->findTemplate(m_prereqUnits[i].name); // might be null - - /** @todo for now removing this assert until we can completely remove - the GDF stuff, the problem is that some INI files refer to GDF names, and they - aren't yet loaded in the world builder but will all go away later anyway etc */ - DEBUG_ASSERTCRASH(m_prereqUnits[i].unit,("could not find prereq %s\n",m_prereqUnits[i].name.str())); - - m_prereqUnits[i].name.clear(); // we're done with it + if( m_prereqUnits[ i ].name.isNotEmpty() ) + { + m_prereqUnits[i].unit = TheThingFactory->findTemplate(m_prereqUnits[i].name); // might be null + + /** @todo for now removing this assert until we can completely remove + the GDF stuff, the problem is that some INI files refer to GDF names, and they + aren't yet loaded in the world builder but will all go away later anyway etc */ + DEBUG_ASSERTCRASH(m_prereqUnits[i].unit,("could not find prereq %s\n",m_prereqUnits[i].name.str())); + + m_prereqUnits[i].name.clear(); // we're done with it + } } diff --git a/Generals/Code/GameEngine/Source/Common/RTS/Team.cpp b/Generals/Code/GameEngine/Source/Common/RTS/Team.cpp index d0ffe86afa..bf41bc1e06 100644 --- a/Generals/Code/GameEngine/Source/Common/RTS/Team.cpp +++ b/Generals/Code/GameEngine/Source/Common/RTS/Team.cpp @@ -2221,7 +2221,7 @@ Bool Team::someInsideSomeOutside(PolygonTrigger *pTrigger, UnsignedInt whichToCo return anyConsidered && anyInside && anyOutside; } -const Coord3D* Team::getEstimateTeamPosition(void) +const Coord3D* Team::getEstimateTeamPosition(void) const { // this doesn't actually calculate the team position, but rather estimates it by // returning the position of the first member of the team diff --git a/Generals/Code/GameEngine/Source/Common/Recorder.cpp b/Generals/Code/GameEngine/Source/Common/Recorder.cpp index e7e2c12f0c..d2d12bee90 100644 --- a/Generals/Code/GameEngine/Source/Common/Recorder.cpp +++ b/Generals/Code/GameEngine/Source/Common/Recorder.cpp @@ -1022,6 +1022,7 @@ void RecorderClass::handleCRCMessage(UnsignedInt newCRC, Int playerIndex, Bool f { m_crcInfo->setSawCRCMismatch(); + //Kris: Patch 1.01 November 10, 2003 (integrated changes from Matt Campbell) // Since we don't seem to have any *visible* desyncs when replaying games, but get this warning // virtually every replay, the assumption is our CRC checking is faulty. Since we're at the // tail end of patch season, let's just disable the message, and hope the users believe the diff --git a/Generals/Code/GameEngine/Source/Common/System/BuildAssistant.cpp b/Generals/Code/GameEngine/Source/Common/System/BuildAssistant.cpp index 9024ae88d5..340aaa251f 100644 --- a/Generals/Code/GameEngine/Source/Common/System/BuildAssistant.cpp +++ b/Generals/Code/GameEngine/Source/Common/System/BuildAssistant.cpp @@ -351,7 +351,7 @@ Object *BuildAssistant::buildObjectNow( Object *constructorObject, const ThingTe // Need to validate that we can make this in case someone fakes their CommandSet // A Null constructorObject is used by the script engine to cheat, so let it slide - if( constructorObject && !isPossibleToMakeUnit(constructorObject, what) ) + if( (constructorObject != NULL) && !isPossibleToMakeUnit(constructorObject, what) ) return NULL; // clear out any objects from the building area that are "auto-clearable" when building @@ -694,8 +694,10 @@ Bool BuildAssistant::isLocationClearOfObjects( const Coord3D *worldPos, continue; // an immobile object may obstruct our building depending on flags. - if( them->isKindOf( KINDOF_IMMOBILE ) ) { - if (onlyCheckEnemies && builderObject && builderObject->getRelationship( them ) != ENEMIES ) { + if( them->isKindOf( KINDOF_IMMOBILE ) ) + { + if (onlyCheckEnemies && builderObject && builderObject->getRelationship( them ) != ENEMIES ) + { continue; } TheTerrainVisual->addFactionBib(them, true); @@ -706,14 +708,16 @@ Bool BuildAssistant::isLocationClearOfObjects( const Coord3D *worldPos, // if this is an enemy object of the builder object (and therefore the thing // that will be constructed) we can't build here // - if( builderObject && builderObject->getRelationship( them ) == ENEMIES ) { + if( builderObject && builderObject->getRelationship( them ) == ENEMIES ) + { TheTerrainVisual->addFactionBib(them, true); return false; } } // end for, them - if (onlyCheckEnemies) { + if (onlyCheckEnemies) + { return true; } // Check for overlapping exit areas. @@ -893,7 +897,6 @@ LegalBuildCode BuildAssistant::isLocationLegalToBuild( const Coord3D *worldPos, { return LBC_OBJECTS_IN_THE_WAY; } - } // end if if (build->isKindOf(KINDOF_CANNOT_BUILD_NEAR_SUPPLIES) && TheGlobalData->m_SupplyBuildBorder > 0) @@ -1021,7 +1024,7 @@ void BuildAssistant::addBibs(const Coord3D *worldPos, const ThingTemplate *build ) { - Real range = build->friend_getVisionRange(); + Real range = build->friend_calcVisionRange(); range += 3*build->getTemplateGeometryInfo().getMajorRadius(); PartitionFilterAcceptByKindOf f1(MAKE_KINDOF_MASK(KINDOF_STRUCTURE), KINDOFMASK_NONE); diff --git a/Generals/Code/GameEngine/Source/Common/System/Debug.cpp b/Generals/Code/GameEngine/Source/Common/System/Debug.cpp index e9fbf6ddb5..d54319842e 100644 --- a/Generals/Code/GameEngine/Source/Common/System/Debug.cpp +++ b/Generals/Code/GameEngine/Source/Common/System/Debug.cpp @@ -66,7 +66,9 @@ #include "GameClient/GameText.h" #include "GameClient/Keyboard.h" #include "GameClient/Mouse.h" -#include "Common/StackDump.h" +#if defined(DEBUG_STACKTRACE) || defined(IG_DEBUG_STACKTRACE) + #include "Common/StackDump.h" +#endif // Horrible reference, but we really, really need to know if we are windowed. extern bool DX8Wrapper_IsWindowed; @@ -264,8 +266,8 @@ static int doCrashBox(const char *buffer, Bool logResult) int result; if (!ignoringAsserts()) { + result = MessageBoxWrapper(buffer, "Assertion Failure", MB_ABORTRETRYIGNORE|MB_TASKMODAL|MB_ICONWARNING|MB_DEFBUTTON3); //result = MessageBoxWrapper(buffer, "Assertion Failure", MB_ABORTRETRYIGNORE|MB_TASKMODAL|MB_ICONWARNING|MB_DEFBUTTON3); - result = MessageBoxWrapper(buffer, "Assertion Failure", MB_ABORTRETRYIGNORE|MB_TASKMODAL|MB_ICONWARNING); } else { result = IDIGNORE; } diff --git a/Generals/Code/GameEngine/Source/Common/System/FileSystem.cpp b/Generals/Code/GameEngine/Source/Common/System/FileSystem.cpp index 6d8e433b92..c2a1b9646e 100644 --- a/Generals/Code/GameEngine/Source/Common/System/FileSystem.cpp +++ b/Generals/Code/GameEngine/Source/Common/System/FileSystem.cpp @@ -196,12 +196,24 @@ File* FileSystem::openFile( const Char *filename, Int access ) Bool FileSystem::doesFileExist(const Char *filename) const { USE_PERF_TIMER(FileSystem) - if (TheLocalFileSystem->doesFileExist(filename)) { + + unsigned key=TheNameKeyGenerator->nameToLowercaseKey(filename); + std::map::iterator i=m_fileExist.find(key); + if (i!=m_fileExist.end()) + return i->second; + + if (TheLocalFileSystem->doesFileExist(filename)) + { + m_fileExist[key]=true; return TRUE; } - if (TheArchiveFileSystem->doesFileExist(filename)) { + if (TheArchiveFileSystem->doesFileExist(filename)) + { + m_fileExist[key]=true; return TRUE; } + + m_fileExist[key]=false; return FALSE; } diff --git a/Generals/Code/GameEngine/Source/Common/System/GameMemory.cpp b/Generals/Code/GameEngine/Source/Common/System/GameMemory.cpp index 6ac1cb3624..adcc16177c 100644 --- a/Generals/Code/GameEngine/Source/Common/System/GameMemory.cpp +++ b/Generals/Code/GameEngine/Source/Common/System/GameMemory.cpp @@ -80,7 +80,9 @@ DECLARE_PERF_TIMER(MemoryPoolInitFilling) faster to free raw DMA blocks. @todo verify this speedup is enough to be worth the extra space */ -#define MPSB_DLINK +#ifndef DISABLE_MEMORYPOOL_MPSB_DLINK + #define MPSB_DLINK +#endif #ifdef MEMORYPOOL_DEBUG @@ -902,9 +904,11 @@ void MemoryPoolSingleBlock::initBlock(Int logicalSize, MemoryPoolBlob *owningBlo #endif } #endif // MEMORYPOOL_DEBUG + #ifdef MEMORYPOOL_CHECKPOINTING m_checkpointInfo = NULL; #endif + #ifdef MEMORYPOOL_BOUNDINGWALL m_wallPattern = theBoundingWallPattern++; debugFillInWalls(); diff --git a/Generals/Code/GameEngine/Source/Common/System/Radar.cpp b/Generals/Code/GameEngine/Source/Common/System/Radar.cpp index c34bc3903b..e04c287467 100644 --- a/Generals/Code/GameEngine/Source/Common/System/Radar.cpp +++ b/Generals/Code/GameEngine/Source/Common/System/Radar.cpp @@ -618,7 +618,7 @@ void Radar::removeObject( Object *obj ) * Return TRUE if the radar points translates to a valid world position * Return FALSE if the radar point is not a valid world position */ //------------------------------------------------------------------------------------------------- -Bool Radar::radarToWorld( const ICoord2D *radar, Coord3D *world ) +Bool Radar::radarToWorld2D( const ICoord2D *radar, Coord3D *world ) { Int x, y; @@ -643,6 +643,19 @@ Bool Radar::radarToWorld( const ICoord2D *radar, Coord3D *world ) // translate to world world->x = x * m_xSample; world->y = y * m_ySample; + return TRUE; +} + +//------------------------------------------------------------------------------------------------- +/** Translate a 2D spot on the radar (from (0,0) to (RADAR_CELL_WIDTH,RADAR_CELL_HEIGHT) + * to a 3D spot in the world on the terrain + * Return TRUE if the radar points translates to a valid world position + * Return FALSE if the radar point is not a valid world position */ +//------------------------------------------------------------------------------------------------- +Bool Radar::radarToWorld( const ICoord2D *radar, Coord3D *world ) +{ + if (!radarToWorld2D(radar,world)) + return FALSE; // find the terrain height here world->z = TheTerrainLogic->getGroundHeight( world->x, world->y ); @@ -1241,8 +1254,15 @@ void Radar::tryUnderAttackEvent( const Object *obj ) // ------------------------------------------------------------------------------------------------ void Radar::tryInfiltrationEvent( const Object *obj ) { + + //Sanity! + if( !obj ) + { + return; + } + // We should only be warned against infiltrations that are taking place against us. - if (obj->getControllingPlayer() != ThePlayerList->getLocalPlayer()) + if( obj->getControllingPlayer() != ThePlayerList->getLocalPlayer() ) return; // create the radar event diff --git a/Generals/Code/GameEngine/Source/Common/System/SaveGame/GameStateMap.cpp b/Generals/Code/GameEngine/Source/Common/System/SaveGame/GameStateMap.cpp index 0625d7e74b..88188bc18f 100644 --- a/Generals/Code/GameEngine/Source/Common/System/SaveGame/GameStateMap.cpp +++ b/Generals/Code/GameEngine/Source/Common/System/SaveGame/GameStateMap.cpp @@ -29,6 +29,7 @@ // INCLUDES /////////////////////////////////////////////////////////////////////////////////////// #include "PreRTS.h" + #include "Common/file.h" #include "Common/FileSystem.h" #include "Common/GameState.h" @@ -410,16 +411,22 @@ void GameStateMap::xfer( Xfer *xfer ) xfer->xferDrawableID( &highDrawableID ); TheGameClient->setDrawableIDCounter( highDrawableID ); - if (TheGameLogic->getGameMode()==GAME_SKIRMISH) { - if (TheSkirmishGameInfo==NULL) { + // Save the Game Info so the game can be started with the correct players on load + if( TheGameLogic->getGameMode()==GAME_SKIRMISH ) + { + if( TheSkirmishGameInfo==NULL ) + { TheSkirmishGameInfo = NEW SkirmishGameInfo; TheSkirmishGameInfo->init(); TheSkirmishGameInfo->clearSlotList(); TheSkirmishGameInfo->reset(); } xfer->xferSnapshot(TheSkirmishGameInfo); - } else { - if (TheSkirmishGameInfo) { + } + else + { + if( TheSkirmishGameInfo ) + { delete TheSkirmishGameInfo; TheSkirmishGameInfo = NULL; } @@ -430,7 +437,8 @@ void GameStateMap::xfer( Xfer *xfer ) // things in the map file that don't don't change (terrain, triggers, teams, script // definitions) etc // - if( xfer->getXferMode() == XFER_LOAD ) { + if( xfer->getXferMode() == XFER_LOAD ) + { TheGameLogic->startNewGame( TRUE ); } diff --git a/Generals/Code/GameEngine/Source/Common/System/StackDump.cpp b/Generals/Code/GameEngine/Source/Common/System/StackDump.cpp index 1450537656..9c29e51879 100644 --- a/Generals/Code/GameEngine/Source/Common/System/StackDump.cpp +++ b/Generals/Code/GameEngine/Source/Common/System/StackDump.cpp @@ -469,6 +469,7 @@ void WriteStackLine(void*address, void (*callback)(const char*)) callback("\n"); } + //***************************************************************************** //***************************************************************************** void DumpExceptionInfo( unsigned int u, EXCEPTION_POINTERS* e_info ) diff --git a/Generals/Code/GameEngine/Source/Common/System/Upgrade.cpp b/Generals/Code/GameEngine/Source/Common/System/Upgrade.cpp index 9a93b83749..05738f4cc3 100644 --- a/Generals/Code/GameEngine/Source/Common/System/Upgrade.cpp +++ b/Generals/Code/GameEngine/Source/Common/System/Upgrade.cpp @@ -155,7 +155,7 @@ UpgradeTemplate::~UpgradeTemplate( void ) //------------------------------------------------------------------------------------------------- Int UpgradeTemplate::calcTimeToBuild( Player *player ) const { -#if defined(_DEBUG) || defined(_INTERNAL) +#if defined(_DEBUG) || defined(_INTERNAL) || defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE) if( player->buildsInstantly() ) { return 1; diff --git a/Generals/Code/GameEngine/Source/Common/System/Xfer.cpp b/Generals/Code/GameEngine/Source/Common/System/Xfer.cpp index 355ae8c402..c14d682e9d 100644 --- a/Generals/Code/GameEngine/Source/Common/System/Xfer.cpp +++ b/Generals/Code/GameEngine/Source/Common/System/Xfer.cpp @@ -364,6 +364,69 @@ void Xfer::xferDrawableID( DrawableID *drawableID ) } // end xferDrawableID + +// ------------------------------------------------------------------------------------------------ +void Xfer::xferSTLObjectIDVector( std::vector *objectIDVectorData ) +{ + // + // the fact that this is a list and a little higher level than a simple data type + // is reason enough to have every one of these versioned + // + XferVersion currentVersion = 1; + XferVersion version = currentVersion; + xferVersion( &version, currentVersion ); + + // xfer the count of the vector + UnsignedShort listCount = objectIDVectorData->size(); + xferUnsignedShort( &listCount ); + + // xfer vector data + ObjectID objectID; + if( getXferMode() == XFER_SAVE || getXferMode() == XFER_CRC ) + { + + // save all ids + std::vector< ObjectID >::const_iterator it; + for( it = objectIDVectorData->begin(); it != objectIDVectorData->end(); ++it ) + { + + objectID = *it; + xferObjectID( &objectID ); + + } // end for + + } // end if, save + else if( getXferMode() == XFER_LOAD ) + { + + // sanity, the list should be empty before we transfer more data into it + if( objectIDVectorData->size() != 0 ) + { + + DEBUG_CRASH(( "Xfer::xferSTLObjectIDList - object vector should be empty before loading\n" )); + throw XFER_LIST_NOT_EMPTY; + + } // end if + + // read all ids + for( UnsignedShort i = 0; i < listCount; ++i ) + { + + xferObjectID( &objectID ); + objectIDVectorData->push_back( objectID ); + + } // end for, i + + } // end else if + else + { + + DEBUG_CRASH(( "xferSTLObjectIDList - Unknown xfer mode '%d'\n", getXferMode() )); + throw XFER_MODE_UNKNOWN; + + } // end else +} + // ------------------------------------------------------------------------------------------------ /** STL Object ID list (cause it's a common data structure we use a lot) * Version Info; diff --git a/Generals/Code/GameEngine/Source/Common/System/registry.cpp b/Generals/Code/GameEngine/Source/Common/System/registry.cpp index 8e016558c4..21e4dccd80 100644 --- a/Generals/Code/GameEngine/Source/Common/System/registry.cpp +++ b/Generals/Code/GameEngine/Source/Common/System/registry.cpp @@ -151,6 +151,7 @@ Bool GetUnsignedIntFromRegistry(AsciiString path, AsciiString key, UnsignedInt& AsciiString GetRegistryLanguage(void) { static Bool cached = FALSE; + // NOTE: static causes a memory leak, but we have to keep it because the value is cached. static AsciiString val = "english"; if (cached) { return val; diff --git a/Generals/Code/GameEngine/Source/Common/Thing/Module.cpp b/Generals/Code/GameEngine/Source/Common/Thing/Module.cpp index d77464a884..8d39fde10f 100644 --- a/Generals/Code/GameEngine/Source/Common/Thing/Module.cpp +++ b/Generals/Code/GameEngine/Source/Common/Thing/Module.cpp @@ -47,6 +47,12 @@ #include "GameLogic/Module/UpdateModule.h" #include "GameLogic/Module/UpgradeModule.h" +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma message("************************************** WARNING, optimization disabled for debugging purposes") +#endif + /////////////////////////////////////////////////////////////////////////////////////////////////// // PUBLIC FUNCTIONS /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Generals/Code/GameEngine/Source/Common/Thing/ModuleFactory.cpp b/Generals/Code/GameEngine/Source/Common/Thing/ModuleFactory.cpp index 5804c7fe41..1ddf9a7f71 100644 --- a/Generals/Code/GameEngine/Source/Common/Thing/ModuleFactory.cpp +++ b/Generals/Code/GameEngine/Source/Common/Thing/ModuleFactory.cpp @@ -57,8 +57,8 @@ #include "GameLogic/Module/OverchargeBehavior.h" #include "GameLogic/Module/HealContain.h" #include "GameLogic/Module/GarrisonContain.h" -#include "GameLogic/Module/TransportContain.h" #include "GameLogic/Module/RailedTransportContain.h" +#include "GameLogic/Module/TransportContain.h" #include "GameLogic/Module/MobNexusContain.h" #include "GameLogic/Module/TunnelContain.h" #include "GameLogic/Module/OverlordContain.h" @@ -214,14 +214,14 @@ #include "GameLogic/Module/FireWeaponCollide.h" #include "GameLogic/Module/SquishCollide.h" +#include "GameLogic/Module/ConvertToCarBombCrateCollide.h" +#include "GameLogic/Module/ConvertToHijackedVehicleCrateCollide.h" #include "GameLogic/Module/HealCrateCollide.h" #include "GameLogic/Module/MoneyCrateCollide.h" +#include "GameLogic/Module/SalvageCrateCollide.h" #include "GameLogic/Module/ShroudCrateCollide.h" #include "GameLogic/Module/UnitCrateCollide.h" #include "GameLogic/Module/VeterancyCrateCollide.h" -#include "GameLogic/Module/ConvertToCarBombCrateCollide.h" -#include "GameLogic/Module/ConvertToHijackedVehicleCrateCollide.h" -#include "GameLogic/Module/SalvageCrateCollide.h" // body includes #include "GameLogic/Module/InactiveBody.h" diff --git a/Generals/Code/GameEngine/Source/Common/Thing/ThingFactory.cpp b/Generals/Code/GameEngine/Source/Common/Thing/ThingFactory.cpp index 64572047cf..4d0d34121b 100644 --- a/Generals/Code/GameEngine/Source/Common/Thing/ThingFactory.cpp +++ b/Generals/Code/GameEngine/Source/Common/Thing/ThingFactory.cpp @@ -139,7 +139,7 @@ ThingTemplate *ThingFactory::newTemplate( const AsciiString& name ) newTemplate = newInstance(ThingTemplate); // if the default template is present, get it and copy over any data to the new template - const ThingTemplate *defaultT = findTemplate( AsciiString( "DefaultThingTemplate" ) ); + const ThingTemplate *defaultT = findTemplate( AsciiString( "DefaultThingTemplate" ), FALSE ); if( defaultT ) { @@ -270,7 +270,7 @@ const ThingTemplate *ThingFactory::findByTemplateID( UnsignedShort id ) //------------------------------------------------------------------------------------------------- /** Return the template with the matching database name */ //------------------------------------------------------------------------------------------------- -ThingTemplate *ThingFactory::findTemplateInternal( const AsciiString& name ) +ThingTemplate *ThingFactory::findTemplateInternal( const AsciiString& name, Bool check ) { ThingTemplateHashMapIt tIt = m_templateHashMap.find(name); @@ -297,7 +297,10 @@ ThingTemplate *ThingFactory::findTemplateInternal( const AsciiString& name ) #endif - //DEBUG_LOG(("*** Object template %s not found\n",name.str())); + if( check && name.isNotEmpty() ) + { + DEBUG_CRASH( ("Failed to find thing template %s (case sensitive) This issue has a chance of crashing after you ignore it!", name.str() ) ); + } return NULL; } // end getTemplate @@ -377,7 +380,7 @@ AsciiString TheThingTemplateBeingParsedName; #endif // find existing item if present - ThingTemplate *thingTemplate = TheThingFactory->findTemplateInternal( name ); + ThingTemplate *thingTemplate = TheThingFactory->findTemplateInternal( name, FALSE ); if( !thingTemplate ) { // no item is present, create a new one diff --git a/Generals/Code/GameEngine/Source/Common/Thing/ThingTemplate.cpp b/Generals/Code/GameEngine/Source/Common/Thing/ThingTemplate.cpp index 37cb205bad..91967c0fce 100644 --- a/Generals/Code/GameEngine/Source/Common/Thing/ThingTemplate.cpp +++ b/Generals/Code/GameEngine/Source/Common/Thing/ThingTemplate.cpp @@ -1116,6 +1116,20 @@ void ThingTemplate::resolveNames() { Int i, j; + //Kris: July 31, 2003 + //NOTE: Make sure that all code in this function supports caching properly. For example, + // templates can be partially overridden by map.ini files. When this happens, strings + // that have been parsed are looked up, cached, then cleared. The problem is if a string + // gets cached, but not overridden, it will be clear the next time we call this function. + // so we will want to make sure we don't NULL out cached data if the string is empty. A + // concrete example is overriding an object with prerequisites. We just override the portrait. + // So the 1st time we call this function, we get the standard template data. During this first + // call, the strings are looked up, cached, and cleared. Then we override the portrait in the + // map.ini. The next time we call this function, we look up all the strings again. The prereq + // names didn't used to check for empty strings so they would NULL out all the previous prereqs + // the object had. So be sure to make sure all string lookups don't blindly lookup things -- check + // if the string isNotEmpty first! + for (i = 0; i < m_prereqInfo.size(); i++) { m_prereqInfo[i].resolveNames(); @@ -1385,7 +1399,7 @@ Int ThingTemplate::calcTimeToBuild( const Player* player) const Real factionModifier = 1 + player->getProductionTimeChangePercent( getName() ); buildTime *= factionModifier; -#if defined (_DEBUG) || defined (_INTERNAL) +#if defined (_DEBUG) || defined (_INTERNAL) || defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE) if( player->buildsInstantly() ) { buildTime = 1; diff --git a/Generals/Code/GameEngine/Source/Common/UserPreferences.cpp b/Generals/Code/GameEngine/Source/Common/UserPreferences.cpp index 3c3f23cc82..17f260f7f3 100644 --- a/Generals/Code/GameEngine/Source/Common/UserPreferences.cpp +++ b/Generals/Code/GameEngine/Source/Common/UserPreferences.cpp @@ -721,7 +721,6 @@ Int GameSpyMiscPreferences::getMaxMessagesPerUpdate( void ) { return getInt("MaxMessagesPerUpdate", 100); } - //----------------------------------------------------------------------------- // IgnorePreferences base class //----------------------------------------------------------------------------- diff --git a/Generals/Code/GameEngine/Source/Common/crc.cpp b/Generals/Code/GameEngine/Source/Common/crc.cpp index 913ddd975e..950a1068f2 100644 --- a/Generals/Code/GameEngine/Source/Common/crc.cpp +++ b/Generals/Code/GameEngine/Source/Common/crc.cpp @@ -28,6 +28,7 @@ #include "Common/crc.h" #include "Common/Debug.h" +#ifdef _DEBUG void CRC::addCRC( UnsignedByte val ) { @@ -79,3 +80,4 @@ UnsignedInt CRC::get( void ) } // end skip +#endif diff --git a/Generals/Code/GameEngine/Source/GameClient/Color.cpp b/Generals/Code/GameEngine/Source/GameClient/Color.cpp index 4f33cdfe84..2fe0f6067c 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Color.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Color.cpp @@ -78,6 +78,17 @@ // GameGetColorComponents ===================================================== /** Get the RGB color comonents of a color */ //============================================================================= + +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif + + +//Put on ice until later M Lorenzen +//static UnsignedByte s_cheaterHasBeenSpied = 0; + void GameGetColorComponents( Color color, UnsignedByte *red, UnsignedByte *green, @@ -92,6 +103,25 @@ void GameGetColorComponents( Color color, } // end GameGetColorComponents +//Put on ice until later M Lorenzen +//void GameGetColorComponentsWithCheatSpy( Color color, +// UnsignedByte *red, +// UnsignedByte *green, +// UnsignedByte *blue, +// UnsignedByte *alpha ) +//{ +// +// *alpha |= (color & 0xFE000000) >> 24; // this waives the low order bit in alpha +// s_cheaterHasBeenSpied |= *alpha & (1<<0); // this records it and gets angry +// *red |= (color & 0x00FE0000) >> 16; // decoy +// s_cheaterHasBeenSpied |= *red & (1<<8); // decoy +// *green |= (color & 0x0000FE00) >> 8; // decoy +// s_cheaterHasBeenSpied |= *green & (1<<17); // decoy +// *blue |= (color & 0x000000FE) >> 0; // decoy +// s_cheaterHasBeenSpied |= *blue & (1<<25); // decoy +// +//} // end GameGetColorComponents + void GameGetColorComponentsReal( Color color, Real *red, Real *green, Real *blue, Real *alpha ) { *alpha = ((color & 0xFF000000) >> 24) / 255.0f; @@ -113,5 +143,15 @@ Color GameDarkenColor( Color color, Int percent ) g -= (g * percent / 100); b -= (b * percent / 100); +// Put on ice until later M Lorenzen +// TheWritableGlobalData->m_cheaterHasBeenSpiedIfMyLowestBitIsTrue = (r<<24) | (g<<16) | (b<<8) | s_cheaterHasBeenSpied; +// DEBUG_ASSERTCRASH( TheWritableGlobalData->m_cheaterHasBeenSpiedIfMyLowestBitIsTrue == FALSE, ("DIRTY ROTTEN CHEATER")); +// //my, but this looks like we just stored an alpha value along with rgb into the global data + + + + return GameMakeColor(r,g,b,a); -}// end GameDarkenColor \ No newline at end of file + +}// end GameDarkenColor + diff --git a/Generals/Code/GameEngine/Source/GameClient/Drawable.cpp b/Generals/Code/GameEngine/Source/GameClient/Drawable.cpp index 5b3161a4a2..8fedebfb20 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Drawable.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Drawable.cpp @@ -413,7 +413,6 @@ Drawable::Drawable( const ThingTemplate *thingTemplate, DrawableStatus statusBit m_ambientSoundEnabled = TRUE; - // // allocate any modules we need to, we should keep // this at or near the end of the drawable construction so that we have // all the valid data about the thing when we create the module @@ -1977,76 +1976,106 @@ void Drawable::calcPhysicsXformWheels( const Locomotor *locomotor, PhysicsXformI m_locoInfo->m_wheelInfo.m_wheelAngle += (newInfo.m_wheelAngle - m_locoInfo->m_wheelInfo.m_wheelAngle)/WHEEL_SMOOTHNESS; const Real SPRING_FACTOR = 0.9f; - if (pitchHeight<0) { // Front raising up + if (pitchHeight<0) + { + // Front raising up newInfo.m_frontLeftHeightOffset = SPRING_FACTOR*(pitchHeight/3+pitchHeight/2); newInfo.m_frontRightHeightOffset = SPRING_FACTOR*(pitchHeight/3+pitchHeight/2); newInfo.m_rearLeftHeightOffset = -pitchHeight/2 + pitchHeight/4; newInfo.m_rearRightHeightOffset = -pitchHeight/2 + pitchHeight/4; - } else { // Back rasing up. + } + else + { + // Back rasing up. newInfo.m_frontLeftHeightOffset = (-pitchHeight/4+pitchHeight/2); newInfo.m_frontRightHeightOffset = (-pitchHeight/4+pitchHeight/2); newInfo.m_rearLeftHeightOffset = SPRING_FACTOR*(-pitchHeight/2 + -pitchHeight/3); newInfo.m_rearRightHeightOffset = SPRING_FACTOR*(-pitchHeight/2 + -pitchHeight/3); } - if (rollHeight>0) { // Right raising up + if (rollHeight>0) + { + // Right raising up newInfo.m_frontRightHeightOffset += -SPRING_FACTOR*(rollHeight/3+rollHeight/2); newInfo.m_rearRightHeightOffset += -SPRING_FACTOR*(rollHeight/3+rollHeight/2); newInfo.m_rearLeftHeightOffset += rollHeight/2 - rollHeight/4; newInfo.m_frontLeftHeightOffset += rollHeight/2 - rollHeight/4; - } else { // Left rasing up. + } + else + { + // Left rasing up. newInfo.m_frontRightHeightOffset += -rollHeight/2 + rollHeight/4; newInfo.m_rearRightHeightOffset += -rollHeight/2 + rollHeight/4; newInfo.m_rearLeftHeightOffset += SPRING_FACTOR*(rollHeight/3+rollHeight/2); newInfo.m_frontLeftHeightOffset += SPRING_FACTOR*(rollHeight/3+rollHeight/2); } - if (newInfo.m_frontLeftHeightOffset < m_locoInfo->m_wheelInfo.m_frontLeftHeightOffset) { + if (newInfo.m_frontLeftHeightOffset < m_locoInfo->m_wheelInfo.m_frontLeftHeightOffset) + { // If it's going down, dampen the movement a bit m_locoInfo->m_wheelInfo.m_frontLeftHeightOffset += (newInfo.m_frontLeftHeightOffset - m_locoInfo->m_wheelInfo.m_frontLeftHeightOffset)/2.0f; - } else { + } + else + { m_locoInfo->m_wheelInfo.m_frontLeftHeightOffset = newInfo.m_frontLeftHeightOffset; } - if (newInfo.m_frontRightHeightOffset < m_locoInfo->m_wheelInfo.m_frontRightHeightOffset) { + if (newInfo.m_frontRightHeightOffset < m_locoInfo->m_wheelInfo.m_frontRightHeightOffset) + { // If it's going down, dampen the movement a bit m_locoInfo->m_wheelInfo.m_frontRightHeightOffset += (newInfo.m_frontRightHeightOffset - m_locoInfo->m_wheelInfo.m_frontRightHeightOffset)/2.0f; - } else { + } + else + { m_locoInfo->m_wheelInfo.m_frontRightHeightOffset = newInfo.m_frontRightHeightOffset; } - if (newInfo.m_rearLeftHeightOffset < m_locoInfo->m_wheelInfo.m_rearLeftHeightOffset) { + if (newInfo.m_rearLeftHeightOffset < m_locoInfo->m_wheelInfo.m_rearLeftHeightOffset) + { // If it's going down, dampen the movement a bit m_locoInfo->m_wheelInfo.m_rearLeftHeightOffset += (newInfo.m_rearLeftHeightOffset - m_locoInfo->m_wheelInfo.m_rearLeftHeightOffset)/2.0f; - } else { + } + else + { m_locoInfo->m_wheelInfo.m_rearLeftHeightOffset = newInfo.m_rearLeftHeightOffset; } - if (newInfo.m_rearRightHeightOffset < m_locoInfo->m_wheelInfo.m_rearRightHeightOffset) { + if (newInfo.m_rearRightHeightOffset < m_locoInfo->m_wheelInfo.m_rearRightHeightOffset) + { // If it's going down, dampen the movement a bit m_locoInfo->m_wheelInfo.m_rearRightHeightOffset += (newInfo.m_rearRightHeightOffset - m_locoInfo->m_wheelInfo.m_rearRightHeightOffset)/2.0f; - } else { + } + else + { m_locoInfo->m_wheelInfo.m_rearRightHeightOffset = newInfo.m_rearRightHeightOffset; } //m_locoInfo->m_wheelInfo = newInfo; - if (m_locoInfo->m_wheelInfo.m_frontLeftHeightOffsetm_wheelInfo.m_frontLeftHeightOffsetm_wheelInfo.m_frontLeftHeightOffset=MAX_SUSPENSION_EXTENSION; } - if (m_locoInfo->m_wheelInfo.m_frontRightHeightOffsetm_wheelInfo.m_frontRightHeightOffsetm_wheelInfo.m_frontRightHeightOffset=MAX_SUSPENSION_EXTENSION; } - if (m_locoInfo->m_wheelInfo.m_rearLeftHeightOffsetm_wheelInfo.m_rearLeftHeightOffsetm_wheelInfo.m_rearLeftHeightOffset=MAX_SUSPENSION_EXTENSION; } - if (m_locoInfo->m_wheelInfo.m_rearRightHeightOffsetm_wheelInfo.m_rearRightHeightOffsetm_wheelInfo.m_rearRightHeightOffset=MAX_SUSPENSION_EXTENSION; } /* - if (m_locoInfo->m_wheelInfo.m_frontLeftHeightOffset>MAX_SUSPENSION_COMPRESSION) { + if (m_locoInfo->m_wheelInfo.m_frontLeftHeightOffset>MAX_SUSPENSION_COMPRESSION) + { m_locoInfo->m_wheelInfo.m_frontLeftHeightOffset=MAX_SUSPENSION_COMPRESSION; } - if (m_locoInfo->m_wheelInfo.m_frontRightHeightOffset>MAX_SUSPENSION_COMPRESSION) { + if (m_locoInfo->m_wheelInfo.m_frontRightHeightOffset>MAX_SUSPENSION_COMPRESSION) + { m_locoInfo->m_wheelInfo.m_frontRightHeightOffset=MAX_SUSPENSION_COMPRESSION; } - if (m_locoInfo->m_wheelInfo.m_rearLeftHeightOffset>MAX_SUSPENSION_COMPRESSION) { + if (m_locoInfo->m_wheelInfo.m_rearLeftHeightOffset>MAX_SUSPENSION_COMPRESSION) + { m_locoInfo->m_wheelInfo.m_rearLeftHeightOffset=MAX_SUSPENSION_COMPRESSION; } - if (m_locoInfo->m_wheelInfo.m_rearRightHeightOffset>MAX_SUSPENSION_COMPRESSION) { + if (m_locoInfo->m_wheelInfo.m_rearRightHeightOffset>MAX_SUSPENSION_COMPRESSION) + { m_locoInfo->m_wheelInfo.m_rearRightHeightOffset=MAX_SUSPENSION_COMPRESSION; } */ @@ -2062,6 +2091,7 @@ void Drawable::calcPhysicsXformWheels( const Locomotor *locomotor, PhysicsXformI info.m_totalZ += fabs(rollHeight)/divisor; } + //------------------------------------------------------------------------------------------------- /** decodes the current previous damage type and sets the ambient sound set from that. */ //------------------------------------------------------------------------------------------------- @@ -3861,9 +3891,10 @@ void Drawable::startAmbientSound(BodyDamageType dt, TimeOfDay tod) { stopAmbientSound(); + Bool trySound = FALSE; + //Get the specific ambient sound for the damage type. const AudioEventRTS& audio = getAmbientSoundByDamage(dt); - Bool trySound = FALSE; if( audio.getEventName().isNotEmpty() ) { if (m_ambientSound == NULL) @@ -3943,7 +3974,9 @@ void Drawable::startAmbientSound() void Drawable::stopAmbientSound( void ) { if (m_ambientSound) + { TheAudio->removeAudioEvent(m_ambientSound->m_event.getPlayingHandle()); + } } //------------------------------------------------------------------------------------------------- diff --git a/Generals/Code/GameEngine/Source/GameClient/Eva.cpp b/Generals/Code/GameEngine/Source/GameClient/Eva.cpp index be519189b6..fb98dffa3b 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Eva.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Eva.cpp @@ -62,6 +62,32 @@ const char *TheEvaMessageNames[] = "EVA_INVALID", }; +//------------------------------------------------------------------------------------------------- +const ShouldPlayFunc Eva::s_shouldPlayFuncs[] = +{ + Eva::shouldPlayLowPower, + Eva::shouldPlayGenericHandler, + Eva::shouldPlayGenericHandler, + Eva::shouldPlayGenericHandler, + Eva::shouldPlayGenericHandler, + Eva::shouldPlayGenericHandler, + Eva::shouldPlayGenericHandler, + Eva::shouldPlayGenericHandler, + Eva::shouldPlayGenericHandler, + Eva::shouldPlayGenericHandler, + Eva::shouldPlayGenericHandler, + Eva::shouldPlayGenericHandler, + Eva::shouldPlayGenericHandler, + Eva::shouldPlayGenericHandler, + Eva::shouldPlayGenericHandler, + Eva::shouldPlayGenericHandler, + Eva::shouldPlayGenericHandler, + Eva::shouldPlayGenericHandler, + Eva::shouldPlayGenericHandler, + NULL, +}; + + //------------------------------------------------------------------------------ INI::parseEvaEvent void INI::parseEvaEvent( INI* ini ) { @@ -123,32 +149,6 @@ const FieldParse EvaCheckInfo::s_evaEventInfo[] = }; - -//------------------------------------------------------------------------------------------------- -const ShouldPlayFunc Eva::s_shouldPlayFuncs[] = -{ - Eva::shouldPlayLowPower, - Eva::shouldPlayGenericHandler, - Eva::shouldPlayGenericHandler, - Eva::shouldPlayGenericHandler, - Eva::shouldPlayGenericHandler, - Eva::shouldPlayGenericHandler, - Eva::shouldPlayGenericHandler, - Eva::shouldPlayGenericHandler, - Eva::shouldPlayGenericHandler, - Eva::shouldPlayGenericHandler, - Eva::shouldPlayGenericHandler, - Eva::shouldPlayGenericHandler, - Eva::shouldPlayGenericHandler, - Eva::shouldPlayGenericHandler, - Eva::shouldPlayGenericHandler, - Eva::shouldPlayGenericHandler, - Eva::shouldPlayGenericHandler, - Eva::shouldPlayGenericHandler, - Eva::shouldPlayGenericHandler, - NULL, -}; - //------------------------------------------------------------------------------------------------- EvaCheck::EvaCheck() : m_evaInfo(NULL), @@ -248,6 +248,10 @@ void Eva::update() //------------------------------------------------------------------------------------------------- EvaMessage Eva::nameToMessage(const AsciiString& name) { + DEBUG_ASSERTCRASH( ELEMENTS_OF( TheEvaMessageNames ) == EVA_COUNT + 1, ("TheEvaMessageNames out of sync" ) ); + DEBUG_ASSERTCRASH( stricmp( TheEvaMessageNames[ EVA_COUNT ], "EVA_INVALID" ) == 0, ("TheEvaMessageNames out of sync" ) ); + DEBUG_ASSERTCRASH( stricmp( TheEvaMessageNames[ EVA_COUNT - 1], "EVA_INVALID" ) != 0, ("TheEvaMessageNames out of sync" ) ); + for (Int i = EVA_FIRST; i < EVA_COUNT; ++i) { if (name.compareNoCase(TheEvaMessageNames[i]) == 0) { return (EvaMessage) i; @@ -261,6 +265,10 @@ EvaMessage Eva::nameToMessage(const AsciiString& name) //------------------------------------------------------------------------------------------------- AsciiString Eva::messageToName(EvaMessage message) { + DEBUG_ASSERTCRASH( ELEMENTS_OF( TheEvaMessageNames ) == EVA_COUNT + 1, ("TheEvaMessageNames out of sync" ) ); + DEBUG_ASSERTCRASH( stricmp( TheEvaMessageNames[ EVA_COUNT ], "EVA_INVALID" ) == 0, ("TheEvaMessageNames out of sync" ) ); + DEBUG_ASSERTCRASH( stricmp( TheEvaMessageNames[ EVA_COUNT - 1], "EVA_INVALID" ) != 0, ("TheEvaMessageNames out of sync" ) ); + if (message >= EVA_FIRST && message < EVA_COUNT) return TheEvaMessageNames[message]; @@ -305,6 +313,8 @@ const EvaCheckInfo *Eva::getEvaCheckInfo(AsciiString name) void Eva::setShouldPlay(EvaMessage messageToPlay) { m_shouldPlay[messageToPlay] = TRUE; + + // DEBUG_LOG( ( "Eva message %s play requested\n", messageToName( messageToPlay).str() ) ); } //------------------------------------------------------------------------------------------------- @@ -337,6 +347,10 @@ Bool Eva::messageShouldPlay(EvaMessage messageToTest, UnsignedInt currentFrame) return FALSE; } + DEBUG_ASSERTCRASH( ELEMENTS_OF( s_shouldPlayFuncs ) == EVA_COUNT + 1, ("Eva::s_shouldPlayFuncs out of sync" ) ); + DEBUG_ASSERTCRASH( s_shouldPlayFuncs[ EVA_COUNT ] == NULL, ("Eva::s_shouldPlayFuncs out of sync" ) ); + DEBUG_ASSERTCRASH( s_shouldPlayFuncs[ EVA_COUNT - 1] != NULL, ("Eva::s_shouldPlayFuncs out of sync" ) ); + m_messageBeingTested = messageToTest; return s_shouldPlayFuncs[messageToTest](m_localPlayer); } diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp index 644a7d34aa..7003f3753c 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBar.cpp @@ -3163,12 +3163,8 @@ void ControlBar::initSpecialPowershortcutBar( Player *player) id = TheNameKeyGenerator->nameToKey( windowName.str() ); m_specialPowerShortcutButtonParents[ i ] = TheWindowManager->winGetWindowFromId( m_specialPowerShortcutParent, id ); - - } // end for i - - } void ControlBar::populateSpecialPowerShortcut( Player *player) @@ -3382,6 +3378,7 @@ void ControlBar::updateSpecialPowerShortcut( void ) } } + void ControlBar::animateSpecialPowerShortcut( Bool isOn ) { if(!m_specialPowerShortcutParent || !m_animateWindowManagerForGenShortcuts || !m_currentlyUsedSpecialPowersButtons) diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBarCommand.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBarCommand.cpp index d3d0ce6324..909edd1e68 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBarCommand.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBarCommand.cpp @@ -1028,11 +1028,12 @@ CommandAvailability ControlBar::getCommandAvailability( const CommandButton *com { case GUI_COMMAND_DOZER_CONSTRUCT: { + const ThingTemplate * whatToBuild = command->getThingTemplate(); // if the command is a dozer construct task and the object dozer is building anything // this command is not available - if(command->getThingTemplate()) + if(whatToBuild) { - BuildableStatus bStatus = command->getThingTemplate()->getBuildable(); + BuildableStatus bStatus = whatToBuild->getBuildable(); if (bStatus == BSTATUS_NO || (bStatus == BSTATUS_ONLY_BY_AI && obj->getControllingPlayer()->getPlayerType() != PLAYER_COMPUTER)) return COMMAND_HIDDEN; } @@ -1057,14 +1058,15 @@ CommandAvailability ControlBar::getCommandAvailability( const CommandButton *com return COMMAND_RESTRICTED; // return whether or not the player can build this thing - if( player->canBuild( command->getThingTemplate() ) == FALSE ) + if( player->canBuild( whatToBuild ) == FALSE ) return COMMAND_RESTRICTED; - if( !player->canAffordBuild( command->getThingTemplate() ) ) + if( !player->canAffordBuild( whatToBuild ) ) { return COMMAND_RESTRICTED;//COMMAND_CANT_AFFORD; } + break; } diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBarCommandProcessing.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBarCommandProcessing.cpp index b1943dc1d2..a76e9ea9a6 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBarCommandProcessing.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBarCommandProcessing.cpp @@ -62,6 +62,42 @@ //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") #endif + +//------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------------- +struct SelectObjectsInfo +{ + const ThingTemplate *thingTemplate; + GameMessage *msg; +}; + +//------------------------------------------------------------------------------------------------- + +void selectObjectOfType( Object* obj, void* selectObjectsInfo ) +{ + SelectObjectsInfo *soInfo = (SelectObjectsInfo*)selectObjectsInfo; + if( !obj || !soInfo ) + { + return; + } + + //Do the templates match? + if( obj->getTemplate()->isEquivalentTo( soInfo->thingTemplate ) ) + { + //Okay, then add it to the selected group. + soInfo->msg->appendObjectIDArgument( obj->getID() ); + + Drawable *draw = obj->getDrawable(); + if( draw ) + { + TheInGameUI->selectDrawable( draw ); + } + } +} +//------------------------------------------------------------------------------------------------- +//------------------------------------------------------------------------------------------------- + + //------------------------------------------------------------------------------------------------- /** Process a button transition message from the window system that should be for one of * our GUI commands */ @@ -261,6 +297,7 @@ CBCommandStatus ControlBar::processCommandUI( GameWindow *control, //--------------------------------------------------------------------------------------------- case GUI_COMMAND_UNIT_BUILD: { + // const ThingTemplate *whatToBuild = commandButton->getThingTemplate(); // get the "factory" object that is going to make the thing @@ -544,6 +581,8 @@ CBCommandStatus ControlBar::processCommandUI( GameWindow *control, } // end if + //what if container is subdued... assert a logic failure, perhaps? + // send message to exit GameMessage *exitMsg = TheMessageStream->appendMessage( GameMessage::MSG_EXIT ); exitMsg->appendObjectIDArgument( objWantingExit->getID() ); // 0 is the thing inside coming out diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBarScheme.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBarScheme.cpp index 06bea9b829..93dfea6a19 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBarScheme.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBarScheme.cpp @@ -362,7 +362,6 @@ ControlBarScheme::ControlBarScheme(void) m_minMaxButtonHightlited = NULL; m_minMaxButtonPushed = NULL; - m_minMaxUL.x = 0; m_minMaxLR.x = 0; diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarCallback.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarCallback.cpp index a19ed13abd..85a5a5dbbf 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarCallback.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarCallback.cpp @@ -263,7 +263,6 @@ WindowMsgHandledType LeftHUDInput( GameWindow *window, UnsignedInt msg, const DrawableList *drawableList = TheInGameUI->getAllSelectedLocalDrawables(); // locally-owned only - // see if the user wants to move the tactical view if ( drawableList->empty() || (! TheGlobalData->m_useAlternateMouse && msg == GWM_RIGHT_DOWN) diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarPopupDescription.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarPopupDescription.cpp index 9429a7f9fe..32da1ead14 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarPopupDescription.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/ControlBarPopupDescription.cpp @@ -264,7 +264,7 @@ void ControlBar::populateBuildTooltipLayout( const CommandButton *commandButton, const UpgradeTemplate *upgradeTemplate = commandButton->getUpgradeTemplate(); ScienceType st = SCIENCE_INVALID; - if(commandButton->getScienceVec().size() > 1) + if( commandButton->getScienceVec().size() > 1 ) { for(Int j = 0; j < commandButton->getScienceVec().size(); ++j) { diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/MainMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/MainMenu.cpp index c2b854f032..55454404cc 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/MainMenu.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/MainMenu.cpp @@ -98,7 +98,7 @@ enum static Bool raiseMessageBoxes = TRUE; static Bool campaignSelected = FALSE; -#if defined _DEBUG || defined _INTERNAL +#if defined _DEBUG || defined _INTERNAL || defined _PROFILE static NameKeyType campaignID = NAMEKEY_INVALID; static GameWindow *buttonCampaign = NULL; #ifdef TEST_COMPRESSION @@ -107,6 +107,7 @@ void DoCompressTest( void ); #endif // TEST_COMPRESSION #endif + // window ids ------------------------------------------------------------------------------------- static NameKeyType mainMenuID = NAMEKEY_INVALID; static NameKeyType skirmishID = NAMEKEY_INVALID; @@ -179,6 +180,7 @@ static Bool buttonPushed = FALSE; static Bool isShuttingDown = FALSE; static Bool startGame = FALSE; static Int initialGadgetDelay = 210; + enum { SHOW_NONE = 0, @@ -517,7 +519,7 @@ void MainMenuInit( WindowLayout *layout, void *userData ) showSelectiveButtons(SHOW_NONE); // Set up the version number -#if defined _DEBUG || defined _INTERNAL +#if defined _DEBUG || defined _INTERNAL || defined _PROFILE WinInstanceData instData; #ifdef TEST_COMPRESSION instData.init(); @@ -1247,7 +1249,7 @@ WindowMsgHandledType MainMenuSystem( GameWindow *window, UnsignedInt msg, if(buttonPushed) break; -#if defined _DEBUG || defined _INTERNAL +#if defined _DEBUG || defined _INTERNAL || defined _PROFILE if( control == buttonCampaign ) { buttonPushed = TRUE; diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/PopupPlayerInfo.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/PopupPlayerInfo.cpp index 13cde82e42..233bd317ec 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/PopupPlayerInfo.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/PopupPlayerInfo.cpp @@ -108,6 +108,7 @@ static const char *rankNames[] = { "Commander", }; + static const Image* lookupRankImage(AsciiString side, Int rank) { if (side.isEmpty()) @@ -142,6 +143,7 @@ static const Image* lookupRankImage(AsciiString side, Int rank) return img; } + static Int getTotalDisconnectsFromFile(Int playerID) { Int retval = 0; @@ -153,7 +155,7 @@ static Int getTotalDisconnectsFromFile(Int playerID) UserPreferences pref; AsciiString userPrefFilename; userPrefFilename.format("GeneralsOnline\\MiscPref%d.ini", playerID); - DEBUG_LOG(("setPersistentDataCallback - reading stats from file %s\n", userPrefFilename.str())); + DEBUG_LOG(("getTotalDisconnectsFromFile - reading stats from file %s\n", userPrefFilename.str())); pref.load(userPrefFilename); // if there is a file override, use that data instead. @@ -221,7 +223,7 @@ void GetAdditionalDisconnectsFromUserFile(PSPlayerStats *stats) UserPreferences pref; AsciiString userPrefFilename; userPrefFilename.format("GeneralsOnline\\MiscPref%d.ini", stats->id); - DEBUG_LOG(("setPersistentDataCallback - reading stats from file %s\n", userPrefFilename.str())); + DEBUG_LOG(("GetAdditionalDisconnectsFromUserFile - reading stats from file %s\n", userPrefFilename.str())); pref.load(userPrefFilename); // if there is a file override, use that data instead. diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/PopupSaveLoad.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/PopupSaveLoad.cpp index 1f93cecb7a..06c00be307 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/PopupSaveLoad.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/PopupSaveLoad.cpp @@ -330,6 +330,16 @@ WindowMsgHandledType SaveLoadMenuInput( GameWindow *window, UnsignedInt msg, Win if( BitIsSet( state, KEY_STATE_UP ) ) { GameWindow *button = TheWindowManager->winGetWindowFromId( parent, buttonBackKey ); + + //Kris: Patch 1.01 - November 12, 2003 + //If you are in the game, then bring up the popup save menu, select a save game, click delete, + //hit ESC (brings you back to menu), then hit save/load again, the delete confirmation is still up + //and clicking on yes causes it to crash. So whenever we hit esc to leave this interface, kill + //the confirmation, and re-enable the listbox and buttonFrame. + deleteConfirm->winHide( TRUE ); + listboxGames->winEnable( TRUE ); + buttonFrame->winEnable( TRUE ); + TheWindowManager->winSendSystemMsg( window, GBM_SELECTED, (WindowMsgData)button, buttonBackKey ); diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/ScoreScreen.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/ScoreScreen.cpp index 8c0cbd5607..df1a8b9695 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/ScoreScreen.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/ScoreScreen.cpp @@ -96,7 +96,6 @@ #include "GameNetwork/GameSpy/BuddyThread.h" #include "GameNetwork/GameSpy/GameResultsThread.h" #include "GameNetwork/GameSpy/PersistentStorageThread.h" -//Added By Saad #include "GameClient/InGameUI.h" #ifdef _INTERNAL diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/SkirmishGameOptionsMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/SkirmishGameOptionsMenu.cpp index 9257a7be95..d164dbb841 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/SkirmishGameOptionsMenu.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/SkirmishGameOptionsMenu.cpp @@ -543,6 +543,7 @@ void MapSelectorTooltip(GameWindow *window, } + void positionStartSpotControls( GameWindow *win, GameWindow *mapWindow, Coord3D *pos, MapMetaData *mmd, GameWindow *buttonMapStartPositions[]) { if(!win || !mmd || !mapWindow || !buttonMapStartPositions) @@ -798,7 +799,7 @@ void updateMapStartSpots( GameInfo *myGame, GameWindow *buttonMapStartPositions[ { buttonMapStartPositions[i]->winSetTooltip(TheGameText->fetch("TOOLTIP:StartPosition")); } - } + } } for( i = 0; i < MAX_SLOTS; ++i) { @@ -1062,6 +1063,7 @@ void InitSkirmishGameGadgets( void ) comboBoxTeam[i] = TheWindowManager->winGetWindowFromId( parentSkirmishGameOptions, comboBoxTeamID[i] ); DEBUG_ASSERTCRASH(comboBoxTeam[i], ("Could not find the comboBoxTeam[%d]",i )); + // tmpString.format("SkirmishGameOptionsMenu.wnd:ButtonStartPosition%d", i); // buttonStartPositionID[i] = TheNameKeyGenerator->nameToKey( tmpString ); // buttonStartPosition[i] = TheWindowManager->winGetWindowFromId( parentSkirmishGameOptions, buttonStartPositionID[i] ); @@ -1355,6 +1357,7 @@ void SkirmishGameOptionsMenuShutdown( WindowLayout *layout, void *userData ) // our shutdown is complete TheTransitionHandler->reverse("SkirmishGameOptionsMenuFade"); + } // void SkirmishGameOptionsMenuShutdown( WindowLayout *layout, void *userData ) //------------------------------------------------------------------------------------------------- diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLBuddyOverlay.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLBuddyOverlay.cpp index a5ad03678c..b51768602e 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLBuddyOverlay.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLBuddyOverlay.cpp @@ -1302,8 +1302,6 @@ WindowMsgHandledType WOLBuddyOverlayRCMenuSystem( GameWindow *window, UnsignedIn BuddyInfoMap *m = TheGameSpyInfo->getBuddyRequestMap(); m->erase( profileID ); - - // DONT CHECK IN UNTIL MATT HAS REVIEWED // if the profile ID is not from a buddy and we're okaying his request, then // request to add him to our list automatically CLH 2-18-03 if(!TheGameSpyInfo->isBuddy(profileID)) @@ -1311,7 +1309,6 @@ WindowMsgHandledType WOLBuddyOverlayRCMenuSystem( GameWindow *window, UnsignedIn RequestBuddyAdd(profileID, nick); } updateBuddyInfo(); - } else if (!isBuddy) { diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp index b38ca41ac0..bc5a111766 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLGameSetupMenu.cpp @@ -263,7 +263,6 @@ void positionStartSpots(AsciiString mapName, GameWindow *buttonMapStartPositions void WOLPositionStartSpots( void ) { GameWindow *win = windowMap; - if (WOLMapSelectLayout != NULL) { win = TheWindowManager->winGetWindowFromId(NULL, windowMapSelectMapID); @@ -935,6 +934,7 @@ void WOLDisplayGameOptions( void ) updateMapStartSpots(TheGameSpyInfo->getCurrentStagingRoom(), buttonMapStartPosition); } + // ----------------------------------------------------------------------------------------- // The Bad munkee slot list displaying function //------------------------------------------------------------------------------------------------- @@ -1555,7 +1555,6 @@ void WOLGameSetupMenuUpdate( WindowLayout * layout, void *userData) { break; } - switch (resp.peerResponseType) { case PeerResponse::PEERRESPONSE_FAILEDTOHOST: @@ -2497,7 +2496,6 @@ WindowMsgHandledType WOLGameSetupMenuSystem( GameWindow *window, UnsignedInt msg GameWindow *control = (GameWindow *)mData1; Int controlID = control->winGetWindowId(); static Int buttonCommunicatorID = NAMEKEY("GameSpyGameOptionsMenu.wnd:ButtonCommunicator"); - if ( controlID == buttonBackID ) { savePlayerInfo(); diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLobbyMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLobbyMenu.cpp index ebdc81d8ab..f4c9a984a3 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLobbyMenu.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLLobbyMenu.cpp @@ -244,7 +244,7 @@ static void playerTooltip(GameWindow *window, return; } - UnicodeString uName = GadgetListBoxGetText(window, row, 2); + UnicodeString uName = GadgetListBoxGetText(window, row, COLUMN_PLAYERNAME); AsciiString aName; aName.translate(uName); @@ -471,8 +471,10 @@ static Int insertPlayerInListbox(const PlayerInfo& info, Color color) return index; } + void PopulateLobbyPlayerListbox(void) { + if (!listboxLobbyPlayers) return; @@ -501,7 +503,7 @@ void PopulateLobbyPlayerListbox(void) } ++numSelected; AsciiString selectedName; - uStr = GadgetListBoxGetText(listboxLobbyPlayers, selectedIndices[i], 2); + uStr = GadgetListBoxGetText(listboxLobbyPlayers, selectedIndices[i], COLUMN_PLAYERNAME); selectedName.translate(uStr); selectedNames.insert(selectedName); DEBUG_LOG(("Saving off old selection %d (%s)\n", selectedIndices[i], selectedName.str())); @@ -704,6 +706,7 @@ void WOLLobbyMenuInit( WindowLayout *layout, void *userData ) if(win) win->winHide(TRUE); DontShowMainMenu = TRUE; + } // WOLLobbyMenuInit //------------------------------------------------------------------------------------------------- diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp index cec8b3873f..f37bc1acd9 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/WOLQuickMatchMenu.cpp @@ -1290,7 +1290,6 @@ void WOLQuickMatchMenuUpdate( WindowLayout * layout, void *userData) AsciiString theMap = *it; theMap.toLower(); const MapMetaData *md = TheMapCache->findMap(theMap); - if (md && md->m_numPlayers >= numPlayers) { TheGameSpyGame->setMap(*it); diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/Gadget/GadgetCheckBox.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/Gadget/GadgetCheckBox.cpp index 70d89bdc04..e3d4803941 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/Gadget/GadgetCheckBox.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/Gadget/GadgetCheckBox.cpp @@ -343,6 +343,29 @@ void GadgetCheckBoxSetChecked( GameWindow *g, Bool isChecked) (WindowMsgData)g, 0 ); } + +// GadgetCheckBoxToggle ============================================ +//============================================================================= +/** Toggle the check state for the check box */ +//============================================================================= +void GadgetCheckBoxToggle( GameWindow *g) +{ + WinInstanceData *instData = g->winGetInstanceData(); + Bool isChecked = BitIsSet(instData->m_state, WIN_STATE_SELECTED); + if (isChecked) + { + BitClear(instData->m_state, WIN_STATE_SELECTED); + } + else + { + BitSet(instData->m_state, WIN_STATE_SELECTED); + } + + TheWindowManager->winSendSystemMsg( g->winGetOwner(), GBM_SELECTED, + (WindowMsgData)g, 0 ); + +} + // GadgetCheckBoxIsChecked ====================================================== /** Check the check state */ //============================================================================= diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/Gadget/GadgetPushButton.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/Gadget/GadgetPushButton.cpp index a6f7f093fa..29d4aa1430 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/Gadget/GadgetPushButton.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/Gadget/GadgetPushButton.cpp @@ -54,6 +54,11 @@ #include "GameClient/GameWindowManager.h" #include "GameClient/InGameUI.h" +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif // DEFINES //////////////////////////////////////////////////////////////////// // PRIVATE TYPES ////////////////////////////////////////////////////////////// diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindow.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindow.cpp index ad874a96b0..6f56dd31cd 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindow.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindow.cpp @@ -658,6 +658,16 @@ Int GameWindow::winEnable( Bool enable ) } // end WinEnable +// GameWindow::winGetEnabled ====================================================== +/** Enable or disable a window based on the enable parameter. + * A disabled window can be seen but accepts no input. */ +//============================================================================= +Bool GameWindow::winGetEnabled( void ) +{ + return BitIsSet( m_status, WIN_STATUS_ENABLED ); + +} // end winGetEnabled + // GameWindow::winHide ======================================================== /** Hide or show a window based on the hide parameter. * A hidden window can't be seen and accepts no input. */ diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp index bd27d407cd..32b92959b7 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp @@ -72,6 +72,13 @@ #include "GameClient/GameText.h" #include "GameClient/HeaderTemplate.h" +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif + + // DEFINES //////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/LoadScreen.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/LoadScreen.cpp index 1794cce95d..4c0d9a8518 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/LoadScreen.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/LoadScreen.cpp @@ -48,47 +48,41 @@ // SYSTEM INCLUDES //////////////////////////////////////////////////////////// //----------------------------------------------------------------------------- #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine -#ifdef _INTERNAL -// for occasional debugging... -//#pragma optimize("", off) -//#pragma message("************************************** WARNING, optimization disabled for debugging purposes") -#endif //----------------------------------------------------------------------------- // USER INCLUDES ////////////////////////////////////////////////////////////// //----------------------------------------------------------------------------- #include "Common/NameKeyGenerator.h" -#include "Common/MultiplayerSettings.h" +#include "Common/AudioAffect.h" +#include "Common/AudioEventRTS.h" +#include "Common/AudioHandleSpecialValues.h" +#include "Common/GameAudio.h" #include "Common/GameEngine.h" +#include "Common/GameLOD.h" #include "Common/GameState.h" -#include "Common/PlayerTemplate.h" -#include "Common/PlayerList.h" +#include "Common/MultiplayerSettings.h" #include "Common/Player.h" -#include "Common/GameLOD.h" -#include "Common/GameAudio.h" -#include "Common/AudioEventRTS.h" -#include "Common/AudioHandleSpecialValues.h" -#include "Common/AudioAffect.h" - -#include "GameClient/LoadScreen.h" -#include "GameClient/Shell.h" -#include "GameClient/GameWindowManager.h" +#include "Common/PlayerList.h" +#include "Common/PlayerTemplate.h" +#include "GameClient/CampaignManager.h" +#include "GameClient/Display.h" #include "GameClient/GadgetProgressBar.h" #include "GameClient/GadgetStaticText.h" #include "GameClient/GameText.h" -#include "GameClient/Display.h" -#include "GameClient/WindowLayout.h" +#include "GameClient/GameWindowManager.h" +#include "GameClient/GameWindowTransitions.h" +#include "GameClient/LoadScreen.h" +#include "GameClient/MapUtil.h" #include "GameClient/Mouse.h" +#include "GameClient/Shell.h" #include "GameClient/VideoPlayer.h" -#include "GameClient/MapUtil.h" +#include "GameClient/WindowLayout.h" #include "GameLogic/FPUControl.h" #include "GameLogic/GameLogic.h" -#include "GameNetwork/NetworkInterface.h" #include "GameNetwork/GameSpy/PeerDefs.h" #include "GameNetwork/GameSpy/PersistentStorageThread.h" -#include "GameClient/CampaignManager.h" +#include "GameNetwork/NetworkInterface.h" #include "GameNetwork/RankPointValue.h" -#include "GameClient/GameWindowTransitions.h" //----------------------------------------------------------------------------- // DEFINES //////////////////////////////////////////////////////////////////// diff --git a/Generals/Code/GameEngine/Source/GameClient/GlobalLanguage.cpp b/Generals/Code/GameEngine/Source/GameClient/GlobalLanguage.cpp index 75a3bffd42..215e66f6af 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GlobalLanguage.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GlobalLanguage.cpp @@ -140,6 +140,7 @@ void GlobalLanguage::init( void ) OSVERSIONINFO osvi; osvi.dwOSVersionInfoSize=sizeof(OSVERSIONINFO); + //GS NOTE: Must call doesFileExist in either case so that NameKeyGenerator will stay in sync AsciiString tempName; tempName.format("Data\\%s\\Language9x.ini", GetRegistryLanguage().str()); @@ -149,6 +150,7 @@ void GlobalLanguage::init( void ) fname = tempName; } + ini.load( fname, INI_LOAD_OVERWRITE, NULL ); StringListIt it = m_localFonts.begin(); while( it != m_localFonts.end()) diff --git a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp index 25704d7e32..6a4c17e207 100644 --- a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -511,7 +511,9 @@ void InGameUI::addSuperweapon(Int playerIndex, const AsciiString& powerName, Obj const Player* player = ThePlayerList->getNthPlayer(playerIndex); Bool hiddenByScience = (powerTemplate->getRequiredScience() != SCIENCE_INVALID) && (player->hasScience(powerTemplate->getRequiredScience()) == false); +#ifndef DO_UNIT_TIMINGS DEBUG_LOG(("Adding superweapon UI timer\n")); +#endif SuperweaponInfo *info = newInstance(SuperweaponInfo)( id, -1, // timestamp @@ -3508,10 +3510,6 @@ void InGameUI::postDraw( void ) } } } - - - - } } } @@ -3876,9 +3874,9 @@ void InGameUI::militarySubtitle( const AsciiString& label, Int duration ) TheInGameUI->disableTooltipsUntil(messageTimeout); // calculate where this screen position should be since the position being passed in is based off 8x6 - Coord2D multiplyer; - multiplyer.x = TheDisplay->getWidth() / 800; - multiplyer.y = TheDisplay->getHeight() / 600; + Coord2D multiplier; + multiplier.x = TheDisplay->getWidth() / 800; + multiplier.y = TheDisplay->getHeight() / 600; // lets bring out the data structure! m_militarySubtitle = NEW MilitarySubtitleData; @@ -3887,8 +3885,8 @@ void InGameUI::militarySubtitle( const AsciiString& label, Int duration ) m_militarySubtitle->blockDrawn = TRUE; m_militarySubtitle->blockBeginFrame = currLogicFrame; m_militarySubtitle->lifetime = messageTimeout; - m_militarySubtitle->blockPos.x = m_militarySubtitle->position.x = m_militaryCaptionPosition.x * multiplyer.x; - m_militarySubtitle->blockPos.y = m_militarySubtitle->position.y = m_militaryCaptionPosition.y * multiplyer.y; + m_militarySubtitle->blockPos.x = m_militarySubtitle->position.x = m_militaryCaptionPosition.x * multiplier.x; + m_militarySubtitle->blockPos.y = m_militarySubtitle->position.y = m_militaryCaptionPosition.y * multiplier.y; m_militarySubtitle->incrementOnFrame = currLogicFrame + (Int)(((Real)LOGICFRAMES_PER_SECOND * m_militaryCaptionDelayMS)/1000.0f); m_militarySubtitle->index = 0; for (int i = 1; i < MAX_SUBTITLE_LINES; i ++) @@ -5133,7 +5131,7 @@ void InGameUI::updateAndDrawWorldAnimations( void ) wad = *it; // update portion ... only when the game is in motion - if( TheGameLogic->isGamePaused() == FALSE ) + if( wad && TheGameLogic->isGamePaused() == FALSE ) { // diff --git a/Generals/Code/GameEngine/Source/GameClient/Input/Mouse.cpp b/Generals/Code/GameEngine/Source/GameClient/Input/Mouse.cpp index e53c3bfb5d..fcd0da025c 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Input/Mouse.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Input/Mouse.cpp @@ -681,6 +681,11 @@ void Mouse::createStreamMessages( void ) Int delay = m_tooltipDelayTime; if(m_tooltipDelay >= 0 ) delay = m_tooltipDelay; + if( TheGlobalData->m_scriptDebug ) + { + //No delay while scriptdebugging! + delay = 0; + } if( now - m_stillTime >= delay ) { diff --git a/Generals/Code/GameEngine/Source/GameClient/LanguageFilter.cpp b/Generals/Code/GameEngine/Source/GameClient/LanguageFilter.cpp index 9790c0b40e..a4f94f96c4 100644 --- a/Generals/Code/GameEngine/Source/GameClient/LanguageFilter.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/LanguageFilter.cpp @@ -58,7 +58,7 @@ void LanguageFilter::init() { return; } - WideChar word[128]; + wchar_t word[128]; while (readWord(file1, word)) { Int wordLen = wcslen(word); if (wordLen == 0) { diff --git a/Generals/Code/GameEngine/Source/GameClient/MapUtil.cpp b/Generals/Code/GameEngine/Source/GameClient/MapUtil.cpp index 04cfe1b4ea..2d86e022bb 100644 --- a/Generals/Code/GameEngine/Source/GameClient/MapUtil.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/MapUtil.cpp @@ -151,7 +151,7 @@ static Bool ParseObjectDataChunk(DataChunkInput &file, DataChunkInfo *info, void // create the map object pThisOne = newInstance( MapObject )( loc, name, angle, flags, &d, - TheThingFactory->findTemplate( name ) ); + TheThingFactory->findTemplate( name, FALSE ) ); //DEBUG_LOG(("obj %s owner %s\n",name.str(),d.getAsciiString(TheKey_originalOwner).str())); diff --git a/Generals/Code/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp b/Generals/Code/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp index 3858c74c00..c6c1c9a8a6 100644 --- a/Generals/Code/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp @@ -205,7 +205,9 @@ static CanAttackResult canObjectForceAttack( Object *obj, const Object *victim, //that try to force attack in a location beyond their reach (range, LOS, etc). if( pos ) { + Object *testObj = obj; + if( obj->isKindOf( KINDOF_IMMOBILE ) || obj->isKindOf( KINDOF_SPAWNS_ARE_THE_WEAPONS ) ) { SpawnBehaviorInterface *spawnInterface = obj->getSpawnBehaviorInterface(); @@ -2917,7 +2919,6 @@ GameMessageDisposition CommandTranslator::translateGameMessage(const GameMessage //----------------------------------------------------------------------------------------- case GameMessage::MSG_META_REMOVE_BEACON: if (TheGameLogic->isInMultiplayerGame() && !TheGameLogic->isInReplayGame()) - { TheMessageStream->appendMessage( GameMessage::MSG_REMOVE_BEACON ); } diff --git a/Generals/Code/GameEngine/Source/GameClient/MessageStream/PlaceEventTranslator.cpp b/Generals/Code/GameEngine/Source/GameClient/MessageStream/PlaceEventTranslator.cpp index 7ae460e94b..dfa556a54e 100644 --- a/Generals/Code/GameEngine/Source/GameClient/MessageStream/PlaceEventTranslator.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/MessageStream/PlaceEventTranslator.cpp @@ -27,19 +27,19 @@ #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine +#include "Common/BuildAssistant.h" #include "Common/GameAudio.h" #include "Common/Player.h" #include "Common/PlayerList.h" #include "Common/ThingTemplate.h" -#include "Common/BuildAssistant.h" - -#include "GameLogic/Object.h" -#include "GameLogic/GameLogic.h" #include "GameClient/CommandXlat.h" -#include "GameClient/PlaceEventTranslator.h" #include "GameClient/Drawable.h" #include "GameClient/Eva.h" +#include "GameClient/PlaceEventTranslator.h" + +#include "GameLogic/GameLogic.h" +#include "GameLogic/Object.h" //------------------------------------------------------------------------------------------------- PlaceEventTranslator::PlaceEventTranslator() : m_frameOfUpButton(-1) diff --git a/Generals/Code/GameEngine/Source/GameClient/SelectionInfo.cpp b/Generals/Code/GameEngine/Source/GameClient/SelectionInfo.cpp index 7aa24453eb..77a246c33e 100644 --- a/Generals/Code/GameEngine/Source/GameClient/SelectionInfo.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/SelectionInfo.cpp @@ -23,18 +23,19 @@ //////////////////////////////////////////////////////////////////////////////// #include "PreRTS.h" -#include "GameClient/SelectionInfo.h" -#include "Common/ActionManager.h" #include "GameLogic/Damage.h" -#include "Common/Player.h" -#include "Common/PlayerList.h" + +#include "Common/ActionManager.h" #include "Common/ThingTemplate.h" +#include "Common/PlayerList.h" +#include "Common/Player.h" +#include "GameClient/SelectionInfo.h" #include "GameClient/CommandXlat.h" #include "GameClient/ControlBar.h" -#include "GameClient/Drawable.h" #include "GameClient/GameClient.h" +#include "GameClient/Drawable.h" #include "GameClient/KeyDefs.h" #ifdef _INTERNAL diff --git a/Generals/Code/GameEngine/Source/GameClient/System/CampaignManager.cpp b/Generals/Code/GameEngine/Source/GameClient/System/CampaignManager.cpp index f58f462e71..caa7c40159 100644 --- a/Generals/Code/GameEngine/Source/GameClient/System/CampaignManager.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/System/CampaignManager.cpp @@ -52,15 +52,24 @@ //----------------------------------------------------------------------------- #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine +#include "GameClient/CampaignManager.h" + #include "Common/INI.h" #include "Common/Xfer.h" -#include "GameClient/CampaignManager.h" #include "GameClient/GameClient.h" //----------------------------------------------------------------------------- // DEFINES //////////////////////////////////////////////////////////////////// //----------------------------------------------------------------------------- CampaignManager *TheCampaignManager = NULL; + +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif + + const FieldParse CampaignManager::m_campaignFieldParseTable[] = { @@ -364,7 +373,6 @@ void CampaignManager::parseMissionPart( INI* ini, void *instance, void *store, c { "LocationNameLabel",INI::parseAsciiString, NULL, offsetof( Mission, m_locationNameLabel ) }, { "VoiceLength", INI::parseInt , NULL, offsetof( Mission, m_voiceLength ) }, - { NULL, NULL, NULL, 0 } // keep this last }; AsciiString name; diff --git a/Generals/Code/GameEngine/Source/GameClient/Terrain/TerrainVisual.cpp b/Generals/Code/GameEngine/Source/GameClient/Terrain/TerrainVisual.cpp index 4193be2905..9d35ed68de 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Terrain/TerrainVisual.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Terrain/TerrainVisual.cpp @@ -31,6 +31,15 @@ #include "Common/Xfer.h" #include "GameClient/TerrainVisual.h" + +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif + + + // GLOBALS //////////////////////////////////////////////////////////////////////////////////////// TerrainVisual *TheTerrainVisual = NULL; diff --git a/Generals/Code/GameEngine/Source/GameLogic/AI/AIPathfind.cpp b/Generals/Code/GameEngine/Source/GameLogic/AI/AIPathfind.cpp index 2e55539592..6b7e339963 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/AI/AIPathfind.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/AI/AIPathfind.cpp @@ -70,7 +70,6 @@ //------------------------------------------------------------------------------------------------- - #ifdef _INTERNAL // for occasional debugging... //#pragma optimize("", off) diff --git a/Generals/Code/GameEngine/Source/GameLogic/AI/AIPlayer.cpp b/Generals/Code/GameEngine/Source/GameLogic/AI/AIPlayer.cpp index 4d45354992..3dfa926944 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/AI/AIPlayer.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/AI/AIPlayer.cpp @@ -1171,13 +1171,16 @@ void AIPlayer::computeSuperweaponTarget(const SpecialPowerTemplate *power, Coord Coord3D bestPos; Int i, j; - for (i=0; i cash) { + if ( curCash > cash) + { cash = curCash; bestPos = pos; } @@ -1189,17 +1192,22 @@ void AIPlayer::computeSuperweaponTarget(const SpecialPowerTemplate *power, Coord yCount = 11; cash = -1; Int count = 0; - for (i=0; i cash) { + Int curCash = getPlayerSuperweaponValue( &pos, playerNdx, weaponRadius ); + if ( curCash > cash) + { cash = curCash; veryBestPos = pos; count = 1; - } else if (curCash==cash) { + } + else if (curCash==cash) + { veryBestPos.x += pos.x; veryBestPos.y += pos.y; count++; @@ -1220,7 +1228,8 @@ void AIPlayer::computeSuperweaponTarget(const SpecialPowerTemplate *power, Coord */ Int AIPlayer::getPlayerSuperweaponValue(Coord3D *center, Int playerNdx, Real radius ) { - if (radius < 4*PATHFIND_CELL_SIZE_F) { + if (radius < 4*PATHFIND_CELL_SIZE_F) + { radius = 4*PATHFIND_CELL_SIZE_F; } Player::PlayerTeamList::const_iterator it; @@ -1228,30 +1237,40 @@ Int AIPlayer::getPlayerSuperweaponValue(Coord3D *center, Int playerNdx, Real rad Real radSqr = sqr(radius); Player* pPlayer = ThePlayerList->getNthPlayer(playerNdx); - if (pPlayer == NULL) return 0; - for (it = pPlayer->getPlayerTeams()->begin(); it != pPlayer->getPlayerTeams()->end(); ++it) { - for (DLINK_ITERATOR iter = (*it)->iterate_TeamInstanceList(); !iter.done(); iter.advance()) { + if (pPlayer == NULL) + return 0; + for (it = pPlayer->getPlayerTeams()->begin(); it != pPlayer->getPlayerTeams()->end(); ++it) + { + for (DLINK_ITERATOR iter = (*it)->iterate_TeamInstanceList(); !iter.done(); iter.advance()) + { Team *team = iter.cur(); if (!team) continue; - for (DLINK_ITERATOR iter = team->iterate_TeamMemberList(); !iter.done(); iter.advance()) { + for (DLINK_ITERATOR iter = team->iterate_TeamMemberList(); !iter.done(); iter.advance()) + { Object *pObj = iter.cur(); - if (!pObj) continue; - if (pObj->isKindOf(KINDOF_AIRCRAFT)) { - if (pObj->isSignificantlyAboveTerrain()) { + if (!pObj) + continue; + if (pObj->isKindOf(KINDOF_AIRCRAFT)) + { + if (pObj->isSignificantlyAboveTerrain()) + { continue; // Don't target flying aircraft. OK if in the airstrip. } } Coord3D pos = *pObj->getPosition(); Real dx = center->x - pos.x; Real dy = center->y - pos.y; - if (dx*dx+dy*dygetTemplate()->calcCostToBuild(pPlayer); - if (pObj->isKindOf(KINDOF_COMMANDCENTER)) { + if (pObj->isKindOf(KINDOF_COMMANDCENTER)) + { value = value/10; // Command centers cannot be killed by any superweapon, so we don't want to target them as highly. jba. } - if (value > 3000) { + if (value > 3000) + { value = value/10; // Superweapons can't be killed by superweapons, so we don't want to value them highly. } cash += factor * value; @@ -1823,7 +1842,10 @@ void AIPlayer::buildBySupplies(Int minimumCash, const AsciiString& thingName) if (valid) break; } } - if (valid) location = newPos; + if (valid) + { + location = newPos; + } TheTerrainVisual->removeAllBibs(); // isLocationLegalToBuild adds bib feedback, turn it off. jba. location.z = 0; // All build list locations are ground relative. m_player->addToPriorityBuildList(thingName, &location, angle); @@ -2255,7 +2277,7 @@ void AIPlayer::recruitSpecificAITeam(TeamPrototype *teamProto, Real recruitRadiu AIUpdateInterface *ai = unit->getAIUpdateInterface(); if (ai) { -#ifdef DEBUG_LOGGING +#if defined(_DEBUG) || defined(_INTERNAL) Coord3D pos = *unit->getPosition(); Coord3D to = teamProto->getTemplateInfo()->m_homeLocation; DEBUG_LOG(("Moving unit from %f,%f to %f,%f\n", pos.x, pos.y , to.x, to.y )); @@ -3449,31 +3471,43 @@ void AIPlayer::getPlayerStructureBounds(Region2D *bounds, Int playerNdx ) objBounds.hi.x = objBounds.lo.x = objBounds.hi.y = objBounds.lo.x = 0; Player* pPlayer = ThePlayerList->getNthPlayer(playerNdx); - if (pPlayer == NULL) return; - for (it = pPlayer->getPlayerTeams()->begin(); it != pPlayer->getPlayerTeams()->end(); ++it) { - for (DLINK_ITERATOR iter = (*it)->iterate_TeamInstanceList(); !iter.done(); iter.advance()) { + if (pPlayer == NULL) + return; + for (it = pPlayer->getPlayerTeams()->begin(); it != pPlayer->getPlayerTeams()->end(); ++it) + { + for (DLINK_ITERATOR iter = (*it)->iterate_TeamInstanceList(); !iter.done(); iter.advance()) + { Team *team = iter.cur(); - if (!team) continue; - for (DLINK_ITERATOR iter = team->iterate_TeamMemberList(); !iter.done(); iter.advance()) { + if (!team) + continue; + for (DLINK_ITERATOR iter = team->iterate_TeamMemberList(); !iter.done(); iter.advance()) + { Object *pObj = iter.cur(); - if (!pObj) continue; - if (pObj->isKindOf(KINDOF_STRUCTURE)) { + if (!pObj) + continue; + if( pObj->isKindOf(KINDOF_STRUCTURE) ) + { Coord3D pos = *pObj->getPosition(); if (firstObject) { objBounds.lo.x = objBounds.hi.x = pos.x; objBounds.lo.y = objBounds.hi.y = pos.y; firstObject = false; - } else { + } + else + { if (objBounds.lo.x>pos.x) objBounds.lo.x = pos.x; if (objBounds.lo.y>pos.y) objBounds.lo.y = pos.y; if (objBounds.hi.xlo.x = bounds->hi.x = pos.x; bounds->lo.y = bounds->hi.y = pos.y; firstStructure = false; - } else { + } + else + { if (bounds->lo.x>pos.x) bounds->lo.x = pos.x; if (bounds->lo.y>pos.y) bounds->lo.y = pos.y; if (bounds->hi.xhi.x = pos.x; diff --git a/Generals/Code/GameEngine/Source/GameLogic/AI/AISkirmishPlayer.cpp b/Generals/Code/GameEngine/Source/GameLogic/AI/AISkirmishPlayer.cpp index df556f9bfa..b501e0fa30 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/AI/AISkirmishPlayer.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/AI/AISkirmishPlayer.cpp @@ -158,7 +158,7 @@ void AISkirmishPlayer::processBaseBuilding( void ) ObjectID builder = bldg->getBuilderID(); Object* myDozer = TheGameLogic->findObjectByID(builder); if (myDozer==NULL) { - DEBUG_LOG(("AI's Dozer got killed. Find another dozer.\n")); + DEBUG_LOG(("AI's Dozer got killed (or captured). Find another dozer.\n")); queueDozer(); myDozer = findDozer(bldg->getPosition()); if (myDozer==NULL || myDozer->getAI()==NULL) { @@ -672,8 +672,8 @@ void AISkirmishPlayer::buildAIBaseDefenseStructure(const AsciiString &thingName, Real s = sin(angle); Real c = cos(angle); - DEBUG_LOG(("Angle is %f sin %f, cos %f \n", 180*angle/PI, s, c)); - DEBUG_LOG(("Offset is %f %f, new is %f, %f \n", + DEBUG_LOG(("buildAIBaseDefenseStructure -- Angle is %f sin %f, cos %f \n", 180*angle/PI, s, c)); + DEBUG_LOG(("buildAIBaseDefenseStructure -- Offset is %f %f, Final Position is %f, %f \n", offset.x, offset.y, offset.x*c - offset.y*s, offset.y*c + offset.x*s @@ -801,7 +801,7 @@ void AISkirmishPlayer::recruitSpecificAITeam(TeamPrototype *teamProto, Real recr AIUpdateInterface *ai = unit->getAIUpdateInterface(); if (ai) { -#ifdef DEBUG_LOGGING +#if defined(_DEBUG) || defined(_INTERNAL) Coord3D pos = *unit->getPosition(); Coord3D to = teamProto->getTemplateInfo()->m_homeLocation; DEBUG_LOG(("Moving unit from %f,%f to %f,%f\n", pos.x, pos.y , to.x, to.y )); diff --git a/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp b/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp index 3d81a08c52..23cb4b1cf6 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp @@ -66,6 +66,7 @@ #include "GameLogic/Module/ContainModule.h" #include "GameLogic/Module/PhysicsUpdate.h" #include "GameLogic/Module/StealthUpdate.h" + #ifdef _INTERNAL // for occasional debugging... //#pragma optimize("", off) @@ -862,7 +863,8 @@ StateReturnType AIStateMachine::updateStateMachine() status = STATE_SUCCESS; } } - if (status==STATE_CONTINUE) { + if (status==STATE_CONTINUE) + { return status; } m_temporaryState->onExit(EXIT_NORMAL); @@ -1724,7 +1726,8 @@ StateReturnType AIInternalMoveToState::update() /// @todo srj -- find a way to sleep for a number of frames here, if possible return STATE_CONTINUE; } - if (thePath==NULL) { + if (thePath==NULL) + { return STATE_FAILURE; } m_waitingForPath = false; @@ -2835,10 +2838,13 @@ StateReturnType AIAttackPursueTargetState::onEnter() } setAdjustsDestination(false); + // Check here: If we are a player, and we got to this state via an ai command (ie we auto-acquired), // we don't want to chase the unit. - if (source->getControllingPlayer()->getPlayerType() == PLAYER_HUMAN) { - if (ai->getLastCommandSource() == CMD_FROM_AI) { + if (source->getControllingPlayer()->getPlayerType() == PLAYER_HUMAN) + { + if (ai->getLastCommandSource() == CMD_FROM_AI) + { return STATE_SUCCESS; } } @@ -4749,6 +4755,7 @@ StateReturnType AIAttackAimAtTargetState::onEnter() Locomotor* curLoco = sourceAI->getCurLocomotor(); m_canTurnInPlace = curLoco ? curLoco->getMinSpeed() == 0.0f : false; + // if (!victim) // return STATE_CONTINUE; // Just continue till we get a victim. // Ick. This was originally a safety to a single line that required victim, and was never meant @@ -4786,6 +4793,7 @@ StateReturnType AIAttackAimAtTargetState::onEnter() WhichTurretType tur = sourceAI->getWhichTurretForCurWeapon(); if (tur != TURRET_INVALID) { + //Order specific turret to attack. if (m_isAttackingObject) { sourceAI->setTurretTargetObject(tur, victim, m_isForceAttacking); diff --git a/Generals/Code/GameEngine/Source/GameLogic/AI/TurretAI.cpp b/Generals/Code/GameEngine/Source/GameLogic/AI/TurretAI.cpp index 433e9c443a..a53d104af9 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/AI/TurretAI.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/AI/TurretAI.cpp @@ -563,9 +563,7 @@ void TurretAI::removeSelfAsTargeter() //---------------------------------------------------------------------------------------------------------- void TurretAI::setTurretTargetObject( Object *victim, Bool forceAttacking ) { - if (!victim || - victim->isEffectivelyDead() || - !isOwnersCurWeaponOnTurret()) + if( !victim || victim->isEffectivelyDead() || !isOwnersCurWeaponOnTurret() ) { victim = NULL; } diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/AutoHealBehavior.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/AutoHealBehavior.cpp index fb13604213..4c8a6d89a3 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/AutoHealBehavior.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/AutoHealBehavior.cpp @@ -44,6 +44,12 @@ #include "GameLogic/Object.h" #include "GameLogic/PartitionManager.h" +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif + //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- struct AutoHealPlayerScanHelper diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/RebuildHoleBehavior.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/RebuildHoleBehavior.cpp index b77d341a3c..84fd37d158 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/RebuildHoleBehavior.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/RebuildHoleBehavior.cpp @@ -217,10 +217,8 @@ UpdateSleepTime RebuildHoleBehavior::update( void ) // if( reconstructing == NULL ) { - newWorkerRespawnProcess( worker ); m_reconstructingID = INVALID_ID; - } // end if } // end if diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/SlowDeathBehavior.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/SlowDeathBehavior.cpp index 0b8b069d47..5dec2158db 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/SlowDeathBehavior.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/SlowDeathBehavior.cpp @@ -479,10 +479,12 @@ UpdateSleepTime SlowDeathBehavior::update() //------------------------------------------------------------------------------------------------- void SlowDeathBehavior::onDie( const DamageInfo *damageInfo ) { + Object *obj = getObject(); + if (!isDieApplicable(damageInfo)) return; - AIUpdateInterface *ai = getObject()->getAIUpdateInterface(); + AIUpdateInterface *ai = obj->getAIUpdateInterface(); if (ai) { // has another AI already handled us. (hopefully another SlowDeathBehavior) @@ -492,10 +494,10 @@ void SlowDeathBehavior::onDie( const DamageInfo *damageInfo ) } // deselect this unit for all players. - TheGameLogic->deselectObject(getObject(), PLAYERMASK_ALL, TRUE); + TheGameLogic->deselectObject(obj, PLAYERMASK_ALL, TRUE); Int total = 0; - BehaviorModule** update = getObject()->getBehaviorModules(); + BehaviorModule** update = obj->getBehaviorModules(); for (; *update; ++update) { SlowDeathBehaviorInterface* sdu = (*update)->getSlowDeathBehaviorInterface(); @@ -510,7 +512,7 @@ void SlowDeathBehavior::onDie( const DamageInfo *damageInfo ) // this returns a value from 1...total, inclusive Int roll = GameLogicRandomValue(1, total); - for (/* UpdateModuleInterface** */ update = getObject()->getBehaviorModules(); *update; ++update) + for (/* UpdateModuleInterface** */ update = obj->getBehaviorModules(); *update; ++update) { SlowDeathBehaviorInterface* sdu = (*update)->getSlowDeathBehaviorInterface(); if (sdu != NULL && sdu->isDieApplicable(damageInfo)) diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp index f02e3de162..22e10458f9 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp @@ -766,14 +766,10 @@ void ActiveBody::createParticleSystems( const AsciiString &boneBaseName, { // pick a bone index to place this particle system at - // MDC: moving to GameLogicRandomValue. This does not need to be synced, but having it so makes searches *so* much nicer. - //Int boneIndex = GameLogicRandomValue( 0, maxSystems - i - 1 ); - // DTEH: Moved back to GameClientRandomValue because of desync problems. July 27th 2003. Int boneIndex = GameClientRandomValue( 0, maxSystems - i - 1 ); - // find the actual bone location to use and mark that bone index as used Int count = 0; Int j = 0; diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Collide/CrateCollide/CrateCollide.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Collide/CrateCollide/CrateCollide.cpp index d44ab0f2dc..288238e811 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Collide/CrateCollide/CrateCollide.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Collide/CrateCollide/CrateCollide.cpp @@ -39,6 +39,12 @@ #include "GameLogic/Object.h" #include "GameLogic/Module/CrateCollide.h" +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif + //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- CrateCollideModuleData::CrateCollideModuleData() diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Contain/GarrisonContain.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Contain/GarrisonContain.cpp index 626230a42f..5477b7cd2c 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Contain/GarrisonContain.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Contain/GarrisonContain.cpp @@ -854,7 +854,6 @@ UpdateSleepTime GarrisonContain::update( void ) // remove if dead if( contained->isEffectivelyDead() ) { - // remove from container removeFromContain( contained ); @@ -1254,6 +1253,7 @@ void GarrisonContain::exitObjectViaDoor( Object *exitObj, ExitDoorType exitDoor Coord3D endPosition; Real exitAngle = getObject()->getOrientation(); + // Garrison doesn't have reserveDoor or exitDelay, so if we do nothing, everyone will appear on top // of each other and get stuck inside each others' extent (except for the first guy). So we'll // scatter the start point around a little to make it better. diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Contain/OverlordContain.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Contain/OverlordContain.cpp index f093146131..9b63a0b9f6 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Contain/OverlordContain.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Contain/OverlordContain.cpp @@ -43,6 +43,14 @@ #include "GameLogic/Object.h" #include "GameLogic/PartitionManager.h" + +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif + + // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ OverlordContainModuleData::OverlordContainModuleData() diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Contain/TransportContain.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Contain/TransportContain.cpp index 071ac662f2..9bb7d25921 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Contain/TransportContain.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Contain/TransportContain.cpp @@ -409,7 +409,6 @@ UpdateSleepTime TransportContain::update() } } } - return OpenContain::update(); //extend } diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Create/GrantUpgradeCreate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Create/GrantUpgradeCreate.cpp index a1c47c7cc8..84e3aed3f4 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Create/GrantUpgradeCreate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Create/GrantUpgradeCreate.cpp @@ -96,10 +96,10 @@ void GrantUpgradeCreate::onCreate( void ) return; } + Player *player = getObject()->getControllingPlayer(); if( upgradeTemplate->getUpgradeType() == UPGRADE_TYPE_PLAYER ) { // get the player - Player *player = getObject()->getControllingPlayer(); player->addUpgrade( upgradeTemplate, UPGRADE_STATUS_COMPLETE ); } else diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Die/CreateObjectDie.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Die/CreateObjectDie.cpp index 6444b3010c..84d8a85b17 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Die/CreateObjectDie.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Die/CreateObjectDie.cpp @@ -37,6 +37,12 @@ #include "GameLogic/Object.h" #include "GameLogic/ObjectCreationList.h" +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif + // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ CreateObjectDieModuleData::CreateObjectDieModuleData() diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Die/DestroyDie.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Die/DestroyDie.cpp index 9124420c6e..dcef87fd17 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Die/DestroyDie.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Die/DestroyDie.cpp @@ -35,6 +35,12 @@ #include "GameLogic/GameLogic.h" #include "GameLogic/Module/DestroyDie.h" +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif + //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- DestroyDie::DestroyDie( Thing *thing, const ModuleData* moduleData ) : DieModule( thing, moduleData ) @@ -52,9 +58,10 @@ DestroyDie::~DestroyDie( void ) //------------------------------------------------------------------------------------------------- void DestroyDie::onDie( const DamageInfo *damageInfo ) { + Object *obj = getObject(); if (!isDieApplicable(damageInfo)) return; - TheGameLogic->destroyObject(getObject()); + TheGameLogic->destroyObject( obj ); } // ------------------------------------------------------------------------------------------------ diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/FiringTracker.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/FiringTracker.cpp index 040dfbbe94..8eda3fbc01 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/FiringTracker.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/FiringTracker.cpp @@ -84,6 +84,7 @@ Int FiringTracker::getNumConsecutiveShotsAtVictim( const Object *victim ) const void FiringTracker::shotFired(const Weapon* weaponFired, ObjectID victimID) { UnsignedInt now = TheGameLogic->getFrame(); + Object *me = getObject(); if( victimID == m_victimID ) { @@ -117,7 +118,7 @@ void FiringTracker::shotFired(const Weapon* weaponFired, ObjectID victimID) Int shotsNeededOne = weaponFired->getContinuousFireOneShotsNeeded(); Int shotsNeededTwo = weaponFired->getContinuousFireTwoShotsNeeded(); - if( getObject()->testWeaponBonusCondition( WEAPONBONUSCONDITION_CONTINUOUS_FIRE_MEAN ) ) + if( me->testWeaponBonusCondition( WEAPONBONUSCONDITION_CONTINUOUS_FIRE_MEAN ) ) { // Can either go up or down from here. if( m_consecutiveShots < shotsNeededOne ) @@ -125,7 +126,7 @@ void FiringTracker::shotFired(const Weapon* weaponFired, ObjectID victimID) else if( m_consecutiveShots > shotsNeededTwo ) speedUp(); } - else if( getObject()->testWeaponBonusCondition( WEAPONBONUSCONDITION_CONTINUOUS_FIRE_FAST ) ) + else if( me->testWeaponBonusCondition( WEAPONBONUSCONDITION_CONTINUOUS_FIRE_FAST ) ) { // Only place I can go here from here is all the way down if( m_consecutiveShots < shotsNeededTwo ) @@ -161,7 +162,7 @@ void FiringTracker::shotFired(const Weapon* weaponFired, ObjectID victimID) } - setWakeFrame(getObject(), calcTimeToSleep()); + setWakeFrame(me, calcTimeToSleep()); } //------------------------------------------------------------------------------------------------- diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Locomotor.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Locomotor.cpp index 04e1f54f1e..8e8541c876 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Locomotor.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Locomotor.cpp @@ -2553,6 +2553,14 @@ void Locomotor::maintainCurrentPositionHover(Object* obj, PhysicsBehavior *physi force.y = accelForce * dir->y; force.z = 0.0f; + + // Apply a random kick (if applicable) to dirty-up visually. + // The idea is that chopper pilots have to do course corrections all the time + // Because of changes in wind, pressure, etc. + // Those changes are added here, then the + + + // apply forces to object physics->applyMotiveForce( &force ); } diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Object.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Object.cpp index 1d82f890e3..5f4be5249c 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Object.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Object.cpp @@ -262,8 +262,8 @@ Object::Object( const ThingTemplate *tt, const ObjectStatusMaskType &objectStatu m_constructionPercent = CONSTRUCTION_COMPLETE; // complete by default - m_visionRange = tt->friend_getVisionRange(); - m_shroudClearingRange = tt->friend_getShroudClearingRange(); + m_visionRange = tt->friend_calcVisionRange(); + m_shroudClearingRange = tt->friend_calcShroudClearingRange(); if( m_shroudClearingRange == -1.0f ) m_shroudClearingRange = m_visionRange;// Backwards compatible, and perfectly logical default to assign m_shroudRange = 0.0f; @@ -284,6 +284,7 @@ Object::Object( const ThingTemplate *tt, const ObjectStatusMaskType &objectStatu // pool[]ify m_behaviors = MSGNEW("ModulePtrs") BehaviorModule*[totalModules + 1]; BehaviorModule** curB = m_behaviors; + const ModuleInfo& mi = tt->getBehaviorModuleInfo(); // set m_team to null before the first call, to avoid naughtiness... // If no team is specified in the constructor, then assign the object @@ -343,7 +344,6 @@ Object::Object( const ThingTemplate *tt, const ObjectStatusMaskType &objectStatu // behaviors are always done first, so they get into the publicModule arrays // before anything else. - const ModuleInfo& mi = tt->getBehaviorModuleInfo(); for (modIdx = 0; modIdx < mi.getCount(); ++modIdx) { modName = mi.getNthName(modIdx); @@ -377,7 +377,10 @@ Object::Object( const ThingTemplate *tt, const ObjectStatusMaskType &objectStatu AIUpdateInterface* ai = newMod->getAIUpdateInterface(); if (ai) { - DEBUG_ASSERTCRASH(m_ai == NULL, ("You should never have more than one AI module (srj)\n")); + if( m_ai ) + { + DEBUG_ASSERTCRASH( m_ai == NULL, ("%s has more than one AI module. This is illegal!\n", getTemplate()->getName().str()) ); + } m_ai = ai; } @@ -603,34 +606,6 @@ Object::~Object() TheScriptEngine->notifyOfObjectDestruction(this); } -//------------------------------------------------------------------------------------------------- -void localIsHero( Object *obj, void* userData ) -{ - Bool *hero = (Bool*)userData; - - if( obj && obj->isKindOf( KINDOF_HERO ) ) - { - *hero = TRUE; - } -} - -//------------------------------------------------------------------------------------------------- -Bool Object::isHero() const -{ - ContainModuleInterface *contain = getContain(); - if( contain ) - { - Bool heroInside = FALSE; - contain->iterateContained( localIsHero, (void*)(&heroInside), FALSE ); - if( heroInside ) - { - return TRUE; - } - } - return isKindOf( KINDOF_HERO ); -} - - //------------------------------------------------------------------------------------------------- /// this object now contained in "containedBy" //------------------------------------------------------------------------------------------------- @@ -1835,6 +1810,32 @@ Bool Object::isNonFactionStructure(void) const return isStructure() && !isFactionStructure(); } +void localIsHero( Object *obj, void* userData ) +{ + Bool *hero = (Bool*)userData; + + if( obj && obj->isKindOf( KINDOF_HERO ) ) + { + *hero = TRUE; + } +} + +//------------------------------------------------------------------------------------------------- +Bool Object::isHero(void) const +{ + ContainModuleInterface *contain = getContain(); + if( contain ) + { + Bool heroInside = FALSE; + contain->iterateContained( localIsHero, (void*)(&heroInside), FALSE ); + if( heroInside ) + { + return TRUE; + } + } + return isKindOf( KINDOF_HERO ); +} + //------------------------------------------------------------------------------------------------- void Object::setReceivingDifficultyBonus(Bool receive) { @@ -4614,7 +4615,7 @@ SpecialPowerModuleInterface *Object::getSpecialPowerModule( const SpecialPowerTe return NULL; // search the modules for the one with the matching template - for (BehaviorModule** m = m_behaviors; *m; ++m) + for( BehaviorModule** m = m_behaviors; *m; ++m ) { SpecialPowerModuleInterface* sp = (*m)->getSpecialPower(); if (!sp) @@ -4818,6 +4819,7 @@ void Object::doCommandButton( const CommandButton *commandButton, CommandSourceT default: break; } + DEBUG_CRASH( ("WARNING: Script doCommandButton for button %s not implemented. Doing nothing.", commandButton->getName().str()) ); } } @@ -4897,6 +4899,7 @@ void Object::doCommandButtonAtObject( const CommandButton *commandButton, Object default: break; } + DEBUG_CRASH( ("WARNING: Script doCommandButtonAtObject for button %s not implemented. Doing nothing.", commandButton->getName().str()) ); } } @@ -5203,6 +5206,15 @@ Int Object::getMultiLogicalBonePosition(const char* boneNamePrefix, Int maxBones } } +//============================================================================= +const AsciiString& Object::getCommandSetString() const +{ + if (m_commandSetStringOverride.isNotEmpty()) + return m_commandSetStringOverride; + + return getTemplate()->friend_getCommandSetString(); +} + //============================================================================= Bool Object::canProduceUpgrade( const UpgradeTemplate *upgrade ) { @@ -5215,22 +5227,12 @@ Bool Object::canProduceUpgrade( const UpgradeTemplate *upgrade ) if( button && ( (button->getCommandType() == GUI_COMMAND_PLAYER_UPGRADE) || (button->getCommandType() == GUI_COMMAND_OBJECT_UPGRADE) ) // Or else a button that requires an upgrade will appear the same as a button that gives an upgrade && button->getUpgradeTemplate() - && (button->getUpgradeTemplate() == upgrade) - ) + && (button->getUpgradeTemplate() == upgrade) ) return TRUE; // getUpgradeTemplate only returns something if it is actually an upgrade } return FALSE;// Cheatin' punk. } - - //============================================================================= -const AsciiString& Object::getCommandSetString() const -{ - if (m_commandSetStringOverride.isNotEmpty()) - return m_commandSetStringOverride; - - return getTemplate()->friend_getCommandSetString(); -} //============================================================================= // Object::defect, and related methods = diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/SpecialPower/OCLSpecialPower.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/SpecialPower/OCLSpecialPower.cpp index 4e86a03c44..7196e3b3f0 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/SpecialPower/OCLSpecialPower.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/SpecialPower/OCLSpecialPower.cpp @@ -154,14 +154,13 @@ void OCLSpecialPower::doSpecialPowerAtLocation( const Coord3D *loc, UnsignedInt if( loc == NULL ) return; + // get the module data + const OCLSpecialPowerModuleData *modData = getOCLSpecialPowerModuleData(); // call the base class action cause we are *EXTENDING* functionality SpecialPowerModule::doSpecialPowerAtLocation( loc, commandOptions ); const ObjectCreationList* ocl = findOCL(); - // get the module data - const OCLSpecialPowerModuleData *modData = getOCLSpecialPowerModuleData(); - // at what point will the "deliverer" come in Coord3D creationCoord; switch (modData->m_createLoc) @@ -265,3 +264,4 @@ void OCLSpecialPower::loadPostProcess( void ) SpecialPowerModule::loadPostProcess(); } // end loadPostProcess + diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialAbility.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialAbility.cpp index 861ac413c3..1a48007469 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialAbility.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialAbility.cpp @@ -39,6 +39,11 @@ /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp index 32b81cd5f2..51b1167ced 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/SpecialPower/SpecialPowerModule.cpp @@ -301,7 +301,7 @@ Bool SpecialPowerModule::isReady() const //------------------------------------------------------------------------------------------------- Real SpecialPowerModule::getPercentReady() const { -#if defined(_DEBUG) || defined(_INTERNAL) +#if defined(_DEBUG) || defined(_INTERNAL) || defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE) if( TheGlobalData->m_specialPowerUsesDelay == FALSE ) return 1.0f; #endif @@ -310,8 +310,10 @@ Real SpecialPowerModule::getPercentReady() const if( isReady() ) return 1.0f; - if ( m_pausedCount > 0 ) + if( m_pausedCount > 0 ) + { return m_pausedPercent; + } // get the module data const SpecialPowerModuleData *modData = getSpecialPowerModuleData(); @@ -349,7 +351,7 @@ Real SpecialPowerModule::getPercentReady() const //------------------------------------------------------------------------------------------------- void SpecialPowerModule::startPowerRecharge() { -#if defined(_DEBUG) || defined(_INTERNAL) +#if defined(_DEBUG) || defined(_INTERNAL) || defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE) // this is a cheat ... remove this for release! if( TheGlobalData->m_specialPowerUsesDelay == FALSE ) return; @@ -472,7 +474,7 @@ void SpecialPowerModule::createViewObject( const Coord3D *location ) //------------------------------------------------------------------------------------------------- void SpecialPowerModule::markSpecialPowerTriggered( const Coord3D *location ) { - triggerSpecialPower(location); + triggerSpecialPower( location ); } diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DeliverPayloadAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DeliverPayloadAIUpdate.cpp index 65a5933674..e312a2ce87 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DeliverPayloadAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DeliverPayloadAIUpdate.cpp @@ -38,12 +38,12 @@ #include "GameClient/FXList.h" #include "GameClient/InGameUI.h" #include "GameLogic/Locomotor.h" -#include "GameLogic/Module/BodyModule.h" -#include "GameLogic/Module/ContainModule.h" -#include "GameLogic/Module/DeliverPayloadAIUpdate.h" #include "GameLogic/Module/GenerateMinefieldBehavior.h" -#include "GameLogic/Module/PhysicsUpdate.h" +#include "GameLogic/Module/DeliverPayloadAIUpdate.h" #include "GameLogic/Module/ParachuteContain.h" +#include "GameLogic/Module/ContainModule.h" +#include "GameLogic/Module/PhysicsUpdate.h" +#include "GameLogic/Module/BodyModule.h" #include "GameLogic/Object.h" #include "GameLogic/PartitionManager.h" #include "GameLogic/Weapon.h" diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp index bf6870b8ce..bb8a21a1ce 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/DozerAIUpdate.cpp @@ -2115,6 +2115,9 @@ void DozerAIUpdate::internalCancelTask( DozerTask task ) // sanity DEBUG_ASSERTCRASH( task >= 0 && task < DOZER_NUM_TASKS, ("Illegal dozer task '%d'\n", task) ); + if(task < 0 || task >= DOZER_NUM_TASKS) + return; //DAMNIT! You CANNOT assert and then not handle the damn error! The. Code. Must. Not. Crash. + if(task < 0 || task >= DOZER_NUM_TASKS) return; //DAMNIT! You CANNOT assert and then not handle the damn error! The. Code. Must. Not. Crash. diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp index 4fec10cdb7..9bba6cf52e 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp @@ -85,9 +85,26 @@ enum JetAIStateType CPP_11(: Int) JETAISTATETYPE_LAST }; + +//------------------------------------------------------------------------------------------------- +Bool JetAIUpdate::getFlag( FlagType f ) const +{ + return (m_flags & (1<getWeaponInWeaponSlot((WeaponSlotType)i); + const Weapon* weapon = jet->getWeaponInWeaponSlot((WeaponSlotType)i); if (weapon == NULL || weapon->getReloadType() != RETURN_TO_BASE_TO_RELOAD) continue; ++specials; @@ -300,7 +317,7 @@ class JetOrHeliCirclingDeadAirfieldState : public State // it might not have an owning airfield, and it might be trying to return // simply due to being idle, not out of ammo. so check and don't die in that // case, but just punt back out to idle. - if (!isOutOfSpecialReloadAmmo(jet) && jet->getProducerID() == INVALID_ID) + if (!jetAI->isOutOfSpecialReloadAmmo() && jet->getProducerID() == INVALID_ID) { return STATE_FAILURE; } @@ -1656,7 +1673,7 @@ UpdateSleepTime JetAIUpdate::update() } // note that we might still have weapons with ammo, but still be forced to return to reload. - if (isOutOfSpecialReloadAmmo(jet) && getFlag(ALLOW_AIR_LOCO)) + if (isOutOfSpecialReloadAmmo() && getFlag(ALLOW_AIR_LOCO)) { m_returnToBaseFrame = 0; @@ -1682,7 +1699,7 @@ UpdateSleepTime JetAIUpdate::update() else if (m_returnToBaseFrame != 0 && now >= m_returnToBaseFrame && getFlag(ALLOW_AIR_LOCO)) { m_returnToBaseFrame = 0; - DEBUG_ASSERTCRASH(isOutOfSpecialReloadAmmo(jet) == false, ("Hmm, this seems unlikely -- isOutOfSpecialReloadAmmo(jet)==false")); + DEBUG_ASSERTCRASH(isOutOfSpecialReloadAmmo() == false, ("Hmm, this seems unlikely -- isOutOfSpecialReloadAmmo()==false")); setFlag(USE_SPECIAL_RETURN_LOCO, false); setLastCommandSource( CMD_FROM_AI ); getStateMachine()->setState(RETURNING_FOR_LANDING); @@ -1700,7 +1717,7 @@ UpdateSleepTime JetAIUpdate::update() } m_returnToBaseFrame = 0; if (getFlag(ALLOW_INTERRUPT_AND_RESUME_OF_CUR_STATE_FOR_RELOAD) && - isOutOfSpecialReloadAmmo(jet) && getFlag(ALLOW_AIR_LOCO)) + isOutOfSpecialReloadAmmo() && getFlag(ALLOW_AIR_LOCO)) { setFlag(USE_SPECIAL_RETURN_LOCO, true); setFlag(HAS_PENDING_COMMAND, true); @@ -2101,7 +2118,7 @@ void JetAIUpdate::doLandingCommand(Object *airfield, CommandSourceType cmdSource } getObject()->setProducer(airfield); - DEBUG_ASSERTCRASH(isOutOfSpecialReloadAmmo(getObject()) == false, ("Hmm, this seems unlikely -- isOutOfSpecialReloadAmmo(jet)==false")); + DEBUG_ASSERTCRASH(isOutOfSpecialReloadAmmo() == false, ("Hmm, this seems unlikely -- isOutOfSpecialReloadAmmo()==false")); setFlag(USE_SPECIAL_RETURN_LOCO, false); setFlag(ALLOW_INTERRUPT_AND_RESUME_OF_CUR_STATE_FOR_RELOAD, false); setLastCommandSource( cmdSource ); diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/RailroadGuideAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/RailroadGuideAIUpdate.cpp index 2838c0a558..6caa757dae 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/RailroadGuideAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/RailroadGuideAIUpdate.cpp @@ -318,7 +318,6 @@ void RailroadBehavior::onCollide( Object *other, const Coord3D *loc, const Coord dlt.y = theirLoc->y - myLoc->y; dlt.z = theirLoc->z - myLoc->z; - //Alert all the players of recent disaster if ( ! m_whistleSound.isCurrentlyPlaying()) m_whistleSound.setPlayingHandle(TheAudio->addAudioEvent( &m_whistleSound )); diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/SupplyTruckAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/SupplyTruckAIUpdate.cpp index 6755ef023f..af8a0fc1d2 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/SupplyTruckAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/SupplyTruckAIUpdate.cpp @@ -47,7 +47,9 @@ //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") #endif +#if defined(_DEBUG) || defined(_INTERNAL) #define NO_DEBUG_SUPPLY_STATE +#endif #ifdef DEBUG_SUPPLY_STATE static const char* statenames[] = diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp index d69e915e23..9e8f53d21b 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/WorkerAIUpdate.cpp @@ -777,6 +777,9 @@ void WorkerAIUpdate::internalCancelTask( DozerTask task ) // sanity DEBUG_ASSERTCRASH( task >= 0 && task < DOZER_NUM_TASKS, ("Illegal dozer task '%d'\n", task) ); + if(task < 0 || task >= DOZER_NUM_TASKS) + return; //DAMNIT! You CANNOT assert and then not handle the damn error! The. Code. Must. Not. Crash. + if(task < 0 || task >= DOZER_NUM_TASKS) return; //DAMNIT! You CANNOT assert and then not handle the damn error! The. Code. Must. Not. Crash. diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AssistedTargetingUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AssistedTargetingUpdate.cpp index f63b490d33..62935b8fcb 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AssistedTargetingUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AssistedTargetingUpdate.cpp @@ -41,6 +41,15 @@ #include "GameLogic/Module/AssistedTargetingUpdate.h" #include "GameLogic/Module/LaserUpdate.h" + +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif + + + //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- void AssistedTargetingUpdateModuleData::buildFieldParse(MultiIniFieldParse& p) @@ -96,6 +105,7 @@ void AssistedTargetingUpdate::assistAttack( const Object *requestingObject, Obje me->setWeaponLock( md->m_weaponSlot, LOCKED_TEMPORARILY ); me->getAI()->aiAttackObject( victimObject, md->m_clipSize, CMD_FROM_AI ); + if( md->m_laserFromAssisted ) makeFeedbackLaser( md->m_laserFromAssisted, requestingObject, me ); if( md->m_laserToTarget ) diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AutoDepositUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AutoDepositUpdate.cpp index 5ce3820628..6d6a036eb4 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AutoDepositUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AutoDepositUpdate.cpp @@ -116,6 +116,7 @@ void AutoDepositUpdate::awardInitialCaptureBonus( Player *player ) //------------------------------------------------------------------------------------------------- UpdateSleepTime AutoDepositUpdate::update( void ) { + const AutoDepositUpdateModuleData *modData = getAutoDepositUpdateModuleData(); /// @todo srj use SLEEPY_UPDATE here if( TheGameLogic->getFrame() >= m_depositOnFrame) { @@ -125,30 +126,31 @@ UpdateSleepTime AutoDepositUpdate::update( void ) m_awardInitialCaptureBonus = TRUE; m_initialized = TRUE; } - m_depositOnFrame = TheGameLogic->getFrame() + getAutoDepositUpdateModuleData()->m_depositFrame; + m_depositOnFrame = TheGameLogic->getFrame() + modData->m_depositFrame; - if(getObject()->isNeutralControlled() || getAutoDepositUpdateModuleData()->m_depositAmount <= 0 ) + if(getObject()->isNeutralControlled() || modData->m_depositAmount <= 0 ) return UPDATE_SLEEP_NONE; // makes sure that buildings under construction do not get a bonus CCB if( getObject()->getConstructionPercent() != CONSTRUCTION_COMPLETE ) return UPDATE_SLEEP_NONE; - getObject()->getControllingPlayer()->getMoney()->deposit( getAutoDepositUpdateModuleData()->m_depositAmount); - getObject()->getControllingPlayer()->getScoreKeeper()->addMoneyEarned( getAutoDepositUpdateModuleData()->m_depositAmount); + int moneyAmount = modData->m_depositAmount; + + getObject()->getControllingPlayer()->getMoney()->deposit( moneyAmount ); + getObject()->getControllingPlayer()->getScoreKeeper()->addMoneyEarned( modData->m_depositAmount); //Display cash income floating over the blacklotus - if(getAutoDepositUpdateModuleData()->m_depositAmount > 0) + if(moneyAmount > 0) { UnicodeString moneyString; - moneyString.format( TheGameText->fetch( "GUI:AddCash" ), getAutoDepositUpdateModuleData()->m_depositAmount ); + moneyString.format( TheGameText->fetch( "GUI:AddCash" ), moneyAmount ); Coord3D pos; pos.set( getObject()->getPosition() ); pos.z += 10.0f; //add a little z to make it show up above the unit. Color color = getObject()->getControllingPlayer()->getPlayerColor() | GameMakeColor( 0, 0, 0, 230 ); TheInGameUI->addFloatingText( moneyString, &pos, color ); } - } return UPDATE_SLEEP_NONE; diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/DockUpdate/DockUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/DockUpdate/DockUpdate.cpp index 1e9131b938..cd3ce51f59 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/DockUpdate/DockUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/DockUpdate/DockUpdate.cpp @@ -491,7 +491,8 @@ Coord3D DockUpdate::computeApproachPosition( Int positionIndex, Object *forWhom // ------------------------------------------------------------------------------------------------ void DockUpdate::loadDockPositions() { - Drawable *myDrawable = getObject()->getDrawable(); + Object *obj = getObject(); + Drawable *myDrawable = obj->getDrawable(); if (myDrawable) { diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/DockUpdate/SupplyCenterDockUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/DockUpdate/SupplyCenterDockUpdate.cpp index 598e226494..3cf1185f83 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/DockUpdate/SupplyCenterDockUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/DockUpdate/SupplyCenterDockUpdate.cpp @@ -37,6 +37,12 @@ #include "GameClient/InGameUI.h" #include "GameClient/GameText.h" +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif + // ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------ SupplyCenterDockUpdateModuleData::SupplyCenterDockUpdateModuleData( void ) diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/FireOCLAfterWeaponCooldownUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/FireOCLAfterWeaponCooldownUpdate.cpp index e0bbaa0780..9e6c42bf91 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/FireOCLAfterWeaponCooldownUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/FireOCLAfterWeaponCooldownUpdate.cpp @@ -51,6 +51,12 @@ #include "GameLogic/Module/AIUpdate.h" #include "GameLogic/Module/BodyModule.h" +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif + //------------------------------------------------------------------------------------------------- FireOCLAfterWeaponCooldownUpdateModuleData::FireOCLAfterWeaponCooldownUpdateModuleData() { diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/LaserUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/LaserUpdate.cpp index 00b90a3b41..dc6c578bea 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/LaserUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/LaserUpdate.cpp @@ -40,6 +40,12 @@ #include "GameLogic/Module/LaserUpdate.h" #include "WWMath/vector3.h" +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif + //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- LaserUpdateModuleData::LaserUpdateModuleData() @@ -243,6 +249,7 @@ void LaserUpdate::initLaser( const Object *parent, const Coord3D *startPos, cons } //Adjust the position of any existing particle system. + //PLEASE NOTE You cannot check an ID for NULL. This should be a check against INVALID_PARTICLE_SYSTEM_ID. Can't change it on the last day without a bug though. if( m_particleSystemID ) { system = TheParticleSystemManager->findParticleSystem( m_particleSystemID ); @@ -251,6 +258,8 @@ void LaserUpdate::initLaser( const Object *parent, const Coord3D *startPos, cons system->setPosition( &m_startPos ); } } + + //PLEASE NOTE You cannot check an ID for NULL. This should be a check against INVALID_PARTICLE_SYSTEM_ID. Can't change it on the last day without a bug though. if( m_targetParticleSystemID ) { system = TheParticleSystemManager->findParticleSystem( m_targetParticleSystemID ); diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/MissileLauncherBuildingUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/MissileLauncherBuildingUpdate.cpp index beaa99eb13..c2a87c9f3b 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/MissileLauncherBuildingUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/MissileLauncherBuildingUpdate.cpp @@ -205,7 +205,12 @@ void MissileLauncherBuildingUpdate::switchToState(DoorStateType dst) //------------------------------------------------------------------------------------------------- void MissileLauncherBuildingUpdate::initiateIntentToDoSpecialPower( const SpecialPowerTemplate *specialPowerTemplate, const Object *targetObj, const Coord3D *targetPos, UnsignedInt commandOptions, Int locationCount ) { -#if defined(_DEBUG) || defined(_INTERNAL) + if( m_specialPowerModule->getSpecialPowerTemplate() != specialPowerTemplate ) + { + return; + } + +#if defined(_DEBUG) || defined(_INTERNAL) || defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE) DEBUG_ASSERTCRASH(!TheGlobalData->m_specialPowerUsesDelay || m_doorState == DOOR_OPEN, ("door is not fully open when specialpower is fired!")); #endif @@ -250,7 +255,7 @@ UpdateSleepTime MissileLauncherBuildingUpdate::update( void ) switchToState(m_timeoutState); } -#if defined(_DEBUG) || defined(_INTERNAL) +#if defined(_DEBUG) || defined(_INTERNAL) || defined(_ALLOW_DEBUG_CHEATS_IN_RELEASE) DEBUG_ASSERTCRASH(!TheGlobalData->m_specialPowerUsesDelay || !(m_specialPowerModule->isReady() && m_doorState != DOOR_OPEN), ("door is not fully open when specialpower is ready!")); #endif diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ProductionExitUpdate/SupplyCenterProductionExitUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ProductionExitUpdate/SupplyCenterProductionExitUpdate.cpp index 9a894e87e2..cf68fdd520 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ProductionExitUpdate/SupplyCenterProductionExitUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ProductionExitUpdate/SupplyCenterProductionExitUpdate.cpp @@ -42,6 +42,12 @@ #include "GameLogic/Object.h" //#include "GameLogic/PartitionManager.h" +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif + //------------------------------------------------------------------------------------------------- SupplyCenterProductionExitUpdate::SupplyCenterProductionExitUpdate( Thing *thing, const ModuleData* moduleData ) : UpdateModule( thing, moduleData ) { diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ProductionUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ProductionUpdate.cpp index 7d953dce32..aca60a4a36 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ProductionUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/ProductionUpdate.cpp @@ -1152,8 +1152,7 @@ void ProductionUpdate::cancelAndRefundAllProduction( void ) else { // unknown production type - DEBUG_CRASH(( "ProductionUpdate::cancelAndRefundAllProduction - Unknown production type '%d'\n", - m_productionQueue->getProductionType() )); + DEBUG_CRASH(( "ProductionUpdate::cancelAndRefundAllProduction - Unknown production type '%d'\n", m_productionQueue->getProductionType() )); return; } // end else } // end if diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/SpyVisionUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/SpyVisionUpdate.cpp index f5d341a455..14530ef8ae 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/SpyVisionUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/SpyVisionUpdate.cpp @@ -38,6 +38,12 @@ #include "GameLogic/GameLogic.h" #include "GameLogic/Module/SpyVisionUpdate.h" +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif + //------------------------------------------------------------------------------------------------- //------------------------------------------------------------------------------------------------- void SpyVisionUpdateModuleData::buildFieldParse(MultiIniFieldParse& p) diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/StealthDetectorUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/StealthDetectorUpdate.cpp index 797d488f31..e9966e97d5 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/StealthDetectorUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/StealthDetectorUpdate.cpp @@ -239,7 +239,6 @@ UpdateSleepTime StealthDetectorUpdate::update( void ) // do audio and UI message if we need to do feedback if( doFeedback ) { - // audio msg static AudioEventRTS discoveredSound = TheAudio->getMiscAudio()->m_stealthDiscoveredSound; discoveredSound.setPlayerIndex( self->getControllingPlayer()->getPlayerIndex() ); diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/StealthUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/StealthUpdate.cpp index 96f8ca46ba..da3b7682ab 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/StealthUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/StealthUpdate.cpp @@ -501,7 +501,6 @@ UpdateSleepTime StealthUpdate::update( void ) } - Bool detectedStatusChangedThisFrame = FALSE; if (m_detectionExpiresFrame > now) { @@ -592,6 +591,7 @@ void setWakeupIfInRange( Object *obj, void *userData) // } } + //------------------------------------------------------------------------------------------------- void StealthUpdate::markAsDetected(UnsignedInt numFrames) { diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/StickyBombUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/StickyBombUpdate.cpp index eec1ecc046..e4e7ace2ae 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/StickyBombUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/StickyBombUpdate.cpp @@ -30,12 +30,13 @@ // USER INCLUDES ////////////////////////////////////////////////////////////////////////////////// #include "PreRTS.h" // This must go first in EVERY cpp file int the GameEngine +#include "GameLogic/Module/StickyBombUpdate.h" + #include "Common/ThingTemplate.h" #include "Common/Xfer.h" #include "GameClient/Drawable.h" #include "GameClient/InGameUI.h" #include "GameLogic/Object.h" -#include "GameLogic/Module/StickyBombUpdate.h" #include "GameLogic/Module/LifetimeUpdate.h" #include "GameLogic/Module/AIUpdate.h" #include "GameLogic/Module/BodyModule.h" diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Upgrade/ArmorUpgrade.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Upgrade/ArmorUpgrade.cpp index aa41b12e2b..ee438b1208 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Upgrade/ArmorUpgrade.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Upgrade/ArmorUpgrade.cpp @@ -90,6 +90,7 @@ void ArmorUpgrade::upgradeImplementation( ) Object *obj = getObject(); if( !obj ) return; + BodyModuleInterface* body = obj->getBodyModule(); if ( body ) body->setArmorSetFlag( ARMORSET_PLAYER_UPGRADE ); diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Upgrade/UpgradeModule.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Upgrade/UpgradeModule.cpp index 00d5359b90..dc0d638232 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Upgrade/UpgradeModule.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Upgrade/UpgradeModule.cpp @@ -160,6 +160,15 @@ Bool UpgradeMux::wouldUpgrade( UpgradeMaskType keyMask ) const return FALSE; } +//------------------------------------------------------------------------------------------------- +void UpgradeMux::giveSelfUpgrade() +{ + // If I have an activation condition, and I haven't activated, and this key matches my condition. + performUpgradeFX(); + upgradeImplementation(); + setUpgradeExecuted(true); +} + //------------------------------------------------------------------------------------------------- Bool UpgradeMux::testUpgradeConditions( UpgradeMaskType keyMask ) const { diff --git a/Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptActions.cpp b/Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptActions.cpp index 479049651c..6d637b19be 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptActions.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptActions.cpp @@ -4831,17 +4831,20 @@ void ScriptActions::doSetToppleDirection( const AsciiString& unitName, const Coo void ScriptActions::doMoveUnitTowardsNearest( const AsciiString& unitName, const AsciiString& objectType, AsciiString triggerName) { Object *obj = TheScriptEngine->getUnitNamed(unitName); - if (!obj) { + if (!obj) + { return; } AIUpdateInterface *ai = obj->getAIUpdateInterface(); - if (!ai) { + if (!ai) + { return; } - const ThingTemplate *templ = TheThingFactory->findTemplate(objectType); - if (!templ) { + const ThingTemplate *templ = TheThingFactory->findTemplate( objectType, FALSE ); + if ( !templ ) + { return; } @@ -4875,7 +4878,7 @@ void ScriptActions::doMoveTeamTowardsNearest( const AsciiString& teamName, const return; } - const ThingTemplate *templ = TheThingFactory->findTemplate(objectType); + const ThingTemplate *templ = TheThingFactory->findTemplate( objectType, FALSE ); if (!templ) { return; } @@ -5328,7 +5331,7 @@ void ScriptActions::doTeamUseCommandButtonOnNearestObjectType( const AsciiString return; } - const ThingTemplate *thingTemplate = TheThingFactory->findTemplate(objectType); + const ThingTemplate *thingTemplate = TheThingFactory->findTemplate( objectType, FALSE ); if (!thingTemplate) { return; } diff --git a/Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptConditions.cpp b/Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptConditions.cpp index 74f761df89..7ca0211caf 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptConditions.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptConditions.cpp @@ -1720,7 +1720,8 @@ Bool ScriptConditions::evaluatePlayerUnitCondition(Condition *pCondition, Parame } Player* pPlayer = playerFromParam(pPlayerParm); - if (!pPlayer) { + if (!pPlayer) + { return false; } @@ -1733,7 +1734,8 @@ Bool ScriptConditions::evaluatePlayerUnitCondition(Condition *pCondition, Parame Int numObjs = types.m_types->prepForPlayerCounting(templates, counts); Int count = 0; - if (numObjs > 0) { + if (numObjs > 0) + { pPlayer->countObjectsByThingTemplate(numObjs, &(*templates.begin()), false, &(*counts.begin())); count = rts::sum(counts); } @@ -1752,7 +1754,8 @@ Bool ScriptConditions::evaluatePlayerUnitCondition(Condition *pCondition, Parame break; } pCondition->setCustomData(-1); // false. - if (comparison) { + if (comparison) + { pCondition->setCustomData(1); // true. } return comparison; @@ -2166,7 +2169,7 @@ Bool ScriptConditions::evaluateSkirmishPlayerTechBuildingWithinDistancePerimeter if (!player) { return false; } - + // If we have a chached value, return it. [8/8/2003] if (pCondition->getCustomData()==1) return true; if (pCondition->getCustomData()==-1) return false; diff --git a/Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptEngine.cpp b/Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptEngine.cpp index 03ff9b0ec5..0b5787bddb 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptEngine.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/ScriptEngine/ScriptEngine.cpp @@ -9644,3 +9644,4 @@ static void _cleanUpVTune() VTResume = NULL; } #endif // VTUNE + diff --git a/Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp b/Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp index 05aec222ba..fad6478bef 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp @@ -482,6 +482,9 @@ static Object * placeObjectAtPosition(Int slotNum, AsciiString objectTemplateNam const PlayerTemplate *pTemplate) { const ThingTemplate* btt = TheThingFactory->findTemplate(objectTemplateName); + + DEBUG_ASSERTCRASH(btt, ("TheThingFactory didn't find a template in placeObjectAtPosition()") ); + Object *obj = TheThingFactory->newObject( btt, pPlayer->getDefaultTeam() ); DEBUG_ASSERTCRASH(obj, ("TheThingFactory didn't give me a valid Object for player %d's (%ls) starting building\n", slotNum, pTemplate->getDisplayName().str())); @@ -2307,18 +2310,22 @@ Bool GameLogic::isIntroMoviePlaying() // ------------------------------------------------------------------------------------------------ void GameLogic::selectObject(Object *obj, Bool createNewSelection, PlayerMaskType playerMask, Bool affectClient) { - if (!obj) { + if (!obj) + { return; } - if (!obj->isMassSelectable() && !createNewSelection) { + if (!obj->isMassSelectable() && !createNewSelection) + { DEBUG_LOG(("GameLogic::selectObject() - Object attempted to be added to selection, but isn't mass-selectable.\n")); return; } - while (playerMask) { + while( playerMask ) + { Player *player = ThePlayerList->getEachPlayerFromMask(playerMask); - if (!player) { + if( !player ) + { return; } @@ -2328,17 +2335,22 @@ void GameLogic::selectObject(Object *obj, Bool createNewSelection, PlayerMaskTyp group->add(obj); // add all selected agents to the AI group - if (createNewSelection) { + if (createNewSelection) + { player->setCurrentlySelectedAIGroup(group); - } else { + } + else + { player->addAIGroupToCurrentSelection(group); } TheAI->destroyGroup(group); - if (affectClient) { + if( affectClient ) + { Drawable *draw = obj->getDrawable(); - if (draw) { + if( draw ) + { TheInGameUI->selectDrawable(draw); } } @@ -2729,6 +2741,7 @@ void GameLogic::friend_awakenUpdateModule(Object* obj, UpdateModulePtr u, Unsign // ------------------------------------------------------------------------------------------------ #ifdef DO_UNIT_TIMINGS enum {TIME_FRAMES=100}; + enum {SETTLE_FRAMES=10}; static void unitTimings(void) { static Int settleFrames = 0; @@ -2738,6 +2751,11 @@ static void unitTimings(void) AsciiString sides[8]; + const Int UNIT_X = 10; + const Int UNIT_Y = 10; + const Int TOTAL_UNITS = UNIT_X*UNIT_Y; + + Int sideCount = 0; #define SINGLE_UNIT "OxFooble." @@ -2793,10 +2811,10 @@ static void unitTimings(void) if (mode == LOGIC) { timeLogic = timeToUpdate; - drawCallLogic = (float)drawCallTotal / (float)(TIME_FRAMES * 100); // 100 units for TIME_FRAMES + drawCallLogic = (float)drawCallTotal / (float)(TIME_FRAMES * TOTAL_UNITS); // 100 units for TIME_FRAMES mode = ALL; - settleFrames = 10; + settleFrames = SETTLE_FRAMES; //g_timing_no_anim = true; Coord3D thePos; thePos.x = 50; @@ -2807,19 +2825,19 @@ static void unitTimings(void) } if (mode == ALL) { timeAll = timeToUpdate; - drawCallAll = (float)drawCallTotal / (float)(TIME_FRAMES * 100); // 100 units for TIME_FRAMES + drawCallAll = (float)drawCallTotal / (float)(TIME_FRAMES * TOTAL_UNITS); // 100 units for TIME_FRAMES mode = NO_PARTICLES; - settleFrames = 10; + settleFrames = SETTLE_FRAMES; if (TheParticleSystemManager->getParticleCount()>1) { TheParticleSystemManager->reset(); - DEBUG_LOG(("Starting noPart - ")); + DEBUG_LOG(("Starting noParticles - \n")); } return; } if (mode == NO_PARTICLES) { timeNoPart = timeToUpdate; - drawCallNoPart = (float)drawCallTotal / (float)(TIME_FRAMES * 100); // 100 units for TIME_FRAMES + drawCallNoPart = (float)drawCallTotal / (float)(TIME_FRAMES * TOTAL_UNITS); // 100 units for TIME_FRAMES mode = NO_SPAWN; Object *obj = TheGameLogic->getFirstObject(); @@ -2832,34 +2850,34 @@ static void unitTimings(void) obj = obj->getNextObject(); } if (gotSpawn) { - DEBUG_LOG(("Starting noSpawn - ")); - settleFrames = 10; + DEBUG_LOG(("Starting noSpawn - \n")); + settleFrames = SETTLE_FRAMES; return; } } if (mode==NO_SPAWN) { timeNoSpawn = timeToUpdate; - drawCallNoSpawn = (float)drawCallTotal / (float)(TIME_FRAMES * 100); // 100 units for TIME_FRAMES + drawCallNoSpawn = (float)drawCallTotal / (float)(TIME_FRAMES * TOTAL_UNITS); // 100 units for TIME_FRAMES } if (g_UT_curThing==NULL) return; - char foo[1024]; + char remark[1024]; AsciiString thingName = g_UT_curThing->getName(); if (veryFirstTime) { thingName = "No Object"; } - sprintf(foo, "\nTime %f, %d ms for 100 %s , noPart %f, noSpawn %f logic %f \n", timeAll, + sprintf(remark, "\nTime %f, %d ms for 100 %s , noPart %f, noSpawn %f logic %f \n", timeAll, (Int)(timeAll*1000/TIME_FRAMES), thingName.str(), timeNoPart, timeNoSpawn, timeLogic); - DEBUG_LOG((foo)); - sprintf(foo, "\nDrawCalls for 100 %s , all %d, noPart %d, noSpawn %d logic %d \n", thingName.str(), + DEBUG_LOG((remark)); + sprintf(remark, "\nDrawCalls for 100 %s , all %d, noPart %d, noSpawn %d logic %d \n", thingName.str(), drawCallAll,drawCallNoPart,drawCallNoSpawn, drawCallLogic); - DEBUG_LOG((foo)); + DEBUG_LOG((remark)); if (g_UT_timingLog) { - fputs(foo, g_UT_timingLog); + fputs(remark, g_UT_timingLog); } if (g_UT_commaLog) { AsciiString type; @@ -2889,14 +2907,14 @@ static void unitTimings(void) modelName = "**NO MODEL**"; veryFirstTime = false; } - sprintf(foo, "%f,%d,%f,%d,%f,%d,%f,%d,%s,%s,%s,%s,%f,%f,%f\n", timeAll, + sprintf(remark, "%f,%d,%f,%d,%f,%d,%f,%d,%s,%s,%s,%s,%f,%f,%f\n", timeAll, (Int)(timeAll*1000/TIME_FRAMES),timeNoPart, (Int)(timeNoPart*1000/TIME_FRAMES),timeNoSpawn, (Int)(timeNoSpawn*1000/TIME_FRAMES),timeLogic, (Int)(timeLogic*1000/TIME_FRAMES), thingName.str(), modelName.str(), type.str(), sides[side].str(), drawCallAll,drawCallNoPart,drawCallNoSpawn); - fputs(foo, g_UT_commaLog); + fputs(remark, g_UT_commaLog); } TheParticleSystemManager->reset(); g_UT_gotUnit = false; @@ -2935,13 +2953,16 @@ static void unitTimings(void) if (unitTypes==END) { side++; unitTypes = INFANTRY; - if (sides[side].isEmpty()) { + if (sides[side].isEmpty() ) // end of sides list + { g_UT_startTiming = false; - if (g_UT_timingLog) { + if (g_UT_timingLog) + { fclose(g_UT_timingLog); g_UT_timingLog = NULL; } - if (g_UT_commaLog) { + if (g_UT_commaLog) + { fclose(g_UT_commaLog); g_UT_commaLog = NULL; } @@ -2952,7 +2973,8 @@ static void unitTimings(void) } const ThingTemplate* btt = g_UT_curThing; - if (btt->getDefaultOwningSide() != sides[side]) { + if (btt->getDefaultOwningSide() != sides[side]) + { continue; } if (unitTypes == INFANTRY) { diff --git a/Generals/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp b/Generals/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp index 31c36e00a1..95d31d152f 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp @@ -888,7 +888,7 @@ void GameLogic::logicMessageDispatcher( GameMessage *msg, void *userData ) break; } -#if defined(_DEBUG) || defined(_INTERNAL) +#if defined(_DEBUG) || defined(_INTERNAL) || defined (_ALLOW_DEBUG_CHEATS_IN_RELEASE) //--------------------------------------------------------------------------------------------- case GameMessage::MSG_DEBUG_KILL_SELECTION: { @@ -907,7 +907,6 @@ void GameLogic::logicMessageDispatcher( GameMessage *msg, void *userData ) } break; } - //--------------------------------------------------------------------------------------------- case GameMessage::MSG_DEBUG_HURT_OBJECT: { diff --git a/Generals/Code/GameEngine/Source/GameNetwork/FirewallHelper.cpp b/Generals/Code/GameEngine/Source/GameNetwork/FirewallHelper.cpp index b34d115042..634f25913d 100644 --- a/Generals/Code/GameEngine/Source/GameNetwork/FirewallHelper.cpp +++ b/Generals/Code/GameEngine/Source/GameNetwork/FirewallHelper.cpp @@ -456,7 +456,6 @@ UnsignedShort FirewallHelperClass::getManglerResponse(UnsignedShort packetID, In } Int retval = m_spareSockets[i].udp->Read((unsigned char *)message, sizeof(ManglerData), &addr); if (retval > 0) { - CRC crc; crc.computeCRC((unsigned char *)(&(message->data.magic)), sizeof(ManglerData) - sizeof(unsigned int)); if (crc.get() != htonl(message->data.CRC)) { diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/PeerDefs.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/PeerDefs.cpp index 9f930de290..6532b740a6 100644 --- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/PeerDefs.cpp +++ b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/PeerDefs.cpp @@ -53,7 +53,7 @@ #endif GameSpyInfoInterface *TheGameSpyInfo = NULL; -GameSpyStagingRoom *TheGameSpyGame = NULL; +extern GameSpyStagingRoom *TheGameSpyGame = NULL; void deleteNotificationBox( void ); bool AsciiComparator::operator()(AsciiString s1, AsciiString s2) const diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/StagingRoomGameInfo.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/StagingRoomGameInfo.cpp index be20575ee4..7a9965a4d0 100644 --- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/StagingRoomGameInfo.cpp +++ b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/StagingRoomGameInfo.cpp @@ -669,7 +669,7 @@ AsciiString GameSpyStagingRoom::generateGameSpyGameResultsPacket( void ) Int gsPlayerID = slot->getProfileID(); Bool disconnected = slot->disconnected(); - AsciiString result = "loss", side = "USA"; + AsciiString result = "loss"; if (disconnected) result = "discon"; else if (TheNetwork->sawCRCMismatch()) @@ -677,9 +677,9 @@ AsciiString GameSpyStagingRoom::generateGameSpyGameResultsPacket( void ) else if (TheVictoryConditions->hasAchievedVictory(p)) result = "win"; - side = p->getPlayerTemplate()->getSide(); + AsciiString side = p->getPlayerTemplate()->getSide(); if (side == "America") - side = "USA"; + side = "USA"; //conform to GameSpy AsciiString playerStr; playerStr.format("\\player_%d\\%s\\pid_%d\\%d\\team_%d\\%d\\result_%d\\%s\\side_%d\\%s", diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/BuddyThread.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/BuddyThread.cpp index 410dbeed1d..421b244610 100644 --- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/BuddyThread.cpp +++ b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/BuddyThread.cpp @@ -545,7 +545,7 @@ void BuddyThreadClass::connectCallback( GPConnection *con, GPConnectResponseArg DEBUG_LOG(("Buddy connect: trying chat connect\n")); PeerRequest req; req.peerRequestType = PeerRequest::PEERREQUEST_LOGIN; - req.nick = m_nick; + req.nick = m_nick.c_str(); req.password = m_pass; req.email = m_email; req.login.profileID = arg->profile; diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/GameResultsThread.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/GameResultsThread.cpp index dc5f43ec27..fbe5191a05 100644 --- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/GameResultsThread.cpp +++ b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/GameResultsThread.cpp @@ -290,6 +290,7 @@ void GameResultsThreadClass::Thread_Function() //------------------------------------------------------------------------- +#ifdef DEBUG_LOGGING #define CASE(x) case (x): return #x; static const char *getWSAErrorString( Int error ) @@ -355,6 +356,7 @@ static const char *getWSAErrorString( Int error ) #undef CASE +#endif //------------------------------------------------------------------------- Int GameResultsThreadClass::sendGameResults( UnsignedInt IP, UnsignedShort port, const std::string& results ) diff --git a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/PeerThread.cpp b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/PeerThread.cpp index b9642a9f0d..48b19f6e46 100644 --- a/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/PeerThread.cpp +++ b/Generals/Code/GameEngine/Source/GameNetwork/GameSpy/Thread/PeerThread.cpp @@ -2745,6 +2745,7 @@ static void playerInfoCallback(PEER peer, RoomType roomType, const char * nick, resp.locale, resp.player.wins, resp.player.losses, resp.player.rankPoints, resp.player.side, resp.player.preorder, roomType, resp.player.flags); +DEBUG_LOG(("**GS playerInfoCallback name=%s, local=%s\n", nick, resp.locale.c_str() )); TheGameSpyPeerMessageQueue->addResponse(resp); } diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/TerrainTex.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/TerrainTex.h index baeb9d2172..3f5e56e084 100644 --- a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/TerrainTex.h +++ b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/TerrainTex.h @@ -56,7 +56,7 @@ class TerrainTextureClass : public TextureClass // just use default destructor. ~TerrainTextureClass(void); public: int update(WorldHeightMap *htMap); ///< Sets the pixels, and returns the actual height of the texture. - + void setLOD(Int LOD); }; diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DAssetManager.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DAssetManager.h index 3403e1d4be..bed74440c6 100644 --- a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DAssetManager.h +++ b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DAssetManager.h @@ -65,11 +65,13 @@ class W3DAssetManager: public WW3DAssetManager // unique to W3DAssetManager virtual HAnimClass * Get_HAnim(const char * name); virtual bool Load_3D_Assets( const char * filename ); // This CANNOT be Bool, as it will not inherit properly if you make Bool == Int - virtual TextureClass * Get_Texture( + virtual TextureClass * Get_Texture + ( const char * filename, MipCountType mip_level_count=MIP_LEVELS_ALL, WW3DFormat texture_format=WW3D_FORMAT_UNKNOWN, - bool allow_compression=true); + bool allow_compression=true + ); //'Generals' customizations void Report_Used_Assets(void); diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DBridgeBuffer.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DBridgeBuffer.h index 1b0b9e73c4..6b885b5da8 100644 --- a/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DBridgeBuffer.h +++ b/Generals/Code/GameEngineDevice/Include/W3DDevice/GameClient/W3DBridgeBuffer.h @@ -164,8 +164,8 @@ friend class HeightMapRenderObjClass; void loadBridges(W3DTerrainLogic *pTerrainLogic, Bool saveGame); ///< Loads the bridges from the map objects list. void worldBuilderUpdateBridgeTowers( W3DAssetManager *assetManager, SimpleSceneClass *scene ); ///< for the editor and showing visual bridge towers void updateCenter(CameraClass *camera, RefRenderObjListIterator *pLightsIterator); - enum { MAX_BRIDGE_VERTEX=8000, - MAX_BRIDGE_INDEX=2*8000, + enum { MAX_BRIDGE_VERTEX=8000, //make sure it stays under 65535 + MAX_BRIDGE_INDEX=2*MAX_BRIDGE_VERTEX, //make sure it stays under 65535 MAX_BRIDGES=200}; protected: DX8VertexBufferClass *m_vertexBridge; ///removeShadow(this);} ///m_width) m_drawWidthX = m_width;} inline void setDrawHeight(Int height) {m_drawHeightY = height; if (m_drawHeightY>m_height) m_drawHeightY = m_height;} - inline Int getBorderSize(void) {return m_borderSize;} + virtual Int getBorderSize(void) {return m_borderSize;} + inline Int getBorderSizeInline(void) const { return m_borderSize; } /// Get height with the offset that HeightMapRenderObjClass uses built in. inline UnsignedByte getDisplayHeight(Int x, Int y) { return m_data[x+m_drawOriginX+m_width*(y+m_drawOriginY)];} @@ -253,6 +254,7 @@ class WorldHeightMap : public RefCountClass TXTextureClass getTextureFromIndex( Int textureIndex ); public: // tile and texture info. + void setTextureLOD(Int lod); ///< set maximum lod level sent to the hardware. TextureClass *getTerrainTexture(void); //< generates if needed and returns the terrain texture TextureClass *getAlphaTerrainTexture(void); //< generates if needed and returns alpha terrain texture TextureClass *getEdgeTerrainTexture(void); //< generates if needed and returns blend edge texture diff --git a/Generals/Code/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp b/Generals/Code/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp index dfa6575d84..200caac754 100644 --- a/Generals/Code/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp +++ b/Generals/Code/GameEngineDevice/Source/MilesAudioDevice/MilesAudioManager.cpp @@ -603,6 +603,7 @@ void MilesAudioManager::pauseAudio( AudioAffect which ) } } + //------------------------------------------------------------------------------------------------- void MilesAudioManager::resumeAudio( AudioAffect which ) { diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/Common/System/W3DRadar.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/Common/System/W3DRadar.cpp index b33978208d..305a5f3d56 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/Common/System/W3DRadar.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/Common/System/W3DRadar.cpp @@ -60,6 +60,7 @@ //#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") #endif + // PRIVATE DATA /////////////////////////////////////////////////////////////////////////////////// enum { OVERLAY_REFRESH_RATE = 6 }; ///< over updates once this many frames @@ -277,8 +278,6 @@ void W3DRadar::drawHeroIcon( Int pixelX, Int pixelY, Int width, Int height, cons } } - - //------------------------------------------------------------------------------------------------- /** Draw a "box" into the texture passed in that represents the viewable area for * the tactical display into the game world */ @@ -616,7 +615,6 @@ void W3DRadar::drawIcons( Int pixelX, Int pixelY, Int width, Int height ) } } - //------------------------------------------------------------------------------------------------- /** Render an object list into the texture passed in */ //------------------------------------------------------------------------------------------------- @@ -1466,3 +1464,154 @@ void W3DRadar::refreshTerrain( TerrainLogic *terrain ) buildTerrainTexture( terrain ); } // end refreshTerrain + + + + + +///The following is an "archive" of an attempt to foil the mapshroud hack... saved for later, since it is too close to release to try it + + +/* + * + void W3DRadar::renderObjectList( const RadarObject *listHead, TextureClass *texture, Bool calcHero ) +{ + + // sanity + if( listHead == NULL || texture == NULL ) + return; + + // get surface for texture to render into + SurfaceClass *surface = texture->Get_Surface_Level(); + + // loop through all objects and draw + ICoord2D radarPoint; + + Player *player = ThePlayerList->getLocalPlayer(); + Int playerIndex=0; + if (player) + playerIndex=player->getPlayerIndex(); + + UnsignedByte minAlpha = 8; + + if( calcHero ) + { + // clear all entries from the cached hero object list + m_cachedHeroPosList.clear(); + } + + for( const RadarObject *rObj = listHead; rObj; rObj = rObj->friend_getNext() ) + { + UnsignedByte h = (UnsignedByte)(rObj->isTemporarilyHidden()); + if ( h ) + continue; + + UnsignedByte a = 0; + + // get object + const Object *obj = rObj->friend_getObject(); + UnsignedByte r = 1; // all decoys + + // cache hero object positions for drawing in icon layer + if( calcHero && obj->isHero() ) + { + m_cachedHeroPosList.push_back(obj->getPosition()); + } + + // get the color we're going to draw in + UnsignedInt c = 0xfe000000;// this is a decoy + c |= (UnsignedInt)( obj->testStatus( OBJECT_STATUS_STEALTHED ) );//so is this + + // check for shrouded status + UnsignedByte k = (UnsignedByte)(obj->getShroudedStatus(playerIndex) > OBJECTSHROUD_PARTIAL_CLEAR); + if ( k || a) + continue; //object is fogged or shrouded, don't render it. + + // + // objects with a local only unit priority will only appear on the radar if they + // are controlled by the local player, or if the local player is an observer (cause + // they are godlike and can see everything) + // + if( obj->getRadarPriority() == RADAR_PRIORITY_LOCAL_UNIT_ONLY && + obj->getControllingPlayer() != ThePlayerList->getLocalPlayer() && + ThePlayerList->getLocalPlayer()->isPlayerActive() ) + continue; + + UnsignedByte g = c|a; + UnsignedByte b = h|a; + // get object position + const Coord3D *pos = obj->getPosition(); + + // compute object position as a radar blip + radarPoint.x = pos->x / (m_mapExtent.width() / RADAR_CELL_WIDTH); + radarPoint.y = pos->y / (m_mapExtent.height() / RADAR_CELL_HEIGHT); + + + const UnsignedInt framesForTransition = LOGICFRAMES_PER_SECOND; + + + + // adjust the alpha for stealth units so they "fade/blink" on the radar for the controller + // if( obj->getRadarPriority() == RADAR_PRIORITY_LOCAL_UNIT_ONLY ) + // ML-- What the heck is this? local-only and neutral-observier-viewed units are stealthy?? Since when? + // Now it twinkles for any stealthed object, whether locally controlled or neutral-observier-viewed + c = rObj->getColor(); + + if( g & r ) + { + Real alphaScale = INT_TO_REAL(TheGameLogic->getFrame() % framesForTransition) / (framesForTransition * 0.5f); + minAlpha <<= 2; // decoy + + if ( ( obj->isLocallyControlled() == (Bool)a ) // another decoy, comparing the return of this non-inline with a local + && !obj->testStatus( OBJECT_STATUS_DISGUISED ) + && !obj->testStatus( OBJECT_STATUS_DETECTED ) + && ++a != 0 // The trick is that this increment does not occur unless all three above conditions are true + && minAlpha == 32 // tricksy hobbit decoy + && c != 0 ) // ditto + { + g = (UnsignedByte)(rObj->getColor()); + continue; + } + + a |= k | b; + GameGetColorComponentsWithCheatSpy( c, &r, &g, &b, &a );//this function does not touch the low order bit in 'a' + + + if( alphaScale > 0.0f ) + a = REAL_TO_UNSIGNEDBYTE( ((alphaScale - 1.0f) * (255.0f - minAlpha)) + minAlpha ); + else + a = REAL_TO_UNSIGNEDBYTE( (alphaScale * (255.0f - minAlpha)) + minAlpha ); + c = GameMakeColor( r, g, b, a ); + + } // end if + + + + + // draw the blip, but make sure the points are legal + if( legalRadarPoint( radarPoint.x, radarPoint.y ) ) + surface->DrawPixel( radarPoint.x, radarPoint.y, c ); + + radarPoint.x++; + if( legalRadarPoint( radarPoint.x, radarPoint.y ) ) + surface->DrawPixel( radarPoint.x, radarPoint.y, c ); + + radarPoint.y++; + if( legalRadarPoint( radarPoint.x, radarPoint.y ) ) + surface->DrawPixel( radarPoint.x, radarPoint.y, c ); + + radarPoint.x--; + if( legalRadarPoint( radarPoint.x, radarPoint.y ) ) + surface->DrawPixel( radarPoint.x, radarPoint.y, c ); + + + + + } // end for + REF_PTR_RELEASE(surface); + +} // end renderObjectList + + + * + */ diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DDependencyModelDraw.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DDependencyModelDraw.cpp index 4f7382b206..fd4e09f6cb 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DDependencyModelDraw.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DDependencyModelDraw.cpp @@ -38,6 +38,15 @@ #include "GameLogic/Module/ContainModule.h" #include "W3DDevice/GameClient/Module/W3DDependencyModelDraw.h" + + +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif + + //------------------------------------------------------------------------------------------------- W3DDependencyModelDrawModuleData::W3DDependencyModelDrawModuleData() { diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DModelDraw.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DModelDraw.cpp index 83df059960..31c16fbe8c 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DModelDraw.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Drawable/Draw/W3DModelDraw.cpp @@ -734,6 +734,23 @@ void ModelConditionInfo::validateWeaponBarrelInfo() const const AsciiString& recoilBoneName = m_weaponRecoilBoneName[wslot]; const AsciiString& mfName = m_weaponMuzzleFlashName[wslot]; const AsciiString& plbName = m_weaponProjectileLaunchBoneName[wslot]; + +// a useful tool for finding missing INI entries in the weapon-bone block +// since this class has no idea which object it refers to, it must assume that the projectilelaunchbonename +// is required if the fxBoneName is specified +// this is not always true, since some weapons have no launched projectiles, hence the caveat in the assert message +//#if defined(_DEBUG) || defined(_INTERNAL) +// if ( +// ( m_modelName.startsWith("UV") || m_modelName.startsWith("NV") || m_modelName.startsWith("AV") || +// m_modelName.startsWith("uv") || m_modelName.startsWith("nv") || m_modelName.startsWith("av") +// ) +// +// && fxBoneName.isNotEmpty() +// +// ) +// DEBUG_ASSERTCRASH( plbName.isNotEmpty(), ("You appear to have a missing projectilelaunchbonename. \n Promptly ignore this assert if this model is used by a non-projectile-weapon-bearing unit\nModel name = %s.", m_modelName.str()) ); +//#endif + if (fxBoneName.isNotEmpty() || recoilBoneName.isNotEmpty() || mfName.isNotEmpty() || plbName.isNotEmpty()) { Int prevFxBone = 0; @@ -1730,7 +1747,10 @@ W3DModelDraw::W3DModelDraw(Thing *thing, const ModuleData* moduleData) : DrawMod } Drawable* draw = getDrawable(); - Object* obj = draw ? draw->getObject() : NULL; + + if ( draw ) + { + Object* obj = draw->getObject(); if (obj) { if (TheGlobalData->m_timeOfDay == TIME_OF_DAY_NIGHT) @@ -1739,6 +1759,7 @@ W3DModelDraw::W3DModelDraw(Thing *thing, const ModuleData* moduleData) : DrawMod m_hexColor = obj->getIndicatorColor(); } + } setModelState(info); } diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/HeightMap.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/HeightMap.cpp index 688ba83480..aca71056ae 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/HeightMap.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/HeightMap.cpp @@ -137,7 +137,7 @@ void oversizeTheTerrain(Int amount) #define DEFAULT_MAX_BATCH_SHORELINE_TILES 512 //maximum number of terrain tiles rendered per call (must fit in one VB) #define DEFAULT_MAX_MAP_SHORELINE_TILES 4096 //default size of array allocated to hold all map shoreline tiles. -#define ADJUST_FROM_INDEX_TO_REAL(k) ((k-m_map->getBorderSize())*MAP_XY_FACTOR) +#define ADJUST_FROM_INDEX_TO_REAL(k) ((k-m_map->getBorderSizeInline())*MAP_XY_FACTOR) inline Int IABS(Int x) { if (x>=0) return x; return -x;}; //----------------------------------------------------------------------------- @@ -640,8 +640,8 @@ Int HeightMapRenderObjClass::updateVB(DX8VertexBufferClass *pVB, char *data, Int if (m_showImpassableAreas) { // Color impassable cells "red" DEBUG_ASSERTCRASH(PATHFIND_CELL_SIZE_F == MAP_XY_FACTOR, ("Pathfind must be terrain cell size, or this code needs reworking. John A.")); - Real borderHiX = (pMap->getXExtent()-2*pMap->getBorderSize())*MAP_XY_FACTOR; - Real borderHiY = (pMap->getYExtent()-2*pMap->getBorderSize())*MAP_XY_FACTOR; + Real borderHiX = (pMap->getXExtent()-2*pMap->getBorderSizeInline())*MAP_XY_FACTOR; + Real borderHiY = (pMap->getYExtent()-2*pMap->getBorderSizeInline())*MAP_XY_FACTOR; Bool border = pCurVertices[0].x == -MAP_XY_FACTOR || pCurVertices[0].y == -MAP_XY_FACTOR; Bool cliffMapped = pMap->isCliffMappedTexture(getXWithOrigin(i), getYWithOrigin(j)); if (pCurVertices[0].x == borderHiX) { @@ -731,7 +731,7 @@ Int HeightMapRenderObjClass::updateVBForLight(DX8VertexBufferClass *pVB, char *d if (m_halfResMesh) { if (j&1) continue; } - Int yCoord = getYWithOrigin(j)+m_map->getDrawOrgY()-m_map->getBorderSize(); + Int yCoord = getYWithOrigin(j)+m_map->getDrawOrgY()-m_map->getBorderSizeInline(); Bool intersect = false; for (k=0; km_minY <= yCoord+1 && @@ -758,7 +758,7 @@ Int HeightMapRenderObjClass::updateVBForLight(DX8VertexBufferClass *pVB, char *d if (m_halfResMesh) { if (i&1) continue; } - Int xCoord = getXWithOrigin(i)+m_map->getDrawOrgX()-m_map->getBorderSize(); + Int xCoord = getXWithOrigin(i)+m_map->getDrawOrgX()-m_map->getBorderSizeInline(); Bool intersect = false; for (k=0; km_minX <= xCoord+1 && @@ -906,7 +906,7 @@ Int HeightMapRenderObjClass::updateVBForLightOptimized(DX8VertexBufferClass *pVB if (m_halfResMesh) { if (j&1) continue; } - Int yCoord = getYWithOrigin(j)+m_map->getDrawOrgY()-m_map->getBorderSize(); + Int yCoord = getYWithOrigin(j)+m_map->getDrawOrgY()-m_map->getBorderSizeInline(); Bool intersect = false; for (k=0; km_minY <= yCoord+1 && @@ -933,7 +933,7 @@ Int HeightMapRenderObjClass::updateVBForLightOptimized(DX8VertexBufferClass *pVB if (m_halfResMesh) { if (i&1) continue; } - Int xCoord = getXWithOrigin(i)+m_map->getDrawOrgX()-m_map->getBorderSize(); + Int xCoord = getXWithOrigin(i)+m_map->getDrawOrgX()-m_map->getBorderSizeInline(); Bool intersect = false; for (k=0; km_minX <= xCoord+1 && @@ -1634,7 +1634,7 @@ bool HeightMapRenderObjClass::Cast_Ray(RayCollisionTestClass & raytest) Int EndCellX = 0; Int StartCellY = 0; Int EndCellY = 0; - const Int overhang = 2*VERTEX_BUFFER_TILE_LENGTH+m_map->getBorderSize(); // Allow picking past the edge for scrolling & objects. + const Int overhang = 2*VERTEX_BUFFER_TILE_LENGTH+m_map->getBorderSizeInline(); // Allow picking past the edge for scrolling & objects. Vector3 minPt(MAP_XY_FACTOR*(-overhang), MAP_XY_FACTOR*(-overhang), -MAP_XY_FACTOR); Vector3 maxPt(MAP_XY_FACTOR*(m_map->getXExtent()+overhang), MAP_XY_FACTOR*(m_map->getYExtent()+overhang), MAP_HEIGHT_SCALE*m_map->getMaxHeightValue()+MAP_XY_FACTOR); @@ -1696,7 +1696,7 @@ bool HeightMapRenderObjClass::Cast_Ray(RayCollisionTestClass & raytest) for (j=StartCellY; j<=EndCellY; j++) { for (i=StartCellX; i<=EndCellX; i++) { - Short cur = getClipHeight(i+m_map->getBorderSize(),j+m_map->getBorderSize()); + Short cur = getClipHeight(i+m_map->getBorderSizeInline(),j+m_map->getBorderSizeInline()); if (curgetBorderSize(); - EndCellX += m_map->getBorderSize(); - StartCellY += m_map->getBorderSize(); - EndCellY += m_map->getBorderSize(); + StartCellX += m_map->getBorderSizeInline(); + EndCellX += m_map->getBorderSizeInline(); + StartCellY += m_map->getBorderSizeInline(); + EndCellY += m_map->getBorderSizeInline(); Int offset; for (offset = 1; offset < 5; offset *= 3) { @@ -1822,8 +1822,8 @@ Real HeightMapRenderObjClass::getHeightMapHeight(Real x, Real y, Coord3D* normal float fy = ydiv - iyf; //get fraction // since ixf & iyf are already floor'ed, we can use the fastest f->i conversion we have... - Int ix = REAL_TO_INT_FLOOR(ixf) + m_map->getBorderSize(); - Int iy = REAL_TO_INT_FLOOR(iyf) + m_map->getBorderSize(); + Int ix = REAL_TO_INT_FLOOR(ixf) + m_map->getBorderSizeInline(); + Int iy = REAL_TO_INT_FLOOR(iyf) + m_map->getBorderSizeInline(); Int xExtent = m_map->getXExtent(); // Check for extent-3, not extent-1: we go into the next row/column of data for smoothed triangle points, so extent-1 @@ -1935,7 +1935,7 @@ Bool HeightMapRenderObjClass::isClearLineOfSight(const Coord3D& pos, const Coord */ const Real MAP_XY_FACTOR_INV = 1.0f / MAP_XY_FACTOR; - Int borderSize = m_map->getBorderSize(); + Int borderSize = m_map->getBorderSizeInline(); Int start_x = REAL_TO_INT_FLOOR(pos.x * MAP_XY_FACTOR_INV) + borderSize; Int start_y = REAL_TO_INT_FLOOR(pos.y * MAP_XY_FACTOR_INV) + borderSize; Int end_x = REAL_TO_INT_FLOOR(posOther.x * MAP_XY_FACTOR_INV) + borderSize; @@ -2131,8 +2131,8 @@ Real HeightMapRenderObjClass::getMaxCellHeight(Real x, Real y) const Int offset = 1; Int iX = x/MAP_XY_FACTOR; Int iY = y/MAP_XY_FACTOR; - iX += m_map->getBorderSize(); - iY += m_map->getBorderSize(); + iX += m_map->getBorderSizeInline(); + iY += m_map->getBorderSizeInline(); if (iX<0) iX = 0; if (iY<0) iY = 0; if (iX >= (m_map->getXExtent()-1)) { @@ -2174,8 +2174,8 @@ Bool HeightMapRenderObjClass::isCliffCell(Real x, Real y) } Int iX = x/MAP_XY_FACTOR; Int iY = y/MAP_XY_FACTOR; - iX += m_map->getBorderSize(); - iY += m_map->getBorderSize(); + iX += m_map->getBorderSizeInline(); + iY += m_map->getBorderSizeInline(); if (iX<0) iX = 0; if (iY<0) iY = 0; if (iX >= (m_map->getXExtent()-1)) { @@ -2424,7 +2424,7 @@ void HeightMapRenderObjClass::setShoreLineDetail(void) water.*/ void HeightMapRenderObjClass::updateShorelineTiles(Int minX, Int minY, Int maxX, Int maxY, WorldHeightMap *pMap) { - Int border = pMap->getBorderSize(); + Int border = pMap->getBorderSizeInline(); //Clamp region to valid terrain tiles if (minX<0) @@ -2871,16 +2871,16 @@ void HeightMapRenderObjClass::updateScorches(void) Int minX = REAL_TO_INT_FLOOR((loc.X-radius)/MAP_XY_FACTOR); Int minY = REAL_TO_INT_FLOOR((loc.Y-radius)/MAP_XY_FACTOR); - if (minX<-m_map->getBorderSize()) minX=-m_map->getBorderSize(); - if (minY<-m_map->getBorderSize()) minY=-m_map->getBorderSize(); + if (minX<-m_map->getBorderSizeInline()) minX=-m_map->getBorderSizeInline(); + if (minY<-m_map->getBorderSizeInline()) minY=-m_map->getBorderSizeInline(); Int maxX = REAL_TO_INT_CEIL((loc.X+radius)/MAP_XY_FACTOR); Int maxY = REAL_TO_INT_CEIL((loc.Y+radius)/MAP_XY_FACTOR); maxX++; maxY++; - if (maxX > m_map->getXExtent()-m_map->getBorderSize()) { - maxX = m_map->getXExtent()-m_map->getBorderSize(); + if (maxX > m_map->getXExtent()-m_map->getBorderSizeInline()) { + maxX = m_map->getXExtent()-m_map->getBorderSizeInline(); } - if (maxY > m_map->getYExtent()-m_map->getBorderSize()) { - maxY = m_map->getYExtent()-m_map->getBorderSize(); + if (maxY > m_map->getYExtent()-m_map->getBorderSizeInline()) { + maxY = m_map->getYExtent()-m_map->getBorderSizeInline(); } Int startVertex = m_curNumScorchVertices; Int i, j; @@ -2889,7 +2889,7 @@ void HeightMapRenderObjClass::updateScorches(void) if (m_curNumScorchVertices >= MAX_SCORCH_VERTEX) return; curVb->diffuse = diffuse; Real theZ; - theZ = amtToFloat+((float)getClipHeight(i+m_map->getBorderSize(),j+m_map->getBorderSize())*MAP_HEIGHT_SCALE); + theZ = amtToFloat+((float)getClipHeight(i+m_map->getBorderSizeInline(),j+m_map->getBorderSizeInline())*MAP_HEIGHT_SCALE); if (m_halfResMesh) { theZ = amtToFloat + this->getMaxCellHeight(i, j); Real amt2 = amtToFloat + getMaxCellHeight(i-1, j-1); @@ -2915,8 +2915,8 @@ void HeightMapRenderObjClass::updateScorches(void) for (j=0; j MAX_SCORCH_INDEX) return; - Int xNdx = i+minX+m_map->getBorderSize(); - Int yNdx = j+minY+m_map->getBorderSize(); + Int xNdx = i+minX+m_map->getBorderSizeInline(); + Int yNdx = j+minY+m_map->getBorderSizeInline(); Bool flipForBlend = m_map->getFlipState(xNdx, yNdx); #if 0 UnsignedByte alpha[4]; @@ -3261,8 +3261,8 @@ void HeightMapRenderObjClass::On_Frame_Update(void) yMin = originY; yMax = originY+VERTEX_BUFFER_TILE_LENGTH; Bool intersect = false; - Int yCoordMin = getYWithOrigin(yMin)+m_map->getDrawOrgY()-m_map->getBorderSize(); - Int yCoordMax = getYWithOrigin(yMax-1)+m_map->getDrawOrgY()+1-m_map->getBorderSize(); + Int yCoordMin = getYWithOrigin(yMin)+m_map->getDrawOrgY()-m_map->getBorderSizeInline(); + Int yCoordMax = getYWithOrigin(yMax-1)+m_map->getDrawOrgY()+1-m_map->getBorderSizeInline(); if (yCoordMax>yCoordMin) { // no wrap occurred. for (k=0; kgetDrawOrgX()-m_map->getBorderSize(); - Int xCoordMax = getXWithOrigin(xMax-1)+m_map->getDrawOrgX()+1-m_map->getBorderSize(); + Int xCoordMin = getXWithOrigin(xMin)+m_map->getDrawOrgX()-m_map->getBorderSizeInline(); + Int xCoordMax = getXWithOrigin(xMax-1)+m_map->getDrawOrgX()+1-m_map->getBorderSizeInline(); if (xCoordMax>xCoordMin) { // no wrap occurred. for (k=0; kgetHeight(x, y); - Vector3 loc((x-pMap->getBorderSize())*MAP_XY_FACTOR, (y-pMap->getBorderSize())*MAP_XY_FACTOR, height*MAP_HEIGHT_SCALE); + Vector3 loc((x-pMap->getBorderSizeInline())*MAP_XY_FACTOR, (y-pMap->getBorderSizeInline())*MAP_XY_FACTOR, height*MAP_HEIGHT_SCALE); if (CollisionMath::Overlap_Test(frustum,loc) == CollisionMath::INSIDE) { if (xvisMaxX) visMaxX=x; @@ -3663,10 +3663,10 @@ void HeightMapRenderObjClass::updateCenter(CameraClass *camera , RefRenderObjLis minY /= MAP_XY_FACTOR; maxY /= MAP_XY_FACTOR; - minX += m_map->getBorderSize(); - maxX += m_map->getBorderSize(); - minY += m_map->getBorderSize(); - maxY += m_map->getBorderSize(); + minX += m_map->getBorderSizeInline(); + maxX += m_map->getBorderSizeInline(); + minY += m_map->getBorderSizeInline(); + maxY += m_map->getBorderSizeInline(); visMinX = m_map->getXExtent(); visMinY = m_map->getYExtent(); @@ -4022,7 +4022,7 @@ void HeightMapRenderObjClass::Render(RenderInfoClass & rinfo) RTS3DScene *pMyScene = (RTS3DScene *)Scene; RefRenderObjListIterator pDynamicLightsIterator(pMyScene->getDynamicLights()); m_roadBuffer->drawRoads(&rinfo.Camera, doCloud?m_stageTwoTexture:NULL, TheGlobalData->m_useLightMap?m_stageThreeTexture:NULL, - m_disableTextures,xCoordMin-m_map->getBorderSize(), xCoordMax-m_map->getBorderSize(), yCoordMin-m_map->getBorderSize(), yCoordMax-m_map->getBorderSize(), &pDynamicLightsIterator); + m_disableTextures,xCoordMin-m_map->getBorderSizeInline(), xCoordMax-m_map->getBorderSizeInline(), yCoordMin-m_map->getBorderSizeInline(), yCoordMax-m_map->getBorderSizeInline(), &pDynamicLightsIterator); } } #endif @@ -4089,7 +4089,7 @@ void HeightMapRenderObjClass::renderShoreLines(CameraClass *pCamera) Int vertexCount = 0; Int indexCount = 0; Int xExtent = m_map->getXExtent(); - Int border = m_map->getBorderSize(); + Int border = m_map->getBorderSizeInline(); Int drawEdgeY=m_map->getDrawOrgY()+m_map->getDrawHeight()-1; Int drawEdgeX=m_map->getDrawOrgX()+m_map->getDrawWidth()-1; if (drawEdgeX > (m_map->getXExtent()-1)) @@ -4292,7 +4292,7 @@ void HeightMapRenderObjClass::renderExtraBlendTiles(void) Int vertexCount = 0; Int indexCount = 0; Int xExtent = m_map->getXExtent(); - Int border = m_map->getBorderSize(); + Int border = m_map->getBorderSizeInline(); static Int maxBlendTiles = DEFAULT_MAX_FRAME_EXTRABLEND_TILES; if (!m_numExtraBlendTiles) diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DProjectedShadow.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DProjectedShadow.cpp index 9dfb98b61c..79cf27e372 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DProjectedShadow.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Shadow/W3DProjectedShadow.cpp @@ -124,39 +124,6 @@ int SHADOW_DECAL_INDEX_SIZE=65536; class W3DShadowTexture; //forward reference class W3DShadowTextureManager; //forward reference -/** Object for maintaining and updating an object's shadow texture. -*/ -class W3DProjectedShadow : public Shadow -{ - friend class W3DProjectedShadowManager; - - public: - W3DProjectedShadow(void); - ~W3DProjectedShadow(void); - void setRenderObject( RenderObjClass *robj) {m_robj=robj;} - void setObjPosHistory(const Vector3 &pos) {m_lastObjPosition=pos;} ///removeShadow(this);} ///getMap(); - borderSize=hmap->getBorderSize(); + borderSize=hmap->getBorderSizeInline(); if (robj) { objPos=robj->Get_Position(); @@ -1947,6 +1914,107 @@ W3DProjectedShadow* W3DProjectedShadowManager::addShadow(RenderObjClass *robj, S return shadow; } +W3DProjectedShadow* W3DProjectedShadowManager::createDecalShadow(Shadow::ShadowTypeInfo *shadowInfo) +{ + W3DShadowTexture *st=NULL; + static char defaultDecalName[]={"shadow.tga"}; + ShadowType shadowType=SHADOW_DECAL; /// type of projection + Bool allowWorldAlign=FALSE; /// wrap shadow around world geometry - else align perpendicular to local z-axis. + Real decalSizeX=0.0f; + Real decalSizeY=0.0f; + Real decalOffsetX=0.0f; + Real decalOffsetY=0.0f; + const Real defaultWidth = 10.0f; + + Char texture_name[64]; + Int nameLen; + + //simple decal using the premade texture specified. + //can be always perpendicular to model's z-axis or projected + //onto world geometry. + nameLen=strlen(shadowInfo->m_ShadowName); + if (nameLen <= 1) //no texture name given, use same as object + { strcpy(texture_name,defaultDecalName); + } + else + { strncpy(texture_name,shadowInfo->m_ShadowName,nameLen); + strcpy(texture_name+nameLen,".tga"); //append texture extension + } + + st=m_W3DShadowTextureManager->getTexture(texture_name); + if (st == NULL) + { + //need to add this texture without creating it from a real renderobject + TextureClass *w3dTexture=WW3DAssetManager::Get_Instance()->Get_Texture(texture_name); + w3dTexture->Get_Filter().Set_U_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP); + w3dTexture->Get_Filter().Set_V_Addr_Mode(TextureFilterClass::TEXTURE_ADDRESS_CLAMP); + w3dTexture->Get_Filter().Set_Mip_Mapping(TextureFilterClass::FILTER_TYPE_NONE); + + DEBUG_ASSERTCRASH(w3dTexture != NULL, ("Could not load decal texture")); + + if (!w3dTexture) + return NULL; + + st = NEW W3DShadowTexture; // poolify + SET_REF_OWNER( st ); + st->Set_Name(texture_name); + m_W3DShadowTextureManager->addTexture( st ); + st->setTexture(w3dTexture); + } + shadowType=SHADOW_DECAL; + decalSizeX=shadowInfo->m_sizeX; + decalSizeY=shadowInfo->m_sizeY; + decalOffsetX=shadowInfo->m_offsetX; + decalOffsetY=shadowInfo->m_offsetY; + + W3DProjectedShadow *shadow = NEW W3DProjectedShadow; + + // sanity + if( shadow == NULL ) + return NULL; + + shadow->setTexture(0,st); + shadow->m_type = shadowType; /// type of projection + shadow->m_allowWorldAlign=allowWorldAlign; /// wrap shadow around world geometry - else align perpendicular to local z-axis. + + + //Check if app is overriding any of the default texture stretch factors. + if (decalSizeX) + decalSizeX=1.0f/decalSizeX; //world space distance to stretch full texture scale + else + decalSizeX=1.0f/(defaultWidth*2.0f);//use bounding box to determine size + + if (decalSizeY) + decalSizeY=-1.0f/decalSizeY; + else + decalSizeY=-1.0f/(defaultWidth*2.0f);//world space distance to stretch full texture + + if (decalOffsetX) + decalOffsetX=-decalOffsetX*decalSizeX; + else + decalOffsetX=0.0f;//-box.Center.X*decalSizeX; + + if (decalOffsetY) + decalOffsetY=-decalOffsetY*decalSizeY; + else + decalOffsetY=0.0f;//-box.Center.Y*decalSizeY; + + //Prestore some values used during projection to optimize out division. + shadow->m_oowDecalSizeX = decalSizeX; //one over width + shadow->m_oowDecalSizeY = decalSizeY; //one over height + shadow->m_decalSizeX = 1.0f/decalSizeX; //width + shadow->m_decalSizeY = 1.0f/decalSizeY; //height + + shadow->m_decalOffsetU= decalOffsetX; + shadow->m_decalOffsetV= decalOffsetY; + + shadow->m_flags = 0; + + shadow->init(); + + return shadow; +} + void W3DProjectedShadowManager::removeShadow (W3DProjectedShadow *shadow) { W3DProjectedShadow *prev_shadow=NULL; diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/TerrainTex.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/TerrainTex.cpp index e62935d9ae..bbe51ac048 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/TerrainTex.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/TerrainTex.cpp @@ -347,6 +347,16 @@ int TerrainTextureClass::update(WorldHeightMap *htMap) return(surface_desc.Height); } #endif + +//============================================================================= +// TerrainTextureClass::setLOD +//============================================================================= +/** Sets the lod of the texture to be loaded into the video card. */ +//============================================================================= +void TerrainTextureClass::setLOD(Int LOD) +{ + if (Peek_D3D_Texture()) Peek_D3D_Texture()->SetLOD(LOD); +} //============================================================================= // TerrainTextureClass::update256 //============================================================================= diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp index 4e1a24e661..a1aaa0b920 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplay.cpp @@ -960,14 +960,14 @@ void W3DDisplay::gatherDebugStats( void ) double cumuFPS = (numFrames > 0 && cumuTime > 0.0) ? (numFrames / cumuTime) : 0.0; double skinPolysPerFrame = Debug_Statistics::Get_DX8_Skin_Polygons(); - //Int LOD = TheGlobalData->m_terrainLOD; + Int LOD = TheGlobalData->m_terrainLOD; //unibuffer.format( L"FPS: %.2f, %.2fms mapLOD=%d [cumu FPS=%.2f] draws: %.2f sort: %.2f", fps, ms, LOD, cumuFPS, drawsPerFrame,sortPolysPerFrame); if (TheGlobalData->m_useFpsLimit) unibuffer.format( L"%.2f/%d FPS, ", fps, TheGameEngine->getFramesPerSecondLimit()); else unibuffer.format( L"%.2f FPS, ", fps); - unibuffer2.format( L"%.2fms [cumuFPS=%.2f] draws: %d skins: %d sortP: %d skinP: %d", ms, cumuFPS, (Int)drawsPerFrame,(Int)skinDrawsPerFrame,(Int)sortPolysPerFrame, (Int)skinPolysPerFrame); + unibuffer2.format( L"%.2fms [cumuFPS=%.2f] draws: %d skins: %d sortP: %d skinP: %d LOD %d", ms, cumuFPS, (Int)drawsPerFrame,(Int)skinDrawsPerFrame,(Int)sortPolysPerFrame, (Int)skinPolysPerFrame, LOD); unibuffer.concat(unibuffer2); #else //Int LOD = TheGlobalData->m_terrainLOD; @@ -1950,6 +1950,12 @@ Bool W3DDisplay::isLetterBoxFading(void) return FALSE; } +//WST 10/2/2002 added query function. JSC Integrated 5/20/03 +Bool W3DDisplay::isLetterBoxed(void) +{ + return (m_letterBoxEnabled); +} + // W3DDisplay::createLightPulse =============================================== /** Create a "light pulse" which is a dynamic light that grows, decays * and vanishes over several frames */ diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayStringManager.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayStringManager.cpp index cd56ba06f0..1e494296fb 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayStringManager.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DDisplayStringManager.cpp @@ -44,7 +44,7 @@ //------------------------------------------------------------------------------------------------- W3DDisplayStringManager::W3DDisplayStringManager( void ) { - for (Int i = 0; i < 10; ++i) + for (Int i = 0; i < MAX_GROUPS; ++i) { m_groupNumeralStrings[i] = NULL; } @@ -56,7 +56,7 @@ W3DDisplayStringManager::W3DDisplayStringManager( void ) //------------------------------------------------------------------------------------------------- W3DDisplayStringManager::~W3DDisplayStringManager( void ) { - for (Int i = 0; i < 10; ++i) + for (Int i = 0; i < MAX_GROUPS; ++i) { if (m_groupNumeralStrings[i]) freeDisplayString(m_groupNumeralStrings[i]); @@ -79,14 +79,20 @@ void W3DDisplayStringManager::postProcessLoad( void ) TheDrawGroupInfo->m_fontSize, TheDrawGroupInfo->m_fontIsBold ); - for (Int i = 0; i < 10; ++i) + for (Int i = 0; i < MAX_GROUPS; ++i) { m_groupNumeralStrings[i] = newDisplayString(); m_groupNumeralStrings[i]->setFont(font); +#ifdef KRIS_BRUTAL_HACK_FOR_AIRCRAFT_CARRIER_DEBUGGING + UnicodeString displayNumber; + displayNumber.format( L"%d", i); + m_groupNumeralStrings[i]->setText( displayNumber ); +#else AsciiString displayNumber; displayNumber.format("NUMBER:%d", i); m_groupNumeralStrings[i]->setText(TheGameText->fetch(displayNumber)); +#endif } m_formationLetterDisplayString = newDisplayString(); @@ -225,7 +231,8 @@ void W3DDisplayStringManager::update( void ) //------------------------------------------------------------------------------------------------- DisplayString *W3DDisplayStringManager::getGroupNumeralString( Int numeral ) { - if (numeral < 0 || numeral > 9) { + if (numeral < 0 || numeral > MAX_GROUPS - 1 ) + { DEBUG_CRASH(("Numeral '%d' out of range.\n", numeral)); return m_groupNumeralStrings[0]; } diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DRoadBuffer.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DRoadBuffer.cpp index a0c2b9187b..e38979f8c2 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DRoadBuffer.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DRoadBuffer.cpp @@ -333,11 +333,12 @@ Int RoadSegment::GetIndices(UnsignedShort *destination_ib, Int numToCopy, Int of void RoadSegment::updateSegLighting(void) { Int i; + Int borderSizeInLine=TheTerrainRenderObject->getMap()->getBorderSizeInline(); for (i=0; igetMap()->getBorderSize(); - y += TheTerrainRenderObject->getMap()->getBorderSize(); + x += borderSizeInLine; + y += borderSizeInLine; m_vb[i].diffuse = (255<<24)|TheTerrainRenderObject->getStaticDiffuse(x, y); } } @@ -3197,6 +3198,33 @@ void W3DRoadBuffer::loadRoads() //============================================================================= void W3DRoadBuffer::updateLighting(void) { + /* + CRASH FIX: Kris Morness + When the player alt-tabs out of the game, m_roads is freed up, but when the other player + places a structure in this area, the terrain gets flattened and calls this code, and BOOM! + + Submitted By: Lee, Pei + Date Submitted: 08/21/03 18:47:25 + Found: + When playing a 2 player game both as USA-based armies, if one of the players uses Satellite Spy to reveal an area not yet reveal by either player then Alt-Tab's out, and then the enemy send a dozer over to build some structure in the previously revealed area, then the game will crash to desktop for the player who Alt-Tab'd. + + Steps to reproduce: + - Play a 2 player network game with both player being USA. + (Not sure if this will happen if the players are of different USA-based armies) + - Have the victim reveal an area that is not yet reveal to either player. + - Wait until the area has been shrouded again. (Not sure if required) + - Have the victim Alt-Tab. + - Have the remaining player then send a dozer to build a Cold Fusion Reactor in the area + previously revealed by the other player's Spy Satellite. (Not sure if it has to be Cold Fusion + Reactor.) + + Result: + As soon as the fence is set up, the player who Alt-tab'd would get Zero Hour crashing to desktop with Serious Error occured. + */ + if( !m_roads ) + { + return; + } Int curRoad; // Do road segments. for (curRoad=0; curRoadm_maxVisibleOccluderObjects]; m_potentialOccludees = NEW RenderObjClass* [TheGlobalData->m_maxVisibleOccludeeObjects]; m_nonOccludersOrOccludees = NEW RenderObjClass* [TheGlobalData->m_maxVisibleNonOccluderOrOccludeeObjects]; + #ifdef USE_NON_STENCIL_OCCLUSION for (i=0; igetFrame(); + if (currentFrame <= TheGlobalData->m_defaultOcclusionDelay) + currentFrame = TheGlobalData->m_defaultOcclusionDelay+1; //make sure occlusion is enabled when game starts (frame 0). + + + if (ShaderClass::Is_Backface_Culling_Inverted()) + { //we are rendering reflections + ///@todo: Have better flag to detect reflection pass + + // Loop over all top-level RenderObjects in this scene. If the bounding sphere is not in front + // of all the frustum planes, it is invisible. + for (it.First(); !it.Is_Done(); it.Next()) { + + robj = it.Peek_Obj(); + + draw=NULL; + drawInfo = (DrawableInfo *)robj->Get_User_Data(); + if (drawInfo) + draw=drawInfo->m_drawable; + + if( draw ) + { + if (robj->Is_Force_Visible()) { + robj->Set_Visible(true); + } else { + robj->Set_Visible(draw->getDrawsInMirror() && !camera->Cull_Sphere(robj->Get_Bounding_Sphere())); + } + } + else + { //perform normal culling on non-drawables + if (robj->Is_Force_Visible()) { + robj->Set_Visible(true); + } else { + robj->Set_Visible(!camera->Cull_Sphere(robj->Get_Bounding_Sphere())); + } + } + } + } + else + { + + // Loop over all top-level RenderObjects in this scene. If the bounding sphere is not in front + // of all the frustum planes, it is invisible. + for (it.First(); !it.Is_Done(); it.Next()) { + + robj = it.Peek_Obj(); + + if (robj->Is_Force_Visible()) { + robj->Set_Visible(true); + } else if (robj->Is_Hidden()) { + robj->Set_Visible(false); + } else { + + UnsignedByte isVisible = 0; + + + //Cheater Foil + isVisible |= (UnsignedByte)(camera->Cull_Sphere(robj->Get_Bounding_Sphere()) == FALSE); + isVisible |= (UnsignedByte)(draw->isDrawableEffectivelyHidden()); + isVisible |= (draw->getFullyObscuredByShroudWithCheatSpy()); + robj->Set_VisibleWithCheatSpy(isVisible); + if (robj->Is_VisibleWithCheatSpy())//this will clear for the bit set above + + { //need to keep track of occluders and ocludees for subsequent code. + drawInfo = (DrawableInfo *)robj->Get_User_Data(); + if (drawInfo && (draw=drawInfo->m_drawable) != NULL) + { + +// now handled above in the cheater foil <<<<<<<<<<<< +// if (draw->isDrawableEffectivelyHidden() || draw->getFullyObscuredByShroud()) +// { robj->Set_Visible(false); +// continue; +// } + //assume normal rendering. + drawInfo->m_flags = DrawableInfo::ERF_IS_NORMAL; //clear any rendering flags that may be in effect. + + + if (draw->getEffectiveOpacity() != 1.0f && m_translucentObjectsCount < TheGlobalData->m_maxVisibleTranslucentObjects) + { drawInfo->m_flags |= DrawableInfo::ERF_IS_TRANSLUCENT; //object is translucent + m_translucentObjectsBuffer[m_translucentObjectsCount++] = robj; + } + if (TheGlobalData->m_enableBehindBuildingMarkers && TheGameLogic->getShowBehindBuildingMarkers()) + { + //visible drawable. Check if it's either an occluder or occludee + if (draw->isKindOf(KINDOF_STRUCTURE) && m_numPotentialOccluders < TheGlobalData->m_maxVisibleOccluderObjects) + { //object which could occlude other objects that need to be visible. + //Make sure this object is not translucent so it's not rendered twice (from m_potentialOccluders and m_translucentObjectsBuffer) + if (drawInfo->m_flags ^ DrawableInfo::ERF_IS_TRANSLUCENT) + m_potentialOccluders[m_numPotentialOccluders++]=robj; + drawInfo->m_flags |= DrawableInfo::ERF_POTENTIAL_OCCLUDER; + } + else + if (draw->getObject() && + (draw->isKindOf(KINDOF_SCORE) || draw->isKindOf(KINDOF_SCORE_CREATE) || draw->isKindOf(KINDOF_SCORE_DESTROY) || draw->isKindOf(KINDOF_MP_COUNT_FOR_VICTORY)) && + (draw->getObject()->getSafeOcclusionFrame()) <= currentFrame && m_numPotentialOccludees < TheGlobalData->m_maxVisibleOccludeeObjects) + { //object which could be occluded but still needs to be visible. + //We process transucent units twice (also in m_translucentObjectsBuffer) because we need to see them when occluded. + m_potentialOccludees[m_numPotentialOccludees++]=robj; + drawInfo->m_flags |= DrawableInfo::ERF_POTENTIAL_OCCLUDEE; + } + else + if (drawInfo->m_flags == DrawableInfo::ERF_IS_NORMAL && m_numNonOccluderOrOccludee < TheGlobalData->m_maxVisibleNonOccluderOrOccludeeObjects) + { //regular object with no custom effects but still needs to be delayed to get the occlusion feature to work correctly. + //Make sure this object is not translucent so it's not rendered twice (from m_potentialOccluders and m_translucentObjectsBuffer) + if (drawInfo->m_flags ^ DrawableInfo::ERF_IS_TRANSLUCENT) //make sure not translucent + m_nonOccludersOrOccludees[m_numNonOccluderOrOccludee++]=robj; + drawInfo->m_flags |= DrawableInfo::ERF_IS_NON_OCCLUDER_OR_OCCLUDEE; + } + } + + + } + } + +// robj->Set_Visible(isVisible); //now handled above in the cheater foil + } + + ///@todo: We're not using LOD yet so I disabled this code. MW + // Also, should check how multiple passes (reflections) get along + // with the LOD manager - we're rendering double the load it thinks we are. + // Prepare visible objects for LOD: + // if (robj->Is_Really_Visible()) { + // robj->Prepare_LOD(*camera); + // } + } + } + + Visibility_Checked = true; +} + + + * + */ + diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DShroud.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DShroud.cpp index 2926c39464..fffe94aad4 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DShroud.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DShroud.cpp @@ -125,8 +125,8 @@ void W3DShroud::init(WorldHeightMap *pMap, Real worldCellSizeX, Real worldCellSi //Precompute a bounding box for entire shroud layer if (pMap) { - m_numCellsX = REAL_TO_INT_CEIL((Real)(pMap->getXExtent() - 1 - pMap->getBorderSize()*2)*MAP_XY_FACTOR/m_cellWidth); - m_numCellsY = REAL_TO_INT_CEIL((Real)(pMap->getYExtent() - 1 - pMap->getBorderSize()*2)*MAP_XY_FACTOR/m_cellHeight); + m_numCellsX = REAL_TO_INT_CEIL((Real)(pMap->getXExtent() - 1 - pMap->getBorderSizeInline()*2)*MAP_XY_FACTOR/m_cellWidth); + m_numCellsY = REAL_TO_INT_CEIL((Real)(pMap->getYExtent() - 1 - pMap->getBorderSizeInline()*2)*MAP_XY_FACTOR/m_cellHeight); //Maximum visible cells will depend on maximum drawable terrain size plus 1 for partial cells (since //shroud cells are larger than terrain cells). @@ -614,10 +614,10 @@ void W3DShroud::render(CameraClass *cam) WorldHeightMap *hm=TheTerrainRenderObject->getMap(); - Int visStartX=REAL_TO_INT_FLOOR((Real)(hm->getDrawOrgX()-hm->getBorderSize())*MAP_XY_FACTOR/m_cellWidth); //start of rendered heightmap rectangle + Int visStartX=REAL_TO_INT_FLOOR((Real)(hm->getDrawOrgX()-hm->getBorderSizeInline())*MAP_XY_FACTOR/m_cellWidth); //start of rendered heightmap rectangle if (visStartX < 0) visStartX = 0; //no shroud is applied in border area so it always starts at > 0 - Int visStartY=REAL_TO_INT_FLOOR((Real)(hm->getDrawOrgY()-hm->getBorderSize())*MAP_XY_FACTOR/m_cellHeight); + Int visStartY=REAL_TO_INT_FLOOR((Real)(hm->getDrawOrgY()-hm->getBorderSizeInline())*MAP_XY_FACTOR/m_cellHeight); if (visStartY < 0) visStartY = 0; //no shroud is applied in border area so it always starts at > 0 Int visEndX=visStartX+REAL_TO_INT_FLOOR((Real)(hm->getDrawWidth()-1)*MAP_XY_FACTOR/m_cellWidth)+1; //size of rendered heightmap rectangle diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainVisual.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainVisual.cpp index e94dc4114d..05103f0da2 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainVisual.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3DTerrainVisual.cpp @@ -552,8 +552,8 @@ Bool W3DTerrainVisual::getWaterGridHeight( Real worldX, Real worldY, Real *heigh void W3DTerrainVisual::setRawMapHeight(const ICoord2D *gridPos, Int height) { if (m_terrainHeightMap) { - Int x = gridPos->x+m_terrainHeightMap->getBorderSize(); - Int y = gridPos->y+m_terrainHeightMap->getBorderSize(); + Int x = gridPos->x+m_terrainHeightMap->getBorderSizeInline(); + Int y = gridPos->y+m_terrainHeightMap->getBorderSizeInline(); //if (m_terrainHeightMap->getHeight(x,y) != height) //ML changed to prevent scissoring with roads if (m_terrainHeightMap->getHeight(x,y) > height) { diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3dWaypointBuffer.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3dWaypointBuffer.cpp index 9dd10b11df..92a6247eaa 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3dWaypointBuffer.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/W3dWaypointBuffer.cpp @@ -105,16 +105,9 @@ W3DWaypointBuffer::W3DWaypointBuffer(void) m_line = new SegmentedLineClass; m_texture = WW3DAssetManager::Get_Instance()->Get_Texture( "EXLaser.tga" ); - if( m_texture ) - { - m_line->Set_Texture( m_texture ); - } - ShaderClass lineShader=ShaderClass::_PresetAdditiveShader; - lineShader.Set_Depth_Compare(ShaderClass::PASS_ALWAYS); - m_line->Set_Shader( lineShader ); //pick the alpha blending mode you want - see shader.h for others. - m_line->Set_Width( 1.5f ); - m_line->Set_Color( Vector3( 0.25f, 0.5f, 1.0f ) ); - m_line->Set_Texture_Mapping_Mode( SegLineRendererClass::TILED_TEXTURE_MAP ); //this tiles the texture across the line + + + setDefaultLineStyle(); } //============================================================================= @@ -139,6 +132,21 @@ void W3DWaypointBuffer::freeWaypointBuffers() } +void W3DWaypointBuffer::setDefaultLineStyle( void ) +{ + if( m_texture ) + { + m_line->Set_Texture( m_texture ); + } + ShaderClass lineShader=ShaderClass::_PresetAdditiveShader; + lineShader.Set_Depth_Compare(ShaderClass::PASS_ALWAYS); + m_line->Set_Shader( lineShader ); //pick the alpha blending mode you want - see shader.h for others. + m_line->Set_Width( 1.5f ); + m_line->Set_Color( Vector3( 0.25f, 0.5f, 1.0f ) ); + m_line->Set_Texture_Mapping_Mode( SegLineRendererClass::TILED_TEXTURE_MAP ); //this tiles the texture across the line +} + + //============================================================================= // W3DWaypointBuffer::drawWaypoints //============================================================================= @@ -147,7 +155,15 @@ void W3DWaypointBuffer::freeWaypointBuffers() void W3DWaypointBuffer::drawWaypoints(RenderInfoClass &rinfo) { - if( TheInGameUI && TheInGameUI->isInWaypointMode() ) + if ( ! TheInGameUI ) + return; + + + setDefaultLineStyle(); + + + + if( TheInGameUI->isInWaypointMode() ) { //Create a default light environment with no lights and only full ambient. //@todo: Fix later by copying default scene light environement from W3DScene.cpp. @@ -200,7 +216,6 @@ void W3DWaypointBuffer::drawWaypoints(RenderInfoClass &rinfo) } } else // maybe we want to draw rally points, then? - if (TheInGameUI) { //Create a default light environment with no lights and only full ambient. //@todo: Fix later by copying default scene light environement from W3DScene.cpp. diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp index 8967d104aa..37f125141b 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/Water/W3DWaterTracks.cpp @@ -866,6 +866,9 @@ Try improving the fit to vertical surfaces like cliffs. */ Int diffuseLight; + if (!TheGlobalData->m_showSoftWaterEdge) + return; + if (TheGlobalData->m_usingWaterTrackEditor) TestWaterUpdate(); diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/WorldHeightMap.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/WorldHeightMap.cpp index c35d24957c..260ab98219 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/WorldHeightMap.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/WorldHeightMap.cpp @@ -54,6 +54,12 @@ #include "Common/file.h" +#ifdef _INTERNAL +// for occasional debugging... +//#pragma optimize("", off) +//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes") +#endif + #define K_OBSOLETE_HEIGHT_MAP_VERSION 8 #define PATHFIND_CLIFF_SLOPE_LIMIT_F 9.8f @@ -1093,7 +1099,7 @@ Bool WorldHeightMap::ParseObjectData(DataChunkInput &file, DataChunkInfo *info, // create the map object pThisOne = newInstance( MapObject )( loc, name, angle, flags, &d, - TheThingFactory->findTemplate( name ) ); + TheThingFactory->findTemplate( name, FALSE ) ); //DEBUG_LOG(("obj %s owner %s\n",name.str(),d.getAsciiString(TheKey_originalOwner).str())); @@ -1946,6 +1952,12 @@ void WorldHeightMap::getAlphaUVData(Int xIndex, Int yIndex, float U[4], float V[ #endif } +void WorldHeightMap::setTextureLOD(Int lod) +{ + if (m_terrainTex) + m_terrainTex->setLOD(lod); +} + TextureClass *WorldHeightMap::getTerrainTexture(void) { if (m_terrainTex == NULL) { diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameLogic/W3DGhostObject.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameLogic/W3DGhostObject.cpp index 9af3f0ec67..f500451138 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameLogic/W3DGhostObject.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameLogic/W3DGhostObject.cpp @@ -84,6 +84,7 @@ class W3DRenderObjectSnapshot : public Snapshot static RenderObjClass::Material_Override animationDisableOverride; //Helper function used to disable all UV mapper animations on a given model. +//Also use this pass to disable muzzle effects. void disableUVAnimations(RenderObjClass *robj) { if (robj && robj->Class_ID() == RenderObjClass::CLASSID_HLOD) @@ -107,6 +108,9 @@ void disableUVAnimations(RenderObjClass *robj) } REF_PTR_RELEASE(mat); } + //We don't want muzzle flashes visible inside fog, so turn them off. + if (subObj->Get_Name() && strstr(subObj->Get_Name(),"MUZZLEFX")) + subObj->Set_Hidden(true); } REF_PTR_RELEASE(subObj); } diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameLogic/W3DTerrainLogic.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameLogic/W3DTerrainLogic.cpp index 5bb26b9c7b..33ea80e805 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameLogic/W3DTerrainLogic.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameLogic/W3DTerrainLogic.cpp @@ -254,7 +254,7 @@ void W3DTerrainLogic::getExtentIncludingBorder( Region3D *extent ) const extent->lo.x = 0.0f; extent->lo.y = 0.0f; - Real border = TheTerrainRenderObject->getMap()->getBorderSize() * MAP_XY_FACTOR; + Real border = TheTerrainRenderObject->getMap()->getBorderSizeInline() * MAP_XY_FACTOR; extent->lo.x -= border; extent->lo.y -= border; extent->hi.x = (m_mapDX * MAP_XY_FACTOR)-border; diff --git a/Generals/Code/GameEngineDevice/Source/Win32Device/Common/Win32GameEngine.cpp b/Generals/Code/GameEngineDevice/Source/Win32Device/Common/Win32GameEngine.cpp index 0844c7fb55..fa6417f794 100644 --- a/Generals/Code/GameEngineDevice/Source/Win32Device/Common/Win32GameEngine.cpp +++ b/Generals/Code/GameEngineDevice/Source/Win32Device/Common/Win32GameEngine.cpp @@ -111,6 +111,12 @@ void Win32GameEngine::update( void ) break; // keep running. } } + + // When we are alt-tabbed out... the MilesAudioManager seems to go into a coma sometimes + // and not regain focus properly when we come back. This seems to wake it up nicely. + AudioAffect aa = (AudioAffect)0x10; + TheAudio->setVolume(TheAudio->getVolume( aa ), aa ); + } // allow windows to perform regular windows maintenance stuff like msgs