Is it possible to run a trigger for each unit found via unitPresence?
-
Another problem I've ran into, is for my map, I need a trigger to replace all units of a given type with a purchase of another type.
The set up for doing it for one unit is simple. The question is there a good way to do it for an arbitrary number of units, ensuring to get the same number of purchases of the other unit?
The "hack" I have right now supports 20 units using a variable list of numbers from 1 to 20:
<attachment name="cond_build_fleet_@players@_@nums_1_to_20@" attachTo="@players@" foreach="$players$^$nums_1_to_20$" javaClass="RulesAttachment" type="player"> <option name="directPresenceTerritories" value="map" count="1"/> <option name="unitPresence" value="build_fleet" count="1"/> </attachment> <attachment name="trigger_build_fleet_@players@_@nums_1_to_20@" attachTo="@players@" foreach="$players$^$nums_1_to_20$" javaClass="TriggerAttachment" type="player"> <option name="conditions" value="cond_build_fleet_@players@_@nums_1_to_20@"/> <option name="when" value="before:@players@Never"/> <option name="removeUnits" value="all:build_fleet" count="1"/> <option name="purchase" value="fleet" count="1"/> </attachment> <attachment name="trigger_build_fleet_@players@" attachTo="@players@" foreach="$players$" javaClass="TriggerAttachment" type="player"> <option name="conditions" value="cond_build_fleet_@players@_1"/> <option name="when" value="before:@players@StructuresPlace"/> <!-- triggerName:numberOfTimes:useUses:testUses:testConditions:testChance, we want to test the cond. --> <option name="activateTrigger" value="trigger_build_fleet_@players@_1:1:false:false:true:false"/> <option name="activateTrigger" value="trigger_build_fleet_@players@_2:1:false:false:true:false"/> <option name="activateTrigger" value="trigger_build_fleet_@players@_3:1:false:false:true:false"/> <option name="activateTrigger" value="trigger_build_fleet_@players@_4:1:false:false:true:false"/> <option name="activateTrigger" value="trigger_build_fleet_@players@_5:1:false:false:true:false"/> <option name="activateTrigger" value="trigger_build_fleet_@players@_6:1:false:false:true:false"/> <option name="activateTrigger" value="trigger_build_fleet_@players@_7:1:false:false:true:false"/> <option name="activateTrigger" value="trigger_build_fleet_@players@_8:1:false:false:true:false"/> <option name="activateTrigger" value="trigger_build_fleet_@players@_9:1:false:false:true:false"/> <option name="activateTrigger" value="trigger_build_fleet_@players@_10:1:false:false:true:false"/> <option name="activateTrigger" value="trigger_build_fleet_@players@_11:1:false:false:true:false"/> <option name="activateTrigger" value="trigger_build_fleet_@players@_12:1:false:false:true:false"/> <option name="activateTrigger" value="trigger_build_fleet_@players@_13:1:false:false:true:false"/> <option name="activateTrigger" value="trigger_build_fleet_@players@_14:1:false:false:true:false"/> <option name="activateTrigger" value="trigger_build_fleet_@players@_15:1:false:false:true:false"/> <option name="activateTrigger" value="trigger_build_fleet_@players@_16:1:false:false:true:false"/> <option name="activateTrigger" value="trigger_build_fleet_@players@_17:1:false:false:true:false"/> <option name="activateTrigger" value="trigger_build_fleet_@players@_18:1:false:false:true:false"/> <option name="activateTrigger" value="trigger_build_fleet_@players@_19:1:false:false:true:false"/> <option name="activateTrigger" value="trigger_build_fleet_@players@_20:1:false:false:true:false"/> </attachment>
(In this case, I'm replacing all instances of "build_fleet" unit with "fleet" unit purchase.)
-
Try using 'each' as the "count" for 'directPresenceTerritories'. Then your trigger should assign the purchase for each territory. A trigger would still be needed to remove all the counted units.
Hope this is helpful.
Cheers...
-
@wc_sumpton said in Is it possible to run a trigger for each unit found via unitPresence?:
Try using 'each' as the "count" for 'directPresenceTerritories'. Then your trigger should assign the purchase for each territory. A trigger would still be needed to remove all the counted units.
Doesn't that count the number of territories and not units?
-
Yes this will count the number of territories. If you need to count the number of units in a territory, you would have to specify the territory and use 'each' in 'unitPresence'.
What can not be done is 'each' with both 'directPresenceTerritories' and 'unitPresence', nor can you create a condition for 1 as a 'conditions' for the other. The engine does not handle multiple 'each' statements.
To count multiple units in multiple territories, a 'variable' list with territories as 'element' could be used to cycle through the territories to count the units.
Just some food for thought.
Cheers...
-
Hmm, I think
each
is not supported onunitPresence
? -
As an aside, I'm running into this again as I'd like to place a new unit next to each unit of a certain type via a trigger. Same problem.
-
Sorry for taking so long to get back to you. You are right 'each' does not work for 'unitPresence', please accept my apologies for giving that bad information. Trying to account for multiple units in multiple territories has limited degrees of success within the TripleA engine.
As to you latest problem. Have you tried 'createsUnitsList' as a possible answer?
Cheers...
-
createsUnitsList
doesn't work for me, since I'm converting the unit to a purchase (i.e. that can be placed in a different territory). The context is my map requires players to spent resources that need to be physically at factories (via consumes units) to build all units, including other factories. But those other factories are allowed to be placed elsewhere. Anyway...I tried using
createsUnitsList
for different, but still somewhat similar problem, where it also seemed like it could be a good solution - where I do want to convert all units of one type to another, in the location where they are. So I tried creates units and a trigger to remove the old one. One challenge with this is that it doesn't work when they're loaded on ships (you want the new units to take the same transport slots which doesn't work if the previous unit is still there.)Anyway, it sounds like without engine changes, these aren't really possible.
-
One problem at a time. Your first one "seems" undoable at present, with simple coding, but I'm still running thoughts through my head. With 'createUnitLists' a trigger could be run prior to 'endTurn' to reduce the "creating" units 'transportCost' to 0 thus allowing the other to be placed in the transport. After the "creating" units are removed, the 'transportCost' can be returned to normal.
Trying to be helpful.
Cheers...
-
@wc_sumpton Ooh, that sounds promising. Let me try that! One thing I'm not sure about is whether placement of newly created land units at sea is possible at all - I seemed to recall some logic in the engine that tries to find a nearby land territory. Possibly something that can be treated as a bug to fix in the engine.
-
I looked at the engine code around
createsUnitsList
and it doesn't look like it will work.The relevant code is in
EndTurnDelegate.java
.} else if (!uaToCreate.getIsSea() && !uaToCreate.getIsAir() && t.isWater()) { toAddLand.addAll(ut.create(createsUnitsMap.getInt(ut), player)); ... if (!toAddLand.isEmpty()) { final Predicate<Territory> myTerrs = Matches.isTerritoryOwnedBy(player).and(Matches.territoryIsLand()); final Collection<Territory> landNeighbors = data.getMap().getNeighbors(t, myTerrs); if (!landNeighbors.isEmpty()) { final Territory location = getRandomTerritory(data, landNeighbors, bridge); createUnits(location, toAddLand, change, endTurnReport); } }
So basically, for any land units that would be created at sea, we instead find a random neighboring land territory owned by the player and create the units there. No considerations for transports are given.
I suppose engine changes could be done to support different semantics, but given this whole line of thinking is already trying to workaround a different engine limitation - perhaps that one could be addressed directly, i.e. making
unitPresence
supporteach
(either as a multiplication on top ofeach
ondirectPresenceTerritories
if both are used, or not allowing multipleeach
values on different options).