Skip to content

Commit

Permalink
new: local speed limits
Browse files Browse the repository at this point in the history
* add additional config `EGVAR(cars,townSpeedLimit)`
* use map locations to determine if a vehicle is in a town
* add speed limit zones to diagnostics views
* add EGVAR(cars,customSpeedLimits) that may contain speed
  limits defined by a tuple (Location, number)
  • Loading branch information
Fusselwurm committed Aug 7, 2022
1 parent 6d82cb5 commit 584be70
Show file tree
Hide file tree
Showing 16 changed files with 169 additions and 12 deletions.
18 changes: 15 additions & 3 deletions addons/cars/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# grad\_civs\_cars

Basic handling of civs driving cars.
Basic handling of civs driving cars.

As a user, see transit and voyage modules to actually get civs driving on the streets.

Expand All @@ -12,6 +12,8 @@ animalTransportChance | 0.4 | Probability that a suitable vehicle w
animalTransportVehicles | [] | optional list of class names whitelisting vehicles that are allowed to carry animals
automaticVehicleGroupSize| 1 | Allow vehicles to be filled according to capacity, ignoring *initialGroupSize* (0,1).
vehicles | ["C_Van_01_fuel_F", "C_Hatchback_01_F", "C_Offroad_02_unarmed_F", "C_Truck_02_fuel_F", "C_Truck_02_covered_F", "C_Offroad_01_F", "C_SUV_01_F", "C_Van_01_transport_F", "C_Van_01_box_F"] | All classnames of vehicles that civilians may drive.
globalSpeedLimit | 50 | Speed limit for civilian vehicles in km/h
townSpeedLimit | 30 | Speed limit for civilian vehicles in km/h while in the area of a city or village Location

## API

Expand All @@ -35,13 +37,23 @@ vehicles | Array - All classnames of vehicles that civilians may drive.

#### grad_civs_cars_car_added

```sqf
```sqf
["grad_civs_cars_car_added", { params ["_vehicle"]; }] call CBA_fnc_addEventHandler;
```


#### grad_civs_cars_vehKilled

```sqf
```sqf
["grad_civs_cars_vehKilled", { params ["_deathPos", "_killer", "_vehicle"]; }] call CBA_fnc_addEventHandler;
```

### Global variables

#### grad_civs_cars_customSpeedLimits

You may define speed limits by setting the `grad_civs_cars_customSpeedLimits` array.

Each entry must be an array with two entries: a [Location](https://community.bistudio.com/wiki/Location) and a number (the speed limit in km/h).

This array must be local on the machines running the civs, i.e. server and/or headless clients.
3 changes: 3 additions & 0 deletions addons/cars/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
PREP(determineTownLocations);
PREP(determineSpeedLimits);
PREP(dismountCondition);
PREP(getGlobalVehicles);
PREP(getGroupVehicle);
PREP(initConfig);
PREP(loadAnimals);
PREP(pfh_speedLimit);
PREP(setGroupVehicle);
PREP(setVehicles);
PREP(sm_business_state_dismount_enter);
Expand Down
19 changes: 19 additions & 0 deletions addons/cars/XEH_postInit.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,24 @@

if (isServer || CBA_isHeadlessClient) then {
["business", ["bus_rally"], FUNC(sm_business)] call EFUNC(common,augmentStateMachine);

ISNILS(GVAR(pfh_speedLimit_interval), EGVAR(lifecycle,minCivUpdateTime));
GVAR(pfh_speedLimit) = [FUNC(pfh_speedLimit), GVAR(pfh_speedLimit_interval)] call CBA_fnc_addPerFrameHandler;

ISNILS(GVAR(localCars), []);
[QGVAR(car_added), {
params ["_veh"];
if (local _veh) then {
GVAR(localCars) pushBackUnique _veh;
};
}] call CBA_fnc_addEventHandler;
[QGVAR(vehKilled), {
params ["_veh"];
GVAR(localCars) = GVAR(localCars) - [_veh];
}] call CBA_fnc_addEventHandler;
GVAR(pfh_groomCarsArray) = [{
GVAR(localCars) = GVAR(localCars) select {!(isNull _x)};
}, 5] call CBA_fnc_addPerFrameHandler;

};
}] call CBA_fnc_addEventHandler;
6 changes: 6 additions & 0 deletions addons/cars/functions/fnc_determineSpeedLimits.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include "..\script_component.hpp"

ISNILS(GVAR(customSpeedLimits), []); // Array<(Location, number)>
ISNILS(GVAR(townSpeedLimits), ([] call FUNC(determineTownLocations)) apply {[ARR_2(_x, GVAR(townSpeedLimit))]});

