Jump to content
Grumpy Old Man

[Release] GOM_fnc_foggyBreath V1.2

Recommended Posts

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!

  • Like 14

Share this post


Link to post
Share on other sites

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

Me gusta, love it.

 

Kind regards,

Sanchez 

Share this post


Link to post
Share on other sites
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
6 hours ago, Grumpy Old Man said:

only for players

 

You can probably spawn a loop for AI

  • Like 1

Share this post


Link to post
Share on other sites
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

I just copied your instructions to the init.sqf with nothing else in it.

  • Like 1

Share this post


Link to post
Share on other sites
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.

  • Like 1

Share this post


Link to post
Share on other sites

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

  • Like 2

Share this post


Link to post
Share on other sites

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.

  • Like 1

Share this post


Link to post
Share on other sites
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

  • Like 1

Share this post


Link to post
Share on other sites

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
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
7 minutes ago, Arcasil said:

I couldn't get this script the file is no longer available.:down:

Refreshed link, should be there.

 

Cheers

  • Like 2

Share this post


Link to post
Share on other sites
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 {};

 

  • Like 2

Share this post


Link to post
Share on other sites
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

Nah, just put the line i posted beneath it.

  • Like 1

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×