Hey Annikk, I've been playing the EXTREME PWN LAZ0RZ!!12
level (I love that name btw
) quite a bit lately, and thus running into that mixed tree bug that I posted about several times in that thread. It was bothering me so I decided to do something about it.
Today I took a long look at the Infected AI code, and did a lot of testing, and I fixed it
The bug actually stems from a flaw in the PlantDysonTree(faction) function in the game engine. This function will plant a tree of the designated faction on any asteroid so long as that asteroid has an available planting slot and the requisite number of that faction's seedlings, even if the asteroid already belongs to another faction and has existing trees growing there (which should make it unplantable by anyone else). The result is trees belonging to different factions growing on the same asteroid. This bug probably also exists in PlantDefenseTree but I didn't test it.
The formulas in the Infected AI that determine the asteroid metric values do allow for conditions where this bug is possible (for those reading along, in a nutshell it has to do with not having enough seedlings on an enemy asteroid to count as an attack, yet enough to plant a tree, and there is an open tree slot). I didn't want to mess with how you have the metrics balanced, and figured it would be best to fix it at the planting stage, not the filtering stage. This makes a sort of secondary metric 100 condition where an enemy asteroid has open tree slots but can't be planted yet; maybe it's a good thing since the low metric will encourage that AI faction to send seedlings towards it anyway, and soon enough tip the balance towards metric 0 and full attack... blood in the water if you will
Without further ado, here is the relevant section from the Infected AI code, with the workaround included. Essentially it performs the check that the function is supposed to, but doesn't. The altered code is enclosed with the comment "bug workaround".
-- There are 3 different action types. We must make sure not to use any actions for players 0 and 1!
-- 1. Plant trees
-- trap for player 0, exclude player 1
if checkedroid.owner == 0 or checkedroid.owner > 1 then
-- so plant one :>
for i = 2,10 do
if metric[checkedroid.id] == 100 and (checkedroid:GetNumSeedlings() - checkedroid:GetNumSeedlings(i)) < 5 and checkedroid:GetNumSeedlings(i) > 9 then
-- this asteroid isn't owned by greys or player, the enemy only has a bit of seedlings here
-- its metric is 100
-- and it has enough seedlings belonging to the asteroid's empire to plant a tree
-- bug workaround: and there are zero growing trees on the asteroid, or the faction with enough seeds to plant actually owns the asteroid
-- this is necessary as PlantDysonTree() will plant a foreign tree on another faction's asteroid even if trees are already present
if checkedroid:IsBarren() or checkedroid.owner == i then
a = checkedroid:PlantDysonTree(i)
-- bug workaround end
-- 2. Send seedlings to the next lowest metric
After spending about three hours today poring over the Infected AI code, I want to once again tip my hat to you for how smart that code is, and thank you especially for the copious comments that made figuring it out a LOT easier!
I made several attempts before settling on the above fix (which happily is quite small!). The secret sauce is the IsBarren() function, which does two magical things at once: it traps for an asteroid with zero trees no matter who owns it, and it also, unlike any other function I could find, distinguishes between a fully planted root and one that hasn't finished planting yet.
I hope you will consider adding this fix into the main code and updating it since IMO the impact of this bug can be rather serious, and make a level unwinnable.
If anyone wants to see the bug in action, I made a test level (attached to this post) based on the the example Infected AI where I tried to set the preconditions that would automatically trigger the bug, but found that a bit daunting. There seems to be an additional required element I haven't figured out yet. But you can use this test level to very easily and clearly show the bug in the PlantDysonTree function:
N.B. the Infected AI in this test level does not
include the workaround for this bug.
1) Load the level.
2) Immediately upon loading, hit esc and ` to pause the game and open the lua console.
3) Enter the following in the console:
4) Unpause, and you will have an asteroid with trees belonging to two different factions.