thy_ 168 Posted March 7, 2023 Hey. I'm coding something strongly based on it I need to make AI tanks hold positions as close as possible at some marker positions managed through Eden. My version is simpler and must be more accurate about synchronizing tank direction to the selected marker direction, with smooth movement when needed, differently when we use setDir, for example: But this is what happens (image down below): tanks got their horizontal azimuths misaligned when compared with their selected marker direction. Even my debug messages (systemChat) don't make sense to me hehe. Here, both functions that m THY_fnc_CSWR_move = { // This function makes the tank goes to a marker position. // Return nothing. params ["_grp"]; private ["_markers", "_mkrSelected", "_mkrPos", "_wp"]; sleep 1; _markers = ["hold_1", "hold_2", "hold_3", "hold_4"]; _mkrSelected = selectRandom _markers; _mkrPos = getMarkerPos _mkrSelected; // Adding waypoint: _wp = _grp addWaypoint [_mkrPos, 0]; _wp setWaypointType "HOLD"; _grp setCurrentWaypoint _wp; // Waiting the tank gets closer: waitUntil { sleep 3; (((leader _grp) distance _mkrPos) < 20) }; // Do rotation: [_mkrSelected, _grp] call THY_fnc_CSWR_hold; // Return: true; }; THY_fnc_CSWR_hold = { // This function makes the tank rotate on your own axis until it reach the same direction of a specific marker. // Return: nothing. params ["_mkr", "_grp"]; private ["_clockwise", "_vehicle", "_directionToHold", "_dirRelative"]; _clockwise = false; _vehicle = vehicle (leader _grp); _directionToHold = markerDir _mkr; _dirRelative = _directionToHold - (getDir _vehicle); // Force the vehicle doest start to turn when still moving (rare, but happens): _vehicle sendSimpleCommand "STOP"; // Wait the vehicle to brakes: sleep 1; // ------------------- NEED HELP HERE DOWN BELOW ------------------------------- if ( abs(_dirRelative) > 2 ) then { if ( _dirRelative > 0 ) then { if (_dirRelative < 180) then { _clockwise = true }; } else { if (_dirRelative < -180) then { _clockwise = true }; }; if (abs(_dirRelative) > 1) then { // Originally was: > 120 if (_clockwise) then { _vehicle sendSimpleCommand "RIGHT" } else { _vehicle sendSimpleCommand "LEFT" }; waitUntil { _dirRelative = _directionToHold - (getDir _vehicle); if ( _dirRelative > 180 ) then { _dirRelative = abs(360 - _dirRelative) }; if ( _dirRelative < -180 ) then { _dirRelative = abs(_dirRelative + 360) }; // Without this line, the tank will rotate on its axis non-stop: if ( abs(_dirRelative) <= 100 ) exitWith { true }; false; }; _vehicle sendSimpleCommand "STOPTURNING"; }; systemChat format ["[Desired %1º | Executed: %2º]", markerDir _mkr, getDir _vehicle]; // ------------------- NEED HELP HERE ABOVE ------------------------------- sleep 10; [_grp] spawn THY_fnc_CSWR_move; }; // Return: true; }; Demo: cswr-tanks-holding.stratis.zip = https://drive.google.com/file/d/1EcPiF2LFo149skR6GV63Vz6hhP7o6PlV/view?usp=share_link 1 Share this post Link to post Share on other sites
mrcurry 511 Posted March 7, 2023 6 hours ago, thy_ said: Hey. I'm coding something strongly based on it I need to make AI tanks hold positions as close as possible at some marker positions managed through Eden. My version is simpler and must be more accurate about synchronizing tank direction to the selected You can only get so accurate when you try and micromanage AI, keep that in mind. However from my short tests this below seems to work okay, ending up within 10-15 degrees of desired direction. Playing around with the value of _dirMargin can get you better results around 10-20 degrees seems to be best for the Slammer. On a few occasions when timeAcc was > 1x I noticed problems with infinite spinning but you can probably work that out from here if you need to support that. Should be fixed with updated code. This will, for what I think is obvious reasons, only work for tracked vehicles that can turn on the spot. A wheeled vehicle would involve a lot more back and forth (both in the literal and figurative sense). Should be MP compatible, the limiting factor here is "sendSimpleCommand" and it's locality requirements. They are unfortunately not listed on the BIKI. I would imagine executing where the vehicle and group is local is probably best. 🙂 This code completely replaces all code inside THY_fnc_CSWR_hold. Spoiler // This function makes the tank rotate on your own axis until it reach the same direction of a specific marker. // Return: nothing. params ["_mkr", "_grp"]; private _vehicle = vehicle (leader _grp); private _directionToHold = markerDir _mkr; // Force the vehicle doest start to turn when still moving (rare, but happens): _vehicle sendSimpleCommand "STOP"; // Wait the vehicle to brakes: sleep 1; private _dirMargin = 20; private ["_dirRelative", "_absDirRelative", "_turnDir"]; waitUntil { // Compute turn parameters _dirRelative = ( getDir _vehicle - _directionToHold + 180 ) % 360 - 180; // Deals with wrapping effects when turning past compass north. > 0 == turn left, < 0 == turn right _absDirRelative = abs _dirRelative; _turnDir = if( _absDirRelative > _dirMargin ) then { // Get normalized turn direction ( 1 = left, -1 = right) _dirRelative / _absDirRelative } else { // Target reach, no turning needed 0 }; // Get current status vehicleMoveInfo _vehicle params ["", "_turnInfo"]; //systemChat format ["TurnInfo: %1", _turnInfo]; switch (_turnDir) do { case 1: { // Target dir is to the left if( _turnInfo != "LEFT" ) then { _vehicle sendSimpleCommand "LEFT"; //systemChat "Left"; }; }; case -1: { // Target dir is to the right if( _turnInfo != "RIGHT" ) then { _vehicle sendSimpleCommand "RIGHT"; //systemChat "Right"; }; }; default { //systemChat "Stop turning"; _vehicle sendSimpleCommand "STOPTURNING"; // AI is too slow to react to STOPTURNING for our needs, so disable the drivers AIs movement to stop the turn immediately. driver _vehicle disableAI "MOVE"; }; }; // Exit out if we have finished turning or the vehicle is unable to move. ( _turnDir == 0 ) || !canMove _vehicle || fuel _vehicle == 0 }; waitUntil { vehicleMoveInfo _vehicle params ["", "_turnInfo"]; _turnInfo == "ABS" || _turnInfo == "NONE" }; // After small delay reenable driver's AI movement. driver _vehicle enableAI "MOVE"; systemChat format ["[Desired %1º | Executed: %2º]", markerDir _mkr, getDir _vehicle]; sleep 10; [_grp] spawn THY_fnc_CSWR_move; // Return: true; Share this post Link to post Share on other sites