Affinity Gain on Improvements

Starrynite120

Prince
Joined
Jul 15, 2015
Messages
472
I'm currently writing a script to make improvements give affinity experience when finished. I'm testing my script on farms, so this is what I've got this far, but it's not working. Could anyone help me out with making this work? Also, for some reason this is making you gain 1 affinity in all affinities every few turns, not sure why.

function OnBuildFinished(playerID, iX, iY, improvementID, buildID)
local bonus = 0;
local farmInfo = GameInfo.Improvements["IMPROVEMENT_FARM"];
local farmID = farmInfo.ID;
local farmBonus = 1;
if (improvementID == farmID) then
bonus = farmBonus and Affinity_ID = GameInfo.Affinity["AFFINITY_PURITY"];
if (bonus > 0) then
Player:ChangeAffinityScore(Affinity_ID, bonus);
end
end
end
GameEvents.BuildFinished.Add(OnBuildFinished);
 
bonus = farmBonus and Affinity_ID = GameInfo.Affinity["AFFINITY_PURITY"];

There's no need for an "and" here, since it's not part of an if statement or any other logical test. If you want to set values for two different variables you can simply set one after the other on seperate lines.

Also, GameInfo.Affinity here is returning a whole row from that table, just like your GameInfo.Improvements lookup earlier. To get only the value from the ID column you can to put .ID after the square brackets (or after Affinity_ID when you use it later, like you did with farmInfo).

And finally, it should be Affinity_Types instead of Affinity

Try:
Code:
function OnBuildFinished(playerID, iX, iY, improvementID, buildID)
  local bonus = 0;
  local farmInfo = GameInfo.Improvements["IMPROVEMENT_FARM"];
  local farmID = farmInfo.ID;
  local farmBonus = 1;
  if (improvementID == farmID) then
    [B]bonus = farmBonus;
    Affinity_ID = GameInfo.Affinity_Types["AFFINITY_TYPE_PURITY"].ID;[/B]
    if (bonus > 0) then
      Player:ChangeAffinityScore(Affinity_ID, bonus);
    end
  end
end
GameEvents.BuildFinished.Add(OnBuildFinished);

P.s. if you wrap your code in
Code:
 tags here on the forum it will preserve spaces at the start of lines, making things easier to read.
 
And another thing I almost forgot, you need to set a value for Player before you can use it to call the ChangeAffinityScore function.

You can look it up from the playerID using Players[playerID]

Code:
function OnBuildFinished(playerID, iX, iY, improvementID, buildID)
  local bonus = 0;
  local farmInfo = GameInfo.Improvements["IMPROVEMENT_FARM"];
  local farmID = farmInfo.ID;
  local farmBonus = 1;
  [B]local Player = Players[playerID];[/B]

  if (improvementID == farmID) then
    bonus = farmBonus;
    Affinity_ID = GameInfo.Affinity_Types["AFFINITY_TYPE_PURITY"].ID;
    if (bonus > 0) then
      Player:ChangeAffinityScore(Affinity_ID, bonus);
    end
  end
end
GameEvents.BuildFinished.Add(OnBuildFinished);
 
Wow, that was a really fast response, and it worked beautifully. Thank you so much for your assistance, I'm really looking forward to getting this working.
 
Nothing to do with the actual question, but are you sure that's a system that you want to use? It seems very easy to abuse to me - just build a few more workers, then construct a farm on a tile that is not being used -> build something else for one turn and build another farm.
 
Yeah you have a point, I'll have to see how it goes. It won't be the only means of affinity gain. Buildings will also give affinity and tech will too, so improvements won't actually generate that much. I'm going to increase by a lot the amount of experience you need to gain a level, and improvements won't give very much.

For example farms yield 1 purity, so if you just kept producing farms you wouldn't gain that much. I'm also adding extra non-affinity related requirements to victory so affinity won't be the end all deciding factor of who wins.
 
If this doesn't work, perhaps I could make buildings that give you experience based on how many nodes you have in the city or something like that, because I do want improvements to be involved in affinity gain.
 
Well, you could also make improvements give affinity every turn by looping through all tiles, testing whether it has a farm on it and then giving Affinity it it belongs to the player whose turn it is (or a bit less clean but less loops required by lopping through all tiles at the start of player 0s turn and giving affinity to the players who own the farm).
 
I wanted to avoid affinity gain every turn and make it instant boosts for what you do. I may try to make a script that makes you lose the affinity you gained from the improvement for removing/replacing improvements. That would prevent this. Though I'm not sure how easy it would be to do that
 
Not sure if there's an easy way to track when Improvements are removed, because there are many situations where that can happen (Improvement is plundered/overridden, City changes owner, Tile changes owner via Aquatic city).

Easiest way I can think of would be to create a table that stores the highest amount of farms that every player ever had and then using the base code above to give out affinity when a player has more than that number, and increasing the number to the new maximum.

Would of course be a bit hard to track for the player.

An alternative would of course be to just let players exploit it if they really want to. The AI won't exploit it, so that's not a big deal
 
Yeah true. It's only game breaking if you want it to be, and it sounds like it'd be quite a lot of work to address. I'll probably just leave it, it's not that much affinity gain anyway, and your have to go out of your way to make an ungodly amount of workers to really exploit it haha and not many people would do that.
 
Back
Top Bottom