Yeah, I read that topic. I understood how code injection works but I didn't understand why the syntax is this way:
rmSetTriggerConditionParamInt("Count", "\"+trQuestVarGet(\"QVpopLimit\")+\"");
You are basically tricking the game moving across the environments when you use "+code+". The backslashes are there so the quotes get carried into the XS Environment. It then becomes:
1. ("\"+code+\"")
So, normally a RM function syntax for triggers is like this:
rmSomethingTriggerSomething("Parameter", "Value");
Using the example in that topic, the value for the Count parameter would be
\"+trQuestVarGet(\"QVpopLimit\")+\"
Why is one backslash inside the quotes and another one outside the quotes here?
And, btw, I've noticed that the syntax for scripted triggers varies to some extent. Here's a sample from a map coded by Ensemble programmers (Silk Road):
rmCreateTrigger("GuardianDeath"+triggerCounter);
rmSwitchToTrigger(rmTriggerID("GuardianDeath"+triggerCounter));
rmSetTriggerPriority(3);
rmSetTriggerActive(true);
rmSetTriggerRunImmediately(true);
rmSetTriggerLoop(false);
rmAddTriggerCondition("Units In Area");
rmSetTriggerConditionParamInt( "DstObject", rmGetUnitPlaced(socketID, triggerCounter), false );
rmSetTriggerConditionParam("Player", "0", false);
rmSetTriggerConditionParam("UnitType", guardianType, false);
rmSetTriggerConditionParam("Dist", guardianDistance, false);
rmSetTriggerConditionParam("Op", "<=", false);
rmSetTriggerConditionParam("Count", "0", false);
rmAddTriggerEffect("Unit Action Suspend");
rmSetTriggerEffectParamInt("SrcObject", rmGetUnitPlaced(socketID, triggerCounter), false);
rmSetTriggerEffectParam("ActionName", "AutoConvert", false);
rmSetTriggerEffectParam("Suspend", "False", false);
rmCreateTrigger("DisableAutoconvert"+triggerCounter);
rmSwitchToTrigger(rmTriggerID("DisableAutoconvert"+triggerCounter));
rmSetTriggerPriority(3);
rmSetTriggerActive(true);
rmSetTriggerRunImmediately(true);
rmSetTriggerLoop(false);
rmAddTriggerCondition("Always");
rmAddTriggerEffect("Unit Action Suspend");
rmSetTriggerEffectParamInt("SrcObject", rmGetUnitPlaced(socketID, triggerCounter), false);
rmSetTriggerEffectParam("ActionName", "AutoConvert", false);
rmSetTriggerEffectParam("Suspend", "True", false);
tempCounter = tempCounter + 2;
And here's another example of scripted triggers from one of your maps (Cannonfodder):
void UnitsInArea(int centeritem=0, int xplayer=0, string xunit="", string xdist="0", string xop="==", string xcount="0") {
rmAddTriggerCondition("Units in Area");
rmSetTriggerConditionParamInt("DstObject", centeritem);
rmSetTriggerConditionParam("Player", ""+xplayer);
rmSetTriggerConditionParam("UnitType", xunit);
rmSetTriggerConditionParam("Dist", xdist);
rmSetTriggerConditionParam("Op", xop);
rmSetTriggerConditionParam("Count", xcount);
}
Notice how Ensemble coders use a boolean variable after each value for a parameter and how the value for each parameter is inserted as string, in quotes. Does that mean that the compiler can accept both types of syntax?
This syntax difference can be tricky. I've been trying to make a trigger work on a map, but so far with no result. The compiler accepts the code as valid, but the trigger doesn't do what is expected -- make a trading post spam a unit at a particular point, if a player controls the socker (aka, player has built a trading post on the socket).
I tried using both types of syntax (with and without a boolean variable, with and without quotes) and the one from the Ensemble map is accepted by the compiler but with no effect. Here's the code:
// Trade route def and placement
int tradeRoute1ID = rmCreateTradeRoute();
int socketID=rmCreateObjectDef("sockets to dock Trade Posts");
rmSetObjectDefTradeRouteID(socketID, tradeRoute1ID);
rmAddObjectDefItem(socketID, "SocketTradeRoute", 1, 0.0);
rmSetObjectDefAllowOverlap(socketID, true);
rmAddObjectDefToClass(socketID, rmClassID("socketClass"));
rmSetObjectDefMinDistance(socketID, 0.0);
rmSetObjectDefMaxDistance(socketID, 8.0);
rmAddTradeRouteWaypoint(tradeRoute1ID, .48, .5);
rmAddTradeRouteWaypoint(tradeRoute1ID, .45, .5);
bool placedTradeRoute1 = rmBuildTradeRoute(tradeRoute1ID, "dirt");
if(placedTradeRoute1 == false) rmEchoError("Failed to place trade route 1");
vector socketLoc1 = rmGetTradeRouteWayPoint(tradeRoute1ID, 0.5);
rmPlaceObjectDefAtPoint(socketID, 0, socketLoc1);
// Locate the socket
int tpSocketSelect = rmGetUnitPlaced(socketID, 0);
vector tpSocketPosition = rmGetUnitPosition(rmGetUnitPlacedOfPlayer(socketID, 0));
// Trading post triggers
rmCreateTrigger("TP revenue");
rmSwitchToTrigger(rmTriggerID("TP revenue"));
rmSetTriggerActive(true);
rmSetTriggerLoop(true);
rmAddTriggerCondition("Player Controls Socket");
rmSetTriggerConditionParam("PlayerID", "1", true);
rmSetTriggerConditionParam("Socket", "tpSocketSelect", true);
rmAddTriggerEffect("Send Chat");
rmSetTriggerEffectParam("PlayerID", "1", true);
rmSetTriggerEffectParam("Message", "The Inca Temple are happy to ally with you and provide you with mercenary support!");
rmAddTriggerCondition("Player Population");
rmSetTriggerConditionParam("PlayerID", "1", true);
rmSetTriggerConditionParam("Op", "<", true);
rmSetTriggerConditionParam("Count", "200", true);
rmAddTriggerEffect("Unit Create");
rmSetTriggerEffectParam("Player", "1", true);
rmSetTriggerEffectParam("ProtoName", "OutlawMusketeer", true);
rmSetTriggerEffectParam("Location", "(xsVectorGetX(tpSocketPosition) + 5 ) + ",0," + xsVectorGetZ(tpSocketPosition)", true);
I tried using the simple syntax, without quotes, and the compiler doesn't accept something like this:
rmSetTriggerConditionParam("Socket", tpSocketSelect);
The "PlayerID" parameter name is from the official typetest.xml trigger definition document which ships with the game. I tried using both versions, Player and PlayerID, without noticing any difference.
I've also tried using a loop to have this trigger run for all players, but again to no effect. So this is just a version to test how it would work for at least Player 1. If I get it to work for one player, I'll get it to work for all.
Do you think it's a problem with the syntax difference (this is a AoE3 vanilla map, while the code from Ensemble is from a TAD map) or I made some mistake in the code?