Changed drag/carry to event driven architecture

This commit is contained in:
Thomas Kooi 2015-01-20 18:57:33 +01:00
parent 8554cf7e6c
commit 9a0b73bf3a
10 changed files with 159 additions and 79 deletions

View File

@ -1,12 +1,12 @@
class Extended_PreInit_EventHandlers {
class ADDON {
init = QUOTE( call compile preprocessFileLineNumbers QUOTE(QUOTE(PATHTOF(XEH_preInit.sqf))));
init = QUOTE(call COMPILE_FILE(XEH_preInit));
};
};
class Extended_PostInit_EventHandlers {
class ADDON {
init = QUOTE( call compile preprocessFileLineNumbers QUOTE(QUOTE(PATHTOF(XEH_postInit.sqf))));
init = QUOTE(call COMPILE_FILE(XEH_postInit));
};
};

View File

@ -48,6 +48,8 @@ call FUNC(handleDisplayEffects);
["Medical_treatmentCompleted", FUNC(onTreatmentCompleted)] call ace_common_fnc_addEventHandler;
["onStartMovingUnit", FUNC(onStartMovingUnit)] call ace_common_fnc_addEventHandler;
["onUnconscious", FUNC(onUnconscious)] call ace_common_fnc_addEventHandler;
["carryObjectDropped", FUNC(onCarryObjectDropped)] call ace_common_fnc_addEventHandler;
// Keybindings

View File

@ -78,6 +78,7 @@ PREP(handleTreatment_Category_Medication);
PREP(handleUI_DisplayOptions);
PREP(handleUI_dropDownTriageCard);
PREP(handleUnitVitals);
PREP(handleDropUnit);
PREP(hasEquipment);
PREP(hasMedicalEnabled);
@ -106,6 +107,7 @@ PREP(onMenuOpen);
PREP(onTreatmentCompleted);
PREP(onUnconscious);
PREP(onStartMovingUnit);
PREP(onCarryObjectDropped);
PREP(openMenu);
PREP(playInjuredSound);

View File

@ -53,7 +53,7 @@ _unit attachTo [_caller, [0.1, -0.1, -1.25], "LeftShoulder"];
[_unit,"AinjPfalMstpSnonWnonDf_carried_dead",1] call EFUNC(common,doAnimation);
_caller setvariable [QGVAR(StartingPositionHandleTreatment), getPos _caller];
[3,
[1,
{((vehicle (_this select 0) != (_this select 0)) ||((getPos (_this select 0)) distance ((_this select 0) getvariable QGVAR(StartingPositionHandleTreatment)) < 1.5))}, // the condition
{
private ["_caller","_target"];

View File

@ -56,7 +56,7 @@ if (currentWeapon _caller == primaryWeapon _caller) then {
};
_caller setvariable [QGVAR(StartingPositionHandleTreatment), getPos _caller];
[3,
[1,
{((vehicle (_this select 0) != (_this select 0)) ||((getPos (_this select 0)) distance ((_this select 0) getvariable QGVAR(StartingPositionHandleTreatment)) < 1.5))}, // the condition
{
private ["_caller","_target"];

View File

@ -17,9 +17,8 @@ private ["_caller", "_unit","_info","_draggedPerson"];
_caller = _this select 0;
_unit = _this select 1;
[_caller,objNull] call EFUNC(common,carryObj);
if (!isnil QGVAR(DROP_ADDACTION)) then {
_caller removeAction GVAR(DROP_ADDACTION);
[_caller,objNull] call EFUNC(common,carryObj);
_caller removeAction GVAR(DROP_ADDACTION);
GVAR(DROP_ADDACTION) = nil;
};
};

View File

@ -10,6 +10,8 @@
#include "script_component.hpp"
#define ARMOURCOEF 2
private ["_unit","_selectionName","_amountOfDamage","_sourceOfDamage", "_typeOfProjectile","_bodyPartn","_newDamage","_typeOfDamage","_caliber", "_hitPointName", "_returnDamage", "_varCheck"];
_unit = _this select 0;
_selectionName = _this select 1;
@ -18,6 +20,14 @@ _sourceOfDamage = _this select 3;
_typeOfProjectile = _this select 4;
_returnDamage = _amountOfDamage;
// From AGM
// This seems to only show up in MP too, but since it doesn't
// collide with anything, I'll check it in SP as well.
if (_selectionName == "r_femur_hit") then {
_selectionName = "leg_r";
};
_bodyPartn = [_selectionName] call FUNC(getBodyPartNumber);
// Check for vehicle crash
@ -46,6 +56,28 @@ if (local _unit && {([_unit] call FUNC(hasMedicalEnabled))}) then {
[_unit, _bodyPartn, _amountOfDamage] call FUNC(setDamageBodyPart);
_newDamage = [_unit, _amountOfDamage, _bodyPartn] call FUNC(getNewDamageBodyPart);
// From AGM medical:
// Exclude falling damage to everything other than legs; reduce structural damage.
if (((velocity _unit) select 2 < -5) && (vehicle _unit == _unit)) then {
_unit setVariable [QGVAR(isFalling), True];
};
if (_unit getVariable [QGVAR(isFalling), false] && !(_selectionName in ["", "leg_l", "leg_r"])) exitWith {};
if (_unit getVariable [QGVAR(isFalling), false]) then {
_newDamage = _newDamage * 0.7;
};
// Increase damage for kinetic penetrators for people inside vehicles
// to simulate hot spikey things flying around (generally unpleasant).
if ((["ACE_Armour"] call EFUNC(common,isModLoaded_f)) && _projectile != "" && vehicle _unit != _unit) then {
_hit = getNumber (configFile >> "CfgAmmo" >> _projectile >> "hit");
if (_hit >= 100) then {
_hit = linearConversion [100, 1000, _hit, 0, ARMOURCOEF, True];
_newDamage = _newDamage * (1 + _hit);
};
};
// TODO collect everything for 3 frames, then execute the handling for the damage.
// figure out the type of damage so we can use that to determine what injures should be given.
_typeOfDamage = [_typeOfProjectile] call FUNC(getTypeOfDamage);

View File

@ -0,0 +1,92 @@
/**
* fnc_handleDropUnit.sqf
* @Descr: N/A
* @Author: Glowbal
*
* @Arguments: []
* @Return:
* @PublicAPI: false
*/
#include "script_component.hpp"
private ["_caller","_target","_killOnDrop","_dragging"];
_caller = _params select 0;
_target = _params select 1;
_killOnDrop = _params select 2;
_dragging = _params select 3;
[format["fnc_handleDropUnit: %1",_this]] call EFUNC(common,debug);
if ((isNull ([_caller] call EFUNC(common,getCarriedObj))) || !([_caller] call EFUNC(common,isAwake)) || (vehicle _caller != _caller)) then {
[_target, false] call EFUNC(common,disableAI_f);
[format["fnc_handleDropUnit: %1 - additional dropping of object", _caller]] call EFUNC(common,debug);
[_caller,ObjNull] call EFUNC(common,carryObj);
[format["fnc_handleDropUnit: %1 - Clearing parameters", _caller]] call EFUNC(common,debug);
_caller setvariable[QGVAR(onStartMovingUnitParams), nil];
// handle the drag & carry administration
if (_dragging) then {
_target setvariable [QGVAR(beingDragged),nil,true];
_caller setvariable [QGVAR(dragging),nil,true];
} else {
_target setvariable [QGVAR(beingCarried),nil,true];
_caller setvariable [QGVAR(carrying),nil,true];
};
[format["fnc_handleDropUnit: %1 - Reset the variables", _caller]] call EFUNC(common,debug);
// handle the drag & carry animiations
if ([_caller] call EFUNC(common,isAwake) && (vehicle _caller == _caller)) then {
if (vehicle _caller == _caller) then {
[_caller,"amovpercmstpsraswrfldnon_amovpknlmstpslowwrfldnon", 1] call EFUNC(common,doAnimation);
[format["Placing animation: getting normal again", _caller]] call EFUNC(common,debug);
};
};
if ([_target] call EFUNC(common,isAwake)) then {
if (vehicle _target == _target) then {
if (_dragging) then {
[_target,"AinjPpneMstpSnonWrflDb_release",1] call EFUNC(common,doAnimation);
} else {
[_target,"",1] call EFUNC(common,doAnimation);
};
} else {
[_target,"", 1] call EFUNC(common,doAnimation); // TODO play animation for the current seat instead
};
} else {
// TODO play animation for dropping first.
[_target,([_target] call EFUNC(common,getDeathAnim)), 1] call EFUNC(common,doAnimation);
};
if (!surfaceIsWater getPos _caller) then {
[{
EXPLODE_3_PVT(_this,_caller,_target,_killOnDrop);
if (vehicle _target == _target && (vehicle _caller == _caller)) then {
// This will set the target body/unit on the correct position, so it doesn't fall through floors.
_positionUnit = getPosATL _target;
_positionUnit set [2, (getPosATL _caller) select 2];
_target setPosATL _positionUnit;
};
if (_killOnDrop) then {
_unit setDamage 1;
};
}, [_caller,_target,_killOnDrop], 0.5, 0.5] call EFUNC(common,waitAndExecute);
} else {
if (_killOnDrop) then {
_unit setDamage 1;
};
};
["onDropInjured", [_caller], [_caller, _unit, 0]] call EFUNC(common,targetEvent);
};

View File

@ -0,0 +1,21 @@
/**
* fnc_onCarryObjectDropped.sqf
* @Descr: N/A
* @Author: Glowbal
*
* @Arguments: []
* @Return:
* @PublicAPI: false
*/
#include "script_component.hpp"
private ["_unit","_params"];
_unit = _this select 0;
[format["fnc_onCarryObjectDropped: %1",_this]] call EFUNC(common,debug);
_params = _unit getvariable QGVAR(onStartMovingUnitParams);
if (!isnil "_params") then {
_params call FUNC(handleDropUnit);
};

View File

@ -1,8 +1,6 @@
/**
* fnc_onStartMovingUnit.sqf
* @Descr: is called when a unit start to move another unit through either carry or drag actions.
* This will monitor until the caller (unit carrying another unit) is no longer awake, in a vehicle or dropped the unit,
* after which it will handle the required animations and administration.
*
* @Author: Glowbal
*
@ -13,8 +11,6 @@
#include "script_component.hpp"
// Time in seconds. There is no need to run this every frame, but it should still be in real time. The user should not experience any delays here.
#define TIME_BETWEEN_CHECKS 0.1
private ["_caller","_target","_killOnDrop","_dragging"];
_caller = _this select 0;
@ -22,72 +18,8 @@ _target = _this select 1;
_killOnDrop = _this select 2;
_dragging = _this select 3;
[{
private ["_caller","_target","_killOnDrop","_dragging"];
_caller = (_this select 0) select 0;
_target = (_this select 0) select 1;
_killOnDrop = (_this select 0) select 2;
_dragging = (_this select 0) select 3;
_caller setvariable[QGVAR(onStartMovingUnitParams), [_caller, _target, _killOnDrop, _dragging]];
if ((isNull ([_caller] call EFUNC(common,getCarriedObj))) || !([_caller] call EFUNC(common,isAwake)) || (vehicle _caller != _caller)) then {
[_caller,ObjNull] call EFUNC(common,carryObj);
[_target, true] call EFUNC(common,disableAI_f);
// handle the drag & carry administration
if (_dragging) then {
_target setvariable [QGVAR(beingDragged),objNull,true];
_caller setvariable [QGVAR(dragging),objNull,true];
} else {
_target setvariable [QGVAR(beingCarried),objNull,true];
_caller setvariable [QGVAR(carrying),objNull,true];
};
// handle the drag & carry animiations
if ([_caller] call EFUNC(common,isAwake) && (vehicle _caller == _caller)) then {
if (vehicle _caller == _caller) then {
[_caller,"amovpercmstpsraswrfldnon_amovpknlmstpslowwrfldnon", 1] call EFUNC(common,doAnimation);
};
};
if ([_target] call EFUNC(common,isAwake)) then {
if (vehicle _target == _target) then {
if (_dragging) then {
[_target,"AinjPpneMstpSnonWrflDb_release",1] call EFUNC(common,doAnimation);
} else {
[_target,"",1] call EFUNC(common,doAnimation);
};
} else {
[_target,"", 1] call EFUNC(common,doAnimation); // TODO play animation for the current seat instead
};
} else {
// TODO play animation for dropping first.
[_target,([_target] call EFUNC(common,getDeathAnim)), 1] call EFUNC(common,doAnimation);
};
if (!surfaceIsWater getPos _caller) then {
[{
EXPLODE_3_PVT(_this,_caller,_target,_killOnDrop);
if (vehicle _target == _target && (vehicle _caller == _caller)) then {
// This will set the target body/unit on the correct position, so it doesn't fall through floors.
_positionUnit = getPosATL _target;
_positionUnit set [2, (getPosATL _caller) select 2];
_target setPosATL _positionUnit;
};
if (_killOnDrop) then {
_unit setDamage 1;
};
}, [_caller,_target,_killOnDrop], 0.5, 0.5] call EFUNC(common,waitAndExecute);
} else {
if (_killOnDrop) then {
_unit setDamage 1;
};
};
["onDropInjured", [_caller], [_caller, _unit, 0]] call EFUNC(common,targetEvent);
[(_this select 1)] call cba_fnc_removePerFrameHandler;
};
}, TIME_BETWEEN_CHECKS, [_caller, _unit, _killOnDrop, _dragging] ] call CBA_fnc_addPerFrameHandler;
nil;