From e9733b31e5a9e90ca2eec5b6cd4a1a377cf2c9c3 Mon Sep 17 00:00:00 2001 From: billw2012 Date: Mon, 3 Jun 2019 13:51:17 +0100 Subject: [PATCH 1/9] WIP test code --- Project_0.Altis/init.sqf | 67 ++++++++++++++++++++++++++++++++++++++-- 1 file changed, 65 insertions(+), 2 deletions(-) diff --git a/Project_0.Altis/init.sqf b/Project_0.Altis/init.sqf index 5f9729866..a46ffc208 100644 --- a/Project_0.Altis/init.sqf +++ b/Project_0.Altis/init.sqf @@ -2,6 +2,8 @@ #define OOP_DEBUG #include "OOP_Light\OOP_Light.h" +#define DEBUG + #ifndef _SQF_VM // No saving enableSaving [ false, false ]; // Saving disabled without autosave. @@ -24,10 +26,10 @@ if (!IS_SERVER) then { if(IS_SERVER) then { gGameModeName = switch (PROFILE_NAME) do { //case "Sparker": { "GameModeRandom" }; - //case "billw": { "EmptyGameMode" }; + case "billw": { "EmptyGameMode" }; case "Jeroen not": { "EmptyGameMode" }; case "Marvis": { "EmptyGameMode" }; - default { "CivilWarGameMode" }; + default { "EmptyGameMode" }; }; PUBLIC_VARIABLE "gGameModeName"; } else { @@ -43,4 +45,65 @@ CRITICAL_SECTION { serverInitDone = 1; PUBLIC_VARIABLE "serverInitDone"; +}; + + +fn_isect_update = { + params ["_obj"]; + + private _pos = getPos _obj; + private _dir = getDir _obj; + private _className = typeOf _obj; + + private _bb = [_className] call misc_fnc_boundingBoxReal; + private _bx = _bb select 1 select 0; //width + private _by = _bb select 1 select 1; //lenth + private _bz = _bb select 1 select 2; //height + + private _c = cos _dir; + private _s = sin _dir; + + + private _posASL = ATLTOASL _pos; + private _pos_0 = _posASL vectorAdd [_bx*_c + _by*_s, -_bx*_s + _by*_c, 1]; + private _pos_1 = _posASL vectorAdd [_bx*_c - _by*_s, -_bx*_s - _by*_c, 1]; + private _pos_2 = _posASL vectorAdd [-_bx*_c - _by*_s, _bx*_s - _by*_c, 1]; + private _pos_3 = _posASL vectorAdd [-_bx*_c + _by*_s, _bx*_s + _by*_c, 1]; + + private _posArray = [_pos_0, _pos_1, _pos_2, _pos_3]; + + private _color = [1,1,0,1]; + drawLine3D [ASLToAGL _pos_0, ASLToAGL _pos_2, _color]; + drawLine3D [ASLToAGL _pos_1, ASLToAGL _pos_3, _color]; + drawLine3D [ASLToAGL _pos_1, ASLToAGL _pos_2, _color]; + drawLine3D [ASLToAGL _pos_0, ASLToAGL _pos_3, _color]; + + //Find objects + //First check with line intersections + private _o = + lineIntersectsSurfaces [_pos_0, _pos_2, _obj, objNull, false]; //CF_FIRST_CONTACT + CF_ALL_OBJECTS + _o append lineIntersectsSurfaces [_pos_1, _pos_3, _obj, objNull, false]; //CF_FIRST_CONTACT + CF_ALL_OBJECTS + _o append lineIntersectsSurfaces [_pos_1, _pos_2, _obj, objNull, false]; //CF_FIRST_CONTACT + CF_ALL_OBJECTS + _o append lineIntersectsSurfaces [_pos_0, _pos_3, _obj, objNull, false]; //CF_FIRST_CONTACT + CF_ALL_OBJECTS + { + _x params ["_intersectPosASL", "_surfaceNormal", "_intersectObj", "_parentObject"]; + drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\BasicLook_ca.paa", [1,1,1,1], ASLToAGL _intersectPosASL, 1, 1, 45, "RayHit", 1, 0.05, "TahomaB"]; + } forEach _o; + + private _radius = sqrt (_bx*_bx + _by*_by); + private _o = nearestObjects [_pos, [], (_radius + 1) max 1.7, true] - [_obj]; + + // private _collisions = _o select { _x isKindOf "allVehicles" }; + { + drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\BasicLook_ca.paa", [1,0.5,0.5,1], ASLToAGL getPosASL _x, 1, 1, 45, typeOf _x, 1, 0.05, "TahomaB"]; + } forEach _o; +}; + +fn_do_thing = { + currObj = cursorObject; + currObj allowDamage false; + currObj enableSimulation false; + onEachFrame { + [currObj] call fn_isect_update; + }; }; \ No newline at end of file From 12ca8070865b350ca60a008362179058c8a1b4b5 Mon Sep 17 00:00:00 2001 From: billw2012 Date: Mon, 3 Jun 2019 23:37:57 +0100 Subject: [PATCH 2/9] Placeholder civ vehicle spawning. --- .../GameMode/CivilWar/CivilWarGameMode.sqf | 41 ++++++++++ .../Fuel/fn_fuel_addActionRefuel.sqf | 2 +- Project_0.Altis/Location/Location.sqf | 29 ++----- Project_0.Altis/Location/isPosSafe.sqf | 76 +++---------------- Project_0.Altis/init.sqf | 65 +--------------- 5 files changed, 60 insertions(+), 153 deletions(-) diff --git a/Project_0.Altis/GameMode/CivilWar/CivilWarGameMode.sqf b/Project_0.Altis/GameMode/CivilWar/CivilWarGameMode.sqf index 63359e203..a39de4530 100644 --- a/Project_0.Altis/GameMode/CivilWar/CivilWarGameMode.sqf +++ b/Project_0.Altis/GameMode/CivilWar/CivilWarGameMode.sqf @@ -17,6 +17,30 @@ gCityStateNames = [ "LIBERATED" ]; + +// no longer used array of civilian vehicles + +g_CivVehs = [ + "C_Hatchback_01_sport_F", + "C_Hatchback_01_F", + "C_Truck_02_box_F", + "C_Truck_02_fuel_F", + "C_Offroad_02_unarmed_F", + "C_Van_01_fuel_F", + "C_Truck_02_transport_F", + "C_Truck_02_covered_F", + "C_Offroad_01_F", + "C_Offroad_01_repair_F", + "C_Quadbike_01_F", + "C_SUV_01_F", + "C_Van_01_transport_F", + "C_Van_02_medevac_F", + "C_Van_02_vehicle_F", + "C_Van_02_service_F", + "C_Van_02_transport_F", + "C_Scooter_Transport_01_F" +]; + CLASS("CivilWarGameMode", "GameModeBase") VARIABLE("phase"); @@ -206,12 +230,14 @@ CLASS("CivilWarCityData", "") VARIABLE("state"); VARIABLE("instability"); VARIABLE("ambientMissions"); + VARIABLE("civVehicles"); METHOD("new") { params [P_THISOBJECT]; T_SETV("state", CITY_STATE_STABLE); T_SETV("instability", 0); T_SETV("ambientMissions", []); + T_SETV("civVehicles", []); } ENDMETHOD; METHOD("spawned") { @@ -253,6 +279,21 @@ CLASS("CivilWarCityData", "") // TODO: police is on player side }; }; + + // Spawn some cars + T_PRVAR(civVehicles); + private _maxCars = 3 + 10 * ln(0.01 * _radius + 1); + for "_i" from 0 to _maxCars do { + private _vehClass = selectRandom g_CivVehs; + private _randomPos = [[[_pos, _radius]],[]] call BIS_fnc_randomPos; + private _house = nearestBuilding _randomPos; + CALLSM("Location", "findSafePosOnRoad", [(getPos _house) ARG _vehClass]) + params ["_safePos", "_safeDir"]; + private _car = _vehClass createVehicle [0,0,0]; //6ms + _car setdir _safeDir; + _car setpos _safePos; + _civVehicles pushBack _car; + }; } ENDMETHOD; METHOD("despawned") { diff --git a/Project_0.Altis/JeroenArsenal/Fuel/fn_fuel_addActionRefuel.sqf b/Project_0.Altis/JeroenArsenal/Fuel/fn_fuel_addActionRefuel.sqf index 5e6003070..7b22e0eae 100644 --- a/Project_0.Altis/JeroenArsenal/Fuel/fn_fuel_addActionRefuel.sqf +++ b/Project_0.Altis/JeroenArsenal/Fuel/fn_fuel_addActionRefuel.sqf @@ -20,7 +20,7 @@ params["_vehicle","_fuelCargoCapacity",["_fuelCargo",0]]; //check if it already has a action -if !isnil(_vehicle getVariable "refuelAction_id")exitWith{diag_log ("JN_fuel already init for object: "+str _vehicle)}; +if (!isnil{ _vehicle getVariable "refuelAction_id" }) exitWith{diag_log ("JN_fuel already init for object: "+str _vehicle)}; pr _id = _vehicle addaction [ "place holder", diff --git a/Project_0.Altis/Location/Location.sqf b/Project_0.Altis/Location/Location.sqf index e85a04e05..8b2c9c111 100644 --- a/Project_0.Altis/Location/Location.sqf +++ b/Project_0.Altis/Location/Location.sqf @@ -530,33 +530,16 @@ CLASS("Location", "MessageReceiverEx") private _rct = roadsConnectedTo _road; // TODO: we can preprocess spawn locations better than this probably. // Need a connected road (this is guaranteed probably?) - if (count _rct > 0 and - // Avoid spawning on a person or another car - {count (nearestObjects [getPos _road, ["LandVehicle", "Man"], 10]) == 0} and + if (count _rct == 2 and // Avoid spawning too close to a junction - {{ count (roadsConnectedTo _x) > 2} count ((getPos _road) nearRoads 10) == 0}) then { // We better don't use terminal road pieces - + {{ count (roadsConnectedTo _x) > 2} count ((getPos _road) nearRoads 15) == 0}) then { // Check position if it's safe private _dir = _road getDir (_rct select 0); - // Get Z component of ATL height from two nearest road pieces - // private _z0 = (getPosASL (_rct select 0)) select 2; - // private _z1 = (getPosASL (_rct select 1)) select 2; - // private _posRoad = getPosASL _road; - //_posRoad set [2, 0.5*(_z0 + _z1)]; - //_posRoad = ASLToATL _posRoad; - private _posRoad = getPos _road; - - private _foundSafePos = []; - for "_offs" from 2 to 8 step 2 do { - // Find offset position away from center of road - private _spawnPos = [_posRoad, _offs, _dir + 90] call BIS_Fnc_relPos; - if(!CALLSM3("Location", "isPosSafe", _spawnPos, _dir, _className)) exitWith {}; - _foundSafePos = _spawnPos; - }; - //diag_log format ["--- road: %1, pos atl: %2", _road, getPosATL _road]; - if (!(_foundSafePos isEqualTo [])) then { - _return = [_foundSafePos, _dir]; + private _width = [_road, 1, 8] call misc_fnc_getRoadWidth; + private _pos = [getPos _road, _width - 3, _dir + 90] call BIS_Fnc_relPos; + if(CALLSM3("Location", "isPosSafe", _pos, _dir, _className)) then { + _return = [_pos, _dir]; _found = true; }; }; diff --git a/Project_0.Altis/Location/isPosSafe.sqf b/Project_0.Altis/Location/isPosSafe.sqf index c5446f10a..208fec6ee 100644 --- a/Project_0.Altis/Location/isPosSafe.sqf +++ b/Project_0.Altis/Location/isPosSafe.sqf @@ -82,77 +82,21 @@ diag_log format ["--- Positions ATL: %1", [[ASLTOATL _pos_0], [ASLTOATL _pos_1], diag_log format [" Pos 0...3 AGL: %1", [ASLToAGL _pos_0, ASLToAGL _pos_1, ASLToAGL _pos_2, ASLToAGL _pos_3]]; #endif +private _o = + lineIntersectsSurfaces [_pos_0, _pos_2, objNull, objNull, false]; +_o append lineIntersectsSurfaces [_pos_1, _pos_3, objNull, objNull, false]; +_o append lineIntersectsSurfaces [_pos_1, _pos_2, objNull, objNull, false]; +_o append lineIntersectsSurfaces [_pos_0, _pos_3, objNull, objNull, false]; - -//Find objects -//First check with line intersections -private _o = lineIntersectsObjs [_pos_0, _pos_2, objNull, objNull, false, 16+32]; //CF_FIRST_CONTACT + CF_ALL_OBJECTS -_o append lineIntersectsObjs [_pos_1, _pos_3, objNull, objNull, false, 16+32]; //CF_FIRST_CONTACT + CF_ALL_OBJECTS -_o append lineIntersectsObjs [_pos_1, _pos_2, objNull, objNull, false, 16+32]; //CF_FIRST_CONTACT + CF_ALL_OBJECTS -_o append lineIntersectsObjs [_pos_0, _pos_3, objNull, objNull, false, 16+32]; //CF_FIRST_CONTACT + CF_ALL_OBJECTS -private _i = 0; -private _c = count _o; -private _good = true; -private _t = ""; //type of object -//private _checkHumans = (_vehType isKindOf ["man", configFile >> "cfgVehicles"]); //Ignore humans if _vehType is not a human - -#ifdef DEBUG -diag_log format [" fn_isPosSafe: line intersections: %1", _o]; -#endif - -while {_i < _c} do -{ - private _obj = _o select _i; - //diag_log format ["type: %1", _t]; - if ( (_obj isKindOf "allVehicles") && - (!(_obj isKindOf "Man")) ) exitWith { - _good = false; - }; - _i = _i + 1; -}; - -if(!_good) exitWith +if(count _o > 0) exitWith { #ifdef DEBUG - diag_log " Line intersects with a vehicle"; + diag_log " Line intersects with a surface"; #endif false }; -//Check for objects in sphere -private _posCheck = _pos; //_pos vectorAdd [0, 0, _bz]; - -//Test: create arrow -/* -private _arrow = "Sign_Arrow_F" createVehicle _pos; -_arrow setPosATL _posCheck; -*/ - -//diag_log format ["%1 %2", _posCheck, _bx]; private _radius = sqrt (_bx*_bx + _by*_by); -_o = nearestObjects [_posCheck, ["allVehicles"], (_radius + 1) max 1.7, true]; -//player setPos _pos; - -#ifdef DEBUG -diag_log format ["fn_isPosSafe: near objects %1: %2", _bx, _o]; -#endif - -_i = 0; -_c = count _o; -private _t = ""; //type of object -while {_i < _c && _good} do { - private _obj = _o select _i; - if (!(_obj isKindOf "Man")) then { - _good = false; - #ifdef DEBUG - diag_log " Found a vehicle inside sphere!"; - #endif - }; - _i = _i + 1; -}; - -#ifdef DEBUG -diag_log format [" Position safe: %1", _good]; -#endif - -_good +// TODO: expand the class set here? +private _o = nearestObjects [_pos, ["allVehicles"], (_radius + 1) max 1.7, true]; +count _o == 0 diff --git a/Project_0.Altis/init.sqf b/Project_0.Altis/init.sqf index a46ffc208..4c51ada67 100644 --- a/Project_0.Altis/init.sqf +++ b/Project_0.Altis/init.sqf @@ -26,10 +26,10 @@ if (!IS_SERVER) then { if(IS_SERVER) then { gGameModeName = switch (PROFILE_NAME) do { //case "Sparker": { "GameModeRandom" }; - case "billw": { "EmptyGameMode" }; + //case "billw": { "EmptyGameMode" }; case "Jeroen not": { "EmptyGameMode" }; case "Marvis": { "EmptyGameMode" }; - default { "EmptyGameMode" }; + default { "CivilWarGameMode" }; }; PUBLIC_VARIABLE "gGameModeName"; } else { @@ -46,64 +46,3 @@ CRITICAL_SECTION { serverInitDone = 1; PUBLIC_VARIABLE "serverInitDone"; }; - - -fn_isect_update = { - params ["_obj"]; - - private _pos = getPos _obj; - private _dir = getDir _obj; - private _className = typeOf _obj; - - private _bb = [_className] call misc_fnc_boundingBoxReal; - private _bx = _bb select 1 select 0; //width - private _by = _bb select 1 select 1; //lenth - private _bz = _bb select 1 select 2; //height - - private _c = cos _dir; - private _s = sin _dir; - - - private _posASL = ATLTOASL _pos; - private _pos_0 = _posASL vectorAdd [_bx*_c + _by*_s, -_bx*_s + _by*_c, 1]; - private _pos_1 = _posASL vectorAdd [_bx*_c - _by*_s, -_bx*_s - _by*_c, 1]; - private _pos_2 = _posASL vectorAdd [-_bx*_c - _by*_s, _bx*_s - _by*_c, 1]; - private _pos_3 = _posASL vectorAdd [-_bx*_c + _by*_s, _bx*_s + _by*_c, 1]; - - private _posArray = [_pos_0, _pos_1, _pos_2, _pos_3]; - - private _color = [1,1,0,1]; - drawLine3D [ASLToAGL _pos_0, ASLToAGL _pos_2, _color]; - drawLine3D [ASLToAGL _pos_1, ASLToAGL _pos_3, _color]; - drawLine3D [ASLToAGL _pos_1, ASLToAGL _pos_2, _color]; - drawLine3D [ASLToAGL _pos_0, ASLToAGL _pos_3, _color]; - - //Find objects - //First check with line intersections - private _o = - lineIntersectsSurfaces [_pos_0, _pos_2, _obj, objNull, false]; //CF_FIRST_CONTACT + CF_ALL_OBJECTS - _o append lineIntersectsSurfaces [_pos_1, _pos_3, _obj, objNull, false]; //CF_FIRST_CONTACT + CF_ALL_OBJECTS - _o append lineIntersectsSurfaces [_pos_1, _pos_2, _obj, objNull, false]; //CF_FIRST_CONTACT + CF_ALL_OBJECTS - _o append lineIntersectsSurfaces [_pos_0, _pos_3, _obj, objNull, false]; //CF_FIRST_CONTACT + CF_ALL_OBJECTS - { - _x params ["_intersectPosASL", "_surfaceNormal", "_intersectObj", "_parentObject"]; - drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\BasicLook_ca.paa", [1,1,1,1], ASLToAGL _intersectPosASL, 1, 1, 45, "RayHit", 1, 0.05, "TahomaB"]; - } forEach _o; - - private _radius = sqrt (_bx*_bx + _by*_by); - private _o = nearestObjects [_pos, [], (_radius + 1) max 1.7, true] - [_obj]; - - // private _collisions = _o select { _x isKindOf "allVehicles" }; - { - drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\BasicLook_ca.paa", [1,0.5,0.5,1], ASLToAGL getPosASL _x, 1, 1, 45, typeOf _x, 1, 0.05, "TahomaB"]; - } forEach _o; -}; - -fn_do_thing = { - currObj = cursorObject; - currObj allowDamage false; - currObj enableSimulation false; - onEachFrame { - [currObj] call fn_isect_update; - }; -}; \ No newline at end of file From 547a032fb510a1214c86fe83aa785028ffde58dd Mon Sep 17 00:00:00 2001 From: billw2012 Date: Tue, 4 Jun 2019 13:50:07 +0100 Subject: [PATCH 3/9] More WIP civilian vehicle spawning --- .../GameMode/CivilWar/CivilWarGameMode.sqf | 41 ----- Project_0.Altis/GameMode/GameModeBase.sqf | 17 ++- Project_0.Altis/Garrison/Garrison.sqf | 2 - Project_0.Altis/Garrison/updateSpawnState.sqf | 6 +- Project_0.Altis/Location/Location.sqf | 2 +- Project_0.Altis/Location/getSpawnPos.sqf | 7 +- Project_0.Altis/Templates/CIVILIAN.sqf | 143 ++++++++++++++++++ Project_0.Altis/initModules.sqf | 1 + 8 files changed, 171 insertions(+), 48 deletions(-) create mode 100644 Project_0.Altis/Templates/CIVILIAN.sqf diff --git a/Project_0.Altis/GameMode/CivilWar/CivilWarGameMode.sqf b/Project_0.Altis/GameMode/CivilWar/CivilWarGameMode.sqf index a39de4530..63359e203 100644 --- a/Project_0.Altis/GameMode/CivilWar/CivilWarGameMode.sqf +++ b/Project_0.Altis/GameMode/CivilWar/CivilWarGameMode.sqf @@ -17,30 +17,6 @@ gCityStateNames = [ "LIBERATED" ]; - -// no longer used array of civilian vehicles - -g_CivVehs = [ - "C_Hatchback_01_sport_F", - "C_Hatchback_01_F", - "C_Truck_02_box_F", - "C_Truck_02_fuel_F", - "C_Offroad_02_unarmed_F", - "C_Van_01_fuel_F", - "C_Truck_02_transport_F", - "C_Truck_02_covered_F", - "C_Offroad_01_F", - "C_Offroad_01_repair_F", - "C_Quadbike_01_F", - "C_SUV_01_F", - "C_Van_01_transport_F", - "C_Van_02_medevac_F", - "C_Van_02_vehicle_F", - "C_Van_02_service_F", - "C_Van_02_transport_F", - "C_Scooter_Transport_01_F" -]; - CLASS("CivilWarGameMode", "GameModeBase") VARIABLE("phase"); @@ -230,14 +206,12 @@ CLASS("CivilWarCityData", "") VARIABLE("state"); VARIABLE("instability"); VARIABLE("ambientMissions"); - VARIABLE("civVehicles"); METHOD("new") { params [P_THISOBJECT]; T_SETV("state", CITY_STATE_STABLE); T_SETV("instability", 0); T_SETV("ambientMissions", []); - T_SETV("civVehicles", []); } ENDMETHOD; METHOD("spawned") { @@ -279,21 +253,6 @@ CLASS("CivilWarCityData", "") // TODO: police is on player side }; }; - - // Spawn some cars - T_PRVAR(civVehicles); - private _maxCars = 3 + 10 * ln(0.01 * _radius + 1); - for "_i" from 0 to _maxCars do { - private _vehClass = selectRandom g_CivVehs; - private _randomPos = [[[_pos, _radius]],[]] call BIS_fnc_randomPos; - private _house = nearestBuilding _randomPos; - CALLSM("Location", "findSafePosOnRoad", [(getPos _house) ARG _vehClass]) - params ["_safePos", "_safeDir"]; - private _car = _vehClass createVehicle [0,0,0]; //6ms - _car setdir _safeDir; - _car setpos _safePos; - _civVehicles pushBack _car; - }; } ENDMETHOD; METHOD("despawned") { diff --git a/Project_0.Altis/GameMode/GameModeBase.sqf b/Project_0.Altis/GameMode/GameModeBase.sqf index fb8530ea4..66b370e8e 100644 --- a/Project_0.Altis/GameMode/GameModeBase.sqf +++ b/Project_0.Altis/GameMode/GameModeBase.sqf @@ -158,8 +158,23 @@ CLASS("GameModeBase", "") }; }; - // Send intel to commanders private _type = GETV(_loc, "type"); + private _radius = GETV(_loc, "boundingRadius"); + + // Create vehicles in civilian area for player to steal + if(_type == LOCATION_TYPE_CITY) then { + private _gar = NEW("Garrison", [CIVILIAN]); + private _maxCars = 3 + 10 * ln(0.01 * _radius + 1); + for "_i" from 0 to _maxCars do { + private _newUnit = NEW("Unit", [tCIVILIAN ARG T_VEH ARG T_VEH_DEFAULT ARG -1 ARG ""]); + CALLM(_gar, "addUnit", [_newUnit]); + }; + CALLM1(_gar, "setLocation", _loc); + CALLM1(_loc, "registerGarrison", _gar); + CALLM0(_gar, "activate"); + }; + + // Send intel to commanders { private _sideCommander = GETV(_x, "side"); if (_sideCommander != WEST) then { // Enemies are smart diff --git a/Project_0.Altis/Garrison/Garrison.sqf b/Project_0.Altis/Garrison/Garrison.sqf index fa9a320c2..e3be70025 100644 --- a/Project_0.Altis/Garrison/Garrison.sqf +++ b/Project_0.Altis/Garrison/Garrison.sqf @@ -1771,7 +1771,6 @@ CLASS("Garrison", "MessageReceiverEx"); if(IS_GARRISON_DESTROYED(_thisObject)) exitWith { WARN_GARRISON_DESTROYED; __MUTEX_UNLOCK; - +T_EFF_null }; // Call handleUnitKilled of the group of this unit @@ -1823,7 +1822,6 @@ CLASS("Garrison", "MessageReceiverEx"); if(IS_GARRISON_DESTROYED(_thisObject)) exitWith { WARN_GARRISON_DESTROYED; __MUTEX_UNLOCK; - +T_EFF_null }; // Get garrison of the unit that entered the vehicle diff --git a/Project_0.Altis/Garrison/updateSpawnState.sqf b/Project_0.Altis/Garrison/updateSpawnState.sqf index 91de21660..84d913ff0 100644 --- a/Project_0.Altis/Garrison/updateSpawnState.sqf +++ b/Project_0.Altis/Garrison/updateSpawnState.sqf @@ -31,7 +31,11 @@ pr _thisPos = if (_loc == "") then { pr _speedMax = 200; // Get distances to all garrisons of other sides -pr _garrisonDist = CALL_STATIC_METHOD("Garrison", "getAllActive", [[] ARG [_side]]) apply {CALLM(_x, "getPos", []) distance _thisPos}; +pr _garrisonDist = if(_side != CIVILIAN) then { + CALL_STATIC_METHOD("Garrison", "getAllActive", [[] ARG [_side ARG CIVILIAN]]) apply {CALLM(_x, "getPos", []) distance _thisPos} + } else { + [] + }; pr _dstMin = if (count _garrisonDist > 0) then {selectMin _garrisonDist} else {_dstSpawnMax}; // Double check unit distances as well if(_dstMin >= _dstSpawnMax) then { diff --git a/Project_0.Altis/Location/Location.sqf b/Project_0.Altis/Location/Location.sqf index 8b2c9c111..70dbd3964 100644 --- a/Project_0.Altis/Location/Location.sqf +++ b/Project_0.Altis/Location/Location.sqf @@ -568,7 +568,7 @@ CLASS("Location", "MessageReceiverEx") Returns: [_pos, _dir] */ STATIC_METHOD("findSafeSpawnPos") { - params ["_thisObject", ["_className", "", [""]], ["_startPos", [], [[]]]]; + params ["_thisClass", ["_className", "", [""]], ["_startPos", [], [[]]]]; private _found = false; private _searchRadius = 50; diff --git a/Project_0.Altis/Location/getSpawnPos.sqf b/Project_0.Altis/Location/getSpawnPos.sqf index e3d68e1d5..25e7bba93 100644 --- a/Project_0.Altis/Location/getSpawnPos.sqf +++ b/Project_0.Altis/Location/getSpawnPos.sqf @@ -136,9 +136,12 @@ if(_found) then {//If the spawn position has been found _return = [ ( _locPos vectorAdd [-_r + (random (2*_r)), -_r + (random (2*_r)), 0] ), 0]; OOP_WARNING_MSG("[Location::getSpawnPos] Warning: spawn position not found for unit: %1. Returning default position.", [_catID ARG _subcatID ARG _groupType]); } else { - // Try to find a safe position on a road for this vehicle + // Try to find a random safe position on a road for this vehicle private _locPos = GET_VAR(_thisObject, "pos"); - _return = CALLSM2("Location", "findSafePosOnRoad", _locPos, _className); + private _locRadius = GET_VAR(_thisObject, "boundingRadius"); + private _testPos = _locPos vectorAdd [_locPos, random [0, 0, _locRadius], random 360] call BIS_fnc_relPos; + // [[[_locPos, _locRadius]],[]] call BIS_fnc_randomPos; + _return = CALLSM2("Location", "findSafePosOnRoad", _testPos, _className); }; }; diff --git a/Project_0.Altis/Templates/CIVILIAN.sqf b/Project_0.Altis/Templates/CIVILIAN.sqf new file mode 100644 index 000000000..08a88bbe6 --- /dev/null +++ b/Project_0.Altis/Templates/CIVILIAN.sqf @@ -0,0 +1,143 @@ +/* +POLICE templates for ARMA III +*/ + +// //==== Infantry ==== +// _inf = []; +// _inf set [T_INF_SIZE-1, nil]; //Make an array full of nil +// _inf set [T_INF_DEFAULT, ["B_GEN_Soldier_F"]]; //Default infantry if nothing is found + +// _inf set [T_INF_SL, ["B_Captain_Dwarden_F"]]; +// _inf set [T_INF_TL, ["B_Captain_Dwarden_F"]]; +// _inf set [T_INF_officer, ["B_GEN_Commander_F"]]; +// _inf set [T_INF_GL, ["B_GEN_Soldier_F"]]; +// _inf set [T_INF_rifleman, ["B_GEN_Soldier_F"]]; +// _inf set [T_INF_marksman, ["B_GEN_Soldier_F"]]; +// _inf set [T_INF_sniper, ["B_GEN_Soldier_F"]]; +// _inf set [T_INF_spotter, ["B_GEN_Soldier_F"]]; +// _inf set [T_INF_exp, ["B_GEN_Soldier_F"]]; +// _inf set [T_INF_ammo, ["B_GEN_Soldier_F"]]; +// _inf set [T_INF_LAT, ["B_GEN_Soldier_F"]]; +// _inf set [T_INF_AT, ["B_GEN_Soldier_F"]]; +// _inf set [T_INF_AA, ["B_GEN_Soldier_F"]]; +// _inf set [T_INF_LMG, ["B_GEN_Soldier_F"]]; +// _inf set [T_INF_HMG, ["B_GEN_Soldier_F"]]; +// _inf set [T_INF_medic, ["B_GEN_Soldier_F"]]; +// _inf set [T_INF_engineer, ["B_GEN_Soldier_F"]]; +// _inf set [T_INF_crew, ["B_GEN_Soldier_F"]]; +// _inf set [T_INF_crew_heli, ["B_GEN_Soldier_F"]]; +// _inf set [T_INF_pilot, ["B_GEN_Soldier_F"]]; +// _inf set [T_INF_pilot_heli, ["B_GEN_Soldier_F"]]; +// _inf set [T_INF_survivor, ["B_GEN_Soldier_F"]]; +// _inf set [T_INF_unarmed, ["B_GEN_Soldier_F"]]; + +//==== Vehicles ==== +_veh = []; +_veh set [T_VEH_SIZE-1, nil]; +_veh set [T_VEH_DEFAULT, [ + "C_Hatchback_01_sport_F", + "C_Hatchback_01_F", + "C_Truck_02_box_F", + "C_Truck_02_fuel_F", + "C_Offroad_02_unarmed_F", + "C_Van_01_fuel_F", + "C_Truck_02_transport_F", + "C_Truck_02_covered_F", + "C_Offroad_01_F", + "C_Offroad_01_repair_F", + "C_Quadbike_01_F", + "C_SUV_01_F", + "C_Van_01_transport_F", + "C_Van_02_medevac_F", + "C_Van_02_vehicle_F", + "C_Van_02_service_F", + "C_Van_02_transport_F"]]; + +// _veh set [T_VEH_car_unarmed, ["B_MRAP_01_F"]]; +// _veh set [T_VEH_car_armed, ["B_MRAP_01_hmg_F"]]; +// _veh set [T_VEH_MRAP_unarmed, ["B_MRAP_01_F"]]; +// _veh set [T_VEH_MRAP_HMG, ["B_MRAP_01_hmg_F"]]; +// _veh set [T_VEH_MRAP_GMG, ["B_MRAP_01_gmg_F"]]; +// _veh set [T_VEH_IFV, ["B_APC_Wheeled_01_cannon_F"]]; //Marshal IFV +// _veh set [T_VEH_APC, ["B_APC_Tracked_01_rcws_F"]]; //Panther +// _veh set [T_VEH_MBT, ["B_MBT_01_cannon_F", "B_MBT_01_TUSK_F"]]; +// _veh set [T_VEH_MRLS, ["B_MBT_01_mlrs_F"]]; +// _veh set [T_VEH_SPA, ["B_MBT_01_arty_F"]]; +// _veh set [T_VEH_SPAA, ["B_APC_Tracked_01_AA_F"]]; +// _veh set [T_VEH_stat_HMG_high, ["B_HMG_01_high_F"]]; +// _veh set [T_VEH_stat_GMG_high, ["B_GMG_01_high_F"]]; +// _veh set [T_VEH_stat_HMG_low, ["B_HMG_01_F"]]; +// _veh set [T_VEH_stat_GMG_low, ["B_GMG_01_F"]]; +// _veh set [T_VEH_stat_AA, ["B_static_AA_F"]]; +// _veh set [T_VEH_stat_AT, ["B_static_AT_F"]]; +// _veh set [T_VEH_stat_mortar_light, ["B_Mortar_01_F"]]; +// //_veh set [T_VEH_stat_mortar_heavy, ["B_Mortar_01_F"]]; +// _veh set [T_VEH_heli_light, ["B_Heli_Light_01_F"]]; +// _veh set [T_VEH_heli_heavy, ["B_Heli_Transport_01_F"]]; +// _veh set [T_VEH_heli_cargo, ["B_Heli_Transport_03_unarmed_F"]]; +// _veh set [T_VEH_heli_attack, ["B_Heli_Attack_01_dynamicLoadout_F"]]; +// _veh set [T_VEH_plane_attack, ["B_Plane_CAS_01_dynamicLoadout_F"]]; +// _veh set [T_VEH_plane_fighter , ["B_Plane_Fighter_01_F"]]; +// //_veh set [T_VEH_plane_cargo, [" "]]; +// //_veh set [T_VEH_plane_unarmed , [" "]]; +// //_veh set [T_VEH_plane_VTOL, [" "]]; +// _veh set [T_VEH_boat_unarmed, ["B_Boat_Transport_01_F"]]; +// _veh set [T_VEH_boat_armed, ["B_Boat_Armed_01_minigun_F"]]; +// _veh set [T_VEH_personal, ["B_GEN_Offroad_01_gen_F"]]; +// _veh set [T_VEH_truck_inf, ["B_GEN_Van_02_transport_F"]]; +// _veh set [T_VEH_truck_cargo, ["B_GEN_Van_02_vehicle_F"]]; +// _veh set [T_VEH_truck_ammo, ["B_Truck_01_ammo_F"]]; +// _veh set [T_VEH_truck_repair, ["B_Truck_01_Repair_F"]]; +// _veh set [T_VEH_truck_medical , ["B_Truck_01_medical_F"]]; +// _veh set [T_VEH_truck_fuel, ["B_Truck_01_fuel_F"]]; +// _veh set [T_VEH_submarine, ["B_SDV_01_F"]]; + + +// //==== Drones ==== +// _drone = []; +// _drone set [T_DRONE_SIZE-1, nil]; +// _drone set [T_DRONE_DEFAULT, ["O_UAV_01_F"]]; + +// _drone set [T_DRONE_UGV_unarmed, ["O_UGV_01_F"]]; +// _drone set [T_DRONE_UGV_armed, ["O_UGV_01_rcws_F"]]; +// _drone set [T_DRONE_plane_attack, ["O_UAV_02_dynamicLoadout_F"]]; +// //_drone set [T_DRONE_plane_unarmed, ["O_UAV_02_dynamicLoadout_F"]]; +// //_drone set [T_DRONE_heli_attack, ["O_T_UAV_04_CAS_F"]]; +// _drone set [T_DRONE_quadcopter, ["O_UAV_01_F"]]; +// _drone set [T_DRONE_designator, ["O_Static_Designator_02_F"]]; +// _drone set [T_DRONE_stat_HMG_low, ["O_HMG_01_A_F"]]; +// _drone set [T_DRONE_stat_GMG_low, ["O_GMG_01_A_F"]]; +// //_drone set [T_DRONE_stat_AA, ["O_SAM_System_04_F"]]; + + +// //==== Groups ==== +// _group = []; +// _group set [T_GROUP_SIZE-1, nil]; +// _group set [T_GROUP_DEFAULT, [configfile >> "CfgGroups" >> "East" >> "BLU_F" >> "Infantry" >> "Bus_InfSquad"]]; + +// _group set [T_GROUP_inf_AA_team, [configfile >> "CfgGroups" >> "East" >> "OPF_F" >> "Infantry" >> "OIA_InfTeam_AA"]]; +// _group set [T_GROUP_inf_AT_team, [configfile >> "CfgGroups" >> "East" >> "OPF_F" >> "Infantry" >> "OIA_InfTeam_AT"]]; +// _group set [T_GROUP_inf_rifle_squad, [configfile >> "CfgGroups" >> "East" >> "OPF_F" >> "Infantry" >> "OIA_InfSquad"]]; +// _group set [T_GROUP_inf_assault_squad, [configfile >> "CfgGroups" >> "East" >> "OPF_F" >> "Infantry" >> "OIA_InfAssault"]]; +// _group set [T_GROUP_inf_weapons_squad, [configfile >> "CfgGroups" >> "East" >> "OPF_F" >> "Infantry" >> "OIA_InfSquad_Weapons"]]; +// _group set [T_GROUP_inf_fire_team, [configfile >> "CfgGroups" >> "East" >> "OPF_F" >> "Infantry" >> "OIA_InfTeam"]]; +// _group set [T_GROUP_inf_recon_patrol, [configfile >> "CfgGroups" >> "East" >> "OPF_F" >> "Infantry" >> "OI_reconPatrol"]]; +// _group set [T_GROUP_inf_recon_sentry, [configfile >> "CfgGroups" >> "East" >> "OPF_F" >> "Infantry" >> "OI_reconSentry"]]; +// _group set [T_GROUP_inf_recon_squad, [configfile >> "CfgGroups" >> "East" >> "OPF_F" >> "Infantry" >> "OIA_ReconSquad"]]; +// _group set [T_GROUP_inf_recon_team, [configfile >> "CfgGroups" >> "East" >> "OPF_F" >> "Infantry" >> "OI_reconTeam"]]; +// _group set [T_GROUP_inf_sentry, [configfile >> "CfgGroups" >> "East" >> "OPF_F" >> "Infantry" >> "OIA_InfSentry"]]; +// _group set [T_GROUP_inf_sniper_team, [configfile >> "CfgGroups" >> "East" >> "OPF_F" >> "Infantry" >> "OI_SniperTeam"]]; + + +//==== Set arrays ==== +_array = []; + +_array set [T_SIZE-1, nil]; //Make an array having the size equal to the number of categories first + +_array set [T_INF, []]; +_array set [T_VEH, _veh]; +_array set [T_DRONE, []]; +_array set [T_GROUP, []]; + + +_array diff --git a/Project_0.Altis/initModules.sqf b/Project_0.Altis/initModules.sqf index 69081a08c..fcf8ce1b4 100644 --- a/Project_0.Altis/initModules.sqf +++ b/Project_0.Altis/initModules.sqf @@ -24,6 +24,7 @@ tCSAT = call compile preprocessFileLineNumbers "Templates\CSAT.sqf"; tAAF = call compile preprocessFileLineNumbers "Templates\AAF.sqf"; tGUERILLA = call compile preprocessFileLineNumbers "Templates\GUERILLA.sqf"; tPOLICE = call compile preprocessFileLineNumbers "Templates\POLICE.sqf"; +tCIVILIAN = call compile preprocessFileLineNumbers "Templates\CIVILIAN.sqf"; // Initialize GameModes From 5bbceaec60c675d567a3571e2371436e8956bcdb Mon Sep 17 00:00:00 2001 From: billw2012 Date: Tue, 4 Jun 2019 23:26:44 +0100 Subject: [PATCH 4/9] Civ vehicle spawning wip --- Project_0.Altis/GameMode/GameModeBase.sqf | 6 +++--- Project_0.Altis/Location/Location.sqf | 4 ++-- Project_0.Altis/Location/getSpawnPos.sqf | 2 +- Project_0.Altis/init.sqf | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Project_0.Altis/GameMode/GameModeBase.sqf b/Project_0.Altis/GameMode/GameModeBase.sqf index 66b370e8e..0bfef0e43 100644 --- a/Project_0.Altis/GameMode/GameModeBase.sqf +++ b/Project_0.Altis/GameMode/GameModeBase.sqf @@ -145,7 +145,6 @@ CLASS("GameModeBase", "") private _cmdr = CALL_STATIC_METHOD("AICommander", "getCommanderAIOfSide", [_side]); if(!IS_NULL_OBJECT(_cmdr)) then { - OOP_DEBUG_MSG("founc cmdr %1 for loc %2", [_cmdr ARG _loc]); CALLM(_cmdr, "registerLocation", [_loc]); private _gar = T_CALLM("initGarrison", [_loc ARG _side]); @@ -153,7 +152,7 @@ CLASS("GameModeBase", "") OOP_DEBUG_MSG("Creating garrison %1 for location %2 (%3)", [_gar ARG _loc ARG _side]); CALLM1(_gar, "setLocation", _loc); - CALLM1(_loc, "registerGarrison", _gar); + // CALLM1(_loc, "registerGarrison", _gar); CALLM0(_gar, "activate"); }; }; @@ -169,8 +168,9 @@ CLASS("GameModeBase", "") private _newUnit = NEW("Unit", [tCIVILIAN ARG T_VEH ARG T_VEH_DEFAULT ARG -1 ARG ""]); CALLM(_gar, "addUnit", [_newUnit]); }; + CALLM1(_gar, "setPos", CALLM0(_loc, "getPos")); CALLM1(_gar, "setLocation", _loc); - CALLM1(_loc, "registerGarrison", _gar); + // CALLM1(_loc, "registerGarrison", _gar); CALLM0(_gar, "activate"); }; diff --git a/Project_0.Altis/Location/Location.sqf b/Project_0.Altis/Location/Location.sqf index 70dbd3964..70977fed0 100644 --- a/Project_0.Altis/Location/Location.sqf +++ b/Project_0.Altis/Location/Location.sqf @@ -572,8 +572,8 @@ CLASS("Location", "MessageReceiverEx") private _found = false; private _searchRadius = 50; - pr _posAndDir = []; - while {!_found} do { + pr _posAndDir = [_startPos, 0]; + while {!_found and _searchRadius < 2000} do { for "_i" from 0 to 16 do { pr _pos = _startPos vectorAdd [-_searchRadius + random(2*_searchRadius), -_searchRadius + random(2*_searchRadius), 0]; if (CALLSM3("Location", "isPosSafe", _pos, 0, _className) && ! (surfaceIsWater _pos)) exitWith { diff --git a/Project_0.Altis/Location/getSpawnPos.sqf b/Project_0.Altis/Location/getSpawnPos.sqf index 25e7bba93..5e9ccb8f3 100644 --- a/Project_0.Altis/Location/getSpawnPos.sqf +++ b/Project_0.Altis/Location/getSpawnPos.sqf @@ -139,7 +139,7 @@ if(_found) then {//If the spawn position has been found // Try to find a random safe position on a road for this vehicle private _locPos = GET_VAR(_thisObject, "pos"); private _locRadius = GET_VAR(_thisObject, "boundingRadius"); - private _testPos = _locPos vectorAdd [_locPos, random [0, 0, _locRadius], random 360] call BIS_fnc_relPos; + private _testPos = _locPos vectorAdd ([_locPos, random [0, 0, _locRadius], random 360] call BIS_fnc_relPos); // [[[_locPos, _locRadius]],[]] call BIS_fnc_randomPos; _return = CALLSM2("Location", "findSafePosOnRoad", _testPos, _className); }; diff --git a/Project_0.Altis/init.sqf b/Project_0.Altis/init.sqf index a83a7f89b..89e517051 100644 --- a/Project_0.Altis/init.sqf +++ b/Project_0.Altis/init.sqf @@ -28,7 +28,7 @@ if (!IS_SERVER) then { if(IS_SERVER) then { gGameModeName = switch (PROFILE_NAME) do { case "Sparker": { "GameModeRandom" }; - case "billw": { "RedVsGreenGameMode" }; + case "billw": { "CivilWarGameMode" }; case "Jeroen not": { "EmptyGameMode" }; case "Marvis": { "StatusQuoGameMode" }; default { "CivilWarGameMode" }; From f197b9cab6d8ede5e2250e34e970cb8ce8a5b1d8 Mon Sep 17 00:00:00 2001 From: billw2012 Date: Wed, 5 Jun 2019 13:45:29 +0100 Subject: [PATCH 5/9] Civ vehicle spawning improvements --- Project_0.Altis/GameMode/GameModeBase.sqf | 2 +- Project_0.Altis/Garrison/Garrison.sqf | 5 ++- Project_0.Altis/Location/getSpawnPos.sqf | 3 +- .../Misc/Math/fn_polygonCollision.sqf | 43 +++++++++++++++++++ Project_0.Altis/Misc/initFunctions.sqf | 4 +- Project_0.Altis/Templates/CIVILIAN.sqf | 2 +- Project_0.Altis/init.sqf | 2 +- 7 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 Project_0.Altis/Misc/Math/fn_polygonCollision.sqf diff --git a/Project_0.Altis/GameMode/GameModeBase.sqf b/Project_0.Altis/GameMode/GameModeBase.sqf index 66b370e8e..0c446a43c 100644 --- a/Project_0.Altis/GameMode/GameModeBase.sqf +++ b/Project_0.Altis/GameMode/GameModeBase.sqf @@ -164,7 +164,7 @@ CLASS("GameModeBase", "") // Create vehicles in civilian area for player to steal if(_type == LOCATION_TYPE_CITY) then { private _gar = NEW("Garrison", [CIVILIAN]); - private _maxCars = 3 + 10 * ln(0.01 * _radius + 1); + private _maxCars = 3 max (15 min (0.02 * _radius)); for "_i" from 0 to _maxCars do { private _newUnit = NEW("Unit", [tCIVILIAN ARG T_VEH ARG T_VEH_DEFAULT ARG -1 ARG ""]); CALLM(_gar, "addUnit", [_newUnit]); diff --git a/Project_0.Altis/Garrison/Garrison.sqf b/Project_0.Altis/Garrison/Garrison.sqf index e3be70025..3df84eda3 100644 --- a/Project_0.Altis/Garrison/Garrison.sqf +++ b/Project_0.Altis/Garrison/Garrison.sqf @@ -333,9 +333,10 @@ CLASS("Garrison", "MessageReceiverEx"); // Check spawn state if active if (T_GETV("active")) then { - T_CALLM("updateSpawnState", []); + T_CALLM("updateSpawnState", []); + // If we are empty except for vehicles then we must abandon them - if(T_CALLM("isOnlyEmptyVehicles", [])) then { + if(T_GETV("side") != CIVILIAN and {T_CALLM("isOnlyEmptyVehicles", [])}) then { OOP_INFO_MSG("This garrison only has vehicles left, abandoning them", []); // Move the units to the abandoned vehicle garrison CALLM(gGarrisonAbandonedVehicles, "addGarrison", [_thisObject]); diff --git a/Project_0.Altis/Location/getSpawnPos.sqf b/Project_0.Altis/Location/getSpawnPos.sqf index 25e7bba93..4ee2d75fb 100644 --- a/Project_0.Altis/Location/getSpawnPos.sqf +++ b/Project_0.Altis/Location/getSpawnPos.sqf @@ -139,7 +139,8 @@ if(_found) then {//If the spawn position has been found // Try to find a random safe position on a road for this vehicle private _locPos = GET_VAR(_thisObject, "pos"); private _locRadius = GET_VAR(_thisObject, "boundingRadius"); - private _testPos = _locPos vectorAdd [_locPos, random [0, 0, _locRadius], random 360] call BIS_fnc_relPos; + private _testPos = [_locPos, _locRadius min random [0, 0, _locRadius*2], random 360] call BIS_fnc_relPos; + // DUMP_CALLSTACK; // [[[_locPos, _locRadius]],[]] call BIS_fnc_randomPos; _return = CALLSM2("Location", "findSafePosOnRoad", _testPos, _className); }; diff --git a/Project_0.Altis/Misc/Math/fn_polygonCollision.sqf b/Project_0.Altis/Misc/Math/fn_polygonCollision.sqf new file mode 100644 index 000000000..eeeb292e1 --- /dev/null +++ b/Project_0.Altis/Misc/Math/fn_polygonCollision.sqf @@ -0,0 +1,43 @@ +// See https://gist.github.com/nyorain/dc5af42c6e83f7ac6d831a2cfd5fbece + +params ["_a", "_b"]; + +private _result = false; +for "_i" from 0 to (count _a - 1) do +{ + // calculate the normal vector of the current edge + // this is the axis will we check in this loop + private _current = _a select _i; + private _next = _a select ((_i + 1) % count _a); + private _edge = [_next#0 - _current#0, _next#1 - _current#1]; + private _axis = [-_edge#1, _edge#0]; + private _aMaxProj = + + // loop over all vertices of both polygons and project them + // onto the axis. We are only interested in max/min projections + private _aMaxProj = -1000000; + private _aMinProj = 1000000; + private _bMaxProj = -1000000; + private _bMinProj = 1000000; + + { + private _proj = _axis#0 * _x#0 + _axis#1 * _x#1; + _aMinProj = _aMinProj min _proj; + _aMaxProj = _aMaxProj max _proj; + } forEach _a; + + { + private _proj = _axis#0 * _x#0 + _axis#1 * _x#1; + _bMinProj = _bMinProj min _proj; + _bMaxProj = _bMaxProj max _proj; + } forEach _b; + + // now check if the intervals the both polygons projected on the + // axis overlap. If they don't, we have found an axis of separation and + // the given polygons cannot overlap + if(_aMaxProj < _bMinProj or _aMinProj > _bMaxProj) exitWith { + _result = true; + }; +}; + +_result \ No newline at end of file diff --git a/Project_0.Altis/Misc/initFunctions.sqf b/Project_0.Altis/Misc/initFunctions.sqf index 6f8beb1ab..e76a910b4 100644 --- a/Project_0.Altis/Misc/initFunctions.sqf +++ b/Project_0.Altis/Misc/initFunctions.sqf @@ -13,4 +13,6 @@ misc_fnc_mapDrawLineLocal = compile preprocessFileLineNumbers "Misc\fn_mapDrawLi misc_fnc_dateToNumber = compile preprocessFileLineNumbers "Misc\fn_dateToNumber.sqf"; misc_fnc_getRoadDirection = compile preprocessFileLineNumbers "Misc\fn_getRoadDirection.sqf"; -misc_fnc_getRoadWidth = compile preprocessFileLineNumbers "Misc\fn_getRoadWidth.sqf"; \ No newline at end of file +misc_fnc_getRoadWidth = compile preprocessFileLineNumbers "Misc\fn_getRoadWidth.sqf"; + +misc_fnc_polygonCollision = compile preprocessFileLineNumbers "Misc\Math\fn_polygonCollision.sqf"; \ No newline at end of file diff --git a/Project_0.Altis/Templates/CIVILIAN.sqf b/Project_0.Altis/Templates/CIVILIAN.sqf index 08a88bbe6..b91dca81a 100644 --- a/Project_0.Altis/Templates/CIVILIAN.sqf +++ b/Project_0.Altis/Templates/CIVILIAN.sqf @@ -35,7 +35,7 @@ POLICE templates for ARMA III _veh = []; _veh set [T_VEH_SIZE-1, nil]; _veh set [T_VEH_DEFAULT, [ - "C_Hatchback_01_sport_F", + "C_Hatchback_01_sport_F", "C_Hatchback_01_F", "C_Truck_02_box_F", "C_Truck_02_fuel_F", diff --git a/Project_0.Altis/init.sqf b/Project_0.Altis/init.sqf index a83a7f89b..89e517051 100644 --- a/Project_0.Altis/init.sqf +++ b/Project_0.Altis/init.sqf @@ -28,7 +28,7 @@ if (!IS_SERVER) then { if(IS_SERVER) then { gGameModeName = switch (PROFILE_NAME) do { case "Sparker": { "GameModeRandom" }; - case "billw": { "RedVsGreenGameMode" }; + case "billw": { "CivilWarGameMode" }; case "Jeroen not": { "EmptyGameMode" }; case "Marvis": { "StatusQuoGameMode" }; default { "CivilWarGameMode" }; From 40bc818a790d7c99f97609b5aa277c17267e29d0 Mon Sep 17 00:00:00 2001 From: billw2012 Date: Wed, 5 Jun 2019 22:41:46 +0100 Subject: [PATCH 6/9] Civ vehicle spawning improvement --- Project_0.Altis/GameMode/GameModeBase.sqf | 7 +- Project_0.Altis/Location/isPosSafe.sqf | 175 +++++++++++------- .../Misc/Math/fn_polygonCollision.sqf | 72 +++---- Project_0.Altis/init.sqf | 141 +++++++++++++- 4 files changed, 285 insertions(+), 110 deletions(-) diff --git a/Project_0.Altis/GameMode/GameModeBase.sqf b/Project_0.Altis/GameMode/GameModeBase.sqf index 4107a472a..8710560bf 100644 --- a/Project_0.Altis/GameMode/GameModeBase.sqf +++ b/Project_0.Altis/GameMode/GameModeBase.sqf @@ -152,7 +152,7 @@ CLASS("GameModeBase", "") OOP_DEBUG_MSG("Creating garrison %1 for location %2 (%3)", [_gar ARG _loc ARG _side]); CALLM1(_gar, "setLocation", _loc); - // CALLM1(_loc, "registerGarrison", _gar); + CALLM1(_loc, "registerGarrison", _gar); CALLM0(_gar, "activate"); }; }; @@ -168,9 +168,8 @@ CLASS("GameModeBase", "") private _newUnit = NEW("Unit", [tCIVILIAN ARG T_VEH ARG T_VEH_DEFAULT ARG -1 ARG ""]); CALLM(_gar, "addUnit", [_newUnit]); }; - CALLM1(_gar, "setPos", CALLM0(_loc, "getPos")); CALLM1(_gar, "setLocation", _loc); - // CALLM1(_loc, "registerGarrison", _gar); + CALLM1(_loc, "registerGarrison", _gar); CALLM0(_gar, "activate"); }; @@ -187,7 +186,7 @@ CLASS("GameModeBase", "") }; }; } forEach gCommanders; - } forEach GET_STATIC_VAR("Location", "all"); + } forEach GET_STATIC_VAR("Location", "alwl"); } ENDMETHOD; // ------------------------------------------------------------------------- diff --git a/Project_0.Altis/Location/isPosSafe.sqf b/Project_0.Altis/Location/isPosSafe.sqf index 208fec6ee..ae45067a3 100644 --- a/Project_0.Altis/Location/isPosSafe.sqf +++ b/Project_0.Altis/Location/isPosSafe.sqf @@ -17,6 +17,25 @@ Author: Sparker 29.07.2018 //#define DEBUG +pr0_fn_getGlobalRectAndSize = { + params [["_pos", [], [[]]], ["_dir", 0, [0]], ["_bbox", [], [[]]] ]; + + private _bx = _bbox select 1 select 0; //width + private _by = _bbox select 1 select 1; //length + private _bz = _bbox select 1 select 2; //height + + private _c = cos _dir; + private _s = sin _dir; + + private _posASL = ATLTOASL _pos; + private _pos_0 = _posASL vectorAdd [_bx*_c + _by*_s, -_bx*_s + _by*_c, 0]; + private _pos_1 = _posASL vectorAdd [_bx*_c - _by*_s, -_bx*_s - _by*_c, 0]; + private _pos_2 = _posASL vectorAdd [-_bx*_c - _by*_s, _bx*_s - _by*_c, 0]; + private _pos_3 = _posASL vectorAdd [-_bx*_c + _by*_s, _bx*_s + _by*_c, 0]; + private _rect = [_pos_0, _pos_1, _pos_2, _pos_3]; + [_rect, [_bx, _by, _bz]] +}; + params [ ["_thisClass", "", [""]], ["_pos", [], [[]]], ["_dir", 0, [0]], ["_className", "", [""]] ]; // Bail if Z is below surface, as it happens with positions of bridges @@ -31,72 +50,94 @@ if (_pos#2 < -0.3) exitWith { false }; -private _bb = [_className] call misc_fnc_boundingBoxReal; -private _bx = _bb select 1 select 0; //width -private _by = _bb select 1 select 1; //lenth -private _bz = _bb select 1 select 2; //height - -#ifdef DEBUG -diag_log format [" Classname: %1, bounding box: %2", _className, _bb]; -#endif - -private _c = cos _dir; -private _s = sin _dir; - -/* -Get positions of corners of bounding box and rotate them _dir degrees. -Positions are: -3 0 - \ / - O - / \ -2 1 -*/ - -private _posASL = ATLTOASL _pos; -private _pos_0 = _posASL vectorAdd [_bx*_c + _by*_s, -_bx*_s + _by*_c, 1]; -private _pos_1 = _posASL vectorAdd [_bx*_c - _by*_s, -_bx*_s - _by*_c, 1]; -private _pos_2 = _posASL vectorAdd [-_bx*_c - _by*_s, _bx*_s - _by*_c, 1]; -private _pos_3 = _posASL vectorAdd [-_bx*_c + _by*_s, _bx*_s + _by*_c, 1]; - - -// Debug drawing -#ifdef DEBUG -diag_log format ["--- Positions ATL: %1", [[ASLTOATL _pos_0], [ASLTOATL _pos_1], [ASLTOATL _pos_2], [ASLTOATL _pos_3]]]; -{ - createVehicle ["Sign_Arrow_F", ASLTOATL _x, [], 0, "CAN_COLLIDE"]; -} forEach [_pos_0, _pos_1, _pos_2, _pos_3]; - - -[{ - (_this select 0) params ["_pos_0", "_pos_1", "_pos_2", "_pos_3"]; - private _color = [1,1,0,1]; - drawLine3D [_pos_0, _pos_2, _color]; - drawLine3D [_pos_1, _pos_3, _color]; - drawLine3D [_pos_1, _pos_2, _color]; - drawLine3D [_pos_0, _pos_3, _color]; -}, -0, -[ASLToAGL _pos_0, ASLToAGL _pos_1, ASLToAGL _pos_2, ASLToAGL _pos_3]] call CBA_fnc_addPerFrameHandler; - -diag_log format [" Pos 0...3 AGL: %1", [ASLToAGL _pos_0, ASLToAGL _pos_1, ASLToAGL _pos_2, ASLToAGL _pos_3]]; -#endif - -private _o = - lineIntersectsSurfaces [_pos_0, _pos_2, objNull, objNull, false]; -_o append lineIntersectsSurfaces [_pos_1, _pos_3, objNull, objNull, false]; -_o append lineIntersectsSurfaces [_pos_1, _pos_2, objNull, objNull, false]; -_o append lineIntersectsSurfaces [_pos_0, _pos_3, objNull, objNull, false]; - -if(count _o > 0) exitWith -{ - #ifdef DEBUG - diag_log " Line intersects with a surface"; - #endif - false -}; +// private _bb = [_className] call misc_fnc_boundingBoxReal; +// private _bx = _bb select 1 select 0; //width +// private _by = _bb select 1 select 1; //lenth +// private _bz = _bb select 1 select 2; //height + +// #ifdef DEBUG +// diag_log format [" Classname: %1, bounding box: %2", _className, _bb]; +// #endif + +// private _c = cos _dir; +// private _s = sin _dir; + +// /* +// Get positions of corners of bounding box and rotate them _dir degrees. +// Positions are: +// 3 0 +// \ / +// O +// / \ +// 2 1 +// */ + +// private _posASL = ATLTOASL _pos; +// private _pos_0 = _posASL vectorAdd [_bx*_c + _by*_s, -_bx*_s + _by*_c, 1]; +// private _pos_1 = _posASL vectorAdd [_bx*_c - _by*_s, -_bx*_s - _by*_c, 1]; +// private _pos_2 = _posASL vectorAdd [-_bx*_c - _by*_s, _bx*_s - _by*_c, 1]; +// private _pos_3 = _posASL vectorAdd [-_bx*_c + _by*_s, _bx*_s + _by*_c, 1]; + +//private _rect = [_pos_0, _pos_1, _pos_2, _pos_3]; + +// // Debug drawing +// #ifdef DEBUG +// diag_log format ["--- Positions ATL: %1", [[ASLTOATL _pos_0], [ASLTOATL _pos_1], [ASLTOATL _pos_2], [ASLTOATL _pos_3]]]; +// { +// createVehicle ["Sign_Arrow_F", ASLTOATL _x, [], 0, "CAN_COLLIDE"]; +// } forEach [_pos_0, _pos_1, _pos_2, _pos_3]; + + +// [{ +// (_this select 0) params ["_pos_0", "_pos_1", "_pos_2", "_pos_3"]; +// private _color = [1,1,0,1]; +// drawLine3D [_pos_0, _pos_2, _color]; +// drawLine3D [_pos_1, _pos_3, _color]; +// drawLine3D [_pos_1, _pos_2, _color]; +// drawLine3D [_pos_0, _pos_3, _color]; +// }, +// 0, +// [ASLToAGL _pos_0, ASLToAGL _pos_1, ASLToAGL _pos_2, ASLToAGL _pos_3]] call CBA_fnc_addPerFrameHandler; + +// diag_log format [" Pos 0...3 AGL: %1", [ASLToAGL _pos_0, ASLToAGL _pos_1, ASLToAGL _pos_2, ASLToAGL _pos_3]]; +// #endif + +([ + _pos, _dir, + [_className] call misc_fnc_boundingBoxReal +] call pr0_fn_getGlobalRectAndSize) params ["_rect3D", "_size"]; + +// private _o = +// lineIntersectsSurfaces [_rect3D#0, _rect3D#2, objNull, objNull, false]; +// _o append lineIntersectsSurfaces [_rect3D#1, _rect3D#3, objNull, objNull, false]; +// _o append lineIntersectsSurfaces [_rect3D#1, _rect3D#2, objNull, objNull, false]; +// _o append lineIntersectsSurfaces [_rect3D#0, _rect3D#3, objNull, objNull, false]; + +// if(count _o > 0) exitWith +// { +// #ifdef DEBUG +// diag_log " Line intersects with a surface"; +// #endif +// false +// }; + +//private _radius = sqrt (_size#0*_size#0 + _size#1*_size#1); -private _radius = sqrt (_bx*_bx + _by*_by); // TODO: expand the class set here? -private _o = nearestObjects [_pos, ["allVehicles"], (_radius + 1) max 1.7, true]; -count _o == 0 +private _o = nearestObjects [_pos, [], 15, true] - (_pos nearRoads 15); + +_o findIf { + //private _className = typeOf _x; + private _bbox = 0 boundingBoxReal _x; + // if(_className != "") then { + // [_className] call misc_fnc_boundingBoxReal + // } else { + // boundingBoxReal _x + // }; + ([getPos _x, getDir _x, _bbox] call pr0_fn_getGlobalRectAndSize) params ["_oRect3D", "_oSize"]; + if(_oSize#2 > 0.3) then { + [_rect3D, _oRect3D] call misc_fnc_polygonCollision + } else { + false + } +} == -1 diff --git a/Project_0.Altis/Misc/Math/fn_polygonCollision.sqf b/Project_0.Altis/Misc/Math/fn_polygonCollision.sqf index eeeb292e1..6e462460d 100644 --- a/Project_0.Altis/Misc/Math/fn_polygonCollision.sqf +++ b/Project_0.Altis/Misc/Math/fn_polygonCollision.sqf @@ -1,43 +1,45 @@ // See https://gist.github.com/nyorain/dc5af42c6e83f7ac6d831a2cfd5fbece +private _fn_separatedPolys = { + params ["_a", "_b"]; + private _result = false; + for "_i" from 0 to (count _a - 1) do + { + // calculate the normal vector of the current edge + // this is the axis will we check in this loop + private _current = _a select _i; + private _next = _a select ((_i + 1) % count _a); + private _edge = [_next#0 - _current#0, _next#1 - _current#1]; + private _axis = [-(_edge#1), _edge#0]; -params ["_a", "_b"]; - -private _result = false; -for "_i" from 0 to (count _a - 1) do -{ - // calculate the normal vector of the current edge - // this is the axis will we check in this loop - private _current = _a select _i; - private _next = _a select ((_i + 1) % count _a); - private _edge = [_next#0 - _current#0, _next#1 - _current#1]; - private _axis = [-_edge#1, _edge#0]; - private _aMaxProj = - - // loop over all vertices of both polygons and project them - // onto the axis. We are only interested in max/min projections - private _aMaxProj = -1000000; - private _aMinProj = 1000000; - private _bMaxProj = -1000000; - private _bMinProj = 1000000; + // loop over all vertices of both polygons and project them + // onto the axis. We are only interested in max/min projections + private _aMaxProj = -1000000; + private _aMinProj = 1000000; + private _bMaxProj = -1000000; + private _bMinProj = 1000000; - { - private _proj = _axis#0 * _x#0 + _axis#1 * _x#1; - _aMinProj = _aMinProj min _proj; - _aMaxProj = _aMaxProj max _proj; - } forEach _a; + { + private _proj = _axis#0 * _x#0 + _axis#1 * _x#1; + _aMinProj = _aMinProj min _proj; + _aMaxProj = _aMaxProj max _proj; + } forEach _a; - { - private _proj = _axis#0 * _x#0 + _axis#1 * _x#1; - _bMinProj = _bMinProj min _proj; - _bMaxProj = _bMaxProj max _proj; - } forEach _b; + { + private _proj = _axis#0 * _x#0 + _axis#1 * _x#1; + _bMinProj = _bMinProj min _proj; + _bMaxProj = _bMaxProj max _proj; + } forEach _b; - // now check if the intervals the both polygons projected on the - // axis overlap. If they don't, we have found an axis of separation and - // the given polygons cannot overlap - if(_aMaxProj < _bMinProj or _aMinProj > _bMaxProj) exitWith { - _result = true; + // now check if the intervals the both polygons projected on the + // axis overlap. If they don't, we have found an axis of separation and + // the given polygons cannot overlap + if(_aMaxProj < _bMinProj or _aMinProj > _bMaxProj) exitWith { + _result = true; + }; }; + _result }; -_result \ No newline at end of file +params ["_a", "_b"]; + +!(([_a, _b] call _fn_separatedPolys) or {([_b, _a] call _fn_separatedPolys)}) \ No newline at end of file diff --git a/Project_0.Altis/init.sqf b/Project_0.Altis/init.sqf index 89e517051..e6d6cee73 100644 --- a/Project_0.Altis/init.sqf +++ b/Project_0.Altis/init.sqf @@ -27,11 +27,11 @@ if (!IS_SERVER) then { // if(true) exitWith {}; // Keep it here in case we want to not start the actual mission but to test some other code if(IS_SERVER) then { gGameModeName = switch (PROFILE_NAME) do { - case "Sparker": { "GameModeRandom" }; - case "billw": { "CivilWarGameMode" }; + case "Sparker": { "GameModeRandom" }; + case "billw": { "CivilWarGameMode" }; case "Jeroen not": { "EmptyGameMode" }; - case "Marvis": { "StatusQuoGameMode" }; - default { "CivilWarGameMode" }; + case "Marvis": { "StatusQuoGameMode" }; + default { "CivilWarGameMode" }; }; PUBLIC_VARIABLE "gGameModeName"; } else { @@ -48,3 +48,136 @@ CRITICAL_SECTION { serverInitDone = 1; PUBLIC_VARIABLE "serverInitDone"; }; + +// pr0_fn_getGlobalRectAndSize = { +// params [["_pos", [], [[]]], ["_dir", 0, [0]], ["_bbox", [], [[]]] ]; + +// private _bx = _bbox select 1 select 0; //width +// private _by = _bbox select 1 select 1; //length +// private _bz = _bbox select 1 select 2; //height + +// private _c = cos _dir; +// private _s = sin _dir; + +// private _posASL = ATLTOASL _pos; +// private _pos_0 = _posASL vectorAdd [_bx*_c + _by*_s, -_bx*_s + _by*_c, 0]; +// private _pos_1 = _posASL vectorAdd [_bx*_c - _by*_s, -_bx*_s - _by*_c, 0]; +// private _pos_2 = _posASL vectorAdd [-_bx*_c - _by*_s, _bx*_s - _by*_c, 0]; +// private _pos_3 = _posASL vectorAdd [-_bx*_c + _by*_s, _bx*_s + _by*_c, 0]; + +// private _color = [1,1,0,1]; +// drawLine3D [ASLToAGL _pos_0, ASLToAGL _pos_1, _color]; +// drawLine3D [ASLToAGL _pos_1, ASLToAGL _pos_2, _color]; +// drawLine3D [ASLToAGL _pos_2, ASLToAGL _pos_3, _color]; +// drawLine3D [ASLToAGL _pos_3, ASLToAGL _pos_0, _color]; +// private _rect = [_pos_0, _pos_1, _pos_2, _pos_3]; +// [_rect, [_bx, _by, _bz]] +// }; + +// fn_isect_update = +// { +// params ["_obj"]; + +// private _pos = getPos _obj; +// private _dir = getDir _obj; +// private _className = typeOf _obj; + +// ([ +// _pos, _dir, +// [_className] call misc_fnc_boundingBoxReal +// ] call pr0_fn_getGlobalRectAndSize) params ["_rect3D", "_size"]; + +// private _o = +// lineIntersectsSurfaces [_rect3D#0, _rect3D#2, _obj, objNull, false]; +// _o append lineIntersectsSurfaces [_rect3D#1, _rect3D#3, _obj, objNull, false]; +// _o append lineIntersectsSurfaces [_rect3D#1, _rect3D#2, _obj, objNull, false]; +// _o append lineIntersectsSurfaces [_rect3D#0, _rect3D#3, _obj, objNull, false]; + +// { +// _x params ["_intersectPosASL", "_surfaceNormal", "_intersectObj", "_parentObject"]; +// drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\BasicLook_ca.paa", [1,1,1,1], ASLToAGL _intersectPosASL, 1, 1, 45, "RayHit", 1, 0.05, "TahomaB"]; +// } forEach _o; + +// private _radius = sqrt (_size#0*_size#0 + _size#1*_size#1); +// private _o = nearestObjects [_pos, [], 15, true] - [_obj] - (_pos nearRoads 15); + +// { +// private _className = typeOf _x; +// private _bbox = +// //if(_className != "") then { +// // [_className] call misc_fnc_boundingBoxReal +// //} else { +// 0 boundingBoxReal _x; +// //}; +// ([getPos _x, getDir _x, _bbox] call pr0_fn_getGlobalRectAndSize) params ["_oRect3D", "_oSize"]; +// if(_oSize#2 > 0.3) then { +// if([_rect3D, _oRect3D] call misc_fnc_polygonCollision) then { +// drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\BasicLook_ca.paa", [1,0.5,0.5,1], ASLToAGL getPosASL _x, 1, 1, 45, +// format["%1 (%2) %3", str _x, typeOf _x, _oSize], 1, 0.05, "TahomaB"]; +// }; +// }; +// } forEach _o; +// }; + + +// // fn_isect_update = { +// // params ["_obj"]; + +// // private _pos = getPos _obj; +// // private _dir = getDir _obj; +// // private _className = typeOf _obj; + +// // private _bb = [_className] call misc_fnc_boundingBoxReal; +// // private _bx = _bb select 1 select 0; //width +// // private _by = _bb select 1 select 1; //lenth +// // private _bz = _bb select 1 select 2; //height + +// // private _c = cos _dir; +// // private _s = sin _dir; + + +// // private _posASL = ATLTOASL _pos; +// // private _pos_0 = _posASL vectorAdd [_bx*_c + _by*_s, -_bx*_s + _by*_c, 1]; +// // private _pos_1 = _posASL vectorAdd [_bx*_c - _by*_s, -_bx*_s - _by*_c, 1]; +// // private _pos_2 = _posASL vectorAdd [-_bx*_c - _by*_s, _bx*_s - _by*_c, 1]; +// // private _pos_3 = _posASL vectorAdd [-_bx*_c + _by*_s, _bx*_s + _by*_c, 1]; + +// // private _posArray = [_pos_0, _pos_1, _pos_2, _pos_3]; + +// // private _color = [1,1,0,1]; +// // drawLine3D [ASLToAGL _pos_0, ASLToAGL _pos_2, _color]; +// // drawLine3D [ASLToAGL _pos_1, ASLToAGL _pos_3, _color]; +// // drawLine3D [ASLToAGL _pos_1, ASLToAGL _pos_2, _color]; +// // drawLine3D [ASLToAGL _pos_0, ASLToAGL _pos_3, _color]; + +// // //Find objects +// // //First check with line intersections +// // private _o = +// // lineIntersectsSurfaces [_pos_0, _pos_2, _obj, objNull, false]; //CF_FIRST_CONTACT + CF_ALL_OBJECTS +// // _o append lineIntersectsSurfaces [_pos_1, _pos_3, _obj, objNull, false]; //CF_FIRST_CONTACT + CF_ALL_OBJECTS +// // _o append lineIntersectsSurfaces [_pos_1, _pos_2, _obj, objNull, false]; //CF_FIRST_CONTACT + CF_ALL_OBJECTS +// // _o append lineIntersectsSurfaces [_pos_0, _pos_3, _obj, objNull, false]; //CF_FIRST_CONTACT + CF_ALL_OBJECTS +// // { +// // _x params ["_intersectPosASL", "_surfaceNormal", "_intersectObj", "_parentObject"]; +// // drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\BasicLook_ca.paa", [1,1,1,1], ASLToAGL _intersectPosASL, 1, 1, 45, "RayHit", 1, 0.05, "TahomaB"]; +// // } forEach _o; + +// // private _radius = sqrt (_bx*_bx + _by*_by); +// // private _o = nearestObjects [_pos, [], (_radius + 1) max 1.7, true] - [_obj]; + +// // // private _collisions = _o select { _x isKindOf "allVehicles" }; +// // { +// // drawIcon3D ["\a3\ui_f\data\gui\cfg\hints\BasicLook_ca.paa", [1,0.5,0.5,1], ASLToAGL getPosASL _x, 1, 1, 45, typeOf _x, 1, 0.05, "TahomaB"]; +// // } forEach _o; +// // }; + +// fn_do_thing = { +// currObj = cursorObject; +// currObj allowDamage false; +// currObj enableSimulation false; +// onEachFrame { +// [currObj] call fn_isect_update; +// }; +// }; + +// player addAction ["dd", fn_do_thing]; \ No newline at end of file From 0c583d868417c20653f0207e92321f5aa4c8d89e Mon Sep 17 00:00:00 2001 From: billw2012 Date: Thu, 6 Jun 2019 13:46:07 +0100 Subject: [PATCH 7/9] Add random weights for vehicle classes --- Project_0.Altis/GameMode/GameModeBase.sqf | 2 +- Project_0.Altis/Location/isPosSafe.sqf | 4 +++ Project_0.Altis/Templates/CIVILIAN.sqf | 31 ++++++++++++++++--- Project_0.Altis/Templates/fn_selectRandom.sqf | 27 +++++++++++++++- Project_0.Altis/Templates/initCategories.sqf | 1 + 5 files changed, 58 insertions(+), 7 deletions(-) diff --git a/Project_0.Altis/GameMode/GameModeBase.sqf b/Project_0.Altis/GameMode/GameModeBase.sqf index 8710560bf..0053ed3c4 100644 --- a/Project_0.Altis/GameMode/GameModeBase.sqf +++ b/Project_0.Altis/GameMode/GameModeBase.sqf @@ -186,7 +186,7 @@ CLASS("GameModeBase", "") }; }; } forEach gCommanders; - } forEach GET_STATIC_VAR("Location", "alwl"); + } forEach GET_STATIC_VAR("Location", "all"); } ENDMETHOD; // ------------------------------------------------------------------------- diff --git a/Project_0.Altis/Location/isPosSafe.sqf b/Project_0.Altis/Location/isPosSafe.sqf index ae45067a3..29fa5e7a6 100644 --- a/Project_0.Altis/Location/isPosSafe.sqf +++ b/Project_0.Altis/Location/isPosSafe.sqf @@ -128,7 +128,11 @@ private _o = nearestObjects [_pos, [], 15, true] - (_pos nearRoads 15); _o findIf { //private _className = typeOf _x; + #ifndef _SQF_VM private _bbox = 0 boundingBoxReal _x; + #else + private _bbox = [[0,0,0],[1,1,1],1]; + #endif // if(_className != "") then { // [_className] call misc_fnc_boundingBoxReal // } else { diff --git a/Project_0.Altis/Templates/CIVILIAN.sqf b/Project_0.Altis/Templates/CIVILIAN.sqf index b91dca81a..7fa4838e9 100644 --- a/Project_0.Altis/Templates/CIVILIAN.sqf +++ b/Project_0.Altis/Templates/CIVILIAN.sqf @@ -34,7 +34,7 @@ POLICE templates for ARMA III //==== Vehicles ==== _veh = []; _veh set [T_VEH_SIZE-1, nil]; -_veh set [T_VEH_DEFAULT, [ +_veh set [T_VEH_default, [ "C_Hatchback_01_sport_F", "C_Hatchback_01_F", "C_Truck_02_box_F", @@ -51,8 +51,29 @@ _veh set [T_VEH_DEFAULT, [ "C_Van_02_medevac_F", "C_Van_02_vehicle_F", "C_Van_02_service_F", - "C_Van_02_transport_F"]]; - + "C_Van_02_transport_F" +]]; +_vehWeights = []; +_vehWeights set [T_VEH_SIZE-1, nil]; +_vehWeights set [T_VEH_default, [ + 5, /* "C_Hatchback_01_sport_F" */ + 20, /* "C_Hatchback_01_F" */ + 3, /* "C_Truck_02_box_F" */ + 0.1, /* "C_Truck_02_fuel_F" */ + 10, /* "C_Offroad_02_unarmed_F" */ + 0.1, /* "C_Van_01_fuel_F" */ + 3, /* "C_Truck_02_transport_F" */ + 3, /* "C_Truck_02_covered_F" */ + 5, /* "C_Offroad_01_F" */ + 0.1, /* "C_Offroad_01_repair_F" */ + 1, /* "C_Quadbike_01_F" */ + 3, /* "C_SUV_01_F" */ + 1, /* "C_Van_01_transport_F" */ + 1, /* "C_Van_02_medevac_F" */ + 1, /* "C_Van_02_vehicle_F" */ + 1, /* "C_Van_02_service_F" */ + 1 /* "C_Van_02_transport_F" */ +]]; // _veh set [T_VEH_car_unarmed, ["B_MRAP_01_F"]]; // _veh set [T_VEH_car_armed, ["B_MRAP_01_hmg_F"]]; // _veh set [T_VEH_MRAP_unarmed, ["B_MRAP_01_F"]]; @@ -132,12 +153,12 @@ _veh set [T_VEH_DEFAULT, [ //==== Set arrays ==== _array = []; -_array set [T_SIZE-1, nil]; //Make an array having the size equal to the number of categories first +_array set [T_SIZE*2-1, nil]; //Make an array having the size equal to the number of categories first _array set [T_INF, []]; _array set [T_VEH, _veh]; _array set [T_DRONE, []]; _array set [T_GROUP, []]; - +_array set [T_VEH+T_WEIGHTS_OFFSET, _vehWeights]; _array diff --git a/Project_0.Altis/Templates/fn_selectRandom.sqf b/Project_0.Altis/Templates/fn_selectRandom.sqf index 1850926e9..2995cda6b 100644 --- a/Project_0.Altis/Templates/fn_selectRandom.sqf +++ b/Project_0.Altis/Templates/fn_selectRandom.sqf @@ -7,6 +7,8 @@ _classID - number, the ID of the classname. [, -1] if nothing found */ +#include "..\OOP_Light\OOP_Light.h" + params ["_template", "_catID", "_subcatID"]; private _cat = []; @@ -32,7 +34,30 @@ else diag_log format ["fn_selectRandom.sqf: Template: subcategory not found: %1 in category: %2", _subcatID, _catID]; _subcat = _cat select 0; //Return default value }; - private _classID = floor (random (count _subcat)); + private _weightsCat = if(count _template > (_catID+T_WEIGHTS_OFFSET)) then { + _template select (_catID+T_WEIGHTS_OFFSET) + } else { + nil + }; + private _weightsSubcat = if(isNil "_weightsCat") then { nil } else { _weightsCat select _subcatID }; + private _classID = if(isNil "_weightsSubcat") then + { + floor (random (count _subcat)) + } + else + { + _subcat find (_subcat selectRandomWeighted _weightsSubcat) + }; + if(_classID == -1) then { + DUMP_CALLSTACK; + diag_log format["RANDOM %1", _this]; + }; + private _class = _subcat select _classID; + if(isNil "_class") then { + DUMP_CALLSTACK; + diag_log format["RANDOM %1", _this]; + }; + // private _classID = floor (random (count _subcat)); [_subcat select _classID, _classID] }; }; diff --git a/Project_0.Altis/Templates/initCategories.sqf b/Project_0.Altis/Templates/initCategories.sqf index 8a7290303..947c9778f 100644 --- a/Project_0.Altis/Templates/initCategories.sqf +++ b/Project_0.Altis/Templates/initCategories.sqf @@ -15,6 +15,7 @@ Author: Sparker 08.2017 */ T_SIZE = 4; //Number of categories in template +T_WEIGHTS_OFFSET = 4; //Number of categories in template T_INF = 0; //The ID of this category T_INF_SIZE = 34; //The size of this category From 57d22c50621612af246c58fac7135ebcb00e7835 Mon Sep 17 00:00:00 2001 From: billw2012 Date: Thu, 6 Jun 2019 22:53:37 +0100 Subject: [PATCH 8/9] Vehicle spawning working --- Project_0.Altis/GameMode/GameModeBase.sqf | 2 +- Project_0.Altis/Location/Location.sqf | 43 +++- Project_0.Altis/Location/getSpawnPos.sqf | 2 +- Project_0.Altis/Location/isPosEvenSafer.sqf | 66 ++++++ Project_0.Altis/Location/isPosSafe.sqf | 237 ++++++++++---------- 5 files changed, 224 insertions(+), 126 deletions(-) create mode 100644 Project_0.Altis/Location/isPosEvenSafer.sqf diff --git a/Project_0.Altis/GameMode/GameModeBase.sqf b/Project_0.Altis/GameMode/GameModeBase.sqf index 0053ed3c4..7da2aa5ac 100644 --- a/Project_0.Altis/GameMode/GameModeBase.sqf +++ b/Project_0.Altis/GameMode/GameModeBase.sqf @@ -163,7 +163,7 @@ CLASS("GameModeBase", "") // Create vehicles in civilian area for player to steal if(_type == LOCATION_TYPE_CITY) then { private _gar = NEW("Garrison", [CIVILIAN]); - private _maxCars = 3 max (15 min (0.02 * _radius)); + private _maxCars = 3 max (25 min (0.03 * _radius)); for "_i" from 0 to _maxCars do { private _newUnit = NEW("Unit", [tCIVILIAN ARG T_VEH ARG T_VEH_DEFAULT ARG -1 ARG ""]); CALLM(_gar, "addUnit", [_newUnit]); diff --git a/Project_0.Altis/Location/Location.sqf b/Project_0.Altis/Location/Location.sqf index 70977fed0..420a84357 100644 --- a/Project_0.Altis/Location/Location.sqf +++ b/Project_0.Altis/Location/Location.sqf @@ -509,6 +509,8 @@ CLASS("Location", "MessageReceiverEx") Returns: Array, [_pos, _dir] */ + #define ROAD_DIR_LIMIT 15 + STATIC_METHOD("findSafePosOnRoad") { params ["_thisClass", ["_startPos", [], [[]]], ["_className", "", [""]] ]; @@ -530,17 +532,32 @@ CLASS("Location", "MessageReceiverEx") private _rct = roadsConnectedTo _road; // TODO: we can preprocess spawn locations better than this probably. // Need a connected road (this is guaranteed probably?) - if (count _rct == 2 and - // Avoid spawning too close to a junction - {{ count (roadsConnectedTo _x) > 2} count ((getPos _road) nearRoads 15) == 0}) then { - // Check position if it's safe - private _dir = _road getDir (_rct select 0); - - private _width = [_road, 1, 8] call misc_fnc_getRoadWidth; - private _pos = [getPos _road, _width - 3, _dir + 90] call BIS_Fnc_relPos; - if(CALLSM3("Location", "isPosSafe", _pos, _dir, _className)) then { - _return = [_pos, _dir]; - _found = true; + // Avoid spawning too close to a junction + if(count _rct > 0) then { + private _dir = _road getDir _rct#0; + if ({ + private _rctOther = roadsConnectedTo _x; + if(count _rctOther == 0) exitWith { false }; + private _dirOther = _x getDir _rctOther#0; + private _relDir = _dir - _dirOther; + if(_relDir < 0) then { _relDir = _relDir + 360 }; + (_relDir > ROAD_DIR_LIMIT and _relDir < 180-ROAD_DIR_LIMIT) or (_relDir > 180+ROAD_DIR_LIMIT and _relDir < 360-ROAD_DIR_LIMIT) + } count ((getPos _road) nearRoads 25) == 0) then { + // Check position if it's safe + + private _width = [_road, 1, 8] call misc_fnc_getRoadWidth; + // Move to the edge + private _pos = [getPos _road, _width - 3, _dir + (selectRandom [90, 270]) ] call BIS_Fnc_relPos; + // Move up and down the street a bit + _pos = [_pos, _width * 0.5, _dir + (selectRandom [0, 180]) ] call BIS_Fnc_relPos; + // Perturb the direction a bit + private _dirPert = _dir + random [-20, 0, 20] + (selectRandom [0, 180]); + // Perturb the position a bit + private _posPert = _pos vectorAdd [random [-1, 0, 1], random [-1, 0, 1], 0]; + if(CALLSM3("Location", "isPosEvenSafer", _posPert, _dirPert, _className)) then { + _return = [_posPert, _dirPert]; + _found = true; + }; }; }; _i = _i + 1; @@ -684,6 +701,10 @@ CLASS("Location", "MessageReceiverEx") // Checks if given position is safe to spawn a vehicle here STATIC_METHOD_FILE("isPosSafe", "Location\isPosSafe.sqf"); + // Checks if given position is even safer to spawn a vehicle here (conservative, doesn't allow spawning + // in buildings etc.) + STATIC_METHOD_FILE("isPosEvenSafer", "Location\isPosEvenSafer.sqf"); + // Returns the nearest location to given position and distance to it STATIC_METHOD_FILE("getNearestLocation", "Location\getNearestLocation.sqf"); diff --git a/Project_0.Altis/Location/getSpawnPos.sqf b/Project_0.Altis/Location/getSpawnPos.sqf index 4ee2d75fb..56d79d104 100644 --- a/Project_0.Altis/Location/getSpawnPos.sqf +++ b/Project_0.Altis/Location/getSpawnPos.sqf @@ -139,7 +139,7 @@ if(_found) then {//If the spawn position has been found // Try to find a random safe position on a road for this vehicle private _locPos = GET_VAR(_thisObject, "pos"); private _locRadius = GET_VAR(_thisObject, "boundingRadius"); - private _testPos = [_locPos, _locRadius min random [0, 0, _locRadius*2], random 360] call BIS_fnc_relPos; + private _testPos = [_locPos, _locRadius min random [0, 0, _locRadius*5], random 360] call BIS_fnc_relPos; // DUMP_CALLSTACK; // [[[_locPos, _locRadius]],[]] call BIS_fnc_randomPos; _return = CALLSM2("Location", "findSafePosOnRoad", _testPos, _className); diff --git a/Project_0.Altis/Location/isPosEvenSafer.sqf b/Project_0.Altis/Location/isPosEvenSafer.sqf new file mode 100644 index 000000000..de5b600fe --- /dev/null +++ b/Project_0.Altis/Location/isPosEvenSafer.sqf @@ -0,0 +1,66 @@ +// Class: Location +/* +Method: (static)isPosEvenSafer +Returns true if the place is guaranteed safe for spawning specific vehicle. +It is very conservative and as such will disallow spawning in buildings or too close +to existing objects. + +Parameters: _pos, _dir, _className +_pos - position ATL +_dir - direction +_className - vehicle class name + +Returns: Bool + +Author: Sparker 29.07.2018 +*/ + +//#define DEBUG + +pr0_fn_getGlobalRectAndSize = { + params [["_pos", [], [[]]], ["_dir", 0, [0]], ["_bbox", [], [[]]] ]; + + private _bx = _bbox select 1 select 0; //width + private _by = _bbox select 1 select 1; //length + private _bz = _bbox select 1 select 2; //height + + private _c = cos _dir; + private _s = sin _dir; + + private _posASL = ATLTOASL _pos; + private _pos_0 = _posASL vectorAdd [_bx*_c + _by*_s, -_bx*_s + _by*_c, 0]; + private _pos_1 = _posASL vectorAdd [_bx*_c - _by*_s, -_bx*_s - _by*_c, 0]; + private _pos_2 = _posASL vectorAdd [-_bx*_c - _by*_s, _bx*_s - _by*_c, 0]; + private _pos_3 = _posASL vectorAdd [-_bx*_c + _by*_s, _bx*_s + _by*_c, 0]; + private _rect = [_pos_0, _pos_1, _pos_2, _pos_3]; + [_rect, [_bx, _by, _bz]] +}; + +params [ ["_thisClass", "", [""]], ["_pos", [], [[]]], ["_dir", 0, [0]], ["_className", "", [""]] ]; + +// Bail if Z is below surface, as it happens with positions of bridges +if (_pos#2 < -0.3) exitWith { + false +}; + +([ + _pos, _dir, + [_className] call misc_fnc_boundingBoxReal +] call pr0_fn_getGlobalRectAndSize) params ["_rect3D", "_size"]; + +// TODO: expand the class set here? +private _o = nearestObjects [_pos, [], 15, true] - (_pos nearRoads 15); + +_o findIf { + #ifndef _SQF_VM + private _bbox = 0 boundingBoxReal _x; + #else + private _bbox = [[0,0,0],[1,1,1],1]; + #endif + ([getPos _x, getDir _x, _bbox] call pr0_fn_getGlobalRectAndSize) params ["_oRect3D", "_oSize"]; + if(_oSize#2 > 0.3) then { + [_rect3D, _oRect3D] call misc_fnc_polygonCollision + } else { + false + } +} == -1 diff --git a/Project_0.Altis/Location/isPosSafe.sqf b/Project_0.Altis/Location/isPosSafe.sqf index 29fa5e7a6..c5446f10a 100644 --- a/Project_0.Altis/Location/isPosSafe.sqf +++ b/Project_0.Altis/Location/isPosSafe.sqf @@ -17,25 +17,6 @@ Author: Sparker 29.07.2018 //#define DEBUG -pr0_fn_getGlobalRectAndSize = { - params [["_pos", [], [[]]], ["_dir", 0, [0]], ["_bbox", [], [[]]] ]; - - private _bx = _bbox select 1 select 0; //width - private _by = _bbox select 1 select 1; //length - private _bz = _bbox select 1 select 2; //height - - private _c = cos _dir; - private _s = sin _dir; - - private _posASL = ATLTOASL _pos; - private _pos_0 = _posASL vectorAdd [_bx*_c + _by*_s, -_bx*_s + _by*_c, 0]; - private _pos_1 = _posASL vectorAdd [_bx*_c - _by*_s, -_bx*_s - _by*_c, 0]; - private _pos_2 = _posASL vectorAdd [-_bx*_c - _by*_s, _bx*_s - _by*_c, 0]; - private _pos_3 = _posASL vectorAdd [-_bx*_c + _by*_s, _bx*_s + _by*_c, 0]; - private _rect = [_pos_0, _pos_1, _pos_2, _pos_3]; - [_rect, [_bx, _by, _bz]] -}; - params [ ["_thisClass", "", [""]], ["_pos", [], [[]]], ["_dir", 0, [0]], ["_className", "", [""]] ]; // Bail if Z is below surface, as it happens with positions of bridges @@ -50,98 +31,128 @@ if (_pos#2 < -0.3) exitWith { false }; -// private _bb = [_className] call misc_fnc_boundingBoxReal; -// private _bx = _bb select 1 select 0; //width -// private _by = _bb select 1 select 1; //lenth -// private _bz = _bb select 1 select 2; //height - -// #ifdef DEBUG -// diag_log format [" Classname: %1, bounding box: %2", _className, _bb]; -// #endif - -// private _c = cos _dir; -// private _s = sin _dir; - -// /* -// Get positions of corners of bounding box and rotate them _dir degrees. -// Positions are: -// 3 0 -// \ / -// O -// / \ -// 2 1 -// */ - -// private _posASL = ATLTOASL _pos; -// private _pos_0 = _posASL vectorAdd [_bx*_c + _by*_s, -_bx*_s + _by*_c, 1]; -// private _pos_1 = _posASL vectorAdd [_bx*_c - _by*_s, -_bx*_s - _by*_c, 1]; -// private _pos_2 = _posASL vectorAdd [-_bx*_c - _by*_s, _bx*_s - _by*_c, 1]; -// private _pos_3 = _posASL vectorAdd [-_bx*_c + _by*_s, _bx*_s + _by*_c, 1]; - -//private _rect = [_pos_0, _pos_1, _pos_2, _pos_3]; - -// // Debug drawing -// #ifdef DEBUG -// diag_log format ["--- Positions ATL: %1", [[ASLTOATL _pos_0], [ASLTOATL _pos_1], [ASLTOATL _pos_2], [ASLTOATL _pos_3]]]; -// { -// createVehicle ["Sign_Arrow_F", ASLTOATL _x, [], 0, "CAN_COLLIDE"]; -// } forEach [_pos_0, _pos_1, _pos_2, _pos_3]; - - -// [{ -// (_this select 0) params ["_pos_0", "_pos_1", "_pos_2", "_pos_3"]; -// private _color = [1,1,0,1]; -// drawLine3D [_pos_0, _pos_2, _color]; -// drawLine3D [_pos_1, _pos_3, _color]; -// drawLine3D [_pos_1, _pos_2, _color]; -// drawLine3D [_pos_0, _pos_3, _color]; -// }, -// 0, -// [ASLToAGL _pos_0, ASLToAGL _pos_1, ASLToAGL _pos_2, ASLToAGL _pos_3]] call CBA_fnc_addPerFrameHandler; - -// diag_log format [" Pos 0...3 AGL: %1", [ASLToAGL _pos_0, ASLToAGL _pos_1, ASLToAGL _pos_2, ASLToAGL _pos_3]]; -// #endif - -([ - _pos, _dir, - [_className] call misc_fnc_boundingBoxReal -] call pr0_fn_getGlobalRectAndSize) params ["_rect3D", "_size"]; - -// private _o = -// lineIntersectsSurfaces [_rect3D#0, _rect3D#2, objNull, objNull, false]; -// _o append lineIntersectsSurfaces [_rect3D#1, _rect3D#3, objNull, objNull, false]; -// _o append lineIntersectsSurfaces [_rect3D#1, _rect3D#2, objNull, objNull, false]; -// _o append lineIntersectsSurfaces [_rect3D#0, _rect3D#3, objNull, objNull, false]; - -// if(count _o > 0) exitWith -// { -// #ifdef DEBUG -// diag_log " Line intersects with a surface"; -// #endif -// false -// }; - -//private _radius = sqrt (_size#0*_size#0 + _size#1*_size#1); - -// TODO: expand the class set here? -private _o = nearestObjects [_pos, [], 15, true] - (_pos nearRoads 15); - -_o findIf { - //private _className = typeOf _x; - #ifndef _SQF_VM - private _bbox = 0 boundingBoxReal _x; - #else - private _bbox = [[0,0,0],[1,1,1],1]; +private _bb = [_className] call misc_fnc_boundingBoxReal; +private _bx = _bb select 1 select 0; //width +private _by = _bb select 1 select 1; //lenth +private _bz = _bb select 1 select 2; //height + +#ifdef DEBUG +diag_log format [" Classname: %1, bounding box: %2", _className, _bb]; +#endif + +private _c = cos _dir; +private _s = sin _dir; + +/* +Get positions of corners of bounding box and rotate them _dir degrees. +Positions are: +3 0 + \ / + O + / \ +2 1 +*/ + +private _posASL = ATLTOASL _pos; +private _pos_0 = _posASL vectorAdd [_bx*_c + _by*_s, -_bx*_s + _by*_c, 1]; +private _pos_1 = _posASL vectorAdd [_bx*_c - _by*_s, -_bx*_s - _by*_c, 1]; +private _pos_2 = _posASL vectorAdd [-_bx*_c - _by*_s, _bx*_s - _by*_c, 1]; +private _pos_3 = _posASL vectorAdd [-_bx*_c + _by*_s, _bx*_s + _by*_c, 1]; + + +// Debug drawing +#ifdef DEBUG +diag_log format ["--- Positions ATL: %1", [[ASLTOATL _pos_0], [ASLTOATL _pos_1], [ASLTOATL _pos_2], [ASLTOATL _pos_3]]]; +{ + createVehicle ["Sign_Arrow_F", ASLTOATL _x, [], 0, "CAN_COLLIDE"]; +} forEach [_pos_0, _pos_1, _pos_2, _pos_3]; + + +[{ + (_this select 0) params ["_pos_0", "_pos_1", "_pos_2", "_pos_3"]; + private _color = [1,1,0,1]; + drawLine3D [_pos_0, _pos_2, _color]; + drawLine3D [_pos_1, _pos_3, _color]; + drawLine3D [_pos_1, _pos_2, _color]; + drawLine3D [_pos_0, _pos_3, _color]; +}, +0, +[ASLToAGL _pos_0, ASLToAGL _pos_1, ASLToAGL _pos_2, ASLToAGL _pos_3]] call CBA_fnc_addPerFrameHandler; + +diag_log format [" Pos 0...3 AGL: %1", [ASLToAGL _pos_0, ASLToAGL _pos_1, ASLToAGL _pos_2, ASLToAGL _pos_3]]; +#endif + + + +//Find objects +//First check with line intersections +private _o = lineIntersectsObjs [_pos_0, _pos_2, objNull, objNull, false, 16+32]; //CF_FIRST_CONTACT + CF_ALL_OBJECTS +_o append lineIntersectsObjs [_pos_1, _pos_3, objNull, objNull, false, 16+32]; //CF_FIRST_CONTACT + CF_ALL_OBJECTS +_o append lineIntersectsObjs [_pos_1, _pos_2, objNull, objNull, false, 16+32]; //CF_FIRST_CONTACT + CF_ALL_OBJECTS +_o append lineIntersectsObjs [_pos_0, _pos_3, objNull, objNull, false, 16+32]; //CF_FIRST_CONTACT + CF_ALL_OBJECTS +private _i = 0; +private _c = count _o; +private _good = true; +private _t = ""; //type of object +//private _checkHumans = (_vehType isKindOf ["man", configFile >> "cfgVehicles"]); //Ignore humans if _vehType is not a human + +#ifdef DEBUG +diag_log format [" fn_isPosSafe: line intersections: %1", _o]; +#endif + +while {_i < _c} do +{ + private _obj = _o select _i; + //diag_log format ["type: %1", _t]; + if ( (_obj isKindOf "allVehicles") && + (!(_obj isKindOf "Man")) ) exitWith { + _good = false; + }; + _i = _i + 1; +}; + +if(!_good) exitWith +{ + #ifdef DEBUG + diag_log " Line intersects with a vehicle"; #endif - // if(_className != "") then { - // [_className] call misc_fnc_boundingBoxReal - // } else { - // boundingBoxReal _x - // }; - ([getPos _x, getDir _x, _bbox] call pr0_fn_getGlobalRectAndSize) params ["_oRect3D", "_oSize"]; - if(_oSize#2 > 0.3) then { - [_rect3D, _oRect3D] call misc_fnc_polygonCollision - } else { - false - } -} == -1 + false +}; + +//Check for objects in sphere +private _posCheck = _pos; //_pos vectorAdd [0, 0, _bz]; + +//Test: create arrow +/* +private _arrow = "Sign_Arrow_F" createVehicle _pos; +_arrow setPosATL _posCheck; +*/ + +//diag_log format ["%1 %2", _posCheck, _bx]; +private _radius = sqrt (_bx*_bx + _by*_by); +_o = nearestObjects [_posCheck, ["allVehicles"], (_radius + 1) max 1.7, true]; +//player setPos _pos; + +#ifdef DEBUG +diag_log format ["fn_isPosSafe: near objects %1: %2", _bx, _o]; +#endif + +_i = 0; +_c = count _o; +private _t = ""; //type of object +while {_i < _c && _good} do { + private _obj = _o select _i; + if (!(_obj isKindOf "Man")) then { + _good = false; + #ifdef DEBUG + diag_log " Found a vehicle inside sphere!"; + #endif + }; + _i = _i + 1; +}; + +#ifdef DEBUG +diag_log format [" Position safe: %1", _good]; +#endif + +_good From 079ef23a4c65725ee04b0fc2467a28d0c53a73e5 Mon Sep 17 00:00:00 2001 From: billw2012 Date: Thu, 6 Jun 2019 23:00:56 +0100 Subject: [PATCH 9/9] Fix for validation CI --- Project_0.Altis/Templates/fn_selectRandom.sqf | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Project_0.Altis/Templates/fn_selectRandom.sqf b/Project_0.Altis/Templates/fn_selectRandom.sqf index 2995cda6b..f365e9bf3 100644 --- a/Project_0.Altis/Templates/fn_selectRandom.sqf +++ b/Project_0.Altis/Templates/fn_selectRandom.sqf @@ -1,3 +1,4 @@ +#include "..\OOP_Light\OOP_Light.h" /* Select a random classname from subcategory from a category from a template array parameters: @@ -7,8 +8,6 @@ _classID - number, the ID of the classname. [, -1] if nothing found */ -#include "..\OOP_Light\OOP_Light.h" - params ["_template", "_catID", "_subcatID"]; private _cat = [];