285 lines
14 KiB
Lua

-- CONTENTS
-- Digilines formspec
-- generate_sonic_screwdriver()
-- Generic Sonic Screwdriver
local S = minetest.get_translator("drwho_tardis")
local data = minetest.get_mod_storage()
local function get_formspec_digilines()
return "size[10,10]"..
"field[1,1;8,1;sonic_message;Message;]"..
"field[1,3;8,1;sonic_channel;Channel;]"..
"button_exit[1,6;3,3;sonic_send;Send]"
end
local sonictypes = 4 --number of variants for end, middle, and top
-- register_all_random_sonic_screwdrivers(sonictypes) is run after it is defined
local function add_sonictypes_texture(item, top, mid, bottom)
local sonicstack = ItemStack(item)
sonicstack:get_meta():set_string("inventory_image", "sonic_screwdriver.png^sonic_top_"..top..".png^sonic_mid_"..mid..".png^sonic_end_"..bottom..".png")
end
-- See API.md for more details
function drwho_tardis:register_sonic_device(def)
--def = {gentype, texture, top, mid, bottom, sonictype, customname, customdescription, no_creative}
-- create random values
-- If they are specified in def.top etc these values are overridden
local top = math.random(1,sonictypes) or def.top
local mid = math.random(1,sonictypes) or def.mid
local bottom = math.random(1,sonictypes) or def.bottom
-- Only run if given values are defined
-- Makes sure that def.top is not above sonictypes as that would result in error
if top > sonictypes then top = 1 end
if mid > sonictypes then mid = 1 end
if bottom > sonictypes then bottom = 1 end
minetest.chat_send_all(sonictypes.." top: "..top.." mid: "..mid.." bottom: "..bottom)
if def.sonictype == nil then def.sonictype = "screwdriver" end -- Default to "screwdriver"
local item_name = ""
if def.customname ~= nil then
item_name = def.customname
else
item_name = ":drwho_tardis:sonic_"..def.sonictype.."_"..top.."_"..mid.."_"..bottom
end
minetest.chat_send_all(".")
-- if playername is not given, custom description must be given.
--local item_description = def.customdescription or def.playername.."\'s Sonic Screwdriver"
local item_description = def.customdescription or S("Sonic Screwdriver (@1-@2-@3)", top, mid, bottom) -- (4-2-3)
local inventoryimage = ""
if def.gentype == "custom" then
inventoryimage = def.texture
else -- Stacked image using top, mid and bottom.
inventoryimage = "sonic_screwdriver.png^sonic_top_"..top..".png^sonic_mid_"..mid..".png^sonic_end_"..bottom..".png"
end
-- Add to appropriate item groups
def.groups = def.groups or {}
def.groups.sonic = 1
def.groups.sonic_screwdriver = def.sonictype == "screwdriver" and 1 or nil -- is sonic a screwdriver? otherwise do not add
def.groups.not_in_creative_inventory = def.no_creative == true and 1 or nil
-- set up tool capabilities
local toolcaps = def.tool_capabilities or {}
toolcaps.full_punch_interval = toolcaps.full_punch_interval or 0.5
toolcaps.groupcaps = toolcaps.groupcaps or {}
toolcaps.groupcaps.sonic = toolcaps.groupcaps.sonic or {}
local sonicgc = toolcaps.groupcaps.sonic
sonicgc.uses = sonicgc.uses or 1000 -- the higher, more durability
sonicgc.maxlevel = sonicgc.maxlevel or 1 -- the higher, more durability
-- sounds
def.sounds = def.sounds or {}
def.sounds.sonic_use = def.sounds.sonic_use or {name="sonic_sound",max_hear_distance = 10}
minetest.register_tool(item_name, {
description = item_description,
inventory_image = inventoryimage,
stack_max=1,
groups = def.groups,
tool_capabilities = toolcaps,
--------------------- ACTUAL SONIC CODE BELOW -----------------------
on_use = function(itemstack, player, pointed_thing)
local pmeta = player:get_meta()
local id = player:get_player_name()
local user = _drwho_tardis.get_user(id) -- get user data
local imeta = itemstack:get_meta()
imeta:set_string("interact", "no")
local select_pos = player:get_pos()
local sonic_add_wear = true
if pointed_thing.type == "node" then
local controls = player:get_player_control()
local node = minetest.get_node(pointed_thing.under)
local meta = minetest.get_meta(pointed_thing.under)
select_pos = pointed_thing.under
local drop = minetest.get_node_drops(node, nil)
if controls.sneak then
-- sneaking
local r_pos = user.r_pos
if user.has_a_tardis == false then
minetest.chat_send_player(id, S("You do not have a Tardis!"))
elseif r_pos.x+50 > select_pos.x and r_pos.x-50 < select_pos.x and r_pos.z+50 > select_pos.z and r_pos.z-50 < select_pos.z and r_pos.y+50 > select_pos.y and r_pos.y-50 < select_pos.y then
minetest.chat_send_player(id, "Your Tardis can not be summoned here!")
else
if user.power < 3 then minetest.chat_send_player(id, "Not Enough Power In Tardis!") else
local select_pos = pointed_thing.above
local out_pos = user.out_pos
minetest.set_node(out_pos, {name = "air"})
out_pos.x = select_pos.x
out_pos.y = select_pos.y
out_pos.z = select_pos.z
out_pos.y = out_pos.y+1
minetest.set_node(out_pos, {name = "air"})
out_pos.y = out_pos.y-1
minetest.set_node(out_pos, {name=user.exterior_skin})
local ometa = minetest.get_meta(out_pos)
ometa:set_string("id", id)
user.out_pos = out_pos
user.power = user.power - 3
local timer = minetest.get_node_timer(out_pos)
timer:start(0.5)
minetest.chat_send_player(id, S("Tardis Summoned"))
end
end
else
-- not sneaking
if id == meta:get_string("id") then
if minetest.get_item_group(node.name, "tardis") == 1 then
minetest.set_node(select_pos, {name = user.exterior_skin.."_locked"})
local ometa = minetest.get_meta(select_pos)
ometa:set_string("id", id)
minetest.chat_send_player(id, S("Tardis Locked"))
end
if minetest.get_item_group(node.name, "tardis_locked") == 1 then
minetest.set_node(select_pos, {name = user.exterior_skin})
local timer = minetest.get_node_timer(select_pos)
timer:start(0.2)
local ometa = minetest.get_meta(select_pos)
ometa:set_string("id", id)
minetest.chat_send_player(id, S("Tardis Unlocked"))
end
elseif string.match(node.name,"doors:door_steel") then
doors.door_toggle(select_pos, nil, nil)
elseif string.match(node.name,"doors:trapdoor_steel") then
doors.trapdoor_toggle(select_pos, nil, nil)
elseif node.name == "default:glass" then
minetest.set_node(select_pos, {name = "default:obsidian_glass"})
elseif node.name == "default:dirt" then
minetest.set_node(select_pos, {name = "default:dirt_with_grass"})
elseif node.name == "default:sand" then
minetest.set_node(select_pos, {name = "default:silver_sand"})
elseif node.name == "default:obsidian" then
minetest.set_node(select_pos, {name = "default:lava_source"} )
elseif minetest.get_item_group(node.name, "mesecon_conductor_craftable") == 1 then
if mesecon.is_conductor_on(node) then
mesecon.turnoff(select_pos, {0, 0, 0})
else
mesecon.turnon(select_pos, {0, 0, 0})
end
elseif drop[1] == "digilines:wire_std_00000000" then
local meta = player:get_meta()
meta:set_string("sonic_digiline", minetest.serialize(select_pos))
minetest.show_formspec(player:get_player_name(), "drwho_tardis:digilines_formspec", get_formspec_digilines() )
else
sonic_add_wear = false -- don't reduce durability
--minetest.chat_send_player(id, "not reducing durability")
return -- we can't do anything with this node
end
end
elseif pointed_thing.type == "object" then
local controls = player:get_player_control()
local obj = pointed_thing.ref
if controls.sneak then
local vpos = obj:get_pos()
select_pos = vpos
local pos = player:get_pos()
if obj:is_player() then
obj:add_player_velocity({ x = 5*(vpos.x - pos.x), y = 5*(vpos.y - pos.y), z = 5*(vpos.z - pos.z)})
else
obj:add_velocity({ x = 5*(vpos.x - pos.x), y = 5*(vpos.y - pos.y), z = 5*(vpos.z - pos.z)})
end
else
minetest.chat_send_player(id, S("Scanned subject had @1 hearts", obj:get_hp()/2))
end
else
sonic_add_wear = false -- don't reduce durability
--minetest.chat_send_player(id, "not reducing durability")
return -- not pointing to anything important, return
end
local sonic_sound = table.copy(def.sounds.sonic_use)
sonic_sound.pos = select_pos
minetest.sound_play(sonic_sound.name, sonic_sound)
if sonic_add_wear == true then
itemstack:add_wear(65535 / (sonicgc.uses * (3^(sonicgc.maxlevel-1) ) - 1 ))
--minetest.chat_send_player(id, "durability added")
end
_drwho_tardis.save_user(id, user) -- save user data if anything was changed, e.g. if Tardis is summoned out_pos is changed
return itemstack
end -- End Sonic Device on_use
})-- end Sonic Device tool registration
----------------------------- Post Registration Code ----------------------------------
---[[
if def.gentype == "custom" then
-- do nothing, it has already been set
else -- if == "choose", == "random", or not specified
add_sonictypes_texture(item_name, top, mid, bottom) -- Add correct textures using ItemStack
minetest.chat_send_all(S("Sonic Screwdriver registered with textures @1-@2-@3 and itemstring @4", top, mid, bottom, item_name))
end
--]]
minetest.register_alias(item_name:match"^.-:(.+)", item_name) -- Just in case
--minetest.register_alias(item_name, item_name:match"^.-:(.+)") -- Who knows?
return item_name
end
-- Loop through and register every random texture screwdriver, based on sonictypes value.
-- Should run each time game starts so if in a recent update new textures have been added
-- and sonictypes is increased, all the new ones will be registered automatically.
-- It also overwrites every other one, but that doesn't affect anything as it's still the same itemstring.
-- I made this before I realised that the actual error was because I was using hyphens.
local function register_all_random_sonic_screwdrivers(sonictypes)
-- NAMING SCHEME
-- drwho_tardis: sonic _screwdriver _ top _ mid _ end
-- e.g. "drwho_tardis:sonic_screwdriver_1_4_3"
-- IMPORTANT: It cannot have any hyphens (-) in the itemstring^^! So I use underscores
-- Sonic Screwdriver (top - mid - end)
-- e.g. "Sonic Screwdriver (1-4-3)"
-- We don't want (sonictypes)^3 diffferent Sonic Screwdrivers flooding the inventory!
-- So these all have no_creative = true
-- Each loop of topCount does every sonic with 1-n-n, then 2-n-n, until sonictypes is reached.
-- There are 3 loops, and they each do it (sonictypes) times, therefore (sonictypes)^3 which is exactly how many we have
for topCount = 1, sonictypes do
for midCount = 1, sonictypes do
for endCount = 1, sonictypes do
drwho_tardis:register_sonic_device({
gentype = "choose", -- Choose the combination of parts
sonictype = "screwdriver", -- Specify it is a screwdriver
top = topCount, -- Choose top texture
mid = midCount, -- Choose middle texture
bottom = endCount, -- Choose bottom texture
customname = "drwho_tardis:sonic_screwdriver_"..topCount.."_"..midCount.."_"..endCount, -- Custom name
customdescription = S("Sonic Screwdriver (@1-@2-@3)",topCount, midCount, endCount), -- Custom player-facing item name
no_creative = true, -- DON'T show up in the creative inventory - see above comment
})
end
end
end
end
register_all_random_sonic_screwdrivers(sonictypes)
-- Generic Sonic Screwdriver
drwho_tardis:register_sonic_device({
gentype = "choose", -- Choose the combination of parts
sonictype = "screwdriver", -- Specify it is a screwdriver
top = 1, -- Choose top texture
mid = 1, -- Choose middle texture
bottom = 1, -- Choose bottom texture
customname = "drwho_tardis:sonic_screwdriver", -- Custom name
customdescription = S("Sonic Screwdriver"), -- Custom player-facing item name
no_creative = false, -- The only screwdriver to show up in the creative inventory
})