241 lines
7.9 KiB
Lua
241 lines
7.9 KiB
Lua
-- RVReassignAddon.lua
|
|
if isServer() then return end
|
|
|
|
local RVReassignAddon = {}
|
|
local SERVER_MODULE = "PROJECTRVTools"
|
|
local SERVER_COMMAND_REASSIGN = "ReassignVehicleToCurrentRoom"
|
|
local CLIENT_COMMAND_RESULT = "ReassignVehicleResult"
|
|
|
|
-- Get the room type based on the player's coordinates
|
|
local function getRoomTypeAtPosition(x, y, z)
|
|
local RV = require("RVVehicleTypes")
|
|
local VehicleTypes = RV.VehicleTypes
|
|
|
|
for roomType, typeDef in pairs(VehicleTypes) do
|
|
for _, room in ipairs(typeDef.rooms) do
|
|
local roomEndX = room.x + (typeDef.roomWidth or 2)
|
|
local roomEndY = room.y + (typeDef.roomHeight or 3)
|
|
|
|
if x >= room.x and x < roomEndX and
|
|
y >= room.y and y < roomEndY and
|
|
z == (room.z or 0) then
|
|
return roomType, room, typeDef
|
|
end
|
|
end
|
|
end
|
|
return nil, nil, nil
|
|
end
|
|
|
|
-- Reassign the vehicle to the current room
|
|
local function reassignVehicleToCurrentRoom(player)
|
|
local modData = ModData.getOrCreate("modPROJECTRVInterior")
|
|
local pmd = player:getModData()
|
|
|
|
-- Verify the player has a recently tracked vehicle
|
|
if not pmd.projectRV_playerId then
|
|
player:Say("No recent vehicle is registered.")
|
|
return
|
|
end
|
|
|
|
local playerData = modData.Players and modData.Players[pmd.projectRV_playerId]
|
|
if not playerData or not playerData.VehicleId then
|
|
player:Say("No recent vehicle was found.")
|
|
return
|
|
end
|
|
|
|
local vehicleId = playerData.VehicleId
|
|
local originalVehicleType = playerData.RoomType or "normal"
|
|
|
|
if not vehicleId then
|
|
player:Say("Vehicle data is incomplete.")
|
|
return
|
|
end
|
|
|
|
-- Get the current room where the player is standing
|
|
local x, y, z = player:getX(), player:getY(), player:getZ()
|
|
local newRoomType, newRoom, newTypeDef = getRoomTypeAtPosition(x, y, z)
|
|
|
|
if not newRoom then
|
|
player:Say("You are not in a valid room.")
|
|
return
|
|
end
|
|
|
|
-- Remove the previous assignment from the original room type table
|
|
local originalAssignedKey = (originalVehicleType == "normal") and "AssignedRooms" or ("AssignedRooms" .. originalVehicleType)
|
|
if modData[originalAssignedKey] then
|
|
modData[originalAssignedKey][vehicleId] = nil
|
|
end
|
|
|
|
-- Assign the new room in the new type table
|
|
local newAssignedKey = (newRoomType == "normal") and "AssignedRooms" or ("AssignedRooms" .. newRoomType)
|
|
modData[newAssignedKey] = modData[newAssignedKey] or {}
|
|
modData[newAssignedKey][vehicleId] = newRoom
|
|
|
|
-- Update player-linked vehicle type data
|
|
playerData.RoomType = newRoomType
|
|
playerData.ActualRoom = newRoom
|
|
|
|
-- Update vehicle modData type if the vehicle is currently loaded
|
|
local vehicles = getCell():getVehicles()
|
|
for i = 0, vehicles:size() - 1 do
|
|
local vehicle = vehicles:get(i)
|
|
local vmd = vehicle:getModData()
|
|
if vmd.projectRV_uniqueId and tostring(vmd.projectRV_uniqueId) == vehicleId then
|
|
vmd.projectRV_type = newRoomType
|
|
break
|
|
end
|
|
end
|
|
|
|
-- Also persist the override for cases where the vehicle is not loaded
|
|
modData.VehicleTypeOverrides = modData.VehicleTypeOverrides or {}
|
|
modData.VehicleTypeOverrides[vehicleId] = newRoomType
|
|
|
|
player:Say("Vehicle reassigned to room type: " .. newRoomType)
|
|
|
|
-- Debug
|
|
print(string.format("[RVReassign] Vehicle %s (original: %s) reassigned to room type %s: x=%d, y=%d, z=%d",
|
|
vehicleId, originalVehicleType, newRoomType, newRoom.x, newRoom.y, newRoom.z))
|
|
end
|
|
|
|
local function requestReassignVehicleToCurrentRoom(player)
|
|
if isClient() then
|
|
sendClientCommand(SERVER_MODULE, SERVER_COMMAND_REASSIGN, {})
|
|
return
|
|
end
|
|
|
|
reassignVehicleToCurrentRoom(player)
|
|
end
|
|
|
|
-- Check whether the player is inside a valid room
|
|
local function isPlayerInValidRoom(player)
|
|
local x, y, z = player:getX(), player:getY(), player:getZ()
|
|
local roomType, room, typeDef = getRoomTypeAtPosition(x, y, z)
|
|
return roomType ~= nil, roomType, room
|
|
end
|
|
|
|
-- Get info for the player's most recent tracked vehicle
|
|
local function getLastVehicleInfo(player)
|
|
local modData = ModData.getOrCreate("modPROJECTRVInterior")
|
|
local pmd = player:getModData()
|
|
|
|
if not pmd.projectRV_playerId then
|
|
return nil, nil, nil
|
|
end
|
|
|
|
local playerData = modData.Players and modData.Players[pmd.projectRV_playerId]
|
|
if not playerData then
|
|
return nil, nil, nil
|
|
end
|
|
|
|
return playerData.VehicleId, playerData.RoomType, playerData.ActualRoom
|
|
end
|
|
|
|
local function canUseReassignInMP(player)
|
|
if not isClient() then
|
|
return false
|
|
end
|
|
|
|
local pmd = player:getModData()
|
|
return pmd and pmd.projectRV_playerId ~= nil
|
|
end
|
|
|
|
-- Main function that adds the context menu option
|
|
local function addReassignOption(player, context)
|
|
local inRoom, roomType, room = isPlayerInValidRoom(player)
|
|
|
|
if not inRoom then
|
|
return
|
|
end
|
|
|
|
local vehicleId, currentRoomType, currentRoom = getLastVehicleInfo(player)
|
|
|
|
if not vehicleId and not canUseReassignInMP(player) then
|
|
return
|
|
end
|
|
|
|
-- Add the option to the context menu
|
|
local optionText
|
|
if currentRoomType and currentRoomType ~= roomType then
|
|
optionText = getText("ContextMenu_ReassignVehicleToRoomDifferent") or
|
|
string.format("Reassign vehicle (%s) to this room (%s)", currentRoomType, roomType)
|
|
else
|
|
optionText = getText("ContextMenu_ReassignVehicleToRoom") or "Reassign vehicle to this room"
|
|
end
|
|
|
|
context:addOption(optionText, player, requestReassignVehicleToCurrentRoom)
|
|
end
|
|
|
|
-- Hook for world-object context menu
|
|
local function onFillWorldObjectContextMenu(player, context, worldObjects)
|
|
local playerObj = getSpecificPlayer(player)
|
|
if playerObj then
|
|
addReassignOption(playerObj, context)
|
|
end
|
|
end
|
|
|
|
-- Hook for inventory context menu
|
|
local function onFillInventoryObjectContextMenu(player, context, items)
|
|
local playerObj = getSpecificPlayer(player)
|
|
if playerObj then
|
|
addReassignOption(playerObj, context)
|
|
end
|
|
end
|
|
|
|
-- Apply saved type overrides when a vehicle is created/loaded
|
|
local function onVehicleCreate(vehicle)
|
|
local modData = ModData.getOrCreate("modPROJECTRVInterior")
|
|
local vmd = vehicle:getModData()
|
|
|
|
if vmd.projectRV_uniqueId and modData.VehicleTypeOverrides then
|
|
local vehicleId = tostring(vmd.projectRV_uniqueId)
|
|
if modData.VehicleTypeOverrides[vehicleId] then
|
|
vmd.projectRV_type = modData.VehicleTypeOverrides[vehicleId]
|
|
end
|
|
end
|
|
end
|
|
|
|
local function onServerCommand(module, command, args)
|
|
if module ~= SERVER_MODULE or command ~= CLIENT_COMMAND_RESULT then
|
|
return
|
|
end
|
|
|
|
local player = getPlayer()
|
|
if not player then
|
|
return
|
|
end
|
|
|
|
if args and args.message then
|
|
player:Say(tostring(args.message))
|
|
end
|
|
end
|
|
|
|
-- Initialize the addon
|
|
local function initReassignAddon()
|
|
Events.OnFillWorldObjectContextMenu.Add(onFillWorldObjectContextMenu)
|
|
Events.OnFillInventoryObjectContextMenu.Add(onFillInventoryObjectContextMenu)
|
|
Events.OnVehicleCreate.Add(onVehicleCreate)
|
|
Events.OnServerCommand.Add(onServerCommand)
|
|
|
|
print("[RVReassignAddon] Vehicle reassignment addon loaded successfully")
|
|
end
|
|
|
|
-- Load fallback translations if needed
|
|
local function loadTranslations()
|
|
if getText and getText("ContextMenu_ReassignVehicleToRoom") == "ContextMenu_ReassignVehicleToRoom" then
|
|
-- If translation key is missing, define English fallback values
|
|
-- Add additional localized values here if needed
|
|
local translations = {
|
|
ContextMenu_ReassignVehicleToRoom = "Reassign vehicle to this room",
|
|
ContextMenu_ReassignVehicleToRoomDifferent = "Reassign vehicle to this room (type change)"
|
|
}
|
|
end
|
|
end
|
|
|
|
-- Initialize when the game starts
|
|
Events.OnGameStart.Add(function()
|
|
loadTranslations()
|
|
initReassignAddon()
|
|
end)
|
|
|
|
return RVReassignAddon
|