GVAR(townSpeedLimits) + GVAR(customSpeedLimits)
10 changes: 10 additions & 0 deletions addons/cars/functions/fnc_determineTownLocations.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include "..\script_component.hpp"

private _radius = worldSize / 2;
private _center = [_radius, _radius];
private _townLocationTypes = ["NameCity", "NameCityCapital", "NameVillage", "FlatAreaCity", "FlatAreaCitySmall"];
nearestLocations [
_center,
_townLocationTypes,
_radius
]
13 changes: 12 additions & 1 deletion addons/cars/functions/fnc_initConfig.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,18 @@ private _settingsGroup = ["GRAD Civilians", "7) cars - basic settings for civili
"SLIDER",
"Vehicle speed limit in km/h",
_settingsGroup,
[-1, 360, 50, 0, false],
[0, 360, 50, 0, false],
false,
{},
false
] call CBA_fnc_addSetting;

[
QGVAR(townSpeedLimit),
"SLIDER",
"Vehicle speed limit within towns in km/h",
_settingsGroup,
[0, 360, 30, 0, false],
false,
{},
false
Expand Down
19 changes: 19 additions & 0 deletions addons/cars/functions/fnc_pfh_speedLimit.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "..\script_component.hpp"

private _speedLimits = call FUNC(determineSpeedLimits);

{
_x setVariable [QGVAR(speedLimit), GVAR(globalSpeedLimit)];
} forEach GVAR(localCars);

{
_x params ["_location", "_speedLimit"];
private _affectedCars = GVAR(localCars) inAreaArray _location;
{
_x setVariable [QGVAR(speedLimit), _speedLimit];
} forEach _affectedCars;
} forEach _speedLimits;

{
_x limitSpeed (_x getVariable [QGVAR(speedLimit), GVAR(globalSpeedLimit)]);
} forEach GVAR(localCars);
2 changes: 1 addition & 1 deletion addons/cars/functions/fnc_spawnVehicle.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ _veh addEventHandler [
{
params ["_unit", "_killer"];

["grad_civs_cars_vehKilled", [getPos _unit, _killer, _unit]] call CBA_fnc_globalEvent;
[QGVAR(vehKilled), [getPos _unit, _killer, _unit]] call CBA_fnc_globalEvent;
}
];

Expand Down
6 changes: 5 additions & 1 deletion addons/diagnostics/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# grad\_civs\_diagnostics

Debugging GUI stuff
Debugging GUI stuff.

A lot of it only works in Singleplayer, as much of the relevant data is local where the civs are, and they're local on server or HCs.

## Settings

Expand All @@ -11,4 +13,6 @@ showFps | false | Show server & HC fps
showOnMap | false | Show civs on map
showInfoLine | false | Show detailed info line on civilian
showPinkArrows | false | Create 3D arrows over civ heads
showSpawnAttempts | false | Show short-lived markers on map to debug spawning
showSpeedLimitsOnMap | false | Show locations + corresponding speed limit on map
showMisc | false | Miscellaneous stuff
2 changes: 2 additions & 0 deletions addons/diagnostics/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
PREP(drawFlyScarePoly);
PREP(drawSpeedLimitsOnMap);
PREP(initConfig);
PREP(showFps);
PREP(showFlyScarePoly);
Expand All @@ -14,5 +15,6 @@ PREP(showPinkArrows_arrowDelete);
PREP(showPinkArrows_arrowEnsure);
PREP(showPointingHints);
PREP(showSpawnAttempts);
PREP(showSpeedLimitsOnMap);
PREP(tempMarker);
PREP(updateInfoLine);
37 changes: 37 additions & 0 deletions addons/diagnostics/functions/fnc_drawSpeedLimitsOnMap.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "..\script_component.hpp"

params [
["_mode", "update", [""]]
];

ISNILS(GVAR(speedLimitMarkers), []);
{
deleteMarkerLocal _x;
} forEach GVAR(speedLimitMarkers);
GVAR(speedLimitMarkers) = [];

if (_mode == "delete") exitWith {};

private _speedLimits = call EFUNC(cars,determineSpeedLimits);

{
_x params ["_location", "_speedLimit"];

private _circle = createMarkerLocal [format ["speed_limit_town_%1_circle", _forEachIndex], position _location];
_circle setMarkerShapeLocal "ELLIPSE";
_circle setMarkerSizeLocal (size _location);
_circle setMarkerBrushLocal "SolidBorder";
_circle setMarkerColorLocal "ColorBlue";
_circle setMarkerAlphaLocal 0.5;

private _text = createMarkerLocal [format ["speed_limit_town_%1_text", _forEachIndex], position _location];
_text setMarkerShapeLocal "ICON";
_text setMarkerTypeLocal "mil_circle_noShadow";
_text setMarkerColorLocal "ColorBlue";
_text setMarkerTextLocal (format ["%1 km/h", _speedLimit]);


GVAR(speedLimitMarkers) pushBack _circle;
GVAR(speedLimitMarkers) pushBack _text;

} forEach _speedLimits;
12 changes: 11 additions & 1 deletion addons/diagnostics/functions/fnc_initConfig.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,17 @@ private _settingsGroup = ["GRAD Civilians", "c) diagnostics - debugging info"];
false
] call CBA_fnc_addSetting;

