Skip to content

Commit

Permalink
houselight switch implementation
Browse files Browse the repository at this point in the history
* while in a house, use self interact/equipment to look for the fuse box
* fuse box will appear as a helper object that will have actions for
turning off/on all lights in the house
  • Loading branch information
Fusselwurm committed Sep 30, 2021
1 parent 10d556d commit 87452c6
Show file tree
Hide file tree
Showing 23 changed files with 279 additions and 0 deletions.
1 change: 1 addition & 0 deletions addons/houseLightSwitch/$PBOPREFIX$
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x\grad\addons\houseLightSwitch
17 changes: 17 additions & 0 deletions addons/houseLightSwitch/CfgEventHandlers.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
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));
};
};
16 changes: 16 additions & 0 deletions addons/houseLightSwitch/CfgVehicles.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class CfgVehicles {
class Man;
class CAManBase: Man {
class ACE_SelfActions {
class ACE_Equipment {
class GRAD_houseLightSwitch_fusebox {
displayName = "Locate fuse box";
condition = QUOTE(call FUNC(condition_fusebox));
exceptions[] = {};
statement = QUOTE(call FUNC(action_fusebox));
icon = "\x\grad\addons\houseLightSwitch\ui\bulb-question.paa";
};
};
};
};
};
9 changes: 9 additions & 0 deletions addons/houseLightSwitch/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
### houseLightSwitch

ACE self interact menu to switch all lights in a house. Requires player to be in and reasonably close to the house center.

To test, move into a house that has lights - for example "Land_House_C_3_EP1" or "Land_House_C_9_EP1". Terrains containing these buildings are Zargabad or Uzbin_Valley . Be close to the center of the house. Self interact should now contain a "switch house lights off" entry.

#### Maintainer(s)

* Fusselwurm
9 changes: 9 additions & 0 deletions addons/houseLightSwitch/XEH_PREP.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
PREP(action_fusebox);
PREP(createFuseboxActions);
PREP(condition);
PREP(condition_fusebox);
PREP(condition_off);
PREP(condition_on);
PREP(ensureFuseboxHelper);
PREP(fadeFuseboxHelper);
PREP(server_setBuildingMainSwitch);
5 changes: 5 additions & 0 deletions addons/houseLightSwitch/XEH_postInit.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "script_component.hpp"

if (isServer) then {
[QGVAR(setBuildingMainSwitch),FUNC(server_setBuildingMainSwitch)] call CBA_fnc_addEventHandler;
};
9 changes: 9 additions & 0 deletions addons/houseLightSwitch/XEH_preInit.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#include "script_component.hpp"

ADDON = false;

PREP_RECOMPILE_START;
#include "XEH_PREP.hpp"
PREP_RECOMPILE_END;

ADDON = true;
3 changes: 3 additions & 0 deletions addons/houseLightSwitch/XEH_preStart.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "script_component.hpp"

#include "XEH_PREP.hpp"
18 changes: 18 additions & 0 deletions addons/houseLightSwitch/config.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "script_component.hpp"

class CfgPatches {
class ADDON {
author = "$STR_grad_Author";
name = QUOTE(ADDON);
url = "$STR_grad_URL";
requiredVersion = 1.0;
requiredAddons[] = {"grad_main", "ace_interact_menu"};
units[] = {};
weapons[] = {};
VERSION_CONFIG;
authors[] = {"Fusselwurm"};
};
};

#include "CfgVehicles.hpp"
#include "CfgEventHandlers.hpp"
23 changes: 23 additions & 0 deletions addons/houseLightSwitch/functions/fnc_action_fusebox.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "script_component.hpp"

private _building = GVAR(house);
private _hasFuseboxActions = _building getVariable [QGVAR(hasFuseboxActions), false];

if (_hasFuseboxActions) exitWith {
[_building] call FUNC(ensureFuseboxHelper);
};

