sudoshakes 10 Posted July 26, 2013 (edited) So as I tried to say in the title as succinctly as possible, I am having trouble dealing with annoying behavior in an SQF I am working on. Essentially what it will do is when the player throws a smoke grenade, depending on the type, a helicopter will fly in and drop off reinforcements on the player's current position. Problem is if I tell the reinforcements to join the player's group inside the grenade type case statement, the chopper flys to the position and then hovers about 100 meters away not moving or landing. I have deduced this has something to do with the chopper's group and how I am handling the waypoint additions. It seems that if I tell a unit in the choppers cargo to join my group, the waypoint addition using the chopper's group suddenly is not valid due to the addwaypoint command using a group to assign it to. Something about taking a unit from the cargo and putting it in the player's group is making the last waypoint command not fire. I cannot confirm this though, so can someone help me out? Thanks! For this demo, the unit in back of the chopper is named rein1, the helicopter is named chopper. There is a gamelogic base named base, with a helipad placed near it. The base is where the last waypoint is mapped to so the chopper always heads back home to base after dropping off reinforcements. The line in the player unit's init to call the script is this addEventHandler ["fired",{_this execvm "reinforce_smoke.sqf"}]; As I said above, the code works fine doing everything until I attempt to make the newly dropped off unit join my group. Do I need to wait until after the helicopter is empty to assign to avoid messing with waypoints? I tried something like this: waituntil{ isNull (assignedVehicle rein1) } hoping that once on the ground, the reinforcements in cargo would no longer hold any assignment to the chopper vehicle, but this did not prevent the behavior either. I also tried to use //waituntil {{_x in chopper}count units blue == 0 but that also did not prevent the behavior. See code below: SQF FILE _ammotype = _this Select 4; switch (_ammotype) do { ...{code omitted}... case "SmokeShellRed": { Hint "Reinforcements Inbound"; _Rwp_3 = group chopper addWaypoint [ getpos player, 50]; _Rwp_3 setWaypointType "TR UNLOAD"; _Rwp_3 setWaypointStatements ["true", "chopper land 'land'; chopper setdamage 0"]; _Rwp_4 = group chopper addWaypoint [getpos base, 50]; _Rwp_4 setWaypointType "MOVE"; [rein1] joinSilent (group player); } ...{code omitted}... } Edited July 26, 2013 by sudoshakes Share this post Link to post Share on other sites
kylania 568 Posted July 26, 2013 Too much to read on my phone but as an idea don't join anything till the AI are on the ground ready. The heli crew should be entirely separate as well. So spawn heli with crew. Spawn refi group and move into cargo. Fly to location drop the group off. Then have the player talk to the AI to join up. Share this post Link to post Share on other sites
sudoshakes 10 Posted July 26, 2013 the reinforcements are totally separate and I am doing just that currently. I am not sure how to programmatically evaluate when the AI are no longer in the chopper cargo, assignedvehicle and such seem to not be null even after exiting the vehicle. Ideas on what to use for seeing when AI are out? I was trying waituntil{ isNull (assignedVehicle rein1) } but that doesnt work and when I tried to print out the assignvehicle object via Hint tostring(assignedvehicle rein1), I also do not get any text. i'm Stumped. Share this post Link to post Share on other sites
kylania 568 Posted July 26, 2013 Group leavevehicle heli; That'll get them out and unassigned. {_x in heli} count units group == 0 To check they are all out. Share this post Link to post Share on other sites
sudoshakes 10 Posted July 27, 2013 Group leavevehicle heli; That'll get them out and unassigned. {_x in heli} count units group == 0 To check they are all out. I have been trying to figure out what the "_X" signifies syntax wise. I am a programmer by trade so I was able to pick up a lot of this fairly quickly today, but I have not got all the syntax down yet. As for the fix, it is still not working. I will mess with it a bit more and get back to you. Share this post Link to post Share on other sites
kylania 568 Posted July 27, 2013 _x is a magic variable which is automatically replaced by the current value of whatever array you're forEach or count'ing through. So if you have units, p1, p2 and p3 in your group that code would run p1 in heli, p2 in heli and p3 in heli and count how many TRUE results they get from that. When it's 0, everyone is out of the heli. Share this post Link to post Share on other sites
sudoshakes 10 Posted July 28, 2013 Ok... so I have messed with this for two days now. no luck. The following is the code I want executed in the script. MAJOR PROBLEMS: Scripts are stupid in that code is executed past the current point of execution. The command to have reinforcements leaveVehicle is fired when the chopper spawns, forcing it to land at the base, then take off to the player. To fix this, I tried to create a waituntil that examines when the chopper lands before executing the levevehicle command on the reinforcements, but I cnanot get the syntax right. This is a stupid problem to have. Why the hell does code in the SQF fire before the previous action being evaluated is complete?!?!?! Observed behavior: When run, this code causes the chopper to spawn, move close to player location, and land. Does not drop off troops. I want the troops dropped off, and then assigned to my player group. Any help would be good here. Also, any idea why the TR UNLOAD for the waypoint isn't forcing the troops out by default? Thanks! switch (_ammotype) do { case "SmokeShellGreen": { Hint "Green Smoke Detected"; pilotGroup = createGroup west; // group for chopper and pilot _bckup = creategroup west; //create group for reinforcements newchopper = createVehicle ["B_Heli_Light_01_F", position base, [], 0, "FLY"]; // use createvehicle array to spawn chopper flying on base gamelogic position named base [newchopper] join pilotGroup; // assign chopper to group for piloted shit "B_soldier_F" createUnit [position newchopper, pilotGroup," pilot1 = this; pilot1 assignAsDriver newchopper; pilot1 moveInDriver newchopper;"]; //spawn pilot in newchopper "B_soldier_F" createUnit [position newchopper, _bckup," soldier1 = this; soldier1 assignAsCargo newchopper; soldier1 moveInCargo newchopper;"];//spawnreinforcement in cargo inchopper //add waypoints so copper moves to players location and drops off cargo. _wp0 = group newchopper addWaypoint [ getpos player, 10]; _wp0 setWaypointType "TR UNLOAD"; _wp0 setWaypointStatements ["true", "newchopper land 'land'"]; // when landed this waypoint completed waituntil {{newchopper land 'land'} == true}; // THROWING SYNTAX ERROR, BUT NEEDED BECAUSE THE DAMN CHOPPER WONT DELAY THE LEAVEVEHICLE COMMAND _bckup leaveVehicle newchopper; //IS STILL NOT FORCING REINFORCEMENTS FROM BACK OF CHOPPER OUT WHEN LANDED. }; }; Share this post Link to post Share on other sites
Larrow 2828 Posted July 28, 2013 Something like //setup waypoint waitUntil {isTouchingGround newchopper}; unassignVehicle soldier1; soldier1 action ["GetOut", newchopper]; [soldier1] joinSilent (group player); //setup return waypoint I have no idea why TR UNLOAD doesnt work for AI! Share this post Link to post Share on other sites
kylania 568 Posted July 28, 2013 (edited) See later post Edited August 1, 2013 by kylania Share this post Link to post Share on other sites
sudoshakes 10 Posted July 31, 2013 literally, nothing happens. Nothing. Not even a yell. I placed the script in the same folder I had been using for the others, and placed "player call SMOKEHELI_fnc_addSmokeCheck; " in the init line of the player. /shrug Ideas? Share this post Link to post Share on other sites
kylania 568 Posted July 31, 2013 The functions won't work if they aren't read and they aren't read just by putting them in a script and not calling it. :) Either put that as your init.sqf or put that in smokeheli.sqf and put: execVM "smokeheli.sqf"; in your init.sqf It also seems to fail miserably on a dedicated server... but then again setting up a dedicated server is failing miserable for me to test with so guess it's all good. Share this post Link to post Share on other sites
sudoshakes 10 Posted July 31, 2013 Well, I get the player to shout "smoke out" but no helocopter spawns, nor any units, nor do I get any syntax errors on screen. Share this post Link to post Share on other sites
kylania 568 Posted August 1, 2013 (edited) Try this code instead, it's a bit more robust. :) Also make sure you change heliBase in the first line to whatever spawn marker you're using. // Options. SMOKEHELI_spawnMarker = "heliBase"; // STRING - marker name of where to start and delete the helicopter. SMOKEHELI_helicopterType = "B_Heli_Light_01_F"; // STRING - class name of the helicopter to use. SMOKEHELI_groupType = (configFile >> "CfgGroups" >> "West" >> "BLU_F" >> "Infantry" >> "BUS_ReconPatrol"); // CONFIG - CfgGroups entry of preset group // SMOKEHELI_groupType = ["B_Soldier_F","B_Soldier_F","B_Soldier_F"]; // ARRAY - List of classnames to spawn for reinforcements. Option instead of above. SMOKEHELI_SmokeColor = "SmokeShellGreen"; // STRING - classname of the smoke grenade to look for. SMOKEHELI_feedback = true; // BOOL - Yell smoke out like a boss? if (isNil "SMOKEHELI_Active") then {SMOKEHELI_Active = false;}; // Function to check for smoke being thrown. SMOKEHELI_fnc_addSmokeCheck = { // Add eventHandler for tossing smoke from Demonized _idx = player addEventHandler ["Fired", { if (((_this select 5) != SMOKEHELI_SmokeColor) || SMOKEHELI_Active) exitWith {}; // Not green so ignore it. // Green! Lets see where it lands. _null = (_this select 6) spawn { // Get current location of the smoke shell _posg = getPos _this; sleep 0.5; // As it rolls keep updating the location. If it keeps rolling or jitters it's last pos when it disappears will be _posg. while {(_posg distance (getPos _this)) > 0} do { _posg = getPos _this; sleep 0.5; }; // We've come to a stop and know where to fly so lets do it! [[_posg, player], "SMOKEHELI_fnc_spawnReinforcements", false] spawn BIS_fnc_MP; if (SMOKEHELI_feedback) then { player sideChat "Smoke out!"; playSound3D ["A3\dubbing_radio_f\data\Male02\RadioProtocolENG\Stealth\200_CombatShouts\ThrowingSmokeE_2.ogg", player]; // so lulz :) }; }; }]; }; // Function to spawn helicopter and reinforcements and deploy them. SMOKEHELI_fnc_spawnReinforcements = { private["_reinforcements", "_heli"]; SMOKEHELI_Active = true; publicVariable "SMOKEHELI_Active"; _landPos = _this select 0; _unit = _this select 1; _spawnPos = getMarkerPos SMOKEHELI_spawnMarker; // Spawn invis helipad at the smoke to land on. _helipad = createVehicle ["Land_HeliPadEmpty_F", _landPos, [], 0, "NONE"]; // Spawn helicopter and crew. _helisv = [_spawnPos, 180, SMOKEHELI_helicopterType, WEST] call BIS_fnc_spawnVehicle; _heli = _helisv select 0; _heliCrew = _helisv select 1; _heliGroup = _helisv select 2; // Spawn reinforcements and get them in the helicopter. _reinforcements = [_spawnPos, blufor, SMOKEHELI_groupType] call BIS_fnc_spawnGroup; {_x assignAsCargo _heli; _x moveInCargo _heli;} forEach units _reinforcements; // Waypoint to the location _wp1 = _heliGroup addWaypoint [_landPos, 0]; _wp1 setWaypointSpeed "FULL"; //_wp1 setWaypointType "MOVE"; //_wp1 setWaypointStatements ["true", "(vehicle this) LAND 'GET IN'; (vehicle this) flyInHeight 0;"]; _wp1 setWaypointType "UNLOAD"; _wp1 setWaypointStatements ["true", "(vehicle this) LAND 'GET IN';"]; //" (vehicle this) flyInHeight 0;"]; // Wait till we're landed. //waitUntil{isTouchingGround _heli}; // Get out! _reinforcements leaveVehicle _heli; //sleep 5; // Wait till we're out. waitUntil{sleep 1; {_x in _heli} count units _reinforcements == 0}; sleep 5; // Release heli from being landed and clean up. _heli flyInHeight 50; deleteVehicle _helipad; // Waypoint back to base and delete. _wp2 = _heliGroup addWaypoint [_spawnPos, 0]; _wp2 setWaypointSpeed "FULL"; _wp2 setWaypointType "MOVE"; _wp2 setWaypointStatements ["true", "{deleteVehicle _x} forEach crew (vehicle this) + [vehicle this]; SMOKEHELI_Active = false; publicVariable 'SMOKEHELI_Active';"]; // Join the units to the player's group. units _reinforcements joinSilent _unit; }; // Add eventhandler to player. player call SMOKEHELI_fnc_addSmokeCheck; Yup, just tested this on dedicated and it worked fine. Edited August 1, 2013 by kylania Share this post Link to post Share on other sites
sudoshakes 10 Posted August 1, 2013 I do not doubt you in any way, but this does not work in the editor. I get the player to call smoke out, so the function is firing, but there is no chopper spawning. I triple checked the invis helipad name used as the spawn location. notta. Any reason you can think this is? Share this post Link to post Share on other sites
kylania 568 Posted August 1, 2013 I triple checked the invis helipad name used as the spawn location. notta. Any reason you can think this is? Read the notes in the script. There's no invis helipad used as the spawn location, it's a marker name. :) Share this post Link to post Share on other sites
sudoshakes 10 Posted August 1, 2013 When I am done crying in the corner in shame, I will be back tomorrow to confirm it is working or further humiliate myself. Sheesh. Thanks for the help though, you are rockin it. Share this post Link to post Share on other sites
sudoshakes 10 Posted August 2, 2013 Well it works but the helicopter seems to delete before flying off. it simply vanishes in mid air right after leaving the smoke. Any way to fix that? Otherwise Fantastic work. Share this post Link to post Share on other sites
kylania 568 Posted August 2, 2013 How far away is the spawn point from where you called the smoke? Share this post Link to post Share on other sites
sudoshakes 10 Posted August 2, 2013 How far away is the spawn point from where you called the smoke? 200 yards maybe. Also in testing, I found that if I place the spawn at the LZ on the hill above the airport, and am as far away as the beach or the land near the runway, the chopper just flies slowly to the oil tanks and lands on it's own, not coming to the green smoke location. Share this post Link to post Share on other sites
kylania 568 Posted August 2, 2013 Put the starting spawn away from all the tempting helipads at the airfield. Out in the water somewhere maybe. Also well away from where you'll be calling it. Share this post Link to post Share on other sites
sudoshakes 10 Posted August 2, 2013 Put the starting spawn away from all the tempting helipads at the airfield. Out in the water somewhere maybe. Also well away from where you'll be calling it. Rather temperamental... I will do as you say. ---------- Post added at 01:04 ---------- Previous post was at 00:59 ---------- Yeah... it is still not being predictable. It lands randomly dropping off the reinforcements far away, not even on landing pads. Random landing on beaches and stuff. Sometimes it works, if the spawn is not too far away, this defeats the point of it being an agile script though. Share this post Link to post Share on other sites
Larrow 2828 Posted August 2, 2013 (edited) 200 yards maybeHelicopters have an automatic waypoint completion of around 500m (especially when using GET OUT type), no matter what completion radius you create the waypoint with.I found that if I place the spawn at the LZ on the hill above the airport, and am as far away as the beach or the land near the runway, the chopper just flies slowly to the oil tanks and lands on it's own, not coming to the green smoke location. This may also be whats causing the other problem. As heli is spawned , its already within 500m of the waypoint so because of the Land command it just looks for the nearest landing spot. You maybe able to get around this by including a distance check in the waypoints condition. e.g _wp1 setWaypointStatements ["true[color="#FF0000"] && ((this distance _landPos) < 20)[/color]", "(vehicle this) LAND 'GET IN';"]; and _wp2 setWaypointStatements ["true [color="#FF0000"]&& ((this distance _spawnPos) < 20)[/color]", "{deleteVehicle _x} forEach crew (vehicle this) + [vehicle this]; SMOKEHELI_Active = false; publicVariable 'SMOKEHELI_Active';"]; This should force the heli to get closer before the waypoint is considered completed, and then the land commands are activated/or the vehicle is deleted. __________________________________________________ OK i played with this for a bit, looks like the main problem was the use of the leaveVehicle command. This was having the unwanted effect off the reinforcements saying 'we want out and we want out NOW' so the pilot would find the nearest place to land. Ive changed the helis waypoint to a TR UNLOAD and the land to GET OUT. So they dismount nicely without the need for the leaveVehicle. Then used the waituntil to count that no one is left in the helicopter before sending it on its way. I tweaked the positioning of the HeliPad to make sure its 0 elevation as i have had this cause me problems before. Ive also sent the heli back to where it came from plus 500m so that it dosent delete to early if you are close to the spawnPoint and moved the clean up of the helipad to the end , I found deleting it to early (especially with other pads nearby like around the airport) made the heli try to reland before moving off to its new waypoint. Ive tested it in lots of different areas and it lands where the smoke is and everything seems to be behaving. // Options. SMOKEHELI_spawnMarker = "heliBase"; // STRING - marker name of where to start and delete the helicopter. SMOKEHELI_helicopterType = "B_Heli_Light_01_F"; // STRING - class name of the helicopter to use. SMOKEHELI_groupType = (configFile >> "CfgGroups" >> "West" >> "BLU_F" >> "Infantry" >> "BUS_ReconPatrol"); // CONFIG - CfgGroups entry of preset group // SMOKEHELI_groupType = ["B_Soldier_F","B_Soldier_F","B_Soldier_F"]; // ARRAY - List of classnames to spawn for reinforcements. Option instead of above. SMOKEHELI_SmokeColor = "SmokeShellGreen"; // STRING - classname of the smoke grenade to look for. SMOKEHELI_feedback = true; // BOOL - Yell smoke out like a boss? if (isNil "SMOKEHELI_Active") then {SMOKEHELI_Active = false;}; // Function to check for smoke being thrown. SMOKEHELI_fnc_addSmokeCheck = { // Add eventHandler for tossing smoke from Demonized _idx = player addEventHandler ["Fired", { if (((_this select 5) != SMOKEHELI_SmokeColor) || SMOKEHELI_Active) exitWith {}; // Not green so ignore it. // Green! Lets see where it lands. _null = (_this select 6) spawn { // Get current location of the smoke shell _posg = getPos _this; sleep 0.5; // As it rolls keep updating the location. If it keeps rolling or jitters it's last pos when it disappears will be _posg. while {(_posg distance (getPos _this)) > 0} do { _posg = getPos _this; sleep 0.5; }; // We've come to a stop and know where to fly so lets do it! [[_posg, player], "SMOKEHELI_fnc_spawnReinforcements", false] spawn BIS_fnc_MP; if (SMOKEHELI_feedback) then { player sideChat "Smoke out!"; playSound3D ["A3\dubbing_radio_f\data\Male02\RadioProtocolENG\Stealth\200_CombatShouts\ThrowingSmokeE_2.ogg", player]; // so lulz :) }; }; }]; }; // Function to spawn helicopter and reinforcements and deploy them. SMOKEHELI_fnc_spawnReinforcements = { private["_reinforcements", "_heli"]; SMOKEHELI_Active = true; publicVariable "SMOKEHELI_Active"; _landPos = _this select 0; _unit = _this select 1; _spawnPos = getMarkerPos SMOKEHELI_spawnMarker; //make sure helipad is at 0 elevation _landPos set [2, 0]; // Spawn invis helipad at the smoke to land on. _helipad = createVehicle ["Land_HeliPadEmpty_F", _landPos, [], 0, "NONE"]; // Spawn helicopter and crew. _helisv = [_spawnPos, [_spawnPos, _landPos] call BIS_fnc_dirTo , SMOKEHELI_helicopterType, west] call BIS_fnc_spawnVehicle; _heli = _helisv select 0; _heliCrew = _helisv select 1; _heliGroup = _helisv select 2; // Spawn reinforcements and get them in the helicopter. _reinforcements = [_spawnPos, blufor, SMOKEHELI_groupType] call BIS_fnc_spawnGroup; {_x assignAsCargo _heli; _x moveInCargo _heli;} forEach units _reinforcements; // Waypoint to the location for heli _wp1 = _heliGroup addWaypoint [_landPos, 0]; _wp1 setWaypointSpeed "FULL"; _wp1 setWaypointType "TR UNLOAD"; _wp1 setWaypointStatements ["true", "(vehicle this) LAND 'GET OUT';"]; // Wait till we're out. waitUntil{sleep 1; {_x in _heli} count units _reinforcements == 0}; // Release heli from being landed and clean up. _heli flyInHeight 50; // Join the units to the player's group. units _reinforcements joinSilent _unit; //Waypoint back to base and delete _dir = [_landPos, _spawnpos] call BIS_fnc_dirTo; _delPos = [_spawnPos, 500, _dir] call BIS_fnc_relPos; _wp2 = _heliGroup addWaypoint [_delPos, 0]; _wp2 setWaypointSpeed "FULL"; _wp2 setWaypointType "MOVE"; _wp2 setWaypointStatements ["true", "{deleteVehicle _x} forEach crew (vehicle this) + [vehicle this]; SMOKEHELI_Active = false; publicVariable 'SMOKEHELI_Active';"]; deleteVehicle _helipad; }; // Add eventhandler to player. player call SMOKEHELI_fnc_addSmokeCheck; Edited August 2, 2013 by Larrow Share this post Link to post Share on other sites
barbolani 198 Posted October 22, 2013 I must say I am amazed... been 6 hours for doing something like this (a "When we were soldiers" continuous reinforcement via heli) with lots of hedeaches and, after a few searches, found this magnificient piece of code (not my usual "I dont know exactly what I am copy pasting" style) Congrats. Share this post Link to post Share on other sites
Smoerble 11 Posted August 24, 2014 Thanks at Larrow and kylani for this, great job! (...and yes, I know this is more than one year old ;)). Share this post Link to post Share on other sites