Add the shelter state to the player

Bases count as a secure area now. This means it will not rain through a base any longer. Also the temperature will not drop when you are inside of your base. This also affects snow, blizzards and evr storms.

Made by @Victor-the-Cleaner
This commit is contained in:
A Man
2022-05-18 18:25:25 +02:00
parent 2ebe0d6552
commit 8071602dd7
6 changed files with 284 additions and 144 deletions

View File

@@ -385,9 +385,10 @@ fnc_evr = {
disableUserInput true; disableUserInput true;
local _vehicle = vehicle player;
local _inside = (dayz_inside || (DZE_roofOverhead && {DZE_sheltered > 0.96}));
if (player == _vehicle) then {
if (_hasAPSI || {DZE_EVRProtectInside && dayz_inside}) then {
if (_hasAPSI || {DZE_EVRProtectInside && _inside}) then {
player switchMove "";
[objNull, player, rswitchMove, ""] call RE;
} else {
@@ -401,7 +402,7 @@ fnc_evr = {
player action ["engineOff",_vehicle];
_vehicle setFuel _fuel;
} else {
if (!_hasAPSI && {!DZE_EVRProtectInside || (DZE_EVRProtectInside && !dayz_inside)}) then {
if (!_hasAPSI && {!DZE_EVRProtectInside || (DZE_EVRProtectInside && !_inside)}) then {
player action ["eject",_vehicle];
[] spawn {
uiSleep 3;
@@ -417,7 +418,7 @@ fnc_evr = {
uiSleep 0.1;
titleText["","BLACK OUT",1];
if (!_hasAPSI && {!DZE_EVRProtectInside || (DZE_EVRProtectInside && !dayz_inside)}) then {
if (!_hasAPSI && {!DZE_EVRProtectInside || (DZE_EVRProtectInside && !_inside)}) then {
r_player_inpain = true;
player setVariable["USEC_inPain",true,true];
local _blood = r_player_blood - ((DZE_EVRBloodLoss select 0) max random(DZE_EVRBloodLoss select 1)); // Player is not inside a building so reduce blood.
@@ -458,7 +459,7 @@ fnc_evr = {
"dynamicBlur" ppEffectCommit 16;
if (!_hasAPSI) then {
if (player == vehicle player && {!DZE_EVRProtectInside || (DZE_EVRProtectInside && !dayz_inside)}) then {
if (player == vehicle player && {!DZE_EVRProtectInside || (DZE_EVRProtectInside && !_inside)}) then {
uiSleep 10; // 10 second knockout.
[nil, player, rSWITCHMOVE, "AmovPpneMstpSnonWnonDnon_healed"] call RE;
player SWITCHMOVE "AmovPpneMstpSnonWnonDnon_healed";

View File

@@ -25,6 +25,7 @@ local _posZ = _posASL select 2;
local _posLowZ = _posLowASL select 2;
local _insideBox = objNull; // object the player is inside of
local _dir = 0;
local _type = ""; // class name
local _roofAbove = false; // is there geometry above
local _intersect = false; // for raycast
@@ -134,7 +135,7 @@ if (isNull _insideBox) then { // no detectable roof
//
///////////////////////////////////////////////////////////////////////////////////////////////////
if (!isNull _insideBox) then { // bounding box detected
local _dir = getDir _insideBox; // direction of object on map
_dir = getDir _insideBox; // direction of object on map
local _rad = sizeOf (typeOf _insideBox); // scan radius
local _seg = 16; // radial scan density (must be evenly divisible by 4)
local _arc = 360 / _seg; // radial scan delta
@@ -172,4 +173,5 @@ if (!isNull _insideBox) then { // bounding box detected
};
};
dayz_insideBuilding = [objNull, _insideBox] select _inside;
_dir call fnc_isSheltered;
_inside

View File

@@ -0,0 +1,113 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// fn_isSheltered.sqf
//
// Author: Victor the Cleaner
// Date: May 2022
//
// Calculate how much shelter the player has and represent it as variable DZE_sheltered.
//
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// Raycast and perform collision check
//
///////////////////////////////////////////////////////////////////////////////////////////////////
local _deepScan = {
local _objects = lineIntersectsWith [_pos1, _pos2, player, objNull, true]; // sorted (nearest last)
local _nearest = (count _objects) - 1; // nearest object
local _idx = _this; // weight index
scopeName "exit";
for "_n" from _nearest to 0 step -1 do {
local _object = _objects select _n;
local _model = _object call fn_getModelName;
if (!(_object isKindOf "AllVehicles") && {!(_model in DZE_allTrees)}) then { // not vehicles or trees
///////////////////////////////////////////////////////////////////////////
//
// Get object edge data
//
///////////////////////////////////////////////////////////////////////////
local _box = boundingBox _object;
local _b0 = _box select 0; // min boundary
local _b1 = _box select 1; // max boundary
local _edgeX = abs (_b0 select 0) + (_b1 select 0);
local _edgeY = abs (_b0 select 1) + (_b1 select 1);
local _edgeZ = abs (_b0 select 2) + (_b1 select 2);
local _proceed = false;
call {
if (_idx < 2) exitWith { // objects close to the horizon
if (_edgeZ > _e1) then { // have a minimum height requirement
if (_edgeX > _e2 || {_edgeY > _e2}) then { // plus at least one long edge
_proceed = true;
};
};
};
if (_edgeX > _e1 && {_edgeY > _e2}) exitWith { // objects above the player
_proceed = true; // must have
}; // at least one long edge
if (_edgeX > _e2 && {_edgeY > _e1}) exitWith { // with a minimum adjacent edge
_proceed = true; // but no minimum height requirement
};
};
if (_proceed) then {
_hitWgt set [_idx, (_hitWgt select _idx) + (_scanWgt select _idx)]; // object meets criteria
breakTo "exit";
};
};
};
};
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// calculate ASL vector dome
//
///////////////////////////////////////////////////////////////////////////////////////////////////
local _dir = _this; // align hemisphere to building if inside
local _rad = 50; // scan radius
local _seg = 8; // initial segments
local _spin = 0; // z spin offset per arc-cycle
local _e1 = 2.5; // minimum edge length
local _e2 = 5.0; // long edge length
local _scanWgt = [1,1.5,2]; // scan weighting index
local _hitWgt = [0,0,0]; // record hit weighting
local _total = 0; // total hits, adjusted for weighting
local _pos1 = aimPos player; // ASL from
local _pos2 = +_pos1; // ASL to
_pos2 set [2, (_pos2 select 2) + _rad]; // overhead pos
2 call _deepScan; // perform initial raycast
DZE_roofOverhead = (_hitWgt select 2) > 0; // valid sized object directly above
for "_r" from 0 to 2 do {
local _rx = 30 * _r; // aggregate x rotation above the horizon
local _arc = 360 / (_seg / (_r max 1)); // arc segments per z rotation
for "_a" from _arc to 360 step _arc do {
local _rz = _dir + _a + _spin; // world direction with radial offset (or aligned to building)
local _pz = sin _rx; // x rotation gives z height
local _py = cos _rx; // x rotation gives y pos
local _px = _py * -(sin _rz); // z rotation gives x pos
_py = _py * (cos _rz); // z rotation gives y pos refactor
_pos2 = [_px, _py, _pz]; // unit vector (relative)
for "_i" from 0 to 2 do { // multiply and add from/to vectors
_pos2 set [_i, ((_pos2 select _i) * _rad) + (_pos1 select _i)];
};
_r call _deepScan; // perform raycast
};
_spin = _spin + 22.5; // incremental z spin
_total = _total + (_hitWgt select _r); // hit weighting running total
};
DZE_sheltered = _total / 30;

View File

@@ -1,7 +1,7 @@
/*
Author: TeeTime
Does: Manages the body temperatur of a Player
Does: Manages the body temperature of a Player
Possible Problems:
=> Balancing
@@ -15,73 +15,82 @@ Missing:
Player Update GUI Colours need to be checked
Shivering Function need improments
Shivering Function need improvements
*/
private ["_difference","_isinvehicle","_daytime","_height_mod","_temp","_looptime","_vehicle_factor","_moving_factor","_fire_factor","_building_factor","_sun_factor","_water_factor","_rain_factor","_night_factor","_wind_factor","_raining","_sunrise","_fireplaces","_building","_heatpack_factor","_warm_clothes","_stand_factor","_snow_factor","_pPos","_sleepTemperatur","_shivering"];
_looptime = _this;
///////////////////////////////////////////////////////////////////////////////////////////////////
local _looptime = _this;
local _pos = [player] call FNC_getPos;
// Factors are equal to win/loss of factor*basic value
//All Values can be seen as x of 100: 100 / x = minutes from min temperetaure to max temperature (without other effects)
// All Values can be seen as x of 100: 100 / x = minutes from min temperature to max temperature (without other effects)
// Positive effects
_vehicle_factor = DZE_TempVars select 0;
_fire_factor = DZE_TempVars select 1;
_building_factor = DZE_TempVars select 2;
_moving_factor = DZE_TempVars select 3;
_sun_factor = DZE_TempVars select 4;
_heatpack_factor = DZE_TempVars select 5;
_warm_clothes = DZE_TempVars select 6;
local _vehicle_factor = DZE_TempVars select 0;
local _fire_factor = DZE_TempVars select 1;
local _building_factor = DZE_TempVars select 2;
local _moving_factor = DZE_TempVars select 3;
local _sun_factor = DZE_TempVars select 4;
local _heatpack_factor = DZE_TempVars select 5;
local _warm_clothes = DZE_TempVars select 6;
// Negative effects
_water_factor = DZE_TempVars select 7;
_stand_factor = DZE_TempVars select 8;
_rain_factor = DZE_TempVars select 9;
_wind_factor = DZE_TempVars select 10;
_night_factor = DZE_TempVars select 11;
_snow_factor = DZE_TempVars select 12;
local _water_factor = DZE_TempVars select 7;
local _stand_factor = DZE_TempVars select 8;
local _rain_factor = DZE_TempVars select 9;
local _wind_factor = DZE_TempVars select 10;
local _night_factor = DZE_TempVars select 11;
local _snow_factor = DZE_TempVars select 12;
// Shivering
_shivering = DZE_TempVars select 13; //Set this to 26 to disabled shivering
local _shivering = DZE_TempVars select 13; // Set this to 26 to disable shivering
_difference = 0;
//_hasfireffect = false;
_isinvehicle = false;
local _difference = 0;
local _isInVehicle = false;
local _raining = (rain > 0);
local _sunrise = call world_sunRise;
_raining = (rain > 0);
_sunrise = call world_sunRise;
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// POSITIVE EFFECTS
//
///////////////////////////////////////////////////////////////////////////////////////////////////
//POSITIV EFFECTS
//vehicle
// Vehicle
if ((vehicle player) != player) then {
_difference = _difference + _vehicle_factor;
_isinvehicle = true;
_isInVehicle = true;
} else {
//speed factor
private["_vel","_speed"];
_vel = velocity player;
_speed = round((_vel distance [0,0,0]) * 3.6);
local _vel = velocity player;
local _speed = round ((_vel distance [0,0,0]) * 3.6);
_difference = (_moving_factor * (_speed / 20)) min 7;
};
//diag_log format["Moving - %1",_difference];
//fire
if !(_isinvehicle) then {
_pPos = [player] call FNC_GetPos;
_fireplaces = nearestObjects [_pPos, ["flamable_DZ","Land_Fire","Land_Campfire"], 8];
///////////////////////////////////////////////////////////////////////////////////////////////////
// Fire
if (!_isInVehicle) then {
local _fireplaces = nearestObjects [_pos, ["flamable_DZ","Land_Fire","Land_Campfire"], 8];
if (({inflamed _x} count _fireplaces) > 0) then {
// Math: factor * 1 / (0.5*(distance max 1)^2) 0.5 = 12.5% of the factor effect in a distance o 4 meters
_difference = _difference + (_fire_factor / (0.5* ((player distance (_fireplaces select 0)) max 1)^2));
//_hasfireffect = true;
//diag_log format["fire - %1",_difference];
};
};
if (dayz_inside) then {_difference = _difference + _building_factor;};
///////////////////////////////////////////////////////////////////////////////////////////////////
//sun
if (daytime > _sunrise && {daytime < (24 - _sunrise)} && {!_raining} && {overcast <= 0.6} && !dayz_inside) then {
/*Mathematic Basic
// Building
local _inside = (dayz_inside || (DZE_roofOverhead && {DZE_sheltered > 0.96}));
if (_inside) then {_difference = _difference + _building_factor;};
///////////////////////////////////////////////////////////////////////////////////////////////////
// Sun
if (daytime > _sunrise && {daytime < (24 - _sunrise)} && {!_raining} && {overcast <= 0.6} && !_inside) then {
/*
Mathematics Basic
t = temperature effect
@@ -97,103 +106,117 @@ if (daytime > _sunrise && {daytime < (24 - _sunrise)} && {!_raining} && {overcas
t = -(f / (12 - s)) * (d - 12) + f
Parabel with highest Point( greatest Effect == _sun_factor) always at 12.00
Zero Points are always at sunrise and sunset -> Only Positiv Values Possible
Parabola with highest Point( greatest Effect == _sun_factor) always at 12.00
Zero Points are always at sunrise and sunset -> Only Positive Values Possible
*/
_difference = _difference + (-((_sun_factor / (12 - _sunrise)^2)) * ((daytime - 12)^2) + _sun_factor);
//diag_log format["sun - %1",_difference];
};
//heatpack
///////////////////////////////////////////////////////////////////////////////////////////////////
// Heatpack
if (r_player_warming_heatpack select 0) then {
_difference = _difference + _heatpack_factor;
if ((diag_tickTime - (r_player_warming_heatpack select 1)) >= r_player_warming_heatpack_time) then {
r_player_warming_heatpack = [false, 0];
};
};
//warm clothes
///////////////////////////////////////////////////////////////////////////////////////////////////
// Warm Clothes
if ((typeOf player) in DZE_WarmClothes) then {
//if (DZE_SnowFall) then {_warm_clothes = _warm_clothes + 14;};
if (DZE_Weather in [3,4]) then {_warm_clothes = _warm_clothes + 14;};
_difference = _difference + _warm_clothes;
};
///////////////////////////////////////////////////////////////////////////////////////////////////
//
// NEGATIVE EFFECTS
//
///////////////////////////////////////////////////////////////////////////////////////////////////
if !(_isinvehicle) then {
if (!_isInVehicle) then {
//water
if ((surfaceIsWater getPosATL player) || dayz_isSwimming) then {
// Water
if ((surfaceIsWater _pos) || dayz_isSwimming) then {
_difference = _difference - _water_factor;
//diag_log format["water - %1",_difference];
};
//night
if((daytime < _sunrise || daytime > (24 - _sunrise)) ) then {
_daytime = if(daytime < 12) then {daytime + 24} else {daytime};
if(dayz_inside) then {
///////////////////////////////////////////////////////////////////////////////////////////
// Night
if (daytime < _sunrise || daytime > (24 - _sunrise)) then {
local _daytime = if (daytime < 12) then {daytime + 24} else {daytime};
if (_inside) then {
_difference = _difference - ((((_night_factor * -1) / (_sunrise^2)) * ((_daytime - 24)^2) + _night_factor)) / 2;
} else {
_difference = _difference - (((_night_factor * -1) / (_sunrise^2)) * ((_daytime - 24)^2) + _night_factor);
};
//diag_log format["night - %1",_difference];
};
//height
///////////////////////////////////////////////////////////////////////////////////////////
// Altitude
if (overcast >= 0.6) then {
_height_mod = ((getPosASL player select 2) / 100) / 2;
local _height_mod = ((getPosASL player select 2) / 100) / 2;
_difference = _difference - _height_mod;
//diag_log format["height - %1",_difference];
};
if !(dayz_inside) then {
//rain
///////////////////////////////////////////////////////////////////////////////////////////
if (!_inside) then {
// Rain
if (_raining) then {
_difference = _difference - (rain * _rain_factor);
//diag_log format["night - %1",_difference];
};
//wind
// Wind
if ((wind select 0) > 4 || (wind select 1) > 4) then {
_difference = _difference - _wind_factor;
//diag_log format["Wind - %1",_difference];
};
//Standing cooldown.
// Standing cooldown
if (speed player == 0) then {
_difference = _difference - _stand_factor;
//diag_log format["Standing - %1",_difference];
};
//Snow fall
// Snow Fall
if (snow > 0) then {
_difference = _difference - _snow_factor;
};
};
};
//Calculate Change Value Basic Factor Looptime Correction Adjust Value to current used temperatur scala
_sleepTemperatur = 90 / 100; //First value = Minutes until player reaches the coldest point at night (without other effects! night factor expected to be -1) //TeeChange
_difference = _difference * _sleepTemperatur / (60 / _looptime) * ((dayz_temperaturmax - dayz_temperaturmin) / 100);
///////////////////////////////////////////////////////////////////////////////////////////////////
if (dayz_temperature_override) then { _difference = 0; if (dayz_temperatur < 37) then { dayz_temperatur = 37; } };
// Calculate Change Value Basic Factor Looptime Correction Adjust Value to current used temperature scale
// First value = Minutes until player reaches the coldest point at night (without other effects! night factor expected to be -1) //TeeChange
_sleepTemperature = 90 / 100;
_difference = _difference * _sleepTemperature / (60 / _looptime) * ((dayz_temperaturmax - dayz_temperaturmin) / 100);
if (dayz_temperature_override) then {
_difference = 0;
dayz_temperatur = 37 max dayz_temperatur;
};
// Change Temperature Should be moved to its own Function to allow adding of Items which increase the Temp like "hot tea"
//Change Temperatur Should be moved in a own Function to allow adding of Items which increase the Temp like "hot tea"
r_player_temp_factor = _difference;
dayz_temperatur = (((dayz_temperatur + _difference) max dayz_temperaturmin) min dayz_temperaturmax);
dayz_temperatur = ((dayz_temperatur + _difference) max dayz_temperaturmin) min dayz_temperaturmax;
// Add Shivering
// Percent when the Shivering will start
if (dayz_temperatur <= _shivering) then { // if the current players temperature is under 34, to disabled set _shivering to 26.
// CamShake as linear Function Maximum reached when Temp is at temp minimum. First Entry = Max Value
_temp = 0.6 * (dayz_temperaturmin / dayz_temperatur );
local _temp = 0.6 * (dayz_temperaturmin / dayz_temperatur);
addCamShake [_temp, (_looptime + 1), 30]; // [0.5,looptime,6] -> Maximum is 25% of the Pain Effect
} else {
addCamShake [0,0,0]; //Not needed at the Moment, but will be necesarry for possible Items
addCamShake [0,0,0]; // Not needed at the Moment, but will be necessary for possible Items
};

View File

@@ -3,35 +3,39 @@
Credit to Sentinel for NIM Weather Effects.
*/
private [ "_i","_pos","_dpos","_windX","_windY","_windZ","_fogOriginal","_windspd","_winddir","_vel","_t"];
local _fogOriginal = _this;
local _windspd = 15;
local _winddir = random 360;
local _windX = _windspd * (sin _winddir);
local _windY = _windspd * (cos _winddir);
local _windZ = 5 - (random 10);
local _t = diag_tickTime;
_fogOriginal = _this;
_windspd = 15;
_winddir = random 360;
_windX = _windspd * (sin _winddir);
_windY = _windspd * (cos _winddir);
_windZ = 5 - (random 10);
snow = 1;
_t = diag_tickTime;
local _isInside = {
local _inside = (dayz_inside || (DZE_roofOverhead && {DZE_sheltered > 0.73}));
_inside
};
// If the player is inside a building play the low volume version of the blizzard sound effect.
playsound (["blizzard","blizzardLow"] select dayz_inside);
playSound (["blizzard","blizzardLow"] select (call _isInside));
if !(isNil "DZE_WeatherDebugTime") then {diag_log format ["Blizzard started at %1",(diag_tickTime - DZE_WeatherDebugTime)];};
while {!DZE_WeatherEndThread} do {
_pos = getPos vehicle player;
_vel = velocity vehicle player;
_i = 0;
local _pos = getPos vehicle player;
local _vel = velocity vehicle player;
local _i = 0;
if (diag_tickTime - _t >= 10) then {
playsound (["blizzard","blizzardLow"] select dayz_inside);
playSound (["blizzard","blizzardLow"] select (call _isInside));
_t = diag_tickTime;
};
if (!dayz_inside) then {
if !(call _isInside) then {
while {_i < 25} do {
_dpos = [((_pos select 0) + (25 - (random (2*25))) + ((_vel select 0)*6)) - (_windX),((_pos select 1) + (25 - (random (2*25))) + ((_vel select 1)*6)) - (_windY),((_pos select 2) + 3)];
local _dpos = [((_pos select 0) + (25 - (random (2*25))) + ((_vel select 0)*6)) - (_windX),((_pos select 1) + (25 - (random (2*25))) + ((_vel select 1)*6)) - (_windY),((_pos select 2) + 3)];
// Snow Particles
drop ["\ca\data\cl_water", "", "Billboard", 1, 6, _dpos, [_windX/2,_windY/2,-1], 1, 1.275, 1, (random .01), [0.05], [[1,1,1,1]], [0,0], 0.2, 1.2, "", "", ""];
_i = _i + 1;
@@ -39,7 +43,7 @@ while {!DZE_WeatherEndThread} do {
// Cloud particles
drop ["\ca\data\cl_basic", "", "Billboard", 0.2, 5, [(_pos select 0) + (75 - (random (2*75))) + (_vel select 0)*4 - _windX,(_pos select 1) + (75 - (random (2*75))) + (_vel select 1)*4 - _windY,(_pos select 2) + 10], [_windX,_windY,_windZ], 10, 1.275, 1, (random .01), [35,60], [[0.95,0.95,0.95,0],[0.95,0.95,0.95,0.4],[0.95,0.95,0.95,0.4],[0.95,0.95,0.95,0.4],[0.95,0.95,0.95,0]], [0,0], 0, 0, "", "",""];
};
uiSleep 0.001;
uiSleep 0.01;
};
0 setFog _fogOriginal; // Reset fog to original.

View File

@@ -4,26 +4,23 @@
Credit to Karel Moricky for particle array definitions in "modules_e/Weather/data/fsms/particle.fsm"
*/
private ["_density","_i","_d","_h","_pos","_dpos","_vel"];
_density = _this;
if (_density > 1) then {_density = 1;};
local _density = _this min 1;
_density = round (25 * _density);
_d = 35;
_h = 15;
local _d = 35;
local _h = 15;
snow = 1;
if !(isNil "DZE_WeatherDebugTime") then {diag_log format ["Snowfall started at %1",(diag_tickTime - DZE_WeatherDebugTime)];};
while {!DZE_WeatherEndThread} do {
uiSleep .01;
_pos = getPos vehicle player;
_vel = velocity vehicle player;
_i = 0;
uiSleep 0.01;
local _pos = getPos vehicle player;
local _vel = velocity vehicle player;
local _i = 0;
if !(dayz_inside) then {
if !(dayz_inside || (DZE_roofOverhead && {DZE_sheltered > 0.73})) then {
while {_i < _density} do {
_dpos = [((_pos select 0) + (_d - (random (2 * _d))) + ((_vel select 0) * 6)), ((_pos select 1) + (_d - (random (2 * _d))) + ((_vel select 1) * 6)), ((_pos select 2) + 15)];
local _dpos = [((_pos select 0) + (_d - (random (2 * _d))) + ((_vel select 0) * 6)), ((_pos select 1) + (_d - (random (2 * _d))) + ((_vel select 1) * 6)), ((_pos select 2) + 15)];
drop [["\Ca\Data\ParticleEffects\Universal\Universal", 16, 12, 8, 1],"","Billboard",1,10,_dpos,[0,0,0],1,0.000001,0,1.1,[0.09,0.09],[[1,1,1,1]],[0,1],0.2,1.2,"","",""];
_i = _i + 1;
};