285 lines
14 KiB
Lua
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
|
|
}) |