digest concept

-use the second set of GVARs to track adding and removing attributes.
-Epoch_player* vars moved to local vars only accessible inside the
master loop.
-TODO: finish digest system with a config entry to control digest
limits. Some extra logic is needed.

Basically, when you consume some food, it will not increase your hunger
level immediately but raise over time.

Each of these should have limits on how much you can store in the digest
and how much each tick the digest var can affect the local player var in
the master loop.
This commit is contained in:
vbawol 2017-09-20 09:23:46 -05:00
parent 104721eced
commit a0e9ec0153
15 changed files with 229 additions and 108 deletions

View File

@ -22,7 +22,7 @@
NOTHING NOTHING
*/ */
//[[[cog import generate_private_arrays ]]] //[[[cog import generate_private_arrays ]]]
private ["_animConfigArray","_animationEffect","_animationEffectGlobal","_bleedAmount","_bleedChance","_bloodpAmount","_bloodpChance","_canSee","_cfgObjectInteraction","_distance","_doAttack","_fatigueChance","_ppEffect","_say3dsoundsConfig","_selectedMove","_selectedSound","_soundConfigArray","_soundEffect","_soundEffectGlobal","_switchMovehandlerConfig","_target","_toxicChance"]; private ["_animConfigArray","_animationEffect","_animationEffectGlobal","_bleedAmount","_bleedChance","_bloodpAmount","_bloodpChance","_canSee","_cfgObjectInteraction","_distance","_doAttack","_fatigueChance","_ppEffect","_say3dsoundsConfig","_selectedMove","_selectedSound","_soundConfigArray","_soundEffect","_soundEffectGlobal","_switchMovehandlerConfig","_target","_toxicAmount","_toxicChance"];
//[[[end]]] //[[[end]]]
params [["_unit",objNull],["_target",player]]; params [["_unit",objNull],["_target",player]];
if (isNull _unit && isNull _target) exitWith {}; if (isNull _unit && isNull _target) exitWith {};
@ -69,6 +69,7 @@ if (_doAttack) then {
_fatigueChance = getNumber (_cfgObjectInteraction >> "fatigueChance"); _fatigueChance = getNumber (_cfgObjectInteraction >> "fatigueChance");
_bleedAmount = getNumber (_cfgObjectInteraction >> "bleedAmount"); _bleedAmount = getNumber (_cfgObjectInteraction >> "bleedAmount");
_bloodpAmount = getNumber (_cfgObjectInteraction >> "bloodpAmount"); _bloodpAmount = getNumber (_cfgObjectInteraction >> "bloodpAmount");
_toxicAmount = getNumber (_cfgObjectInteraction >> "toxicAmount");
_soundConfigArray = getArray (_cfgObjectInteraction >> "soundEffect"); _soundConfigArray = getArray (_cfgObjectInteraction >> "soundEffect");
_soundEffect = ""; _soundEffect = "";
@ -112,13 +113,13 @@ if (_doAttack) then {
}; };
if (random 1 < _toxicChance) then { if (random 1 < _toxicChance) then {
EPOCH_playerToxicity = (EPOCH_playerToxicity + (random(100 - EPOCH_playerImmunity))) min 100; EPOCH_digestToxicity = (EPOCH_digestToxicity + random(_toxicAmount)) min 100;
}; };
if (random 1 < _bleedChance) then { if (random 1 < _bleedChance) then {
player setBleedingRemaining((getBleedingRemaining player) + _bleedAmount); player setBleedingRemaining((getBleedingRemaining player) + _bleedAmount);
}; };
if (random 1 < _bloodpChance) then { if (random 1 < _bloodpChance) then {
EPOCH_playerBloodP = (EPOCH_playerBloodP + (_bloodpAmount + (EPOCH_playerBloodP - 100))) min 190; EPOCH_digestBloodP = (EPOCH_digestBloodP + _bloodpAmount) min 100;
if !(_ppEffect isEqualTo []) then { if !(_ppEffect isEqualTo []) then {
[_ppEffect] spawn EPOCH_fnc_spawnEffects; [_ppEffect] spawn EPOCH_fnc_spawnEffects;
}; };

View File

@ -119,6 +119,6 @@ switch true do {
}; };
// Nuisance System 0.1 // Nuisance System 0.1
(EPOCH_customVarLimits select (EPOCH_customVars find "Nuisance")) params [["_playerLimitMax",100],["_playerLimitMin",0]]; (EPOCH_customVarLimits select (EPOCH_customVars find "Nuisance")) params [["_playerLimitMax",100],["_playerLimitMin",0]];
EPOCH_playerNuisance = ((EPOCH_playerNuisance + _nuisanceLevel) min _playerLimitMax) max _playerLimitMin; EPOCH_digestNuisance = ((EPOCH_digestNuisance + _nuisanceLevel) min _playerLimitMax) max _playerLimitMin;
}; };
}; };

View File

