Port AGM cook off

This commit is contained in:
commy2 2016-07-14 16:16:53 +02:00
parent 0dfee34a56
commit c42004449d
18 changed files with 573 additions and 0 deletions

View File

@ -0,0 +1 @@
z\ace\addons\cookoff

View File

@ -0,0 +1,54 @@
class CfgCloudlets {
class GVAR(CookOff) {
interval = 0.004;
circleRadius = 0;
circleVelocity[] = {2,2,2};
particleShape = "\A3\data_f\ParticleEffects\Universal\Universal";
particleFSNtieth = 16;
particleFSIndex = 0;
particleFSFrameCount = 32;
particleFSLoop = 0;
angle = 0;
angleVar = 0;
animationName = "";
particleType = "Billboard";
timerPeriod = 1;
lifeTime = 1;
moveVelocity[] = {0,4,0};
rotationVelocity = 1;
weight = 0.4;
volume = 0.45;
rubbing = 0;
size[] = {0.01,0.5,1,1,1.5,0.01,0.001};
color[] = {{1,1,1,-4},{1,1,1,-3},{1,1,1,-2},{1,1,1,-1},{1,1,1,0}};
animationSpeed[] = {1};
randomDirectionPeriod = 5;
randomDirectionIntensity = 1;
onTimerScript = "";
beforeDestroyScript = "";
position[] = {0,0,0};
lifeTimeVar = 0;
positionVar[] = {0,0,0};
positionVarConst[] = {0,0,0};
moveVelocityVar[] = {1,2,1};
moveVelocityVarConst[] = {0,0,0};
rotationVelocityVar = 3;
sizeVar = 0.1;
colorVar[] = {0,0,0,2};
randomDirectionPeriodVar = 1;
randomDirectionIntensityVar = 2;
colorCoef[] = {1,1,1,1};
sizeCoef = 1;
animationSpeedCoef = 1;
particleEffects = "";
postEffects = "";
onSurface = 1;
surfaceOffset = 0;
keepOnSurface = 0;
bounceOnSurface = 0.6;
bounceOnSurfaceVar = 0;
destroyOnWaterSurface = 0;
destroyOnWaterSurfaceOffset = 0;
};
};

View File

@ -0,0 +1,18 @@
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));
};
};
class Extended_PostInit_EventHandlers {
class ADDON {
init = QUOTE(call COMPILE_FILE(XEH_postInit));
};
};

View File

@ -0,0 +1,9 @@
class CfgSFX {
class GVAR(CookOff) {
name = QGVAR(cookoff);
sounds[] = {QGVAR(cookoff)};
GVAR(cookoff)[] = {PATHTOF(sounds\cookoff.wss),6,1.8,400,1,0,0,0};
empty[] = {"",0,0,0,0,0,0,0};
};
};

View File

@ -0,0 +1,56 @@
class CfgVehicles {
class Sound;
class GVAR(Sound): Sound {
author = ECSTRING(common,ACETeam);
_generalMacro = QGVAR(Sound);
scope = 1;
sound = QGVAR(CookOff);
};
class ThingX;
class GVAR(Turret_MBT_01): ThingX {
author = ECSTRING(common,ACETeam);
_generalMacro = QGVAR(TurretDummy);
scope = 1;
model = "\A3\Structures_F\Wrecks\Wreck_Slammer_turret_F.p3d";
};
class GVAR(Turret_MBT_02): ThingX {
author = ECSTRING(common,ACETeam);
_generalMacro = QGVAR(TurretDummy);
scope = 1;
model = "\A3\Structures_F\Wrecks\Wreck_T72_turret_F.p3d";
};
class Tank;
class Tank_F: Tank {
GVAR(ammoLocation) = "HitTurret";
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 Car_F;
class Wheeled_APC_F: Car_F {
GVAR(ammoLocation) = "HitTurret";
GVAR(cookoffSelections)[] = {"poklop_gunner","poklop_commander"};
// big explosions for wheeled APCs (same as for tanks)
explosionEffect = "FuelExplosionBig";
};
class B_MBT_01_base_F;
class B_MBT_01_cannon_F: B_MBT_01_base_F {
GVAR(turret)[] = {QGVAR(Turret_MBT_01),{0,-1,0.5}};
};
class O_MBT_02_base_F;
class O_MBT_02_cannon_F: O_MBT_02_base_F {
GVAR(turret)[] = {QGVAR(Turret_MBT_02),{0,-1,0}};
};
};

View File

@ -0,0 +1,6 @@
PREP(handleDamage);
PREP(engineFire);
PREP(cookOff);
PREP(blowOffTurret);
PREP(secondaryExplosions);

View File

@ -0,0 +1,31 @@
#include "script_component.hpp"
[QGVAR(engineFire), FUNC(engineFire)] call CBA_fnc_addEventHandler;
[QGVAR(cookOff), FUNC(cookOff)] call CBA_fnc_addEventHandler;
// cookoff and burning engine
["Tank", "init", {
(_this select 0) addEventHandler ["HandleDamage", {
["tank", _this] call FUNC(handleDamage);
}];
}, nil, nil, true] call CBA_fnc_addClassEventHandler;
["Wheeled_APC_F", "init", {
(_this select 0) addEventHandler ["HandleDamage", {
["tank", _this] call FUNC(handleDamage);
}];
}, nil, nil, true] call CBA_fnc_addClassEventHandler;
["Car", "init", {
(_this select 0) addEventHandler ["HandleDamage", {
["car", _this] call FUNC(handleDamage);
}];
}, nil, ["Wheeled_APC_F"], true] call CBA_fnc_addClassEventHandler;
// secondary explosions
["AllVehicles", "killed", {(_this select 0) call FUNC(secondaryExplosions)}, nil, ["Man"]] call CBA_fnc_addClassEventHandler;
// blow off turret effect
["Tank", "killed", {(_this select 0) call FUNC(blowOffTurret)}] call CBA_fnc_addClassEventHandler;
//Reammobox_F

View File

@ -0,0 +1,7 @@
#include "script_component.hpp"
ADDON = false;
#include "XEH_PREP.hpp"
ADDON = true;

View File

@ -0,0 +1,3 @@
#include "script_component.hpp"
#include "XEH_PREP.hpp"

21
addons/cookoff/config.cpp Normal file
View File

@ -0,0 +1,21 @@
#include "script_component.hpp"
class CfgPatches {
class ADDON {
name = COMPONENT_NAME;
units[] = {QGVAR(Sound),QGVAR(Turret_MBT_01),QGVAR(Turret_MBT_02)};
weapons[] = {};
requiredVersion = REQUIRED_VERSION;
requiredAddons[] = {"ace_common"};
author = ECSTRING(common,ACETeam);
authors[] = {"commy2"};
url = ECSTRING(main,URL);
VERSION_CONFIG;
};
};
#include "CfgEventHandlers.hpp"
#include "CfgCloudlets.hpp"
#include "CfgSFX.hpp"
#include "CfgVehicles.hpp"

View File

@ -0,0 +1,33 @@
/*
* Author: commy2
* Blow off turret effect.
*
* Arguments:
* 0: Vehicle <Object>
*
* Return Value:
* None
*
* Example:
* (vehicle player) call ace_cookoff_fnc_blowOffTurret
*
* Public: No
*/
#include "script_component.hpp"
// delayed so the object is spawned after the model changes to a wreck
// the sudden change in the model would cause nearby physx objects to get stuck
[{
params ["_vehicle"];
private _config = _vehicle call CBA_fnc_getObjectConfig;
getArray (_config >> QGVAR(turret)) params [["_model", "", [""]], ["_offset", [0,0,0], [[]], 3]];
if (_model isEqualTo "") exitWith {};
private _position = _vehicle modelToWorld _offset;
private _turret = createVehicle [_model, _position, [], 0, "CAN_COLLIDE"];
_turret setVectorUp [random 1, random 1, 1];
_turret setVelocity [random 7, random 7, 8 + random 5];
}, _this, 1] call CBA_fnc_waitAndExecute;

View File

@ -0,0 +1,126 @@
/*
* Author: KoffeinFlummi, commy2
* Start a cook-off in the given vehicle.
*
* Arguments:
* 0: Vehicle <Object>
*
* Return Value:
* None
*
* Example:
* (vehicle player) call ace_cookoff_fnc_cookOff
*
* Public: No
*/
#include "script_component.hpp"
params ["_vehicle"];
if (_vehicle getVariable [QGVAR(isCookingOff), false]) exitWith {};
_vehicle setVariable [QGVAR(isCookingOff), true];
[QGVAR(cookOff), _vehicle] call CBA_fnc_remoteEvent;
[{
params ["_vehicle"];
private _config = _vehicle call CBA_fnc_getObjectConfig;
private _positions = getArray (_config >> QGVAR(cookoffSelections)) select {!((_vehicle selectionPosition _x) isEqualTo [0,0,0])};
if (_positions isEqualTo []) then {
ACE_LOGWARNING_1("no valid selection for cookoff found. %1", typeOf _vehicle);
_positions pushBack "#noselection";
};
private _turretConfig = [_vehicle, [0]] call CBA_fnc_getTurret;
private _positionBarrelEnd = getText (_turretConfig >> "gunBeg");
// smoke out of cannon and hatches
private _smokeBarrel = "#particlesource" createVehicleLocal [0,0,0];
_smokeBarrel setParticleClass "MediumDestructionSmoke";
_smokeBarrel attachTo [_vehicle, [0,0,0], _positionBarrelEnd];
private _effects = [_smokeBarrel];
{
private _position = [0,-2,0];
if !(_x isEqualTo "#noselection") then {
_position = _vehicle selectionPosition _x;
};
private _smoke = "#particlesource" createVehicleLocal [0,0,0];
_smoke setParticleClass "ObjectDestructionSmoke1_2Smallx";
_smoke attachTo [_vehicle, _position];
_effects pushBack _smoke;
} forEach _positions;
[{
params ["_vehicle", "_effects", "_positions"];
// this shit is busy being on fire, can't go driving around all over the place
if (local _vehicle) then {
_vehicle setFuel 0;
};
private _light = "#lightpoint" createVehicleLocal [0,0,0];
_light setLightBrightness 0.7;
_light setLightAmbient [1,0.4,0.15];
_light setLightColor [1,0.4,0.15];
_light lightAttachObject [_vehicle, [0,0,4]];
_effects pushBack _light;
// cookoffs
{
private _position = [0,-2,0];
if !(_x isEqualTo "#noselection") then {
_position = _vehicle selectionPosition _x;
};
private _fire = "#particlesource" createVehicleLocal [0,0,0];
_fire setParticleClass QGVAR(CookOff);
_fire attachTo [_vehicle, _position];
_effects pushBack _fire;
} forEach _positions;
if (isServer) then {
private _sound = createSoundSource [QGVAR(Sound), position _vehicle, [], 0];
_effects pushBack _sound;
};
// indicator for the crew - yo, your shit's on fire
private _fnc_FlameEffect = {
params ["_vehicle", "_fnc_FlameEffect", "_counter"];
if (_vehicle == cameraOn) then {
[] call BIS_fnc_flamesEffect;
};
DEC(_counter);
if (_counter > 0) then {
[_fnc_FlameEffect, [_vehicle, _fnc_FlameEffect, _counter], 0.4] call CBA_fnc_waitAndExecute
};
};
[_vehicle, _fnc_FlameEffect, 12] call _fnc_FlameEffect; // recursive function
[{
params ["_vehicle", "_effects"];
{
deleteVehicle _x;
} forEach _effects;
if (local _vehicle) then {
_vehicle setDamage 1;
};
}, [_vehicle, _effects], 4 + random 1] call CBA_fnc_waitAndExecute;
}, [_vehicle, _effects, _positions], 3 + random 2] call CBA_fnc_waitAndExecute;
}, _vehicle, 0.5 + random 0.3] call CBA_fnc_waitAndExecute;

View File

@ -0,0 +1,43 @@
/*
* Author: KoffeinFlummi, commy2
* Start fire in engine block of a car.
*
* Arguments:
* 0: Vehicle <Object>
*
* Return Value:
* None
*
* Example:
* (vehicle player) call ace_cookoff_fnc_engineFire
*
* Public: No
*/
#include "script_component.hpp"
params ["_vehicle"];
if (_vehicle getVariable [QGVAR(isEngineSmoking), false]) exitWith {};
_vehicle setVariable [QGVAR(isEngineSmoking), true];
[QGVAR(engineFire), _vehicle] call CBA_fnc_remoteEvent;
private _position = [
0,
(boundingBoxReal _vehicle select 1 select 1) - 4,
(boundingBoxReal _vehicle select 0 select 2) + 2
];
private _smoke = "#particlesource" createVehicleLocal [0,0,0];
_smoke setParticleClass "ObjectDestructionSmoke1_2Smallx";
_smoke attachTo [_vehicle, _position];
[{
(_this select 0) params ["_vehicle", "_smoke", "_time"];
if (!alive _vehicle || {_vehicle getHitPointDamage "HitEngine" < 0.9} || {CBA_missionTime > _time}) then {
deleteVehicle _smoke;
_vehicle setVariable [QGVAR(isEngineSmoking), false];
[_this select 1] call CBA_fnc_removePerFrameHandler;
};
}, 5, [_vehicle, _smoke, CBA_missionTime + 240]] call CBA_fnc_addPerFrameHandler;

View File

@ -0,0 +1,80 @@
/*
* Author: KoffeinFlummi, commy2
* Handles all incoming damage for tanks (including wheeled APCs).
*
* Arguments:
* HandleDamage EH
*
* Return Value:
* Damage to be inflicted.
*
* Example:
* _this call ace_cookoff_fnc_handleDamage
*
* Public: No
*/
#include "script_component.hpp"
params ["_simulationType", "_thisHandleDamage"];
_thisHandleDamage params ["_vehicle", "", "_damage", "", "_ammo", "_hitIndex"];
// it's already dead, who cares?
if (damage _vehicle >= 1) exitWith {};
// get hitpoint name
private _hitpoint = "#structural";
if (_hitIndex != -1) then {
_hitpoint = toLower ((getAllHitPointsDamage _vehicle param [0, []]) select _hitIndex);
};
// get change in damage
private "_oldDamage";
if (_hitpoint isEqualTo "#structural") then {
_oldDamage = damage _vehicle;
} else {
_oldDamage = _vehicle getHitIndex _hitIndex;
};
private _newDamage = _damage - _oldDamage;
// handle different types of vehicles
// note: exitWith only works here, because this is not the main scope of handleDamage
// you cannot use the return value together with exitWith in the main scope, it's a bug
// also, we add this event handler with the addEventHandler SQF command,
// because the config version ignores the return value completely
if (_simulationType == "car") exitWith {
// prevent destruction, let cook-off handle it if necessary
if (_hitpoint in ["hithull", "hitfuel", "#structural"] && {!IS_EXPLOSIVE_AMMO(_ammo)}) then {
_damage min 0.89
} else {
if (_hitpoint isEqualTo "hitengine" && {_damage > 0.9}) then {
_vehicle call FUNC(engineFire);
};
_damage
};
};
if (_simulationType == "tank") exitWith {
// determine ammo storage location
private _ammoLocationHitpoint = getText (_vehicle call CBA_fnc_getObjectConfig >> QGVAR(ammoLocation));
// ammo was hit, high chance for cook-off
if (_hitpoint == _ammoLocationHitpoint) then {
if (_damage > 0.5 && {random 1 < 0.7}) then {
_vehicle call FUNC(cookOff);
};
} else {
if (_hitpoint in ["hitbody", "hitturret", "#structural"] && {_newDamage > 0.6 + random 0.3}) then {
_vehicle call FUNC(cookOff);
};
};
// prevent destruction, let cook-off handle it if necessary
if (_hitpoint in ["hithull", "hitfuel", "#structural"]) then {
_damage min 0.89
} else {
_damage
};
};

View File

@ -0,0 +1,64 @@
/*
* Author: Maddmatt, commy2
* Generate an amount of secondary explosions
*
* Arguments:
* 0: Vehicle <OBJECT>
* 1: Amount <NUMBER>
*
* Return Value:
* None
*
* Public: No
*/
#include "script_component.hpp"
#define SECONDARIES_DELAY (1 + random 45)
params ["_vehicle", "_amount"];
if (isNil "_amount") then {
// calculate amount of secondary explosions if not specified
_amount = 0;
{
_x params ["_magazine", "_count"];
private _ammo = getText (_magazine call CBA_fnc_getItemConfig >> "ammo");
if (IS_EXPLOSIVE_AMMO(_ammo)) then {
if (_ammo isKindOf "ShellBase") then {
ADD(_amount,_count);
} else {
ADD(_amount,_count/50);
};
};
} forEach magazinesAmmo _vehicle;
};
if (_amount <= 0) exitWith {};
private _fnc_secondaryExplosion = {
params ["_vehicle", "_amount", "_fnc_secondaryExplosion"];
private _position = _vehicle modelToWorld (_vehicle selectionPosition "destructionEffect2");
// these CfgAmmo objects are always global
"SmallSecondary" createVehicle _position;
DEC(_amount);
if (!isNull _vehicle && {_amount > 0}) then {
[_fnc_secondaryExplosion, [_vehicle, _amount, _fnc_secondaryExplosion], SECONDARIES_DELAY] call CBA_fnc_waitAndExecute;
};
};
[_fnc_secondaryExplosion, [_vehicle, _amount, _fnc_secondaryExplosion], SECONDARIES_DELAY] call CBA_fnc_waitAndExecute;
nil
/*SencondaryExplosion
SecondaryExp
SecondarySmoke
GrenadeExploLight
*/

View File

@ -0,0 +1 @@
#include "\z\ace\addons\cookoff\script_component.hpp"

View File

@ -0,0 +1,20 @@
#define COMPONENT cookoff
#define COMPONENT_BEAUTIFIED Cook off
#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_COOKOFF
#define DEBUG_MODE_FULL
#endif
#ifdef DEBUG_SETTINGS_COOKOFF
#define DEBUG_SETTINGS DEBUG_SETTINGS_COOKOFF
#endif
#include "\z\ace\addons\main\script_macros.hpp"
#define IS_EXPLOSIVE_AMMO(ammo) (getNumber (ammo call CBA_fnc_getObjectConfig >> "explosive") > 0.5)

Binary file not shown.