Jump to content

[1.4.1] Snap Building PRO


Recommended Posts

snappro.png

 

Download files, updates and Installation instructions on:

Github

HQ Screenshot of an in-game Tutorial dialog

Ever wanted to run hardcore server with 3rd person cam disabled? Now's your chance.

 

Credits and Contributors:

Awol - player_build.sqf, Epoch and permission to modify script.

Mudzereli - Commanding menus

Rimblock - with modular build (github)

PryMary - with Plot for Life

KamikazeXeX - Support for

striker - using snap pro as a base for

 

Github contributors - mattispro, Mikeeeyy

 

 

Legal:

You can use/modify/redistribute this file as long as it complies with License. You can not use this script to promote donations or shops.

This script is open source, you are allowed to add it to your @mods as long as appropriate credits and terms of license are met.

Edited by raymix
Link to comment
Share on other sites

Q & A

 

Q: Is there a tutorial video showing how to install the addon?

A: Yes, a youtuber Dayz Playground have uploaded a nice and clean video showing how to install this addon, it is aimed towards GTX gaming servers, but the installation is actually the same everywhere.

 

Q: Can I add my own snap points or change some of yours and how do I do that?

A: Yes! Yes you can and here's how:

 

Q: Will this work with #n version?

A: I don't know, tested with 1.62.103718 / 1.5.0.1 only. (Help me update this one).

flakvest: "I can confirm this is working on 1.63 Overpoch"

Kixbike: "works perfectly on Epoch 1.0.5.1 , 1.63.112555 "

Anarior: "We're running Overpoch on 1.63.125548 and no issues at all."

Logan: "Working perfect Overpoch 1.0.5.1 112555"

 

Q: Will this work with Overpoch?

A: Yes, it was designed in Epoch and video was shot in Overpoch.

 

Q: Wait you removed commanding menus? I liked them!

A: Not entirely. To reduce compatibility issues I had to separate addon into 2 different repos. If you still prefer commanding menus, please use SnapProCMD repo.
 

Q: Anyone else notices fps drop or desync?

A: Please refer to

 

Q: My action menus are dissapearing / My select action menus are being deleted / My infistar AH is broken!!

A: Make sure to follow AH part very carefully on Installation page, it is important that you understand the changes you make there, don't blindly follow the guide. Variables goes on top, array goes on bottom part. A single typo will break the whole antihack!

 

Q: Will this work with "X" script?

A: If it uses custom player_build then no, but you can merge differences of my code with yours to get it to work, as I did not do much editing on original player_build.sqf file intentionally. It should be easy to port.

Watch this video, it explains in detail how code works (snap_build code part is a bit outdated, but it does cover full basics and shows How's and Why's, it also covers how player_build works)

 

Q: Can you fix my "Y" script? Can you make it work with "Z" script?

A: Probably no, as I've things to do, please stay on topic, if it's help on code you are seeking, post it away, but don't raise expectations, maybe  I will help, maybe someone else will, as I've much work to do with other bigger sorry.

 

Q:  I can turn snap on but when I hit "F" nothing happens despite 2 matching green dots.

A: Something is overwriting your dayz_spaceinterrupt.sqf file, check all your custom compiles and read

 

Q: Will this work with ""?

A: Maybe, check out for a code. EDIT: RimBlock is ?p=101271 of the issue, expect an update soon.

 

Q: Will this work with Admin Fast Build?

A: Yes. KamikazeXeX released guide how to make it compatible:

 

Q: It says object limit reached (or something along these lines), but I can still build without snap enabled?
A: You will need to either increase object limit inside of your init.sqf file OR you can exclude spheres from nearestObjects check in player_build.sqf

 

Q: I am getting BE: Script restriction #17 kicks

A: You are using latest BE filters by Infistar, remove line #19 (double check readme file on github)

 

Q: Have you encountered a problem when placing plotpole it spawns, and seems to put the entire radius of the plotpole where the plotpole is placed, MASS desync then ensues

A: Yes, it was related to Infistar AH, Chris is aware of an issue, see if new update fixes it and report back please.

 

Q: players on my server build very large bases with hundreds of objects. They reported me about massive fps-drops while using the snap function. So some players can't use it because of older hardware etc.  Any Idea how to reduce the amount of objects or improve the performance

