New building functions, vanilla building checks

DZE_RequiredItemsCheck returns bool, displays an error of all the tools
the player is missing to build the item.

DZE_BuildChecks returns array of bools, canBuild and if the item is a
plotPole.  Also has the ability to check if the player has required
tools to build using DZE_RequiredItemsCheck.

The vanilla build script still needs to be modified to work over water
and allow players to place floating objects, but now uses plot checks.
It would be easiest to just modify the configs to use the epoch building
scripts instead.

fnc_getSetPos now accepts a position as the second element of the input
array. the object will be set to this position if it is used. This
change requires no code updates

Note: scripts with build and/or tool checks should be updated to use the
new functions
This commit is contained in:
icomrade
2016-04-27 14:30:05 -04:00
parent bb66b4446c
commit 7ea9a270f2
5 changed files with 153 additions and 210 deletions

View File

@@ -82,111 +82,27 @@ if (_abort) exitWith {
DZE_ActionInProgress = false;
};
_classname = getText (configFile >> "CfgMagazines" >> DZE_buildItem >> "ItemActions" >> "Build" >> "create");
_classnametmp = _classname;
_require = getArray (configFile >> "cfgMagazines" >> DZE_buildItem >> "ItemActions" >> "Build" >> "require");
_text = getText (configFile >> "CfgVehicles" >> _classname >> "displayName");
_ghost = getText (configFile >> "CfgVehicles" >> _classname >> "ghostpreview");
_canBuild = [_pos, _this, true] call DZE_BuildChecks;
if (_canBuild select 0) then {
_classname = getText (configFile >> "CfgMagazines" >> DZE_buildItem >> "ItemActions" >> "Build" >> "create");
_classnametmp = _classname;
_text = getText (configFile >> "CfgVehicles" >> _classname >> "displayName");
_ghost = getText (configFile >> "CfgVehicles" >> _classname >> "ghostpreview");
_lockable = 0; //default define if lockable not found in config file below
if(isNumber (configFile >> "CfgVehicles" >> _classname >> "lockable")) then { //find out if item is lockable object
_lockable = getNumber(configFile >> "CfgVehicles" >> _classname >> "lockable"); // 2=lockbox, 3=combolock, 4=safe
};
_requireplot = DZE_requireplot; //check for plotpole requirements defined in init.sqf
if(isNumber (configFile >> "CfgVehicles" >> _classname >> "requireplot")) then {
_requireplot = getNumber(configFile >> "CfgVehicles" >> _classname >> "requireplot");
};
_isAllowedUnderGround = 1; //check if allowed to build under terrain
if(isNumber (configFile >> "CfgVehicles" >> _classname >> "nounderground")) then {
_isAllowedUnderGround = getNumber(configFile >> "CfgVehicles" >> _classname >> "nounderground");
};
_offset = getArray (configFile >> "CfgVehicles" >> _classname >> "offset"); //check default distance offset, define if does not exist
if((count _offset) <= 0) then {
_offset = [0,1.5,0];
};
_isPole = (_classname == "Plastic_Pole_EP1_DZ"); //check if item is plotpole
_isLandFireDZ = (_classname == "Land_Fire_DZ"); //check if item is campfire
_distance = DZE_PlotPole select 0;
_needText = localize "str_epoch_player_246"; //text for when requirements not met
_canBuildOnPlot = false;
_nearestPole = objNull;
_ownerID = 0;
_friendlies = [];
if(_isPole) then { //check if object is plotpole and adjust distance accordingly
_distance = DZE_PlotPole select 1;
};
// check for near plotpoles
_findNearestPoles = nearestObjects [(vehicle player), ["Plastic_Pole_EP1_DZ"], _distance]; //create an array of nearby objects that are plotpoles, nearest will always be first in array
_findNearestPole = []; //must define an empty array to avoid problems
{
if (alive _x) then { //only look for non-destroyed plotpoles
_findNearestPole set [(count _findNearestPole),_x]; //build an array of live plotpoles found nearby
_lockable = 0; //default define if lockable not found in config file below
if(isNumber (configFile >> "CfgVehicles" >> _classname >> "lockable")) then { //find out if item is lockable object
_lockable = getNumber(configFile >> "CfgVehicles" >> _classname >> "lockable"); // 2=lockbox, 3=combolock, 4=safe
};
} count _findNearestPoles; //count each item in previously created array of nearby plotpoles
_IsNearPlot = count (_findNearestPole); //count our new array of non-destroyed plotpoles. Empty array will return 0
// End script if item is plot pole and another one exists within defined radius
if(_isPole && _IsNearPlot > 0) exitWith {DZE_ActionInProgress = false; format[localize "str_epoch_player_44",_distance] call dayz_rollingMessages;};
if(_IsNearPlot == 0) then { //No live plotpoles were found nearby
// Allow building of plot
if(_requireplot == 0 || _isLandFireDZ) then {
_canBuildOnPlot = true;
_isAllowedUnderGround = 1; //check if allowed to build under terrain
if(isNumber (configFile >> "CfgVehicles" >> _classname >> "nounderground")) then {
_isAllowedUnderGround = getNumber(configFile >> "CfgVehicles" >> _classname >> "nounderground");
};
} else {
// Since there are plots nearby we check for ownership and then for friend status
// check nearby plots ownership and then for friend status
_nearestPole = _findNearestPole select 0; //nearest is always first in array when using nearestObjects check
// Find owner
_ownerID = _nearestPole getVariable ["CharacterID","0"];
// 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;
};
};
_offset = getArray (configFile >> "CfgVehicles" >> _classname >> "offset"); //check default distance offset, define if does not exist
if((count _offset) <= 0) then {
_offset = [0,1.5,0];
};
};
if(!_canBuildOnPlot) exitWith { DZE_ActionInProgress = false; format[localize "STR_EPOCH_PLAYER_135",_needText,_distance] call dayz_rollingMessages;};
_buildables = DZE_maintainClasses + DZE_LockableStorage + ["DZ_buildables"];
_buildables set [count _buildables,"TentStorage"];
_center = if (isNull _nearestPole) then {_pos} else {_nearestPole};
if ((count (nearestObjects [_center,_buildables,_distance])) >= DZE_BuildingLimit) exitWith {DZE_ActionInProgress = false; format[localize "str_epoch_player_41",_distance] call dayz_rollingMessages;};
_missing = "";
_hasrequireditem = true;
{
_hastoolweapon = _x in weapons player; //check each required item against weapons array on player
if(!_hastoolweapon) exitWith {_hasrequireditem = false; _missing = getText (configFile >> "cfgWeapons" >> _x >> "displayName");};
} count _require; //count each item in requirements array
_hasbuilditem = DZE_buildItem in magazines player;
if (!_hasbuilditem) exitWith {DZE_ActionInProgress = false; format[localize "str_player_31",_text,"build"] call dayz_rollingMessages;};
if (!_hasrequireditem) exitWith {DZE_ActionInProgress = false; format[localize "str_epoch_player_137",_missing] call dayz_rollingMessages;};
if (_hasrequireditem) then {
_objectHelper = objNull;
_isOk = true;
@@ -525,7 +441,7 @@ if (_hasrequireditem) then {
format[localize "str_build_01",_text] call dayz_rollingMessages;
if (_isPole) then { //if item was a plotpole, build a visual radius around it
if (_canBuild select 1) then { //if item was a plotpole, build a visual radius around it
[] spawn player_plotPreview;
};

View File

@@ -88,118 +88,28 @@ if(_abort) exitWith {
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");
_canBuild = [_pos, _item, true] call DZE_BuildChecks;
if (_canBuild select 0) then {
_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";
_canBuildOnPlot = false;
_nearestPole = objNull;
_ownerID = 0;
_friendlies = [];
if(_isPole) then {
_distance = DZE_PlotPole select 1;
};
// check for near plot
_findNearestPoles = nearestObjects [_pos, ["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 and another one exists within 45m
if(_isPole && _IsNearPlot > 0) exitWith { DZE_ActionInProgress = false; format[localize "str_epoch_player_44",_distance] call dayz_rollingMessages; };
if(_IsNearPlot == 0) then {
// Allow building of plot
if(_requireplot == 0 || _isLandFireDZ) then {
_canBuildOnPlot = true;
_lockable = 0;
if(isNumber (configFile >> "CfgVehicles" >> _classname >> "lockable")) then {
_lockable = getNumber(configFile >> "CfgVehicles" >> _classname >> "lockable");
};
} else {
// Since there are plots nearby we check for ownership and then for friend status
// check nearby plots ownership and 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;
};
};
_isAllowedUnderGround = 1;
if(isNumber (configFile >> "CfgVehicles" >> _classname >> "nounderground")) then {
_isAllowedUnderGround = getNumber(configFile >> "CfgVehicles" >> _classname >> "nounderground");
};
};
// _message
if(!_canBuildOnPlot) exitWith { DZE_ActionInProgress = false; format[localize "STR_EPOCH_PLAYER_135",_needText,_distance] call dayz_rollingMessages; };
_buildables = DZE_maintainClasses + DZE_LockableStorage + ["DZ_buildables"];
_buildables set [count _buildables,"TentStorage"];
_center = if (isNull _nearestPole) then {_pos} else {_nearestPole};
if ((count (nearestObjects [_center,_buildables,_distance])) >= DZE_BuildingLimit) exitWith {DZE_ActionInProgress = false; format[localize "str_epoch_player_41",_distance] call dayz_rollingMessages;};
_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; format[localize "str_player_31",_text,"build"] call dayz_rollingMessages; };
if (!_hasrequireditem) exitWith {DZE_ActionInProgress = false; format[localize "str_epoch_player_137",_missing] call dayz_rollingMessages; };
if (_hasrequireditem) then {
_offset = getArray (configFile >> "CfgVehicles" >> _classname >> "offset");
if((count _offset) <= 0) then {
_offset = [0,1.5,0];
};
_location = [0,0,0];
_isOk = true;
@@ -471,7 +381,7 @@ if (_hasrequireditem) then {
format[localize "str_build_01",_text] call dayz_rollingMessages;
if (_isPole) then {
if (_canBuild select 1) then {
[] spawn player_plotPreview;
};

View File

@@ -107,6 +107,10 @@ if (!_ok) exitWith {
_msg call dayz_rollingMessages;
};
_posReference = [player] call FNC_GetPos;
_canBuild = [_posReference, _item, false] call DZE_BuildChecks;
if (!(_canBuild select 0)) exitWith {};
//localize "str_player_build_rotate" call dayz_rollingMessages;
_msg = localize "str_player_build_rotate";
@@ -288,7 +292,7 @@ _dir = getDir player;
_object setDir _dir;
Dayz_constructionContext = [_object, round (_dir/5)*5, cameraView, false, true, _keepOnSlope];
// ghost, angle, previous camera, build view on/off, continue on/off, slope on/off
_posReference = getPosATL player;
//_posReference = getPosATL player;
_objColliding = objNull;
_best = [50,[0,0,0],[0,0,0]];
_maxplanting = 10;

View File

@@ -2,7 +2,11 @@
private "_pos";
_thingy = _this select 0;
_pos = getPosASL _thingy;
if ((count _this) > 1) then {
_pos = _this select 1;
} else {
_pos = getPosASL _thingy;
};
if (surfaceIsWater _pos) then {
_thingy setPosASL _pos;

View File

@@ -173,6 +173,115 @@ if (!isDedicated) then {
player_upgradeVehicle = compile preprocessFileLineNumbers "\z\addons\dayz_code\compile\player_upgradeVehicle.sqf";
player_vaultPitch = compile preprocessFileLineNumbers "\z\addons\dayz_code\actions\vault_pitch.sqf";
DZE_RequiredItemsCheck = {
private ["_missingText","_hasrequireditem","_hastoolweapon","_item","_require","_missing","_missingCount","_text","_classname","_hasbuilditem"];
_item = _this select 0;
_require = _this select 1;
_classname = _this select 2;
_missing = [];
_missingText = "";
_hasrequireditem = true;
_text = getText (configFile >> "CfgVehicles" >> _classname >> "displayName");
{
_hastoolweapon = _x in weapons player;
if (!_hastoolweapon) then {
_missingText = getText (configFile >> "cfgWeapons" >> _x >> "displayName");
_missing set [count _missing, _missingText];
_hasrequireditem = false;
};
} forEach _require;
_missingText = "";
{
if (_forEachIndex == 0) then {
_missingText = _x;
} else {
if (_forEachIndex == ((count _missing) - 1)) then {
_missingText = _missingText + " and " + _x;
} else {
_missingText = _missingText + ", " + _x;
};
};
} forEach _missing;
_hasbuilditem = _item in magazines player;
if (!_hasbuilditem) exitWith {DZE_ActionInProgress = false; format[localize "str_player_31",_text,"build"] call dayz_rollingMessages; false;};
if (!_hasrequireditem) exitWith {DZE_ActionInProgress = false; format[localize "str_epoch_player_137",_missingText] call dayz_rollingMessages; false;};
//When calling this function in another script use a silent exitWith, unless you have something special to say. i.e. if (!_hasrequireditem) exitWith{};
_hasrequireditem;
};
DZE_BuildChecks = { //Checks if item is near a plot, if the player is plot owner or friendly, if there are too many items, and if the player has required tools
private ["_requireplot","_distance","_canBuild","_friendlies","_nearestPole","_ownerID","_pos","_item","_classname","_isPole","_isLandFireDZ","_needText","_findNearestPoles","_findNearestPole","_IsNearPlot","_buildables","_center"];
_pos = _This select 0;
_item = _this select 1;
_toolCheck = _this select 2;
_classname = getText (configFile >> "CfgMagazines" >> _item >> "ItemActions" >> "Build" >> "create");
_requireplot = DZE_requireplot;
if(isNumber (configFile >> "CfgVehicles" >> _classname >> "requireplot")) then {
_requireplot = getNumber(configFile >> "CfgVehicles" >> _classname >> "requireplot");
};
_isPole = (_classname == "Plastic_Pole_EP1_DZ");
_isLandFireDZ = (_classname == "Land_Fire_DZ");
_needText = localize "str_epoch_player_246";
_distance = DZE_PlotPole select 0;
_canBuild = false;
_nearestPole = objNull;
_ownerID = 0;
_friendlies = [];
if(_isPole) then {
_distance = DZE_PlotPole select 1;
};
_findNearestPoles = nearestObjects [_pos, ["Plastic_Pole_EP1_DZ"], _distance];
_findNearestPole = [];
{
if (alive _x) then {
_findNearestPole set [(count _findNearestPole),_x];
};
} count _findNearestPoles;
_IsNearPlot = count (_findNearestPole);
if(_isPole && {_IsNearPlot > 0}) exitWith {DZE_ActionInProgress = false; format[localize "str_epoch_player_44",_distance] call dayz_rollingMessages; [_canBuild, _isPole];};
if(_IsNearPlot == 0) then {
if (_requireplot == 0 || _isLandFireDZ) then {
_canBuild = true;
};
} else {
_nearestPole = _findNearestPole select 0;
_ownerID = _nearestPole getVariable ["CharacterID","0"];
if(dayz_characterID == _ownerID) then {
if (!_isPole) then {
_canBuild = true;
};
} else {
if(!_isPole) then {
_friendlies = player getVariable ["friendlyTo",[]];
if(_ownerID in _friendlies) then {
_canBuild = true;
};
};
};
};
if(!_canBuild) exitWith { DZE_ActionInProgress = false; format[localize "STR_EPOCH_PLAYER_135",_needText,_distance] call dayz_rollingMessages; [_canBuild, _isPole];};
_buildables = DZE_maintainClasses + DZE_LockableStorage + ["DZ_buildables"];
_buildables set [count _buildables,"TentStorage"];
_center = if (isNull _nearestPole) then {_pos} else {_nearestPole};
if ((count (nearestObjects [_center,_buildables,_distance])) >= DZE_BuildingLimit) exitWith {DZE_ActionInProgress = false; format[localize "str_epoch_player_41",_distance] call dayz_rollingMessages; [false, _isPole];};
if (_toolCheck) then {
_require = getArray (configFile >> "cfgMagazines" >> _item >> "ItemActions" >> "Build" >> "require");
_classname = getText (configFile >> "CfgMagazines" >> _item >> "ItemActions" >> "Build" >> "create");
_canBuild = [_item, _require, _classname] call DZE_RequiredItemsCheck;
};
//When calling this function in another script use a silent exitWith, unless you have something special to say. i.e. if (!(_canBuild select 0)) exitWith{};
[_canBuild, _isPole];
};
dayz_losChance = {
private["_agent","_maxDis","_dis","_val","_maxExp","_myExp"];
_agent = _this select 0;