pftq.com
Welcome! Please Login or Register!
November 21, 2024, 03:09:45 AM
Home Login Register
pftq Forums  |  Game Design  |  Age of Empires III  |  Can you select collections of objects in a map script or just individual objects 0 Members and 1 Guest are viewing this topic. « previous next »
Latest News!Lunar Trigger(Aug 27, 2023)
Pages: 1 [2] 3 Print
Author Topic: Can you select collections of objects in a map script or just individual objects  (Read 14544 times)
Neuron
Member
*****
Offline Offline

Posts: 30

« Reply #15 on: June 26, 2013, 04:08:47 PM »

// Post moved up
« Last Edit: June 26, 2013, 04:16:11 PM by Neuron » Logged
pftq
Administrator
*****
Offline Offline



Posts: 4204

WWW
« Reply #16 on: June 26, 2013, 04:36:34 PM »

Yes, guid() increments each time.  Sorry, it's been a while. Tongue

I don't remember if the name is important.  I don't think it should be but just a guess.
Logged
Neuron
Member
*****
Offline Offline

Posts: 30

« Reply #17 on: June 27, 2013, 02:54:06 AM »

Well, this time I don't get the inserted commands (the XS code) ouput on the screen as chat, but nothing happens.

To be clear, I'm using this code on a blank map template, so there is nothing else in it but the map basics (map initialisation, player area definition and one unit per player, otherwise the game doesn't work). So, on this blank map I define these functions before the main one:


int add = 0;
int fnPlus(void) {  add = add + 1;  return(add); }  

void beginGlobals() {
   rmSwitchToTrigger(rmCreateTrigger("globals_start_"+fnPlus()));
   rmSetTriggerActive(false);
   rmAddTriggerEffect("Send Chat");
   rmSetTriggerEffectParam("Message", "\"); }} /*", false);
}

void xsInject(string code=""){
   rmAddTriggerEffect("Send Chat");
   rmSetTriggerEffectParam("Message", "*/"+code+"/*", false);
}

void endGlobals() {
   rmAddTriggerEffect("Send Chat");
   rmSetTriggerEffectParam("Message", "*/ rule _globals_end_"+fnPlus()+" minInterval 4 inactive { if (1==0) { trChatSend(0, \"", false);
}

