diff --git a/.github/workflows/zip-release.yml b/.github/workflows/zip-release.yml index 8f045ec..e2df33e 100644 --- a/.github/workflows/zip-release.yml +++ b/.github/workflows/zip-release.yml @@ -159,8 +159,8 @@ jobs: - name: Bump Version if: steps.check_changes.outputs.should_proceed == 'true' run: | - sed -i "s|return \".*\"|return \"${{steps.increment_tag.outputs.no_prefix}}\"|" SSV2/includes/version.lua - sed -i "s|https://img.shields.io/badge/Script%20Version-v[0-9]\+\.[0-9]\+\.[0-9]\+-blue|https://img.shields.io/badge/Script%20Version-${{steps.increment_tag.outputs.version_number}}-blue|g" README.md + sed -i "s|return \".*\"|return \"${{ steps.increment_tag.outputs.no_prefix }}\"|" SSV2/includes/version.lua + sed -i "s|https://img.shields.io/badge/Script%20Version-v[0-9]\+\.[0-9]\+\.[0-9]\+-blue|https://img.shields.io/badge/Script%20Version-${{ steps.increment_tag.outputs.version_number }}-blue|g" README.md git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" git add SSV2/includes/version.lua README.md @@ -173,7 +173,7 @@ jobs: with: type: 'zip' filename: "Samurais_Scripts_${{ steps.increment_tag.outputs.version_number }}.zip" - exclusions: /.git* /scripts* /docs* *.json *.md *.editorconfig *.py *.txt LICENSE + exclusions: /.git* /dev* /docs* **.json **.md **.editorconfig **.py **.txt *.ps1 .gitignore LICENSE - name: Upload Release if: steps.check_changes.outputs.should_proceed == 'true' diff --git a/SSV2/includes/classes/Vector2.lua b/SSV2/includes/classes/Vector2.lua index d941fc4..afd70b4 100644 --- a/SSV2/includes/classes/Vector2.lua +++ b/SSV2/includes/classes/Vector2.lua @@ -25,9 +25,8 @@ ---@operator eq(vec2): boolean ---@operator le(vec2): boolean ---@operator lt(vec2): boolean -vec2 = {} +vec2 = { __type = "vec2" } vec2.__index = vec2 -vec2.__type = "vec2" -------------------------------------- diff --git a/SSV2/includes/classes/Vector4.lua b/SSV2/includes/classes/Vector4.lua index bb57487..2b1a137 100644 --- a/SSV2/includes/classes/Vector4.lua +++ b/SSV2/includes/classes/Vector4.lua @@ -27,9 +27,8 @@ ---@operator eq(vec4): boolean ---@operator le(vec4): boolean ---@operator lt(vec4): boolean -vec4 = {} +vec4 = { __type = "vec4" } vec4.__index = vec4 -vec4.__type = "vec4" -------------------------------------- diff --git a/SSV2/includes/classes/gta/CPlayerInfo.lua b/SSV2/includes/classes/gta/CPlayerInfo.lua index f1e9086..5a51615 100644 --- a/SSV2/includes/classes/gta/CPlayerInfo.lua +++ b/SSV2/includes/classes/gta/CPlayerInfo.lua @@ -20,6 +20,7 @@ local rlGamerInfo = require("includes.classes.gta.rlGamerInfo") ---@field m_swim_speed pointer ---@field m_walk_speed pointer ---@field m_game_state pointer +---@field m_ped pointer_ref ---@field m_is_wanted pointer ---@field m_wanted_level pointer ---@field m_wanted_level_display pointer @@ -40,6 +41,7 @@ function CPlayerInfo.new(ptr) m_swim_speed = ptr:add(0x01C8), m_walk_speed = ptr:add(0x01E4), m_game_state = ptr:add(0x0230), + m_ped = ptr:add(0x0240), m_is_wanted = ptr:add(0x08E0), m_wanted_level = ptr:add(0x08E8), m_wanted_level_display = ptr:add(0x08EC), diff --git a/SSV2/includes/classes/gta/CVehicle.lua b/SSV2/includes/classes/gta/CVehicle.lua index cddec70..16821d5 100644 --- a/SSV2/includes/classes/gta/CVehicle.lua +++ b/SSV2/includes/classes/gta/CVehicle.lua @@ -47,6 +47,7 @@ local SubHandlingCtorMap = { ---@field public m_car_handling_data pointer? ---@field public m_model_info_layout pointer ---@field public m_can_boost_jump pointer `bool` +---@field public m_velocity pointer ---@field public m_deform_god pointer ---@field public m_water_damage pointer ---@field public m_next_gear pointer @@ -107,8 +108,9 @@ function CVehicle:init(vehicle) instance.m_sub_handling_data = atArray(instance.m_handling_data:add(0x158), CCarHandlingData) instance.m_model_info_layout = instance.m_model_info:add(0x00B0):deref() instance.m_physics_fragments = phFragInst(ptr:add(0x0030):deref()) - instance.m_draw_data = CVehicleDrawData:init(ptr:add(0x0048):deref()) + instance.m_draw_data = CVehicleDrawData(ptr:add(0x0048):deref()) instance.m_can_boost_jump = ptr:add(0x03A4) + instance.m_velocity = ptr:add(0x07D0) instance.m_deform_god = ptr:add(0x096C) instance.m_is_targetable = ptr:add(0x0AEE) instance.m_door_lock_status = ptr:add(0x13D0) @@ -185,7 +187,9 @@ end ---@return CCarHandlingData|CBikeHandlingData|CFlyingHandlingData|any function CVehicle:GetSubHandlingData(handlingType) return self:__safecall(nil, function() - for _, sub_ptr in self.m_sub_handling_data:Iter() do + local array = self.m_sub_handling_data + for i = 1, array:Size() do + local sub_ptr = array:At(i) if (sub_ptr:is_valid()) then -- local base = CBaseSubHandlingData.new(sub_ptr) -- if (base and base:GetHandlingType() == handlingType) then @@ -440,7 +444,7 @@ function CVehicle:GetWheel(index) return end - local ptr = self.m_wheels:Get(index) + local ptr = self.m_wheels:At(index) if (not ptr or ptr:is_null()) then return end diff --git a/SSV2/includes/classes/gta/CVehicleDrawData.lua b/SSV2/includes/classes/gta/CVehicleDrawData.lua index b25be31..64174a5 100644 --- a/SSV2/includes/classes/gta/CVehicleDrawData.lua +++ b/SSV2/includes/classes/gta/CVehicleDrawData.lua @@ -73,17 +73,19 @@ end -------------------------------------- -- Class: CVehicleDrawData -------------------------------------- ----@class CVehicleDrawData : fwDrawData +---@class CVehicleDrawData ---@field m_wheel_draw_data pointer_ref ---@overload fun(ptr: pointer): CVehicleDrawData -local CVehicleDrawData = Class("CVehicleDrawData", { parent = fwDrawData, pointer_ctor = true }) +local CVehicleDrawData = Class("CVehicleDrawData", { pointer_ctor = true }) ---@param ptr pointer ---@return CVehicleDrawData function CVehicleDrawData:init(ptr) - self.m_ptr = ptr - self.m_wheel_draw_data = ptr:add(0x370) - return self + return setmetatable({ + m_ptr = ptr, + m_wheel_draw_data = ptr:add(0x370) + ---@diagnostic disable-next-line: param-type-mismatch + }, CVehicleDrawData) end ---@return CWheelDrawData diff --git a/SSV2/includes/classes/gta/CWheel.lua b/SSV2/includes/classes/gta/CWheel.lua index bb3b7ba..bf07edd 100644 --- a/SSV2/includes/classes/gta/CWheel.lua +++ b/SSV2/includes/classes/gta/CWheel.lua @@ -266,4 +266,14 @@ function CWheel:SetConfigFlag(flag, toggle) end) end +---@return boolean +function CWheel:IsLeftWheel() + return self:GetConfigFlag(Enums.eWheelConfigFlags.LEFTWHEEL) +end + +---@return boolean +function CWheel:IsRearWheel() + return self:GetConfigFlag(Enums.eWheelConfigFlags.REARWHEEL) +end + return CWheel diff --git a/SSV2/includes/classes/gta/atArray.lua b/SSV2/includes/classes/gta/atArray.lua index ccfcdff..afaa9ed 100644 --- a/SSV2/includes/classes/gta/atArray.lua +++ b/SSV2/includes/classes/gta/atArray.lua @@ -13,13 +13,12 @@ ---@ignore ---@generic T ---@class atArray ----@field private m_address pointer +---@field protected m_ptr pointer ---@field private m_data_ptr pointer +---@field private m_data array> ---@field private m_size uint16_t ----@field private m_count uint16_t ----@field private m_data array +---@field private m_capacity uint16_t ---@field private m_data_type any ----@field private m_last_update_time TimePoint ---@overload fun(address: pointer, data_type?: any): atArray local atArray = { __type = "atArray", @@ -35,38 +34,36 @@ setmetatable(atArray, { }) ---@generic T ----@param address pointer +---@param ptr pointer ---@param data_type optional ---@return atArray -function atArray.new(address, data_type) +function atArray.new(ptr, data_type) local instance = setmetatable({ - m_address = nullptr, + m_ptr = ptr, m_data_ptr = nullptr, - m_size = 0x0, - m_count = 0x0, + m_size = 0, + m_capacity = 0, m_data = {}, m_data_type = nil - ---@diagnostic disable-next-line + ---@diagnostic disable-next-line: param-type-mismatch }, atArray) - if not (IsInstance(address, "pointer") and address:is_valid()) then + if (ptr:is_null()) then return instance end - local array_size = address:add(0x8):get_word() + local array_size = ptr:add(0x8):get_word() if (array_size == 0) then return instance end - instance.m_address = address - instance.m_data_ptr = address:deref() - instance.m_size = array_size - instance.m_count = address:add(0xA):get_word() - instance.m_data_type = data_type - instance.m_last_update_time = TimePoint:new() + instance.m_data_ptr = ptr:deref() + instance.m_size = array_size + instance.m_capacity = ptr:add(0x10):get_word() + instance.m_data_type = data_type for i = 0, array_size - 1 do - instance.m_data[i + 1] = instance.m_data_ptr:add(i * 0x8):deref() + instance.m_data[i + 1] = instance.m_data_ptr:add(i * 0x8) end return instance @@ -74,7 +71,7 @@ end ---@return boolean function atArray:IsValid() - return self.m_address:is_valid() and self.m_data_ptr:is_valid() + return self.m_ptr:is_valid() and self.m_data_ptr:is_valid() end ---@return boolean @@ -84,56 +81,30 @@ end ---@return boolean function atArray:IsEmpty() - self:Update() return self.m_size == 0 end function atArray:Clear() - self.m_address = nullptr + self.m_ptr = nullptr self.m_data_ptr = nullptr + self.m_size = 0 + self.m_capacity = 0 self.m_data = {} - self.m_size = 0x0 - self.m_count = 0x0 self.m_data_type = nil - self.m_last_update_time:Reset() -end - -function atArray:Update() - if not self:IsValid() then - return - end - - if not self.m_last_update_time:HasElapsed(250) then - return - end - - self.m_size = self.m_address:add(0x8):get_word() - self.m_count = self.m_address:add(0xA):get_word() - if (self.m_size == 0) then - self.m_data = {} - self.m_last_update_time:Reset() - return - end - - for i = 0, self.m_size - 1 do - self.m_data[i + 1] = self.m_data_ptr:add(i * 0x8):deref() - end - - self.m_last_update_time:Reset() end ---@return pointer|nil function atArray:GetPointer() - if not self:IsValid() then + if (not self:IsValid()) then return end - return self.m_address + return self.m_ptr end ---@return pointer|nil function atArray:GetDataPointer() - if not self:IsValid() then + if (not self:IsValid()) then return end @@ -142,7 +113,7 @@ end ---@return uint64_t function atArray:GetAddress() - return self:IsValid() and self.m_address:get_address() or 0x0 + return self:IsValid() and self.m_ptr:get_address() or 0x0 end ---@return uint64_t @@ -150,65 +121,47 @@ function atArray:GetDataAddress() return self:IsValid() and self.m_data_ptr:get_address() or 0x0 end ----@return uint16_t -function atArray:Size() - self:Update() - return self.m_size -end - ----@return uint16_t -function atArray:Count() - self:Update() - return self.m_count -end - ----@return uint16_t -function atArray:DataSize() - return SizeOf(self.m_data) -end - ---@return string -function atArray:DataType() +function atArray:GetDataType() local _t = "unknonwn" - if (self.m_data_type and IsInstance(self.m_data_type.__type, "string")) then + if (type(self.m_data_type) == "table" and self.m_data_type.__type) then _t = self.m_data_type.__type end return _F("pointer<%s>", _t) end ----@param i number ----@return pointer -function atArray:Get(i) - self:Update() +---@param i integer +---@return pointer +function atArray:At(i) assert(math.is_inrange(i, 1, self.m_size), "[atArray]: Index out of bounds!") - return self.m_data[i] + return self.m_data[i]:deref() end ----@param i number ----@param v pointer -function atArray:Set(i, v) - self:Update() - assert(math.is_inrange(i, 1, self.m_size), "[atArray]: Index out of bounds!") - assert(IsInstance(v, "pointer"), "[atArray]: Attempt to set array value to non-pointer value!") +---@return uint16_t +function atArray:Size() + return self.m_size +end - self.m_data[i] = v +---@return uint16_t +function atArray:Capacity() + return self.m_capacity end ----@return fun(): integer, pointer Iterator +-- NOTE: As opposed to the `At` method, you must dereference the pointers returned by this iterator. +---@return fun(): integer, pointer_ref Iterator function atArray:Iter() - self:Update() local i = 0 - return function() i = i + 1 - if i <= self.m_size then + if (i <= self.m_size) then return i, self.m_data[i] ---@diagnostic disable-next-line: missing-return end end end +---@return fun(): integer, pointer Iterator function atArray:__pairs() log.warning("[atArray]: Use of pairs! Please use atArray:Iter() instead.") return self:Iter() @@ -216,20 +169,16 @@ end ---@return integer function atArray:__len() - self:Update() return self.m_size end ---@return string function atArray:__tostring() - self:Update() local buffer = "" - local data_type = self:DataType() - + local __type = self:GetDataType() for i, data in self:Iter() do - buffer = buffer .. _F("\n[%d] %s @ 0x%X>", i, data_type, data:get_address()) + buffer = buffer .. _F("\n[%d] %s* @ 0x%X>", i, __type, data:get_address()) end - return buffer end diff --git a/SSV2/includes/classes/gta/fwDrawData.lua b/SSV2/includes/classes/gta/fwDrawData.lua index b061317..9f48531 100644 --- a/SSV2/includes/classes/gta/fwDrawData.lua +++ b/SSV2/includes/classes/gta/fwDrawData.lua @@ -12,7 +12,7 @@ -------------------------------------- ---@class fwDrawData ---@field protected m_ptr pointer ----@field m_stream_render_gfx pointer +---@field m_stream_render_gfx pointer_ref ---@overload fun(ptr: pointer): fwDrawData local fwDrawData = Class("fwDrawData", { pointer_ctor = true, symbolic_size = 0x378 }) diff --git a/SSV2/includes/classes/gta/rlGamerInfo.lua b/SSV2/includes/classes/gta/rlGamerInfo.lua index 97a354e..90aee72 100644 --- a/SSV2/includes/classes/gta/rlGamerInfo.lua +++ b/SSV2/includes/classes/gta/rlGamerInfo.lua @@ -9,6 +9,7 @@ local CStructView = require("includes.classes.gta.CStructView") + ---@class IPAddress ---@field private m_decimal uint32_t ---@field private m_packed vec4 diff --git a/SSV2/includes/data/yrv3_data.lua b/SSV2/includes/data/yrv3_data.lua index 0afd70a..bbf79d4 100644 --- a/SSV2/includes/data/yrv3_data.lua +++ b/SSV2/includes/data/yrv3_data.lua @@ -394,7 +394,7 @@ local RawBusinessData = { SellMissionTunables = { ["CEO"] = { type = "bool", - tuneable = { + tuneables = { "EXEC_DISABLE_SELL_AIRATTACKED", "EXEC_DISABLE_SELL_AIRDROP", "EXEC_DISABLE_SELL_AIRFLYLOW", @@ -415,7 +415,7 @@ local RawBusinessData = { }, ["Biker"] = { type = "bool", - tuneable = { + tuneables = { "BIKER_DISABLE_SELL_CONVOY", "BIKER_DISABLE_SELL_PROVEN", "BIKER_DISABLE_SELL_FRIENDS_IN_NEED", @@ -428,7 +428,7 @@ local RawBusinessData = { }, ["Nightclub"] = { type = "float", - tuneable = { + tuneables = { "BB_SELL_MISSIONS_WEIGHTING_MULTI_DROP", "BB_SELL_MISSIONS_WEIGHTING_HACK_DROP", "BB_SELL_MISSIONS_WEIGHTING_ROADBLOCK", @@ -442,7 +442,7 @@ local RawBusinessData = { }, ["Hangar"] = { type = "float", - tuneable = { + tuneables = { "SMUG_SELL_HEAVY_LIFTING_WEIGHTING", "SMUG_SELL_CONTESTED_WEIGHTING", "SMUG_SELL_AGILE_DELIVERY_WEIGHTING", diff --git a/SSV2/includes/features/CasinoPacino.lua b/SSV2/includes/features/CasinoPacino.lua index 53802ec..cb258df 100644 --- a/SSV2/includes/features/CasinoPacino.lua +++ b/SSV2/includes/features/CasinoPacino.lua @@ -7,11 +7,11 @@ -- * Provide a copy of or a link to the original license (GPL-3.0 or later); see LICENSE.md or . -local SGSL = require("includes.services.SGSL") -local RawBusinessData = require("includes.data.yrv3_data") +local SGSL = require("includes.services.SGSL") +local RawBusinessData = require("includes.data.yrv3_data") ---@enum eCasinoPrize -Enums.eCasinoPrize = { +Enums.eCasinoPrize = { VEHICLE = 1, MYSTERY = 2, CASH = 3, @@ -22,7 +22,7 @@ Enums.eCasinoPrize = { RANDOM = 8, } -local CasinoPrizes = { +local CasinoPrizes = { [Enums.eCasinoPrize.VEHICLE] = { v = 18 }, [Enums.eCasinoPrize.MYSTERY] = { v = 11 }, [Enums.eCasinoPrize.CASH] = { v = 19 }, @@ -32,12 +32,20 @@ local CasinoPrizes = { [Enums.eCasinoPrize.CLOTHING] = { v = 8 }, } +local CardNumToString = { + [0] = _T("CP_CARD_KING"), + [1] = _T("CP_CARD_ACE"), + [11] = _T("CP_CARD_JACK"), + [12] = _T("CP_CARD_QUEEN"), +} + + ---@class CasinoPacino ---@field private m_arcade_prop { coords: vec3, gxt: string } ---@field protected m_thread Thread? ---@field protected m_initialized boolean -local CasinoPacino = {} -CasinoPacino.__index = CasinoPacino +local CasinoPacino = {} +CasinoPacino.__index = CasinoPacino ---@return CasinoPacino function CasinoPacino:init() @@ -91,7 +99,7 @@ function CasinoPacino:GiveWheelPrize(prizeID) local idx = prizeID if (prizeID == Enums.eCasinoPrize.RANDOM) then - math.randomseed(os.time() * 60) + math.randomseed(math.floor(os.time() * 60)) idx = math.random(Enums.eCasinoPrize.VEHICLE, Enums.eCasinoPrize.CLOTHING) end @@ -101,11 +109,40 @@ function CasinoPacino:GiveWheelPrize(prizeID) return end - prize_wheel_win_state:At(prize_wheel_prize):WriteInt(obj.v) prize_wheel_win_state:At(prize_wheel_prize_state):WriteInt(11) end +---@param script_name string +---@param timeout? integer +---@return boolean +function CasinoPacino:TakeControlOfScript(script_name, timeout) + if (not script.is_active(script_name)) then + return false + end + + timeout = timeout or 10000 + local success = true + local timer = Timer.new(timeout) + + Notifier:ShowMessage("Casino Pacino", _F("%s '%s'...", _T("GENERIC_SCRIPT_CONTROL"), script_name)) + while (not LocalPlayer:IsHostOfScript(script_name)) do + if (timer:IsDone()) then + success = false + break + end + + network.force_script_host(script_name) + yield() + end + + if (not success) then + Notifier:ShowError("Casino Pacino", _F("%s '%s'", _T("GENERIC_SCRIPT_CTRL_FAIL"), script_name)) + end + + return success +end + ---@param card_index number function CasinoPacino:GetCardNameFromIndex(card_index) if (card_index == 0) then @@ -113,23 +150,16 @@ function CasinoPacino:GetCardNameFromIndex(card_index) end local card_number = math.fmod(card_index, 13) - local numberCases = { - [0] = _T("CP_CARD_KING"), - [1] = _T("CP_CARD_ACE"), - [11] = _T("CP_CARD_JACK"), - [12] = _T("CP_CARD_QUEEN"), - default = tostring(card_number) - } - local cardName = Match(card_number, numberCases) - local cardSuit = "" - - if card_index >= 1 or card_index <= 13 then + local cardName = CardNumToString[card_number] or tostring(card_number) + local cardSuit = "" + + if (card_index >= 1 or card_index <= 13) then cardSuit = _T("CP_CARD_CLUBS") - elseif card_index >= 14 or card_index <= 26 then + elseif (card_index >= 14 or card_index <= 26) then cardSuit = _T("CP_CARD_DIAMONDS") - elseif card_index >= 27 or card_index <= 39 then + elseif (card_index >= 27 or card_index <= 39) then cardSuit = _T("CP_CARD_HEARTS") - elseif card_index >= 40 or card_index <= 52 then + elseif (card_index >= 40 or card_index <= 52) then cardSuit = _T("CP_CARD_SPADES") end @@ -137,43 +167,23 @@ function CasinoPacino:GetCardNameFromIndex(card_index) end function CasinoPacino:ForceDealerBust() - ThreadManager:Run(function(s) - local player_id = LocalPlayer:GetPlayerID() - local bjc_obj = SGSL:Get(SGSL.data.blackjack_cards) - local btp_obj = SGSL:Get(SGSL.data.blackjack_table_players) - local blackjack_cards = bjc_obj:GetValue() - local blackjack_decks = bjc_obj:GetOffset(1) - local blackjack_table_players = btp_obj:GetValue() - local blackjack_table_players_size = btp_obj:GetOffset(1) - if (not player_id - or not blackjack_cards - or not blackjack_decks - or not blackjack_table_players - or not blackjack_table_players_size - ) then - Notifier:ShowError("Casino Pacino", "Failed to force dealer to bsut! Unable to read script local.") + ThreadManager:Run(function() + if (not script.is_active("three_card_poker")) then return end - local giveupTimer = Timer.new(3e4) - local success = true - Notifier:ShowMessage("Casino Pacino", _T("CP_BLACKJACK_SCRIPT_CONTROL")) - while (not LocalPlayer:IsHostOfScript("blackjack")) do - if (giveupTimer:IsDone()) then - success = false - break - end - - network.force_script_host("blackjack") - s:yield() - end - - if (not success) then - Notifier:ShowError("Casino Pacino", _T("GENERIC_SCRIPT_CTRL_FAIL")) + if (not self:TakeControlOfScript("blackjack")) then return end - local blackjack_table = locals.get_int("blackjack", + local player_id = LocalPlayer:GetID() + local bjc_obj = SGSL:Get(SGSL.data.blackjack_cards) + local btp_obj = SGSL:Get(SGSL.data.blackjack_table_players) + local blackjack_cards = bjc_obj:GetValue() + local blackjack_decks = bjc_obj:GetOffset(1) + local blackjack_table_players = btp_obj:GetValue() + local blackjack_table_players_size = btp_obj:GetOffset(1) + local blackjack_table = locals.get_int("blackjack", blackjack_table_players + 1 + (player_id * blackjack_table_players_size) @@ -184,9 +194,7 @@ function CasinoPacino:ForceDealerBust() return end - local BJCards = ScriptLocal( - blackjack_cards, - "blackjack") + local BJCards = ScriptLocal(blackjack_cards, "blackjack") :At(blackjack_decks) :At(1) :At(blackjack_table * 13) @@ -211,17 +219,13 @@ function CasinoPacino:SetPokerCards(player_id, players_current_table, card_one, local three_card_poker_deck_size = SGSL:Get(SGSL.data.three_card_poker_deck_size):GetValue() local three_card_poker_anti_cheat = tcp_ac_obj:GetValue() local three_card_poker_anti_cheat_deck = tcp_ac_obj:GetOffset(1) - local TCPCards = ScriptLocal( - three_card_poker_cards, - "three_card_poker") + local TCPCards = ScriptLocal(three_card_poker_cards, "three_card_poker") :At(three_card_poker_current_deck) :At(1) :At(players_current_table * three_card_poker_deck_size) :At(2) - local TCPAC = ScriptLocal( - three_card_poker_anti_cheat, - "three_card_poker") + local TCPAC = ScriptLocal(three_card_poker_anti_cheat, "three_card_poker") :At(three_card_poker_anti_cheat_deck) :At(1) :At(1) @@ -242,18 +246,11 @@ function CasinoPacino:ForcePokerCards() return end - local player_id = LocalPlayer:GetPlayerID() - while ((NETWORK.NETWORK_GET_HOST_OF_SCRIPT("three_card_poker", -1, 0) ~= player_id) - and (NETWORK.NETWORK_GET_HOST_OF_SCRIPT("three_card_poker", 0, 0) ~= player_id) - and (NETWORK.NETWORK_GET_HOST_OF_SCRIPT("three_card_poker", 1, 0) ~= player_id) - and (NETWORK.NETWORK_GET_HOST_OF_SCRIPT("three_card_poker", 2, 0) ~= player_id) - and (NETWORK.NETWORK_GET_HOST_OF_SCRIPT("three_card_poker", 3, 0) ~= player_id) - ) do - network.force_script_host("three_card_poker") - Notifier:ShowMessage("CasinoPacino", _T("CP_POKER_SCRIPT_CONTROL")) - sleep(500) + if (not self:TakeControlOfScript("three_card_poker")) then + return end + local player_id = LocalPlayer:GetID() local tcpt_obj = SGSL:Get(SGSL.data.three_card_poker_table) local tcpc_obj = SGSL:Get(SGSL.data.three_card_poker_cards) local three_card_poker_table = tcpt_obj:GetValue() @@ -264,39 +261,39 @@ function CasinoPacino:ForcePokerCards() local TCTable = ScriptLocal(three_card_poker_table, "three_card_poker"):At(1) local players_current_table = TCTable:At(player_id * three_card_poker_table_size):At(2):ReadInt() - if (players_current_table ~= -1) then -- If the player is sitting at a poker table - -- "three_card_poker", (three_card_poker_cards) + (three_card_poker_current_deck) + (1 + (players_current_table * three_card_poker_deck_size)) + (2) + - local PlayerCardLocal = ScriptLocal( - three_card_poker_cards, - "three_card_poker") - :At(three_card_poker_current_deck) - :At(1) - :At(players_current_table * three_card_poker_deck_size) - :At(2) - - local player_0_card_1 = PlayerCardLocal:At(1):At(0 * 3):ReadInt() - local player_0_card_2 = PlayerCardLocal:At(2):At(0 * 3):ReadInt() - local player_0_card_3 = PlayerCardLocal:At(3):At(0 * 3):ReadInt() + if (players_current_table == -1) then + return + end - if (player_0_card_1 ~= 50) or (player_0_card_2 ~= 51) or (player_0_card_3 ~= 52) then - local total_players = 0 + local PlayerCardLocal = ScriptLocal(three_card_poker_cards, "three_card_poker") + :At(three_card_poker_current_deck) + :At(1) + :At(players_current_table * three_card_poker_deck_size) + :At(2) - for player_iter = 0, 31, 1 do - local player_table = TCTable:At(player_iter * three_card_poker_table_size):At(2):ReadInt() - if (player_iter ~= player_id) and (player_table == players_current_table) then - total_players = total_players + 1 - end - end + local player_0_card_1 = PlayerCardLocal:At(1):At(0 * 3):ReadInt() + local player_0_card_2 = PlayerCardLocal:At(2):At(0 * 3):ReadInt() + local player_0_card_3 = PlayerCardLocal:At(3):At(0 * 3):ReadInt() - for playing_player_iter = 0, total_players, 1 do - self:SetPokerCards(playing_player_iter, players_current_table, 50, 51, 52) - end + if (player_0_card_1 == 50 or player_0_card_2 == 51 or player_0_card_3 == 52) then + return + end - if (GVars.features.dunk.set_dealers_poker_cards) then - self:SetPokerCards(total_players + 1, players_current_table, 1, 8, 22) - end + local total_players = 0 + for player_iter = 0, 31, 1 do + local player_table = TCTable:At(player_iter * three_card_poker_table_size):At(2):ReadInt() + if ((player_iter ~= player_id) and (player_table == players_current_table)) then + total_players = total_players + 1 end end + + for playing_player_iter = 0, total_players, 1 do + self:SetPokerCards(playing_player_iter, players_current_table, 50, 51, 52) + end + + if (GVars.features.dunk.set_dealers_poker_cards) then + self:SetPokerCards(total_players + 1, players_current_table, 1, 8, 22) + end end function CasinoPacino:ForceRouletteWheel() @@ -304,26 +301,24 @@ function CasinoPacino:ForceRouletteWheel() return end - local player_id = LocalPlayer:GetPlayerID() + if (not self:TakeControlOfScript("casinoroulette")) then + return + end + local rmt_obj = SGSL:Get(SGSL.data.roulette_master_table) local roulette_master_table = rmt_obj:GetValue() local roulette_outcomes_table = rmt_obj:GetOffset(1) local roulette_ball_table = SGSL:Get(SGSL.data.roulette_ball_table_offset):GetValue() - while (NETWORK.NETWORK_GET_HOST_OF_SCRIPT("casinoroulette", -1, 0) ~= player_id - and NETWORK.NETWORK_GET_HOST_OF_SCRIPT("casinoroulette", 0, 0) ~= player_id - and NETWORK.NETWORK_GET_HOST_OF_SCRIPT("casinoroulette", 1, 0) ~= player_id - and NETWORK.NETWORK_GET_HOST_OF_SCRIPT("casinoroulette", 2, 0) ~= player_id - and NETWORK.NETWORK_GET_HOST_OF_SCRIPT("casinoroulette", 3, 0) ~= player_id - ) do - network.force_script_host("casinoroulette") - Notifier:ShowMessage("CasinoPacino", _T("CP_ROULETTE_SCRIPT_CONTROL")) --If you see this spammed, someone if fighting you for control. - sleep(500) - end - - for tabler_iter = 0, 6, 1 do - locals.set_int("casinoroulette", - (roulette_master_table) + (roulette_outcomes_table) + (roulette_ball_table) + (tabler_iter), 18) + for table_iter = 0, 6, 1 do + locals.set_int( + "casinoroulette", + (roulette_master_table) + + (roulette_outcomes_table) + + (roulette_ball_table) + + (table_iter), + 18 + ) end end @@ -332,16 +327,21 @@ function CasinoPacino:RigSlotMachine() return end - local needs_run = false + local needs_run = false + local rig_enabled = GVars.features.dunk.rig_slot_machine local SlotsResultLocal = SGSL:Get(SGSL.data.slots_random_result_table):AsLocal() - if (GVars.features.dunk.rig_slot_machine) then + if (rig_enabled) then for slots_iter = 3, 196, 1 do - if (slots_iter ~= 67 and slots_iter ~= 132) then - if (SlotsResultLocal:At(slots_iter):ReadInt() ~= 6) then - needs_run = true - end + if (slots_iter == 67 or slots_iter == 132) then + goto continue end + + if (SlotsResultLocal:At(slots_iter):ReadInt() ~= 6) then + needs_run = true + end + + ::continue:: end else local sum = 0 @@ -358,15 +358,19 @@ function CasinoPacino:RigSlotMachine() end for slots_iter = 3, 196, 1 do - if (slots_iter ~= 67 and slots_iter ~= 132) then - local slot_result = 6 - if (not GVars.features.dunk.rig_slot_machine) then - math.randomseed(os.time() + slots_iter) - slot_result = math.random(0, 7) - end + if (slots_iter == 67 or slots_iter == 132) then + goto continue + end - SlotsResultLocal:At(slots_iter):WriteInt(slot_result) + local slot_result = 6 + if (not rig_enabled) then + math.randomseed(os.time() + slots_iter) + slot_result = math.random(0, 7) end + + SlotsResultLocal:At(slots_iter):WriteInt(slot_result) + + ::continue:: end end @@ -407,8 +411,7 @@ function CasinoPacino:GetCooldownString() local chipswon_gd = stats.get_int("MPPLY_CASINO_CHIPS_WON_GD") local max_chip_wins = tunables.get_int("VC_CASINO_CHIP_MAX_WIN_DAILY") - return - (chipswon_gd >= max_chip_wins) + return (chipswon_gd >= max_chip_wins) and _F(_T("CP_COOLDOWN_BYPASS_STATUS_FORMAT"), minutes_left) or _T("CP_COOLDOWN_BYPASS_STATUS_OFF") end @@ -428,38 +431,35 @@ function CasinoPacino:GetBJDealerCard() local blackjack_table = locals.get_int("blackjack", blackjack_table_players + 1 - + (LocalPlayer:GetPlayerID() * blackjack_table_players_size) + + (LocalPlayer:GetID() * blackjack_table_players_size) + 4 ) - if (blackjack_table ~= -1) then - local dealers_card = locals.get_int("blackjack", - blackjack_cards - + blackjack_decks - + 1 - + (blackjack_table * 13) - + 1 - ) - return self:GetCardNameFromIndex(dealers_card) - else + if (blackjack_table == -1) then return _T("CP_NOT_PLAYING_BLACKJACK") end + + local dealers_card = locals.get_int("blackjack", + blackjack_cards + + blackjack_decks + + 1 + + (blackjack_table * 13) + + 1 + ) + return self:GetCardNameFromIndex(dealers_card) end function CasinoPacino:SetCartAutoGrab() - if (not GVars.features.dunk.ch_cart_autograb) then - return - end - - local fmmc_obj = SGSL:Get(SGSL.data.fm_mission_controller_cart_grab) - local fmmc_cg = fmmc_obj:AsLocal() - local fmmc_cg_spd = fmmc_obj:GetOffset(1) - - if (fmmc_cg:ReadInt() == 3) then - fmmc_cg:WriteInt(4) - elseif (fmmc_cg:ReadInt() == 4) then - if (fmmc_cg:At(fmmc_cg_spd):ReadFloat() < 2.0) then - fmmc_cg:At(fmmc_cg_spd):WriteFloat(2.0) + local FMMC_OBJ = SGSL:Get(SGSL.data.fm_mission_controller_cart_grab) + local SceneLocal = FMMC_OBJ:AsLocal() + local PlaybackRate = FMMC_OBJ:GetOffset(1) + local SceneState = SceneLocal:ReadInt() + + if (SceneState == 3) then + SceneLocal:WriteInt(4) + elseif (SceneState == 4) then + if (SceneLocal:At(PlaybackRate):ReadFloat() < 2.0) then + SceneLocal:At(PlaybackRate):WriteFloat(2.0) end end end @@ -492,9 +492,9 @@ function CasinoPacino:Main() self:RigSlotMachine() self:AutoPlaySlots() - if (script.is_active("fm_mission_controller")) then + if (script.is_active("fm_mission_controller") and GVars.features.dunk.ch_cart_autograb) then self:SetCartAutoGrab() end end -return CasinoPacino +return CasinoPacino:init() diff --git a/SSV2/includes/features/EntityForge.lua b/SSV2/includes/features/EntityForge.lua index 3d47d60..cf7ec28 100644 --- a/SSV2/includes/features/EntityForge.lua +++ b/SSV2/includes/features/EntityForge.lua @@ -77,7 +77,7 @@ function EntityForge:init() return end - PLAYER.DISABLE_PLAYER_FIRING(LocalPlayer:GetPlayerID(), true) + PLAYER.DISABLE_PLAYER_FIRING(LocalPlayer:GetID(), true) instance:EntityGun() end) @@ -346,7 +346,7 @@ end -- Grabs and manipulates world entities. function EntityForge:EntityGun() - if (not PLAYER.IS_PLAYER_FREE_AIMING(LocalPlayer:GetPlayerID())) then + if (not PLAYER.IS_PLAYER_FREE_AIMING(LocalPlayer:GetID())) then if (self.GrabbedEntity) then ENTITY.SET_ENTITY_COLLISION(self.GrabbedEntity.m_handle, true, true) end diff --git a/SSV2/includes/features/Mastermind.lua b/SSV2/includes/features/Mastermind.lua index f0dcfb4..54e9099 100644 --- a/SSV2/includes/features/Mastermind.lua +++ b/SSV2/includes/features/Mastermind.lua @@ -111,7 +111,7 @@ local function getServiceVehicleCoords() local vec_offset = 13 local final = ser_veh_global:AsGlobal() - :At(LocalPlayer:GetPlayerID(), pid_size) + :At(LocalPlayer:GetID(), pid_size) :At(offset2) :At(vec_offset) @@ -125,7 +125,7 @@ local function isSubmarineSpawned() local offset2 = sub_global:GetOffset(2) local sub_offset = 4 local sub_status = sub_global:AsGlobal() - :At(LocalPlayer:GetPlayerID(), pid_size) + :At(LocalPlayer:GetID(), pid_size) :At(offset2) :At(sub_offset) :ReadInt() @@ -173,9 +173,9 @@ function Mastermind:ReadPropertyData() local sub_hash = stats.get_int("MPX_IH_SUB_OWNED") if (sub_hash == _J("kosatka")) then self.m_properties.submarine = { - name = Game.GetGXTLabel("CELL_SUBMARINE"), - coords = vec3:zero(), - heading = 0.0, + name = Game.GetGXTLabel("CELL_SUBMARINE"), + coords = vec3:zero(), + heading = 0.0, is_spawned = isSubmarineSpawned() } end diff --git a/SSV2/includes/features/YimActionsV3.lua b/SSV2/includes/features/YimActionsV3.lua index 4eb9f15..b3a8502 100644 --- a/SSV2/includes/features/YimActionsV3.lua +++ b/SSV2/includes/features/YimActionsV3.lua @@ -7,12 +7,13 @@ -- * Provide a copy of or a link to the original license (GPL-3.0 or later); see LICENSE.md or . -local SceneManager = require("includes.services.SceneManager") -local CompanionManager = require("includes.services.CompanionManager") -local t_AnimList = require("includes.data.actions.animations") -local t_PedScenarios = require("includes.data.actions.scenarios") -local Action = require("includes.structs.Action") -local Weapons = require("includes.data.weapons") +local SceneManager = require("includes.services.SceneManager") +local CompanionManager = require("includes.services.CompanionManager") +local t_AnimList = require("includes.data.actions.animations") +local t_PedScenarios = require("includes.data.actions.scenarios") +local Action = require("includes.structs.Action") +local Weapons = require("includes.data.weapons") +local COL_YELLOW = Color("yellow") ---@alias ActionCategory --- | "anims" @@ -1283,10 +1284,10 @@ function YimActions.Debugger:Draw() ImGui.BeginChild("##debugPropInfo", 250, 200) ImGui.SeparatorText("Prop Info") if (not self.selectedProp) then - GUI:Text("Not Selected.", Color("yellow")) + GUI:Text("Not Selected.", { color = COL_YELLOW }) else - ImGui.BulletText(("Prop Type: [ %s ]"):format(self.selectedProp.type)) - ImGui.BulletText(("Is Attached: [ %s ]"):format(self.selectedProp.attached)) + ImGui.BulletText(_F("Prop Type: [ %s ]", self.selectedProp.type)) + ImGui.BulletText(_F("Is Attached: [ %s ]", self.selectedProp.attached)) end ImGui.EndChild() ImGui.EndGroup() diff --git a/SSV2/includes/features/YimResupplierV3.lua b/SSV2/includes/features/YimResupplierV3.lua index b69c79d..0c52885 100644 --- a/SSV2/includes/features/YimResupplierV3.lua +++ b/SSV2/includes/features/YimResupplierV3.lua @@ -234,7 +234,7 @@ function YRV3:GetSalvageYard() return self.m_businesses.salvage_yard end ----@return table +---@return dict<{ type: "float"|"bool", tuneables: array }> function YRV3:GetSaleMissionTunables() return self.m_raw_data.SellMissionTunables end diff --git a/SSV2/includes/features/self/laser_sights.lua b/SSV2/includes/features/self/laser_sights.lua index 1863728..75efe39 100644 --- a/SSV2/includes/features/self/laser_sights.lua +++ b/SSV2/includes/features/self/laser_sights.lua @@ -49,7 +49,7 @@ function LaserSights:Init() GVars.features.weapon.laser_sights.keybind, function() ThreadManager:Run(function() - if (not PLAYER.IS_PLAYER_FREE_AIMING(LocalPlayer:GetPlayerID())) then + if (not PLAYER.IS_PLAYER_FREE_AIMING(LocalPlayer:GetID())) then return end @@ -71,7 +71,7 @@ function LaserSights:ShouldRun() and LocalPlayer:IsAlive() and LocalPlayer:IsOnFoot() and WEAPON.IS_PED_ARMED(LocalPlayer:GetHandle(), 4) - and PLAYER.IS_PLAYER_FREE_AIMING(LocalPlayer:GetPlayerID()) + and PLAYER.IS_PLAYER_FREE_AIMING(LocalPlayer:GetID()) end ---@param startPos vec3 diff --git a/SSV2/includes/features/self/magic_bullet.lua b/SSV2/includes/features/self/magic_bullet.lua index 286a3f4..cc7d94f 100644 --- a/SSV2/includes/features/self/magic_bullet.lua +++ b/SSV2/includes/features/self/magic_bullet.lua @@ -42,7 +42,7 @@ function MagicBullet:Update() return end - if PLAYER.IS_PLAYER_FREE_AIMING(LocalPlayer:GetPlayerID()) then + if PLAYER.IS_PLAYER_FREE_AIMING(LocalPlayer:GetID()) then local entity = LocalPlayer:GetEntityInCrosshairs(false) if (entity and ENTITY.IS_ENTITY_A_PED(entity) and PED.IS_PED_HUMAN(entity)) then if (entity ~= 0) then diff --git a/SSV2/includes/features/vehicle/drift_mode.lua b/SSV2/includes/features/vehicle/drift_mode.lua index a094a88..6cfdaaa 100644 --- a/SSV2/includes/features/vehicle/drift_mode.lua +++ b/SSV2/includes/features/vehicle/drift_mode.lua @@ -8,6 +8,7 @@ local FeatureBase = require("includes.modules.FeatureBase") +local CWheel = require("includes.classes.gta.CWheel") ---@class DriftMode : FeatureBase ---@field private m_entity PlayerVehicle -- Reference to PlayerVehicle @@ -158,9 +159,9 @@ end -- 4 -- ) --- for i, wheel in wheels:Iter() do --- local cwheel = CWheel(wheel) --- if (not cwheel) then +-- for i, pWheel in wheels:Iter() do +-- local cwheel = CWheel(pWheel:deref()) +-- if (not cwheel or not cwheel:IsValid()) then -- goto continue -- end @@ -169,9 +170,9 @@ end -- local drag_co = cwheel.m_tire_drag_coeff:get_float() -- local rot_spd = cwheel.m_rotation_speed:get_float() -- local top_spd_mult = cwheel.m_top_speed_mult:get_float() --- local is_full_thottle = cwheel:GetWheelFlag(Enums.eWheelFlags.FULL_THROTTLE) --- local is_cheat_tc = cwheel:GetWheelFlag(Enums.eWheelFlags.CHEAT_TC) --- local is_cheat_sc = cwheel:GetWheelFlag(Enums.eWheelFlags.CHEAT_SC) +-- local is_full_thottle = cwheel:GetDynamicFlag(Enums.eWheelDynamicFlags.FULL_THROTTLE) +-- local is_cheat_tc = cwheel:GetDynamicFlag(Enums.eWheelDynamicFlags.CHEAT_TC) +-- local is_cheat_sc = cwheel:GetDynamicFlag(Enums.eWheelDynamicFlags.CHEAT_SC) -- local is_driven = cwheel:GetConfigFlag(Enums.eWheelConfigFlags.POWERED) -- local wheel_txt = _F( -- "- %d: Power: %.3f | Brake: %.3f | Drag: %.3f | Rotation: %.3f | Speed Mult: %.3f", diff --git a/SSV2/includes/features/vehicle/stancer.lua b/SSV2/includes/features/vehicle/stancer.lua index 92395e8..b28a6cd 100644 --- a/SSV2/includes/features/vehicle/stancer.lua +++ b/SSV2/includes/features/vehicle/stancer.lua @@ -164,8 +164,16 @@ function Stancer:Init() m_last_seen = 0.0 } + self:ResetDeltas() + if (self.m_entity:IsValid()) then + local handle = self.m_entity:GetHandle() + if (not Decorator:IsEntityRegistered(handle)) then + Decorator:Register(handle, "Stancer", true) + end + self:ReadWheelArray() + self:ReadDefaults() self.m_cached_model = self.m_entity:GetModelHash() self.m_last_wheels_mod = self.m_entity:GetCustomWheels() end @@ -178,39 +186,43 @@ end ---@return boolean function Stancer:CanApplyDrawData() return self.m_entity and self.m_entity:HasWheelDrawData() + and self.m_last_wheels_mod and self.m_last_wheels_mod.index ~= -1 end function Stancer:Reset() - self.m_suspension_height.m_current = 0.0 - self.m_suspension_height.m_last_seen = 0.0 + self:ReadWheelArray() + self:ResetDeltas() - if (not self.m_wheels) then + if not (self.m_entity and self.m_entity:IsValid()) then return end + self.m_entity:SetRideHeight(0.0) + local handle = self.m_entity:GetHandle() + if (not Decorator:IsEntityRegistered(handle)) then + return + end + + local visual_size = Decorator:GetDecor(handle, "m_visual_size") + local visual_width = Decorator:GetDecor(handle, "m_visual_width") + if (visual_size and visual_size > 0) then + self.m_entity:SetVisualWheelSize(visual_size) + end + + if (visual_width and visual_width > 0) then + self.m_entity:SetVisualWheelWidth(visual_width) + end + for _, v in ipairs(self.decorators) do - self.m_deltas[v.wheel_side][v.key] = 0.0 local wheel_array = self:GetAllWheelsForSide(v.wheel_side) self:ForEach(wheel_array, function(i, cwheel) local decor_key = _F("%s_%d_%d", v.key, v.wheel_side, i) - local default = Decorator:GetDecor(self.m_entity:GetHandle(), decor_key) + local default = Decorator:GetDecor(handle, decor_key) if (type(default) == "number") then v.write_func(cwheel, default, self.m_entity) end end) end - - if (self.m_entity and self.m_entity:IsValid()) then - self.m_entity:SetRideHeight(0.0) - local visual_size = Decorator:GetDecor(self.m_entity:GetHandle(), "m_visual_size") - local visual_width = Decorator:GetDecor(self.m_entity:GetHandle(), "m_visual_width") - if (visual_size and visual_size > 0) then - self.m_entity:SetVisualWheelSize(visual_size) - end - if (visual_width and visual_width > 0) then - self.m_entity:SetVisualWheelWidth(visual_width) - end - end end function Stancer:Cleanup() @@ -219,41 +231,36 @@ function Stancer:Cleanup() self.m_cached_model = nil end -function Stancer:ResetDeltas() - for _, v in pairs(self.decorators) do - self.m_deltas[self.eWheelSide.FRONT][v.key] = 0.0 - self.m_deltas[self.eWheelSide.BACK][v.key] = 0.0 - end -end - -- Main entry function Stancer:OnNewVehicle() - self.m_reloading = true - self:ResetDeltas() - - if (not self.m_entity or not self.m_entity:IsValid()) then - self.m_reloading = false + if (not self.m_entity:IsValid()) then return end - self.m_cached_model = self.m_entity:GetModelHash() - self.m_last_wheels_mod = self.m_entity:GetCustomWheels() + self.m_reloading = true + + local handle = self.m_entity:GetHandle() + if (not Decorator:IsEntityRegistered(handle)) then + Decorator:Register(handle, "Stancer", true) + end + self.m_cached_model = self.m_entity:GetModelHash() + self:ResetDeltas() self:ReadWheelArray() self:ReadDefaults() + self.m_reloading = false end ----@param wheelIndex integer +---@param wheel CWheel ---@param value number ---@return number -function Stancer:GetValueByWheelIndex(wheelIndex, value) - -- this is not flipped. default values are referenced from the first wheel per side (front/back) - return wheelIndex == 1 and value or -value +function Stancer:GetValueBySideLR(wheel, value) + return wheel:IsLeftWheel() and value or -value end ---@param array array? ----@param fn function +---@param fn fun(i: integer, cwheel: CWheel) function Stancer:ForEach(array, fn) if (not array or #array == 0) then return @@ -274,33 +281,14 @@ function Stancer:IsVehicleModelSaved() return GVars.features.vehicle.stancer.saved_models[tostring(self.m_entity:GetModelHash())] ~= nil end -function Stancer:ReadWheelArray() - self.m_wheels = { - [self.eWheelSide.FRONT] = {}, - [self.eWheelSide.BACK] = {} - } - - local wheel_array = self.m_entity:Resolve().m_wheels - local wheel_count = self.m_entity:GetNumberOfWheels() - if (wheel_count == 2) then - table.insert(self.m_wheels[self.eWheelSide.FRONT], CWheel(wheel_array:Get(1))) - table.insert(self.m_wheels[self.eWheelSide.BACK], CWheel(wheel_array:Get(2))) - else - -- I don't think there are any "cars" in GTA with more or less than 2 front wheels - local front_count = 2 - local back_count = wheel_count - front_count - for i = 1, front_count do - self.m_wheels[self.eWheelSide.FRONT][i] = CWheel(wheel_array:Get(i)) - end - - if (back_count == 1) then -- I think there's one vehicle with just one back wheel. I have the memory of a goldfish so I can't remember - self.m_wheels[self.eWheelSide.BACK][1] = CWheel(wheel_array:Get(3)) - else - for i = 1, back_count do - self.m_wheels[self.eWheelSide.BACK][i] = CWheel(wheel_array:Get(i + front_count)) - end - end +function Stancer:ResetDeltas() + for _, v in ipairs(self.decorators) do + self.m_deltas[self.eWheelSide.FRONT][v.key] = 0.0 + self.m_deltas[self.eWheelSide.BACK][v.key] = 0.0 end + + self.m_suspension_height.m_current = 0.0 + self.m_suspension_height.m_last_seen = 0.0 end ---@return table> @@ -374,6 +362,7 @@ function Stancer:OnWheelsChanged() for k, v in pairs(prev_deltas_f) do self.m_deltas[self.eWheelSide.FRONT][k] = v end + for k, v in pairs(prev_deltas_r) do self.m_deltas[self.eWheelSide.BACK][k] = v end @@ -404,39 +393,15 @@ function Stancer:AreSavedDeltasLoaded() return false end - local front_match = true - local rear_match = true for k, v in pairs(self.m_deltas[self.eWheelSide.FRONT]) do if (not math.is_equal(v, front_obj[k])) then - front_match = false - break + return false end end for k, v in pairs(self.m_deltas[self.eWheelSide.BACK]) do if (not math.is_equal(v, rear_obj[k])) then - rear_match = false - break - end - end - - return front_match and rear_match -end - ----@return boolean -function Stancer:AreDefaultsRegistered() - if (not self.m_wheels) then - return false - end - - local handle = self.m_entity:GetHandle() - for _, v in ipairs(self.decorators) do - local wheel_array = self:GetAllWheelsForSide(v.wheel_side) - for i = 1, #wheel_array do - local decor = _F("%s_%d_%d", v.key, v.wheel_side, i) - if (not Decorator:ExistsOn(handle, decor)) then - return false - end + return false end end @@ -485,71 +450,83 @@ function Stancer:SaveCurrentVehicle() saved[strModel][self.eWheelSide.FRONT]["m_suspension_height"] = self.m_suspension_height.m_current end ----@return boolean function Stancer:RestoreQueueFromDecors() if (self:IsVehicleModelSaved() and GVars.features.vehicle.stancer.auto_apply_saved) then - self:LoadSavedDeltas() - return true - end - - return false - -- local handle = self.m_entity:GetHandle() - -- if (not Decorator:IsEntityRegistered(handle)) then - -- return false - -- end - - -- local success = true - -- for _, v in ipairs(self.decorators) do - -- local queued_key = _F("%s_%d_queue", v.key, v.wheel_side) - -- local val = Decorator:GetDecor(handle, queued_key) - -- if (type(val) ~= "number") then - -- success = false - -- else - -- self.m_deltas[v.wheel_side][v.key] = val - -- end - -- end - - -- local suspension = Decorator:GetDecor(handle, "m_suspension_height_q") - -- if (type(suspension) ~= "number") then - -- return false - -- end - - -- self.m_suspension_height.m_current = suspension - -- return success -end + return self:LoadSavedDeltas() + end -function Stancer:ReadDefaults() - if (not self.m_entity:IsValid() or not self.m_entity:IsCar()) then + local handle = self.m_entity:GetHandle() + if (not Decorator:IsEntityRegistered(handle)) then return end - local queued_decors_loaded = self:RestoreQueueFromDecors() - if (self:AreDefaultsRegistered()) then + for _, v in ipairs(self.decorators) do + local queued_key = _F("%s_%d_queue", v.key, v.wheel_side) + local val = Decorator:GetDecor(handle, queued_key) + if (type(val) == "number") then + self.m_deltas[v.wheel_side][v.key] = val + end + end + + local suspension = Decorator:GetDecor(handle, "m_suspension_height_q") + if (type(suspension) == "number") then + self.m_suspension_height.m_current = suspension + end +end + +function Stancer:ReadWheelArray() + self.m_wheels = { + [self.eWheelSide.FRONT] = {}, + [self.eWheelSide.BACK] = {} + } + + if (not self.m_entity or not self.m_entity:IsValid()) then return end - local handle = self.m_entity:GetHandle() - for _, v in ipairs(self.decorators) do - local read_func = v.read_func - local wheel_array = self:GetAllWheelsForSide(v.wheel_side) - local visual_size = self.m_entity:GetVisualWheelSize() - local visual_width = self.m_entity:GetVisualWheelWidth() + local wheel_array = self.m_entity:Resolve().m_wheels + local wheel_count = wheel_array:Size() + for i = 1, wheel_count do + local cwheel = CWheel(wheel_array:At(i)) + if (not cwheel or not cwheel:IsValid()) then + goto continue + end - Decorator:Register(handle, "m_visual_size", visual_size) - Decorator:Register(handle, "m_visual_width", visual_width) + if (cwheel:IsRearWheel()) then + table.insert(self.m_wheels[self.eWheelSide.BACK], cwheel) + else + table.insert(self.m_wheels[self.eWheelSide.FRONT], cwheel) + end - self:ForEach(wheel_array, function(i, cwheel) - local default_val = read_func(cwheel) - local wheel_key = _F("%s_%d_%d", v.key, v.wheel_side, i) + ::continue:: + end +end - Decorator:Register(handle, wheel_key, default_val) +function Stancer:ReadDefaults() + if (not self.m_entity:IsValid() or not self.m_entity:IsCar()) then + return + end + + self:RestoreQueueFromDecors() + local handle = self.m_entity:GetHandle() + local visual_size = self.m_entity:GetVisualWheelSize() + local visual_width = self.m_entity:GetVisualWheelWidth() + Decorator:Register(handle, "m_visual_size", visual_size) + Decorator:Register(handle, "m_visual_width", visual_width) + + for _, v in ipairs(self.decorators) do + local wheel_array = self:GetAllWheelsForSide(v.wheel_side) + self:ForEach(wheel_array, function(i, cwheel) + local decor = _F("%s_%d_%d", v.key, v.wheel_side, i) + local existsOn = Decorator:ExistsOn(handle, decor) + local default_val = existsOn and Decorator:GetDecor(handle, decor) or v.read_func(cwheel) + if (not existsOn) then + Decorator:Register(handle, decor, default_val) + end - -- our values are based on the first wheel per axle - if (i % 2 == 1) then + -- our base values are based on left wheels per axle + if (cwheel:IsLeftWheel()) then self.m_base_values[v.wheel_side][v.key] = default_val - if (not queued_decors_loaded) then - self.m_deltas[v.wheel_side][v.key] = 0.0 - end end end) end @@ -618,12 +595,6 @@ function Stancer:Update() return end - -- thanks for making me reload this slow ass game 15 times. - -- here's a guard dog - if (not self:AreDefaultsRegistered()) then - return - end - self:OnWheelsChanged() self:UpdateBounceMode() @@ -641,20 +612,21 @@ function Stancer:Update() end for _, v in ipairs(self.decorators) do - local delta_val = self.m_deltas[v.wheel_side][v.key] - -- local pending_key = _F("%s_%d_queue", v.key, v.wheel_side) - -- local pending_val = Decorator:GetDecor(handle, pending_key) - -- if (pending_val and not math.is_equal(pending_val, delta_val)) then - -- Decorator:UpdateDecor(handle, pending_key, delta_val) - -- end - local wheel_array = self:GetAllWheelsForSide(v.wheel_side) - local base_val = self.m_base_values[v.wheel_side][v.key] - self:ForEach(wheel_array, function(i, cwheel) - local desired = v.side_dont_care and base_val + delta_val or - self:GetValueByWheelIndex(i, base_val + delta_val) + local delta = self.m_deltas[v.wheel_side][v.key] + local base = self.m_base_values[v.wheel_side][v.key] + local sum = base + delta + local queued_key = _F("%s_%d_queue", v.key, v.wheel_side) + if (Decorator:ExistsOn(handle, queued_key)) then + Decorator:UpdateDecor(handle, queued_key, delta) + else + Decorator:Register(handle, queued_key, delta) + end - if (math.abs(desired) ~= math.abs(v.read_func(cwheel))) then + self:ForEach(wheel_array, function(_, cwheel) + local current = v.read_func(cwheel) + local desired = v.side_dont_care and sum or self:GetValueBySideLR(cwheel, sum) + if (math.abs(desired) ~= math.abs(current)) then v.write_func(cwheel, desired, self.m_entity) end end) diff --git a/SSV2/includes/features/world/HideNSeek.lua b/SSV2/includes/features/world/HideNSeek.lua index 00f0da9..fc69342 100644 --- a/SSV2/includes/features/world/HideNSeek.lua +++ b/SSV2/includes/features/world/HideNSeek.lua @@ -111,7 +111,7 @@ function HideNSeek:Cleanup() local pedHandle = LocalPlayer:GetHandle() TASK.CLEAR_PED_TASKS(pedHandle) - PLAYER.RESET_WANTED_LEVEL_DIFFICULTY(LocalPlayer:GetPlayerID()) + PLAYER.RESET_WANTED_LEVEL_DIFFICULTY(LocalPlayer:GetID()) if (ENTITY.IS_ENTITY_ATTACHED(pedHandle)) then ENTITY.DETACH_ENTITY(pedHandle, true, false) end @@ -525,19 +525,19 @@ function HideNSeek:WhileHiding() if (self.m_context == eHNSContext.IN_VEHICLE and not ENTITY.DOES_ENTITY_EXIST(LocalPlayer:GetVehicleNative())) then self:Cleanup() LocalPlayer:ClearTasks() - PLAYER.RESET_WANTED_LEVEL_DIFFICULTY(LocalPlayer:GetPlayerID()) + PLAYER.RESET_WANTED_LEVEL_DIFFICULTY(LocalPlayer:GetID()) end if (self.m_context == eHNSContext.CAR_BOOT and not ENTITY.DOES_ENTITY_EXIST(self.m_boot_vehicle.m_handle)) then self:Cleanup() LocalPlayer:ClearTasks() - PLAYER.RESET_WANTED_LEVEL_DIFFICULTY(LocalPlayer:GetPlayerID()) + PLAYER.RESET_WANTED_LEVEL_DIFFICULTY(LocalPlayer:GetID()) end if (self.m_context == eHNSContext.TRASH and not ENTITY.DOES_ENTITY_EXIST(self.m_trash_bin)) then self:Cleanup() LocalPlayer:ClearTasks() - PLAYER.RESET_WANTED_LEVEL_DIFFICULTY(LocalPlayer:GetPlayerID()) + PLAYER.RESET_WANTED_LEVEL_DIFFICULTY(LocalPlayer:GetID()) end if (not v_WantedCentrePos) then @@ -552,7 +552,7 @@ function HideNSeek:WhileHiding() if (self.m_is_wanted and not self.m_was_spotted) then PED.SET_COP_PERCEPTION_OVERRIDES(0.1, 0.1, 0.1, 1.0, 1.0, 1.0, 0.0) ---@diagnostic disable-next-line - PLAYER.SET_PLAYER_WANTED_CENTRE_POSITION(LocalPlayer:GetPlayerID(), v_WantedCentrePos, true) + PLAYER.SET_PLAYER_WANTED_CENTRE_POSITION(LocalPlayer:GetID(), v_WantedCentrePos, true) end if (self.m_context == eHNSContext.IN_VEHICLE) then @@ -705,8 +705,8 @@ function HideNSeek:OnTick() return end - self.m_is_wanted = PLAYER.GET_PLAYER_WANTED_LEVEL(LocalPlayer:GetPlayerID()) > 0 - self.m_was_spotted = PLAYER.IS_WANTED_AND_HAS_BEEN_SEEN_BY_COPS(LocalPlayer:GetPlayerID()) + self.m_is_wanted = PLAYER.GET_PLAYER_WANTED_LEVEL(LocalPlayer:GetID()) > 0 + self.m_was_spotted = PLAYER.IS_WANTED_AND_HAS_BEEN_SEEN_BY_COPS(LocalPlayer:GetID()) if (not self.m_is_active) then self:GetHidingContext() else diff --git a/SSV2/includes/frontend/casino_ui.lua b/SSV2/includes/frontend/casino_ui.lua index 509ec98..49a4850 100644 --- a/SSV2/includes/frontend/casino_ui.lua +++ b/SSV2/includes/frontend/casino_ui.lua @@ -7,9 +7,10 @@ -- * Provide a copy of or a link to the original license (GPL-3.0 or later); see LICENSE.md or . -local CasinoPacino = require("includes.features.CasinoPacino"):init() -local SGSL = require("includes.services.SGSL") -local casino_pos = vec3:new(924.6380, 46.6918, 81.1063) +local CasinoPacino = require("includes.features.CasinoPacino") +local SGSL = require("includes.services.SGSL") +local casino_pos = vec3:new(924.6380, 46.6918, 81.1063) +local COL_RED = Color("#AA0000") local function drawGamblingTab() if (GUI:Button(_T("CP_TP_CASINO"))) then @@ -26,7 +27,7 @@ local function drawGamblingTab() GVars.features.dunk.bypass_casino_bans, _ = GUI:CustomToggle(_T("CP_COOLDOWN_BYPASS_ENABLE"), GVars.features.dunk.bypass_casino_bans, { tooltip = _T("CP_COOLDOWN_BYPASS_TOOLTIP"), - color = Color("#AA0000") + color = COL_RED }) ImGui.BulletText(_T("CP_COOLDOWN_BYPASS_STATUS")) diff --git a/SSV2/includes/frontend/settings/debug_ui.lua b/SSV2/includes/frontend/settings/debug_ui.lua index ea0e18e..6c5b1ae 100644 --- a/SSV2/includes/frontend/settings/debug_ui.lua +++ b/SSV2/includes/frontend/settings/debug_ui.lua @@ -396,7 +396,7 @@ local function DrawSerializerDebug() ImGui.BulletText("Thread State:") ImGui.SameLine() - GUI:Text(EnumToString(eThreadState, eState), state_colors[eState]) + GUI:Text(EnumToString(eThreadState, eState), { color = state_colors[eState] }) ImGui.BulletText(_F("Is Disabled: %s", not Serializer:CanAccess())) ImGui.BulletText(_F("Time Since Last Flush: %.0f seconds ago.", Serializer:GetTimeSinceLastFlush() / 1e3)) diff --git a/SSV2/includes/frontend/settings/keybinds_ui.lua b/SSV2/includes/frontend/settings/keybinds_ui.lua index e2736d5..2c9e8e3 100644 --- a/SSV2/includes/frontend/settings/keybinds_ui.lua +++ b/SSV2/includes/frontend/settings/keybinds_ui.lua @@ -12,6 +12,7 @@ local ReservedKeys = { gpad = Set.new(23, 24, 25, 71, 75) } +local COL_RED = Color("red") local NoUnbindKeys = Set.new("gui_toggle") local DefaultConfig = Serializer:GetDefaultConfig() local keyName, keyCode @@ -168,7 +169,7 @@ local function DrawKeybind(gvarKey, isController) _reserved = reserved_set:Contains(keyCode) if (_reserved) then - GUI:Text(_T("SETTINGS_HOTKEY_RESERVED"), { color = Color("red"), alpha = 0.86, wrap_pos = winSize.x }) + GUI:Text(_T("SETTINGS_HOTKEY_RESERVED"), { color = COL_RED, alpha = 0.86 }) else local valueBarSize = vec2:new(button_size.x, ImGui.GetTextLineHeightWithSpacing()) ImGui.Text(_T("SETTINGS_HOTKEY_FOUND")) diff --git a/SSV2/includes/frontend/vehicle/stancer_ui.lua b/SSV2/includes/frontend/vehicle/stancer_ui.lua index 7568107..9dcaedb 100644 --- a/SSV2/includes/frontend/vehicle/stancer_ui.lua +++ b/SSV2/includes/frontend/vehicle/stancer_ui.lua @@ -248,7 +248,7 @@ return function() ImGui.Separator() - if (GUI:Button(_T("GENERIC_RESET"))) then + if (GUI:Button(_T("GENERIC_RESET_ALL"))) then ThreadManager:Run(function() Stancer:Reset() if (not PV:IsValid()) then return end diff --git a/SSV2/includes/frontend/yav3_ui.lua b/SSV2/includes/frontend/yav3_ui.lua index 5b2b822..6d0556b 100644 --- a/SSV2/includes/frontend/yav3_ui.lua +++ b/SSV2/includes/frontend/yav3_ui.lua @@ -868,9 +868,9 @@ local function DrawJsonMovementClipsets() if (#t_MovementClipsetsJson == 0) then local exists = io.exists("movementClipsetsCompact.json") if not exists then - ImGui.TextWrapped("You must download the clipsets Json file and save it to the 'scripts_config' folder.") + ImGui.TextWrapped("You must download the clipsets Json file and save it to the 'scripts_config/samurais_scripts' folder.") ImGui.SetWindowFontScale(0.8) - GUI:Text(s_MovementClipsetsGitHub, Color(s_GitHubLinkColor)) + GUI:Text(s_MovementClipsetsGitHub, { color = Color(s_GitHubLinkColor) }) ImGui.SetWindowFontScale(1.0) GUI:Tooltip("Right click to copy the link.") diff --git a/SSV2/includes/frontend/yim_resupplier/basic_business.lua b/SSV2/includes/frontend/yim_resupplier/basic_business.lua index 40e1f34..e18abf5 100644 --- a/SSV2/includes/frontend/yim_resupplier/basic_business.lua +++ b/SSV2/includes/frontend/yim_resupplier/basic_business.lua @@ -7,7 +7,9 @@ -- * Provide a copy of or a link to the original license (GPL-3.0 or later); see LICENSE.md or . local drawCashSafeLoopToggle = require("includes.frontend.yim_resupplier.cashloop_toggle") -local colMoneyGreen = Color("#85BB65") +local colMoneyGreen = Color("#85BB65") +local U32_RED = Color("red"):AsU32() +local U32_GREEN = colMoneyGreen:Darken(0.12):AsU32() ---@param business CarWash|CarWashSubBusiness ---@param isParent boolean @@ -70,8 +72,8 @@ return function(business, isParent, kvSpacing, clearHeatLabel) ImGuiValueBarFlags.MULTI_VAL, { value2 = duffDirtyCash / maxDuffle, - v1Col = colMoneyGreen:Darken(0.12):AsU32(), - v2Col = Color("red"):AsU32(), + v1Col = U32_GREEN, + v2Col = U32_RED, fmt = duffCashTxt } ) diff --git a/SSV2/includes/frontend/yim_resupplier/factory.lua b/SSV2/includes/frontend/yim_resupplier/factory.lua index c412e8e..c3fa016 100644 --- a/SSV2/includes/frontend/yim_resupplier/factory.lua +++ b/SSV2/includes/frontend/yim_resupplier/factory.lua @@ -9,6 +9,8 @@ local measureBulletWidths = require("includes.frontend.helpers.measure_text_width") local colMoneyGreen = Color("#85BB65") +local COL_RED = Color("red") +local COL_GREEN = Color("green") ---@type array local bulletWidths = {} @@ -49,8 +51,10 @@ return function(bb, notOwnedLabel) local supplies = bb:GetSuppliesCount() local stock = bb:GetProductCount() local totalValue = bb:GetProductValue() - local eqLabelCol = updgrade1 and "green" or "red" - local staffLabelCol = updgrade2 and "green" or "red" + local eqLabel = updgrade1 and "GENERIC_ACTIVE" or "GENERIC_INACTIVE" + local eqLabelCol = updgrade1 and COL_GREEN or COL_RED + local staffLabel = updgrade2 and "GENERIC_ACTIVE" or "GENERIC_INACTIVE" + local staffLabelCol = updgrade2 and COL_GREEN or COL_RED local maxUnits = bb:GetMaxUnits() local index = bb:GetIndex() or -1 @@ -77,12 +81,12 @@ return function(bb, notOwnedLabel) ImGui.BulletText(_T("YRV3_EQUIP_UPGDRADE")) ImGui.SameLine(bulletWidth) - GUI:Text(updgrade1 and _T("GENERIC_ACTIVE") or _T("GENERIC_INACTIVE"), { color = Color(eqLabelCol) }) + GUI:Text(_T(eqLabel), { color = eqLabelCol }) if (index < 6) then ImGui.BulletText(_T("YRV3_STAFF_UPGDRADE")) ImGui.SameLine(bulletWidth) - GUI:Text(updgrade2 and _T("GENERIC_ACTIVE") or _T("GENERIC_INACTIVE"), { color = Color(staffLabelCol) }) + GUI:Text(_T(staffLabel), { color = staffLabelCol }) end ImGui.BulletText(_T("YRV3_SUPPLIES_LABEL")) diff --git a/SSV2/includes/frontend/yim_resupplier/misc.lua b/SSV2/includes/frontend/yim_resupplier/misc.lua index f4761b5..0938180 100644 --- a/SSV2/includes/frontend/yim_resupplier/misc.lua +++ b/SSV2/includes/frontend/yim_resupplier/misc.lua @@ -9,6 +9,7 @@ local sCooldownButtonLabel, bCooldownParam local maxSellMissionButtonSize = vec2:new(80, 30) +local COL_WARN_YELLOW = Color(240, 190, 2, 255) local function getAllCDCheckboxes() return GVars.features.yrv3.mc_work_cd @@ -22,7 +23,7 @@ local function getAllCDCheckboxes() and GVars.features.yrv3.ceo_crate_sell_cd and GVars.features.yrv3.dax_work_cd and GVars.features.yrv3.garment_rob_cd - -- and GVars.features.yrv3.cfr_cd -- chicken factory raid + -- and GVars.features.yrv3.cfr_cd -- chicken factory raid end ---@param value boolean @@ -175,7 +176,7 @@ return function() ImGui.TextWrapped(_T("YRV3_SELL_MISSIONS_TT")) ImGui.Spacing() - GUI:Text(_T("YRV3_SELL_MISSIONS_NOTE"), Color("yellow")) + GUI:Text(_T("YRV3_SELL_MISSIONS_NOTE"), { color = COL_WARN_YELLOW }) for name, data in pairs(YRV3:GetSaleMissionTunables()) do local isFloat = (data.type == "float") @@ -190,18 +191,15 @@ return function() end if (GUI:Button(label, { size = maxSellMissionButtonSize })) then - for _, index in pairs(data.tuneable) do - if get_func(index) ~= desiredValue then - set_func(index, desiredValue) + for _, tuneable_name in pairs(data.tuneables) do + if (get_func(tuneable_name) ~= desiredValue) then + set_func(tuneable_name, desiredValue) end end - Notifier:ShowSuccess("YRV3", _F(_T("YRV3_SELL_MISSIONS_NOTIF"), name:lower())) + Notifier:ShowSuccess("YRV3", _F(_T("YRV3_SELL_MISSIONS_NOTIF"), name)) end - ImGui.SameLine() - if (ImGui.GetContentRegionAvail() <= (buttonWidth + style.ItemSpacing.x)) then - ImGui.NewLine() - end + ImGui.SameLineIfAvail(buttonWidth + style.ItemSpacing.x) end end diff --git a/SSV2/includes/frontend/yim_resupplier/nightclub.lua b/SSV2/includes/frontend/yim_resupplier/nightclub.lua index b4d10a8..55f9e9a 100644 --- a/SSV2/includes/frontend/yim_resupplier/nightclub.lua +++ b/SSV2/includes/frontend/yim_resupplier/nightclub.lua @@ -11,6 +11,7 @@ local measureBulletWidths = require("includes.frontend.helpers.measure_text_w local drawNamePlate = require("includes.frontend.yim_resupplier.nameplate") local drawCashSafeLoopToggle = require("includes.frontend.yim_resupplier.cashloop_toggle") local colMoneyGreen = Color("#85BB65") +local hubChildWidth = 90 local tempHubVal = 0 local bools = { coloredNameplate = false, @@ -150,7 +151,7 @@ return function() ImGui.PushID(i) ImGui.SetNextWindowBgAlpha(0.64) ImGui.BeginChildEx("##hub_child", - vec2:new(90, 300), + vec2:new(hubChildWidth, 300), ImGuiChildFlags.AlwaysUseWindowPadding, ImGuiWindowFlags.NoScrollbar ) @@ -176,7 +177,7 @@ return function() ImGui.Spacing() ImGui.SetCursorPosX((ImGui.GetCursorPosX() + 35) * 0.5) ImGui.ValueBar( - _F("##bb_hub_%d", i), + "##bb_hub", prod / max_units, vec2:new(40, 140), ImGuiValueBarFlags.VERTICAL @@ -192,7 +193,7 @@ return function() local prod_time = this:GetTimeLeftBeforeProd() local safe_to_trigger = this:CanTriggerProduction() and not this.fast_prod_running - local btn_label = (safe_to_trigger or prod_time <= -1) + local btn_label = (safe_to_trigger or prod_time < 0) and _T("YRV3_TRIGGER_PROD_HUB") or ImGui.TextSpinner() @@ -206,10 +207,7 @@ return function() ImGui.EndChild() ImGui.PopID() - ImGui.SameLine() - if (ImGui.GetContentRegionAvail() < 90) then - ImGui.NewLine() - end + ImGui.SameLineIfAvail(hubChildWidth) end tempHubVal = HubTotalValue diff --git a/SSV2/includes/frontend/yim_resupplier/office.lua b/SSV2/includes/frontend/yim_resupplier/office.lua index b591a18..dcfe57e 100644 --- a/SSV2/includes/frontend/yim_resupplier/office.lua +++ b/SSV2/includes/frontend/yim_resupplier/office.lua @@ -8,19 +8,19 @@ -local drawNamePlate = require("includes.frontend.yim_resupplier.nameplate") -local drawVehicleWarehouse = require("includes.frontend.yim_resupplier.vehicle_warehouse") -local drawWarehouse = require("includes.frontend.yim_resupplier.warehouse") -local measureBulletWidths = require("includes.frontend.helpers.measure_text_width") -local colMoneyGreen = Color("#85BB65") +local drawNamePlate = require("includes.frontend.yim_resupplier.nameplate") +local drawVehicleWarehouse = require("includes.frontend.yim_resupplier.vehicle_warehouse") +local drawWarehouse = require("includes.frontend.yim_resupplier.warehouse") +local measureBulletWidths = require("includes.frontend.helpers.measure_text_width") +local colMoneyGreen = Color("#85BB65") ---@type array -local bulletWidths = {} -local showEarningsData = false -local earningDataIntBuff = nil -local earningDataIdx = 1 -local earningPopupName = "" -local earningData = { +local bulletWidths = {} +local showEarningsData = false +local earningDataIntBuff = nil +local earningDataIdx = 1 +local earningPopupName = "" +local earningData = { { label = "YRV3_LIFETIME_BUY_UNDERTAKEN", pstat = "MPX_LIFETIME_BUY_UNDERTAKEN", min = 0, max = 5e3, step = 1, step_fast = 100 }, { label = "YRV3_LIFETIME_BUY_COMPLETE", pstat = "MPX_LIFETIME_BUY_COMPLETE", min = 0, max = 5e3, step = 1, step_fast = 100 }, { label = "YRV3_LIFETIME_SELL_UNDERTAKEN", pstat = "MPX_LIFETIME_SELL_UNDERTAKEN", min = 0, max = 5e3, step = 1, step_fast = 100 }, @@ -84,7 +84,7 @@ return function() ImGui.BulletText(_T(data.label)) ImGui.SameLine(bulletWidth) if (GUI:Button(_F("%s##%d", _T("GENERIC_EDIT"), i))) then - earningDataIdx = i + earningDataIdx = i earningPopupName = _F("%s##%d", _T("YRV3_EDIT_EARNINGS_DATA"), i) ImGui.OpenPopup(earningPopupName) end diff --git a/SSV2/includes/frontend/yim_resupplier/salvage_yard.lua b/SSV2/includes/frontend/yim_resupplier/salvage_yard.lua index 84e1c25..de043f6 100644 --- a/SSV2/includes/frontend/yim_resupplier/salvage_yard.lua +++ b/SSV2/includes/frontend/yim_resupplier/salvage_yard.lua @@ -10,6 +10,8 @@ local measureBulletWidths = require("includes.frontend.helpers.measure_text_width") local drawNamePlate = require("includes.frontend.yim_resupplier.nameplate") local drawCashSafeLoopToggle = require("includes.frontend.yim_resupplier.cashloop_toggle") +local colMoneyGreen = Color("#85BB65") +local childWidth = 240 ---@type array local bulletWidths = {} @@ -41,10 +43,9 @@ return function() bulletWidths[lang_index] = bulletWidth end - local childWidth = 240 - local cashSafe = salvage_yard:GetCashSafe() - local cashValue = cashSafe:GetCashValue() - local maxCash = cashSafe:GetCapacity() + local cashSafe = salvage_yard:GetCashSafe() + local cashValue = cashSafe:GetCashValue() + local maxCash = cashSafe:GetCapacity() ImGui.BulletText(_T("YRV3_CASH_SAFE")) ImGui.SameLine(bulletWidth) @@ -138,7 +139,7 @@ return function() ImGui.BulletText(_T("GENERIC_VALUE")) ImGui.SameLine() ImGui.SetCursorPosX(ImGui.GetCursorPosX() + ImGui.GetContentRegionAvail() - valWidth - 10) - GUI:Text(value, Color("#00AA00")) + GUI:Text(value, { color = colMoneyGreen }) ImGui.BulletText(_T("GENERIC_TIME_LEFT")) ImGui.SameLine() @@ -155,10 +156,7 @@ return function() end ImGui.EndChild() ImGui.EndDisabled() - ImGui.SameLine() - if (ImGui.GetContentRegionAvail() < childWidth) then - ImGui.NewLine() - end + ImGui.SameLineIfAvail(childWidth) end ImGui.EndTabItem() end @@ -245,15 +243,12 @@ return function() ImGui.BulletText(_T("GENERIC_VALUE")) ImGui.SameLine() ImGui.SetCursorPosX(ImGui.GetCursorPosX() + ImGui.GetContentRegionAvail() - valWidth - 10) - GUI:Text(string.formatmoney(carValue), Color("#00AA00")) + GUI:Text(string.formatmoney(carValue), { color = colMoneyGreen }) end ImGui.EndChild() ImGui.EndDisabled() - ImGui.SameLine() - if (ImGui.GetContentRegionAvail() < childWidth) then - ImGui.NewLine() - end + ImGui.SameLineIfAvail(childWidth) end ImGui.EndTabItem() end diff --git a/SSV2/includes/frontend/yim_resupplier/settings.lua b/SSV2/includes/frontend/yim_resupplier/settings.lua index 6deccf1..a3fbb89 100644 --- a/SSV2/includes/frontend/yim_resupplier/settings.lua +++ b/SSV2/includes/frontend/yim_resupplier/settings.lua @@ -7,6 +7,7 @@ -- * Provide a copy of or a link to the original license (GPL-3.0 or later); see LICENSE.md or . +local COL_RED = Color("red") local timer_data = { { label = "GENERIC_MILLIS_LABEL", mult = 1 }, { label = "GENERIC_SECONDS_LABEL", mult = 1e3 }, @@ -90,7 +91,7 @@ return function() GUI:Tooltip(_T("YRV3_AUTOSELL_TT")) if (script.is_active("fm_content_smuggler_sell")) then - GUI:Text(_T("YRV3_HANGAR_LAND_ERR"), Color("red")) + GUI:Text(_T("YRV3_HANGAR_LAND_ERR"), { color = COL_RED }) else ImGui.BeginDisabled(GVars.features.yrv3.autosell or autoSellTriggered diff --git a/SSV2/includes/frontend/yim_resupplier/vehicle_warehouse.lua b/SSV2/includes/frontend/yim_resupplier/vehicle_warehouse.lua index a56d3f8..1908a8a 100644 --- a/SSV2/includes/frontend/yim_resupplier/vehicle_warehouse.lua +++ b/SSV2/includes/frontend/yim_resupplier/vehicle_warehouse.lua @@ -7,15 +7,15 @@ -- * Provide a copy of or a link to the original license (GPL-3.0 or later); see LICENSE.md or . -local measureBulletWidths = require("includes.frontend.helpers.measure_text_width") -local colMoneyGreen = Color("#85BB65") -local colGreen = Color("green") -local colRed = Color("red") -local drawDetailsTable = false +local measureBulletWidths = require("includes.frontend.helpers.measure_text_width") +local colMoneyGreen = Color("#85BB65") +local colGreen = Color("green") +local colRed = Color("red") +local drawDetailsTable = false local bottomTextSize ---@type array -local bulletWidths = {} +local bulletWidths = {} ---@param warehouse? VehicleWarehouse return function(warehouse) diff --git a/SSV2/includes/frontend/yim_resupplier/warehouse.lua b/SSV2/includes/frontend/yim_resupplier/warehouse.lua index 5c2c29c..d3b412e 100644 --- a/SSV2/includes/frontend/yim_resupplier/warehouse.lua +++ b/SSV2/includes/frontend/yim_resupplier/warehouse.lua @@ -7,11 +7,11 @@ -- * Provide a copy of or a link to the original license (GPL-3.0 or later); see LICENSE.md or . -local measureBulletWidths = require("includes.frontend.helpers.measure_text_width") -local colMoneyGreen = Color("#85BB65") +local measureBulletWidths = require("includes.frontend.helpers.measure_text_width") +local colMoneyGreen = Color("#85BB65") ---@type array -local bulletWidths = {} +local bulletWidths = {} ---@param warehouse? Warehouse ---@param notOwnedLabel? string Optional label to display if the business isn't owned diff --git a/SSV2/includes/frontend/yim_resupplier/yrv3_ui.lua b/SSV2/includes/frontend/yim_resupplier/yrv3_ui.lua index 0f8128c..01d2b24 100644 --- a/SSV2/includes/frontend/yim_resupplier/yrv3_ui.lua +++ b/SSV2/includes/frontend/yim_resupplier/yrv3_ui.lua @@ -7,9 +7,9 @@ -- * Provide a copy of or a link to the original license (GPL-3.0 or later); see LICENSE.md or . -local selectedTabID = 1 -local colMoneyGreen = Color("#85BB65") -local tabNames = { +local selectedTabID = 1 +local colMoneyGreen = Color("#85BB65") +local tabNames = { "GB_BOSSC", "CELL_HANGAR", "GB_REST_ACCM", @@ -23,7 +23,7 @@ local tabNames = { "CELL_16" } -local tabCallbacks = { +local tabCallbacks = { require("includes.frontend.yim_resupplier.office"), require("includes.frontend.yim_resupplier.hangar"), require("includes.frontend.yim_resupplier.clubhouse"), diff --git a/SSV2/includes/lib/imgui_ext.lua b/SSV2/includes/lib/imgui_ext.lua index 1455244..f8f094c 100644 --- a/SSV2/includes/lib/imgui_ext.lua +++ b/SSV2/includes/lib/imgui_ext.lua @@ -985,6 +985,7 @@ function ImGui.BeginChildEx(name, size, childFlags, windowFlags) if (padding) then windowFlags = windowFlags | ImGuiWindowFlags.AlwaysUseWindowPadding end + ---@diagnostic disable-next-line: param-type-mismatch return ImGui.BeginChild(name, size.x, size.y, border, windowFlags) end end diff --git a/SSV2/includes/lib/translations/__hashmap.json b/SSV2/includes/lib/translations/__hashmap.json index 3620a47..91decdb 100644 --- a/SSV2/includes/lib/translations/__hashmap.json +++ b/SSV2/includes/lib/translations/__hashmap.json @@ -824,5 +824,7 @@ "YAV3_FLAGS_PROCESS_ATTACHMENTS": 4075099086, "YAV3_FLAGS_ALTERNATIVE_FP_ANIM": 1745215392, "YAV3_FLAGS_USE_FULL_BLENDING": 4047640931, - "YAV3_FLAGS_DEAD_POSE_LOOPED_TT": 2012397132 + "YAV3_FLAGS_DEAD_POSE_LOOPED_TT": 2012397132, + "GENERIC_SCRIPT_CONTROL": 3406496005, + "GENERIC_RESET_ALL": 726886180 } \ No newline at end of file diff --git a/SSV2/includes/lib/translations/de-DE.lua b/SSV2/includes/lib/translations/de-DE.lua index 958cb8b..036cb16 100644 --- a/SSV2/includes/lib/translations/de-DE.lua +++ b/SSV2/includes/lib/translations/de-DE.lua @@ -824,5 +824,7 @@ return { ["YAV3_FLAGS_HOLD_LAST_FRAME"] = "Letzten Frame halten", ["YAV3_FLAGS_TURN_OFF_COLLISION"] = "Kollision deaktivieren", ["YAV3_FLAGS_PROCESS_ATTACHMENTS"] = "Prozessanhänge", - ["YAV3_FLAGS_DEAD_POSE_LOOPED_TT"] = "Dies hat keine Auswirkung, wenn die Animation in einer Schleife ausgeführt wird." + ["YAV3_FLAGS_DEAD_POSE_LOOPED_TT"] = "Dies hat keine Auswirkung, wenn die Animation in einer Schleife ausgeführt wird.", + ["GENERIC_SCRIPT_CONTROL"] = "Versuch, die Kontrolle über das Skript zu übernehmen", + ["GENERIC_RESET_ALL"] = "Alles zurücksetzen" } diff --git a/SSV2/includes/lib/translations/en-US.lua b/SSV2/includes/lib/translations/en-US.lua index 46d5277..b3b2e0e 100644 --- a/SSV2/includes/lib/translations/en-US.lua +++ b/SSV2/includes/lib/translations/en-US.lua @@ -69,6 +69,7 @@ return { ["GENERIC_CANCEL"] = "Cancel", ["GENERIC_APPLY"] = "Apply", ["GENERIC_RESET"] = "Reset", + ["GENERIC_RESET_ALL"] = "Reset All", ["GENERIC_REPAIR"] = "Repair", ["GENERIC_CLEAR"] = "Clear", ["GENERIC_CLEAR_ALL"] = "Clear All", @@ -162,6 +163,7 @@ return { ["GENERIC_COMMANDS"] = "Commands", ["GENERIC_TURN_ON"] = "Turn On", ["GENERIC_TURN_OFF"] = "Turn Off", + ["GENERIC_SCRIPT_CONTROL"] = "Attempting to take control of script", --#endregion --#region CasinoPacino @@ -189,16 +191,13 @@ return { ["CP_POKER_SETTINGS"] = "Three Card Poker", ["CP_POKER_FORCE_ROYAL_FLUSH"] = "Force all Players Hands to Royal Flush", ["CP_POKER_FORCE_BAD_BEAT"] = "Force Dealer's Hand to 'Bad Beat'", - ["CP_POKER_SCRIPT_CONTROL"] = "Taking control of the Three Card Poker script...", ["CP_BLACKJACK_SETTINGS"] = "Blackjack", ["CP_BLACKJACK_DEALER_FACE_DOWN_CARD"] = "Dealer's Face Down Card:", ["CP_BLACKJACK_FORCE_DEALER_BUST"] = "Force Dealer to Bust", - ["CP_BLACKJACK_SCRIPT_CONTROL"] = "Taking control of the blackjack script...", ["CP_NOT_IN_CASINO"] = "Not in Casino", ["CP_NOT_PLAYING_BLACKJACK"] = "Not Playing Blackjack", ["CP_ROULETTE_SETTINGS"] = "Roulette", ["CP_ROULETTE_FORCE_RED_18"] = "Force Roulette Wheel to Land on Red 18", - ["CP_ROULETTE_SCRIPT_CONTROL"] = "Taking control of the 'Casino Roulette' script...", ["CP_SLOT_MACHINES_SETTINGS"] = "Slot Machines", ["CP_SLOT_MACHINES_RIG"] = "Rig Slot Machines", ["CP_SLOT_MACHINES_AUTOPLAY"] = "Autoplay Slot Machines", diff --git a/SSV2/includes/lib/translations/es-ES.lua b/SSV2/includes/lib/translations/es-ES.lua index 6d8a910..ba1878c 100644 --- a/SSV2/includes/lib/translations/es-ES.lua +++ b/SSV2/includes/lib/translations/es-ES.lua @@ -824,5 +824,7 @@ return { ["YAV3_FLAGS_TURN_OFF_COLLISION"] = "Deshabilitar colisión", ["YAV3_FLAGS_PROCESS_ATTACHMENTS"] = "Adjuntos de proceso", ["YAV3_FLAGS_USE_FULL_BLENDING"] = "Usar fusión completa", - ["YAV3_FLAGS_DEAD_POSE_LOOPED_TT"] = "Esto no hará nada si la animación se repite." + ["YAV3_FLAGS_DEAD_POSE_LOOPED_TT"] = "Esto no hará nada si la animación se repite.", + ["GENERIC_SCRIPT_CONTROL"] = "Intentando tomar el control del guión.", + ["GENERIC_RESET_ALL"] = "Restablecer todo" } diff --git a/SSV2/includes/lib/translations/fr-FR.lua b/SSV2/includes/lib/translations/fr-FR.lua index dd00b82..2b05dfb 100644 --- a/SSV2/includes/lib/translations/fr-FR.lua +++ b/SSV2/includes/lib/translations/fr-FR.lua @@ -824,5 +824,7 @@ return { ["YAV3_FLAGS_NOT_INTERRUPTABLE"] = "Non Interruptible", ["YAV3_FLAGS_HOLD_LAST_FRAME"] = "Conserver la dernière image", ["YAV3_FLAGS_USE_FULL_BLENDING"] = "Utiliser le mélange complet", - ["YAV3_FLAGS_ALTERNATIVE_FP_ANIM"] = "Animation alternative à la première personne" + ["YAV3_FLAGS_ALTERNATIVE_FP_ANIM"] = "Animation alternative à la première personne", + ["GENERIC_SCRIPT_CONTROL"] = "Tentative de prendre le contrôle du script", + ["GENERIC_RESET_ALL"] = "Tout réinitialiser" } diff --git a/SSV2/includes/lib/translations/it-IT.lua b/SSV2/includes/lib/translations/it-IT.lua index 81e4e25..a12f1df 100644 --- a/SSV2/includes/lib/translations/it-IT.lua +++ b/SSV2/includes/lib/translations/it-IT.lua @@ -824,5 +824,7 @@ return { ["YAV3_FLAGS_ALTERNATIVE_FP_ANIM"] = "Animazione alternativa in prima persona", ["YAV3_FLAGS_DEAD_POSE_LOOPED_TT"] = "Questo non farà nulla se l'animazione è in loop.", ["YAV3_FLAGS_PROCESS_ATTACHMENTS"] = "Allegati del processo", - ["YAV3_FLAGS_USE_FULL_BLENDING"] = "Usa la miscelazione completa" + ["YAV3_FLAGS_USE_FULL_BLENDING"] = "Usa la miscelazione completa", + ["GENERIC_SCRIPT_CONTROL"] = "Tentativo di prendere il controllo della sceneggiatura", + ["GENERIC_RESET_ALL"] = "Reimposta tutto" } diff --git a/SSV2/includes/lib/translations/ja-JP.lua b/SSV2/includes/lib/translations/ja-JP.lua index e974dbb..8bd3bbd 100644 --- a/SSV2/includes/lib/translations/ja-JP.lua +++ b/SSV2/includes/lib/translations/ja-JP.lua @@ -824,5 +824,7 @@ return { ["YAV3_FLAGS_UPPERBODY"] = "上半身のみ", ["YAV3_FLAGS_FORCE_START"] = "強制開始", ["YAV3_FLAGS_DEAD_POSE_LOOPED_TT"] = "アニメーションがループしている場合、これは何も行いません。", - ["YAV3_FLAGS_ALTERNATIVE_FP_ANIM"] = "代替一人称アニメーション" + ["YAV3_FLAGS_ALTERNATIVE_FP_ANIM"] = "代替一人称アニメーション", + ["GENERIC_SCRIPT_CONTROL"] = "スクリプトを制御しようとしています", + ["GENERIC_RESET_ALL"] = "すべてリセット" } diff --git a/SSV2/includes/lib/translations/ko-KR.lua b/SSV2/includes/lib/translations/ko-KR.lua index efcb6d2..4d16719 100644 --- a/SSV2/includes/lib/translations/ko-KR.lua +++ b/SSV2/includes/lib/translations/ko-KR.lua @@ -824,5 +824,7 @@ return { ["YAV3_FLAGS_USE_FULL_BLENDING"] = "전체 혼합 사용", ["YAV3_FLAGS_NOT_INTERRUPTABLE"] = "중단할 수 없음", ["YAV3_FLAGS_ALTERNATIVE_FP_ANIM"] = "대체 1인칭 애니메이션", - ["YAV3_FLAGS_DEAD_POSE_LOOPED_TT"] = "애니메이션이 반복되면 아무 작업도 수행되지 않습니다." + ["YAV3_FLAGS_DEAD_POSE_LOOPED_TT"] = "애니메이션이 반복되면 아무 작업도 수행되지 않습니다.", + ["GENERIC_SCRIPT_CONTROL"] = "스크립트를 제어하려고 시도 중입니다.", + ["GENERIC_RESET_ALL"] = "모두 재설정" } diff --git a/SSV2/includes/lib/translations/pl-PL.lua b/SSV2/includes/lib/translations/pl-PL.lua index 962bf76..c229e5e 100644 --- a/SSV2/includes/lib/translations/pl-PL.lua +++ b/SSV2/includes/lib/translations/pl-PL.lua @@ -824,5 +824,7 @@ return { ["YAV3_FLAGS_FORCE_START"] = "Wymuś start", ["YAV3_FLAGS_TURN_OFF_COLLISION"] = "Wyłącz kolizję", ["YAV3_FLAGS_DEAD_POSE_LOOPED_TT"] = "To nic nie da, jeśli animacja jest zapętlona.", - ["YAV3_FLAGS_ALTERNATIVE_FP_ANIM"] = "Alternatywna animacja pierwszoosobowa" + ["YAV3_FLAGS_ALTERNATIVE_FP_ANIM"] = "Alternatywna animacja pierwszoosobowa", + ["GENERIC_SCRIPT_CONTROL"] = "Próba przejęcia kontroli nad scenariuszem", + ["GENERIC_RESET_ALL"] = "Zresetuj wszystko" } diff --git a/SSV2/includes/lib/translations/pt-BR.lua b/SSV2/includes/lib/translations/pt-BR.lua index 67b6290..0b54087 100644 --- a/SSV2/includes/lib/translations/pt-BR.lua +++ b/SSV2/includes/lib/translations/pt-BR.lua @@ -824,5 +824,7 @@ return { ["YAV3_FLAGS_USE_FULL_BLENDING"] = "Use mistura completa", ["YAV3_FLAGS_TURN_OFF_COLLISION"] = "Desativar colisão", ["YAV3_FLAGS_FORCE_START"] = "Forçar início", - ["YAV3_FLAGS_DEAD_POSE_LOOPED_TT"] = "Isso não fará nada se a animação estiver em loop." + ["YAV3_FLAGS_DEAD_POSE_LOOPED_TT"] = "Isso não fará nada se a animação estiver em loop.", + ["GENERIC_SCRIPT_CONTROL"] = "Tentando assumir o controle do script", + ["GENERIC_RESET_ALL"] = "Redefinir tudo" } diff --git a/SSV2/includes/lib/translations/ru-RU.lua b/SSV2/includes/lib/translations/ru-RU.lua index 99b6504..6fc1e03 100644 --- a/SSV2/includes/lib/translations/ru-RU.lua +++ b/SSV2/includes/lib/translations/ru-RU.lua @@ -824,5 +824,7 @@ return { ["YAV3_FLAGS_DEAD_POSE_LOOPED_TT"] = "Это ничего не даст, если анимация зациклена.", ["YAV3_FLAGS_ALTERNATIVE_FP_ANIM"] = "Альтернативная анимация от первого лица", ["YAV3_FLAGS_USE_FULL_BLENDING"] = "Используйте полное смешивание", - ["YAV3_FLAGS_PROCESS_ATTACHMENTS"] = "Вложения процесса" + ["YAV3_FLAGS_PROCESS_ATTACHMENTS"] = "Вложения процесса", + ["GENERIC_SCRIPT_CONTROL"] = "Попытка взять под контроль сценарий", + ["GENERIC_RESET_ALL"] = "Сбросить все" } diff --git a/SSV2/includes/lib/translations/zh-CN.lua b/SSV2/includes/lib/translations/zh-CN.lua index 8466c7a..f09e9a7 100644 --- a/SSV2/includes/lib/translations/zh-CN.lua +++ b/SSV2/includes/lib/translations/zh-CN.lua @@ -824,5 +824,7 @@ return { ["YAV3_FLAGS_FORCE_START"] = "强制启动", ["YAV3_FLAGS_ALTERNATIVE_FP_ANIM"] = "替代第一人称动画", ["YAV3_FLAGS_DEAD_POSE_LOOPED_TT"] = "如果动画循环播放,这不会执行任何操作。", - ["YAV3_FLAGS_USE_FULL_BLENDING"] = "使用完全混合" + ["YAV3_FLAGS_USE_FULL_BLENDING"] = "使用完全混合", + ["GENERIC_SCRIPT_CONTROL"] = "试图控制脚本", + ["GENERIC_RESET_ALL"] = "全部重置" } diff --git a/SSV2/includes/lib/translations/zh-TW.lua b/SSV2/includes/lib/translations/zh-TW.lua index 0c0d1cc..97923a7 100644 --- a/SSV2/includes/lib/translations/zh-TW.lua +++ b/SSV2/includes/lib/translations/zh-TW.lua @@ -824,5 +824,7 @@ return { ["YAV3_FLAGS_HIDE_WEAPON"] = "隱藏武器", ["YAV3_FLAGS_DEAD_POSE_LOOPED_TT"] = "如果動畫循環播放,這不會執行任何操作。", ["YAV3_FLAGS_USE_FULL_BLENDING"] = "使用完全混合", - ["YAV3_FLAGS_ALTERNATIVE_FP_ANIM"] = "替代第一人稱動畫" + ["YAV3_FLAGS_ALTERNATIVE_FP_ANIM"] = "替代第一人稱動畫", + ["GENERIC_SCRIPT_CONTROL"] = "試著控制腳本", + ["GENERIC_RESET_ALL"] = "全部重置" } diff --git a/SSV2/includes/lib/types.lua b/SSV2/includes/lib/types.lua index 7178e90..cd0838a 100644 --- a/SSV2/includes/lib/types.lua +++ b/SSV2/includes/lib/types.lua @@ -68,8 +68,12 @@ GenericClass = setmetatable({}, { ---@class handle: integer -- RAGE JOAAT hash ---@class hash: joaat_t + ---@class pointer_ref ----@field deref fun(self: pointer): pointer|nullptr +---@field deref fun(self: pointer_ref): pointer|nullptr +---@field get_address fun(self: pointer_ref): uint64_t +---@field is_null fun(self: pointer_ref): boolean +---@field is_valid fun(self: pointer_ref): boolean ---@alias anyval table|metatable|userdata|lightuserdata|function|string|number|boolean Any Lua value except nil. ---@alias optional T? diff --git a/SSV2/includes/modules/BSV2/Bodyguard.lua b/SSV2/includes/modules/BSV2/Bodyguard.lua index 6f41370..ca1bafa 100644 --- a/SSV2/includes/modules/BSV2/Bodyguard.lua +++ b/SSV2/includes/modules/BSV2/Bodyguard.lua @@ -382,7 +382,7 @@ function Bodyguard:UpdatePosition(allowInside) return end - if (PLAYER.IS_PLAYER_TELEPORT_ACTIVE() and not PLAYER.UPDATE_PLAYER_TELEPORT(LocalPlayer:GetPlayerID())) then + if (PLAYER.IS_PLAYER_TELEPORT_ACTIVE() and not PLAYER.UPDATE_PLAYER_TELEPORT(LocalPlayer:GetID())) then sleep(10) return end diff --git a/SSV2/includes/modules/HandlingEditor.lua b/SSV2/includes/modules/HandlingEditor.lua index f3c542b..d0904d1 100644 --- a/SSV2/includes/modules/HandlingEditor.lua +++ b/SSV2/includes/modules/HandlingEditor.lua @@ -30,8 +30,8 @@ HandlingObject.__index = HandlingObject ---@param predicate? Predicate function HandlingObject.new(flag, flagType, predicate) return setmetatable({ - m_flag = flag, - m_type = flagType, + m_flag = flag, + m_type = flagType, m_predicate = predicate }, HandlingObject) end @@ -50,9 +50,9 @@ function HandlingEditor:init(pv) return self end - self.m_pv = pv + self.m_pv = pv self.m_handling_objects = {} - self.m_initialized = true + self.m_initialized = true return self end @@ -83,10 +83,10 @@ end ---@return boolean function HandlingEditor:GetFlagDefault(obj) return Switch(obj.m_type) { - [Enums.eHandlingEditorTypes.TYPE_HF] = self.m_pv:GetHandlingFlag(obj.m_flag), - [Enums.eHandlingEditorTypes.TYPE_AF] = self.m_pv:GetAdvancedFlag(obj.m_flag), + [Enums.eHandlingEditorTypes.TYPE_HF] = self.m_pv:GetHandlingFlag(obj.m_flag), + [Enums.eHandlingEditorTypes.TYPE_AF] = self.m_pv:GetAdvancedFlag(obj.m_flag), [Enums.eHandlingEditorTypes.TYPE_MIF] = self.m_pv:GetModelInfoFlag(obj.m_flag), - default = false + default = false } end @@ -123,9 +123,7 @@ function HandlingEditor:SetFlag(obj, toggle, reset) set_func = Vehicle.SetModelInfoFlag end - if (not set_func) then - return - end + if (not set_func) then return end set_func(self.m_pv, obj.m_flag, toggle) local callback = toggle and obj.m_on_enable or obj.m_on_disable @@ -147,7 +145,7 @@ function HandlingEditor:ResetFlag(obj) return end - if (not obj.m_was_edited or obj.m_default == nil) then + if (obj.m_was_edited == false or obj.m_default == nil) then return end @@ -173,9 +171,6 @@ function HandlingEditor:Apply() end local checkboxState = table.get_nested_key(GVars, key) - -- explicit eval becayse these can be nil or garbage - -- we only act on checkbox enabled and default is off because checkboxes don't represent actual flag state in memory - -- this prevents disabling default enabled flags on init when a checkbox was never set in the first place if (checkboxState == true and obj.m_default == false) then self:SetFlag(obj, true) end diff --git a/SSV2/includes/modules/LocalPlayer.lua b/SSV2/includes/modules/LocalPlayer.lua index 9868a70..82e7815 100644 --- a/SSV2/includes/modules/LocalPlayer.lua +++ b/SSV2/includes/modules/LocalPlayer.lua @@ -78,7 +78,7 @@ end -- Returns the current local player's ID. ---@return number -function LocalPlayer:GetPlayerID() +function LocalPlayer:GetID() return _G.self.get_id() end @@ -171,7 +171,7 @@ function LocalPlayer:OnVehicleExit() end if (not self.m_vehicle:IsValid()) then - self.m_vehicle:Reset() + self.m_vehicle:Cleanup() end end @@ -179,7 +179,7 @@ end ---@param skip_players? boolean -- Ignore network players. ---@return handle | nil function LocalPlayer:GetEntityInCrosshairs(skip_players) - local is_aiming, entity, pid = false, 0, self:GetPlayerID() + local is_aiming, entity, pid = false, 0, self:GetID() if not PLAYER.IS_PLAYER_FREE_AIMING(pid) then return 0 @@ -247,7 +247,7 @@ end ---@return boolean function LocalPlayer:IsBeingArrested() - return PLAYER.IS_PLAYER_BEING_ARRESTED(self:GetPlayerID(), true) + return PLAYER.IS_PLAYER_BEING_ARRESTED(self:GetID(), true) end -- Teleports local player to the provided coordinates. @@ -283,17 +283,6 @@ function LocalPlayer:Teleport(where, keepVehicle, loadGround) end) end ----@param scriptName string ----@return boolean -function LocalPlayer:IsHostOfScript(scriptName) - local pid = self:GetPlayerID() - return (NETWORK.NETWORK_GET_HOST_OF_SCRIPT(scriptName, -1, 0) == pid) - or (NETWORK.NETWORK_GET_HOST_OF_SCRIPT(scriptName, 0, 0) == pid) - or (NETWORK.NETWORK_GET_HOST_OF_SCRIPT(scriptName, 1, 0) == pid) - or (NETWORK.NETWORK_GET_HOST_OF_SCRIPT(scriptName, 2, 0) == pid) - or (NETWORK.NETWORK_GET_HOST_OF_SCRIPT(scriptName, 3, 0) == pid) -end - -- Returns whether the player is currently using any mobile or computer app. ---@return boolean function LocalPlayer:IsBrowsingApps() @@ -543,8 +532,7 @@ ThreadManager:RegisterLooped("SS_PV_HANDLER", function() end if (LocalPlayer.m_vehicle:GetHandle() ~= 0 and not LocalPlayer.m_vehicle:IsValid()) then - LocalPlayer.m_vehicle:Reset() - sleep(1000) + LocalPlayer.m_vehicle:Cleanup() end end) diff --git a/SSV2/includes/modules/Ped.lua b/SSV2/includes/modules/Ped.lua index efcb59f..bc28d1a 100644 --- a/SSV2/includes/modules/Ped.lua +++ b/SSV2/includes/modules/Ped.lua @@ -126,18 +126,18 @@ function Ped:IsPedMyEnemy(pedHandle) return false end - local this = self:GetHandle() - if (this == pedHandle) then + local localHandle = self:GetHandle() + if (localHandle == pedHandle) then return false end - local rel1 = PED.GET_RELATIONSHIP_BETWEEN_PEDS(this, pedHandle) - local rel2 = PED.GET_RELATIONSHIP_BETWEEN_PEDS(pedHandle, this) + local rel1 = PED.GET_RELATIONSHIP_BETWEEN_PEDS(localHandle, pedHandle) + local rel2 = PED.GET_RELATIONSHIP_BETWEEN_PEDS(pedHandle, localHandle) local pos = self:GetPos(true) return ( - PED.IS_PED_IN_COMBAT(pedHandle, this) - or PED.IS_PED_IN_COMBAT(this, pedHandle) + PED.IS_PED_IN_COMBAT(pedHandle, localHandle) + or PED.IS_PED_IN_COMBAT(localHandle, pedHandle) or math.is_inrange(rel1, 3, 5) or math.is_inrange(rel2, 3, 5) or PED.IS_ANY_HOSTILE_PED_NEAR_POINT( diff --git a/SSV2/includes/modules/Player.lua b/SSV2/includes/modules/Player.lua index 23a0c41..7684a3a 100644 --- a/SSV2/includes/modules/Player.lua +++ b/SSV2/includes/modules/Player.lua @@ -37,7 +37,7 @@ Player.SetAsNoLongerNeeded = nil ---@return Player function Player.new(p0) local ped, pid = 0, 0 - if (math.is_inrange(p0, 0, 32)) then + if (math.is_inrange(p0, 0, 31)) then pid = p0 ped = PLAYER.GET_PLAYER_PED_SCRIPT_INDEX(pid) elseif (Game.IsScriptHandle(p0)) then @@ -48,25 +48,19 @@ function Player.new(p0) end if (not PED.IS_PED_A_PLAYER(ped)) then - error("Attempt to create a Player instance from a non-player ped.") + error("Attempt to create a Player instance from an NPC.") end - ---@type Player - local instance = setmetatable({ + return setmetatable({ m_pid = pid, m_handle = ped, ---@diagnostic disable-next-line: param-type-mismatch }, Player) - - return instance end ---@return boolean function Player:IsValid() - if (self == LocalPlayer) then - return true - end - + if (self == LocalPlayer) then return true end return self:Exists() and PED.IS_PED_A_PLAYER(self:GetHandle()) end @@ -85,11 +79,19 @@ end ---@param scriptName string ---@return boolean function Player:IsHostOfScript(scriptName) - return (NETWORK.NETWORK_GET_HOST_OF_SCRIPT(scriptName, -1, 0) == self.m_pid) - or (NETWORK.NETWORK_GET_HOST_OF_SCRIPT(scriptName, 0, 0) == self.m_pid) - or (NETWORK.NETWORK_GET_HOST_OF_SCRIPT(scriptName, 1, 0) == self.m_pid) - or (NETWORK.NETWORK_GET_HOST_OF_SCRIPT(scriptName, 2, 0) == self.m_pid) - or (NETWORK.NETWORK_GET_HOST_OF_SCRIPT(scriptName, 3, 0) == self.m_pid) + local pid = self:GetID() + for i = -1, 3 do + if (NETWORK.NETWORK_GET_HOST_OF_SCRIPT(scriptName, i, 0) == pid) then + return true + end + end + + return false +end + +---@return ID +function Player:GetID() + return self.m_pid end ---@return eGameState diff --git a/SSV2/includes/modules/PlayerVehicle.lua b/SSV2/includes/modules/PlayerVehicle.lua index 1bc1ce6..de6511b 100644 --- a/SSV2/includes/modules/PlayerVehicle.lua +++ b/SSV2/includes/modules/PlayerVehicle.lua @@ -229,9 +229,11 @@ function PlayerVehicle:Reset() self:Destroy() self.m_handle = 0 +end - -- called late so it only resets deltas and keeps the vehicle untouched. - self.m_stance_mgr:Reset() +function PlayerVehicle:Cleanup() + self:Reset() + self.m_stance_mgr:Cleanup() end ---@return hash diff --git a/SSV2/includes/modules/businesses/Factory.lua b/SSV2/includes/modules/businesses/Factory.lua index f6a0b75..0022b63 100644 --- a/SSV2/includes/modules/businesses/Factory.lua +++ b/SSV2/includes/modules/businesses/Factory.lua @@ -63,7 +63,7 @@ function Factory.new(opts) local offset_3 = g_obj:GetOffset(3) local index_size = g_obj:GetOffset(4) instance.m_prod_time_g = g_obj:AsGlobal() - :At(LocalPlayer:GetPlayerID(), pid_size) + :At(LocalPlayer:GetID(), pid_size) :At(offset_2) :At(offset_3) :At(base:GetIndex(), index_size) diff --git a/SSV2/includes/modules/businesses/SalvageYard.lua b/SSV2/includes/modules/businesses/SalvageYard.lua index 0318c31..9cd45e8 100644 --- a/SSV2/includes/modules/businesses/SalvageYard.lua +++ b/SSV2/includes/modules/businesses/SalvageYard.lua @@ -135,13 +135,8 @@ end ---@param slot integer ---@return string function SalvageYard:GetRobberyCarInSlot(slot) - local index = stats.get_int(_F("MPX_MPSV_MODEL_SALVAGE_VEH%d", slot)) - local modelName = data.vehicle_targets[index] - if (not modelName) then - return "" - end - - return Game.GetVehicleDisplayName(modelName) + local index = stats.get_int(_F("MPX_MPSV_MODEL_SALVAGE_VEH%d", slot)) + return data.vehicle_targets[index] or "NULL" end function SalvageYard:DisableRobberyCooldown() @@ -351,4 +346,12 @@ function SalvageYard:GetEstimatedIncome() return sum + self.m_safe:GetCashValue() end +ThreadManager:Run(function() + local array = data.vehicle_targets + for i = 1, #array do + local model = array[i] + array[i] = Game.GetVehicleDisplayName(model) + end +end) + return SalvageYard diff --git a/SSV2/includes/services/GUI.lua b/SSV2/includes/services/GUI.lua index b9eb02f..10ff6fb 100644 --- a/SSV2/includes/services/GUI.lua +++ b/SSV2/includes/services/GUI.lua @@ -867,20 +867,24 @@ function GUI:Text(text, opts) text = _F(text, table.unpack(opts.fmt)) end - if (not IsInstance(opts.color, Color)) then - ImGui.TextWrapped(text) - return - end - local has_wrap_pos = type(opts.wrap_pos) == "number" - local r, g, b, a = opts.color:AsFloat() + local has_color = IsInstance(opts.color, Color) + + if (has_color) then + local r, g, b, a = opts.color:AsFloat() + ImGui.PushStyleColor(ImGuiCol.Text, r, g, b, opts.alpha or a or 1) + end - ImGui.PushStyleColor(ImGuiCol.Text, r, g, b, opts.alpha or a or 1) if (has_wrap_pos) then ImGui.PushTextWrapPos(opts.wrap_pos) end - ImGui.Text(text) - ImGui.PopStyleColor(1) + + ImGui.TextWrapped(text) + + if (has_color) then + ImGui.PopStyleColor(1) + end + if (has_wrap_pos) then ImGui.PopTextWrapPos() end