This commit is contained in:
SzwedzikPL 2016-01-25 09:08:50 +01:00
commit 8a2250768d
92 changed files with 813 additions and 402 deletions

View File

@ -28,7 +28,7 @@ if (currentWeapon ACE_player != primaryWeapon ACE_player) exitWith { false };
2 cutText ["", "PLAIN"];
EGVAR(weather,WindInfo) = false;
0 cutText ["", "PLAIN"];
(["RscWindIntuitive"] call BIS_fnc_rscLayer) cutText ["", "PLAIN"];
GVAR(Protractor) = true;
[{

View File

@ -49,7 +49,7 @@ if (_unit == _attachToVehicle) then { //Self Attachment
} else {
GVAR(placeAction) = PLACE_WAITING;
[_unit, QGVAR(vehAttach), true] call EFUNC(common,setForceWalkStatus);
[_unit, "forceWalk", "ACE_Attach", true] call EFUNC(common,statusEffect_set);
[{[localize LSTRING(PlaceAction), ""] call EFUNC(interaction,showMouseHint)}, []] call EFUNC(common,execNextFrame);
_unit setVariable [QGVAR(placeActionEH), [_unit, "DefaultAction", {true}, {GVAR(placeAction) = PLACE_APPROVE;}] call EFUNC(common,AddActionEventHandler)];
@ -88,7 +88,7 @@ if (_unit == _attachToVehicle) then { //Self Attachment
{!([_attachToVehicle, _unit, _itemClassname] call FUNC(canAttach))}) then {
[_idPFH] call CBA_fnc_removePerFrameHandler;
[_unit, QGVAR(vehAttach), false] call EFUNC(common,setForceWalkStatus);
[_unit, "forceWalk", "ACE_Attach", false] call EFUNC(common,statusEffect_set);
[] call EFUNC(interaction,hideMouseHint);
[_unit, "DefaultAction", (_unit getVariable [QGVAR(placeActionEH), -1])] call EFUNC(common,removeActionEventHandler);
_unit removeAction _actionID;

View File

@ -40,12 +40,12 @@ if (_respawn > 3) then {
if (_unit getVariable [QGVAR(isHandcuffed), false]) then {
[_unit, false] call FUNC(setHandcuffed);
};
[_unit, QGVAR(Handcuffed), false] call EFUNC(common,setCaptivityStatus);
[_unit, "setCaptive", QGVAR(Handcuffed), false] call EFUNC(common,statusEffect_set);
if (_unit getVariable [QGVAR(isSurrendering), false]) then {
[_unit, false] call FUNC(setSurrendered);
};
[_unit, QGVAR(Surrendered), false] call EFUNC(common,setCaptivityStatus);
[_unit, "setCaptive", QGVAR(Surrendered), false] call EFUNC(common,statusEffect_set);
if (_oldUnit getVariable [QGVAR(isEscorting), false]) then {
_oldUnit setVariable [QGVAR(isEscorting), false, true];

View File

@ -28,7 +28,7 @@ if ((_unit getVariable [QGVAR(isHandcuffed), false]) isEqualTo _state) exitWith
if (_state) then {
_unit setVariable [QGVAR(isHandcuffed), true, true];
[_unit, QGVAR(Handcuffed), true] call EFUNC(common,setCaptivityStatus);
[_unit, "setCaptive", QGVAR(Handcuffed), true] call EFUNC(common,statusEffect_set);
if (_unit getVariable [QGVAR(isSurrendering), false]) then { //If surrendering, stop
[_unit, false] call FUNC(setSurrendered);
@ -89,7 +89,7 @@ if (_state) then {
}, [_unit], 0.01] call EFUNC(common,waitAndExecute);
} else {
_unit setVariable [QGVAR(isHandcuffed), false, true];
[_unit, QGVAR(Handcuffed), false] call EFUNC(common,setCaptivityStatus);
[_unit, "setCaptive", QGVAR(Handcuffed), false] call EFUNC(common,statusEffect_set);
//remove AnimChanged EH
private _animChangedEHID = _unit getVariable [QGVAR(handcuffAnimEHID), -1];

View File

@ -33,7 +33,7 @@ if (_state) then {
_unit setVariable [QGVAR(isSurrendering), true, true];
[_unit, QGVAR(Surrendered), true] call EFUNC(common,setCaptivityStatus);
[_unit, "setCaptive", QGVAR(Surrendered), true] call EFUNC(common,statusEffect_set);
if (_unit == ACE_player) then {
["captive", [false, false, false, false, false, false, false, false]] call EFUNC(common,showHud);
@ -65,7 +65,7 @@ if (_state) then {
}, [_unit], 0.01] call EFUNC(common,waitAndExecute);
} else {
_unit setVariable [QGVAR(isSurrendering), false, true];
[_unit, QGVAR(Surrendered), false] call EFUNC(common,setCaptivityStatus);
[_unit, "setCaptive", QGVAR(Surrendered), false] call EFUNC(common,statusEffect_set);
//remove AnimChanged EH
private _animChangedEHID = _unit getVariable [QGVAR(surrenderAnimEHID), -1];

View File

@ -23,9 +23,6 @@ class Extended_InitPost_EventHandlers {
class GVAR(setName) {
init = QUOTE(if (local (_this select 0)) then {_this call FUNC(setName)};);
};
class GVAR(forceWalk) {
init = QUOTE(_this call FUNC(applyForceWalkStatus));
};
class GVAR(muteUnit) {
init = QUOTE(_this call FUNC(muteUnitHandleInitPost));
};
@ -43,6 +40,9 @@ class Extended_Respawn_EventHandlers {
class GVAR(RESETDefaults) {
respawn = QUOTE(_this call FUNC(resetAllDefaults));
};
class GVAR(statusEffect) {
respawn = QUOTE(_this call FUNC(statusEffect_respawnEH));
};
};
class CAManBase {
class GVAR(muteUnit) {
@ -50,3 +50,12 @@ class Extended_Respawn_EventHandlers {
};
};
};
class Extended_Local_EventHandlers {
class All {
class GVAR(statusEffect) {
local = QUOTE(_this call FUNC(statusEffect_localEH));
};
};
};

View File

@ -1,5 +1,6 @@
// ACE - Common
// #define ENABLE_PERFORMANCE_COUNTERS
// #define DEBUG_MODE_FULL
#include "script_component.hpp"
@ -57,6 +58,39 @@
// Eventhandlers
//////////////////////////////////////////////////
//Status Effect EHs:
["setStatusEffect", {_this call FUNC(statusEffect_set)}] call FUNC(addEventHandler);
["forceWalk", false, ["ACE_SwitchUnits", "ACE_Attach", "ACE_dragging", "ACE_Explosives", "ACE_Ladder", "ACE_Sandbag", "ACE_refuel", "ACE_rearm", "ACE_dragging"]] call FUNC(statusEffect_addType);
["blockSprint", false, []] call FUNC(statusEffect_addType);
["setCaptive", true, [QEGVAR(captives,Handcuffed), QEGVAR(captives,Surrendered), QEGVAR(medical,unconscious)]] call FUNC(statusEffect_addType);
["blockDamage", false, ["fixCollision"]] call FUNC(statusEffect_addType);
["forceWalk", {
params ["_object", "_set"];
TRACE_2("forceWalk EH",_object,_set);
_object forceWalk (_set > 0);
}] call FUNC(addEventHandler);
["blockSprint", { //Name reversed from `allowSprint` because we want NOR logic
params ["_object", "_set"];
TRACE_2("blockSprint EH",_object,_set);
_object allowSprint (_set == 0);
}] call FUNC(addEventHandler);
["setCaptive", {
params ["_object", "_set"];
TRACE_2("setCaptive EH",_object,_set);
_object setCaptive (_set > 0);
}] call FUNC(addEventHandler);
["blockDamage", { //Name reversed from `allowDamage` because we want NOR logic
params ["_object", "_set"];
if ((_object isKindOf "CAManBase") && {(["ace_medical"] call FUNC(isModLoaded))}) then {
TRACE_2("blockDamage EH (using medical)",_object,_set);
_object setvariable [QEGVAR(medical,allowDamage), (_set == 0), true];
} else {
TRACE_2("blockDamage EH (using allowDamage)",_object,_set);
_object allowDamage (_set == 0);
};
}] call FUNC(addEventHandler);
//Add a fix for BIS's zeus remoteControl module not reseting variables on DC when RC a unit
//This variable is used for isPlayer checks
if (isServer) then {
@ -431,9 +465,6 @@ if (!isNil QGVAR(PreInit_playerChanged_PFHID)) then {
// Eventhandlers for player controlled machines
//////////////////////////////////////////////////
// @todo still needed?
[QGVAR(StateArrested), false, true, QUOTE(ADDON)] call FUNC(defineVariable);
["displayTextStructured", {_this call FUNC(displayTextStructured)}] call FUNC(addEventhandler);
["displayTextPicture", {_this call FUNC(displayTextPicture)}] call FUNC(addEventhandler);

View File

@ -10,7 +10,6 @@ PREP(addToInventory);
PREP(assignedItemFix);
PREP(assignObjectsInList);
PREP(ambientBrightness);
PREP(applyForceWalkStatus);
PREP(ASLToPosition);
PREP(binarizeNumber);
PREP(blurScreen);
@ -53,8 +52,8 @@ PREP(fixLoweredRifleAnimation);
PREP(fixPosition);
PREP(getAllDefinedSetVariables);
PREP(getAllGear);
PREP(getCaptivityStatus);
PREP(getDeathAnim);
PREP(getCaptivityStatus);
PREP(getDefaultAnim);
PREP(getDefinedVariable);
PREP(getDefinedVariableDefault);
@ -170,6 +169,13 @@ PREP(setVariablePublic);
PREP(setVolume);
PREP(sortAlphabeticallyBy);
PREP(showHud);
PREP(statusEffect_addType);
PREP(statusEffect_get);
PREP(statusEffect_localEH);
PREP(statusEffect_resetVariables);
PREP(statusEffect_respawnEH);
PREP(statusEffect_sendEffects);
PREP(statusEffect_set);
PREP(stringCompare);
PREP(stringToColoredText);
PREP(stringRemoveWhiteSpace);
@ -316,6 +322,8 @@ if (isServer) then {
call FUNC(loadSettingsOnServer);
};
GVAR(statusEffect_Names) = [];
GVAR(statusEffect_isGlobal) = [];
//////////////////////////////////////////////////
// Set up PlayerChanged eventhandler for pre init

View File

@ -1,22 +0,0 @@
/*
* Author: Pabst Mirror
* Applys the forceWalk status of an unit. Called from Extended_InitPost_EventHandlers.
*
* Arguments:
* 0: Unit <OBJECT>
*
* Return Value:
* None
*
* Example:
* [ACE_Player] call ace_common_fnc_applyForceWalkStatus
*
* Public: No
*/
#include "script_component.hpp"
params ["_unit"];
private _forceWalkNumber = _unit getVariable ["ACE_forceWalkStatusNumber", 0];
_unit forceWalk (_forceWalkNumber > 0);

View File

@ -15,8 +15,8 @@
// allowDamage requires local object
if (!local _this) exitWith {};
// prevent collision damage, @todo allowDamage API
_this allowDamage false;
// prevent collision damage
[_this, "blockDamage", "fixCollision", true] call FUNC(statusEffect_set);
// re-allow damage after 2 seconds
[{_this allowDamage true}, _this, 2, 0] call EFUNC(common,waitAndExecute);
[{[_this, "blockDamage", "fixCollision", false] call FUNC(statusEffect_set);}, _this, 2] call EFUNC(common,waitAndExecute);

View File

@ -1,6 +1,7 @@
/*
* Author: commy2
* Attempt to fix floating physx with disabled damage after setPosXXX commands.
* Handles the "fixFloating" event
*
* Arguments:
* PhysX object <OBJECT>
@ -16,6 +17,11 @@ params ["_object"];
// setHitPointDamage requires local object
if (!local _object) exitWith {};
//Ignore mans
if (_object isKindOf "CAManBase") exitWith {};
//We need to manually set allowDamage to true for setHitIndex to function
["blockDamage", [_object, 0]] call FUNC(localEvent);
// save and restore hitpoints, see below why
private _hitPointDamages = getAllHitPointsDamage _object;
@ -31,3 +37,8 @@ _object setDamage damage _object;
{
_object setHitIndex [_forEachIndex, _x];
} forEach (_hitPointDamages select 2);
//manually re-enable allowDamage to previous setting (ref statusEffect_funcs)
private _effectVarName = format [QGVAR(effect_%1), "blockDamage"];
private _effectNumber = _object getVariable [_effectVarName, 0];
["blockDamage", [_object, _effectNumber]] call FUNC(localEvent);

View File

@ -14,15 +14,7 @@
params ["_unit"];
private _captivityReasons = missionNamespace getVariable ["ACE_captivityReasons", []];
private _unitCaptivityStatus = [captiveNum _unit, count _captivityReasons] call FUNC(binarizeNumber);
//Now just a wrapper for FUNC(statusEffect_get) [No longer used in ace as of 3.5]
ACE_DEPRECATED("ace_common_fnc_getCaptivityStatus","3.7.0","ace_common_fnc_statusEffect_get");
private _unitCaptivityReasons = [];
{
if (_unitCaptivityStatus select _forEachIndex) then {
_unitCaptivityReasons pushBack _x;
};
} forEach _captivityReasons;
_unitCaptivityReasons
([_unit, "setCaptive"] call FUNC(statusEffect_get)) select 1

View File

@ -17,16 +17,7 @@
params ["_unit"];
private _forceWalkReasons = missionNamespace getVariable ["ACE_forceWalkReasons", []];
private _unitForceWalkNumber = _unit getVariable ["ACE_forceWalkStatusNumber", 0];
private _unitForceWalkStatus = [_unitForceWalkNumber, count _forceWalkReasons] call FUNC(binarizeNumber);
//Now just a wrapper for FUNC(statusEffect_get) [No longer used in ace as of 3.5]
ACE_DEPRECATED("ace_common_fnc_getForceWalkStatus","3.7.0","ace_common_fnc_statusEffect_get");
private _unitForceWalkReasons = [];
{
if (_unitForceWalkStatus select _forEachIndex) then {
_unitForceWalkReasons pushBack _x;
};
} forEach _forceWalkReasons;
_unitForceWalkReasons
([_unit, "forceWalk"] call FUNC(statusEffect_get)) select 1

View File

@ -19,11 +19,6 @@ _unit setVariable ["ACE_isUnconscious", nil, true];
if (isPlayer _unit) then {
[true] call FUNC(setVolume);
// [false] call FUNC(disableKeyInput); //func does not exist
if (["ace_medical"] call FUNC(isModLoaded)) then {
// [false] call EFUNC(medical,effectBlackOut); //func does not exist
};
if !(isNil QGVAR(DISABLE_USER_INPUT_COLLECTION)) then {
// clear all disable user input
@ -40,5 +35,3 @@ if (isPlayer _unit) then {
};
false
} count ([_unit] call FUNC(getAllDefinedSetVariables));
_unit setVariable ["ACE_forceWalkStatusNumber", 0, true];

View File

@ -16,28 +16,7 @@
params ["_unit", "_reason", "_status"];
private _captivityReasons = missionNamespace getVariable ["ACE_captivityReasons", []];
//Now just a wrapper for FUNC(statusEffect_set) [No longer used in ace as of 3.5]
ACE_DEPRECATED("ace_common_fnc_setCaptivityStatus","3.7.0","ace_common_fnc_statusEffect_set");
// register new reason (these reasons are shared publicly, since units can change ownership, but keep their captivity status)
if !(_reason in _captivityReasons) then {
_captivityReasons pushBack _reason;
ACE_captivityReasons = _captivityReasons;
publicVariable "ACE_captivityReasons";
};
// get reasons why the unit is captive already and update to the new status
private _unitCaptivityReasons = _unit call FUNC(getCaptivityStatus);
private _captivityReasonsBooleans = [];
{
_captivityReasonsBooleans set [_forEachIndex, (_captivityReasons select _forEachIndex) in _unitCaptivityReasons];
} forEach _captivityReasons;
_captivityReasonsBooleans set [_captivityReasons find _reason, _status];
private _bitmask = _captivityReasonsBooleans call FUNC(toBitmask);
// actually apply the setCaptive command globaly
[[_unit, _bitmask], "{(_this select 0) setCaptive (_this select 1)}", _unit] call FUNC(execRemoteFnc);
[_unit, "setCaptive", _reason, _status] call FUNC(statusEffect_set);

View File

@ -20,29 +20,7 @@
params ["_unit", "_reason", "_status"];
private _forceWalkReasons = missionNamespace getVariable ["ACE_forceWalkReasons", []];
//Now just a wrapper for FUNC(statusEffect_set) [No longer used in ace as of 3.5]
ACE_DEPRECATED("ace_common_fnc_setForceWalkStatus","3.7.0","ace_common_fnc_statusEffect_set");
// register new reason (these reasons are shared publicly, since units can change ownership, but keep their forceWalk status)
if !(_reason in _forceWalkReasons) then {
_forceWalkReasons pushBack _reason;
ACE_forceWalkReasons = _forceWalkReasons;
publicVariable "ACE_forceWalkReasons";
};
// get reasons why the unit is forceWalking already and update to the new status
private _unitForceWalkReasons = [_unit] call FUNC(getForceWalkStatus);
private _forceWalkReasonsBooleans = [];
{
_forceWalkReasonsBooleans set [_forEachIndex, (_forceWalkReasons select _forEachIndex) in _unitForceWalkReasons];
} forEach _forceWalkReasons;
_forceWalkReasonsBooleans set [_forceWalkReasons find _reason, _status];
private _bitmaskNumber = _forceWalkReasonsBooleans call FUNC(toBitmask);
_unit setVariable ["ACE_forceWalkStatusNumber", _bitmaskNumber, true];
// actually apply the forceWalk command globaly
[[_unit], QFUNC(applyForceWalkStatus), 2] call FUNC(execRemoteFnc);
[_unit, "forceWalk", _reason, _status] call FUNC(statusEffect_set);

View File

@ -0,0 +1,37 @@
/*
* Author: PabstMirror
* Adds a status effect that will be handled.
*
* Arguments:
* 0: Status Effect Name, this should match a corisponding event name <STRING>
* 1: Send event globaly <BOOL>
* 2: Common Effect Reaons to pre-seed durring init <ARRAY>
*
* Return Value:
* Nothing
*
* Example:
* ["setCaptive", true, []] call ace_common_fnc_statusEffect_addType
*
* Public: No
*/
// #define DEBUG_MODE_FULL
#include "script_component.hpp"
params [["_name", "", [""]], ["_isGlobal", false, [false]], ["_commonReasonsArray", [], [[]]]];
TRACE_3("params",_name,_isGlobal,_commonReasonsArray);
if (_name == "") exitWith {ACE_LOGERROR_1("addStatusEffect - Bad Name %1", _this)};
if (_name in GVAR(statusEffect_Names)) exitWith {ACE_LOGWARNING_1("addStatusEffect - Effect Already Added (note, will not update global bit) %1", _this)};
GVAR(statusEffect_Names) pushBack _name;
GVAR(statusEffect_isGlobal) pushBack _isGlobal;
//We add reasons at any time, but more efficenet to add all common ones at one time during init
if (isServer && {!(_commonReasonsArray isEqualTo [])}) then {
//Switch case to lower:
{
_commonReasonsArray set [_forEachIndex, toLower _x];
} forEach _commonReasonsArray;
missionNamespace setVariable [(format [QGVAR(statusEffects_%1), _name]), _commonReasonsArray, true];
};

View File

@ -0,0 +1,63 @@
/*
* Author: PabstMirror
* Retrives list of current status effects
*
* Arguments:
* 0: vehicle that it will be attached to (player or vehicle) <OBJECT>
* 1: Effect Name <STRING>
*
* Return Value:
* Effect status <ARRAY>
* 0: is activly set (if false, the effect is ignored and never modified) <BOOL>
* 1: reasons why it is set true (list of strings, count of 0 = false, 1+ = true) <ARRAY>
*
* Example:
* [player, "forceWalk"] call ace_common_fnc_statusEffect_get
*
* Public: Yes
*/
// #define DEBUG_MODE_FULL
#include "script_component.hpp"
params [["_object", objNull, [objNull]], ["_effectName", "", [""]]];
TRACE_2("params",_object,_effectName);
if (isNull _object) exitWith {
TRACE_1("null",_object);
[false, []]
};
[_object, false] call FUNC(statusEffect_resetVariables); //Check for mismatch
//List of reasons
private _statusReasons = missionNamespace getVariable [(format [QGVAR(statusEffects_%1), _effectName]), []];
if (_statusReasons isEqualTo []) exitWith {
TRACE_1("no reasons - bad effect?",_statusReasons);
[false, []]
};
//Get Effect Number
private _effectVarName = format [QGVAR(effect_%1), _effectName];
private _effectNumber = _object getVariable [_effectVarName, -1];
TRACE_2("current",_effectVarName,_effectNumber);
if (_effectNumber == -1) exitWith { //Nil array - no effect
[false, []]
};
if (_effectNumber == 0) exitWith { //empty array - false effect
[true, []]
};
//if no change: skip sending publicVar and events
private _effectBoolArray = [_effectNumber, count _statusReasons] call FUNC(binarizeNumber);
TRACE_2("bitArray",_statusIndex,_effectBoolArray);
private _activeEffects = [];
{
if (_x) then {
_activeEffects pushBack (_statusReasons select _forEachIndex);
};
} forEach _effectBoolArray;
//non-empty array - true effect
[true, _activeEffects]

View File

@ -0,0 +1,36 @@
/*
* Author: PabstMirror
* Handles locality switch, runs a respawn check and then reapplies all effect events.
*
* Arguments:
* 0: vehicle that it will be attached to (player or vehicle) <OBJECT>
*
* Return Value:
* Nothing
*
* Example:
* [player, true] call ace_common_fnc_statusEffect_localEH
*
* Public: No
*/
// #define DEBUG_MODE_FULL
#include "script_component.hpp"
params ["_object", "_isLocal"];
TRACE_2("params",_object,_isLocal);
//Only run this after the settings are initialized
//Need to wait for all EH to be installed (local event will happen between pre and post init)
if !(GVAR(settingsInitFinished)) exitWith {
TRACE_1("pushing to runAtSettingsInitialized", _this);
GVAR(runAtSettingsInitialized) pushBack [FUNC(statusEffect_localEH), _this];
};
if (!_isLocal) exitWith {TRACE_1("object no longer local", _this)};
if (isNull _object) exitWith {TRACE_1("object null", _this)};
//Reset any variables because of respawn
[_object, false] call FUNC(statusEffect_resetVariables);
//Send all Variables to client
[_object, ""] call FUNC(statusEffect_sendEffects);

View File

@ -0,0 +1,45 @@
/*
* Author: PabstMirror
* Resets all effect numbers to 0 when an object respawns (but does not apply the effect event).
*
* Arguments:
* 0: vehicle that it will be attached to (player or vehicle) <OBJECT>
*
* Return Value:
* Nothing
*
* Example:
* [player, true] call ace_common_fnc_statusEffect_resetVariables
*
* Public: No
*/
// #define DEBUG_MODE_FULL
#include "script_component.hpp"
params [["_object", objNull, [objNull]], ["_setObjectRef", false, [false]]];
TRACE_2("params",_object,_setObjectRef);
if (isNull _object) exitWith {};
private _objectRef = _object getVariable QGVAR(statusEffect_object);
TRACE_2("testing",_object,_objectRef);
// If nothing was ever set, or objects match, exit (always true unless respawned)
if (isNil "_objectRef") exitWith {
if (_setObjectRef) then {
_object setVariable [QGVAR(statusEffect_object), _object, true]; //explicitly set new object ref
};
};
if (_object == _objectRef) exitWith {};
//Mismatch, so if effect has ever been defined, reset to 0
{
private _effectVarName = format [QGVAR(effect_%1), _x];
private _effectNumber = _object getVariable [_effectVarName, -1];
if (_effectNumber != -1) then {
TRACE_2("forced reset defined array on object mismatch",_x,_effectNumber);
_object setVariable [_effectVarName, 0, true]; //This always resets to 0 (not -1/nil)!
};
} forEach GVAR(statusEffect_Names);
_object setVariable [QGVAR(statusEffect_object), _object, true];

View File

@ -0,0 +1,36 @@
/*
* Author: PabstMirror
* Handles the Respawn Event Handler to reset effects.
*
* Arguments:
* 0: vehicle that it will be attached to (player or vehicle) <OBJECT>
*
* Return Value:
* Nothing
*
* Example:
* [player, objNull] call ace_common_fnc_statusEffect_respawnEH
*
* Public: No
*/
// #define DEBUG_MODE_FULL
#include "script_component.hpp"
params ["_object"];
TRACE_1("params",_object);
//Only run this after the settings are initialized
//Need to wait for all EH to be installed (local event will happen between pre and post init)
if !(GVAR(settingsInitFinished)) exitWith {
TRACE_1("pushing to runAtSettingsInitialized", _this);
GVAR(runAtSettingsInitialized) pushBack [FUNC(statusEffect_respawnEH), _this];
};
if (!local _object) exitWith {TRACE_1("object no longer local", _this)};
if (isNull _object) exitWith {TRACE_1("object null", _this)};
//Reset any variables on "real" respawn
[_object, false] call FUNC(statusEffect_resetVariables);
//Send all Variables to client
[_object, ""] call FUNC(statusEffect_sendEffects);

View File

@ -0,0 +1,48 @@
/*
* Author: PabstMirror
* Sends all status effects for an object (can be run on non-local objects)
*
* Arguments:
* 0: Object <OBJECT>
* 1: Effect name (or "" or send all) <STRING>
*
* Return Value:
* Nothing
*
* Example:
* [player, ""] call ace_common_fnc_statusEffect_sendEffects
*
* Public: No
*/
// #define DEBUG_MODE_FULL
#include "script_component.hpp"
params [["_object", objNull, [objNull]], ["_effectName", "", [""]]];
TRACE_2("params",_object,_effectName);
if (isNull _object) exitWith {};
{
if ((_effectName == "") || {_effectName == _x}) then {
private _effectVarName = format [QGVAR(effect_%1), _x];
private _effectNumber = _object getVariable [_effectVarName, -1];
//We only do anything if the effect has been defined at some point in the game for this unit
TRACE_2("checking if event is nil",_x,_effectNumber);
if (_effectNumber != -1) then {
if (GVAR(statusEffect_isGlobal) select _forEachIndex) then {
TRACE_2("Sending Global Event", _object, _effectNumber);
[_x, [_object, _effectNumber]] call FUNC(globalEvent);
} else {
if (local _object) then {
//If local, send directly to bypass network delay of targetEvent call
TRACE_2("Sending Target Local Event", _object, _effectNumber);
[_x, [_object, _effectNumber]] call FUNC(localEvent);
} else {
TRACE_2("Sending Target Non-Local Event", _object, _effectNumber);
[_x, [_object], [_object, _effectNumber]] call FUNC(targetEvent);
};
};
};
};
} forEach GVAR(statusEffect_Names);

View File

@ -0,0 +1,70 @@
/*
* Author: PabstMirror
* Adds or removes an id to a status effect and will send an event to apply.
*
* Arguments:
* 0: vehicle that it will be attached to (player or vehicle) <OBJECT>
* 1: Effect Name <STRING>
* 2: Unique Reason ID <STRING>
* 3: Is Set (true adds/false removes) <BOOL>
*
* Return Value:
* Nothing
*
* Example:
* [player, "setCaptive", "reason1", true] call ace_common_fnc_statusEffect_set
*
* Public: Yes
*/
// #define DEBUG_MODE_FULL
#include "script_component.hpp"
params [["_object", objNull, [objNull]], ["_effectName", "", [""]], ["_ID", "", [""]], ["_set", true, [false]]];
TRACE_4("params",_object,_effectName,_ID,_set);
//Only run this after the settings are initialized
if !(GVAR(settingsInitFinished)) exitWith {
TRACE_1("pushing to runAtSettingsInitialized", _this);
GVAR(runAtSettingsInitialized) pushBack [FUNC(statusEffect_set), _this];
};
if (isNull _object) exitWith {TRACE_1("null",_object);};
[_object, true] call FUNC(statusEffect_resetVariables); //Check for mismatch, and set object ref
//check ID case and set globaly if not already set:
_ID = toLower _ID;
private _statusReasons = missionNamespace getVariable [(format [QGVAR(statusEffects_%1), _effectName]), []];
private _statusIndex = _statusReasons find _ID;
if (_statusIndex == -1) then {
TRACE_2("ID not in global reasons, adding",_statusReasons,_ID);
_statusIndex = _statusReasons pushBack _ID;
missionNamespace setVariable [(format [QGVAR(statusEffects_%1), _effectName]), _statusReasons, true];
};
private _effectVarName = format [QGVAR(effect_%1), _effectName];
private _effectNumber = _object getVariable [_effectVarName, -1];
TRACE_2("current",_effectVarName,_effectNumber);
if ((_effectNumber == -1) && {!_set}) exitWith {
//Optimization for modules that always set an ID to false even if never set true
TRACE_2("Set False on nil array, exiting",_set,_effectNumber);
};
if (_effectNumber == -1) then {_effectNumber = 0}; //reset (-1/nil) to 0
//if no change: skip sending publicVar and events
private _effectBoolArray = [_effectNumber, count _statusReasons] call FUNC(binarizeNumber);
TRACE_2("bitArray",_statusIndex,_effectBoolArray);
if (_set isEqualTo (_effectBoolArray select _statusIndex)) exitWith {
TRACE_2("No Change, exiting",_set,_effectBoolArray select _statusIndex);
};
TRACE_2("Setting to new value",_set,_effectBoolArray select _statusIndex);
_effectBoolArray set [_statusIndex, _set];
_effectNumber = _effectBoolArray call FUNC(toBitmask); //Convert array back to number
TRACE_2("Saving globaly",_effectVarName,_effectNumber);
_object setVariable [_effectVarName, _effectNumber, true];
[_object, _effectName] call FUNC(statusEffect_sendEffects);

View File

@ -2,6 +2,7 @@
#include "\z\ace\addons\main\script_mod.hpp"
// #define DEBUG_MODE_FULL
// #define CBA_DEBUG_SYNCHRONOUS
#ifdef DEBUG_ENABLED_COMMON
#define DEBUG_MODE_FULL

View File

@ -48,7 +48,7 @@ _unit removeWeapon "ACE_FakePrimaryWeapon";
// reselect weapon and re-enable sprint
_unit selectWeapon primaryWeapon _unit;
[_unit, "isDragging", false] call EFUNC(common,setforceWalkStatus);
[_unit, "forceWalk", "ACE_dragging", false] call EFUNC(common,statusEffect_set);
// prevent object from flipping inside buildings
if (_inBuilding) then {

View File

@ -53,7 +53,7 @@ if (_target isKindOf "CAManBase") then {
_unit action ["SwitchWeapon", _unit, _unit, 99];
[_unit, "AmovPercMstpSnonWnonDnon", 0] call EFUNC(common,doAnimation);
[_unit, "isDragging", true] call EFUNC(common,setforceWalkStatus);
[_unit, "forceWalk", "ACE_dragging", true] call EFUNC(common,statusEffect_set);
};

View File

@ -32,7 +32,7 @@ if (!isClass (configFile >> "CfgVehicles" >> _setupObjectClass)) exitWith {ERROR
_p3dModel = getText (configFile >> "CfgVehicles" >> _setupObjectClass >> "model");
if (_p3dModel == "") exitWith {ERROR("No Model");}; //"" - will crash game!
[_unit, "ACE_Explosives", true] call EFUNC(common,setForceWalkStatus);
[_unit, "forceWalk", "ACE_Explosives", true] call EFUNC(common,statusEffect_set);
//Show mouse buttons:
[localize LSTRING(PlaceAction), localize LSTRING(CancelAction), localize LSTRING(ScrollAction)] call EFUNC(interaction,showMouseHint);
@ -152,7 +152,7 @@ GVAR(TweakedAngle) = 0;
[_pfID] call CBA_fnc_removePerFrameHandler;
GVAR(pfeh_running) = false;
[_unit, "ACE_Explosives", false] call EFUNC(common,setForceWalkStatus);
[_unit, "forceWalk", "ACE_Explosives", false] call EFUNC(common,statusEffect_set);
[] call EFUNC(interaction,hideMouseHint);
[_unit, "DefaultAction", (_unit getVariable [QGVAR(placeActionEH), -1])] call EFUNC(common,removeActionEventHandler);
[_unit, "zoomtemp", (_unit getVariable [QGVAR(cancelActionEH), -1])] call EFUNC(common,removeActionEventHandler);

View File

@ -2,6 +2,9 @@
if (!hasInterface) exitWith {};
GVAR(cacheAmmoLoudness) = createLocation ["ACE_HashLocation", [-10000,-10000,-10000], 0, 0];
GVAR(cacheAmmoLoudness) setText QGVAR(cacheAmmoLoudness);
GVAR(deafnessDV) = 0;
GVAR(deafnessPrior) = 0;
GVAR(volume) = 1;

View File

@ -28,11 +28,12 @@ if (_unit getVariable ["ACE_hasEarPlugsin", false]) then {
//headgear hearing protection
if(headgear _unit != "") then {
private ["_protection"];
_protection = (getNumber (configFile >> "CfgWeapons" >> (headgear _unit) >> QGVAR(protection))) min 1;
private _protection = (getNumber (configFile >> "CfgWeapons" >> (headgear _unit) >> QGVAR(protection))) min 1;
if(_protection > 0) then {
_strength = _strength * (1 - _protection);
};
};
TRACE_2("adding",_strength,GVAR(deafnessDV));
GVAR(deafnessDV) = GVAR(deafnessDV) + _strength;

View File

@ -32,31 +32,28 @@ if ((ACE_player != _object) && {(vehicle ACE_player) != _object}) exitWith {};
if (_weapon in ["Throw", "Put"]) exitWith {};
if (_distance > 50) exitWith {};
private ["_silencer", "_audibleFireCoef", "_loudness", "_strength", "_vehAttenuation", "_magazine", "_muzzles", "_weaponMagazines", "_muzzleMagazines", "_ammoType", "_initSpeed", "_ammoConfig", "_caliber"];
private _vehAttenuation = if ((ACE_player == (vehicle ACE_player)) || {isTurnedOut ACE_player}) then {1} else {GVAR(playerVehAttenuation)};
private _distance = 1 max _distance;
_vehAttenuation = if ((ACE_player == (vehicle ACE_player)) || {isTurnedOut ACE_player}) then {1} else {GVAR(playerVehAttenuation)};
_distance = 1 max _distance;
_silencer = switch (_weapon) do {
private _silencer = switch (_weapon) do {
case (primaryWeapon _firer) : {(primaryWeaponItems _firer) select 0};
case (secondaryWeapon _firer) : {(secondaryWeaponItems _firer) select 0};
case (handgunWeapon _firer) : {(handgunItems _firer) select 0};
default {""};
};
_audibleFireCoef = 1;
private _audibleFireCoef = 1;
if (_silencer != "") then {
_audibleFireCoef = getNumber (configFile >> "CfgWeapons" >> _silencer >> "ItemInfo" >> "AmmoCoef" >> "audibleFire");
};
_weaponMagazines = missionNamespace getVariable [format[QEGVAR(common,weaponMagazines_%1),_weapon], []];
if (count _weaponMagazines == 0) then {
_muzzles = getArray (configFile >> "CfgWeapons" >> _weapon >> "muzzles");
_weaponMagazines = getArray (configFile >> "CfgWeapons" >> _weapon >> "magazines");
private _loudness = GVAR(cacheAmmoLoudness) getVariable (format ["%1%2",_weapon,_ammo]);
if (isNil "_loudness") then {
private _muzzles = getArray (configFile >> "CfgWeapons" >> _weapon >> "muzzles");
private _weaponMagazines = getArray (configFile >> "CfgWeapons" >> _weapon >> "magazines");
{
if (_x != "this") then {
_muzzleMagazines = getArray (configFile >> "CfgWeapons" >> _weapon >> _x >> "magazines");
private _muzzleMagazines = getArray (configFile >> "CfgWeapons" >> _weapon >> _x >> "magazines");
_weaponMagazines append _muzzleMagazines;
};
} count _muzzles;
@ -64,34 +61,39 @@ if (count _weaponMagazines == 0) then {
_ammoType = getText(configFile >> "CfgMagazines" >> _x >> "ammo");
_weaponMagazines set [_forEachIndex, [_x, _ammoType]];
} forEach _weaponMagazines;
missionNamespace setVariable [format[QEGVAR(common,weaponMagazines_%1),_weapon], _weaponMagazines];
};
_magazine = "";
{
_x params ["_magazineType", "_ammoType"];
if (_ammoType == _ammo) exitWith {
_magazine = _magazineType;
private _magazine = "";
{
_x params ["_magazineType", "_ammoType"];
if (_ammoType == _ammo) exitWith {
_magazine = _magazineType;
};
} count _weaponMagazines;
if (_magazine == "") then {
_loudness = 0;
TRACE_2("No mag for Weapon/Ammo??",_weapon,_ammo);
} else {
private _initSpeed = getNumber(configFile >> "CfgMagazines" >> _magazine >> "initSpeed");
private _caliber = getNumber (configFile >> "CfgAmmo" >> _ammo >> "ACE_caliber");
_caliber = call {
if (_ammo isKindOf ["ShellBase", (configFile >> "CfgAmmo")]) exitWith { 80 };
if (_ammo isKindOf ["RocketBase", (configFile >> "CfgAmmo")]) exitWith { 200 };
if (_ammo isKindOf ["MissileBase", (configFile >> "CfgAmmo")]) exitWith { 600 };
if (_ammo isKindOf ["SubmunitionBase", (configFile >> "CfgAmmo")]) exitWith { 80 };
if (_caliber <= 0) then { 6.5 } else { _caliber };
};
_loudness = (_caliber ^ 1.25 / 10) * (_initspeed / 1000) / 5;
TRACE_6("building cache",_weapon,_ammo,_magazine,_initSpeed,_caliber,_loudness);
};
} count _weaponMagazines;
if (_magazine == "") exitWith {};
_initSpeed = getNumber(configFile >> "CfgMagazines" >> _magazine >> "initSpeed");
_ammoConfig = (configFile >> "CfgAmmo" >> _ammo);
_caliber = getNumber(_ammoConfig >> "ACE_caliber");
_caliber = call {
if (_ammo isKindOf ["ShellBase", (configFile >> "CfgAmmo")]) exitWith { 80 };
if (_ammo isKindOf ["RocketBase", (configFile >> "CfgAmmo")]) exitWith { 200 };
if (_ammo isKindOf ["MissileBase", (configFile >> "CfgAmmo")]) exitWith { 600 };
if (_ammo isKindOf ["SubmunitionBase", (configFile >> "CfgAmmo")]) exitWith { 80 };
if (_caliber <= 0) then { 6.5 } else { _caliber };
GVAR(cacheAmmoLoudness) setVariable [(format ["%1%2",_weapon,_ammo]), _loudness];
};
_loudness = (_caliber ^ 1.25 / 10) * (_initspeed / 1000) * _audibleFireCoef / 5;
_strength = _vehAttenuation * (_loudness - (_loudness / 50 * _distance)); // linear drop off
//systemChat format["%1 : %2", _strength, _initSpeed];
//systemChat format["%1 : %2 : %3", _weapon, _magazine, _initSpeed];
_loudness = _loudness * _audibleFireCoef;
private _strength = _vehAttenuation * (_loudness - (_loudness / 50 * _distance)); // linear drop off
TRACE_1("result",_strength);
if (_strength < 0.01) exitWith {};

View File

@ -1,6 +1,6 @@
/*
* Author: commy2 and esteldunedain and Ruthberg
* Updates and applys the current deafness. Called every 0.1 sec from a PFEH.
* Updates and applys the current deafness. Called every 1 sec from a PFEH.
*
* Arguments:
* 0: Args <ARRAY>
@ -19,7 +19,6 @@
//Only run if deafness or ear ringing is enabled:
if ((!GVAR(enableCombatDeafness)) && GVAR(DisableEarRinging)) exitWith {};
private["_volume", "_soundTransitionTime"];
(_this select 0) params ["_justUpdateVolume"];
@ -71,7 +70,7 @@ if (!_justUpdateVolume) then {
if ((missionNameSpace getVariable [QGVAR(disableVolumeUpdate), false]) || {!GVAR(enableCombatDeafness)}) exitWith {};
_volume = GVAR(volume);
private _volume = GVAR(volume);
// Earplugs reduce hearing 50%
if ([ACE_player] call FUNC(hasEarPlugsIn)) then {
@ -92,7 +91,7 @@ if (ACE_player getVariable ["ACE_isUnconscious", false]) then {
_volume = _volume min GVAR(UnconsciousnessVolume);
};
_soundTransitionTime = if (_justUpdateVolume) then {0.1} else {1};
private _soundTransitionTime = if (_justUpdateVolume) then {0.1} else {1};
_soundTransitionTime fadeSound _volume;
_soundTransitionTime fadeSpeech _volume;

View File

@ -7,7 +7,7 @@ params ["_unit"];
// Reset captive status for respawning unit
if (!(_unit getVariable ["ACE_isUnconscious", false])) then {
[_unit, QGVAR(unconscious), false] call EFUNC(common,setCaptivityStatus);
[_unit, "setCaptive", QGVAR(unconscious), false] call EFUNC(common,statusEffect_set);
};
// Remove maximum unconsciousness time handler

View File

@ -95,7 +95,7 @@ if (GVAR(moveUnitsFromGroupOnUnconscious)) then {
[_unit, true, "ACE_isUnconscious", side group _unit] call EFUNC(common,switchToGroupSide);
};
[_unit, QGVAR(unconscious), true] call EFUNC(common,setCaptivityStatus);
[_unit, "setCaptive", QGVAR(unconscious), true] call EFUNC(common,statusEffect_set);
_anim = [_unit] call EFUNC(common,getDeathAnim);
[_unit, _anim, 1, true] call EFUNC(common,doAnimation);
[{

View File

@ -33,7 +33,7 @@ if (!alive _unit) exitWith {
if (GVAR(moveUnitsFromGroupOnUnconscious)) then {
[_unit, false, "ACE_isUnconscious", side group _unit] call EFUNC(common,switchToGroupSide);
};
[_unit, QGVAR(unconscious), false] call EFUNC(common,setCaptivityStatus);
[_unit, "setCaptive", QGVAR(unconscious), false] call EFUNC(common,statusEffect_set);
[_unit, false] call EFUNC(common,disableAI);
//_unit setUnitPos _originalPos;
_unit setUnconscious false;
@ -102,7 +102,7 @@ if !(_unit getVariable ["ACE_isUnconscious",false]) exitWith {
};
if (!_hasMovedOut) then {
// Reset the unit back to the previous captive state.
[_unit, QGVAR(unconscious), false] call EFUNC(common,setCaptivityStatus);
[_unit, "setCaptive", QGVAR(unconscious), false] call EFUNC(common,statusEffect_set);
// Swhich the unit back to its original group
//Unconscious units shouldn't be put in another group #527:

View File

@ -36,7 +36,7 @@ if (_actionID != -1) then {
_unit removeAction _actionID;
_unit setVariable [QGVAR(ReleaseActionID), nil];
};
[_unit, QGVAR(vehRearm), false] call EFUNC(common,setForceWalkStatus);
[_unit, "forceWalk", QGVAR(vehRearm), false] call EFUNC(common,statusEffect_set);
if (_unholster) then {
REARM_UNHOLSTER_WEAPON

View File

@ -19,7 +19,7 @@
params ["_dummy", "_unit"];
REARM_HOLSTER_WEAPON
[_unit, QGVAR(vehRearm), true] call EFUNC(common,setForceWalkStatus);
[_unit, "forceWalk", QGVAR(vehRearm), true] call EFUNC(common,statusEffect_set);
[
5,

View File

@ -22,7 +22,7 @@ private ["_ammo", "_dummyName", "_dummy", "_actionID"];
params ["_args"];
_args params ["_unit", "_magazineClass", "_target"]; // _target is for future possible finite ammo
[_unit, QGVAR(vehRearm), true] call EFUNC(common,setForceWalkStatus);
[_unit, "forceWalk", QGVAR(vehRearm), true] call EFUNC(common,statusEffect_set);
_dummy = [_unit, _magazineClass] call FUNC(createDummy);
[_dummy, _unit] call FUNC(pickUpAmmo);

View File

@ -6,6 +6,6 @@ _unit = _this select 0;
if !(local _unit) exitWith {};
[_unit, QGVAR(vehAttach), false] call EFUNC(common,setForceWalkStatus);
[_unit, "forceWalk", "ACE_refuel", false] call EFUNC(common,statusEffect_set);
_unit setVariable [QGVAR(selectedWeaponOnRefuel), nil];
_unit setVariable [QGVAR(isRefueling), false];

View File

@ -80,7 +80,7 @@ _endPosTestOffset set [2, (_startingOffset select 2)];
_args params ["_unit", "_nozzle", "_target", "_endPosTestOffset"];
_unit setVariable [QGVAR(nozzle), nil];
_unit setVariable [QGVAR(isRefueling), false];
[_unit, QGVAR(vehAttach), false] call EFUNC(common,setForceWalkStatus);
[_unit, "forceWalk", "ACE_refuel", false] call EFUNC(common,statusEffect_set);
REFUEL_UNHOLSTER_WEAPON
_actionID = _unit getVariable [QGVAR(ReleaseActionID), -1];
if (_actionID != -1) then {

View File

@ -22,7 +22,7 @@ if (!local _unit || {!_isUnconscious}) exitWith {};
private "_nozzle";
[_unit, QGVAR(vehAttach), false] call EFUNC(common,setForceWalkStatus);
[_unit, "forceWalk", "ACE_refuel", false] call EFUNC(common,statusEffect_set);
_nozzle = _unit getVariable [QGVAR(nozzle), objNull];
if !(isNull _nozzle) then {
[_unit, _nozzle] call FUNC(dropNozzle);

View File

@ -33,7 +33,7 @@ if (isNull _nozzle || {_source != _target}) exitWith {false};
_args params ["_unit", "_nozzle", "_target"];
_unit setVariable [QGVAR(nozzle), nil];
detach _nozzle;
[_unit, QGVAR(vehAttach), false] call EFUNC(common,setForceWalkStatus);
[_unit, "ACE_refuel", false] call EFUNC(common,statusEffect_set);
REFUEL_UNHOLSTER_WEAPON
_unit setVariable [QGVAR(isRefueling), false];
_actionID = _unit getVariable [QGVAR(ReleaseActionID), -1];

View File

@ -21,7 +21,7 @@
private ["_endPosOffset"],
params ["_unit", "_target", ["_nozzle", objNull]];
[_unit, QGVAR(vehAttach), true] call EFUNC(common,setForceWalkStatus);
[_unit, "forceWalk", "ACE_refuel", true] call EFUNC(common,statusEffect_set);
REFUEL_HOLSTER_WEAPON
@ -70,7 +70,7 @@ if (isNull _nozzle) then { // func is called on fuel truck
};
_actionID = _unit addAction [
format ["<t color='#FF0000'>%1</t>", localize ELSTRING(dragging,Drop)],
'_unit = _this select 0; _nozzle = _unit getVariable QGVAR(nozzle); [_unit, _nozzle] call FUNC(dropNozzle); [_unit, QGVAR(vehAttach), false] call EFUNC(common,setForceWalkStatus); REFUEL_UNHOLSTER_WEAPON',
'_unit = _this select 0; _nozzle = _unit getVariable QGVAR(nozzle); [_unit, _nozzle] call FUNC(dropNozzle); [_unit, "forceWalk", "ACE_refuel", false] call EFUNC(common,statusEffect_set); REFUEL_UNHOLSTER_WEAPON',
nil,
20,
false,
@ -107,7 +107,7 @@ if (isNull _nozzle) then { // func is called on fuel truck
};
_actionID = _unit addAction [
format ["<t color='#FF0000'>%1</t>", localize ELSTRING(dragging,Drop)],
'_unit = _this select 0; _nozzle = _unit getVariable QGVAR(nozzle); [_unit, _nozzle] call FUNC(dropNozzle); [_unit, QGVAR(vehAttach), false] call EFUNC(common,setForceWalkStatus); REFUEL_UNHOLSTER_WEAPON',
'_unit = _this select 0; _nozzle = _unit getVariable QGVAR(nozzle); [_unit, _nozzle] call FUNC(dropNozzle); [_unit, "forceWalk", "ACE_refuel", false] call EFUNC(common,statusEffect_set); REFUEL_UNHOLSTER_WEAPON',
nil,
20,
false,
@ -138,7 +138,7 @@ if !(_nozzle getVariable [QGVAR(jerryCan), false]) then {
[_unit, _nozzle] call FUNC(dropNozzle);
REFUEL_UNHOLSTER_WEAPON
[_unit, QGVAR(vehAttach), false] call EFUNC(common,setForceWalkStatus);
[_unit, "forceWalk", "ACE_refuel", false] call EFUNC(common,statusEffect_set);
[LSTRING(Hint_TooFar), 2, _unit] call EFUNC(common,displayTextStructured);
};
[_pfID] call cba_fnc_removePerFrameHandler;

View File

@ -18,7 +18,7 @@
params ["_unit"];
// prevent the placing unit from running
[_unit, "ACE_Sandbag", true] call EFUNC(common,setForceWalkStatus);
[_unit, "forceWalk", "ACE_Sandbag", true] call EFUNC(common,statusEffect_set);
// create the sandbag
private "_sandBag";

View File

@ -18,7 +18,7 @@
params ["_unit"];
// enable running again
[_unit, "ACE_Sandbag", false] call EFUNC(common,setForceWalkStatus);
[_unit, "forceWalk", "ACE_Sandbag", false] call EFUNC(common,statusEffect_set);
// delete placement dummy
deleteVehicle GVAR(sandBag);

View File

@ -18,7 +18,7 @@
params ["_unit"];
// enable running again
[_unit, "ACE_Sandbag", false] call EFUNC(common,setForceWalkStatus);
[_unit, "forceWalk", "ACE_Sandbag", false] call EFUNC(common,statusEffect_set);
// remove sandbag from inventory
_unit removeItem "ACE_Sandbag_empty";

View File

@ -39,7 +39,7 @@ if (vehicle _playerUnit == _playerUnit) then {
_playerUnit linkItem "ItemMap";
removeUniform _playerUnit;
[_playerUnit, "ACE_SwitchUnits", true] call EFUNC(common,setForceWalkStatus);
[_playerUnit, "forceWalk", "ACE_SwitchUnits", true] call EFUNC(common,statusEffect_set);
[_playerUnit, _sides] call FUNC(addMapFunction);
};

View File

@ -21,7 +21,7 @@
params ["_unit", "_ladder"];
// enable running again
[_unit, "ACE_Ladder", false] call EFUNC(common,setForceWalkStatus);
[_unit, "forceWalk", "ACE_Ladder", false] call EFUNC(common,statusEffect_set);
detach _ladder;

View File

@ -19,7 +19,7 @@
params ["_unit", "_ladder"];
// enable running again
[_unit, "ACE_Ladder", false] call EFUNC(common,setForceWalkStatus);
[_unit, "forceWalk", "ACE_Ladder", false] call EFUNC(common,statusEffect_set);
private ["_pos1", "_pos2"];

View File

@ -21,7 +21,7 @@
params ["_unit", "_ladder"];
// prevent the placing unit from running
[_unit, "ACE_Ladder", true] call EFUNC(common,setForceWalkStatus);
[_unit, "forceWalk", "ACE_Ladder", true] call EFUNC(common,statusEffect_set);
{
_ladder animate [_x, 0];

View File

@ -53,4 +53,4 @@ class CfgVehicles {
description = CSTRING(Module_Description);
};
};
};
};

View File

@ -48,4 +48,4 @@ class CfgWorlds {
{0.08, 0.38, 0.06, 0.04, 0.19, 0.03, 0.02, 0.02}, // November
{0.06, 0.37, 0.05, 0.03, 0.18, 0.04, 0.02, 0.02}};// December
};
};
};

View File

@ -1,17 +1,13 @@
class RscTitles
{
class RscWindIntuitive
{
class RscTitles {
class RscWindIntuitive {
idd=-1;
onLoad="with uiNameSpace do { RscWindIntuitive = _this select 0 };";
movingEnable=0;
duration=60;
fadeIn="false";
fadeOut="false";
class controls
{
class RscWindIntuitive
{
class controls {
class RscWindIntuitive {
idc=132948;
type=0;
style=48;
@ -28,4 +24,4 @@ class RscTitles
};
};
};
};
};

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -14,6 +14,7 @@ GVAR(ACE_rain) = rain;
"ACE_RAIN_PARAMS" addPublicVariableEventHandler { GVAR(rain_period_start_time) = ACE_time; };
"ACE_MISC_PARAMS" addPublicVariableEventHandler {
if (!isServer) then {
TRACE_1("MISC PARAMS PVEH",ACE_MISC_PARAMS);
if (GVAR(syncMisc)) then {
30 setLightnings (ACE_MISC_PARAMS select 0);
30 setRainbow (ACE_MISC_PARAMS select 1);
@ -27,10 +28,11 @@ GVAR(ACE_rain) = rain;
};
};
GVAR(WindInfo) = false;
["ACE3 Common", QGVAR(WindInfoKey), localize LSTRING(WindInfoKey),
{
// Conditions: canInteract
if !([ACE_player, objNull, []] call EFUNC(common,canInteractWith)) exitWith {false};
if !([ACE_player, ACE_player, []] call EFUNC(common,canInteractWith)) exitWith {false};
// Statement
[] call FUNC(displayWindInfo);
@ -40,12 +42,40 @@ GVAR(ACE_rain) = rain;
simulWeatherSync;
[FUNC(updateTemperature), 20, []] call CBA_fnc_addPerFrameHandler;
[FUNC(updateHumidity), 20, []] call CBA_fnc_addPerFrameHandler;
[FUNC(updateWind), 1, []] call CBA_fnc_addPerFrameHandler;
[FUNC(updateRain), 2, []] call CBA_fnc_addPerFrameHandler;
[{
["SettingsInitialized",{
TRACE_1("SettingsInitialized",GVAR(syncRain));
//Create a 0 sec delay PFEH to update rain every frame:
if (GVAR(syncRain)) then {
0 setRain GVAR(ACE_rain);
[{
0 setRain GVAR(ACE_rain);
}, 0, []] call CBA_fnc_addPerFrameHandler;
};
}, 0, []] call CBA_fnc_addPerFrameHandler;
//Create a 1 sec delay PFEH to update wind/rain/temp/humidity:
//If we don't sync rain, set next time to infinity
GVAR(nextUpdateRain) = if (GVAR(syncRain)) then {0} else {1e99};
GVAR(nextUpdateTempAndHumidity) = 0;
[{
BEGIN_COUNTER(weatherPFEH);
[] call FUNC(updateWind); //Every 1 second
if (ACE_time >= GVAR(nextUpdateRain)) then {
[] call FUNC(updateRain); //Every 2 seconds
GVAR(nextUpdateRain) = 2 + ACE_time;
};
if (ACE_time >= GVAR(nextUpdateTempAndHumidity)) then {
[] call FUNC(updateTemperature); //Every 20 seconds
[] call FUNC(updateHumidity); //Every 20 seconds
GVAR(nextUpdateTempAndHumidity) = 20 + ACE_time;
};
END_COUNTER(weatherPFEH);
}, 1, []] call CBA_fnc_addPerFrameHandler;
}] call EFUNC(common,addEventHandler);

View File

@ -9,4 +9,10 @@ GVAR(rain_current_range) = -1+(random 2);
// Wind
call FUNC(initWind);
[FUNC(serverController), GVAR(serverUpdateInterval)] call CBA_fnc_addPerFrameHandler;
["SettingsInitialized", {
TRACE_2("SettingsInitialized",GVAR(enableServerController),GVAR(serverUpdateInterval));
if (GVAR(enableServerController)) then {
[FUNC(serverController), GVAR(serverUpdateInterval)] call CBA_fnc_addPerFrameHandler;
};
}] call EFUNC(common,addEventHandler);

View File

@ -1,18 +1,19 @@
/*
* Author: Ruthberg
*
* Calculates the air density
*
* Arguments:
* 0: temperature - degrees celcius <NUMBER>
* 0: temperature - degrees celsius <NUMBER>
* 1: pressure - hPa <NUMBER>
* 2: relativeHumidity - value between 0.0 and 1.0 <NUMBER>
*
* Return Value:
* density of air - kg * m^(-3) <NUMBER>
*
* Return value:
* None
* Example:
* [0, 1020, 0.5] call ace_weather_fnc_calculateAirDensity
*
* Public: No
*/
#include "script_component.hpp"
@ -21,11 +22,10 @@ params ["_temperature", "_pressure", "_relativeHumidity"];
_pressure = _pressure * 100; // hPa to Pa
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;
private _pSat = 6.1078 * 10 ^ ((7.5 * _temperature) / (_temperature + 237.3));
private _vaporPressure = _relativeHumidity * _pSat;
private _partialPressure = _pressure - _vaporPressure;
(_partialPressure * DRY_AIR_MOLAR_MASS + _vaporPressure * WATER_VAPOR_MOLAR_MASS) / (UNIVERSAL_GAS_CONSTANT * KELVIN(_temperature))
} else {

View File

@ -1,6 +1,5 @@
/*
* Author: Ruthberg
*
* Calculates the barometric pressure based on altitude and weather
*
* Arguments:
@ -9,8 +8,10 @@
* Return Value:
* barometric pressure - hPA <NUMBER>
*
* Return value:
* None
* Example:
* 0 call ace_weather_fnc_calculateBarometricPressure
*
* Public: No
*/
#include "script_component.hpp"

View File

@ -1,6 +1,5 @@
/*
* Author: Ruthberg
*
* Calculates density altitude for a given air density
*
* Arguments:
@ -9,8 +8,10 @@
* Return Value:
* density altitude - m <NUMBER>
*
* Return value:
* None
* Example:
* 1.225 call ace_weather_fnc_calculateDensityAltitude
*
* Public: No
*/
#include "script_component.hpp"

View File

@ -1,17 +1,18 @@
/*
* Author: Ruthberg
*
* Calculates dew point based on temperature and relative humidity
*
* Arguments:
* 0: temperature - degrees celcius <NUMBER>
* 2: relativeHumidity - value between 0.0 and 1.0 <NUMBER>
* 0: temperature - degrees celsius <NUMBER>
* 1: relativeHumidity - value between 0.0 and 1.0 <NUMBER>
*
* Return Value:
* dew point <NUMBER>
*
* Return value:
* None
* Example:
* [32, 0.4] call ace_weather_fnc_calculateDewPoint
*
* Public: No
*/
#include "script_component.hpp"
@ -24,7 +25,6 @@ if (_rh == 0) exitWith { CELSIUS(0) };
// Source: https://en.wikipedia.org/wiki/Dew_point
private ["_gamma"];
_gamma = ln(_rh) + (__b * _t) / (__c + _t);
private _gamma = ln(_rh) + (__b * _t) / (__c + _t);
(__c * _gamma) / (__b - _gamma)

View File

@ -1,17 +1,18 @@
/*
* Author: Ruthberg
*
* Calculates heat index based on temperature and relative humidity
*
* Arguments:
* 0: temperature - degrees celcius <NUMBER>
* 0: temperature - degrees celsius <NUMBER>
* 1: relativeHumidity - value between 0.0 and 1.0 <NUMBER>
*
* Return Value:
* heat index <NUMBER>
*
* Return value:
* None
* Example:
* [36, 0.75] call ace_weather_fnc_calculateHeatIndex
*
* Public: No
*/
#include "script_component.hpp"

View File

@ -1,6 +1,5 @@
/*
* Author: Ruthberg
*
* Calculates the terrain roughness length at a given world position
*
* Arguments:
@ -9,19 +8,20 @@
* Return Value:
* roughness length <NUMBER>
*
* Example:
* (getPosASL player) call ace_weather_fnc_calculateRoughnessLength
*
* Public: No
*/
#include "script_component.hpp"
private ["_roughness_lengths", "_windSource", "_nearBuildings", "_isWater"];
// Source: http://es.ucsc.edu/~jnoble/wind/extrap/index.html
_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]
_windSource = _this vectorDiff ((vectorNormalized ACE_wind) vectorMultiply 25);
private _windSource = _this vectorDiff ((vectorNormalized ACE_wind) vectorMultiply 25);
_nearBuildings = count (_windSource nearObjects ["Building", 50]);
_isWater = surfaceIsWater _windSource;
private _nearBuildings = count (_windSource nearObjects ["Building", 50]);
private _isWater = surfaceIsWater _windSource;
if (_nearBuildings == 0 && _isWater) exitWith {
0.0005
@ -31,4 +31,4 @@ if (_nearBuildings >= 10) exitWith {
1.6
};
_roughness_lengths select (2 + (_nearBuildings min 6))
ROUGHNESS_LENGTHS select (2 + (_nearBuildings min 6))

View File

@ -1,16 +1,17 @@
/*
* Author: Ruthberg
*
* Calculates the speed of sound for a given temperature
*
* Arguments:
* temperature - degrees celcius <NUMBER>
* temperature - degrees celsius <NUMBER>
*
* Return Value:
* speed of sound - m/s <NUMBER>
*
* Return value:
* None
* Example:
* 0 call ace_weather_fnc_calculateSpeedOfSound
*
* Public: No
*/
#include "script_component.hpp"

View File

@ -1,6 +1,5 @@
/*
* Author: Ruthberg
*
* Calculates the temperature based on altitude and weather
*
* Arguments:
@ -9,8 +8,10 @@
* Return Value:
* temperature - degrees celsius <NUMBER>
*
* Return value:
* None
* Example:
* 500 call ace_weather_fnc_calculateTemperatureAtHeight
*
* Public: No
*/
#include "script_component.hpp"

View File

@ -1,36 +1,35 @@
/*
* Author: Ruthberg
*
* Calculates wet bulb based on temperature and relative humidity
*
* Arguments:
* 0: temperature - degrees celcius <NUMBER>
* 0: temperature - degrees celsius <NUMBER>
* 1: pressure - hPa <NUMBER>
* 2: relativeHumidity - value between 0.0 and 1.0 <NUMBER>
*
* Return Value:
* wet bulb <NUMBER>
*
* Return value:
* None
* Example:
* [0, 1020, 0.5] call ace_weather_fnc_calculateWetBulb
*
* Public: No
*/
#include "script_component.hpp"
private ["_es", "_e", "_eDiff", "_eGuessPrev", "_cTempDelta", "_twGuess", "_eguess"];
params ["_temperature", "_pressure", "_relativeHumidity"];
// Source: http://cosmoquest.org/forum/showthread.php?155366-Calculating-Wet-Bulb-Temperature-from-RH-amp-Dry-Bulb
_es = 6.112 * exp((17.67 * _temperature) / (_temperature + 243.5));
_e = _es * _relativeHumidity;
_eDiff = _es - _e;
_eGuessPrev = _es;
_cTempDelta = 3.3145;
_twGuess = _temperature;
private _es = 6.112 * exp((17.67 * _temperature) / (_temperature + 243.5));
private _e = _es * _relativeHumidity;
private _eDiff = _es - _e;
private _eGuessPrev = _es;
private _cTempDelta = 3.3145;
private _twGuess = _temperature;
for "_j" from 1 to 50 do {
_twGuess = _twGuess - _cTempDelta;
_eguess = 6.112 * exp((17.67 * _twGuess) / (_twGuess + 243.5));
private _eguess = 6.112 * exp((17.67 * _twGuess) / (_twGuess + 243.5));
_eguess = _eguess - (_pressure * (_temperature - _twGuess) * 0.00066 * (1 + (0.00115 * _twGuess)));
_eDiff = _eguess - _e;
if (abs(_eDiff) <= 0.001) exitWith {};

View File

@ -1,15 +1,17 @@
/*
* Author: Ruthberg
*
* Calculates wind chill based on temperature and wind speed
*
* Arguments:
* 0: temperature - degrees celcius <NUMBER>
* 0: temperature - degrees celsius <NUMBER>
* 1: wind speed - m/s <NUMBER>
*
* Return Value:
* wind chill <NUMBER>
*
* Example:
* [0, 10] call ace_weather_fnc_calculateWindChill
*
* Public: No
*/
#include "script_component.hpp"

View File

@ -1,43 +1,42 @@
/*
* Author: Ruthberg
*
* Calculates the true wind speed at a given world position
*
* Arguments:
* 0: world position - posASL <POSTION>
* 1: Account for wind gradient <BOOL>
* 1: Account for wind gradient (used in advanced ballistics) <BOOL>
* 2: Account for terrain <BOOL>
* 3: Account for obstacles <BOOL>
*
* Return Value:
* wind speed - m/s <NUMBER>
*
* Example:
* [eyePos ACE_player, true, true, true] call ace_weather_fnc_calculateWindSpeed;
*
* Public: No
*/
#include "script_component.hpp"
private ["_fnc_polar2vect", "_windSpeed", "_windDir", "_windDirAdjusted", "_height", "_newWindSpeed", "_windSource", "_roughnessLength"];
params ["_position", "_windGradientEnabled", "_terrainEffectEnabled", "_obstacleEffectEnabled"];
_fnc_polar2vect = {
private ["_mag2D"];
params ["_x", "_y", "_z"];
_mag2D = _x * cos(_z);
[_mag2D * sin(_y), _mag2D * cos(_y), _x * sin(_z)];
private _fnc_polar2vect = {
params ["_mag","_dir","_elev"];
private _mag2D = _mag * cos(_elev);
[_mag2D * sin(_dir), _mag2D * cos(_dir), _mag * sin(_elev)];
};
_windSpeed = vectorMagnitude ACE_wind;
_windDir = (ACE_wind select 0) atan2 (ACE_wind select 1);
_windDirAdjusted = _windDir + 180;
private _windSpeed = vectorMagnitude ACE_wind;
private _windDir = (ACE_wind select 0) atan2 (ACE_wind select 1);
private _windDirAdjusted = _windDir + 180;
// Wind gradient
if (_windGradientEnabled) then {
if (_windSpeed > 0.05) then {
_height = (ASLToATL _position) select 2;
private _height = (ASLToATL _position) select 2;
_height = 0 max _height min 20;
if (_height < 20) then {
_roughnessLength = _position call FUNC(calculateRoughnessLength);
private _roughnessLength = _position call FUNC(calculateRoughnessLength);
_windSpeed = _windSpeed * abs(ln(_height / _roughnessLength) / ln(20 / _roughnessLength));
};
};
@ -46,9 +45,9 @@ if (_windGradientEnabled) then {
// Terrain effect on wind
if (_terrainEffectEnabled) then {
if (_windSpeed > 0.05) then {
_newWindSpeed = 0;
private _newWindSpeed = 0;
{
_windSource = [100, _windDirAdjusted, _x] call _fnc_polar2vect;
private _windSource = [100, _windDirAdjusted, _x] call _fnc_polar2vect;
if (!(terrainIntersectASL [_position, _position vectorAdd _windSource])) exitWith {
_newWindSpeed = cos(_x * 9) * _windSpeed;
};
@ -60,6 +59,7 @@ if (_terrainEffectEnabled) then {
if (!(terrainIntersectASL [_position, _position vectorAdd _windSource])) exitWith {
_newWindSpeed = cos(_x * 9) * _windSpeed;
};
nil
} count [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
_windSpeed = _newWindSpeed;
};
@ -68,9 +68,9 @@ if (_terrainEffectEnabled) then {
// Obstacle effect on wind
if (_obstacleEffectEnabled) then {
if (_windSpeed > 0.05) then {
_newWindSpeed = 0;
private _newWindSpeed = 0;
{
_windSource = [20, _windDirAdjusted, _x] call _fnc_polar2vect;
private _windSource = [20, _windDirAdjusted, _x] call _fnc_polar2vect;
if (!(lineIntersects [_position, _position vectorAdd _windSource])) exitWith {
_newWindSpeed = cos(_x * 2) * _windSpeed;
};
@ -82,6 +82,7 @@ if (_obstacleEffectEnabled) then {
if (!(lineIntersects [_position, _position vectorAdd _windSource])) exitWith {
_newWindSpeed = cos(_x * 2) * _windSpeed;
};
nil
} count [0, 5, 10, 15, 20, 25, 30, 35, 40, 45];
_windSpeed = _newWindSpeed;
};

View File

@ -1,6 +1,5 @@
/*
* Author: Ruthberg
*
* Displays a wind info (colored arrow) in the top left corner of the screen
*
* Argument:
@ -8,6 +7,11 @@
*
* Return value:
* None
*
* Example:
* [] call ace_weather_fnc_displayWindInfo
*
* Public: No
*/
#include "script_component.hpp"
@ -16,64 +20,87 @@
if (GVAR(WindInfo)) exitWith {
GVAR(WindInfo) = false;
0 cutText ["", "PLAIN"];
(["RscWindIntuitive"] call BIS_fnc_rscLayer) cutText ["", "PLAIN"];
true
};
if (underwater ACE_player) exitWith { false };
if (vehicle ACE_player != ACE_player) exitWith { false };
2 cutText ["", "PLAIN"];
EGVAR(advanced_ballistics,Protractor) = false;
1 cutText ["", "PLAIN"];
GVAR(WindInfo) = true;
[{
private ["_windSpeed", "_windDir", "_playerDir", "_windIndex", "_windColor"];
if !(GVAR(WindInfo) && !(underwater ACE_player) && vehicle ACE_player == ACE_player) exitWith {
TRACE_1("Starting Wind Info PFEH", GVAR(WindInfo));
[{
disableSerialization;
params ["", "_pfID"];
if ((!GVAR(WindInfo)) || {!([ACE_player, ACE_player, []] call EFUNC(common,canInteractWith))}) exitWith {
TRACE_1("Ending Wind Info PFEH", GVAR(WindInfo));
GVAR(WindInfo) = false;
0 cutText ["", "PLAIN"];
[_this select 1] call CBA_fnc_removePerFrameHandler;
(["RscWindIntuitive"] call BIS_fnc_rscLayer) cutText ["", "PLAIN"];
[_pfID] call CBA_fnc_removePerFrameHandler;
};
_windIndex = 12;
_windColor = [1, 1, 1, 1];
_windSpeed = if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
//Keeps the display open:
(["RscWindIntuitive"] call BIS_fnc_rscLayer) cutRsc ["RscWindIntuitive", "PLAIN", 1, false];
private _windSpeed = if (missionNamespace getVariable [QEGVAR(advanced_ballistics,enabled), false]) then {
// With wind gradient
[eyePos ACE_player, true, true, true] call FUNC(calculateWindSpeed);
} else {
// Without wind gradient
[eyePos ACE_player, false, true, true] call FUNC(calculateWindSpeed);
};
if (_windSpeed > 0.2) then {
_playerDir = (ACE_player call CBA_fnc_headDir) select 0;
_windDir = (ACE_wind select 0) atan2 (ACE_wind select 1);
_windIndex = round(((_playerDir - _windDir + 360) % 360) / 30);
_windIndex = _windIndex % 12;
};
private _playerDir = (ACE_player call CBA_fnc_headDir) select 0;
private _windDir = (ACE_wind select 0) atan2 (ACE_wind select 1);
_windDir = 30 * (round(((_windDir - _playerDir + 360) % 360) / 30));
// Color Codes from https://en.wikipedia.org/wiki/Beaufort_scale#Modern_scale
if (_windSpeed > 0.3) then { _windColor = [0.796, 1, 1, 1]; };
if (_windSpeed > 1.5) then { _windColor = [0.596, 0.996, 0.796, 1]; };
if (_windSpeed > 3.3) then { _windColor = [0.596, 0.996, 0.596, 1]; };
if (_windSpeed > 5.4) then { _windColor = [0.6, 0.996, 0.4, 1]; };
if (_windSpeed > 7.9) then { _windColor = [0.6, 0.996, 0.047, 1]; };
if (_windSpeed > 10.7) then { _windColor = [0.8, 0.996, 0.059, 1]; };
if (_windSpeed > 13.8) then { _windColor = [1, 0.996, 0.067, 1]; };
if (_windSpeed > 17.1) then { _windColor = [1, 0.796, 0.051, 1]; };
if (_windSpeed > 20.7) then { _windColor = [1, 0.596, 0.039, 1]; };
if (_windSpeed > 24.4) then { _windColor = [1, 0.404, 0.031, 1]; };
if (_windSpeed > 28.4) then { _windColor = [1, 0.22, 0.027, 1]; };
if (_windSpeed > 32.6) then { _windColor = [1, 0.078, 0.027, 1]; };
private _beaufortNumber = 0;
private _windColor = [1, 1, 1, 1];
if (_windSpeed > 0.3) then { _windColor = [0.796, 1, 1, 1]; _beaufortNumber = 1; };
if (_windSpeed > 1.5) then { _windColor = [0.596, 0.996, 0.796, 1]; _beaufortNumber = 2; };
if (_windSpeed > 3.3) then { _windColor = [0.596, 0.996, 0.596, 1]; _beaufortNumber = 3; };
if (_windSpeed > 5.4) then { _windColor = [0.6, 0.996, 0.4, 1]; _beaufortNumber = 4; };
if (_windSpeed > 7.9) then { _windColor = [0.6, 0.996, 0.047, 1]; _beaufortNumber = 5; };
if (_windSpeed > 10.7) then { _windColor = [0.8, 0.996, 0.059, 1]; _beaufortNumber = 6; };
if (_windSpeed > 13.8) then { _windColor = [1, 0.996, 0.067, 1]; _beaufortNumber = 7; };
if (_windSpeed > 17.1) then { _windColor = [1, 0.796, 0.051, 1]; _beaufortNumber = 8; };
if (_windSpeed > 20.7) then { _windColor = [1, 0.596, 0.039, 1]; _beaufortNumber = 9; };
if (_windSpeed > 24.4) then { _windColor = [1, 0.404, 0.031, 1]; _beaufortNumber = 10; };
if (_windSpeed > 28.4) then { _windColor = [1, 0.22, 0.027, 1]; _beaufortNumber = 11; };
if (_windSpeed > 32.6) then { _windColor = [1, 0.078, 0.027, 1]; _beaufortNumber = 12; };
0 cutRsc ["RscWindIntuitive", "PLAIN", 1, false];
__ctrl ctrlSetScale 0.75;
TRACE_3("update display",_beaufortNumber,_windDir,_windSpeed);
__ctrl ctrlSetTextColor _windColor;
if (_beaufortNumber > 0) then {
__ctrl ctrlSetText QUOTE(PATHTOF(UI\wind_arrow_ca.paa));
__ctrl ctrlSetAngle [_windDir, 0.5, 0.5];
} else {
__ctrl ctrlSetText QUOTE(PATHTOF(UI\wind_noneCircle_ca.paa));
};
__ctrl ctrlCommit 0;
__ctrl ctrlSetText format[QUOTE(PATHTOF(UI\wind%1.paa)), _windIndex];
__ctrl ctrlSetTextColor _windColor;
//Update the beaufort balls:
(ctrlPosition __ctrl) params ["_ctrlX", "_ctrlY", "_ctrlWidth", "_ctrlHeight"];
private _centerX = _ctrlX + _ctrlWidth / 2;
private _centerY = _ctrlY + _ctrlHeight / 2;
private _ballHeight = _ctrlHeight / 17;
private _ballWidth = _ballHeight * 3/4;
for "_index" from 0 to (_beaufortNumber - 1) do {
private _ball = __dsp ctrlCreate ["RscPicture", _index];
_ball ctrlSetText QUOTE(PATHTOF(UI\wind_dot_ca.paa));
_ball ctrlSetTextColor [1,1,1,1];
private _ballCenterX = _centerX - (_ballWidth / 2) + ((sin _windDir) * 0.013333) * (_index - 4.9) + ((cos _windDir) * 0.0125);
private _ballCenterY = _centerY - (_ballHeight / 2) - ((1 * cos _windDir) * 4/3*0.013333) * (_index - 4.9) + ((sin _windDir) * 0.0125);
_ball ctrlSetPosition [_ballCenterX, _ballCenterY, _ballWidth, _ballHeight];
_ball ctrlCommit 0;
};
}, 0.5, []] call CBA_fnc_addPerFrameHandler;

View File

@ -1,6 +1,5 @@
/*
* Author: Ruthberg, esteldunedain
*
* Get the weather data for the current map
*
* Argument:
@ -8,6 +7,11 @@
*
* Return value:
* None
*
* Example:
* [] call ace_weather_fnc_getMapData
*
* Public: No
*/
#include "script_component.hpp"
@ -207,4 +211,4 @@ 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(currentTemperature) = 20;
GVAR(currentHumidity) = 0.5;
GVAR(currentHumidity) = 0.5;

View File

@ -1,6 +1,5 @@
/*
* Author: ACE2 Team, Ruthberg
*
* Calculate current wind locally from the data broadcasted by the server
*
* Argument:
@ -8,17 +7,21 @@
*
* Return value:
* Wind <ARRAY>
*
* Example:
* [] call ace_weather_fnc_getWind
*
* Public: No
*/
#include "script_component.hpp"
private ["_periodPercent", "_periodPosition"];
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];]
_periodPosition = (ACE_time - GVAR(wind_period_start_time)) min _period;
_periodPercent = _periodPosition / _period;
private _periodPosition = (ACE_time - GVAR(wind_period_start_time)) min _period;
private _periodPercent = _periodPosition / _period;
_spd = _spd + _spdChange * _periodPercent;
_dir = _dir + _dirChange * _periodPercent;

View File

@ -10,6 +10,9 @@
* Return Value:
* None <NIL>
*
* Example:
* [module, [], true] call ace_weather_fnc_initModuleSettings
*
* Public: No
*/

View File

@ -1,6 +1,5 @@
/*
* Author: Ruthberg
*
* Inits the wind variables on mission start
*
* Argument:
@ -8,28 +7,32 @@
*
* Return value:
* None
*
* Example:
* [] call ace_weather_fnc_initWind
*
* Public: No
*/
#include "script_component.hpp"
private ["_sum", "_rand", "_csum", "_index", "_month", "_windDirectionProbabilities"];
_month = date select 1;
_windDirectionProbabilities = GVAR(WindDirectionProbabilities) select (_month - 1);
private _month = date select 1;
private _windDirectionProbabilities = GVAR(WindDirectionProbabilities) select (_month - 1);
ACE_wind = [0, 0, 0];
GVAR(wind_direction_reference) = random 360;
_sum = 0;
private _sum = 0;
for "_i" from 0 to 7 do {
_sum = _sum + (_windDirectionProbabilities select _i);
};
_rand = random _sum;
_csum = [0, 0, 0, 0, 0, 0, 0, 0];
private _rand = random _sum;
private _csum = [0, 0, 0, 0, 0, 0, 0, 0];
for "_i" from 0 to 7 do {
for "_j" from 0 to _i do {
_csum set [_i, (_csum select _i) + (_windDirectionProbabilities select _j)];
};
};
_index = 0;
private _index = 0;
for "_i" from 0 to 7 do {
if (_rand > (_csum select _i)) then {
_index = _index + 1;

View File

@ -1,6 +1,5 @@
/*
* Author: Ruthberg
*
* Gather weather parameters and broadcast them to the clients
*
* Argument:
@ -8,11 +7,14 @@
*
* Return value:
* None
*
* Example:
* [] call ace_weather_fnc_serverController
*
* Public: No
*/
#include "script_component.hpp"
if (!GVAR(enableServerController)) exitWith {};
if (GVAR(useACEWeather)) then {
// Use location based real world weather data
[] call FUNC(updateAceWeather);
@ -23,7 +25,9 @@ if (GVAR(useACEWeather)) then {
publicVariable "ACE_RAIN_PARAMS";
};
if (GVAR(syncWind)) then {
ACE_WIND_PARAMS = [wind call CBA_fnc_vectDir, 0, vectorMagnitude wind, 0, GVAR(serverUpdateInterval)];
//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 {

View File

@ -1,6 +1,5 @@
/*
* Author: ACE2 Team, esteldunedain, ruthberg
*
* Updates the wind and rain evolution on the server. Broadcasts the current and next values to the clients
*
* Argument:
@ -8,40 +7,44 @@
*
* Return value:
* None
*
* Example:
* [] call ace_weather_fnc_updateAceWeather
*
* Public: No
*/
#include "script_component.hpp"
private ["_overcastMultiplier", "_lastRain", "_rainOverCast", "_transitionTime", "_windDirectionVariance", "_windSpeed", "_windSpeedChange", "_windMaxDiff", "_windMinDiff", "_windDirection", "_windDirectionChange", "_ratioMin", "_ratioMax"];
_overcastMultiplier = 1 max (2* overcast) min 2; // 0 (@ overcast 0), 2 (@ overcast 1)
private _overcastMultiplier = 1 max (2* overcast) min 2; // 0 (@ overcast 0), 2 (@ overcast 1)
// Rain simulation
if (GVAR(syncRain) && GVAR(rain_period_count) > GVAR(rain_next_period)) then {
if (GVAR(syncRain) && {GVAR(rain_period_count) > GVAR(rain_next_period)}) then {
GVAR(rain_next_period) = ceil((1 + (random 10)) / _overcastMultiplier);
GVAR(rain_period_count) = 0;
_lastRain = GVAR(current_rain);
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;
};
_transitionTime = 1 + (_rainOverCast * 5) + (random (_rainOverCast * 20));
private _transitionTime = 1 + (_rainOverCast * 5) + (random (_rainOverCast * 20));
ACE_RAIN_PARAMS = [_lastRain, GVAR(current_rain), _transitionTime];
TRACE_4("",_lastRain,_rainOverCast,_transitionTime,overcast);
@ -50,47 +53,47 @@ if (GVAR(syncRain) && GVAR(rain_period_count) > GVAR(rain_next_period)) then {
};
// Wind simulation
if (GVAR(syncWind) && GVAR(wind_period_count) > GVAR(wind_next_period)) then {
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;
_windDirectionVariance = (90 - (random 180)) * (overcast ^ 2);
_windDirection = (360 + GVAR(wind_direction_reference) + _windDirectionVariance) % 360;
_windDirectionChange = _windDirection - GVAR(current_wind_direction);
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;
};
_windMaxDiff = GVAR(mean_wind_speed) - GVAR(max_wind_speed);
_windMinDiff = GVAR(min_wind_speed) - GVAR(mean_wind_speed);
_ratioMax = (random 1) ^ 2;
_ratioMin = (random 1) ^ 2;
_windSpeed = GVAR(current_wind_speed);
_windSpeedChange = 0;
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);
};
_transitionTime = GVAR(wind_next_period) * GVAR(serverUpdateInterval);
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];
_windDirectionChange,
GVAR(current_wind_speed),
_windSpeedChange,
_transitionTime];
GVAR(current_wind_direction) = _windDirection;
GVAR(current_wind_speed) = _windSpeed;
GVAR(wind_period_start_time) = ACE_time;
publicVariable "ACE_WIND_PARAMS";
};
@ -102,4 +105,4 @@ if (GVAR(syncMisc)) then {
};
GVAR(rain_period_count) = GVAR(rain_period_count) + 1;
GVAR(wind_period_count) = GVAR(wind_period_count) + 1;
GVAR(wind_period_count) = GVAR(wind_period_count) + 1;

View File

@ -1,27 +1,30 @@
/*
* Author: ACE2 Team
*
* Updates GVAR(currentHumidity) based on
* Updates GVAR(currentHumidity)
*
* Argument:
* Nothing
*
* Return value:
* Nothing
*
* Example:
* [] call ace_weather_fnc_updateHumidity
*
* Public: No
*/
#include "script_component.hpp"
private ["_month", "_avgTemperature", "_pS1", "_pS2"];
_month = date select 1;
private _month = date select 1;
GVAR(currentHumidity) = (GVAR(Humidity) select (_month - 1)) / 100;
if (rain > 0 && overcast > 0.7) then {
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)));
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 _PS2 = 6.112 * exp((17.62 * GVAR(currentTemperature)) / (243.12 + GVAR(currentTemperature)));
GVAR(currentHumidity) = GVAR(currentHumidity) * _PS1 / _PS2;
GVAR(currentHumidity) = GVAR(currentHumidity) + GVAR(humidityShift);

View File

@ -1,6 +1,5 @@
/*
* Author: ACE2 Team, Ruthberg
*
* Updates rain based on ACE_RAIN_PARAMS
*
* Argument:
@ -8,17 +7,21 @@
*
* Return value:
* Nothing
*
* Example:
* [] call ace_weather_fnc_updateRain
*
* Public: No
*/
#include "script_component.hpp"
if (!GVAR(syncRain)) exitWith {};
if (!isNil "ACE_RAIN_PARAMS") then {
ACE_RAIN_PARAMS params ["_oldRain", "_newRain", "_period"];
private ["_periodPosition", "_periodPercent"];
_periodPosition = (ACE_time - GVAR(rain_period_start_time)) min _period;
_periodPercent = (_periodPosition / _period) min 1;
private _periodPosition = (ACE_time - GVAR(rain_period_start_time)) min _period;
private _periodPercent = (_periodPosition / _period) min 1;
GVAR(ACE_Rain) = (_oldRain + (_newRain - _oldRain) * _periodPercent);
GVAR(ACE_Rain) = linearConversion [GVAR(rain_period_start_time), (GVAR(rain_period_start_time) + _period), ACE_time, _oldRain, _newRain];
TRACE_3("Update Rain",rain,ACE_RAIN_PARAMS,GVAR(ACE_Rain));
};

View File

@ -1,6 +1,5 @@
/*
* Author: ACE2 Team
*
* Updates GVAR(currentTemperature) based on the map data
*
* Argument:
@ -8,14 +7,18 @@
*
* Return value:
* Nothing
*
* Example:
* [] call ace_weather_fnc_updateTemperature
*
* Public: No
*/
#include "script_component.hpp"
private ["_time", "_month", "_timeRatio"];
_time = daytime;
_month = date select 1;
private _time = daytime;
private _month = date select 1;
_timeRatio = abs(_time - 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(currentTemperature) + GVAR(temperatureShift) - GVAR(badWeatherShift) * overcast;

View File

@ -1,6 +1,5 @@
/*
* Author: ACE2 Team, Ruthberg
*
* Updates wind, gusts and waves based on ACE_wind
*
* Argument:
@ -8,19 +7,22 @@
*
* Return value:
* Nothing
*
* Example:
* [] call ace_weather_fnc_updateWind
*
* Public: No
*/
#include "script_component.hpp"
if (!GVAR(syncWind)) exitWith { ACE_wind = wind };
private ["_newWaves"];
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
_newWaves = ((vectorMagnitude ACE_wind) / 16.0) min 1.0;
private _newWaves = ((vectorMagnitude ACE_wind) / 16.0) min 1.0;
if (abs(_newWaves - waves) > 0.1) then {
1 setWaves _newWaves;
};

View File

@ -1,6 +1,9 @@
#define COMPONENT weather
#include "\z\ace\addons\main\script_mod.hpp"
//#define DEBUG_ENABLED_WEATHER
// #define DEBUG_MODE_FULL
// #define ENABLE_PERFORMANCE_COUNTERS
#ifdef DEBUG_ENABLED_WEATHER
#define DEBUG_MODE_FULL
#endif