Grumpy Old Man 3545 Posted January 15, 2017 GOM_fnc_foggyBreath V1.2 Purpose of this script: Adds authentic visible breath for missions taking place in colder climates. Features: Adds effect to all units (players and AI) in mission, also works for units being spawned mid mission. Visible Breath below 8°C, getting more prominent the lower the temperature, maximum reached at -9°C You can determine the current mission temperature by defining a global variable Units getting hit/injured will exhale, resulting in visible breath Breath frequency increases depending on fatigue, slowly returns to initial frequency when unit catches its breath How to use this script: Copy all files and folders except mission.sqm from the demo mission inside your own mission. Backup all of your files before overwriting anything! The script runs on its own, nothing else needed besides setting the temperature as mentioned below: Files: description.ext: Spoiler class CfgFunctions { #include "scripts\GOM\foggyBreath\GOM_foggyBreath.hpp" }; scripts\GOM\foggyBreath\GOM_fnc_foggyBreathInit.sqf: Spoiler //GOM_fnc_foggyBreath.sqf V1.2 - Made by Grumpy Old Man 15.01.2017 //adds visible breath in colder climates //breath frequency is adjusted according to fatigue, being hit and for sounds played by the player character (injury etc) //works with dynamically spawned units mid mission //adjust GOM_fnc_temperature to dynamically add foggy breath effect during mission runtime, default will be 7°C //breath will start to show below 8°C and be most prominent at -9°C /* Changelog: 1.1: Changed file structure to utilize CfgFunctions and description.ext Made function auto run on mission start To stop the breath from being visible set GOM_fnc_temperature above 7. */ GOM_fnc_visibleBreathInit = { waituntil {time > 0 AND count allplayers > 0}; GOM_fnc_addBreath = true; while {GOM_fnc_addBreath} do { { if (!(_x getvariable ["GOM_fnc_visibleBreath",false]) AND typeof _x iskindof "CAManBase") then { _x setVariable ["GOM_fnc_visibleBreath",true,true]; if (isPlayer _x) then { _x addEventHandler ["SoundPlayed","_this spawn GOM_fnc_visibleBreath"]; _breathe = [_x] spawn GOM_fnc_breathLoop; }; if !(isPlayer _x) then {_breathe = [_x] spawn GOM_fnc_breathLoop; _x addEventHandler ["Hit",{ params ["_unit"]; [_unit,6] spawn GOM_fnc_visibleBreath; }]; }; }; } forEach allUnits; sleep 5; }; }; _defaultTemp = 7; if (missionnamespace getVariable ["GOM_fnc_temperature",""] isEqualTo "") then { missionNamespace setVariable ["GOM_fnc_temperature",_defaultTemp,true] }; GOM_fnc_breathLoop = { params ["_unit",["_debug",false]]; if (!alive _unit) exitWith {false}; sleep random 12; _sleep = 0; if (isplayer _unit) then { _sleep = 12; }; while {alive _unit} do { if (!alive _unit) exitWith {false}; waituntil {simulationEnabled _unit isEqualTo true}; waituntil {if (speed _unit > 10) exitWith {true};sleep 0.5; GOM_fnc_temperature < 8}; waituntil {if (speed _unit > 10) exitWith {true};sleep 0.5;((_unit getVariable ["GOM_fnc_eventBreath",-60]) + _sleep < time)}; if (!alive _unit) exitWith {false}; _cause = ""; if ((_unit getVariable ["GOM_fnc_eventBreath",-60]) + _sleep < time) then { _index = 1; _sleep = random [3,6,12]; _cause = "ambient breath"; if (damage _unit > 0.1) then { _index = 2; _sleep = random [3,6,6]; _cause = "light hurt breath"; }; if (damage _unit > 0.4) then { _index = 4; _sleep = random [3,4,5]; _cause = "hurt breath"; }; _exhaustTimer = _unit getVariable ["GOM_fnc_exhaustTimer",-60]; if (speed _unit > 10 OR getfatigue _unit > 0.05 OR time < _exhaustTimer + 60) then { _cause = "running breath"; if (time < _exhaustTimer + 60) then {_cause = "exhausted breath"}; _sleep = random [2,2.5,3]; _index = 1; if (getfatigue _unit > 0.5) then {_unit setVariable ["GOM_fnc_exhaustTimer",time]}; }; if (!alive _unit) exitWith {false}; if (behaviour _unit isEqualTo "COMBAT") then {_sleep = _sleep * 0.5}; if (behaviour _unit isEqualTo "AWARE") then {_sleep = _sleep * 0.75}; _breathe = [_unit,_index,_cause] call GOM_fnc_visibleBreath; _sleep = (_sleep - (damage _unit) - (getfatigue _unit * 1.5)) max random [0.3,0.4,0.5]; if (_debug) then { playsound "click"; systemchat str _cause; systemchat str _sleep; }; if (!alive _unit) exitWith {false}; sleep _sleep; }; }; if (!alive _unit) exitWith {false}; }; GOM_fnc_visibleBreath = { params ["_unit","_soundID",["_cause","EH breath"]]; if !(alive _unit) exitWith {false}; if (((eyepos _unit) # 2) <= 0) exitWith {false}; if (GOM_fnc_temperature >= 8) exitWith {false}; if (lineIntersects [eyepos _unit,eyepos _unit vectoradd [0,0,3],_unit,objnull]) exitWith {false}; _reference = ["BREATH","BREATHINJURED","INJURED","PULSATION","HITSCREAM","GASPING","STABILIZING","RECOVERED"]; _allowed = [1,2,4,5,6,10,11,14]; if !(_soundID in _allowed) exitWith {false}; if (_soundID != 6) then { sleep 0.5; }; _index = (_allowed find _soundID); _speedIntensities = [1,1.5,2,1.3,2.5,2.5,1.3,1.1]; _exhaleTimeFactors = [1,0.7,0.5,0.3,.4,1.2,1,1]; _speedFactor = _speedIntensities select _index; _exhaleTimeFactor = _exhaleTimeFactors select _index; _fatigue = if (_unit isEqualTo objnull) then {0} else {getFatigue _unit}; _preint = (0.03 * _fatigue) max 0.006; _cold = linearConversion [8,-9,GOM_fnc_temperature,0.02,0.055,true]; _lifeTime = linearConversion [8,-9,GOM_fnc_temperature,0.3,2,true]; _lifeTime = random [_lifeTime * 0.95,_lifeTime,_lifeTime * 1.15]; _preInt = _preInt + _cold; _int = random [_preint * 0.95,_preint,_preint * 1.15] min 0.006; _vec = eyeDirection _unit; _vec params["_dirX","_dirY"]; _exhaleDir = _dirX atan2 _dirY; if (_exhaleDir < 0) then {_exhaleDir = 360 + _exhaleDir}; _unitVelocity = velocity _unit; _getExhaleSpeed = 0.02 * _speedFactor; _exhaleSpeed = random [_getExhaleSpeed * 0.95,_getExhaleSpeed,_getExhaleSpeed * 1.05]; _exhaleVelocity = [ (_unitVelocity select 0) + (sin _exhaleDir * _exhaleSpeed), (_unitVelocity select 1) + (cos _exhaleDir * _exhaleSpeed), (_unitVelocity select 2) ]; _source = "logic" createVehicleLocal (getpos _unit); _fog = "#particlesource" createVehicleLocal getpos _source; _intensity = linearConversion [8,-9,GOM_fnc_temperature,0.0125,0.025,true]; _fog setParticleParams [ ["\A3\Data_F\ParticleEffects\Universal\universal.p3d", 16, 12, 13,0], "", "Billboard", 0.5, _lifeTime, [0,0,0], _exhaleVelocity, random [0.75,1,1.25], random [1.25,1.3,1.325], random [0.9,1,1.2], random [0.75,0.9,1], [0.001, 0.05,0.2,0.4,0.8,2.1], [[0.25,0.25,0.25, _intensity], [0.35,0.35,0.35, _intensity],[0.5,0.5,0.5, _intensity],[0.25,0.25,0.25, _intensity/2], [0.15,0.15,0.15, _intensity/10]], [1200,800,600,300,125,12], 0.9, 0.25, "", "", _source ]; _fog setParticleRandom [2, [0, 0, 0], [0.25, 0.25, 0.25], 0, 0.5, [0, 0, 0, 0.1], 0, 0, 10]; _fog setDropInterval 0.001; _eyepos = ASLToAGL (eyepos _unit); _mouthpos = _unit worldToModelVisual (_eyepos vectoradd [0,0.09,-0.09]); _source attachto [_unit,_mouthpos]; _exhaleTime = 0.4 * _exhaleTimeFactor; sleep random [_exhaleTime - 0.25,_exhaleTime,_exhaleTime + 0.25]; deletevehicle _source; deletevehicle _fog; _unit setVariable ["GOM_fnc_eventBreath",time]; true }; _breathe = [] spawn GOM_fnc_visibleBreathInit; scripts\GOM\foggyBreath\GOM_fnc_foggyBreath.hpp: Spoiler //GOM_fnc_foggyBreath.sqf V1.1 - Made by Grumpy Old Man 15.01.2017 class GOM { class ambient { class foggyBreathInit {file = "scripts\GOM\foggyBreath\GOM_fnc_foggyBreathInit.sqf";postInit = 1;}; } }; Updates: Options: GOM_fnc_temperature = -9; This will set the temperature to -9°C, giving the maximum effect. At +8°C the fog will stop. Decided to do it this way so you can give every unit an individual temperature, so if a unit is on top of a mountain it will obviously have a colder temperature than a unit near the beach. Download GOM_fnc_foggyBreath V1.2 Demo Mission Changelog: V1.2: Fog is now more influenced by wind, also helicopter downwash etc Is less prominent at higher temperatures Fog now also works for unit in open vehicles Fog will stop once in a closed vehicle/inside a building Spoiler V1.1: Fixed undefined variable error Changed file structure to utilize CfgFunctions and description.ext Made function auto run on mission start To stop the breath from being visible set GOM_fnc_temperature above 7. Known Issues: None so far. Enjoy! 14 Share this post Link to post Share on other sites
johnnyboy 3789 Posted January 15, 2017 Beautiful script Grumpy Old Dude. Forced exhale on being hit or certain sounds is brilliant. What sounds cause an exale when using "SoundPlayed" eventhandler? Does it include any speaking? Plus, what WWII mode is that in the video? Share this post Link to post Share on other sites
warlord554 2065 Posted January 15, 2017 nice addition! great job Share this post Link to post Share on other sites
MrSanchez 243 Posted January 16, 2017 Me gusta, love it. Kind regards, Sanchez Share this post Link to post Share on other sites
Grumpy Old Man 3545 Posted January 16, 2017 18 hours ago, johnnyboy said: Beautiful script Grumpy Old Dude. Forced exhale on being hit or certain sounds is brilliant. What sounds cause an exale when using "SoundPlayed" eventhandler? Does it include any speaking? Plus, what WWII mode is that in the video? Breaths triggered by sounds is done with the soundplayed eventhandler, only for players, since the EH only works for players. The map is Chernarus Winter with Iron Front lite mod by .kju. Added info to the OP. Cheers Share this post Link to post Share on other sites
killzone_kid 1329 Posted January 16, 2017 6 hours ago, Grumpy Old Man said: only for players You can probably spawn a loop for AI 1 Share this post Link to post Share on other sites
Grumpy Old Man 3545 Posted January 17, 2017 That's exactly what the script does. Changed the OP to be a bit more clear. Cheers Share this post Link to post Share on other sites
McDoom51 0 Posted April 30, 2017 how do you add the parameters in? Share this post Link to post Share on other sites
Grumpy Old Man 3545 Posted April 30, 2017 11 minutes ago, McDoom51 said: how do you add the parameters in? What parameters? Everything's explained in the first post. Cheers Share this post Link to post Share on other sites
_leech 29 Posted July 29, 2017 Looks beauty indeed, but am i the only one who gets this? https://image.prntscr.com/image/luGu2IL1Q0CVLKhXHpZsbw.jpg Share this post Link to post Share on other sites
Grumpy Old Man 3545 Posted July 30, 2017 That's weird, how's the init.sqf looking? Cheers Share this post Link to post Share on other sites
_leech 29 Posted July 30, 2017 I just copied your instructions to the init.sqf with nothing else in it. 1 Share this post Link to post Share on other sites
Mynock 244 Posted August 26, 2017 On 7/29/2017 at 10:19 AM, neetch said: Looks beauty indeed, but am i the only one who gets this? https://image.prntscr.com/image/luGu2IL1Q0CVLKhXHpZsbw.jpg I'm having this error as well. Followed the instructions provided. 1.74 stable, running 3 RHS mods (USAF, AFRF, GREF), CUP map mods (including CWA maps), and Bariga terrain. Using the following in the init.sqf file: _init = [] execVM "scripts\GOM_fnc_foggyBreath.sqf"; _breath = [] spawn GOM_fnc_visibleBreathInit; GOM_fnc_temperature = -3; And yes, the scripts\ portion is intentional. I like to organize my mission files. What am I doing wrong? If I comment out the _breath = [] spawn GOM_fnc_visibleBreathInit; line I can get rid of the error, but then I don't see anything in the mission for breath, so clearly that line is needed somehow, but unless I comment it out it throws the error of being an undefined variable. I don't want to go messing with anything else because it's not my script therefore I cannot legally modify it, and I wouldn't really know where to modify it anyway seeing as I didn't write it and would need to figure out line-by-line what it's doing. 1 Share this post Link to post Share on other sites
Grumpy Old Man 3545 Posted August 26, 2017 Fixed the error, 1.1 is out. To use it simply copy all files from the demo mission except mission.sqm into your own mission, but backup first before overwriting anything! Nothing in init.sqf is needed, function is running on its own. Cheers 2 Share this post Link to post Share on other sites
Mynock 244 Posted August 26, 2017 Thanks for the information. Hope I didn't cause you any trouble; I wasn't after a complete rework but I appreciate you taking the time to do so. 1 Share this post Link to post Share on other sites
Grumpy Old Man 3545 Posted August 27, 2017 7 hours ago, Mynock said: Thanks for the information. Hope I didn't cause you any trouble; I wasn't after a complete rework but I appreciate you taking the time to do so. No trouble at all. The switch to CfgFunctions was due anyway. Cheers 1 Share this post Link to post Share on other sites
badpr1m3r 2 Posted October 13, 2017 Kewl thanks. Anyway to add a function where if the player is away from a fireplace or campfire he takes damage due to the cold? Share this post Link to post Share on other sites
Grumpy Old Man 3545 Posted October 13, 2017 4 hours ago, badpr1m3r said: Kewl thanks. Anyway to add a function where if the player is away from a fireplace or campfire he takes damage due to the cold? I'm sure there's plenty of ways, since this script is about foggy breath this would be outside the scope of it. Cheers Share this post Link to post Share on other sites
Arcasil 2 Posted December 16, 2017 I couldn't get this script the file is no longer available. Share this post Link to post Share on other sites
Grumpy Old Man 3545 Posted December 16, 2017 7 minutes ago, Arcasil said: I couldn't get this script the file is no longer available. Refreshed link, should be there. Cheers 2 Share this post Link to post Share on other sites
major-stiffy 277 Posted July 6, 2018 File is no longer available. New link please? Also, is this compatible with MP hosted server? Thanks Edit: NM found it on Armaholic. http://www.armaholic.com/page.php?id=33611 Share this post Link to post Share on other sites
diwako 409 Posted July 6, 2018 1 hour ago, major-stiffy said: File is no longer available. New link please? Also, is this compatible with MP hosted server? Thanks Edit: NM found it on Armaholic. http://www.armaholic.com/page.php?id=33611 I used it in a few of my missions before. It works great in mp. In my missions units spawn in and out dynamically so I found one problem with the script. Directly in line 189 add this small bit if you do not want to see some error message when a unit gets deleted. if(isNil "_preint") exitWith {}; 2 Share this post Link to post Share on other sites
major-stiffy 277 Posted July 6, 2018 3 hours ago, diwako said: Directly in line 189 add this small bit if you do not want to see some error message when a unit gets deleted. if(isNil "_preint") exitWith {}; So your saying replace _preint = (0.06 * (getfatigue _unit)) max 0.006; with if(isNil "_preint") exitWith {}; or? Share this post Link to post Share on other sites
diwako 409 Posted July 6, 2018 Nah, just put the line i posted beneath it. 1 Share this post Link to post Share on other sites