[
ACE_player distance _building,
[_building],
{
params ["_args"];
_args params ["_building"];
assert(!isNull(_building));
hint "Found the fuse box. Look for a bright helper object!";
[_building] call FUNC(ensureFuseboxHelper);
[_building] call FUNC(createFuseboxActions);
},
{hint "Failure"},
"Searching fuse box..."
] call ace_common_fnc_progressBar;
13 changes: 13 additions & 0 deletions addons/houseLightSwitch/functions/fnc_condition.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include "script_component.hpp"

private _cursorTarget = cursorTarget;

private _isUnderSomething = lineIntersectsObjs [getposASL ace_player, getposASL ace_player vectorAdd [0, 0, 20]] isNotEqualTo [];
private _pointsAtHouse = _cursorTarget isKindOf "House" || {_cursorTarget isKindOf "Building"};

if (_pointsAtHouse && {_isUnderSomething}) then {
GVAR(house) = _cursorTarget;
true
} else {
false
};
3 changes: 3 additions & 0 deletions addons/houseLightSwitch/functions/fnc_condition_fusebox.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "script_component.hpp"

call FUNC(condition)
3 changes: 3 additions & 0 deletions addons/houseLightSwitch/functions/fnc_condition_off.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "script_component.hpp"

[] call FUNC(condition) && {GVAR(house) getVariable [QGVAR(mainSwitchState), true] isEqualTo true};
3 changes: 3 additions & 0 deletions addons/houseLightSwitch/functions/fnc_condition_on.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#include "script_component.hpp"

[] call FUNC(condition) && {GVAR(house) getVariable [QGVAR(mainSwitchState), true] isEqualTo false};
44 changes: 44 additions & 0 deletions addons/houseLightSwitch/functions/fnc_createFuseboxActions.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#include "script_component.hpp"

params [
["_building", objNull, [objNull]]
];

assert(!(isNull _building));

if (_building getVariable [QGVAR(hasFuseboxActions), false]) exitWith {
WARNING_1("fusebox actions already added for %1", _building);
};
_building setVariable [QGVAR(hasFuseboxActions), true];

private _onAction = [
QGVAR(on),
"Turn on house lights",
"x\grad\addons\houseLightSwitch\ui\bulb-on.paa",
{
params ["", "", "_args"];
_args params [["_building", objNull, [objNull]]];
[QGVAR(setBuildingMainSwitch), [GVAR(house), true]] call CBA_fnc_serverEvent;
[_building] call FUNC(fadeFuseboxHelper);
},
{call FUNC(condition_on)},
{[]},
[_building]
] call ace_interact_menu_fnc_createAction;
[_building, 0, [], _onAction] call ace_interact_menu_fnc_addActionToObject;

private _offAction = [
QGVAR(off),
"Turn off house lights",
"\x\grad\addons\houseLightSwitch\ui\bulb-off.paa",
{
params ["", "", "_args"];
_args params [["_building", objNull, [objNull]]];
[QGVAR(setBuildingMainSwitch), [GVAR(house), false]] call CBA_fnc_serverEvent;
[_building] call FUNC(fadeFuseboxHelper);
},
{call FUNC(condition_off)},
{[]},
[_building]
] call ace_interact_menu_fnc_createAction;
[_building, 0, [], _offAction] call ace_interact_menu_fnc_addActionToObject;
21 changes: 21 additions & 0 deletions addons/houseLightSwitch/functions/fnc_ensureFuseboxHelper.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#include "script_component.hpp"

params [
["_building", objNull, [objNull]]
];
assert(!(isNull _building));

private _helper = _building getVariable [QGVAR(fuseboxHelper), objNull];
if (_helper isNotEqualTo objNull) exitWith {
TRACE_1("helper for %1 exists already!", _building);
};

private _helperPos = _building modelToWorld [0, 0, 0];
TRACE_2("creating helper for building %1 at %2", _building, _helperPos);

// NOTE: cannot use createSimpleObject, as these cannot hold ACE actions
// NOTE: createVehicleLocal will avoid collisions! hence setpos later
_helper = "Sign_Sphere25cm_F" createVehicleLocal [0, 0, 0];
_helper setPos _helperPos;