Then the main function starts, after which I use these custom functions immediately to test if they work (it's similar with how they were used in AoE Racer):

void main(void) { rmSetStatusText("",0.01);

beginGlobals();
xsInject("trRevealEntireMap();");
endGlobals();

//...............
}

I also looked into the AoE Racer script and noticed that you only used this header and footer functions right at the start of the main function, with a bit of XS code insertion in between them. But after you used the footer (endGlobals) function, you continued to use XS code insertion with the Send Chat, even though you used the footer function before (which I thought it was supposed to end the XS code insertion, but it doesn't seem to be the case).

So, right now the functions are basically similar with those from AoE Racer, except for their names and for variable names. But the inserted tr function doesn't do anything. I also tested with another function, such as trPlayerSetHCAccess(), but to no effect, again.

I don't want to keep you anymore busy with this, so you can answer if you want to or have the time. I'll look more into other scripts and see how they work, maybe I manage to pull it off eventually.
Logged
pftq
Administrator
*****
Offline Offline



Posts: 4204

WWW
« Reply #18 on: June 27, 2013, 12:56:18 PM »

Did you run the triggers?
Logged
Neuron
Member
*****
Offline Offline

Posts: 30

« Reply #19 on: June 28, 2013, 03:24:55 AM »

Well, I thought about the fact that those triggers in the functions are inactive and wanted to ask why you used a send chat with a boolean variable set to false. But then I thought that maybe simply switching to the triggers will make them run.

It's tricky to run them, because they are created inactive so, what do you do: do you first call the function so that they can be created and then fire them or activate them with another function?
But then how do you get reference to triggers created using increments, since you never know when Trigger2, 3, 4, etc was created in a script. I mean, when you run a function which is supposed to fire the triggers just created inactive, how do you get reference to their unique ID (not to their general ID like rmTriggerID("globals_start_"+fnPlus()) or something like that).

I'll see if I find a way to activate them after the function created them.

LE. Lol, I just did an experiment: I set all the boolean variables in the functions to true to see what happens if the triggers are created active and I got three messages saying "default". Still no other effect.
« Last Edit: June 28, 2013, 03:37:02 AM by Neuron » Logged
pftq
Administrator
*****
Offline Offline



Posts: 4204

WWW
« Reply #20 on: June 28, 2013, 09:30:53 AM »

I fire them in other triggers that are active in the beginning of the game. I don't think it mattered if they started inactive or not.  I think at the time I was just trying to delay triggers that ran at start to minimize lag.

I'm not sure what you're asking with the reference.  The name will be the string+guid() - you can just save that to a string variable before using so it doesn't increment again.  Then it's just like any other trigger name.
Logged
Neuron
Member
*****
Offline Offline

Posts: 30

« Reply #21 on: June 29, 2013, 06:16:04 AM »

In order to save the name of the trigger without having it increment, I have to do it before it's created, like this:

// The function which provides the increment

int var = 0;
int fnIncrement(void) {  var = var + 1;  return(var); }  

void beginGlobals() {
   string event = "globals_start_"+fnIncrement();    // The string used for trigger creation, saved as a variable
   rmSwitchToTrigger(rmCreateTrigger(event));
   rmSetTriggerActive(false);
   rmAddTriggerEffect("Send Chat");
   rmSetTriggerEffectParam("Message", "\"); }} /*", false);
}

void xsInject(string code=""){
   rmAddTriggerEffect("Send Chat");
   rmSetTriggerEffectParam("Message", "*/"+code+"/*", false);
}

void endGlobals() {
   rmAddTriggerEffect("Send Chat");
   rmSetTriggerEffectParam("Message", "*/ rule _globals_end_"+fnIncrement()+" minInterval 4 inactive { if (1==0) { trChatSend(0, \"", false);
}

Now, here's the problem. If I create a function with a Fire Event trigger, which I would later use to fire the trigger created in the beginGlobals function, I have to define a variable for the trigger name again. I can't simply use the the variable event which stores the name of the incremented trigger. The interpreter rejects this, it needs to have the variable defined for this function to work.

So this doesnt work:

void evFire() {
   rmAddTriggerEffect("Fire Event");
   rmSetTriggerEffectParam("EventID", rmTriggerID(event)); // Needs this variable defined....
}


void main(void) {

rmSetStatusText("",0.01);

beginGlobals();
xsInject("trRevealEntireMap();");
endGlobals();
evFire();

//...........
}

I also tried creating the string variable which stores the trigger name outside of the function, so that it can be used globally, but the interpreter rejects this too.

If I define the variable for the evFire function, like

void evFire(string event="") {...}

I have to write the name of the trigger when I call this function.

evFire(""); // event = what?

Not sure I'm making myself clear, but any method I used to have the trigger name re-used across functions doesn't work, unless I re-declare the variable which stored the trigger name, but then it might re-increment itself and there's no reference to the same trigger.

I also tried simply creating the trigger as active so it doesn't need to be fired, but the output is 3 "default" messages on the screen. Not sure where this comes from.

Well, I've only started using scripted triggers a short while ago, I was using mostly RM functions until now, so this method of mixing normal RM functions with custom functions and scripted triggers is someting I'm still trying to master.
« Last Edit: June 29, 2013, 06:24:19 AM by Neuron » Logged
pftq
Administrator
*****
Offline Offline



Posts: 4204

WWW
« Reply #22 on: June 29, 2013, 10:29:49 AM »

Sorry, not sure I understand.  You tried defining event outside as a global first?

string event = "";

....

beginGlobals() {
event = ...
}

That should work.

Alternatively you know the name will always be "globals_start_"+var (which is global and incremented).
Logged
Neuron
Member
*****
Offline Offline

Posts: 30

« Reply #23 on: June 30, 2013, 01:39:23 AM »

Yeah, I tried that. I tried lots of things, none of which work.

This is what the game accepts so far:

// Increment function - accepted

int var = 0;
int fnIncrement(void) {  var = var + 1;  return(var); }  

// Trigger creation function - accepted

void beginGlobals() {
   rmCreateTrigger("globals_start_"+fnIncrement());
   rmSetTriggerActive(false);
   rmAddTriggerEffect("Send Chat");
   rmSetTriggerEffectParam("Message", "\"); }} /*", false);
}

// XS insertion function - accepted

void xsInject(string code=""){
   rmAddTriggerEffect("Send Chat");
   rmSetTriggerEffectParam("Message", "*/"+code+"/*", false);
}

// End globals function accepted

void endGlobals() {
   rmAddTriggerEffect("Send Chat");
   rmSetTriggerEffectParam("Message", "*/ rule _globals_end_"+fnIncrement()+" minInterval 4 inactive { if (1==0) { trChatSend(0, \"", false);
}

// Fire event function not accepted
/*
void evFire(string event="") {
   rmAddTriggerEffect("Fire Event");
   rmSetTriggerEffectParam("EventID", rmTriggerID(event);
}
*/


void main(void) { rmSetStatusText("",0.01);

beginGlobals();
xsInject("trRevealEntireMap();");
endGlobals();

// evFire();

}
Logged
Neuron
Member
*****
Offline Offline

Posts: 30

« Reply #24 on: June 30, 2013, 02:11:33 AM »

I'll keep trying other methods and see if I get to the right one.
Logged
pftq
Administrator
*****
Offline Offline



Posts: 4204

WWW
« Reply #25 on: June 30, 2013, 06:03:03 AM »

You're missing a parenthesis on the right:
rmSetTriggerEffectParam("EventID", rmTriggerID(event);
Logged
Neuron
Member
*****
Offline Offline

Posts: 30

« Reply #26 on: June 30, 2013, 09:09:58 AM »

I corrected the mistake after I pasted the chunk here.  Grin
It still didn't work.

Well, this is annoying, but... I went back to how TOS used this method in Bloodsport and Sacrifice, so I simplified the whole thing into two functions. So now I don't need to save any trigger in a string or increment anything.

void addXS(string code=""){
   rmAddTriggerEffect("Send Chat");
   rmSetTriggerEffectParam("Message", "*/"+code+"/*", false);
}

void xsInject() {
   rmCreateTrigger("Globals start");
   rmSwitchToTrigger(rmTriggerID("Globals start"));
   rmSetTriggerActive(false);
   rmAddTriggerEffect("Send Chat");
   rmSetTriggerEffectParam("Message", "\"); }} /*", false);
   addXS("trRevealEntireMap();");
   rmAddTriggerEffect("Send Chat");
   rmSetTriggerEffectParam("Message", "*/ rule globals_end minInterval 4 inactive { if (1==1) { trChatSend(0, \"", false);
}

void main(void) {

xsInject();
}

Nothing controversial here. But again, this doesn't accomplish anything.

So, I tried to make the trigger active or to fire it, in any way possible, either inside the second function or outside, in the main function. Neither was considered legit by the interpreter. It rejects the line commented out here:

   rmCreateTrigger("Globals run");
   rmAddTriggerEffect("Activate Trigger");
//  rmSetTriggerEffectParam("EventID", rmTriggerID("Globals start"));

[In the meanwhile I noticed there was another mistake here: I forgot to switch to this new trigger which was created to activate the first, not just fire it.]

But I noticed TOS never activated his "global start" trigger, within which he called the xs function to inject code. It seems to me this is not the problem.

Maybe this whole "global start" trigger was made only to create a method to hack into the game environment and make the interpreter listen to all types of XS commands in a map script (not just the usual rm- and xs- functions, but also tr/kb functions). So this "global start" trigger was never meant to be active or fired or run as such, but only the code that was inserted after the send-chat "opened the gate" and tricked the interpreter into getting tr/kb commands directly from within the RMS.

If you look into TOS's maps he never activates this trigger he created to open the possibility of injecting XS code. The trigger itself doesn't do anything besides sending a send-chat to trick the interpreter. The stuff which needs to be active and run is the actual code inserted in the send-chats, right?
« Last Edit: June 30, 2013, 09:19:07 AM by Neuron » Logged
pftq
Administrator
*****
Offline Offline



Posts: 4204

WWW
« Reply #27 on: June 30, 2013, 02:58:21 PM »

The injection stuff doesn't get interpreted until game starts and just crashes your triggers (they don't run). If the interpreter is not letting the game load, then it has to be a syntax error in the code outside the xs stuff.
Logged
Neuron
Member
*****
Offline Offline

Posts: 30

« Reply #28 on: June 30, 2013, 04:33:02 PM »

Of course. The code I wrote above is accepted by the game, but it has no effect.  Undecided

I thought it must be the trigger not being activated, but then when I looked into TOS's RM scripts in which he used this method (Bloodsport: http://aom.heavengames.com/downloads/showfile.php?fileid=1093), he never runs the trigger with which he starts the whole thing (the "Globals start" trigger). He only fires other triggers created inside this function.

He creates one small function which adds XS code and a huge one in which he starts the sendchat thing and starts injecting code of all types -- all this before the main function. And then he closes this huge function, starts the main function, defines a few areas and stuff (other map stuff which has to be placed inside the main function) and closes the whole thing by simply calling the XS injection function, without any arguments.  

So, I thought maybe not firing these triggers is not the problem, since I'm only creating one, which uses the send-chat functionality. My xs insertion consists of one simple, no-arguments, function. I don't see why it wouldn't work (if it's not really necessary to run that trigger for this thing to do its job).  Huh

Well, I guess I'll keep digging.  Grin
« Last Edit: June 30, 2013, 04:45:52 PM by Neuron » Logged
pftq
Administrator
*****
Offline Offline



Posts: 4204

WWW
« Reply #29 on: June 30, 2013, 05:13:11 PM »

I don't think it has anything to do with the firing/non-firing.  Triggers not running means that there's a syntax error in the XS code (so the stuff that's in the addXS).

What you commented probably helps if only because then none of the XS stuff is run.  I'd try leaving the fire event in and commenting parts of the XS code instead.
Logged
Pages: 1 [2] 3 Print 
pftq Forums  |  Game Design  |  Age of Empires III  |  Can you select collections of objects in a map script or just individual objects « previous next »
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.21 | SMF © 2006-2007, Simple Machines | RSS Feed Valid XHTML 1.0! Valid CSS!
Page created in 0.133 seconds with 21 queries.