A: Yeah, download the version 1.3 (or up). It lets you adjust ranges, negative values will reduce detection range effectively reducing snap point amount and giving more performance, add/adjust this to your init.sqf:

DZE_snapExtraRange = 0;

Q:  I had issues with not being able to return to the players lobby by pressing ESC after installing Snap Pro.

A: You are probably running 1.0.4.2, comment out

 

Positive/Negative Feedback from live servers:

STENCHOVDETH: "I've had this working on all my servers for about a week now and the players just go nuts for it."

Tricks: "This is very true, have it on my server and my players love it!"

Anarior: "Other than a few issues with people finding it quite complex to start with, the feedback has been overwhelmingly positive from users."

MatthewK: "Had this on my server for the past 24 hours and my players are spending so much time building stuff, they aren't even bothering to kill each other any more."

|Changelog----------------------------------|Date---------------|Version----|
|Rare bug fix  -----------------------------|30/08/2014---------|1.4.1------|
|ASL based player/snap_build, fixes, extras |21/08/2014---------|1.4--------|
|Full support for water bases --------------|09/08/2014---------|1.3.1------|
|Fixed defines, adjustable snap ranges -----|09/08/2014---------|1.3--------|
|Anti-grief temporarily removed	------------|23/07/2014---------|1.2.1------|
|CMD menus removed and pushed to a new repo-|21/07/2014---------|1.2.0------|
|Snap point radius is now config based------|18/07/2014---------|1.1.6------|
|Build range and anti-grief fix-------------|16/07/2014---------|1.1.5------|
|Missing stairs with support in config------|14/07/2014---------|1.1.4------|
|Code optimization, vault points added------|12/07/2014---------|1.1.3------|
|Ghost fix for metal floor (GenCamoUGL)-----|10/07/2014---------|1.1.2------|
|CMD/Action menu toggle---------------------|09/07/2014---------|1.1.1------|
|CMD menu added	(mudzerelli)----------------|09/07/2014---------|1.1.0------|
|Missing objects added----------------------|07/07/2014---------|1.0.1------|
|SBP release--------------------------------|06/07/2014---------|1.0.0------|
Edited by raymix
Link to comment
Share on other sites

Hello All,

I've had this working on all my servers for about a week now and the players just go nuts for it.

Also I would like to say a massive Thank You! to raymix and everyone that helped on this project.

Like Floss said it really does blow the old snapping out of the water.

Great Job as always raymix

 

Edit: Thank You raymix also for You Tube tutorials on how the actual code works for this addon.

STENCH

Link to comment
Share on other sites

Nice one raymix for this just have a couple of questions... Is this compatible with the following mods also:

 

Plot for life: 

 

Also WGAdmin build: 

 

I have tried this version of snap build and works to a degree but when placing a metal floor after first enabling snap by selecting OFF?!? (Mouse wheel option shows as off to select it as on!) then pressing f to snap i press space to build and it says built but the building object disappears!

 

I have included my player_build for you so you may be able to point me in the right direction of where I went wrong adding the above 2 mod's back into the player_build file:

 


/*
DayZ Base Building
Made for DayZ Epoch please ask permission to use/edit/distrubute email [email protected].
*/
private ["_helperColor","_objectHelper","_objectHelperDir","_objectHelperPos","_canDo","_location","_dir","_classname","_item","_hasRequiredTools","_missingT","_missingB","_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","_objHupDiff","_needNear","_vehicle","_inVehicle","_previewCounter","_requireplot","_objHDiff","_isLandFireDZ","_isTankTrap","_isNear2","_typeIsString","_isBuildAdmin","_needBuildItem","_hasbuilditems","_itemIn","_countIn","_qty","_missingQty","_textMissing","_removed","_tobe_removed_total","_removed_total","_ownerPUID", "_playerUID","_isHedgehog"];
 
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;
_isBuildAdmin = (getPlayerUID player) in WG_adminBuild;
 
_vehicle = vehicle player;
_inVehicle = (_vehicle != player);
_playerUID = getPlayerUID 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"];};
 
_typeIsString = ((typeName _this) == "STRING");
//diag_log format["Type is STRING: %1",_typeIsString];
if (_typeIsString) then {
_item = _this;
};
if (!_typeIsString) then {
_item = _this select 0;
};
 
