Using objective capture status for triggering events

  1. 7 years ago

    Hello there!

    Can the objective capture status (captured & occupied) be somehow parsed and then be used for triggering events?

    So for example when the ALiVE virtualized (or spawned) units "occupy" an objective I'd like to use that moment when the "Occupied" text appears over the objective to trigger an event of my choice.

    I've put ALIVE_fnc_getNearProfiles to good use for the purpose of triggering events but "capturing" and "occupying" an objective takes n-amount of time and it's slightly difficult to set the trigger timer to match the actual time when an objective will turn to "Occupied" state.

  2. This file is a good one to learn from:
    https://github.com/ALiVEOS/ALiVE.OS/blob/master/addons/fnc_analysis/fnc_militaryIntel.sqf

    Notably, the "listen" operation

  3. Hey spyder and thanks for shoving me in the right direction.

    I guess you meant this when you mentioned the "listen" operation?

    case "listen": {
    private["_listenerID"];
    
    _listenerID = [ALIVE_eventLog, "addListener",[_logic, ["LOGISTICS_INSERTION","LOGISTICS_DESTINATION","PROFILE_KILLED","AGENT_KILLED","OPCOM_RECON","OPCOM_CAPTURE","OPCOM_DEFEND","OPCOM_RESERVE","OPCOM_TERRORIZE"]]] call ALIVE_fnc_eventLog;
    [_logic,"listenerID",_listenerID] call ALIVE_fnc_hashSet;
    };

    Now that is just the stuff I never seem to be able to wrap my head around.

    Ok, so how much wrong I get this when I say that the OPCOM markers are the one's that switch state between neutral/captured/occupied and those are the ones that I should monitor (or in this case "listen")? Or is it actually the military placement modules that I should be "listening" and the markers are just there to relay the changing status information?

    Is everything that is inside the fnc_militaryIntel.sqf file actual code or.. if I want to use that case "listen" somehow do I need to change _listenerID, _logic and "listener" to something actual (like variable names) I have placed in the editor?

    I guess I should start with a plain SQF-file, give it a name such as "listen.sqf" and paste that code block in it and then call the SQF-file with []exec listen.sqf from somewhere or?

  4. So how could I go on to create triggers that activate endMission or BIS_fnc_endMission state with the help of this "listener"?

  5. Edited 6 years ago by SpyderBlack723

    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
            };
        };
    };
  6. Edited 7 years ago by Asmodeus

    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

  7. highhead

    21 Aug 2017 Administrator
    Edited 7 years ago by highhead

    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

  8. Edited 7 years ago by Reddog

    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??

  9. highhead

    4 Sep 2017 Administrator

    Correct! :)

  10. highhead

    4 Sep 2017 Administrator
    Edited 7 years ago by highhead

    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

  11. 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?

  12. 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:

    • What if one wanted a mission to end when multiple objectives are occupied? Would I need to create an array of objectives and if yes then how? (to this day I haven't digested how to "array" in Arma..)
    • Naturally a mission should end when certain objectives have been occupied by a certain Side and not just any, so the code for this should include a side check. How should one approach this?

    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?

  13. If youve got logging switched on, it all gets dumped into the log file?

  14. 6 years ago

    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.

  15. Edited 6 years ago by marceldev89

    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. ^^

  16. 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?

  17. 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.

  18. 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
  19. Hnmm weird. Try replacing

    [_opcom, "objectives"] call ALIVE_fnc_OPCOM

    with

    [_opcom, "objectives"] call ALIVE_fnc_hashGet
  20. Edited 6 years ago by Asmodeus

    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?

  21. Newer ›
 

or Sign Up to reply!