Our World: Civilizations of the Modern Age Design Discussion

Yes, that's the one I was looking for. Couldn't get it this morning, probably because I was being lazy :/

I agree it looks like the real thing, it's just not as high quality as maybe I'm used to? But for me, it absolutely works and we should use it. And yes hopefully we can get the icon soon!
 
Hey all. Nigeria was released over in the CL thread, here.

This completes 2/3 of Our World's collaborations with Colonialist Legacies. Once again, CL did the lion's share of the work, but do feel comfortable taking credit for a) help bringing the civ to CL's attention, a very long time ago 2) some design discussion and 3) pedias.

Hopefully, onto Israel and Iran!
 
Okay friends, inspired by the latest resurgence in released civs, I'm really feeling the need to get Iran out. Also it's been almost a year (eek!) since Mao came out. So let's get stuff done.

First things first, is anyone interested in compiling the mod? I've got finals like super soon.
We also need an icon for the Bonyad. There's no great image reference, but I picked this out as representative of prominent Iranian skyscrapers. Link

Once I get a compiler to work with, we can start to do Lua! Please PM me or post if you're interested in any of these things.
 
Hmm... well, I normally offer my services pretty liberally, but Iran doesn't interest me in the slightest...
 
Given that JFD already gave us the UI element for the policies-from-faith, the rest of the Lua shouldn't be too hard, so long as Firaxis' [FAMILY-FRIENDLY] espionage API actually has the right events for the Spy-related stuff. I'll give it a crack tomorrow.
 
Thanks Kilsz. Senshi, that's cool. I should be able to compile, but it'll just take longer. Also I have to remind myself how to do all this stuff! I honestly have no clue how JFD et al can turn out a mod so quickly.
 
I like it! I would definitely use that. Up close it's bit blurry but at any game size it's hardly noticeable. Thank you!
 
Blurry is usually better then sharp, atleast for icons.
 
Well that's not necessarily true at all. If you're going for a Firaxis-like icon style, they shouldn't be blurry, rather fewer - but sharp - details and smooth-surfaced. At least that's my opinion.

That said, the icon is pretty cool I think. Glad to see the Our World projects being worked on :D.
 
so long as Firaxis' [FAMILY-FRIENDLY] espionage API actually has the right events for the Spy-related stuff

