diff --git a/addons/ai/CfgWeapons.hpp b/addons/ai/CfgWeapons.hpp index 22e8f703fc..be3245cce3 100644 --- a/addons/ai/CfgWeapons.hpp +++ b/addons/ai/CfgWeapons.hpp @@ -574,4 +574,198 @@ class CfgWeapons { maxRange = 1200; //1000; }; }; + + // marksmen marksmen + class DMR_03_base_F: Rifle_Long_Base_F { + modes[] += {"ACE_Burst_far"}; + + class Single: Mode_SemiAuto { + minRange = 120; // 2; + minRangeProbab = 0.7; // 0.3; + midRangeProbab = 0.3; // 0.7; + }; + + class FullAuto; + + class single_close_optics1: Single { + minRange = 120; // 2; + minRangeProbab = 0.8; // 0.05; + midRangeProbab = 0.05; // 0.8; + }; + + class single_medium_optics1: single_close_optics1 { + minRangeProbab = 0.7; // 0.05; + midRangeProbab = 0.05; // 0.7; + }; + + class single_far_optics1: single_medium_optics1 { + minRange = 400; // 300; + minRangeProbab = 0.5; // 0.05; + midRangeProbab = 0.05; // 0.5; + }; + + class fullauto_medium: FullAuto { + minRange = 20; // 2; + maxRange = 150; // 100; + burst = "3 + round random 5"; // 3; + }; + + class ACE_Burst_far: fullauto_medium { + aiRateOfFire = 2.0; + aiRateOfFireDistance = 500; + minRange = 400; + minRangeProbab = 0.1; + midRange = 500; + midRangeProbab = 0.2; + maxRange = 600; + maxRangeProbab = 0.2; + burst = "2 + round random 3"; + }; + }; + + class DMR_05_base_F: Rifle_Long_Base_F { + modes[] += {"ACE_Burst_far"}; + + class Single: Mode_SemiAuto { + minRange = 120; // 2; + minRangeProbab = 0.7; // 0.3; + midRangeProbab = 0.3; // 0.7; + }; + + class FullAuto; + + class single_close_optics1: Single { + minRange = 120; // 2; + minRangeProbab = 0.8; // 0.05; + midRangeProbab = 0.05; // 0.8; + }; + + class single_medium_optics1: single_close_optics1 { + minRangeProbab = 0.7; // 0.05; + midRangeProbab = 0.05; // 0.7; + }; + + class single_far_optics1: single_medium_optics1 { + minRange = 400; // 300; + minRangeProbab = 0.5; // 0.05; + midRangeProbab = 0.05; // 0.5; + }; + + class fullauto_medium: FullAuto { + minRange = 20; // 2; + maxRange = 150; // 100; + burst = "3 + round random 5"; // 3; + }; + + class ACE_Burst_far: fullauto_medium { + aiRateOfFire = 2.0; + aiRateOfFireDistance = 500; + minRange = 400; + minRangeProbab = 0.1; + midRange = 500; + midRangeProbab = 0.2; + maxRange = 600; + maxRangeProbab = 0.2; + burst = "2 + round random 3"; + }; + }; + + class DMR_06_base_F: Rifle_Long_Base_F { + modes[] += {"ACE_Burst_far"}; + + class Single: Mode_SemiAuto { + minRange = 120; // 2; + minRangeProbab = 0.7; // 0.3; + midRangeProbab = 0.3; // 0.7; + }; + + class FullAuto; + + class single_close_optics1: Single { + minRange = 120; // 2; + minRangeProbab = 0.8; // 0.05; + midRangeProbab = 0.05; // 0.8; + }; + + class single_medium_optics1: single_close_optics1 { + minRangeProbab = 0.7; // 0.05; + midRangeProbab = 0.05; // 0.7; + }; + + class single_far_optics1: single_medium_optics1 { + minRange = 400; // 300; + minRangeProbab = 0.5; // 0.05; + midRangeProbab = 0.05; // 0.5; + }; + + class fullauto_medium: FullAuto { + minRange = 20; // 2; + maxRange = 150; // 100; + burst = "3 + round random 5"; // 3; + }; + + class ACE_Burst_far: fullauto_medium { + aiRateOfFire = 2.0; + aiRateOfFireDistance = 500; + minRange = 400; + minRangeProbab = 0.1; + midRange = 500; + midRangeProbab = 0.2; + maxRange = 600; + maxRangeProbab = 0.2; + burst = "2 + round random 3"; + }; + }; + + // marksmen medium mg + class MMG_01_base_F: Rifle_Long_Base_F { + aiDispersionCoefY = 25.0; + aiDispersionCoefX = 20.0; + modes[] += {"ACE_Burst_far"}; + + class manual; + class burst; + class close; + class short; + class medium; + class ACE_Burst_far: medium { + aiRateOfFire = 6.0; + aiRateOfFireDistance = 900; + minRange = 700; + minRangeProbab = 0.1; + midRange = 900; + midRangeProbab = 0.2; + maxRange = 1100; + maxRangeProbab = 0.2; + burst = "3 + round random 5"; + }; + + class far_optic1; + class far_optic2; + }; + + class MMG_02_base_F: Rifle_Long_Base_F { + aiDispersionCoefY = 20.0; + aiDispersionCoefX = 15.0; + modes[] += {"ACE_Burst_far"}; + + class manual; + class close; + class short; + class medium; + class ACE_Burst_far: medium { + aiRateOfFire = 6.0; + aiRateOfFireDistance = 900; + minRange = 700; + minRangeProbab = 0.1; + midRange = 900; + midRangeProbab = 0.2; + maxRange = 1100; + maxRangeProbab = 0.2; + burst = "3 + round random 5"; + }; + + class far_optic1; + class far_optic2; + }; }; diff --git a/addons/common/CfgEventHandlers.hpp b/addons/common/CfgEventHandlers.hpp index eef90451ae..ce0938f063 100644 --- a/addons/common/CfgEventHandlers.hpp +++ b/addons/common/CfgEventHandlers.hpp @@ -26,6 +26,9 @@ class Extended_InitPost_EventHandlers { class GVAR(forceWalk) { init = QUOTE(if (local (_this select 0)) then {_this call FUNC(applyForceWalkStatus);};); }; + class GVAR(muteUnit) { + init = QUOTE(_this call FUNC(muteUnitHandleInitPost)); + }; }; }; @@ -41,4 +44,9 @@ class Extended_Respawn_EventHandlers { respawn = QUOTE(_this call FUNC(resetAllDefaults)); }; }; + class CAManBase { + class GVAR(muteUnit) { + respawn = QUOTE(_this call FUNC(muteUnitHandleRespawn)); + }; + }; }; diff --git a/addons/common/XEH_postInit.sqf b/addons/common/XEH_postInit.sqf index f09dae0eb3..e470e91c95 100644 --- a/addons/common/XEH_postInit.sqf +++ b/addons/common/XEH_postInit.sqf @@ -35,6 +35,7 @@ if (hasInterface) then { ["setDir", {(_this select 0) setDir (_this select 1)}] call FUNC(addEventhandler); ["setFuel", {(_this select 0) setFuel (_this select 1)}] call FUNC(addEventhandler); +["setSpeaker", {(_this select 0) setSpeaker (_this select 1)}] call FUNC(addEventhandler); // hack to get PFH to work in briefing [QGVAR(onBriefingPFH), "onEachFrame", { diff --git a/addons/common/XEH_preInit.sqf b/addons/common/XEH_preInit.sqf index 8d62e9df70..b5382d0b5e 100644 --- a/addons/common/XEH_preInit.sqf +++ b/addons/common/XEH_preInit.sqf @@ -124,6 +124,8 @@ PREP(moduleCheckPBOs); PREP(moduleLSDVehicles); PREP(moveToTempGroup); PREP(muteUnit); +PREP(muteUnitHandleInitPost); +PREP(muteUnitHandleRespawn); PREP(numberToDigits); PREP(numberToDigitsString); PREP(numberToString); diff --git a/addons/common/functions/fnc_muteUnit.sqf b/addons/common/functions/fnc_muteUnit.sqf index 8edf9df391..5c496ea58e 100644 --- a/addons/common/functions/fnc_muteUnit.sqf +++ b/addons/common/functions/fnc_muteUnit.sqf @@ -5,21 +5,34 @@ * * Argument: * 0: Unit (Object) + * 1: Reason to mute the unit (String) * * Return value: * Nothing */ #include "script_component.hpp" -private ["_unit", "_speaker"]; +private ["_unit", "_reason"]; _unit = _this select 0; +_reason = _this select 1; if (isNull _unit) exitWith {}; +// add reason to mute to the unit +private "_muteUnitReasons"; +_muteUnitReasons = _unit getVariable [QGVAR(muteUnitReasons), []]; + +if !(_reason in _muteUnitReasons) then { + _muteUnitReasons pushBack _reason; + _unit setVariable [QGVAR(muteUnitReasons), _muteUnitReasons, true]; +}; + +private "_speaker"; _speaker = speaker _unit; + if (_speaker == "ACE_NoVoice") exitWith {}; -[0, "{(_this select 1) setSpeaker 'ACE_NoVoice'}", _unit, "ACE_Speaker"] call FUNC(execPersistentFnc); +["setSpeaker", [_unit, "ACE_NoVoice"]] call FUNC(globalEvent); _unit setVariable ["ACE_OriginalSpeaker", _speaker, true]; diff --git a/addons/common/functions/fnc_muteUnitHandleInitPost.sqf b/addons/common/functions/fnc_muteUnitHandleInitPost.sqf new file mode 100644 index 0000000000..f0abcfcf01 --- /dev/null +++ b/addons/common/functions/fnc_muteUnitHandleInitPost.sqf @@ -0,0 +1,11 @@ +// by commy2 +#include "script_component.hpp" + +private "_unit"; + +_unit = _this select 0; + +// setSpeaker gets overwritten after init on remote units; if unit is muted, setSpeaker again +if (count (_unit getVariable [QGVAR(muteUnitReasons), []]) > 0) then { + ["setSpeaker", [_unit, "ACE_NoVoice"]] call FUNC(localEvent); +}; diff --git a/addons/common/functions/fnc_muteUnitHandleRespawn.sqf b/addons/common/functions/fnc_muteUnitHandleRespawn.sqf new file mode 100644 index 0000000000..021b083bfd --- /dev/null +++ b/addons/common/functions/fnc_muteUnitHandleRespawn.sqf @@ -0,0 +1,12 @@ +// by commy2 +#include "script_component.hpp" + +private "_unit"; + +_unit = _this select 0; + +// setVariable is broken on JIP after respawn +_unit setVariable [QGVAR(muteUnitReasons), _unit getVariable [QGVAR(muteUnitReasons), []], true]; + +// fix mp issues with respawning and the speaker +["setSpeaker", [_unit, speaker _unit]] call FUNC(globalEvent); diff --git a/addons/common/functions/fnc_restoreVariablesJIP.sqf b/addons/common/functions/fnc_restoreVariablesJIP.sqf index 2c173a054c..ca185082cb 100644 --- a/addons/common/functions/fnc_restoreVariablesJIP.sqf +++ b/addons/common/functions/fnc_restoreVariablesJIP.sqf @@ -23,6 +23,3 @@ _respawnVariables pushBack "ACE_PersistentFunctions"; { _unit setVariable [_x, _unit getVariable _x, true]; } forEach _respawnVariables; - -// fix speaker after respawn -[_unit, format ["{_this setSpeaker '%1'}", speaker _unit], 2] call FUNC(execRemoteFnc); diff --git a/addons/common/functions/fnc_unmuteUnit.sqf b/addons/common/functions/fnc_unmuteUnit.sqf index 8de7708d4b..94ba72f5a4 100644 --- a/addons/common/functions/fnc_unmuteUnit.sqf +++ b/addons/common/functions/fnc_unmuteUnit.sqf @@ -1,23 +1,39 @@ /* * Author: commy2 * - * Unmutes the unit. + * Unmutes the unit. Only unmutes if the last reason was removed. * * Argument: * 0: Unit (Object) + * 1: Reason to unmute the unit. (String) * * Return value: * Nothing */ #include "script_component.hpp" -private ["_unit", "_speaker"]; +private ["_unit", "_reason"]; _unit = _this select 0; +_reason = _this select 1; if (isNull _unit) exitWith {}; +// remove reason to mute to the unit +private "_muteUnitReasons"; +_muteUnitReasons = _unit getVariable [QGVAR(muteUnitReasons), []]; + +if (_reason in _muteUnitReasons) then { + _muteUnitReasons deleteAt (_muteUnitReasons find _reason); + _unit setVariable [QGVAR(muteUnitReasons), _muteUnitReasons, true]; +}; + +// don't unmute if there is another mute reason! +if (count _muteUnitReasons > 0) exitWith {}; + +private "_speaker"; _speaker = _unit getVariable ["ACE_OriginalSpeaker", ""]; + if (_speaker == "") exitWith {}; -[0, format ["{(_this select 1) setSpeaker '%1'}", _speaker], _unit, "ACE_Speaker"] call FUNC(execPersistentFnc); +["setSpeaker", _unit, [_unit, _speaker]] call FUNC(targetEvent); diff --git a/addons/magazines/CfgWeapons.hpp b/addons/magazines/CfgWeapons.hpp index 18cff2fe83..787867070e 100644 --- a/addons/magazines/CfgWeapons.hpp +++ b/addons/magazines/CfgWeapons.hpp @@ -30,7 +30,7 @@ class CfgWeapons { /* Katiba */ - + class Rifle_Long_Base_F; class arifle_katiba_Base_F: Rifle_Base_F { magazines[] += { "ACE_30Rnd_65x39_caseless_green_mag_Tracer_Dim", diff --git a/addons/noradio/XEH_post_initClient.sqf b/addons/noradio/XEH_post_initClient.sqf index e192a101f8..4f35a1ced9 100644 --- a/addons/noradio/XEH_post_initClient.sqf +++ b/addons/noradio/XEH_post_initClient.sqf @@ -1,31 +1,29 @@ // by commy2 - #include "script_component.hpp" +/* _setupPlayer = { - if (!isNull ACE_player) then { - [(_this select 1)] call cba_fnc_removePerFrameHandler; + if (!isNull ACE_player) then { + [(_this select 1)] call cba_fnc_removePerFrameHandler; - [ACE_player] call EFUNC(common,muteUnit); - ACE_player setVariable [QGVAR(isMuted), true, true]; - }; + [ACE_player, "isPlayer"] call EFUNC(common,muteUnit); + }; }; [_setupPlayer, 0, []] call CBA_fnc_addPerFrameHandler; +*/ + +if (!hasInterface) exitWith {}; // Mutes/unmutes units when the player changes ["playerChanged", { - EXPLODE_2_PVT(_this,_newPlayer,_oldPlayer); + EXPLODE_2_PVT(_this,_newPlayer,_oldPlayer); - // On player change mute the new player - [_newPlayer] call EFUNC(common,muteUnit); - _newPlayer setVariable [QGVAR(isMuted), true, true]; - - // Unmute the old player - //@todo: sort interaction with medical system - if (!(_oldPlayer getVariable ["ACE_isUnconscious", false]) && {alive _oldPlayer}) then { - [_oldPlayer] call EFUNC(common,unMuteUnit); - }; - _oldPlayer setVariable [QGVAR(isMuted), false, true]; + // On player change mute the new player + [_newPlayer, "isPlayer"] call EFUNC(common,muteUnit); + // Unmute the old player + if (alive _oldPlayer) then { + [_oldPlayer, "isPlayer"] call EFUNC(common,unmuteUnit); + }; }] call EFUNC(common,addEventhandler); diff --git a/addons/noradio/XEH_post_initServer.sqf b/addons/noradio/XEH_post_initServer.sqf index 90b7473144..ae2dc16ec1 100644 --- a/addons/noradio/XEH_post_initServer.sqf +++ b/addons/noradio/XEH_post_initServer.sqf @@ -1,10 +1,6 @@ // by commy2 - #include "script_component.hpp" addMissionEventHandler ["HandleDisconnect", { - if !((_this select 0) getVariable ["ACE_isUnconscious", false]) then { //@ToDo: ai waking up will be silent? - _this call EFUNC(common,unMuteUnit); - }; - (_this select 0) setVariable [QGVAR(isMuted), false, true]; + [_this select 0, "isPlayer"] call EFUNC(common,unmuteUnit); }]; diff --git a/tools/make.py b/tools/make.py index 65f447bff9..6222932727 100644 --- a/tools/make.py +++ b/tools/make.py @@ -606,14 +606,17 @@ See the make.cfg file for additional build options. cmd = [os.path.join(arma3tools_path, "CfgConvert", "CfgConvert.exe"), "-bin", "-dst", os.path.join(work_drive, prefix, module, "config.bin"), os.path.join(work_drive, prefix, module, "config.cpp")] ret = subprocess.call(cmd) if ret != 0: - print_error("CfgConvert -bin return code == " + str(ret)) - input("Press Enter to continue...") + print_error("CfgConvert -bin return code == " + str(ret) + ". Usually means there is a syntax error within the config.cpp file.") + os.remove(os.path.join(work_drive, prefix, module, "config.cpp")) + shutil.copyfile(os.path.join(work_drive, prefix, module, "config.backup"), os.path.join(work_drive, prefix, module, "config.cpp")) cmd = [os.path.join(arma3tools_path, "CfgConvert", "CfgConvert.exe"), "-txt", "-dst", os.path.join(work_drive, prefix, module, "config.cpp"), os.path.join(work_drive, prefix, module, "config.bin")] ret = subprocess.call(cmd) if ret != 0: - print_error("CfgConvert -txt) return code == " + str(ret)) - input("Press Enter to continue...") + print_error("CfgConvert -txt return code == " + str(ret) + ". Usually means there is a syntax error within the config.cpp file.") + os.remove(os.path.join(work_drive, prefix, module, "config.cpp")) + shutil.copyfile(os.path.join(work_drive, prefix, module, "config.backup"), os.path.join(work_drive, prefix, module, "config.cpp")) + # Include build number try: @@ -622,13 +625,16 @@ See the make.cfg file for additional build options. configtext = f.read() f.close() - patchestext = re.search(r"class CfgPatches\n\{(.*?)\n\}", configtext, re.DOTALL).group(1) - patchestext = re.sub(r'version(.*?)="(.*?)"', r'version\1="\2-{}"'.format(commit_id), patchestext) - configtext = re.sub(r"class CfgPatches\n\{(.*?)\n\}", "class CfgPatches\n{"+patchestext+"\n}", configtext, flags=re.DOTALL) - - f = open(configpath, "w") - f.write(configtext) - f.close() + if configtext: + patchestext = re.search(r"class CfgPatches\n\{(.*?)\n\}", configtext, re.DOTALL).group(1) + patchestext = re.sub(r'version(.*?)="(.*?)"', r'version\1="\2-{}"'.format(commit_id), patchestext) + configtext = re.sub(r"class CfgPatches\n\{(.*?)\n\}", "class CfgPatches\n{"+patchestext+"\n}", configtext, flags=re.DOTALL) + f = open(configpath, "w") + f.write(configtext) + f.close() + else: + os.remove(os.path.join(work_drive, prefix, module, "config.cpp")) + os.rename(os.path.join(work_drive, prefix, module, "config.backup"), os.path.join(work_drive, prefix, module, "config.cpp")) except: raise print_error("Failed to include build number") diff --git a/tools/make64.py b/tools/make64.py index 0382bb9179..24f8ea2b0b 100644 --- a/tools/make64.py +++ b/tools/make64.py @@ -606,14 +606,17 @@ See the make.cfg file for additional build options. cmd = [os.path.join(arma3tools_path, "CfgConvert", "CfgConvert.exe"), "-bin", "-dst", os.path.join(work_drive, prefix, module, "config.bin"), os.path.join(work_drive, prefix, module, "config.cpp")] ret = subprocess.call(cmd) if ret != 0: - print_error("CfgConvert -bin return code == " + str(ret)) - input("Press Enter to continue...") + print_error("CfgConvert -bin return code == " + str(ret) + ". Usually means there is a syntax error within the config.cpp file.") + os.remove(os.path.join(work_drive, prefix, module, "config.cpp")) + shutil.copyfile(os.path.join(work_drive, prefix, module, "config.backup"), os.path.join(work_drive, prefix, module, "config.cpp")) cmd = [os.path.join(arma3tools_path, "CfgConvert", "CfgConvert.exe"), "-txt", "-dst", os.path.join(work_drive, prefix, module, "config.cpp"), os.path.join(work_drive, prefix, module, "config.bin")] ret = subprocess.call(cmd) if ret != 0: - print_error("CfgConvert -txt) return code == " + str(ret)) - input("Press Enter to continue...") + print_error("CfgConvert -txt return code == " + str(ret) + ". Usually means there is a syntax error within the config.cpp file.") + os.remove(os.path.join(work_drive, prefix, module, "config.cpp")) + shutil.copyfile(os.path.join(work_drive, prefix, module, "config.backup"), os.path.join(work_drive, prefix, module, "config.cpp")) + # Include build number try: @@ -622,13 +625,16 @@ See the make.cfg file for additional build options. configtext = f.read() f.close() - patchestext = re.search(r"class CfgPatches\n\{(.*?)\n\}", configtext, re.DOTALL).group(1) - patchestext = re.sub(r'version(.*?)="(.*?)"', r'version\1="\2-{}"'.format(commit_id), patchestext) - configtext = re.sub(r"class CfgPatches\n\{(.*?)\n\}", "class CfgPatches\n{"+patchestext+"\n}", configtext, flags=re.DOTALL) - - f = open(configpath, "w") - f.write(configtext) - f.close() + if configtext: + patchestext = re.search(r"class CfgPatches\n\{(.*?)\n\}", configtext, re.DOTALL).group(1) + patchestext = re.sub(r'version(.*?)="(.*?)"', r'version\1="\2-{}"'.format(commit_id), patchestext) + configtext = re.sub(r"class CfgPatches\n\{(.*?)\n\}", "class CfgPatches\n{"+patchestext+"\n}", configtext, flags=re.DOTALL) + f = open(configpath, "w") + f.write(configtext) + f.close() + else: + os.remove(os.path.join(work_drive, prefix, module, "config.cpp")) + os.rename(os.path.join(work_drive, prefix, module, "config.backup"), os.path.join(work_drive, prefix, module, "config.cpp")) except: raise print_error("Failed to include build number")