GMS_RC/@GMS/addons/GMS/Compiles/Groups/fn_setNextWaypoint.sqf
2023-09-23 10:05:31 -04:00

119 lines
5.4 KiB
Plaintext

// 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];
};