_building setVariable [QGVAR(fuseboxHelper), _helper];
42 changes: 42 additions & 0 deletions addons/houseLightSwitch/functions/fnc_fadeFuseboxHelper.sqf
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#include "script_component.hpp"

params [
["_building", objNull, [objNull]]
];
assert(!(isNull _building));

private _helper = _building getVariable [QGVAR(fuseboxHelper), objNull];
private _existingOpacity = _helper getVariable [QGVAR(opaqueness), -1];
if (_existingOpacity != -1) exitWith {
WARNING_1("helper already has non-default opacity %1 , will not add another handler", _existingOpacity);
};
_helper setVariable [QGVAR(opaqueness), 1];

[
{
params [
["_args", [], [[]]],
["_handle", 0, [0]]
];
_args params [
["_building", objNull, [objNull]]
];
assert(!(isNull _building));
private _helper = _building getVariable [QGVAR(fuseboxHelper), objNull];
private _opaqueness = _helper getVariable [QGVAR(opaqueness), 0];
_helper setVariable [QGVAR(opaqueness), _opaqueness - 0.05];
if (isNull _helper) exitWith {
[_handle] call CBA_fnc_removePerFrameHandler;
_building setVariable [QGVAR(fuseboxHelper), nil];
WARNING_1("null helper in loop for building %1!", _building);
};
if (_opaqueness <= 0) exitWith {
[_handle] call CBA_fnc_removePerFrameHandler;
_building setVariable [QGVAR(fuseboxHelper), nil];
deleteVehicle _helper;
};
_helper setObjectTexture [0, format ["#(argb,8,8,3)color(1,0.6,0.1,%1,ca)", _opaqueness]];
},
0.1,
[_building]
] call CBA_fnc_addPerFrameHandler;
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#include "script_component.hpp"
// assumption: any damage to a light source should be enough to kill it.
// therefore, I can use a magic damage (< 1) to mark as light as "switched off" as opposed to "destroyed"
#define MAGIC_DAMAGE_LIGHT_OFF 0.9

params [
["_building", objNull, [objNull]],
["_newState", false, [false]]
];

assert(isServer); // terrain objects are local *everywhere*. therefore, force server to have a single point of truth.

private _isOn = _building getVariable [QGVAR(mainSwitchState), true];
if (_newState isEqualTo _isOn) exitWith {
TRACE_2("someone tried to switch lights on building %1 to pre-existing state %2", _building, _newState);
};
_building setVariable [QGVAR(mainSwitchState), _newState, true];

private _existingDmg = getAllHitPointsDamage _building;

{
if (_x find "#" == 0) then { // assume indices starting with "#" to be lights
private _prevLightDmg = (_existingDmg#2#_forEachIndex);
// using setHitIndex over setHitPointDamage as there are buildings - looking at you, Land_House_C_2_EP1 - where hitpointnames are not unique
_building setHitIndex [
_forEachIndex,
if (_newState) then {
if (_prevLightDmg isEqualTo MAGIC_DAMAGE_LIGHT_OFF) then {0} else {_prevLightDmg}
} else {
_prevLightDmg max MAGIC_DAMAGE_LIGHT_OFF
},
false
];
};
} forEach _existingDmg#0;
1 change: 1 addition & 0 deletions addons/houseLightSwitch/functions/script_component.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "..\script_component.hpp"
4 changes: 4 additions & 0 deletions addons/houseLightSwitch/script_component.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#define COMPONENT houseLightSwitch

#include "\x\grad\addons\main\script_mod.hpp"
#include "\x\grad\addons\main\script_macros.hpp"
Binary file added addons/houseLightSwitch/ui/bulb-off.paa
Binary file not shown.
Binary file added addons/houseLightSwitch/ui/bulb-on.paa
Binary file not shown.
Binary file added addons/houseLightSwitch/ui/bulb-question.paa
Binary file not shown.

0 comments on commit 87452c6

Please sign in to comment.