Refactored the weather module:

* No changes in functionality
This commit is contained in:
ulteq 2015-04-20 13:54:22 +02:00
parent 6c2982548f
commit 89e33dc177
18 changed files with 217 additions and 105 deletions

View File

@ -2,7 +2,6 @@
ADDON = false; ADDON = false;
PREP(calculateAirDensity);
PREP(calculateAmmoTemperatureVelocityShift); PREP(calculateAmmoTemperatureVelocityShift);
PREP(calculateAtmosphericCorrection); PREP(calculateAtmosphericCorrection);
PREP(calculateBarrelLengthVelocityShift); PREP(calculateBarrelLengthVelocityShift);

View File

@ -24,7 +24,7 @@ _pressure = _this select 2; // in hPa
_relativeHumidity = _this select 3; // as ratio 0-1 _relativeHumidity = _this select 3; // as ratio 0-1
_atmosphereModel = _this select 4; // "ICAO" or "ASM" _atmosphereModel = _this select 4; // "ICAO" or "ASM"
_airDensity = [_temperature, _pressure, _relativeHumidity] call FUNC(calculateAirDensity); _airDensity = [_temperature, _pressure, _relativeHumidity] call EFUNC(weather,calculateAirDensity);
if (_atmosphereModel == "ICAO") then { if (_atmosphereModel == "ICAO") then {
(STD_AIR_DENSITY_ICAO / _airDensity) * _ballisticCoefficient (STD_AIR_DENSITY_ICAO / _airDensity) * _ballisticCoefficient

View File

@ -110,7 +110,7 @@ _stabilityFactor = 1.5;
if (_caliber > 0 && _bulletLength > 0 && _bulletMass > 0 && _barrelTwist > 0) then { if (_caliber > 0 && _bulletLength > 0 && _bulletMass > 0 && _barrelTwist > 0) then {
_temperature = GET_TEMPERATURE_AT_HEIGHT((getPosASL _unit) select 2); _temperature = GET_TEMPERATURE_AT_HEIGHT((getPosASL _unit) select 2);
_barometricPressure = 1013.25 * exp(-(EGVAR(weather,Altitude) + ((getPosASL _bullet) select 2)) / 7990) - 10 * overcast; _barometricPressure = ((getPosASL _bullet) select 2) call EFUNC(weather,calculateBarometricPressure);
_stabilityFactor = [_caliber, _bulletLength, _bulletMass, _barrelTwist, _muzzleVelocity, _temperature, _barometricPressure] call FUNC(calculateStabilityFactor); _stabilityFactor = [_caliber, _bulletLength, _bulletMass, _barrelTwist, _muzzleVelocity, _temperature, _barometricPressure] call FUNC(calculateStabilityFactor);
}; };
@ -288,7 +288,7 @@ if (GVAR(AdvancedAirDragEnabled)) then {
}; };
if (GVAR(AtmosphericDensitySimulationEnabled)) then { if (GVAR(AtmosphericDensitySimulationEnabled)) then {
_pressure = 1013.25 * exp(-(EGVAR(weather,Altitude) + (_bulletPosition select 2)) / 7990) - 10 * overcast; _pressure = (_bulletPosition select 2) call EFUNC(weather,calculateBarometricPressure);
_temperature = GET_TEMPERATURE_AT_HEIGHT(_bulletPosition select 2); _temperature = GET_TEMPERATURE_AT_HEIGHT(_bulletPosition select 2);
_humidity = EGVAR(weather,currentHumidity); _humidity = EGVAR(weather,currentHumidity);
_airDensity = STD_AIR_DENSITY_ICAO; _airDensity = STD_AIR_DENSITY_ICAO;
@ -315,7 +315,7 @@ if (GVAR(AdvancedAirDragEnabled)) then {
_bulletVelocity = _bulletVelocity vectorDiff _accel; _bulletVelocity = _bulletVelocity vectorDiff _accel;
} else { } else {
if (GVAR(AtmosphericDensitySimulationEnabled)) then { if (GVAR(AtmosphericDensitySimulationEnabled)) then {
_pressureDeviation = 1013.25 * exp(-(EGVAR(weather,Altitude) + (_bulletPosition select 2)) / 7990) - 1013.25 - 10 * overcast; _pressureDeviation = (_bulletPosition select 2) call EFUNC(weather,calculateBarometricPressure) - 1013.25;
_temperature = GET_TEMPERATURE_AT_HEIGHT(_bulletPosition select 2); _temperature = GET_TEMPERATURE_AT_HEIGHT(_bulletPosition select 2);
_humidity = EGVAR(weather,currentHumidity); _humidity = EGVAR(weather,currentHumidity);
_airFriction = _airFriction + ((_temperature - 15) * 0.0000015 + _humidity * 0.0000040 + _pressureDeviation * -0.0000009); _airFriction = _airFriction + ((_temperature - 15) * 0.0000015 + _humidity * 0.0000040 + _pressureDeviation * -0.0000009);

View File

@ -19,7 +19,7 @@ private ["_playerDir", "_windSpeed", "_windDir", "_crosswind", "_headwind", "_hu
if (isNil QGVAR(MIN) || isNil QGVAR(MAX)) then { if (isNil QGVAR(MIN) || isNil QGVAR(MAX)) then {
_temperature = GET_TEMPERATURE_AT_HEIGHT((getPosASL ACE_player) select 2); _temperature = GET_TEMPERATURE_AT_HEIGHT((getPosASL ACE_player) select 2);
_humidity = EGVAR(weather,currentHumidity); _humidity = EGVAR(weather,currentHumidity);
_barometricPressure = 1013.25 * exp(-(EGVAR(weather,Altitude) + ((getPosASL ACE_player) select 2)) / 7990) - 10 * overcast; _barometricPressure = ((getPosASL ACE_player) select 2) call EFUNC(weather,calculateBarometricPressure);
_altitude = EGVAR(weather,Altitude) + ((getPosASL ACE_player) select 2); _altitude = EGVAR(weather,Altitude) + ((getPosASL ACE_player) select 2);
GVAR(MIN) = [0, 0, 0, 0, _temperature, _humidity, _barometricPressure, _altitude]; GVAR(MIN) = [0, 0, 0, 0, _temperature, _humidity, _barometricPressure, _altitude];
GVAR(MAX) = [0, 0, 0, 0, _temperature, _humidity, _barometricPressure, _altitude]; GVAR(MAX) = [0, 0, 0, 0, _temperature, _humidity, _barometricPressure, _altitude];
@ -82,7 +82,7 @@ GVAR(MAX) set [5, _humidity max (GVAR(MAX) select 5)];
GVAR(TOTAL) set [5, (GVAR(TOTAL) select 5) + _humidity]; GVAR(TOTAL) set [5, (GVAR(TOTAL) select 5) + _humidity];
// BARO // BARO
_barometricPressure = 1013.25 * exp(-(EGVAR(weather,Altitude) + ((getPosASL ACE_player) select 2)) / 7990) - 10 * overcast; _barometricPressure = ((getPosASL ACE_player) select 2) call EFUNC(weather,calculateBarometricPressure);
GVAR(MIN) set [6, (GVAR(MIN) select 6) min _barometricPressure]; GVAR(MIN) set [6, (GVAR(MIN) select 6) min _barometricPressure];
GVAR(MAX) set [6, _barometricPressure max (GVAR(MAX) select 6)]; GVAR(MAX) set [6, _barometricPressure max (GVAR(MAX) select 6)];
GVAR(TOTAL) set [6, (GVAR(TOTAL) select 6) + _barometricPressure]; GVAR(TOTAL) set [6, (GVAR(TOTAL) select 6) + _barometricPressure];

View File

@ -174,7 +174,7 @@ switch (GVAR(Menu)) do {
}; };
case 6: { // BARO case 6: { // BARO
if (!GVAR(MinAvgMax)) then { if (!GVAR(MinAvgMax)) then {
_textCenterBig = Str(round((1013.25 * exp(-(EGVAR(weather,Altitude) + ((getPosASL ACE_player) select 2)) / 7990) - 10 * overcast) * 10) / 10); _textCenterBig = Str(round((((getPosASL ACE_player) select 2) call EFUNC(weather,calculateBarometricPressure)) * 10) / 10);
} else { } else {
_textCenterLine1Left = "Min"; _textCenterLine1Left = "Min";
_textCenterLine2Left = "Avg"; _textCenterLine2Left = "Avg";

View File

@ -1,6 +1,36 @@
//XEH_postInit.sqf
//#define DEBUG_MODE_FULL
#include "script_component.hpp" #include "script_component.hpp"
// Rain variables
GVAR(enableRain) = true;
GVAR(rain_next_period) = -1;
GVAR(rain_period_count) = 0;
GVAR(rain_initial_rain) = 0;
if(overcast >= 0.7) then {
GVAR(rain_initial_rain) = (random ((overcast-0.7)/0.3));
};
GVAR(current_rain) = GVAR(rain_initial_rain);
GVAR(rain_current_range) = -1+(random 2);
GVAR(overcast_multiplier) = 1;
// Wind Variables
ACE_wind = [0, 0, 0];
GVAR(wind_initial_dir) = (random 360);
GVAR(wind_initial_speed) = (overcast*5)+(random (overcast*5)) max 1;
GVAR(wind_mean_speed) = GVAR(wind_initial_speed);
GVAR(wind_mean_dir) = GVAR(wind_initial_dir);
GVAR(wind_current_speed) = GVAR(wind_initial_speed);
GVAR(wind_current_dir) = GVAR(wind_initial_dir);
GVAR(wind_current_range_speed) = -1+(random 2);
GVAR(wind_current_range_dir) = -1+(random 2);
GVAR(wind_next_period) = -1; //ceil((2+random(5))/(GVAR(overcast_multiplier)/10));
GVAR(wind_next_major_period) = -1;
GVAR(wind_period_count) = 0;
GVAR(wind_major_period_count) = 0;
GVAR(wind_total_time) = 0;
GVAR(wind_period_start_time) = time;
call FUNC(getMapData);
"ACE_WIND_PARAMS" addPublicVariableEventHandler { GVAR(wind_period_start_time) = time; }; "ACE_WIND_PARAMS" addPublicVariableEventHandler { GVAR(wind_period_start_time) = time; };
"ACE_RAIN_PARAMS" addPublicVariableEventHandler { GVAR(rain_period_start_time) = time; }; "ACE_RAIN_PARAMS" addPublicVariableEventHandler { GVAR(rain_period_start_time) = time; };
"ACE_MISC_PARAMS" addPublicVariableEventHandler { "ACE_MISC_PARAMS" addPublicVariableEventHandler {
@ -22,66 +52,9 @@
{false}, {false},
[37, [true, false, false]], false, 0] call CBA_fnc_addKeybind; // (SHIFT + K) [37, [true, false, false]], false, 0] call CBA_fnc_addKeybind; // (SHIFT + K)
// Update Wind
simulWeatherSync; simulWeatherSync;
_fnc_updateWind = {
ACE_wind = [] call FUNC(getWind);
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 [FUNC(updateTemperature), 20, []] call CBA_fnc_addPerFrameHandler;
1 setWaves (((vectorMagnitude ACE_wind) / 16.0) min 1.0); [FUNC(updateHumidity), 20, []] call CBA_fnc_addPerFrameHandler;
[FUNC(updateWind), 1, []] call CBA_fnc_addPerFrameHandler;
//systemChat format ["w:%1 %2,ACE_w:%1 %2, w", [wind select 0, wind select 1, ACE_wind select 0, ACE_wind select 1]]; [FUNC(updateRain), 2, []] call CBA_fnc_addPerFrameHandler;
};
[_fnc_updateWind, 1, []] call CBA_fnc_addPerFrameHandler;
// Update Rain
_fnc_updateRain = {
private ["_oldStrength","_rainStrength","_transitionTime","_periodPosition","_periodPercent"];
if(GVAR(enableRain)) then {
if(!isNil "ACE_RAIN_PARAMS" && {!isNil QGVAR(rain_period_start_time)}) then {
_oldStrength = ACE_RAIN_PARAMS select 0;
_rainStrength = ACE_RAIN_PARAMS select 1;
_transitionTime = ACE_RAIN_PARAMS select 2;
_periodPosition = (time - GVAR(rain_period_start_time)) min _transitionTime;
_periodPercent = (_periodPosition/_transitionTime) min 1;
0 setRain ((_periodPercent*(_rainStrength-_oldStrength))+_oldStrength);
};
};
};
[_fnc_updateRain, 2, []] call CBA_fnc_addPerFrameHandler;
// Update Temperature
_fnc_updateTemperature = {
private ["_time","_month","_hourlyCoef","_avgTemperature","_pS1","_pS2"];
_time = daytime;
_month = date select 1;
// Temperature
_hourlyCoef = -0.5 * sin(360 * ((3 + (date select 3))/24 + (date select 4)/1440));
GVAR(currentTemperature) = (GVAR(TempDay) select (_month - 1)) * (1 - _hourlyCoef) + (GVAR(TempNight) select (_month - 1)) * _hourlyCoef;
GVAR(currentTemperature) = GVAR(currentTemperature) - 2 * humidity - 4 * overcast;
GVAR(currentTemperature) = round(GVAR(currentTemperature) * 10) / 10;
// Humidity
GVAR(currentHumidity) = (GVAR(Humidity) select _month) / 100;
if (rain > 0 && overcast > 0.7) then {
GVAR(currentHumidity) = 1;
} else {
_avgTemperature = ((GVAR(TempDay) select (_month - 1)) + (GVAR(TempNight) select (_month - 1))) / 2;
_pS1 = 6.112 * exp((17.62 * _avgTemperature) / (243.12 + _avgTemperature));
_PS2 = 6.112 * exp((17.62 * GVAR(currentTemperature)) / (243.12 + GVAR(currentTemperature)));
GVAR(currentHumidity) = GVAR(currentHumidity) * _PS1 / _PS2;
};
GVAR(currentHumidity) = 0 max GVAR(currentHumidity) min 1;
// @todo: take altitude and humidity into account
GVAR(currentRelativeDensity) = (273.15 + 20) / (273.15 + GVAR(currentTemperature));
};
[_fnc_updateTemperature, 20, []] call CBA_fnc_addPerFrameHandler;

View File

@ -2,44 +2,16 @@
#include "script_component.hpp" #include "script_component.hpp"
ADDON = false; ADDON = false;
LOG(MSG_INIT);
PREP(calculateAirDensity);
PREP(calculateBarometricPressure);
PREP(displayWindInfo); PREP(displayWindInfo);
PREP(getMapData); PREP(getMapData);
PREP(getWind); PREP(getWind);
PREP(serverController); PREP(serverController);
PREP(updateHumidity);
PREP(updateRain);
// Rain variables PREP(updateTemperature);
GVAR(enableRain) = true; PREP(updateWind);
GVAR(rain_next_period) = -1;
GVAR(rain_period_count) = 0;
GVAR(rain_initial_rain) = 0;
if(overcast >= 0.7) then {
GVAR(rain_initial_rain) = (random ((overcast-0.7)/0.3));
};
GVAR(current_rain) = GVAR(rain_initial_rain);
GVAR(rain_current_range) = -1+(random 2);
GVAR(overcast_multiplier) = 1;
// Wind Variables
ACE_wind = [0, 0, 0];
GVAR(wind_initial_dir) = (random 360);
GVAR(wind_initial_speed) = (overcast*5)+(random (overcast*5)) max 1;
GVAR(wind_mean_speed) = GVAR(wind_initial_speed);
GVAR(wind_mean_dir) = GVAR(wind_initial_dir);
GVAR(wind_current_speed) = GVAR(wind_initial_speed);
GVAR(wind_current_dir) = GVAR(wind_initial_dir);
GVAR(wind_current_range_speed) = -1+(random 2);
GVAR(wind_current_range_dir) = -1+(random 2);
GVAR(wind_next_period) = -1; //ceil((2+random(5))/(GVAR(overcast_multiplier)/10));
GVAR(wind_next_major_period) = -1;
GVAR(wind_period_count) = 0;
GVAR(wind_major_period_count) = 0;
GVAR(wind_total_time) = 0;
GVAR(wind_period_start_time) = time;
// Init weather variables, in case they are needed before postInit
call FUNC(getMapData);
ADDON = true; ADDON = true;

View File

@ -0,0 +1,36 @@
/*
* Author: Ruthberg
*
* Calculates the air density
*
* Arguments:
* 0: temperature - degrees celcius <NUMBER>
* 1: pressure - hPa <NUMBER>
* 2: relativeHumidity - value between 0.0 and 1.0 <NUMBER>
*
* Return Value:
* 0: density of air - kg * m^(-3) <NUMBER>
*
* Return value:
* None
*/
#include "script_component.hpp"
private ["_temperature", "_pressure", "_relativeHumidity"];
_temperature = _this select 0; // in C
_pressure = _this select 1; // in hPa
_relativeHumidity = _this select 2; // as ratio 0-1
_pressure = _pressure * 100;
if (_relativeHumidity > 0) then {
private ["_pSat", "_vaporPressure", "_partialPressure"];
// Saturation vapor pressure calculated according to: http://wahiduddin.net/calc/density_algorithms.htm
_pSat = 6.1078 * 10 ^ ((7.5 * _temperature) / (_temperature + 237.3));
_vaporPressure = _relativeHumidity * _pSat;
_partialPressure = _pressure - _vaporPressure;
(_partialPressure * DRY_AIR_MOLAR_MASS + _vaporPressure * WATER_VAPOR_MOLAR_MASS) / (UNIVERSAL_GAS_CONSTANT * KELVIN(_temperature))
} else {
_pressure / (SPECIFIC_GAS_CONSTANT_DRY_AIR * KELVIN(_temperature))
};

View File

@ -0,0 +1,20 @@
/*
* Author: Ruthberg
*
* Calculates the barometric pressure based on altitude and weather
*
* Arguments:
* 0: altitude - meters <NUMBER>
*
* Return Value:
* 0: barometric pressure - hPA <NUMBER>
*
* Return value:
* None
*/
#include "script_component.hpp"
private ["_altitude"];
_altitude = _this;
(1013.25 * exp(-(GVAR(Altitude) + _altitude) / 7990) - 10 * overcast)

View File

@ -1,5 +1,6 @@
/* /*
* Author: Ruthberg * Author: Ruthberg
*
* Displays a wind info (colored arrow) in the top left corner of the screen * Displays a wind info (colored arrow) in the top left corner of the screen
* *
* Argument: * Argument:

View File

@ -1,5 +1,6 @@
/* /*
* Author: Ruthberg, esteldunedain * Author: Ruthberg, esteldunedain
*
* Get the weather data for the current map * Get the weather data for the current map
* *
* Argument: * Argument:
@ -109,3 +110,6 @@ if (worldName in ["Imrali"]) exitWith {
GVAR(TempDay) = [1, 3, 9, 14, 19, 23, 25, 24, 21, 13, 7, 2]; 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(currentHumidity) = 0.5;

View File

@ -1,5 +1,6 @@
/* /*
* Author: ACE2 Team * Author: ACE2 Team
*
* Calculate current wind locally from the data broadcasted by the server * Calculate current wind locally from the data broadcasted by the server
* *
* Argument: * Argument:

View File

@ -1,5 +1,6 @@
/* /*
* Author: ACE2 Team, esteldunedain * Author: ACE2 Team, esteldunedain
*
* Calculate the wind and rain evolution on the server. Broadcast the current and next values to the clients * Calculate the wind and rain evolution on the server. Broadcast the current and next values to the clients
* *
* Argument: * Argument:

View File

@ -0,0 +1,28 @@
/*
* Author: ACE2 Team
*
* Updates GVAR(currentHumidity) based on
*
* Argument:
* Nothing
*
* Return value:
* Nothing
*/
#include "script_component.hpp"
private ["_month", "_avgTemperature", "_pS1", "_pS2"];
_month = date select 1;
GVAR(currentHumidity) = (GVAR(Humidity) select _month) / 100;
if (rain > 0 && overcast > 0.7) then {
GVAR(currentHumidity) = 1;
} else {
_avgTemperature = ((GVAR(TempDay) select (_month - 1)) + (GVAR(TempNight) select (_month - 1))) / 2;
_pS1 = 6.112 * exp((17.62 * _avgTemperature) / (243.12 + _avgTemperature));
_PS2 = 6.112 * exp((17.62 * GVAR(currentTemperature)) / (243.12 + GVAR(currentTemperature)));
GVAR(currentHumidity) = GVAR(currentHumidity) * _PS1 / _PS2;
};
GVAR(currentHumidity) = 0 max GVAR(currentHumidity) min 1;

View File

@ -0,0 +1,26 @@
/*
* Author: ACE2 Team
*
* Updates rain based on ACE_RAIN_PARAMS
*
* Argument:
* Nothing
*
* Return value:
* Nothing
*/
#include "script_component.hpp"
private ["_oldStrength", "_rainStrength", "_transitionTime", "_periodPosition", "_periodPercent"];
if (!GVAR(enableRain)) exitWith {};
if (!isNil "ACE_RAIN_PARAMS" && {!isNil QGVAR(rain_period_start_time)}) then {
_oldStrength = ACE_RAIN_PARAMS select 0;
_rainStrength = ACE_RAIN_PARAMS select 1;
_transitionTime = ACE_RAIN_PARAMS select 2;
_periodPosition = (time - GVAR(rain_period_start_time)) min _transitionTime;
_periodPercent = (_periodPosition/_transitionTime) min 1;
0 setRain ((_periodPercent*(_rainStrength-_oldStrength))+_oldStrength);
};

View File

@ -0,0 +1,22 @@
/*
* Author: ACE2 Team
*
* Updates GVAR(currentTemperature) based on the map data
*
* Argument:
* Nothing
*
* Return value:
* Nothing
*/
#include "script_component.hpp"
private ["_time", "_month", "_hourlyCoef"];
_time = daytime;
_month = date select 1;
_hourlyCoef = -0.5 * sin(360 * ((3 + (date select 3))/24 + (date select 4)/1440));
GVAR(currentTemperature) = (GVAR(TempDay) select (_month - 1)) * (1 - _hourlyCoef) + (GVAR(TempNight) select (_month - 1)) * _hourlyCoef;
GVAR(currentTemperature) = GVAR(currentTemperature) - 2 * humidity - 4 * overcast;
GVAR(currentTemperature) = round(GVAR(currentTemperature) * 10) / 10;

View File

@ -0,0 +1,21 @@
/*
* Author: ACE2 Team
*
* Updates wind, gusts and waves based on ACE_wind
*
* Argument:
* Nothing
*
* Return value:
* Nothing
*/
#include "script_component.hpp"
ACE_wind = [] call FUNC(getWind);
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
1 setWaves (((vectorMagnitude ACE_wind) / 16.0) min 1.0);
//hintSilent format["Wind: %1\nACE_wind: %2\nDeviation: %3 (m/s)", wind, ACE_wind, Round((vectorMagnitude (ACE_wind vectorDiff wind)) * 1000) / 1000];

View File

@ -10,3 +10,11 @@
#endif #endif
#include "\z\ace\addons\main\script_macros.hpp" #include "\z\ace\addons\main\script_macros.hpp"
#define ABSOLUTE_ZERO_IN_CELSIUS -273.15
#define KELVIN(t) (t - ABSOLUTE_ZERO_IN_CELSIUS)
#define CELSIUS(t) (t + ABSOLUTE_ZERO_IN_CELSIUS)
#define UNIVERSAL_GAS_CONSTANT 8.314
#define WATER_VAPOR_MOLAR_MASS 0.018016
#define DRY_AIR_MOLAR_MASS 0.028964
#define SPECIFIC_GAS_CONSTANT_DRY_AIR 287.058