// Sets the WP type for WP for the specified group and updates other atributes accordingly. /* GMS_fnc_setNextWaypoint for ghostridergaming By Ghostrider [GRG] Copyright 2016 -------------------------- License -------------------------- All the code and information provided here is provided under an Attribution Non-Commercial ShareAlike 4.0 Commons License. http://creativecommons.org/licenses/by-nc-sa/4.0/ TODO: Replaces changeToMoveWaypoint and Replaces changeToSADWaypoint */ #include "\GMS\Compiles\Init\GMS_defines.hpp" private["_group","_wp","_index","_pattern","_mode","_arc","_dis","_wpPos"]; private _group = group _this; private _leader = _this; private _pos = _group getVariable "patrolCenter"; // Center of the area to be patroleld. private _minDis = _group getVariable "minDis"; // minimum distance between waypoints private _maxDis = _group getVariable "maxDis"; // maximum distance between waypoints private _patrolRadius = _group getVariable "patrolRadius"; // radius of the area to be patrolled private _wpMode = _group getVariable "wpMode"; // The default mode used when the waypoint becomes active https://community.bistudio.com/wiki/AI_Behaviour private _wpTimeout = _group getVariable "wpTimeout"; // Here to alow you to have the game engine pause before advancing to the next waypoing. a timout of 10-20 sec is recommended for infantry and land vehicles, and 1 sec for aircraft private _wpDir = _group getVariable "wpDir"; // Used to note the degrees along the circumference of the patrol area at which the last waypoint was positioned. private _arc = _group getVariable "wpArc"; // Increment in degrees to be used when advancing the position of the patrol to the next position along the patrol perimeter private _wp = [_group,0]; private _nearestEnemy = _leader findNearestEnemy (getPosATL _leader); private _maxTime = _group getVariable["maxTime",300]; // Extricate stuck group. if (diag_tickTime > (_group getVariable "timeStamp") + _maxTime) exitWith { // try to get unit to move and do antiStuck actions _group setBehaviour "CARELESS"; // We need them to forget about enemies and move _group setCombatMode "BLUE"; // We need them to disengage and move private _vector = _wpDir + _arc + 180; // this should force units to cross back and forth across the zone being patrolled _group setVariable["wpDir",_vector,true]; private _newWPPos = _pos getPos[_patrolRadius,_vector]; _wp setWaypointPosition [_newWPPos,0]; _wp setWaypointBehaviour "SAFE"; _wp setWaypointCompletionRadius 0; _wp setWaypointTimeout _wpTimeout; _wp setWaypointType "MOVE"; _group setCurrentWaypoint _wp; //diag_log format["_fnc_setNextWaypoint[antiSticking]: _group = %1 | _newPos = %2 | waypointStatements = %3",_group,_newWPPos,waypointStatements _wp]; }; // Move when no enemies are nearby if (isNull _nearestEnemy) then { // Use standard waypoint algorythms /* Have groups zig-zag back and forth their patrol area Setting more relaxed criteria for movement and rules of engagement */ private _vector = _wpDir + _arc + 180; // this should force units to cross back and forth across the zone being patrolled _group setVariable["wpDir",_vector,true]; _group setCombatMode "YELLOW"; private _newWPPos = _pos getPos[_patrolRadius,_vector]; _wp setWaypointPosition [_newWPPos,0]; _group setBehaviour "SAFE"; // no enemies detected so lets put the group in a relaxed mode _wp setWaypointBehaviour "SAFE"; _wp setWaypointCombatMode "YELLOW"; _wp setWaypointCompletionRadius 0; _wp setWaypointTimeout _wpTimeout; _group setCurrentWaypoint _wp; //diag_log format["_fnc_setNextWaypoint[no enemies]: _group = %1 | _newPos = %2 | waypointStatements = %3",_group,_newWPPos,waypointStatements _wp]; } else { // move toward nearest enemy using hunting logic // set mode to SAD / COMBAT /* _vector set to relative direction from leader to enemy +/- random adjustment of up to 33 degrees _distance can be up to one patrol radius outside of the normal perimeter closer to enemy _timout set to longer period when coupled with SAD behavior should cause interesting behaviors */ // [point1, point2] call BIS_fnc_relativeDirTo private _vector = ([_leader,_nearestEnemy] call BIS_fnc_relativeDirTo) + (random(33)*selectRandom[-1,1]); _group setVariable["wpDir",_vector]; private ["_huntDistance"]; if ((leader _group) distance _nearestEnemy > (_patrolRadius * 2)) then { if (((leader _group) distance _pos) > (2 * _patrolRadius)) then { _huntdistance = 0; } else { _huntDistance = _patrolRadius; }; } else { _huntDistance = ((leader _group) distance _nearestEnemy) / 2; }; private _newWPPos = _pos getPos[_huntDistance,_vector]; //diag_log format["_fnc_setextWaypoint: _pos = %1 | _patrolRadius = %5 | _newWPPos = %2 | _huntDistance = %3 | _vector = %4",_pos,_newWPPos,_huntDistance,_vector,_patrolRadius]; _wp setWaypointPosition [_newWPPos,0]; _wp setWaypointBehaviour"COMBAT"; _group setBehaviour "COMBAT"; _group setCombatMode "RED"; _wp setWaypointCombatMode "RED"; _wp setWaypointType "SAD"; _wp setWaypointTimeout[30,45,60]; _wp setWaypointCompletionRadius 0; _group setCurrentWaypoint _wp; // Assume the same waypoint statement will be available //diag_log format["_fnc_setNextWaypoint[enemies]t: _group = %1 | _newPos = %2 | _nearestEnemy = 54 | waypointStatements = %3",_group,_newWPPos,waypointStatements _wp,_nearestEnemy]; };