mirror of
https://github.com/EpochModTeam/Epoch.git
synced 2024-08-30 18:22:13 +00:00
12e5746c82
- Helper 3D-Icon + Line on the part, where element is snapped on (while Base-Building) - "PLAYER_REJECT_ServerVersion" kick, if connecting with older version
253 lines
9.2 KiB
Plaintext
253 lines
9.2 KiB
Plaintext
/*
|
|
Author: Aaron Clark - EpochMod.com
|
|
|
|
Contributors:
|
|
|
|
Description:
|
|
Base building base building with physics
|
|
|
|
Licence:
|
|
Arma Public License Share Alike (APL-SA) - https://www.bistudio.com/community/licenses/arma-public-license-share-alike
|
|
|
|
Github:
|
|
https://github.com/EpochModTeam/Epoch/tree/release/Sources/epoch_code/compile/building/EPOCH_simulSwap.sqf
|
|
|
|
Example:
|
|
[_object] spawn EPOCH_simulSwap;
|
|
|
|
Parameter(s):
|
|
_this select 0: OBJECT - Base building object
|
|
|
|
Returns:
|
|
NOTHING
|
|
*/
|
|
//[[[cog import generate_private_arrays ]]]
|
|
private ["_allowedSnapObjects","_allowedSnapPoints","_cfgBaseBuilding","_class","_create","_currentTarget","_dir2","_direction","_disallowed","_distance","_distanceMod","_distanceNear","_energyCost","_isSnap","_lastCheckTime","_maxHeight","_nearestObject","_nearestObjectRaw","_newObj","_objSlot","_objType","_object","_oemType","_offset","_onContactEH","_pOffset","_playerEnergy","_playerEnergyKeyFinal","_playerdistance","_pos2","_prevSnapDistance","_previousDistanceNear","_rejectMove","_return","_simulClassConfig","_snapArrayPara","_snapArrayPerp","_snapConfig","_snapDistance","_snapObjects","_snapPointsPara","_snapPointsPerp","_snapPos","_snapPosition","_snapType","_textureSlot","_up2","_vel2","_velocityTransformation","_worldspace"];
|
|
//[[[end]]]
|
|
|
|
if !(isNil "EPOCH_simulSwap_Lock") exitWith{};
|
|
|
|
_object = param [0,objNull];
|
|
if (isNull _object) exitWith{ EPOCH_target = objNull; };
|
|
|
|
_objType = typeOf _object;
|
|
|
|
_isSnap = false;
|
|
|
|
_playerEnergyKeyFinal = "EPOCH_playerEnergy";
|
|
if !(isNil "_playerEnergyKey") then {_playerEnergyKeyFinal = _playerEnergyKey};
|
|
_playerEnergy = missionNamespace getVariable [_playerEnergyKeyFinal,[]];
|
|
|
|
if (_playerEnergy <= 0) exitWith {
|
|
["Need Energy", 5] call Epoch_message;
|
|
};
|
|
if !(_object call EPOCH_isBuildAllowed) exitWith{};
|
|
|
|
EPOCH_simulSwap_Lock = true;
|
|
_return = _object;
|
|
_velocityTransformation = [];
|
|
_prevSnapDistance = 0;
|
|
_distanceMod = 0;
|
|
_oemType = (typeOf _object);
|
|
|
|
_cfgBaseBuilding = 'CfgBaseBuilding' call EPOCH_returnConfig;
|
|
|
|
_simulClassConfig = (_cfgBaseBuilding >> _oemType >> "simulClass");
|
|
if (isText(_simulClassConfig)) then {
|
|
_class = getText(_simulClassConfig);
|
|
_create = true;
|
|
_allowedSnapPoints = getArray(_cfgBaseBuilding >> _class >> "allowedSnapPoints");
|
|
_allowedSnapObjects = ["Constructions_static_F"];
|
|
_snapObjects = _cfgBaseBuilding >> _class >> "allowedSnapObjects";
|
|
_energyCost = getNumber(_cfgBaseBuilding >> _class >> "energyCost");
|
|
_maxHeight = getNumber(_cfgBaseBuilding >> _class >> "maxHeight");
|
|
if (_energyCost == 0) then {
|
|
_energyCost = 0.1;
|
|
};
|
|
if (_maxHeight == 0) then {
|
|
_maxHeight = 500;
|
|
};
|
|
if !(EPOCH_maxBuildingHeight == 0) then {
|
|
_maxHeight = _maxHeight min EPOCH_maxBuildingHeight;
|
|
};
|
|
if (isArray(_snapObjects)) then {
|
|
_allowedSnapObjects = getArray(_snapObjects);
|
|
};
|
|
_newObj = _object;
|
|
if (_create) then {
|
|
_worldspace = [(getposATL _object),(vectordir _object),(vectorup _object)];
|
|
_objSlot = _object getVariable["BUILD_SLOT", -1];
|
|
_textureSlot = _object getVariable["TEXTURE_SLOT", 0];
|
|
deleteVehicle _object;
|
|
waitUntil {sleep 0.01; isNull _object};
|
|
_newObj = createVehicle [_class, (_worldspace select 0), [], 0, "CAN_COLLIDE"];
|
|
if (_objSlot != -1) then {
|
|
_newObj setVariable ["BUILD_SLOT",_objSlot,true];
|
|
};
|
|
|
|
_newObj setposATL (_worldspace select 0);
|
|
_newObj setVectorDirAndUp [_worldspace select 1,_worldspace select 2];
|
|
|
|
if (_textureSlot != 0) then {
|
|
[_newObj, _textureSlot, player, Epoch_personalToken] remoteExec ["EPOCH_server_paintBUILD",2];
|
|
};
|
|
};
|
|
EP_velocityTransformation = [];
|
|
EPOCH_oldTarget = EPOCH_target;
|
|
EPOCH_target = _newObj;
|
|
_currentTarget = EPOCH_target;
|
|
EPOCH_velTransform = true;
|
|
EPOCH_objHold = 0;
|
|
_onContactEH = _currentTarget addEventHandler["EpeContactStart", { if ((_this select 1) isKindOf "LandVehicle" || (_this select 1) isKindOf "Air" || (_this select 1) isKindOf "Ship" || (_this select 1) isKindOf "Tank") then{ EPOCH_target = objNull }; }];
|
|
EP_snap = objNull;
|
|
_previousDistanceNear = 0;
|
|
_offset = player worldToModel (getposATL _currentTarget);
|
|
if (surfaceiswater (getpos _currentTarget)) then {
|
|
_offset = player worldToModel (getposASL _currentTarget);
|
|
};
|
|
EPOCH_X_OFFSET = _offset select 0;
|
|
EPOCH_Y_OFFSET = _offset select 1;
|
|
EPOCH_Z_OFFSET = _offset select 2;
|
|
_lastCheckTime = diag_tickTime;
|
|
while {EPOCH_target == _currentTarget} do {
|
|
_playerEnergy = missionNamespace getVariable [_playerEnergyKeyFinal,[]];
|
|
if (_playerEnergy <= 0) exitWith { EPOCH_target = objNull; };
|
|
_rejectMove = false;
|
|
if ((diag_tickTime - _lastCheckTime) > 10) then {
|
|
_lastCheckTime = diag_tickTime;
|
|
_rejectMove = !(EPOCH_target call EPOCH_isBuildAllowed);
|
|
};
|
|
if (_rejectMove) exitWith { EPOCH_target = objNull; };
|
|
_playerdistance = player distance EPOCH_target;
|
|
if (_playerdistance < 10) then {
|
|
_isSnap = false;
|
|
_snapPosition = [0,0,0];
|
|
_snapType = "para";
|
|
_nearestObject = objNull;
|
|
|
|
// see if this can prevent riding on object
|
|
if (EPOCH_Y_OFFSET < 3.6) then {
|
|
EPOCH_Y_OFFSET = EPOCH_Y_OFFSET + 0.1;
|
|
};
|
|
|
|
_pos2 = player modelToWorld[EPOCH_X_OFFSET, EPOCH_Y_OFFSET, EPOCH_Z_OFFSET];
|
|
if (_pos2 select 2 > _maxHeight) then {
|
|
_pos2 set[2, _maxHeight];
|
|
};
|
|
_distance = _pos2 distance EPOCH_target;
|
|
if (EPOCH_buildMode == 1) then {
|
|
if (isNull _nearestObject) then {
|
|
{
|
|
_nearestObjectRaw = nearestObject [EPOCH_target,_x];
|
|
_distanceNear = EPOCH_target distance _nearestObjectRaw;
|
|
if (_distanceNear < _previousDistanceNear) then {
|
|
_nearestObject = _nearestObjectRaw;
|
|
};
|
|
_previousDistanceNear = _distanceNear;
|
|
} forEach _allowedSnapObjects;
|
|
};
|
|
if (!isNull _nearestObject) then {
|
|
_snapConfig = _cfgBaseBuilding >> (typeOf _nearestObject);
|
|
_snapPointsPara = getArray(_snapConfig >> "snapPointsPara");
|
|
_snapPointsPerp = getArray(_snapConfig >> "snapPointsPerp");
|
|
_snapArrayPara = [];
|
|
{
|
|
if (_x in _allowedSnapPoints) then {
|
|
_pOffset = getArray (_snapConfig >> _x);
|
|
_snapPos = _nearestObject modelToWorld _pOffset;
|
|
if ((_pos2 distance _snapPos) < 3) then {
|
|
_snapArrayPara pushBackUnique _snapPos;
|
|
};
|
|
};
|
|
} forEach _snapPointsPara;
|
|
_snapArrayPerp = [];
|
|
{
|
|
if (_x in _allowedSnapPoints) then {
|
|
_pOffset = getArray (_snapConfig >> _x);
|
|
_snapPos = _nearestObject modelToWorld _pOffset;
|
|
if ((_pos2 distance _snapPos) < 3) then {
|
|
_snapArrayPerp pushBackUnique _snapPos;
|
|
};
|
|
};
|
|
} forEach _snapPointsPerp;
|
|
{
|
|
_snapDistance = _pos2 distance _x;
|
|
if (_snapDistance < 1 && (_snapDistance < _prevSnapDistance)) exitWith {
|
|
_isSnap = true;
|
|
_snapPosition = _x;
|
|
_snapType = "para";
|
|
};
|
|
_prevSnapDistance = _snapDistance;
|
|
} forEach _snapArrayPara;
|
|
{
|
|
_snapDistance = _pos2 distance _x;
|
|
if (_snapDistance < 1 && (_snapDistance < _prevSnapDistance)) exitWith {
|
|
_isSnap = true;
|
|
_snapPosition = _x;
|
|
_snapType = "perp";
|
|
};
|
|
_prevSnapDistance = _snapDistance;
|
|
} forEach _snapArrayPerp;
|
|
};
|
|
if (_isSnap && _distance < 5) then {
|
|
_pos2 = _snapPosition;
|
|
_vel2 = (velocity _nearestObject);
|
|
_direction = getDir _nearestObject;
|
|
if (_snapType == "perp") then {
|
|
_direction = _direction - (_snapPosition getDir _nearestObject);
|
|
} else {
|
|
_direction = 0;
|
|
};
|
|
if (EPOCH_snapDirection > 0) then {
|
|
if (EPOCH_snapDirection == 1) then {
|
|
_direction = _direction + 90;
|
|
};
|
|
if (EPOCH_snapDirection == 2) then {
|
|
_direction = _direction + 180;
|
|
};
|
|
if (EPOCH_snapDirection == 3) then {
|
|
_direction = _direction + 270;
|
|
};
|
|
};
|
|
if (_direction > 360) then {
|
|
_direction = _direction - 360;
|
|
};
|
|
if (_direction < 0) then {
|
|
_direction = 360 + _direction;
|
|
};
|
|
_dir2 = [vectorDir _nearestObject, _direction] call BIS_fnc_returnVector;
|
|
_up2 = (vectorUp _nearestObject);
|
|
EP_velocityTransformation = [AGLToASL _pos2,_vel2,_dir2,_up2];
|
|
EPOCH_arr_snapObjects = [_nearestObject, _currentTarget];
|
|
};
|
|
};
|
|
if (!_isSnap) then {
|
|
if (EPOCH_doRotate) then {
|
|
_vel2 = (velocity player);
|
|
_dir2 = [vectorDir player, EPOCH_buildDirection] call BIS_fnc_returnVector;
|
|
_up2 = (vectorUp player);
|
|
EPOCH_doRotate = false;
|
|
EP_velocityTransformation = [AGLToASL _pos2,_vel2,_dir2,_up2];
|
|
} else {
|
|
EP_velocityTransformation = [];
|
|
};
|
|
EPOCH_arr_snapObjects = [];
|
|
};
|
|
};
|
|
[_playerEnergyKeyFinal, -_energyCost, 2500 , 0] call EPOCH_fnc_setVariableLimited;
|
|
uiSleep 0.1;
|
|
};
|
|
_currentTarget removeEventHandler["EpeContactStart", _onContactEH];
|
|
EPOCH_velTransform = false;
|
|
EPOCH_arr_snapObjects = [];
|
|
_disallowed = ["Tarp_SIM_EPOCH", "Freezer_SIM_EPOCH", "Fridge_SIM_EPOCH", "Shelf_SIM_EPOCH", "Pelican_SIM_EPOCH", "Wardrobe_SIM_EPOCH", "Bed_SIM_EPOCH", "Couch_SIM_EPOCH", "Cooker_SIM_EPOCH", "Chair_SIM_EPOCH", "Filing_SIM_EPOCH", "Table_SIM_EPOCH", "Locker_SIM_EPOCH", "ToolRack_SIM_EPOCH", "Shoebox_SIM_EPOCH", "Bunk_SIM_EPOCH", "Jack_SIM_EPOCH", "toilet_SIM_EPOCH", "KitchenSink_SIM_EPOCH"];
|
|
if !(_class in _disallowed) then {
|
|
_currentTarget spawn EPOCH_countdown;
|
|
};
|
|
_currentTarget setVelocity [0,0,-0.01];
|
|
};
|
|
[] spawn{
|
|
uiSleep 2;
|
|
EPOCH_simulSwap_Lock = nil;
|
|
};
|