#define MW4PRINT #define Check_Pointer(x) #define Check_Object(x) #define Verify(x) #define gosASSERT(x) #define MString CString #define GetLengthSafe GetLength #define Scalar float #define Max_Clamp(v,c) if (v>c) v=c; else (void)0 class ReplicatorID; class MemoryStream; class DynamicMemoryStream; namespace Adept { enum { BeamDamageType = 0, MissileDamageType, ProjectileDamageType, SplashDamageType, HeatDamageType, RammingDamageFromAboveType, RammingDamageFromBelowType, RammingDamageFromLeftType, RammingDamageFromRightType, RammingDamageFromAheadType, RammingDamageFromBehindType, HighExplosiveDamageType, LavaDamageType, AmmoFireDamageType }; namespace DamageObject { enum { NullZone=-1, LeftLegZone = 0, //Mech pieces must follow default zone RightLegZone, LeftArmZone, RightArmZone, RightTorsoZone, LeftTorsoZone, CenterTorsoZone, HeadZone, SpecialZone1, SpecialZone2, VehicleHullZone, //All Vehicle and non-mech zones must be after the specials VehicleWeaponZone, VehicleSpecialZone, DefaultZone, NextDamageZone }; enum { NullArmorZone=-1, LeftLegArmorZone = 0, RightLegArmorZone, LeftArmArmorZone, RightArmArmorZone, RightTorsoArmorZone, LeftTorsoArmorZone, CenterTorsoArmorZone, CenterRearTorsoArmorZone, HeadArmorZone, SpecialArmorZone1, SpecialArmorZone2, DefaultArmorZone }; } class AdeptNetMissionParameters { public: int m_runDedicated; int m_closedGame; int m_playerLimit; int m_visibility; AdeptNetMissionParameters(); virtual void ResetParameters(void); virtual void SaveParameters(DynamicMemoryStream *stream); virtual void LoadParameters(MemoryStream *stream); }; } using namespace Adept; namespace NetMissionParameters { class TeamParameters { public: int m_maxPlayersOnTeam; int m_minimumTonnage; int m_maximumTonnage; int m_maximumTotalTonnage; Scalar m_currentTotalTonnage; int m_skin; int m_alignment; DWORD m_allowedMech[2]; DWORD m_allowedBeam[2]; DWORD m_allowedMissile[2]; DWORD m_allowedProjectile[2]; DWORD m_allowedSubsystem[2]; TeamParameters(); void ResetParameters(int index); void SaveParameters(DynamicMemoryStream *stream); void LoadParameters(MemoryStream *stream); }; class MWNetMissionParameters : public AdeptNetMissionParameters { public: int m_joinInProgress; int m_joinInProgressCutOff; int m_joinInProgressCutOffTime; int m_heatOn; int m_killLimit; int m_killLimitNumber; int m_respawnLimit; int m_respawnLimitNumber; int m_forceRespawn; int m_splashOn; int m_weaponjamOn; int m_ammobayfireOn; // MSL 5.05 Advance Mode int m_advancemodeOn; // MSL 5.06 Armor Mode int m_armormodeOn; int m_splashPercentage; int m_unlimitedAmmo; int m_friendlyFirePercentage; int m_allowZoom; int m_allow3rdPerson; int m_allowAutoAim; int m_allowDeadToChat; int m_invulnerableDrop; int m_isNight; int m_weather; int m_reportStats; int m_serverConnection; int m_serverBandwidth; int m_radarMode; int m_onlyStockMech; int m_minimumTonnage; int m_maximumTonnage; int m_gameLength; int m_serverRecycle; int m_recycleDelay; int m_playMissionReview; int m_ruleType; int m_deadMechCantSee; int m_deadMechCantSeeOtherTeam; int m_allowdecaltransfer; int m_useMapCycle; int m_pureMapCycle; DWORD m_allowedMech[2]; DWORD m_allowedBeam[2]; DWORD m_allowedMissile[2]; DWORD m_allowedProjectile[2]; DWORD m_allowedSubsystem[2]; // there are always 8 teams, // but sometimes a team won't allow players int m_teamAllowed; int m_teamCount; TeamParameters m_teamParams[8]; int m_maxPlayers; int m_maxBots; int m_mapID; char m_mapName[128]; char m_scenarioName[128]; char m_scenarioPath[128]; char m_serverName[256]; char m_serverIP[256]; char m_serverCPU[256]; char m_scriptName[256]; char m_scenarioText[1024]; __int64 m_mapClientCRC; MWNetMissionParameters(); void ResetParameters(void); void SaveParameters(DynamicMemoryStream *stream); void LoadParameters(MemoryStream *stream); }; }; using namespace NetMissionParameters; namespace CBucketManager { enum Bucket_Type { KILL_LINK = 0, // linked to mission scoring system DEATH_LINK = 1, // linked to mission scoring system // mods KILLS = 2, FRIENDLY_KILLS = 3, ENEMY_KILLS = 4, KILLS_BY_TONNAGE = 5, FRIENDLY_KILLS_BY_TONNAGE = 6, ENEMY_KILLS_BY_TONNAGE = 7, DEATHS = 8, SUICIDES = 9, DAMAGE_INFLICT = 10, FRIENDLY_DAMAGE_INFLICT = 11, ENEMY_DAMAGE_INFLICT = 12, DAMAGE_RECEIVE = 13, FRIENDLY_DAMAGE_RECEIVE = 14, ENEMY_DAMAGE_RECEIVE = 15, COMPONENT_KILLS = 16, COMPONENT_DEATHS = 17, FRIENDLY_COMPONENT_KILLS = 18, FRIENDLY_COMPONENT_DEATHS = 19, ENEMY_COMPONENT_KILLS = 20, ENEMY_COMPONENT_DEATHS = 21, DFA = 22, SHOTS_HIT = 23, SHOTS_FIRED = 24, HEAD_SHOTS = 25, ARM_SHOTS = 26, LEG_SHOTS = 27, TORSO_SHOTS = 28, KILLS_PC = 29, KILLS_AI = 30, BLANK = 31, // used just to hold values // these are automatically checked SHUTDOWN_TIMER = 32, OBJECTIVE = 33, // mod2 is distance OBJECTIVE_CONTESTED = 34, OBJECTIVE_UNCONTESTED = 35, FLAGS_TAKEN = 36, FLAGS_DROPPED = 37, FLAGS_CAPTURED = 38, FLAG_HOLD_TIME = 39, TIME = 40, ALIVE_PLAYERS = 41, DEAD_PLAYERS = 42, CUSTOM = 43, // MSL 5.04 bucket // MAX_TYPES = 44 ENEMY_TURRET_KILLS = 44, FRIENDLY_TURRET_KILLS = 45, ENEMY_BUILDING_KILLS = 46, FRIENDLY_BUILDING_KILLS = 47, MAX_TYPES = 48 }; } using namespace CBucketManager; namespace MWApplication { enum Bandwidth_Type{ c_14_4kbps = 0, c_28_8kbps, c_56_6kbps, c_64_kbps, c_128_kbps, c_384_kbps, c_768_kbps, c_1500_kbps, c_10_Mbps, c_100_Mbps }; enum Connection_Type{ Modem = 0, ISDN, xDSL, Cable, LAN }; } using namespace MWApplication; class ReplicatorID { public: ReplicatorID() : connectionID(0), localID(0) {Check_Pointer(this);} ReplicatorID(const ReplicatorID& id) : connectionID(id.connectionID), localID(id.localID) {Check_Pointer(this); Check_Object(&id);} explicit ReplicatorID(BYTE connection_id) : connectionID(connection_id), localID(0) {Check_Pointer(this);} ReplicatorID(BYTE connection_id, WORD local_id) : connectionID(connection_id), localID(local_id) {Check_Pointer(this);} public: static ReplicatorID Null; bool operator!() const { Check_Object(this); return operator==(Null); } ReplicatorID& operator=(const ReplicatorID& id) { Check_Pointer(this); Check_Object(&id); connectionID = id.connectionID; localID = id.localID; return *this; } ReplicatorID& operator+=(const ReplicatorID& id) { Check_Object(this); Check_Object(&id); connectionID = static_cast(connectionID + id.connectionID); localID = static_cast(localID + id.localID); return *this; } ReplicatorID& operator+=(WORD span) { Check_Object(this); localID = static_cast(localID + span); return *this; } ReplicatorID& operator++() {Check_Pointer(this); ++localID; return *this;} bool operator<(const ReplicatorID& id) const { Check_Object(this); Check_Object(&id); return (connectionID == id.connectionID) ? (localID < id.localID) : (connectionID < id.connectionID); } bool operator<=(const ReplicatorID& id) const { Check_Object(this); Check_Object(&id); return (connectionID == id.connectionID) ? (localID <= id.localID) : (connectionID < id.connectionID); } bool operator>(const ReplicatorID& id) const { Check_Object(this); Check_Object(&id); return (connectionID == id.connectionID) ? (localID > id.localID) : (connectionID > id.connectionID); } bool operator>=(const ReplicatorID& id) const { Check_Object(this); Check_Object(&id); return (connectionID == id.connectionID) ? (localID >= id.localID) : (connectionID > id.connectionID); } bool operator==(const ReplicatorID& id) const { Check_Object(this); Check_Object(&id); return (connectionID == id.connectionID && localID == id.localID); } bool operator!=(const ReplicatorID& id) const { Check_Object(this); Check_Object(&id); return (connectionID != id.connectionID || localID != id.localID); } BYTE connectionID; WORD localID; }; const int End_Of_Stream=-1; const int Empty_Bit_Buffer=-20; class MemoryStream { public: MemoryStream(void *stream_start, DWORD stream_size, DWORD initial_offset=0); virtual ~MemoryStream(); public: virtual void* GetPointer() const {Check_Object(this); return currentPosition;} BYTE* GetStreamStart() const {Check_Object(this); return streamStart; } DWORD GetIndex() const {Check_Object(this); return currentPosition - streamStart;} DWORD GetSize() const {Check_Object(this); return streamSize;} DWORD GetBufferBytesUsed() {Check_Object(this); return highWaterByte - streamStart;} DWORD GetBytesUsed() const {Check_Object(this); return currentPosition - streamStart;} virtual DWORD GetBytesRemaining() const {Check_Object(this); return streamSize - GetBytesUsed();} void AdvanceToDwordBoundary() { Check_Pointer(this); if((int)currentPosition & 0x3) { AdvancePointer(4-(int)currentPosition & 0x3); } Check_Object(this); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Assignment methods // public: virtual void SetPointer(void *new_pointer) { Check_Pointer(this); currentPosition = (BYTE*)new_pointer; if (currentPosition > highWaterByte) highWaterByte = currentPosition; Check_Object(this); } void operator=(void *new_pointer) {SetPointer(new_pointer);} virtual void SetPointer(DWORD index) { Check_Pointer(this); currentPosition = streamStart + index; if (currentPosition > highWaterByte) highWaterByte = currentPosition; Check_Object(this); } void operator=(DWORD index) {SetPointer(index);} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Stream methods // public: void Rewind() {SetPointer((DWORD) 0U);currentBit = Empty_Bit_Buffer;} virtual bool AllocateBytes(DWORD count) {return GetBytesRemaining() <= count;} virtual MemoryStream& AdvancePointer(DWORD count) { Check_Object(this); currentPosition += count; if (currentPosition > highWaterByte) highWaterByte = currentPosition; Verify(currentPosition >= streamStart); Verify(currentPosition <= streamStart + streamSize); Check_Object(this); return *this; } MemoryStream& operator+=(DWORD count) {return AdvancePointer(count);} virtual MemoryStream& RewindPointer(DWORD count) { Check_Object(this); currentPosition -= count; if (currentPosition > highWaterByte) highWaterByte = currentPosition; Verify(currentPosition >= streamStart); Verify(currentPosition <= streamStart + streamSize); Check_Object(this); return *this; } MemoryStream& operator-=(DWORD count) {return RewindPointer(count);} virtual MemoryStream& ReadBytes( void *ptr, DWORD number_of_bytes ); virtual MemoryStream& WriteBytes( const void *ptr, DWORD number_of_bytes ); MemoryStream& ReadSwappedBytes( void *ptr, DWORD number_of_bytes ); MemoryStream& WriteSwappedBytes( const void *ptr, DWORD number_of_bytes ); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Bit operators // // WARNING - DO NOT MIX AND MATCH WITH BYTE METHODS!!!!! // private: int currentBit; BYTE workingBitBuffer; MemoryStream& ReadUnsafeBits(void *ptr, DWORD number_of_bits); public: int GetCurrentBitCount() { Check_Object(this); int current_bit = GetBytesUsed() * 8; if (currentBit != Empty_Bit_Buffer) { current_bit -= (8-currentBit); } return current_bit; } MemoryStream& ReadBit(bool &bit_value); MemoryStream& WriteBit(const bool &bit_value); MemoryStream& ReadBits(__int64 *ptr, DWORD number_of_bits) { Verify(number_of_bits <= 64); Check_Object(this); Check_Pointer(ptr); *ptr = 0; return ReadUnsafeBits(ptr, number_of_bits); } MemoryStream& ReadBits(int *ptr, DWORD number_of_bits) { Verify(number_of_bits <= 32); Check_Object(this); Check_Pointer(ptr); *ptr = 0; return ReadUnsafeBits(ptr, number_of_bits); } MemoryStream& ReadBits(BYTE *ptr, DWORD number_of_bits) { Verify(number_of_bits <= 8); Check_Object(this); Check_Pointer(ptr); *ptr = 0; return ReadUnsafeBits(ptr, number_of_bits); } MemoryStream& ReadBits(WORD *ptr, DWORD number_of_bits) { Verify(number_of_bits <= 16); Check_Object(this); Check_Pointer(ptr); *ptr = 0; return ReadUnsafeBits(ptr, number_of_bits); } MemoryStream& ReadBits(DWORD *ptr, DWORD number_of_bits) { Verify(number_of_bits <= 32); Check_Object(this); Check_Pointer(ptr); *ptr = 0; return ReadUnsafeBits(ptr, number_of_bits); } MemoryStream& ReadBits(float *ptr, DWORD number_of_bits) { Verify(number_of_bits == 32); Check_Object(this); Check_Pointer(ptr); *ptr = 0.0; return ReadUnsafeBits(ptr, number_of_bits); } MemoryStream& ReadBits(double *ptr, DWORD number_of_bits) { Verify(number_of_bits == 64); Check_Object(this); Check_Pointer(ptr); *ptr = 0.0; return ReadUnsafeBits(ptr, number_of_bits); } MemoryStream& WriteBits(const void *ptr, DWORD number_of_bits); MemoryStream& ReadBitsToScaledInt(int &number, int min, int max, DWORD number_of_bits); MemoryStream& WriteScaledIntToBits(const int &number, int min, int max, DWORD number_of_bits); MemoryStream& ReadBitsToScaledFloat(float &number, float min, float max, DWORD number_of_bits); MemoryStream& WriteScaledFloatToBits(const float &number, float min, float max, DWORD number_of_bits); void WriteByteAlign(); void ReadByteAlign(); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Protected data // protected: BYTE *streamStart, *currentPosition, *highWaterByte; DWORD streamSize; }; class DynamicMemoryStream: public MemoryStream { //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Construction, destruction, and testing // public: DynamicMemoryStream(DWORD stream_size=0); DynamicMemoryStream( void *stream_start, DWORD stream_size, DWORD initial_offset=0 ); DynamicMemoryStream(const DynamicMemoryStream& otherStream); ~DynamicMemoryStream(); void TestInstance() const { Verify((DWORD)(currentPosition - streamStart) <= streamSize); Verify(streamSize <= bufferSize); } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Accessors // public: DWORD GetBufferSize() { Check_Object(this); return bufferSize; } void SetSize(DWORD stream_length) { Check_Object(this); Verify(stream_length <= bufferSize); streamSize = stream_length; } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Stream methods // public: MemoryStream& WriteBytes( const void *ptr, DWORD number_of_bytes ); bool AllocateBytes(DWORD count); //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // Private data // private: DWORD bufferSize; bool ownsStream; };