// Need Near Requirements
_abort = false;
_reason = "";
 
if (_typeIsString) then {
_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]);
_isNear2 = 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;
};
};
 
if (_typeIsString) then {
_classname = getText (configFile >> "CfgMagazines" >> _item >> "ItemActions" >> "Build" >> "create");
_classnametmp = _classname;
_require =  getArray (configFile >> "cfgMagazines" >> _this >> "ItemActions" >> "Build" >> "require");
};
if (!_typeIsString) then {
_classname = _this select 0;
_classnametmp = _classname;
_require = _this select 1;
};
_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");
};
 
 
if (!_typeIsString) then {
_offset = _this select 3;
};
if (_typeIsString) then {
_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");
_isHedgehog = (_classname == "Hedgehog_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 ["ownerPUID","0"];
 
diag_log format["Player_build start: [PlayerUID = %1]  [OwnerID = %2]", _playerUID, _ownerID];
 
// check if friendly to owner
if(_playerUID == _ownerID) then {  //Keep ownership
// owner can build anything within his plot except other plots
diag_log text "Player is owner";
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;
};
};
};
};
 
//Item Check
if(!_canBuildOnPlot) exitWith {  DZE_ActionInProgress = false; cutText [format[(localize "STR_EPOCH_PLAYER_135"),_needText,_distance] , "PLAIN DOWN"]; };
 
_missingT = "";
_missingB = "";
_hasRequiredTools = true;
_hasbuilditem = true;
if (!_isBuildAdmin) then {
{
//diag_log format["Testing for tool: %1",_x];
_hastoolweapon = _x in weapons player;
if(!_hastoolweapon) exitWith {_hasRequiredTools = false; _missingT = getText (configFile >> "cfgWeapons" >> _x >> "displayName");};
} forEach _require;
 
if (!_typeIsString && _hasRequiredTools) then {
_needBuildItem = _this select 2;
{
_itemIn = _x select 0;
_countIn = _x select 1;
_qty = { (_x == _itemIn) || (configName(inheritsFrom(configFile >> "cfgMagazines" >> _x)) == _itemIn) } count magazines player;
if(_qty < _countIn) exitWith { _missingB = getText(configFile >> "CfgMagazines" >> _itemIn >> "displayName"); _missingQty = (_countIn - _qty); _hasbuilditem = false;};
} forEach _needBuildItem;
};
 
if (_typeIsString && _hasRequiredTools) then {
_hasbuilditem = _this in magazines player;
};
};
// Message If missing
if (!_hasRequiredTools) exitWith {DZE_ActionInProgress = false; cutText [format[(localize "str_epoch_player_137"),_missingT] , "PLAIN DOWN"];};
 
if (!_typeIsString && !_hasbuilditem) exitWith {DZE_ActionInProgress = false; cutText [format[(localize "str_epoch_player_146"),_missingQty, _missingB], "PLAIN DOWN"];};
 
if (_typeIsString && !_hasbuilditem) exitWith {DZE_ActionInProgress = false; cutText [format[(localize "str_player_31"),_text,"build"] , "PLAIN DOWN"]; };
 
 
//Proceed after item check
if (_hasRequiredTools && _hasbuilditem) 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 (missionConfigFile >> "SnapBuilding" >> _classname)) then {
["","","",["Init",_object,_classname,_objectHelper]] spawn snap_build;
};
 
