diff --git a/CHANGE LOG 1.0.5.2.txt b/CHANGE LOG 1.0.5.2.txt
index 6bc7e0d03..db2a592a3 100644
--- a/CHANGE LOG 1.0.5.2.txt
+++ b/CHANGE LOG 1.0.5.2.txt
@@ -1,6 +1,7 @@
[NEW] Use DayZ_UseSteamID = false; in your init.sqf to use the old PlayerUID, instead of SteamID @icomrade
[NEW] UI Update - Graphical and code changes, enable using Dayz_Dark_UI = true; in init.sqf. @hogscraper http://epochmod.com/forum/index.php?/topic/13654-proposed-ui-change/
[NOTE] It's recommend to convert to the new SteamID system if possible, new servers should not use DayZ_UseSteamID = false;
+[NEW] Snap building (disabled by default), use DZE_snapBuilding = true; in your init.sqf to enable. @raymix
[CHANGED] An infection chance of -1 disables self-transfusion infection. 0 is always infected. (DZE_selfTransfuse_Values) @icomrade
[CHANGED] Removed weapons from Traders hands and made them stand with arms by their side. @SilvDev
diff --git a/SQF/dayz_code/Configs/CfgExtra/snappoints.hpp b/SQF/dayz_code/Configs/CfgExtra/snappoints.hpp
new file mode 100644
index 000000000..87fa6d754
--- /dev/null
+++ b/SQF/dayz_code/Configs/CfgExtra/snappoints.hpp
@@ -0,0 +1,374 @@
+/*
+Created by Raymix
+*/
+
+
+class SnapBuilding {
+ //Barriers whitelist
+ class Barrier {
+ snapTo[] = {
+ "Land_HBarrier5_DZ",
+ "Land_HBarrier3_DZ",
+ "Land_HBarrier1_DZ",
+ "Sandbag1_DZ",
+ "BagFenceRound_DZ",
+ "Fort_RazorWire"
+ };
+ };
+ //snap points
+ class Land_HBarrier5Preview: Barrier{ //fix for broken offsets in ghost
+ points[] = {
+ {0,0,0,"Pivot"},
+ {0,-0.75,0.1,"Back"},
+ {0,0.75,0.1,"Front"},
+ {-2.85,0,0.1,"Left"},
+ {2.85,0,0.1,"Right"},
+ {0,0,0.9,"Top"}
+ };
+ };
+ class Land_HBarrier5_DZ: Land_HBarrier5Preview {
+ points[] = {
+ {0,0,0,"Pivot"},
+ {0,-0.75,0,"Back"},
+ {0,0.75,0,"Front"},
+ {-2.85,0,0,"Left"},
+ {2.85,0,0,"Right"},
+ {0,0,0.9,"Top"}
+ };
+ };
+
+ class Land_HBarrier3ePreview: Barrier { //whitelist inheritance
+ points[] = {
+ {0,0,0,"Pivot"},
+ {0,-0.75,0,"Back"},
+ {0,0.75,0,"Front"},
+ {-1.7,0,0,"Left"},
+ {1.7,0,0,"Right"},
+ {0,0,0.9,"Top"}
+ };
+ };
+ class Land_HBarrier3_DZ: Land_HBarrier3ePreview{}; //point inheritance
+
+ class Land_HBarrier1Preview: Barrier {
+ points[] = {
+ {0,0,0,"Pivot"},
+ {0,-0.75,0,"Back"},
+ {0,0.75,0,"Front"},
+ {-0.6,0,0,"Left"},
+ {0.6,0,0,"Right"},
+ {0,0,0.9,"Top"}
+ };
+ };
+ class Land_HBarrier1_DZ: Land_HBarrier1Preview{};
+
+ class Fort_RazorWirePreview: Barrier {
+ points[] = {
+ {0,0,0,"Pivot"},
+ {0,-0.95,-0.3,"Back"},
+ {0,0.95,-0.3,"Front"},
+ {-4.1,0,-0.3,"Left"},
+ {4.1,0,-0.3,"Right"},
+ {0,0,1,"Top"}
+ };
+ };
+ class Fort_RazorWire: Fort_RazorWirePreview {};
+
+ class Sandbag1_DZ: Barrier {
+ points[] = {
+ {0,0,0,"Pivot"},
+ {-1.5,0,0,"Left"},
+ {1.5,0,0,"Right"},
+ {0,0,0.4,"Top"}
+ };
+ };
+
+ class BagFenceRound_DZ: Barrier {
+ points[] = {
+ {0,0,0,"Pivot"},
+ {-1.295,0.38,0,"Left"},
+ {1.295,0.38,0,"Right"},
+ {0,0,0.4,"Top"}
+ };
+ };
+
+ //Snapping whitelists for Floors, walls and stairs
+ class FloorsWallsStairs {
+ snapTo[] = {
+ "WoodFloorQuarter_DZ",
+ "WoodFloorHalf_DZ",
+ "WoodFloor_DZ",
+ "WoodStairs_DZ",
+ "WoodStairsSans_DZ",
+ "WoodSmallWallDoor_DZ",
+ "WoodSmallWall_DZ",
+ "WoodSmallWallWin_DZ",
+ "Land_DZE_WoodDoor",
+ "Land_DZE_WoodDoorLocked",
+ "WoodLargeWall_DZ",
+ "Land_DZE_LargeWoodDoor",
+ "WoodLargeWallWin_DZ",
+ "WoodLargeWallDoor_DZ",
+ "Land_DZE_GarageWoodDoor",
+ "Land_DZE_GarageWoodDoorLocked",
+ "Land_DZE_LargeWoodDoorLocked",
+ "WoodSmallWallThird_DZ",
+ "CinderWall_DZ",
+ "CinderWallDoorway_DZ",
+ "CinderWallDoorLocked_DZ",
+ "CinderWallDoor_DZ",
+ "CinderWallSmallDoorway_DZ",
+ "CinderWallDoorSmallLocked_DZ",
+ "CinderWallHalf_DZ",
+ "CinderWallDoorSmall_DZ",
+ "MetalFloor_DZ"
+ };
+ };
+
+ class WoodFloorQuarter_Preview_DZ: FloorsWallsStairs { //fix for broken offsets in ghost
+ points[] = {
+ {0,0,0,"Pivot"},
+ {0,-1.23,0,"Back"},
+ {0,1.23,0,"Front"},
+ {-1.24,0,0,"Left"},
+ {1.24,0,0,"Right"}
+ };
+ };
+
+ class WoodFloorQuarter_DZ: FloorsWallsStairs {
+ points[] = {
+ {0,0,0,"Pivot"},
+ {0,-1.23,0.137726,"Back"},
+ {0,1.23,0.137726,"Front"},
+ {-1.24,0,0.137726,"Left"},
+ {1.24,0,0.137726,"Right"}
+ };
+ };
+
+ class WoodFloorHalf_Preview_DZ: FloorsWallsStairs { //fix for broken offsets in ghost
+ points[] = {
+ {0,0,0,"Pivot"},
+ {0,-2.34,0,"Back"},
+ {0,2.34,0,"Front"},
+ {-1.25,0,0,"Left"},
+ {1.25,0,0,"Right"}
+ };
+ };
+ class WoodFloorHalf_DZ: FloorsWallsStairs{
+ points[] = {
+ {0,0,0,"Pivot"},
+ {0,-2.34,0.1407,"Back"},
+ {0,2.34,0.1407,"Front"},
+ {-1.25,0,0.1407,"Left"},
+ {1.25,0,0.1407,"Right"}
+ };
+ };
+
+ class WoodFloor_Preview_DZ: FloorsWallsStairs {
+ points[] = {
+ {0,0,0,"Pivot"},
+ {0,-2.33,0.130,"Back"},
+ {0,2.33,0.130,"Front"},
+ {-2.45,0,0.130,"Left"},
+ {2.45,0,0.130,"Right"}
+ };
+ };
+ class WoodFloor_DZ: WoodFloor_Preview_DZ{};
+
+ class Stairs_DZE: FloorsWallsStairs {
+ points[] = {
+ {0,0,0,"Pivot"},
+ {1.56055,-0.78,1.5,"Back"},
+ {1.56055,0.78,1.5,"Front"},
+ {1.73926,0.05,2.9,"Top"},
+ {-1.73926,0.05,0,"Bottom"}
+ };
+ };
+ class WoodStairs_Preview_DZ: Stairs_DZE {};
+ class WoodStairsSans_Preview_DZ: Stairs_DZE {};
+ class WoodStairsSans_DZ: Stairs_DZE {};
+
+ class WoodSmall_DZE: FloorsWallsStairs { // Small wood walls
+ points[] = {
+ {0,0,0,"Pivot"},
+ {-2.285, 0, 1.5,"Left"},
+ {2.285, 0, 1.5,"Right"},
+ {0, 0, 3,"Top"}
+ };
+ };
+ class WoodSmallWallDoor_Preview_DZ: WoodSmall_DZE {};
+ class WoodSmallWall_Preview_DZ: WoodSmall_DZE {};
+ class WoodSmallWallWin_Preview_DZ: WoodSmall_DZE {};
+ class WoodSmallWallDoor_DZ: WoodSmall_DZE {};
+ class WoodSmallWall_DZ: WoodSmall_DZE {};
+ class WoodSmallWallWin_DZ: WoodSmall_DZE {};
+ class Land_DZE_WoodDoor: WoodSmall_DZE {};
+ class Land_DZE_WoodDoorLocked: WoodSmall_DZE {};
+
+ class WoodLarge_DZE: FloorsWallsStairs { //Large wood walls
+ points[] = {
+ {0,0,0,"Pivot"},
+ {-2.45, 0, 1.5,"Left"},
+ {2.45, 0, 1.5,"Right"},
+ {0, 0, 3,"Top"}
+ };
+ };
+ class WoodLargeWall_Preview_DZ: WoodLarge_DZE {};
+ class WoodLargeWallWin_Preview_DZ: WoodLarge_DZE {};
+ class WoodLargeWallDoor_Preview_DZ: WoodLarge_DZE {};
+ class WoodSmallWallThird_Preview_DZ: WoodLarge_DZE {
+ points[] = {
+ {0,0,0,"Pivot"},
+ {-2.445, 0, 1.5,"Left"},
+ {2.445, 0, 1.5,"Right"},
+ {0, 0, 1.17,"Top"}
+ };
+ };
+ class WoodSmallWallThird_DZ: WoodSmallWallThird_Preview_DZ{};
+ class WoodLargeWall_DZ: WoodLarge_DZE {};
+ class Land_DZE_LargeWoodDoor: WoodLarge_DZE {};
+ class WoodLargeWallWin_DZ: WoodLarge_DZE {};
+ class WoodLargeWallDoor_DZ: WoodLarge_DZE {};
+ class Land_DZE_GarageWoodDoor: WoodLarge_DZE {};
+ class GarageWoodDoor_Preview_DZ: WoodLarge_DZE {};
+ class Land_DZE_GarageWoodDoorLocked: WoodLarge_DZE {};
+ class Land_DZE_LargeWoodDoorLocked: WoodLarge_DZE {};
+ class LargeWoodDoor_Preview_DZ: WoodLarge_DZE {};
+
+ class Cinder_DZE: FloorsWallsStairs { //All cinder walls and doors
+ points[] = {
+ {0,0,0,"Pivot"},
+ {-2.752, 0, 1.5,"Left"},
+ {2.752, 0, 1.5,"Right"},
+ {0, 0, 3.37042,"Top"}
+ };
+ };
+ class CinderWall_Preview_DZ: Cinder_DZE {};
+ class CinderWallDoorway_Preview_DZ: Cinder_DZE {};
+ class CinderWallSmallDoorway_Preview_DZ: Cinder_DZE {};
+ class CinderWallHalf_Preview_DZ: Cinder_DZE {
+ points[] = {
+ {0,0,0,"Pivot"},
+ {-2.752, 0, 1.5,"Left"},
+ {2.752, 0, 1.5,"Right"},
+ {0, 0, 1.5,"Top"}
+ };
+ };
+ class CinderWall_DZ: Cinder_DZE {};
+ class CinderWallDoorway_DZ: Cinder_DZE {};
+ class CinderWallDoorLocked_DZ: Cinder_DZE {};
+ class CinderWallDoor_DZ: Cinder_DZE {};
+ class CinderWallSmallDoorway_DZ: Cinder_DZE {};
+ class CinderWallDoorSmallLocked_DZ: Cinder_DZE {};
+ class CinderWallHalf_DZ: Cinder_DZE {
+ points[] = {
+ {0,0,0,"Pivot"},
+ {-2.752, 0, 1.5,"Left"},
+ {2.752, 0, 1.5,"Right"},
+ {0, 0, 1.5,"Top"}
+ };
+ };
+ class CinderWallDoorSmall_DZ: Cinder_DZE {};
+
+ class MetalFloor_Preview_DZ: FloorsWallsStairs { //fix for broken offsets in ghost
+ points[] = {
+ {0,0,0.011,"Pivot"},
+ {0, -2.64, 0.009,"Back"},
+ {0, 2.64, 0.009,"Front"},
+ {-2.64, 0, 0.009,"Left"},
+ {2.64, 0, 0.009,"Right"}
+ };
+ };
+ class MetalFloor_DZ: FloorsWallsStairs{
+ points[] = {
+ {0,0,0,"Pivot"},
+ {0, -2.64, 0.15,"Back"},
+ {0, 2.64, 0.15,"Front"},
+ {-2.64, 0, 0.15,"Left"},
+ {2.64, 0, 0.15,"Right"}
+ };
+ };
+
+
+ //Non essential Items that only snap to themselves, do whitelist inheritance if you want these to snap
+ class WoodCrate_DZ {
+ snapTo[] = {
+ "WoodCrate_DZ"
+ };
+ points[] = {
+ {0,0,0,"Pivot"},
+ {0,-0.47,0,"Back"},
+ {0,0.47,0,"Front"},
+ {-0.47,0,0,"Left"},
+ {0.47,0,0,"Right"},
+ {0,0,0.47,"Top"}
+ };
+ };
+
+ class MetalPanel_DZ {
+ snapTo[] = {
+ "MetalPanel_DZ"
+ };
+ points[] = {
+ {0,0,0,"Pivot"},
+ {-1.5,0,0,"Left"},
+ {1.5,0,0,"Right"}
+ };
+ };
+
+ class MetalGate_DZ {
+ snapTo[] = {
+ "MetalGate_DZ"
+ };
+ points[] = {
+ {0,0,0,"Pivot"},
+ {-4.1,0,0,"Left"}
+ };
+ };
+
+ class StickFence_DZ {
+ snapTo[] = {
+ "StickFence_DZ"
+ };
+ points[] = {
+ {0,0,0,"Pivot"},
+ {-2.95,0,0.3,"Left"},
+ {2.95,0,0.3,"Right"}
+ };
+ };
+
+ class Fence_corrugated_DZ {
+ snapTo[] = {
+ "Fence_corrugated_DZ"
+ };
+ points[] = {
+ {0,0,0,"Pivot"},
+ {-1.95,0,0.88,"Left"},
+ {1.95,0,0.88,"Right"}
+ };
+ };
+
+ class WoodRamp_Preview_DZ {
+ snapTo[] = {
+ "WoodRamp_DZ"
+ };
+ points[] = {
+ {0,0,0,"Pivot"},
+ {0.65,-1.7,1.2,"Back"},
+ {0.65,1.5,1.2,"Front"},
+ {3.34,-0.115,2.82,"Top"}
+ };
+ };
+ class WoodRamp_DZ: WoodRamp_Preview_DZ{};
+
+ class WoodLadder_Preview_DZ {
+ snapTo[] = {
+ "WoodLadder_DZ"
+ };
+ points[] = {
+ {0,0,0,"Pivot"},
+ {-0.4,0,1.725,"Left"},
+ {0.4,0,1.725,"Right"}
+ };
+ };
+ class WoodLadder_DZ: WoodLadder_Preview_DZ{};
+};
diff --git a/SQF/dayz_code/actions/dayz_spaceInterrupt.sqf b/SQF/dayz_code/actions/dayz_spaceInterrupt.sqf
index 0df2ca363..53de8087d 100644
--- a/SQF/dayz_code/actions/dayz_spaceInterrupt.sqf
+++ b/SQF/dayz_code/actions/dayz_spaceInterrupt.sqf
@@ -189,4 +189,9 @@ if (_dikCode == 0x39 || (_dikCode in actionKeys "User19")) then {
DZE_5 = true;
};
+// F key
+if ((_dikCode == 0x21 && (!_alt && !_ctrl)) || (_dikCode in actionKeys "User6")) then {
+ DZE_F = true;
+};
+
_handled
diff --git a/SQF/dayz_code/actions/player_build2.sqf b/SQF/dayz_code/actions/player_build2.sqf
new file mode 100644
index 000000000..d7f554b29
--- /dev/null
+++ b/SQF/dayz_code/actions/player_build2.sqf
@@ -0,0 +1,617 @@
+/*
+ DayZ Base Building
+ Made for DayZ Epoch please ask permission to use/edit/distrubute email vbawol@veteranbastards.com.
+*/
+private ["_helperColor","_objectHelper","_objectHelperDir","_objectHelperPos","_canDo",
+"_location","_dir","_classname","_item","_hasrequireditem","_missing","_hastoolweapon","_cancel","_reason","_started","_finished","_animState","_isMedic","_dis","_sfx","_hasbuilditem","_tmpbuilt","_onLadder","_isWater","_require","_text","_offset","_IsNearPlot","_isOk","_location1","_location2","_counter","_limit","_proceed","_num_removed","_position","_object","_canBuildOnPlot","_friendlies","_nearestPole","_ownerID","_findNearestPoles","_findNearestPole","_distance","_classnametmp","_ghost","_isPole","_needText","_lockable","_zheightchanged","_rotate","_combination_1","_combination_2","_combination_3","_combination_4","_combination","_combination_1_Display","_combinationDisplay","_zheightdirection","_abort","_isNear","_need","_needNear","_vehicle","_inVehicle","_requireplot","_objHDiff","_isLandFireDZ","_isTankTrap"];
+
+if(DZE_ActionInProgress) exitWith { cutText [(localize "str_epoch_player_40") , "PLAIN DOWN"]; };
+DZE_ActionInProgress = true;
+
+// disallow building if too many objects are found within 30m
+if((count ((getPosATL player) nearObjects ["All",30])) >= DZE_BuildingLimit) exitWith {DZE_ActionInProgress = false; cutText [(localize "str_epoch_player_41"), "PLAIN DOWN"];};
+
+_onLadder = (getNumber (configFile >> "CfgMovesMaleSdr" >> "States" >> (animationState player) >> "onLadder")) == 1;
+_isWater = dayz_isSwimming;
+_cancel = false;
+_reason = "";
+_canBuildOnPlot = false;
+
+_vehicle = vehicle player;
+_inVehicle = (_vehicle != player);
+//snap
+helperDetach = false;
+_canDo = (!r_drag_sqf and !r_player_unconscious);
+
+DZE_Q = false;
+DZE_Z = false;
+
+DZE_Q_alt = false;
+DZE_Z_alt = false;
+
+DZE_Q_ctrl = false;
+DZE_Z_ctrl = false;
+
+DZE_5 = false;
+DZE_4 = false;
+DZE_6 = false;
+DZE_F = false;
+
+DZE_cancelBuilding = false;
+
+call gear_ui_init;
+closeDialog 1;
+
+if (_isWater) exitWith {DZE_ActionInProgress = false; cutText [localize "str_player_26", "PLAIN DOWN"];};
+if (_inVehicle) exitWith {DZE_ActionInProgress = false; cutText [(localize "str_epoch_player_42"), "PLAIN DOWN"];};
+if (_onLadder) exitWith {DZE_ActionInProgress = false; cutText [localize "str_player_21", "PLAIN DOWN"];};
+if (player getVariable["combattimeout", 0] >= time) exitWith {DZE_ActionInProgress = false; cutText [(localize "str_epoch_player_43"), "PLAIN DOWN"];};
+
+_item = _this;
+
+// Need Near Requirements
+_abort = false;
+_reason = "";
+
+_needNear = getArray (configFile >> "CfgMagazines" >> _item >> "ItemActions" >> "Build" >> "neednearby");
+
+{
+ switch(_x) do{
+ case "fire":
+ {
+ _distance = 3;
+ _isNear = {inflamed _x} count (getPosATL player nearObjects _distance);
+ if(_isNear == 0) then {
+ _abort = true;
+ _reason = "fire";
+ };
+ };
+ case "workshop":
+ {
+ _distance = 3;
+ _isNear = count (nearestObjects [player, ["Wooden_shed_DZ","WoodShack_DZ","WorkBench_DZ"], _distance]);
+ if(_isNear == 0) then {
+ _abort = true;
+ _reason = "workshop";
+ };
+ };
+ case "fueltank":
+ {
+ _distance = 30;
+ _isNear = count (nearestObjects [player, dayz_fuelsources, _distance]);
+ if(_isNear == 0) then {
+ _abort = true;
+ _reason = "fuel tank";
+ };
+ };
+ };
+} forEach _needNear;
+
+
+if(_abort) exitWith {
+ cutText [format[(localize "str_epoch_player_135"),_reason,_distance], "PLAIN DOWN"];
+ DZE_ActionInProgress = false;
+};
+
+_classname = getText (configFile >> "CfgMagazines" >> _item >> "ItemActions" >> "Build" >> "create");
+_classnametmp = _classname;
+_require = getArray (configFile >> "cfgMagazines" >> _this >> "ItemActions" >> "Build" >> "require");
+_text = getText (configFile >> "CfgVehicles" >> _classname >> "displayName");
+_ghost = getText (configFile >> "CfgVehicles" >> _classname >> "ghostpreview");
+
+_lockable = 0;
+if(isNumber (configFile >> "CfgVehicles" >> _classname >> "lockable")) then {
+ _lockable = getNumber(configFile >> "CfgVehicles" >> _classname >> "lockable");
+};
+
+_requireplot = DZE_requireplot;
+if(isNumber (configFile >> "CfgVehicles" >> _classname >> "requireplot")) then {
+ _requireplot = getNumber(configFile >> "CfgVehicles" >> _classname >> "requireplot");
+};
+
+_isAllowedUnderGround = 1;
+if(isNumber (configFile >> "CfgVehicles" >> _classname >> "nounderground")) then {
+ _isAllowedUnderGround = getNumber(configFile >> "CfgVehicles" >> _classname >> "nounderground");
+};
+
+_offset = getArray (configFile >> "CfgVehicles" >> _classname >> "offset");
+if((count _offset) <= 0) then {
+ _offset = [0,1.5,0];
+};
+
+_isPole = (_classname == "Plastic_Pole_EP1_DZ");
+_isLandFireDZ = (_classname == "Land_Fire_DZ");
+
+_distance = DZE_PlotPole select 0;
+_needText = localize "str_epoch_player_246";
+
+if(_isPole) then {
+ _distance = DZE_PlotPole select 1;
+};
+
+// check for near plot
+_findNearestPoles = nearestObjects [(vehicle player), ["Plastic_Pole_EP1_DZ"], _distance];
+_findNearestPole = [];
+
+{
+ if (alive _x) then {
+ _findNearestPole set [(count _findNearestPole),_x];
+ };
+} count _findNearestPoles;
+
+_IsNearPlot = count (_findNearestPole);
+
+// If item is plot pole && another one exists within 45m
+if(_isPole && _IsNearPlot > 0) exitWith { DZE_ActionInProgress = false; cutText [(localize "str_epoch_player_44") , "PLAIN DOWN"]; };
+
+if(_IsNearPlot == 0) then {
+
+ // Allow building of plot
+ if(_requireplot == 0 || _isLandFireDZ) then {
+ _canBuildOnPlot = true;
+ };
+
+} else {
+ // Since there are plots nearby we check for ownership && then for friend status
+
+ // check nearby plots ownership && then for friend status
+ _nearestPole = _findNearestPole select 0;
+
+ // Find owner
+ _ownerID = _nearestPole getVariable ["CharacterID","0"];
+
+ // diag_log format["DEBUG BUILDING: %1 = %2", dayz_characterID, _ownerID];
+
+ // check if friendly to owner
+ if(dayz_characterID == _ownerID) then { //Keep ownership
+ // owner can build anything within his plot except other plots
+ if(!_isPole) then {
+ _canBuildOnPlot = true;
+ };
+
+ } else {
+ // disallow building plot
+ if(!_isPole) then {
+ _friendlies = player getVariable ["friendlyTo",[]];
+ // check if friendly to owner
+ if(_ownerID in _friendlies) then {
+ _canBuildOnPlot = true;
+ };
+ };
+ };
+};
+
+// _message
+if(!_canBuildOnPlot) exitWith { DZE_ActionInProgress = false; cutText [format[(localize "STR_EPOCH_PLAYER_135"),_needText,_distance] , "PLAIN DOWN"]; };
+
+_missing = "";
+_hasrequireditem = true;
+{
+ _hastoolweapon = _x in weapons player;
+ if(!_hastoolweapon) exitWith { _hasrequireditem = false; _missing = getText (configFile >> "cfgWeapons" >> _x >> "displayName"); };
+} count _require;
+
+_hasbuilditem = _this in magazines player;
+if (!_hasbuilditem) exitWith {DZE_ActionInProgress = false; cutText [format[(localize "str_player_31"),_text,"build"] , "PLAIN DOWN"]; };
+
+if (!_hasrequireditem) exitWith {DZE_ActionInProgress = false; cutText [format[(localize "str_epoch_player_137"),_missing] , "PLAIN DOWN"]; };
+if (_hasrequireditem) then {
+
+ _location = [0,0,0];
+ _isOk = true;
+
+ // get inital players position
+ _location1 = getPosATL player;
+ _dir = getDir player;
+
+ // if ghost preview available use that instead
+ if (_ghost != "") then {
+ _classname = _ghost;
+ };
+
+ _object = createVehicle [_classname, _location, [], 0, "CAN_COLLIDE"];
+ //Build gizmo
+ _objectHelper = "Sign_sphere10cm_EP1" createVehicle _location;
+ _helperColor = "#(argb,8,8,3)color(0,0,0,0,ca)";
+ _objectHelper setobjecttexture [0,_helperColor];
+ _objectHelper attachTo [player,_offset];
+ _object attachTo [_objectHelper,[0,0,0]];
+ _position = getPosATL _objectHelper;
+
+ //cutText [(localize "str_epoch_player_45"), "PLAIN DOWN"];
+
+ _objHDiff = 0;
+
+if (isClass (configFile >> "SnapBuilding" >> _classname)) then {
+ ["","","",["Init",_object,_classname,_objectHelper]] spawn snap_build;
+};
+
+ while {_isOk} do {
+
+ _zheightchanged = false;
+ _zheightdirection = "";
+ _rotate = false;
+
+ if (DZE_Q) then {
+ DZE_Q = false;
+ _zheightdirection = "up";
+ _zheightchanged = true;
+ };
+ if (DZE_Z) then {
+ DZE_Z = false;
+ _zheightdirection = "down";
+ _zheightchanged = true;
+ };
+ if (DZE_Q_alt) then {
+ DZE_Q_alt = false;
+ _zheightdirection = "up_alt";
+ _zheightchanged = true;
+ };
+ if (DZE_Z_alt) then {
+ DZE_Z_alt = false;
+ _zheightdirection = "down_alt";
+ _zheightchanged = true;
+ };
+ if (DZE_Q_ctrl) then {
+ DZE_Q_ctrl = false;
+ _zheightdirection = "up_ctrl";
+ _zheightchanged = true;
+ };
+ if (DZE_Z_ctrl) then {
+ DZE_Z_ctrl = false;
+ _zheightdirection = "down_ctrl";
+ _zheightchanged = true;
+ };
+ if (DZE_4) then {
+ _rotate = true;
+ DZE_4 = false;
+ if (helperDetach) then {
+ _dir = -45;
+ } else {
+ _dir = 180;
+ };
+ };
+ if (DZE_6) then {
+ _rotate = true;
+ DZE_6 = false;
+ if (helperDetach) then {
+ _dir = 45;
+ } else {
+ _dir = 0;
+ };
+ };
+
+ if (DZE_F and _canDo) then {
+ if (helperDetach) then {
+ _objectHelperDir = getDir _objectHelper;
+ _objectHelper attachTo [player];
+ _objectHelper setDir _objectHelperDir-(getDir player);
+ helperDetach = false;
+ } else {
+ _objectHelperPos = getPosATL _objectHelper;
+ detach _objectHelper;
+ _objectHelper setPosATL _objectHelperPos;
+ _objectHelperDir = getDir _objectHelper;
+ _objectHelper setVelocity [0,0,0]; //fix sliding glitch
+ helperDetach = true;
+ };
+ DZE_F = false;
+ };
+
+ if(_rotate) then {
+ if (helperDetach) then {
+ _objectHelperDir = getDir _objectHelper;
+ _objectHelperPos = getPosATL _objectHelper;
+ _objectHelper setDir _objectHelperDir+_dir;
+ _objectHelper setPosATL _objectHelperPos;
+ } else {
+ _objectHelper setDir _dir;
+ _objectHelper setPosATL _position;
+ //diag_log format["DEBUG Rotate BUILDING POS: %1", _position];
+ };
+
+ };
+
+ if(_zheightchanged) then {
+ if (!helperDetach) then {
+ detach _objectHelper;
+ };
+
+ _position = getPosATL _objectHelper;
+
+ if(_zheightdirection == "up") then {
+ _position set [2,((_position select 2)+0.1)];
+ _objHDiff = _objHDiff + 0.1;
+ };
+ if(_zheightdirection == "down") then {
+ _position set [2,((_position select 2)-0.1)];
+ _objHDiff = _objHDiff - 0.1;
+ };
+
+ if(_zheightdirection == "up_alt") then {
+ _position set [2,((_position select 2)+1)];
+ _objHDiff = _objHDiff + 1;
+ };
+ if(_zheightdirection == "down_alt") then {
+ _position set [2,((_position select 2)-1)];
+ _objHDiff = _objHDiff - 1;
+ };
+
+ if(_zheightdirection == "up_ctrl") then {
+ _position set [2,((_position select 2)+0.01)];
+ _objHDiff = _objHDiff + 0.01;
+ };
+ if(_zheightdirection == "down_ctrl") then {
+ _position set [2,((_position select 2)-0.01)];
+ _objHDiff = _objHDiff - 0.01;
+ };
+
+ _objectHelper setDir (getDir _objectHelper);
+
+ if((_isAllowedUnderGround == 0) && ((_position select 2) < 0)) then {
+ _position set [2,0];
+ };
+
+ _objectHelper setPosATL _position;
+
+ //diag_log format["DEBUG Change BUILDING POS: %1", _position];
+
+ if (!helperDetach) then {
+ _objectHelper attachTo [player];
+ };
+ };
+
+ sleep 0.5;
+
+ _location2 = getPosATL player;
+
+ if(DZE_5) exitWith {
+ _isOk = false;
+ detach _object;
+ _dir = getDir _object;
+ _position = getPosATL _object;
+ //diag_log format["DEBUG BUILDING POS: %1", _position];
+ deleteVehicle _object;
+ detach _objectHelper;
+ deleteVehicle _objectHelper;
+ };
+
+ if(_location1 distance _location2 > 10) exitWith {
+ _isOk = false;
+ _cancel = true;
+ _reason = "You've moved to far away from where you started building (within 10 meters)";
+ detach _object;
+ deleteVehicle _object;
+ detach _objectHelper;
+ deleteVehicle _objectHelper;
+ };
+
+ if(abs(_objHDiff) > 10) exitWith {
+ _isOk = false;
+ _cancel = true;
+ _reason = "Cannot move up or down more than 10 meters";
+ detach _object;
+ deleteVehicle _object;
+ detach _objectHelper;
+ deleteVehicle _objectHelper;
+ };
+
+ if (player getVariable["combattimeout", 0] >= time) exitWith {
+ _isOk = false;
+ _cancel = true;
+ _reason = (localize "str_epoch_player_43");
+ detach _object;
+ deleteVehicle _object;
+ detach _objectHelper;
+ deleteVehicle _objectHelper;
+ };
+
+ if (DZE_cancelBuilding) exitWith {
+ _isOk = false;
+ _cancel = true;
+ _reason = "Cancelled building.";
+ detach _object;
+ deleteVehicle _object;
+ detach _objectHelper;
+ deleteVehicle _objectHelper;
+ };
+ };
+
+ //No building on roads unless toggled
+ if (!DZE_BuildOnRoads) then {
+ if (isOnRoad _position) then { _cancel = true; _reason = "Cannot build on a road."; };
+ };
+
+ // No building in trader zones
+ if(!canbuild) then { _cancel = true; _reason = "Cannot build in a city."; };
+
+ if(!_cancel) then {
+
+ _classname = _classnametmp;
+
+ // Start Build
+ _tmpbuilt = createVehicle [_classname, _location, [], 0, "CAN_COLLIDE"];
+
+ _tmpbuilt setdir _dir;
+
+ // Get position based on object
+ _location = _position;
+
+ if((_isAllowedUnderGround == 0) && ((_location select 2) < 0)) then {
+ _location set [2,0];
+ };
+
+ _tmpbuilt setPosATL _location;
+
+
+ cutText [format[(localize "str_epoch_player_138"),_text], "PLAIN DOWN"];
+
+ _limit = 3;
+
+ if (DZE_StaticConstructionCount > 0) then {
+ _limit = DZE_StaticConstructionCount;
+ }
+ else {
+ if (isNumber (configFile >> "CfgVehicles" >> _classname >> "constructioncount")) then {
+ _limit = getNumber(configFile >> "CfgVehicles" >> _classname >> "constructioncount");
+ };
+ };
+
+ _isOk = true;
+ _proceed = false;
+ _counter = 0;
+
+ while {_isOk} do {
+
+ [10,10] call dayz_HungerThirst;
+ player playActionNow "Medic";
+
+ _dis=20;
+ _sfx = "repair";
+ [player,_sfx,0,false,_dis] call dayz_zombieSpeak;
+ [player,_dis,true,(getPosATL player)] spawn player_alertZombies;
+
+ r_interrupt = false;
+ r_doLoop = true;
+ _started = false;
+ _finished = false;
+
+ while {r_doLoop} do {
+ _animState = animationState player;
+ _isMedic = ["medic",_animState] call fnc_inString;
+ if (_isMedic) then {
+ _started = true;
+ };
+ if (_started && !_isMedic) then {
+ r_doLoop = false;
+ _finished = true;
+ };
+ if (r_interrupt || (player getVariable["combattimeout", 0] >= time)) then {
+ r_doLoop = false;
+ };
+ if (DZE_cancelBuilding) exitWith {
+ r_doLoop = false;
+ };
+ sleep 0.1;
+ };
+ r_doLoop = false;
+
+
+ if(!_finished) exitWith {
+ _isOk = false;
+ _proceed = false;
+ };
+
+ if(_finished) then {
+ _counter = _counter + 1;
+ };
+
+ cutText [format[(localize "str_epoch_player_139"),_text, _counter,_limit], "PLAIN DOWN"];
+
+ if(_counter == _limit) exitWith {
+ _isOk = false;
+ _proceed = true;
+ };
+
+ };
+
+ if (_proceed) then {
+
+ _num_removed = ([player,_item] call BIS_fnc_invRemove);
+ if(_num_removed == 1) then {
+
+ cutText [format[localize "str_build_01",_text], "PLAIN DOWN"];
+
+ if (_isPole) then {
+ [] spawn player_plotPreview;
+ };
+
+ _tmpbuilt setVariable ["OEMPos",_location,true];
+
+ if(_lockable > 1) then {
+
+ _combinationDisplay = "";
+
+ switch (_lockable) do {
+
+ case 2: { // 2 lockbox
+ _combination_1 = (floor(random 3)) + 100; // 100=red,101=green,102=blue
+ _combination_2 = floor(random 10);
+ _combination_3 = floor(random 10);
+ _combination = format["%1%2%3",_combination_1,_combination_2,_combination_3];
+ dayz_combination = _combination;
+ if (_combination_1 == 100) then {
+ _combination_1_Display = "Red";
+ };
+ if (_combination_1 == 101) then {
+ _combination_1_Display = "Green";
+ };
+ if (_combination_1 == 102) then {
+ _combination_1_Display = "Blue";
+ };
+ _combinationDisplay = format["%1%2%3",_combination_1_Display,_combination_2,_combination_3];
+ };
+
+ case 3: { // 3 combolock
+ _combination_1 = floor(random 10);
+ _combination_2 = floor(random 10);
+ _combination_3 = floor(random 10);
+ _combination = format["%1%2%3",_combination_1,_combination_2,_combination_3];
+ dayz_combination = _combination;
+ _combinationDisplay = _combination;
+ };
+
+ case 4: { // 4 safe
+ _combination_1 = floor(random 10);
+ _combination_2 = floor(random 10);
+ _combination_3 = floor(random 10);
+ _combination_4 = floor(random 10);
+ _combination = format["%1%2%3%4",_combination_1,_combination_2,_combination_3,_combination_4];
+ dayz_combination = _combination;
+ _combinationDisplay = _combination;
+ };
+ };
+
+ _tmpbuilt setVariable ["CharacterID",_combination,true];
+
+
+ PVDZE_obj_Publish = [_combination,_tmpbuilt,[_dir,_location],_classname];
+ publicVariableServer "PVDZE_obj_Publish";
+
+ cutText [format[(localize "str_epoch_player_140"),_combinationDisplay,_text], "PLAIN DOWN", 5];
+
+
+ } else {
+ _tmpbuilt setVariable ["CharacterID",dayz_characterID,true];
+
+ // fire?
+ if(_tmpbuilt isKindOf "Land_Fire_DZ") then {
+ _tmpbuilt spawn player_fireMonitor;
+ } else {
+ PVDZE_obj_Publish = [dayz_characterID,_tmpbuilt,[_dir,_location],_classname];
+ publicVariableServer "PVDZE_obj_Publish";
+ };
+ };
+ } else {
+ deleteVehicle _tmpbuilt;
+ cutText [(localize "str_epoch_player_46") , "PLAIN DOWN"];
+ };
+
+ } else {
+ r_interrupt = false;
+ if (vehicle player == player) then {
+ [objNull, player, rSwitchMove,""] call RE;
+ player playActionNow "stop";
+ };
+
+ deleteVehicle _tmpbuilt;
+
+ cutText [(localize "str_epoch_player_46") , "PLAIN DOWN"];
+ };
+
+ } else {
+ cutText [format[(localize "str_epoch_player_47"),_text,_reason], "PLAIN DOWN"];
+ };
+};
+
+DZE_ActionInProgress = false;
diff --git a/SQF/dayz_code/actions/snap_build.sqf b/SQF/dayz_code/actions/snap_build.sqf
new file mode 100644
index 000000000..a325a01e6
--- /dev/null
+++ b/SQF/dayz_code/actions/snap_build.sqf
@@ -0,0 +1,293 @@
+/*-----------------------------------*/
+// by Raymix //
+// July 10 2014 //
+/*--------------------------------*/
+
+private ["_object","_objectSnapGizmo","_objColorActive","_objColorInactive","_classname","_whitelist","_points","_cfg","_cnt","_pos","_findWhitelisted","_nearbyObject","_posNearby","_selectedAction","_newPos","_pointsNearby","_onWater"];
+//Args
+snapActionState = _this select 3 select 0;
+_object = _this select 3 select 1;
+_classname = _this select 3 select 2;
+_objectHelper = _this select 3 select 3;
+_selectedAction = _this select 3 select 4;
+
+//Snap config file
+_cfg = (configFile >> "SnapBuilding" >> _classname);
+_whitelist = getArray (_cfg >> "snapTo");
+_points = getArray (_cfg >> "points");
+
+//colors
+_objColorActive = "#(argb,8,8,3)color(0,0.92,0.06,1,ca)";
+_objColorInactive = "#(argb,8,8,3)color(0.04,0.84,0.92,0.3,ca)";
+
+
+fnc_snapActionCleanup = {
+ private ["_s1","_s2","_s3","_cnt"];
+ _s1 = _this select 0;
+ _s2 = _this select 1;
+ _s3 = _this select 2;
+ player removeAction s_player_toggleSnap;
+ player removeAction s_player_toggleSnapSelect;
+ {player removeAction _x;} count s_player_toggleSnapSelectPoint;
+ if (_s1 > 0) then {
+ s_player_toggleSnap = player addaction [format[("" + ("Snap: %1") +""),snapActionState],"\z\addons\dayz_code\actions\snap_build.sqf",[snapActionState,_object,_classname,_objectHelper],6,false,true];
+ };
+ if (_s2 > 0) then {
+ s_player_toggleSnapSelect = player addaction [format[("" + ("Snap Point: %1") +""),snapActionStateSelect],"\z\addons\dayz_code\actions\snap_build.sqf",[snapActionStateSelect,_object,_classname,_objectHelper],5,false,true];
+ };
+ if (_s3 > 0) then {
+ s_player_toggleSnapSelectPoint=[];
+ _cnt = 0;
+ {snapActions = player addaction [format[("" + ("%1)Select: %2") +""),_cnt,_x select 3],"\z\addons\dayz_code\actions\snap_build.sqf",["Selected",_object,_classname,_objectHelper,_cnt],4,false,false];
+ s_player_toggleSnapSelectPoint set [count s_player_toggleSnapSelectPoint,snapActions];
+ _cnt = _cnt+1;
+ }count _points;
+ };
+};
+
+fnc_initSnapPoints = {
+ snapGizmos = [];
+ {
+ _objectSnapGizmo = "Sign_sphere10cm_EP1" createVehicleLocal [0,0,0];
+ _objectSnapGizmo setobjecttexture [0,_objColorInactive];
+ _objectSnapGizmo attachTo [_object,[_x select 0,_x select 1,_x select 2]];
+ snapGizmos set [count snapGizmos,_objectSnapGizmo];
+ } count _points;
+};
+
+fnc_initSnapPointsNearby = {
+ _pos = getPosATL _object;
+ _findWhitelisted = []; _pointsNearby = [];
+ _findWhitelisted = nearestObjects [_pos,_whitelist,15]-[_object];
+ snapGizmosNearby = [];
+ {
+ _nearbyObject = _x;
+ _pointsNearby = getArray (configFile >> "SnapBuilding" >> (typeOf _x) >> "points");
+ {
+ _onWater = surfaceIsWater position _nearbyObject;
+ _objectSnapGizmo = "Sign_sphere10cm_EP1" createVehicleLocal [0,0,0];
+ _objectSnapGizmo setobjecttexture [0,_objColorInactive];
+ _posNearby = _nearbyObject modelToWorld [_x select 0,_x select 1,_x select 2];
+ if (_onWater) then {
+ _objectSnapGizmo setPosASL [(_posNearby) select 0,(_posNearby) select 1,(getPosASL _nearbyObject select 2) + (_x select 2)];
+ } else {
+ _objectSnapGizmo setPosATL _posNearby;
+ };
+ _objectSnapGizmo setDir (getDir _nearbyObject);
+ snapGizmosNearby set [count snapGizmosNearby,_objectSnapGizmo];
+ } count _pointsNearby;
+ } forEach _findWhitelisted;
+};
+
+fnc_initSnapPointsCleanup = {
+ {detach _x;deleteVehicle _x;}count snapGizmos;snapGizmos=[];
+ {deleteVehicle _x;}count snapGizmosNearby;snapGizmosNearby=[];
+ snapActionState = "OFF";
+};
+
+fnc_snapDistanceCheck = {
+ while {snapActionState != "OFF"} do {
+ private ["_distClosestPointFound","_distCheck","_distClosest","_distClosestPoint","_testXPos","_testXDir","_distClosestPointFoundPos","_distClosestPointFoundDir","_distClosestAttached","_distCheckAttached","_distClosestAttachedFoundPos"];
+ _distClosestPointFound = objNull; _distCheck = 0; _distClosest = 10; _distClosestPoint = objNull; _testXPos = []; _distClosestPointFoundPos =[]; _distClosestPointFoundDir = 0;
+ {
+ if (_x !=_distClosestPointFound) then {_x setobjecttexture [0,_objColorInactive];};
+ _onWater = surfaceIsWater position _x;
+ if (_onWater) then {
+ _testXPos = [(getPosASL _x select 0),(getPosASL _x select 1),(getPosASL _x select 2)];
+ } else {
+ _testXPos = [(getPosATL _x select 0),(getPosATL _x select 1),(getPosATL _x select 2)];
+ };
+ _distCheck = _objectHelper distance _testXPos;
+ _distClosestPoint = _x;
+ if (_distCheck < _distClosest) then {
+ _distClosest = _distCheck;
+ _distClosestPointFound setobjecttexture [0,_objColorInactive];
+ _distClosestPointFound = _x;
+ _distClosestPointFound setobjecttexture [0,_objColorActive];
+ };
+ } count snapGizmosNearby;
+
+ if (!isNull _distClosestPointFound) then {
+ if (snapActionStateSelect == "Manual") then {
+ if (helperDetach) then {
+ _onWater = surfaceIsWater position _distClosestPointFound;
+ _distClosestPointFoundDir = getDir _distClosestPointFound;
+ if (_onWater) then {
+ _distClosestPointFoundPos = getPosASL _distClosestPointFound;
+ _objectHelper setPosASL _distClosestPointFoundPos;
+ } else {
+ _distClosestPointFoundPos = getPosATL _distClosestPointFound;
+ _objectHelper setPosATL _distClosestPointFoundPos;
+ };
+ _objectHelper setDir _distClosestPointFoundDir;
+ waitUntil {sleep 0.1; !helperDetach};
+ };
+ } else {
+ _distClosestAttached = objNull; _distCheckAttached = 0; _distClosest = 10; _distClosestAttachedFoundPos = [];
+ {
+ if (_x !=_distClosestAttached) then {_x setobjecttexture [0,_objColorInactive];};
+ _onWater = surfaceIsWater position _x;
+ if (_onWater) then {
+ _testXPos = [(getPosASL _x select 0),(getPosASL _x select 1),(getPosASL _x select 2)];
+ } else {
+ _testXPos = [(getPosATL _x select 0),(getPosATL _x select 1),(getPosATL _x select 2)];
+ };
+ _distCheckAttached = _distClosestPointFound distance _testXPos;
+ _distClosestPoint = _x;
+ if (_distCheckAttached < _distClosest) then {
+ _distClosest = _distCheckAttached;
+ _distClosestAttached setobjecttexture [0,_objColorInactive];
+ _distClosestAttached = _x;
+ _distClosestAttached setobjecttexture [0,_objColorActive];
+ };
+ } count snapGizmos;
+
+ if (helperDetach) then {
+ _distClosestPointFoundDir = getDir _distClosestPointFound;
+ _onWater = surfaceIsWater position _distClosestPointFound;
+ if (_onWater) then {
+ _distClosestPointFoundPos = getPosASL _distClosestPointFound;
+ _distClosestAttachedFoundPos = getPosASL _distClosestAttached;
+ detach _object;
+ _objectHelper setPosASL _distClosestAttachedFoundPos;
+ _object attachTo [_objectHelper];
+ _objectHelper setPosASL _distClosestPointFoundPos;
+ } else {
+ _distClosestPointFoundPos = getPosATL _distClosestPointFound;
+ _distClosestAttachedFoundPos = getPosATL _distClosestAttached;
+ detach _object;
+ _objectHelper setPosATL _distClosestAttachedFoundPos;
+ _object attachTo [_objectHelper];
+ _objectHelper setPosATL _distClosestPointFoundPos;
+ };
+ _objectHelper setDir _distClosestPointFoundDir;
+ waitUntil {sleep 0.1; !helperDetach};
+ };
+ };
+ };
+ sleep 0.1;
+ };
+};
+
+fnc_initSnapTutorial = {
+/*
+ Shows help dialog for player ONCE per log in, explaining controls.
+ Add snapTutorial = false; to your init.sqf to disable this tutorial completely.
+ You can also add this bool to the end of this function to only show tutorial once per player login (not recommended)
+*/
+ private ["_bldTxtSwitch","_bldTxtEnable","_bldTxtClrO","_bldTxtClrW","_bldTxtClrR","_bldTxtClrG","_bldTxtSz","_bldTxtSzT","_bldTxtShdw","_bldTxtAlgnL","_bldTxtUndrln","_bldTxtBold","_bldTxtFinal","_bldTxtStringTitle","_bldTxtStringSD","_bldTxtStringSE","_bldTxtStringSA","_bldTxtStringSM","_bldTxtStringPG","_bldTxtStringAPG","_bldTxtStringCPG","_bldTxtStringQE","_bldTxtStringQEF","_bldTxtStringFD","_bldTxtStringFS"];
+ if (isNil "snapTutorial") then {
+ _bldTxtSwitch = _this select 0;
+ _bldTxtEnable = _this select 1;
+ _bldTxtClrO = "color='#ff8800'"; //orange
+ _bldTxtClrW = "color='#ffffff'"; //white
+ _bldTxtClrR = "color='#fd0a05'"; //red
+ _bldTxtClrG = "color='#11ef00'"; //green
+ _bldTxtSz = "size='0.76'"; //Title font size
+ _bldTxtSzT = "size='0.4'"; //Text font size
+ _bldTxtShdw = "shadow='1'"; //Font shadow
+ _bldTxtAlgnL = "align='left'"; //Text align left
+ _bldTxtUndrln = "underline='true'";
+ _bldTxtBold = "font='Zeppelin33'"; //Bold text
+ _bldTxtFinal = "";
+
+ //Delete on init
+ 800 cutRsc ["Default", "PLAIN"];
+ sleep 0.1;
+
+ //Init Tutorial text
+ if (_bldTxtEnable) then {
+ _bldTxtStringTitle = format ["Epoch Snap Building
",_bldTxtClrW,_bldTxtSz,_bldTxtShdw,_bldTxtAlgnL,_bldTxtClrO,_bldTxtUndrln,_bldTxtBold];
+ _bldTxtStringSD = format["[Snap] Disabled: use action menu to enable.
",_bldTxtClrO,_bldTxtClrR,_bldTxtClrW,_bldTxtSzT,_bldTxtShdw,_bldTxtAlgnL];
+ _bldTxtStringSE = format["[Snap] Enabled: use action menu to disable.
",_bldTxtClrO,_bldTxtClrG,_bldTxtClrW,_bldTxtSzT,_bldTxtShdw,_bldTxtAlgnL];
+ _bldTxtStringSA = format["[Auto]: Automatic snap point detection.
",_bldTxtClrO,_bldTxtClrW,_bldTxtSzT,_bldTxtShdw,_bldTxtAlgnL];
+ _bldTxtStringSM = format["[Manual]: Select your preferred snap point.
",_bldTxtClrO,_bldTxtClrW,_bldTxtSzT,_bldTxtShdw,_bldTxtAlgnL];
+ _bldTxtStringPG = format["[PgUP / PgDOWN]: Adjust height of object by 10cm
",_bldTxtClrO,_bldTxtClrW,_bldTxtSzT,_bldTxtShdw,_bldTxtAlgnL];
+ _bldTxtStringAPG = format["[Alt]+[PgUP / PgDOWN]: Adjust height of object by 1m
",_bldTxtClrO,_bldTxtClrW,_bldTxtSzT,_bldTxtShdw,_bldTxtAlgnL];
+ _bldTxtStringCPG = format["[Ctrl]+[PgUP / PgDOWN]: Adjust height of object by 1cm
",_bldTxtClrO,_bldTxtClrW,_bldTxtSzT,_bldTxtShdw,_bldTxtAlgnL];
+ _bldTxtStringQE = format["[Q / E]: Rotate object 180 degrees while holding.
",_bldTxtClrO,_bldTxtClrW,_bldTxtSzT,_bldTxtShdw,_bldTxtAlgnL];
+ _bldTxtStringQEF = format["[Q / E]: Rotate object 45 degrees while dropped or snapped.
",_bldTxtClrO,_bldTxtClrW,_bldTxtSzT,_bldTxtShdw,_bldTxtAlgnL];
+ _bldTxtStringFD = format["[F]: Drop / Pick up object.
",_bldTxtClrO,_bldTxtClrW,_bldTxtSzT,_bldTxtShdw,_bldTxtAlgnL];
+ _bldTxtStringFS = format["[F]: Snap /Pick up object.
",_bldTxtClrO,_bldTxtClrW,_bldTxtSzT,_bldTxtShdw,_bldTxtAlgnL];
+ switch (_bldTxtSwitch) do {
+ case "init": {
+ _bldTxtFinal = _bldTxtStringTitle + _bldTxtStringSD + _bldTxtStringPG + _bldTxtStringAPG + _bldTxtStringCPG + _bldTxtStringQE + _bldTxtStringQEF + _bldTxtStringFD;
+ };
+ case "OnAuto": {
+ _bldTxtFinal = _bldTxtStringTitle + _bldTxtStringSE + _bldTxtStringSA + _bldTxtStringPG + _bldTxtStringAPG + _bldTxtStringCPG + _bldTxtStringQE + _bldTxtStringQEF + _bldTxtStringFS;
+ };
+ case "manual": {
+ _bldTxtFinal = _bldTxtStringTitle + _bldTxtStringSE + _bldTxtStringSM + _bldTxtStringPG + _bldTxtStringAPG + _bldTxtStringCPG + _bldTxtStringQE + _bldTxtStringQEF + _bldTxtStringFS;
+ };
+ };
+
+ [
+ _bldTxtFinal, //structured text
+ [0.73 * safezoneW + safezoneX], //number - x
+ [0.65 * safezoneH + safezoneY], //number - y
+ 30, //number - duration
+ 1, // number - fade in time
+ 0, // number - delta y
+ 800 //number - layer ID
+ ] spawn bis_fnc_dynamicText;
+ };
+ };
+};
+
+switch (snapActionState) do {
+ case "Init": {
+ ["init",true] call fnc_initSnapTutorial;
+ snapActionState = "OFF";
+ [1,0,0] call fnc_snapActionCleanup;
+ [] spawn {
+ while {true} do {
+ if(!DZE_ActionInProgress) exitWith {call fnc_initSnapPointsCleanup;[0,0,0] call fnc_snapActionCleanup; ["",false] call fnc_initSnapTutorial; snapActionState = "OFF";};
+ sleep 2;
+ };
+ };
+ };
+ case "OFF": {
+ ["OnAuto",true] call fnc_initSnapTutorial;
+ snapActionState = "ON"; snapActionStateSelect = "Auto";
+ [1,1,0] call fnc_snapActionCleanup;
+ call fnc_initSnapPoints;
+ call fnc_initSnapPointsNearby;
+ sleep 0.25;
+ call fnc_snapDistanceCheck;
+ };
+
+ case "ON": {
+ ["init",true] call fnc_initSnapTutorial;
+ snapActionState = "OFF";
+ [1,0,0] call fnc_snapActionCleanup;
+ call fnc_initSnapPointsCleanup;
+ };
+
+ case "Auto": {
+ ["manual",true] call fnc_initSnapTutorial;
+ snapActionState = "ON";snapActionStateSelect = "Manual";
+ [1,1,1] call fnc_snapActionCleanup;
+ };
+
+ case "Manual": {
+ ["OnAuto",true] call fnc_initSnapTutorial;
+ snapActionState = "ON";snapActionStateSelect = "Auto";
+ [1,1,0] call fnc_snapActionCleanup;
+ };
+
+ case "Selected": { _cnt = 0; _newPos = [];
+{
+ _x setobjecttexture [0,_objColorInactive];
+ if (_cnt == _selectedAction) then {
+ _newPos = [(getPosATL _x select 0),(getPosATL _x select 1),(getPosATL _x select 2)];
+ detach _object;
+ detach _objectHelper;
+ _objectHelper setPosATL _newPos;
+ _object attachTo [_objectHelper];
+ _x setobjecttexture [0,_objColorActive];
+ if (!helperDetach) then {_objectHelper attachTo [player];};
+ };
+ _cnt = _cnt+1;
+}count snapGizmos;
+ };
+};
diff --git a/SQF/dayz_code/config.cpp b/SQF/dayz_code/config.cpp
index becabf882..db6405fcd 100644
--- a/SQF/dayz_code/config.cpp
+++ b/SQF/dayz_code/config.cpp
@@ -97,5 +97,6 @@ class CfgAddons
#include "Configs\CfgAmmo.hpp"
#include "Configs\CfgLoot\CfgBuildingLoot.hpp"
#include "Configs\CfgArma.hpp"
+#include "Configs\CfgExtra\snappoints.hpp"
#include "external\R3F_Realism\R3F_Weight\R3F_CfgWeight.h"
\ No newline at end of file
diff --git a/SQF/dayz_code/init/compiles.sqf b/SQF/dayz_code/init/compiles.sqf
index b7950d631..e9ef510d9 100644
--- a/SQF/dayz_code/init/compiles.sqf
+++ b/SQF/dayz_code/init/compiles.sqf
@@ -106,7 +106,13 @@ if (!isDedicated) then {
player_sleep = compile preprocessFileLineNumbers "\z\addons\dayz_code\actions\player_sleep.sqf";
player_antiWall = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\player_antiWall.sqf";
player_deathBoard = compile preprocessFileLineNumbers "\z\addons\dayz_code\actions\list_playerDeathsAlt.sqf";
-
+
+ //Snap building - disabled by default, not sure about your stance towards this mod yet, feel free to edit
+ if (DZE_snapBuilding) then {
+ player_build = compile preprocessFileLineNumbers "\z\addons\dayz_code\actions\player_build2.sqf";
+ snap_build = compile preprocessFileLineNumbers "\z\addons\dayz_code\actions\snap_build.sqf";
+ };
+
player_plotPreview = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\object_showPlotRadius.sqf";
player_upgradeVehicle = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\player_upgradeVehicle.sqf";