Weather - Major Cleanup (#5710)

* Single global on/off switch (that really turns everything off properly)
* Less coupling between code that runs on the client / server
* Simpler update routines
* More cohesive code
* Less module options
* Less network traffic
This commit is contained in:
ulteq 2017-11-10 15:44:15 +01:00 committed by GitHub
parent 70c25aacaf
commit dcc934202b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 134 additions and 495 deletions

View File

@ -31,7 +31,7 @@
drop ["\A3\data_f\ParticleEffects\Universal\Refract","","Billboard",1,0.1,getPos _bullet,[0,0,0],0,1.275,1,0,[0.02*_caliber,0.01*_caliber],[[0,0,0,0.65],[0,0,0,0.2]],[1,0],0,0,"","",""]; drop ["\A3\data_f\ParticleEffects\Universal\Refract","","Billboard",1,0.1,getPos _bullet,[0,0,0],0,1.275,1,0,[0.02*_caliber,0.01*_caliber],[[0,0,0,0.65],[0,0,0,0.2]],[1,0],0,0,"","",""];
}; };
_bullet setVelocity (_bulletVelocity vectorAdd (parseSimpleArray ("ace_advanced_ballistics" callExtension format["simulate:%1:%2:%3:%4:%5:%6", _index, _bulletVelocity, _bulletPosition, ACE_wind, ASLToATL(_bulletPosition) select 2, CBA_missionTime toFixed 6]))); _bullet setVelocity (_bulletVelocity vectorAdd (parseSimpleArray ("ace_advanced_ballistics" callExtension format["simulate:%1:%2:%3:%4:%5:%6", _index, _bulletVelocity, _bulletPosition, wind, ASLToATL(_bulletPosition) select 2, CBA_missionTime toFixed 6])));
}; };
nil nil
} count +GVAR(allBullets); } count +GVAR(allBullets);

View File

@ -59,7 +59,7 @@ private _textCenterLine5 = "";
private _textCenterLine6 = ""; private _textCenterLine6 = "";
private _windSpeed = call FUNC(measureWindSpeed); private _windSpeed = call FUNC(measureWindSpeed);
private _windDir = (ACE_wind select 0) atan2 (ACE_wind select 1); private _windDir = (wind select 0) atan2 (wind select 1);
private _playerDir = getDir ACE_player; private _playerDir = getDir ACE_player;
private _playerAltitude = (getPosASL ACE_player) select 2; private _playerAltitude = (getPosASL ACE_player) select 2;

View File

