diff --git a/Server/mpmissions/epoch.Bornholm/addons/service_point/service_point.sqf b/Server/mpmissions/epoch.Bornholm/addons/service_point/service_point.sqf new file mode 100644 index 0000000..d39118e --- /dev/null +++ b/Server/mpmissions/epoch.Bornholm/addons/service_point/service_point.sqf @@ -0,0 +1,219 @@ + + + // Vehicle Service Point by Axe Cop +fix to rearm all weapons from driver+only delete ammo in rearmed weapon only (not entire turret) by HALV + //reworked for a3 epoch by Halv + + private ["_folder","_servicePointClasses","_maxDistance","_costsFree","_message","_messageShown","_repair_enable","_repair_costs","_repair_repairTime","_rearm_enable","_rearm_costs","_lastVehicle","_lastRole","_fnc_removeActions","_fnc_getCosts","_fnc_actionTitle","_fnc_getWeapons"]; + + //====================== general settings + _folder = "addons\service_point\"; // folder where the service point scripts are saved, relative to the mission file + _servicePointClasses = ["Land_CarService_F","Land_FuelStation_Feed_F","Land_fs_feed_F"]; // Current Arma 3 service point classes (can be house, vehicle and unit classes) + // Add the Arma 2 fuel stations + _servicePointClasses = _servicePointClasses + ["Land_A_FuelStation_Shed","Land_repair_center","FuelStation","FuelStation_army","Land_A_FuelStation_Build","Land_A_FuelStation_Feed","Land_Ind_FuelStation_Feed_EP1","Land_Ind_FuelStation_Build_EP1","Land_Ind_FuelStation_Shed_EP1","Land_Ind_Garage01_EP1","Land_benzina_schnell","Land_fuelstation","Land_fuelstation_army"]; + _maxDistance = 15; // maximum distance from a service point for the options to be shown + _costsFree = "free"; // text for no costs + _message = "-- Vehicle Service Point --"; // message to be shown when in range of a service point (set to "" to disable) + _actionColour = "#0096ff"; //the colour of the scroll action Blue: "#0096ff" + + //====================== repair settings + _repair_enable = true; // enable or disable the repair option + _repair_repairTime = 5; // time needed to repair each damaged part (in seconds) + + _repair_costs = [ + ["Air",5750], // 250 Crypto for air + ["Tank",5750], // 250 Crypto Tank + ["Tracked_APC",5500], // 200 Crypto Tracked_APC + ["Wheeled_APC",5500], // 200 Crypto Wheeled_APC + ["AllVehicles",5000] // 150 Crypto all other vehicles + ]; + + //====================== rearm settings + _rearm_enable = true; // enable or disable the rearm option + + //deny re-arm if more than this amount of current weapons magazines already in the vehicle + _deny_already_armed_with = 1; + //deny re-arm if more than this amount of magazines already in the vehicle + _GlobalMagazineMAX = 6; + + //weapon classes disabled from re-arming + _NoGoWeapCName = [ + //irrelevant ones + "SmokeLauncher","MiniCarHorn","SportCarHorn","TruckHorn2","TruckHorn","BikeHorn","CarHorn", + //not allowed ones + "FFARLauncher_14","2A46M","2A46MRocket","M256","AT5LauncherSingle","LMG_Minigun_heli","missiles_DAGR","missiles_DAR","gatling_30mm","missiles_SCALPEL","rockets_Skyfire", + "Cannon_30mm_Plane_CAS_02_F","Missile_AA_03_Plane_CAS_02_F","Missile_AGM_01_Plane_CAS_02_F","Rocket_03_HE_Plane_CAS_02_F","Rocket_03_AP_Plane_CAS_02_F","Bomb_03_Plane_CAS_02_F", + "Twin_Cannon_20mm","missiles_SCALPEL","missiles_ASRAAM","GBU12BombLauncher_Plane_Fighter_03_F","missiles_Zephyr","M134_minigun","missiles_DAR","Gatling_30mm_Plane_CAS_01_F", + "Missile_AA_04_Plane_CAS_01_F","Missile_AGM_02_Plane_CAS_01_F","Rocket_04_HE_Plane_CAS_01_F","Rocket_04_AP_Plane_CAS_01_F","Bomb_04_Plane_CAS_01_F" + ]; + + //magazine classnames not allowed to be rearmed + _NoGoAmmoCName = [ + "missiles_DAR","gatling_30mm","gatling_20mm","missiles_DAGR","cannon_30mm_Plane_CAS_02_F","Missile_AA_03_Plane_CAS_02_F","Missile_AGM_01_Plane_CAS_02_F","Rocket_03_HE_Plane_CAS_02_F", + "Rocket_03_AP_Plane_CAS_02_F","Bomb_03_Plane_CAS_02_F","Bomb_04_Plane_CAS_01_F","Rocket_04_AP_Plane_CAS_01_F","Rocket_04_HE_Plane_CAS_01_F","Missile_AGM_02_Plane_CAS_01_F","Missile_AA_04_Plane_CAS_01_F", + "Gatling_30mm_Plane_CAS_01_F","GBU12BombLauncher_Plane_Fighter_03_F","missiles_ASRAAM","missiles_SCALPEL","Twin_Cannon_20mm","missiles_Zephyr","rockets_skyfire","gatling_30mm_vtol_02", + "2000Rnd_65x39_Belt_Tracer_Green_Splash","12Rnd_PG_missiles","12Rnd_missiles","38Rnd_80mm_rockets","8Rnd_LG_scalpel","250Rnd_30mm_APDS_shells_Tracer_Green","250Rnd_30mm_HE_shells_Tracer_Green", + "500Rnd_Cannon_30mm_Plane_CAS_02_F","2Rnd_Missile_AA_03_F","4Rnd_Missile_AGM_01_F","2Rnd_Bomb_03_F","20Rnd_Rocket_03_HE_F","20Rnd_Rocket_03_AP_F","300Rnd_20mm_shells","2Rnd_LG_scalpel", + "2Rnd_AAA_missiles","2Rnd_GBU12_LGB_MI10","5000Rnd_762x51_Belt","24Rnd_missiles","1000Rnd_Gatling_30mm_Plane_CAS_01_F","2Rnd_Missile_AA_04_F","6Rnd_Missile_AGM_02_F","4Rnd_Bomb_04_F", + "7Rnd_Rocket_04_HE_F","7Rnd_Rocket_04_AP_F" + ]; + + //cost per magazine for individual vehicles + _rearm_costs = [ + // ["ArmoredSUV_PMC_DZE",100], // special costs for a single vehicle type + ["Air",500], // 500 Crypto for air + ["Tank",400], // 400 Crypto for Tank + ["Tracked_APC",350], // 350 Crypto for Tracked_APC + ["Wheeled_APC",300], // 300 Crypto for Wheeled_APC + ["AllVehicles",250] // 250 Crypto for all other vehicles + ]; + + //debug weapons to see classnames in chat/rpt + _debugWeapon = false; + + + //=================================== CONFIG END + + _lastVehicle = objNull; + _lastRole = []; + + SP_repair_action = -1; + SP_rearm_actions = []; + + _messageShown = false; + + _fnc_removeActions = { + if (isNull _lastVehicle) exitWith {}; + _lastVehicle removeAction SP_repair_action; + SP_repair_action = -1; + { + _lastVehicle removeAction _x; + } forEach SP_rearm_actions; + SP_rearm_actions = []; + _lastVehicle = objNull; + _lastRole = []; + }; + + _fnc_getCosts = { + private ["_vehicle","_costs","_cost"]; + _vehicle = _this select 0; + _costs = _this select 1; + _cost = []; + { + private "_typeName"; + _typeName = _x select 0; + if (_vehicle isKindOf _typeName) exitWith { + _cost = _x select 1; + }; + } forEach _costs; + _cost + }; + + _fnc_actionTitle = { + private ["_actionName","_costs","_costsText","_actionTitle"]; + _actionName = _this select 0; + _costs = _this select 1; + _costsText = _costsFree; + if (_costs > 0) then { + private ["_itemName","_displayName"]; + _costsText = format ["%1 Crypto",_costs]; + }; + _actionTitle = format ["%1 (%2)", _actionName, _costsText,_actionColour]; + _actionTitle + }; + + _fnc_getWeapons = { + private ["_vehicle","_role","_weapons"]; + _vehicle = _this select 0; + //turrets positions to search for weapons + _turrets = [[-1],[0],[1],[2],[0,0],[1,0],[2,0],[0,1],[0,2]]; + _weapons = []; + { + _turret = _x; + _weaponsTurret = _vehicle weaponsTurret _turret; + { + _weapon = _x; + if !(_weapon in _NoGoWeapCName) then{ + _weaponName = getText (configFile >> "CfgWeapons" >> _weapon >> "displayName"); + _weapons set [count _weapons, [_weapon, _weaponName, _turret]]; + }; + }forEach _weaponsTurret; + }forEach _turrets; + _weapons + }; + + _fnc_getAmmo = { + private ["_vehicle","_role","_weapons"]; + _vehicle = _this select 0; + _weapon = _this select 1; + _allammo = getArray (configFile >> "CfgWeapons" >> _weapon >> "magazines"); + _ammoreturn = []; + { + _curammo = _x; + if !(_curammo in _NoGoAmmoCName) then{ + _ammoname = getText (configFile >> "Cfgmagazines" >> _curammo >> "displayName"); + _ammoreturn set [count _ammoreturn, [_curammo, _ammoname]]; + }; + }forEach _allammo; + _ammoreturn + }; + + while {true} do { + private ["_vehicle","_inVehicle"]; + _vehicle = vehicle player; + _inVehicle = _vehicle != player; + if (local _vehicle && _inVehicle) then { + private ["_pos","_servicePoints","_inRange"]; + _pos = getPosATL _vehicle; + _servicePoints = (nearestObjects [_pos, _servicePointClasses, _maxDistance]) - [_vehicle]; + _inRange = count _servicePoints > 0; + if (_inRange && (speed (_vehicle) < 1)) then { + private ["_servicePoint","_role","_actionCondition","_costs","_actionTitle"]; + _servicePoint = _servicePoints select 0; + _role = assignedVehicleRole player; + if (((str _role) != (str _lastRole)) || (_vehicle != _lastVehicle)) then { + // vehicle or seat changed + call _fnc_removeActions; + }; + _lastVehicle = _vehicle; + _lastRole = _role; + _actionCondition = "vehicle _this == _target && local _target"; + if (SP_repair_action < 0 && _repair_enable) then { + _costs = [_vehicle, _repair_costs] call _fnc_getCosts; + _actionTitle = [format["Repair %1",getText (configFile >> "Cfgvehicles" >> typeOf _vehicle >> "displayName")], _costs] call _fnc_actionTitle; + SP_repair_action = _vehicle addAction [_actionTitle, _folder + "service_point_repair.sqf", [_servicePoint, _costs, _repair_repairTime], -1, false, true, "", _actionCondition]; + }; + if ((count SP_rearm_actions == 0) && _rearm_enable) then { + private ["_weapons"]; + _costs = [_vehicle, _rearm_costs] call _fnc_getCosts; + _weapons = [_vehicle, _role] call _fnc_getWeapons; + { + private "_weaponName"; + _curweapon = _x select 0; + _weaponName = _x select 1; + _curturret = _x select 2; + if(_debugWeapon)then{_msg = format["WEAPONS DEBUG: %1",_x];diag_log _msg;systemChat _msg;}; + _ammo = [_vehicle,_curweapon] call _fnc_getAmmo; + { + _ammoclass = _x select 0; + _ammoname = _x select 1; + _actionTitle = [format["Rearm %1 with %2", _weaponName,_ammoname], _costs] call _fnc_actionTitle; + SP_rearm_action = _vehicle addAction [_actionTitle, _folder + "service_point_rearm.sqf", [_servicePoint, _costs, [_weaponName,_ammoclass,_ammoname,_GlobalMagazineMAX,_deny_already_armed_with,_curturret]], -1, false, true, "", _actionCondition]; + SP_rearm_actions set [count SP_rearm_actions, SP_rearm_action]; + }forEach _ammo; + + } forEach _weapons; + }; + if (!_messageShown && _message != "") then { + _messageShown = true; + _vehicle vehicleChat _message; + }; + } else { + call _fnc_removeActions; + _messageShown = false; + }; + } else { + call _fnc_removeActions; + _messageShown = false; + }; + sleep 2; + }; diff --git a/Server/mpmissions/epoch.Bornholm/addons/service_point/service_point_rearm.sqf b/Server/mpmissions/epoch.Bornholm/addons/service_point/service_point_rearm.sqf new file mode 100644 index 0000000..8da3ab4 --- /dev/null +++ b/Server/mpmissions/epoch.Bornholm/addons/service_point/service_point_rearm.sqf @@ -0,0 +1,37 @@ + + + // Vehicle Service Point (Rearm) by Axe Cop + //reworked for a3 epoch by Halv + + private ["_vehicle","_args","_servicePoint","_costs","_magazineCount","_weapon","_type","_name","_weaponType","_weaponName","_turret","_magazines","_ammo"]; + + _vehicle = _this select 0; + _args = _this select 3; + _servicePoint = _args select 0; + _costs = _args select 1; + _weapon = _args select 2; + _type = typeOf _vehicle; + _name = getText(configFile >> "cfgVehicles" >> _type >> "displayName"); + _weaponName = _weapon select 0; + _ammoClass = _weapon select 1; + _ammoName = _weapon select 2; + _ammoMAX = _weapon select 3; + _ammoMIN = _weapon select 4; + _turret = _weapon select 5; + + if (!local _vehicle) exitWith {cutText [format["%2 is not local to %1 - Re-Arm Denied!",name player, _name], "PLAIN DOWN"]; diag_log format["Error: called service_point_rearm.sqf with non-local vehicle: %1", _vehicle] }; + if(count (crew _vehicle) > 1) exitWith {cutText ["All Passengers Must Exit Vehicle - Re-Arm Denied!", "PLAIN DOWN"];}; + if (EPOCH_playerCrypto <_costs) exitWith {cutText [format["You need %1 Crypto to re-arm %2", _costs,_name], "PLAIN DOWN"];}; + _currentmags = magazines _vehicle; + _magscount = count _currentmags; + _ammocount = {_ammoClass == _x}count _currentmags; + if(_magscount > _ammoMAX)exitWith{cutText [format["You already have %1 magazine(s) in %2",_magscount,_weaponName], "PLAIN DOWN"];}; + if(_ammocount > _ammoMIN)exitWith{cutText [format["You already have %1 magazine(s) of %2 in %3\nTotal of %4 magazine(s)",_ammocount,_ammoName,_weaponName,_magscount], "PLAIN DOWN"];}; + + EPOCH_playerCrypto = EPOCH_playerCrypto - _costs ; + + // add a magazines + _vehicle addMagazineTurret [_ammoClass, _turret]; + + cutText [format["%1 of %2 Rearmed", _weaponName, _name], "PLAIN DOWN"]; + diff --git a/Server/mpmissions/epoch.Bornholm/addons/service_point/service_point_repair.sqf b/Server/mpmissions/epoch.Bornholm/addons/service_point/service_point_repair.sqf new file mode 100644 index 0000000..720417e --- /dev/null +++ b/Server/mpmissions/epoch.Bornholm/addons/service_point/service_point_repair.sqf @@ -0,0 +1,81 @@ +// Vehicle Service Point (Repair) by Axe Cop +//reworked for a3 epoch by Halv + +private ["_vehicle","_args","_servicePoint","_costs","_repairTime","_type","_name","_hitpoints","_allRepaired"]; + +_vehicle = _this select 0; + +if (!local _vehicle) exitWith { diag_log format["Error: called service_point_repair.sqf with non-local vehicle: %1", _vehicle] }; + +_args = _this select 3; +_servicePoint = _args select 0; +_costs = _args select 1; +_repairTime = _args select 2; +_type = typeOf _vehicle; +_name = getText(configFile >> "cfgVehicles" >> _type >> "displayName"); + +if (EPOCH_playerCrypto < _costs) exitWith {cutText [format["You need %1 Crypto to Repair %2", _costs,_name], "PLAIN DOWN"];}; + +EPOCH_playerCrypto = EPOCH_playerCrypto - _costs ; + +//taken from a2 epoch vehicle_getHitpoints.sqf +_fnc_vehicle_getHitpoints = { + private ["_cfgHitPoints", "_hps", "_funcGetHitPoints"]; + _cfgHitPoints = configFile >> "CfgVehicles" >> (typeOf _this) >> "HitPoints"; + _hps = []; + + _funcGetHitPoints = + { + for "_i" from 0 to ((count _this) - 1) do + { + private ["_hp"]; + _hp = configName (_this select _i); + + if (!(_hp in _hps)) then + { + _hps set [count _hps, _hp]; + }; + }; + }; + + while {(configName _cfgHitPoints) != ""} do + { + _cfgHitPoints call _funcGetHitPoints; + _cfgHitPoints = inheritsFrom _cfgHitPoints; + }; + + _hps +}; + +_vehicle engineOn false; + +_hitpoints = _vehicle call _fnc_vehicle_getHitpoints; +_allRepaired = true; +{ + private "_damage"; + if ((vehicle player != _vehicle) || (!local _vehicle) || ([0,0,0] distance (velocity _vehicle) > 1)) exitWith { + _allRepaired = false; + titleText [format["Repairing of %1 stopped", _name], "PLAIN DOWN"]; + }; + _damage = _vehicle getHitPointDamage _x; + if (_damage > 0) then { + if (_repairTime > 0) then { + private "_partName"; + //change "HitPart" to " - Part" rather than complicated string replace + _partName = toArray _x; + _partName set [0,20]; + _partName set [1,45]; + _partName set [2,20]; + _partName = toString _partName; + titleText [format["Repairing%1 ...", _partName], "PLAIN DOWN", _repairTime]; + sleep _repairTime; + }; + _vehicle setHitPointDamage [_x, 0]; + }; +} forEach _hitpoints; + +if (_allRepaired) then { + _vehicle setDamage 0; + _vehicle setVelocity [0,0,1]; + titleText [format["%1 Repaired", _name], "PLAIN DOWN"]; +}; \ No newline at end of file diff --git a/Server/mpmissions/epoch.Bornholm/init.sqf b/Server/mpmissions/epoch.Bornholm/init.sqf index 36ed58b..fe4d889 100644 --- a/Server/mpmissions/epoch.Bornholm/init.sqf +++ b/Server/mpmissions/epoch.Bornholm/init.sqf @@ -9,11 +9,8 @@ if hasInterface then [] ExecVM "VEMFr_client\sqf\initClient.sqf"; // Client-side part of VEMFr FlipVic = compileFinal preProcessFileLineNumbers "scripts\flip.sqf"; execVM "scripts\playermarker.sqf"; + execVM "addons\service_point\service_point.sqf"; }; - - -//#include "A3EAI_Client\A3EAI_initclient.sqf"; - //Advanced towing only tow 1 car SA_MAX_TOWED_CARGO = 1;