_key_monitor = [_isAllowedUnderGround] spawn player_buildControls;
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) and ((_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 {
            if (!_isHedgehog) 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 {
//diag_log "Cancel is FALSE";
 
_classname = _classnametmp;
 
_location = _position;
 
if((_isAllowedUnderGround == 0) && ((_location select 2) < 0)) then {
_location set [2,0];
};
 
_object 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 && !_isBuildAdmin} 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;
_animState = animationState player;
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 (_isBuildAdmin) then {
_isOk = false;
_proceed = true;
};
 
if (_proceed) then {
//diag_log "Proceed OK";
_tobe_removed_total = 0;
_removed_total = 0;
_temp_removed_array = [];
if (!_isBuildAdmin) then {
//diag_log "Is Admin REMOVE NOT OK";
if (_typeIsString) then {
_tobe_removed_total = ([player,_item] call BIS_fnc_invRemove);
_removed_total = _tobe_removed_total;
};
if (!_typeIsString) then {
{
_removed = 0;
_itemIn = _x select 0;
_countIn = _x select 1;
// //diag_log format["Recipe Finish: %1 %2", _itemIn,_countIn];
_tobe_removed_total = _tobe_removed_total + _countIn;
 
{
if( (_removed < _countIn) && ((_x == _itemIn) || configName(inheritsFrom(configFile >> "cfgMagazines" >> _x)) == _itemIn)) then {
_num_removed = ([player,_x] call BIS_fnc_invRemove);
_removed = _removed + _num_removed;
_removed_total = _removed_total + _num_removed;
if(_num_removed >= 1) then {
_temp_removed_array set [count _temp_removed_array,_x];
};
};
} forEach magazines player;
} forEach _needBuildItem;
};
} else {
//diag_log "Is Admin REMOVE OK";
_tobe_removed_total = 1;
_removed_total = 1;
};
if((_tobe_removed_total == _removed_total) && (_removed_total >= 1)) then {
//diag_log "Removed Item OK";
cutText [format[localize "str_build_01",_text], "PLAIN DOWN"];
 
if (_isPole) then {
[] spawn player_plotPreview;
};
 
_object setVariable ["OEMPos",_location,true];
 
if(_lockable > 1) then {
//diag_log "Is Lockable OK";
_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;
};
};
 
_object setVariable ["CharacterID",_combination,true];
_object setVariable ["ownerPUID",_playerUID,true];
 
 
PVDZE_obj_Publish = [_combination,_object,[_dir,_location],_classname];
//diag_log "Publish Lockable";
publicVariableServer "PVDZE_obj_Publish";
 
cutText [format[(localize "str_epoch_player_140"),_combinationDisplay,_text], "PLAIN DOWN", 5];
 
 
} else {
_object setVariable ["CharacterID",dayz_characterID,true];
_object setVariable ["ownerPUID",_playerUID,true];
 
// fire?
if(_object isKindOf "Land_Fire_DZ") then {
_object spawn player_fireMonitor;
} else {
//diag_log "Publish Other";
PVDZE_obj_Publish = [dayz_characterID,_object,[_dir,_location,_playerUID],_classname];
publicVariableServer "PVDZE_obj_Publish";
};
};
} else {
//diag_log "Remove Item NOT OK";
deleteVehicle _object;
cutText [(localize "str_epoch_player_46") , "PLAIN DOWN"];
{
[player,_x] call BIS_fnc_invAdd;
} forEach _temp_removed_array;
};
 
} else {
//diag_log "Proceed NOT OK";
r_interrupt = false;
if (vehicle player == player) then {
[objNull, player, rSwitchMove,""] call RE;
player playActionNow "stop";
};
 
deleteVehicle _object;
cutText [(localize "str_epoch_player_46") , "PLAIN DOWN"];
};
 
} else {
//diag_log "Cancel is TRUE";
deleteVehicle _object;
cutText [format[(localize "str_epoch_player_47"),_text,_reason], "PLAIN DOWN"];
};
};
 
DZE_ActionInProgress = false;
 

 

Many Thanks

 

Pry

Link to comment
Share on other sites

I must admit I was skeptical when trying it but I must say, it is amazing. great work.

 

The only complaint I have is it's a little hard to control the manual snapping, but that's nothing compared to how much easier this makes everything else :)

 

Thanks!

Link to comment
Share on other sites

OK so after playing around a little bit, I have figured it doesn't work with the Admin build but does work with the plot for life, which is the important one.

 

One thing to note: If you had the old snap build you could point items in extra_RC to it and it would build item's. With this it seems to not be working as I had houses (set for events) to build on using an Obsidian. When I try to do that now it states building but nothing happens after, no preview or anything. Yet when selecting another option / type of building it states "currently building"

 

I'm moving away from the Extra_RC script at the moment and as this is so much better and more advanced and would rather keep this than have extra build items on the server!

 

Cheers!

 

Oh and if you guys also have plot for life and want a copy/paste see below:

 