[
QGVAR(showSpeedLimitsOnMap),
"CHECKBOX",
"Show speed limits on map",
_settingsGroup,
false,
false,
FUNC(showSpeedLimitsOnMap),
false
] call CBA_fnc_addSetting;

[
QGVAR(showMisc),
"CHECKBOX",
Expand All @@ -70,7 +81,6 @@ private _settingsGroup = ["GRAD Civilians", "c) diagnostics - debugging info"];
{ deleteVehicle _x } forEach GVAR(dangerPolyGroundHelpers);
[] call FUNC(showHonkAtArea);
[] call FUNC(showFlyScarePoly);

},
false
] call CBA_fnc_addSetting;
8 changes: 7 additions & 1 deletion addons/diagnostics/functions/fnc_showInfoLine.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,13 @@ ISNILS(GVAR(userActionIds), []);
private _driver = driver _veh;
if ((_veh != _x) && (_driver != _x)) exitWith { "x" };

format["%1 | %2km/h in speedmode: %3 %4", _x, round speed _veh, speedMode _x, if (leader _x == _x) then {"(is leader)"} else {""}];
format["%1 | %2 / %3 km/h in speedmode: %4 %5",
_x,
round speed _veh,
round (_veh getVariable [QEGVAR(cars,speedLimit), -1]),
speedMode _x,
if (leader _x == _x) then {"(is leader)"} else {""}
];
};
case 3: {format["%1 | %2 guns point at him", _x, _x getVariable [QEGVAR(interact,pointedAtCount), 0]]};
case 4: {format["%1 | is local at %2", _x, _x getVariable [QGVAR(localAt), 0]]};
Expand Down
22 changes: 22 additions & 0 deletions addons/diagnostics/functions/fnc_showSpeedLimitsOnMap.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include "..\script_component.hpp"

ISNILS(GVAR(speedLimitsPfh), -1);

if (!GVAR(showSpeedLimitsOnMap)) exitWith {
[GVAR(speedLimitsPfh)] call CBA_fnc_removePerFrameHandler;
GVAR(speedLimitsPfh) = -1;
["delete"] call FUNC(drawSpeedLimitsOnMap);
};

if (GVAR(speedLimitsPfh) != -1) exitWith {
WARNING("showSpeedLimitsOnMap already has pfh, not adding another one");
};

GVAR(speedLimitsPfh) = [
{
if (!isGameFocused || isGamePaused) exitWith {};
["update"] call FUNC(drawSpeedLimitsOnMap);
},
2,
[]
] call CBA_fnc_addPerFrameHandler;
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,3 @@ if (isNull _group) exitWith {
private _livedAs = _this getVariable ["grad_civs_livedAs", str _this];
WARNING_5("unit %1 (type %2) in voyage loop has no group. will ignore. alive %3 index %4 pos %5", _livedAs, typeof _this, alive _this, EGVAR(lifecycle,localCivs) find _this, getPos _this);
};

(vehicle _this) limitSpeed EGVAR(cars,globalSpeedLimit);
2 changes: 0 additions & 2 deletions addons/voyage/functions/fnc_sm_business_state_voyage_loop.sqf
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,3 @@ if (isNull _group) exitWith {
private _livedAs = _this getVariable ["grad_civs_livedAs", str _this];
WARNING_5("unit %1 (type %2) in voyage loop has no group. will ignore. alive %3 index %4 pos %5", _livedAs, typeof _this, alive _this, EGVAR(lifecycle,localCivs) find _this, getPos _this);
};

(vehicle _this) limitSpeed EGVAR(cars,globalSpeedLimit);

0 comments on commit 584be70

Please sign in to comment.