Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions SSV2/includes/data/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ local Config <const> = {
dre_cd = false,
ogfa_cd = false,
cayo_cd = false,
dday_cd = false,
},
yrv3 = {
autofill_delay = 500,
Expand Down
44 changes: 40 additions & 4 deletions SSV2/includes/data/globals_locals.lua
Original file line number Diff line number Diff line change
Expand Up @@ -894,17 +894,53 @@ return {
}
},
request_services_global = {
description = "Request Services Global.",
file = "am_prostitute.c", -- definitely the right file to use I'm sure of it
description = "Request Services Global. Only used for Kosatka atm, same global for all services.",
file = "am_mp_submarine.c",
LEGACY = {
value = 2733002,
pattern = [[Global_(\d{7})\.f_4 = 0;]],
pattern = [[return Global_(\d{7})\.f_371;]],
capture_group = 1
},
ENHANCED = {
value = 2733138,
pattern = [[Global_(\d{7})\.f_4 = 0;]],
pattern = [[return Global_(\d{7})\.f_371;]],
capture_group = 1
}
},
submarine_global = {
description = "Submarine Global",
file = "am_mp_submarine.c",
LEGACY = {
value = 2658291,
pattern = [[if \(NETWORK::NETWORK_DOES_NETWORK_ID_EXIST\(Global_(\d{7})\[.*?Param0 /\*(\d+)\*/\]\.(f_\d{2})\)\)]],
capture_group = 1,
offsets = {
{
value = 468,
capture_group = 2,
description = "playerID read size."
},
{
value = 52,
capture_group = 3
}
}
},
ENHANCED = {
value = 2658294,
pattern = [[if \(NETWORK::NETWORK_DOES_NETWORK_ID_EXIST\(Global_(\d{7})\[.*?Param0 /\*(\d+)\*/\]\.(f_\d{2})\)\)]],
capture_group = 1,
offsets = {
{
value = 468,
capture_group = 2,
description = "playerID read size."
},
{
value = 52,
capture_group = 3
}
}
}
}
}
44 changes: 33 additions & 11 deletions SSV2/includes/data/yrv3_data.lua
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,17 @@ local RawBusinessData <const> = {
end
end
},
["dday_cd"] = {
dirty = false,
gstate = function()
return GVars.features.yim_heists.dday_cd
end,
onEnable = function()
if (stats.get_int("MPX_GANGOPS_LAUNCH_TIME") > 0) then
stats.set_int("MPX_GANGOPS_LAUNCH_TIME", 0)
end
end
},
},
SellScripts = {
["gb_smuggler"] = { -- air
Expand Down Expand Up @@ -515,17 +526,28 @@ local RawBusinessData <const> = {
[30] = { coords = vec3:new(-3030.341797, 3334.570068, 10.105902) },
[31] = { coords = vec3:new(-3156.140625, 1376.710693, 17.073570) },
},
Facilities = {
{ gxt = "MP_DBASE_1", coords = vec3:new(1273.1376, 2835.0068, 48.0734) }, -- freemode.c func_7238
{ gxt = "MP_DBASE_2", coords = vec3:new(34.4699, 2620.9768, 84.6202) },
{ gxt = "MP_DBASE_3", coords = vec3:new(2755.9807, 3907.2722, 44.3148) },
{ gxt = "MP_DBASE_4", coords = vec3:new(3389.6028, 5508.971, 24.875) },
{ gxt = "MP_DBASE_6", coords = vec3:new(19.4492, 6825.3613, 14.4952) },
{ gxt = "MP_DBASE_7", coords = vec3:new(-2229.408, 2395.4102, 12.0106) },
{ gxt = "MP_DBASE_8", coords = vec3:new(-3.0095, 3344.4888, 40.2769) },
{ gxt = "MP_DBASE_9", coords = vec3:new(2086.0674, 1761.3461, 103.043) },
{ gxt = "MP_DBASE_10", coords = vec3:new(1864.8027, 269.0474, 163.0169) },
},
Nightclubs = {
{ name = "", coords = vec3:new(757.009, -1332.32, 26.1802) }, -- am_mp_nightclub.c func_5118 // case 102: *uParam5 is main entrance corona coords
{ name = "", coords = vec3:new(345.7519, -978.8848, 28.2681) },
{ name = "", coords = vec3:new(-120.906, -1260.49, 28.2088) },
{ name = "", coords = vec3:new(5.53709, 221.35, 106.6566) },
{ name = "", coords = vec3:new(871.47, -2099.57, 29.3768) },
{ name = "", coords = vec3:new(-675.225, -2459.15, 12.8444) },
{ name = "", coords = vec3:new(195.534, -3168.88, 4.7903) },
{ name = "", coords = vec3:new(373.05, 252.13, 101.9097) },
{ name = "", coords = vec3:new(-1283.38, -649.916, 25.5198) },
{ name = "", coords = vec3:new(-1174.85, -1152.3, 4.56128) },
{ coords = vec3:new(757.009, -1332.32, 26.1802) }, -- am_mp_nightclub.c func_5118 // case 102: *uParam5 is main entrance corona coords
{ coords = vec3:new(345.7519, -978.8848, 28.2681) },
{ coords = vec3:new(-120.906, -1260.49, 28.2088) },
{ coords = vec3:new(5.53709, 221.35, 106.6566) },
{ coords = vec3:new(871.47, -2099.57, 29.3768) },
{ coords = vec3:new(-675.225, -2459.15, 12.8444) },
{ coords = vec3:new(195.534, -3168.88, 4.7903) },
{ coords = vec3:new(373.05, 252.13, 101.9097) },
{ coords = vec3:new(-1283.38, -649.916, 25.5198) },
{ coords = vec3:new(-1174.85, -1152.3, 4.56128) },
},
---@alias BusinessHubs array<{ name: string, vpu_tunable: string, max_units_tunable: string, prod_time_tunable: string }>
BusinessHubs = {
Expand Down Expand Up @@ -608,7 +630,7 @@ local RawBusinessData <const> = {
{ gxt = "HD_GARNAME", coords = vec3:new(719.3386, -983.1850, 24.1402) },
},
FieldHangar = {
{ gxt = "FHAN_NME_1", coords = vec3:new(2150.65, 4796.60, 41.17) },
{ gxt = "FHAN_NME_1", coords = vec3:new(2152.74, 4791.05, 41.17) },
},
CashSafes = {
regular = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
-- * Provide a copy of or a link to the original license (GPL-3.0 or later); see LICENSE.md or <https://www.gnu.org/licenses/>.


local SGSL = require("includes.services.SGSL")
local secondary_targets = { "CASH", "WEED", "COKE", "GOLD" }

---@class HeistStat
---@field public name string
---@field public val integer
Expand All @@ -24,28 +27,29 @@
---@field public coords vec3

---@class AgencyProperty : GenericProperty
---@class FacilityProperty : GenericProperty
---@class FieldHangarProperty : GenericProperty
---@class SubmarineProperty : GenericProperty
---@field public heading float

---@alias HEIST_TYPES table<integer, HeistInfo>

---@class YimHeists
---@class Mastermind
---@field private m_raw_data RawBusinessData
---@field private m_properties { agency: AgencyProperty, hangar: FieldHangarProperty, submarine: SubmarineProperty }
---@field private m_properties { agency: AgencyProperty, hangar: FieldHangarProperty, facility: FacilityProperty, submarine: SubmarineProperty }
---@field m_tab Tab
local YimHeists = { m_raw_data = require("includes.data.yrv3_data") }
YimHeists.__index = YimHeists
local Mastermind = { m_raw_data = require("includes.data.yrv3_data") }
Mastermind.__index = Mastermind
Mastermind.__label = "Mastermind"

---@return YimHeists
function YimHeists:init()
---@return Mastermind
function Mastermind:init()
local instance = setmetatable({
m_properties = {}
}, self)

if (Game.IsOnline()) then
ThreadManager:Run(function()
instance:ReadPropertyData()
end)
instance:ReadPropertyData()
end

Backend:RegisterEventCallback(Enums.eBackendEvent.SESSION_SWITCH, function()
Expand All @@ -58,53 +62,61 @@ end
---@param statName string
---@param statVal integer
---@param notifTitle string
function YimHeists:SkipPrep(statName, statVal, notifTitle)
function Mastermind:SkipPrep(statName, statVal, notifTitle)
stats.set_int(statName, statVal)
Notifier:ShowSuccess(notifTitle, _T("YH_PREP_SKIP_NOTIF"))
end

-- https://www.unknowncheats.me/forum/4489469-post16.html EXCEPT setting values as that's greater risk
---@param type string I or C
-- https://www.unknowncheats.me/forum/4489469-post16.html
---@param type string
---@param index integer
function YimHeists:SetSecondaryTargets(type, index)
local secondary_targets = { "CASH", "WEED", "COKE", "GOLD" }
function Mastermind:SetCayoSecTargets(type, index)
local targets = { 0, 0, 0, 0 }
targets[index] = -1

for st = 1, #secondary_targets do
for st = 1, 4 do
local stat_name = _F("MPX_H4LOOT_%s_%s", secondary_targets[st], type)
stats.set_int(stat_name, targets[st])
stats.set_int(stat_name .. "_SCOPED", targets[st])
stats.set_int(_F("%s_SCOPED", stat_name), targets[st])
end

stats.set_int("MPX_H4LOOT_PAINT", -1) -- Not really any reason to have an option for paintings
stats.set_int("MPX_H4LOOT_PAINT_SCOPED", -1)
end

---@return integer, integer
function YimHeists:GetSecondaryTargets()
local secondary_targets = { "CASH", "WEED", "COKE", "GOLD" }
local return_i
local return_c
function Mastermind:GetCayoSecTargets()
local loot_i, loot_c

for st = 1, #secondary_targets do
for st = 1, 4 do
local stat_name = _F("MPX_H4LOOT_%s", secondary_targets[st])
if (stats.get_int(stat_name .. "_I") == -1) then
return_i = st - 1 -- ImGui indexes by 0
if (stats.get_int(_F("%s_I", stat_name)) == -1) then
loot_i = st - 1 -- ImGui indexes by 0
end
if (stats.get_int(stat_name .. "_C") == -1) then
return_c = st - 1
if (stats.get_int(_F("%s_C", stat_name)) == -1) then
loot_c = st - 1
end
end

return return_i or -1, return_c or -1
return loot_i or -1, loot_c or -1
end

---@return ScriptGlobal
local function GetSubCoordsGlobal()
local coords_global = SGSL:Get(SGSL.data.submarine_global)
local pid_size = coords_global:GetOffset(1)
local offset2 = coords_global:GetOffset(2)
local vec_offset = 286 -- magic

return coords_global:AsGlobal()
:At(LocalPlayer:GetPlayerID(), pid_size)
:At(offset2)
:At(vec_offset)
end

function YimHeists:ReadPropertyData()
function Mastermind:ReadPropertyData()
ThreadManager:Run(function()
-- a better approach to this would be to read transition state.
-- I forgot how to do that so this will do.
while (script.is_active("maintransition")) do
while (Game.IsInTransition()) do
yield()
end

Expand All @@ -123,35 +135,56 @@ function YimHeists:ReadPropertyData()
end

local hangar_idx = stats.get_int("MPX_MCKENZIE_HANGAR_OWNED")
if (YRV3:IsPropertyIndexValid(hangar_idx)) then
if (hangar_idx > 0) then
local hangar_ref = self.m_raw_data.FieldHangar[1]
self.m_properties.hangar = {
name = Game.GetGXTLabel(hangar_ref.gxt),
coords = hangar_ref.coords
}
end

local facility_idx = stats.get_int("MPX_DBASE_OWNED")
if (facility_idx > 0) then
local facility_ref = self.m_raw_data.Facilities[facility_idx]
self.m_properties.facility = {
name = Game.GetGXTLabel(facility_ref.gxt),
coords = facility_ref.coords
}
end

local sub_hash = stats.get_int("MPX_IH_SUB_OWNED")
if (sub_hash == _J("kosatka")) then
local global = GetSubCoordsGlobal()
self.m_properties.submarine = {
name = Game.GetGXTLabel("CELL_SUBMARINE"),
-- TODO: I have no idea how to properly get the location of player Kosatka
--
-- It's an index in some global which also has offsets to show if its currently requested or not
-- I attempted to do the same for the acid lab truck but quickly got irritated
coords = Game.Ensure3DCoords(760) or vec3:zero()
name = Game.GetGXTLabel("CELL_SUBMARINE"),
coords = global:ReadVec3(),
heading = global:At(3):ReadFloat()
}
end
end)
end

---@return vec3
function Mastermind:GetAviLocation()
local stat = stats.get_int("MPX_M25_AVI_MISSION_CURRENT")
local blip = HUD.GET_FIRST_BLIP_INFO_ID(76)
if (blip and stat ~= 4) then
local blip_coords = HUD.GET_BLIP_INFO_ID_COORD(blip)
local forward_angle = math.rad(HUD.GET_BLIP_ROTATION(blip) + 90)
local offset = vec3:new(math.cos(forward_angle), math.sin(forward_angle), 0) -- front of payphone
return blip_coords + offset
end

return vec3:new(42.82, -1599.19, 29.60) -- final payphone
end

---@return AgencyProperty?
function YimHeists:GetAgencyProperty()
function Mastermind:GetAgencyProperty()
return self.m_properties.agency
end

---@return vec3?
function YimHeists:GetAgencyLocation()
function Mastermind:GetAgencyLocation()
local agency = self:GetAgencyProperty()
if (not agency) then
return
Expand All @@ -161,12 +194,12 @@ function YimHeists:GetAgencyLocation()
end

---@return FieldHangarProperty?
function YimHeists:GetFieldHangarProperty()
function Mastermind:GetFieldHangarProperty()
return self.m_properties.hangar
end

---@return vec3?
function YimHeists:GetFieldHangarLocation()
function Mastermind:GetFieldHangarLocation()
local hangar = self:GetFieldHangarProperty()
if (not hangar) then
return
Expand All @@ -175,20 +208,32 @@ function YimHeists:GetFieldHangarLocation()
return hangar.coords
end

---@return SubmarineProperty?
function YimHeists:HasSubmarine()
return self.m_properties.submarine
---@return FacilityProperty?
function Mastermind:GetFacilityProperty()
return self.m_properties.facility
end

-- ---@return vec3?
-- function YimHeists:GetSubmarineLocation()
-- local sub = self:HasSubmarine()
-- if (not sub) then
-- return
-- end
---@return vec3?
function Mastermind:GetFacilityLocation()
local facility = self:GetFacilityProperty()
if (not facility) then
return
end

return facility.coords
end

-- sub.coords = Game.Ensure3DCoords(760)
-- return sub.coords
-- end
---@return SubmarineProperty?
function Mastermind:GetSubmarine()
local sub = self.m_properties.submarine
if (not sub) then
return
end

local sub_global = GetSubCoordsGlobal()
sub.coords = sub_global:ReadVec3()
sub.heading = sub_global:At(3):ReadFloat()
return sub
end

return YimHeists
return Mastermind
Loading