First commit
73
README.md
Normal file
@ -0,0 +1,73 @@
|
||||
# Throwing
|
||||
|
||||
## Developped by the Mynetest team
|
||||
|
||||
This mod is a new rewrite of the original throwing mod by PilzAdam. Compatible replacement for it.
|
||||
|
||||
## Configuration
|
||||
|
||||
The settings are the following (they all default to true):
|
||||
```
|
||||
throwing.enable_arrow = true
|
||||
throwing.enable_golden_arrow = true
|
||||
throwing.enable_fire_arrow = true
|
||||
throwing.enable_teleport_arrow = true
|
||||
throwing.enable_dig_arrow = true
|
||||
throwing.enable_dig_arrow_admin = true
|
||||
throwing.enable_build_arrow = true
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
There are two available functions in the mod API:
|
||||
```lua
|
||||
function throwing.register_bow(name, itemcraft, description, texture[, groups])
|
||||
--[[
|
||||
Name: Bow name (in second part of the itemstring).
|
||||
Itemcraft: item used to craft the bow (nil if uncraftable).
|
||||
Description: Description of the bow.
|
||||
Texture: Texture of the bow, shown in inventory.
|
||||
Groups: optional groups.
|
||||
]]
|
||||
|
||||
-- Example:
|
||||
throwing.register_bow("bow_stone", "default:cobble", "Stone Bow", "throwing_bow_stone.png")
|
||||
|
||||
|
||||
function throwing.register_arrow(name, itemcraft, craft_quantity, description, tiles, on_hit_sound, on_hit[, groups])
|
||||
--[[
|
||||
Name: Arrow name (in second part of the itemstring).
|
||||
Itemcraft: item used to craft the arrow (nil if uncraftable).
|
||||
Craft_quantity: quantity of arrows in the craft output.
|
||||
Tiles: tiles of the arrow.
|
||||
On_hit_sound: sound played when the arrow hits a node or an object (nil if no sound).
|
||||
On_hit: callback function: on_hit(pos, last_pos, node, object, hitter) where:
|
||||
* Pos: the position of the hitted node or object
|
||||
* Last_pos: the last air node where the arrow was (used by the build_arrow, for example)
|
||||
* Node and object: hitted node or object. Either node or object is nil, depending
|
||||
whether the arrow hitted a node or an object (you should always check for that).
|
||||
An object can be a player or a luaentity.
|
||||
* Hitter: the ObjectRef of the player who throwed the arrow.
|
||||
]]
|
||||
|
||||
-- Examples:
|
||||
throwing.register_arrow("arrow_gold", "default:gold_ingot", 16, "Golden Arrow",
|
||||
{"throwing_arrow_gold.png", "throwing_arrow_gold.png", "throwing_arrow_gold_back.png", "throwing_arrow_gold_front.png", "throwing_arrow_gold_2.png", "throwing_arrow_gold.png"}, "throwing_arrow",
|
||||
function(pos, last_pos, node, object, hitter)
|
||||
if not object then
|
||||
return
|
||||
end
|
||||
object:punch(minetest.get_player_by_name(hitter), 1, {
|
||||
full_punch_interval = 1,
|
||||
damage_groups = {fleshy = 5}
|
||||
})
|
||||
end)
|
||||
throwing.register_arrow("arrow_build", "default:obsidian_glass", 1, "Build Arrow",
|
||||
{"throwing_arrow_build.png", "throwing_arrow_build.png", "throwing_arrow_build_back.png", "throwing_arrow_build_front.png", "throwing_arrow_build_2.png", "throwing_arrow_build.png"}, "throwing_build_arrow",
|
||||
function(pos, last_pos, node, object, hitter)
|
||||
if not node then
|
||||
return
|
||||
end
|
||||
minetest.set_node(last_pos, {name="default:obsidian_glass"})
|
||||
end)
|
||||
```
|
4
depends.txt
Normal file
@ -0,0 +1,4 @@
|
||||
default
|
||||
bucket
|
||||
fire
|
||||
farming
|
191
init.lua
Normal file
@ -0,0 +1,191 @@
|
||||
throwing = {}
|
||||
|
||||
throwing.arrows = {}
|
||||
|
||||
local modname = minetest.get_current_modname()
|
||||
|
||||
--------- Arrows functions ---------
|
||||
local function shoot_arrow(itemstack, player)
|
||||
for _,arrow in ipairs(throwing.arrows) do
|
||||
if player:get_inventory():get_stack("main", player:get_wield_index()+1):get_name() == arrow then
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
player:get_inventory():remove_item("main", arrow[1])
|
||||
end
|
||||
local playerpos = player:getpos()
|
||||
local obj = minetest.add_entity({x=playerpos.x,y=playerpos.y+1.5,z=playerpos.z}, arrow.."_entity")
|
||||
local dir = player:get_look_dir()
|
||||
obj:setvelocity({x=dir.x*19, y=dir.y*19, z=dir.z*19})
|
||||
obj:setacceleration({x=dir.x*-3, y=-10, z=dir.z*-3})
|
||||
obj:setyaw(player:get_look_yaw()+math.pi)
|
||||
minetest.sound_play("throwing_sound", {pos=playerpos, gain = 0.5})
|
||||
obj:get_luaentity().player = player:get_player_name()
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function arrow_step(self, dtime)
|
||||
self.timer = self.timer + dtime
|
||||
local pos = self.object:getpos()
|
||||
local node = minetest.get_node(pos)
|
||||
|
||||
local logging = function(message, level)
|
||||
minetest.log(level or "action", "[throwing] Arrow "..self.node.." throwed by player "..self.player.." "..tostring(self.timer).."s ago "..message)
|
||||
end
|
||||
|
||||
local hit = function(pos, node, obj)
|
||||
self.object:remove()
|
||||
|
||||
if obj then
|
||||
if obj:is_player() then
|
||||
if self.timer > 0.2 and obj:get_playername() == self.player then -- Avoid hitting the hitter
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if node and minetest.is_protected(pos, self.player) then -- Forbid hitting nodes in protected areas
|
||||
return
|
||||
end
|
||||
|
||||
self.on_hit(pos, self.last_pos, node, obj, minetest.get_player_by_name(self.player))
|
||||
if self.on_hit_sound then
|
||||
minetest.sound_play(self.on_hit_sound, {pos = pos, gain = 0.8})
|
||||
end
|
||||
if node then
|
||||
logging("collided with node "..node.name.." at ("..pos.x..","..pos.y..","..pos.z..")")
|
||||
elseif obj then
|
||||
if obj:get_luaentity() then
|
||||
logging("collided with luaentity "..obj:get_luaentity().name.." at ("..pos.x..","..pos.y..","..pos.z..")")
|
||||
elseif obj:is_player() then
|
||||
logging("collided with player "..obj:get_playername().." at ("..pos.x..","..pos.y..","..pos.z..")")
|
||||
else
|
||||
logging("collided with object at ("..pos.x..","..pos.y..","..pos.z..")")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Collision with a node
|
||||
if node.name == "ignore" then
|
||||
self.object:remove()
|
||||
logging("reached ignore. Removing.")
|
||||
return
|
||||
elseif node.name ~= "air" then
|
||||
hit(pos, node, nil)
|
||||
return
|
||||
end
|
||||
|
||||
-- Collision with an object
|
||||
local objs = minetest.get_objects_inside_radius(pos, 1)
|
||||
for k, obj in pairs(objs) do
|
||||
if obj:get_luaentity() then
|
||||
if obj:get_luaentity().name ~= self.name and obj:get_luaentity().name ~= "__builtin:item" then
|
||||
hit(pos, nil, obj)
|
||||
end
|
||||
else
|
||||
hit(pos, nil, obj)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
self.last_pos = pos -- Used by the build arrow
|
||||
end
|
||||
|
||||
--[[
|
||||
on_hit(pos, last_pos, node, object, hitter)
|
||||
Either node or object is nil, depending whether the arrow collided with an object (luaentity or player) or with a node.
|
||||
No log message is needed in this function (a generic log message is automatically emitted), except on error or warning.
|
||||
]]
|
||||
function throwing.register_arrow(name, itemcraft, craft_quantity, description, tiles, on_hit_sound, on_hit, groups)
|
||||
table.insert(throwing.arrows, modname..":"..name)
|
||||
|
||||
minetest.register_node(modname..":"..name, {
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
-- Shaft
|
||||
{-6.5/17, -1.5/17, -1.5/17, 6.5/17, 1.5/17, 1.5/17},
|
||||
-- Spitze
|
||||
{-4.5/17, 2.5/17, 2.5/17, -3.5/17, -2.5/17, -2.5/17},
|
||||
{-8.5/17, 0.5/17, 0.5/17, -6.5/17, -0.5/17, -0.5/17},
|
||||
-- Federn
|
||||
{6.5/17, 1.5/17, 1.5/17, 7.5/17, 2.5/17, 2.5/17},
|
||||
{7.5/17, -2.5/17, 2.5/17, 6.5/17, -1.5/17, 1.5/17},
|
||||
{7.5/17, 2.5/17, -2.5/17, 6.5/17, 1.5/17, -1.5/17},
|
||||
{6.5/17, -1.5/17, -1.5/17, 7.5/17, -2.5/17, -2.5/17},
|
||||
|
||||
{7.5/17, 2.5/17, 2.5/17, 8.5/17, 3.5/17, 3.5/17},
|
||||
{8.5/17, -3.5/17, 3.5/17, 7.5/17, -2.5/17, 2.5/17},
|
||||
{8.5/17, 3.5/17, -3.5/17, 7.5/17, 2.5/17, -2.5/17},
|
||||
{7.5/17, -2.5/17, -2.5/17, 8.5/17, -3.5/17, -3.5/17},
|
||||
}
|
||||
},
|
||||
tiles = tiles,
|
||||
inventory_image = tiles[1],
|
||||
description = description,
|
||||
groups = groups
|
||||
})
|
||||
|
||||
minetest.register_entity(modname..":"..name.."_entity", {
|
||||
physical = false,
|
||||
timer = 0,
|
||||
visual = "wielditem",
|
||||
visual_size = {x = 0.125, y = 0.125},
|
||||
textures = {modname..":"..name},
|
||||
collisionbox = {0, 0, 0, 0, 0, 0},
|
||||
on_hit = on_hit,
|
||||
on_hit_sound = on_hit_sound,
|
||||
node = modname..":"..name,
|
||||
player = "",
|
||||
on_step = arrow_step
|
||||
})
|
||||
|
||||
if itemcraft then
|
||||
minetest.register_craft({
|
||||
output = modname..":"..name.." "..craft_quantity,
|
||||
recipe = {
|
||||
{itemcraft, "default:stick", "default:stick"}
|
||||
}
|
||||
})
|
||||
minetest.register_craft({
|
||||
output = modname..":"..name.." "..craft_quantity,
|
||||
recipe = {
|
||||
{ "default:stick", "default:stick", itemcraft}
|
||||
}
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
---------- Bows -----------
|
||||
function throwing.register_bow(name, itemcraft, description, texture, groups)
|
||||
minetest.register_tool(modname..":"..name, {
|
||||
description = description,
|
||||
inventory_image = texture,
|
||||
on_use = function(itemstack, user, pointed_thing)
|
||||
if shoot_arrow(itemstack, user, pointed_thing) then
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
itemstack:add_wear(65535/30)
|
||||
end
|
||||
end
|
||||
return itemstack
|
||||
end,
|
||||
groups = groups
|
||||
})
|
||||
|
||||
if itemcraft then
|
||||
minetest.register_craft({
|
||||
output = modname..":"..name,
|
||||
recipe = {
|
||||
{"farming:cotton", itemcraft, ""},
|
||||
{"farming:cotton", "", itemcraft},
|
||||
{"farming:cotton", itemcraft, ""},
|
||||
}
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
dofile(minetest.get_modpath(modname).."/registration.lua")
|
111
registration.lua
Normal file
@ -0,0 +1,111 @@
|
||||
throwing.register_bow("bow_wood", "default:wood", "Wooden Bow", "throwing_bow_wood.png")
|
||||
throwing.register_bow("bow_stone", "default:cobble", "Stone Bow", "throwing_bow_stone.png")
|
||||
throwing.register_bow("bow_steel", "default:steel_ingot", "Steel Bow", "throwing_bow_steel.png")
|
||||
throwing.register_bow("bow_bronze", "default:bronze_ingot", "Bronze Bow", "throwing_bow_bronze.png")
|
||||
throwing.register_bow("bow_mese", "default:mese_crystal", "Mese Bow", "throwing_bow_mese.png")
|
||||
throwing.register_bow("bow_diamond", "default:diamond", "Diamond Bow", "throwing_bow_diamond.png")
|
||||
|
||||
local function get_setting(name)
|
||||
local value = minetest.setting_getbool("throwing.enable_"..name)
|
||||
if value == true or value == nil then
|
||||
return true
|
||||
else
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
if get_setting("arrow") then
|
||||
throwing.register_arrow("arrow", "default:steel_ingot", 16, "Arrow",
|
||||
{"throwing_arrow.png", "throwing_arrow.png", "throwing_arrow_back.png", "throwing_arrow_front.png", "throwing_arrow_2.png", "throwing_arrow.png"}, "throwing_arrow",
|
||||
function(pos, _, _, object, _)
|
||||
if not object then
|
||||
return
|
||||
end
|
||||
object:punch(minetest.get_player_by_name(hitter), 1, {
|
||||
full_punch_interval = 1,
|
||||
damage_groups = {fleshy = 3}
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
if get_setting("golden_arrow") then
|
||||
throwing.register_arrow("arrow_gold", "default:gold_ingot", 16, "Golden Arrow",
|
||||
{"throwing_arrow_gold.png", "throwing_arrow_gold.png", "throwing_arrow_gold_back.png", "throwing_arrow_gold_front.png", "throwing_arrow_gold_2.png", "throwing_arrow_gold.png"}, "throwing_arrow",
|
||||
function(pos, last_pos, node, object, hitter)
|
||||
if not object then
|
||||
return
|
||||
end
|
||||
object:punch(minetest.get_player_by_name(hitter), 1, {
|
||||
full_punch_interval = 1,
|
||||
damage_groups = {fleshy = 5}
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
if get_setting("dig_arrow") then
|
||||
throwing.register_arrow("arrow_dig", "default:pick_wood", 1, "Dig Arrow",
|
||||
{"throwing_arrow_dig.png", "throwing_arrow_dig.png", "throwing_arrow_dig_back.png", "throwing_arrow_dig_front.png", "throwing_arrow_dig_2.png", "throwing_arrow_dig.png"}, "throwing_dig_arrow",
|
||||
function(pos, _, node, _, _)
|
||||
if not node then
|
||||
return
|
||||
end
|
||||
minetest.dig_node(pos)
|
||||
end)
|
||||
end
|
||||
|
||||
if get_setting("dig_arrow_admin") then
|
||||
throwing.register_arrow("arrow_dig_admin", nil, nil, "Admin Dig Arrow",
|
||||
{"throwing_arrow_dig.png", "throwing_arrow_dig.png", "throwing_arrow_dig_back.png", "throwing_arrow_dig_front.png", "throwing_arrow_dig_2.png", "throwing_arrow_dig.png"}, nil,
|
||||
function(pos, _, node, _, _)
|
||||
if not node then
|
||||
return
|
||||
end
|
||||
minetest.remove_node(pos)
|
||||
end, {not_in_creative_inventory = 1})
|
||||
end
|
||||
|
||||
if get_setting("teleport_arrow") then
|
||||
throwing.register_arrow("arrow_teleport", "default:diamond", 1, "Teleport Arrow",
|
||||
{"throwing_arrow_teleport.png", "throwing_arrow_teleport.png", "throwing_arrow_teleport_back.png", "throwing_arrow_teleport_front.png", "throwing_arrow_teleport_2.png", "throwing_arrow_teleport.png"}, "throwing_teleport_arrow",
|
||||
function(_, last_pos, node, _, hitter)
|
||||
if not node then
|
||||
return
|
||||
end
|
||||
if minetest.get_node(last_pos).name ~= "air" then
|
||||
minetest.log("warning", "[throwing] BUG: node at last_pos was not air")
|
||||
return
|
||||
end
|
||||
|
||||
hitter:moveto(last_pos)
|
||||
end)
|
||||
end
|
||||
|
||||
if get_setting("fire_arrow") then
|
||||
throwing.register_arrow("arrow_fire", "default:torch", 1, "Torch Arrow",
|
||||
{"throwing_arrow_fire.png", "throwing_arrow_fire.png", "throwing_arrow_fire_back.png", "throwing_arrow_fire_front.png", "throwing_arrow_fire_2.png", "throwing_arrow_fire.png"}, "default_place_node",
|
||||
function(_, last_pos, node, _, _)
|
||||
if not node then
|
||||
return
|
||||
end
|
||||
if minetest.get_node(last_pos).name ~= "air" then
|
||||
minetest.log("warning", "[throwing] BUG: node at last_pos was not air")
|
||||
return
|
||||
end
|
||||
minetest.set_node(last_pos, {name="default:torch"})
|
||||
end)
|
||||
end
|
||||
|
||||
if get_setting("build_arrow") then
|
||||
throwing.register_arrow("arrow_build", "default:obsidian_glass", 1, "Build Arrow",
|
||||
{"throwing_arrow_build.png", "throwing_arrow_build.png", "throwing_arrow_build_back.png", "throwing_arrow_build_front.png", "throwing_arrow_build_2.png", "throwing_arrow_build.png"}, "throwing_build_arrow",
|
||||
function(_, last_pos, node, _, _)
|
||||
if not node then
|
||||
return
|
||||
end
|
||||
if minetest.get_node(last_pos).name ~= "air" then
|
||||
minetest.log("warning", "[throwing] BUG: node at last_pos was not air")
|
||||
return
|
||||
end
|
||||
minetest.set_node(last_pos, {name="default:obsidian_glass"})
|
||||
end)
|
||||
end
|
BIN
sounds/throwing_arrow.ogg
Normal file
BIN
sounds/throwing_build_arrow.ogg
Normal file
BIN
sounds/throwing_dig_arrow.ogg
Normal file
BIN
sounds/throwing_sound.ogg
Normal file
BIN
sounds/throwing_teleport_arrow.ogg
Normal file
BIN
textures/throwing_arrow.png
Normal file
After Width: | Height: | Size: 139 B |
BIN
textures/throwing_arrow_2.png
Normal file
After Width: | Height: | Size: 141 B |
BIN
textures/throwing_arrow_back.png
Normal file
After Width: | Height: | Size: 153 B |
BIN
textures/throwing_arrow_build.png
Normal file
After Width: | Height: | Size: 139 B |
BIN
textures/throwing_arrow_build_2.png
Normal file
After Width: | Height: | Size: 141 B |
BIN
textures/throwing_arrow_build_back.png
Normal file
After Width: | Height: | Size: 146 B |
BIN
textures/throwing_arrow_build_front.png
Normal file
After Width: | Height: | Size: 120 B |
BIN
textures/throwing_arrow_dig.png
Normal file
After Width: | Height: | Size: 139 B |
BIN
textures/throwing_arrow_dig_2.png
Normal file
After Width: | Height: | Size: 141 B |
BIN
textures/throwing_arrow_dig_admin.png
Normal file
After Width: | Height: | Size: 148 B |
BIN
textures/throwing_arrow_dig_admin_2.png
Normal file
After Width: | Height: | Size: 147 B |
BIN
textures/throwing_arrow_dig_admin_back.png
Normal file
After Width: | Height: | Size: 145 B |
BIN
textures/throwing_arrow_dig_admin_front.png
Normal file
After Width: | Height: | Size: 120 B |
BIN
textures/throwing_arrow_dig_back.png
Normal file
After Width: | Height: | Size: 146 B |
BIN
textures/throwing_arrow_dig_front.png
Normal file
After Width: | Height: | Size: 120 B |
BIN
textures/throwing_arrow_fire.png
Normal file
After Width: | Height: | Size: 195 B |
BIN
textures/throwing_arrow_fire_2.png
Normal file
After Width: | Height: | Size: 190 B |
BIN
textures/throwing_arrow_fire_back.png
Normal file
After Width: | Height: | Size: 197 B |
BIN
textures/throwing_arrow_fire_front.png
Normal file
After Width: | Height: | Size: 234 B |
BIN
textures/throwing_arrow_front.png
Normal file
After Width: | Height: | Size: 119 B |
BIN
textures/throwing_arrow_gold.png
Normal file
After Width: | Height: | Size: 148 B |
BIN
textures/throwing_arrow_gold_2.png
Normal file
After Width: | Height: | Size: 147 B |
BIN
textures/throwing_arrow_gold_back.png
Normal file
After Width: | Height: | Size: 145 B |
BIN
textures/throwing_arrow_gold_front.png
Normal file
After Width: | Height: | Size: 120 B |
BIN
textures/throwing_arrow_teleport.png
Normal file
After Width: | Height: | Size: 139 B |
BIN
textures/throwing_arrow_teleport_2.png
Normal file
After Width: | Height: | Size: 141 B |
BIN
textures/throwing_arrow_teleport_back.png
Normal file
After Width: | Height: | Size: 141 B |
BIN
textures/throwing_arrow_teleport_front.png
Normal file
After Width: | Height: | Size: 119 B |
BIN
textures/throwing_bow_bronze.png
Normal file
After Width: | Height: | Size: 422 B |
BIN
textures/throwing_bow_diamond.png
Normal file
After Width: | Height: | Size: 408 B |
BIN
textures/throwing_bow_mese.png
Normal file
After Width: | Height: | Size: 425 B |
BIN
textures/throwing_bow_steel.png
Normal file
After Width: | Height: | Size: 391 B |
BIN
textures/throwing_bow_stone.png
Normal file
After Width: | Height: | Size: 397 B |
BIN
textures/throwing_bow_wood.png
Normal file
After Width: | Height: | Size: 388 B |
BIN
textures/throwing_empty.png
Normal file
After Width: | Height: | Size: 68 B |