--~ log("Entered minime control script!") require("util") local minime = require("__minime_temp__/common")("minime_temp") local minime_gui = require("gui") --~ local minime_gui = minime.minime_character_selector and require("gui") ------------------------------------------------------------------------------------ -- If the mod is added to an existing game, script.on_init() will be run before -- the migration script, and script.on_configuration_changed will be run after it. -- We only need to run the initialization once, so we set a flag once that's done. local game_initialized = false ------------------------------------------------------------------------------------ -- script.on_load() won't call init(), so we set separate flags if events and -- remote interface have been attached local events_attached = false local interface_attached = false ------------------------------------------------------------------------------------ -- Compile list of characters local function make_character_list() local f_name = "make_character_list" minime.dprint("Entered function " .. f_name .. "().") local chars = game.get_filtered_entity_prototypes({ {filter = "type", type = "character"} }) minime.dprint("Game characters after get_filtered_entity_prototypes: " .. serpent.block(chars)) ------------------------------------------------------------------------------------ -- Initialise list of characters with base character global.minime_characters = { ["character"] = {"", chars["character"].localised_name or chars["character"].name}, } minime.dprint("global.minime_characters: " .. serpent.block(global.minime_characters)) for c, char in pairs(chars) do if string.find( string.upper(c or ""), minime.pattern ) then global.minime_characters[c] = minime.loc_name(char) minime.dprint("ADDED character " .. serpent.line(c) .. ".") else minime.dprint("IGNORED character " .. serpent.line(c) .. ".") end end minime.dprint("End of function " .. f_name .. ".") end ------------------------------------------------------------------------------------ -- Switch characters! -- ------------------------------------------------------------------------------------ local function switch_characters(player, restore) local f_name = "switch_characters" minime.dprint("Entered function " .. f_name .. "(" .. tostring(player) .. ")") player = player and type(player) == "number" and game.players[player] or player if not (player and player.valid and player.is_player()) then error(serpent.block(player) .. " is not a valid player!") end -- Only act in default mode and god mode! if (player.controller_type == defines.controllers.character or player.controller_type == defines.controllers.god) then global.player_data[player.index].dummy = global.player_data[player.index].dummy or minime.make_dummy(player) local backup = global.player_data[player.index].dummy local old_char = player.character local new_char -- Does the player have on open character GUI? local opened_GUI = player.opened_gui_type -- GUI must be of a valid type. These types are not valid local invalid_GUI = { [defines.gui_type.item] = true, } opened_GUI = invalid_GUI[opened_GUI] and 0 or opened_GUI -- We already have a character if old_char and old_char.valid then -- Restore: Player has already switched characters with another mod, -- we just need to restore inventories/settings! if restore then minime.dprint("Restore mode: not exchanging characters!") new_char = old_char -- We have to exchange the characters! else -- Detach old character so we can create the new one player.character = nil -- Create new character player.create_character(global.player_data[player.index].last_character) new_char = player.character minime.dprint("Created new character " .. serpent.line(minime.loc_name(new_char)) .. " for player " .. serpent.line(player.name)) -- Copy inventory and settings from old to new character minime.copy_character(old_char, new_char) minime.dprint("Copied inventories and settings from " .. serpent.line(minime.loc_name(old_char)) .. " to " .. serpent.line(minime.loc_name(new_char))) -- Backup inventory and settings from old character minime.copy_character(old_char, backup) minime.dprint("Copied inventories and settings from " .. serpent.line(minime.loc_name(old_char)) .. " to " .. serpent.line(minime.loc_name(backup))) -- Remove old character old_char.destroy() minime.dprint("Removed old character!") end -- We don't have a character yet! else -- Create character player.create_character(global.player_data[player.index].last_character) new_char = player.character minime.dprint("Created new character for player " .. serpent.line(player.name)) end -- Last character may have had a smaller inventory than the current one, and we -- may be able to restore them from the backup if backup then minime.copy_character(backup, new_char) end minime.dprint("Restored character inventories and settings of character " .. serpent.line(minime.loc_name(new_char)) .. " from backup.") -- Open the GUI again if it was closed by exchanging characters player.opened = opened_GUI minime.dprint("Restored player GUI: " .. player.opened_gui_type) end minime.dprint("End of function " .. f_name .. "(" .. player.name .. ")") end ------------------------------------------------------------------------------------ -- GUI-ACTION DETECTED! -- ------------------------------------------------------------------------------------ local function on_gui_click(event) local f_name = "on_gui_click" minime.dprint("Entered function " .. f_name .. " (" .. serpent.line(event) .. ")!") local button = event.element.name if not minime.prefixed(button, "minime") then minime.dprint("Nothing to do -- leaving early!") return end local player = game.players[event.player_index] -- Toggle button was clicked if button == "minime_toggle_list" then minime.dprint(player.name .. " toggled the selection list.") minime_gui.gui_toggle(player) -- A button from the character list was clicked -- --~ elseif minime.prefixed(button, "minime_characters_") then -- Prevent changing to empty character for now! elseif minime.prefixed(button, "minime_characters_") and not (button == "minime_characters_") then minime.dprint(player.name .. " clicked button " .. serpent.line(button)) minime_gui.select_character(player, button) switch_characters(player) end minime.dprint("End of function " .. f_name .. " (" .. serpent.line(event) .. ")!") end ------------------------------------------------------------------------------------ -- REMOVE PLAYER! -- ------------------------------------------------------------------------------------ local function remove_player(event) local f_name = "remove_player" minime.dprint("Entered function " .. f_name .. "(" .. serpent.block(event) .. ")") -- We only need to act if there are characters to choose from if table_size(global.minime_characters) > 1 then local p = event.player_index local player = global.player_data[p] or {} minime_gui.remove_gui(p) end global.player_data[p] = nil minime.dprint("Removed GUI and data of player " .. game.players[p] .. "!") minime.dprint("End of function " .. f_name .. "(" .. serpent.block(event) .. ")") end ------------------------------------------------------------------------------------ -- INITIALIZE A NEW PLAYER! -- table: { player = player_arg, remove_character = remove_arg, restore = restore_arg } -- -- player_arg: player_index (number) OR player (entity) -- remove_arg (optional): anything (Will be passed on to init_gui()!) -- restore_arg (optional): anything ------------------------------------------------------------------------------------ local function init_player(event) local f_name = "init_player" minime.dprint("Entered function " .. f_name .. "(" .. serpent.line(event) .. ")") if not (event and type(event) == "table") then error("Invalid argument: " .. serpent.line(event)) end -- Mandatory argument local player = (type(event.player) == "table" and event.player) or (type(event.player) == "number" and game.players[event.player]) if not (player and player.valid and player.is_player()) then error(serpent.line(event) .. " contains no valid player data!") end -- Only proceed if player is connected! if not player.connected then minime.dprint("Player " .. player.name .. "(" .. player.index .. ")" .. " is not connected -- nothing to do!") return else minime.dprint("Player " .. player.name .. "(" .. player.index .. ")" .. " is connected -- proceeding with initialization!") end -- Optional arguments local remove_character = event.remove_character local restore = event.restore minime.dprint("global.minime_characters (" .. table_size(global.minime_characters) .. "):" .. serpent.block(global.minime_characters)) local p = player.index -- Initialize player data local player_data = global.player_data and global.player_data[p] or {} -- Check if the character that was used last still exists in the game, otherwise -- fall back to the current character, or to god mode player_data.last_character = -- The character used last time still exists (player_data.last_character and global.minime_characters[player_data.last_character] and player_data.last_character) or -- The character currently in use (e.g. if minime was loaded into an existing game) (player.character and player.character.name) or -- The player doesn't have a character (e.g. in god mode) --> empty string! "" -- If last_character is an unknown character, count it together with the names on the list -- when deciding whether to create a GUI. local name_cnt = 0 if not global.minime_characters[player_data.last_character] then name_cnt = 1 end player_data.dummy = player_data.dummy or minime.make_dummy(game.players[p]) -- Copy player_data to global table for long-term storage global.player_data[p] = player_data minime.dprint("Initialised player_data: " .. serpent.block(global.player_data[p])) global.player_data[p].show_character_list = global.player_data[p].show_character_list or false -- Characters could have been deleted from or added the game by mod changes. -- So, let's remove an existing GUI! minime_gui.remove_gui(p) minime.dprint("Removed GUI of player " .. p) -- We only want a GUI if there are characters to choose from if table_size(global.minime_characters) + name_cnt > 1 then minime_gui.init_gui(p, remove_character and true or false) minime.dprint("Made GUI for player " .. p) else minime.dprint("Only " .. tostring(table_size(global.minime_characters) + name_cnt) .. " characters are available -- no GUI is needed!") end minime.dprint("Current character: " .. serpent.line(player.character and player.character.name) .. "\nLast character: " .. serpent.line(player_data.last_character)) -- If we are not in god mode, and if the character has changed (default), switch -- to the stored character! If any value has been passed to init, this will also -- call switch_characters(), so we can restore the inventory if we react to a -- character change by another mod. if (player_data.last_character ~= "") and ((player_data.last_character ~= (player.character and player.character.name)) or restore) then minime.dprint("Switching characters: " .. tostring(player.character and player.character.name) .. " --> " .. player_data.last_character) switch_characters(p, restore and true or false) -- Otherwise just make a backup of the current character elseif player.character then -- Copy inventory and settings from old to new character minime.dprint("No need to switch characters, backing up old character!") minime.copy_character(player.character, global.player_data[p].dummy) end minime.dprint("End of function " .. f_name .. "(" .. serpent.line(event) .. ")") end ------------------------------------------------------------------------------------ -- INITIALIZE A NEW GAME! -- ------------------------------------------------------------------------------------ local function init() local f_name = "init" minime.dprint("Entered function " .. f_name .. "().") -- We need to initialize the game only once -- return if init() was already run! if game_initialized then minime.dprint("Function " .. f_name .. "() has already been run -- nothing to do!") return end ------------------------------------------------------------------------------------ -- Learned that from eradicator: It basically checks that there are no undefined -- global variables setmetatable(_ENV,{ __newindex=function (self,key,value) --locked_global_write error('\n\n[ER Global Lock] Forbidden global *write*:\n' .. serpent.line{key=key or '',value=value or ''} .. '\n') end, __index =function (self,key) --locked_global_read error('\n\n[ER Global Lock] Forbidden global *read*:\n' .. serpent.line{key=key or ''} .. '\n') end }) ------------------------------------------------------------------------------------ global = global or {} global.player_data = global.player_data or {} -- The character list will be rebuilt each time, but we need to store it in the -- global table so we can access it from gui.lua global.minime_characters = {} make_character_list() -- Create surface for placing dummy characters if not game.surfaces[minime.dummy_surface] then game.create_surface(minime.dummy_surface, {width = 1, height = 1}) minime.dprint("Created dummy surface " .. serpent.line(minime.dummy_surface)) else minime.dprint("Dummy surface already exists!") end -- Initialize players minime.dprint("Players: " .. serpent.block(game.players[1])) for p, player in pairs(game.players) do minime.dprint("Before calling init_player for " .. player.name ) init_player({ player = p }) end -- Mark game as initialized, game_initialized = true minime.dprint("End of function " .. f_name .. "().") end ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------ -- REGISTER REMOTE INTERFACES! -- ------------------------------------------------------------------------------------ local function attach_interfaces() local f_name = "attach_interfaces" log("Entered function " .. f_name .. "().") -- Need to attach interfaces if interface_attached then --~ log("Already attached remote interface -- nothing to do!") --~ return else interface_attached = true --~ log("Adding remote interface \"minime\".") remote.add_interface('minime', { -- Add a new character to the GUI -- name: character.name (string value); -- loc_name (optional): character.localised_name (defaults to name if not given) register_character = function(name, loc_name) if not (name and type(name) == "string") then error(serpent.line(name) .. " is not a valid name!") elseif (loc_name and type(loc_name) ~= "table") then error(serpent.line(loc_name) .. " is not a localised name!") end --~ log("Registering character " .. name) global.minime_characters[name] = loc_name or name for p, player in pairs(game.players) do init_player({ player = player }) end end, -- Add several new characters to the GUI (GUI will be rebuilt just once) -- table: { {name = name, loc_name = loc_name}, {name = name, loc_name = loc_name}, …} -- name: character.name (string value); -- loc_name (optional): character.localised_name (defaults to name if not given) register_characters = function(table) if not table then error(serpent.line(table) .. " is not a valid name!") end for _, char in pairs(table) do if not (char.name and type(char.name) == "string") then error(serpent.line(char.name) .. " is not a valid name!") elseif (char.loc_name and type(char.loc_name) ~= "table") then error(serpent.line(char.loc_name) .. " is not a localised name!") end minime.dprint("Registering character " .. char.name) global.minime_characters[char.name] = char.loc_name or char.name end for p, player in pairs(game.players) do init_player({ player = player }) end end, -- Remove character from GUI -- name: character.name (string value) unregister_character = function(name) if not (name and type(name) == "string") then error(serpent.line(name) .. " is not a valid name!") end minime.dprint("Removing character " .. name) global.minime_characters[name] = nil for p, player in pairs(game.players) do init_player({ player = player, remove_character = true }) end end, -- Remove several characters from GUI (GUI will be rebuilt just once) -- table: { name1, name2, …} -- name: character.name (string value) unregister_characters = function(table) if not table then error(serpent.line(table) .. " is not a valid name!") end for _, name in pairs(table) do if not (name and type(name) == "string") then error(serpent.line(name) .. " is not a valid name!") end global.minime_characters[name] = nil end for p, player in pairs(game.players) do init_player({ player = player, remove_character = true }) end end, -- A player's character will be changed -- make a backup! make_character_backup = function(player) player = player and type(player) == "number" and game.players[player] or player if not (player and player.valid and player.is_player()) then error(serpent.line(player) .. " is not a valid player!") end local char = player.character minime.dprint("Make backup of character " .. tostring(char) .. " for player " .. player.name .. "!") if char then local dummy = global.player_data[player.index].dummy or minime.make_dummy(player.index) minime.copy_character(char, dummy) end end, -- A player's character has changed player_changed_character = function(player) player = player and type(player) == "number" and game.players[player] or player if not (player and player.valid and player.is_player()) then error(serpent.line(player) .. " is not a valid player!") end local char = player.character and player.character.name minime.dpriint("Player changed character to " .. tostring(char)) if char and not global.minime_characters[char] then global.minime_characters[char] = minime.loc_name(char) end init_player({ player = player, restore = true }) end, -- Debugging: Dump contents of dummy inventory dump = function(player, inventory_list) minime.dprint("Entered function dump(" .. serpent.line(player) .. ", " .. serpent.line(inventory_list)) player = player and type(player) == "number" and game.players[player] or player if not (player and player.valid and player.is_player()) then error(serpent.line(player) .. " is not a valid player!") end local inventory_list = inventory_list and ( (type(inventory_list) == "string" and {inventory_list}) or (type(inventory_list) == "table" and inventory_list) ) or minime.inventory_list for i, inventory in pairs(inventory_list) do minime.dprint("Inventory " .. serpent.line(inventory) .. ":") local inv = defines.inventory["character_" .. inventory] local slots = global.player_data[player.index].dummy.get_inventory(inv) for x = 1, #slots do local test = slots[x].valid_for_read minime.dprint(x .. ":\t" .. serpent.line(test and slots[x].name or "NOT VALID FOR READ") .. " (" .. serpent.line(test and slots[x].count or "NOT VALID FOR READ") .. ")") end end minime.dprint("End of function dump(" .. serpent.line(player) .. ", " .. serpent.line(inventory_list)) end }) for f, _ in pairs(remote.interfaces["minime"]) do --~ log("Added function " .. serpent.line(f) .. " to remote interface \"minime\".") end end log("End of function " .. f_name .. "().") end ------------------------------------------------------------------------------------ -- UNREGISTER REMOTE INTERFACES! -- ------------------------------------------------------------------------------------ local function detach_interfaces() local f_name = "detach_interfaces" minime.dprint("Entered function " .. f_name .. "().") -- Need to attach interfaces local del = remote.remove_interface('minime') if del then local msg = "Removed remote interface!" if game then minime.dprint(msg) elseif del then log(msg) end end interface_attached = false minime.dprint("End of function " .. f_name .. "().") end ------------------------------------------------------------------------------------ -- REGISTER EVENT HANDLERS! -- ------------------------------------------------------------------------------------ local function attach_events() local f_name = "attach_events" log("Entered function " .. f_name .. "().") if events_attached then --~ log("Already attached events -- nothing to do!") else events_attached = true ------------------------------------------------------------------------------------ -- GUI-related events ------------------------------------------------------------------------------------ -- If a new player joins the game or respawns, initialize GUI and data! --~ log("Registering event handlers \"on_player_joined_game\", \"on_player_respawned\"") script.on_event({defines.events.on_player_joined_game, defines.events.on_player_respawned}, function(event) local f_name = (event.name == defines.events.on_player_joined_game and "on_player_joined_game") or (event.name == defines.events.on_player_respawned and "on_player_respawned") minime.dprint("Entered event script: " .. f_name .. " (" .. serpent.line(event) .. ").") init_player({ player = event.player_index }) minime.dprint("End of event script: " .. f_name .. " (" .. serpent.line(event) .. ").") end) ------------------------------------------------------------------------------------ -- Before a player dies, make a backup of the character! --~ log("Registering event handlers \"on_pre_player_died\", \"on_pre_player_left_game\"") script.on_event({defines.events.on_pre_player_died, defines.events.on_pre_player_left_game}, function(event) local f_name = (event.name == defines.events.on_pre_player_died and "on_pre_player_died") or (event.name == defines.events.on_pre_player_left_game and "on_pre_player_left_game") minime.dprint("Entered event script: " .. f_name .. " (" .. serpent.line(event) .. ").") local p = event.player_index local player = game.players[p] if player and player.character and global.player_data[p].dummy then minime.copy_character(game.players[p].character, global.player_data[p].dummy) minime.dprint("Made backup of character for player " .. serpent.line(player.name) .. ".") end minime.dprint("End of event script: " .. f_name .. " (" .. serpent.line(event) .. ").") end) ------------------------------------------------------------------------------------ -- If a player is removed from the game, remove his GUI and data! --~ log("Registering event handler \"on_pre_player_removed\"") script.on_event(defines.events.on_pre_player_removed, function(event) local f_name = "on_pre_player_removed" minime.dprint("Entered event script: " .. f_name .. " (" .. serpent.line(event) .. ").") remove_player(event) minime.dprint("End of event script: " .. f_name .. " (" .. serpent.line(event) .. ").") end) ------------------------------------------------------------------------------------ -- If a player leaves the game, remove just the GUI! --~ log("Registering event handler \"on_player_left_game\"") script.on_event(defines.events.on_player_left_game, function(event) local f_name = "on_player_left_game" minime.dprint("Entered event script: " .. f_name .. " (" .. serpent.line(event) .. ").") minime_gui.remove_gui(event) minime.dprint("End of event script: " .. f_name .. " (" .. serpent.line(event) .. ").") end) ------------------------------------------------------------------------------------ -- React to GUI clicks --~ log("Registering event handler \"on_gui_click\"") script.on_event(defines.events.on_gui_click, function(event) local f_name = "on_gui_click" minime.dprint("Entered event script: " .. f_name .. " (" .. serpent.line(event) .. ").") on_gui_click(event) minime.dprint("End of event script: " .. f_name .. " (" .. serpent.line(event) .. ").") end) end log("End of function " .. f_name .. "().") end ------------------------------------------------------------------------------------ -- UNREGISTER EVENT HANDLERS! -- ------------------------------------------------------------------------------------ local function detach_events() local f_name = "detach_events" minime.dprint("Entered function " .. f_name .. "().") local events = { "on_player_joined_game", "on_player_respawned", "on_pre_player_died", "on_pre_player_left_game", "on_player_left_game", "on_gui_click", } for e, event in ipairs(events) do script.on_event(defines.events[event], nil) local msg = "Detached event " .. event .. "." if game then minime.dprint(msg) else log(msg) end end events_attached = false minime.dprint("End of function " .. f_name .. "().") end ------------------------------------------------------------------------------------ -- Check if we need to attach event handlers and interfaces! -- ------------------------------------------------------------------------------------ local function must_attach() local f_name = "must_attach" minime.dprint("Entered function " .. f_name .. "()") local attach = false -- We have access to 'game', so we can poll players directly -- if they exist yet! -- In that case, they will have been initialized, so we could just check if they -- have a GUI. if game then minime.dprint("We've access to 'game' -- polling players directly!") for p, player in pairs(game.players) do minime.show(player.name, "Player " .. p) if player.gui.top["minime_gui"] then minime.dprint("Player has GUI!") attach = true break end end end -- Players may not exist yet if this was called from on_init or on_cutscene_cancelled, -- or this was called from on_load, where we don't have access to 'game'. -- Perhaps we can use stored player data? if not attach then minime.dprint("Using stored player data!") -- Check how many characters are registered local char_list = {} for name, char in pairs(global.minime_characters or {}) do char_list[name] = true end -- Do we have enough already? if table_size(char_list) > 1 then attach = true else minime.dprint("global.minime_characters: " .. serpent.block(global.minime_characters)) for p, player in pairs(global.player_data or {}) do minime.show(player, "Player " .. p) if player.last_character then minime.show(player.last_character, "player.last_character") char_list[player.last_character] = true if table_size(char_list) > 1 then minime.dprint("We've " .. table_size(char_list) .. "characters -- attach events!") attach = true break end end end end minime.show(char_list, "char_list") end minime.show(global.player_data, "global.player_data") minime.dprint("Must attach events and interfaces: " .. tostring(attach)) minime.dprint("End of function " .. f_name .. "()") return attach end ------------------------------------------------------------------------------------ -- EVENTS RELATED TO STARTING/LOADING A GAME -- ------------------------------------------------------------------------------------ -- New game script.on_init(function() local f_name = "on_init" minime.dprint("Entered script." .. f_name .. "()") -- Factorio <1.0.0 has no cutscene, so new games must be initialized in on_init if minime.check_mod_version_less("base", "1.0.0") then minime.dprint("Factorio version is less than 1.0.0 -- should try to init game!") -- Only do stuff if the GUI has been requested if minime.minime_character_selector then minime.dprint("Character selector is enabled -- will initialize game!") init() -- Only listen to events if GUI may be needed if must_attach() then attach_events() attach_interfaces() -- Single player: Explicitly detach events and interfaces again! else detach_events() detach_interfaces() end else minime.dprint("Character selector is disabled -- check if any players have a GUI.") for p, player in pairs(game.players) do minime_gui.remove_gui(player) end end else minime.dprint("Factorio version should start with a cutscene -- delaying initialization!") end minime.dprint("End of script." .. f_name .. "()") end) ------------------------------------------------------------------------------------ -- While the cutscene introduced with Factorio 1.0 is running, the player is not -- connected to a character. So, in factorio 1.0, we'll init the game after the -- cutscene has finished! ------------------------------------------------------------------------------------ --~ minime.show(minime.check_mod_version_ge("base", "1.0.0"), "minime.check_mod_version_ge(\"base\", \"1.0.0\")") if minime.check_mod_version_ge("base", "1.0.0") then log("Registering event handler \"on_cutscene_cancelled\"") script.on_event(defines.events.on_cutscene_cancelled, function() local f_name = "on_cutscene_cancelled" minime.dprint("Entered event script: " .. f_name .. " ().") -- In vanilla Factorio, the cutscene runs only once. Mods may introduce more cut- -- scenes, though, so we want to make sure this code won't be run repeatedly! if not global.cutscene_cancelled then global.cutscene_cancelled = true -- Only do stuff if the GUI has been requested if minime.minime_character_selector then minime.dprint("Character selector is enabled -- trying to initialize game!") init() -- Only listen to events if GUI may be needed. --~ if table_size(global.minime_characters) > 1 then if must_attach() then minime.dprint("Will attach event handlers and interfaces!") attach_events() attach_interfaces() -- Explicitly detach events and interfaces again! else detach_events() detach_interfaces() minime.dprint("Won't attach event handlers and interfaces!") end else minime.dprint("Character selector is disabled -- check if any players have a GUI.") for p, player in pairs(game.players) do minime_gui.remove_gui(player) end end end minime.dprint("End of event script: " .. f_name .. " ().") end) log("Done.") end -------------------------------------------------------------------------------------------- -- Configuration changed script.on_configuration_changed(function(event) local f_name = "on_configuration_changed" minime.dprint("Entered script." .. f_name .. "(" .. serpent.line(event) .. ")") -- Check if GUI setting has been changed. if event.mod_startup_settings_changed then minime.minime_character_selector = settings.startup["minime_character-selector"].value minime.dprint("Re-read startup setting. User has " .. tostring(minime.minime_character_selector and "requested" or "not requested") .. " a GUI.") end if minime.minime_character_selector then minime.dprint("Character selector is enabled -- trying to initialize the game!") init() minime.dprint("Check if we need to attach events and interfaces!") -- Attach events and interfaces only if more characters than one are available! if must_attach() then minime.dprint("Attaching event handlers and interfaces!") attach_events() attach_interfaces() -- Explicitly detach events and interfaces again! (Doing this in multiplayer will desync!) elseif not game.is_multiplayer() then detach_events() detach_interfaces() end -- Check if players already have a GUI else minime.dprint("Character selector is disabled -- check if any players have a GUI.") for p, player in pairs(game.players) do minime_gui.remove_gui(player) --~ if player.gui.top.minime_gui then --~ minime.dprint("Player " .. player.name .. " (" .. p .. ") has a GUI!") --~ player.gui.top.minime_gui.destroy() --~ minime.dprint("Removed GUI of player " .. p) --~ end end minime.dprint("Done!") end minime.dprint("End of script." .. f_name .. "(" .. serpent.line(event) .. ")") end) -------------------------------------------------------------------------------------------- -- Loaded existing game script.on_load(function() --~ log("Entered script.on_load()") if minime.minime_character_selector and must_attach() then attach_events() attach_interfaces() -- Explicitly detach events and interfaces again! else detach_events() detach_interfaces() end --~ log("End of script.on_load()") end)