Browse files

added new map config value map_options

added support for custom maps that allow selectable teams, colours, and races
changed the meaning of SLOTRACE_FIXED to SLOTRACE_SELECTABLE as the previous meaning was incorrect
fixed the bot's logic for changing teams, colours, and races to take the map options into account
note: these changes may "break" existing map configs since previously the bot would assume a map was "custom" by default and now it assumes a map has selectable teams, colours, and races by default

git-svn-id: http://ghostplusplus.googlecode.com/svn/trunk@411 a7494f72-a4b0-11dd-a887-7ffe1a420f8d
  • Loading branch information...
1 parent 7824c19 commit 295fe3addbebf4fcec127d47921aa46111b1b670 hogantp committed Apr 4, 2010
Showing with 120 additions and 65 deletions.
  1. +9 −9 ghost/game.cpp
  2. +26 −24 ghost/game_base.cpp
  3. +6 −6 ghost/gameprotocol.cpp
  4. +3 −3 ghost/gameprotocol.h
  5. +2 −2 ghost/gameslot.h
  6. +59 −21 ghost/map.cpp
  7. +15 −0 ghost/map.h
View
18 ghost/game.cpp
@@ -722,7 +722,7 @@ bool CGame :: EventPlayerBotCommand( CGamePlayer *player, string command, string
{
unsigned char SID = (unsigned char)( Slot - 1 );
- if( m_Map->GetMapGameType( ) != GAMETYPE_CUSTOM && Colour < 12 && SID < m_Slots.size( ) )
+ if( !( m_Map->GetMapOptions( ) & MAPOPT_FIXEDPLAYERSETTINGS ) && Colour < 12 && SID < m_Slots.size( ) )
{
if( m_Slots[SID].GetSlotStatus( ) == SLOTSTATUS_OCCUPIED && m_Slots[SID].GetComputer( ) == 1 )
ColourSlot( SID, Colour );
@@ -763,7 +763,7 @@ bool CGame :: EventPlayerBotCommand( CGamePlayer *player, string command, string
{
unsigned char SID = (unsigned char)( Slot - 1 );
- if( m_Map->GetMapGameType( ) != GAMETYPE_CUSTOM && ( Handicap == 50 || Handicap == 60 || Handicap == 70 || Handicap == 80 || Handicap == 90 || Handicap == 100 ) && SID < m_Slots.size( ) )
+ if( !( m_Map->GetMapOptions( ) & MAPOPT_FIXEDPLAYERSETTINGS ) && ( Handicap == 50 || Handicap == 60 || Handicap == 70 || Handicap == 80 || Handicap == 90 || Handicap == 100 ) && SID < m_Slots.size( ) )
{
if( m_Slots[SID].GetSlotStatus( ) == SLOTSTATUS_OCCUPIED && m_Slots[SID].GetComputer( ) == 1 )
{
@@ -808,33 +808,33 @@ bool CGame :: EventPlayerBotCommand( CGamePlayer *player, string command, string
transform( Race.begin( ), Race.end( ), Race.begin( ), (int(*)(int))tolower );
unsigned char SID = (unsigned char)( Slot - 1 );
- if( m_Map->GetMapGameType( ) != GAMETYPE_CUSTOM && !( m_Map->GetMapFlags( ) & MAPFLAG_RANDOMRACES ) && SID < m_Slots.size( ) )
+ if( !( m_Map->GetMapOptions( ) & MAPOPT_FIXEDPLAYERSETTINGS ) && !( m_Map->GetMapFlags( ) & MAPFLAG_RANDOMRACES ) && SID < m_Slots.size( ) )
{
if( m_Slots[SID].GetSlotStatus( ) == SLOTSTATUS_OCCUPIED && m_Slots[SID].GetComputer( ) == 1 )
{
if( Race == "human" )
{
- m_Slots[SID].SetRace( SLOTRACE_HUMAN );
+ m_Slots[SID].SetRace( SLOTRACE_HUMAN | SLOTRACE_SELECTABLE );
SendAllSlotInfo( );
}
else if( Race == "orc" )
{
- m_Slots[SID].SetRace( SLOTRACE_ORC );
+ m_Slots[SID].SetRace( SLOTRACE_ORC | SLOTRACE_SELECTABLE );
SendAllSlotInfo( );
}
else if( Race == "night elf" )
{
- m_Slots[SID].SetRace( SLOTRACE_NIGHTELF );
+ m_Slots[SID].SetRace( SLOTRACE_NIGHTELF | SLOTRACE_SELECTABLE );
SendAllSlotInfo( );
}
else if( Race == "undead" )
{
- m_Slots[SID].SetRace( SLOTRACE_UNDEAD );
+ m_Slots[SID].SetRace( SLOTRACE_UNDEAD | SLOTRACE_SELECTABLE );
SendAllSlotInfo( );
}
else if( Race == "random" )
{
- m_Slots[SID].SetRace( SLOTRACE_RANDOM );
+ m_Slots[SID].SetRace( SLOTRACE_RANDOM | SLOTRACE_SELECTABLE );
SendAllSlotInfo( );
}
else
@@ -876,7 +876,7 @@ bool CGame :: EventPlayerBotCommand( CGamePlayer *player, string command, string
{
unsigned char SID = (unsigned char)( Slot - 1 );
- if( m_Map->GetMapGameType( ) != GAMETYPE_CUSTOM && Team < 12 && SID < m_Slots.size( ) )
+ if( !( m_Map->GetMapOptions( ) & MAPOPT_FIXEDPLAYERSETTINGS ) && Team < 12 && SID < m_Slots.size( ) )
{
if( m_Slots[SID].GetSlotStatus( ) == SLOTSTATUS_OCCUPIED && m_Slots[SID].GetComputer( ) == 1 )
{
View
50 ghost/game_base.cpp
@@ -1208,7 +1208,7 @@ void CBaseGame :: SendAllSlotInfo( )
{
if( !m_GameLoading && !m_GameLoaded )
{
- SendAll( m_Protocol->SEND_W3GS_SLOTINFO( m_Slots, m_RandomSeed, m_Map->GetMapGameType( ) == GAMETYPE_CUSTOM ? 3 : 0, m_Map->GetMapNumPlayers( ) ) );
+ SendAll( m_Protocol->SEND_W3GS_SLOTINFO( m_Slots, m_RandomSeed, m_Map->GetMapLayoutStyle( ), m_Map->GetMapNumPlayers( ) ) );
m_SlotInfoChanged = false;
}
}
@@ -1753,7 +1753,7 @@ void CBaseGame :: EventPlayerJoined( CPotentialPlayer *potential, CIncomingJoinP
// this causes them to be kicked back to the chat channel on battle.net
vector<CGameSlot> Slots = m_Map->GetSlots( );
- potential->Send( m_Protocol->SEND_W3GS_SLOTINFOJOIN( 1, potential->GetSocket( )->GetPort( ), potential->GetExternalIP( ), Slots, 0, m_Map->GetMapGameType( ) == GAMETYPE_CUSTOM ? 3 : 0, m_Map->GetMapNumPlayers( ) ) );
+ potential->Send( m_Protocol->SEND_W3GS_SLOTINFOJOIN( 1, potential->GetSocket( )->GetPort( ), potential->GetExternalIP( ), Slots, 0, m_Map->GetMapLayoutStyle( ), m_Map->GetMapNumPlayers( ) ) );
potential->SetDeleteMe( true );
return;
}
@@ -1781,7 +1781,7 @@ void CBaseGame :: EventPlayerJoined( CPotentialPlayer *potential, CIncomingJoinP
// this causes them to be kicked back to the chat channel on battle.net
vector<CGameSlot> Slots = m_Map->GetSlots( );
- potential->Send( m_Protocol->SEND_W3GS_SLOTINFOJOIN( 1, potential->GetSocket( )->GetPort( ), potential->GetExternalIP( ), Slots, 0, m_Map->GetMapGameType( ) == GAMETYPE_CUSTOM ? 3 : 0, m_Map->GetMapNumPlayers( ) ) );
+ potential->Send( m_Protocol->SEND_W3GS_SLOTINFOJOIN( 1, potential->GetSocket( )->GetPort( ), potential->GetExternalIP( ), Slots, 0, m_Map->GetMapLayoutStyle( ), m_Map->GetMapNumPlayers( ) ) );
potential->SetDeleteMe( true );
return;
}
@@ -1989,11 +1989,14 @@ void CBaseGame :: EventPlayerJoined( CPotentialPlayer *potential, CIncomingJoinP
m_Slots[SID] = EnforceSlot;
else
{
- if( m_Map->GetMapGameType( ) == GAMETYPE_CUSTOM )
+ if( m_Map->GetMapOptions( ) & MAPOPT_FIXEDPLAYERSETTINGS )
m_Slots[SID] = CGameSlot( Player->GetPID( ), 255, SLOTSTATUS_OCCUPIED, 0, m_Slots[SID].GetTeam( ), m_Slots[SID].GetColour( ), m_Slots[SID].GetRace( ) );
else
{
- m_Slots[SID] = CGameSlot( Player->GetPID( ), 255, SLOTSTATUS_OCCUPIED, 0, 12, 12, SLOTRACE_RANDOM );
+ if( m_Map->GetMapFlags( ) & MAPFLAG_RANDOMRACES )
+ m_Slots[SID] = CGameSlot( Player->GetPID( ), 255, SLOTSTATUS_OCCUPIED, 0, 12, 12, SLOTRACE_RANDOM );
+ else
+ m_Slots[SID] = CGameSlot( Player->GetPID( ), 255, SLOTSTATUS_OCCUPIED, 0, 12, 12, SLOTRACE_RANDOM | SLOTRACE_SELECTABLE );
// try to pick a team and colour
// make sure there aren't too many other players already
@@ -2021,7 +2024,7 @@ void CBaseGame :: EventPlayerJoined( CPotentialPlayer *potential, CIncomingJoinP
// send slot info to the new player
// the SLOTINFOJOIN packet also tells the client their assigned PID and that the join was successful
- Player->Send( m_Protocol->SEND_W3GS_SLOTINFOJOIN( Player->GetPID( ), Player->GetSocket( )->GetPort( ), Player->GetExternalIP( ), m_Slots, m_RandomSeed, m_Map->GetMapGameType( ) == GAMETYPE_CUSTOM ? 3 : 0, m_Map->GetMapNumPlayers( ) ) );
+ Player->Send( m_Protocol->SEND_W3GS_SLOTINFOJOIN( Player->GetPID( ), Player->GetSocket( )->GetPort( ), Player->GetExternalIP( ), m_Slots, m_RandomSeed, m_Map->GetMapLayoutStyle( ), m_Map->GetMapNumPlayers( ) ) );
// send virtual host info and fake player info (if present) to the new player
@@ -2394,7 +2397,7 @@ void CBaseGame :: EventPlayerJoinedWithScore( CPotentialPlayer *potential, CInco
// send slot info to the new player
// the SLOTINFOJOIN packet also tells the client their assigned PID and that the join was successful
- Player->Send( m_Protocol->SEND_W3GS_SLOTINFOJOIN( Player->GetPID( ), Player->GetSocket( )->GetPort( ), Player->GetExternalIP( ), m_Slots, m_RandomSeed, m_Map->GetMapGameType( ) == GAMETYPE_CUSTOM ? 3 : 0, m_Map->GetMapNumPlayers( ) ) );
+ Player->Send( m_Protocol->SEND_W3GS_SLOTINFOJOIN( Player->GetPID( ), Player->GetSocket( )->GetPort( ), Player->GetExternalIP( ), m_Slots, m_RandomSeed, m_Map->GetMapLayoutStyle( ), m_Map->GetMapNumPlayers( ) ) );
// send virtual host info and fake player info (if present) to the new player
@@ -2894,7 +2897,7 @@ void CBaseGame :: EventPlayerChangeTeam( CGamePlayer *player, unsigned char team
if( m_SaveGame )
return;
- if( m_Map->GetMapGameType( ) == GAMETYPE_CUSTOM )
+ if( m_Map->GetMapOptions( ) & MAPOPT_FIXEDPLAYERSETTINGS )
{
unsigned char oldSID = GetSIDFromPID( player->GetPID( ) );
unsigned char newSID = GetEmptySlot( team, player->GetPID( ) );
@@ -2960,7 +2963,7 @@ void CBaseGame :: EventPlayerChangeColour( CGamePlayer *player, unsigned char co
if( m_SaveGame )
return;
- if( m_Map->GetMapGameType( ) == GAMETYPE_CUSTOM )
+ if( m_Map->GetMapOptions( ) & MAPOPT_FIXEDPLAYERSETTINGS )
return;
if( colour > 11 )
@@ -2986,7 +2989,7 @@ void CBaseGame :: EventPlayerChangeRace( CGamePlayer *player, unsigned char race
if( m_SaveGame )
return;
- if( m_Map->GetMapGameType( ) == GAMETYPE_CUSTOM )
+ if( m_Map->GetMapOptions( ) & MAPOPT_FIXEDPLAYERSETTINGS )
return;
if( m_Map->GetMapFlags( ) & MAPFLAG_RANDOMRACES )
@@ -2999,7 +3002,7 @@ void CBaseGame :: EventPlayerChangeRace( CGamePlayer *player, unsigned char race
if( SID < m_Slots.size( ) )
{
- m_Slots[SID].SetRace( race );
+ m_Slots[SID].SetRace( race | SLOTRACE_SELECTABLE );
SendAllSlotInfo( );
}
}
@@ -3011,7 +3014,7 @@ void CBaseGame :: EventPlayerChangeHandicap( CGamePlayer *player, unsigned char
if( m_SaveGame )
return;
- if( m_Map->GetMapGameType( ) == GAMETYPE_CUSTOM )
+ if( m_Map->GetMapOptions( ) & MAPOPT_FIXEDPLAYERSETTINGS )
return;
if( handicap != 50 && handicap != 60 && handicap != 70 && handicap != 80 && handicap != 90 && handicap != 100 )
@@ -3294,7 +3297,7 @@ void CBaseGame :: EventGameStarted( )
m_Replay->SetSlots( m_Slots );
m_Replay->SetRandomSeed( m_RandomSeed );
- m_Replay->SetSelectMode( m_Map->GetMapGameType( ) == GAMETYPE_CUSTOM ? 3 : 0 );
+ m_Replay->SetSelectMode( m_Map->GetMapLayoutStyle( ) );
m_Replay->SetStartSpotCount( m_Map->GetMapNumPlayers( ) );
/*
@@ -3790,19 +3793,19 @@ void CBaseGame :: SwapSlots( unsigned char SID1, unsigned char SID2 )
CGameSlot Slot1 = m_Slots[SID1];
CGameSlot Slot2 = m_Slots[SID2];
- if( m_Map->GetMapGameType( ) != GAMETYPE_CUSTOM )
+ if( m_Map->GetMapOptions( ) & MAPOPT_FIXEDPLAYERSETTINGS )
{
- // regular game - swap everything
+ // don't swap the team, colour, or race
- m_Slots[SID1] = Slot2;
- m_Slots[SID2] = Slot1;
+ m_Slots[SID1] = CGameSlot( Slot2.GetPID( ), Slot2.GetDownloadStatus( ), Slot2.GetSlotStatus( ), Slot2.GetComputer( ), Slot1.GetTeam( ), Slot1.GetColour( ), Slot1.GetRace( ), Slot2.GetComputerType( ), Slot2.GetHandicap( ) );
+ m_Slots[SID2] = CGameSlot( Slot1.GetPID( ), Slot1.GetDownloadStatus( ), Slot1.GetSlotStatus( ), Slot1.GetComputer( ), Slot2.GetTeam( ), Slot2.GetColour( ), Slot2.GetRace( ), Slot1.GetComputerType( ), Slot1.GetHandicap( ) );
}
else
{
- // custom game - don't swap the team, colour, or race
+ // swap everything
- m_Slots[SID1] = CGameSlot( Slot2.GetPID( ), Slot2.GetDownloadStatus( ), Slot2.GetSlotStatus( ), Slot2.GetComputer( ), Slot1.GetTeam( ), Slot1.GetColour( ), Slot1.GetRace( ), Slot2.GetComputerType( ), Slot2.GetHandicap( ) );
- m_Slots[SID2] = CGameSlot( Slot1.GetPID( ), Slot1.GetDownloadStatus( ), Slot1.GetSlotStatus( ), Slot1.GetComputer( ), Slot2.GetTeam( ), Slot2.GetColour( ), Slot2.GetRace( ), Slot1.GetComputerType( ), Slot1.GetHandicap( ) );
+ m_Slots[SID1] = Slot2;
+ m_Slots[SID2] = Slot1;
}
SendAllSlotInfo( );
@@ -3964,9 +3967,8 @@ void CBaseGame :: ShuffleSlots( )
// now we shuffle PlayerSlots
- if( m_Map->GetMapGameType( ) == GAMETYPE_CUSTOM )
+ if( m_Map->GetMapOptions( ) & MAPOPT_FIXEDPLAYERSETTINGS )
{
- // custom game
// rather than rolling our own probably broken shuffle algorithm we use random_shuffle because it's guaranteed to do it properly
// so in order to let random_shuffle do all the work we need a vector to operate on
// unfortunately we can't just use PlayerSlots because the team/colour/race shouldn't be modified
@@ -4110,9 +4112,9 @@ vector<unsigned char> CBaseGame :: BalanceSlotsRecursive( vector<unsigned char>
void CBaseGame :: BalanceSlots( )
{
- if( m_Map->GetMapGameType( ) != GAMETYPE_CUSTOM )
+ if( !( m_Map->GetMapOptions( ) & MAPOPT_FIXEDPLAYERSETTINGS ) )
{
- CONSOLE_Print( "[GAME: " + m_GameName + "] error balancing slots - can't balance slots in non custom games" );
+ CONSOLE_Print( "[GAME: " + m_GameName + "] error balancing slots - can't balance slots without fixed player settings" );
return;
}
View
12 ghost/gameprotocol.cpp
@@ -308,11 +308,11 @@ BYTEARRAY CGameProtocol :: SEND_W3GS_PING_FROM_HOST( )
return packet;
}
-BYTEARRAY CGameProtocol :: SEND_W3GS_SLOTINFOJOIN( unsigned char PID, BYTEARRAY port, BYTEARRAY externalIP, vector<CGameSlot> &slots, uint32_t randomSeed, unsigned char gameType, unsigned char playerSlots )
+BYTEARRAY CGameProtocol :: SEND_W3GS_SLOTINFOJOIN( unsigned char PID, BYTEARRAY port, BYTEARRAY externalIP, vector<CGameSlot> &slots, uint32_t randomSeed, unsigned char layoutStyle, unsigned char playerSlots )
{
unsigned char Zeros[] = { 0, 0, 0, 0 };
- BYTEARRAY SlotInfo = EncodeSlotInfo( slots, randomSeed, gameType, playerSlots );
+ BYTEARRAY SlotInfo = EncodeSlotInfo( slots, randomSeed, layoutStyle, playerSlots );
BYTEARRAY packet;
if( port.size( ) == 2 && externalIP.size( ) == 4 )
@@ -439,9 +439,9 @@ BYTEARRAY CGameProtocol :: SEND_W3GS_GAMELOADED_OTHERS( unsigned char PID )
return packet;
}
-BYTEARRAY CGameProtocol :: SEND_W3GS_SLOTINFO( vector<CGameSlot> &slots, uint32_t randomSeed, unsigned char gameType, unsigned char playerSlots )
+BYTEARRAY CGameProtocol :: SEND_W3GS_SLOTINFO( vector<CGameSlot> &slots, uint32_t randomSeed, unsigned char layoutStyle, unsigned char playerSlots )
{
- BYTEARRAY SlotInfo = EncodeSlotInfo( slots, randomSeed, gameType, playerSlots );
+ BYTEARRAY SlotInfo = EncodeSlotInfo( slots, randomSeed, layoutStyle, playerSlots );
BYTEARRAY packet;
packet.push_back( W3GS_HEADER_CONSTANT ); // W3GS header constant
packet.push_back( W3GS_SLOTINFO ); // W3GS_SLOTINFO
@@ -943,7 +943,7 @@ bool CGameProtocol :: ValidateLength( BYTEARRAY &content )
return false;
}
-BYTEARRAY CGameProtocol :: EncodeSlotInfo( vector<CGameSlot> &slots, uint32_t randomSeed, unsigned char gameType, unsigned char playerSlots )
+BYTEARRAY CGameProtocol :: EncodeSlotInfo( vector<CGameSlot> &slots, uint32_t randomSeed, unsigned char layoutStyle, unsigned char playerSlots )
{
BYTEARRAY SlotInfo;
SlotInfo.push_back( (unsigned char)slots.size( ) ); // number of slots
@@ -952,7 +952,7 @@ BYTEARRAY CGameProtocol :: EncodeSlotInfo( vector<CGameSlot> &slots, uint32_t ra
UTIL_AppendByteArray( SlotInfo, slots[i].GetByteArray( ) );
UTIL_AppendByteArray( SlotInfo, randomSeed, false ); // random seed
- SlotInfo.push_back( gameType ); // GameType (seems to be 0 for regular game, 3 for custom game)
+ SlotInfo.push_back( layoutStyle ); // LayoutStyle (0 = melee, 1 = custom forces, 3 = custom forces + fixed player settings)
SlotInfo.push_back( playerSlots ); // number of player slots (non observer)
return SlotInfo;
}
View
6 ghost/gameprotocol.h
@@ -120,12 +120,12 @@ class CGameProtocol
// send functions
BYTEARRAY SEND_W3GS_PING_FROM_HOST( );
- BYTEARRAY SEND_W3GS_SLOTINFOJOIN( unsigned char PID, BYTEARRAY port, BYTEARRAY externalIP, vector<CGameSlot> &slots, uint32_t randomSeed, unsigned char gameType, unsigned char playerSlots );
+ BYTEARRAY SEND_W3GS_SLOTINFOJOIN( unsigned char PID, BYTEARRAY port, BYTEARRAY externalIP, vector<CGameSlot> &slots, uint32_t randomSeed, unsigned char layoutStyle, unsigned char playerSlots );
BYTEARRAY SEND_W3GS_REJECTJOIN( uint32_t reason );
BYTEARRAY SEND_W3GS_PLAYERINFO( unsigned char PID, string name, BYTEARRAY externalIP, BYTEARRAY internalIP );
BYTEARRAY SEND_W3GS_PLAYERLEAVE_OTHERS( unsigned char PID, uint32_t leftCode );
BYTEARRAY SEND_W3GS_GAMELOADED_OTHERS( unsigned char PID );
- BYTEARRAY SEND_W3GS_SLOTINFO( vector<CGameSlot> &slots, uint32_t randomSeed, unsigned char gameType, unsigned char playerSlots );
+ BYTEARRAY SEND_W3GS_SLOTINFO( vector<CGameSlot> &slots, uint32_t randomSeed, unsigned char layoutStyle, unsigned char playerSlots );
BYTEARRAY SEND_W3GS_COUNTDOWN_START( );
BYTEARRAY SEND_W3GS_COUNTDOWN_END( );
BYTEARRAY SEND_W3GS_INCOMING_ACTION( queue<CIncomingAction *> actions, uint16_t sendInterval );
@@ -147,7 +147,7 @@ class CGameProtocol
private:
bool AssignLength( BYTEARRAY &content );
bool ValidateLength( BYTEARRAY &content );
- BYTEARRAY EncodeSlotInfo( vector<CGameSlot> &slots, uint32_t randomSeed, unsigned char gameType, unsigned char playerSlots );
+ BYTEARRAY EncodeSlotInfo( vector<CGameSlot> &slots, uint32_t randomSeed, unsigned char layoutStyle, unsigned char playerSlots );
};
//
View
4 ghost/gameslot.h
@@ -30,7 +30,7 @@
#define SLOTRACE_NIGHTELF 4
#define SLOTRACE_UNDEAD 8
#define SLOTRACE_RANDOM 32
-#define SLOTRACE_FIXED 64
+#define SLOTRACE_SELECTABLE 64
#define SLOTCOMP_EASY 0
#define SLOTCOMP_NORMAL 1
@@ -49,7 +49,7 @@ class CGameSlot
unsigned char m_Computer; // computer (0 = no, 1 = yes)
unsigned char m_Team; // team
unsigned char m_Colour; // colour
- unsigned char m_Race; // race (1 = human, 2 = orc, 4 = night elf, 8 = undead, 32 = random, 64 = fixed)
+ unsigned char m_Race; // race (1 = human, 2 = orc, 4 = night elf, 8 = undead, 32 = random, 64 = selectable)
unsigned char m_ComputerType; // computer type (0 = easy, 1 = human or normal comp, 2 = hard comp)
unsigned char m_Handicap; // handicap
View
80 ghost/map.cpp
@@ -50,23 +50,24 @@ CMap :: CMap( CGHost *nGHost )
m_MapObservers = MAPOBS_NONE;
m_MapFlags = MAPFLAG_TEAMSTOGETHER | MAPFLAG_FIXEDTEAMS;
m_MapGameType = 9;
+ m_MapOptions = MAPOPT_MELEE;
m_MapWidth = UTIL_ExtractNumbers( "172 0", 2 );
m_MapHeight = UTIL_ExtractNumbers( "172 0", 2 );
m_MapLoadInGame = false;
m_MapNumPlayers = 12;
m_MapNumTeams = 12;
- m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 0, 0, SLOTRACE_RANDOM ) );
- m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 1, 1, SLOTRACE_RANDOM ) );
- m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 2, 2, SLOTRACE_RANDOM ) );
- m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 3, 3, SLOTRACE_RANDOM ) );
- m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 4, 4, SLOTRACE_RANDOM ) );
- m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 5, 5, SLOTRACE_RANDOM ) );
- m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 6, 6, SLOTRACE_RANDOM ) );
- m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 7, 7, SLOTRACE_RANDOM ) );
- m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 8, 8, SLOTRACE_RANDOM ) );
- m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 9, 9, SLOTRACE_RANDOM ) );
- m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 10, 10, SLOTRACE_RANDOM ) );
- m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 11, 11, SLOTRACE_RANDOM ) );
+ m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 0, 0, SLOTRACE_RANDOM | SLOTRACE_SELECTABLE ) );
+ m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 1, 1, SLOTRACE_RANDOM | SLOTRACE_SELECTABLE ) );
+ m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 2, 2, SLOTRACE_RANDOM | SLOTRACE_SELECTABLE ) );
+ m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 3, 3, SLOTRACE_RANDOM | SLOTRACE_SELECTABLE ) );
+ m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 4, 4, SLOTRACE_RANDOM | SLOTRACE_SELECTABLE ) );
+ m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 5, 5, SLOTRACE_RANDOM | SLOTRACE_SELECTABLE ) );
+ m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 6, 6, SLOTRACE_RANDOM | SLOTRACE_SELECTABLE ) );
+ m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 7, 7, SLOTRACE_RANDOM | SLOTRACE_SELECTABLE ) );
+ m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 8, 8, SLOTRACE_RANDOM | SLOTRACE_SELECTABLE ) );
+ m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 9, 9, SLOTRACE_RANDOM | SLOTRACE_SELECTABLE ) );
+ m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 10, 10, SLOTRACE_RANDOM | SLOTRACE_SELECTABLE ) );
+ m_Slots.push_back( CGameSlot( 0, 255, SLOTSTATUS_OPEN, 0, 11, 11, SLOTRACE_RANDOM | SLOTRACE_SELECTABLE ) );
}
CMap :: CMap( CGHost *nGHost, CConfig *CFG, string nCFGFile )
@@ -154,6 +155,22 @@ BYTEARRAY CMap :: GetMapGameFlags( )
return UTIL_CreateByteArray( GameFlags, false );
}
+unsigned char CMap :: GetMapLayoutStyle( )
+{
+ // 0 = melee
+ // 1 = custom forces
+ // 2 = fixed player settings (not possible with the Warcraft III map editor)
+ // 3 = custom forces + fixed player settings
+
+ if( !( m_MapOptions & MAPOPT_CUSTOMFORCES ) )
+ return 0;
+
+ if( !( m_MapOptions & MAPOPT_FIXEDPLAYERSETTINGS ) )
+ return 1;
+
+ return 3;
+}
+
void CMap :: Load( CConfig *CFG, string nCFGFile )
{
m_Valid = true;
@@ -378,6 +395,7 @@ void CMap :: Load( CConfig *CFG, string nCFGFile )
// try to calculate map_width, map_height, map_slot<x>, map_numplayers, map_numteams
+ uint32_t MapOptions = 0;
BYTEARRAY MapWidth;
BYTEARRAY MapHeight;
uint32_t MapNumPlayers = 0;
@@ -552,6 +570,8 @@ void CMap :: Load( CConfig *CFG, string nCFGFile )
getline( ISS, GarbageString, '\0' ); // team name
}
+ MapOptions = RawMapFlags;
+ CONSOLE_Print( "[MAP] calculated map_options = " + UTIL_ToString( MapOptions ) );
MapWidth = UTIL_CreateByteArray( (uint16_t)RawMapWidth, false );
CONSOLE_Print( "[MAP] calculated map_width = " + UTIL_ByteArrayToDecString( MapWidth ) );
MapHeight = UTIL_CreateByteArray( (uint16_t)RawMapHeight, false );
@@ -569,9 +589,7 @@ void CMap :: Load( CConfig *CFG, string nCFGFile )
SlotNum++;
}
- // if it's a melee map...
-
- if( RawMapFlags & 4 )
+ if( MapOptions & MAPOPT_MELEE )
{
CONSOLE_Print( "[MAP] found melee map, initializing slots" );
@@ -585,24 +603,32 @@ void CMap :: Load( CConfig *CFG, string nCFGFile )
(*i).SetRace( SLOTRACE_RANDOM );
}
}
+
+ if( !( MapOptions & MAPOPT_FIXEDPLAYERSETTINGS ) )
+ {
+ // make races selectable
+
+ for( vector<CGameSlot> :: iterator i = Slots.begin( ); i != Slots.end( ); i++ )
+ (*i).SetRace( (*i).GetRace( ) | SLOTRACE_SELECTABLE );
+ }
}
}
else
- CONSOLE_Print( "[MAP] unable to calculate map_width, map_height, map_slot<x>, map_numplayers, map_numteams - unable to extract war3map.w3i from MPQ file" );
+ CONSOLE_Print( "[MAP] unable to calculate map_options, map_width, map_height, map_slot<x>, map_numplayers, map_numteams - unable to extract war3map.w3i from MPQ file" );
delete [] SubFileData;
}
SFileCloseFile( SubFile );
}
else
- CONSOLE_Print( "[MAP] unable to calculate map_width, map_height, map_slot<x>, map_numplayers, map_numteams - couldn't find war3map.w3i in MPQ file" );
+ CONSOLE_Print( "[MAP] unable to calculate map_options, map_width, map_height, map_slot<x>, map_numplayers, map_numteams - couldn't find war3map.w3i in MPQ file" );
}
else
- CONSOLE_Print( "[MAP] unable to calculate map_width, map_height, map_slot<x>, map_numplayers, map_numteams - map MPQ file not loaded" );
+ CONSOLE_Print( "[MAP] unable to calculate map_options, map_width, map_height, map_slot<x>, map_numplayers, map_numteams - map MPQ file not loaded" );
}
else
- CONSOLE_Print( "[MAP] no map data available, using config file for map_width, map_height, map_slot<x>, map_numplayers, map_numteams" );
+ CONSOLE_Print( "[MAP] no map data available, using config file for map_options, map_width, map_height, map_slot<x>, map_numplayers, map_numteams" );
// close the map MPQ
@@ -656,6 +682,18 @@ void CMap :: Load( CConfig *CFG, string nCFGFile )
m_MapFlags = CFG->GetInt( "map_flags", MAPFLAG_TEAMSTOGETHER | MAPFLAG_FIXEDTEAMS );
m_MapGameType = CFG->GetInt( "map_gametype", 1 );
+ // todotodo: it might be possible for MapOptions to legitimately be zero so this is not a valid way of checking if it wasn't parsed out earlier
+
+ if( MapOptions == 0 )
+ MapOptions = CFG->GetInt( "map_options", 0 );
+ else if( CFG->Exists( "map_options" ) )
+ {
+ CONSOLE_Print( "[MAP] overriding calculated map_options with config value map_options = " + CFG->GetString( "map_options", string( ) ) );
+ MapOptions = CFG->GetInt( "map_options", 0 );
+ }
+
+ m_MapOptions = MapOptions;
+
if( MapWidth.empty( ) )
MapWidth = UTIL_ExtractNumbers( CFG->GetString( "map_width", string( ) ), 2 );
else if( CFG->Exists( "map_width" ) )
@@ -734,14 +772,14 @@ void CMap :: Load( CConfig *CFG, string nCFGFile )
m_Slots = Slots;
- // if random races is set force every slot's race to random + fixed
+ // if random races is set force every slot's race to random
if( m_MapFlags & MAPFLAG_RANDOMRACES )
{
CONSOLE_Print( "[MAP] forcing races to random" );
for( vector<CGameSlot> :: iterator i = m_Slots.begin( ); i != m_Slots.end( ); i++ )
- (*i).SetRace( SLOTRACE_RANDOM | SLOTRACE_FIXED );
+ (*i).SetRace( SLOTRACE_RANDOM );
}
// add observer slots
View
15 ghost/map.h
@@ -41,6 +41,18 @@
#define MAPFLAG_RANDOMHERO 8
#define MAPFLAG_RANDOMRACES 16
+#define MAPOPT_HIDEMINIMAP 1 << 0
+#define MAPOPT_MODIFYALLYPRIORITIES 1 << 1
+#define MAPOPT_MELEE 1 << 2 // the bot cares about this one...
+#define MAPOPT_REVEALTERRAIN 1 << 4
+#define MAPOPT_FIXEDPLAYERSETTINGS 1 << 5 // and this one...
+#define MAPOPT_CUSTOMFORCES 1 << 6 // and this one, the rest don't affect the bot's logic
+#define MAPOPT_CUSTOMTECHTREE 1 << 7
+#define MAPOPT_CUSTOMABILITIES 1 << 8
+#define MAPOPT_CUSTOMUPGRADES 1 << 9
+#define MAPOPT_WATERWAVESONCLIFFSHORES 1 << 11
+#define MAPOPT_WATERWAVESONSLOPESHORES 1 << 12
+
#include "gameslot.h"
//
@@ -65,6 +77,7 @@ class CMap
unsigned char m_MapObservers;
unsigned char m_MapFlags;
unsigned char m_MapGameType;
+ uint32_t m_MapOptions;
BYTEARRAY m_MapWidth; // config value: map width (2 bytes)
BYTEARRAY m_MapHeight; // config value: map height (2 bytes)
string m_MapType; // config value: map type (for stats class)
@@ -97,6 +110,8 @@ class CMap
unsigned char GetMapFlags( ) { return m_MapFlags; }
BYTEARRAY GetMapGameFlags( );
unsigned char GetMapGameType( ) { return m_MapGameType; }
+ uint32_t GetMapOptions( ) { return m_MapOptions; }
+ unsigned char GetMapLayoutStyle( );
BYTEARRAY GetMapWidth( ) { return m_MapWidth; }
BYTEARRAY GetMapHeight( ) { return m_MapHeight; }
string GetMapType( ) { return m_MapType; }

0 comments on commit 295fe3a

Please sign in to comment.