2020-04-05 15:06:02 -07:00
local S = minetest.get_translator ( " teletool " )
2014-07-14 07:32:20 -07:00
2020-04-05 15:03:32 -07:00
local REACH = 20.0
2014-10-12 14:23:01 -07:00
teletool = { }
2015-02-15 17:50:23 -08:00
--[[ Load settings, apply default settings ]]
2015-02-13 23:44:30 -08:00
teletool.settings = { }
2015-02-15 17:50:23 -08:00
teletool.settings . avoid_collisions = true
teletool.settings . adjust_head = true
2015-02-15 19:00:25 -08:00
teletool.settings . cost_mana = 20
2017-06-20 07:54:45 -07:00
local avoid_collisions = minetest.settings : get_bool ( " teletool_avoid_collisions " )
2015-02-15 17:50:23 -08:00
if avoid_collisions ~= nil then
teletool.settings . avoid_collision = avoid_collisions
end
2017-06-20 07:54:45 -07:00
local adjust_head = minetest.settings : get_bool ( " teletool_adjust_head " )
2015-02-15 17:50:23 -08:00
if adjust_head ~= nil then
teletool.settings . adjust_head = adjust_head
end
2017-06-20 07:54:45 -07:00
local cost_mana = tonumber ( minetest.settings : get ( " teletool_cost_mana " ) )
2015-02-15 19:00:25 -08:00
if cost_mana ~= nil then
teletool.settings . cost_mana = cost_mana
end
2015-02-15 17:50:23 -08:00
2015-02-13 23:44:30 -08:00
2014-10-12 14:23:01 -07:00
function teletool . teleport ( player , pointed_thing )
local pos = pointed_thing.above
local src = player : getpos ( )
local dest = { x = pos.x , y = math.ceil ( pos.y ) - 0.5 , z = pos.z }
2015-02-15 17:32:53 -08:00
local over = { x = dest.x , y = dest.y + 1 , z = dest.z }
local destnode = minetest.get_node ( { x = dest.x , y = math.ceil ( dest.y ) , z = dest.z } )
local overnode = minetest.get_node ( { x = over.x , y = math.ceil ( over.y ) , z = over.z } )
2015-02-15 17:50:23 -08:00
if teletool.settings . adjust_head then
-- This trick prevents the player's head to spawn in a walkable node if the player clicked on the lower side of a node
-- NOTE: This piece of code must be updated as soon the collision boxes of players become configurable
if minetest.registered_nodes [ overnode.name ] . walkable then
dest.y = dest.y - 1
end
2015-02-15 16:28:27 -08:00
end
2015-02-15 17:50:23 -08:00
if teletool.settings . avoid_collisions then
-- The destination must be collision free
destnode = minetest.get_node ( { x = dest.x , y = math.ceil ( dest.y ) , z = dest.z } )
if minetest.registered_nodes [ destnode.name ] . walkable then
return false
end
2015-02-15 16:28:27 -08:00
end
2014-10-12 15:02:22 -07:00
minetest.add_particlespawner ( {
amount = 25 ,
time = 0.1 ,
minpos = { x = src.x - 0.4 , y = src.y + 0.25 , z = src.z - 0.4 } ,
maxpos = { x = src.x + 0.4 , y = src.y + 0.75 , z = src.z + 0.4 } ,
minvel = { x =- 0.1 , y =- 0.1 , z =- 0.1 } ,
maxvel = { x = 0 , y = 0.1 , z = 0 } ,
minexptime = 1 ,
maxexptime = 1.5 ,
minsize = 1 ,
maxsize = 1.25 ,
texture = " teletool_particle_departure.png " ,
} )
2020-04-05 15:43:25 -07:00
minetest.sound_play ( { name = " teletool_teleport1 " , gain = 1 } , { pos = src , max_hear_distance = 12 } , true )
2015-02-15 16:12:25 -08:00
2014-10-12 14:23:01 -07:00
player : setpos ( dest )
2014-10-12 15:02:22 -07:00
minetest.add_particlespawner ( {
amount = 25 ,
time = 0.1 ,
minpos = { x = dest.x - 0.4 , y = dest.y + 0.25 , z = dest.z - 0.4 } ,
maxpos = { x = dest.x + 0.4 , y = dest.y + 0.75 , z = dest.z + 0.4 } ,
minvel = { x = 0 , y =- 0.1 , z = 0 } ,
maxvel = { x = 0.1 , y = 0.1 , z = 0.1 } ,
minexptime = 1 ,
maxexptime = 1.5 ,
minsize = 1 ,
maxsize = 1.25 ,
texture = " teletool_particle_arrival.png " ,
} )
2020-04-05 15:43:25 -07:00
minetest.after ( 0.5 , function ( dest ) minetest.sound_play ( { name = " teletool_teleport2 " , gain = 1 } , { pos = dest , max_hear_distance = 12 } , true ) end , dest )
2015-02-15 16:28:27 -08:00
return true
2014-10-12 14:23:01 -07:00
end
2016-11-02 15:34:36 -07:00
-- doc_items help texts
local base = S ( " Point teleporters are short-range teleportation devices which allow the user to teleport instantly towards a block they point at. " )
local inf = S ( " Infinite point teleporters are very powerful, they can be used without limits. " )
local baseuse = S ( " To use this tool, point to a face of a block and punch to teleport in front of it. The target location must have a minimum amount of space for you to stand in, otherwise, teleportation will fail. " )
local desc_inf = base .. " \n " .. inf
local use_inf = baseuse
2015-02-15 15:55:19 -08:00
minetest.register_tool ( " teletool:teletool_infinite " , {
2016-08-07 09:27:58 -07:00
description = S ( " Infinite point teleporter " ) ,
2016-11-15 21:41:39 -08:00
_doc_items_longdesc = desc_inf ,
_doc_items_usagehelp = use_inf ,
2020-04-05 15:03:32 -07:00
range = REACH ,
2014-07-14 07:32:20 -07:00
tool_capabilities = { } ,
2015-02-15 15:55:19 -08:00
wield_image = " teletool_teletool_infinite.png " ,
inventory_image = " teletool_teletool_infinite.png " ,
2014-07-14 07:32:20 -07:00
on_use = function ( itemstack , user , pointed_thing )
2015-02-13 23:11:50 -08:00
local failure = false
2014-07-14 07:32:20 -07:00
if ( pointed_thing.type == " node " ) then
2015-02-15 16:28:27 -08:00
failure = not teletool.teleport ( user , pointed_thing )
2015-02-15 15:55:19 -08:00
else
failure = true
end
if failure then
2020-04-05 15:43:25 -07:00
minetest.sound_play ( { name = " teletool_fail " , gain = 0.5 } , { pos = user : getpos ( ) , max_hear_distance = 4 } , true )
2015-02-15 15:55:19 -08:00
end
return itemstack
end ,
2018-10-16 03:58:50 -07:00
groups = { teletool = 1 , disable_repair = 1 } ,
2015-02-15 15:55:19 -08:00
} )
if ( minetest.get_modpath ( " technic " ) ) then
technic.register_power_tool ( " teletool:teletool_technic " , 50000 )
2016-11-02 15:34:36 -07:00
local technic = S ( " Electronic point teleporters run on electricity and must be charged initially. Fully charged, they can be used about 50 times. " )
local technicuse = S ( " To recharge this tool, place it in a powered battery box. " )
local desc_technic = base .. " \n " .. technic
local use_technic = technicuse .. " " .. baseuse
2015-02-15 15:55:19 -08:00
minetest.register_tool ( " teletool:teletool_technic " , {
2016-08-07 09:27:58 -07:00
description = S ( " Electronic point teleporter " ) ,
2016-11-15 21:41:39 -08:00
_doc_items_longdesc = desc_technic ,
_doc_items_usagehelp = use_technic ,
2020-04-05 15:03:32 -07:00
range = REACH ,
2015-02-15 15:55:19 -08:00
tool_capabilities = { } ,
wield_image = " teletool_teletool_technic.png " ,
inventory_image = " teletool_teletool_technic.png " ,
on_use = function ( itemstack , user , pointed_thing )
local failure = false
if ( pointed_thing.type == " node " ) then
2014-10-12 14:23:01 -07:00
local meta = minetest.deserialize ( itemstack : get_metadata ( ) )
2015-02-15 16:02:26 -08:00
if not meta or not meta.charge then
failure = true
elseif meta.charge >= 1000 then
2014-10-12 14:23:01 -07:00
meta.charge = meta.charge - 1000
2015-02-15 16:28:27 -08:00
failure = not teletool.teleport ( user , pointed_thing )
if not failure then
technic.set_RE_wear ( itemstack , meta.charge , 50000 )
itemstack : set_metadata ( minetest.serialize ( meta ) )
end
2015-02-13 23:11:50 -08:00
else
failure = true
2014-10-12 14:23:01 -07:00
end
2015-02-15 15:55:19 -08:00
else
failure = true
end
if failure then
2020-04-05 15:43:25 -07:00
minetest.sound_play ( { name = " teletool_fail " , gain = 0.5 } , { pos = user : getpos ( ) , max_hear_distance = 4 } , true )
2015-02-15 15:55:19 -08:00
end
return itemstack
end ,
2018-10-16 03:58:50 -07:00
groups = { teletool = 1 , disable_repair = 1 } ,
2015-02-15 15:55:19 -08:00
-- Technic data
wear_represents = " technic_RE_charge " ,
on_refill = technic.refill_RE_charge
} )
end
if ( minetest.get_modpath ( " mana " ) ~= nil ) then
2016-11-02 15:34:36 -07:00
local dmana = string.format ( S ( " Magical point teleporters are fueled by mana and require %d mana per teleportation. " ) , teletool.settings . cost_mana )
local manause = string.format ( S ( " First make sure you have at least %d mana. " ) , teletool.settings . cost_mana )
local desc_mana = base .. " \n " .. dmana
local use_mana = manause .. " " .. baseuse
2015-02-15 15:55:19 -08:00
minetest.register_tool ( " teletool:teletool_mana " , {
2016-08-07 09:27:58 -07:00
description = S ( " Magical point teleporter " ) ,
2016-11-15 21:41:39 -08:00
_doc_items_longdesc = desc_mana ,
_doc_items_usagehelp = use_mana ,
2020-04-05 15:03:32 -07:00
range = REACH ,
2015-02-15 15:55:19 -08:00
tool_capabilities = { } ,
wield_image = " teletool_teletool_mana.png " ,
inventory_image = " teletool_teletool_mana.png " ,
on_use = function ( itemstack , user , pointed_thing )
local failure = false
if ( pointed_thing.type == " node " ) then
2015-02-15 19:04:16 -08:00
if ( mana.get ( user : get_player_name ( ) ) >= teletool.settings . cost_mana ) then
2015-02-15 16:28:27 -08:00
failure = not teletool.teleport ( user , pointed_thing )
2015-02-15 19:04:16 -08:00
if not failure then
2015-02-15 19:13:45 -08:00
failure = not mana.subtract ( user : get_player_name ( ) , teletool.settings . cost_mana )
2015-02-15 19:04:16 -08:00
end
2015-02-13 23:44:30 -08:00
else
failure = true
end
else
failure = true
2014-10-12 14:13:53 -07:00
end
2015-02-15 15:55:19 -08:00
if failure then
2020-04-05 15:43:25 -07:00
minetest.sound_play ( { name = " teletool_fail " , gain = 0.5 } , { pos = user : getpos ( ) , max_hear_distance = 4 } , true )
2015-02-15 15:55:19 -08:00
end
return itemstack
end ,
2018-10-16 03:58:50 -07:00
groups = { teletool = 1 , disable_repair = 1 } ,
2015-02-15 15:55:19 -08:00
} )
end
2014-10-12 14:13:53 -07:00
if ( minetest.get_modpath ( " default " ) ~= nil and minetest.get_modpath ( " technic " ) ~= nil ) then
minetest.register_craft ( {
2015-02-15 15:55:19 -08:00
output = " teletool:teletool_technic " ,
2014-10-12 14:13:53 -07:00
recipe = {
{ " " , " default:mese_crystal " , " " } ,
{ " technic:stainless_steel_ingot " , " technic:red_energy_crystal " , " technic:stainless_steel_ingot " } ,
{ " technic:stainless_steel_ingot " , " technic:battery " , " technic:stainless_steel_ingot " }
}
} )
2016-11-02 15:34:36 -07:00
if ( minetest.get_modpath ( " awards " ) ~= nil ) then
awards.register_achievement ( " teletool_technic " , {
title = S ( " What an awesome device! " ) ,
description = S ( " Craft an electronic point teleporter. " ) ,
icon = " teletool_teletool_technic.png " ,
trigger = {
type = " craft " ,
item = " teletool:teletool_technic " ,
target = 1 ,
} ,
} )
end
2016-08-07 10:36:31 -07:00
end
2015-02-15 15:55:19 -08:00
minetest.register_alias ( " teletool:teletool " , " teletool:teletool_infinite " )