First off, good on you for not giving up and actually trying to forge ahead and learn, rather than sitting around waiting for help, or mindlessly copying code.
While that's not truly "real" code, it's a decent start for "pseudo code" in which you basically write up the logic you'll need to eventually replace with actual code. Think of it as an outline for a paper.
There are a few problems with what you've prototyped, but the biggest problem is the order of your statements. For reference, you'll also want to wrap your code inside the CODE block tags, instead of QUOTE, because it will preserve whitespace formatting.
Code:
[COLOR="Red"]if[/COLOR]
[COLOR="Green"]function WarStateChangedHandler( team1, team2, bool war)[/COLOR]
[COLOR="Red"]if[/COLOR] player's culture > lGetLastTurnLifetimeCulture of enemy?
[COLOR="Red"]then[/COLOR]
ChangeOccupiedPopulationUnhappinessMod ==?
ChangeUnhappinessFromCapturedCityCount ==?
ChangeUnhappinessFromOccupiedCities ==?
[COLOR="Red"]end[/COLOR]
[COLOR="Blue"]Events.WarStateChanged.Add(WarStateChangedHandler)[/COLOR] ;
Starting from the top, you have an
if check. However, the
if must be able to check some kind of condition. Unfortunately, your 'condition' is a function which does other things. An
if block merely checks for true or false, and then runs whatever is specified in the "
then" section, which is missing for at least one of your
if blocks, since you have two of them.
Furthermore, for Lua, every
if and every
function call
must have a corresponding
end in its pair. If not, Lua will complain and throw an error. On this point, I find it's easiest to remember this if I immediately write the "
end" whenever I open up a new block:
Code:
[B]function[/B] XYZ()
[B]end[/B]
Code:
function XYZ()
[B]if[/B] X then
[B]end[/B]
end
Code:
function XYZ()
if X then
[B]if[/B] Y then
elseif Z then
else
[B]end[/B]
end
end
This is an example of how I make sure that I have the appropriate number of
end calls even before I start filling the function in with logic.
So, the first problem is that you really shouldn't have an
if there before you define your function. As it's a function, let it sort itself out -- that's what functions are meant to do. Easy fix in this case -- delete the
if in the line before
function.
Your next line defines a new function called
WarStateChangedHandler and it takes a number of
arguments -- in this case, it's information called
team1,
team2, and
bool war. Keep in mind that the space may throw that off, so always keep your variable names without spaces.
At the very end you've specified this function via its name to be added to the
WarStateChanged event. This is an event hook made available to us by Firaxis, and simply means that at the point that Firaxis is running their game code related to war state being changed, it will additionally run any user functions provided here at the same time.
Recall that your function needed three arguments --
team1,
team2, and
boolwar. This event, when it fires your function, will also provide those three arguments automatically.
Code:
if [COLOR="Red"]player's[/COLOR] culture > lGetLastTurnLifetimeCulture of [COLOR="Red"]enemy[/COLOR]?
Here is where things start getting tricky.
This is fine pseudo code, as you want to compare culture levels of the two players, but you haven't actually specified who is who. This is where you need to make use of the
team1 and
team2 information and match them up with player ID's. You need to store this information into variables (either global or local) so that you can use them to find other information you need.
Typically, in order to find information about a player, you need to gain access to the
'Player' game object which is the game table which contains all of the data about that player. This game table is called
Players (note the '
s') and the table index matches up with the player ID. For example, to get the player
game object for player 3, you would specify something like this:
Code:
local pPlayer = Players[3]
In this case, we are defining a new variable caleld
pPlayer to hold the data contained in the
Players table for player
3 -- this gives us the
game object for
player 3 and we can then start querying that table to find out what is up with player 3.
However, hardcoding like this is usually bad, so we want to let the game fill in the player number for us whenever possible. This is
usually achieved via the use of
iPlayer or
playerID, or whatever other naming convention you like to use.
Code:
local pPlayer = Players[iPlayer]
There is still a problem, though --
iPlayer/B] here is not defined. Lua requires all variables to be defined with a value first, or else it turns up as nil -- nothing at all. Normally, we depend on the game's events to give it to us (for example, GameEvents.PlayerDoTurn() returns the iPlayer for which it is running functions for at the time) but it doesn't appear like your WarStateChanged event does so. I haven't used it personally, so I can't remember if it returns team numbers or player numbers, but I believe team numbers is accurate, since wars are waged between teams rather than players.
In this case you'll need to figure out the player from the team number. This is other logic though, and this is getting on the long side, and I've got to go soon so I'm unable to be any more precise than this -- hopefully it's a good starting point for you.
The Modiki is a great reference for what commands / methods and hooks are available to you, though.
This leads into your last section:
Code:
ChangeOccupiedPopulationUnhappinessMod ==?
ChangeUnhappinessFromCapturedCityCount ==?
ChangeUnhappinessFromOccupiedCities ==?
Again, pseudo code is fine, but I have no idea of those methods actually exist (check with the Modiki there) and even if they do, they are missing the game object/B] they are supposed to be for.
As an example, there exists a player method called ChangeUnhappinessFromUnits(). In order to use it properly, since it's a player method, we need to link it with a player object:
Code:
local pPlayer = Players[iPlayer]
pPlayer:ChangeUnhappinessFromUnits()
Hope that helps!