Change doc_items format, add award
[minetest_teletool.git] / init.lua
blob081e8d1bfcca6e298a0b8de4a692cdd85a011bdb
1 local S
2 if (minetest.get_modpath("intllib")) then
3 dofile(minetest.get_modpath("intllib").."/intllib.lua")
4 S = intllib.Getter(minetest.get_current_modname())
5 else
6 S = function ( s ) return s end
7 end
9 teletool = {}
11 --[[ Load settings, apply default settings ]]
12 teletool.settings = {}
13 teletool.settings.avoid_collisions = true
14 teletool.settings.adjust_head = true
15 teletool.settings.cost_mana = 20
16 local avoid_collisions = minetest.setting_getbool("teletool_avoid_collisions")
17 if avoid_collisions ~= nil then
18 teletool.settings.avoid_collision = avoid_collisions
19 end
20 local adjust_head = minetest.setting_getbool("teletool_adjust_head")
21 if adjust_head ~= nil then
22 teletool.settings.adjust_head = adjust_head
23 end
24 local cost_mana = tonumber(minetest.setting_get("teletool_cost_mana"))
25 if cost_mana ~= nil then
26 teletool.settings.cost_mana = cost_mana
27 end
30 function teletool.teleport(player, pointed_thing)
31 local pos = pointed_thing.above
32 local src = player:getpos()
33 local dest = {x=pos.x, y=math.ceil(pos.y)-0.5, z=pos.z}
34 local over = {x=dest.x, y=dest.y+1, z=dest.z}
35 local destnode = minetest.get_node({x=dest.x, y=math.ceil(dest.y), z=dest.z})
36 local overnode = minetest.get_node({x=over.x, y=math.ceil(over.y), z=over.z})
38 if teletool.settings.adjust_head then
39 -- This trick prevents the player's head to spawn in a walkable node if the player clicked on the lower side of a node
40 -- NOTE: This piece of code must be updated as soon the collision boxes of players become configurable
41 if minetest.registered_nodes[overnode.name].walkable then
42 dest.y = dest.y - 1
43 end
44 end
46 if teletool.settings.avoid_collisions then
47 -- The destination must be collision free
48 destnode = minetest.get_node({x=dest.x, y=math.ceil(dest.y), z=dest.z})
49 if minetest.registered_nodes[destnode.name].walkable then
50 return false
51 end
52 end
54 minetest.add_particlespawner({
55 amount = 25,
56 time = 0.1,
57 minpos = {x=src.x-0.4, y=src.y+0.25, z=src.z-0.4},
58 maxpos = {x=src.x+0.4, y=src.y+0.75, z=src.z+0.4},
59 minvel = {x=-0.1, y=-0.1, z=-0.1},
60 maxvel = {x=0, y=0.1, z=0},
61 minexptime=1,
62 maxexptime=1.5,
63 minsize=1,
64 maxsize=1.25,
65 texture = "teletool_particle_departure.png",
67 minetest.sound_play( {name="teletool_teleport1", gain=1}, {pos=src, max_hear_distance=12})
69 player:setpos(dest)
70 minetest.add_particlespawner({
71 amount = 25,
72 time = 0.1,
73 minpos = {x=dest.x-0.4, y=dest.y+0.25, z=dest.z-0.4},
74 maxpos = {x=dest.x+0.4, y=dest.y+0.75, z=dest.z+0.4},
75 minvel = {x=0, y=-0.1, z=0},
76 maxvel = {x=0.1, y=0.1, z=0.1},
77 minexptime=1,
78 maxexptime=1.5,
79 minsize=1,
80 maxsize=1.25,
81 texture = "teletool_particle_arrival.png",
83 minetest.after(0.5, function(dest) minetest.sound_play( {name="teletool_teleport2", gain=1}, {pos=dest, max_hear_distance=12}) end, dest)
85 return true
86 end
88 -- doc_items help texts
89 local base = S("Point teleporters are short-range teleportation devices which allow the user to teleport instantly towards a block they point at.")
90 local inf = S("Infinite point teleporters are very powerful, they can be used without limits.")
91 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.")
92 local desc_inf = base .. "\n" .. inf
93 local use_inf = baseuse
95 minetest.register_tool("teletool:teletool_infinite", {
96 description = S("Infinite point teleporter"),
97 x_doc_items_longdesc = desc_inf,
98 x_doc_items_usagehelp = use_inf,
99 range = 20.0,
100 tool_capabilities = {},
101 wield_image = "teletool_teletool_infinite.png",
102 inventory_image = "teletool_teletool_infinite.png",
103 on_use = function(itemstack, user, pointed_thing)
104 local failure = false
105 if(pointed_thing.type == "node") then
106 failure = not teletool.teleport(user, pointed_thing)
107 else
108 failure = true
110 if failure then
111 minetest.sound_play( {name="teletool_fail", gain=0.5}, {pos=user:getpos(), max_hear_distance=4})
113 return itemstack
114 end,
115 groups = { teletool = 1 },
119 if(minetest.get_modpath("technic")) then
120 technic.register_power_tool("teletool:teletool_technic", 50000)
122 local technic = S("Electronic point teleporters run on electricity and must be charged initially. Fully charged, they can be used about 50 times.")
123 local technicuse = S("To recharge this tool, place it in a powered battery box.")
124 local desc_technic = base .. "\n" .. technic
125 local use_technic = technicuse .. " " .. baseuse
127 minetest.register_tool("teletool:teletool_technic", {
128 description = S("Electronic point teleporter"),
129 x_doc_items_longdesc = desc_technic,
130 x_doc_items_usagehelp = use_technic,
131 range = 20.0,
132 tool_capabilities = {},
133 wield_image = "teletool_teletool_technic.png",
134 inventory_image = "teletool_teletool_technic.png",
135 on_use = function(itemstack, user, pointed_thing)
136 local failure = false
137 if(pointed_thing.type == "node") then
138 local meta = minetest.deserialize(itemstack:get_metadata())
139 if not meta or not meta.charge then
140 failure = true
141 elseif meta.charge >= 1000 then
142 meta.charge = meta.charge - 1000
143 failure = not teletool.teleport(user, pointed_thing)
144 if not failure then
145 technic.set_RE_wear(itemstack, meta.charge, 50000)
146 itemstack:set_metadata(minetest.serialize(meta))
148 else
149 failure = true
151 else
152 failure = true
154 if failure then
155 minetest.sound_play( {name="teletool_fail", gain=0.5}, {pos=user:getpos(), max_hear_distance=4})
157 return itemstack
158 end,
159 groups = { teletool = 1 },
161 -- Technic data
162 wear_represents = "technic_RE_charge",
163 on_refill = technic.refill_RE_charge
167 if(minetest.get_modpath("mana") ~= nil) then
168 local dmana = string.format(S("Magical point teleporters are fueled by mana and require %d mana per teleportation."), teletool.settings.cost_mana)
169 local manause = string.format(S("First make sure you have at least %d mana."), teletool.settings.cost_mana)
170 local desc_mana = base .. "\n" .. dmana
171 local use_mana = manause .. " " .. baseuse
173 minetest.register_tool("teletool:teletool_mana", {
174 description = S("Magical point teleporter"),
175 x_doc_items_longdesc = desc_mana,
176 x_doc_items_usagehelp = use_mana,
177 range = 20.0,
178 tool_capabilities = {},
179 wield_image = "teletool_teletool_mana.png",
180 inventory_image = "teletool_teletool_mana.png",
181 on_use = function(itemstack, user, pointed_thing)
182 local failure = false
183 if(pointed_thing.type == "node") then
184 if(mana.get(user:get_player_name()) >= teletool.settings.cost_mana) then
185 failure = not teletool.teleport(user, pointed_thing)
186 if not failure then
187 failure = not mana.subtract(user:get_player_name(), teletool.settings.cost_mana)
189 else
190 failure = true
192 else
193 failure = true
195 if failure then
196 minetest.sound_play( {name="teletool_fail", gain=0.5}, {pos=user:getpos(), max_hear_distance=4})
198 return itemstack
199 end,
200 groups = { teletool = 1 },
204 if(minetest.get_modpath("default") ~= nil and minetest.get_modpath("technic") ~= nil) then
205 minetest.register_craft({
206 output = "teletool:teletool_technic",
207 recipe = {
208 {"", "default:mese_crystal", ""},
209 {"technic:stainless_steel_ingot", "technic:red_energy_crystal", "technic:stainless_steel_ingot"},
210 {"technic:stainless_steel_ingot", "technic:battery", "technic:stainless_steel_ingot"}
213 if(minetest.get_modpath("awards") ~= nil) then
214 awards.register_achievement("teletool_technic", {
215 title = S("What an awesome device!"),
216 description = S("Craft an electronic point teleporter."),
217 icon = "teletool_teletool_technic.png",
218 trigger = {
219 type = "craft",
220 item = "teletool:teletool_technic",
221 target = 1,
227 minetest.register_alias("teletool:teletool", "teletool:teletool_infinite")