-- 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