...which it does not. No event for spies being recruited, spies leveling up, or spies killing other spies. :(

Here's the Revolutionary Guard's XP from adopting policies and faith from garrisoning:
Spoiler :
Code:
local iRevolutionaryGuard = GameInfoTypes.UNIT_PLACEHOLDER
local iMarineClass = GameInfoTypes.UNITCLASS_MARINE
local i2FaithDummy = GameInfoTypes.BUILDING_PLACEHOLDER -- Dummy building that yields 2 faith
local iExperienceFromPolicies = 10 -- Amount of experience Revolutionary Guards get per policy; wasn't specified in the design, so I've set it to 10 as an arbitrary placeholder.

function RevGuardXPFromPolicies(iPlayer, iPolicy)
	local pPlayer = Players[iPlayer]
	if not pPlayer:HasUnitOfClassType(iMarineClass) then return end -- don't bother iterating through all the units if we don't have any of the right class anyway
	for pUnit in pPlayer:Units() do
		if pUnit:GetUnitType() == iRevolutionaryGuard then
			pUnit:ChangeExperience(iExperienceFromPolicies)
		end
	end
end

GameEvents.PlayerAdoptPolicy.Add(RevGuardXPFromPolicies)

function UpdateRevGuardDummyBuildings(iPlayer, iUnit, iX, iY)
	local pPlayer = Players[iPlayer]
	if not pPlayer:HasUnitOfClassType(iMarineClass) then return end
	for pCity in pPlayer:Cities() do -- iterate through all the cities to ensure that the dummy buildings are removed when the unit *stops* being garrisoned
		pCity:SetNumRealBuilding(i2FaithDummy, 0)
		local pPlot = pCity:Plot()
		for i = 0, pPlot:GetNumUnits() - 1, 1 do
			local pUnit = pPlot:GetUnit(i)
			if pUnit:GetUnitType() == iRevGuardID then
				pCity:SetNumRealBuilding(i2FaithDummy, pUnit:GetLevel())
			end
		end
	end
end

GameEvents.UnitSetXY.Add(UpdateRevGuardDummyBuildings)

And here's the Bonyad's faith from gold:

Spoiler :
Code:
local iBonyad = GameInfoTypes.BUILDING_PLACEHOLDER
local i1FaithDummy = GameInfoTypes.BUILDING_PLACEHOLDER -- Dummy building that yields 1 Faith

function UpdateBonyadFaith(iPlayer)
	local pPlayer = Players[iPlayer]
	for pCity in pPlayer:Cities() do
		if pCity:IsHasBuilding(iBonyad) then
			pCity:SetNumRealBuilding(i1FaithDummy, iGoldPerTurn = pCity:GetYieldRateTimes100(YieldTypes.YIELD_GOLD) / 400)
		else
			pCity:SetNumRealBuilding(i1FaithDummy, 0)
		end
	end
end

GameEvents.PlayerDoTurn.Add(UpdateBonyadFaith)
 
...which it does not. No event for spies being recruited, spies leveling up, or spies killing other spies. :(

Here's the Revolutionary Guard's XP from adopting policies and faith from garrisoning:
Spoiler :
Code:
local iRevolutionaryGuard = GameInfoTypes.UNIT_PLACEHOLDER
local iMarineClass = GameInfoTypes.UNITCLASS_MARINE
local i2FaithDummy = GameInfoTypes.BUILDING_PLACEHOLDER -- Dummy building that yields 2 faith
local iExperienceFromPolicies = 10 -- Amount of experience Revolutionary Guards get per policy; wasn't specified in the design, so I've set it to 10 as an arbitrary placeholder.

function RevGuardXPFromPolicies(iPlayer, iPolicy)
	local pPlayer = Players[iPlayer]
	if not pPlayer:HasUnitOfClassType(iMarineClass) then return end -- don't bother iterating through all the units if we don't have any of the right class anyway
	for pUnit in pPlayer:Units() do
		if pUnit:GetUnitType() == iRevolutionaryGuard then
			pUnit:ChangeExperience(iExperienceFromPolicies)
		end
	end
end

GameEvents.PlayerAdoptPolicy.Add(RevGuardXPFromPolicies)

function UpdateRevGuardDummyBuildings(iPlayer, iUnit, iX, iY)
	local pPlayer = Players[iPlayer]
	if not pPlayer:HasUnitOfClassType(iMarineClass) then return end
	for pCity in pPlayer:Cities() do -- iterate through all the cities to ensure that the dummy buildings are removed when the unit *stops* being garrisoned
		pCity:SetNumRealBuilding(i2FaithDummy, 0)
		local pPlot = pCity:Plot()
		for i = 0, pPlot:GetNumUnits() - 1, 1 do
			local pUnit = pPlot:GetUnit(i)
			if pUnit:GetUnitType() == iRevGuardID then
				pCity:SetNumRealBuilding(i2FaithDummy, pUnit:GetLevel())
			end
		end
	end
end

GameEvents.UnitSetXY.Add(UpdateRevGuardDummyBuildings)

And here's the Bonyad's faith from gold:

Spoiler :
Code:
local iBonyad = GameInfoTypes.BUILDING_PLACEHOLDER
local i1FaithDummy = GameInfoTypes.BUILDING_PLACEHOLDER -- Dummy building that yields 1 Faith

function UpdateBonyadFaith(iPlayer)
	local pPlayer = Players[iPlayer]
	for pCity in pPlayer:Cities() do
		if pCity:IsHasBuilding(iBonyad) then
			pCity:SetNumRealBuilding(i1FaithDummy, iGoldPerTurn = pCity:GetYieldRateTimes100(YieldTypes.YIELD_GOLD) / 400)
		else
			pCity:SetNumRealBuilding(i1FaithDummy, 0)
		end
	end
end

GameEvents.PlayerDoTurn.Add(UpdateBonyadFaith)

Aren't there methods to find out this kind of information? Could you use dummy buildings to detect changes to spies?
 
Aren't there methods to find out this kind of information? Could you use dummy buildings to detect changes to spies?

Any other Lua experts want to chime in on this?
 
Any other Lua experts want to chime in on this?

The best would be Player:GetEspionageSpies(), which returns a table of data that you could make use of (City co-ordinates, Rank, State, TurnsLeft, PercentComplete, EstablishedSurveillance, IsDiplomat) - I guess you could store data as dummy buildings, and then check for changes each turn. Not sure about spies killing spies - but something must push the notification...
 
I don't think you'd even need dummy buildings for this, you could probably just store all the spy information locally in the Lua script, by looking at all players at the start of the game, storing the spy data for each and then updating that data on each player's turn. You won't need something like TableSaverLoader, since spy information is always in the game and you can re-store it on game load.

Receive faith upon recruiting a new spy or whenever a Spy levels up.
This one should be pretty easy. Since GetEspionageSpies() returns a table, according to Chrisy15, every turn you can check the length of the stored table for an Iranian player*, and it increases, give that Iranian player faith.

On level up is a tiny bit trickier - before you store the spy data for the current turn, go through the stored spy data you already have, and if a specific spy's rank has increased, then you give the player faith.

If a Spy kills an enemy spy, all Revolutionary Guards gain a level.
This is... possible, I'd say, but really tricky since there's no GameEvents for spies in the base game as far as I know.

I might be talking nonsense here, but what I'm thinking now, is that you store the spy data for all players, and if someone's spy that was in an Iranian city - and isn't from that Iranian player - disappears (you can only lose spies from being killed, I believe), you can assume that the spy was killed by Iran and level up the Revolutionary Guards.

This hinges on the fact that a killed spy will decrease the spy count for the player. If not, then we'd have to examine what GetEspionageSpies() returns after a spy is killed. Examining the contents of GetEspionageSpies() in general is probably a good idea - perhaps create a Lua script that prints the information on each players turn, and then observe how it changes with the events in a test game.

(*Remember that you can't assume there's only one player that's Iran in the game, so you have to write the code to be adaptable to multiple Irans in the same game.)
 
I don't think you'd even need dummy buildings for this, you could probably just store all the spy information locally in the Lua script, by looking at all players at the start of the game, storing the spy data for each and then updating that data on each player's turn. You won't need something like TableSaverLoader, since spy information is always in the game and you can re-store it on game load.


This one should be pretty easy. Since GetEspionageSpies() returns a table, according to Chrisy15, every turn you can check the length of the stored table for an Iranian player*, and it increases, give that Iranian player faith.

On level up is a tiny bit trickier - before you store the spy data for the current turn, go through the stored spy data you already have, and if a specific spy's rank has increased, then you give the player faith.


This is... possible, I'd say, but really tricky since there's no GameEvents for spies in the base game as far as I know.

I might be talking nonsense here, but what I'm thinking now, is that you store the spy data for all players, and if someone's spy that was in an Iranian city - and isn't from that Iranian player - disappears (you can only lose spies from being killed, I believe), you can assume that the spy was killed by Iran and level up the Revolutionary Guards.

This hinges on the fact that a killed spy will decrease the spy count for the player. If not, then we'd have to examine what GetEspionageSpies() returns after a spy is killed. Examining the contents of GetEspionageSpies() in general is probably a good idea - perhaps create a Lua script that prints the information on each players turn, and then observe how it changes with the events in a test game.

(*Remember that you can't assume there's only one player that's Iran in the game, so you have to write the code to be adaptable to multiple Irans in the same game.)

'State' *might* tell you whether the spy is dead, alive or moving - could you check the state of a spy that has been in your city to see if it's changed?
 
Ah, I missed that bit about "state".

Okay, I'm checking the code in CvLuaPlayer.cpp:
Code:
switch(pSpy->m_eSpyState)
{
case SPY_STATE_UNASSIGNED:
	lua_pushstring(L, "TXT_KEY_SPY_STATE_UNASSIGNED");
	break;
case SPY_STATE_TRAVELLING:
	lua_pushstring(L, "TXT_KEY_SPY_STATE_TRAVELLING");
	break;
case SPY_STATE_SURVEILLANCE:
	lua_pushstring(L, "TXT_KEY_SPY_STATE_SURVEILLANCE");
	break;
case SPY_STATE_GATHERING_INTEL:
	lua_pushstring(L, "TXT_KEY_SPY_STATE_GATHERING_INTEL");
	break;
case SPY_STATE_RIG_ELECTION:
	lua_pushstring(L, "TXT_KEY_SPY_STATE_RIGGING_ELECTION");
	break;
case SPY_STATE_COUNTER_INTEL:
	lua_pushstring(L, "TXT_KEY_SPY_STATE_COUNTER_INTEL");
	break;
case SPY_STATE_DEAD:
	lua_pushstring(L, "TXT_KEY_SPY_STATE_DEAD");
	break;
case SPY_STATE_MAKING_INTRODUCTIONS:
	lua_pushstring(L, "TXT_KEY_SPY_STATE_MAKING_INTRODUCTIONS");
	break;
case SPY_STATE_SCHMOOZE:
	lua_pushstring(L, "TXT_KEY_SPY_STATE_SCHMOOZING");
	break;
default:
	CvAssertMsg(false, "pSpy->m_eSpyState not in case statement");
	break;
}
lua_setfield(L, t, "State");
Looks like you can check for a dead spy!

Since we don't know what values to check for that will ensure we catch a spy killed in an Iranian city, I still recommend you test the function in game to see what it actually returns in certain situations. I can try it myself either tonight or tomorrow, as I have some free time, but if you want to do it yourself, this quick and dirty function I just did up should print the information for all player's spies at the start of their turn if you use FireTuner:
Code:
function CheckSpyStatus(iPlayer)
    local pPlayer = Players[iPlayer]
	if (pPlayer:IsAlive() and iPlayer < GameDefines.MAX_MAJOR_CIVS) then
		print("Turn " .. Game.GetElapsedGameTurns() .. " for Player " .. iPlayer .. " (" .. Locale.ConvertTextKey(GameInfo.Civilizations[pPlayer:GetCivilizationType()].ShortDescription) .. " - checking their spies.")
		
		tPlayerSpies = pPlayer:GetEspionageSpies()
		if (#tPlayerSpies < 1) then
			print("This player doesn't have any spies yet!")
		else
			print("This player has " .. #tPlayerSpies .. " spies.")
			
			for i = 0, #tPlayerSpies, 1 do
				print("Information for spy " .. (i + 1))
				
				for k, v in pairs tPlayerSpies[i] do
					print (k .. ": " .. v)
				end
			end
		end
	end
end

GameEvents.PlayerDoTurn.Add(CheckSpyStatus)
 
Wow, now those are some freaking recent civilizations. (INB4 Putin)

I particularly like how that Angola map looks.
 
Top Bottom