/*
	DayZ Base Building
	Made for DayZ Epoch please ask permission to use/edit/distrubute email [email protected].
*/
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","_ownerPUID","_playerUID"];

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);
_playerUID = getPlayerUID 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 ["ownerPUID","0"];

	 diag_log format["Player_build start: [PlayerUID = %1]  [OwnerID = %2]", _playerUID, _ownerID];

	// check if friendly to owner
	if(_playerUID == _ownerID) then {  //Keep ownership
		// owner can build anything within his plot except other plots
		diag_log text "Player is owner";
		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 (missionConfigFile >> "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];
					_tmpbuilt setVariable ["ownerPUID",_playerUID,true];


					PVDZE_obj_Publish = [_combination,_tmpbuilt,[_dir,_location,_playerUID],_classname];
					publicVariableServer "PVDZE_obj_Publish";

					cutText [format[(localize "str_epoch_player_140"),_combinationDisplay,_text], "PLAIN DOWN", 5];


				} else {
					_tmpbuilt setVariable ["CharacterID",dayz_characterID,true];
					_tmpbuilt setVariable ["ownerPUID",_playerUID,true];
					
					// fire?
					if(_tmpbuilt isKindOf "Land_Fire_DZ") then {
						_tmpbuilt spawn player_fireMonitor;
					} else {
						PVDZE_obj_Publish = [dayz_characterID,_tmpbuilt,[_dir,_location,_playerUID],_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;

 

Pry

Link to comment
Share on other sites

Good morning and Holy crap so much positive attitude, haha, love you guys, thanks for great responses. I'll update Q&A section in a bit.

 

Hello All,

I've had this working on all my servers for about a week now and the players just go nuts for it.

Also I would like to say a massive Thank You! to raymix and everyone that helped on this project.

Like Floss said it really does blow the old snapping out of the water.

Great Job as always raymix

 

Edit: Thank You raymix also for You Tube tutorials on how the actual code works for this addon.

STENCH

Thanks for sticking around the development of this in DZEI thread, buddy, appreciate your feedback and testing ^^

 

 

very nice script, but i tend to have some issues with metal floors snaping to the center of the other floors even if the edge balls are green. anyone else have this issue?

It can happen when building is between water and land, these things tend to feck up search code, it's not very sophisticated as I am no mathematician. It'd be great if you could give me more info on this. What I'd suggest you to do is: drop the item down while in auto snap, then switch to manual and choose your point, pick it up again and go from there, should be ok.

 

 

I can confirm this is working on 1.63 Overpoch

Thanks for confirm, i'll add that to Q&A

 

 

The only complaint I have is it's a little hard to control the manual snapping, but that's nothing compared to how much easier this makes everything else :)

 

Well, it will take little bit of time to get your head around it, I know some players have trouble learning it, too, but once they get more comfortable with it, it gets much easier and faster.

 

 

OK so after playing around a little bit, I have figured it doesn't work with the Admin build but does work with the plot for life, which is the important one.

 

One thing to note: If you had the old snap build you could point items in extra_RC to it and it would build item's. With this it seems to not be working as I had houses (set for events) to build on using an Obsidian. When I try to do that now it states building but nothing happens after, no preview or anything. Yet when selecting another option / type of building it states "currently building"

 

I'm moving away from the Extra_RC script at the moment and as this is so much better and more advanced and would rather keep this than have extra build items on the server!

It should work with all those things as long as you are not using different player_build from mine, it's very much the original script by awol with the exception that it adds 45 degree turns and spawns external file. What it basically does is generates a helper object and attaches item you are building to it, does not matter if it has ghost preview or not. However, if you are using third party player_build.sqf make launch your diffmerge and look up how to add object helpers and how to spawn snap_build.sqf script in your file. It should be a simple matter of a fix.

Link to comment
Share on other sites

OK so after playing around a little bit, I have figured it doesn't work with the Admin build but does work with the plot for life, which is the important one.

 

One thing to note: If you had the old snap build you could point items in extra_RC to it and it would build item's. With this it seems to not be working as I had houses (set for events) to build on using an Obsidian. When I try to do that now it states building but nothing happens after, no preview or anything. Yet when selecting another option / type of building it states "currently building"

 

I'm moving away from the Extra_RC script at the moment and as this is so much better and more advanced and would rather keep this than have extra build items on the server!

 

Cheers!

 

Oh and if you guys also have plot for life and want a copy/paste see below:

 

/*
	DayZ Base Building
	Made for DayZ Epoch please ask permission to use/edit/distrubute email [email protected].
*/
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","_ownerPUID","_playerUID"];

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);
_playerUID = getPlayerUID 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 ["ownerPUID","0"];

	 diag_log format["Player_build start: [PlayerUID = %1]  [OwnerID = %2]", _playerUID, _ownerID];

	// check if friendly to owner
	if(_playerUID == _ownerID) then {  //Keep ownership
		// owner can build anything within his plot except other plots
		diag_log text "Player is owner";
		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 (missionConfigFile >> "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];
					_tmpbuilt setVariable ["ownerPUID",_playerUID,true];


					PVDZE_obj_Publish = [_combination,_tmpbuilt,[_dir,_location,_playerUID],_classname];
					publicVariableServer "PVDZE_obj_Publish";

					cutText [format[(localize "str_epoch_player_140"),_combinationDisplay,_text], "PLAIN DOWN", 5];


				} else {
					_tmpbuilt setVariable ["CharacterID",dayz_characterID,true];
					_tmpbuilt setVariable ["ownerPUID",_playerUID,true];
					
					// fire?
					if(_tmpbuilt isKindOf "Land_Fire_DZ") then {
						_tmpbuilt spawn player_fireMonitor;
					} else {
						PVDZE_obj_Publish = [dayz_characterID,_tmpbuilt,[_dir,_location,_playerUID],_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;

 

Pry

works with the fast upgrade just use his http://www.wreckinggames.net/download/player_upgrade.sqf

and change the path to it in fn_selfactions.sqf

 

[spolier]if (s_player_upgrade_build < 0) then {
// s_player_lastTarget = _cursorTarget;
s_player_lastTarget set [0,_cursorTarget];
s_player_upgrade_build = player addAction [format[localize "STR_EPOCH_ACTIONS_UPGRADE",_text], "custom\snap_pro\player_upgrade.sqf",_cursorTarget, -1, false, true, "","];
};
 
add the _isBuildAdmin in variables.sqf like this 
WG_adminBuild = ["765611115664072","76561117980015761"]; use your new steam ID
 
still attempting the admin instant build part
Link to comment
Share on other sites

Great job, love it

but why no credit to maca134 for original idea atleast?

Thank you. 

It's a grey area when it comes to credits. Just crediting somebody for an idea is rather silly, imo. I could rather credit tens and hundreds of people who posted code examples on BI and epoch forums that helped me understand syntax instead. From popular snap system, i'd give more credit to otter for keeping that project updated and giving me a hint that building's does not work on water using ATL, his solution was simple and effective. Other than that, whole script is made completely from scratch and it does not in any way resemble popular snap building, in terms of functionality and code, the system had to be redesigned from ground up - starting with an idea. I've even did code based on my own hypothesis with addAction - that calling external scripts is not required (normally code blocks are only supported in Arma 3) and action could instead call origin script (itself) while the rest of code inside sqf is filtered out by using spawned functions running their on external threads, so variables don't go corrupt. I've yet to see anyone else doing this, tbh. I believe that calling itself and using switch is better and easier on resources as only single file needs to be precompiled into memory.

Anyway, I thought by giving any credit to authors or editors of similar scripts would imply this script is somehow based on them, while it's not. It's merely an alternative version designed to apply similar function to the game - snap stuff together.

Hope this does not offend any of authors and creators of similar scripts, I've high respect for anyone that contributes their work to public for free and what they do for our community. Without people like them we would not have awesome stuff and ability to learn.

Link to comment
Share on other sites

 

Nice work mate :-)

I have noticed 2 things: 
1) floors, walls, etc.  not snap exactly to each other, light height offset 
2) the wood garagedoor can not be snapt?

 

Thanks for heads up:

1) There will always be height offsets no matter how you do it, otherwise I'd have to make tons of useless snap points on a single object. However this is not a major problem, since height can be adjusted when snapped. For example if you snap a wall to a floor, i'd suggest adjusting height properly (its not hard since you can now walk around it) and snap rest of future walls to this wall to maintain same height.

2) I'll check that out now and update snappoints.hpp file on github later, thanks for letting me know, mate. Updated

Edited by raymix
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
×
×
  • Create New...