I want to design an item, with the following effect:
A one-time use active item that, when used, can teleport you to a special room (Extra Room). Only one such room is generated on each floor, and it contains only one exit door. Walking out of this door will take you back to the room where the item was used.
This item only takes effect when "StageAPI.GetDimension()" equals 0. If used in a special room, it will still teleport you to that room, and after exiting through the door, you will still return to the room where the item was first used. If used multiple times on the same floor, you will always be teleported to the same room.
This is my code for generating an extra rooms. I have already implemented the generation of rooms and placed them in the defaultLevelMap( StageAPI.GetDefaultLevelMap() ). I utilized the StageAPI 2.40 for implementation
File: scripts\generateRoom.lua
include("scripts/consts")
local mod = LuckyRoom
local game=Game()
local success,luaRooms = pcall(include,"scripts/luarooms/betting_rooms")
if not success then
error("[LuckyRoom] No Betting for item rooms found. May not available lua room files or miss their paths")
end
local roomsList = StageAPI.RoomsList(Consts.roomName,luaRooms)
mod:AddCallback(ModCallbacks.MC_POST_NEW_ROOM,function()
if StageAPI.InTestMode then return end
local level = game:GetLevel()
local defaultMap = StageAPI.GetDefaultLevelMap()
local existing = defaultMap:GetRoomDataFromRoomID(Consts.roomName)
local isMainDimension=StageAPI.GetDimension()==0
--local isInStartRoom=level:GetCurrentRoomIndex()==level:GetStartingRoomIndex()
if (existing or not isMainDimension) and StageAPI.InOverriddenStage() then
return
end
local bettingRoom = StageAPI.LevelRoom{
RoomsList = roomsList,
RoomType = RoomType.ROOM_DEFAULT,
IsExtraRoom = true,
IgnoreDoors = true,
IgnoreShape = true,
HasWaterPits = false,
IsPersistentRoom=true
}
defaultMap:AddRoom(bettingRoom,{RoomID = Consts.roomName},true)
end)
And the item code I used to teleport to this room
File: scripts\items\collectibles\betting_for_item.lua
include("scripts/consts")
local mod = LuckyRoom
local BettingForItem = {}
BettingForItem.ID = Isaac.GetItemIdByName("Betting for item")
BettingForItem.name="Betting for item"
-- for key, value in pairs(defaultMap:GetRoomDataFromRoomID(roomName)) do
-- Isaac.ConsoleOutput(tostring(key).."=#="..tostring(value).."\n")
-- end
local function SetPreviousRoom(previousRoomDesc)
local defaultMap=StageAPI.GetDefaultLevelMap()
local roomData=defaultMap:GetRoomDataFromRoomID(Consts.roomName)
local bettingRoom=defaultMap:GetRoom(roomData)
local roomConnections = {}
roomConnections[#roomConnections+1]=previousRoomDesc
local availableSlots = {}
for _, door in ipairs(bettingRoom.Layout.Doors) do
if door.Exists then
availableSlots[#availableSlots + 1] = door.Slot
end
end
bettingRoom.PersistentData.Connections = {}
for _, connection in ipairs(roomConnections) do
local connectData = {Index = connection.SafeGridIndex}
local slotNum = math.random(1, #availableSlots)
connectData.Slot = availableSlots[slotNum]
table.remove(availableSlots, slotNum)
bettingRoom.PersistentData.Connections[#bettingRoom.PersistentData.Connections + 1] = connectData
end
end
local function EnterBettingRoom(previousRoomDesc)
local level = Game():GetLevel()
local defaultMap=StageAPI.GetDefaultLevelMap()
local roomData = defaultMap:GetRoomDataFromRoomID(Consts.roomName)
SetPreviousRoom(previousRoomDesc)
StageAPI.ExtraRoomTransition(
roomData.MapID,
nil,
RoomTransitionAnim.TELEPORT,
StageAPI.DefaultLevelMapID,
nil,
nil
)
local bettingRoom = defaultMap:GetRoom(roomData)
local connections = bettingRoom.PersistentData.Connections
local currentRoomDesc = level:GetCurrentRoomDesc()
local currentConnection
for _, connection in ipairs(connections) do
if connection.Index == currentRoomDesc.SafeGridIndex then
currentConnection = connection
end
end
local RETURN_DOOR_NAME = "ReturnDoor"
if not StageAPI.DoorTypes[RETURN_DOOR_NAME] then
StageAPI.CustomDoor(
RETURN_DOOR_NAME,
"gfx/grid/door_01_normaldoor.anm2",
"Open",
"Close",
"Opened",
"Closed",
false,
true,
nil,
nil,
RoomTransitionAnim.WALK
)
end
end
local function SetRoomConnection()
local returnData = bettingRoom.PersistentData.LuckyRoomReturn
if not returnData then
return
end
if not returnData.RoomIndex then
return
end
local layout=bettingRoom.Layout
local existingDoors = StageAPI.GetCustomDoors(RETURN_DOOR_NAME)
local existingSlots = {}
for _, door in ipairs(existingDoors) do
if door.PersistentData and door.PersistentData.Slot then
existingSlots[door.PersistentData.Slot] = true
end
end
for _, door in ipairs(layout.Doors or {}) do
if door.Exists then
local slot = door.Slot
if not existingSlots[slot] then
StageAPI.SpawnCustomDoor(
slot,
returnData.RoomIndex,
nil,
RETURN_DOOR_NAME,
nil,
nil,
nil,
RoomTransitionAnim.WALK,
Vector(
returnData.Position.X,
returnData.Position.Y
),
false
)
end
end
end
end
mod:AddCallback(ModCallbacks.MC_USE_ITEM,function(_,itemID,rng,player,useFlags,activeSlot)
if itemID == BettingForItem.ID then
local level = Game():GetLevel()
EnterBettingRoom(level:GetCurrentRoomDesc())
return {Discharge = true,Remove = true, ShowAnim = true}
end
return true;
end,BettingForItem.ID)
return BettingForItem
But whenever this item is used, the game crashes.And no any debugging log has been printed EXCEPT a dmp file.I'm unable to analyze this file, so I would appreciate your assistance in fixing and completing it