Scenario in hotseat

PawelS

Ancient Druid
Joined
Dec 11, 2003
Messages
2,811
Location
Poland
I took Wallengren's Europe map and placed starting locations of some civs from the Anno Domini mod there. Now I want to play this map in hotseat, is there a way to do it? (Gedemon's Custom Advanced Setup Screen doesn't take start locations into account.) I'm going to find a solution myself, but perhaps someone already did it, that's why I'm posting about it here...
 
You can use one of the setup files from R.E.D. WWII as a template, I'll try to summarize the change I've done to allow the launch of a hotseat game there:

1/ add a "dummy" civilization to your scenario, which must be player 0.

in the custom setup Lua your ScenarioCivilizations table will start at 1, not 0.

Spoiler :
Code:
ScenarioCivilizations = {
	-- [0] = "CIVILIZATION_MONGOL", -- Fake civilization defined as player one in scenario tab of WB (with a starting plot in the middle of nowhere), and killed at start of any game. Used to fix a hotseat bug that make the player one of any scenario always human whatever the settings here
	[1] = "CIVILIZATION_FRANCE",
	[2] = "CIVILIZATION_GERMANY",
	[3] = "CIVILIZATION_ENGLAND",
	[4] = "CIVILIZATION_ROME",
	[5] = "CIVILIZATION_RUSSIA",
	[6] = "CIVILIZATION_GREECE",
}

TYPE_SINGLE = 1
TYPE_HOTSEAT = 2
RED_COMPUTER = 1
RED_HUMAN = 2

also note the 4 defines I'm using later in the code...

2/ add a few things in the Controls.StartButton:RegisterCallback

Spoiler :
Code:
	local scenarioPlayer, scenarioPlayerName
	local bHotseat = PreGame.GetGameOption("GameType") == TYPE_HOTSEAT
	if bHotseat then
		PreGame.SetGameType(GameTypes.GAME_HOTSEAT_MULTIPLAYER)
		for i, CIVILIZATION_TYPE in ipairs(ScenarioCivilizations) do
			if PreGame.GetGameOption(CIVILIZATION_TYPE) == RED_HUMAN then
				print (CIVILIZATION_TYPE .. " is human")
				--UI.MoveScenarioPlayerToSlot( i, 0 )
				PreGame.SetSlotStatus( i, SlotStatus.SS_TAKEN )
				PreGame.SetSlotClaim( i, SlotClaim.SLOTCLAIM_RESERVED )
				PreGame.SetHandicap( i, g_CurrentDifficulty )

				local civ = GameInfo.Civilizations[CIVILIZATION_TYPE]
				local leader = GameInfo.Leaders[GameInfo.Civilization_Leaders( "CivilizationType = '" .. civ.Type .. "'" )().LeaderheadType];
				local leaderName = Locale.ConvertTextKey(leader.Description)
				PreGame.SetNickName( i, leaderName )
				scenarioPlayer = i
				scenarioPlayerName = leaderName
			else
				PreGame.SetSlotStatus(i, SlotStatus.SS_COMPUTER)
				PreGame.SetSlotClaim(i, SlotClaim.SLOTCLAIM_ASSIGNED)
			end
		end
	else
		PreGame.SetGameType( GAME_SINGLE_PLAYER )
		local playerIndex = g_CurrentPlayerIndex;
		if(playerIndex == nil) then
			playerIndex = math.random(1, table.count(ScenarioCivilizations)); -- theres one slot for the hotseat fix...
		end	
		scenarioPlayer = playerIndex
		PreGame.SetHandicap(0, g_CurrentDifficulty)
		if(scenarioPlayer ~= nil) then
			UI.MoveScenarioPlayerToSlot( scenarioPlayer, 0 )
		end
	end

3/ you should have a RefreshDropDownGameOptions used somewhere, mine is like that:

Spoiler :
Code:
function RefreshDropDownGameOptions()
	g_DropDownOptionsManager:ResetInstances();

	local options = {};