@ -1,14 +1,20 @@
// EPOCH_giveAttributes // EPOCH_giveAttributes
//[[[cog import generate_private_arrays ]]] //[[[cog import generate_private_arrays ]]]
private ["_addPlus","_celcuis","_celcuisNew","_currentVal","_customVarIndex","_data","_limits","_max","_min","_newValue","_return","_varName"]; private ["_addPlus","_celcuis","_currentVal","_customVarIndex","_customVarLimits","_customVarNames","_customVarsInit","_data","_defaultVarValues","_limits","_max","_min","_newValue","_return","_varName"];
//[[[end]]] //[[[end]]]
params ["_selectedVarName",["_data",0],["_randomizeData",0]]; params ["_selectedVarName",["_data",0],["_randomizeData",0]];
_addPlus = if (_data > 0) then {"+"} else {""}; _addPlus = if (_data > 0) then {"+"} else {""};
_return = ""; _return = "";
_customVarIndex = EPOCH_customVars find _selectedVarName;
_customVarsInit = ["CfgEpochClient", "customVarsDefaults", EPOCH_customVarsDefaults] call EPOCH_fnc_returnConfigEntryV2;
_customVarNames = _customVarsInit apply {_x param [0,""]};
_defaultVarValues = _customVarsInit apply {_x param [1,0]};
_customVarLimits = _customVarsInit apply {_x param [2,[]]};
_customVarIndex = _customVarNames find _selectedVarName;
if (_customVarIndex != -1) then { if (_customVarIndex != -1) then {
_varName = format["EPOCH_player%1",_selectedVarName]; _varName = format["EPOCH_digest%1",_selectedVarName];
_limits = EPOCH_customVarLimits select _customVarIndex; _limits = _customVarLimits select _customVarIndex;
_limits params [["_max",100],["_min",0]]; _limits params [["_max",100],["_min",0]];
if (_max isEqualType "") then { if (_max isEqualType "") then {
_max = missionNamespace getVariable [_max, 0]; _max = missionNamespace getVariable [_max, 0];
@ -16,7 +22,7 @@ if (_customVarIndex != -1) then {
if (_min isEqualType "") then { if (_min isEqualType "") then {
_min = missionNamespace getVariable [_min, 0]; _min = missionNamespace getVariable [_min, 0];
}; };
_currentVal = missionNamespace getVariable [_varName, EPOCH_defaultVars select _customVarIndex]; _currentVal = missionNamespace getVariable [_varName, 0];
if (_randomizeData isEqualTo 1) then { if (_randomizeData isEqualTo 1) then {
_data = round(random _data); _data = round(random _data);
}; };
@ -25,10 +31,9 @@ if (_customVarIndex != -1) then {
missionNamespace setVariable [_varName, _newValue]; missionNamespace setVariable [_varName, _newValue];
if (_selectedVarName == "Temp") then { if (_selectedVarName == "Temp") then {
_celcuis = _data call EPOCH_convertTemp; _celcuis = _data call EPOCH_convertTemp;
_celcuisNew = _newValue call EPOCH_convertTemp; _return = format["%1: %2%3°F %2%4°C",(localize format["str_epoch_pvar_%1",_selectedVarName]),_addPlus,_data,_celcuis];
_return = format["%1: %2%3 (%4 °F) %2%5 (%6 °C)",(localize format["str_epoch_pvar_%1",_selectedVarName]),_addPlus,_data,_newValue,_celcuis,_celcuisNew];
} else { } else {
_return = format["%1: %2%3 (%4/%5)", (localize format["str_epoch_pvar_%1",_selectedVarName]), _addPlus, _data, _newValue, _max]; _return = format["%1: %2%3", (localize format["str_epoch_pvar_%1",_selectedVarName]), _addPlus, _data];
}; };
}; };
}; };

View File

@ -30,7 +30,6 @@ EPOCH_debugMode = false;
EPOCH_snapDirection = 0; EPOCH_snapDirection = 0;
EPOCH_stabilityTarget = objNull; EPOCH_stabilityTarget = objNull;
EPOCH_equippedItem_PVS = []; EPOCH_equippedItem_PVS = [];
EPOCH_nearPower = false;
EPOCH_pendingP2ptradeTarget = objNull; EPOCH_pendingP2ptradeTarget = objNull;
EPOCH_lastNPCtradeTarget = objNull; EPOCH_lastNPCtradeTarget = objNull;
EPOCH_lastJumptime = diag_tickTime; EPOCH_lastJumptime = diag_tickTime;
@ -44,7 +43,6 @@ EPOCH_arr_snapPoints = [];
EPOCH_prevTarget = objNull; EPOCH_prevTarget = objNull;
EPOCH_interactOption = 0; EPOCH_interactOption = 0;
EPOCH_playerStaminaMax = 100; EPOCH_playerStaminaMax = 100;
EPOCH_playerEnergyMax = 2500;
{ {
missionNamespace setVariable [format ["EPOCH_player%1",_x],EPOCH_defaultVars select _forEachIndex]; missionNamespace setVariable [format ["EPOCH_player%1",_x],EPOCH_defaultVars select _forEachIndex];

View File

@ -57,6 +57,9 @@ if !(alive player && alive _playerObject && !isPlayer _playerObject) then {
Epoch_canBeRevived = false; Epoch_canBeRevived = false;
Epoch_personalToken = _personalToken; Epoch_personalToken = _personalToken;
// reset blood Pressure to warning level
EPOCH_playerBloodP = 120;
// restart masterloop // restart masterloop
[] spawn EPOCH_masterLoop; [] spawn EPOCH_masterLoop;
[5, 100] call EPOCH_niteLight; [5, 100] call EPOCH_niteLight;
@ -69,8 +72,6 @@ if !(alive player && alive _playerObject && !isPlayer _playerObject) then {
player addEventHandler [_x,(["CfgEpochClient", _x, ""] call EPOCH_fnc_returnConfigEntryV2)]; player addEventHandler [_x,(["CfgEpochClient", _x, ""] call EPOCH_fnc_returnConfigEntryV2)];
} forEach (["CfgEpochClient", "addEventHandler", []] call EPOCH_fnc_returnConfigEntryV2); } forEach (["CfgEpochClient", "addEventHandler", []] call EPOCH_fnc_returnConfigEntryV2);
// reset blood Pressure to warning level
EPOCH_playerBloodP = 120;
}; };
} else { } else {
deleteVehicle _playerObject; deleteVehicle _playerObject;

View File

@ -3,7 +3,7 @@ _forceBloodRise = false;
_forceFatigue = false; _forceFatigue = false;
_allowBloodDrop = false; _allowBloodDrop = false;
_forceStaminaDrop = false; _forceStaminaDrop = false;
_warnbloodPressure = EPOCH_playerBloodP > 120; _warnbloodPressure = _playerBloodP > 120;
_increaseStamina = true; _increaseStamina = true;
_val = 0; _val = 0;
@ -104,7 +104,7 @@ EPOCH_currentTargetMode = _currentTargetMode;
if (_forceBloodRise || _forceFatigue) then { if (_forceBloodRise || _forceFatigue) then {
_increaseStamina = false; _increaseStamina = false;
} else { } else {
if (EPOCH_playerStamina > 0 && !_panic) then { if (_playerStamina > 0 && !_panic) then {
_allowBloodDrop = true; _allowBloodDrop = true;
}; };
}; };
@ -118,17 +118,23 @@ if (_forceFatigue) then {
}; };
}; };
// force Blood Pressure Rise // Blood pressure handler
if (_forceBloodRise) then { if (EPOCH_digestBloodP > 0) then {
EPOCH_playerBloodP = (EPOCH_playerBloodP + 0.05) min 190; _playerBloodP = ((_playerBloodP + EPOCH_digestBloodP) min _playerBloodPMax) max _playerBloodPMin;
} else { } else {
if (_forceBloodRise) then {
// force Blood Pressure Rise
_playerBloodP = (_playerBloodP + 0.05) min 190;
} else {
if (_allowBloodDrop) then { if (_allowBloodDrop) then {
// allow player to bleed out // allow player to bleed out
_lowerBPlimit = [100,0] select (isBleeding player); _lowerBPlimit = [100,0] select (isBleeding player);
EPOCH_playerBloodP = EPOCH_playerBloodP - 1 max _lowerBPlimit; _playerBloodP = _playerBloodP - 1 max _lowerBPlimit;
};
}; };
}; };
// check if player On Foot // check if player On Foot
_isOnFoot = isNull objectParent player; _isOnFoot = isNull objectParent player;
if (_isOnFoot) then { if (_isOnFoot) then {
@ -141,11 +147,11 @@ if (_isOnFoot) then {
// Decrease Stamina // Decrease Stamina
if (_forceStaminaDrop) then { if (_forceStaminaDrop) then {
EPOCH_playerStamina = (EPOCH_playerStamina - (_val/4)) max 0; _playerStamina = (_playerStamina - (_val/4)) max 0;
} else { } else {
// Increase Stamina if player is not Fatigued // Increase Stamina if player is not Fatigued
if (_increaseStamina && (getFatigue player) == 0) then { if (_increaseStamina && (getFatigue player) == 0) then {
EPOCH_playerStamina = (EPOCH_playerStamina + 0.5) min EPOCH_playerStaminaMax; _playerStamina = (_playerStamina + 0.5) min EPOCH_playerStaminaMax;
}; };
}; };
@ -273,6 +279,18 @@ if !(EPOCH_ActiveTraderMission isequalto []) then {
// Update read only vars // Update read only vars
EPOCH_playerRadiation = _playerRadiation; EPOCH_playerRadiation = _playerRadiation;
EPOCH_playerAliveTime = _playerAliveTime; EPOCH_playerAliveTime = _playerAliveTime;
EPOCH_playerBloodP = _playerBloodP;
EPOCH_playerNuisance = _playerNuisance;
EPOCH_playerHunger = _playerHunger;
EPOCH_playerThirst = _playerThirst;
EPOCH_playerSoiled = _playerSoiled;
EPOCH_playerToxicity = _playerToxicity;
EPOCH_playerImmunity = _playerImmunity;
EPOCH_playerTemp = _playerTemp;
EPOCH_playerWet = _playerWet;
EPOCH_playerEnergy = _playerEnergy;
EPOCH_playerAlcohol = _playerAlcohol;
EPOCH_playerStamina = _playerStamina;
// force update // force update
if (EPOCH_forceUpdateNow) then { if (EPOCH_forceUpdateNow) then {

View File

@ -17,7 +17,7 @@ if (damage player != _damagePlayer) then {
// 1. number of players // 1. number of players
// 2. Other sources of drain (Lights) // 2. Other sources of drain (Lights)
_energyValue = EPOCH_chargeRate min _energyRegenMax; _energyValue = _chargeRate min _energyRegenMax;
_vehicle = vehicle player; _vehicle = vehicle player;
if (_vehicle != player && isEngineOn _vehicle) then { if (_vehicle != player && isEngineOn _vehicle) then {
_energyValue = _energyValue + 5; _energyValue = _energyValue + 5;
@ -25,15 +25,15 @@ if (_vehicle != player && isEngineOn _vehicle) then {
if (currentVisionMode player == 1) then { //NV enabled if (currentVisionMode player == 1) then { //NV enabled
_energyValue = _energyValue - _energyCostNV; _energyValue = _energyValue - _energyCostNV;
if (EPOCH_playerEnergy == 0) then { if (_playerEnergy == 0) then {
player action["nvGogglesOff", player]; player action["nvGogglesOff", player];
["Night Vision Goggles: Need Energy", 5] call Epoch_message; ["Night Vision Goggles: Need Energy", 5] call Epoch_message;
}; };
}; };
// Sets visual effect // Sets visual effect
if (EPOCH_playerAlcohol > 20) then { if (_playerAlcohol > 20) then {
_drunkVal = linearConversion [0,100,EPOCH_playerAlcohol,0.1,1,true]; _drunkVal = linearConversion [0,100,_playerAlcohol,0.1,1,true];
[_drunkVal, 2] call epoch_setDrunk; [_drunkVal, 2] call epoch_setDrunk;
} else { } else {
[0, 2] call epoch_setDrunk; [0, 2] call epoch_setDrunk;
@ -54,18 +54,23 @@ if (_playerRadiation > 1) then {
[0, 2] call epoch_setRadiation; [0, 2] call epoch_setRadiation;
}; };
EPOCH_playerEnergy = ((EPOCH_playerEnergy + _energyValue) min EPOCH_playerEnergyMax) max 0; // Energy Handler
if (EPOCH_digestEnergy > 0) then {
_energyValue = _energyValue + EPOCH_digestEnergy;
EPOCH_digestEnergy = 0;
};
_playerEnergy = ((_playerEnergy + _energyValue) min _playerEnergyMax) max _playerEnergyMin;
if !(EPOCH_playerEnergy isEqualTo _prevEnergy) then { if !(_playerEnergy isEqualTo _prevEnergy) then {
9993 cutRsc["EpochGameUI3", "PLAIN", 0, false]; 9993 cutRsc["EpochGameUI3", "PLAIN", 0, false];
_display3 = uiNamespace getVariable "EPOCH_EpochGameUI3"; _display3 = uiNamespace getVariable "EPOCH_EpochGameUI3";
_energyDiff = round(EPOCH_playerEnergy - _prevEnergy); _energyDiff = round(_playerEnergy - _prevEnergy);
_diffText = if (_energyDiff > 0) then {format["+%1",_energyDiff]} else {format["%1",_energyDiff]}; _diffText = if (_energyDiff > 0) then {format["+%1",_energyDiff]} else {format["%1",_energyDiff]};
(_display3 displayCtrl 21210) ctrlSetText format["%1/%2 %3", round(EPOCH_playerEnergy), EPOCH_playerEnergyMax, _diffText]; (_display3 displayCtrl 21210) ctrlSetText format["%1/%2 %3", round(_playerEnergy), _playerEnergyMax, _diffText];
_prevEnergy = EPOCH_playerEnergy; _prevEnergy = _playerEnergy;
}; };
if (EPOCH_playerEnergy == 0) then { if (_playerEnergy == 0) then {
if (EPOCH_buildMode > 0) then { if (EPOCH_buildMode > 0) then {
EPOCH_buildMode = 0; EPOCH_buildMode = 0;
EPOCH_snapDirection = 0; EPOCH_snapDirection = 0;
@ -111,7 +116,7 @@ if (_isOnFoot) then {
_increaseWet = 10; _increaseWet = 10;
}; };
} else { } else {
if (EPOCH_playerWet > 50 && _airTemp <= 32) then { if (_playerWet > 50 && _airTemp <= 32) then {
_isNearFire = {inflamed _x} count (nearestObjects [player, ["ALL"], 3]); _isNearFire = {inflamed _x} count (nearestObjects [player, ["ALL"], 3]);
if (!(call EPOCH_fnc_isInsideBuilding) && _isNearFire == 0) then { if (!(call EPOCH_fnc_isInsideBuilding) && _isNearFire == 0) then {
_warming = false; _warming = false;
@ -134,28 +139,34 @@ if ((getFatigue player) >= 0.7 && _airTemp > 100) then {
_maxTemp = _airTemp; _maxTemp = _airTemp;
}; };
// Immunity Handler
if (EPOCH_digestImmunity > 0) then {
_playerImmunity = ((_playerImmunity + EPOCH_digestImmunity) min _playerImmunityMax) max _playerImmunityMin;
EPOCH_digestImmunity = 0;
};
// toxic fever and immunity increase // toxic fever and immunity increase
if (EPOCH_playerToxicity > 0) then { if (_playerToxicity > 0) then {
EPOCH_playerImmunity = (EPOCH_playerImmunity + 0.1) min 100; _playerImmunity = ((_playerImmunity + 0.1) min _playerImmunityMax) max _playerImmunityMin;
EPOCH_playerToxicity = (EPOCH_playerToxicity - 0.1) max 0; _playerToxicity = ((_playerToxicity - 0.1) min _playerToxicityMax) max _playerToxicityMin;
_maxTemp = 106.7 + 10; _maxTemp = 106.7 + 10;
}; };
if (_warming) then { if (_warming) then {
EPOCH_playerTemp = (EPOCH_playerTemp + 0.01) min _maxTemp; _playerTemp = (_playerTemp + 0.01) min _maxTemp;
} else { } else {
EPOCH_playerTemp = (EPOCH_playerTemp - 0.01) max (95.0 - 10); _playerTemp = (_playerTemp - 0.01) max (95.0 - 10);
}; };
// wet/dry // wet/dry
if (_wet) then { if (_wet) then {
EPOCH_playerWet = (EPOCH_playerWet + _increaseWet) min 100; _playerWet = ((_playerWet + _increaseWet) min _playerWetMax) max _playerWetMin;
if (EPOCH_playerWet > 50) then { if (_playerWet > 50) then {
EPOCH_playerSoiled = (EPOCH_playerSoiled - 1) max 0; _playerSoiled = ((_playerSoiled - 1) min _playerSoiledMax) max _playerSoiledMin;
}; };
} else { } else {
if (_warming) then { if (_warming) then {
EPOCH_playerWet = (EPOCH_playerWet - 1) max 0; _playerWet = ((_playerWet - 1) min _playerWetMax) max _playerWetMin;
}; };
}; };
@ -164,7 +175,7 @@ _hungerlossRate = _baseHungerLoss * timeMultiplier;
_thirstlossRate = _baseThirstLoss * timeMultiplier; _thirstlossRate = _baseThirstLoss * timeMultiplier;
// Increase hunger if player is Fatigued // Increase hunger if player is Fatigued
if (EPOCH_playerStamina < 100) then { if (_playerStamina < 100) then {
if ((getFatigue player) > 0) then { if ((getFatigue player) > 0) then {
_hungerlossRate = _hungerlossRate + (_hungerlossRate*(getFatigue player)); _hungerlossRate = _hungerlossRate + (_hungerlossRate*(getFatigue player));
}; };
@ -173,13 +184,58 @@ if (EPOCH_playerStamina < 100) then {
_hungerlossRate = (_hungerlossRate / 2); _hungerlossRate = (_hungerlossRate / 2);
}; };
EPOCH_playerHunger = (EPOCH_playerHunger - _hungerlossRate) max 0; // Alcohol Handler
EPOCH_playerThirst = (EPOCH_playerThirst - _thirstlossRate) max 0; if (EPOCH_digestAlcohol > 0) then {
_playerAlcohol = ((_playerAlcohol + EPOCH_digestAlcohol) min _playerAlcoholMax) max _playerAlcoholMin;
EPOCH_digestAlcohol = 0;
} else {
// downtick Alcohol
_alcoholLossRate = 0.17;
_playerAlcohol = ((_playerAlcohol - _alcoholLossRate) min _playerAlcoholMax) max _playerAlcoholMin;
};
call _lootBubble; // Hunger Handler
if (EPOCH_digestHunger > 0) then {
_playerHunger = ((_playerHunger + EPOCH_digestHunger) min _playerHungerMax) max _playerHungerMin;
EPOCH_digestHunger = 0;
} else {
// downtick Hunger
_playerHunger = ((_playerHunger - _hungerlossRate) min _playerHungerMax) max _playerHungerMin;
};
// Thirst Handler
if (EPOCH_digestThirst > 0) then {
_playerThirst = ((_playerThirst + EPOCH_digestThirst) min _playerThirstMax) max _playerThirstMin;
EPOCH_digestThirst = 0;
} else {
// downtick Thirst
_playerThirst = ((_playerThirst - _thirstlossRate) min _playerThirstMax) max _playerThirstMin;
};
// Nuisance Handler, this only allows var to increse not decrease
if (EPOCH_digestNuisance > 0) then {
_playerNuisance = ((_playerNuisance + EPOCH_digestNuisance) min _playerNuisanceMax) max _playerNuisanceMin;
EPOCH_digestNuisance = 0;
} else {
// downtick Nuisance
_playerNuisance = ((_playerNuisance - 1) min _playerNuisanceMax) max _playerNuisanceMin;
};
// Radiation Handler
if (EPOCH_digestRadiation < 0 && _radsLevel == 0) then {
// only lower rads if player has taken medicine and it no longer in a radiation zone.
_playerRadiation = ((_playerRadiation - 0.01) min _playerRadiationMax) max _playerRadiationMin;
EPOCH_digestRadiation = (EPOCH_digestRadiation + 1) min 0;
} else {
// allow increase rads based on radiation levels and consumed rads
if (EPOCH_digestRadiation > 0) then {
_radsLevel = _radsLevel + EPOCH_digestRadiation;
EPOCH_digestRadiation = 0;
};
_playerRadiation = ((_playerRadiation + _radsLevel) min _playerRadiationMax) max _playerRadiationMin;
};
EPOCH_playerStaminaMax = (100 * (round(_playerAliveTime/360)/10)) min 2500; EPOCH_playerStaminaMax = (100 * (round(_playerAliveTime/360)/10)) min 2500;
// downtick Nuisance // process loot
(_customVarLimits select (_customVarNames find "Nuisance")) params [["_playerLimitMax",100],["_playerLimitMin",0]]; call _lootBubble;
EPOCH_playerNuisance = ((EPOCH_playerNuisance - 1) min _playerLimitMax) max _playerLimitMin;

View File

@ -7,32 +7,22 @@ _powerSources = nearestObjects[player, ["Land_spp_Tower_F","Land_wpp_Turbine_V2_
_nearbyRadioactiveObjects = (_powerSources + EPOCH_nearestLocations) select {_x getVariable ["EPOCH_Rads", 0] > 0}; _nearbyRadioactiveObjects = (_powerSources + EPOCH_nearestLocations) select {_x getVariable ["EPOCH_Rads", 0] > 0};
// check if player is out of map bounds. // check if player is out of map bounds.
_radsLevel = 0;
_worldSize = worldSize/2; _worldSize = worldSize/2;
_outOfBounds = !(player inArea [[_worldSize,_worldSize,0], _worldSize, _worldSize, 0, true ]); _outOfBounds = !(player inArea [[_worldSize,_worldSize,0], _worldSize, _worldSize, 0, true ]);
if (_outOfBounds) then { if (_outOfBounds) then {
// player is out of map bounds, give ten times background rads // player is out of map bounds, give ten times background rads
["You are out of the play area!", 5] call Epoch_message; ["You are out of the play area!", 5] call Epoch_message;
_radsLevel = _backgroundRadiation; _radsLevel = _outOfBoundsRadiation;
_playerRadiation = ((_playerRadiation + _radsLevel) min 100) max 0;
} else { } else {
// radiated objects or locations nearby // radiated objects or locations nearby
if !(_nearbyRadioactiveObjects isEqualTo []) then { if !(_nearbyRadioactiveObjects isEqualTo []) then {
// add extra rads based on intensity and distance from site. // add extra rads based on intensity and distance from site.
_radioActiveSite = _nearbyRadioactiveObjects select 0; _radsLevel = ((_nearbyRadioactiveObjects select 0) getVariable ["EPOCH_Rads", 0]) / (player distance _radioActiveSite);
_radsLevel = (_radioActiveSite getVariable ["EPOCH_Rads", 0]) / (player distance _radioActiveSite);
_playerRadiation = ((_playerRadiation + _radsLevel) min 100) max 0;
} else {
// TODO handle reduction of rads in master loop
_anitRadiation = player getVariable ["EPOCH_antiRadiation", 0];
if (_anitRadiation > 0) then {
// lower radiation by 0.1 per tick
_playerRadiation = ((_playerRadiation - 0.1) min 100) max 0;
// lower anti rad level
player setVariable ["EPOCH_antiRadiation", _anitRadiation - 1];
};
}; };
}; };
EPOCH_playerIsSwimming = false; EPOCH_playerIsSwimming = false;
if !(surfaceIsWater _position) then { if !(surfaceIsWater _position) then {
@ -53,8 +43,7 @@ if !(surfaceIsWater _position) then {
}; };
// default power state // default power state
EPOCH_nearPower = false; _chargeRate = 0;
EPOCH_chargeRate = 0;
// energy Charge from nearby power plants // energy Charge from nearby power plants
if !(_powerSources isEqualTo[]) then { if !(_powerSources isEqualTo[]) then {
@ -76,15 +65,13 @@ if !(_powerSources isEqualTo[]) then {
if (_totalCapacity > 0) then { if (_totalCapacity > 0) then {
_players = player nearEntities[["Epoch_Male_F", "Epoch_Female_F"], _energyRange]; _players = player nearEntities[["Epoch_Male_F", "Epoch_Female_F"], _energyRange];
if (_players isEqualTo []) then { if (_players isEqualTo []) then {
EPOCH_chargeRate = ceil _totalCapacity; _chargeRate = ceil _totalCapacity;
} else { } else {
EPOCH_chargeRate = ceil (_totalCapacity / (count _players)); _chargeRate = ceil (_totalCapacity / (count _players));
}; };
EPOCH_nearPower = true;
}; };
}; };
// downtick Alcohol
EPOCH_playerAlcohol = ((EPOCH_playerAlcohol - 1) min 100) max 0;
_playerAliveTime = round(_playerAliveTime + (_tickTime - _clientAliveTimer)); _playerAliveTime = round(_playerAliveTime + (_tickTime - _clientAliveTimer));
_clientAliveTimer = _tickTime; _clientAliveTimer = _tickTime;

View File

@ -1,4 +1,4 @@
_spawnChance = ((EPOCH_playerNuisance + EPOCH_playerSoiled)/2) max 1; _spawnChance = ((_playerNuisance + _playerSoiled)/2) max 1;
// add more antagonist spawn chances // add more antagonist spawn chances
if (random _antagonistRndChance < _spawnChance) then { if (random _antagonistRndChance < _spawnChance) then {
// selectRandomWeighted arma 1.76 or higher // selectRandomWeighted arma 1.76 or higher

View File

@ -1,5 +1,8 @@
// make sure we wait for Display #46 // make sure we wait for Display #46
waitUntil {!(isNull (findDisplay 46))}; waitUntil {!isNull (findDisplay 46) && (!isNil "EPOCH_loadingScreenDone")};
// load favBar
'load' call epoch_favBar_draw;
// force update within 15 seconds // force update within 15 seconds
EPOCH_forceUpdate = false; EPOCH_forceUpdate = false;
@ -10,6 +13,18 @@ EPOCH_forceUpdateNow = false;
// init local player stat vars // init local player stat vars
_playerRadiation = EPOCH_playerRadiation; _playerRadiation = EPOCH_playerRadiation;
_playerAliveTime = EPOCH_playerAliveTime; _playerAliveTime = EPOCH_playerAliveTime;
_playerNuisance = EPOCH_playerNuisance;
_playerBloodP = EPOCH_playerBloodP;
_playerHunger = EPOCH_playerHunger;
_playerThirst = EPOCH_playerThirst;
_playerSoiled = EPOCH_playerSoiled;
_playerToxicity = EPOCH_playerToxicity;
_playerImmunity = EPOCH_playerImmunity;
_playerTemp = EPOCH_playerTemp;
_playerWet = EPOCH_playerWet;
_playerEnergy = EPOCH_playerEnergy;
_playerAlcohol = EPOCH_playerAlcohol;
_playerStamina = EPOCH_playerStamina;
// start alive timer // start alive timer
_clientAliveTimer = diag_tickTime; _clientAliveTimer = diag_tickTime;
@ -20,18 +35,64 @@ _customVarNames = _customVarsInit apply {_x param [0,""]};
_defaultVarValues = _customVarsInit apply {_x param [1,0]}; _defaultVarValues = _customVarsInit apply {_x param [1,0]};
_customVarLimits = _customVarsInit apply {_x param [2,[]]}; _customVarLimits = _customVarsInit apply {_x param [2,[]]};
// init limits
/*
{
_varLimits = _customVarLimits select _forEachIndex;
call compile format['_varLimits params [["_player%1Max",100],["_player%1Min",0]];',_x];
} forEach _customVarNames;
*/
(_customVarLimits select (_customVarNames find "Temp")) params [["_playerTempMax",100],["_playerTempMin",0]];
(_customVarLimits select (_customVarNames find "Hunger")) params [["_playerHungerMax",100],["_playerHungerMin",0]];
(_customVarLimits select (_customVarNames find "Thirst")) params [["_playerThirstMax",100],["_playerThirstMin",0]];
(_customVarLimits select (_customVarNames find "Energy")) params [["_playerEnergyMax",100],["_playerEnergyMin",0]];
(_customVarLimits select (_customVarNames find "Wet")) params [["_playerWetMax",100],["_playerWetMin",0]];
(_customVarLimits select (_customVarNames find "Soiled")) params [["_playerSoiledMax",100],["_playerSoiledMin",0]];
(_customVarLimits select (_customVarNames find "Immunity")) params [["_playerImmunityMax",100],["_playerImmunityMin",0]];
(_customVarLimits select (_customVarNames find "Toxicity")) params [["_playerToxicityMax",100],["_playerToxicityMin",0]];
(_customVarLimits select (_customVarNames find "Stamina")) params [["_playerStaminaMax",100],["_playerStaminaMin",0]];
(_customVarLimits select (_customVarNames find "BloodP")) params [["_playerBloodPMax",100],["_playerBloodPMin",0]];
(_customVarLimits select (_customVarNames find "Alcohol")) params [["_playerAlcoholMax",100],["_playerAlcoholMin",0]];
(_customVarLimits select (_customVarNames find "Radiation")) params [["_playerRadiationMax",100],["_playerRadiationMin",0]];
(_customVarLimits select (_customVarNames find "Nuisance")) params [["_playerNuisanceMax",100],["_playerNuisanceMin",0]];
EPOCH_playerEnergyMax = _playerEnergyMax;
// inline function to sync player stats to server // inline function to sync player stats to server
_fnc_forceUpdate = { _fnc_forceUpdate = {
private _customVars = []; private _customVars = [];
{ {
// use local var from inside master loop // use local var from inside master loop
/*
call compile format['_customVars pushBack _player%1;',_x];
*/
switch (_x) do { switch (_x) do {
case ("Radiation"): { case ("Radiation"): {
_customVars pushBack _playerRadiation; _customVars pushBack _playerRadiation;
}; };
case ("Nuisance"): {
_customVars pushBack _playerNuisance;
};
case ("BloodP"): {
_customVars pushBack _playerBloodP;
};
case ("AliveTime"):{ case ("AliveTime"):{
_customVars pushBack _playerAliveTime; _customVars pushBack _playerAliveTime;
}; };
case ("Hunger"):{
_customVars pushBack _playerHunger;
};
case ("Thirst"):{
_customVars pushBack _playerThirst;
};
case ("Alcohol"):{
_customVars pushBack _playerAlcohol;
};
case ("Energy"):{
_customVars pushBack _playerEnergy;
};
default { default {
private _customVarIndex = _customVarNames find _x; private _customVarIndex = _customVarNames find _x;
if (_customVarIndex != -1) then { if (_customVarIndex != -1) then {
@ -61,14 +122,14 @@ if (isNil "EPOCH_display_setup_complete") then {
// Background radiation // Background radiation
_backgroundRadiation = ["CfgEpochClient", "backgroundRadiation", 10] call EPOCH_fnc_returnConfigEntryV2; _outOfBoundsRadiation = ["CfgEpochClient", "outOfBoundsRadiation", 10] call EPOCH_fnc_returnConfigEntryV2;
_radsLevel = 0; _radsLevel = 0;
_prevEquippedItem = []; _prevEquippedItem = [];
_damagePlayer = damage player; _damagePlayer = damage player;
_isOnFoot = isNull objectParent player; _isOnFoot = isNull objectParent player;
_panic = false; _panic = false;
_prevEnergy = EPOCH_playerEnergy; _prevEnergy = _playerEnergy;
// init config data // init config data
@ -81,7 +142,7 @@ _energyRegenMax = ["CfgEpochClient", "energyRegenMax", 5] call EPOCH_fnc_returnC
_energyRange = ["CfgEpochClient", "energyRange", 75] call EPOCH_fnc_returnConfigEntryV2; _energyRange = ["CfgEpochClient", "energyRange", 75] call EPOCH_fnc_returnConfigEntryV2;
_hudConfigs = ["CfgEpochClient", "hudConfigs", []] call EPOCH_fnc_returnConfigEntryV2; _hudConfigs = ["CfgEpochClient", "hudConfigs", []] call EPOCH_fnc_returnConfigEntryV2;
EPOCH_chargeRate = 0; _chargeRate = 0;
EPOCH_playerIsSwimming = false; EPOCH_playerIsSwimming = false;
_antagonistChanceDefaults = [ _antagonistChanceDefaults = [

View File

@ -89,11 +89,4 @@ addMissionEventHandler ["PlayerViewChanged", {if (cameraView isEqualTo "GROUP")
// testing for civilan males // testing for civilan males
player addRating -2000; player addRating -2000;
//Start processing right after Loading screen is done and game has started
[] spawn {
waitUntil {!isNull (findDisplay 46) && (!isNil "EPOCH_loadingScreenDone")};
'load' call epoch_favBar_draw;
};
true true

View File

@ -11,7 +11,7 @@ interactAttributes[] = {
{"Toxicity",0}, {"Toxicity",0},
{"Stamina",0}, {"Stamina",0},
{"Wet",0}, {"Wet",0},
{"BloodP",0}, {"BloodP",0}, // only increase is allowed
{"Karma",0}, {"Karma",0},
{"Alcohol",0}, {"Alcohol",0},
{"Radiation",0} {"Radiation",0}
@ -76,7 +76,7 @@ class CfgItemInteractions
class honey_epoch : Food_Jar_base class honey_epoch : Food_Jar_base
{ {
interactText = "EAT"; interactText = "EAT";
interactAttributes[] = {{"Immunity",1},{"Stamina",30},{"BloodP",10}}; interactAttributes[] = {{"Immunity",1},{"Stamina",30}};
interactActions[] = {{"EMPTY","[1,[],'emptyjar_epoch'] call EPOCH_consumeItem;"}}; interactActions[] = {{"EMPTY","[1,[],'emptyjar_epoch'] call EPOCH_consumeItem;"}};
}; };
class sardines_epoch : Food_TinCan_base class sardines_epoch : Food_TinCan_base
@ -342,7 +342,7 @@ class CfgItemInteractions
class ItemVitamins : Food_base class ItemVitamins : Food_base
{ {
interactText = "Take Pills"; interactText = "Take Pills";
interactAttributes[] = {{"Immunity",20},{"Stamina",50},{"BloodP",-10},{"Toxicity",-5},{"Thirst",-150}}; interactAttributes[] = {{"Immunity",20},{"Stamina",50},{"Toxicity",-5},{"Thirst",-150}};
}; };
class KitSpikeTrap : Item_Build_base class KitSpikeTrap : Item_Build_base
{ {
@ -500,7 +500,7 @@ class CfgItemInteractions
{ {
interactAction = 6; interactAction = 6;
interactText = "USE"; interactText = "USE";
interactAttributes[] = {{"Immunity",10},{"Stamina",-100},{"BloodP",-10}}; interactAttributes[] = {{"Immunity",10},{"Stamina",-100}};
}; };
class Goldenseal : Default class Goldenseal : Default
{ {

View File

@ -18,6 +18,7 @@ class CfgObjectInteractions
fatigueChance = 0; fatigueChance = 0;
bleedAmount = 0; bleedAmount = 0;
bloodpAmount = 0; bloodpAmount = 0;
toxicAmount = 0;
soundEffect[] = {}; soundEffect[] = {};
soundEffectGlobal = 0; soundEffectGlobal = 0;
animationEffect[] = {}; animationEffect[] = {};
@ -166,6 +167,7 @@ class CfgObjectInteractions
interactMode = 3; interactMode = 3;
distance = 3; distance = 3;
toxicChance = 0.2; toxicChance = 0.2;
toxicAmount = 10;
bloodpChance = 1; bloodpChance = 1;
fatigueChance = 0.5; fatigueChance = 0.5;
bleedAmount = 30; bleedAmount = 30;
@ -181,6 +183,7 @@ class CfgObjectInteractions
interactMode = 3; interactMode = 3;
distance = 3; distance = 3;
toxicChance = 0.1; toxicChance = 0.1;
toxicAmount = 10;
bloodpChance = 1; bloodpChance = 1;
fatigueChance = 0.5; fatigueChance = 0.5;
bleedAmount = 30; bleedAmount = 30;
@ -210,6 +213,7 @@ class CfgObjectInteractions
{ {
distance = 6; distance = 6;
toxicChance = 1; toxicChance = 1;
toxicAmount = 100;
bleedChance = 0; bleedChance = 0;
bloodpChance = 1; bloodpChance = 1;
fatigueChance = 1; fatigueChance = 1;
@ -238,6 +242,7 @@ class CfgObjectInteractions
{ {
distance = 3; distance = 3;
toxicChance = 0.1; toxicChance = 0.1;
toxicAmount = 10;
bloodpChance = 0.9; bloodpChance = 0.9;
fatigueChance = 0.4; fatigueChance = 0.4;
bleedAmount = 30; bleedAmount = 30;

View File

@ -6,27 +6,23 @@
https://github.com/EpochModTeam/Epoch/tree/release/Sources/epoch_server_settings/EpochEvents/Satellite.sqf https://github.com/EpochModTeam/Epoch/tree/release/Sources/epoch_server_settings/EpochEvents/Satellite.sqf
*/ */
//[[[cog import generate_private_arrays ]]] //[[[cog import generate_private_arrays ]]]
private ["_item","_marker","_playersNearEpicenter","_position","_satellites"]; private ["_satellite","_marker","_playersNearEpicenter","_position","_satellites"];
//[[[end]]] //[[[end]]]
_position = [epoch_centerMarkerPosition, 0, EPOCH_dynamicVehicleArea, 10, 0, 1000, 0] call BIS_fnc_findSafePos; _position = [epoch_centerMarkerPosition, 0, EPOCH_dynamicVehicleArea, 10, 0, 1000, 0] call BIS_fnc_findSafePos;
if ((count _position) == 2) then{ if ((count _position) == 2) then{
_playersNearEpicenter = _position nearEntities[["Epoch_Male_F", "Epoch_Female_F"], 1000];
// todo send shockwave + effects to each player in zone // spawn Satellite
/*
if !(_playersNearEpicenter isEqualTo[]) then{
// todo add shockwave effects script
[_position] remoteExec ['EPOCH_client_earthQuake',_playersNearEpicenter];
};
*/
// Satellite classes
_satellites = ["Land_Wreck_Satellite_EPOCH"]; _satellites = ["Land_Wreck_Satellite_EPOCH"];
_satellite = createVehicle[(selectRandom _satellites), _position, [], 0.0, "CAN_COLLIDE"];
_item = createVehicle[(selectRandom _satellites), _position, [], 0.0, "CAN_COLLIDE"]; // send shockwave + effects to each player in zone at time of crash
_playersNearEpicenter = _position nearEntities[["Epoch_Male_F", "Epoch_Female_F"], 1000];
if !(_playersNearEpicenter isEqualTo[]) then{
[_satellite, -1, 0.8, false] remoteExec ['BIS_fnc_sandstorm',_playersNearEpicenter];
};
// set rads // set rads
_item setVariable ["EPOCH_Rads", 100, true]; _satellite setVariable ["EPOCH_Rads", 10, true];
if (EPOCH_showSatellites) then{ if (EPOCH_showSatellites) then{
_marker = createMarker[str(_position), _position]; _marker = createMarker[str(_position), _position];

View File

@ -11,12 +11,12 @@ All changes for [Arma 3](https://arma3.com/) [Epoch Mod](https://epochmod.com) a
- Vehicle Upgrade System - Upgrade your ride by using one of the new vehicle upgrade documents found in the world. @DirtySanchez - Vehicle Upgrade System - Upgrade your ride by using one of the new vehicle upgrade documents found in the world. @DirtySanchez
- Vector Base Building (uses Arrow keys by default and with SHIFT / ALT you can control the steps). @DirtySanchez & @Ignatz-Heman - Vector Base Building (uses Arrow keys by default and with SHIFT / ALT you can control the steps). @DirtySanchez & @Ignatz-Heman
- New Base Building Objects: Quarter and Half wood floors @DirtySanchez, Cinder block floor, Cinder wall with window. @Helion. - New Base Building Objects: Quarter and Half wood floors @DirtySanchez, Cinder block floor, Cinder wall with a window. @Helion.
- Medical items: Adrenaline Shot (adrenaline_epoch), Caffeine Pills (caffeinepills_epoch). Orlistat Pills (orlistat_epoch) by @Helion and configs by @DirtySanchez - Medical items: Adrenaline Shot (adrenaline_epoch), Caffeine Pills (caffeinepills_epoch). Orlistat Pills (orlistat_epoch) by @Helion and configs by @DirtySanchez
- Food items: ItemCereals, ItemPowderMilk_F, ItemRiceBox, ItemVitamins. @DirtySanchez - Food items: ItemCereals, ItemPowderMilk_F, ItemRiceBox, ItemVitamins. @DirtySanchez
- Digital Geiger Counter - used to detect Radiation. (Sounds @vbawol, Model @Helion and UI + digital font @raymix) - Digital Geiger Counter - used to detect Radiation. (Sounds @vbawol, Model @Helion, and UI + digital font @raymix)
- Barrel Bomb - large craft-able explosive that can be placed and detonated. @DirtySanchez - Barrel Bomb - large craft-able explosive that can be placed and detonated. @DirtySanchez
- Brown Briefcase that contains 100oz Silver. @DirtySanchez - Brown Briefcase that contains 100oz Silver. @DirtySanchez
- Old "Zombie Parts" Bag (ItemBioHazardBag). - Old "Zombie Parts" Bag (ItemBioHazardBag).
@ -40,13 +40,13 @@ All changes for [Arma 3](https://arma3.com/) [Epoch Mod](https://epochmod.com) a
### Changed ### Changed
- CBA extended event handler and zeus curator support for Epoch Vehicles. @DirtySanchez - CBA extended event handler and zeus curator support for Epoch Vehicles. @DirtySanchez
- Base PlotPole ESP added to Epoch Admin Panel. @SMVampire - Base PlotPole ESP added to Epoch Admin Panel. @SMVampire
- Helper arrow to indicate door-opening direction for Base Building. @Ignatz-Heman - Helper arrow to indicate the door-opening direction for Base Building. @Ignatz-Heman
- Base Building elements can be detached to walk around the Element before saving. @Ignatz-Heman - Base Building elements can be detached to walk around the Element before saving. @Ignatz-Heman
- Made ServicePoint more configurable @Ignatz-Heman - Made ServicePoint more configurable @Ignatz-Heman
- Base Building: Replaced 0/90/180/270° direction build mode with "Rotate 90°". @Ignatz-Heman - Base Building: Replaced 0/90/180/270° direction build mode with "Rotate 90°". @Ignatz-Heman
- Base Building: Max building height now will be checked directly at building element placement. @Ignatz-Heman - Base Building: Max building height now will be checked directly at building element placement. @Ignatz-Heman
- Separated Hunger and Thirst loss values to baseHungerLoss/baseThirstLoss and removed baseHTLoss from CfgEpochClient. - Separated Hunger and Thirst loss values to baseHungerLoss/baseThirstLoss and removed baseHTLoss from CfgEpochClient.
- Hunger and Thirst loss rates are now effected by timeMultiplier. - Hunger and Thirst loss rates are now affected by timeMultiplier.
- Bump to hive version 0.6.0.0, Note: this requires epochserver hive extension updates server side. - Bump to hive version 0.6.0.0, Note: this requires epochserver hive extension updates server side.
- Gas Station Auto-Refuel is now disabled on all maps. Use disableAutoRefuel = false; via epochconfig.hpp to disable. @SMVampire - Gas Station Auto-Refuel is now disabled on all maps. Use disableAutoRefuel = false; via epochconfig.hpp to disable. @SMVampire
### Fixed ### Fixed