diff --git a/media/lua/client/TOC/Admin.lua b/media/lua/client/TOC/Admin.lua index 2fd6797..1e0390d 100644 --- a/media/lua/client/TOC/Admin.lua +++ b/media/lua/client/TOC/Admin.lua @@ -1,4 +1,5 @@ local CommandsData = require("TOC/CommandsData") +local ClientRelayCommands = require("TOC/ClientRelayCommands") local StaticData = require("TOC/StaticData") local DataController = require("TOC/Controllers/DataController") ------------------- @@ -7,7 +8,8 @@ local DataController = require("TOC/Controllers/DataController") ---@param context ISContextMenu ---@param worldobjects table local function AddAdminTocOptions(playerNum, context, worldobjects) - if not isAdmin() then return end + + if (isClient() and not isDebugEnabled()) or isAdmin() then return end local players = {} for _, v in ipairs(worldobjects) do @@ -40,8 +42,13 @@ local function AddAdminTocOptions(playerNum, context, worldobjects) context:addSubMenu(option, subMenu) subMenu:addOption(getText("ContextMenu_Admin_ResetTOC"), nil, function() - sendClientCommand(CommandsData.modules.TOC_RELAY, CommandsData.server.Relay.RelayExecuteInitialization, - { patientNum = clickedPlayerNum }) + if isClient() then + sendClientCommand(CommandsData.modules.TOC_RELAY, CommandsData.server.Relay.RelayExecuteInitialization, + { patientNum = clickedPlayerNum }) + else + -- TODO ugly + ClientRelayCommands.ReceiveExecuteInitialization() + end end) -- Force amputation @@ -54,8 +61,14 @@ local function AddAdminTocOptions(playerNum, context, worldobjects) local limbTranslatedName = getText("ContextMenu_Limb_" .. limbName) forceAmpSubMenu:addOption(limbTranslatedName, nil, function() - sendClientCommand(CommandsData.modules.TOC_RELAY, CommandsData.server.Relay.RelayForcedAmputation, + if isClient() then + sendClientCommand(CommandsData.modules.TOC_RELAY, CommandsData.server.Relay.RelayForcedAmputation, { patientNum = clickedPlayerNum, limbName = limbName }) + else + ClientRelayCommands.ReceiveExecuteAmputationAction({surgeonNum=clickedPlayerNum, limbName=limbName, damagePlayer=false}) + -- todo ugly + end + end) end end diff --git a/media/lua/client/TOC/ClientRelayCommands.lua b/media/lua/client/TOC/ClientRelayCommands.lua index ae5b3b9..354a690 100644 --- a/media/lua/client/TOC/ClientRelayCommands.lua +++ b/media/lua/client/TOC/ClientRelayCommands.lua @@ -72,3 +72,6 @@ local function OnServerRelayCommand(module, command, args) end Events.OnServerCommand.Add(OnServerRelayCommand) + +-- TODO temporary +return ClientRelayCommands \ No newline at end of file diff --git a/media/lua/client/TOC/CommonMethods.lua b/media/lua/client/TOC/CommonMethods.lua index 5c96a80..2a6f15e 100644 --- a/media/lua/client/TOC/CommonMethods.lua +++ b/media/lua/client/TOC/CommonMethods.lua @@ -26,7 +26,7 @@ end ---Returns full name for the side, to be used with BodyLocations ---@param side string ----@return string +---@return string? function CommonMethods.GetSideFull(side) if side == 'R' then return "Right" diff --git a/media/lua/client/TOC/Controllers/LimitActionsController.lua b/media/lua/client/TOC/Controllers/LimitActionsController.lua index ffdf343..a5fb74b 100644 --- a/media/lua/client/TOC/Controllers/LimitActionsController.lua +++ b/media/lua/client/TOC/Controllers/LimitActionsController.lua @@ -32,8 +32,12 @@ function ISBaseTimedAction:adjustMaxTime(maxTime) local time = og_ISBaseTimedAction_adjustMaxTime(self, maxTime) -- Exceptions handling, if we find that parameter then we just use the original time - local queue = ISTimedActionQueue.getTimedActionQueue(getPlayer()) - if queue and queue.current and queue.current.skipTOC then return time end + local actionsQueue = ISTimedActionQueue.getTimedActionQueue(getPlayer()) + + if actionsQueue and actionsQueue.current and actionsQueue.skipTOC then + --TOC_DEBUG.print("Should skip TOC stuff") + return time + end -- Action is valid, check if we have any cut limb and then modify maxTime local dcInst = DataController.GetInstance() @@ -57,6 +61,10 @@ function ISBaseTimedAction:adjustMaxTime(maxTime) time = time * (StaticData.LIMBS_TIME_MULTIPLIER_IND_NUM[limbName] - perkLevelScaled) end end + if actionsQueue and actionsQueue.current then + TOC_DEBUG.print("OG Action: " .. tostring(actionsQueue.current.Type)) + end + TOC_DEBUG.print("New time with amputations: " .. tostring(time)) return time end @@ -74,7 +82,7 @@ function ISBaseTimedAction:perform() if not dcInst:getIsAnyLimbCut() then return end local amputatedLimbs = CachedDataHandler.GetAmputatedLimbs(LocalPlayerController.username) - local xp = self.maxTime/100 + local xp = self.maxTime / 100 for k, _ in pairs(amputatedLimbs) do local limbName = k @@ -92,7 +100,6 @@ function ISBaseTimedAction:perform() if dcInst:getIsProstEquipped(limbName) then LocalPlayerController.playerObj:getXp():AddXP(Perks["ProstFamiliarity"], xp) end - end end end @@ -123,9 +130,7 @@ function ISEquipWeaponAction:isValid() end ---A recreation of the original method, but with amputations in mind ----@param dcInst DataController -function ISEquipWeaponAction:performWithAmputation(dcInst) - +function ISEquipWeaponAction:performWithAmputation() TOC_DEBUG.print("running ISEquipWeaponAction performWithAmputation") local hand = nil local otherHand = nil @@ -204,12 +209,15 @@ local og_ISEquipWeaponAction_perform = ISEquipWeaponAction.perform function ISEquipWeaponAction:perform() og_ISEquipWeaponAction_perform(self) - -- TODO Can we do it earlier? + + --if self.character == getPlayer() then local dcInst = DataController.GetInstance(self.character:getUsername()) -- Just check it any limb has been cut. If not, we can just return from here - if dcInst:getIsAnyLimbCut() == true then - self:performWithAmputation(dcInst) + if dcInst:getIsAnyLimbCut() then + self:performWithAmputation() end + + --end end function ISInventoryPaneContextMenu.doEquipOption(context, playerObj, isWeapon, items, player) @@ -269,6 +277,23 @@ function ISWorldObjectContextMenu.createMenu(player, worldobjects, x, y, test) ---@type ISContextMenu local ogContext = og_ISWorldObjectContextMenu_createMenu(player, worldobjects, x, y, test) + + -- The vanilla game doesn't count an item in the off hand as "equipped" for picking up glass. Let's fix that here + local brokenGlassOption = ogContext:getOptionFromName(getText("ContextMenu_RemoveBrokenGlass")) + + if brokenGlassOption then + local playerObj = getSpecificPlayer(player) + if (CachedDataHandler.GetHandFeasibility(StaticData.SIDES_IND_STR.R) and playerObj:getPrimaryHandItem()) or + (CachedDataHandler.GetHandFeasibility(StaticData.SIDES_IND_STR.L) and playerObj:getSecondaryHandItem()) + then + brokenGlassOption.notAvailable = false + brokenGlassOption.toolTip = nil -- This is active only when you can't do the action. + end + end + + + + -- check if no hands, disable various interactions if not CachedDataHandler.GetBothHandsFeasibility() then TOC_DEBUG.print("NO hands :((") @@ -283,8 +308,7 @@ function ISWorldObjectContextMenu.createMenu(player, worldobjects, x, y, test) return ogContext end - ---* DISABLE WEARING CERTAIN ITEMS WHEN NO LIMB +--* DISABLE WEARING CERTAIN ITEMS WHEN NO LIMB local function CheckLimbFeasibility(limbName) local dcInst = DataController.GetInstance() @@ -322,4 +346,4 @@ local og_ISClothingExtraAction_isValid = ISClothingExtraAction.isValid ---@diagnostic disable-next-line: duplicate-set-field function ISClothingExtraAction:isValid() return WrapClothingAction(self, og_ISClothingExtraAction_isValid, InventoryItemFactory.CreateItem(self.extra)) -end \ No newline at end of file +end diff --git a/media/lua/client/TOC/Handlers/CachedDataHandler.lua b/media/lua/client/TOC/Handlers/CachedDataHandler.lua index 38f5cdb..8e1c6ec 100644 --- a/media/lua/client/TOC/Handlers/CachedDataHandler.lua +++ b/media/lua/client/TOC/Handlers/CachedDataHandler.lua @@ -123,7 +123,8 @@ function CachedDataHandler.CalculateHandFeasibility(limbName) CachedDataHandler.handFeasibility[side] = not dcInst:getIsCut(limbName) or dcInst:getIsProstEquipped(limbName) end - +---@param side string Either "L" or "R" +---@return boolean function CachedDataHandler.GetHandFeasibility(side) return CachedDataHandler.handFeasibility[side] end diff --git a/media/lua/client/TOC/Main.lua b/media/lua/client/TOC/Main.lua index 4f53a7e..d8fec14 100644 --- a/media/lua/client/TOC/Main.lua +++ b/media/lua/client/TOC/Main.lua @@ -6,7 +6,7 @@ require("TOC/Events") ---@class Main local Main = { - _version = "2.1.2" + _version = "2.1.3" } function Main.Start() diff --git a/media/lua/client/TOC/TimedActions/IgnoredActions.lua b/media/lua/client/TOC/TimedActions/IgnoredActions.lua index e668e74..6fb660c 100644 --- a/media/lua/client/TOC/TimedActions/IgnoredActions.lua +++ b/media/lua/client/TOC/TimedActions/IgnoredActions.lua @@ -1,10 +1,60 @@ ---@diagnostic disable: duplicate-set-field -- Bunch of actions shouldn't be modified by the adjusted time +----------------------------------------------- +---* Some actions have specific maxTime calculations and we must account for that +---ISAttachItemHotbar +---ISDetachItemHotbar +---ISEquipWeaponAction +---ISUnequipAction + +--- We're forced to re-run this crap to fix it +---@param action ISBaseTimedAction +local function HandleSpeedSpecificAction(action) + action.skipTOC = true + action.animSpeed = action.maxTime / action:adjustMaxTime(action.maxTime) + action.maxTime = -1 +end + +local og_ISAttachItemHotbar_new = ISAttachItemHotbar.new +function ISAttachItemHotbar:new(character, item, slot, slotIndex, slotDef) + local action = og_ISAttachItemHotbar_new(self, character, item, slot, slotIndex, slotDef) + HandleSpeedSpecificAction(action) + return action +end + +local og_ISDetachItemHotbar_new = ISDetachItemHotbar.new +function ISDetachItemHotbar:new(character, item) + local action = og_ISDetachItemHotbar_new(self, character, item) + HandleSpeedSpecificAction(action) + return action +end + +local og_ISEquipWeaponAction_new = ISEquipWeaponAction.new +function ISEquipWeaponAction:new(character, item, time, primary, twoHands) + local action = og_ISEquipWeaponAction_new(self, character, item, time, primary, twoHands) + --TOC_DEBUG.print("Override ISEquipWeaponAction") + if not twoHands then + HandleSpeedSpecificAction(action) + end + return action +end + +local og_ISUnequipAction_new = ISUnequipAction.new +function ISUnequipAction:new(character, item, time) + local action = og_ISUnequipAction_new(self, character, item, time) + HandleSpeedSpecificAction(action) + return action +end + +------------------------------------------------------ +--- Normal cases + + local og_ISEatFoodAction_new = ISEatFoodAction.new function ISEatFoodAction:new(character, item, percentage) local action = og_ISEatFoodAction_new(self, character, item, percentage) - TOC_DEBUG.print("Override ISEatFoodAction") + --TOC_DEBUG.print("Override ISEatFoodAction") action.skipTOC = true return action end @@ -12,7 +62,7 @@ end local og_ISReadABook_new = ISReadABook.new function ISReadABook:new(character, item, time) local action = og_ISReadABook_new(self, character, item, time) - TOC_DEBUG.print("Override ISReadABook") + --TOC_DEBUG.print("Override ISReadABook") action.skipTOC = true return action end @@ -20,7 +70,7 @@ end local og_ISTakePillAction_new = ISTakePillAction.new function ISTakePillAction:new(character, item, time) local action = og_ISTakePillAction_new(self, character, item, time) - TOC_DEBUG.print("Override ISTakePillAction") + --TOC_DEBUG.print("Override ISTakePillAction") action.skipTOC = true return action end @@ -28,7 +78,7 @@ end local og_ISTakeWaterAction_new = ISTakeWaterAction.new function ISTakeWaterAction:new(character, item, waterUnit, waterObject, time, oldItem) local action = og_ISTakeWaterAction_new(self, character, item, waterUnit, waterObject, time, oldItem) - TOC_DEBUG.print("Override ISTakeWaterAction") + --TOC_DEBUG.print("Override ISTakeWaterAction") action.skipTOC = true return action end @@ -36,7 +86,7 @@ end local og_ISDrinkFromBottle_new = ISDrinkFromBottle.new function ISDrinkFromBottle:new(character, item, uses) local action = og_ISDrinkFromBottle_new(self, character, item, uses) - TOC_DEBUG.print("Override ISDrinkFromBottle") + --TOC_DEBUG.print("Override ISDrinkFromBottle") action.skipTOC = true return action end @@ -44,7 +94,7 @@ end local og_ISFinalizeDealAction_new = ISFinalizeDealAction.new function ISFinalizeDealAction:new(player, otherPlayer, itemsToGive, itemsToReceive, time) local action = og_ISFinalizeDealAction_new(self, player, otherPlayer, itemsToGive, itemsToReceive, time) - TOC_DEBUG.print("Override ISFinalizeDealAction") + --TOC_DEBUG.print("Override ISFinalizeDealAction") action.skipTOC = true return action end @@ -52,7 +102,7 @@ end local og_ISCampingInfoAction_new = ISCampingInfoAction.new function ISCampingInfoAction:new(character, campfireObject, campfire) local action = og_ISCampingInfoAction_new(self, character, campfireObject, campfire) - TOC_DEBUG.print("Override ISCampingInfoAction") + --TOC_DEBUG.print("Override ISCampingInfoAction") action.skipTOC = true return action end \ No newline at end of file diff --git a/mod.info b/mod.info index 871e831..416e141 100644 --- a/mod.info +++ b/mod.info @@ -4,5 +4,5 @@ description=You've been bitten. You have only two choices. id=TheOnlyCure icon=icon.png url=https://github.com/ZioPao/The-Only-Cure -modversion=2.1.2 +modversion=2.1.3 pzversion=41.65