diff --git a/Advanced Repair/custom/advancedRepair/Bones_fnc_salvageAndRepair.sqf b/Advanced Repair/custom/advancedRepair/Bones_fnc_salvageAndRepair.sqf index a6e5729..dea3595 100644 --- a/Advanced Repair/custom/advancedRepair/Bones_fnc_salvageAndRepair.sqf +++ b/Advanced Repair/custom/advancedRepair/Bones_fnc_salvageAndRepair.sqf @@ -1,499 +1,450 @@ -private ["_partsNeeded","_itemsNeeded","_partsToActOn","_partToActOn","_brokenParts","_repairableParts","_salvageableParts","_itemAction","_equippedMagazines","_vehicle","_action","_usedArray","_missingArray","_duration","_progress","_sleepDuration","_startTime","_label"]; - -_partsNeeded = []; -_itemsNeeded = []; -_partsToActOn = []; -_partToActOn = []; -_repairableParts =[]; -_salvageableParts =[]; -_equippedMagazines = magazines player; -_vehicle = _this select 1; -_action = _this select 0; -_usedArray = []; -_missingArray = []; - -if (ExileClientActionDelayShown) exitWith { false }; -ExileClientActionDelayShown = true; -ExileClientActionDelayAbort = false; - -//Check if repairable -if (!local _vehicle) exitwith -{ - ["InfoTitleAndText", ["Salvage/Repair Info", "Get in driver seat first"]] call ExileClient_gui_toaster_addTemplateToast; - ExileClientActionDelayShown = false; - ExileClientActionDelayAbort = false; -}; -if (ExileClientPlayerIsInCombat) exitWith -{ - ["ErrorTitleOnly", ["You are in combat!"]] call ExileClient_gui_toaster_addTemplateToast; - ExileClientActionDelayShown = false; - ExileClientActionDelayAbort = false; -}; -if (vehicle player isEqualTo _vehicle) exitWith -{ - ["ErrorTitleOnly", ["Are you serious?"]] call ExileClient_gui_toaster_addTemplateToast; - ExileClientActionDelayShown = false; - ExileClientActionDelayAbort = false; -}; -if (ExilePlayerInSafezone) exitWith -{ - ["ErrorTitleOnly", ["Leave Safezone First!"]] call ExileClient_gui_toaster_addTemplateToast; - ExileClientActionDelayShown = false; - ExileClientActionDelayAbort = false; -}; - -//Get the attributes for the type of repair -if (_action == 'repairHeloHull') then -{ -_partsToActOn = ["HitHull","HitBatteries","HitGlass1","HitGlass2","HitGlass3","HitGlass4","HitGlass5","HitRGlass","HitLGlass","HitMissiles","HitLight","HitHydraulics","HitTransmission","HitAvionics","HitGear","HitFuel","HitHStabilizerL1","HitHStabilizerR1","HitVStabilizer1","HitTail","HitPitotTube","HitStaticPort","HitStarter1","HitStarter2","HitStarter3","HitWinch"]; -_partsNeeded = - [ - ["Exile_Item_MetalBoard","Metal Board"], - ["Exile_Item_DuctTape","Duct Tape"], - ["Exile_Item_MetalScrews","Metal Screws"] - ]; -_itemsNeeded = - [ - ["Exile_Item_Screwdriver","ScrewDriver"] - ]; -_itemAction = 0; -_duration = 20; -}; - -if (_action == 'repairMainRotor') then -{ - _partsToActOn = ["HitHRotor"]; - _partsNeeded = - [ - ["Exile_Item_MetalBoard","Metal Board"] - ]; - _itemsNeeded = - [ - ["Exile_Item_Wrench","Wrench"] - ]; - _itemAction = 0; - _duration = 10; -}; - -if (_action == 'salvageMainRotor') then -{ - _partsToActOn = ["HitHRotor"]; - _partsNeeded = - [ - ["Exile_Item_MetalBoard","Metal Board"] - ]; - _itemsNeeded = - [ - ["Exile_Item_Wrench","Wrench"] - ]; - _itemAction = 1; - _duration = 10; -}; -if (_action == 'repairTailRotor') then -{ - _partsToActOn = ["HitVRotor"]; - _partsNeeded = - [ - ["Exile_Item_MetalBoard","Metal Board"] - ]; - _itemsNeeded = - [ - ["Exile_Item_Wrench","Wrench"] - ]; - _itemAction = 0; - _duration = 10; -}; - -if (_action == 'salvageTailRotor') then -{ - _partsToActOn = ["HitVRotor"]; - _partsNeeded = - [ - ["Exile_Item_MetalBoard","Metal Board"] - ]; - _itemsNeeded = - [ - ["Exile_Item_Wrench","Wrench"] - ]; - _itemAction = 1; - _duration = 10; -}; - -if (_action == 'repairEngine') then -{ - _partsToActOn = ["HitEngine","HitEngine2","HitEngine3"]; - _partsNeeded = - [ - ["Exile_Item_MetalWire","Metal Wire"], - ["Exile_Item_JunkMetal","Junk Metal"], - ["Exile_Item_OilCanister","Oil Canister"] - ]; - _itemsNeeded = - [ - ["Exile_Item_Foolbox","Foolbox"] - ]; - _itemAction = 0; - _duration = 20; -}; - -if (_action == 'salvageEngine') then -{ - _partsToActOn = ["HitEngine","HitEngine2","HitEngine3"]; - _partsNeeded = - [ - ["Exile_Item_MetalWire","Metal Wire"], - ["Exile_Item_JunkMetal","Junk Metal"], - ["Exile_Item_OilCanister","Oil Canister"] - ]; - _itemsNeeded = - [ - ["Exile_Item_Foolbox","Foolbox"] - ]; - _itemAction = 1; - _duration = 20; -}; - -if (_action == 'repairAllHelo') then -{ - _partsToActOn = ["HitEngine","HitEngine2","HitEngine3","HitVRotor","HitHRotor","HitHull","HitBatteries","HitGlass1","HitGlass2","HitGlass3","HitGlass4","HitGlass5","HitRGlass","HitLGlass","HitMissiles","HitLight","HitHydraulics","HitTransmission","HitAvionics","HitGear","HitFuel","HitHStabilizerL1","HitHStabilizerR1","HitVStabilizer1","HitTail","HitPitotTube","HitStaticPort","HitStarter1","HitStarter2","HitStarter3","HitWinch"]; - _partsNeeded = - [ - ["Exile_Item_MetalBoard","Metal Board"], - ["Exile_Item_MetalWire","Metal Wire"], - ["Exile_Item_JunkMetal","Junk Metal"], - ["Exile_Item_OilCanister","Oil Canister"], - ["Exile_Item_MetalBoard","Metal Board"], - ["Exile_Item_DuctTape","Duct Tape"], - ["Exile_Item_MetalScrews","Metal Screws"] - ]; - _itemsNeeded = - [ - ["Exile_Item_Foolbox","Foolbox"] - ]; - _itemAction = 0; - _duration = 60; -}; - -if (_action == 'repairCarHull') then -{ - _partsToActOn = ["HitBody","HitGlass1","HitGlass2","HitGlass3","HitGlass4","HitGlass5","HitGlass6","HitGlass7","HitGlass8","HitRGlass","HitLGlass","HitFuel"]; - _partsNeeded = - [ - ["Exile_Item_MetalBoard","Metal Board"], - ["Exile_Item_DuctTape","Duct Tape"], - ["Exile_Item_MetalScrews","Metal Screws"] - ]; - _itemsNeeded = - [ - ["Exile_Item_Screwdriver","ScrewDriver"] - ]; - _itemAction = 0; - _duration = 20; -}; - -if (_action == 'repairWheel') then -{ - _vehicleClass = typeOf cursortarget; - if (_vehicleClass == "Exile_Car_HEMMT")then - { - _partsToActOn = ["HitLF2Wheel","HitLFWheel","HitRFWheel","HitRF2Wheel","HitLMWheel","HitLBWheel","HitRMWheel","HitRBWheel"]; - } - else - { - if (_vehicleClass == "Exile_Car_Zamak" || _vehicleClass == "Exile_Car_Tempest" || _vehicleClass == "Exile_Car_Ural_Open_Worker" || _vehicleClass == "Exile_Car_Ural_Open_Blue" || _vehicleClass == "Exile_Car_Ural_Open_Military" || _vehicleClass == "Exile_Car_Ural_Open_Yellow" || _vehicleClass == "Exile_Car_Ural_Covered_Worker" || _vehicleClass == "Exile_Car_Ural_Covered_Blue" || _vehicleClass == "Exile_Car_Ural_Covered_Military" || _vehicleClass == "Exile_Car_Ural_Covered_Yellow" || _vehicleClass == "Exile_Car_V3S_Open" || _vehicleClass == "Exile_Car_V3S_Covered") then - { - _partsToActOn = ["HitLF2Wheel","HitLFWheel","HitRFWheel","HitRF2Wheel","HitLMWheel","HitRMWheel"]; - } - else - { - _partsToActOn = ["HitLF2Wheel","HitLFWheel","HitRFWheel","HitRF2Wheel"]; - }; - }; - _partsNeeded = - [ - ["Exile_Item_CarWheel","Car Wheel"] - ]; - _itemsNeeded = - [ - ["Exile_Item_Wrench","Wrench"] - ]; - _itemAction = 0; - _duration = 10; -}; - -if (_action == 'salvageWheel') then -{ - _vehicleClass = typeOf cursortarget; - if (_vehicleClass == "Exile_Car_HEMMT")then - { - _partsToActOn = ["HitLF2Wheel","HitLFWheel","HitRFWheel","HitRF2Wheel","HitLMWheel","HitLBWheel","HitRMWheel","HitRBWheel"]; - } - else - { - if (_vehicleClass == "Exile_Car_Zamak" || _vehicleClass == "Exile_Car_Tempest" || _vehicleClass == "Exile_Car_Ural_Open_Worker" || _vehicleClass == "Exile_Car_Ural_Open_Blue" || _vehicleClass == "Exile_Car_Ural_Open_Military" || _vehicleClass == "Exile_Car_Ural_Open_Yellow" || _vehicleClass == "Exile_Car_Ural_Covered_Worker" || _vehicleClass == "Exile_Car_Ural_Covered_Blue" || _vehicleClass == "Exile_Car_Ural_Covered_Military" || _vehicleClass == "Exile_Car_Ural_Covered_Yellow" || _vehicleClass == "Exile_Car_V3S_Open" || _vehicleClass == "Exile_Car_V3S_Covered") then - { - _partsToActOn = ["HitLF2Wheel","HitLFWheel","HitRFWheel","HitRF2Wheel","HitLMWheel","HitRMWheel"]; - } - else - { - _partsToActOn = ["HitLF2Wheel","HitLFWheel","HitRFWheel","HitRF2Wheel"]; - }; - }; - _partsNeeded = - [ - ["Exile_Item_CarWheel","Car Wheel"] - ]; - _itemsNeeded = - [ - ["Exile_Item_Wrench","Wrench"] - ]; - _itemAction = 1; - _duration = 10; -}; - -if (_action == 'repairCarEngine') then -{ - _partsToActOn = ["HitEngine"]; - _partsNeeded = - [ - ["Exile_Item_MetalWire","Metal Wire"], - ["Exile_Item_JunkMetal","Junk Metal"], - ["Exile_Item_OilCanister","Oil Canister"] - ]; - _itemsNeeded = - [ - ["Exile_Item_Foolbox","Foolbox"] - ]; - _itemAction = 0; - _duration = 20; -}; - -if (_action == 'salvageCarEngine') then -{ - _partsToActOn = ["HitEngine"]; - _partsNeeded = - [ - ["Exile_Item_MetalWire","Metal Wire"], - ["Exile_Item_JunkMetal","Junk Metal"], - ["Exile_Item_OilCanister","Oil Canister"] - ]; - _itemsNeeded = - [ - ["Exile_Item_Foolbox","Foolbox"] - ]; - _itemAction = 1; - _duration = 20; -}; - -if (_action == 'repairAllCar') then -{ - _partsToActOn = ["HitEngine","HitEngine2","HitEngine3","HitLF2Wheel","HitLFWheel","HitRFWheel","HitRF2Wheel","HitLMWheel","HitLBWheel","HitRMWheel","HitRBWheel","HitBody","HitGlass1","HitGlass2","HitGlass3","HitGlass4","HitGlass5","HitGlass6","HitGlass7","HitGlass8","HitRGlass","HitLGlass","HitFuel"]; - _partsNeeded = - [ - ["Exile_Item_MetalBoard","Metal Board"], - ["Exile_Item_MetalWire","Metal Wire"], - ["Exile_Item_JunkMetal","Junk Metal"], - ["Exile_Item_OilCanister","Oil Canister"], - ["Exile_Item_MetalBoard","Metal Board"], - ["Exile_Item_DuctTape","Duct Tape"], - ["Exile_Item_MetalScrews","Metal Screws"] - ]; - _itemsNeeded = - [ - ["Exile_Item_Foolbox","Foolbox"] - ]; - _itemAction = 0; - _duration = 60; -}; - -//find all repairable and salvageable parts - -{ - if ((_vehicle getHitPointDamage _x) > 0) then - { - _repairableParts pushBack _x; - }; -}forEach _partsToActOn; - -{ - if ((_vehicle getHitPointDamage _x) < .2) then - { - _salvageableParts pushBack _x; - }; -}forEach _partsToActOn; - -//Check for all required tools and parts - -if (_itemAction == 0) then -{ - { - _currentItem = _x select 0; - if (_currentItem in _equippedMagazines) then - { - _usedArray pushback (_x select 1); - } - else - { - _missingArray pushback (_x select 1); - }; - }forEach _partsNeeded; -}; - -{ -_currentItem = _x select 0; -if (_currentItem in _equippedMagazines) then - { - _usedArray pushback (_x select 1); - } - else - { - _missingArray pushback (_x select 1); - }; -}forEach _itemsNeeded; - -//Check if there is anything to salvage/repair -if ((_itemAction == 1) && (_salvageableParts isEqualto [])) exitwith - { - ["ErrorTitleAndText", ["Salvage/Repair Info", "The items you are trying to salvage are all broken!"]] call ExileClient_gui_toaster_addTemplateToast; - ExileClientActionDelayShown = false; - ExileClientActionDelayAbort = false; - }; -if ((_itemAction == 0) && (_repairableParts isEqualto [])) exitwith - { - ["ErrorTitleAndText", ["Salvage/Repair Info", "The items you are trying to repair are all fine!"]] call ExileClient_gui_toaster_addTemplateToast; - ExileClientActionDelayShown = false; - ExileClientActionDelayAbort = false; - }; - -_temp1 = count _missingArray; -if !(_temp1 == 0) exitwith - { - ["ErrorTitleAndText", ["Missing Items!", format ["You are missing the following items : %1, %2, %3, %4. Aborted!",(_missingArray select 0), (_missingArray select 1),(_missingArray select 2),(_missingArray select 3)]]] call ExileClient_gui_toaster_addTemplateToast; - ExileClientActionDelayShown = false; - ExileClientActionDelayAbort = false; - }; - -//Repair-Salvage the parts listed -if (_action == 'repairHeloHull' || _action == 'repairAllHelo' || _action == 'repairEngine' || _action == 'repairCarEngine' || _action == 'salvageEngine' || _action == 'salvageCarEngine' || _action == 'repairAllCar' || _action == 'repairCarHull') then -{ - if(_itemAction == 0) then - { - _partToActOn = _repairableParts; - } - else - { - _partToActOn = _salvageableParts; - }; -} -else -{ - if(_itemAction == 0) then - { - _partToActOn pushback (_repairableParts select 0); - } - else - { - _partToActOn pushback (_salvageableParts select 0); - }; -}; -_animation = "Exile_Acts_RepairVehicle01_Animation01"; -disableSerialization; -("ExileActionProgressLayer" call BIS_fnc_rscLayer) cutRsc ["RscExileActionProgress", "PLAIN", 1, false]; - -_keyDownHandle = (findDisplay 46) displayAddEventHandler ["KeyDown","_this call ExileClient_action_event_onKeyDown"]; -_mouseButtonDownHandle = (findDisplay 46) displayAddEventHandler ["MouseButtonDown","_this call ExileClient_action_event_onMouseButtonDown"]; - -player switchMove _animation; -["switchMoveRequest", [netId player, _animation]] call ExileClient_system_network_send; - -_startTime = diag_tickTime; -_sleepDuration = _duration / 100; -_progress = 0; - -_display = uiNamespace getVariable "RscExileActionProgress"; -_label = _display displayCtrl 4002; -_label ctrlSetText "0%"; -_progressBarBackground = _display displayCtrl 4001; -_progressBarMaxSize = ctrlPosition _progressBarBackground; -_progressBar = _display displayCtrl 4000; -_progressBar ctrlSetPosition [_progressBarMaxSize select 0, _progressBarMaxSize select 1, 0, _progressBarMaxSize select 3]; -_progressBar ctrlSetBackgroundColor [0, 0.78, 0.93, 1]; -_progressBar ctrlCommit 0; -_progressBar ctrlSetPosition _progressBarMaxSize; -_progressBar ctrlCommit _duration; - -try -{ - while {_progress < 1} do - { - if (ExileClientActionDelayAbort) then - { - throw 1; - }; - - uiSleep _sleepDuration; - _progress = ((diag_tickTime - _startTime) / _duration) min 1; - _label ctrlSetText format["%1%2", round (_progress * 100), "%"]; - }; - throw 0; -} -catch -{ - _progressBarColor = []; - switch (_exception) do - { - case 0: - { - _progressBarColor = [0.7, 0.93, 0, 1]; - if(_action == 'repairAllHelo' || _action == 'repairAllCar') then - { - _vehicle setdamage 0; - } - else - { - { - _vehicle setHitPointDamage [_x,_itemAction]; - }forEach _partToActOn; - }; - if (_itemAction == 0) then - { - { - _tempItem = _x select 0; - player removeItem _tempItem; - }forEach _partsNeeded; - } - else - { - { - _tempPart = _x select 0; - _itemCount = {_x == _tempPart} count (Magazines player); - player addItem _tempPart select 0; - _tempcount = {_x == _tempPart} count (Magazines player); - if(_itemCount == _tempcount) then - { - _holder = createVehicle ["GroundWeaponHolder", position player, [], 0, "CAN_COLLIDE"]; - _holder addItemCargoGlobal [_tempPart, 1]; - ["InfoTitleAndText",["Repair/Salvage Info", format["You have no space, %1 placed on the ground!",_x select 1]]] call ExileClient_gui_toaster_addTemplateToast; - }; - }forEach _partsNeeded; - }; - ["InfoTitleAndText",["Repair/Salvage Info", "You have completed the action!"]] call ExileClient_gui_toaster_addTemplateToast; - }; - case 1: - { - ["InfoTitleAndText",["Repair/Salvage Info", "Do not move while repairing or salvaging!"]] call ExileClient_gui_toaster_addTemplateToast; - _progressBarColor = [0.82, 0.82, 0.82, 1]; - }; - }; - player switchMove ""; - ["switchMoveRequest", [netId player, ""]] call ExileClient_system_network_send; - _progressBar ctrlSetBackgroundColor _progressBarColor; - _progressBar ctrlSetPosition _progressBarMaxSize; - _progressBar ctrlCommit 0; -}; - -("ExileActionProgressLayer" call BIS_fnc_rscLayer) cutFadeOut 2; -(findDisplay 46) displayRemoveEventHandler ["KeyDown", _keyDownHandle]; -(findDisplay 46) displayRemoveEventHandler ["MouseButtonDown", _mouseButtonDownHandle]; -ExileClientActionDelayShown = false; -ExileClientActionDelayAbort = false; \ No newline at end of file +/* +Bones Vehicle Repair Script + +Executed from Bones_fnc_salvageAndRepairMenu.sqf + +*/ + +private [ + "_partsNeeded", + "_itemsNeeded", + "_partsToActOn", + "_equippedMagazines", + "_vehicle", + "_action", + "_items", + "_usedArray", + "_missingArray", + "_duration", + "_progress", + "_sleepDuration", + "_startTime", + "_label", + "_chance", + "_runOut", + "_itemAction", + "_additionalParts", + "_actionConfigs", + "_actionConfig", + "_fnc_getActionConfig", + "_fnc_contains", + "_fnc_itemClass", + "_fnc_itemLabel", + "_fnc_itemQuantity", + "_fnc_formatItem", + "_fnc_addItemQuantity", + "_fnc_removeItemQuantity", + "_fnc_requirementIndex", + "_fnc_pushRequirement", + "_allHitpoints", + "_hitpointNames", + "_noWheels", + "_animation", + "_keyDownHandle", + "_mouseButtonDownHandle", + "_display", + "_progressBarBackground", + "_progressBarMaxSize", + "_progressBar", + "_progressBarColor", + "_targetDamage", + "_requiredItems", + "_isSalvageAction" +]; + +_partsNeeded = []; +_itemsNeeded = []; +_items = _this select 2; +_equippedMagazines = magazines player; +_vehicle = _this select 1; +_action = _this select 0; +_usedArray = []; +_missingArray = []; +_partsToActOn = [_items]; +_additionalParts = []; +_chance = 4; // 1 in x chance of duct tape being consumed if used. + +if (ExileClientActionDelayShown) exitWith {false}; +ExileClientActionDelayShown = true; +ExileClientActionDelayAbort = false; + +if (!local _vehicle) exitWith +{ + ["InfoTitleAndText", ["Salvage/Repair Info", "Get in driver seat first"]] call ExileClient_gui_toaster_addTemplateToast; + ExileClientActionDelayShown = false; + ExileClientActionDelayAbort = false; +}; + +if (ExileClientPlayerIsInCombat) exitWith +{ + ["ErrorTitleOnly", ["You are in combat!"]] call ExileClient_gui_toaster_addTemplateToast; + ExileClientActionDelayShown = false; + ExileClientActionDelayAbort = false; +}; + +if (vehicle player isEqualTo _vehicle) exitWith +{ + ["ErrorTitleOnly", ["Are you serious?"]] call ExileClient_gui_toaster_addTemplateToast; + ExileClientActionDelayShown = false; + ExileClientActionDelayAbort = false; +}; + +if (ExilePlayerInSafezone) exitWith +{ + ["ErrorTitleOnly", ["Leave Safezone First!"]] call ExileClient_gui_toaster_addTemplateToast; + ExileClientActionDelayShown = false; + ExileClientActionDelayAbort = false; +}; + +_actionConfigs = [ + ["replaceCarWheel", [["Exile_Item_CarWheel", "Car Wheel"], ["Exile_Item_JunkMetal", "Junk Metal"]], [["Exile_Item_Wrench", "Wrench"]], 0, 10, []], + ["repairCarWheel", [["Exile_Item_DuctTape", "Duct Tape"], ["Exile_Item_JunkMetal", "Junk Metal"]], [], 0, 10, []], + ["salvageCarWheel", [["Exile_Item_CarWheel", "Car Wheel"]], [["Exile_Item_Wrench", "Wrench"]], 1, 10, []], + + ["repairRotor", [["Exile_Item_DuctTape", "Duct Tape"], ["Exile_Item_JunkMetal", "Junk Metal"]], [], 0, 20, []], + ["repairTrack", [["Exile_Item_DuctTape", "Duct Tape"], ["Exile_Item_JunkMetal", "Junk Metal", 3]], [], 0, 20, []], + + ["replaceLeft Track", [["Exile_Item_JunkMetal", "Junk Metal", 3]], [["Exile_Item_Wrench", "Wrench"]], 0, 20, []], + ["replaceRight Track", [["Exile_Item_JunkMetal", "Junk Metal", 3]], [["Exile_Item_Wrench", "Wrench"]], 0, 20, []], + + ["replaceMain Rotor", [["Exile_Item_MetalBoard", "Metal Board", 2], ["Exile_Item_JunkMetal", "Junk Metal", 4]], [["Exile_Item_Wrench", "Wrench"]], 0, 20, []], + ["salvageMain Rotor", [["Exile_Item_MetalBoard", "Metal Board", 2]], [["Exile_Item_Wrench", "Wrench"]], 1, 20, []], + ["replaceTail Rotor", [["Exile_Item_MetalBoard", "Metal Board"], ["Exile_Item_JunkMetal", "Junk Metal", 3]], [["Exile_Item_Wrench", "Wrench"]], 0, 10, []], + ["salvageTail Rotor", [["Exile_Item_MetalBoard", "Metal Board"]], [["Exile_Item_Wrench", "Wrench"]], 1, 10, []], + + ["repairGlass", [["Exile_Item_DuctTape", "Duct Tape"], ["Exile_Item_MetalScrews", "Metal Screws"]], [], 0, 10, []], + ["replaceGlass", [["Exile_Item_MetalBoard", "Metal Board"], ["Exile_Item_MetalScrews", "Metal Screws"]], [["Exile_Item_Screwdriver", "ScrewDriver"]], 0, 10, []], + ["salvageGlass", [["Exile_Item_MetalBoard", "Metal Board"]], [["Exile_Item_Screwdriver", "ScrewDriver"]], 1, 10, []], + + ["replaceEngine", [["Exile_Item_MetalWire", "Metal Wire"], ["Exile_Item_JunkMetal", "Junk Metal", 2], ["Exile_Item_OilCanister", "Oil Canister"]], [["Exile_Item_Foolbox", "Foolbox"]], 0, 20, ["hitEngine1", "hitEngine2", "hitEngine3", "hitEngine4"]], + ["repairEngine", [["Exile_Item_DuctTape", "Duct Tape"], ["Exile_Item_JunkMetal", "Junk Metal", 2]], [], 0, 10, ["hitEngine1", "hitEngine2", "hitEngine3", "hitEngine4"]], + ["salvageEngine", [["Exile_Item_MetalWire", "Metal Wire"], ["Exile_Item_JunkMetal", "Junk Metal", 2], ["Exile_Item_OilCanister", "Oil Canister"]], [["Exile_Item_Foolbox", "Foolbox"]], 1, 20, ["hitEngine1", "hitEngine2", "hitEngine3", "hitEngine4"]], + + ["replaceFuel", [["Exile_Item_OilCanister", "Oil Canister"], ["Exile_Item_JunkMetal", "Junk Metal"]], [["Exile_Item_Wrench", "Wrench"]], 0, 10, []], + ["repairFuel", [["Exile_Item_DuctTape", "Duct Tape"], ["Exile_Item_JunkMetal", "Junk Metal"]], [], 0, 10, []], + ["salvageFuel", [["Exile_Item_OilCanister", "Oil Canister"]], [["Exile_Item_Wrench", "Wrench"]], 1, 10, []], + + ["repairOther", [["Exile_Item_DuctTape", "Duct Tape"]], [], 0, 10, []] +]; + +_fnc_getActionConfig = { + params ["_configs", "_actionName"]; + private _result = []; + { + if ((_x select 0) == _actionName) exitWith + { + _result = _x; + }; + } forEach _configs; + _result +}; + +_fnc_contains = { + params ["_needle", "_text"]; + [_needle, _text] call BIS_fnc_inString +}; + +_fnc_itemClass = { + params ["_item"]; + _item select 0 +}; + +_fnc_itemLabel = { + params ["_item"]; + _item select 1 +}; + +_fnc_itemQuantity = { + params ["_item"]; + if ((count _item) > 2) exitWith {_item select 2}; + 1 +}; + +_fnc_formatItem = { + params ["_item"]; + private _quantity = [_item] call _fnc_itemQuantity; + private _label = [_item] call _fnc_itemLabel; + if (_quantity > 1) exitWith {format ["%1x %2", _quantity, _label]}; + _label +}; + +_fnc_addItemQuantity = { + params ["_item"]; + private _itemClass = [_item] call _fnc_itemClass; + private _itemLabel = [_item] call _fnc_itemLabel; + private _quantity = [_item] call _fnc_itemQuantity; + + for "_i" from 1 to _quantity do + { + private _itemCount = {_x == _itemClass} count (magazines player); + player addItem _itemClass; + private _tempCount = {_x == _itemClass} count (magazines player); + if (_itemCount == _tempCount) then + { + private _holder = createVehicle ["GroundWeaponHolder", position player, [], 0, "CAN_COLLIDE"]; + _holder addItemCargoGlobal [_itemClass, 1]; + ["InfoTitleAndText", ["Repair/Salvage Info", format ["You have no space, %1 placed on the ground!", _itemLabel]]] call ExileClient_gui_toaster_addTemplateToast; + }; + }; +}; + +_fnc_removeItemQuantity = { + params ["_item"]; + private _itemClass = [_item] call _fnc_itemClass; + private _quantity = [_item] call _fnc_itemQuantity; + + for "_i" from 1 to _quantity do + { + player removeItem _itemClass; + }; +}; + +_fnc_requirementIndex = { + params ["_requirements", "_itemClass"]; + private _index = -1; + { + if ((_x select 0) == _itemClass) exitWith + { + _index = _forEachIndex; + }; + } forEach _requirements; + _index +}; + +_fnc_pushRequirement = { + params ["_requirements", "_item"]; + private _itemClass = [_item] call _fnc_itemClass; + private _itemLabel = [_item] call _fnc_itemLabel; + private _quantity = [_item] call _fnc_itemQuantity; + private _index = [_requirements, _itemClass] call _fnc_requirementIndex; + + if (_index == -1) then + { + _requirements pushBack [_itemClass, _quantity, _itemLabel]; + } + else + { + private _requirement = _requirements select _index; + _requirement set [1, (_requirement select 1) + _quantity]; + _requirements set [_index, _requirement]; + }; +}; + +_actionConfig = [_actionConfigs, _action] call _fnc_getActionConfig; +if (_actionConfig isEqualTo []) exitWith +{ + ["ErrorTitleAndText", ["Repair/Salvage Info", format ["Unknown repair action: %1", _action]]] call ExileClient_gui_toaster_addTemplateToast; + ExileClientActionDelayShown = false; + ExileClientActionDelayAbort = false; +}; + +_partsNeeded = _actionConfig select 1; +_itemsNeeded = _actionConfig select 2; +_itemAction = _actionConfig select 3; +_duration = _actionConfig select 4; +_additionalParts = _actionConfig select 5; +_targetDamage = 0; +if (_items != "") then +{ + _targetDamage = _vehicle getHitPointDamage _items; +}; + +_isSalvageAction = (_action find "salvage") == 0; +if (_isSalvageAction && {_targetDamage >= 1}) exitWith +{ + ["InfoTitleAndText", ["Repair/Salvage Info", "This part is already removed or fully destroyed."]] call ExileClient_gui_toaster_addTemplateToast; + ExileClientActionDelayShown = false; + ExileClientActionDelayAbort = false; +}; + +if (_action == "repairRotor") then +{ + if (_items == "HitHRotor") then {_partsNeeded = [["Exile_Item_DuctTape", "Duct Tape"], ["Exile_Item_JunkMetal", "Junk Metal", 4]]}; + if (_items == "HitVRotor") then {_partsNeeded = [["Exile_Item_DuctTape", "Duct Tape"], ["Exile_Item_JunkMetal", "Junk Metal", 3]]}; +}; + +if (_targetDamage >= 0.5) then +{ + if (_action == "salvageCarWheel") then {_partsNeeded = [["Exile_Item_JunkMetal", "Junk Metal"]]}; + if (_action == "salvageMain Rotor") then {_partsNeeded = [["Exile_Item_JunkMetal", "Junk Metal", 4]]}; + if (_action == "salvageTail Rotor") then {_partsNeeded = [["Exile_Item_JunkMetal", "Junk Metal", 3]]}; + if (_action == "salvageEngine") then {_partsNeeded = [["Exile_Item_JunkMetal", "Junk Metal", 2]]}; + if (_action == "salvageFuel") then {_partsNeeded = [["Exile_Item_JunkMetal", "Junk Metal"]]}; + if (_action == "salvageGlass") then {_partsNeeded = [["Exile_Item_JunkMetal", "Junk Metal"]]}; +}; + +{ + _partsToActOn pushBack _x; +} forEach _additionalParts; + +if (_action == "repairOther") then +{ + _partsToActOn = []; + _allHitpoints = getAllHitPointsDamage _vehicle; + _hitpointNames = _allHitpoints select 0; + _noWheels = getNumber (configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "numberPhysicalWheels"); + + { + private _isGlass = ["glass", _x] call _fnc_contains; + private _isRotor = ["rotor", _x] call _fnc_contains; + private _isWheel = ["wheel", _x] call _fnc_contains; + private _isEngine = ["engine", _x] call _fnc_contains; + private _isFuel = ["fuel", _x] call _fnc_contains; + private _isTrack = ["track", _x] call _fnc_contains; + + if !(_isGlass || _isRotor || _isWheel || _isFuel || _isEngine || _isTrack) then + { + _partsToActOn pushBack _x; + }; + + if (_noWheels == 4) then + { + if (_x == "HitRMWheel") then {_partsToActOn pushBack _x}; + if (_x == "HitLMWheel") then {_partsToActOn pushBack _x}; + if (_x == "HitLBWheel") then {_partsToActOn pushBack _x}; + if (_x == "HitRBWheel") then {_partsToActOn pushBack _x}; + }; + + if (_noWheels == 6) then + { + if (_x == "HitLBWheel") then {_partsToActOn pushBack _x}; + if (_x == "HitRBWheel") then {_partsToActOn pushBack _x}; + }; + } forEach _hitpointNames; +}; + +_requiredItems = []; +if (_itemAction == 0) then +{ + { + [_requiredItems, _x] call _fnc_pushRequirement; + } forEach _partsNeeded; +}; +{ + [_requiredItems, _x] call _fnc_pushRequirement; +} forEach _itemsNeeded; + +{ + private _currentItem = _x select 0; + private _currentQuantity = _x select 1; + private _currentLabel = _x select 2; + private _formattedItem = if (_currentQuantity > 1) then {format ["%1x %2", _currentQuantity, _currentLabel]} else {_currentLabel}; + + if (({_x == _currentItem} count _equippedMagazines) >= _currentQuantity) then + { + _usedArray pushBack _formattedItem; + } + else + { + _missingArray pushBack _formattedItem; + }; +} forEach _requiredItems; + +if ((count _missingArray) > 0) exitWith +{ + ["ErrorTitleAndText", ["Missing Items!", format ["You are missing the following items: %1. Aborted!", _missingArray joinString ", "]]] call ExileClient_gui_toaster_addTemplateToast; + ExileClientActionDelayShown = false; + ExileClientActionDelayAbort = false; +}; + +_animation = "Exile_Acts_RepairVehicle01_Animation01"; +disableSerialization; +("ExileActionProgressLayer" call BIS_fnc_rscLayer) cutRsc ["RscExileActionProgress", "PLAIN", 1, false]; + +_keyDownHandle = (findDisplay 46) displayAddEventHandler ["KeyDown", "_this call ExileClient_action_event_onKeyDown"]; +_mouseButtonDownHandle = (findDisplay 46) displayAddEventHandler ["MouseButtonDown", "_this call ExileClient_action_event_onMouseButtonDown"]; + +player switchMove _animation; +["switchMoveRequest", [netId player, _animation]] call ExileClient_system_network_send; + +_startTime = diag_tickTime; +_sleepDuration = _duration / 100; +_progress = 0; + +_display = uiNamespace getVariable "RscExileActionProgress"; +_label = _display displayCtrl 4002; +_label ctrlSetText "0%"; +_progressBarBackground = _display displayCtrl 4001; +_progressBarMaxSize = ctrlPosition _progressBarBackground; +_progressBar = _display displayCtrl 4000; +_progressBar ctrlSetPosition [_progressBarMaxSize select 0, _progressBarMaxSize select 1, 0, _progressBarMaxSize select 3]; +_progressBar ctrlSetBackgroundColor [0, 0.78, 0.93, 1]; +_progressBar ctrlCommit 0; +_progressBar ctrlSetPosition _progressBarMaxSize; +_progressBar ctrlCommit _duration; + +try +{ + while {_progress < 1} do + { + if (ExileClientActionDelayAbort) then + { + throw 1; + }; + + uiSleep _sleepDuration; + _progress = ((diag_tickTime - _startTime) / _duration) min 1; + _label ctrlSetText format ["%1%2", round (_progress * 100), "%"]; + }; + throw 0; +} +catch +{ + _progressBarColor = []; + switch (_exception) do + { + case 0: + { + _progressBarColor = [0.7, 0.93, 0, 1]; + { + _vehicle setHitPointDamage [_x, _itemAction]; + } forEach _partsToActOn; + + if (_itemAction == 0) then + { + { + private _tempItem = [_x] call _fnc_itemClass; + if !(_tempItem == "Exile_Item_DuctTape") then + { + [_x] call _fnc_removeItemQuantity; + } + else + { + _runOut = floor random _chance; + if (_runOut == 0) then + { + player removeItem _tempItem; + if (_tempItem == "Exile_Item_DuctTape") then + { + ["ErrorTitleOnly", ["Your Duct Tape has run out!"]] call ExileClient_gui_toaster_addTemplateToast; + }; + }; + }; + } forEach _partsNeeded; + } + else + { + { + [_x] call _fnc_addItemQuantity; + } forEach _partsNeeded; + }; + ["InfoTitleAndText", ["Repair/Salvage Info", "You have completed the action!"]] call ExileClient_gui_toaster_addTemplateToast; + }; + case 1: + { + ["InfoTitleAndText", ["Repair/Salvage Info", "Do not move while repairing or salvaging!"]] call ExileClient_gui_toaster_addTemplateToast; + _progressBarColor = [0.82, 0.82, 0.82, 1]; + }; + }; + player switchMove ""; + ["switchMoveRequest", [netId player, ""]] call ExileClient_system_network_send; + _progressBar ctrlSetBackgroundColor _progressBarColor; + _progressBar ctrlSetPosition _progressBarMaxSize; + _progressBar ctrlCommit 0; +}; + +("ExileActionProgressLayer" call BIS_fnc_rscLayer) cutFadeOut 2; +(findDisplay 46) displayRemoveEventHandler ["KeyDown", _keyDownHandle]; +(findDisplay 46) displayRemoveEventHandler ["MouseButtonDown", _mouseButtonDownHandle]; +ExileClientActionDelayShown = false; +ExileClientActionDelayAbort = false; diff --git a/Advanced Repair/custom/advancedRepair/Bones_fnc_salvageAndRepairMenu.sqf b/Advanced Repair/custom/advancedRepair/Bones_fnc_salvageAndRepairMenu.sqf new file mode 100644 index 0000000..3715a5d --- /dev/null +++ b/Advanced Repair/custom/advancedRepair/Bones_fnc_salvageAndRepairMenu.sqf @@ -0,0 +1,416 @@ +private [ + "_vehicle", + "_allHitpoints", + "_hitpointNames", + "_noWheels", + "_tempMenu", + "_tempSubMenuSalvage", + "_tempSubMenuRepair", + "_tempSubMenuReplace", + "_tempSubMenuSalvageWheels", + "_tempSubMenuRepairWheels", + "_tempSubMenuReplaceWheels", + "_tempSubMenuSalvageWindows", + "_tempSubMenuRepairWindows", + "_tempSubMenuReplaceWindows", + "_fnc_contains", + "_fnc_lookup", + "_fnc_hasActions", + "_fnc_pushSubMenu", + "_fnc_pushMenuItem", + "_fnc_wheelLabel", + "_fnc_windowLabel", + "_fnc_isRepairOtherHitpoint", + "_wheelLabelsByCount", + "_trackLabels", + "_rotorLabels", + "_overallDamage", + "_backButton" +]; + +_vehicle = cursorTarget; +_allHitpoints = getAllHitPointsDamage _vehicle; +_hitpointNames = _allHitpoints select 0; +_noWheels = getNumber (configFile >> "CfgVehicles" >> (typeOf _vehicle) >> "numberPhysicalWheels"); + +_tempMenu = [["Repair Menu", true]]; +_tempSubMenuSalvage = [["Salvage Menu", true]]; +_tempSubMenuRepair = [["Repair Menu", true]]; +_tempSubMenuReplace = [["Replace Menu", true]]; +_tempSubMenuSalvageWheels = [["Salvage Wheel Menu", true]]; +_tempSubMenuRepairWheels = [["Repair Wheel Menu", true]]; +_tempSubMenuReplaceWheels = [["Replace Wheel Menu", true]]; +_tempSubMenuSalvageWindows = [["Salvage Glass Menu", true]]; +_tempSubMenuRepairWindows = [["Repair Glass Menu", true]]; +_tempSubMenuReplaceWindows = [["Replace Glass Menu", true]]; + +_fnc_contains = { + params ["_needle", "_text"]; + [_needle, _text] call BIS_fnc_inString +}; + +_fnc_lookup = { + params ["_pairs", "_key", ["_default", ""]]; + private _result = _default; + { + if ((_x select 0) == _key) exitWith + { + _result = _x select 1; + }; + } forEach _pairs; + _result +}; + +_fnc_hasActions = { + params ["_menu"]; + (count _menu) > 1 +}; + +_fnc_pushSubMenu = { + params ["_menu", "_label", "_menuVariable"]; + _menu pushBack [_label, [0], format ["#USER:%1", _menuVariable], -5, [["expression", "true"]], "1", "1"]; +}; + +_fnc_pushMenuItem = { + params ["_menu", "_label", "_action", "_hitpoint"]; + private _statement = format ["['%1','%2'] call salvage_setup", _action, _hitpoint]; + if (_hitpoint != "") then + { + private _damage = _vehicle getHitPointDamage _hitpoint; + private _conditionPercent = round ((1 - _damage) * 100); + _label = (format ["%1 %2", _label, _conditionPercent]) + "%%"; + }; + _menu pushBack [_label, [0], "", -5, [["expression", _statement]], "1", "1"]; +}; + +_wheelLabelsByCount = [ + [4, [ + ["HitRFWheel", "Right Front Wheel"], + ["HitRF2Wheel", "Right Rear Wheel"], + ["HitLFWheel", "Left Front Wheel"], + ["HitLF2Wheel", "Left Rear Wheel"] + ]], + [6, [ + ["HitRFWheel", "Right Front Wheel"], + ["HitRF2Wheel", "Right Middle Wheel"], + ["HitRMWheel", "Right Rear Wheel"], + ["HitLFWheel", "Left Front Wheel"], + ["HitLF2Wheel", "Left Middle Wheel"], + ["HitLMWheel", "Left Rear Wheel"] + ]], + [8, [ + ["HitRFWheel", "Right Front Wheel"], + ["HitRF2Wheel", "Right Front Wheel 2"], + ["HitRMWheel", "Right Rear Wheel 2"], + ["HitRBWheel", "Right Rear Wheel"], + ["HitLFWheel", "Left Front Wheel"], + ["HitLF2Wheel", "Left Front Wheel 2"], + ["HitLMWheel", "Left Rear Wheel 2"], + ["HitLBWheel", "Left Rear Wheel"] + ]] +]; + +_trackLabels = [ + ["HitLTrack", "Left Track"], + ["HitRTrack", "Right Track"] +]; + +_rotorLabels = [ + ["HitHRotor", "Main Rotor"], + ["HitVRotor", "Tail Rotor"] +]; + +_fnc_wheelLabel = { + params ["_prefix", "_hitpoint", "_wheelCount"]; + private _wheelLabels = []; + { + if ((_x select 0) == _wheelCount) exitWith + { + _wheelLabels = _x select 1; + }; + } forEach _wheelLabelsByCount; + + private _partLabel = [_wheelLabels, _hitpoint, ""] call _fnc_lookup; + if (_partLabel == "") exitWith {""}; + format ["%1 %2", _prefix, _partLabel] +}; + +_fnc_windowLabel = { + params ["_prefix", "_hitpoint"]; + private _partLabel = ""; + + if (_hitpoint == "HitRGlass") exitWith {format ["%1 Window Right", _prefix]}; + if (_hitpoint == "HitLGlass") exitWith {format ["%1 Window Left", _prefix]}; + + if (["HitGlass", _hitpoint] call _fnc_contains) then + { + _partLabel = _hitpoint select [8]; + }; + + if (_partLabel == "") exitWith {""}; + format ["%1 Window %2", _prefix, _partLabel] +}; + +_fnc_isRepairOtherHitpoint = { + params ["_hitpoint", "_wheelCount"]; + + private _isKnownPart = + (["glass", _hitpoint] call _fnc_contains) || + (["rotor", _hitpoint] call _fnc_contains) || + (["engine", _hitpoint] call _fnc_contains) || + (["fuel", _hitpoint] call _fnc_contains) || + (["track", _hitpoint] call _fnc_contains); + + private _isKnownWheel = false; + if (["wheel", _hitpoint] call _fnc_contains) then + { + _isKnownWheel = (["", _hitpoint, _wheelCount] call _fnc_wheelLabel) != ""; + }; + + !(_isKnownPart || _isKnownWheel) +}; + +{ + private _hitpoint = _x; + private _damage = _vehicle getHitPointDamage _hitpoint; + + if (["wheel", _hitpoint] call _fnc_contains) then + { + if (_damage == 1) then + { + private _label = ["Replace", _hitpoint, _noWheels] call _fnc_wheelLabel; + if (_label != "") then + { + [_tempSubMenuReplaceWheels, _label, "replaceCarWheel", _hitpoint] call _fnc_pushMenuItem; + }; + } + else + { + if (_damage > .49 && _damage < 1) then + { + private _label = ["Repair", _hitpoint, _noWheels] call _fnc_wheelLabel; + if (_label != "") then + { + [_tempSubMenuRepairWheels, _label, "repairCarWheel", _hitpoint] call _fnc_pushMenuItem; + }; + }; + }; + + if (_damage < 1) then + { + private _label = ["Salvage", _hitpoint, _noWheels] call _fnc_wheelLabel; + if (_label != "") then + { + [_tempSubMenuSalvageWheels, _label, "salvageCarWheel", _hitpoint] call _fnc_pushMenuItem; + }; + }; + }; + + if (["track", _hitpoint] call _fnc_contains) then + { + private _partLabel = [_trackLabels, _hitpoint, ""] call _fnc_lookup; + if (_partLabel != "") then + { + if (_damage == 1) then + { + [_tempSubMenuReplace, format ["Replace %1", _partLabel], format ["replace%1", _partLabel], _hitpoint] call _fnc_pushMenuItem; + } + else + { + if (_damage > 0 && _damage < 1) then + { + [_tempSubMenuRepair, format ["Repair %1", _partLabel], "repairTrack", _hitpoint] call _fnc_pushMenuItem; + }; + }; + }; + }; + + if (["rotor", _hitpoint] call _fnc_contains) then + { + private _partLabel = [_rotorLabels, _hitpoint, ""] call _fnc_lookup; + if (_partLabel != "") then + { + if (_damage == 1) then + { + [_tempSubMenuReplace, format ["Replace %1", _partLabel], format ["replace%1", _partLabel], _hitpoint] call _fnc_pushMenuItem; + } + else + { + if (_damage > .49 && _damage < 1) then + { + [_tempSubMenuRepair, format ["Repair %1", _partLabel], "repairRotor", _hitpoint] call _fnc_pushMenuItem; + }; + }; + + if (_damage < 1) then + { + [_tempSubMenuSalvage, format ["Salvage %1", _partLabel], format ["salvage%1", _partLabel], _hitpoint] call _fnc_pushMenuItem; + }; + }; + }; + + if (["glass", _hitpoint] call _fnc_contains) then + { + if (_damage == 1) then + { + private _label = ["Replace", _hitpoint] call _fnc_windowLabel; + if (_label != "") then + { + [_tempSubMenuReplaceWindows, _label, "replaceGlass", _hitpoint] call _fnc_pushMenuItem; + }; + } + else + { + if (_damage > 0) then + { + private _label = ["Repair", _hitpoint] call _fnc_windowLabel; + if (_label != "") then + { + [_tempSubMenuRepairWindows, _label, "repairGlass", _hitpoint] call _fnc_pushMenuItem; + }; + }; + }; + + if (_damage < 1) then + { + private _label = ["Salvage", _hitpoint] call _fnc_windowLabel; + if (_label != "") then + { + [_tempSubMenuSalvageWindows, _label, "salvageGlass", _hitpoint] call _fnc_pushMenuItem; + }; + }; + }; + + if ((toLower _hitpoint) == "hitengine") then + { + if (_damage == 1) then + { + [_tempSubMenuReplace, "Replace Engine", "replaceEngine", _hitpoint] call _fnc_pushMenuItem; + } + else + { + if (_damage > .49 && _damage < 1) then + { + [_tempSubMenuRepair, "Repair Engine", "repairEngine", _hitpoint] call _fnc_pushMenuItem; + }; + }; + + if (_damage < 1) then + { + [_tempSubMenuSalvage, "Salvage Engine", "salvageEngine", _hitpoint] call _fnc_pushMenuItem; + }; + }; + + if ((toLower _hitpoint) == "hitfuel") then + { + if (_damage == 1) then + { + [_tempSubMenuReplace, "Replace Fuel Tank", "replaceFuel", _hitpoint] call _fnc_pushMenuItem; + } + else + { + if (_damage > .49 && _damage < 1) then + { + [_tempSubMenuRepair, "Repair Fuel Tank", "repairFuel", _hitpoint] call _fnc_pushMenuItem; + }; + }; + + if (_damage < 1) then + { + [_tempSubMenuSalvage, "Salvage Fuel Tank", "salvageFuel", _hitpoint] call _fnc_pushMenuItem; + }; + }; +} forEach _hitpointNames; + +_overallDamage = 0; +{ + if ([_x, _noWheels] call _fnc_isRepairOtherHitpoint) then + { + _overallDamage = _overallDamage + (_vehicle getHitPointDamage _x); + }; +} forEach _hitpointNames; + +if (_overallDamage > 0) then +{ + [_tempSubMenuRepair, "Repair All Other Damaged Items", "repairOther", ""] call _fnc_pushMenuItem; +}; + +_backButton = ["Back", [0], "", -4, [["expression", "Back ""Mainmenu"" "]], "1", "1"]; + +if ([_tempSubMenuSalvageWheels] call _fnc_hasActions) then +{ + _tempSubMenuSalvageWheels pushBack _backButton; + [_tempSubMenuSalvage, "Salvage Wheels", "ASL_Show_Repair_Options_SubMenuSalvageWheels_Array"] call _fnc_pushSubMenu; +}; + +if ([_tempSubMenuRepairWheels] call _fnc_hasActions) then +{ + _tempSubMenuRepairWheels pushBack _backButton; + [_tempSubMenuRepair, "Repair Wheels", "ASL_Show_Repair_Options_SubMenuRepairWheels_Array"] call _fnc_pushSubMenu; +}; + +if ([_tempSubMenuReplaceWheels] call _fnc_hasActions) then +{ + _tempSubMenuReplaceWheels pushBack _backButton; + [_tempSubMenuReplace, "Replace Wheels", "ASL_Show_Repair_Options_SubMenuReplaceWheels_Array"] call _fnc_pushSubMenu; +}; + +if ([_tempSubMenuSalvageWindows] call _fnc_hasActions) then +{ + _tempSubMenuSalvageWindows pushBack _backButton; + [_tempSubMenuSalvage, "Salvage Glass", "ASL_Show_Repair_Options_SubMenuSalvageWindows_Array"] call _fnc_pushSubMenu; +}; + +if ([_tempSubMenuRepairWindows] call _fnc_hasActions) then +{ + _tempSubMenuRepairWindows pushBack _backButton; + [_tempSubMenuRepair, "Repair Glass", "ASL_Show_Repair_Options_SubMenuRepairWindows_Array"] call _fnc_pushSubMenu; +}; + +if ([_tempSubMenuReplaceWindows] call _fnc_hasActions) then +{ + _tempSubMenuReplaceWindows pushBack _backButton; + [_tempSubMenuReplace, "Replace Glass", "ASL_Show_Repair_Options_SubMenuReplaceWindows_Array"] call _fnc_pushSubMenu; +}; + +if ([_tempSubMenuSalvage] call _fnc_hasActions) then +{ + _tempSubMenuSalvage pushBack _backButton; + [_tempMenu, "Salvage Options", "ASL_Show_Repair_Options_SubMenuSalvage_Array"] call _fnc_pushSubMenu; +}; + +if ([_tempSubMenuRepair] call _fnc_hasActions) then +{ + _tempSubMenuRepair pushBack _backButton; + [_tempMenu, "Repair Options", "ASL_Show_Repair_Options_SubMenuRepair_Array"] call _fnc_pushSubMenu; +}; + +if ([_tempSubMenuReplace] call _fnc_hasActions) then +{ + _tempSubMenuReplace pushBack _backButton; + [_tempMenu, "Replace Options", "ASL_Show_Repair_Options_SubMenuReplace_Array"] call _fnc_pushSubMenu; +}; + +if (count _tempMenu < 2) exitWith {hint str("nothing to repair")}; + +ASL_Show_Repair_Options_SubMenuSalvage_Array = _tempSubMenuSalvage; +ASL_Show_Repair_Options_SubMenuRepair_Array = _tempSubMenuRepair; +ASL_Show_Repair_Options_SubMenuReplace_Array = _tempSubMenuReplace; +ASL_Show_Repair_Options_SubMenuSalvageWheels_Array = _tempSubMenuSalvageWheels; +ASL_Show_Repair_Options_SubMenuRepairWheels_Array = _tempSubMenuRepairWheels; +ASL_Show_Repair_Options_SubMenuReplaceWheels_Array = _tempSubMenuReplaceWheels; +ASL_Show_Repair_Options_SubMenuSalvageWindows_Array = _tempSubMenuSalvageWindows; +ASL_Show_Repair_Options_SubMenuRepairWindows_Array = _tempSubMenuRepairWindows; +ASL_Show_Repair_Options_SubMenuReplaceWindows_Array = _tempSubMenuReplaceWindows; +ASL_Show_Repair_Options_Menu_Array = _tempMenu; + +showCommandingMenu ""; +showCommandingMenu "#USER:ASL_Show_Repair_Options_Menu_Array"; + +salvage_setup = { + private ["_vehicle", "_action", "_items"]; + _vehicle = cursorTarget; + _action = _this select 0; + _items = _this select 1; + [_action, _vehicle, _items] execVM "Custom\advancedRepair\Bones_fnc_salvageAndRepair.sqf"; +}; diff --git a/Advanced Repair/custom/advancedRepair/Bones_fnc_salvageAndRepairMenuCar.sqf b/Advanced Repair/custom/advancedRepair/Bones_fnc_salvageAndRepairMenuCar.sqf index c0e45f5..1531a9e 100644 --- a/Advanced Repair/custom/advancedRepair/Bones_fnc_salvageAndRepairMenuCar.sqf +++ b/Advanced Repair/custom/advancedRepair/Bones_fnc_salvageAndRepairMenuCar.sqf @@ -1,18 +1 @@ -ASL_Show_Repair_Options_Menu_Array = -[ - ["Repair Menu",false], - ["Repair Body",[0],"",-5,[["expression","['repairCarHull'] Call salvage_setup"]],"1","1"], - ["Repair Wheel",[0],"",-5,[["expression","['repairWheel'] Call salvage_setup"]],"1","1"], - ["Repair Engine",[0],"",-5,[["expression","['repairCarEngine'] Call salvage_setup"]],"1","1"], - ["Repair All",[0],"",-5,[["expression","['repairAllCar'] Call salvage_setup"]],"1","1"], - ["Salvage Wheel",[0],"",-5,[["expression","['salvageWheel'] Call salvage_setup"]],"1","1"], - ["Salvage Engine",[0],"",-5,[["expression","['salvageCarEngine'] Call salvage_setup"]],"1","1"] -]; -showCommandingMenu ""; -showCommandingMenu "#USER:ASL_Show_Repair_Options_Menu_Array"; - -salvage_setup = { -_vehicle = cursorObject; -_action = _this select 0; -[_action,_vehicle] execVM 'Custom\advancedRepair\Bones_fnc_salvageAndRepair.sqf'; -}; \ No newline at end of file +execVM "Custom\advancedRepair\Bones_fnc_salvageAndRepairMenu.sqf"; diff --git a/Advanced Repair/custom/advancedRepair/Bones_fnc_salvageAndRepairMenuHelo.sqf b/Advanced Repair/custom/advancedRepair/Bones_fnc_salvageAndRepairMenuHelo.sqf index 2fbd1e1..1531a9e 100644 --- a/Advanced Repair/custom/advancedRepair/Bones_fnc_salvageAndRepairMenuHelo.sqf +++ b/Advanced Repair/custom/advancedRepair/Bones_fnc_salvageAndRepairMenuHelo.sqf @@ -1,20 +1 @@ -ASL_Show_Repair_Options_Menu_Array = -[ - ["Repair Menu",false], - ["Repair Hull",[0],"",-5,[["expression","['repairHeloHull'] Call salvage_setup"]],"1","1"], - ["Repair Main Rotor",[0],"",-5,[["expression","['repairMainRotor'] Call salvage_setup"]],"1","1"], - ["Repair Tail Rotor",[0],"",-5,[["expression","['repairTailRotor'] Call salvage_setup"]],"1","1"], - ["Repair Engine",[0],"",-5,[["expression","['repairEngine'] Call salvage_setup"]],"1","1"], - ["Repair All",[0],"",-5,[["expression","['repairAllHelo'] Call salvage_setup"]],"1","1"], - ["Salvage Main Rotor",[0],"",-5,[["expression","['salvageMainRotor'] Call salvage_setup"]],"1","1"], - ["Salvage Tail Rotor",[0],"",-5,[["expression","['salvageTailRotor'] Call salvage_setup"]],"1","1"], - ["Salvage Engine",[0],"",-5,[["expression","['salvageEngine'] Call salvage_setup"]],"1","1"] -]; -showCommandingMenu ""; -showCommandingMenu "#USER:ASL_Show_Repair_Options_Menu_Array"; - -salvage_setup = { -_vehicle = cursorObject; -_action = _this select 0; -[_action,_vehicle] execVM 'Custom\advancedRepair\Bones_fnc_salvageAndRepair.sqf'; -}; \ No newline at end of file +execVM "Custom\advancedRepair\Bones_fnc_salvageAndRepairMenu.sqf"; diff --git a/Advanced Repair/install instructions.txt b/Advanced Repair/install instructions.txt index 91320a1..d382116 100644 --- a/Advanced Repair/install instructions.txt +++ b/Advanced Repair/install instructions.txt @@ -1,69 +1,103 @@ -Install Instructions: -1. UnPBO your Mission File. -2. Open the Advanced Repair folder and copy the "custom" folder to the mission file you just unPBO'd (same folder as config.cpp file). -3. Add the below lines into the "initPlayerLocal.sqf" file from your mission file, immediately after "if (!hasInterface || isServer) exitWith {};". - -//Advanced repair -Bones_fnc_salvageAndRepairMenuHelo = compileFinal preprocessFileLineNumbers "Custom\advancedRepair\Bones_fnc_salvageAndRepairMenuHelo.sqf"; -Bones_fnc_salvageAndRepairMenuCar = compileFinal preprocessFileLineNumbers "Custom\advancedRepair\Bones_fnc_salvageAndRepairMenuCar.sqf"; - -4. Open the description.ext file and change: -showHUD[] = -{ - true, // Scripted HUD (same as showHUD command) - true, // Vehicle + soldier info - true, // Vehicle radar - true, // Vehicle compass - true, // Tank direction indicator - false, // Commanding menu - false, // Group Bar - true, // HUD Weapon Cursors - false // Squad Radar -}; - -TO - -showHUD[] = -{ - true, // Scripted HUD (same as showHUD command) - true, // Vehicle + soldier info - true, // Vehicle radar - true, // Vehicle compass - true, // Tank direction indicator - true, // Commanding menu - false, // Group Bar - true, // HUD Weapon Cursors - false // Squad Radar -}; - -5. Open the config.cpp file in your mission, find the "class CfgInteractionMenus" section, and replace the repair function for cars and helos respectively, with the following: - -//Bones Custom Vehicle Repairs - -class Repair: ExileAbstractAction -{ - title = "Repair/Salvage"; - condition = "true"; - action = "_this call Bones_fnc_salvageAndRepairMenuCar"; -}; - - -// Bones Custom Air Repairs -class Repair: ExileAbstractAction -{ - title = "Repair/Salvage"; - condition = "true"; - action = "_this call Bones_fnc_salvageAndRepairMenuHelo"; -}; - -6. FOR INFISTAR USERS ONLY: -a. Look for infistar config line - -KCM = "true"; /* Just close ALL CommandingMenus */ -and change "true" to "false" - -OR - -b. Add "#USER:ASL_Show_Repair_Options_Menu_Array" to the "allowedCommandingMenus[]" option. - -7. Re-PBO your mission file (and Infistar file if modified) and re-upload to the server. +Install Instructions: + +1. UnPBO your mission file. + +2. Open the Advanced Repair folder and copy the "custom" folder to the mission file you just unPBO'd. + Copy it into the same folder that contains your mission config.cpp / description.ext. + +3. Add the lines below to your mission initPlayerLocal.sqf immediately after: + +if (!hasInterface || isServer) exitWith {}; + +// Advanced Repair +Bones_fnc_salvageAndRepairMenuHelo = compileFinal preprocessFileLineNumbers "Custom\advancedRepair\Bones_fnc_salvageAndRepairMenuHelo.sqf"; +Bones_fnc_salvageAndRepairMenuCar = compileFinal preprocessFileLineNumbers "Custom\advancedRepair\Bones_fnc_salvageAndRepairMenuCar.sqf"; + +4. Open description.ext and make sure the commanding menu is enabled. + +Change: + +showHUD[] = +{ + true, // Scripted HUD (same as showHUD command) + true, // Vehicle + soldier info + true, // Vehicle radar + true, // Vehicle compass + true, // Tank direction indicator + false, // Commanding menu + false, // Group Bar + true, // HUD Weapon Cursors + false // Squad Radar +}; + +To: + +showHUD[] = +{ + true, // Scripted HUD (same as showHUD command) + true, // Vehicle + soldier info + true, // Vehicle radar + true, // Vehicle compass + true, // Tank direction indicator + true, // Commanding menu + false, // Group Bar + true, // HUD Weapon Cursors + false // Squad Radar +}; + +5. Open config.cpp in your mission, find class CfgInteractionMenus, and replace the repair action for cars and helos. + +For ground vehicles: + +// Bones Custom Vehicle Repairs +class Repair: ExileAbstractAction +{ + title = "Repair/Salvage"; + condition = "true"; + action = "_this call Bones_fnc_salvageAndRepairMenuCar"; +}; + +For helicopters: + +// Bones Custom Air Repairs +class Repair: ExileAbstractAction +{ + title = "Repair/Salvage"; + condition = "true"; + action = "_this call Bones_fnc_salvageAndRepairMenuHelo"; +}; + +6. FOR INFISTAR USERS ONLY: + +Option A: + +Look for the infiSTAR config line: + +KCM = "true"; /* Just close ALL CommandingMenus */ + +and change "true" to "false". + +Option B: + +Keep KCM enabled and add these commanding menus to allowedCommandingMenus[]: + +"#USER:ASL_Show_Repair_Options_Menu_Array", +"#USER:ASL_Show_Repair_Options_SubMenuSalvage_Array", +"#USER:ASL_Show_Repair_Options_SubMenuRepair_Array", +"#USER:ASL_Show_Repair_Options_SubMenuReplace_Array", +"#USER:ASL_Show_Repair_Options_SubMenuSalvageWheels_Array", +"#USER:ASL_Show_Repair_Options_SubMenuRepairWheels_Array", +"#USER:ASL_Show_Repair_Options_SubMenuReplaceWheels_Array", +"#USER:ASL_Show_Repair_Options_SubMenuSalvageWindows_Array", +"#USER:ASL_Show_Repair_Options_SubMenuRepairWindows_Array", +"#USER:ASL_Show_Repair_Options_SubMenuReplaceWindows_Array" + +7. Optional recipe changes: + +Open Custom\advancedRepair\Bones_fnc_salvageAndRepair.sqf and edit _actionConfigs if your server uses custom repair parts. +Recipe entries support optional quantities: + +["Exile_Item_JunkMetal", "Junk Metal"] +["Exile_Item_JunkMetal", "Junk Metal", 3] + +8. Re-PBO your mission file and your infiSTAR file if you modified it, then upload them to your server. diff --git a/README.md b/README.md index 8384186..76d9651 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,53 @@ -# ExileMod-Advanced-Repair -Complex repair script for ExileMod with a selection menu that allows:
- a. Repair and salvage of engine and wheels for vehicles
- b. Repair and salvage of engine, tail rotor and main rotors for helo's.
- c. Repair of vehicle body.
- d. Repair entire Vehicle.
+# ExileMod Advanced Repair -To-do list:
- a. Include need for wheels for repairing entire vehicle, and repair only as many wheels as what the player currently has in inventory.
+Advanced client-side repair and salvage menu for ExileMod vehicles. -Installation: +The script builds a contextual commanding menu from the hitpoints on the vehicle under the player's cursor. It only shows actions that are valid for the current vehicle state, groups long wheel/glass lists into submenus, and shows each part's current condition as a percentage. -Refer to Install instructions contained within the file. +## Features -Credit to John for his original idea and work, that portions of this script are based on (http://www.exilemod.com/profile/38-john/) +- Dynamic `Repair`, `Replace`, and `Salvage` menus based on vehicle hitpoint damage. +- Nested wheel and glass menus to keep large vehicles readable. +- Per-part condition display where `100%` is healthy and `0%` is fully broken or removed. +- Repair and salvage support for wheels, glass, rotors, engine, fuel tank, tracks, and generic body damage. +- Anti-exploit salvage checks so a removed or fully destroyed part cannot be salvaged repeatedly. +- Damaged salvage rewards return raw materials instead of pristine replacement parts. +- Quantity-aware recipes in `custom\advancedRepair\Bones_fnc_salvageAndRepair.sqf`. +- Original car/helicopter entrypoint function names are preserved for install compatibility. + +## Installation + +See `Advanced Repair/install instructions.txt`. + +In short: + +1. UnPBO your mission. +2. Copy the `custom` folder from `Advanced Repair` into your mission root. +3. Compile the repair menu functions in `initPlayerLocal.sqf`. +4. Enable the commanding menu in `description.ext`. +5. Point the Exile vehicle and air `Repair` interaction actions at the Advanced Repair functions. +6. Update infiSTAR commanding menu settings when needed. +7. Re-PBO and upload your mission. + +## Configuration + +Recipes are stored in `_actionConfigs` inside: + +`Advanced Repair/custom/advancedRepair/Bones_fnc_salvageAndRepair.sqf` + +Each recipe item supports an optional quantity: + +```sqf +["Exile_Item_JunkMetal", "Junk Metal"] +["Exile_Item_JunkMetal", "Junk Metal", 3] +``` + +Tools are checked but not consumed. Duct tape has a chance to be consumed during repair. Other repair/replacement materials are consumed directly. + +## Credits + +Original script by Bones50. + +Credit to John for the original idea and work that portions of this script are based on: + +http://www.exilemod.com/profile/38-john/