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