November 10, 2024, 15:47:24

Author Topic: [Fixed/Answered] List and MEvent calls  (Read 8559 times)

Offline Mularac

  • Lieutenant
  • ***
  • Posts: 531
  • Karma: 11
    • View Profile
[Fixed/Answered] List and MEvent calls
« on: October 24, 2010, 06:28:07 »
Hey guys, I come to you with quite a problem.
The other day I was coding a sort of "function", a rule with no parent state or machine that given a set of coordinates it would create and place a group of ships and then return a selection with all those ships. However, it didn't quite work. For an unexplained reason, sending or receiving collections from such events proved to be impossible, as the game won't interpret them as lists but as something else, so they weren't iterable or accesible.

Placing those rules in a machine and state wouldn't work, too.

Any ideas?
« Last Edit: April 05, 2011, 04:31:14 by Mularac »

Offline Arparso

  • Administrator
  • Lieutenant
  • *****
  • Posts: 558
  • Karma: 14
  • I can see you...
    • View Profile
    • http://arparso.de/nexus
(No subject)
« Reply #1 on: October 24, 2010, 11:56:14 »
Got any quick sample code we could try out?

Offline Mularac

  • Lieutenant
  • ***
  • Posts: 531
  • Karma: 11
    • View Profile
(No subject)
« Reply #2 on: October 24, 2010, 17:12:37 »
Yeah, here: It's what I've been using to test it:


Code: [Select]
MACHINE "Director"

STATE IntroMovie

RULE event In
:action
e.list:=MEvent(Create_list, 0);
ExecList(e.list,
debug(s.this);
);
:end
END

Rule event PassingArgumentTest
:action
debug(allNumOf(e.list));
ExecList(e.list,
debug(s.this);
);
:end
END
END
END

Rule event Create_List
:action
E.list := GetFreeSel();
Dim(e.list,3);
SetN(e.list,0,123);
SetN(e.list,1,345);
SEtN(e.list,2,321);
MEvent(PassingArgumentTest,e.list:=p.list);
return(e.list);
:end
END

Offline Arparso

  • Administrator
  • Lieutenant
  • *****
  • Posts: 558
  • Karma: 14
  • I can see you...
    • View Profile
    • http://arparso.de/nexus
(No subject)
« Reply #3 on: October 25, 2010, 12:14:04 »
Did some experiments and found a working solution, I think. First some explanation:

How lists/selections are being stored and accessed:
Imagine lists as being stored in a table and being accessed by their index. For example, the various select()-functions expect a list index so they know where to store the selection. If you assign a variable to a selection like with E.MyList := GetFreeSel(), you don't really store a selection object in that variable, but rather only its index. Unlike other event variables, this variable won't even really go out of scope outside this event's rule: the list will still exist after that rule has finished - only the stored index won't be accessible anymore.

Lists are also being stored per ruleset - each MACHINE has its own independent table storing these lists. If you created a selection with index 1 in one MACHINE and try to access the same index in another MACHINE, the selection will appear empty. The most basic ruleset - the RULES section of the mission outside any of your MACHINES - has its own list table as well.

Why returning lists or passing lists as parameters doesn't work as expected:
If you write a function creating a list and return that list using return() or pass it as a parameter to another event, you don't really pass along the list itself, but only its table index. The rule will create a list, store it in its local table and pass along the index to the receiving RULE. If that RULE is in a different ruleset (e.g. a different MACHINE), it'll use that index to access its own local table - where there will be no list at that index or at least not the expected list.

How to overcome the problem:
Both the RULE creating your list and the RULEs accessing the list afterwards need to agree on what table to store the list in, so they know where to save to and load their lists from. I can think of two approaches:

a) store each list in the mission's table outside of any of your MACHINEs and access it using the M-prefix:
e.g. M:Dump(E.MyListIndex);

b) store the list locally in the machine of the calling RULE. The list-creation RULE will need to know the machine, so pass it as argument to the event.

I did a test implementation of both, which seemed to work just fine:

Code: [Select]
// this rule handles ReturnList events by storing lists in machine-specific tables
RULE event ReturnList
condition E.Machine!=0
:action
Debug("ReturnList was called for machine", E.Machine);
E.Blarg := E.Machine:GetFreeSel();
E.Machine:Select(E.Blarg, s.ship);
return(E.Blarg);
:end
END

// this rule handles ReturnList events by storing them in the mission's list table
RULE event ReturnList
condition E.Machine=0
:action
Debug("ReturnList was called, no machine");
E.List := GetFreeSel();
Select(E.List, s.ship);
return(E.List);
:end
END

MACHINE "foo"

STATE default

RULE event Cheat1
:action
// initialize the E.Machine argument by storing the current machine in it
E.MyList := MEvent(ReturnList, E.Machine := M:GetMachine("foo"));
Debug("In-MACHINE list:", E.MyList);
Dump(E.MyList);
:end
END

                RULE event Cheat2
:action
// initialize the E.Machine to 0 - store list in mission's table
E.MyList := MEvent(ReturnList, 0);
M:Debug("Mission list:", E.MyList);
M:Dump(E.MyList);
:end
END

END

END

If your MACHINE happens to be nested in another MACHINE, you'd initialize the E.Machine argument like this:
E.Machine := M:GetMachine("parentMachine"):GetMachine("childMachine");

Offline Mularac

  • Lieutenant
  • ***
  • Posts: 531
  • Karma: 11
    • View Profile
(No subject)
« Reply #4 on: October 25, 2010, 15:25:22 »
Oh... great, thanks. Yeah, that makes sense.

Thanks a lot, that worked.

An other, completely unrelated question:
I've been re-reading the modding manual and found out about some variables with a t. , c. and d. scope:

Quote
C – caller’s variable
D – the variables of the dialogue. These can be set in the message() command, and the dialogue’s expire event and the possible scripts of the options’ can reach it by this prefix.
T – variables of the tactics

Do you happen to know something about them?

Offline Arparso

  • Administrator
  • Lieutenant
  • *****
  • Posts: 558
  • Karma: 14
  • I can see you...
    • View Profile
    • http://arparso.de/nexus
(No subject)
« Reply #5 on: October 25, 2010, 16:49:37 »
Nope, never used them before.  :huh: