Codebase list minetest-mod-throwing / 77007512-7029-4f52-9300-ecbf64917afd/upstream
Import upstream version 1.1+git20200814.1.31f0cf5 Debian Janitor 2 years ago
6 changed file(s) with 91 addition(s) and 36 deletion(s). Raw diff Collapse all Expand all
0 std = "lua51+minetest"
1 unused_args = false
2 allow_defined_top = true
3 max_line_length = 999
4
5 stds.minetest = {
6 read_globals = {
7 "minetest",
8 "VoxelManip",
9 "VoxelArea",
10 "PseudoRandom",
11 "ItemStack",
12 "default",
13 table = {
14 fields = {
15 "copy",
16 },
17 },
18 }
19 }
20
21 read_globals = {
22 "toolranks",
23 "toolranks_extras",
24 "wielded_light",
25 }
3535
3636 By default, the trajectory of the arrow is a simple parabola. You can set the vertical acceleration (acceleration of gravity) using `throwing.vertical_acceleration`.
3737
38 If you want a more realistic trajectory that uses a first-order modelling of air friction, you can set `throwing.realistic_trajectory` to true. In this mode, `throwing.frictional_coefficient` indicates the ratio between the friction force on the arrow and its velocity. It should be negative. The acceleration of the arrow is subsequently determined by dividing the force by the "mass" of the arrow, the reference mass of 1 being the mass of a simple steel arrow. Generally, the frictional coefficient should be quite small; a value of -1 will already drastically shorten the range of the arrow. The default is -0.5.
38 If you want a more realistic trajectory that uses a first-order modelling of air friction, you can set `throwing.realistic_trajectory` to true. In this mode, `throwing.frictional_coefficient` indicates the ratio between the friction force on the arrow and its velocity. It should be negative. The acceleration of the arrow is subsequently determined by dividing the force by the "mass" of the arrow, the reference mass of 1 being the mass of the steel arrow in `throwing_arrows`. Generally, the frictional coefficient should be quite small; a value of -1 will already drastically shorten the range of the arrow. The default is -0.5.
3939
4040 ### Initial velocity computation
4141
42 The mod provides three modes to compute the initial speed of an arrow: simple, strength or strengthmass.
42 The mod provides three modes to compute the initial velocity of an arrow after it is shot: simple, strength and momentum.
4343
44 In simple mode, the initial velocity of the arrow is always the same. The `throwing.velocity_factor` contains the value of this velocity.
44 In simple mode, the initial velocity of the arrow is always the same. The value of this velocity is controlled by the `throwing.velocity_factor` setting, which defaults to 19.
4545
46 In strength mode (the default), the initial velocity of the arrow only depends on the bow that is used---the more expensive the bow, the faster the arrow. The arrow strength is multiplied by the velocity factor to compute the speed of the arrow, an arrow strength of 1 is about the strength of the steel bow in `throwing_arrows`.
46 In strength mode (the default), the initial velocity of the arrow only depends on the bow that is used---the more expensive the bow, the faster the arrow. The bow strength is multiplied by the velocity factor to compute the speed of the arrow. For reference, the steel bow in `throwing_arrows` has a strength of about 1.
4747
4848 Finally, momentum mode is the most realistic. It computes the velocity of the arrow based on the bow strength, as in the strength mode, and on the mass of the arrow: the heavier the arrow, the slower it will be shot. It is called the momentum mode because, in this mode, the strength of a bow indicates the initial momentum of the arrow rather than its initial speed.
4949
7575 * sound: sound to be played when the bow is used
7676 * delay: delay before throwing the arrow
7777 * no_toolranks: If true, toolranks support is disabled for this item. Defaults to false.
78 * strength: strength of the bow, see above. Defaults to 1.
7879 ]]
7980
8081 -- Example:
9293 * tiles (essential): tiles of the arrow.
9394 * target (optional, defaulting to throwing.target_both): what the arrow is able to hit (throwing.target_node, throwing.target_object, throwing.target_both).
9495 * allow_protected (optional, defaulting to false): whether the arrow can be throw in a protected area
96 * mass (optional, defaulting to 1): the mass of the arrow (see above)
9597 * on_hit_sound (optional): sound played when the arrow hits a node or an object.
9698 * on_hit(self, pos, last_pos, node, object, hitter, data) (optional but very useful): callback function:
9799 - pos: the position of the hit node or object.
66 throwing.target_both = 3
77
88 throwing.modname = minetest.get_current_modname()
9 local S = minetest.get_translator("throwing")
910 local use_toolranks = minetest.get_modpath("toolranks") and minetest.settings:get_bool("throwing.toolranks", true)
1011
1112 --------- Arrows functions ---------
2324 return minetest.registered_items[arrow].throwing_entity(pos, player)
2425 end
2526 else
26 obj = minetest.add_entity(pos, "__builtin:item", arrow)
27 return minetest.add_entity(pos, "__builtin:item", arrow)
2728 end
2829 end
2930
108109 end
109110
110111 if not minetest.settings:get_bool("creative_mode") then
111 if new_stack then
112 inventory:set_stack("main", arrrow_index, new_stack)
113 else
114 local stack = inventory:get_stack("main", arrow_index)
115 stack:take_item()
116 inventory:set_stack("main", arrow_index, stack)
117 end
112 inventory:set_stack("main", arrow_index, new_stack)
118113 end
119114
120115 return true
134129 minetest.log(level or "action", "[throwing] Arrow "..(self.item or self.name).." throwed by player "..self.player.." "..tostring(self.timer).."s ago "..message)
135130 end
136131
137 local hit = function(pos, node, obj)
132 local hit = function(pos1, node1, obj)
138133 if obj then
139134 if obj:is_player() then
140135 if obj:get_player_name() == self.player then -- Avoid hitting the hitter
153148 player:get_inventory():add_item("main", self.item)
154149 end
155150 if self.on_hit_fails then
156 self:on_hit_fails(pos, player, self.data)
151 self:on_hit_fails(pos1, player, self.data)
157152 end
158153 end
159154
163158 return
164159 end
165160
166 if node and minetest.is_protected(pos, self.player) and not self.allow_protected then -- Forbid hitting nodes in protected areas
167 minetest.record_protection_violation(pos, self.player)
161 if node1 and minetest.is_protected(pos1, self.player) and not self.allow_protected then -- Forbid hitting nodes in protected areas
162 minetest.record_protection_violation(pos1, self.player)
168163 logging("hitted a node into a protected area")
169164 return
170165 end
171166
172167 if self.on_hit then
173 local ret, reason = self:on_hit(pos, self.last_pos, node, obj, player, self.data)
168 local ret, reason = self:on_hit(pos1, self.last_pos, node1, obj, player, self.data)
174169 if ret == false then
175170 if reason then
176171 logging(": on_hit function failed for reason: "..reason)
184179 end
185180
186181 if self.on_hit_sound then
187 minetest.sound_play(self.on_hit_sound, {pos = pos, gain = 0.8})
188 end
189 if node then
190 logging("collided with node "..node.name.." at ("..pos.x..","..pos.y..","..pos.z..")")
182 minetest.sound_play(self.on_hit_sound, {pos = pos1, gain = 0.8})
183 end
184
185 local identifier
186 if node1 then
187 identifier = "node " .. node1.name
191188 elseif obj then
192189 if obj:get_luaentity() then
193 logging("collided with luaentity "..obj:get_luaentity().name.." at ("..pos.x..","..pos.y..","..pos.z..")")
190 identifier = "luaentity " .. obj:get_luaentity().name
194191 elseif obj:is_player() then
195 logging("collided with player "..obj:get_player_name().." at ("..pos.x..","..pos.y..","..pos.z..")")
192 identifier = "player " .. obj:get_player_name()
196193 else
197 logging("collided with object at ("..pos.x..","..pos.y..","..pos.z..")")
198 end
194 identifier = "unknown object"
195 end
196 end
197 if identifier then
198 logging("collided with " .. identifier .. " at " .. minetest.pos_to_string(pos1) .. ")")
199199 end
200200
201201 -- Toolranks support: update bow uses
202202 if self.toolranks then
203203 local inventory = player:get_inventory()
204204 -- Check that the player did not move the bow
205 if inventory:get_stack("main", self.toolranks.index):get_name() == self.toolranks.itemstack:get_name() then
206 local new_itemstack = toolranks.new_afteruse(self.toolranks.itemstack, player, nil, {wear = self.toolranks.wear})
205 local current_stack = inventory:get_stack("main", self.toolranks.index)
206 if current_stack:get_name() == self.toolranks.name then
207 local new_itemstack = toolranks.new_afteruse(current_stack, player, nil, {wear = self.toolranks.wear})
207208 inventory:set_stack("main", self.toolranks.index, new_itemstack)
208209 end
209210 end
294295 if minetest.settings:get_bool("throwing.allow_arrow_placing") and pointed_thing.above then
295296 local playername = placer:get_player_name()
296297 if not minetest.is_protected(pointed_thing.above, playername) then
297 minetest.log("action", "Player "..playername.." placed arrow "..name.." at ("..pointed_thing.above.x..","..pointed_thing.above.y..","..pointed_thing.above.z..")")
298 minetest.log("action", "Player "..playername.." placed arrow "..name.." at "..minetest.pos_to_string(pointed_thing.above))
298299 minetest.set_node(pointed_thing.above, {name = name})
299300 itemstack:take_item()
300301 return itemstack
301302 else
302 minetest.log("warning", "Player "..playername.." tried to place arrow "..name.." into a protected area at ("..pointed_thing.above.x..","..pointed_thing.above.y..","..pointed_thing.above.z..")")
303 minetest.log("warning", "Player "..playername.." tried to place arrow "..name.." into a protected area at "..minetest.pos_to_string(pointed_thing.above))
303304 minetest.record_protection_violation(pointed_thing.above, playername)
304305 return itemstack
305306 end
352353
353354
354355 ---------- Bows -----------
356 if use_toolranks and minetest.get_modpath("toolranks_extras") and toolranks_extras.register_tool_type then
357 toolranks_extras.register_tool_type("bow", S("bow"), S("Arrows thrown"))
358 end
359
355360 function throwing.register_bow(name, def)
356361 local enable_toolranks = use_toolranks and not def.no_toolranks
357362
400405 minetest.after(def.delay or 0, function()
401406 -- Re-check that the arrow can be thrown. Overwrite the new_stack
402407 local old_new_stack = new_stack
403 res, new_stack = def.allow_shot(user, user:get_inventory():get_stack("main", arrow_index), arrow_index, true)
408
409 local arrow_stack = user:get_inventory():get_stack("main", arrow_index)
410
411 res, new_stack = def.allow_shot(user, arrow_stack, arrow_index, true)
412 if not res then
413 return
414 end
415
404416 if not new_stack then
405417 new_stack = old_new_stack
406418 end
407 if not res then
408 return
419 if not new_stack then
420 arrow_stack:take_item()
421 new_stack = arrow_stack
409422 end
410423
411424 -- Shoot arrow
413426 local toolranks_data
414427 if enable_toolranks then
415428 toolranks_data = {
416 itemstack = itemstack,
429 name = itemstack:get_name(),
417430 index = bow_index,
418431 wear = uses
419432 }
427440
428441 if def.throw_itself then
429442 -- This is a bug. If we return ItemStack(nil), the player punches the entity,
430 -- and if the entity if a __builtin:item, it gets back to his inventory.
443 -- and if the entity is a __builtin:item, it gets back to his inventory.
431444 minetest.after(0.1, function()
432445 user:get_inventory():remove_item("main", itemstack)
433446 end)
441454
442455 if enable_toolranks then
443456 def.original_description = def.original_description or def.description
444 def.description = toolranks.create_description(def.description, 0, 1)
457 def.description = toolranks.create_description(def.description)
445458 end
446459
447460 minetest.register_tool(name, def)
0 # textdomain: throwing
1
2
3 ### init.lua ###
4
5 Arrows thrown=
6 bow=
0 # textdomain: throwing
1
2
3 ### init.lua ###
4
5 Arrows thrown=Flèches lancées
6 bow=arc
00 name = throwing
1 optional_depends = wielded_light, toolranks
1 optional_depends = wielded_light, toolranks, toolranks_extras
22 description = Throwing library: provides an API for registering throwing and throwable things