Epoch/Sources/epoch_code/compile/building/EPOCH_simulSwap.sqf
He-Man d3309926fa Building Parts not delete when disallowed
When already building (simulswap) but building is disallowed, the building part will fall down instead of been deleted (without returning items)
2017-03-29 19:43:10 +02:00

230 lines
8.3 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","_nearestObject","_nearestObjectRaw","_newObj","_objSlot","_objType","_object","_oemType","_offset","_onContactEH","_pOffset","_playerdistance","_pos2","_prevSnapDistance","_previousDistanceNear","_rejectMove","_removeParts","_return","_simulClassConfig","_snapArrayPara","_snapArrayPerp","_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;
if (EPOCH_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");
if (_energyCost == 0) then {
_energyCost = 0.1;
};
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 setVectorDirAndUp [_worldspace select 1,_worldspace select 2];
_newObj setposATL (_worldspace select 0);
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);
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 {
if (EPOCH_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];
_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 {
_snapPointsPara = getArray(_cfgBaseBuilding >> (typeOf _nearestObject) >> "snapPointsPara");
_snapPointsPerp = getArray(_cfgBaseBuilding >> (typeOf _nearestObject) >> "snapPointsPerp");
_snapArrayPara = [];
{
if (_x in _allowedSnapPoints) then {
_pOffset = _nearestObject selectionPosition _x;
_snapPos = _nearestObject modelToWorld _pOffset;
if ((_pos2 distance _snapPos) < 3) then {
_snapArrayPara pushBackUnique _snapPos;
};
};
} forEach _snapPointsPara;
_snapArrayPerp = [];
{
if (_x in _allowedSnapPoints) then {
_pOffset = _nearestObject selectionPosition _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];
};
};
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_playerEnergy = (EPOCH_playerEnergy - _energyCost) max 0;
uiSleep 0.1;
};
_currentTarget removeEventHandler["EpeContactStart", _onContactEH];
EPOCH_velTransform = false;
_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"];
if !(_class in _disallowed) then {
_currentTarget spawn EPOCH_countdown;
};
_currentTarget setVelocity [0,0,-0.01];
};
[] spawn{
uiSleep 2;
EPOCH_simulSwap_Lock = nil;
};