253 lines
11 KiB
Lua
253 lines
11 KiB
Lua
-- API FILE
|
|
|
|
-- Does not include:
|
|
-- Sonic screwdriver (sonic.lua)
|
|
-- Exterior registering (tardis/exterior_api.lua)
|
|
|
|
-- Does include:
|
|
-- Get exterior position
|
|
-- Place Tardis interior
|
|
-- Rebuild Tardis interior
|
|
-- Locate Tardis
|
|
-- Is this node a Time Rotor?
|
|
-- Switch a Time Rotor on/off
|
|
-- Lock/Unlock Tardis exit door
|
|
-- Toggle antigrav system
|
|
|
|
--Planned:
|
|
-- Summon Tardis API
|
|
-- Waypoints
|
|
-- Power
|
|
-- and more
|
|
|
|
local data = minetest.get_mod_storage()
|
|
local S = minetest.get_translator("drwho_tardis")
|
|
drwho_tardis.get = {}
|
|
|
|
-- Returns the default depth Tardis interiors are placed at
|
|
function drwho_tardis.get:interior_depth()
|
|
return _drwho_tardis.interiorDepth
|
|
end
|
|
|
|
-- Returns the interior type of a player's Tardis
|
|
function drwho_tardis.get:interior_type(id)
|
|
local user = _drwho_tardis.get_user(id)
|
|
local type = user.console_room.type or "old"
|
|
return type
|
|
end
|
|
|
|
-- Returns the exterior position of a player's Tardis (locate_tardis)
|
|
function drwho_tardis.get:tardis_ext_position(id)
|
|
local user = _drwho_tardis.get_user(id)
|
|
if user.out_pos == nil or user.out_pos == "" then
|
|
return false, "They don't have a Tardis!", nil -- sucess, errmsg, value
|
|
end
|
|
return true, "", user.out_pos
|
|
end
|
|
|
|
-- Returns the Tardis exterior list, or an empty table if for some reason "exterior_list" doesn't exist
|
|
function drwho_tardis.get:exterior_list()
|
|
local ext_list = minetest.deserialize(data:get_string("exterior_list")) or {}
|
|
return ext_list
|
|
end
|
|
|
|
-- Returns exterior information based on it's index in the exterior_list
|
|
function drwho_tardis.get:exterior_info(index)
|
|
local ext_list = drwho_tardis.get:exterior_list()
|
|
return ext_list[index] -- if it's nil that's sad
|
|
end
|
|
|
|
-- Returns the current power levels of a player's Tardis
|
|
function drwho_tardis.get:power(id)
|
|
local user = _drwho_tardis.get_user(id)
|
|
return true, user.power, nil
|
|
end
|
|
|
|
-------------------------------------------------------------------------------------------------------
|
|
---------------------- PRIVATE API FUNCTIONS -----------------------------------------------
|
|
-------------------------------------------------------------------------------------------------------
|
|
|
|
-- [PRIVATE] Places a Tardis interior for a player (console room)
|
|
function _drwho_tardis:place_tardis_interior(id, type, pos)
|
|
if pos == nil then
|
|
return false, "Position not provided!", nil
|
|
else
|
|
local user = _drwho_tardis.get_user(id) -- get user data
|
|
if type == "custom" then
|
|
-- Assume that the given pos is where the door is going to be
|
|
user.console_room.type = type -- Save the fact their interior is custom
|
|
user.console_room.door_pos_table = {door_0 = pos} -- Remember the door position
|
|
user.console_room.door_offset_table = {door_0={x=0,y=0,z=0}} -- door offset is 0
|
|
user.in_pos = pos -- save new interior position
|
|
_drwho_tardis.save_user(id, user) -- save user data
|
|
return true, "", {door_0 = pos} -- success, message, door_pos_table
|
|
end
|
|
pos.y = _drwho_tardis.interiorDepth -- set the y pos of the interior
|
|
local exit_door_offset = {x=0,y=0,z=0}
|
|
|
|
if _drwho_tardis.rooms[type] then
|
|
minetest.place_schematic(pos, _drwho_tardis.rooms[type].path) --minetest.get_modpath("drwho_tardis") .. "/schems/console_room.mts"
|
|
exit_door_offset = _drwho_tardis.rooms[type].exit_door_offset -- = {x=7,y=2,z=16}
|
|
local exit_door_pos = vector.add(pos, exit_door_offset) -- Schematic adjustments so that the player gets teleported right in front of the door
|
|
user.console_room.type = type -- Save what type of interior they have
|
|
user.console_room.exit_door_pos = exit_door_pos -- Remember the door position
|
|
user.console_room.exit_door_offset = exit_door_offset -- Remember the door offset
|
|
user.console_room.anchor_pos = pos -- Remember the schematic place anchor pos
|
|
user.in_pos = exit_door_pos -- save new interior position
|
|
_drwho_tardis.save_user(id, user) -- save user data
|
|
return true, "", exit_door_pos -- success, message, door position
|
|
else
|
|
return false, "Invalid interior room type! Use /tardis_int to change it.", type -- success, errmsg, int_type
|
|
end
|
|
end
|
|
end
|
|
|
|
-- id is the username of the player who owns the Tardis
|
|
function _drwho_tardis:init_interior_door(id, exit_door_pos)
|
|
|
|
local d_meta = minetest.get_meta(exit_door_pos)
|
|
local d_timer = minetest.get_node_timer(exit_door_pos)
|
|
d_timer:start(0.2) --start door timer (in case it doesn't start on construct)
|
|
d_meta:set_string("id", id) --set door id
|
|
d_meta:set_string("type", "exit") -- set door type
|
|
return true, exit_door_pos
|
|
end
|
|
|
|
-- [PRIVATE] Rebuilds a player's Tardis (rebuild_tardis)
|
|
-- Can fix old interiors being too high up in the world, and fix caves running through them
|
|
function _drwho_tardis:rebuild_tardis_interior(id)
|
|
local user = _drwho_tardis.get_user(id, user) -- get user data
|
|
|
|
local in_pos = table.copy(user.in_pos)
|
|
if in_pos == "" or in_pos == nil then
|
|
return false, "You don't have a Tardis!" -- success, errmsg
|
|
end
|
|
|
|
local type = user.console_room.type
|
|
if type=="" or type==nil then type = "default" end -- defaults
|
|
local exit_door_offset = table.copy(user.console_room.exit_door_offset)
|
|
if exit_door_offset == nil or exit_door_offset == "" or exit_door_offset == {} then
|
|
exit_door_offset = _drwho_tardis.rooms[type].exit_door_offset
|
|
user.console_room.exit_door_offset = exit_door_offset
|
|
end
|
|
local exit_door_offset = user.console_room.exit_door_offset
|
|
if exit_door_offset=="" or exit_door_offset==nil then exit_door_offset = {x=7,y=2,z=16} end -- defaults
|
|
|
|
-- This ensures that the old and new line up properly
|
|
local anchor_pos = vector.subtract(in_pos, exit_door_offset)
|
|
local success, msg, exit_door_pos = _drwho_tardis:place_tardis_interior(id, type, anchor_pos)
|
|
|
|
if success == false then
|
|
_drwho_tardis.save_user(id, user) -- save user data
|
|
return false, msg, exit_door_pos -- exit_door_pos is actually the type in this situation after returned by the place API function
|
|
end
|
|
|
|
-- Interior door stuff
|
|
_drwho_tardis:init_interior_door(id, exit_door_pos)
|
|
|
|
-- Clear Time Rotor pos because that doesn't exist anymore
|
|
_drwho_tardis.update_one_value(id, "r_pos", "")
|
|
|
|
return true, "", exit_door_pos -- success!
|
|
end
|
|
|
|
-- Check if the Time Rotor is there or not
|
|
-- name is required, pos is not
|
|
function _drwho_tardis.is_time_rotor(id, pos)
|
|
local user = _drwho_tardis.get_user(id) -- get user data
|
|
local r_pos = pos or table.copy(user.r_pos)
|
|
if not r_pos or r_pos == "" or r_pos == {} then return false, "r_pos doesn't exist", r_pos end
|
|
local rmeta = minetest.get_meta(r_pos)
|
|
local rotor_node = minetest.get_node(r_pos)
|
|
|
|
if minetest.get_item_group(rotor_node.name, 'tardis_time_rotor') == 1 or
|
|
minetest.get_item_group(rotor_node.name, 'tardis_time_rotor_active') == 1 then
|
|
return true, "rotor is there", r_pos
|
|
else
|
|
return false, "rotor is not there", r_pos
|
|
end
|
|
end
|
|
|
|
-- Starts/stops time rotor animation
|
|
function _drwho_tardis.switch_time_rotor(id, on_off)
|
|
local user = _drwho_tardis.get_user(id) -- get user data
|
|
-- 'r' is the Rotor
|
|
local r_pos = table.copy(user.r_pos)
|
|
local is_it_there, msg = _drwho_tardis.is_time_rotor(id)
|
|
|
|
if is_it_there then
|
|
local rmeta = minetest.get_meta(r_pos)
|
|
local style = rmeta:get_string("style")
|
|
local rotor_node = minetest.get_node(r_pos)
|
|
if on_off == "on" then
|
|
minetest.swap_node(r_pos, {name = "drwho_tardis:rotor_active"..style })
|
|
return true, r_pos
|
|
elseif on_off == "off" then
|
|
minetest.swap_node(r_pos, {name = "drwho_tardis:rotor"..style })
|
|
return true, r_pos
|
|
end
|
|
else
|
|
minetest.chat_send_player(id, S("You need to have a Time Rotor!"))
|
|
return false, r_pos
|
|
end
|
|
end
|
|
|
|
-- locks or unlocks the interior door. if on_off is not given, it will toggle.
|
|
function _drwho_tardis.toggle_int_door(id, on_off)
|
|
local user = _drwho_tardis.get_user(id) -- get user data
|
|
local in_pos = table.copy(user.in_pos)
|
|
|
|
if on_off == "lock" then
|
|
minetest.set_node(in_pos, { name = "drwho_tardis:in_door_locked" })
|
|
local dmeta = minetest.get_meta(in_pos)
|
|
dmeta:set_string("id", id) -- set door id
|
|
dmeta:set_string("type", "exit") -- set door type
|
|
return true, "Interior door locked"
|
|
elseif on_off == "unlock" then
|
|
minetest.set_node(in_pos, { name = "drwho_tardis:in_door" })
|
|
-- Start door timer
|
|
local dtimer = minetest.get_node_timer(in_pos)
|
|
local dmeta = minetest.get_meta(in_pos)
|
|
dmeta:set_string("id", id) -- set door id
|
|
dmeta:set_string("type", "exit") -- set door type
|
|
dtimer:start(0.2) -- start door timer (in case it doesn't start on construct)
|
|
return true, "Interior door unlocked"
|
|
else -- on_off is not given, toggle door
|
|
if minetest.get_node(in_pos).name == "drwho_tardis:in_door" then
|
|
minetest.set_node(in_pos, { name = "drwho_tardis:in_door_locked" })
|
|
local dmeta = minetest.get_meta(in_pos)
|
|
dmeta:set_string("id", id) -- set door id
|
|
dmeta:set_string("type", "exit") -- set door type
|
|
return true, "Interior door locked"
|
|
else
|
|
minetest.set_node(in_pos, { name = "drwho_tardis:in_door" })
|
|
-- Start door timer
|
|
local dtimer = minetest.get_node_timer(in_pos)
|
|
local dmeta = minetest.get_meta(in_pos)
|
|
dmeta:set_string("id", id) -- set door id
|
|
dmeta:set_string("type", "exit") -- set door type
|
|
dtimer:start(0.2) -- start door timer (in case it doesn't start on construct)
|
|
return true, "Interior door unlocked"
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
-- Toggle the antigrav system
|
|
-- returns success, status
|
|
function _drwho_tardis.toggle_mavity(id)
|
|
local user = _drwho_tardis.get_user(id) -- get user data
|
|
local msg
|
|
if user.respect_mavity == "yes" then -- It's on, turn it off
|
|
user.respect_mavity = "no"
|
|
msg = "Antigrav system disabled"
|
|
elseif user.respect_mavity == "no" then -- It's off, set to sink
|
|
user.respect_mavity = "sink" -- sink in liquids mode
|
|
msg = "Antigrav system enabled and set to sink in liquids"
|
|
else -- it's "sink" or nil; turn it on
|
|
user.respect_mavity = "yes"
|
|
msg = "Antigrav system enabled but won't sink in water"
|
|
end
|
|
_drwho_tardis.save_user(id, user) -- save user data
|
|
return true, msg
|
|
end |