diff --git a/Client Side/Framework/CfgFunctions.hpp b/Client Side/Framework/CfgFunctions.hpp index d261516c..858194a8 100644 --- a/Client Side/Framework/CfgFunctions.hpp +++ b/Client Side/Framework/CfgFunctions.hpp @@ -802,6 +802,15 @@ class CfgFunctions { file = "Functions\Shipwreck"; class onShipwreckSpawn {}; }; + + class Placeables { + file = "Functions\Placeables"; + class placedObjects {}; + class placeObject {}; + class removeObject {}; + class stopPlacement {}; + class isPlaceable {}; + }; }; class ULP_Functions_UI { diff --git a/Client Side/Framework/Configuration/CfgSettings.hpp b/Client Side/Framework/Configuration/CfgSettings.hpp index 19027fb0..2a9b8851 100644 --- a/Client Side/Framework/Configuration/CfgSettings.hpp +++ b/Client Side/Framework/Configuration/CfgSettings.hpp @@ -1,7 +1,7 @@ class CfgSettings { developers[] = { "76561198092567307", "76561197971322689" }; - framework_version = "1.0.8"; + framework_version = "1.1.0"; total_maxWeight = 5; diff --git a/Client Side/Framework/Functions/Admin/CfgAdmin.hpp b/Client Side/Framework/Functions/Admin/CfgAdmin.hpp index bef69b18..156fb71f 100644 --- a/Client Side/Framework/Functions/Admin/CfgAdmin.hpp +++ b/Client Side/Framework/Functions/Admin/CfgAdmin.hpp @@ -8,6 +8,7 @@ class CfgAdmin { }; class Camera : Suit {}; class Invis : Camera {}; + class RemovePlaceable : Suit {}; // ADMINISTRATOR (L3) class Teleport { diff --git a/Client Side/Framework/Functions/Events/fn_onGetIn.sqf b/Client Side/Framework/Functions/Events/fn_onGetIn.sqf index 390419b4..ece91971 100644 --- a/Client Side/Framework/Functions/Events/fn_onGetIn.sqf +++ b/Client Side/Framework/Functions/Events/fn_onGetIn.sqf @@ -22,4 +22,6 @@ if ([] call ULP_fnc_isEscorting) then { ["SecondNature", _unit] call ULP_fnc_activatePerk; +[] call ULP_fnc_stopPlacement; + true \ No newline at end of file diff --git a/Client Side/Framework/Functions/Initialisation/fn_initEventHandlers.sqf b/Client Side/Framework/Functions/Initialisation/fn_initEventHandlers.sqf index d6ad86bf..e36d74a1 100644 --- a/Client Side/Framework/Functions/Initialisation/fn_initEventHandlers.sqf +++ b/Client Side/Framework/Functions/Initialisation/fn_initEventHandlers.sqf @@ -139,13 +139,7 @@ if ([player, ["Police", "Hato"]] call ULP_fnc_isFaction) then { }] call ULP_fnc_addEventHandler; ["Incapacitated", { - if !(isNull (missionNamespace getVariable ["ULP_Spike", objNull])) then { - deleteVehicle ULP_Spike; - player removeAction (missionNamespace getVariable ["ULP_SpikePlaceAction", -1]); - - ULP_SpikePlaceAction = nil; - ULP_Spike = nil; - }; + [] call ULP_fnc_stopPlacement; }] call ULP_fnc_addEventHandler; ["CommunicationsSeized", { diff --git a/Client Side/Framework/Functions/Initialisation/fn_initPlayer.sqf b/Client Side/Framework/Functions/Initialisation/fn_initPlayer.sqf index 59baaf30..677fec81 100644 --- a/Client Side/Framework/Functions/Initialisation/fn_initPlayer.sqf +++ b/Client Side/Framework/Functions/Initialisation/fn_initPlayer.sqf @@ -28,13 +28,13 @@ if (_addActions) then { if ([player, ["Police", "Hato"]] call ULP_fnc_isFaction) then { ULP_PlayerActions pushBackUnique (player addAction ["Packup Stinger", { - private _spike = (nearestObjects [player, ["Land_Razorwire_F"], 5] select { !((_x getVariable ["spike_owner", []]) isEqualTo []) }) param [0, objNull]; + private _spike = (nearestObjects [player, ["Land_Razorwire_F"], 5] select { !((_x getVariable ["object_owner", []]) isEqualTo []) }) param [0, objNull]; if (isNull _spike) exitWith {}; if (["Stinger", 1, false, true] call ULP_fnc_handleItem) then { ["You have packed up a stinger..."] call ULP_fnc_hint; deleteVehicle _spike; }; - }, nil, 10, false, false, "", "isNull (objectParent player) && { !([] call ULP_UI_fnc_isProgress) } && { private _spike = (nearestObjects [player, [""Land_Razorwire_F""], 5] select { !((_x getVariable [""spike_owner"", []]) isEqualTo []) }) param [0, objNull]; (!(isNull _spike) && { (damage _spike) isEqualTo 1 })}"]); + }, nil, 10, false, false, "", "isNull (objectParent player) && { !([] call ULP_UI_fnc_isProgress) } && { private _spike = (nearestObjects [player, [""Land_Razorwire_F""], 5] select { !((_x getVariable [""object_owner"", []]) isEqualTo []) }) param [0, objNull]; (!(isNull _spike) && { (damage _spike) isEqualTo 1 })}"]); }; }; \ No newline at end of file diff --git a/Client Side/Framework/Functions/Interactions/CfgInteractions.hpp b/Client Side/Framework/Functions/Interactions/CfgInteractions.hpp index 4cdb3729..a49257e0 100644 --- a/Client Side/Framework/Functions/Interactions/CfgInteractions.hpp +++ b/Client Side/Framework/Functions/Interactions/CfgInteractions.hpp @@ -13,6 +13,15 @@ class CfgInteractions { }; }; + class Placeable { + class Remove { + title = "Remove Placeable"; + factions[] = { "Police", "Medic", "Hato", "Civilian" }; + onClick = "_this call ULP_fnc_removeObject; closeDialog 0;"; + condition = "[player, [""Police"", ""Medic"", ""Hato""]] call ULP_fnc_isFaction || { [] call ULP_fnc_isStaff && { [player] call ULP_fnc_onDuty } && { [""RemovePlaceable"", false] call ULP_fnc_checkPower } }"; + }; + }; + class Person { class GiveKeys { title = "Give Keys"; diff --git a/Client Side/Framework/Functions/Interactions/fn_getInteractions.sqf b/Client Side/Framework/Functions/Interactions/fn_getInteractions.sqf index 64703aac..144026cb 100644 --- a/Client Side/Framework/Functions/Interactions/fn_getInteractions.sqf +++ b/Client Side/Framework/Functions/Interactions/fn_getInteractions.sqf @@ -17,6 +17,7 @@ private _typeOf = typeOf _object; (_typeOf call BIS_fnc_objectType) params ["", "_type"]; private _actions = missionConfigFile >> "CfgInteractions" >> (switch (true) do { + case ([_object] call ULP_fnc_isPlaceable): { "Placeable" }; case ([getNumber (missionConfigFile >> "CfgVehicles" >> _typeOf >> "isHouse")] call ULP_fnc_bool): { "HouseStorage" }; case (_typeOf isEqualTo "Land_MoneyBills_01_stack_F" && { (_object getVariable ["ULP_MoneyStack", 0]) > 0 }): { "Money" }; case (_typeOf isEqualTo "Land_CargoBox_V1_F"): { "Vault" }; diff --git a/Client Side/Framework/Functions/Items/CfgVirtualItems.hpp b/Client Side/Framework/Functions/Items/CfgVirtualItems.hpp index 3cd6fa66..f529e1f9 100644 --- a/Client Side/Framework/Functions/Items/CfgVirtualItems.hpp +++ b/Client Side/Framework/Functions/Items/CfgVirtualItems.hpp @@ -535,7 +535,7 @@ class CfgVirtualItems { blueprints[] = { { "Tools", "B_MakeshiftStinger" } }; materials[] = { {"SteelBar", 22} }; }; - class Events { onUse = "[] call ULP_fnc_spikeStrip;"; }; + class Events { onUse = "_this call ULP_fnc_spikeStrip;"; }; conditions = "true"; }; class MakeshiftStinger : Stinger { @@ -788,6 +788,7 @@ class CfgVirtualItems { isEventItem = false; isSystemItem = false; }; + class Events { onUse = "[""TapeSign"", _this select 0] call ULP_fnc_placeObject;"; }; conditions = "true"; }; class PlasticBarrier_02_yellow_F : TapeSign_F { @@ -833,10 +834,12 @@ class CfgVirtualItems { sellPrice = 0; weight = 2; class Settings : Settings {}; + class Events { onUse = "[""RoadCone"", _this select 0] call ULP_fnc_placeObject;"; }; }; class RoadCone_L_F : RoadCone_F { displayName = "Road Cone (Light)"; class Settings : Settings {}; + class Events { onUse = "[""RoadConeWithLight"", _this select 0] call ULP_fnc_placeObject;"; }; }; class Land_PortableLight_single_F : TapeSign_F { displayName = "Portable Light (Single)"; @@ -844,12 +847,14 @@ class CfgVirtualItems { buyPrice = 0; sellPrice = 0; class Settings : Settings {}; + class Events { onUse = "[""SinglePortableLight"", _this select 0] call ULP_fnc_placeObject;"; }; }; class Land_PortableLight_double_F : Land_PortableLight_single_F { displayName = "Portable Light (Double)"; buyPrice = 0; sellPrice = 0; class Settings : Settings {}; + class Events { onUse = "[""DoublePortableLight"", _this select 0] call ULP_fnc_placeObject;"; }; }; class TargetP_Inf4_F : TapeSign_F { displayName = "Pop-Up Target (Hostile)"; diff --git a/Client Side/Framework/Functions/Items/Scripts/fn_spikeStrip.sqf b/Client Side/Framework/Functions/Items/Scripts/fn_spikeStrip.sqf index e4021265..23dbaf41 100644 --- a/Client Side/Framework/Functions/Items/Scripts/fn_spikeStrip.sqf +++ b/Client Side/Framework/Functions/Items/Scripts/fn_spikeStrip.sqf @@ -5,52 +5,6 @@ #include "..\..\..\script_macros.hpp" scopeName "fn_spikeStrip"; -if !(isNull (objectParent player)) exitWith { - ["You must be outside of a vehicle..."] call ULP_fnc_hint; -}; +_this params [ ["_item", "", [""]] ]; -if !(isNull (missionNamespace getVariable ["ULP_Spike", objNull])) exitWith { - ["You must place your current stringer before you can place another..."] call ULP_fnc_hint; -}; - -private _spike = createVehicle ["Land_Razorwire_F", [0, 0, 0]]; -_spike attachTo [player, [0, 5.5, 0]]; -_spike setDir 90; -_spike setVariable ["spike_owner", [getPlayerUID player, profileName], true]; - -ULP_Spike = _spike; - -ULP_SpikePlaceAction = player addAction ["Place Stinger", { - _this params ["", "", "_actionId"]; - - private _spike = missionNamespace getVariable ["ULP_Spike", objNull]; - player removeAction _actionId; - - if (isNull _spike) exitWith { - ["An error occured while attempting to place this stringer..."] call ULP_fnc_hint; - }; - - ["Placing Stringer", 2, [_spike], { !(isNull (_this select 0)) && { (["Stinger"] call ULP_fnc_hasItem) > 0 } }, { - _this params [ "_spike" ]; - - if (isNull _spike) exitWith {}; - - if !(["Stinger", 1, true] call ULP_fnc_handleItem) exitWith { - deleteVehicle _spike; - }; - - detach _spike; - - private _pos = getPosATL _spike; - _pos set[2, 0]; - - _spike setPosATL _pos; - _spike setVectorUp surfaceNormal _pos; - _spike setDamage 1; - - [_spike] remoteExecCall ["ULP_SRV_fnc_registerStinger", RSERV]; - - ["You have placed a stinger..."] call ULP_fnc_hint; - ULP_Spike = nil; - }, { deleteVehicle (_this select 0); }, ["GRAB", "CROUCH"]] call ULP_UI_fnc_startProgress; -}, nil, 10, false, false, "", "!(isNull (missionNamespace getVariable [""ULP_Spike"", objNull]))"]; \ No newline at end of file +["SpikeStrip", _item] call ULP_fnc_placeObject; \ No newline at end of file diff --git a/Client Side/Framework/Functions/Placeables/CfgPlaceables.hpp b/Client Side/Framework/Functions/Placeables/CfgPlaceables.hpp new file mode 100644 index 00000000..fe11d0ec --- /dev/null +++ b/Client Side/Framework/Functions/Placeables/CfgPlaceables.hpp @@ -0,0 +1,41 @@ +class CfgPlaceables { + maxPlaceables = 20; + + class Objects { + class SpikeStrip { + displayName = "Stinger"; + className = "Land_Razorwire_F"; + positioning[] = { { 0, 5.5, 0 }, 90 }; + placementTime = 2; + onPlaced = "(_this select 0) setDamage 1; _this remoteExecCall [""ULP_SRV_fnc_registerStinger"", 2];"; + }; + + class RoadCone { + displayName = "Road Cone"; + className = "RoadCone_F"; + positioning[] = { { 0, 3, 0.5 }, 0 }; + placementTime = 2; + onPlaced = ""; + }; + + class RoadConeWithLight : RoadCone { + displayName = "Road Cone With Light"; + className = "RoadCone_L_F"; + }; + + class SinglePortableLight : RoadCone { + displayName = "Portable Light (Single)"; + className = "Land_PortableLight_single_F"; + }; + + class DoublePortableLight : RoadCone { + displayName = "Portable Light (Double)"; + className = "Land_PortableLight_double_F"; + }; + + class TapeSign : RoadCone { + displayName = "Red-White Tape"; + className = "TapeSign_F"; + }; + }; +}; \ No newline at end of file diff --git a/Client Side/Framework/Functions/Placeables/fn_isPlaceable.sqf b/Client Side/Framework/Functions/Placeables/fn_isPlaceable.sqf new file mode 100644 index 00000000..a5851c20 --- /dev/null +++ b/Client Side/Framework/Functions/Placeables/fn_isPlaceable.sqf @@ -0,0 +1,10 @@ +/* +** Author: Jack "Scarso" Farhall +** Description: Returns count of all objects placed by a certain player +*/ +#include "..\..\script_macros.hpp" +scopeName "fn_isPlaceable"; + +private _object = _this param [0, objNull, [objNull]]; + +!(isNull _object && { isNil { _object getVariable "object_owner" } }) \ No newline at end of file diff --git a/Client Side/Framework/Functions/Placeables/fn_placeObject.sqf b/Client Side/Framework/Functions/Placeables/fn_placeObject.sqf new file mode 100644 index 00000000..bb22f2f0 --- /dev/null +++ b/Client Side/Framework/Functions/Placeables/fn_placeObject.sqf @@ -0,0 +1,91 @@ +/* +** Author: Jack "Scarso" Farhall +** Description: +*/ +#include "..\..\script_macros.hpp" +scopeName "fn_placeObject"; + +if (canSuspend) exitWith { _this call ULP_fnc_placeObject; }; + +_this params [ + ["_placeable", "", [""]], + ["_item", "", [""]] +]; + +private _cfg = missionConfigFile >> "CfgPlaceables" >> "Objects" >> _placeable; +if !(isClass _cfg) exitWith { false }; + +if !(isNull (objectParent player)) exitWith { + ["You must be outside of a vehicle..."] call ULP_fnc_hint; + false +}; + +if !(isNull (missionNamespace getVariable ["ULP_PlaceableObject", objNull])) exitWith { + ["You must place your current object before you can place another..."] call ULP_fnc_hint; + false +}; + +private _maxPlaceables = getNumber (missionConfigFile >> "CfgPlaceables" >> "maxPlaceables"); +if (([] call ULP_fnc_placedObjects) >= _maxPlaceables) exitWith { + [format ["You've got %1 objects still active, please delete some to place more...", _maxPlaceables]] call ULP_fnc_hint; + false +}; + +// Ensure no ui is open for this step +[] spawn ULP_UI_fnc_closeDialogs; + +[{ !dialog }, [_cfg, _item], { + _this params [ "_cfg", "_item" ]; + + private _className = getText(_cfg >> "className"); + private _positioning = getArray(_cfg >> "positioning") params [ + "_attachPoint", "_rot" + ]; + + private _object = createVehicle [_className, [0, 0, 0]]; + _object attachTo [player, _attachPoint]; + _object setDir _rot; + _object setVariable ["object_owner", [getPlayerUID player, profileName], true]; + + ULP_PlaceableObject = _object; + + ULP_PlaceableObjectAction = player addAction [format ["Place %1", getText(_cfg >> "displayName")], { + _this params ["", "", "_actionId", "_params"]; + _params params [ "_cfg", "_item" ]; + + private _object = missionNamespace getVariable ["ULP_PlaceableObject", objNull]; + player removeAction _actionId; + + if (isNull _object) exitWith { + ["An error occured while attempting to place this object..."] call ULP_fnc_hint; + }; + + [format ["Placing %1", getText(_cfg >> "displayName")], getNumber(_cfg >> "placementTime"), + [_object, _item, _cfg], { !(isNull (_this select 0)) && { ([(_this select 1)] call ULP_fnc_hasItem) > 0 } }, { + _this params [ "_object", "_item", "_cfg" ]; + + if (isNull _object) exitWith {}; + + if !([_item, 1, true] call ULP_fnc_handleItem) exitWith { + deleteVehicle _object; + }; + + detach _object; + + private _pos = getPosATL _object; + _pos set[2, 0]; + + _object setPosATL _pos; + _object setVectorUp surfaceNormal _pos; + + [_object] call compile getText(_cfg >> "onPlaced"); + + [format["You have placed a %1...", getText(_cfg >> "displayName")]] call ULP_fnc_hint; + [false] call ULP_fnc_stopPlacement; + }, { + [] call ULP_fnc_stopPlacement; + }, ["GRAB", "CROUCH"]] call ULP_UI_fnc_startProgress; + }, [_cfg, _item], 10, false, false, "", "!(isNull (missionNamespace getVariable [""ULP_PlaceableObject"", objNull]))"]; +}] call ULP_fnc_waitUntilExecute; + +true \ No newline at end of file diff --git a/Client Side/Framework/Functions/Placeables/fn_placedObjects.sqf b/Client Side/Framework/Functions/Placeables/fn_placedObjects.sqf new file mode 100644 index 00000000..14285452 --- /dev/null +++ b/Client Side/Framework/Functions/Placeables/fn_placedObjects.sqf @@ -0,0 +1,15 @@ +/* +** Author: Jack "Scarso" Farhall +** Description: Returns count of all objects placed by a certain player +*/ +#include "..\..\script_macros.hpp" +scopeName "fn_placedObjects"; + +_this params [ + ["_steamId", getPlayerUID player, [""]] +]; + +if (_steamId isEqualTo "") exitWith { 0 }; + +// Semi-Intensive - Will be a good idea to look into alternatives but only runs once when initially placing an objects so not high prio +count (vehicles select { ((_x getVariable ["object_owner", [""]]) param [0, "", [""]]) isEqualTo _steamId }) \ No newline at end of file diff --git a/Client Side/Framework/Functions/Placeables/fn_removeObject.sqf b/Client Side/Framework/Functions/Placeables/fn_removeObject.sqf new file mode 100644 index 00000000..3921c3cd --- /dev/null +++ b/Client Side/Framework/Functions/Placeables/fn_removeObject.sqf @@ -0,0 +1,19 @@ +/* +** Author: Jack "Scarso" Farhall +** Description: +*/ +#include "..\..\script_macros.hpp" +scopeName "fn_removeObject"; + +if (canSuspend) exitWith { + [ULP_fnc_removeObject, _this] call ULP_fnc_directCall; +}; + +_this params [ + ["_object", objNull, [objNull]] +]; + +if !([_object] call ULP_fnc_isPlaceable) exitWith { false }; + +deleteVehicle _object; +true \ No newline at end of file diff --git a/Client Side/Framework/Functions/Placeables/fn_stopPlacement.sqf b/Client Side/Framework/Functions/Placeables/fn_stopPlacement.sqf new file mode 100644 index 00000000..8af9393d --- /dev/null +++ b/Client Side/Framework/Functions/Placeables/fn_stopPlacement.sqf @@ -0,0 +1,21 @@ +/* +** Author: Jack "Scarso" Farhall +** Description: Stops placement of any objects if the user is placing one +*/ +#include "..\..\script_macros.hpp" +scopeName "fn_stopPlacement"; + +_this params [ + ["_delete", true, [false]] +]; + +if !(isNull (missionNamespace getVariable ["ULP_PlaceableObject", objNull])) then { + // This is used after successfully placement + // In this case we want to keep object but let the client "forget" about it + if (_delete) then { deleteVehicle ULP_PlaceableObject; }; + + player removeAction (missionNamespace getVariable ["ULP_PlaceableObjectAction", -1]); + + ULP_PlaceableObjectAction = nil; + ULP_PlaceableObject = nil; +}; \ No newline at end of file diff --git a/Client Side/Framework/Functions/VirtualStore/CfgVirtualStores.hpp b/Client Side/Framework/Functions/VirtualStore/CfgVirtualStores.hpp index a17d1926..639e3a66 100644 --- a/Client Side/Framework/Functions/VirtualStore/CfgVirtualStores.hpp +++ b/Client Side/Framework/Functions/VirtualStore/CfgVirtualStores.hpp @@ -23,17 +23,17 @@ class CfgVirtualStores { class FirstAidKit {}; class MediKit {}; class AutomatedExternalDefibrillator {}; - //class TapeSign_F {}; + class TapeSign_F {}; //class PlasticBarrier_02_yellow_F {}; //class PlasticBarrier_02_grey_F {}; //class PlasticBarrier_03_orange_F {}; //class PlasticBarrier_03_blue_F {}; //class RoadBarrier_small_F {}; //class RoadBarrier_F {}; - //class RoadCone_F {}; - //class RoadCone_L_F {}; - //class Land_PortableLight_single_F {}; - //class Land_PortableLight_double_F {}; + class RoadCone_F {}; + class RoadCone_L_F {}; + class Land_PortableLight_single_F {}; + class Land_PortableLight_double_F {}; //class TargetP_Inf4_F {}; //class TargetP_Civ_F {}; //class TargetP_Civ3_F {}; @@ -64,17 +64,17 @@ class CfgVirtualStores { class FirstAidKit {}; class MediKit {}; class AutomatedExternalDefibrillator {}; - //class TapeSign_F {}; + class TapeSign_F {}; //class PlasticBarrier_02_yellow_F {}; //class PlasticBarrier_02_grey_F {}; //class PlasticBarrier_03_orange_F {}; //class PlasticBarrier_03_blue_F {}; //class RoadBarrier_small_F {}; //class RoadBarrier_F {}; - //class RoadCone_F {}; - //class RoadCone_L_F {}; - //class Land_PortableLight_single_F {}; - //class Land_PortableLight_double_F {}; + class RoadCone_F {}; + class RoadCone_L_F {}; + class Land_PortableLight_single_F {}; + class Land_PortableLight_double_F {}; }; }; class Hato { @@ -97,17 +97,17 @@ class CfgVirtualStores { class FirstAidKit {}; class MediKit {}; class AutomatedExternalDefibrillator {}; - //class TapeSign_F {}; + class TapeSign_F {}; //class PlasticBarrier_02_yellow_F {}; //class PlasticBarrier_02_grey_F {}; //class PlasticBarrier_03_orange_F {}; //class PlasticBarrier_03_blue_F {}; //class RoadBarrier_small_F {}; //class RoadBarrier_F {}; - //class RoadCone_F {}; - //class RoadCone_L_F {}; - //class Land_PortableLight_single_F {}; - //class Land_PortableLight_double_F {}; + class RoadCone_F {}; + class RoadCone_L_F {}; + class Land_PortableLight_single_F {}; + class Land_PortableLight_double_F {}; }; }; diff --git a/Client Side/Framework/description.ext b/Client Side/Framework/description.ext index 8adece62..f74465db 100644 --- a/Client Side/Framework/description.ext +++ b/Client Side/Framework/description.ext @@ -87,6 +87,7 @@ class CfgWorlds { #include "Functions\Moves\CfgMoves.hpp" #include "Functions\Options\CfgOptions.hpp" #include "Functions\Perks\CfgPerks.hpp" +#include "Functions\Placeables\CfgPlaceables.hpp" #include "Functions\PlayerTags\CfgTags.hpp" #include "Functions\PNC\CfgWarrants.hpp" #include "Functions\Prison\CfgPrison.hpp"