Larrow 2822 Posted August 12, 2013 Instead of leaving you hanging here is my quick knock up, totally untested, I have run out of time this evening before i need to go out. Have a look, if it has any problems, which its more than likely to have loads of stupid mistakes (hopefully kylania can chip in to help you if hes not busy this evening) , otherwise i will finish it off with some testing tomorrow. removeTasks.sqf //init.sqf //call compile preprocessFileLineNumbers "removeTasks.sqf" if (isServer) then { //[targets, taskid] call LARs_fnc_removeTask; LARs_fnc_removeTask = { _targets = [_this,0,true,[true,sideunknown,grpnull,objnull,[]]] call BIS_fnc_param; _taskID = [_this,1,"",[""]] call BIS_fnc_param; { _target = _x; switch (typeName _target) do { //case (typeName objNull || typeName sideUnknown || typeName [] || typeName true): { // [[_taskID],"LARs_fnc_removeTaskLocal",_target,true] call BIS_fnc_MP; //}; case (typeName grpNull): { [[_taskID],"LARs_fnc_removeTaskLocal",units _target,true] call BIS_fnc_MP; }; default { [[_taskID],"LARs_fnc_removeTaskLocal",_target,true] call BIS_fnc_MP; }; }; } foreach [_targets]; }; }; if (!(isDedicated)) then { //preprocess on clients LARs_fnc_removeTaskLocal = { _taskID = [_this,0,"",[""]] call BIS_fnc_param; _taskVar = [_taskID] call BIS_fnc_taskVar; missionNamespace setVariable [_taskVar,nil]; player removeSimpleTask ([_taskID,player] call BIS_fnc_taskReal); _playerTasks = player getVariable ["BIS_fnc_setTaskLocal_tasks",[]]; _playerTasks = _playerTasks - [_taskID]; player setVariable ["BIS_fnc_setTaskLocal_tasks", _playerTasks]; _playerTaskVar = "BIS_fnc_taskvar_" + _taskID; player setVariable [_playerTaskVar,nil]; }; }; precompile in your init.sqf with call compile preprocessFileLineNumbers "removeTasks.sqf" To use, using your tasks for example [west, "mob_arty"] call LARs_fnc_removeTask; Share this post Link to post Share on other sites
Valixx 11 Posted August 12, 2013 Thanks for "using" your free time for me. Very much appreciated! I'll test it tomorrow though.. and report back to you. Again, thanks! Share this post Link to post Share on other sites
Valixx 11 Posted August 13, 2013 Hey Larrow. I've tested it with my brother today and it works flawfless. I can't thank you enough for this. Share this post Link to post Share on other sites
Larrow 2822 Posted August 13, 2013 Excellent glad it worked ok. Your welcome. Share this post Link to post Share on other sites
Valixx 11 Posted August 14, 2013 (edited) Hey. Sry to bother you again. Detected another problem. If i come to the spawned crate the task is complete. If another soldier goes to the crate the task will not be updated. I have to go there..But in the code it is waitUntil { Player distance art < 10}; Every player should do the trick no? Here is one of the missions: /* ================================================================================================================== Create and spawn the Weapon Crate Task - Sidemission ================================================================================================================== */ fn_spawnCrateMission = { _smhint = "<t align='center' color='#ffffff' shadow='2' size='1.75'>Side Objective</t><br/><t align='center' color='#000000'>------------------------------</t><br/><t color='#ffffff' size='1.0'>Get to the weapon crates for more weapons and stuff.</t>"; GlobalHint = _smhint; publicVariable "GlobalHint"; hintsilent parseText _smhint; //creating the marker _marker = createMarker ["mob_wpcr", call fn_findMissionSpot]; _marker setMarkerType "mil_objective"; _marker setMarkerColor "ColorRed"; _marker setMarkerText "Weapon Crates"; _marker setMarkerSize [1,1]; _null = [west, "mob_wpcr", ["Get to the weapon crates for more weapons and stuff.", "Capture the Weapon Crates", "Capture the Weapon Crates"], getMarkerPos "mob_wpcr", false] spawn BIS_fnc_taskCreate; //creating the crates _veh = ["Box_NATO_Wps_F","Box_NATO_WpsSpecial_F","Box_NATO_Ammo_F","Box_NATO_AmmoOrd_F","Box_NATO_Grenades_F","Box_NATO_Support_F"] call BIS_fnc_selectRandom; art = createVehicle [_veh,[(getMarkerpos _marker select 0) + 30, getMarkerpos _marker select 1,0],[], 0, "NONE"]; ensoldier = [getMarkerPos _marker, east, (configfile >> "CfgGroups" >> "East" >> "OPF_F" >> "Infantry" >> "OIA_InfTeam")] call BIS_fnc_spawnGroup; waitUntil { Player distance art < 10}; deleteMarker _marker; _null = ["mob_wpcr", "SUCCEEDED"] spawn BIS_fnc_taskSetState; _myHint ="Gear up soldier!!"; GlobalHint = _myHint; publicVariable "GlobalHint"; hintsilent parseText _myHint; _mySChat ="Excellent work, use it to your advantage!"; GlobalSCHat = _mySChat; publicVariable "GlobalSCHat"; player sideChat _mySChat; sleep 5; [west, "mob_wpcr"] call LARs_fnc_removeTask; hint ""; }; Edited August 14, 2013 by Valixx Share this post Link to post Share on other sites
Larrow 2822 Posted August 14, 2013 (edited) Hi Valixx Detected another problem. If i come to the spawned crate the task is complete. If another soldier goes to the crate the task will not be updated. I have to go there..But in the code it isPHP Code: waitUntil { Player distance art < 10}; Every player should do the trick no? I always thought it was wierd that you were using player in some places in the script. Im presuming the mission selection is all handled server side and that when you are playing on lan with your brother you are hosting the mission rather than using a dedicated server?? So player will not do, as you are hosting your machine is both server and a client (player) that is why it works for you. Your missions _null = [west, "mob_wpcr", ["Get to the weapon /*snip spawn BIS_fnc_taskCreate; and the code i wrote to delete them work for everyone as those function do it for a selection (west) of all connected clients. You will need to work out the code of what completes the mission, so its not just is the player close to item but are any WEST (said west as you are giving the mission to all players on the WEST side e.g [west, "mob_wpcr",). So maybe a while loop that checks all west units distance to the objective. //set a default variable to change for mission status _missionDone = false; //while the mission is not done while {!(_missionDone)} do { //loop around all playable units (playable is human and AI that are in a slot in the lobby) { //if any of playable are within the distance if ((_x distance art) < 10) then { //set mission as done (while loop will now finish _missionDone = true; }; }foreach playableUnits; //trigger check their condition every 0.5 so this is similar sleep 0.5; }; The above is tailored to your specific setup as you are only playing west (all clients are west side versus AI on the east??), if your were playing another side or had only given the quest to certain individuals then you would need to change this to only check who you need. Edited August 14, 2013 by Larrow Share this post Link to post Share on other sites
Valixx 11 Posted August 14, 2013 Hey Larrow, thanks for your answer. Currently i'm testing the mission on lan with my brother. Once my mission is finished, it will be hosted on my server ( see signature ) hosted by nitrado.net. I'm currently working on the mission for over 2 weeks straight now. Wouldn't be far without you and kylania :P Yep, we are are west versus east. So.. instead of player in my scripts i could use west / playableUnits? Share this post Link to post Share on other sites
Larrow 2822 Posted August 14, 2013 So.. instead of player in my scripts i could use west / playableUnits?A hesitant yes.playableunits = all units in a slot in the lobby including any AI, (AI maybe currently using a slot because AI is on in the lobby and no player has taken the slot) If your scenario is always going to be the same e.g players are only ever going to be west and all players are assigned the task e.g _null = [west, "mob_wpcr", west here meaning all west players are given the task then yes playableunits will be good enough for you to check against. Just replace your current line checking against the player with the code in my last post. Share this post Link to post Share on other sites
Valixx 11 Posted August 14, 2013 Thank you Larrow. I've disabled the AI and the players will always be Blufor. I'll do the change in the code tomorrow. 11PM now and i have to get up early.. Thanks again, it's a big help! Share this post Link to post Share on other sites
Valixx 11 Posted August 15, 2013 Hey. Got a little question. //set a default variable to change for mission status _missionDone = false; //while the mission is not done while {!(_missionDone)} do { //loop around all playable units (playable is human and AI that are in a slot in the lobby) { //if any of playable are within the distance if ((_x distance art) < 10) then { //set mission as done (while loop will now finish _missionDone = true; }; }foreach playableUnits; //trigger check their condition every 0.5 so this is similar sleep 0.5; }; I spawn two enemy infantry groups. What should i change in "if ((_x distance art) < 10)" to "if enemies are dead or no enemie in area"? I hope you can help me out here. Cheers, Valixx Share this post Link to post Share on other sites
Larrow 2822 Posted August 16, 2013 Something like {{alive _x && (_x distance myArea < areaSize)}count units _x == 0}count [AIGroup1, AIGroup2] == 2 Where myArea is the position of your mission marker, areaSize is the radius, AIGroup1/2 are your spawned AI groups. Is true, if 0 (none) of the units are alive and in the area, for both groups. Share this post Link to post Share on other sites
Valixx 11 Posted August 16, 2013 (edited) Thanks larrow. ---------- Post added at 10:48 ---------- Previous post was at 10:01 ---------- _trg = createTrigger ["EmptyDetector", getMarkerPos _marker]; _trg setTriggerArea [200, 200, 0, false]; _trg setTriggerActivation ["EAST", "NOT PRESENT", false]; _trg setTriggerStatements ["this", "_enemyDead = true;", ""]; _enemyDead = false; while {!(_enemyDead)} do { { if (/*what should i put here to check the trigger?*/) then { _enemyDead = true; }; } foreach playableUnits; sleep 0.5; }; deleteMarker _marker; _null = ["mob_infa", "SUCCEEDED"] spawn BIS_fnc_taskSetState; I know i have something wrong here but can't figure it out. Studying web-design, learning sqf at the same time..... i'm going nuts.. Edited August 16, 2013 by Valixx Share this post Link to post Share on other sites
kylania 568 Posted August 16, 2013 You have a local variable in the trigger. Change that to global and public variable it when you set it. Share this post Link to post Share on other sites
Larrow 2822 Posted August 16, 2013 There are two possibilities here. 1. TRIGGERS: I see in the snippet of code you have shown above that you have a trigger set up and your trying to set a variable in the trigger statement that will satisfy the condition of your while loop. As the code in the trigger statement is not run in the same scope as your script, using the local variable _enemyDead is not going to work. We can split this into four workable options. Hey having options is always good :D 1a. _trg = createTrigger ["EmptyDetector", getMarkerPos _marker]; _trg setTriggerArea [200, 200, 0, false]; _trg setTriggerActivation ["EAST", "NOT PRESENT", false]; _trg setTriggerStatements ["this", "enemyDead = true;", ""]; enemyDead = false; waitUntil {!(enemyDead)}; deleteMarker _marker; _null = ["mob_infa", "SUCCEEDED"] spawn BIS_fnc_taskSetState; Here we have turned the variable set in the trigger statement into a global variable which can now be checked by your script. Only down side here is what if you wanted to spawn two of these types of mission at the same time! the global variable enemyDead is now going to conflict between the two missions. 1b. _trg = createTrigger ["EmptyDetector", getMarkerPos _marker]; _trg setTriggerArea [200, 200, 0, false]; _trg setTriggerActivation ["EAST", "NOT PRESENT", false]; _trg setTriggerStatements ["this", "", ""]; enemyDead = false; waitUntil {triggerActivated _trg}; deleteMarker _marker; _null = ["mob_infa", "SUCCEEDED"] spawn BIS_fnc_taskSetState; Here we use a trigger to whittle down to the option we require e.g (EAST, NOT PRESENT, false). Then in script check for the trigger activation to advance our script. 1c. _trg = createTrigger ["EmptyDetector", getMarkerPos _marker]; _trg setTriggerArea [200, 200, 0, false]; _trg setTriggerActivation ["ANY", "PRESENT", true]; _enemyDead = false; while {!(_enemyDead)} do { _triggerContents = list _trg; if ({side _x == opfor} count _triggerContents == 0) then { _enemyDead = true; }; }; deleteMarker _marker; _null = ["mob_infa", "SUCCEEDED"] spawn BIS_fnc_taskSetState; In this example we use a simple trigger continuously monitoring for anything. Then in script we get a reference to what is in the trigger by using the command list and use script to whittle down the options we want, which in this case we count everything that is in the triggers list that is side opfor, if this equals 0 we know there are no opfor in the trigger. Remember you could put extra checks in here, as written above if there was a opfor vehicle with three men in it the count is only going to return 1 as the men are seen as being part of the vehicle. 2. MANUALLY checking the area: This is what my previous post was referencing. I was being lazy and already knew from your previous posts that you had a mission marker so did not want to explain trigger options at the time :D. waitUntil {{{alive _x && (_x distance _marker < 200)}count units _x == 0}count [AIGroup1, AIGroup2] == 2}; deleteMarker _marker; _null = ["mob_infa", "SUCCEEDED"] spawn BIS_fnc_taskSetState; Wait until none of the units from AIGroup1 or 2 are alive and within 200 meters of _marker, then then continue on with the script. There are other options to not using a trigger aswell, for instance you could use nearEntities along with the position of you marker and a radius to get a list of things back that you could whittle down using iskindof and side etc but i think thats enough examples for now and should give you a good idea of how to get pretty much anything your looking for in your areas. BTW all these option are written as a copy & paste to replace everything that you wrote in your last post. //Disclaimer: untested and may contain silly mistakes, but i have used all these options before in one way or another, so should be good to go. ---------- Post added at 13:56 ---------- Previous post was at 13:42 ---------- and public variable it when you set it.No need for the PV, from what ive read of this thread this is all happening server side. Trigger will be created server side and global variable will be on the server, logic is all checked server side and task given out by the BIS_fnc_MP in the task functions. Share this post Link to post Share on other sites
Valixx 11 Posted August 16, 2013 Oh man, that's a huge help. Can't thank you enough for this! 1a and 1b are looking so easy... I'm still confused that i didn't get this on my own :butbut: Share this post Link to post Share on other sites
delta99 34 Posted August 16, 2013 if ({side _x == opfor} count _triggerContents == 0) then { I've seen syntax like this a few times now in this thread. Does this actually work as it doesn't seem to make sense to me at all. It looks like what you are trying to do is count the number of opfor in the triggerContents array/list and if 0 then if statement is true. But I don't see how that would do it with that syntax. I've never used an iteration like that with _x in that manner. Share this post Link to post Share on other sites
kylania 568 Posted August 16, 2013 _x works with count just like it does with forEach, it just counts instead of just iterates. :) Share this post Link to post Share on other sites
Larrow 2822 Posted August 17, 2013 (edited) It looks like what you are trying to do is count the number of opfor in the triggerContents array/list and if 0 then if statement is true. But I don't see how that would do it with that syntax.Thats exactly what it is doing. CODE count ARRAY For each index of the array the code is evaluated, if the code is true then 1 is added to the total count. Say you wanted to know atleast 1 unit was alive out of a list of units, you could _numberOfAliveUnits = 0; { if (alive _x) then { _numberOfAliveUnits = _numberOfAliveUnits + 1; }; } forEach [unit1, unit2, unit3]; if (_numberOfAliveUnits > 0) then { hint "someone is alive"; }; or if ( { alive _x } count [unit1, unit2, unit3] > 0 ) then { hint "someone is alive"; } I know which one id rather type out and keep track of :) Edited August 17, 2013 by Larrow Share this post Link to post Share on other sites
Valixx 11 Posted August 17, 2013 Quick question: To name a group, you go to the group leader's init box and type: groupname = group this; ? And then you can call it with your code above. Share this post Link to post Share on other sites
delta99 34 Posted August 17, 2013 Thats exactly what it is doing. Cool. Never ran across this syntax before. It is handy!! Share this post Link to post Share on other sites
Larrow 2822 Posted August 17, 2013 To name a group, you go to the group leader's init box and type: groupname = group this; ?You can do, yes. groupname is now a global variable holding a reference to the group.And then you can call it with your code above. Yes, with a slight change as you would want to count through an array of the units of groupname.if ( { alive _x } count (units groupname) > 0 ) then { hint "someone is alive"; } Share this post Link to post Share on other sites
hellstorm77 2 Posted August 29, 2013 Gread idea Delta99, here it is with SHK_Pos and a few changes.init.sqf: call compile preprocessfile "SHK_pos\shk_pos_init.sqf"; call compile preprocessfile "globaltools.sqf"; globalTools.sqf: //ENABLE GLOBAL HINT from Occupation by BangaBob "GlobalHint" addPublicVariableEventHandler {private ["_GHint"];_GHint = _this select 1;hint parseText format["%1", _GHint]; }; "GlobalSideChat" addPublicVariableEventHandler {private ["_GSChat"];_GSChat = _this select 1;player sideChat _GSChat; }; missionFinder.sqf: //Mission Select if(!isServer) exitWith {}; //waituntil {!isnil "bis_fnc_init"}; //waiting _missions = ["arty","harrier","tank","heli","truck","c130wreck"]; //mission array //_choose = _missions call BIS_fnc_selectRandom; // random mission _choose = "arty"; [_choose] execVM "makemission.sqf"; //call mission missionMaker.sqf: // Mission _missionType = [_this, 0, ""] call BIS_fnc_param; sleep random 15; fn_findMissionSpot = { private ["_mapCenter"]; _mapCenter = getArray (configFile >> "CfgWorlds" >> worldName >> "centerPosition"); [_mapCenter, random 4000, random 360, false] call SHK_pos; }; fn_spawnArtyMission = { hint "Capture the Artillery First!!!"; //creating the marker _marker = createMarker ["Mobile Artillery", call fn_findMissionSpot]; _marker setMarkerType "mil_destroy"; _marker setMarkerColor "ColorRed"; _marker setMarkerText "Mobile Artillery"; _marker setMarkerSize [1,1]; //creating the vehicle _veh = ["B_MRAP_01_F","B_MRAP_01_F"] call BIS_fnc_selectRandom; art = createVehicle [_veh,[(getMarkerpos _marker select 0) + 30, getMarkerpos _marker select 1,0],[], 0, "NONE"]; art setFuel 1; art setVehicleAmmo 1; waitUntil { Player distance art < 20}; deleteMarker _marker; _myHint ="Destroy some stuff soldier!!"; GlobalHint = _myHint; publicVariable "GlobalHint"; hintsilent parseText _myHint; _mySChat ="Excellent work, use it to your advantage!"; GlobalSCHat = _mySChat; publicVariable "GlobalSCHat"; player sideChat _mySChat; sleep 3; hint ""; }; // MAIN LOGIC _missionDetails = switch (_missionType) do { case "arty": {call fn_spawnArtyMission;}; }; nul = [] execVM "missionfinder.sqf"; Do i need to add any markers? Share this post Link to post Share on other sites
kylania 568 Posted August 29, 2013 Not for that, it'll create it's own. Due to JIP issues though you might wanna just have a mission marker on the map already and just move it maybe? Share this post Link to post Share on other sites
hellstorm77 2 Posted August 29, 2013 i was wondering why nothing was spawning ---------- Post added at 21:25 ---------- Previous post was at 20:41 ---------- do you have a test mission Share this post Link to post Share on other sites
kylania 568 Posted August 29, 2013 Here's a test mission. 0-0-1 to start the missions spawning. 0-0-2 to teleport to the mission. Walk towards the vehicle to complete the mission and spawn another. Share this post Link to post Share on other sites