Epoch/Sources/epoch_code/compile/building/EPOCH_simulSwap.sqf
He-Man 12e5746c82 Snap Helper + BE kicks
- Helper 3D-Icon + Line on the part, where element is snapped on (while
Base-Building)
- "PLAYER_REJECT_ServerVersion" kick, if connecting with older version
2018-02-01 18:52:55 +01:00

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;
};