@ -16,8 +16,8 @@
#include "script_component.hpp" #include "script_component.hpp"
private _playerDir = getDir ACE_player; private _playerDir = getDir ACE_player;
private _windSpeed = vectorMagnitude ACE_wind; private _windSpeed = vectorMagnitude wind;
private _windDir = (ACE_wind select 0) atan2 (ACE_wind select 1); private _windDir = (wind select 0) atan2 (wind select 1);
if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then { if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
// With wind gradient // With wind gradient
_windSpeed = [eyePos ACE_player, true, true, true] call EFUNC(weather,calculateWindSpeed); _windSpeed = [eyePos ACE_player, true, true, true] call EFUNC(weather,calculateWindSpeed);

View File

@ -73,7 +73,7 @@ if (_newMuzzleVelocityCoefficent != 1) then {
private _bulletVelocity = velocity _shell; private _bulletVelocity = velocity _shell;
private _bulletSpeed = vectorMagnitude _bulletVelocity; private _bulletSpeed = vectorMagnitude _bulletVelocity;
private _trueVelocity = _bulletVelocity vectorDiff ACE_wind; private _trueVelocity = _bulletVelocity vectorDiff wind;
private _trueSpeed = vectorMagnitude _trueVelocity; private _trueSpeed = vectorMagnitude _trueVelocity;
private _drag = _deltaT * _airFriction * _trueSpeed * _relativeDensity; private _drag = _deltaT * _airFriction * _trueSpeed * _relativeDensity;

View File

@ -1,32 +1,20 @@
class ACE_Settings { class ACE_Settings {
class GVAR(enableServerController) { class GVAR(enabled) {
displayName = CSTRING(enableServerController_DisplayName); displayName = CSTRING(enabled_DisplayName);
description = CSTRING(enableServerController_Description); description = CSTRING(enabled_Description);
typeName = "BOOL"; typeName = "BOOL";
value = 1; value = 1;
}; };
class GVAR(useACEWeather) { class GVAR(updateInterval) {
displayName = CSTRING(useACEWeather_DisplayName); displayName = CSTRING(updateInterval_DisplayName);
description = CSTRING(useACEWeather_Description); description = CSTRING(updateInterval_Description);
typeName = "BOOL";
value = 1;
};
class GVAR(syncWind) {
displayName = CSTRING(syncWind_DisplayName);
description = CSTRING(syncWind_Description);
typeName = "BOOL";
value = 1;
};
class GVAR(syncMisc) {
displayName = CSTRING(syncMisc_DisplayName);
description = CSTRING(syncMisc_Description);
typeName = "BOOL";
value = 1;
};
class GVAR(serverUpdateInterval) {
displayName = CSTRING(serverUpdateInterval_DisplayName);
description = CSTRING(serverUpdateInterval_Description);
typeName = "SCALAR"; typeName = "SCALAR";
value = 60; value = 60;
}; };
class GVAR(windSimulation) {
displayName = CSTRING(windSimulation_DisplayName);
description = CSTRING(windSimulation_Description);
typeName = "BOOL";
value = 1;
};
}; };

View File

@ -12,36 +12,24 @@ class CfgVehicles {
isTriggerActivated = 0; isTriggerActivated = 0;
author = ECSTRING(common,ACETeam); author = ECSTRING(common,ACETeam);
class Arguments { class Arguments {
class enableServerController { class enabled {
displayName = CSTRING(enableServerController_DisplayName); displayName = CSTRING(enabled_DisplayName);
description = CSTRING(enableServerController_Description); description = CSTRING(enabled_Description);
typeName = "BOOL"; typeName = "BOOL";
defaultValue = 1; defaultValue = 1;
}; };
class useACEWeather { class updateInterval {
displayName = CSTRING(useACEWeather_DisplayName); displayName = CSTRING(updateInterval_DisplayName);
description = CSTRING(useACEWeather_Description); description = CSTRING(updateInterval_Description);
typeName = "BOOL";
defaultValue = 1;
};
class syncWind {
displayName = CSTRING(syncWind_DisplayName);
description = CSTRING(syncWind_Description);
typeName = "BOOL";
defaultValue = 1;
};
class syncMisc {
displayName = CSTRING(syncMisc_DisplayName);
description = CSTRING(syncMisc_Description);
typeName = "BOOL";
defaultValue = 1;
};
class serverUpdateInterval {
displayName = CSTRING(serverUpdateInterval_DisplayName);
description = CSTRING(serverUpdateInterval_Description);
typeName = "NUMBER"; typeName = "NUMBER";
defaultValue = 60; defaultValue = 60;
}; };
class windSimulation {
displayName = CSTRING(windSimulation_DisplayName);
description = CSTRING(windSimulation_Description);
typeName = "BOOL";
defaultValue = 1;
};
}; };
class ModuleDescription { class ModuleDescription {
description = CSTRING(Module_Description); description = CSTRING(Module_Description);

View File

@ -12,12 +12,9 @@ PREP(calculateWindChill);
PREP(calculateWindSpeed); PREP(calculateWindSpeed);
PREP(displayWindInfo); PREP(displayWindInfo);
PREP(getMapData); PREP(getMapData);
PREP(getWind);
PREP(initModuleSettings); PREP(initModuleSettings);
PREP(initWind); PREP(initWind);
PREP(serverController);
PREP(updateAceWeather);
PREP(updateHumidity); PREP(updateHumidity);
PREP(updateRain);
PREP(updateTemperature); PREP(updateTemperature);
PREP(updateWeather);
PREP(updateWind); PREP(updateWind);

View File

@ -1,29 +1,5 @@
#include "script_component.hpp" #include "script_component.hpp"
// Randomization
GVAR(temperatureShift) = 3 - random 6;
GVAR(badWeatherShift) = (random 1) ^ 2 * 10;
GVAR(humidityShift) = (5 - random 10) / 100;
GVAR(wind_period_start_time) = CBA_missionTime;
"ACE_WIND_PARAMS" addPublicVariableEventHandler { GVAR(wind_period_start_time) = CBA_missionTime; };
if (!isServer) then {
"ACE_MISC_PARAMS" addPublicVariableEventHandler {
TRACE_1("MISC PARAMS PVEH",ACE_MISC_PARAMS);
GVAR(currentOvercast) = (ACE_MISC_PARAMS select 0);
if (GVAR(syncMisc)) then {
30 setRainbow (ACE_MISC_PARAMS select 1);
30 setFog (ACE_MISC_PARAMS select 2);
};
GVAR(temperatureShift) = (ACE_MISC_PARAMS select 3);
GVAR(badWeatherShift) = (ACE_MISC_PARAMS select 4);
GVAR(humidityShift) = (ACE_MISC_PARAMS select 5);
call FUNC(updateTemperature);
call FUNC(updateHumidity);
};
};
GVAR(WindInfo) = false; GVAR(WindInfo) = false;
["ACE3 Common", QGVAR(WindInfoKey), localize LSTRING(WindInfoKeyToggle), ["ACE3 Common", QGVAR(WindInfoKey), localize LSTRING(WindInfoKeyToggle),
{ {
@ -49,27 +25,3 @@ GVAR(WindInfo) = false;
(["RscWindIntuitive"] call BIS_fnc_rscLayer) cutText ["", "PLAIN", 2]; (["RscWindIntuitive"] call BIS_fnc_rscLayer) cutText ["", "PLAIN", 2];
}, },
[0, [false, false, false]], false, 0] call CBA_fnc_addKeybind; // (empty default key) [0, [false, false, false]], false, 0] call CBA_fnc_addKeybind; // (empty default key)
simulWeatherSync;
["ace_settingsInitialized",{
// Create a 1 sec delay PFEH to update wind/temp/humidity
GVAR(nextUpdateTempAndHumidity) = 0;
[{
BEGIN_COUNTER(weatherPFEH);
[] call FUNC(updateWind); //Every 1 second
if (CBA_missionTime >= GVAR(nextUpdateTempAndHumidity)) then {
[] call FUNC(updateTemperature); //Every 20 seconds
[] call FUNC(updateHumidity); //Every 20 seconds
GVAR(nextUpdateTempAndHumidity) = 20 + CBA_missionTime;
};
END_COUNTER(weatherPFEH);
}, 1, []] call CBA_fnc_addPerFrameHandler;
}] call CBA_fnc_addEventHandler;

View File

@ -1,32 +1,16 @@
#include "script_component.hpp" #include "script_component.hpp"
// Rain
GVAR(rain_next_period) = -1;
GVAR(rain_period_count) = 0;
GVAR(current_rain) = 0;
GVAR(rain_current_range) = -1+(random 2);
GVAR(rain_period_start_time) = CBA_missionTime;
GVAR(ACE_rain) = rain;
// Wind
call FUNC(initWind);
["ace_settingsInitialized", { ["ace_settingsInitialized", {
TRACE_3("ace_settingsInitialized eh",GVAR(enableServerController),GVAR(serverUpdateInterval),GVAR(useACEWeather)); if (!GVAR(enabled)) exitWith {};
if (GVAR(enableServerController)) then { GVAR(temperatureShift) = random [-5, 0, 5];
[FUNC(serverController), GVAR(serverUpdateInterval)] call CBA_fnc_addPerFrameHandler; GVAR(badWeatherShift) = random [10, 0, 10];
}; GVAR(humidityShift) = random [-0.1, 0, 0.1];
if (GVAR(useACEWeather)) then { if (GVAR(windSimulation)) then {
GVAR(nextUpdateRain) = 0; call FUNC(initWind);
[FUNC(updateWind), 1] call CBA_fnc_addPerFrameHandler;
};
[FUNC(updateWeather), GVAR(updateInterval)] call CBA_fnc_addPerFrameHandler;
addMissionEventHandler ["EachFrame", {
if (CBA_missionTime >= GVAR(nextUpdateRain)) then {
[] call FUNC(updateRain); // Every 2 seconds
GVAR(nextUpdateRain) = 2 + CBA_missionTime;
};
0 setRain GVAR(ACE_rain); // Update rain every frame
}];
};
}] call CBA_fnc_addEventHandler; }] call CBA_fnc_addEventHandler;

View File

@ -18,7 +18,7 @@
// Source: http://es.ucsc.edu/~jnoble/wind/extrap/index.html // Source: http://es.ucsc.edu/~jnoble/wind/extrap/index.html
#define ROUGHNESS_LENGTHS [0.0002, 0.0005, 0.0024, 0.03, 0.055, 0.1, 0.2, 0.4, 0.8, 1.6] #define ROUGHNESS_LENGTHS [0.0002, 0.0005, 0.0024, 0.03, 0.055, 0.1, 0.2, 0.4, 0.8, 1.6]
private _windSource = _this vectorDiff ((vectorNormalized ACE_wind) vectorMultiply 25); private _windSource = _this vectorDiff ((vectorNormalized wind) vectorMultiply 25);
private _nearBuildings = count (_windSource nearObjects ["Building", 50]); private _nearBuildings = count (_windSource nearObjects ["Building", 50]);
private _isWater = surfaceIsWater _windSource; private _isWater = surfaceIsWater _windSource;

View File

@ -26,8 +26,8 @@ private _fnc_polar2vect = {
[_mag2D * sin(_dir), _mag2D * cos(_dir), _mag * sin(_elev)]; [_mag2D * sin(_dir), _mag2D * cos(_dir), _mag * sin(_elev)];
}; };
private _windSpeed = vectorMagnitude ACE_wind; private _windSpeed = vectorMagnitude wind;
private _windDir = (ACE_wind select 0) atan2 (ACE_wind select 1); private _windDir = (wind select 0) atan2 (wind select 1);
private _windDirAdjusted = _windDir + 180; private _windDirAdjusted = _windDir + 180;
// Wind gradient // Wind gradient

View File

@ -55,7 +55,7 @@ TRACE_1("Starting Wind Info PFEH", GVAR(WindInfo));
private _playerDir = (ACE_player call CBA_fnc_headDir) select 0; private _playerDir = (ACE_player call CBA_fnc_headDir) select 0;
private _windDir = (ACE_wind select 0) atan2 (ACE_wind select 1); private _windDir = (wind select 0) atan2 (wind select 1);
_windDir = 30 * (round(((_windDir - _playerDir + 360) % 360) / 30)); _windDir = 30 * (round(((_windDir - _playerDir + 360) % 360) / 30));
// Color Codes from https://en.wikipedia.org/wiki/Beaufort_scale#Modern_scale // Color Codes from https://en.wikipedia.org/wiki/Beaufort_scale#Modern_scale

View File

@ -43,8 +43,8 @@ GVAR(TempDay) = [1, 3, 9, 14, 19, 23, 25, 24, 21, 13, 7, 2];
GVAR(TempNight) = [-4, -3, 0, 4, 9, 12, 14, 14, 10, 6, 2, -2]; GVAR(TempNight) = [-4, -3, 0, 4, 9, 12, 14, 14, 10, 6, 2, -2];
GVAR(Humidity) = [82, 80, 78, 70, 71, 72, 70, 73, 78, 80, 83, 82]; GVAR(Humidity) = [82, 80, 78, 70, 71, 72, 70, 73, 78, 80, 83, 82];
GVAR(currentTemperature) = 20; GVAR(currentTemperature) = 15;
GVAR(currentHumidity) = 0.5; GVAR(currentHumidity) = 0;
GVAR(currentOvercast) = 0; GVAR(currentOvercast) = 0;
// Get all non inherited arrays to filter maps that inherit from Stratis/Altis/Tanoa // Get all non inherited arrays to filter maps that inherit from Stratis/Altis/Tanoa

View File

@ -1,38 +0,0 @@
/*
* Author: ACE2 Team, Ruthberg
* Calculate current wind locally from the data broadcasted by the server
*
* Arguments:
* None
*
* Return Value:
* Wind <ARRAY>
*
* Example:
* [] call ace_weather_fnc_getWind
*
* Public: No
*/
#include "script_component.hpp"
if (isNil "ACE_WIND_PARAMS") exitWith { [0, 0, 0] };
ACE_WIND_PARAMS params ["_dir", "_dirChange", "_spd", "_spdChange", "_period"];
//Wind _dir is the "source" of the wind [eg: "northerly wind": _dir = 0 -> wind = [0,-1,0];]
private _periodPosition = (CBA_missionTime - GVAR(wind_period_start_time)) min _period;
private _periodPercent = _periodPosition / _period;
_spd = _spd + _spdChange * _periodPercent;
_dir = _dir + _dirChange * _periodPercent;
_dir = (360 + _dir) % 360;
TRACE_1("PeriodStartTime",Round(GVAR(wind_period_start_time)));
TRACE_2("Dir: Current/Change",Round(_dir),Round(_dirChange));
TRACE_2("Spd: Current/Change",Round(_spd * 10) / 10,Round(_spdChange * 10) / 10);
TRACE_3("Period/Position/Percent",Round(_period),Round(_periodPosition),Round(_periodPercent * 100) / 100);
// TODO: Add some deterministic noise
[-_spd * sin(_dir), -_spd * cos(_dir), 0]

View File

@ -22,17 +22,13 @@ params ["_logic", "_units", "_activated"];
if !(_activated) exitWith {}; if !(_activated) exitWith {};
// Control server side weather propagation // Turns the weather module on / off
[_logic, QGVAR(enableServerController), "enableServerController"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(enabled), "enabled"] call EFUNC(common,readSettingFromModule);
// Overrides the default weather (editor, mission settings) with ACE weather (map based)
[_logic, QGVAR(useACEWeather), "useACEWeather"] call EFUNC(common,readSettingFromModule);
// Control client side weather effects
[_logic, QGVAR(syncWind), "syncWind"] call EFUNC(common,readSettingFromModule); // Wind, Gusts, Waves
[_logic, QGVAR(syncMisc), "syncMisc"] call EFUNC(common,readSettingFromModule); // Rainbow, Fog
// Server weather update interval // Server weather update interval
[_logic, QGVAR(serverUpdateInterval), "serverUpdateInterval"] call EFUNC(common,readSettingFromModule); [_logic, QGVAR(updateInterval), "updateInterval"] call EFUNC(common,readSettingFromModule);
GVAR(serverUpdateInterval) = 1 max GVAR(serverUpdateInterval) min 600; // Turns the (map based) wind simulation on / off
[_logic, QGVAR(windSimulation), "windSimulation"] call EFUNC(common,readSettingFromModule);
GVAR(updateInterval) = 1 max GVAR(updateInterval) min 600;

View File

@ -1,6 +1,6 @@
/* /*
* Author: Ruthberg * Author: Ruthberg
* Inits the wind variables on mission start * Inits the wind variables on the server (on mission start)
* *
* Arguments: * Arguments:
* None * None
@ -18,8 +18,6 @@
private _month = date select 1; private _month = date select 1;
private _windDirectionProbabilities = GVAR(WindDirectionProbabilities) select (_month - 1); private _windDirectionProbabilities = GVAR(WindDirectionProbabilities) select (_month - 1);
ACE_wind = [0, 0, 0];
GVAR(wind_direction_reference) = random 360; GVAR(wind_direction_reference) = random 360;
private _sum = 0; private _sum = 0;
for "_i" from 0 to 7 do { for "_i" from 0 to 7 do {
@ -52,10 +50,14 @@ GVAR(max_wind_speed) = GVAR(WindSpeedMax) select (_month - 1);
GVAR(max_wind_speed) = (GVAR(max_wind_speed) select 0) + (random (GVAR(max_wind_speed) select 1)) - (random (GVAR(max_wind_speed) select 1)); GVAR(max_wind_speed) = (GVAR(max_wind_speed) select 0) + (random (GVAR(max_wind_speed) select 1)) - (random (GVAR(max_wind_speed) select 1));
GVAR(max_wind_speed) = 0 max GVAR(max_wind_speed); GVAR(max_wind_speed) = 0 max GVAR(max_wind_speed);
GVAR(wind_upper_span) = GVAR(max_wind_speed) - GVAR(mean_wind_speed);
GVAR(wind_lower_span) = GVAR(min_wind_speed) - GVAR(mean_wind_speed);
GVAR(current_wind_direction) = GVAR(wind_direction_reference); GVAR(current_wind_direction) = GVAR(wind_direction_reference);
GVAR(next_wind_direction) = GVAR(current_wind_direction);
GVAR(current_wind_speed) = GVAR(min_wind_speed) + (GVAR(max_wind_speed) - GVAR(min_wind_speed)) * (random 1); GVAR(current_wind_speed) = GVAR(min_wind_speed) + (GVAR(max_wind_speed) - GVAR(min_wind_speed)) * (random 1);
GVAR(next_wind_speed) = GVAR(current_wind_speed);
GVAR(wind_period_count) = 0; GVAR(last_wind_update) = 0;
GVAR(wind_next_period) = -1; GVAR(next_wind_udpate) = 0;
GVAR(wind_speed_debug_output) = [];

View File

@ -1,33 +0,0 @@
/*
* Author: Ruthberg
* Gather weather parameters and broadcast them to the clients
*
* Arguments:
* None
*
* Return Value:
* None
*
* Example:
* [] call ace_weather_fnc_serverController
*
* Public: No
*/
#include "script_component.hpp"
if (GVAR(useACEWeather)) then {
// Use location based real world weather data
[] call FUNC(updateAceWeather);
} else {
// Simply replicate the server weather on the clients
if (GVAR(syncWind)) then {
//Wind _dir is the "source" of the wind [eg: "northerly wind": _dir = 0 -> wind = [0,-1,0];]
private _windDir = ((((wind select 0) atan2 (wind select 1)) + 180) % 360);
ACE_WIND_PARAMS = [_windDir, 0, vectorMagnitude wind, 0, GVAR(serverUpdateInterval)];
publicVariable "ACE_WIND_PARAMS";
};
if (GVAR(syncMisc)) then {
ACE_MISC_PARAMS = [overcast, rainbow, fogParams, GVAR(temperatureShift), GVAR(badWeatherShift), GVAR(humidityShift)];
publicVariable "ACE_MISC_PARAMS";
};
};

View File

@ -1,107 +0,0 @@
/*
* Author: ACE2 Team, esteldunedain, ruthberg
* Updates the wind and rain evolution on the server. Broadcasts the current and next values to the clients where needed.
*
* Arguments:
* None
*
* Return Value:
* None
*
* Example:
* [] call ace_weather_fnc_updateAceWeather
*
* Public: No
*/
#include "script_component.hpp"
private _overcastMultiplier = 1 max (2* overcast) min 2; // 0 (@ overcast 0), 2 (@ overcast 1)
// Rain simulation
if (GVAR(rain_period_count) > GVAR(rain_next_period)) then {
GVAR(rain_next_period) = ceil((1 + (random 10)) / _overcastMultiplier);
GVAR(rain_period_count) = 0;
private _lastRain = GVAR(current_rain);
private _rainOverCast = 0;
if (overcast >= 0.7) then {
_rainOverCast = (overcast - 0.7) / 0.3;
if (GVAR(current_rain) == 0) then {
// Initialize rain with a random strength depending on the current overcast value
GVAR(current_rain) = -0.25 + (random 0.75) + (random 0.5) * _rainOverCast;
};
GVAR(current_rain) = GVAR(current_rain) + GVAR(current_rain) * ((_rainOverCast * _overcastMultiplier) / 8) * GVAR(rain_current_range);
GVAR(current_rain) = 0 max GVAR(current_rain) min 1;
GVAR(rain_current_range) = -1 + (random 2);
} else {
_rainOverCast = 1;
GVAR(current_rain) = 0;
};
private _transitionTime = 1 + (_rainOverCast * 5) + (random (_rainOverCast * 20));
ACE_RAIN_PARAMS = [_lastRain, GVAR(current_rain), _transitionTime];
TRACE_4("",_lastRain,_rainOverCast,_transitionTime,overcast);
GVAR(rain_period_start_time) = CBA_missionTime;
};
// Wind simulation
if (GVAR(syncWind) && {GVAR(wind_period_count) > GVAR(wind_next_period)}) then {
GVAR(wind_next_period) = ceil((2 + (random 5)) / _overcastMultiplier);
GVAR(wind_period_count) = 0;
private _windDirectionVariance = (90 - (random 180)) * (overcast ^ 2);
private _windDirection = (360 + GVAR(wind_direction_reference) + _windDirectionVariance) % 360;
private _windDirectionChange = _windDirection - GVAR(current_wind_direction);
if (_windDirectionChange > 180) then {
_windDirectionChange = _windDirectionChange - 360;
};
if (_windDirectionChange < -180) then {
_windDirectionChange = 360 + _windDirectionChange;
};
private _windMaxDiff = GVAR(mean_wind_speed) - GVAR(max_wind_speed);
private _windMinDiff = GVAR(min_wind_speed) - GVAR(mean_wind_speed);
private _ratioMax = (random 1) ^ 2;
private _ratioMin = (random 1) ^ 2;
private _windSpeed = GVAR(current_wind_speed);
private _windSpeedChange = 0;
if ((random 1) < (0.3 max overcast)) then {
_windSpeed = GVAR(mean_wind_speed) + _windMaxDiff * _ratioMax + _windMinDiff * _ratioMin;
_windSpeedChange = _windSpeed - GVAR(current_wind_speed);
};
private _transitionTime = GVAR(wind_next_period) * GVAR(serverUpdateInterval);
TRACE_5("dirCur/dirNew/spdCur/spdNew/period",GVAR(current_wind_direction),_windDirection,GVAR(current_wind_speed),_windSpeed,_transitionTime);
ACE_WIND_PARAMS = [GVAR(current_wind_direction),
_windDirectionChange,
GVAR(current_wind_speed),
_windSpeedChange,
_transitionTime];
GVAR(current_wind_direction) = _windDirection;
GVAR(current_wind_speed) = _windSpeed;
GVAR(wind_period_start_time) = CBA_missionTime;
publicVariable "ACE_WIND_PARAMS";
};
if (GVAR(syncMisc)) then {
ACE_MISC_PARAMS = [overcast, rainbow, fogParams, GVAR(temperatureShift), GVAR(badWeatherShift), GVAR(humidityShift)];
publicVariable "ACE_MISC_PARAMS";
};
GVAR(rain_period_count) = GVAR(rain_period_count) + 1;
GVAR(wind_period_count) = GVAR(wind_period_count) + 1;

View File

@ -1,6 +1,6 @@
/* /*
* Author: ACE2 Team * Author: ACE2 Team
* Updates GVAR(currentHumidity) * Smoothly updates GVAR(currentHumidity) on the server (based on time of day and map data)
* *
* Arguments: * Arguments:
* None * None
@ -15,20 +15,18 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
private _month = date select 1; if (rain > 0 && overcast > 0.7) then {
GVAR(currentHumidity) = (GVAR(Humidity) select (_month - 1)) / 100;
if ((rain > 0) && {GVAR(currentOvercast) > 0.7}) then {
GVAR(currentHumidity) = 1; GVAR(currentHumidity) = 1;
} else { } else {
private _month = date select 1;
GVAR(currentHumidity) = (GVAR(Humidity) select (_month - 1)) / 100;
GVAR(currentHumidity) = GVAR(currentHumidity) + GVAR(humidityShift);
private _avgTemperature = ((GVAR(TempDay) select (_month - 1)) + (GVAR(TempNight) select (_month - 1))) / 2; private _avgTemperature = ((GVAR(TempDay) select (_month - 1)) + (GVAR(TempNight) select (_month - 1))) / 2;
private _pS1 = 6.112 * exp((17.62 * _avgTemperature) / (243.12 + _avgTemperature)); private _pS1 = 6.112 * exp((17.62 * _avgTemperature) / (243.12 + _avgTemperature));
private _PS2 = 6.112 * exp((17.62 * GVAR(currentTemperature)) / (243.12 + GVAR(currentTemperature))); private _PS2 = 6.112 * exp((17.62 * GVAR(currentTemperature)) / (243.12 + GVAR(currentTemperature)));
GVAR(currentHumidity) = GVAR(currentHumidity) * _PS1 / _PS2; GVAR(currentHumidity) = GVAR(currentHumidity) * _PS1 / _PS2;
GVAR(currentHumidity) = GVAR(currentHumidity) + GVAR(humidityShift);
TRACE_1("humidityShift",GVAR(humidityShift));
}; };
GVAR(currentHumidity) = 0 max GVAR(currentHumidity) min 1; GVAR(currentHumidity) = 0 max GVAR(currentHumidity) min 1;
publicVariable QGVAR(currentHumidity);

View File

@ -1,24 +0,0 @@
/*
* Author: ACE2 Team, Ruthberg
* Updates rain based on ACE_RAIN_PARAMS
*
* Arguments:
* None
*
* Return Value:
* None
*
* Example:
* [] call ace_weather_fnc_updateRain
*
* Public: No
*/
#include "script_component.hpp"
if (!isNil "ACE_RAIN_PARAMS") then {
ACE_RAIN_PARAMS params ["_oldRain", "_newRain", "_period"];
GVAR(ACE_Rain) = linearConversion [GVAR(rain_period_start_time), (GVAR(rain_period_start_time) + _period), CBA_missionTime, _oldRain, _newRain];
TRACE_3("Update Rain",rain,ACE_RAIN_PARAMS,GVAR(ACE_Rain));
};

View File

@ -1,6 +1,6 @@
/* /*
* Author: ACE2 Team * Author: ACE2 Team
* Updates GVAR(currentTemperature) based on the map data * Smoothly updates GVAR(currentTemperature) on the server (based on time of day and map data)
* *
* Arguments: * Arguments:
* None * None
@ -15,13 +15,11 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
private _time = daytime;
private _month = date select 1; private _month = date select 1;
private _timeRatio = abs(daytime - 12) / 12;
private _timeRatio = abs(_time - 12) / 12;
GVAR(currentTemperature) = (GVAR(TempDay) select (_month - 1)) * (1 - _timeRatio) + (GVAR(TempNight) select (_month - 1)) * _timeRatio; GVAR(currentTemperature) = (GVAR(TempDay) select (_month - 1)) * (1 - _timeRatio) + (GVAR(TempNight) select (_month - 1)) * _timeRatio;
GVAR(currentTemperature) = GVAR(currentTemperature) + GVAR(temperatureShift) - GVAR(badWeatherShift) * GVAR(currentOvercast); GVAR(currentTemperature) = GVAR(currentTemperature) + GVAR(temperatureShift) - GVAR(badWeatherShift) * GVAR(currentOvercast);
GVAR(currentTemperature) = round(GVAR(currentTemperature) * 10) / 10; GVAR(currentTemperature) = round(GVAR(currentTemperature) * 10) / 10;
TRACE_2("temperatureShift/badWeatherShift",GVAR(temperatureShift),GVAR(badWeatherShift)); publicVariable QGVAR(currentTemperature);

View File

@ -0,0 +1,43 @@
/*
* Author: ACE2 Team, esteldunedain, Ruthberg
* Updates the weather evolution on the server. Broadcasts relevant weather information to the clients.
*
* Arguments:
* None
*
* Return Value:
* None
*
* Example:
* [] call ace_weather_fnc_updateWeather
*
* Public: No
*/
#include "script_component.hpp"
missionNamespace setVariable [QGVAR(currentOvercast), overcast, true];
[] call FUNC(updateTemperature);
[] call FUNC(updateHumidity);
// Wind simulation
if (GVAR(windSimulation) && CBA_missionTime > GVAR(next_wind_udpate)) then {
GVAR(current_wind_direction) = GVAR(next_wind_direction);
GVAR(current_wind_speed) = GVAR(next_wind_speed);
private _transitionPeriod = GVAR(updateInterval) * (2 + (random 4)) / (1 + overcast);
GVAR(next_wind_udpate) = CBA_missionTime + _transitionPeriod;
private _windDirectionVariance = (90 - (random 180)) * (overcast ^ 2);
GVAR(next_wind_direction) = (360 + GVAR(wind_direction_reference) + _windDirectionVariance) % 360;
if ((random 1) < (0.3 max overcast)) then {
private _speedVariance = GVAR(wind_upper_span) * (random 1) ^ 2 + GVAR(wind_lower_span) * (random 1) ^ 2;
GVAR(next_wind_speed) = GVAR(mean_wind_speed) + _speedVariance;
};
GVAR(last_wind_update) = CBA_missionTime;
TRACE_5("dirCur/dirNew/spdCur/spdNew/period",GVAR(current_wind_direction),GVAR(next_wind_direction),GVAR(current_wind_speed),GVAR(next_wind_speed),_transitionPeriod);
};

View File

@ -1,6 +1,6 @@
/* /*
* Author: ACE2 Team, Ruthberg * Author: ACE2 Team, Ruthberg
* Updates wind, gusts and waves based on ACE_wind * Smoothly updates wind on the server (based on time of year and map data)
* *
* Arguments: * Arguments:
* None * None
@ -15,21 +15,7 @@
*/ */
#include "script_component.hpp" #include "script_component.hpp"
if (!GVAR(syncWind)) exitWith { ACE_wind = wind }; private _speed = linearConversion [GVAR(last_wind_update), GVAR(next_wind_udpate), CBA_missionTime, GVAR(current_wind_speed), GVAR(next_wind_speed), true];
private _direction = linearConversion [GVAR(last_wind_update), GVAR(next_wind_udpate), CBA_missionTime, GVAR(current_wind_direction), GVAR(next_wind_direction), true];
ACE_wind = [] call FUNC(getWind); setWind [-_speed * sin(_direction), -_speed * cos(_direction), true];
// setWind correctly replicates to clients
if (isServer) then {
setWind [ACE_wind select 0, ACE_wind select 1, true];
};
2 setGusts 0;
// Set waves: 0 when no wind, 1 when wind >= 16 m/s
private _newWaves = ((vectorMagnitude ACE_wind) / 16.0) min 1.0;
if (abs(_newWaves - waves) > 0.1) then {
1 setWaves _newWaves;
};
TRACE_3("Wind/ACE_wind/Deviation(m/s)",wind,ACE_wind,Round((vectorMagnitude (ACE_wind vectorDiff wind)) * 1000) / 1000);

View File

@ -65,39 +65,7 @@
<Chinesesimp>使用ACE天气模块来同步所有客户端的天气状态(多人游戏)</Chinesesimp> <Chinesesimp>使用ACE天气模块来同步所有客户端的天气状态(多人游戏)</Chinesesimp>
<Chinese>使用ACE天氣模塊來同步所有客戶端的天氣狀態(多人遊戲)</Chinese> <Chinese>使用ACE天氣模塊來同步所有客戶端的天氣狀態(多人遊戲)</Chinese>
</Key> </Key>
<Key ID="STR_ACE_Weather_enableServerController_DisplayName"> <Key ID="STR_ACE_Weather_enabled_DisplayName">
<English>Weather propagation</English>
<Polish>Zmiany pogody</Polish>
<Spanish>Propagación del clima</Spanish>
<German>Wetterübertragung</German>
<Czech>Změny počasí</Czech>
<Portuguese>Propagação do clima</Portuguese>
<French>Propagation de la météo</French>
<Hungarian>Időjárás-változás</Hungarian>
<Russian>Единая погода для всех</Russian>
<Italian>Propagazione Meteo</Italian>
<Japanese>天候の統一</Japanese>
<Korean>기후 전파</Korean>
<Chinesesimp>天气状态广播</Chinesesimp>
<Chinese>天氣狀態廣播</Chinese>
</Key>
<Key ID="STR_ACE_Weather_enableServerController_Description">
<English>Enables server side weather propagation</English>
<Polish>Aktywuje zmiany pogody po stronie serwera</Polish>
<Spanish>Permite al servidor controlar la propagación del clima</Spanish>
<German>Aktiviere serverseitige Wetterübertragung</German>
<Czech>Aktivuje změny počasí na straně serveru</Czech>
<Portuguese>Ativa propagação de clima via server</Portuguese>
<French>Active la propagation météo par le serveur</French>
<Hungarian>Engedélyezi a szerveroldali időjárás-változást</Hungarian>
<Russian>Включает управление погодой на серверной стороне</Russian>
<Italian>Abilita propagazione meteo lato server</Italian>
<Japanese>サーバ側による天候の統一を有効化</Japanese>
<Korean>서버의 기후를 전파합니다 </Korean>
<Chinesesimp>启用伺服器的天气状态广播</Chinesesimp>
<Chinese>啟用伺服器的天氣狀態廣播</Chinese>
</Key>
<Key ID="STR_ACE_Weather_useACEWeather_DisplayName">
<English>ACE Weather</English> <English>ACE Weather</English>
<Polish>Pogoda ACE</Polish> <Polish>Pogoda ACE</Polish>
<Spanish>Clima ACE</Spanish> <Spanish>Clima ACE</Spanish>
@ -113,78 +81,11 @@
<Chinesesimp>ACE 天气</Chinesesimp> <Chinesesimp>ACE 天气</Chinesesimp>
<Chinese>ACE 天氣</Chinese> <Chinese>ACE 天氣</Chinese>
</Key> </Key>
<Key ID="STR_ACE_Weather_useACEWeather_Description"> <Key ID="STR_ACE_Weather_enabled_Description">
<English>Overrides the default weather (editor, mission settings) with ACE weather (map based)</English> <English>Expands the existing weather by temperature, humidity and air pressure.</English>
<Polish>Nadpisuje domyślne ustawienia pogody (edytor, wywiad) przy użyciu pogody ACE (zależna od mapy)</Polish> <German>Erweitert das vorhandene Wetter um Temperatur, Luftfeuchtigkeit und Luftdruck.</German>
<Spanish>Sobreescribe el sistema climático por defecto (editor, ajustes de mision) con clima del ACE (basado en el mapa)</Spanish>
<German>Überschreibt das Standardwetter (Editor, Missionseinstellungen) mit dem ACE-Wetter (kartenbasiert)</German>
<Czech>Přepíše výchozí počasí (editor, nastavení mise) s ACE počasím (podle mapy)</Czech>
<Portuguese>Sobreescreve o clima padrão (editor, ajustes de missão) pelo sistema de clima ACE (baseado por mapa)</Portuguese>
<French>Force la métao par défaut (éditeur, paramètres de mission) avec la météo ACE (basé sur la carte)</French>
<Hungarian>Felülbírálja az alapértelmezett időjárást (editor, küldetésbeállítások) az ACE időjárással (térkép-alapú) </Hungarian>
<Russian>Заменяет погоду по-умолчанию (из редактора, настроек миссии) погодой ACE (на основе карты)</Russian>
<Italian>Scavalca il meteo default (editor, parametri missione) con il meteo ACE (basato su mappa)</Italian>
<Japanese>ACE 天候 (マップを元) による標準の天候 (エディタやミッション設定) を上書きします。</Japanese>
<Korean>기존의 기후(에디터, 임무 설정)를 ACE 기후로 치환합니다. (지도에 따라)</Korean>
<Chinesesimp>使ACE天气覆盖预设的天气 (编辑任务设置)</Chinesesimp>
<Chinese>使ACE天氣覆蓋預設的天氣 (編輯任務設置)</Chinese>
</Key> </Key>
<Key ID="STR_ACE_Weather_syncWind_DisplayName"> <Key ID="STR_ACE_Weather_updateInterval_DisplayName">
<English>Sync Wind</English>
<Polish>Synchronizuj wiatr</Polish>
<Spanish>Sincronizar viento</Spanish>
<German>Wind synchronisieren</German>
<Czech>Synchronizuj vítr</Czech>
<Portuguese>Sincronizar vento</Portuguese>
<French>Synchronisation du vent</French>
<Hungarian>Szél szinkronizálása</Hungarian>
<Russian>Синхрониз. ветер</Russian>
<Italian>Sincronizza Vento</Italian>
<Japanese>風を同期</Japanese>
<Korean>바람 동기화</Korean>
<Chinesesimp>同步风</Chinesesimp>
<Chinese>同步風</Chinese>
</Key>
<Key ID="STR_ACE_Weather_syncWind_Description">
<English>Synchronizes wind</English>
<Polish>Synchronizuje wiatr</Polish>
<Spanish>Sincroniza el viento</Spanish>
<German>Synchronisiert den Wind</German>
<Czech>Synchronizace větru</Czech>
<Portuguese>Sincroniza o vento</Portuguese>
<French>Synchronise le vent</French>
<Hungarian>Szinkronizálja a szelet</Hungarian>
<Russian>Синхронизирует ветер</Russian>
<Italian>Sincronizza Vento</Italian>
<Japanese>風を同期</Japanese>
<Korean>바람을 동기화 합니다</Korean>
<Chinesesimp>同步风</Chinesesimp>
<Chinese>同步風</Chinese>
</Key>
<Key ID="STR_ACE_Weather_syncMisc_DisplayName">
<English>Sync Misc</English>
<Polish>Synchronizuj różne</Polish>
<Spanish>Sincronizar otros</Spanish>
<German>Sonstiges synchronisieren</German>
<Czech>Synchronizuj různé</Czech>
<Portuguese>Sincronizar outros</Portuguese>
<French>Synchronisation autres</French>
<Hungarian>Egyéb szinkronizálása</Hungarian>
<Russian>Синхрониз. прочее</Russian>
<Italian>Sincronizza Misto</Italian>
<Japanese>その他を同期</Japanese>
<Korean>기타 동기화</Korean>
<Chinesesimp>同步杂项</Chinesesimp>
<Chinese>同步雜項</Chinese>
</Key>
<Key ID="STR_ACE_Weather_syncMisc_Description">
<English>Synchronizes rainbow, fog, temperature and humidity</English>
<Italian>Sincronizza arcobaleno, nebbia, temperatura e umidità</Italian>
<Chinese>同步彩虹、霧、溫度與濕度</Chinese>
<Chinesesimp>同步彩虹、雾、温度与湿度</Chinesesimp>
<Korean>무지개, 안개, 온도, 습도 동기화</Korean>
</Key>
<Key ID="STR_ACE_Weather_serverUpdateInterval_DisplayName">
<English>Update Interval</English> <English>Update Interval</English>
<Polish>Interwał aktualizacji</Polish> <Polish>Interwał aktualizacji</Polish>
<Spanish>Intervalo de actualización</Spanish> <Spanish>Intervalo de actualización</Spanish>
@ -200,7 +101,7 @@
<Chinesesimp>更新间隔</Chinesesimp> <Chinesesimp>更新间隔</Chinesesimp>
<Chinese>更新間隔</Chinese> <Chinese>更新間隔</Chinese>
</Key> </Key>
<Key ID="STR_ACE_Weather_serverUpdateInterval_Description"> <Key ID="STR_ACE_Weather_updateInterval_Description">
<English>Defines the interval (seconds) between weather updates</English> <English>Defines the interval (seconds) between weather updates</English>
<Polish>Określa interwał (sekundy) pomiędzy aktualizacjami pogody</Polish> <Polish>Określa interwał (sekundy) pomiędzy aktualizacjami pogody</Polish>
<Spanish>Defina el intervalo (en segundos) entre actualizacions de clima</Spanish> <Spanish>Defina el intervalo (en segundos) entre actualizacions de clima</Spanish>
@ -216,5 +117,13 @@
<Chinesesimp>设定天气更新的时间间隔(秒)</Chinesesimp> <Chinesesimp>设定天气更新的时间间隔(秒)</Chinesesimp>
<Chinese>設定天氣更新的時間間隔(秒)</Chinese> <Chinese>設定天氣更新的時間間隔(秒)</Chinese>
</Key> </Key>
<Key ID="STR_ACE_Weather_windSimulation_DisplayName">
<English>Wind Simulation (map based)</English>
<German>Wind Simulation (kartenbasiert)</German>
</Key>
<Key ID="STR_ACE_Weather_windSimulation_Description">
<English>Enables the map based wind simulation (overwrites vanilla wind)</English>
<German>Aktiviert die kartenbasierte Windsimulation (überschreibt Vanilla Wind)</German>
</Key>
</Package> </Package>
</Project> </Project>

View File

@ -24,7 +24,7 @@
_args params ["_lastTime"]; _args params ["_lastTime"];
private _deltaT = CBA_missionTime - _lastTime; private _deltaT = CBA_missionTime - _lastTime;
_args set [0, CBA_missionTime]; _args set [0, CBA_missionTime];
private _isWind = (vectorMagnitude ACE_wind > 0); private _isWind = (vectorMagnitude wind > 0);
{ {
_x params ["_bullet", "_airFriction"]; _x params ["_bullet", "_airFriction"];
@ -36,7 +36,7 @@
GVAR(trackedBullets) deleteAt (GVAR(trackedBullets) find _x); GVAR(trackedBullets) deleteAt (GVAR(trackedBullets) find _x);
} else { } else {
if (_isWind) then { if (_isWind) then {
private _trueVelocity = _bulletVelocity vectorDiff ACE_wind; private _trueVelocity = _bulletVelocity vectorDiff wind;
private _trueSpeed = vectorMagnitude _trueVelocity; private _trueSpeed = vectorMagnitude _trueVelocity;
private _dragRef = _deltaT * _airFriction * _bulletSpeedSqr; private _dragRef = _deltaT * _airFriction * _bulletSpeedSqr;