[B]	g_REDPulldownOptions =	{
			{
			Type = "GameType",
			Name = "Game Type",
			ToolTip = "Single Player or Hotseat",
			Disabled = false,
			DefaultValue = TYPE_SINGLE,
			SortPriority = 0,
			Values = { 
				{ Name	= "Single Player", ToolTip = "Local single player", Value = TYPE_SINGLE,},
				{ Name	= "HotSeat", ToolTip = "Local Multiplayer", Value = TYPE_HOTSEAT,},
					},
		},  
	}

	for i, option in ipairs(g_REDPulldownOptions) do
		table.insert(options, option)
	end

	if PreGame.GetGameOption("GameType") == TYPE_HOTSEAT then
		for i, CIVILIZATION_TYPE in ipairs(ScenarioCivilizations) do
			local option = {}
			local civ = GameInfo.Civilizations[CIVILIZATION_TYPE]
			option.Type = CIVILIZATION_TYPE
			option.Name = "[ICON_BULLET]" .. Locale.ConvertTextKey(civ.ShortDescription)
			option.ToolTip = Locale.ConvertTextKey(civ.Description)
			option.DefaultValue = RED_COMPUTER
			option.SortPriority = 5
			option.Values = { 
				{ Name	= "Computer", ToolTip = "Brainless AI", Value = RED_COMPUTER,},
				{ Name	= "Human", ToolTip = "Girlfriend, little brother, great father or any other worthy adversary like yourself", Value = RED_HUMAN,},
					},
			table.insert(options, option)
		end
	end[/B]

	
	local sortedOptions = {};
	for k,v in pairs(options) do
		table.insert(sortedOptions, v);
	end
	 
	-- Sort the options
	table.sort(sortedOptions, function(a, b) 
		if(a.SortPriority == b.SortPriority) then
			return a.Name < b.Name; 
		else
			return a.SortPriority < b.SortPriority;
		end
	end);
	
	-- Update the UI!
	for _, option in ipairs(sortedOptions) do
	
		local gameOption = g_DropDownOptionsManager:GetInstance();
				
		gameOption.OptionName:SetText(option.Name);
								
		if(option.ToolTip ~= nil) then
			gameOption.OptionName:SetToolTipString(option.ToolTip);
		else
			gameOption.OptionName:SetToolTipString();
		end
		
		gameOption.OptionDropDown:SetDisabled(option.Disabled);
		local dropDownButton = gameOption.OptionDropDown:GetButton();
		
		gameOption.OptionDropDown:ClearEntries();
		for _, possibleValue in ipairs(option.Values) do
			controlTable = {};
			gameOption.OptionDropDown:BuildEntry( "InstanceOne", controlTable );
			controlTable.Button:SetText(possibleValue.Name);
			
			if(possibleValue.ToolTip ~= nil) then
				controlTable.Button:SetToolTipString(possibleValue.ToolTip);
			else
				controlTable.Button:SetToolTipString();
			end
			
			
			controlTable.Button:RegisterCallback(Mouse.eLClick, function()
				dropDownButton:SetText(possibleValue.Name);
				if(possibleValue.ToolTip) then
					dropDownButton:SetToolTipString(possibleValue.ToolTip);
				else
					dropDownButton:SetToolTipString();
				end
				PreGame.SetGameOption(option.Type, possibleValue.Value);
				modUserData.SetValue (option.Type, possibleValue.Value);
				PerformPartialSync()
			end);
		end
		
		--Assign the currently selected value.

		local modSavedValue = modUserData.GetValue (option.Type);
		local savedValue = PreGame.GetGameOption(option.Type);
		local defaultValue;

		if(modSavedValue ~= -1) then
			defaultValue = option.Values[modSavedValue];
		else
			defaultValue = option.Values[option.DefaultValue];
		end

		if(savedValue ~= -1) then
			defaultValue = option.Values[savedValue];
		else
			defaultValue = option.Values[option.DefaultValue];
		end
		
		if(defaultValue ~= nil) then
			dropDownButton:SetText(defaultValue.Name);
			
			if(defaultValue.ToolTip ~= nil) then
				dropDownButton:SetToolTipString(defaultValue.ToolTip);
			else
				dropDownButton:SetToolTipString();
			end
		end
	
		if(option.Disabled) then
			dropDownButton:SetDisabled(true);
		end
		
		gameOption.OptionDropDown:CalculateInternals();
	end
	
	Controls.DropDownOptionsStack:CalculateSize();
	Controls.DropDownOptionsStack:ReprocessAnchoring();

	Controls.OptionsScrollPanel:CalculateInternalSize();
end

(in bold the part added for hotseat in R.E.D., the rest is C/P from vanilla code)


4/ in the initialize function, there are also a few part related to hotseat initialization

Spoiler :
Code:
	for i, CIVILIZATION_TYPE in ipairs(ScenarioCivilizations) do
		PreGame.SetGameOption(CIVILIZATION_TYPE, RED_COMPUTER)
	end

and

Spoiler :
Code:
	SetPlayerIndex(g_CurrentPlayerIndex);


IIRC there is also a few change I've made for the difficulty setting.


edit: and related to the dummy player zero, it have to be killed at start, and you may want to edit the end game screen that will be shown then. Or just don't use player 0, but note that this one will always be human if you launch a hotseat game then.
 
Thanks for the detailed explanation :) It sounds quite complicated, I'll try it when I have some free time...
 
hmm, do you have a working version of the map (with all civs you want in) ?

I need to take a small break of my current work...
 
hmm, do you have a working version of the map (with all civs you want in) ?

I need to take a small break of my current work...

Yes, I have all 12 civs in, the map is attached to this post (it requires the Anno Domini G&K mod). But the city states aren't placed yet, if you need them I can add them tonight.

Thanks in advance for your support!
 

Attachments

  • Europe AD.Civ5Map
    138.2 KB · Views: 152
I'm on it and will post back the result in a few hours.
 
Here it is. Let me know if you have issues with it.

I've put art files as placeholder that you may want to change, just keep the file names or be prepared to edit the files at 2-3 places.

The texts are in Database.xml.

If you had made change to your map and want to replace the one in the modbuddy's solution I'm posting here, note that you have to add the Amazons at the first player position in the scenario setting. That civilization will be "killed" at first turn, it's the only fix I've found to the following problem: with a WB map, the first player (on the map scenario tab) is always human when activating hotseat.

That dummy civ will not be on the selection screen, and will not spawn at all in single player.
 

Attachments

  • Europe AD.7z
    771.3 KB · Views: 207
The mod works perfectly, now I can use it as an example when I need to create similar scenarios in the future. Thanks again!
 
I have a small problem with the mod: After the Amazons are killed on turn 0, suddenly it becomes turn 1, so all other civs start at that turn. This fact alone wouldn't be very important, but it has consequences: the AI players can move their starting settlers around before founding a city, which I'd prefer to avoid...

Needless to say I have no idea how to fix this problem :(
 
if it's for a scenario, why not put the intial city on the map using the WB ?

else you can replace the AI settler by a city in Lua on turn 1 if the game is in hotseat mod.
 
OK, I'm going to place the cities in WB, I think I need to give them a palace, right?

(It seems a much simpler solution than replacing a settler with a city in Lua :))
 
OK, I'm going to place the cities in WB, I think I need to give them a palace, right?

yep. :)

Moderator Action: moved to Tutorials & Reference as I've got relatively frequently asked questions about how to do this, and it's the best answer I can give until I find the time to make a real tutorial out of it
 
Top Bottom