mirror of
https://github.com/acemod/ACE3.git
synced 2024-08-30 18:23:18 +00:00
Merge branch 'master' into medical-rewrite
Conflicts: addons/medical_blood/XEH_postInit.sqf
This commit is contained in:
commit
866612b974
@ -29,6 +29,7 @@ Walter Pearce <jaynus@gmail.com>
|
||||
# CONTRIBUTORS
|
||||
[BIG]Bull
|
||||
11RDP-LoupVert <loupvert@11rdp.fr>
|
||||
654wak654 <ozanegitmen@gmail.com>
|
||||
ACCtomeek <tomeek99@gmail.com>
|
||||
adam3adam <br.ada@seznam.cz>
|
||||
Adanteh
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/acemod/ACE3/releases/latest">
|
||||
<img src="https://img.shields.io/badge/Version-3.8.0-blue.svg?style=flat-square" alt="ACE3 Version">
|
||||
<img src="https://img.shields.io/badge/Version-3.8.1-blue.svg?style=flat-square" alt="ACE3 Version">
|
||||
</a>
|
||||
<a href="https://github.com/acemod/ACE3/issues">
|
||||
<img src="https://img.shields.io/github/issues-raw/acemod/ACE3.svg?style=flat-square&label=Issues" alt="ACE3 Issues">
|
||||
|
@ -142,6 +142,7 @@ PREP(setHearingCapability);
|
||||
PREP(setName);
|
||||
PREP(setParameter);
|
||||
PREP(setPitchBankYaw);
|
||||
PREP(setPlayerOwner);
|
||||
PREP(setProne);
|
||||
PREP(setSetting);
|
||||
PREP(setSettingFromConfig);
|
||||
|
54
addons/common/functions/fnc_setPlayerOwner.sqf
Normal file
54
addons/common/functions/fnc_setPlayerOwner.sqf
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Author: PabstMirror
|
||||
* Sets the player's owner id as a variable on his player ojbect.
|
||||
* Should be called on all machines (including server)
|
||||
* Note: Needs to wait for CBA_clientID to be recieved from server.
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* [] call ace_common_fnc_setPlayerOwner
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
|
||||
// #define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
|
||||
if (missionNameSpace getVariable [QGVAR(setPlayerOwnerRunning), false]) exitWith {};
|
||||
GVAR(setPlayerOwnerRunning) = true;
|
||||
|
||||
if (isServer) then {
|
||||
addMissionEventHandler ["HandleDisconnect", {
|
||||
params ["_dcPlayer"];
|
||||
TRACE_1("HandleDisconnect eh",_dcPlayer);
|
||||
if (!isNil {_dcPlayer getVariable QGVAR(playerOwner)}) then {
|
||||
_dcPlayer setVariable [QGVAR(playerOwner), nil, true];
|
||||
};
|
||||
}];
|
||||
};
|
||||
|
||||
if (hasInterface) then {
|
||||
[{
|
||||
(!isNil "CBA_clientID") && {CBA_clientID > -1}
|
||||
}, {
|
||||
TRACE_1("CBA_clientID ready",CBA_clientID);
|
||||
|
||||
["unit", {
|
||||
params ["_newUnit", "_oldUnit"];
|
||||
TRACE_2("unit changed",_newUnit,_oldUnit);
|
||||
if ((_oldUnit getVariable [QGVAR(playerOwner), -1]) == CBA_clientID) then {
|
||||
_oldUnit setVariable [QGVAR(playerOwner), nil, true];
|
||||
};
|
||||
if (alive _newUnit) then {
|
||||
_newUnit setVariable [QGVAR(playerOwner), CBA_clientID, true];
|
||||
};
|
||||
}, true] call CBA_fnc_addPlayerEventHandler;
|
||||
|
||||
}, []] call CBA_fnc_waitUntilAndExecute;
|
||||
};
|
||||
|
@ -28,20 +28,16 @@ class CfgVehicles {
|
||||
|
||||
class Tank;
|
||||
class Tank_F: Tank {
|
||||
GVAR(ammoLocation) = "HitTurret";
|
||||
GVAR(ammoLocation) = "HitHull";
|
||||
GVAR(cookoffSelections)[] = {"poklop_gunner","poklop_commander"};
|
||||
};
|
||||
|
||||
class MBT_01_base_F: Tank_F {
|
||||
GVAR(ammoLocation) = "HitHull";
|
||||
};
|
||||
class APC_Tracked_01_base_F: Tank_F {
|
||||
GVAR(ammoLocation) = "HitHull";
|
||||
class MBT_02_base_F: Tank_F {
|
||||
GVAR(ammoLocation) = "HitTurret";
|
||||
};
|
||||
|
||||
class Car_F;
|
||||
class Wheeled_APC_F: Car_F {
|
||||
GVAR(ammoLocation) = "HitTurret";
|
||||
GVAR(ammoLocation) = "HitHull";
|
||||
GVAR(cookoffSelections)[] = {"poklop_gunner","poklop_commander"};
|
||||
|
||||
// big explosions for wheeled APCs (same as for tanks)
|
||||
|
@ -36,6 +36,22 @@ GVAR(cacheTankDuplicates) = call CBA_fnc_createNamespace;
|
||||
["Wheeled_APC_F", "init", {
|
||||
params ["_vehicle"];
|
||||
|
||||
private _typeOf = typeOf _vehicle;
|
||||
|
||||
if (isNil {GVAR(cacheTankDuplicates) getVariable _typeOf}) then {
|
||||
private _hitpoints = (getAllHitPointsDamage _vehicle param [0, []]) apply {toLower _x};
|
||||
private _duplicateHitpoints = [];
|
||||
|
||||
{
|
||||
if ((_x != "") && {_x in (_hitpoints select [0,_forEachIndex])}) then {
|
||||
_duplicateHitpoints pushBack _forEachIndex;
|
||||
};
|
||||
} forEach _hitpoints;
|
||||
|
||||
TRACE_2("dupes",_typeOf,_duplicateHitpoints);
|
||||
GVAR(cacheTankDuplicates) setVariable [_typeOf, _duplicateHitpoints];
|
||||
};
|
||||
|
||||
_vehicle addEventHandler ["HandleDamage", {
|
||||
if ((_this select 0) getVariable [QGVAR(enable), GVAR(enable)]) then {
|
||||
["tank", _this] call FUNC(handleDamage);
|
||||
|
@ -9,7 +9,7 @@
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* (vehicle player) call ace_cookoff_fnc_cookOff
|
||||
* [(vehicle player)] call ace_cookoff_fnc_cookOff
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
@ -113,9 +113,12 @@ if (local _vehicle) then {
|
||||
|
||||
[_vehicle, _fnc_FlameEffect, 12] call _fnc_FlameEffect; // recursive function
|
||||
|
||||
private _randomPosition = _vehicle getPos [100, random 360];
|
||||
|
||||
{
|
||||
if (local _x && {!(_x call EFUNC(common,isPlayer))}) then {
|
||||
_x action ["Eject", _vehicle];
|
||||
_x leaveVehicle _vehicle;
|
||||
_x doMove _randomPosition;
|
||||
};
|
||||
} forEach crew _vehicle;
|
||||
|
||||
|
@ -34,6 +34,7 @@ class CfgVehicles {
|
||||
displayName = CSTRING(checkItem);
|
||||
condition = "true";
|
||||
statement = "";
|
||||
exceptions[] = {"isNotInside", "isNotSitting"};
|
||||
insertChildren = QUOTE(_this call DFUNC(addDogtagActions));
|
||||
};
|
||||
};
|
||||
|
@ -32,7 +32,7 @@ private _unitDogtagIDs = [];
|
||||
//Create action children for all dogtags
|
||||
private _actions = [];
|
||||
{
|
||||
private _displayName = format ["%1", getText (configFile >> "CfgWeapons" >> _x >> "displayName")];
|
||||
private _displayName = getText (configFile >> "CfgWeapons" >> _x >> "displayName");
|
||||
private _picture = getText (configFile >> "CfgWeapons" >> _x >> "picture");
|
||||
|
||||
private _action = [_x, _displayName, _picture, {_this call FUNC(checkDogtagItem)}, {true}, {}, _x] call EFUNC(interact_menu,createAction);
|
||||
|
@ -1 +1 @@
|
||||
z\ace\addons\frag
|
||||
z\ace\addons\frag
|
||||
|
@ -34,7 +34,6 @@ class ACE_Settings {
|
||||
typeName = "SCALAR";
|
||||
value = 50;
|
||||
};
|
||||
|
||||
class GVAR(enableDebugTrace) {
|
||||
category = CSTRING(Module_DisplayName);
|
||||
displayName = CSTRING(EnableDebugTrace);
|
||||
|
@ -1,6 +1,6 @@
|
||||
#define BASE_DRAG -0.01
|
||||
#define HD_MULT 5
|
||||
#define BASE_DRAG_HD (BASE_DRAG*HD_MULT)
|
||||
#define BASE_DRAG -0.01
|
||||
#define HD_MULT 5
|
||||
#define BASE_DRAG_HD (BASE_DRAG * HD_MULT)
|
||||
|
||||
class CfgAmmo {
|
||||
//class ace_arty_105mm_m1_m782_time;
|
||||
@ -104,10 +104,8 @@ class CfgAmmo {
|
||||
GVAR(gurney_k) = 1/2;
|
||||
};
|
||||
|
||||
class ACE_G_40mm_HEDP: G_40mm_HEDP {
|
||||
};
|
||||
class ACE_G_40mm_HE: G_40mm_HE {
|
||||
};
|
||||
class ACE_G_40mm_HEDP: G_40mm_HEDP {};
|
||||
class ACE_G_40mm_HE: G_40mm_HE {};
|
||||
class ACE_G_40mm_Practice: ACE_G_40mm_HE {
|
||||
GVAR(skip) = 1;
|
||||
GVAR(force) = 0;
|
||||
@ -438,8 +436,6 @@ class CfgAmmo {
|
||||
indirectHitRange = 0.25;
|
||||
airFriction = BASE_DRAG_HD*0.65;
|
||||
caliber = 2;
|
||||
|
||||
|
||||
};
|
||||
|
||||
class GVAR(huge): GVAR(large) {
|
||||
|
@ -1,5 +1,3 @@
|
||||
//CfgAmmoReflections.hpp
|
||||
|
||||
#define ACE_EXPLOSION_REFLECTION(range, hit)\
|
||||
class ace_explosion_reflection_##range##_##hit : ace_explosion_reflection_base {\
|
||||
indirectHitRange = range;\
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
class Extended_PreStart_EventHandlers {
|
||||
class ADDON {
|
||||
init = QUOTE(call COMPILE_FILE(XEH_preStart));
|
||||
|
@ -22,7 +22,6 @@ PREP(addPfhRound);
|
||||
PREP(removePfhRound); // THIS SHOULD ABE USED SPARINGLY
|
||||
|
||||
// Explosive Reflection
|
||||
GVAR(replacedBisArtyWrapper) = true;
|
||||
PREP(findReflections);
|
||||
PREP(doExplosions);
|
||||
PREP(doReflections);
|
||||
|
@ -1,16 +1,15 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
if(GVAR(EnableDebugTrace) && !isMultiplayer) then {
|
||||
if (GVAR(EnableDebugTrace) && {!isMultiplayer}) then {
|
||||
GVAR(traceFrags) = true;
|
||||
GVAR(autoTrace) = true;
|
||||
};
|
||||
|
||||
if(isServer) then {
|
||||
[QGVAR(frag_eh), { _this call FUNC(frago); }] call CBA_fnc_addEventHandler;
|
||||
if (isServer) then {
|
||||
[QGVAR(frag_eh), {_this call FUNC(frago);}] call CBA_fnc_addEventHandler;
|
||||
};
|
||||
|
||||
["ace_settingsInitialized", {
|
||||
//If not enabled, exit
|
||||
if (!GVAR(enabled)) exitWith {};
|
||||
|
||||
// Register fire event handler
|
||||
@ -20,9 +19,8 @@ if(isServer) then {
|
||||
["ace_firedNonPlayerVehicle", DFUNC(fired)] call CBA_fnc_addEventHandler;
|
||||
|
||||
[FUNC(masterPFH), 0, []] call CBA_fnc_addPerFrameHandler;
|
||||
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
||||
//Cache for ammo type configs
|
||||
GVAR(cacheRoundsTypesToTrack) = createLocation ["ACE_HashLocation", [-10000,-10000,-10000], 0, 0];
|
||||
// Cache for ammo type configs
|
||||
GVAR(cacheRoundsTypesToTrack) = createLocation ["ACE_HashLocation", [-10000, -10000, -10000], 0, 0];
|
||||
GVAR(cacheRoundsTypesToTrack) setText QGVAR(cacheRoundsTypesToTrack);
|
||||
|
@ -4,10 +4,11 @@ ADDON = false;
|
||||
|
||||
#include "XEH_PREP.hpp"
|
||||
|
||||
GVAR(replacedBisArtyWrapper) = true;
|
||||
GVAR(blackList) = [];
|
||||
GVAR(traceFrags) = false;
|
||||
|
||||
GVAR(TOTALFRAGS) = 0;
|
||||
GVAR(totalFrags) = 0;
|
||||
|
||||
GVAR(spallHPData) = [];
|
||||
GVAR(spallIsTrackingCount) = 0;
|
||||
|
@ -1,4 +1,5 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
class CfgPatches {
|
||||
class ADDON {
|
||||
name = COMPONENT_NAME;
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_round"];
|
||||
GVAR(blackList) set [(count GVAR(blackList)), _round];
|
||||
|
||||
GVAR(blackList) pushBack _round;
|
||||
|
@ -1,73 +1,67 @@
|
||||
//#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_enabled", "_doSpall", "_spallTrack", "_spallTrackID"];
|
||||
PARAMS_3(_gun,_type,_round);
|
||||
DEFAULT_PARAM(3,_doFragTrack,false);
|
||||
params ["_gun", "_type", "_round", ["_doFragTrack", false]];
|
||||
|
||||
if (!GVAR(enabled)) exitWith {};
|
||||
|
||||
//_enabled = getNumber (configFile >> "CfgAmmo" >> _type >> QGVAR(enabled));
|
||||
//if(_enabled < 1) exitWith {};
|
||||
//if (_enabled < 1) exitWith {};
|
||||
|
||||
if(_round in GVAR(blackList)) exitWith {
|
||||
GVAR(blackList) = GVAR(blackList) - [_round];
|
||||
if (_round in GVAR(blackList)) exitWith {
|
||||
REM(GVAR(blackList),_round);
|
||||
};
|
||||
|
||||
// Exit on max track
|
||||
if( (count GVAR(objects)) > GVAR(MaxTrack)) exitWith { };
|
||||
if ((count GVAR(objects)) > GVAR(MaxTrack)) exitWith {};
|
||||
|
||||
if(_gun == ACE_player) then {
|
||||
if (
|
||||
_gun == ACE_player ||
|
||||
{(gunner _gun) == ACE_player} ||
|
||||
{local _gun && {!(isPlayer (gunner _gun))} && {!(isPlayer _gun)}}
|
||||
) then {
|
||||
_doFragTrack = true;
|
||||
} else {
|
||||
if((gunner _gun) == ACE_player) then {
|
||||
_doFragTrack = true;
|
||||
} else {
|
||||
if(local _gun && {!(isPlayer (gunner _gun))} && {!(isPlayer _gun)}) then {
|
||||
_doFragTrack = true;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
_doSpall = false;
|
||||
if(GVAR(SpallEnabled)) then {
|
||||
if(GVAR(spallIsTrackingCount) <= 0) then {
|
||||
private _doSpall = false;
|
||||
if (GVAR(SpallEnabled)) then {
|
||||
if (GVAR(spallIsTrackingCount) <= 0) then {
|
||||
GVAR(spallHPData) = [];
|
||||
};
|
||||
if(GVAR(spallIsTrackingCount) > 5) then {
|
||||
if (GVAR(spallIsTrackingCount) > 5) then {
|
||||
// ACE_player sideChat "LIMT!";
|
||||
} else {
|
||||
_doSpall = true;
|
||||
GVAR(spallIsTrackingCount) = GVAR(spallIsTrackingCount) + 1;
|
||||
INC(GVAR(spallIsTrackingCount));
|
||||
};
|
||||
};
|
||||
// ACE_player sideChat format["c: %1", GVAR(spallIsTrackingCount)];
|
||||
// ACE_player sideChat format ["c: %1", GVAR(spallIsTrackingCount)];
|
||||
|
||||
if(GVAR(autoTrace)) then {
|
||||
[ACE_player, _round, [1,0,0,1]] call FUNC(addTrack);
|
||||
if (GVAR(autoTrace)) then {
|
||||
[ACE_player, _round, [1, 0, 0, 1]] call FUNC(addTrack);
|
||||
};
|
||||
|
||||
// We only do the single track object check here.
|
||||
// We should do an {!(_round in GVAR(objects))}
|
||||
// But we leave that out here for optimization. So this cannot be a framework function
|
||||
// Otherwise, it should only be added once and from the FiredEH
|
||||
if(_doFragTrack && {alive _round}) then {
|
||||
_spallTrack = [];
|
||||
_spallTrackID = [];
|
||||
if (_doFragTrack && {alive _round}) then {
|
||||
private _spallTrack = [];
|
||||
private _spallTrackID = [];
|
||||
|
||||
private ["_args"];
|
||||
_args = [_round, (getPosASL _round), (velocity _round), _type, diag_frameno, _gun, _doSpall, _spallTrack, _spallTrackID,
|
||||
(getNumber (configFile >> "CfgAmmo" >> _type >> QGVAR(skip))),
|
||||
(getNumber (configFile >> "CfgAmmo" >> _type >> "explosive")),
|
||||
(getNumber (configFile >> "CfgAmmo" >> _type >> "indirectHitRange")),
|
||||
(getNumber (configFile >> "CfgAmmo" >> _type >> QGVAR(force))),
|
||||
(getNumber(configFile >> "CfgAmmo" >> _type >> "indirecthit")*(sqrt((getNumber (configFile >> "CfgAmmo" >> _type >> "indirectHitRange")))))
|
||||
private _args = [
|
||||
_round, getPosASL _round, velocity _round, _type, diag_frameno, _gun, _doSpall, _spallTrack, _spallTrackID,
|
||||
getNumber (configFile >> "CfgAmmo" >> _type >> QGVAR(skip)),
|
||||
getNumber (configFile >> "CfgAmmo" >> _type >> "explosive"),
|
||||
getNumber (configFile >> "CfgAmmo" >> _type >> "indirectHitRange"),
|
||||
getNumber (configFile >> "CfgAmmo" >> _type >> QGVAR(force)),
|
||||
getNumber (configFile >> "CfgAmmo" >> _type >> "indirecthit") * (sqrt (getNumber (configFile >> "CfgAmmo" >> _type >> "indirectHitRange")))
|
||||
];
|
||||
TRACE_1("Initializing track", _round);
|
||||
GVAR(objects) pushBack _round;
|
||||
GVAR(arguments) pushBack _args;
|
||||
|
||||
if(_doSpall) then {
|
||||
if (_doSpall) then {
|
||||
[_round, 1, _spallTrack, _spallTrackID] call FUNC(spallTrack);
|
||||
};
|
||||
// ACE_player sideChat "WTF2";
|
||||
|
@ -5,16 +5,12 @@ if (GVAR(autoTrace)) then {
|
||||
};
|
||||
|
||||
// setAccTime 0.05;
|
||||
private _index = count GVAR(traces);
|
||||
params ["_origin", "_obj"];
|
||||
private _color = [1,0,0,1];
|
||||
if((count _this) > 2) then {
|
||||
_color = _this select 2;
|
||||
};
|
||||
params ["_origin", "_obj", ["_color", [1, 0, 0, 1]]];
|
||||
|
||||
private _positions = [];
|
||||
private _objSpd = vectorMagnitude (velocity _obj);
|
||||
_positions set[(count _positions), [(getPos _obj), _objSpd]];
|
||||
_positions pushBack [getPos _obj, _objSpd];
|
||||
private _data = [_origin, typeOf _origin, typeOf _obj, _objSpd, _positions, _color];
|
||||
|
||||
GVAR(traces) set[_index, _data];
|
||||
private _index = GVAR(traces) pushBack _data;
|
||||
[DFUNC(trackTrace), 0, [_obj, _index, CBA_missionTime]] call CBA_fnc_addPerFrameHandler;
|
||||
|
@ -1,7 +1,11 @@
|
||||
#define DEBUG_MODE_FULL
|
||||
#include "script_component.hpp"
|
||||
|
||||
params [["_debugMissing", true, [false]], ["_debugForce", false, [false]], ["_debugNonFrag", false, [false]]];
|
||||
params [
|
||||
["_debugMissing", true, [false]],
|
||||
["_debugForce", false, [false]],
|
||||
["_debugNonFrag", false, [false]]
|
||||
];
|
||||
|
||||
diag_log text format ["~~~~~~~~~~~~~Start [%1]~~~~~~~~~~~~~", _this];
|
||||
|
||||
@ -10,7 +14,7 @@ private _processedCfgAmmos = [];
|
||||
|
||||
{
|
||||
private _ammo = toLower getText (_x >> "ammo");
|
||||
if ((_ammo != "") && {!(_ammo in _processedCfgAmmos)}) then {
|
||||
if (_ammo != "" && {!(_ammo in _processedCfgAmmos)}) then {
|
||||
_processedCfgAmmos pushBack _ammo;
|
||||
|
||||
//Ignore mines/bombs
|
||||
@ -23,37 +27,37 @@ private _processedCfgAmmos = [];
|
||||
private _explosive = getNumber (_ammoConfig >> "explosive");
|
||||
private _indirectRange = getNumber (_ammoConfig >> "indirectHitRange");
|
||||
private _force = getNumber (_ammoConfig >> QGVAR(force));
|
||||
private _fragPower = getNumber(_ammoConfig >> "indirecthit")*(sqrt((getNumber (_ammoConfig >> "indirectHitRange"))));
|
||||
private _fragPower = getNumber (_ammoConfig >> "indirecthit") * (sqrt ((getNumber (_ammoConfig >> "indirectHitRange"))));
|
||||
|
||||
private _shouldAdd = (_skip == 0) && {(_force == 1) || {_explosive > 0.5 && {_indirectRange >= 4.5} && {_fragPower >= 35}}};
|
||||
|
||||
if (_shouldAdd) then {
|
||||
if (_debugForce && {((getNumber(_ammoConfig >> "hit")) < 5) || {_fragPower < 10}}) then {
|
||||
diag_log text format ["Ammo [%1] from Mag [%2] - Weak but will still frag!",_ammo,configName _x];
|
||||
diag_log text format [" - _force=%1,_fragPower=%2",_force,_fragPower];
|
||||
diag_log text format ["Ammo [%1] from Mag [%2] - Weak but will still frag!", _ammo, configName _x];
|
||||
diag_log text format [" - _force=%1,_fragPower=%2", _force, _fragPower];
|
||||
};
|
||||
|
||||
_warn = false;
|
||||
|
||||
private _warn = false;
|
||||
|
||||
_fragTypes = getArray (_ammoConfig >> QGVAR(CLASSES));
|
||||
if(_fragTypes isEqualTo []) then {_warn = true;};
|
||||
if (_fragTypes isEqualTo []) then {_warn = true;};
|
||||
_c = getNumber(_ammoConfig >> QGVAR(CHARGE));
|
||||
if(_c == 0) then {_warn = true;};
|
||||
if (_c == 0) then {_warn = true;};
|
||||
_m = getNumber(_ammoConfig >> QGVAR(METAL));
|
||||
if(_m == 0) then {_warn = true;};
|
||||
if (_m == 0) then {_warn = true;};
|
||||
_k = getNumber(_ammoConfig >> QGVAR(GURNEY_K));
|
||||
if(_k == 0) then {_warn = true;};
|
||||
if (_k == 0) then {_warn = true;};
|
||||
_gC = getNumber(_ammoConfig >> QGVAR(GURNEY_C));
|
||||
if(_gC == 0) then { _warn = true;};
|
||||
if (_gC == 0) then {_warn = true;};
|
||||
|
||||
if(_debugMissing && _warn) then {
|
||||
diag_log text format ["Ammo [%1] from Mag [%2] MISSING frag configs:",_ammo,configName _x];
|
||||
diag_log text format [" - _c=%1,_m=%2,_k=%3,_gC=%4,_fragTypes=%5",_c,_m,_k,_gC,_fragTypes];
|
||||
if (_debugMissing && {_warn}) then {
|
||||
diag_log text format ["Ammo [%1] from Mag [%2] MISSING frag configs:", _ammo, configName _x];
|
||||
diag_log text format [" - _c=%1,_m=%2,_k=%3,_gC=%4,_fragTypes=%5", _c, _m, _k, _gC, _fragTypes];
|
||||
};
|
||||
} else {
|
||||
if (_debugNonFrag && {isArray (_ammoConfig >> QGVAR(CLASSES))}) then {
|
||||
diag_log text format ["Ammo [%1] from Mag [%2] has frag configs but will NOT frag:",_ammo,configName _x];
|
||||
diag_log text format ["- skip=%1,explosive=%2,indirectHitRange=%3,force=%4,fragPower=%5",_skip,_explosive,_indirectRange,_force,_fragPower];
|
||||
diag_log text format ["Ammo [%1] from Mag [%2] has frag configs but will NOT frag:", _ammo, configName _x];
|
||||
diag_log text format ["- skip=%1,explosive=%2,indirectHitRange=%3,force=%4,fragPower=%5", _skip, _explosive, _indirectRange, _force, _fragPower];
|
||||
};
|
||||
};
|
||||
};
|
||||
|
@ -1,20 +1,22 @@
|
||||
//fnc_doExplosions.sqf
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_args"];
|
||||
params ["_args", "_pfhID"];
|
||||
_args params ["_explosions", "_index"];
|
||||
|
||||
for "_i" from _index to ((_index+2) min (count _explosions)) do {
|
||||
for "_i" from _index to ((_index + 2) min (count _explosions)) do {
|
||||
private _exp = _explosions select _i;
|
||||
_exp params ["_refExp", "_bpos", "_hit", "_distance", "_indirectHitRange", "_depth"];
|
||||
_refExp createVehicle (ASLtoATL _bpos);
|
||||
// if(_hit >= 150 && _distance > _indirectHitRange) then {
|
||||
// if (_hit >= 150 && _distance > _indirectHitRange) then {
|
||||
// [_bpos, _refExp, _depth] call FUNC(doReflections);
|
||||
// };
|
||||
};
|
||||
_index = _index + 2;
|
||||
if(_index >= (count _explosions)) then {
|
||||
[(_this select 1)] call CBA_fnc_removePerFrameHandler;
|
||||
|
||||
ADD(_index,2);
|
||||
|
||||
if (_index >= count _explosions) then {
|
||||
[_pfhID] call CBA_fnc_removePerFrameHandler;
|
||||
} else {
|
||||
_params set[1, _index];
|
||||
_args set [1, _index];
|
||||
};
|
||||
|
@ -1,14 +1,10 @@
|
||||
//fnc_doReflections.sqf
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_pos", "_ammo"];
|
||||
params ["_pos", "_ammo", ["_depth", 1]];
|
||||
|
||||
private _depth = 1;
|
||||
if(count _this > 2) then {
|
||||
_depth = _this select 2;
|
||||
};
|
||||
// TEST_ICONS pushBack [_pos, format["EXP!", _hit, _range, _hitFactor]];
|
||||
if(_depth <= 2) then {
|
||||
// TEST_ICONS pushBack [_pos, format ["EXP!", _hit, _range, _hitFactor]];
|
||||
if (_depth <= 2) then {
|
||||
private _indirectHitRange = getNumber(configFile >> "CfgAmmo" >> _ammo >> "indirectHitRange");
|
||||
private _indirectHit = getNumber(configFile >> "CfgAmmo" >> _ammo >> "indirectHit");
|
||||
private _testParams = [_pos, [_indirectHitRange, _indirectHit], [], [], -4, _depth, 0];
|
||||
|
@ -2,145 +2,126 @@
|
||||
#include "script_component.hpp"
|
||||
// ACE_player sideChat "WAAAAAAAAAAAAAAAAAAAAA";
|
||||
|
||||
params ["_hitData"];
|
||||
params ["_hitData", "_hitPartDataIndex"];
|
||||
private _initialData = GVAR(spallHPData) select (_hitData select 0);
|
||||
private _hpData = (_hitData select 1) select (_this select 1);
|
||||
_initialData params ["_hpId", "_object", "_roundType", "_round", "_curPos", "_velocity"];
|
||||
|
||||
_hpData params ["_object"];
|
||||
_object removeEventHandler ["hitPart", _initialData select 0];
|
||||
private _foundObjects = _initialData select 7;
|
||||
private _index = _foundObjects find _object;
|
||||
if(_index != -1) then {
|
||||
_foundObjects set[_index, nil];
|
||||
};
|
||||
private _hpData = (_hitData select 1) select _hitPartDataIndex;
|
||||
(_hpData select 0) removeEventHandler ["hitPart", _hpId];
|
||||
|
||||
_initialData params ["", "_object", "_roundType", "_round"];
|
||||
private _caliber = getNumber (configFile >> "CfgAmmo" >> _roundType >> "caliber");
|
||||
private _explosive = getNumber (configFile >> "CfgAmmo" >> _roundType >> "explosive");
|
||||
private _idh = getNumber (configFile >> "CfgAmmo" >> _roundType >> "indirectHitRange");
|
||||
|
||||
private _caliber = getNumber(configFile >> "CfgAmmo" >> _roundType >> "caliber");
|
||||
private _explosive = getNumber(configFile >> "CfgAmmo" >> _roundType >> "explosive");
|
||||
private _idh = getNumber(configFile >> "CfgAmmo" >> _roundType >> "indirectHitRange");
|
||||
if !(_caliber >= 2.5 || {(_explosive > 0 && {_idh >= 1})}) exitWith {};
|
||||
// ACE_player sideChat format ["BBBB"];
|
||||
private _exit = false;
|
||||
private _vm = 1;
|
||||
|
||||
private _alive = true;
|
||||
if(!alive _round && (_initialData select 6) isEqualTo 1) then {
|
||||
_alive = false;
|
||||
};
|
||||
private _oldVelocity = vectorMagnitude _velocity;
|
||||
private _curVelocity = vectorMagnitude (velocity _round);
|
||||
|
||||
if(_alive || {_caliber >= 2.5} || {(_explosive > 0 && {_idh >= 1})}) then {
|
||||
// ACE_player sideChat format["BBBB"];
|
||||
private _exit = false;
|
||||
private _vm = 1;
|
||||
private _velocity = _initialData select 5;
|
||||
|
||||
private _oldVelocity = vectorMagnitude _velocity;
|
||||
private _curVelocity = vectorMagnitude (velocity _round);
|
||||
|
||||
if(alive _round) then {
|
||||
private _diff = _velocity vectorDiff (velocity _round);
|
||||
private _polar = _diff call CBA_fnc_vect2polar;
|
||||
// ACE_player sideChat format["polar: %1", _polar];
|
||||
if((abs(_polar select 1) > 45 || abs(_polar select 2) > 45)) then {
|
||||
if(_caliber < 2.5) then {
|
||||
// ACE_player sideChat format["exit!"];
|
||||
_exit = true;
|
||||
} else {
|
||||
_vm = 1-(_curVelocity/_oldVelocity);
|
||||
};
|
||||
};
|
||||
};
|
||||
if(!_exit) then {
|
||||
private _unitDir = vectorNormalized _velocity;
|
||||
private _pos = _hpData select 3;
|
||||
private _spallPos = nil;
|
||||
for "_i" from 0 to 100 do {
|
||||
private _pos1 = _pos vectorAdd (_unitDir vectorMultiply (0.01 * _i));
|
||||
private _pos2 = _pos vectorAdd (_unitDir vectorMultiply (0.01 * (_i + 1)));
|
||||
// _blah = [_object, "FIRE"] intersect [_object worldToModel (ASLtoATL _pos1), _object worldToModel (ASLtoATL _pos2)];
|
||||
// diag_log text format["b: %1", _blah];
|
||||
|
||||
// _data = [nil, nil, nil, 1, [[ASLtoATL _pos1, 1], [ASLtoATL _pos2, 1]]];
|
||||
// NOU_TRACES set[(count NOU_TRACES), _data];
|
||||
|
||||
if(!lineIntersects [_pos1, _pos2]) exitWith {
|
||||
// ACE_player sideChat format["FOUND!"];
|
||||
_spallPos = _pos2;
|
||||
};
|
||||
};
|
||||
if(!isNil "_spallPos") then {
|
||||
private _spallPolar = _velocity call CBA_fnc_vect2polar;
|
||||
|
||||
if(_explosive > 0) then {
|
||||
// ACE_player sideChat format["EXPLOSIVE!"];
|
||||
private _warn = false;
|
||||
private _c = getNumber(configFile >> "CfgAmmo" >> _roundType >> QGVAR(CHARGE));
|
||||
if(_c == 0) then { _c = 1; _warn = true;};
|
||||
private _m = getNumber(configFile >> "CfgAmmo" >> _roundType >> QGVAR(METAL));
|
||||
if(_m == 0) then { _m = 2; _warn = true;};
|
||||
private _k = getNumber(configFile >> "CfgAmmo" >> _roundType >> QGVAR(GURNEY_K));
|
||||
if(_k == 0) then { _k = 1/2; _warn = true;};
|
||||
private _gC = getNumber(configFile >> "CfgAmmo" >> _roundType >> QGVAR(GURNEY_C));
|
||||
if(_gC == 0) then { _gC = 2440; _warn = true;};
|
||||
|
||||
if(_warn) then {
|
||||
WARNING_1("Ammo class %1 lacks proper explosive properties definitions for frag!",_roundType); //TODO: turn this off when we get closer to release
|
||||
};
|
||||
|
||||
private _fragPower = (((_m/_c)+_k)^-(1/2))*_gC;
|
||||
_spallPolar set[0, _fragPower*0.66];
|
||||
};
|
||||
|
||||
private _fragTypes = [
|
||||
QGVAR(spall_small), QGVAR(spall_small), QGVAR(spall_small),
|
||||
QGVAR(spall_small),QGVAR(spall_medium),QGVAR(spall_medium),QGVAR(spall_medium),
|
||||
QGVAR(spall_medium), QGVAR(spall_large), QGVAR(spall_large), QGVAR(spall_huge),
|
||||
QGVAR(spall_huge)
|
||||
|
||||
];
|
||||
|
||||
// diag_log text format["SPALL POWER: %1", _spallPolar select 0];
|
||||
private _spread = 15+(random 25);
|
||||
private _spallCount = 5+(random 10);
|
||||
for "_i" from 1 to _spallCount do {
|
||||
private _elev = ((_spallPolar select 2)-_spread)+(random (_spread*2));
|
||||
private _dir = ((_spallPolar select 1)-_spread)+(random (_spread*2));
|
||||
if(abs _elev > 90) then {
|
||||
_dir = _dir + 180;
|
||||
};
|
||||
_dir = _dir % 360;
|
||||
private _vel = (_spallPolar select 0)*0.33*_vm;
|
||||
_vel = (_vel-(_vel*0.25))+(random (_vel*0.5));
|
||||
|
||||
private _spallFragVect = [_vel, _dir, _elev] call CBA_fnc_polar2vect;
|
||||
private _fragType = round (random ((count _fragTypes)-1));
|
||||
private _fragment = (_fragTypes select _fragType) createVehicleLocal [0,0,10000];
|
||||
_fragment setPosASL _spallPos;
|
||||
_fragment setVelocity _spallFragVect;
|
||||
|
||||
if(GVAR(traceFrags)) then {
|
||||
[ACE_player, _fragment, [1,0.5,0,1]] call FUNC(addTrack);
|
||||
};
|
||||
};
|
||||
_spread = 5+(random 5);
|
||||
_spallCount = 3+(random 5);
|
||||
for "_i" from 1 to _spallCount do {
|
||||
private _elev = ((_spallPolar select 2)-_spread)+(random (_spread*2));
|
||||
private _dir = ((_spallPolar select 1)-_spread)+(random (_spread*2));
|
||||
if(abs _elev > 90) then {
|
||||
_dir = _dir + 180;
|
||||
};
|
||||
_dir = _dir % 360;
|
||||
private _vel = (_spallPolar select 0)*0.55*_vm;
|
||||
_vel = (_vel-(_vel*0.25))+(random (_vel*0.5));
|
||||
|
||||
private _spallFragVect = [_vel, _dir, _elev] call CBA_fnc_polar2vect;
|
||||
private _fragType = round (random ((count _fragTypes)-1));
|
||||
private _fragment = (_fragTypes select _fragType) createVehicleLocal [0,0,10000];
|
||||
_fragment setPosASL _spallPos;
|
||||
_fragment setVelocity _spallFragVect;
|
||||
|
||||
if(GVAR(traceFrags)) then {
|
||||
[ACE_player, _fragment, [1,0,0,1]] call FUNC(addTrack);
|
||||
};
|
||||
};
|
||||
if (alive _round) then {
|
||||
private _diff = _velocity vectorDiff (velocity _round);
|
||||
private _polar = _diff call CBA_fnc_vect2polar;
|
||||
// ACE_player sideChat format ["polar: %1", _polar];
|
||||
if (abs (_polar select 1) > 45 || {abs (_polar select 2) > 45}) then {
|
||||
if (_caliber < 2.5) then {
|
||||
// ACE_player sideChat format ["exit!"];
|
||||
_exit = true;
|
||||
} else {
|
||||
SUB(_vm,_curVelocity / _oldVelocity);
|
||||
};
|
||||
};
|
||||
};
|
||||
if (_exit) exitWith {};
|
||||
private _unitDir = vectorNormalized _velocity;
|
||||
private _pos = _hpData select 3;
|
||||
private _spallPos = [];
|
||||
for "_i" from 0 to 100 do {
|
||||
private _pos1 = _pos vectorAdd (_unitDir vectorMultiply (0.01 * _i));
|
||||
private _pos2 = _pos vectorAdd (_unitDir vectorMultiply (0.01 * (_i + 1)));
|
||||
// _data = [nil, nil, nil, 1, [[ASLtoATL _pos1, 1], [ASLtoATL _pos2, 1]]];
|
||||
// NOU_TRACES pushBack _data;
|
||||
|
||||
if (!lineIntersects [_pos1, _pos2]) exitWith {
|
||||
// ACE_player sideChat format ["FOUND!"];
|
||||
_spallPos = _pos2;
|
||||
};
|
||||
};
|
||||
if (_spallPos isEqualTo []) exitWith {};
|
||||
private _spallPolar = _velocity call CBA_fnc_vect2polar;
|
||||
|
||||
if (_explosive > 0) then {
|
||||
// ACE_player sideChat format ["EXPLOSIVE!"];
|
||||
private _warn = false;
|
||||
private _c = getNumber (configFile >> "CfgAmmo" >> _roundType >> QGVAR(CHARGE));
|
||||
if (_c == 0) then {_c = 1; _warn = true;};
|
||||
private _m = getNumber (configFile >> "CfgAmmo" >> _roundType >> QGVAR(METAL));
|
||||
if (_m == 0) then {_m = 2; _warn = true;};
|
||||
private _k = getNumber (configFile >> "CfgAmmo" >> _roundType >> QGVAR(GURNEY_K));
|
||||
if (_k == 0) then {_k = 1 / 2; _warn = true;};
|
||||
private _gC = getNumber (configFile >> "CfgAmmo" >> _roundType >> QGVAR(GURNEY_C));
|
||||
if (_gC == 0) then {_gC = 2440; _warn = true;};
|
||||
|
||||
if (_warn) then {
|
||||
WARNING_1("Ammo class %1 lacks proper explosive properties definitions for frag!",_roundType); //TODO: turn this off when we get closer to release
|
||||
};
|
||||
|
||||
private _fragPower = (((_m / _c) + _k) ^ - (1 / 2)) * _gC;
|
||||
_spallPolar set [0, _fragPower * 0.66];
|
||||
};
|
||||
|
||||
private _fragTypes = [
|
||||
QGVAR(spall_small), QGVAR(spall_small), QGVAR(spall_small),
|
||||
QGVAR(spall_small),QGVAR(spall_medium),QGVAR(spall_medium),QGVAR(spall_medium),
|
||||
QGVAR(spall_medium), QGVAR(spall_large), QGVAR(spall_large), QGVAR(spall_huge),
|
||||
QGVAR(spall_huge)
|
||||
|
||||
];
|
||||
|
||||
// diag_log text format ["SPALL POWER: %1", _spallPolar select 0];
|
||||
private _spread = 15 + (random 25);
|
||||
private _spallCount = 5 + (random 10);
|
||||
for "_i" from 1 to _spallCount do {
|
||||
private _elev = ((_spallPolar select 2) - _spread) + (random (_spread * 2));
|
||||
private _dir = ((_spallPolar select 1) - _spread) + (random (_spread * 2));
|
||||
if (abs _elev > 90) then {
|
||||
ADD(_dir,180);
|
||||
};
|
||||
_dir = _dir % 360;
|
||||
private _vel = (_spallPolar select 0) * 0.33 * _vm;
|
||||
_vel = (_vel - (_vel * 0.25)) + (random (_vel * 0.5));
|
||||
|
||||
private _spallFragVect = [_vel, _dir, _elev] call CBA_fnc_polar2vect;
|
||||
private _fragType = round (random ((count _fragTypes) - 1));
|
||||
private _fragment = (_fragTypes select _fragType) createVehicleLocal [0,0,10000];
|
||||
_fragment setPosASL _spallPos;
|
||||
_fragment setVelocity _spallFragVect;
|
||||
|
||||
if (GVAR(traceFrags)) then {
|
||||
[ACE_player, _fragment, [1, 0.5, 0, 1]] call FUNC(addTrack);
|
||||
};
|
||||
};
|
||||
_spread = 5 + (random 5);
|
||||
_spallCount = 3 + (random 5);
|
||||
for "_i" from 1 to _spallCount do {
|
||||
private _elev = ((_spallPolar select 2) - _spread) + (random (_spread * 2));
|
||||
private _dir = ((_spallPolar select 1) - _spread) + (random (_spread * 2));
|
||||
if (abs _elev > 90) then {
|
||||
ADD(_dir,180);
|
||||
};
|
||||
_dir = _dir % 360;
|
||||
private _vel = (_spallPolar select 0) * 0.55 * _vm;
|
||||
_vel = (_vel - (_vel * 0.25)) + (random (_vel * 0.5));
|
||||
|
||||
private _spallFragVect = [_vel, _dir, _elev] call CBA_fnc_polar2vect;
|
||||
private _fragType = round (random ((count _fragTypes) - 1));
|
||||
private _fragment = (_fragTypes select _fragType) createVehicleLocal [0, 0, 10000];
|
||||
_fragment setPosASL _spallPos;
|
||||
_fragment setVelocity _spallFragVect;
|
||||
|
||||
if (GVAR(traceFrags)) then {
|
||||
[ACE_player, _fragment, [1, 0, 0, 1]] call FUNC(addTrack);
|
||||
};
|
||||
};
|
||||
|
@ -1,31 +1,23 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_color", "_index", "_lastPos", "_lastSpd", "_max", "_positions", "_startSpeed"];
|
||||
|
||||
{
|
||||
_positions = _x select 4;
|
||||
_color = _x select 5;
|
||||
_index = 0;
|
||||
_max = count _positions;
|
||||
_startSpeed = 0.01 max ((_positions select 0) select 1);
|
||||
_lastSpd = [];
|
||||
_lastPos = [];
|
||||
private _positions = _x select 4;
|
||||
private _color = _x select 5;
|
||||
private _index = 0;
|
||||
private _max = count _positions;
|
||||
private _lastSpd = [];
|
||||
private _lastPos = [];
|
||||
while {_index < _max} do {
|
||||
_data1 = _positions select _index;
|
||||
_data2 = nil;
|
||||
if(_index + ACE_TRACE_DRAW_INC >= _max) then {
|
||||
_data2 = _positions select (_max - 1);
|
||||
} else {
|
||||
_data2 = _positions select (_index + ACE_TRACE_DRAW_INC);
|
||||
};
|
||||
_data2 = _positions select ([_index + ACE_TRACE_DRAW_INC, _max - 1] select (_index + ACE_TRACE_DRAW_INC >= _max));
|
||||
|
||||
_pos1 = _data1 select 0;
|
||||
_pos2 = _data2 select 0;
|
||||
_index = _index + ACE_TRACE_DRAW_INC;
|
||||
ADD(_index,ACE_TRACE_DRAW_INC);
|
||||
|
||||
drawLine3D [_pos1, _pos2, _color];
|
||||
_lastPos = _pos2;
|
||||
_lastSpd = _data1 select 1;
|
||||
};
|
||||
// drawIcon3D ["", [1,0,0,1], _lastPos, 0, 0, 0, format["%1m/s", _lastSpd], 1, 0.05, "RobotoCondensed"];
|
||||
// drawIcon3D ["", [1,0,0,1], _lastPos, 0, 0, 0, format ["%1m/s", _lastSpd], 1, 0.05, "RobotoCondensed"];
|
||||
} forEach GVAR(traces);
|
||||
|
@ -1,61 +1,58 @@
|
||||
//fnc_findReflections.sqf
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_lastPos", "_test", "_vec", "_testPos", "_buckets", "_excludes", "_bucketIndex", "_bucketPos", "_bucketList", "_c", "_index", "_blist", "_avgX", "_avgY", "_avgZ", "_bpos", "_distance", "_hitFactor", "_hit", "_range", "_refExp", "_i", "_x", "_res", "_forEachIndex", "_explosions", "_can", "_dirvec", "_zAng"];
|
||||
|
||||
BEGIN_COUNTER(fnc_findReflections);
|
||||
params ["_args"];
|
||||
params ["_args", "_pfhID"];
|
||||
_args params ["_pos", "_explosiveInfo", "_los", "_nlos", "_zIndex", "_depth", "_rand"];
|
||||
|
||||
private _split = 15;
|
||||
private _radi = (360/_split*_depth);
|
||||
private _radi = 360 / _split * _depth;
|
||||
|
||||
// player sideChat format["p: %1", _explosiveInfo];
|
||||
// player sideChat format ["p: %1", _explosiveInfo];
|
||||
_explosiveInfo params ["_indirectHitRange", "_indirectHit"];
|
||||
private _distanceCount = (floor _indirectHitRange*4) min 100;
|
||||
private _distanceCount = (floor _indirectHitRange * 4) min 100;
|
||||
|
||||
if(_zIndex < 5) then {
|
||||
_lastPos = _pos;
|
||||
_zAng = _zIndex*20+2;
|
||||
if(_zAng > 80) then {
|
||||
if (_zIndex < 5) then {
|
||||
private _lastPos = _pos;
|
||||
private _zAng = _zIndex * 20 + 2;
|
||||
if (_zAng > 80) then {
|
||||
_radi = 1;
|
||||
_zAng = 90;
|
||||
};
|
||||
for "_i" from 0 to _radi do {
|
||||
_test = true;
|
||||
_vec = [1, ((_i*_split)+_rand) mod 360, _zAng] call CBA_fnc_polar2vect;
|
||||
private _test = true;
|
||||
private _vec = [1, ((_i * _split) + _rand) % 360, _zAng] call CBA_fnc_polar2vect;
|
||||
for "_x" from 1 to _distanceCount do {
|
||||
_testPos = _pos vectorAdd (_vec vectorMultiply _x);
|
||||
private _testPos = _pos vectorAdd (_vec vectorMultiply _x);
|
||||
// drop ["\a3\data_f\Cl_basic","","Billboard",1,15,ASLtoATL _testPos,[0,0,0],1,1.275,1.0,0.0,[1],[[1,0,0,1]],[0],0.0,2.0,"","",""];
|
||||
_res = lineIntersectsWith [_pos, _testPos];
|
||||
if(count _res > 0) exitWith {
|
||||
private _res = lineIntersectsWith [_pos, _testPos];
|
||||
if (count _res > 0) exitWith {
|
||||
_test = false;
|
||||
_nlos pushBack _lastPos;
|
||||
// {
|
||||
// _x addEventHandler ["HandleDamage", { diag_log text format["this: %1", _this]; }];
|
||||
// _x addEventHandler ["HandleDamage", { diag_log text format ["this: %1", _this]; }];
|
||||
// } forEach _res;
|
||||
// drop ["\a3\data_f\Cl_basic","","Billboard",1,15,ASLtoATL _testPos,[0,0,0],1,1.275,1.0,0.0,[1],[[1,0,0,1]],[0],0.0,2.0,"","",""];
|
||||
// TEST_PAIRS pushBack [_pos, _lastPos, [1,0,0,1]];
|
||||
|
||||
};
|
||||
// if(terrainIntersectASL [_pos, _testPos]) exitWith {};
|
||||
// if (terrainIntersectASL [_pos, _testPos]) exitWith {};
|
||||
_lastPos = _testPos;
|
||||
};
|
||||
};
|
||||
_args set[4, _zIndex+1];
|
||||
_args set [4, _zIndex + 1];
|
||||
} else {
|
||||
_depth = _depth + 1;
|
||||
_buckets = [];
|
||||
_excludes = [];
|
||||
_bucketIndex = 0;
|
||||
_bucketPos = nil;
|
||||
_bucketList = nil;
|
||||
_c = 0;
|
||||
while { count(_nlos) != count(_excludes) && _c < (count _nlos) } do {
|
||||
INC(_depth);
|
||||
private _buckets = [];
|
||||
private _excludes = [];
|
||||
private _bucketPos = nil;
|
||||
private _bucketList = nil;
|
||||
private _c = 0;
|
||||
while {count _nlos != count _excludes && {_c < (count _nlos)}} do {
|
||||
scopeName "mainSearch";
|
||||
{
|
||||
if(!(_forEachIndex in _excludes)) then {
|
||||
_index = _buckets pushBack [_x, [_x]];
|
||||
if (!(_forEachIndex in _excludes)) then {
|
||||
private _index = _buckets pushBack [_x, [_x]];
|
||||
_excludes pushBack _forEachIndex;
|
||||
_bucketPos = _x;
|
||||
_bucketList = (_buckets select _index) select 1;
|
||||
@ -63,59 +60,58 @@ if(_zIndex < 5) then {
|
||||
};
|
||||
} forEach _nlos;
|
||||
{
|
||||
if(!(_forEachIndex in _excludes)) then {
|
||||
if (!(_forEachIndex in _excludes)) then {
|
||||
_testPos = _x;
|
||||
if(_testPos vectorDistanceSqr _bucketPos <= 30) then {
|
||||
if (_testPos vectorDistanceSqr _bucketPos <= 30) then {
|
||||
_bucketList pushBack _x;
|
||||
_excludes pushBack _forEachIndex;
|
||||
};
|
||||
};
|
||||
} forEach _nlos;
|
||||
_c = _c + 1;
|
||||
INC(_c);
|
||||
};
|
||||
|
||||
// player sideChat format["c: %1", count _buckets];
|
||||
_explosions = [];
|
||||
// player sideChat format ["c: %1", count _buckets];
|
||||
private _explosions = [];
|
||||
{
|
||||
_blist = _x select 1;
|
||||
_avgX = 0;
|
||||
_avgY = 0;
|
||||
_avgZ = 0;
|
||||
private _blist = _x select 1;
|
||||
private _avgX = 0;
|
||||
private _avgY = 0;
|
||||
private _avgZ = 0;
|
||||
|
||||
{
|
||||
_avgX = _avgX + (_x select 0);
|
||||
_avgY = _avgY + (_x select 1);
|
||||
_avgZ = _avgZ + (_x select 2);
|
||||
ADD(_avgX,_x select 0);
|
||||
ADD(_avgY,_x select 1);
|
||||
ADD(_avgZ,_x select 2);
|
||||
} forEach _blist;
|
||||
_c = count _blist;
|
||||
_bpos = [_avgX/_c, _avgY/_c, _avgZ/_c];
|
||||
private _bpos = [_avgX / _c, _avgY / _c, _avgZ / _c];
|
||||
|
||||
_distance = _pos vectorDistance _bpos;
|
||||
_hitFactor = 1-(((_distance/(_indirectHitRange*4)) min 1) max 0);
|
||||
// _hitFactor = 1/(_distance^2);
|
||||
_hit = _indirectHit*_hitFactor;
|
||||
_hit = (floor (_hit/4)) min 500;
|
||||
_hit = _hit - (_hit%10);
|
||||
_range = (floor (_indirectHitRange-(_distance/4))) min 100;
|
||||
_range = _range - (_range%2);
|
||||
private _distance = _pos vectorDistance _bpos;
|
||||
private _hitFactor = 1 - (((_distance / (_indirectHitRange * 4)) min 1) max 0);
|
||||
// _hitFactor = 1 / (_distance ^ 2);
|
||||
private _hit = _indirectHit * _hitFactor;
|
||||
_hit = (floor (_hit / 4)) min 500;
|
||||
SUB(_hit,_hit % 10);
|
||||
private _range = (floor (_indirectHitRange - (_distance / 4))) min 100;
|
||||
SUB(_range,_range % 2);
|
||||
|
||||
if(_hit >= 10 && _range > 0) then {
|
||||
// TEST_ICONS pushBack [_bpos, format["h: %1, r: %2, hf: %3 d: %4 ihr: %5", _hit, _range, _hitFactor, _distance, _indirectHitRange*4]];
|
||||
if (_hit >= 10 && {_range > 0}) then {
|
||||
// TEST_ICONS pushBack [_bpos, format ["h: %1, r: %2, hf: %3 d: %4 ihr: %5", _hit, _range, _hitFactor, _distance, _indirectHitRange*4]];
|
||||
// TEST_PAIRS pushBack [_pos, _bpos, [1,0,0,1]];
|
||||
_refExp = format["ace_explosion_reflection_%1_%2", _range, _hit];
|
||||
private _refExp = format ["ace_explosion_reflection_%1_%2", _range, _hit];
|
||||
// _refExp createVehicle (ASLtoATL _bpos);
|
||||
// drop ["\a3\data_f\Cl_basic","","Billboard",1,15,ASLtoATL _bpos,[0,0,0],1,1.275,1.0,0.0,[1],[[1,0,0,1]],[0],0.0,2.0,"","",""];
|
||||
|
||||
_explosions pushBack [_refExp, _bpos, _hit, _distance, _indirectHitRange/4, _depth];
|
||||
|
||||
_explosions pushBack [_refExp, _bpos, _hit, _distance, _indirectHitRange / 4, _depth];
|
||||
};
|
||||
if(count _explosions > (_radi*2)/_depth) exitWith {};
|
||||
if (count _explosions > (_radi * 2) / _depth) exitWith {};
|
||||
} forEach _buckets;
|
||||
// _can = "Land_Bricks_V4_F" createVehicle (ASLtoATL _pos);
|
||||
// _dirvec = _pos vectorFromTo ((ATLtoASL (player modelToWorldVisual (player selectionPosition "Spine3"))));
|
||||
// _dirvec = _dirvec vectorMultiply 100;
|
||||
// _can setVelocity _dirvec;
|
||||
[DFUNC(doExplosions), 0, [_explosions, 0]] call CBA_fnc_addPerFrameHandler;
|
||||
[(_this select 1)] call CBA_fnc_removePerFrameHandler;
|
||||
[_pfhID] call CBA_fnc_removePerFrameHandler;
|
||||
};
|
||||
END_COUNTER(fnc_findReflections);
|
||||
|
@ -42,7 +42,7 @@ if (isNil "_shouldAdd") then {
|
||||
private _explosive = getNumber (configFile >> "CfgAmmo" >> _ammo >> "explosive");
|
||||
private _indirectRange = getNumber (configFile >> "CfgAmmo" >> _ammo >> "indirectHitRange");
|
||||
private _force = getNumber (configFile >> "CfgAmmo" >> _ammo >> QGVAR(force));
|
||||
private _fragPower = getNumber(configFile >> "CfgAmmo" >> _ammo >> "indirecthit")*(sqrt((getNumber (configFile >> "CfgAmmo" >> _ammo >> "indirectHitRange"))));
|
||||
private _fragPower = getNumber (configFile >> "CfgAmmo" >> _ammo >> "indirecthit") * (sqrt (getNumber (configFile >> "CfgAmmo" >> _ammo >> "indirectHitRange")));
|
||||
|
||||
_shouldAdd = (_skip == 0) && {(_force == 1) || {_explosive > 0.5 && {_indirectRange >= 4.5} && {_fragPower >= 35}}};
|
||||
TRACE_6("SettingCache[willFrag?]",_skip,_explosive,_indirectRange,_force,_fragPower,_shouldAdd);
|
||||
|
@ -6,44 +6,36 @@
|
||||
|
||||
#define MAX_FRAG_COUNT 50
|
||||
|
||||
if(!isServer) exitWith { };
|
||||
if (!isServer) exitWith {};
|
||||
|
||||
BEGIN_COUNTER(frago);
|
||||
// _startTime = diag_tickTime;
|
||||
|
||||
private ["_fuseDist", "_indirectHitRange", "_fragRange", "_c", "_m", "_k", "_gC", "_fragPower", "_fragPowerRandom", "_manObjects", "_objects", "_crew", "_fragCount", "_fragArcs", "_doRandom", "_boundingBox", "_targetPos", "_distance", "_add", "_bbX", "_bbY", "_bbZ", "_cubic", "_targetVel", "_baseVec", "_dir", "_currentCount", "_count", "_vecVar", "_vec", "_fp", "_vel", "_fragType", "_fragObj", "_randomCount", "_sectorSize", "_sectorOffset", "_i", "_randomDir", "_endTime", "_target"];
|
||||
|
||||
params ["_round", "_lastPos", "_lastVel", "_shellType"];
|
||||
private _gun = nil;
|
||||
if((count _this) > 5) then {
|
||||
_gun = _this select 5;
|
||||
};
|
||||
params ["_round", "_lastPos", "_lastVel", "_shellType", "_firedFrame", "_gun"];
|
||||
|
||||
private _fragTypes = [
|
||||
QGVAR(tiny), QGVAR(tiny), QGVAR(tiny),
|
||||
QGVAR(tiny_HD), QGVAR(tiny_HD), QGVAR(tiny_HD),
|
||||
QGVAR(small),QGVAR(small),QGVAR(small),QGVAR(small),
|
||||
QGVAR(small_HD),QGVAR(small_HD),QGVAR(small_HD),QGVAR(small_HD),
|
||||
QGVAR(small), QGVAR(small), QGVAR(small), QGVAR(small),
|
||||
QGVAR(small_HD), QGVAR(small_HD), QGVAR(small_HD), QGVAR(small_HD),
|
||||
QGVAR(medium_HD), QGVAR(medium_HD), QGVAR(medium_HD), QGVAR(medium_HD), QGVAR(medium_HD)
|
||||
];
|
||||
|
||||
private _warn = false;
|
||||
if(isArray (configFile >> "CfgAmmo" >> _shellType >> QGVAR(CLASSES))) then {
|
||||
if (isArray (configFile >> "CfgAmmo" >> _shellType >> QGVAR(CLASSES))) then {
|
||||
_fragTypes = getArray (configFile >> "CfgAmmo" >> _shellType >> QGVAR(CLASSES));
|
||||
} else {
|
||||
_warn = true;
|
||||
};
|
||||
|
||||
private _atlPos = ASLtoATL _lastPos;
|
||||
|
||||
private _isArmed = true;
|
||||
if(!isNil "_gun") then {
|
||||
_fuseDist = getNumber(configFile >> "CfgAmmo" >> _shellType >> "fuseDistance");
|
||||
if (!isNil "_gun") then {
|
||||
private _fuseDist = getNumber(configFile >> "CfgAmmo" >> _shellType >> "fuseDistance");
|
||||
_isArmed = ((getPosASL _gun) distance _lastPos > _fuseDist);
|
||||
};
|
||||
|
||||
_indirectHitRange = getNumber(configFile >> "CfgAmmo" >> _shellType >> "indirecthitrange");
|
||||
_fragRange = 20 * _indirectHitRange * 4;
|
||||
private _indirectHitRange = getNumber(configFile >> "CfgAmmo" >> _shellType >> "indirecthitrange");
|
||||
private _fragRange = 20 * _indirectHitRange * 4;
|
||||
// _c = 185; // grams of comp-b
|
||||
// _m = 210; // grams of fragmentating metal
|
||||
// _k = 3/5; // spherical K factor
|
||||
@ -54,26 +46,27 @@ _fragRange = 20 * _indirectHitRange * 4;
|
||||
// _k = 1/2; // spherical K factor
|
||||
// _gC = 2320; // Gurney constant of tritonal in /ms
|
||||
|
||||
private _c = getNumber (configFile >> "CfgAmmo" >> _shellType >> QGVAR(CHARGE));
|
||||
if (_c == 0) then {_c = 1; _warn = true;};
|
||||
private _m = getNumber (configFile >> "CfgAmmo" >> _shellType >> QGVAR(METAL));
|
||||
if (_m == 0) then {_m = 2; _warn = true;};
|
||||
private _k = getNumber (configFile >> "CfgAmmo" >> _shellType >> QGVAR(GURNEY_K));
|
||||
if (_k == 0) then {_k = 0.5; _warn = true;};
|
||||
private _gC = getNumber (configFile >> "CfgAmmo" >> _shellType >> QGVAR(GURNEY_C));
|
||||
if (_gC == 0) then {_gC = 2440; _warn = true;};
|
||||
|
||||
_c = getNumber(configFile >> "CfgAmmo" >> _shellType >> QGVAR(CHARGE));
|
||||
if(_c == 0) then { _c = 1; _warn = true;};
|
||||
_m = getNumber(configFile >> "CfgAmmo" >> _shellType >> QGVAR(METAL));
|
||||
if(_m == 0) then { _m = 2; _warn = true;};
|
||||
_k = getNumber(configFile >> "CfgAmmo" >> _shellType >> QGVAR(GURNEY_K));
|
||||
if(_k == 0) then { _k = 1/2; _warn = true;};
|
||||
_gC = getNumber(configFile >> "CfgAmmo" >> _shellType >> QGVAR(GURNEY_C));
|
||||
if(_gC == 0) then { _gC = 2440; _warn = true;};
|
||||
|
||||
if(_warn) then {
|
||||
if (_warn) then {
|
||||
WARNING_1("Ammo class %1 lacks proper explosive properties definitions for frag!",_shellType); //TODO: turn this off when we get closer to release
|
||||
};
|
||||
|
||||
_fragPower = (((_m/_c)+_k)^-(1/2))*_gC;
|
||||
private _fragPower = (((_m / _c) + _k) ^ - (1 / 2)) * _gC;
|
||||
_fragPower = _fragPower * 0.8; // Gunery equation is for a non-fragmenting metal, imperical value of 80% represents fragmentation
|
||||
|
||||
_fragPowerRandom = _fragPower * 0.5;
|
||||
if((_atlPos select 2) < 0.5) then {
|
||||
_lastPos set[2, (_lastPos select 2)+0.5];
|
||||
private _atlPos = ASLtoATL _lastPos;
|
||||
|
||||
private _fragPowerRandom = _fragPower * 0.5;
|
||||
if ((_atlPos select 2) < 0.5) then {
|
||||
_lastPos set [2, (_lastPos select 2) + 0.5];
|
||||
};
|
||||
|
||||
// _manObjects = _atlPos nearEntities ["CaManBase", _fragRange];
|
||||
@ -81,134 +74,130 @@ if((_atlPos select 2) < 0.5) then {
|
||||
// setAccTime 0.01;
|
||||
|
||||
//_objects = nearestObjects [_atlPos, ["AllVehicles"], _fragRange]; // Not sure if tracking "ReammoBox" is required, if so revert this change for _objects
|
||||
_objects = _atlPos nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], _fragRange];
|
||||
private _objects = _atlPos nearEntities [["Car", "Motorcycle", "Tank", "StaticWeapon", "CAManBase", "Air", "Ship"], _fragRange];
|
||||
|
||||
// _objects = _manObjects;
|
||||
// Target also people inside vehicles or manning weapons
|
||||
_crew = [];
|
||||
// Add unique crews in faster way
|
||||
{
|
||||
{
|
||||
_crew set [count _crew,_x]
|
||||
_objects pushBackUnique _x;
|
||||
} forEach (crew _x);
|
||||
} forEach _objects;
|
||||
|
||||
_objects = _objects - _crew;
|
||||
_objects = _objects + _crew;
|
||||
private _fragCount = 0;
|
||||
|
||||
_fragCount = 0;
|
||||
|
||||
_fragArcs = [];
|
||||
_fragArcs set[360, 0];
|
||||
private _fragArcs = [];
|
||||
_fragArcs set [360, 0];
|
||||
|
||||
#ifdef DEBUG_MODE_FULL
|
||||
ACE_player sideChat format["_fragRange: %1", _fragRange];
|
||||
ACE_player sideChat format["_objects: %1", _objects];
|
||||
ACE_player sideChat format ["_fragRange: %1", _fragRange];
|
||||
ACE_player sideChat format ["_objects: %1", _objects];
|
||||
#endif
|
||||
_doRandom = true;
|
||||
if(_isArmed && (count _objects) > 0) then {
|
||||
|
||||
private _doRandom = true;
|
||||
if (_isArmed && {!(_objects isEqualTo [])}) then {
|
||||
if (GVAR(ReflectionsEnabled)) then {
|
||||
[_lastPos, _shellType] call FUNC(doReflections);
|
||||
};
|
||||
{
|
||||
//if(random(1) > 0.5) then {
|
||||
_target = _x;
|
||||
if(alive _target) then {
|
||||
_boundingBox = boundingBox _target;
|
||||
_targetPos = (getPosASL _target);
|
||||
_distance = _targetPos distance _lastPos;
|
||||
_add = (((_boundingBox select 1) select 2)/2)+((((_distance-(_fragpower/8)) max 0)/_fragPower)*10);
|
||||
_bbX = (abs((_boundingBox select 0) select 0))+((_boundingBox select 1) select 0);
|
||||
_bbY = (abs((_boundingBox select 0) select 1))+((_boundingBox select 1) select 1);
|
||||
_bbZ = (abs((_boundingBox select 0) select 2))+((_boundingBox select 1) select 2);
|
||||
_cubic = _bbX * _bbY * _bbZ;
|
||||
if(_cubic > 1) then {
|
||||
//if (random(1) > 0.5) then {
|
||||
private _target = _x;
|
||||
if (alive _target) then {
|
||||
private _boundingBox = boundingBox _target;
|
||||
private _targetPos = getPosASL _target;
|
||||
private _distance = _targetPos distance _lastPos;
|
||||
private _add = (((_boundingBox select 1) select 2) / 2) + ((((_distance - (_fragpower / 8)) max 0) / _fragPower) * 10);
|
||||
private _bbX = (abs ((_boundingBox select 0) select 0)) + ((_boundingBox select 1) select 0);
|
||||
private _bbY = (abs ((_boundingBox select 0) select 1)) + ((_boundingBox select 1) select 1);
|
||||
private _bbZ = (abs ((_boundingBox select 0) select 2)) + ((_boundingBox select 1) select 2);
|
||||
private _cubic = _bbX * _bbY * _bbZ;
|
||||
if (_cubic > 1) then {
|
||||
_doRandom = true;
|
||||
|
||||
_targetVel = (velocity _target);
|
||||
private _targetVel = velocity _target;
|
||||
|
||||
_targetPos = _targetPos vectorAdd [
|
||||
(_targetVel select 0) * (_distance / _fragPower),
|
||||
(_targetVel select 1) * (_distance / _fragPower),
|
||||
_add
|
||||
];
|
||||
|
||||
_targetPos set[0, (_targetPos select 0)+((_targetVel select 0)*(_distance/_fragPower))];
|
||||
_targetPos set[1, (_targetPos select 1)+((_targetVel select 1)*(_distance/_fragPower))];
|
||||
_targetPos set[2, (_targetPos select 2)+_add];
|
||||
private _baseVec = _lastPos vectorFromTo _targetPos;
|
||||
|
||||
_baseVec = _lastPos vectorFromTo _targetPos;
|
||||
|
||||
_dir = floor(_baseVec call CBA_fnc_vectDir);
|
||||
_currentCount = _fragArcs select _dir;
|
||||
if(isNil "_currentCount") then {
|
||||
_currentCount = 0;
|
||||
};
|
||||
if(_currentCount < 20) then {
|
||||
_count = ceil(random(sqrt(_m/1000)));
|
||||
_vecVar = FRAG_VEC_VAR;
|
||||
if(!(_target isKindOf "Man")) then {
|
||||
_vecVar = ((sqrt _cubic)/2000)+FRAG_VEC_VAR;
|
||||
if((count (crew _target)) == 0 && _count > 0) then {
|
||||
_count = 0 max (_count/2);
|
||||
private _dir = floor (_baseVec call CBA_fnc_vectDir);
|
||||
private _currentCount = _fragArcs select _dir;
|
||||
ISNILS(_currentCount,0);
|
||||
if (_currentCount < 20) then {
|
||||
private _count = ceil (random (sqrt (_m / 1000)));
|
||||
private _vecVar = FRAG_VEC_VAR;
|
||||
if (!(_target isKindOf "Man")) then {
|
||||
_vecVar = ((sqrt _cubic) / 2000) + FRAG_VEC_VAR;
|
||||
if ((crew _target) isEqualTo [] && {_count > 0}) then {
|
||||
_count = 0 max (_count / 2);
|
||||
};
|
||||
};
|
||||
for "_i" from 1 to _count do {
|
||||
_vec = +_baseVec;
|
||||
private _vec = _baseVec vectorDiff [
|
||||
(_vecVar / 2) + (random _vecVar),
|
||||
(_vecVar / 2) + (random _vecVar),
|
||||
(_vecVar / 2) + (random _vecVar)
|
||||
];
|
||||
|
||||
_vec set[0, (_vec select 0)-(_vecVar/2)+(random _vecVar)];
|
||||
_vec set[1, (_vec select 1)-(_vecVar/2)+(random _vecVar)];
|
||||
_vec set[2, (_vec select 2)-(_vecVar/2)+(random _vecVar)];
|
||||
private _fp = _fragPower - (random (_fragPowerRandom));
|
||||
private _vel = _vec vectorMultiply _fp;
|
||||
|
||||
_fp = (_fragPower-(random (_fragPowerRandom)));
|
||||
_vel = _vec vectorMultiply _fp;
|
||||
|
||||
_fragType = round (random ((count _fragTypes)-1));
|
||||
_fragObj = (_fragTypes select _fragType) createVehicleLocal [0,0,10000];
|
||||
// diag_log text format["fp: %1 %2", _fp, typeOf _fragObj];
|
||||
private _fragType = round (random ((count _fragTypes) - 1));
|
||||
private _fragObj = (_fragTypes select _fragType) createVehicleLocal [0,0,10000];
|
||||
// diag_log text format ["fp: %1 %2", _fp, typeOf _fragObj];
|
||||
_fragObj setPosASL _lastPos;
|
||||
_fragObj setVectorDir _vec;
|
||||
_fragObj setVelocity _vel;
|
||||
if(GVAR(traceFrags)) then {
|
||||
GVAR(TOTALFRAGS) = GVAR(TOTALFRAGS) + 1;
|
||||
if (GVAR(traceFrags)) then {
|
||||
INC(GVAR(totalFrags));
|
||||
[ACE_player, _fragObj, [1,0,0,1]] call FUNC(addTrack);
|
||||
};
|
||||
_fragCount = _fragCount + 1;
|
||||
_currentCount = _currentCount + 1;
|
||||
INC(_fragCount);
|
||||
INC(_currentCount);
|
||||
};
|
||||
_fragArcs set[_dir, _currentCount];
|
||||
_fragArcs set [_dir, _currentCount];
|
||||
};
|
||||
};
|
||||
};
|
||||
//};
|
||||
if(_fragCount > MAX_FRAG_COUNT) exitWith {};
|
||||
if (_fragCount > MAX_FRAG_COUNT) exitWith {};
|
||||
} forEach _objects;
|
||||
if(_fragCount > MAX_FRAG_COUNT) exitWith {};
|
||||
_randomCount = ((ceil((MAX_FRAG_COUNT - _fragCount)*0.1)) max 0)+20;
|
||||
_sectorSize = 360 / (_randomCount max 1);
|
||||
if (_fragCount > MAX_FRAG_COUNT) exitWith {};
|
||||
private _randomCount = ((ceil ((MAX_FRAG_COUNT - _fragCount) * 0.1)) max 0) + 20;
|
||||
private _sectorSize = 360 / (_randomCount max 1);
|
||||
// _doRandom = false;
|
||||
if(_doRandom) then {
|
||||
if (_doRandom) then {
|
||||
for "_i" from 1 to _randomCount do {
|
||||
// Distribute evenly
|
||||
_sectorOffset = 360 * (_i - 1) / (_randomCount max 1);
|
||||
_randomDir = random(_sectorSize);
|
||||
_vec = [cos(_sectorOffset + _randomDir), sin(_sectorOffset + _randomDir), sin(30 - (random 45))];
|
||||
private _sectorOffset = 360 * (_i - 1) / (_randomCount max 1);
|
||||
private _randomDir = random (_sectorSize);
|
||||
_vec = [cos (_sectorOffset + _randomDir), sin (_sectorOffset + _randomDir), sin (30 - (random 45))];
|
||||
|
||||
_fp = (_fragPower-(random (_fragPowerRandom)));
|
||||
_fp = (_fragPower - (random (_fragPowerRandom)));
|
||||
|
||||
_vel = _vec vectorMultiply _fp;
|
||||
|
||||
_fragType = round (random ((count _fragTypes)-1));
|
||||
_fragObj = (_fragTypes select _fragType) createVehicleLocal [0,0,10000];
|
||||
_fragType = round (random ((count _fragTypes) - 1));
|
||||
_fragObj = (_fragTypes select _fragType) createVehicleLocal [0, 0, 10000];
|
||||
_fragObj setPosASL _lastPos;
|
||||
_fragObj setVectorDir _vec;
|
||||
_fragObj setVelocity _vel;
|
||||
|
||||
if(GVAR(traceFrags)) then {
|
||||
GVAR(TOTALFRAGS) = GVAR(TOTALFRAGS) + 1;
|
||||
if (GVAR(traceFrags)) then {
|
||||
INC(GVAR(totalFrags));
|
||||
[ACE_player, _fragObj, [1,0.5,0,1]] call FUNC(addTrack);
|
||||
};
|
||||
_fragCount = _fragCount + 1;
|
||||
INC(_fragCount);
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
// #ifdef DEBUG_MODE_FULL
|
||||
// ACE_player sideChat format["total frags: %1", GVAR(TOTALFRAGS)];
|
||||
// ACE_player sideChat format["total frags: %1", GVAR(totalFrags)];
|
||||
// ACE_player sideChat format["tracks: %1", (count GVAR(trackedObjects))];
|
||||
// #endif
|
||||
// _endTime = diag_tickTime;
|
||||
|
@ -15,36 +15,35 @@
|
||||
|
||||
if (!GVAR(enabled)) exitWith {};
|
||||
|
||||
private ["_gcIndex", "_iter"];
|
||||
_gcIndex = [];
|
||||
private _gcIndex = [];
|
||||
|
||||
_iter = 0;
|
||||
while { (count GVAR(objects)) > 0 && { _iter < (GVAR(MaxTrackPerFrame) min (count GVAR(objects))) } } do {
|
||||
private ["_object", "_args"];
|
||||
if(GVAR(lastIterationIndex) >= (count GVAR(objects))) then {
|
||||
private _iter = 0;
|
||||
private _objectCount = count GVAR(objects);
|
||||
while {_objectCount > 0 && {_iter < (GVAR(MaxTrackPerFrame) min _objectCount)}} do {
|
||||
|
||||
if (GVAR(lastIterationIndex) >= _objectCount) then {
|
||||
GVAR(lastIterationIndex) = 0;
|
||||
};
|
||||
_object = GVAR(objects) select GVAR(lastIterationIndex);
|
||||
private _object = GVAR(objects) select GVAR(lastIterationIndex);
|
||||
|
||||
if(!isNil "_object") then {
|
||||
_args = GVAR(arguments) select GVAR(lastIterationIndex);
|
||||
if (!isNil "_object") then {
|
||||
private _args = GVAR(arguments) select GVAR(lastIterationIndex);
|
||||
|
||||
if(!(_args call FUNC(pfhRound))) then {
|
||||
_gcIndex pushBack GVAR(lastIterationIndex); // Add it to the GC if it returns false
|
||||
if (!(_args call FUNC(pfhRound))) then {
|
||||
_gcIndex pushBack GVAR(lastIterationIndex); // Add it to the GC if it returns false
|
||||
};
|
||||
};
|
||||
_iter = _iter + 1;
|
||||
GVAR(lastIterationIndex) = GVAR(lastIterationIndex) + 1;
|
||||
INC(_iter);
|
||||
INC(GVAR(lastIterationIndex));
|
||||
};
|
||||
|
||||
// clean up dead object references
|
||||
private ["_deletionCount", "_deleteIndex"];
|
||||
_deletionCount = 0;
|
||||
// Clean up dead object references
|
||||
private _deletionCount = 0;
|
||||
{
|
||||
TRACE_1("GC Projectile", _x);
|
||||
_deleteIndex = _x - _deletionCount;
|
||||
private _deleteIndex = _x - _deletionCount;
|
||||
GVAR(objects) deleteAt _deleteIndex;
|
||||
GVAR(arguments) deleteAt _deleteIndex;
|
||||
|
||||
_deletionCount = _deletionCount + 1;
|
||||
INC(_deletionCount);
|
||||
} forEach _gcIndex;
|
||||
|
@ -1,26 +1,26 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_round", "_lastPos", "_lastVel", "_type", "_firedFrame", "", "_doSpall", "_spallTrack", "_foundObjectHPIds", "_skip", "_explosive", "_indirectRange", "_force", "_fragPower"];
|
||||
params ["_round", "_lastPos", "_lastVel", "_type", "_firedFrame", "_gun", "_doSpall", "_spallTrack", "_foundObjectHPIds", "_skip", "_explosive", "_indirectRange", "_force", "_fragPower"];
|
||||
|
||||
if(_round in GVAR(blackList)) exitWith {
|
||||
if (_round in GVAR(blackList)) exitWith {
|
||||
false
|
||||
};
|
||||
|
||||
if (!alive _round) exitWith {
|
||||
if((diag_frameno - _firedFrame) > 1) then { //skip if deleted within a single frame
|
||||
if(_skip == 0) then {
|
||||
if((_explosive > 0.5 && {_indirectRange >= 4.5} && {_fragPower >= 35}) || {_force == 1} ) then {
|
||||
if ((diag_frameno - _firedFrame) > 1) then { //skip if deleted within a single frame
|
||||
if (_skip == 0) then {
|
||||
if ((_explosive > 0.5 && {_indirectRange >= 4.5} && {_fragPower >= 35}) || {_force == 1}) then {
|
||||
// shotbullet, shotShell don't seem to explode when touching water, so don't create frags
|
||||
if (((_lastPos select 2) < 0) && {(toLower getText (configFile >> "CfgAmmo" >> _type >> "simulation")) in ["shotbullet", "shotshell"]}) exitWith {};
|
||||
[QGVAR(frag_eh), _this] call CBA_fnc_serverEvent;
|
||||
};
|
||||
};
|
||||
};
|
||||
if(_doSpall) then {
|
||||
GVAR(spallIsTrackingCount) = GVAR(spallIsTrackingCount) - 1;
|
||||
// diag_log text format["F: %1", _foundObjectHPIds];
|
||||
if (_doSpall) then {
|
||||
DEC(GVAR(spallIsTrackingCount));
|
||||
// diag_log text format ["F: %1", _foundObjectHPIds];
|
||||
{
|
||||
if(!isNil "_x") then {
|
||||
if (!isNil "_x") then {
|
||||
_x removeEventHandler ["hitPart", _foundObjectHPIds select _forEachIndex];
|
||||
};
|
||||
} forEach _spallTrack;
|
||||
@ -28,12 +28,12 @@ if (!alive _round) exitWith {
|
||||
false
|
||||
};
|
||||
|
||||
_this set[1, (getPosASL _round)];
|
||||
_this set[2, (velocity _round)];
|
||||
_this set [1, getPosASL _round];
|
||||
_this set [2, velocity _round];
|
||||
|
||||
if(_doSpall) then {
|
||||
if (_doSpall) then {
|
||||
private ["_scale"];
|
||||
_scale = ( (count GVAR(objects)) / GVAR(MaxTrackPerFrame) ) max 0.1;
|
||||
_scale = ((count GVAR(objects)) / GVAR(MaxTrackPerFrame)) max 0.1;
|
||||
[_round, _scale, _spallTrack, _foundObjectHPIds] call FUNC(spallTrack);
|
||||
};
|
||||
|
||||
|
@ -4,8 +4,8 @@
|
||||
|
||||
PARAMS_1(_round);
|
||||
|
||||
if(_round in GVAR(blackList)) then {
|
||||
GVAR(blackList) = GVAR(blackList) - [_round];
|
||||
if (_round in GVAR(blackList)) then {
|
||||
REM(GVAR(blackList),_round);
|
||||
};
|
||||
|
||||
GVAR(objects) = GVAR(objects) - [_round];
|
||||
REM(GVAR(objects),_round);
|
||||
|
@ -1,12 +1,11 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_ret"];
|
||||
_ret = true;
|
||||
if(IS_ARRAY((_this select 0))) then {
|
||||
private _ret = true;
|
||||
if (IS_ARRAY(_this select 0)) then {
|
||||
_ret = false;
|
||||
} else {
|
||||
if((_this select 0) in GVAR(trackedObjects)) then {
|
||||
GVAR(trackedObjects) = GVAR(trackedObjects) - [(_this select 0)];
|
||||
if ((_this select 0) in GVAR(trackedObjects)) then {
|
||||
REM(GVAR(trackedObjects),_this select 0);
|
||||
} else {
|
||||
_ret = false;
|
||||
};
|
||||
|
@ -1,29 +1,27 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_initialData", "_hpData", "_round", "_hpRound", "_hpDirect"];
|
||||
//player sideChat format["f: %1 c: %2", (_this select 0), (count GVAR(spallHPData))];
|
||||
//player sideChat format ["f: %1 c: %2", (_this select 0), (count GVAR(spallHPData))];
|
||||
|
||||
if ((_this select 0) <= (count GVAR(spallHPData))) then {
|
||||
_initialData = GVAR(spallHPData) select (_this select 0);
|
||||
if (!isNil "_initialData") then {
|
||||
_hpRound = ((_this select 1) select 0) select 2;
|
||||
_round = _initialData select 3;
|
||||
_hpDirect = ((_this select 1) select 0) select 10;
|
||||
if (_hpDirect && {_round == _hpRound}) then {
|
||||
{
|
||||
_hpData = _x;
|
||||
_round = _initialData select 3;
|
||||
// diag_log text format["HPDUMP-------------------------------------"];
|
||||
// {
|
||||
// _hp = _x;
|
||||
// diag_log text format["%1 --", _forEachIndex];
|
||||
// {
|
||||
// diag_log text format["%1: %2", _forEachIndex, _x];
|
||||
// } forEach _hp;
|
||||
// } forEach (_this select 1);
|
||||
[DFUNC(doSpall), [_this, _forEachIndex]] call CBA_fnc_execNextFrame;
|
||||
// player sideChat "WEEE";
|
||||
} forEach (_this select 1);
|
||||
};
|
||||
};
|
||||
params ["_index", "_hitPartData"];
|
||||
|
||||
private _initialData = GVAR(spallHPData) param [_index, []];
|
||||
if (_initialData isEqualTo []) exitWith {};
|
||||
|
||||
private _hpRound = (_hitPartData select 0) select 2;
|
||||
private _round = _initialData select 3;
|
||||
private _hpDirect = (_hitPartData select 0) select 10;
|
||||
|
||||
if (_hpDirect && {_round == _hpRound}) then {
|
||||
{
|
||||
// diag_log text format ["HPDUMP-------------------------------------"];
|
||||
// {
|
||||
// _hp = _x;
|
||||
// diag_log text format ["%1 --", _forEachIndex];
|
||||
// {
|
||||
// diag_log text format ["%1: %2", _forEachIndex, _x];
|
||||
// } forEach _hp;
|
||||
// } forEach (_this select 1);
|
||||
[DFUNC(doSpall), [_this, _forEachIndex]] call CBA_fnc_execNextFrame;
|
||||
// player sideChat "WEEE";
|
||||
} forEach _hitPartData;
|
||||
};
|
||||
|
@ -3,7 +3,7 @@
|
||||
|
||||
params ["_round", "_multiplier", "_foundObjects", "_foundObjectHPIds"];
|
||||
|
||||
private _delta = (1/diag_fps) * _multiplier;
|
||||
private _delta = (1 / diag_fps) * _multiplier;
|
||||
private _curPos = getPosASL _round;
|
||||
private _velocity = velocity _round;
|
||||
|
||||
@ -12,17 +12,15 @@ private _forwardPos = _curPos vectorAdd _velocityStep;
|
||||
|
||||
private _intersectsWith = lineIntersectsWith [_curPos, _forwardPos];
|
||||
|
||||
if (count _intersectsWith > 0) then {
|
||||
// player sideChat format["inter: %1", _intersectsWith];
|
||||
{
|
||||
if(!(_x in _foundObjects)) then {
|
||||
// diag_log text format["Adding HP: %1", _x];
|
||||
private _index = count GVAR(spallHPData);
|
||||
private _hpId = _x addEventHandler ["hitPart", compile format["[%1, _this] call " + QFUNC(spallHP), _index]];
|
||||
_foundObjects set[(count _foundObjects), _x];
|
||||
_foundObjectHPIds set[(count _foundObjectHPIds), _hpId];
|
||||
private _data = [_hpId, _x, typeOf _round, _round, _curPos, _velocity, 0, _foundObjects, _foundObjectHPIds];
|
||||
GVAR(spallHPData) set[_index, _data];
|
||||
};
|
||||
} forEach _intersectsWith;
|
||||
};
|
||||
if (_intersectsWith isEqualTo []) exitWith {};
|
||||
|
||||
// player sideChat format ["inter: %1", _intersectsWith];
|
||||
{
|
||||
// diag_log text format ["Adding HP: %1", _x];
|
||||
private _index = count GVAR(spallHPData);
|
||||
private _hpId = _x addEventHandler ["hitPart", compile format ["[%1, _this] call " + QFUNC(spallHP), _index]];
|
||||
_foundObjects pushBack _x;
|
||||
_foundObjectHPIds pushBack _hpId;
|
||||
private _data = [_hpId, _x, typeOf _round, _round, _curPos, _velocity, 0, _foundObjects, _foundObjectHPIds];
|
||||
GVAR(spallHPData) pushBack _data;
|
||||
} forEach (_intersectsWith select {!(_x in _foundObjects)});
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "script_component.hpp"
|
||||
if(!GVAR(tracesStarted)) then {
|
||||
GVAR(tracesStarted) = true;
|
||||
GVAR(traceID) = [FUNC(drawTraces), 0, []] call CBA_fnc_addPerFrameHandler;
|
||||
};
|
||||
|
||||
if (GVAR(tracesStarted)) exitWith {};
|
||||
GVAR(tracesStarted) = true;
|
||||
GVAR(traceID) = [FUNC(drawTraces)] call CBA_fnc_addPerFrameHandler;
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "script_component.hpp"
|
||||
if(GVAR(tracesStarted)) then {
|
||||
GVAR(tracesStarted) = false;
|
||||
[GVAR(traceID)] call CBA_fnc_removePerFrameHandler;
|
||||
};
|
||||
|
||||
if (!GVAR(tracesStarted)) exitWith {};
|
||||
GVAR(tracesStarted) = false;
|
||||
[GVAR(traceID)] call CBA_fnc_removePerFrameHandler;
|
||||
|
@ -1,12 +1,12 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_args"];
|
||||
params ["_args", "_pfhID"];
|
||||
_args params ["_tracerObj", "_index"];
|
||||
|
||||
if (alive _tracerObj && (count GVAR(traces)) > 0) then {
|
||||
if (alive _tracerObj && {!(GVAR(traces) isEqualTo [])}) then {
|
||||
private _data = GVAR(traces) select _index;
|
||||
private _positions = _data select 4;
|
||||
_positions pushBack [(getPos _tracerObj), vectorMagnitude (velocity _tracerObj)];
|
||||
_positions pushBack [getPos _tracerObj, vectorMagnitude (velocity _tracerObj)];
|
||||
} else {
|
||||
[(_this select 1)] call CBA_fnc_removePerFrameHandler;
|
||||
[_pfhID] call CBA_fnc_removePerFrameHandler;
|
||||
};
|
||||
|
@ -1 +1 @@
|
||||
#include "\z\ace\addons\frag\script_component.hpp"
|
||||
#include "\z\ace\addons\frag\script_component.hpp"
|
||||
|
@ -17,4 +17,4 @@
|
||||
|
||||
#include "\z\ace\addons\main\script_macros.hpp"
|
||||
|
||||
#define ACE_TRACE_DRAW_INC 1
|
||||
#define ACE_TRACE_DRAW_INC 1
|
||||
|
@ -167,4 +167,4 @@
|
||||
<Japanese>(SP のみ) ミッションとエディタの再起動が必要です。有効化すると、シングルプレイでのみ破片と剥離の弾頭が見えるようになります。</Japanese>
|
||||
</Key>
|
||||
</Package>
|
||||
</Project>
|
||||
</Project>
|
||||
|
@ -23,6 +23,6 @@ if (_unit == ACE_player) then {
|
||||
addCamShake [4, 0.5, 5];
|
||||
};
|
||||
|
||||
[_unit, "PutDown"] call EFUNC(common,doGesture);
|
||||
[_unit, "gesturePoint"] call EFUNC(common,doGesture);
|
||||
|
||||
[QGVAR(tapShoulder), [_target, _shoulderNum], [_target]] call CBA_fnc_targetEvent;
|
||||
|
@ -1,14 +1,11 @@
|
||||
|
||||
class RscOpticsValue;
|
||||
class RscControlsGroup;
|
||||
class RscControlsGroupNoScrollbars;
|
||||
class RscPicture;
|
||||
class RscMapControl;
|
||||
class VScrollbar;
|
||||
class HScrollbar;
|
||||
class RscLine;
|
||||
|
||||
|
||||
// Taken from AGM for optics management.
|
||||
|
||||
class RscInGameUI {
|
||||
class ACE_RscOptics_javelin {
|
||||
idd = 300;
|
||||
@ -16,24 +13,13 @@ class RscInGameUI {
|
||||
onLoad = QUOTE(_this call FUNC(onOpticLoad));
|
||||
onUnload = QUOTE(_this call FUNC(onOpticUnload));
|
||||
|
||||
class GVAR(elements_group): RscControlsGroup
|
||||
{
|
||||
class GVAR(elements_group): RscControlsGroupNoScrollbars {
|
||||
x = "SafezoneX";
|
||||
y = "SafezoneY";
|
||||
w = "SafezoneW";
|
||||
h = "SafezoneH";
|
||||
idc = 170;
|
||||
class VScrollbar {
|
||||
autoScrollSpeed = -1;
|
||||
autoScrollDelay = 5;
|
||||
autoScrollRewind = 0;
|
||||
color[] = {1,1,1,0};
|
||||
width = 0.001;
|
||||
};
|
||||
class HScrollbar {
|
||||
color[] = {1,1,1,0};
|
||||
height = 0.001;
|
||||
};
|
||||
|
||||
class Controls {
|
||||
class CA_Distance: RscOpticsValue {
|
||||
idc = 151;
|
||||
@ -63,23 +49,13 @@ class RscInGameUI {
|
||||
x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (0.307/4)*3*SafezoneH - SafezoneX";
|
||||
text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\wfov_co.paa";
|
||||
};
|
||||
class GVAR(WFOV_mode_group): RscControlsGroup {
|
||||
class GVAR(WFOV_mode_group): RscControlsGroupNoScrollbars {
|
||||
x = "SafezoneX";
|
||||
y = "SafezoneY";
|
||||
w = "SafezoneW";
|
||||
h = "SafezoneH";
|
||||
idc = 163;
|
||||
class VScrollbar {
|
||||
autoScrollSpeed = -1;
|
||||
autoScrollDelay = 5;
|
||||
autoScrollRewind = 0;
|
||||
color[] = {1,1,1,0};
|
||||
width = 0.001;
|
||||
};
|
||||
class HScrollbar {
|
||||
color[] = {1,1,1,0};
|
||||
height = 0.001;
|
||||
};
|
||||
|
||||
class Controls {
|
||||
class StadiaL: RscLine {
|
||||
x = "0.4899*SafezoneW - SafezoneX";
|
||||
@ -131,23 +107,13 @@ class RscInGameUI {
|
||||
x = "(SafezoneX+(SafezoneW -SafezoneH*3/4)/2)+ (0.586/4)*3*SafezoneH - SafezoneX";
|
||||
text = "\A3\ui_f\data\igui\rscingameui\rscoptics_titan\nfov_co.paa";
|
||||
};
|
||||
class GVAR(NFOV_mode_group): RscControlsGroup {
|
||||
class GVAR(NFOV_mode_group): RscControlsGroupNoScrollbars {
|
||||
x = "SafezoneX";
|
||||
y = "SafezoneY";
|
||||
w = "SafezoneW-SafezoneX";
|
||||
h = "SafezoneH-SafezoneY";
|
||||
idc = 162;
|
||||
class VScrollbar {
|
||||
autoScrollSpeed = -1;
|
||||
autoScrollDelay = 5;
|
||||
autoScrollRewind = 0;
|
||||
color[] = {1,1,1,0};
|
||||
width = 0.001;
|
||||
};
|
||||
class HScrollbar {
|
||||
color[] = {1,1,1,0};
|
||||
height = 0.001;
|
||||
};
|
||||
|
||||
class Controls {
|
||||
class StadiaL: RscLine {
|
||||
x = "0.4788*SafezoneW - SafezoneX";
|
||||
@ -251,7 +217,7 @@ class RscInGameUI {
|
||||
};
|
||||
};
|
||||
};
|
||||
class ACE_Targeting : RscControlsGroup {
|
||||
class ACE_Targeting: RscControlsGroupNoScrollbars {
|
||||
idc = 6999;
|
||||
|
||||
x = "SafezoneX";
|
||||
@ -261,24 +227,14 @@ class RscInGameUI {
|
||||
|
||||
enabled = 0;
|
||||
class Controls {
|
||||
class ACE_TargetingConstrains: RscControlsGroup {
|
||||
class ACE_TargetingConstrains: RscControlsGroupNoScrollbars {
|
||||
x = "SafezoneX";
|
||||
y = "SafezoneY";
|
||||
w = "SafezoneW-SafezoneX";
|
||||
h = "SafezoneH-SafezoneY";
|
||||
|
||||
enabled = 0;
|
||||
class VScrollbar {
|
||||
autoScrollSpeed = -1;
|
||||
autoScrollDelay = 5;
|
||||
autoScrollRewind = 0;
|
||||
color[] = {1,1,1,0};
|
||||
width = 0.001;
|
||||
};
|
||||
class HScrollbar {
|
||||
color[] = {1,1,1,0};
|
||||
height = 0.001;
|
||||
};
|
||||
|
||||
class Controls {
|
||||
class Top: RscPicture {
|
||||
idc = 699101;
|
||||
|
@ -3,10 +3,7 @@
|
||||
#define MAINPREFIX z
|
||||
#define PREFIX ace
|
||||
|
||||
#define MAJOR 3
|
||||
#define MINOR 8
|
||||
#define PATCHLVL 0
|
||||
#define BUILD 10
|
||||
#include "script_version.hpp"
|
||||
|
||||
#define VERSION MAJOR.MINOR.PATCHLVL.BUILD
|
||||
#define VERSION_AR MAJOR,MINOR,PATCHLVL,BUILD
|
||||
|
4
addons/main/script_version.hpp
Normal file
4
addons/main/script_version.hpp
Normal file
@ -0,0 +1,4 @@
|
||||
#define MAJOR 3
|
||||
#define MINOR 8
|
||||
#define PATCHLVL 1
|
||||
#define BUILD 11
|
@ -44,18 +44,4 @@ class ACE_Settings {
|
||||
typeName = "COLOR";
|
||||
value[] = {1, 0.88, 0, 0.7};
|
||||
};
|
||||
class GVAR(groupColorConfigurations) {
|
||||
displayName = CSTRING(groupColorConfigurations_displayName);
|
||||
description = CSTRING(groupColorConfigurations_description);
|
||||
category = CSTRING(mapGestures_category);
|
||||
typeName = "ARRAY";
|
||||
value[] = {};
|
||||
};
|
||||
class GVAR(groupColorConfigurationMapping) {
|
||||
displayName = CSTRING(groupColorConfigurationMapping_displayName);
|
||||
description = CSTRING(groupColorConfigurationMapping_description);
|
||||
category = CSTRING(mapGestures_category);
|
||||
typeName = "ARRAY";
|
||||
value[] = {{}, {}};
|
||||
};
|
||||
};
|
||||
|
@ -14,6 +14,5 @@ class Extended_PreInit_EventHandlers {
|
||||
class Extended_PostInit_EventHandlers {
|
||||
class ADDON {
|
||||
init = QUOTE(call COMPILE_FILE(XEH_postInit));
|
||||
serverInit = QUOTE(call COMPILE_FILE(XEH_serverPostInit));
|
||||
};
|
||||
};
|
||||
|
@ -47,7 +47,7 @@ class CfgVehicles {
|
||||
category = "ACE";
|
||||
displayName = CSTRING(moduleGroupSettings_displayName);
|
||||
function = QFUNC(moduleGroupSettings);
|
||||
isGlobal = 0;
|
||||
isGlobal = 2;
|
||||
author = ECSTRING(common,ACETeam);
|
||||
icon = QPATHTOF(ui\icon_module_map_gestures_ca.paa);
|
||||
class Arguments {
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
PREP(assignClientIDOnServer);
|
||||
PREP(addGroupColorMapping);
|
||||
PREP(drawMapGestures);
|
||||
PREP(endTransmit);
|
||||
PREP(getProximityPlayers);
|
||||
|
@ -8,6 +8,17 @@ if (!hasInterface) exitWith {};
|
||||
|
||||
["ace_settingsInitialized", {
|
||||
if (!GVAR(enabled)) exitWith {};
|
||||
|
||||
// This will set QEGVAR(common,playerOwner) var on player objects
|
||||
[] call EFUNC(common,setPlayerOwner);
|
||||
|
||||
GVAR(pointPosition) = [0,0,0];
|
||||
|
||||
[QGVAR(syncPos), {
|
||||
params ["_unit", "_pointPos"];
|
||||
_unit setVariable [QGVAR(pointPosition), _pointPos];
|
||||
}] call CBA_fnc_addEventHandler;
|
||||
|
||||
[{
|
||||
if (isNull (findDisplay 12)) exitWith {};
|
||||
|
||||
|
@ -4,4 +4,6 @@ ADDON = false;
|
||||
|
||||
#include "XEH_PREP.hpp"
|
||||
|
||||
GVAR(GroupColorCfgMappingNew) = call CBA_fnc_createNamespace;
|
||||
|
||||
ADDON = true;
|
||||
|
@ -1,3 +0,0 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
[QGVAR(noOwnerID), FUNC(assignClientIDOnServer)] call CBA_fnc_addEventHandler;
|
30
addons/map_gestures/functions/fnc_addGroupColorMapping.sqf
Normal file
30
addons/map_gestures/functions/fnc_addGroupColorMapping.sqf
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Author: Dslyecxi, MikeMatrix, PabstMirror
|
||||
* Adds a group id color mapping.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Group ID or group <STRING><GROUP>
|
||||
* 1: Leader color array (4 numbers including alpha) <ARRAY>
|
||||
* 2: Unit (non-leader) color array (4 numbers including alpha) <ARRAY>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* ["Alpha 1-1", [1,0,0,1], [0,1,0,1]] call ace_map_gestures_fnc_addGroupColorMapping
|
||||
*
|
||||
* Public: Yes
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
if (!params [["_group", "", [grpNull, ""]], ["_leadColor", [1,1,1,1], [[]], 4], ["_unitColor", [1,1,1,1], [[]], 4]]) exitWith {
|
||||
ERROR_1("Bad Params: %1",_this);
|
||||
};
|
||||
TRACE_3("params",_group,_leadColor,_unitColor);
|
||||
|
||||
if (_group isEqualType grpNull) then {_group = groupID _group};
|
||||
|
||||
if (!([_leadColor] call FUNC(isValidColorArray))) exitWith {ERROR("leadColor is not a valid color array.")};
|
||||
if (!([_unitColor] call FUNC(isValidColorArray))) exitWith {ERROR("color is not a valid color array.")};
|
||||
|
||||
GVAR(GroupColorCfgMappingNew) setVariable [_group, [_leadColor, _unitColor]];
|
@ -1,24 +0,0 @@
|
||||
/*
|
||||
* Author: Dslyecxi, MikeMatrix
|
||||
* Assign readable client ID to unit on the server.
|
||||
*
|
||||
* Arguments:
|
||||
* 0: Unit name <STRING>
|
||||
*
|
||||
* Return Value:
|
||||
* None
|
||||
*
|
||||
* Example:
|
||||
* ["MikeMatrix"] call ace_map_gestures_fnc_assignClientIDOnServer
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
params ["_unitName"];
|
||||
|
||||
{
|
||||
if (name _x == _unitName) exitWith {
|
||||
_x setVariable [QGVAR(owner_id), owner _x, true];
|
||||
};
|
||||
} count playableUnits;
|
@ -15,6 +15,8 @@
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
BEGIN_COUNTER(draw);
|
||||
|
||||
#define ICON_RENDER_SIZE 55
|
||||
#define ICON_TEXT_ALIGN "left"
|
||||
#define ICON_ANGLE 0
|
||||
@ -26,36 +28,34 @@
|
||||
|
||||
if (!GVAR(enabled) || !visibleMap) exitWith {};
|
||||
|
||||
private ["_color", "_drawPosVariableName", "_group", "_grpName", "_pos", "_unitUID"];
|
||||
|
||||
params ["_mapHandle"];
|
||||
|
||||
// Iterate over all nearby players and render their pointer if player is transmitting.
|
||||
{
|
||||
// Data variable name for unit
|
||||
_unitUID = getPlayerUID _x;
|
||||
_drawPosVariableName = if (!isNil "_unitUID" && _unitUID != "") then {format [QGVAR(%1_DrawPos), _unitUID]} else {nil};
|
||||
|
||||
if (!isNil "_drawPosVariableName") then {
|
||||
if (isNil {missionNamespace getVariable _drawPosVariableName}) then {missionNamespace setVariable [_drawPosVariableName, [1, 1, 1]];};
|
||||
_pos = missionNamespace getVariable _drawPosVariableName;
|
||||
// Only render if the unit is alive and transmitting
|
||||
if (alive _x && {_x getVariable [QGVAR(Transmit), false]}) then {
|
||||
|
||||
// Only render if the unit is alive and transmitting
|
||||
if (alive _x && {_x getVariable QGVAR(Transmit)}) then {
|
||||
_group = group _x;
|
||||
_grpName = groupID _group;
|
||||
private _pos = _x getVariable [QGVAR(pointPosition), [0,0,0]];
|
||||
|
||||
// If color settings for the group exist, then use those, otherwise fall back to the default colors
|
||||
_color = if ([GVAR(GroupColorConfigurationMapping), _grpName] call CBA_fnc_hashHasKey) then {
|
||||
(GVAR(GroupColorConfigurations) select ([GVAR(GroupColorConfigurationMapping), _grpName] call CBA_fnc_hashGet)) select (_x != leader _group)
|
||||
} else {
|
||||
if (_x == leader _group) then {GVAR(defaultLeadColor)} else {GVAR(defaultColor)};
|
||||
};
|
||||
private _group = group _x;
|
||||
private _grpName = groupID _group;
|
||||
|
||||
// Render icon and player name
|
||||
_mapHandle drawIcon ["\a3\ui_f\data\gui\cfg\Hints\icon_text\group_1_ca.paa", _color, _pos, ICON_RENDER_SIZE, ICON_RENDER_SIZE, ICON_ANGLE, "", ICON_SHADOW, TEXT_SIZE, TEXT_FONT, ICON_TEXT_ALIGN];
|
||||
_mapHandle drawIcon ["#(argb,8,8,3)color(0,0,0,0)", GVAR(nameTextColor), _pos, TEXT_ICON_RENDER_SIZE, TEXT_ICON_RENDER_SIZE, ICON_ANGLE, name _x, TEXT_SHADOW, TEXT_SIZE, TEXT_FONT, ICON_TEXT_ALIGN];
|
||||
// If color settings for the group exist, then use those, otherwise fall back to the default colors
|
||||
private _colorMap = GVAR(GroupColorCfgMappingNew) getVariable _grpName;
|
||||
private _color = if (isNil "_colorMap") then {
|
||||
[GVAR(defaultLeadColor), GVAR(defaultColor)] select (_x != leader _group);
|
||||
} else {
|
||||
_colorMap select (_x != leader _group);
|
||||
};
|
||||
|
||||
TRACE_2("",_colorMap,_color);
|
||||
|
||||
// Render icon and player name
|
||||
_mapHandle drawIcon ["\a3\ui_f\data\gui\cfg\Hints\icon_text\group_1_ca.paa", _color, _pos, ICON_RENDER_SIZE, ICON_RENDER_SIZE, ICON_ANGLE, "", ICON_SHADOW, TEXT_SIZE, TEXT_FONT, ICON_TEXT_ALIGN];
|
||||
_mapHandle drawIcon ["#(argb,8,8,3)color(0,0,0,0)", GVAR(nameTextColor), _pos, TEXT_ICON_RENDER_SIZE, TEXT_ICON_RENDER_SIZE, ICON_ANGLE, name _x, TEXT_SHADOW, TEXT_SIZE, TEXT_FONT, ICON_TEXT_ALIGN];
|
||||
};
|
||||
nil
|
||||
} count ([ACE_player, GVAR(maxRange)] call FUNC(getProximityPlayers));
|
||||
|
||||
END_COUNTER(draw);
|
||||
|
@ -10,7 +10,7 @@
|
||||
* All units in proximity <ARRAY>
|
||||
*
|
||||
* Example:
|
||||
* ["example value"] call ace_module_fnc_functionName
|
||||
* [player, 7] call ace_map_gestures_fnc_getProximityPlayers
|
||||
*
|
||||
* Public: No
|
||||
*/
|
||||
@ -21,4 +21,5 @@ params ["_unit", "_range"];
|
||||
private _proximityPlayers = (getPos _unit) nearEntities [["CAMAnBase"], _range];
|
||||
_proximityPlayers deleteAt (_proximityPlayers find _unit);
|
||||
_proximityPlayers append (crew vehicle _unit);
|
||||
_proximityPlayers
|
||||
|
||||
_proximityPlayers select {[_x, false] call EFUNC(common,isPlayer);}
|
||||
|
@ -17,29 +17,18 @@
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_color", "_configurationGroupMappings", "_configurationIndex", "_configurations", "_leadColor"];
|
||||
|
||||
params ["_logic", "_units", "_activated"];
|
||||
TRACE_3("params",_logic,_units,_activated);
|
||||
|
||||
if (!_activated || !isServer) exitWith {};
|
||||
if (!_activated) exitWith {};
|
||||
|
||||
// Transcode string setting into usable array. Example: "1,1,1,1" -> [1, 1, 1, 1]
|
||||
_leadColor = call compile ("[" + (_logic getVariable ["leadColor", ""]) + "]");
|
||||
private _leadColor = call compile ("[" + (_logic getVariable ["leadColor", ""]) + "]");
|
||||
if (!([_leadColor] call FUNC(isValidColorArray))) exitWith {ERROR("leadColor is not a valid color array.")};
|
||||
_color = call compile ("[" + (_logic getVariable ["color", ""]) + "]");
|
||||
private _color = call compile ("[" + (_logic getVariable ["color", ""]) + "]");
|
||||
if (!([_color] call FUNC(isValidColorArray))) exitWith {ERROR("color is not a valid color array.")};
|
||||
|
||||
// If we already have color configurations from another source, use those, otherwise use default.
|
||||
_configurations = if (isNil QGVAR(GroupColorConfigurations)) then { [] } else { +GVAR(GroupColorConfigurations) };
|
||||
_configurationGroupMappings = if(isNil QGVAR(GroupColorConfigurationMapping)) then { [] call CBA_fnc_hashCreate } else { +GVAR(GroupColorConfigurationMapping) };
|
||||
|
||||
// Save custom color configuration and keep the index of the entry.
|
||||
_configurationIndex = _configurations pushBack [_leadColor, _color];
|
||||
|
||||
// Add all synchronized groups and reference custom configuration for them
|
||||
{
|
||||
[_configurationGroupMappings, groupID group _x, _configurationIndex] call CBA_fnc_hashSet;
|
||||
[group _x, _leadColor, _color] call FUNC(addGroupColorMapping);
|
||||
} forEach _units;
|
||||
|
||||
[QGVAR(GroupColorConfigurations), _configurations, false, true] call EFUNC(common,setSetting);
|
||||
[QGVAR(GroupColorConfigurationMapping), _configurationGroupMappings, false, true] call EFUNC(common,setSetting);
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_ownerID", "_unitUID", "_drawPosVariableName", "_playerOwnerID"];
|
||||
BEGIN_COUNTER(transmit);
|
||||
|
||||
params ["", "_pfhId"];
|
||||
|
||||
@ -29,17 +29,14 @@ if (!GVAR(EnableTransmit) || !visibleMap) exitWith {
|
||||
};
|
||||
|
||||
{
|
||||
_ownerID = _x getVariable QGVAR(owner_id);
|
||||
if (isNil "_ownerID") then {
|
||||
[QGVAR(noOwnerID), [name _x]] call CBA_fnc_serverEvent;
|
||||
} else {
|
||||
_playerOwnerID = ACE_player getVariable QGVAR(owner_id);
|
||||
if (!isNil "_playerOwnerID" && _ownerID != _playerOwnerID) then {
|
||||
_unitUID = getPlayerUID ACE_Player;
|
||||
_drawPosVariableName = if (!isNil "_unitUID" && _unitUID != "") then {format [QGVAR(%1_DrawPos), _unitUID]} else {nil};
|
||||
if (!isNil "_drawPosVariableName") then {
|
||||
_ownerID publicVariableClient _drawPosVariableName;
|
||||
};
|
||||
private _owner = _x getVariable [QEGVAR(common,playerOwner), -1];
|
||||
if (_owner > -1) then {
|
||||
private _remotePos = _x getVariable [QGVAR(remotePos), [0,0,0]];
|
||||
if ((_remotePos distance2d GVAR(pointPosition)) > 1) then { // Only transmit when actually moving
|
||||
[QGVAR(syncPos), [ACE_Player, GVAR(pointPosition)], _owner] call CBA_fnc_ownerEvent;
|
||||
_x setVariable [QGVAR(remotePos), GVAR(pointPosition)];
|
||||
};
|
||||
};
|
||||
} count ([ACE_player, GVAR(maxRange)] call FUNC(getProximityPlayers));
|
||||
|
||||
END_COUNTER(transmit);
|
||||
|
@ -15,11 +15,9 @@
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
private ["_mapCtrl", "_unitUID", "_drawPosVariableName"];
|
||||
|
||||
disableSerialization;
|
||||
|
||||
_mapCtrl = findDisplay 12 displayCtrl 51;
|
||||
private _mapCtrl = findDisplay 12 displayCtrl 51;
|
||||
|
||||
// MouseMoving EH.
|
||||
if (!isNil QGVAR(MouseMoveHandlerID)) then {
|
||||
@ -36,11 +34,7 @@ GVAR(MouseMoveHandlerID) = _mapCtrl ctrlAddEventHandler ["MouseMoving", {
|
||||
ACE_player setVariable [QGVAR(Transmit), true, true];
|
||||
};
|
||||
|
||||
_unitUID = getPlayerUID ACE_player;
|
||||
_drawPosVariableName = if (!isNil "_unitUID" && _unitUID != "") then {format [QGVAR(%1_DrawPos), _unitUID]} else {nil};
|
||||
if (!isNil "_drawPosVariableName") then {
|
||||
missionNamespace setVariable [_drawPosVariableName, _control ctrlMapScreenToWorld [_posX, _posY]];
|
||||
};
|
||||
GVAR(pointPosition) = _control ctrlMapScreenToWorld [_posX, _posY];
|
||||
}];
|
||||
|
||||
// MouseDown EH
|
||||
|
@ -177,51 +177,6 @@
|
||||
<French>Temps entre les actualisations de données</French>
|
||||
<Japanese>データの更新間隔</Japanese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_map_gestures_GroupColorConfigurations_displayName">
|
||||
<English>Group color configurations</English>
|
||||
<Portuguese>Configurações de cores de grupo</Portuguese>
|
||||
<Polish>Konf. koloru grup</Polish>
|
||||
<Russian>Конфигурация цвета групп</Russian>
|
||||
<Czech>Konfigurace barvy pro skupinu</Czech>
|
||||
<Italian>Configurazioni colori dei gruppi</Italian>
|
||||
<German>Konfiguration der Gruppenfarbe</German>
|
||||
<Spanish>Configuración de color de grupo</Spanish>
|
||||
<French>Configuration des couleurs de groupe</French>
|
||||
<Japanese>グループで使う色の設定</Japanese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_map_gestures_GroupColorConfigurations_description">
|
||||
<English>Group color configuration containing arrays of color pairs ([leadColor, color]).</English>
|
||||
<Portuguese>Configuração de cores de grupo contendo arrays com pares de cores ([leadColor, color]).</Portuguese>
|
||||
<Polish>Konfiguracja kolorów grup zawierająca tablice par kolorów ([kolorLidera, kolor]).</Polish>
|
||||
<Russian>Конфигурация цвета групп содержит массив цветовых пар ([лид. цвет, цвет]).</Russian>
|
||||
<Italian>Configurazioni colori gruppi contenenti array di coppie di colori ([leadColor, color]).</Italian>
|
||||
<German>Konfiguration der Gruppenfarbe mit zugeordneten Farbpaaren der Aufstellung ([leadColor, color]).</German>
|
||||
<Spanish>Configuración de color de grupo conteniendo una lista de pares de colores ([colorLider, colo]).</Spanish>
|
||||
<French>Configuration des couleurs de groupe contenant des tableaux de paires de couleurs ([couleurDeCommandement, couleur]).</French>
|
||||
<Japanese>アライに格納された組によりグループの色を設定します。([leadColor, color])</Japanese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_map_gestures_GroupColorConfigurationMapping_description">
|
||||
<English>Hash of Group ID mapped to the Group color configuration index.</English>
|
||||
<Portuguese>Hashes de ID de grupos mapeados para o índice de configuração de cor de grupos.</Portuguese>
|
||||
<Polish>Hasz ID grup zmapowanych w indeksie konfiguracji koloru grup.</Polish>
|
||||
<Russian>Хеш ID групп, соответствующих индексам конфигурации цвета групп.</Russian>
|
||||
<Italian>Hash degli ID Gruppi mappati nell'indice configurazioni colori gruppi.</Italian>
|
||||
<German>Hashwert der Gruppen-ID, die dem Konfigurations-Index der Gruppenfarbe zugeordnet werden.</German>
|
||||
<Spanish>ID de Grupo mapeado al índice de la configuración de color de grupo.</Spanish>
|
||||
<French>Hash de l'identifiant du groupe mappé à l'index de la configuration de la couleur du groupe.</French>
|
||||
<Japanese>グループ ID のハッシュはグループの色を設定するインデックスへマッピングされます。</Japanese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_map_gestures_GroupColorConfigurationMapping_displayName">
|
||||
<English>GroupID Color configuration mapping</English>
|
||||
<Portuguese>Mapeamento de configuração para cores de GroupID</Portuguese>
|
||||
<Polish>Mapowanie kolorów poprzez GroupID</Polish>
|
||||
<Russian>Соответствие ID групп конфигурации цвета групп</Russian>
|
||||
<Italian>Mappatura configurazioni colori GroupID</Italian>
|
||||
<German>Gruppen-ID-Farbe Konfigurationszuordnung</German>
|
||||
<Spanish>Mapeado de ID de Grupo</Spanish>
|
||||
<French>Configuration du mappage de l'identifiant de la couleur du groupe.</French>
|
||||
<Japanese>GroupID の色への設定をマッピング</Japanese>
|
||||
</Key>
|
||||
<Key ID="STR_ACE_map_gestures_enabled_description">
|
||||
<English>Enables the Map Gestures.</English>
|
||||
<Portuguese>Ativa os gestos no mapa</Portuguese>
|
||||
@ -270,4 +225,4 @@
|
||||
<Japanese>マップ ジェスチャ</Japanese>
|
||||
</Key>
|
||||
</Package>
|
||||
</Project>
|
||||
</Project>
|
||||
|
@ -10,9 +10,7 @@ if (isServer) then {
|
||||
|
||||
[QGVAR(bloodDropCreated), {
|
||||
params ["_bloodDrop"];
|
||||
|
||||
GVAR(bloodDrops) pushBack _bloodDrop;
|
||||
|
||||
if (count GVAR(bloodDrops) >= MAX_BLOOD_OBJECTS) then {
|
||||
private _deletedBloodDrop = GVAR(bloodDrops) deleteAt 0;
|
||||
deleteVehicle _deletedBloodDrop;
|
||||
@ -25,7 +23,7 @@ if (isServer) then {
|
||||
["ace_settingsInitialized", {
|
||||
TRACE_1("settingsInitialized", GVAR(enabledFor));
|
||||
if (GVAR(enabledFor) == 0) exitWith {}; // 0: disabled
|
||||
if (GVAR(enabledFor) == 1 && {!hasInterface}) exitWith {}; // 1: enabledFor_OnlyPlayers
|
||||
if ((GVAR(enabledFor) == 1) && {!hasInterface}) exitWith {}; // 1: enabledFor_OnlyPlayers
|
||||
|
||||
private _listcode = if (GVAR(enabledFor) == 1) then {
|
||||
{[ACE_player] select {[_x] call FUNC(isBleeding)}} // ace_player is only possible local player
|
||||
|
@ -22,6 +22,7 @@
|
||||
#define OFFSET 0.25
|
||||
|
||||
params ["_unit", "_dir", "_damage"];
|
||||
_damage = _damage min 1;
|
||||
|
||||
private _distanceBetweenDrops = DISTANCE_BETWEEN_DROPS * _damage;
|
||||
private _offset = OFFSET + _distanceBetweenDrops;
|
||||
|
@ -23,8 +23,8 @@ if (isNull _target ||
|
||||
{_target getVariable [QGVAR(jerryCan), false]}) exitWith {};
|
||||
|
||||
[_target, _fuelAmount] call FUNC(setFuel);
|
||||
_target setVariable [QGVAR(jerryCan), true, true];
|
||||
_target setVariable [QGVAR(source), _target, true];
|
||||
_target setVariable [QGVAR(jerryCan), true];
|
||||
_target setVariable [QGVAR(source), _target];
|
||||
|
||||
// Main Action
|
||||
private _action = [QGVAR(Refuel),
|
||||
|
@ -84,7 +84,7 @@ for "_i" from 0 to (count _hitPoint) do {
|
||||
|
||||
// Don't display part name if no string is found in stringtable
|
||||
if (_text == LSTRING(Hit)) then {
|
||||
if (_hitPoint != "") then { WARNING_1("Hitpoint [%1] - could not be localized", _hitPoint); };
|
||||
if (_hitPoint != "") then { LOG_1("Hitpoint [%1] - could not be localized", _hitPoint); };
|
||||
_text = _textDefault;
|
||||
};
|
||||
|
||||
|
@ -51,6 +51,7 @@ if (!([[_unit, _veh]] call _condition)) exitWith {false};
|
||||
|
||||
_returnValue = _funcType in ["canLockpick", "startLockpick", "finishLockpick"];
|
||||
switch (_funcType) do {
|
||||
case "canLockpick": {};
|
||||
case "startLockpick": {
|
||||
[_vehLockpickStrenth, [_unit, _veh, "finishLockpick"], {(_this select 0) call FUNC(lockpick)}, {}, (localize LSTRING(Action_LockpickInUse)), _condition] call EFUNC(common,progressBar);
|
||||
};
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/acemod/ACE3/releases">
|
||||
<img src="https://img.shields.io/badge/Version-3.8.0-blue.svg?style=flat-square" alt="ACE3 Version">
|
||||
<img src="https://img.shields.io/badge/Version-3.8.1-blue.svg?style=flat-square" alt="ACE3 Version">
|
||||
</a>
|
||||
<a href="https://github.com/acemod/ACE3/issues">
|
||||
<img src="https://img.shields.io/github/issues-raw/acemod/ACE3.svg?style=flat-square&label=Issues" alt="ACE3 Fehlermeldungen">
|
||||
|
@ -3,7 +3,7 @@
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://github.com/acemod/ACE3/releases">
|
||||
<img src="https://img.shields.io/badge/Wersja-3.8.0-blue.svg?style=flat-square" alt="ACE3 Wersja">
|
||||
<img src="https://img.shields.io/badge/Wersja-3.8.1-blue.svg?style=flat-square" alt="ACE3 Wersja">
|
||||
</a>
|
||||
<a href="https://github.com/acemod/ACE3/issues">
|
||||
<img src="https://img.shields.io/github/issues-raw/acemod/ACE3.svg?label=Zagadnienia&style=flat-square" alt="ACE3 Zagadnienia">
|
||||
|
@ -11,8 +11,8 @@ ace:
|
||||
version:
|
||||
major: 3
|
||||
minor: 8
|
||||
patch: 0
|
||||
build: 10
|
||||
patch: 1
|
||||
build: 11
|
||||
|
||||
acex:
|
||||
githubUrl: https://github.com/acemod/ACEX
|
||||
|
@ -11,8 +11,8 @@ ace:
|
||||
version:
|
||||
major: 3
|
||||
minor: 8
|
||||
patch: 0
|
||||
build: 10
|
||||
patch: 1
|
||||
build: 11
|
||||
|
||||
acex:
|
||||
githubUrl: https://github.com/acemod/ACEX
|
||||
|
@ -470,6 +470,10 @@
|
||||
`ace_common`
|
||||
{% endif %}
|
||||
|
||||
{% if include.component == "nouniformrestrictions" %}
|
||||
`ace_common`
|
||||
{% endif %}
|
||||
|
||||
{% if include.component == "particles" %}
|
||||
`ace_common`
|
||||
{% endif %}
|
||||
|
@ -73,6 +73,19 @@ Class Name | In-Game Name | Type |
|
||||
---------- | --------- | ---------
|
||||
ACE_CableTie | cable tie | ACE_ItemCore |
|
||||
|
||||
### Chemlights
|
||||
`Added in 3.7.0`
|
||||
|
||||
Class Name | In-Game Name | Type |
|
||||
---------- | --------- | ---------
|
||||
ACE_Chemlight_HiOrange | Chemlight (Hi Orange) | Throwable |
|
||||
ACE_Chemlight_HiRed | Chemlight (Hi Red) | Throwable |
|
||||
ACE_Chemlight_HiYellow | Chemlight (Hi Yellow) | Throwable |
|
||||
ACE_Chemlight_HiWhite | Chemlight (Hi White) | Throwable |
|
||||
ACE_Chemlight_Orange | Chemlight (Orange) | Throwable |
|
||||
ACE_Chemlight_White | Chemlight (White) | Throwable |
|
||||
ACE_Chemlight_IR | Chemlight (IR) | Throwable |
|
||||
|
||||
### Common
|
||||
`Added in 3.0.0`
|
||||
|
||||
@ -131,6 +144,7 @@ ACE_HandFlare_White | M127A1 Hand Held Signal (White) | Grenade |
|
||||
ACE_HandFlare_Red | M127A1 Hand Held Signal (Red | Grenade |
|
||||
ACE_HandFlare_Green | M127A1 Hand Held Signal (Green) | Grenade |
|
||||
ACE_HandFlare_Yellow | M127A1 Hand Held Signal (Yellow) | Grenade |
|
||||
ACE_M14 | AN-M14 Incendiary Grenade | Grenade |
|
||||
ACE_M84 | M84 Stun Grenade | Grenade |
|
||||
|
||||
### Gun Bag
|
||||
@ -339,6 +353,7 @@ Class Name | In-Game Name | Type |
|
||||
ACE_SpottingScope | Spotting Scope | ACE_ItemCore |
|
||||
ACE_SpottingScopeObject | Spotting Scope (placed) | StaticATWeapon |
|
||||
|
||||
|
||||
### Tactical Ladder
|
||||
`Added in 3.1.1`
|
||||
|
||||
@ -352,10 +367,10 @@ ACE_Tactical_Ladder | Telescopic Ladder (placed) | house |
|
||||
|
||||
Class Name | In-Game Name | Type |
|
||||
---------- | --------- | ---------
|
||||
ACE_SpraypaintBlack | Spraypaint Black | ACE_ItemCore |
|
||||
ACE_SpraypaintBlue | Spraypaint Blue | ACE_ItemCore |
|
||||
ACE_SpraypaintGreen | Spraypaint Green | ACE_ItemCore |
|
||||
ACE_SpraypaintRed | Spraypaint Red | ACE_ItemCore |
|
||||
ACE_SpraypaintBlack | Black spray paint | ACE_ItemCore |
|
||||
ACE_SpraypaintBlue | Blue spray paint | ACE_ItemCore |
|
||||
ACE_SpraypaintGreen | Green spray paint | ACE_ItemCore |
|
||||
ACE_SpraypaintRed | Red spray paint | ACE_ItemCore |
|
||||
|
||||
### Trenches
|
||||
`Added in 3.5.0`
|
||||
|
@ -16,9 +16,10 @@ This page describes how you can setup your development environment for ACE3, all
|
||||
- A proper installation of the Arma 3 Tools (available on Steam)
|
||||
- A properly setup P-drive
|
||||
- Run Arma 3 and Arma 3 Tools directly from steam once to install registry entries (and again after every update)
|
||||
- Python 3.x, available [here](http://www.python.org)
|
||||
- The following Mikero's Tools (available [here](https://dev.withsix.com/projects/mikero-pbodll/files)): DePbo, DeRap, DeOgg, Rapify, MakePbo, pboProject
|
||||
- A properly setup PATH variable (containing Python, the Mikero's Tools and git)
|
||||
- [Python 3.x](https://www.python.org/)
|
||||
- [Mikero Tools](https://dev.withsix.com/projects/mikero-pbodll/files): DePbo, DeRap, DeOgg, Rapify, MakePbo, PboProject
|
||||
- Python, Mikero Tools and Git in PATH environment variable
|
||||
- [CBA](https://github.com/CBATeam/CBA_A3/releases/latest) mod (release or development version)
|
||||
|
||||
|
||||
## 2. Why so complicated?
|
||||
@ -28,24 +29,29 @@ If you have contributed to AGM you might be used to an easier build process, whe
|
||||
Not offering .exes for the Python scripts we use allows us to make easy changes without the hassle of compiling self-extracting exes all the time.
|
||||
|
||||
|
||||
## 3. Getting ACE
|
||||
## 3. Getting Source Code
|
||||
|
||||
To actually get the ACE source code on your machine, it is recommended that you use Git. Tutorials for this are all around the web, and it allows you to track your changes and easily update your local copy.
|
||||
To actually get the ACE3 source code on your machine, it is recommended that you use Git. Tutorials for this are all around the web, and it allows you to track your changes and easily update your local copy.
|
||||
|
||||
If you just want to create a quick and dirty build, you can also directly download the source code using the "Download ZIP" button on the front page of the GitHub repo.
|
||||
|
||||
|
||||
## 4. Initial Setup
|
||||
## 4. Setup and Building
|
||||
|
||||
After ensuring that you have installed all requirements, execute the `setup.py` script found in the `tools` folder. This will do most of the heavy lifting for you, create the links you need and copy the required CBA code to the proper place. Please note that these links are tied to the location of your ACE3 source code, so make sure that the project folder is where you want it to be. We recommend that you store the ACE3 project on your P-drive.
|
||||
### 4.1 Initial Setup
|
||||
|
||||
### 4.1 Manual Setup
|
||||
Navigate to `tools` folder in command line.
|
||||
|
||||
Should the script fail, here is how you create the required links manually:
|
||||
```
|
||||
cd "[location of the ACE3 project]\tools"
|
||||
```
|
||||
|
||||
First, to set up the links, create `z` folders both in your Arma 3 directory and on your P-drive. Then run the following commands as admin, replacing the text in brackets with the appropriate paths:
|
||||
Execute `setup.py` to create symbolic links to P-drive and Arma 3 directory required for building.
|
||||
|
||||
```sh
|
||||
|
||||
Should the script fail, you can create the required links manually. First, create `z` folders both in your Arma 3 directory and on your P-drive. Then run the following commands as admin, replacing the text in brackets with the appropriate paths:
|
||||
|
||||
```bat
|
||||
mklink /J "[Arma 3 installation folder]\z\ace" "[location of the ACE3 project]"
|
||||
mklink /J "P:\z\ace" "[location of the ACE3 project]"
|
||||
```
|
||||
@ -53,33 +59,50 @@ mklink /J "P:\z\ace" "[location of the ACE3 project]"
|
||||
Then, copy the `cba` folder from the `tools` folder to `P:\x\cba`. Create the `x` folder if needed. That folder contains the parts of the CBA source code that are required for the macros to work.
|
||||
|
||||
|
||||
## 5. Creating a Test Build
|
||||
## 4.2 Creating a Test Build
|
||||
|
||||
To create a development build of ACE to test changes or to debug something, run the `build.py` file in the `tools` folder. This will populate the `addons` folder with binarized PBOs. These PBOs still point to the source files in their respective folders however, which allows you to use [file patching](#file-patching).
|
||||
|
||||
This also means that you cannot distribute this build to others.
|
||||
To create a development build of ACE3 to test changes or to debug something, run the `build.py` file in the `tools` folder. This will populate the `addons` folder with binarized PBOs. These PBOs still point to the source files in their respective folders however, which allows you to use [file patching](#file-patching). This also means that you cannot distribute this build to others.
|
||||
|
||||
To start the game using this build, you can use the following modline:
|
||||
|
||||
```sh
|
||||
-mod=@cba_a3;z\ace
|
||||
-mod=@CBA_A3;z\ace
|
||||
```
|
||||
|
||||
## 4.3 Creating a Release Build
|
||||
|
||||
## 6. Creating a Release Build
|
||||
To create a complete build of ACE3 that you can use without the source files you will need to:
|
||||
- Ensure `.hpp` is **NOT** in pboProject's "Exclude From Pbo" list
|
||||
|
||||
To create a complete build of ACE that you can use without the source files, run the `make.py` file in the `tools` folder. This will populate the `release` folder with binarized PBOs that you can redistribute. These handle like those of any other mod.
|
||||
When the requirements are met:
|
||||
- Execute `make.py version increment_build <other-increment-args> force check_external release` in the `tools` folder, replacing `<other-increment-args>` with the part of version you want to increment (options described below)
|
||||
|
||||
This will populate the `release` folder with binarized PBOs, compiled extensions, copied extras, bisigns and a bikey. Additionally, an archive file will also be created in the folder. The folder and archive handle like those of any other mod.
|
||||
|
||||
Different `make.py` command line options include:
|
||||
- `version` - update version number in all files and leave them in working directory (leaving this out will still update the version in all files present in the `release` folder, but they will be reverted to not disturb the working directory)
|
||||
- `increment_build` - increments _build_ version number
|
||||
- `increment_patch` - increments _patch_ version number (ignored with `increment_minor` or `increment_major`)
|
||||
- `increment_minor` - increments _minor_ version number and resets _patch_ version number to `0` (ignored with `increment_major`)
|
||||
- `increment_major` - increments _major_ version number and resets _minor_ and _patch_ version numbers to `0`
|
||||
- `force` - force rebuild all PBOs, even those already present in the `release` directory (combined with `compile` it will also rebuild all extensions)
|
||||
- `check_external` - check external references (incompatible only with `<component1> <component2>` and `force <component1> <component2>`)
|
||||
- `release` - create release packages/archives
|
||||
- `<component1> <component2>` - build only specified component(s) (incompatible with `release`)
|
||||
- `force <component1> <component2>` - force rebuild specified component(s) (incompatible with `release`)
|
||||
|
||||
|
||||
## 7. File Patching
|
||||
|
||||
File Patching allows you to change the files in an addon while the game is running, requiring only a restart of the mission. This makes it great for debugging, as it cuts down the time required between tests. Note that this only works with PBOs created using MakePBO, as outlined in [Creating a Test Build](#creating-a-test-build).
|
||||
File Patching allows you to change the files in an addon while the game is running, requiring only a restart of the mission. This makes it great for debugging, as it cuts down the time required between tests. Note that this only works with PBOs created using MakePBO, which `build.py` uses.
|
||||
|
||||
To run Arma 3 with file patching add the `-filePatching` startup parameter (since Arma 3 v1.50, file patching is disabled by default).
|
||||
|
||||
### 7.1 Disabling CBA Function Caching
|
||||
|
||||
By default CBA caches a compiled version of functions to reduce mission load times. This interferes with file patching. There are three ways to disable function caching:
|
||||
|
||||
- Load `cba_cache_disable.pbo` (included in CBA's optional folder)
|
||||
- Load `cba_cache_disable.pbo` (included in CBA's optional folder - simply move it to `addons` folder for the time being)
|
||||
- Add the following to your test missions description.ext:
|
||||
|
||||
```cpp
|
||||
@ -94,20 +117,16 @@ class CfgSettings {
|
||||
};
|
||||
```
|
||||
|
||||
- To only disable caching for a single module, hence greatly improving mission restart time, add the following line to the `script_component.hpp` file of said module:
|
||||
- To only disable caching for a single module, hence greatly improving mission restart time, add the following line to the `script_component.hpp` file of said module (prepared in each ACE3 component, simply uncomment):
|
||||
|
||||
```cpp
|
||||
#define DISABLE_COMPILE_CACHE
|
||||
```
|
||||
|
||||
### 7.2 Running Arma 3 with File Patching Enabled
|
||||
|
||||
Starting from version 1.50, Arma 3 was changed to disable file patching by default, making the feature opt-in. To execute the game with file patching enabled add the `-filePatching` flag to the command line.
|
||||
|
||||
### 7.3 Restrictions of File Patching
|
||||
### 7.2 Restrictions
|
||||
|
||||
Files must exist in the built PBOs for file patching to work. If you create a new file you must rebuild the PBO or Arma will not find it in your file paths.
|
||||
|
||||
Configs are not patched during run time, only at load time. You do not have have to rebuild a PBO to make config changes, just restart Arma. You can get around this though if you are on the dev branch of Arma 3 and running the [diagnostic exe](https://community.bistudio.com/wiki/Arma_3_Diagnostics_Exe). That includes `diag_mergeConfigFile` which takes a full system path (as in `diag_mergeConfigFile ["p:\z\ace\addons\my_module\config.cpp"]`) and allows you selectively reload config files.
|
||||
|
||||
If you need to add/remove files, then you'll need to run build.py again without the game running, and restart. That is all that is required to add new files to then further use in testing.
|
||||
If you need to add/remove files, then you'll need to run `build.py` again without the game running, and restart. That is all that is required to add new files for further use in testing.
|
||||
|
27
docs/wiki/feature/chemlights.md
Normal file
27
docs/wiki/feature/chemlights.md
Normal file
@ -0,0 +1,27 @@
|
||||
---
|
||||
layout: wiki
|
||||
title: Chemlights
|
||||
description: Adds enhanced types of chemlights.
|
||||
group: feature
|
||||
category: equipment
|
||||
parent: wiki
|
||||
mod: ace
|
||||
version:
|
||||
major: 3
|
||||
minor: 7
|
||||
patch: 0
|
||||
---
|
||||
|
||||
<div class="panel callout">
|
||||
<h5>Note:</h5>
|
||||
<p>Check out the <a href="{{ site.baseurl }}/wiki/feature/advanced-throwing.html">Advanced Throwing</a> page for the new alternative system introduced in version 3.7.0.</p>
|
||||
</div>
|
||||
|
||||
## 1. Overview
|
||||
|
||||
### 1.1 Chemlights
|
||||
Adds throwable chemlights in the colors white, red, green and yellow. Additionally "Hi" chemlights are added that emit a brighter glow.
|
||||
|
||||
## 2. Dependencies
|
||||
|
||||
{% include dependencies_list.md component="chemlights" %}
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
layout: wiki
|
||||
title: Grenades
|
||||
description: Different throwing modes for grenades, a flashbang and hand flares.
|
||||
description: Different throwing modes for grenades, a flashbang, incendiary grenade and hand flares.
|
||||
group: feature
|
||||
category: equipment
|
||||
parent: wiki
|
||||
@ -28,6 +28,9 @@ Adds throwable hand flares in the colors white, red, green and yellow. Additiona
|
||||
### 1.3 M84 stun grenade
|
||||
Adds the M84 stun grenade. The stun effect will also affect AI.
|
||||
|
||||
### 1.4 M14 Incendiary grenade
|
||||
Adds the AN-M14 incendiary grenade. This grenade has a thermate filler and is primarily used for the destruction of material.
|
||||
|
||||
## 2. Usage
|
||||
|
||||
### 2.1 Switching between throw modes
|
||||
|
4
mod.cpp
4
mod.cpp
@ -1,8 +1,8 @@
|
||||
name = "Advanced Combat Environment 3.8.0";
|
||||
name = "Advanced Combat Environment 3.8.1";
|
||||
picture = "logo_ace3_ca.paa";
|
||||
actionName = "GitHub";
|
||||
action = "https://github.com/acemod/ACE3";
|
||||
description = "ACE3 - Version 3.8.0";
|
||||
description = "ACE3 - Version 3.8.1";
|
||||
logo = "logo_ace3_ca.paa";
|
||||
logoOver = "logo_ace3_ca.paa";
|
||||
tooltip = "ACE3";
|
||||
|
1
optionals/nouniformrestrictions/$PBOPREFIX$
Normal file
1
optionals/nouniformrestrictions/$PBOPREFIX$
Normal file
@ -0,0 +1 @@
|
||||
z\ace\addons\nouniformrestrictions
|
11
optionals/nouniformrestrictions/CfgEventHandlers.hpp
Normal file
11
optionals/nouniformrestrictions/CfgEventHandlers.hpp
Normal file
@ -0,0 +1,11 @@
|
||||
class Extended_PreStart_EventHandlers {
|
||||
class ADDON {
|
||||
init = QUOTE(call COMPILE_FILE(XEH_preStart));
|
||||
};
|
||||
};
|
||||
|
||||
class Extended_PreInit_EventHandlers {
|
||||
class ADDON {
|
||||
init = QUOTE(call COMPILE_FILE(XEH_preInit));
|
||||
};
|
||||
};
|
1658
optionals/nouniformrestrictions/CfgVehicles.hpp
Normal file
1658
optionals/nouniformrestrictions/CfgVehicles.hpp
Normal file
File diff suppressed because it is too large
Load Diff
12
optionals/nouniformrestrictions/README.md
Normal file
12
optionals/nouniformrestrictions/README.md
Normal file
@ -0,0 +1,12 @@
|
||||
ace_nouniformrestrictions
|
||||
=======
|
||||
|
||||
Removes side restrictions from all vanilla uniforms.
|
||||
|
||||
|
||||
## Maintainers
|
||||
|
||||
The people responsible for merging changes to this component or answering potential questions.
|
||||
|
||||
- [654wak654](https://github.com/654wak654)
|
||||
- [Jonpas](https://github.com/jonpas)
|
1
optionals/nouniformrestrictions/XEH_PREP.hpp
Normal file
1
optionals/nouniformrestrictions/XEH_PREP.hpp
Normal file
@ -0,0 +1 @@
|
||||
PREP(exportConfig);
|
7
optionals/nouniformrestrictions/XEH_preInit.sqf
Normal file
7
optionals/nouniformrestrictions/XEH_preInit.sqf
Normal file
@ -0,0 +1,7 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
ADDON = false;
|
||||
|
||||
#include "XEH_PREP.hpp"
|
||||
|
||||
ADDON = true;
|
3
optionals/nouniformrestrictions/XEH_preStart.sqf
Normal file
3
optionals/nouniformrestrictions/XEH_preStart.sqf
Normal file
@ -0,0 +1,3 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
#include "XEH_PREP.hpp"
|
18
optionals/nouniformrestrictions/config.cpp
Normal file
18
optionals/nouniformrestrictions/config.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
#include "script_component.hpp"
|
||||
|
||||
class CfgPatches {
|
||||
class ADDON {
|
||||
name = COMPONENT_NAME;
|
||||
units[] = {};
|
||||
weapons[] = {};
|
||||
requiredVersion = REQUIRED_VERSION;
|
||||
requiredAddons[] = {"ace_common"};
|
||||
author = ECSTRING(common,ACETeam);
|
||||
authors[] = {"654wak654", "jonpas"};
|
||||
url = ECSTRING(main,URL);
|
||||
VERSION_CONFIG;
|
||||
};
|
||||
};
|
||||
|
||||
#include "CfgEventHandlers.hpp"
|
||||
#include "CfgVehicles.hpp"
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Author: BaerMitUmlaut, 654wak654
|
||||
* Generates the CfgVehicles.hpp to unlock all uniforms.
|
||||
*
|
||||
* Arguments:
|
||||
* None
|
||||
*
|
||||
* Return Value:
|
||||
* CfgVehicles.hpp content <STRING>
|
||||
*
|
||||
* Example:
|
||||
* [] call ace_nouniformrestrictions_fnc_exportConfig
|
||||
*
|
||||
* Public: [Yes]
|
||||
*/
|
||||
#include "script_component.hpp"
|
||||
|
||||
private _modifyClasses = [];
|
||||
private _baseClasses = [];
|
||||
{
|
||||
private _modifyClass = {
|
||||
if (!isNull (_x >> "modelSides")) exitWith {_x};
|
||||
} forEach (configHierarchy _x);
|
||||
private _baseClass = inheritsFrom _modifyClass;
|
||||
_modifyClasses pushBackUnique [_modifyClass, _baseClass];
|
||||
if !(_baseClass in (_modifyClasses apply {_x select 0})) then {
|
||||
_baseClasses pushBackUnique _baseClass;
|
||||
};
|
||||
false
|
||||
} count (
|
||||
("!isNull (_x >> 'modelSides') &&" +
|
||||
"{!(getArray (_x >> 'modelSides') isEqualTo [6])} &&" +
|
||||
"{!(getArray (_x >> 'modelSides') isEqualTo [0,1,2,3])}")
|
||||
configClasses (configFile >> "CfgVehicles")
|
||||
);
|
||||
|
||||
private _nl = toString [13, 10];
|
||||
private _output = "class CfgVehicles {" + _nl;
|
||||
{
|
||||
ADD(_output,format [ARR_3(" class %1;%2",configName _x,_nl)]);
|
||||
false
|
||||
} count _baseClasses;
|
||||
ADD(_output,_nl);
|
||||
{
|
||||
_x params ["_class", "_parent"];
|
||||
ADD(_output,format [ARR_4(" class %1: %2 {%3 modelSides[] = {6};%3 };%3",configName _class,configName _parent,_nl)]);
|
||||
false
|
||||
} count _modifyClasses;
|
||||
ADD(_output,"};");
|
||||
|
||||
copyToClipboard _output;
|
||||
_output;
|
@ -0,0 +1 @@
|
||||
#include "\z\ace\addons\nouniformrestrictions\script_component.hpp"
|
18
optionals/nouniformrestrictions/script_component.hpp
Normal file
18
optionals/nouniformrestrictions/script_component.hpp
Normal file
@ -0,0 +1,18 @@
|
||||
#define COMPONENT nouniformrestrictions
|
||||
#define COMPONENT_BEAUTIFIED No Uniform Restrictions
|
||||
#include "\z\ace\addons\main\script_mod.hpp"
|
||||
|
||||
// #define DEBUG_MODE_FULL
|
||||
// #define DISABLE_COMPILE_CACHE
|
||||
// #define CBA_DEBUG_SYNCHRONOUS
|
||||
// #define ENABLE_PERFORMANCE_COUNTERS
|
||||
|
||||
#ifdef DEBUG_ENABLED_UNIFORMS
|
||||
#define DEBUG_MODE_FULL
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_SETTINGS_UNIFORMS
|
||||
#define DEBUG_SETTINGS DEBUG_SETTINGS_UNIFORMS
|
||||
#endif
|
||||
|
||||
#include "\z\ace\addons\main\script_macros.hpp"
|
234
tools/make.py
234
tools/make.py
@ -30,7 +30,7 @@
|
||||
|
||||
###############################################################################
|
||||
|
||||
__version__ = "0.7"
|
||||
__version__ = "0.8"
|
||||
|
||||
import sys
|
||||
|
||||
@ -51,8 +51,7 @@ import traceback
|
||||
import time
|
||||
import timeit
|
||||
import re
|
||||
|
||||
from tempfile import mkstemp
|
||||
import fileinput
|
||||
|
||||
if sys.platform == "win32":
|
||||
import winreg
|
||||
@ -329,7 +328,6 @@ def print_yellow(msg):
|
||||
|
||||
|
||||
def copy_important_files(source_dir,destination_dir):
|
||||
|
||||
originalDir = os.getcwd()
|
||||
|
||||
# Copy importantFiles
|
||||
@ -340,17 +338,17 @@ def copy_important_files(source_dir,destination_dir):
|
||||
|
||||
for file in importantFiles:
|
||||
filePath = os.path.join(module_root_parent, file)
|
||||
# Take only file name for destination path (to put it into root of release dir)
|
||||
if "\\" in file:
|
||||
count = file.count("\\")
|
||||
file = file.split("\\", count)[-1]
|
||||
print_green("Copying file => {}".format(os.path.join(source_dir,file)))
|
||||
shutil.copyfile(os.path.join(source_dir,filePath),os.path.join(destination_dir,file))
|
||||
if os.path.exists(filePath):
|
||||
print_green("Copying file => {}".format(filePath))
|
||||
shutil.copy(os.path.join(source_dir,filePath), destination_dir)
|
||||
else:
|
||||
missingFiles.append("{}".format(filePath))
|
||||
print_error("Failed copying file => {}".format(filePath))
|
||||
except:
|
||||
print_error("COPYING IMPORTANT FILES.")
|
||||
raise
|
||||
|
||||
#copy all extension dlls
|
||||
# Copy all extension DLL's
|
||||
try:
|
||||
os.chdir(os.path.join(source_dir))
|
||||
print_blue("\nSearching for DLLs in {}".format(os.getcwd()))
|
||||
@ -370,13 +368,13 @@ def copy_important_files(source_dir,destination_dir):
|
||||
os.chdir(originalDir)
|
||||
|
||||
|
||||
|
||||
def copy_optionals_for_building(mod,pbos):
|
||||
src_directories = os.listdir(optionals_root)
|
||||
current_dir = os.getcwd()
|
||||
|
||||
print_blue("\nChecking Optionals folder...")
|
||||
print_blue("\nChecking optionals folder...")
|
||||
try:
|
||||
|
||||
#special server.pbo processing
|
||||
files = glob.glob(os.path.join(release_dir, project, "optionals", "*.pbo"))
|
||||
for file in files:
|
||||
@ -400,7 +398,6 @@ def copy_optionals_for_building(mod,pbos):
|
||||
finally:
|
||||
os.chdir(current_dir)
|
||||
|
||||
print("")
|
||||
try:
|
||||
for dir_name in src_directories:
|
||||
mod.append(dir_name)
|
||||
@ -467,9 +464,10 @@ def cleanup_optionals(mod):
|
||||
|
||||
def purge(dir, pattern, friendlyPattern="files"):
|
||||
print_green("Deleting {} files from directory: {}".format(friendlyPattern,dir))
|
||||
for f in os.listdir(dir):
|
||||
if re.search(pattern, f):
|
||||
os.remove(os.path.join(dir, f))
|
||||
if os.path.exists(dir):
|
||||
for f in os.listdir(dir):
|
||||
if re.search(pattern, f):
|
||||
os.remove(os.path.join(dir, f))
|
||||
|
||||
|
||||
def build_signature_file(file_name):
|
||||
@ -525,13 +523,13 @@ def addon_restore(modulePath):
|
||||
return True
|
||||
|
||||
|
||||
def get_project_version():
|
||||
def get_project_version(version_increments=[]):
|
||||
global project_version
|
||||
versionStamp = project_version
|
||||
#do the magic based on https://github.com/acemod/ACE3/issues/806#issuecomment-95639048
|
||||
|
||||
try:
|
||||
scriptModPath = os.path.join(work_drive, prefix, "main\script_mod.hpp")
|
||||
scriptModPath = os.path.join(module_root, "main\script_version.hpp")
|
||||
|
||||
if os.path.isfile(scriptModPath):
|
||||
f = open(scriptModPath, "r")
|
||||
@ -541,11 +539,36 @@ def get_project_version():
|
||||
if hpptext:
|
||||
majorText = re.search(r"#define MAJOR (.*\b)", hpptext).group(1)
|
||||
minorText = re.search(r"#define MINOR (.*\b)", hpptext).group(1)
|
||||
patchlvlText = re.search(r"#define PATCHLVL (.*\b)", hpptext).group(1)
|
||||
patchText = re.search(r"#define PATCHLVL (.*\b)", hpptext).group(1)
|
||||
buildText = re.search(r"#define BUILD (.*\b)", hpptext).group(1)
|
||||
|
||||
# Increment version (reset all below except build)
|
||||
if version_increments != []:
|
||||
if "major" in version_increments:
|
||||
majorText = int(majorText) + 1
|
||||
minorText = 0
|
||||
patchText = 0
|
||||
elif "minor" in version_increments:
|
||||
minorText = int(minorText) + 1
|
||||
patchText = 0
|
||||
elif "patch" in version_increments:
|
||||
patchText = int(patchText) + 1
|
||||
|
||||
# Always increment build
|
||||
if "build" in version_increments:
|
||||
buildText = int(buildText) + 1
|
||||
|
||||
print_green("Incrementing version to {}.{}.{}.{}".format(majorText,minorText,patchText,buildText))
|
||||
with open(scriptModPath, "w", newline="\n") as file:
|
||||
file.writelines([
|
||||
"#define MAJOR {}\n".format(majorText),
|
||||
"#define MINOR {}\n".format(minorText),
|
||||
"#define PATCHLVL {}\n".format(patchText),
|
||||
"#define BUILD {}\n".format(buildText)
|
||||
])
|
||||
|
||||
if majorText:
|
||||
versionStamp = "{major}.{minor}.{patchlvl}.{build}".format(major=majorText,minor=minorText,patchlvl=patchlvlText,build=buildText)
|
||||
versionStamp = "{}.{}.{}.{}".format(majorText,minorText,patchText,buildText)
|
||||
|
||||
else:
|
||||
print_error("A Critical file seems to be missing or inaccessible: {}".format(scriptModPath))
|
||||
@ -565,22 +588,15 @@ def get_project_version():
|
||||
|
||||
|
||||
def replace_file(filePath, oldSubstring, newSubstring):
|
||||
#Create temp file
|
||||
fh, absPath = mkstemp()
|
||||
with open(absPath,'w') as newFile:
|
||||
with open(filePath) as oldFile:
|
||||
for line in oldFile:
|
||||
newFile.write(line.replace(oldSubstring, newSubstring))
|
||||
newFile.close()
|
||||
#Remove original file
|
||||
os.remove(filePath)
|
||||
#Move new file
|
||||
shutil.move(absPath, filePath)
|
||||
for line in fileinput.input(filePath, inplace=True):
|
||||
# Use stdout directly, print() adds newlines automatically
|
||||
sys.stdout.write(line.replace(oldSubstring,newSubstring))
|
||||
|
||||
|
||||
def set_version_in_files():
|
||||
newVersion = project_version # MAJOR.MINOR.PATCH.BUILD
|
||||
newVersionShort = newVersion[:-2] # MAJOR.MINOR.PATCH
|
||||
newVersionArr = newVersion.split(".")
|
||||
newVersionShort = ".".join((newVersionArr[0],newVersionArr[1],newVersionArr[2])) # MAJOR.MINOR.PATCH
|
||||
|
||||
# Regex patterns
|
||||
pattern = re.compile(r"([\d]+\.[\d]+\.[\d]+\.[\d]+)") # MAJOR.MINOR.PATCH.BUILD
|
||||
@ -598,28 +614,26 @@ def set_version_in_files():
|
||||
f.close()
|
||||
|
||||
if fileText:
|
||||
# Search and save version stamp, search short if long not found
|
||||
versionFound = re.findall(pattern, fileText)
|
||||
if not versionFound:
|
||||
versionFound = re.findall(patternShort, fileText)
|
||||
# Version string files
|
||||
# Search and save version stamp
|
||||
versionsFound = re.findall(pattern, fileText) + re.findall(patternShort, fileText)
|
||||
# Filter out sub-versions of other versions
|
||||
versionsFound = [j for i, j in enumerate(versionsFound) if all(j not in k for k in versionsFound[i + 1:])]
|
||||
|
||||
# Replace version stamp if any of the new version parts is higher than the one found
|
||||
if versionFound:
|
||||
# First item in the list findall returns
|
||||
versionFound = versionFound[0]
|
||||
|
||||
newVersionUsed = ""
|
||||
# Use the same version length as the one found
|
||||
if len(versionFound) == len(newVersion):
|
||||
newVersionUsed = newVersion
|
||||
if len(versionFound) == len(newVersionShort):
|
||||
newVersionUsed = newVersionShort
|
||||
|
||||
# Print change and modify the file if changed
|
||||
if versionFound != newVersionUsed:
|
||||
print_green("Changing version {} => {} in {}".format(versionFound, newVersionUsed, filePath))
|
||||
replace_file(filePath, versionFound, newVersionUsed)
|
||||
for versionFound in versionsFound:
|
||||
if versionFound:
|
||||
# Use the same version length as the one found
|
||||
newVersionUsed = "" # In case undefined
|
||||
if versionFound.count(".") == newVersion.count("."):
|
||||
newVersionUsed = newVersion
|
||||
if versionFound.count(".") == newVersionShort.count("."):
|
||||
newVersionUsed = newVersionShort
|
||||
|
||||
# Print change and modify the file if changed
|
||||
if newVersionUsed and versionFound != newVersionUsed:
|
||||
print_green("Changing version {} => {} in {}".format(versionFound, newVersionUsed, filePath))
|
||||
replace_file(filePath, versionFound, newVersionUsed)
|
||||
except WindowsError as e:
|
||||
# Temporary file is still "in use" by Python, pass this exception
|
||||
pass
|
||||
@ -634,13 +648,17 @@ def stash_version_files_for_building():
|
||||
try:
|
||||
for file in versionFiles:
|
||||
filePath = os.path.join(module_root_parent, file)
|
||||
# Take only file name for stash location if in subfolder (otherwise it gets removed when removing folders from release dir)
|
||||
if "\\" in file:
|
||||
count = file.count("\\")
|
||||
file = file.split("\\", count)[-1]
|
||||
stashPath = os.path.join(release_dir, file)
|
||||
print("Temporarily stashing {} => {}.bak for version update".format(filePath, stashPath))
|
||||
shutil.copy(filePath, "{}.bak".format(stashPath))
|
||||
if os.path.exists(filePath):
|
||||
# Take only file name for stash location if in subfolder (otherwise it gets removed when removing folders from release dir)
|
||||
if "\\" in file:
|
||||
count = file.count("\\")
|
||||
file = file.split("\\", count)[-1]
|
||||
stashPath = os.path.join(release_dir, file)
|
||||
print("Temporarily stashing {} => {}.bak for version update".format(filePath, stashPath))
|
||||
shutil.copy(filePath, "{}.bak".format(stashPath))
|
||||
else:
|
||||
print_error("Failed temporarily stashing {} for version update".format(filePath))
|
||||
missingFiles.append("{}".format(filePath))
|
||||
except:
|
||||
print_error("Stashing version files failed")
|
||||
raise
|
||||
@ -652,6 +670,8 @@ def stash_version_files_for_building():
|
||||
|
||||
def restore_version_files():
|
||||
try:
|
||||
print_blue("\nRestoring version files...")
|
||||
|
||||
for file in versionFiles:
|
||||
filePath = os.path.join(module_root_parent, file)
|
||||
# Take only file name for stash path if in subfolder (otherwise it gets removed when removing folders from release dir)
|
||||
@ -659,8 +679,9 @@ def restore_version_files():
|
||||
count = file.count("\\")
|
||||
file = file.split("\\", count)[-1]
|
||||
stashPath = os.path.join(release_dir, file)
|
||||
print("Restoring {}".format(filePath))
|
||||
shutil.move("{}.bak".format(stashPath), filePath)
|
||||
if os.path.exists(filePath):
|
||||
print("Restoring {}".format(filePath))
|
||||
shutil.move("{}.bak".format(stashPath), filePath)
|
||||
except:
|
||||
print_error("Restoring version files failed")
|
||||
raise
|
||||
@ -669,9 +690,9 @@ def restore_version_files():
|
||||
|
||||
def get_private_keyname(commitID,module="main"):
|
||||
global pbo_name_prefix
|
||||
global project_version
|
||||
|
||||
aceVersion = get_project_version()
|
||||
keyName = str("{prefix}{version}-{commit_id}".format(prefix=pbo_name_prefix,version=aceVersion,commit_id=commitID))
|
||||
keyName = str("{prefix}{version}-{commit_id}".format(prefix=pbo_name_prefix,version=project_version,commit_id=commitID))
|
||||
return keyName
|
||||
|
||||
|
||||
@ -786,6 +807,7 @@ def main(argv):
|
||||
global prefix
|
||||
global pbo_name_prefix
|
||||
global ciBuild
|
||||
global missingFiles
|
||||
|
||||
if sys.platform != "win32":
|
||||
print_error("Non-Windows platform (Cygwin?). Please re-run from cmd.")
|
||||
@ -854,12 +876,9 @@ See the make.cfg file for additional build options.
|
||||
|
||||
if "release" in argv:
|
||||
make_release_zip = True
|
||||
release_version = argv[argv.index("release") + 1]
|
||||
argv.remove(release_version)
|
||||
argv.remove("release")
|
||||
else:
|
||||
make_release_zip = False
|
||||
release_version = project_version
|
||||
|
||||
if "target" in argv:
|
||||
make_target = argv[argv.index("target") + 1]
|
||||
@ -889,8 +908,22 @@ See the make.cfg file for additional build options.
|
||||
else:
|
||||
version_update = False
|
||||
|
||||
if "--ci" in argv:
|
||||
argv.remove("--ci")
|
||||
version_increments = []
|
||||
if "increment_build" in argv:
|
||||
argv.remove("increment_build")
|
||||
version_increments.append("build")
|
||||
if "increment_patch" in argv:
|
||||
argv.remove("increment_patch")
|
||||
version_increments.append("patch")
|
||||
if "increment_minor" in argv:
|
||||
argv.remove("increment_minor")
|
||||
version_increments.append("minor")
|
||||
if "increment_major" in argv:
|
||||
argv.remove("increment_major")
|
||||
version_increments.append("major")
|
||||
|
||||
if "ci" in argv:
|
||||
argv.remove("ci")
|
||||
ciBuild = True
|
||||
|
||||
print_yellow("\nCheck external references is set to {}".format(str(check_external)))
|
||||
@ -956,21 +989,21 @@ See the make.cfg file for additional build options.
|
||||
optionals_root = os.path.join(module_root_parent, "optionals")
|
||||
extensions_root = os.path.join(module_root_parent, "extensions")
|
||||
|
||||
commit_id = get_commit_ID()
|
||||
key_name = versionStamp = get_private_keyname(commit_id)
|
||||
print_green ("module_root: {}".format(module_root))
|
||||
|
||||
if (os.path.isdir(module_root)):
|
||||
os.chdir(module_root)
|
||||
else:
|
||||
print_error ("Directory {} does not exist.".format(module_root))
|
||||
sys.exit()
|
||||
sys.exit(1)
|
||||
|
||||
commit_id = get_commit_ID()
|
||||
get_project_version(version_increments)
|
||||
key_name = versionStamp = get_private_keyname(commit_id)
|
||||
print_green ("module_root: {}".format(module_root))
|
||||
|
||||
if (os.path.isdir(optionals_root)):
|
||||
print_green ("optionals_root: {}".format(optionals_root))
|
||||
else:
|
||||
print_error ("Directory {} does not exist.".format(optionals_root))
|
||||
sys.exit()
|
||||
print("optionals_root does not exist: {}".format(optionals_root))
|
||||
|
||||
print_green ("release_dir: {}".format(release_dir))
|
||||
|
||||
@ -1022,7 +1055,6 @@ See the make.cfg file for additional build options.
|
||||
cache = {}
|
||||
|
||||
# Check the build version (from main) with cached version - forces a full rebuild when version changes
|
||||
project_version = get_project_version()
|
||||
cacheVersion = "None";
|
||||
if 'cacheVersion' in cache:
|
||||
cacheVersion = cache['cacheVersion']
|
||||
@ -1046,6 +1078,9 @@ See the make.cfg file for additional build options.
|
||||
print_error("Cannot create release directory")
|
||||
raise
|
||||
|
||||
failedBuilds = []
|
||||
missingFiles = []
|
||||
|
||||
# Update version stamp in all files that contain it
|
||||
# Update version only for release if full update not requested (backup and restore files)
|
||||
print_blue("\nChecking for obsolete version numbers...")
|
||||
@ -1056,14 +1091,12 @@ See the make.cfg file for additional build options.
|
||||
set_version_in_files();
|
||||
print("Version in files has been changed, make sure you commit and push the updates!")
|
||||
|
||||
amountOfBuildsFailed = 0
|
||||
namesOfBuildsFailed = []
|
||||
|
||||
try:
|
||||
# Temporarily copy optionals_root for building. They will be removed later.
|
||||
optionals_modules = []
|
||||
optional_files = []
|
||||
copy_optionals_for_building(optionals_modules,optional_files)
|
||||
if (os.path.isdir(optionals_root)):
|
||||
optionals_modules = []
|
||||
optional_files = []
|
||||
copy_optionals_for_building(optionals_modules,optional_files)
|
||||
|
||||
# Get list of subdirs in make root.
|
||||
dirs = next(os.walk(module_root))[1]
|
||||
@ -1128,15 +1161,14 @@ See the make.cfg file for additional build options.
|
||||
if (file.endswith(".pbo") and os.path.isfile(os.path.join(obsolete_check_path,file))):
|
||||
if check_for_obsolete_pbos(module_root, file):
|
||||
fileName = os.path.splitext(file)[0]
|
||||
print_yellow("Removing obsolete file => {}".format(file))
|
||||
print_yellow("Removing obsolete pbo => {}".format(file))
|
||||
purge(obsolete_check_path, "{}\..".format(fileName), "{}.*".format(fileName))
|
||||
|
||||
obsolete_check_path = os.path.join(module_root, release_dir, project)
|
||||
for file in os.listdir(obsolete_check_path):
|
||||
if (file.endswith(".dll") and os.path.isfile(os.path.join(obsolete_check_path,file))):
|
||||
if check_for_obsolete_pbos(extensions_root, file):
|
||||
fileName = os.path.splitext(file)[0]
|
||||
print_yellow("Removing obsolete file => {}".format(file))
|
||||
if not os.path.exists(os.path.join(module_root_parent, file)):
|
||||
print_yellow("Removing obsolete dll => {}".format(file))
|
||||
try:
|
||||
os.remove(os.path.join(obsolete_check_path,file))
|
||||
except:
|
||||
@ -1282,8 +1314,7 @@ See the make.cfg file for additional build options.
|
||||
print_error("pboProject return code == {}".format(str(ret)))
|
||||
print_error("Module not successfully built/signed. Check your {}temp\{}_packing.log for more info.".format(work_drive,module))
|
||||
print ("Resuming build...")
|
||||
amountOfBuildsFailed += 1
|
||||
namesOfBuildsFailed.append("{}".format(module))
|
||||
failedBuilds.append("{}".format(module))
|
||||
continue
|
||||
|
||||
# Back to the root
|
||||
@ -1379,7 +1410,8 @@ See the make.cfg file for additional build options.
|
||||
|
||||
finally:
|
||||
copy_important_files(module_root_parent,os.path.join(release_dir, project))
|
||||
cleanup_optionals(optionals_modules)
|
||||
if (os.path.isdir(optionals_root)):
|
||||
cleanup_optionals(optionals_modules)
|
||||
if not version_update:
|
||||
restore_version_files()
|
||||
|
||||
@ -1399,8 +1431,7 @@ See the make.cfg file for additional build options.
|
||||
|
||||
# Make release
|
||||
if make_release_zip:
|
||||
release_name = "{}_{}".format(zipPrefix, release_version)
|
||||
print_blue("\nMaking release: {}.zip".format(release_name))
|
||||
release_name = "{}_{}".format(zipPrefix, project_version)
|
||||
|
||||
try:
|
||||
# Delete all log files
|
||||
@ -1415,7 +1446,10 @@ See the make.cfg file for additional build options.
|
||||
os.remove(os.path.join(release_dir, file))
|
||||
|
||||
# Create a zip with the contents of release folder in it
|
||||
print_blue("\nMaking release: {}.zip ...".format(release_name))
|
||||
print("Packing...")
|
||||
release_zip = shutil.make_archive("{}".format(release_name), "zip", release_dir)
|
||||
|
||||
# Move release zip to release folder
|
||||
shutil.copy(release_zip, release_dir)
|
||||
os.remove(release_zip)
|
||||
@ -1450,15 +1484,23 @@ See the make.cfg file for additional build options.
|
||||
except:
|
||||
print_error("Could not copy files. Is Arma 3 running?")
|
||||
|
||||
if amountOfBuildsFailed > 0:
|
||||
print_error("Build failed. {} pbos failed.".format(amountOfBuildsFailed))
|
||||
if len(failedBuilds) > 0 or len(missingFiles) > 0:
|
||||
if len(failedBuilds) > 0:
|
||||
print()
|
||||
print_error("Build failed! {} PBOs failed!".format(len(failedBuilds)))
|
||||
for failedBuild in failedBuilds:
|
||||
print("- {} failed.".format(failedBuild))
|
||||
|
||||
for failedModuleName in namesOfBuildsFailed:
|
||||
print("- {} failed.".format(failedModuleName))
|
||||
if len(missingFiles) > 0:
|
||||
missingFiles = set(missingFiles)
|
||||
print()
|
||||
print_error("Missing files! {} files not found!".format(len(missingFiles)))
|
||||
for missingFile in missingFiles:
|
||||
print("- {} failed.".format(missingFile))
|
||||
|
||||
sys.exit(1)
|
||||
else:
|
||||
print_green("\Completed with 0 errors.")
|
||||
print_green("\nCompleted with 0 errors.")
|
||||
|
||||
if __name__ == "__main__":
|
||||
start_time = timeit.default_timer()
|
||||
|
Loading…
Reference in New Issue
Block a user