Update vanilla building

Vanilla commits applied:

44f2552ff2

213a333ce5

423d53299d

43bce6554f

f551cdac6e
This commit is contained in:
ebaydayz
2016-09-21 17:14:13 -04:00
parent 33cf7611ed
commit 5e71793c17
2 changed files with 208 additions and 168 deletions

View File

@@ -17,6 +17,8 @@ _keepOnSlope = 0 == (getNumber (configFile >> "CfgVehicles" >> _classname >> "ca
Dayz_constructionContext set [ 4, false ]; // Stop the construction mode, cf. player_build.sqf
//if (count Dayz_constructionContext < 5) then { Dayz_constructionContext set [ 5, false ]; // };
if (_build) then {
_location = getPosATL _ghost;
_direction = getDir _ghost;
@@ -24,6 +26,8 @@ if (_build) then {
_object setDir _direction;
diag_log (Dayz_constructionContext);
if ((Dayz_constructionContext select 5) or (_keepOnSlope)) then {
_object setVectorUp surfaceNormal _location;
_location set [2,0];

View File

@@ -4,7 +4,7 @@ private ["_classType","_item","_action","_missingTools","_missingItem","_emergin
"_o","_offset","_rot","_r","_p","_bn","_bb","_h","_bx","_by","_minElevation","_maxElevation","_insideCheck","_building",
"_unit","_bbb","_ubb","_check","_min","_max","_myX","_myY","_checkBuildingCollision","_objColliding","_inside","_checkOnRoad",
"_roadCollide","_checkBeam2Magnet","_a","_beams","_best","_b","_d","_checkNotBuried","_elevation","_position","_delta","_overElevation",
"_maxplanting","_safeDistance","_dir","_angleRef","_tmp","_actionCancel","_sfx","_actionBuild","_byPassChecks","_keepOnSlope",
"_maxplanting","_safeDistance","_dir","_angleRef","_tmp","_actionCancel","_sfx","_actionBuild","_byPassChecks","_keepOnSlope","_msg",
"_isCollisionBypass","_ok","_missing","_upgradeParts","_ownerID","_posReference"];
/*
Needs a full rewrite to keep up with the demand of everything we plan to add.
@@ -27,8 +27,8 @@ _emergingLevel = 1.1;
dayz_actionInProgress = true;
_isClass = switch (1==1) do {
case (isClass (configFile >> "CfgMagazines" >> _item)): {"CfgMagazines"};
case (isClass (configFile >> "CfgWeapons" >> _item)): {"CfgWeapons"};
case (isClass (configFile >> "CfgMagazines" >> _item)): {"CfgMagazines"};
case (isClass (configFile >> "CfgWeapons" >> _item)): {"CfgWeapons"};
};
//need to swap all build systems to this "ItemActions"
@@ -52,74 +52,83 @@ _onLadder = {getNumber (configFile >> "CfgMovesMaleSdr" >> "States" >> (animatio
_isWater = {(surfaceIsWater (getPosATL _object)) or dayz_isSwimming};
if (0 != count Dayz_constructionContext) then {
dayz_actionInProgress = false;
localize "str_already_building" call dayz_rollingMessages;
diag_log [ diag_ticktime, __FILE__, 'already building, exiting', Dayz_constructionContext, typeName Dayz_constructionContext];
dayz_actionInProgress = false;
//cutText [localize "str_already_building", "PLAIN DOWN"];
_msg = localize "str_already_building";
_msg call dayz_rollingMessages;
diag_log [ diag_ticktime, __FILE__, 'already building, exiting', Dayz_constructionContext, typeName Dayz_constructionContext];
};
// item is missin - this really is pointless but it aint broke so dont fix it
if (isClass (configFile >> _isClass >> _item)) then {
if ((!(_item IN magazines player))) exitWith {
_string = switch true do {
case (_item isKindOf "Land_A_tent"): {"str_player_31_pitch"};
default {"str_player_31_build"};
};
format[localize "str_player_31",_text,(localize _string)] call dayz_rollingMessages;
//diag_log(format["player_build: item:%1 require:%2 Player items:%3 magazines:%4", _item, _requiredTools, (items player), (magazines player)]);
};
};
// lets check player has requiredTools for upgrade
_ok = true;
_missing = "";
{
if (!(_x IN items player)) exitWith {
//systemchat("Missing tools for upgrade." +str());
_missing = getText (configFile >> "CfgWeapons" >> _x >> "displayName");
_ok = false;
};
} count _requiredTools;
if (!_ok) exitWith {
dayz_actionInProgress = false;
format[localize "str_player_31_missingtools",_text,_missing] call dayz_rollingMessages;
if ((!(_item IN magazines player))) exitWith {
_string = switch true do {
case (_item isKindOf "Land_A_tent"): {"str_player_31_pitch"};
default {"str_player_31_build"};
};
//cutText [format [localize "str_player_31",_text,(localize _string)] , "PLAIN DOWN"];
_msg = format [localize "str_player_31",_text,(localize _string)];
_msg call dayz_rollingMessages;
//diag_log(format["player_build: item:%1 require:%2 Player items:%3 magazines:%4", _item, _requiredTools, (items player), (magazines player)]);
};
};
_posReference = [player] call FNC_GetPos;
_canBuild = [_posReference, _item, false] call DZE_BuildChecks;
if !(_canBuild select 0) exitWith {dayz_actionInProgress = false;};
// lets check player has requiredTools for upgrade
_ok = true;
_missing = "";
{
if (!(_x IN items player)) exitWith {
//systemchat("Missing tools for upgrade." +str());
_missing = getText (configFile >> "CfgWeapons" >> _x >> "displayName");
_ok = false;
};
} count _requiredTools;
if (!_ok) exitWith {
dayz_actionInProgress = false;
//cutText [format [localize "str_player_31_missingtools",_text,_missing] , "PLAIN DOWN"];
_msg = format [localize "str_player_31_missingtools",_text,_missing];
_msg call dayz_rollingMessages;
};
// lets check player has requiredParts for upgrade
_ok = true;
_upgradeParts = [];
{
if (!(_x IN magazines player)) exitWith {
_missing = getText (configFile >> "CfgMagazines" >> _x >> "displayName");
_ok = false;
};
if (_x IN magazines player) then {
_upgradeParts set [count _upgradeParts, _x];
player removeMagazine _x;
};
if (!(_x IN magazines player)) exitWith {
_missing = getText (configFile >> "CfgMagazines" >> _x >> "displayName");
_ok = false;
};
if (_x IN magazines player) then {
_upgradeParts set [count _upgradeParts, _x];
player removeMagazine _x;
};
} count _requiredParts;
call player_forceSave;
if (!_ok) exitWith {
{ player addMagazine _x; } foreach _upgradeParts;
dayz_actionInProgress = false;
format[localize "str_player_31", _missing, localize "str_player_31_build"] call dayz_rollingMessages;
{ player addMagazine _x; } foreach _upgradeParts;
dayz_actionInProgress = false;
// cutText [format [localize "str_player_31", _missing, localize "str_player_31_build"] , "PLAIN DOWN"];
_msg = format [localize "str_player_31", _missing, localize "str_player_31_build"];
_msg call dayz_rollingMessages;
};
localize "str_player_build_rotate" call dayz_rollingMessages;
_msg = localize "str_player_build_rotate";
_msg call dayz_rollingMessages;
//Get fence beams based on model
_getBeams = {
private [ "_p", "_r", "_bn", "_bb", "_bx", "_by" ];
private [ "_p", "_r", "_bn", "_bb", "_bx", "_by" ];
_o = _this select 0;
_offset = _this select 1;
_rot = _this select 2;
_r = [];
_o = _this select 0;
_offset = _this select 1;
_rot = _this select 2;
_r = [];
for "_bn" from 1 to 4 do {
_p = _o selectionPosition Format [ "beam%1", _bn ];
@@ -143,93 +152,124 @@ _getBeams = {
_r set [ count _r, _o modelToWorld _p];
};
_r
_r
};
_minElevation = {
private "_r";
_r = 400;
{ _r = _r min (_x select 2); } count _this;
private "_r";
_r = 400;
{ _r = _r min (_x select 2); } count _this;
_r
_r
};
_maxElevation = {
private "_r";
_r = -400;
{ _r = _r max (_x select 2); } count _this;
private "_r";
_r = -400;
{ _r = _r max (_x select 2); } count _this;
_r
_r
};
#define COLLIDABLE_OBJECT_MIN_SIZE 8
//check if building being placed and objects around placement is free to be built on.
//Fence owners must build all the foundations by one player anyone can still upgrade (pending lock build level)
_checkBuildingCollision =
{
_objColliding = objNull;
local _wall = _object isKindOf "DZ_buildables";
scopeName "root";
_objColliding = objNull;
local _count = getNumber (configFile >> "CfgVehicles" >> _ghost >> "buildCollisionPoints");
if (_count == 0) exitWith {};
local _wall = _object isKindOf "DZ_buildables";
//Load object collision points
local _points = [];
_points resize _count;
for "_i" from 0 to _count - 1 do
{ _points set [_i, ATLtoASL (_object modelToWorld (_object selectionPosition format ["buildCollision%1", _i]))]; };
//Trace paths
{
if (!(isNull _x || { _x == player || _x == _object}) && { !(_wall && { _x isKindOf "DZ_buildables" && { _x getVariable ["ownerArray", [""]] select 0 == getPlayerUID player } }) && { [_object, _x] call fn_collisions } }) exitWith
local _p2 = _x select 0; //[0,1,3,2,0,3]
for "_i" from 1 to count _x - 1 do
{
_objColliding = _x;
local _p1 = _p2;
_p2 = _x select _i;
{
if (!_wall || { !(_x isKindOf "DZ_buildables" && { _x getVariable ["ownerArray", [""]] select 0 == getPlayerUID player }) }) then
{
local _type = typeof _x;
if (_type != "" && { sizeof _type >= COLLIDABLE_OBJECT_MIN_SIZE }) then
{
_objColliding = _x;
breakTo "root";
};
};
}
foreach lineIntersectsWith [_points select _p1, _points select _p2, _object, player];
};
}
foreach nearestObjects [_object, ["AllVehicles", "Building", "DZ_buildables"], 35];
} foreach getArray (configFile >> "CfgVehicles" >> _ghost >> "buildCollisionPaths");
};
//Is placement on a road?
_checkOnRoad = {
_roadCollide = false;
{
_x set [2,0];
if (isOnRoad _x) exitWith { _roadCollide = true; };
} forEach ([_object, 0,0] call _getBeams);
_roadCollide
_roadCollide = false;
{
_x set [2,0];
if (isOnRoad _x) exitWith { _roadCollide = true; };
} forEach ([_object, 0,0] call _getBeams);
_roadCollide
};
//Make the object attach to beams if it can
_checkBeam2Magnet = {
_a = [];
{
_a = [];
{
if ((!isNull _x) and (_x != _object)) then { _a = _a + ([_x, 0,0] call _getBeams); };
} forEach (nearestObjects [getPosATL _object, ["DZ_buildables"], 15]);
} forEach (nearestObjects [getPosATL _object, ["DZ_buildables"], 15]);
_beams = [_object, 0,0] call _getBeams;
_best = [50,[0,0,0],[0,0,0]];
{
_b = _x;
{
_beams = [_object, 0,0] call _getBeams;
_best = [50,[0,0,0],[0,0,0]];
{
_b = _x;
{
_d = [_x, _b] call BIS_fnc_distance2D;
if (_d < _best select 0) then {
_best = [_d,_b,_x];
};
} forEach _a;
} count _beams;
// _best contains the best beam to dock to. [ distance, coor of beam found around, coor of beam of ghost object ]
} forEach _a;
} count _beams;
// _best contains the best beam to dock to. [ distance, coor of beam found around, coor of beam of ghost object ]
};
_checkNotBuried = {
// lift up the object so that any beams are buried, but also don't lift further the planting level (straight placement only)
_elevation = _position select 2;
_delta = 0;
_overElevation = 0;
_beams = [_object, 0,0] call _getBeams;
if (_elevation < 0) then { _delta = -_elevation; }
else {
_overElevation = _beams call _minElevation;
if (_overElevation>0.05) then { // bury the object so that posATL is still positif and all beams are above the ground
_delta = - (_overElevation min _elevation);
};
if (_overElevation < -0.05) then { // lift up the object because a beam is burried
_delta = - _overElevation + 0.10;
};
};
_position set [ 2, _elevation + _delta ];
_maxplanting = _beams call _maxElevation;
// _maxplanting is the height of the emerging foundations, must not be so high because we don't want some "floating" foundations
// lift up the object so that any beams are buried, but also don't lift further the planting level (straight placement only)
_elevation = _position select 2;
_delta = 0;
_overElevation = 0;
_beams = [_object, 0,0] call _getBeams;
if (_elevation < 0) then { _delta = -_elevation; }
else {
_overElevation = _beams call _minElevation;
if (_overElevation>0.05) then { // bury the object so that posATL is still positif and all beams are above the ground
_delta = - (_overElevation min _elevation);
};
if (_overElevation < -0.05) then { // lift up the object because a beam is burried
_delta = - _overElevation + 0.10;
};
};
_position set [ 2, _elevation + _delta ];
_maxplanting = _beams call _maxElevation;
// _maxplanting is the height of the emerging foundations, must not be so high because we don't want some "floating" foundations
};
_object = _ghost createVehicleLocal getMarkerpos "respawn_west";
@@ -237,8 +277,8 @@ _safeDistance = 0.5 + (sizeOf _ghost) * 0.5; // beware of hedgehogs
_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;
// ghost, angle, previous camera, build view on/off, continue on/off, slope on/off
_posReference = getPosATL player;
_objColliding = objNull;
_best = [50,[0,0,0],[0,0,0]];
_maxplanting = 10;
@@ -247,73 +287,69 @@ _position = getPosATL _object;
_actionBuildHidden = true;
_actionCancel = player addAction [localize "str_player_build_cancel", "\z\addons\dayz_code\actions\object_build.sqf", [_object, _requiredParts, _classname, _text, false, 0, "none"], 1, true, true, "", "0 != count Dayz_constructionContext"];
while {dayz_actionInProgress && Dayz_constructionContext select 4} do {
while {dayz_actionInProgress and Dayz_constructionContext select 4} do {
// force the angle so that the ghost is showing always the same side
_angleRef=Dayz_constructionContext select 1;
_dir = _angleRef - (getDir player);
if (_dir > 180) then {_dir = _dir - 360};
if (_dir < -180) then {_dir = _dir + 360};
if (_dir < -75) then {
_angleRef = ceil(((getDir player) - 75)/5)*5;
Dayz_constructionContext set [ 1, _angleRef];
};
if (_dir > 75) then {
_angleRef = floor(((getDir player) + 75)/5)*5;
Dayz_constructionContext set [ 1, _angleRef];
};
// move object according to player position
if ((abs(([_object, player] call BIS_fnc_distance2D) - _safeDistance) > (if (_best select 0 < 0.50) then {0.50} else {0.05}))
or (abs([player, _object] call BIS_fnc_relativeDirTo) > (if (_best select 0 < 0.50) then {5} else {1})) or (r_interrupt)) then {
r_interrupt = false;
_object setDir _angleRef;
_tmp = player modelToWorld [0, _safeDistance,0];
if (Dayz_constructionContext select 5 or _keepOnSlope) then {
_tmp set [2, 0];
_object setVectorUp surfaceNormal _tmp;
}
else {
_tmp set [2, _position select 2];
_object setVectorUp [0,0,1];
};
_position = +(_tmp);
_object setPosATL _position;
};
//Need to add config based bypass checks array.
if (!_isCollisionBypass) then {
// check now that ghost is not colliding
call _checkBuildingCollision;
//diag_log ("Collision Test");
// force the angle so that the ghost is showing always the same side
_angleRef=Dayz_constructionContext select 1;
_dir = _angleRef - (getDir player);
if (_dir > 180) then {_dir = _dir - 360};
if (_dir < -180) then {_dir = _dir + 360};
if (_dir < -75) then {
_angleRef = ceil(((getDir player) - 75)/5)*5;
Dayz_constructionContext set [ 1, _angleRef];
};
if (_dir > 75) then {
_angleRef = floor(((getDir player) + 75)/5)*5;
Dayz_constructionContext set [ 1, _angleRef];
};
// try to dock a beam from current ghost to another beams nearby
call _checkBeam2Magnet;
// move object according to player position
if ((abs(([_object, player] call BIS_fnc_distance2D) - _safeDistance) > (if (_best select 0 < 0.50) then {0.50} else {0.05}))
or (abs([player, _object] call BIS_fnc_relativeDirTo) > (if (_best select 0 < 0.50) then {5} else {1})) or (r_interrupt)) then {
r_interrupt = false;
_object setDir _angleRef;
_tmp = player modelToWorld [0, _safeDistance,0];
if (Dayz_constructionContext select 5 or _keepOnSlope) then {
_tmp set [2, 0];
_object setVectorUp surfaceNormal _tmp;
}
else {
_tmp set [2, _position select 2];
_object setVectorUp [0,0,1];
};
_position = +(_tmp);
_object setPosATL _position;
};
if (_best select 0 < 0.50) then {
_position = [
(_position select 0) + ((_best select 2) select 0) - ((_best select 1) select 0),
(_position select 1) + ((_best select 2) select 1) - ((_best select 1) select 1),
_position select 2
];
_object setPosATL _position;
};
//Check collisions
call _checkBuildingCollision;
// try to dock a beam from current ghost to another beams nearby
call _checkBeam2Magnet;
if (_best select 0 < 0.50) then {
_position = [
(_position select 0) + ((_best select 2) select 0) - ((_best select 1) select 0),
(_position select 1) + ((_best select 2) select 1) - ((_best select 1) select 1),
_position select 2
];
_object setPosATL _position;
};
if (Dayz_constructionContext select 5 or _keepOnSlope) then {
_maxplanting = 0;
_position set [2, 0];
}
else {
// adjust the elevation of the object according to slope and beams to keep them visible (straight placement only)
call _checkNotBuried;
};
_object setPosATL _position;
if (Dayz_constructionContext select 5 or _keepOnSlope) then {
_maxplanting = 0;
_position set [2, 0];
}
else {
// adjust the elevation of the object according to slope and beams to keep them visible (straight placement only)
call _checkNotBuried;
};
_object setPosATL _position;
if ((((vehicle player) != player or _posReference distance player > 20 or 0 != player getVariable["startcombattimer",0]) or {(!alive player)}) or {((call _onLadder) or {(call _isWater)})}) exitWith {
[[],[],[],[_object, _requiredParts , _classname, _text, false, 0, "none"]] call object_build;
};
if ((((vehicle player) != player or _posReference distance player > 20 or 0 != player getVariable["startcombattimer",0]) or {(!alive player)}) or {((call _onLadder) or {(call _isWater)})}) exitWith {
[[],[],[],[_object, _requiredParts , _classname, _text, false, 0, "none"]] call object_build;
};
if (_byPassChecks == "byPassRoadCheck") then {
if (isNull _objColliding and _maxplanting <= _emergingLevel) then { // placement is fine, enable "Build" in the menu
@@ -348,17 +384,17 @@ while {dayz_actionInProgress && Dayz_constructionContext select 4} do {
};
};
};
uiSleep 0.03;
uiSleep 0.03;
};
if (!_actionBuildHidden) then { // player can't build until all is fine
_actionBuildHidden = true;
player removeAction _actionBuild;
_actionBuildHidden = true;
player removeAction _actionBuild;
};
player removeAction _actionCancel;
if (Dayz_constructionContext select 3) then { // "build" camera was on, switch it off
call fn_buildCamera;
call fn_buildCamera;
};
Dayz_constructionContext = [];