So how could I go on to create triggers that activate endMission or BIS_fnc_endMission state with the help of this "listener"?
So how could I go on to create triggers that activate endMission or BIS_fnc_endMission state with the help of this "listener"?
Somewhere...
_listener = [nil,"create"] call ALiVE_fnc_baseClass; _listener setVariable ["class","somefunction"]; _listenerID = [ALiVE_eventLog,"addListener",[_listener, ["OPCOM_CAPTURE"]]] call ALIVE_fnc_eventLog;
// [_listener,"handleEvent",_event] call _class; // how the event is dispatched within ALiVE internals
inside someFunction
handle event
params ["_logic","_operation","_args"]; switch (_operation) do { case "handleEvent": { _event = _args; _id = [_event, "id"] call ALIVE_fnc_hashGet; _data = [_event, "data"] call ALIVE_fnc_hashGet; // not sure if _objective is an ID or actual objective hash/array // most likely just a string ID _data params ["_side","_objective"]; if (_side == "WEST") then { // or whatever side as a string private _objectiveID = [_objective,"id"] call ALiVE_fnc_hashGet; private _objectivePos = [_objective,"center"] call ALiVE_fnc_hashGet; // do magic here }; }; };
Hopeless for me. Is there anyone that could decipher what to put and where and if something needs to be changed? for greater good and so not to cause an untimely death to SpyderBlack because putting all the strain on him
Hi!
I have provided a sample init.sqf for you, with included documentation - In this example a side chat info is given, when an objective is reserved by side west! Open for better readability, but below i pasted whats inside.
http://s000.tinyupload.com/index.php?file_id=22219349752712892355
/////////////////////////////////////////////////////////////////////////////////////////////////// //Put in init.sqf //only use on an ALiVE mission with virtual AI module placed waituntil {!isnil "ALiVE_eventLog"}; //Leave alone _fnc_custom = { //Do not touch that params ["_logic","_operation","_args"]; //Also do not touch that switch (_operation) do { case "handleEvent": { _event = _args; _event params ["_id","_data"]; _id = [_event, "id"] call ALIVE_fnc_hashGet; _data = [_event, "data"] call ALIVE_fnc_hashGet; _data params ["_side","_objective"]; /////////////////////////////////////////////////////////////////////////// ///// ///// ///// //// This is the part you can put your code in ///// // // /* Example objective data from _objective call ALiVE_fnc_InspectHash; ---------------- Inspecting Hash -------------------- k [0]: objectiveID v: OPCOM_2390318919_objective_0 k [1]: center v: [23334.9,19291.6,0] k [2]: size v: 50 k [3]: objectiveType v: MIL k [4]: priority v: 50 k [5]: opcom_state v: idle k [6]: clusterID v: CUSTOM_42626 k [7]: opcomID v: 2390318919 k [8]: _rev v: k [9]: opcom_orders v: none k [10]: danger v: -1 k [11]: sectionAssist v: ["BLU_F-entity_12"] k [12]: section v: ["BLU_F-entity_12"] k [13]: tacom_state v: reserve ---------------- Inspection Complete -------------------- */ //Get objective id and position private _objectiveID = [_objective,"objectiveID","empty"] call ALiVE_fnc_hashGet; private _objectivePos = [_objective,"center",[]] call ALiVE_fnc_hashGet; //If objective is of side east ("GUER" for resistance) if (_side == "EAST") then { ["ALiVE - objective %1 reserved at position %2 side %3 - id %4!",_objectiveID,_objectivePos,_side,_id] call ALiVE_fnc_DumpR; }; //// /////////////////////////////////////////////////////////////////////////// }; }; }; //Register function _listener = [nil,"create"] call ALiVE_fnc_baseClass; _listener setVariable ["class",_fnc_custom]; //Will always fire the function above if one of the events below is fired //Possible values are: "OPCOM_RESERVE","OPCOM_RECON","OPCOM_CAPTURE","OPCOM_DEFEND","OPCOM_TERRORIZE" _listenerID = [ALiVE_eventLog,"addListener",[_listener, ["OPCOM_RESERVE"]]] call ALIVE_fnc_eventLog; // ///////////////////////////////////////////////////////////////////////////////////////////////////
enjoy
Thanks @highhead . So if I wanted to trigger a message when west capture an objective from east, I'd change this to be something along the lines of
//Reddog ALIVE CODE /////////////////////////////////////////////////////////////////////////////////////////////////// //Put in init.sqf //only use on an ALiVE mission with virtual AI module placed waituntil {!isnil "ALiVE_eventLog"}; //Leave alone _fnc_custom = { //Do not touch that params ["_logic","_operation","_args"]; //Also do not touch that switch (_operation) do { case "handleEvent": { _event = _args; _event params ["_id","_data"]; _id = [_event, "id"] call ALIVE_fnc_hashGet; _data = [_event, "data"] call ALIVE_fnc_hashGet; _data params ["_side","_objective"]; /////////////////////////////////////////////////////////////////////////// ///// ///// ///// //// This is the part you can put your code in ///// // // /* Example objective data from _objective call ALiVE_fnc_InspectHash; ---------------- Inspecting Hash -------------------- k [0]: objectiveID v: OPCOM_2390318919_objective_0 k [1]: center v: [23334.9,19291.6,0] k [2]: size v: 50 k [3]: objectiveType v: MIL k [4]: priority v: 50 k [5]: opcom_state v: idle k [6]: clusterID v: CUSTOM_42626 k [7]: opcomID v: 2390318919 k [8]: _rev v: k [9]: opcom_orders v: none k [10]: danger v: -1 k [11]: sectionAssist v: ["BLU_F-entity_12"] k [12]: section v: ["BLU_F-entity_12"] k [13]: tacom_state v: reserve ---------------- Inspection Complete -------------------- */ //Get objective id and position private _objectiveID = [_objective,"objectiveID","empty"] call ALiVE_fnc_hashGet; private _objectivePos = [_objective,"center",[]] call ALiVE_fnc_hashGet; //If objective is of side east ("GUER" for resistance) if (_side == "WEST") then { systemchat format ["WEST JUST CAPTURED OBJ- %1 at position %2", _objectiveID, _objectivePos]; }; //// /////////////////////////////////////////////////////////////////////////// }; }; }; //Register function _listener = [nil,"create"] call ALiVE_fnc_baseClass; _listener setVariable ["class",_fnc_custom]; //Will always fire the function above if one of the events below is fired //Possible values are: "OPCOM_RESERVE","OPCOM_RECON","OPCOM_CAPTURE","OPCOM_DEFEND","OPCOM_TERRORIZE" _listenerID = [ALiVE_eventLog,"addListener",[_listener, ["OPCOM_CAPTURE"]]] call ALIVE_fnc_eventLog; // ///////////////////////////////////////////////////////////////////////////////////////////////////
I'm assuming (BIG ASSUMPTION) that I can use the position to generate a town name/map label for the major towns at least, and that OPCOM_CAPTURE is the right event to listen for??
Correct! :)
PS:
Please mind:
Once an objective has been secured it is "OPCOM_RESERVE". Basically if "OPCOM_CAPTURE" is triggered, then the groups have been finished grouping at the attack staging position and will go blazing it up, and once it is secured its reserved! Basically the flow is --> RECON -> CAPTURE -> RESERVE
Thanks Highhead. That makes sense.
Is there any documentation about the various functions in alive except whats in the script snippets on the wiki and the source code itself?
I also would like to thank You @highhead for sharing the script here!
When testing with your initial version I couldn't see any info on the side chat for some reason. Probably because of me :)
Thus I did test with @Reddog 's version and that was printing objective info on the systemchat so now I could somewhat understand what's going on there.
When I started this discussion I was looking a way to end (ALiVE) missions when a side has Occupied objectives that are needed to successfully complete one.
Apparently I got this far on my own: when I place the following code
if (_objectiveID == "OPCOM_7388496_objective_0") then {"end1" call BIS_fnc_endMissionServer;};
in highhead's script the mission successfully ends. But after that I haven't been able to come up with anything level-headed that would solve the following problems:
Additionally: I used the Reddog's version to display a single objective's objectiveID but how can one find objectiveID's of multiple objectives in a single mission? Is there a convenient way to dump them to clipboard or something the like with a code snippet?
If youve got logging switched on, it all gets dumped into the log file?
Hello,
I'm still at a loss: what kind of script needs to be created so that a mission can be ended when certain side has triggered OPCOM_RESERVE state for multiple objectives?
For example if there are three objectives in a mission
OPCOM_46275344_objective_1
OPCOM_46275344_objective_2
OPCOM_46275344_objective_3
and we'd want to force the mission to end when side WEST has occupied all three objectives.
One question from me would be that can (or should) the script provided by highhead earlier in this discussion be used or can it be a completely separate one?
If it can be a completely separate script then I'm thinking something like if OPCOM_46275344_objective_1+OPCOM_46275344_objective_2+OPCOM_46275344_objective_3 = side West call BIS_fnc_endMissionServer;
but I'm unable to come up with anything that would resemble an actual working script snippet.
The easiest way to do this without a somewhat proper scripting knowledge is something like this:
if (isServer) then { [] spawn { while {true} do { { private _opcom = _x; private _opcomSide = [_opcom, "side"] call ALIVE_fnc_hashGet; if (_opcomSide == "WEST") then { private _allObjectivesReserved = true; { private _objective = _x; private _objectiveState = [_objective, "tacom_state", "none"] call ALIVE_fnc_hashGet; if (_objectiveState != "reserve") exitWith { _allObjectivesReserved = false; }; } forEach ([_opcom, "objectives"] call ALIVE_fnc_OPCOM); if (_allObjectivesReserved) then { // end mission here }; }; } forEach OPCOM_INSTANCES; sleep 60; }; }; };
Put that in your init.sqf and whenever the WEST OPCOM has "reserved" all of it's objectives it'll run the code inside the "if (_allObjectivesReserved) then {}" block. So you can add your end mission code in there.
Note that this is untested and probably not the cleanest way to do this but if it works it works. ^^
Thank you for the quick reply marceldev!
I substituted the //end mission here with a plain "end1" call BIS_fnc_endMissionServer; just to get a quick test run going.
At the mission start the game hit me with this
19:39:39 [ALIVE] (mil_OPCOM) ERROR: Assertion failed! x\alive\addons\mil_opcom\fnc_OPCOM.sqf:1949 19:39:39 Assertion (typeName _args == "ARRAY") failed! 19:39:39 19:39:39 <NULL-object> 19:39:39 Error in expression < { _allObjectivesReserved = false; }; } forEach ([_opcom, "objectives"] call ALI> 19:39:39 Error position: <forEach ([_opcom, "objectives"] call ALI> 19:39:39 Error foreach: Type Object, expected Array 19:39:39 File C:\Users\username\Documents\Arma 3\mpmission\alive_ironfront_victoryOnCapture.Staszow\initServer.sqf, line 18
Where this problem might supposedly be hiding then?
It probably started before the ALiVE finished starting up.
You can add
waitUntil {!(isNil "ALIVE_REQUIRE_INITIALISED")};
between the "[] spawn {" and "while {true} do {" lines.
marceldev, thank you for the suggestion which I did apply like this
[] spawn { waitUntil {!(isNil "ALIVE_REQUIRE_INITIALISED")}; while {true} do {
yet the game (or should I say the mission) is still outputting the same error that I pasted in my previous response.
Here's a more complete RPT output. There are some other errors too but I at least consider them to be directly because of the first error (that is about the Assertion failed!)
18:07:01 [55697,761.211,0,"CBA_VERSIONING: cba=3.7.1.180604, alive_main=1.6.1.1804271, "] 18:07:01 [55697,761.27,0,"XEH: PostInit finished."] 18:07:01 ALiVE_sys_acemenu: ACE interact_menu not active or no interface found, exiting 18:07:01 [ALIVE] (mil_OPCOM) ERROR: Assertion failed! x\alive\addons\mil_opcom\fnc_OPCOM.sqf:1949 18:07:01 Assertion (typeName _args == "ARRAY") failed! 18:07:01 18:07:01 <NULL-object> 18:07:01 Error in expression <{ _allObjectivesReserved = false; }; } forEach ([_opcom, "objectives"] call ALI> 18:07:01 Error position: <forEach ([_opcom, "objectives"] call ALI> 18:07:01 Error foreach: Type Object, expected Array 18:07:01 File C:\Users\username\Documents\Arma 3\mpmissions\alive_ironfront_victoryOnCapture.Staszow\initServer.sqf, line 19 18:07:01 Registered SITREP controls for NON-JIP on briefing screen: keijo 18:07:01 Registered controls for NON-JIP on briefing screen: keijo 18:07:01 Registered PATROLREP controls for NON-JIP on briefing screen: keijo 18:07:06 OPC DATA [2,"xxxx","Player",false,2] 18:07:07 ALiVE [m_3|43] Module ALiVE_SYS_spotrep INIT COMPLETE TIME: 15.621 18:07:07 ALiVE [m_4|44] Module ALiVE_SYS_marker INIT COMPLETE TIME: 15.62 18:07:07 ALiVE [m_18|152] Module ALiVE_SYS_patrolrep INIT COMPLETE TIME: 9.76099 18:07:07 ALiVE [m_17|151] Module ALiVE_SYS_sitrep INIT COMPLETE TIME: 9.76398 18:07:07 Error in expression <ding"]) then {_active = _active + 1}; } foreach _obj; switch (_controltype) d> 18:07:07 Error position: <foreach _obj; switch (_controltype) d> 18:07:07 Error foreach: Type Object, expected Array 18:07:07 Error in expression <ding"]) then {_active = _active + 1}; } foreach _obj; switch (_controltype) d> 18:07:07 Error position: <foreach _obj; switch (_controltype) d> 18:07:07 Error Generic error in expression 18:07:07 Registering Advanced Marker controls for keijo on map screen. 18:07:07 Registered controls for PLAYER on map screen: keijo 18:07:07 Registering SITREP controls for keijo on map screen. 18:07:07 Registering PATROLREP controls for keijo on map screen. 18:07:07 Registered PATROLREP controls for PLAYER on map screen: keijo 18:07:07 Registered SITREP controls for PLAYER on map screen: keijo 18:07:08 "ALiVE - Starting Garbage Collector..." 18:07:10 ALiVE [m_16|150] Module ALiVE_MIL_C2ISTAR INIT COMPLETE TIME: 12.37 18:07:11 ALIVE PLAYER TASK REQUEST ["EAST","LIB_USSR_TANK_TROOPS","CaptureObjective",[["#CBA_HASH#",["debug","active","position","side","profileID","type","objectType","vehicleAssignments","vehiclesInCommandOf","vehiclesInCargoOf","leader","unitClasses","unitCount","group","companyID","groupID","waypoints","waypointsCompleted","positions","damages","ranks","units","speedPerSecond","despawnPosition","hasSimulated","isCycling","activeCommands","inactiveCommands","spawnType","faction","isPlayer","_rev","_id","busy"],[false,false,[5481.61,6137.85,0],"WEST","LIB_WEHRMACHT-entity_0","entity","LIB_GER_AT_squad",["#CBA_HASH#",[],[],any],[],[],<NULL-object>,["LIB_GER_unterofficer","LIB_GER_AT_soldier","LIB_GER_AT_soldier","LIB_GER_AT_grenadier","LIB_GER_AT_grenadier","LIB_GER_AT_grenadier","LIB_GER_AT_grenadier","LIB_GER_AT_grenadier","LIB_GER_AT_soldier","LIB_GER_AT_soldier"],0,<NULL-group>,"","",[],[],[[5481.61,6137.85,0],[5481.61,6137.85,0],[5481.61,6137.85,0],[5481.61,6137.85,0],[5481.61,6137.85,0],[5481.61,6137.85,0],[54 18:07:13 Duplicate weapon Throw detected for LIB_GER_rifleman 18:07:13 Duplicate weapon Put detected for LIB_GER_rifleman 18:07:16 Error in expression <nc_hashGet; (!(isnil "_objectives") && {count _objectives > 0}) }; _modulesFact> 18:07:16 Error position: <count _objectives > 0}) }; _modulesFact> 18:07:16 Error count: Type Object, expected Array,String,Config entry 18:07:16 File \x\alive\addons\mil_logistics\fnc_ML.sqf [ALiVE_fnc_ML], line 2276 18:07:16 ALiVE [m_20|170] Module ALiVE_SUP_PLAYER_RESUPPLY INIT COMPLETE TIME: 18.07
Hnmm weird. Try replacing
[_opcom, "objectives"] call ALIVE_fnc_OPCOM
with
[_opcom, "objectives"] call ALIVE_fnc_hashGet
gasp That did the trick marcel, thank You! FYI there's also now no need for the waitUntil part you suggested earlier since the whole script package you have provided works just fine without.
Now the test mission ends when side WEST has captured all the objectives that I have laid out for the mission (be it one or ten) in the in-game editor.
Just to return to my original question: what about picking let's say three objectives out of five? Anything to start with scripting-wise to make a mission end when certain three objectives out of five have been captured by a side?
I can't think of anything quick to do that. It's fairly complicated because you can't really say something like "I want to keep track of this specific objective", it's more something like "I want to keep of an objective that's closest to this position" kind of thing.
There is one thing I can think of and that is using the custom objective module and setting a (unique) name in the "Variable Name" field of the module. For example, you place down 3 custom objectives and name them custom_objective_1, custom_objective_2 and custom_objective_3. You should now theoretically be able to replace
} forEach ([_opcom, "objectives"] call ALIVE_fnc_OPCOM);
with
} [custom_objective_1, custom_objective_2, custom_objective_3];
and it'll only check those 3 custom objectives. I've got no clue if this works or not but that's the only thing I can come up with at the moment.
EDIT: Hmm, I don't think that's going to work.
First, sorry for being a necromancer.
If I followed this thread correctly, the final product would look like this?
if (isServer) then { [] spawn { waitUntil {!(isNil "ALIVE_REQUIRE_INITIALISED")}; while {true} do { { private _opcom = _x; private _opcomSide = [_opcom, "side"] call ALIVE_fnc_hashGet; if (_opcomSide == "WEST") then { private _allObjectivesReserved = true; { private _objective = _x; private _objectiveState = [_objective, "tacom_state", "none"] call ALIVE_fnc_hashGet; if (_objectiveState != "reserve") exitWith { _allObjectivesReserved = false; }; } forEach ([_opcom, "objectives"] call ALIVE_fnc_hashGet); if (_allObjectivesReserved) then { "end1" call BIS_fnc_endMissionServer; }; }; } forEach OPCOM_INSTANCES; sleep 60; }; }; };
At a quick glance (on mobile), your solution appears correct.