From 5e71793c17ef1608c84ab5b1eaddfdef34271782 Mon Sep 17 00:00:00 2001 From: ebaydayz Date: Wed, 21 Sep 2016 17:14:13 -0400 Subject: [PATCH] Update vanilla building Vanilla commits applied: https://github.com/DayZMod/DayZ/commit/44f2552ff2b4baf9dd9391f7705bd05647c02267 https://github.com/DayZMod/DayZ/commit/213a333ce505b7e5e60bd1f5f0c2721f06a52267 https://github.com/DayZMod/DayZ/commit/423d53299dbddf37174133f3795b7050ab715df4 https://github.com/DayZMod/DayZ/commit/43bce6554f747e1831a13338523f6e2964236acb https://github.com/DayZMod/DayZ/commit/f551cdac6e449d25ad30e373af30abb16fa98df0 --- SQF/dayz_code/actions/object_build.sqf | 4 + SQF/dayz_code/actions/player_buildVanilla.sqf | 372 ++++++++++-------- 2 files changed, 208 insertions(+), 168 deletions(-) diff --git a/SQF/dayz_code/actions/object_build.sqf b/SQF/dayz_code/actions/object_build.sqf index 73ecd9a93..e753d624b 100644 --- a/SQF/dayz_code/actions/object_build.sqf +++ b/SQF/dayz_code/actions/object_build.sqf @@ -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]; diff --git a/SQF/dayz_code/actions/player_buildVanilla.sqf b/SQF/dayz_code/actions/player_buildVanilla.sqf index f4a2d9ea7..2ad97f07d 100644 --- a/SQF/dayz_code/actions/player_buildVanilla.sqf +++ b/SQF/dayz_code/actions/player_buildVanilla.sqf @@ -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 = [];