Using objective capture status for triggering events

  1. ‹ Older
  2. 7 years ago

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

  3. 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
            };
        };
    };
  4. 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

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

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

  7. highhead

    4 Sep 2017 Administrator

    Correct! :)

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

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

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

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

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

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

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

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

  16. 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
  17. Hnmm weird. Try replacing

    [_opcom, "objectives"] call ALIVE_fnc_OPCOM

    with

    [_opcom, "objectives"] call ALIVE_fnc_hashGet
  18. 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?

  19. Edited 6 years ago by marceldev89

    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.

  20. 5 years ago

    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;
            };
        };
    };
  21. At a quick glance (on mobile), your solution appears correct.

  22. Newer ›
 

or Sign Up to reply!