diff --git a/src/scripts/mapper/mapper.lua b/src/scripts/mapper/mapper.lua index 57283bf..ed4fdcd 100644 --- a/src/scripts/mapper/mapper.lua +++ b/src/scripts/mapper/mapper.lua @@ -227,6 +227,7 @@ function lotj.mapper.startMapping(areaName) end lotj.mapper.mappingArea = areaName + lotj.mapper.lastMoveDirs = {} lotj.mapper.processCurrentRoom() end @@ -344,8 +345,11 @@ function lotj.mapper.setup() loadMap(getMudletHomeDir().."/@PKGNAME@/starter-map.dat") end + lotj.mapper.loadShipData() + lotj.setup.registerEventHandler("sysDataSendRequest", lotj.mapper.handleSentCommand) lotj.setup.registerEventHandler("gmcp.Room.Info", lotj.mapper.onEnterRoom) + lotj.setup.registerEventHandler("sysExitEvent", lotj.mapper.saveShipData) end function lotj.mapper.teardown() @@ -353,11 +357,28 @@ function lotj.mapper.teardown() geyserMapper:hide() end +function lotj.mapper.loadShipData() + local location = getMudletHomeDir() .. "/lotjmapper_ship.lua" + lotj.mapper.shipLastRoom = lotj.mapper.shipLastRoom or {} + if io.exists(location) then table.load(location, lotj.mapper.shipLastRoom) end +end + +function lotj.mapper.saveShipData() + if lotj.mapper.shipLastRoom then + local location = getMudletHomeDir() .. "/lotjmapper_ship.lua" + table.save(location, lotj.mapper.shipLastRoom) + end +end -- Track the most recent movement command so we know which direction we moved when automapping function lotj.mapper.handleSentCommand(event, cmd) - -- If we're not mapping, don't bother + -- If we're not mapping, store the last direction only for ships if lotj.mapper.mappingArea == nil then + if not gmcp.Room.Info.planet then + -- only store movement if we're actually on a ship + lotj.mapper.shipMovement = lotj.mapper.shipMovement or {} + table.insert(lotj.mapper.shipMovement, dirObj(trim(cmd))) + end return end @@ -380,6 +401,32 @@ function lotj.mapper.popMoveDir() return result end +-- Function used to handle virtual ship maps. This will process the room +-- as a ship and attempt to position a player on an existing map of the same ship. +function lotj.mapper.processCurrentRoomAsShip(roomData, movement) + local roomVnum = table.keys(roomData)[1] + local matchesMany = #table.keys(roomData) + + if matchesMany == 1 then + -- Only one room matched. + lotj.mapper.shipLastRoom = {actual = gmcp.Room.Info.vnum, virtual = roomVnum} + centerview(roomVnum) + elseif matchesMany > 1 then + -- Multiple matches + if lotj.mapper.shipLastRoom ~= nil and lotj.mapper.shipLastRoom.actual == gmcp.Room.Info.vnum then + -- This is likely a reboot. The last room and the current room match. + centerview(lotj.mapper.shipLastRoom.virtual) + elseif lotj.mapper.shipLastRoom ~= nil and movement then + -- position based on movement + local nextRoom = getRoomExits(lotj.mapper.shipLastRoom.virtual) + if table.contains(nextRoom, movement.long) then + lotj.mapper.shipLastRoom = {acutal = gmcp.Room.Info.vnum, virtual = nextRoom[movement.long]} + centerview(lotj.mapper.shipLastRoom.virtual) + end + end + end +end + -- Function used to handle a room that we've moved into. This will use the data on -- lotj.mapper.current, compared with lotj.mapper.last, to potentially create a new room and @@ -388,6 +435,25 @@ function lotj.mapper.processCurrentRoom() local vnum = lotj.mapper.current.vnum local moveDir = lotj.mapper.popMoveDir() local room = lotj.mapper.getRoomByVnum(vnum) + local searchData = searchRoom(gmcp.Room.Info.name, false, true) + + -- Only virtualize ships when we aren't actively mapping + if not gmcp.Room.Info.planet and lotj.mapper.mappingArea == nil then + if room == nil then + -- Don't virtualize if it's actually mapped + if not table.is_empty(searchData) then + if lotj.mapper.shipMovement then + lotj.mapper.processCurrentRoomAsShip(searchData, table.remove(lotj.mapper.shipMovement,1)) + else + lotj.mapper.processCurrentRoomAsShip(searchData, nil) + end + return + end + end + else + -- if we're not virtualizing, make sure this is empty + lotj.mapper.shipMovement = {} + end if lotj.mapper.mappingArea == nil and room == nil then lotj.mapper.logDebug("Room not found, but mapper not running.") @@ -399,6 +465,26 @@ function lotj.mapper.processCurrentRoom() lastRoom = lotj.mapper.getRoomByVnum(lotj.mapper.last.vnum) end + -- Try to account for moving between visible and non-visible rooms + if moveDir ~= nil then + if not table.contains(gmcp.Room.Info.exits, revDirObj(moveDir.long).long) then + -- There was no return exit in this room matching the movement + if not table.is_empty(lotj.mapper.lastMoveDirs) then + -- There are additional movements in the table so test those + while not table.is_empty(lotj.mapper.lastMoveDirs) do + local tempDir = lotj.mapper.popMoveDir() + + if table.contains(gmcp.Room.Info.exits, revDirObj(tempDir.long).long) then + -- This seems to be a match so use this one and empty out the last room as it is incorrect + moveDir = tempDir + lotj.mapper.last = nil + lastRoom = nil + end + end + end + end + end + -- Create the room if we don't have it yet if room == nil then lotj.mapper.log("Added new room: "..lotj.mapper.current.name.."")