Version 1.2
[minetest_teletool.git] / init.lua
blobff5b1bf0b51a1b75d31b996cbad2798897fbb765
1 if (minetest.get_modpath("intllib")) then
2 dofile(minetest.get_modpath("intllib").."/intllib.lua")
3 S = intllib.Getter(minetest.get_current_modname())
4 else
5 S = function ( s ) return s end
6 end
8 teletool = {}
10 --[[ Load settings, apply default settings ]]
11 teletool.settings = {}
12 teletool.settings.avoid_collisions = true
13 teletool.settings.adjust_head = true
14 teletool.settings.cost_mana = 20
15 local avoid_collisions = minetest.setting_getbool("teletool_avoid_collisions")
16 if avoid_collisions ~= nil then
17 teletool.settings.avoid_collision = avoid_collisions
18 end
19 local adjust_head = minetest.setting_getbool("teletool_adjust_head")
20 if adjust_head ~= nil then
21 teletool.settings.adjust_head = adjust_head
22 end
23 local cost_mana = tonumber(minetest.setting_get("teletool_cost_mana"))
24 if cost_mana ~= nil then
25 teletool.settings.cost_mana = cost_mana
26 end
29 function teletool.teleport(player, pointed_thing)
30 local pos = pointed_thing.above
31 local src = player:getpos()
32 local dest = {x=pos.x, y=math.ceil(pos.y)-0.5, z=pos.z}
33 local over = {x=dest.x, y=dest.y+1, z=dest.z}
34 local destnode = minetest.get_node({x=dest.x, y=math.ceil(dest.y), z=dest.z})
35 local overnode = minetest.get_node({x=over.x, y=math.ceil(over.y), z=over.z})
37 if teletool.settings.adjust_head then
38 -- This trick prevents the player's head to spawn in a walkable node if the player clicked on the lower side of a node
39 -- NOTE: This piece of code must be updated as soon the collision boxes of players become configurable
40 if minetest.registered_nodes[overnode.name].walkable then
41 dest.y = dest.y - 1
42 end
43 end
45 if teletool.settings.avoid_collisions then
46 -- The destination must be collision free
47 destnode = minetest.get_node({x=dest.x, y=math.ceil(dest.y), z=dest.z})
48 if minetest.registered_nodes[destnode.name].walkable then
49 return false
50 end
51 end
53 minetest.add_particlespawner({
54 amount = 25,
55 time = 0.1,
56 minpos = {x=src.x-0.4, y=src.y+0.25, z=src.z-0.4},
57 maxpos = {x=src.x+0.4, y=src.y+0.75, z=src.z+0.4},
58 minvel = {x=-0.1, y=-0.1, z=-0.1},
59 maxvel = {x=0, y=0.1, z=0},
60 minexptime=1,
61 maxexptime=1.5,
62 minsize=1,
63 maxsize=1.25,
64 texture = "teletool_particle_departure.png",
66 minetest.sound_play( {name="teletool_teleport1", gain=1}, {pos=src, max_hear_distance=12})
68 player:setpos(dest)
69 minetest.add_particlespawner({
70 amount = 25,
71 time = 0.1,
72 minpos = {x=dest.x-0.4, y=dest.y+0.25, z=dest.z-0.4},
73 maxpos = {x=dest.x+0.4, y=dest.y+0.75, z=dest.z+0.4},
74 minvel = {x=0, y=-0.1, z=0},
75 maxvel = {x=0.1, y=0.1, z=0.1},
76 minexptime=1,
77 maxexptime=1.5,
78 minsize=1,
79 maxsize=1.25,
80 texture = "teletool_particle_arrival.png",
82 minetest.after(0.5, function(dest) minetest.sound_play( {name="teletool_teleport2", gain=1}, {pos=dest, max_hear_distance=12}) end, dest)
84 return true
85 end
87 minetest.register_tool("teletool:teletool_infinite", {
88 description = S("Infinite point teleporter"),
89 range = 20.0,
90 tool_capabilities = {},
91 wield_image = "teletool_teletool_infinite.png",
92 inventory_image = "teletool_teletool_infinite.png",
93 on_use = function(itemstack, user, pointed_thing)
94 local failure = false
95 if(pointed_thing.type == "node") then
96 failure = not teletool.teleport(user, pointed_thing)
97 else
98 failure = true
99 end
100 if failure then
101 minetest.sound_play( {name="teletool_fail", gain=0.5}, {pos=user:getpos(), max_hear_distance=4})
103 return itemstack
104 end,
105 groups = { teletool = 1 },
109 if(minetest.get_modpath("technic")) then
110 technic.register_power_tool("teletool:teletool_technic", 50000)
112 minetest.register_tool("teletool:teletool_technic", {
113 description = S("Electronic point teleporter"),
114 range = 20.0,
115 tool_capabilities = {},
116 wield_image = "teletool_teletool_technic.png",
117 inventory_image = "teletool_teletool_technic.png",
118 on_use = function(itemstack, user, pointed_thing)
119 local failure = false
120 if(pointed_thing.type == "node") then
121 local meta = minetest.deserialize(itemstack:get_metadata())
122 if not meta or not meta.charge then
123 failure = true
124 elseif meta.charge >= 1000 then
125 meta.charge = meta.charge - 1000
126 failure = not teletool.teleport(user, pointed_thing)
127 if not failure then
128 technic.set_RE_wear(itemstack, meta.charge, 50000)
129 itemstack:set_metadata(minetest.serialize(meta))
131 else
132 failure = true
134 else
135 failure = true
137 if failure then
138 minetest.sound_play( {name="teletool_fail", gain=0.5}, {pos=user:getpos(), max_hear_distance=4})
140 return itemstack
141 end,
142 groups = { teletool = 1 },
144 -- Technic data
145 wear_represents = "technic_RE_charge",
146 on_refill = technic.refill_RE_charge
150 if(minetest.get_modpath("mana") ~= nil) then
151 minetest.register_tool("teletool:teletool_mana", {
152 description = S("Magical point teleporter"),
153 range = 20.0,
154 tool_capabilities = {},
155 wield_image = "teletool_teletool_mana.png",
156 inventory_image = "teletool_teletool_mana.png",
157 on_use = function(itemstack, user, pointed_thing)
158 local failure = false
159 if(pointed_thing.type == "node") then
160 if(mana.get(user:get_player_name()) >= teletool.settings.cost_mana) then
161 failure = not teletool.teleport(user, pointed_thing)
162 if not failure then
163 failure = not mana.subtract(user:get_player_name(), teletool.settings.cost_mana)
165 else
166 failure = true
168 else
169 failure = true
171 if failure then
172 minetest.sound_play( {name="teletool_fail", gain=0.5}, {pos=user:getpos(), max_hear_distance=4})
174 return itemstack
175 end,
176 groups = { teletool = 1 },
180 if(minetest.get_modpath("default") ~= nil and minetest.get_modpath("technic") ~= nil) then
181 minetest.register_craft({
182 output = "teletool:teletool_technic",
183 recipe = {
184 {"", "default:mese_crystal", ""},
185 {"technic:stainless_steel_ingot", "technic:red_energy_crystal", "technic:stainless_steel_ingot"},
186 {"technic:stainless_steel_ingot", "technic:battery", "technic:stainless_steel_ingot"}
191 if(minetest.get_modpath("doc_items") ~= nil) then
192 local base = S("Point teleporters are short-range teleportation devices which allow the user to teleport instantly towards a block they point at.")
193 local inf = S("Infinite point teleporters are very powerful, they can be used without limits.")
194 local mana = string.format(S("Magical point teleporters are fueled by mana and require %d mana per teleportation."), teletool.settings.cost_mana)
195 local technic = S("Electronic point teleporters run on electricity and must be charged initially. Fully charged, they can be used about 50 times.")
196 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.")
197 local technicuse = S("To recharge this tool, place it in a powered battery box.")
198 local manause = string.format(S("First make sure you have at least %d mana."), teletool.settings.cost_mana)
200 local desc_inf = base .. "\n" .. inf
201 local desc_mana = base .. "\n" .. mana
202 local desc_technic = base .. "\n" .. technic
203 local use_inf = baseuse
204 local use_mana = manause .. " " .. baseuse
205 local use_technic = technicuse .. " " .. baseuse
207 doc.sub.items.set_items_longdesc({
208 ["teletool:teletool_infinite"] = desc_inf,
209 ["teletool:teletool_mana"] = desc_mana,
210 ["teletool:teletool_technic"] = desc_technic,
212 doc.sub.items.set_items_usagehelp({
213 ["teletool:teletool_infinite"] = use_inf,
214 ["teletool:teletool_mana"] = use_mana,
215 ["teletool:teletool_technic"] = use_technic,
219 minetest.register_alias("teletool:teletool", "teletool:teletool_infinite")