Added some more help information.
|
@ -27,7 +27,7 @@ local function check_moved()
|
|||
end
|
||||
end
|
||||
|
||||
local pos = p:getpos()
|
||||
local pos = p:get_pos()
|
||||
local sit = false -- for now, assume that they are not afk. Well change that if we need to later on in this function
|
||||
-- (below) if the player is not registered on the afk and no afk list, add them with them not being afk
|
||||
if chat_noafk[plname] == nil then
|
||||
|
|
|
@ -182,13 +182,14 @@ local function is_all_empty(player_inv)
|
|||
end
|
||||
|
||||
minetest.register_on_dieplayer(function(player)
|
||||
print 'player died, bones reporting in.'
|
||||
|
||||
local bones_mode = minetest.settings:get("bones_mode") or "bones"
|
||||
if bones_mode ~= "bones" and bones_mode ~= "drop" and bones_mode ~= "keep" then
|
||||
bones_mode = "bones"
|
||||
end
|
||||
|
||||
local bones_position_message = minetest.settings:get_bool("bones_position_message") == true
|
||||
local bones_position_message = true
|
||||
local player_name = player:get_player_name()
|
||||
local pos = vector.round(player:get_pos())
|
||||
local pos_string = minetest.pos_to_string(pos)
|
||||
|
|
|
@ -38,7 +38,7 @@ minetest.register_abm({
|
|||
local above_pos = {x=pos.x, y=pos.y+1, z=pos.z}
|
||||
local above_node = minetest.get_node(above_pos).name
|
||||
local node_count = 0
|
||||
while above_node == 'caverealms:fire_vine' and node_count < 25 do
|
||||
while above_node == 'caverealms:fire_vine' and node_count < 15 do
|
||||
above_pos.y = above_pos.y + 1
|
||||
above_node = minetest.get_node(above_pos).name
|
||||
local node_count = node_count + 1
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
minetest.register_on_dieplayer(function(player)
|
||||
local player_name = player:get_player_name()
|
||||
local pos = player:getpos()
|
||||
local location = minetest.pos_to_string(pos,1)
|
||||
minetest.chat_send_player(player_name, "Your bones are waiting at "..location)
|
||||
end)
|
|
@ -24,7 +24,10 @@ doc.add_entry("epic_server", "stations", {
|
|||
name = ("Stations"),
|
||||
data = { text = ('The Stations are where you\'ll do a goodly portion of your crafting. You can use the public ones in spawn, or create your own. Using public stations you leave yourself vulnerable to people stealing your resources.'..
|
||||
'You can craft locked stations which will only allow people who have access to the area protection to place or remove items from the station inventories. This makes it safe to leave resources in the locked stations.'..
|
||||
'Nearly all the stations provide their own craft guides which you can view by clicking the "Show Guide" button in the lower left.')
|
||||
'Nearly all the stations provide their own craft guides which you can view by clicking the "Show Guide" button in the lower left.\n\n'..
|
||||
'You can toggle between a single item, and the max you can craft or have in a stack by clicking the [Max Output] or [Min Output] button in the lower left corner.'..
|
||||
'Using Shift + Click you can instantly move an entire stack into your inventory, or into the station resource pool, Shift+Scrollwheel over an item will send a single to or from the station.'..
|
||||
'You can pull up the craft guide by clicking the [Show Guide] button in the very bottom left corner.')
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@ dofile(minetest.get_modpath('epic')..'/ABMs.lua')
|
|||
dofile(minetest.get_modpath('epic')..'/awards.lua')
|
||||
dofile(minetest.get_modpath('epic')..'/crafts.lua')
|
||||
dofile(minetest.get_modpath('epic')..'/craftitems.lua')
|
||||
dofile(minetest.get_modpath('epic')..'/death.lua')
|
||||
dofile(minetest.get_modpath('epic')..'/doc.lua')
|
||||
dofile(minetest.get_modpath('epic')..'/fireextinguisher.lua')
|
||||
dofile(minetest.get_modpath('epic')..'/functions.lua')
|
||||
|
|
|
@ -97,7 +97,7 @@ minetest.register_node('epic:nether_with_diamond', {
|
|||
})
|
||||
|
||||
minetest.register_node('epic:nether_basalt_with_huntite', {
|
||||
description = 'Netherrack with Diamond',
|
||||
description = 'Netherrack with Huntite',
|
||||
tiles = {
|
||||
"epic_huntite_basalt.png",
|
||||
"nether_basalt.png",
|
||||
|
|
|
@ -1,302 +0,0 @@
|
|||
-----------------------------------------------------------------------------------------------
|
||||
-- Fishing - Mossmanikin's version - Bobber 0.1.7
|
||||
-- License (code & textures): WTFPL
|
||||
-- Contains code from: fishing (original), mobs, throwing, volcano
|
||||
-- Supports: 3d_armor, animal_clownfish, animal_fish_blue_white, animal_rat, flowers_plus, mobs, seaplants
|
||||
-----------------------------------------------------------------------------------------------
|
||||
|
||||
local PoLeWeaR = (65535/(30-(math.random(15, 29))))
|
||||
local BooTSWear = (2000*(math.random(20, 29)))
|
||||
-- Here's what you can catch
|
||||
local CaTCH = {
|
||||
-- MoD iTeM WeaR MeSSaGe ("You caught "..) GeTBaiTBack NRMiN CHaNCe (../120)
|
||||
{"fishing", "fish_raw", 0, "a Fish.", false, 1, 100},
|
||||
-- {"animal_clownfish", "clownfish", 0, "a Clownfish.", false, 61, 10},
|
||||
-- {"animal_fish_blue_white", "fish_blue_white", 0, "a Blue white fish.", false, 71, 10},
|
||||
{"default", "stick", 0, "a Twig.", true, 81, 2},
|
||||
-- {"mobs", "rat", 0, "a Rat.", false, 83, 1},
|
||||
-- {"animal_rat", "rat", 0, "a Rat.", false, 84, 1},
|
||||
-- {"", "rat", 0, "a Rat.", false, 85, 1},
|
||||
-- {"flowers_plus", "seaweed", 0, "some Seaweed.", true, 86, 20},
|
||||
-- {"seaplants", "kelpgreen", 0, "a Green Kelp.", true, 106, 10},
|
||||
{"farming", "string", 0, "a String.", true, 116, 2},
|
||||
{"fishing", "pole", PoLeWeaR, "an old Fishing Pole.", true, 118, 2},
|
||||
-- {"3d_armor", "boots_wood", BooTSWear, "some very old Boots.", true, 120, 1},
|
||||
-- {"trunks", "twig_1", 0, "a Twig.", true, 121, 2},
|
||||
}
|
||||
minetest.register_alias("flowers_plus:seaweed", "flowers:seaweed") -- exception
|
||||
|
||||
local PLaNTS = {
|
||||
-- MoD* iTeM MeSSaGe ("You caught "..)
|
||||
{"flowers", "waterlily", "a Waterlily." },
|
||||
{"flowers", "waterlily_225", "a Waterlily." },
|
||||
{"flowers", "waterlily_45", "a Waterlily." },
|
||||
{"flowers", "waterlily_675", "a Waterlily." },
|
||||
{"flowers", "waterlily_s1", "a Waterlily." },
|
||||
{"flowers", "waterlily_s2", "a Waterlily." },
|
||||
{"flowers", "waterlily_s3", "a Waterlily." },
|
||||
{"flowers", "waterlily_s4", "a Waterlily." },
|
||||
{"flowers", "seaweed", "some Seaweed."},
|
||||
{"flowers", "seaweed_2", "some Seaweed."},
|
||||
{"flowers", "seaweed_3", "some Seaweed."},
|
||||
{"flowers", "seaweed_4", "some Seaweed."},
|
||||
{"trunks", "twig_1", "a Twig." },
|
||||
{"trunks", "twig_2", "a Twig." },
|
||||
{"trunks", "twig_3", "a Twig." },
|
||||
{"trunks", "twig_4", "a Twig." },
|
||||
{"trunks", "twig_5", "a Twig." },
|
||||
{"trunks", "twig_7", "a Twig." },
|
||||
{"trunks", "twig_8", "a Twig." },
|
||||
{"trunks", "twig_9", "a Twig." },
|
||||
{"trunks", "twig_10", "a Twig." },
|
||||
{"trunks", "twig_11", "a Twig." },
|
||||
{"trunks", "twig_12", "a Twig." },
|
||||
{"trunks", "twig_13", "a Twig." },
|
||||
}
|
||||
-- *as used in the node name
|
||||
|
||||
local MoBS = { -- not in use
|
||||
-- iTeM MeSSaGe ("You caught "..)
|
||||
{"animal_clownfish:clownfish", "a Clownfish." },
|
||||
{"animal_fish_blue_white:fish_blue_white", "a Blue white fish."},
|
||||
}
|
||||
|
||||
local say = minetest.chat_send_player
|
||||
|
||||
|
||||
minetest.register_node("fishing:bobber_box", {
|
||||
drawtype = "nodebox",
|
||||
node_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
-- { left, bottom, front, right, top , back}
|
||||
{-8/16, -8/16, 0, 8/16, 8/16, 0}, -- feathers
|
||||
{-2/16, -8/16, -2/16, 2/16, -4/16, 2/16}, -- bobber
|
||||
}
|
||||
},
|
||||
tiles = {
|
||||
"fishing_bobber_top.png",
|
||||
"fishing_bobber_bottom.png",
|
||||
"fishing_bobber.png",
|
||||
"fishing_bobber.png",
|
||||
"fishing_bobber.png",
|
||||
"fishing_bobber.png^[transformFX"
|
||||
}, --
|
||||
groups = {not_in_creative_inventory=1},
|
||||
})
|
||||
|
||||
local FISHING_BOBBER_ENTITY={
|
||||
hp_max = 605,
|
||||
water_damage = 1,
|
||||
physical = true,
|
||||
timer = 0,
|
||||
env_damage_timer = 0,
|
||||
visual = "wielditem",
|
||||
visual_size = {x=1/3, y=1/3, z=1/3},
|
||||
textures = {"fishing:bobber_box"},
|
||||
-- {left ,bottom, front, right, top , back}
|
||||
collisionbox = {-2/16, -4/16, -2/16, 2/16, 0/16, 2/16},
|
||||
view_range = 7,
|
||||
-- DESTROY BOBBER WHEN PUNCHING IT
|
||||
on_punch = function (self, puncher, time_from_last_punch, tool_capabilities, dir)
|
||||
local player = puncher:get_player_name()
|
||||
local inv = puncher:get_inventory()
|
||||
if MESSAGES == true then minetest.chat_send_player(player, "You didn't catch anything.", false) end -- fish escaped
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
if inv:room_for_item("main", {name="fishing:bait_worm", count=1, wear=0, metadata=""}) then
|
||||
inv:add_item("main", {name="fishing:bait_worm", count=1, wear=0, metadata=""})
|
||||
if MESSAGES == true then minetest.chat_send_player(player, "The bait is still there.", false) end -- bait still there
|
||||
end
|
||||
end
|
||||
-- make sound and remove bobber
|
||||
minetest.sound_play("fishing_bobber1", {
|
||||
pos = self.object:getpos(),
|
||||
gain = 0.5,
|
||||
})
|
||||
self.object:remove()
|
||||
placed_bobbler[player] = nil
|
||||
end,
|
||||
-- WHEN RIGHTCLICKING THE BOBBER THE FOLLOWING HAPPENS (CLICK AT THE RIGHT TIME WHILE HOLDING A FISHING POLE)
|
||||
|
||||
on_activate = function(self,staticdata)
|
||||
if staticdata then
|
||||
local tmp = minetest.deserialize(staticdata)
|
||||
if tmp and tmp.owner then
|
||||
self.owner = tmp.owner
|
||||
end
|
||||
end
|
||||
end,
|
||||
|
||||
get_staticdata = function(self)
|
||||
local tmp = {
|
||||
owner=self.owner,
|
||||
}
|
||||
return minetest.serialize(tmp)
|
||||
end,
|
||||
-- AS SOON AS THE BOBBER IS PLACED IT WILL ACT LIKE
|
||||
on_step = function(self, dtime)
|
||||
local pos = self.object:getpos()
|
||||
|
||||
|
||||
if math.random(1, 4) == 1 then
|
||||
self.object:setyaw(self.object:getyaw()+((math.random(0,360)-180)/2880*math.pi))
|
||||
end
|
||||
for _,player in pairs(minetest.get_connected_players()) do
|
||||
local s = self.object:getpos()
|
||||
local p = player:getpos()
|
||||
local dist = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5
|
||||
if dist > self.view_range then
|
||||
-- make sound and remove bobber
|
||||
minetest.sound_play("fishing_bobber1", {
|
||||
pos = self.object:getpos(),
|
||||
gain = 0.5,
|
||||
})
|
||||
self.object:remove()
|
||||
placed_bobbler[player] = nil
|
||||
end
|
||||
end
|
||||
|
||||
if self.object:get_hp() > 310 then
|
||||
local find_fish = minetest.get_objects_inside_radius({x=pos.x,y=pos.y+0.5,z=pos.z}, 1)
|
||||
for k, obj in pairs(find_fish) do
|
||||
if obj:get_luaentity() ~= nil then
|
||||
if obj:get_luaentity().name == "animal_fish_blue_white:fish_blue_white" then
|
||||
if math.random(1, 30) == 1 then
|
||||
self.object:set_hp(310)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local do_env_damage = function(self)
|
||||
self.object:set_hp(self.object:get_hp()-self.water_damage)
|
||||
if self.object:get_hp() == 600 then
|
||||
self.object:moveto({x=pos.x,y=pos.y-0.015625,z=pos.z})
|
||||
elseif self.object:get_hp() == 595 then
|
||||
self.object:moveto({x=pos.x,y=pos.y+0.015625,z=pos.z})
|
||||
elseif self.object:get_hp() == 590 then
|
||||
self.object:moveto({x=pos.x,y=pos.y+0.015625,z=pos.z})
|
||||
elseif self.object:get_hp() == 585 then
|
||||
self.object:moveto({x=pos.x,y=pos.y-0.015625,z=pos.z})
|
||||
self.object:set_hp(self.object:get_hp()-(math.random(1, 275)))
|
||||
elseif self.object:get_hp() == 300 then
|
||||
minetest.sound_play("fishing_bobber1", {
|
||||
pos = self.object:getpos(),
|
||||
gain = 0.5,
|
||||
})
|
||||
minetest.add_particlespawner(30, 0.5, -- for how long (?) -- Particles on splash
|
||||
{x=pos.x,y=pos.y-0.0625,z=pos.z}, {x=pos.x,y=pos.y,z=pos.z}, -- position min, pos max
|
||||
{x=-2,y=-0.0625,z=-2}, {x=2,y=3,z=2}, -- velocity min, vel max
|
||||
{x=0,y=-9.8,z=0}, {x=0,y=-9.8,z=0},
|
||||
0.3, 1.2,
|
||||
0.25, 0.5, -- min size, max size
|
||||
false, "default_snow.png")
|
||||
self.object:moveto({x=pos.x,y=pos.y-0.0625,z=pos.z})
|
||||
elseif self.object:get_hp() == 295 then
|
||||
self.object:moveto({x=pos.x,y=pos.y+0.0625,z=pos.z})
|
||||
elseif self.object:get_hp() == 290 then
|
||||
self.object:moveto({x=pos.x,y=pos.y+0.0625,z=pos.z})
|
||||
elseif self.object:get_hp() == 285 then
|
||||
self.object:moveto({x=pos.x,y=pos.y-0.1,z=pos.z})
|
||||
elseif self.object:get_hp() < 284 then
|
||||
self.object:moveto({x=pos.x+(0.001*(math.random(-8, 8))),y=pos.y,z=pos.z+(0.001*(math.random(-8, 8)))})
|
||||
--self.object:setyaw(self.object:getyaw()+((math.random(0,360)-180)/1440*math.pi))
|
||||
self.object:setyaw(((math.random(0,360)-180)/1440*math.pi))
|
||||
elseif self.object:get_hp() == 0 then
|
||||
-- make sound and remove bobber
|
||||
minetest.sound_play("fishing_bobber1", {
|
||||
pos = self.object:getpos(),
|
||||
gain = 0.5,
|
||||
})
|
||||
self.object:remove()
|
||||
placed_bobbler[player] = nil
|
||||
end
|
||||
end
|
||||
do_env_damage(self)
|
||||
|
||||
|
||||
local objects = minetest.get_objects_inside_radius(pos, BOBBER_CHECK_RADIUS)
|
||||
if #objects==0 then return true end
|
||||
-- minetest.chat_send_all('#objects > 0 ')
|
||||
|
||||
for i,clicker in ipairs(objects) do
|
||||
if clicker:is_player() then
|
||||
-- minetest.chat_send_all('clicker is player')
|
||||
|
||||
local pll = clicker:get_player_name()
|
||||
if self.owner == pll then
|
||||
-- minetest.chat_send_all('self==owner')
|
||||
local rmb = clicker:get_player_control()['RMB']
|
||||
|
||||
local item = clicker:get_wielded_item()
|
||||
local player = clicker:get_player_name()
|
||||
if not pused[pll] and rmb and item:get_name() == "fishing:pole" then
|
||||
pused[pll]=true
|
||||
local inv = clicker:get_inventory()
|
||||
local say = minetest.chat_send_player
|
||||
if self.object:get_hp() <= 300 then
|
||||
if math.random(1, 100) < FISH_CHANCE then
|
||||
local chance = math.random(1, 122) -- ><((((<28>>
|
||||
for i in pairs(CaTCH) do
|
||||
local MoD = CaTCH[i][1]
|
||||
local iTeM = CaTCH[i][2]
|
||||
local WeaR = CaTCH[i][3]
|
||||
local MeSSaGe = CaTCH[i][4]
|
||||
local GeTBaiTBack = CaTCH[i][5]
|
||||
local NRMiN = CaTCH[i][6]
|
||||
local CHaNCe = CaTCH[i][7]
|
||||
local NRMaX = NRMiN + CHaNCe - 1
|
||||
if chance <= NRMaX and chance >= NRMiN then
|
||||
if minetest.get_modpath(MoD) ~= nil then
|
||||
-- remove visible fish, if there
|
||||
|
||||
-- add (in)visible fish to inventory
|
||||
if inv:room_for_item("main", {name=MoD..":"..iTeM, count=1, wear=WeaR, metadata=""}) then
|
||||
inv:add_item("main", {name=MoD..":"..iTeM, count=1, wear=WeaR, metadata=""})
|
||||
if MESSAGES == true then say(player, "You caught "..MeSSaGe, false) end -- caught somethin'
|
||||
end
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
if GeTBaiTBack == true then
|
||||
if inv:room_for_item("main", {name="fishing:bait_worm", count=1, wear=0, metadata=""}) then
|
||||
inv:add_item("main", {name="fishing:bait_worm", count=1, wear=0, metadata=""})
|
||||
if MESSAGES == true then say(player, "The bait is still there.", false) end -- bait still there?
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
if inv:room_for_item("main", {name="fishing:fish_raw", count=1, wear=0, metadata=""}) then
|
||||
inv:add_item("main", {name="fishing:fish_raw", count=1, wear=0, metadata=""})
|
||||
if MESSAGES == true then say(player, "You caught a Fish.", false) end -- caught Fish
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else --if math.random(1, 100) > FISH_CHANCE then
|
||||
if MESSAGES == true then say(player, "Your fish escaped.", false) end -- fish escaped
|
||||
end
|
||||
|
||||
end -- 300
|
||||
minetest.sound_play("fishing_bobber1", {
|
||||
pos = self.object:getpos(),
|
||||
gain = 0.5,
|
||||
})
|
||||
minetest.chat_send_player(player, 'bobber\'s dead')
|
||||
|
||||
self.object:remove()
|
||||
placed_bobbler[player] = nil
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end,
|
||||
}
|
||||
|
||||
|
||||
|
||||
minetest.register_entity("fishing:bobber_entity", FISHING_BOBBER_ENTITY)
|
|
@ -1,223 +0,0 @@
|
|||
-----------------------------------------------------------------------------------------------
|
||||
-- Fishing - Mossmanikin's version - Bobber Shark 0.0.6
|
||||
-- License (code & textures): WTFPL
|
||||
-----------------------------------------------------------------------------------------------
|
||||
|
||||
-- Here's what you can catch if you use a fish as bait
|
||||
local CaTCH_BiG = {
|
||||
-- MoD iTeM WeaR MeSSaGe ("You caught "..) GeTBaiTBack NRMiN CHaNCe (../120)
|
||||
{"fishing", "shark", 0, "a small Shark.", false, 1, 2},
|
||||
{"fishing", "pike", 0, "a Northern Pike.", false, 3, 3}
|
||||
}
|
||||
|
||||
local PLaNTS = {
|
||||
-- MoD* iTeM MeSSaGe ("You caught "..)
|
||||
{"flowers", "waterlily", "a Waterlily." },
|
||||
{"flowers", "waterlily_225", "a Waterlily." },
|
||||
{"flowers", "waterlily_45", "a Waterlily." },
|
||||
{"flowers", "waterlily_675", "a Waterlily." },
|
||||
{"flowers", "waterlily_s1", "a Waterlily." },
|
||||
{"flowers", "waterlily_s2", "a Waterlily." },
|
||||
{"flowers", "waterlily_s3", "a Waterlily." },
|
||||
{"flowers", "waterlily_s4", "a Waterlily." },
|
||||
{"flowers", "seaweed", "some Seaweed."},
|
||||
{"flowers", "seaweed_2", "some Seaweed."},
|
||||
{"flowers", "seaweed_3", "some Seaweed."},
|
||||
{"flowers", "seaweed_4", "some Seaweed."},
|
||||
{"trunks", "twig_1", "a Twig." },
|
||||
{"trunks", "twig_2", "a Twig." },
|
||||
{"trunks", "twig_3", "a Twig." },
|
||||
{"trunks", "twig_4", "a Twig." },
|
||||
{"trunks", "twig_5", "a Twig." },
|
||||
{"trunks", "twig_7", "a Twig." },
|
||||
{"trunks", "twig_8", "a Twig." },
|
||||
{"trunks", "twig_9", "a Twig." },
|
||||
{"trunks", "twig_10", "a Twig." },
|
||||
{"trunks", "twig_11", "a Twig." },
|
||||
{"trunks", "twig_12", "a Twig." },
|
||||
{"trunks", "twig_13", "a Twig." },
|
||||
}
|
||||
-- *as used in the node name
|
||||
|
||||
local FISHING_BOBBER_ENTITY_SHARK={
|
||||
hp_max = 605,
|
||||
water_damage = 1,
|
||||
physical = true,
|
||||
timer = 0,
|
||||
env_damage_timer = 0,
|
||||
visual = "wielditem",
|
||||
visual_size = {x=1/3, y=1/3, z=1/3},
|
||||
textures = {"fishing:bobber_box"},
|
||||
-- {left ,bottom, front, right, top , back}
|
||||
collisionbox = {-2/16, -4/16, -2/16, 2/16, 0/16, 2/16},
|
||||
view_range = 7,
|
||||
-- DESTROY BOBBER WHEN PUNCHING IT
|
||||
on_punch = function (self, puncher, time_from_last_punch, tool_capabilities, dir)
|
||||
local player = puncher:get_player_name()
|
||||
if MESSAGES == true then minetest.chat_send_player(player, "Your fish escaped.", false) end -- fish escaped
|
||||
minetest.sound_play("fishing_bobber1", {
|
||||
pos = self.object:getpos(),
|
||||
gain = 0.5,
|
||||
})
|
||||
self.object:remove()
|
||||
end,
|
||||
-- WHEN RIGHTCLICKING THE BOBBER THE FOLLOWING HAPPENS (CLICK AT THE RIGHT TIME WHILE HOLDING A FISHING POLE)
|
||||
on_rightclick = function (self, clicker)
|
||||
local item = clicker:get_wielded_item()
|
||||
local player = clicker:get_player_name()
|
||||
local say = minetest.chat_send_player
|
||||
if item:get_name() == "fishing:pole" then
|
||||
local inv = clicker:get_inventory()
|
||||
local pos = self.object:getpos()
|
||||
-- catch visible plant
|
||||
if minetest.get_node(pos).name ~= "air" then
|
||||
for i in ipairs(PLaNTS) do
|
||||
local PLaNT = PLaNTS[i][1]..":"..PLaNTS[i][2]
|
||||
local MeSSaGe = PLaNTS[i][3]
|
||||
local DRoP = minetest.registered_nodes[PLaNT].drop
|
||||
if minetest.get_node(pos).name == PLaNT then
|
||||
minetest.add_node({x=pos.x, y=pos.y, z=pos.z}, {name="air"})
|
||||
if inv:room_for_item("main", {name=DRoP, count=1, wear=0, metadata=""}) then
|
||||
inv:add_item("main", {name=DRoP, count=1, wear=0, metadata=""})
|
||||
if MESSAGES == true then say(player, "You caught "..MeSSaGe, false) end -- caught Plant
|
||||
end
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
if inv:room_for_item("main", {name="fishing:fish_raw", count=1, wear=0, metadata=""}) then
|
||||
inv:add_item("main", {name="fishing:bait_worm", count=1, wear=0, metadata=""})
|
||||
if MESSAGES == true then say(player, "The bait is still there.", false) end -- bait still there
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
--elseif minetest.get_node(pos).name == "air" then
|
||||
if self.object:get_hp() <= 300 then
|
||||
if math.random(1, 100) < SHARK_CHANCE then
|
||||
local chance = math.random(1, 5) -- ><((((º>
|
||||
for i in pairs(CaTCH_BiG) do
|
||||
local MoD = CaTCH_BiG[i][1]
|
||||
local iTeM = CaTCH_BiG[i][2]
|
||||
local WeaR = CaTCH_BiG[i][3]
|
||||
local MeSSaGe = CaTCH_BiG[i][4]
|
||||
local GeTBaiTBack = CaTCH_BiG[i][5]
|
||||
local NRMiN = CaTCH_BiG[i][6]
|
||||
local CHaNCe = CaTCH_BiG[i][7]
|
||||
local NRMaX = NRMiN + CHaNCe - 1
|
||||
if chance <= NRMaX and chance >= NRMiN then
|
||||
if minetest.get_modpath(MoD) ~= nil then
|
||||
if inv:room_for_item("main", {name=MoD..":"..iTeM, count=1, wear=WeaR, metadata=""}) then
|
||||
inv:add_item("main", {name=MoD..":"..iTeM, count=1, wear=WeaR, metadata=""})
|
||||
if MESSAGES == true then say(player, "You caught "..MeSSaGe, false) end -- caught somethin'
|
||||
end
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
if GeTBaiTBack == true then
|
||||
if inv:room_for_item("main", {name="fishing:fish_raw", count=1, wear=0, metadata=""}) then
|
||||
inv:add_item("main", {name="fishing:fish_raw", count=1, wear=0, metadata=""})
|
||||
if MESSAGES == true then say(player, "The bait is still there.", false) end -- bait still there?
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else --if math.random(1, 100) > FISH_CHANCE then
|
||||
if MESSAGES == true then say(player, "Your fish escaped.", false) end -- fish escaped
|
||||
end
|
||||
end
|
||||
if self.object:get_hp() > 300 and minetest.get_node(pos).name == "air" then
|
||||
if MESSAGES == true then say(player, "You didn't catch any fish.", false) end -- fish escaped
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
if math.random(1, 3) == 1 then
|
||||
if inv:room_for_item("main", {name="fishing:fish_raw", count=1, wear=0, metadata=""}) then
|
||||
inv:add_item("main", {name="fishing:fish_raw", count=1, wear=0, metadata=""})
|
||||
if MESSAGES == true then say(player, "The bait is still there.", false) end -- bait still there
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
--end
|
||||
else
|
||||
if MESSAGES == true then say(player, "Your fish escaped.", false) end -- fish escaped
|
||||
end
|
||||
minetest.sound_play("fishing_bobber1", {
|
||||
pos = self.object:getpos(),
|
||||
gain = 0.5,
|
||||
})
|
||||
self.object:remove()
|
||||
end,
|
||||
-- AS SOON AS THE BOBBER IS PLACED IT WILL ACT LIKE
|
||||
on_step = function(self, dtime)
|
||||
local pos = self.object:getpos()
|
||||
if BOBBER_CHECK_RADIUS > 0 then
|
||||
local objs = minetest.env:get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, BOBBER_CHECK_RADIUS)
|
||||
for k, obj in pairs(objs) do
|
||||
if obj:get_luaentity() ~= nil then
|
||||
if obj:get_luaentity().name == "fishing:bobber_entity_shark" then
|
||||
if obj:get_luaentity() ~= self then
|
||||
self.object:remove()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if math.random(1, 4) == 1 then
|
||||
self.object:setyaw(self.object:getyaw()+((math.random(0,360)-180)/2880*math.pi))
|
||||
end
|
||||
for _,player in pairs(minetest.get_connected_players()) do
|
||||
local s = self.object:getpos()
|
||||
local p = player:getpos()
|
||||
local dist = ((p.x-s.x)^2 + (p.y-s.y)^2 + (p.z-s.z)^2)^0.5
|
||||
if dist > self.view_range then
|
||||
minetest.sound_play("fishing_bobber1", {
|
||||
pos = self.object:getpos(),
|
||||
gain = 0.5,
|
||||
})
|
||||
self.object:remove()
|
||||
end
|
||||
end
|
||||
local do_env_damage = function(self)
|
||||
self.object:set_hp(self.object:get_hp()-self.water_damage)
|
||||
if self.object:get_hp() == 600 then
|
||||
self.object:moveto({x=pos.x,y=pos.y-0.015625,z=pos.z})
|
||||
elseif self.object:get_hp() == 595 then
|
||||
self.object:moveto({x=pos.x,y=pos.y+0.015625,z=pos.z})
|
||||
elseif self.object:get_hp() == 590 then
|
||||
self.object:moveto({x=pos.x,y=pos.y+0.015625,z=pos.z})
|
||||
elseif self.object:get_hp() == 585 then
|
||||
self.object:moveto({x=pos.x,y=pos.y-0.015625,z=pos.z})
|
||||
self.object:set_hp(self.object:get_hp()-(math.random(1, 200)))
|
||||
elseif self.object:get_hp() == 300 then
|
||||
minetest.sound_play("fishing_bobber1", {
|
||||
pos = self.object:getpos(),
|
||||
gain = 0.7,
|
||||
})
|
||||
minetest.add_particlespawner(40, 0.5, -- for how long (?) -- Particles on splash
|
||||
{x=pos.x,y=pos.y-0.0625,z=pos.z}, {x=pos.x,y=pos.y-0.2,z=pos.z}, -- position min, pos max
|
||||
{x=-3,y=-0.0625,z=-3}, {x=3,y=5,z=3}, -- velocity min, vel max
|
||||
{x=0,y=-9.8,z=0}, {x=0,y=-9.8,z=0},
|
||||
0.3, 2.4,
|
||||
0.25, 0.5, -- min size, max size
|
||||
false, "default_snow.png")
|
||||
self.object:moveto({x=pos.x,y=pos.y-0.625,z=pos.z})
|
||||
elseif self.object:get_hp() == 295 then
|
||||
self.object:moveto({x=pos.x,y=pos.y+0.425,z=pos.z})
|
||||
elseif self.object:get_hp() == 290 then
|
||||
self.object:moveto({x=pos.x,y=pos.y+0.0625,z=pos.z})
|
||||
elseif self.object:get_hp() == 285 then
|
||||
self.object:moveto({x=pos.x,y=pos.y-0.0625,z=pos.z})
|
||||
elseif self.object:get_hp() < 284 then
|
||||
self.object:moveto({x=pos.x+(0.001*(math.random(-8, 8))),y=pos.y,z=pos.z+(0.001*(math.random(-8, 8)))})
|
||||
self.object:setyaw(self.object:getyaw()+((math.random(0,360)-180)/720*math.pi))
|
||||
elseif self.object:get_hp() == 0 then
|
||||
minetest.sound_play("fishing_bobber1", {
|
||||
pos = self.object:getpos(),
|
||||
gain = 0.5,
|
||||
})
|
||||
self.object:remove()
|
||||
end
|
||||
end
|
||||
do_env_damage(self)
|
||||
end,
|
||||
}
|
||||
|
||||
minetest.register_entity("fishing:bobber_entity_shark", FISHING_BOBBER_ENTITY_SHARK)
|
|
@ -1,92 +0,0 @@
|
|||
-----------------------------------------------------------------------------------------------
|
||||
-- Fishing - Mossmanikin's version - Recipes 0.0.7
|
||||
-----------------------------------------------------------------------------------------------
|
||||
-- License (code & textures): WTFPL
|
||||
-- Contains code from: animal_clownfish, animal_fish_blue_white, fishing (original), stoneage
|
||||
-- Looked at code from:
|
||||
-- Dependencies: default, farming
|
||||
-- Supports: animal_clownfish, animal_fish_blue_white, animal_rat, mobs
|
||||
-----------------------------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------------------------
|
||||
-- Fishing Pole
|
||||
-----------------------------------------------------------------------------------------------
|
||||
-- mc style
|
||||
minetest.register_craft({
|
||||
output = "fishing:pole",
|
||||
recipe = {
|
||||
{"", "", "default:stick" },
|
||||
{"", "default:stick", "ropes:rope" },
|
||||
{"default:stick", "", "ropes:rope" },
|
||||
}
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "fishing:pole",
|
||||
recipe = {
|
||||
{"", "", "default:stick" },
|
||||
{"", "default:stick", "farming:string"},
|
||||
{"default:stick", "", "farming:string"},
|
||||
}
|
||||
})
|
||||
|
||||
-----------------------------------------------------------------------------------------------
|
||||
-- Roasted Fish
|
||||
-----------------------------------------------------------------------------------------------
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "fishing:fish",
|
||||
recipe = "fishing:fish_raw",
|
||||
cooktime = 2,
|
||||
})
|
||||
|
||||
-----------------------------------------------------------------------------------------------
|
||||
-- Wheat Seed
|
||||
-----------------------------------------------------------------------------------------------
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "farming:seed_wheat",
|
||||
recipe = {"farming:wheat"},
|
||||
})
|
||||
-----------------------------------------------------------------------------------------------
|
||||
-- Sushi
|
||||
-----------------------------------------------------------------------------------------------
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "fishing:sushi",
|
||||
recipe = {"fishing:fish_raw","farming:seed_wheat","flowers:seaweed"},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "fishing:sushi",
|
||||
recipe = {"fishing:fish_raw","farming:seed_wheat","seaplants:kelpgreen"},
|
||||
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
type = "shapeless",
|
||||
output = "fishing:sushi",
|
||||
recipe = {"fishing:fish_raw","farming:seed_wheat","seaplants:kelpgreenmiddle"},
|
||||
|
||||
})
|
||||
|
||||
-----------------------------------------------------------------------------------------------
|
||||
-- Roasted Shark
|
||||
-----------------------------------------------------------------------------------------------
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "fishing:shark_cooked",
|
||||
recipe = "fishing:shark",
|
||||
cooktime = 2,
|
||||
})
|
||||
|
||||
-----------------------------------------------------------------------------------------------
|
||||
-- Roasted Pike
|
||||
-----------------------------------------------------------------------------------------------
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = "fishing:pike_cooked",
|
||||
recipe = "fishing:pike",
|
||||
cooktime = 2,
|
||||
})
|
|
@ -1,70 +0,0 @@
|
|||
-----------------------------------------------------------------------------------------------
|
||||
-- Fishing - Mossmanikin's version - Fishes 0.0.4
|
||||
-- License (code & textures): WTFPL
|
||||
-----------------------------------------------------------------------------------------------
|
||||
|
||||
-----------------------------------------------------------------------------------------------
|
||||
-- Fish
|
||||
-----------------------------------------------------------------------------------------------
|
||||
minetest.register_craftitem("fishing:fish_raw", {
|
||||
description = "Fish",
|
||||
groups = {},
|
||||
inventory_image = "fishing_fish.png",
|
||||
on_use = minetest.item_eat(2),
|
||||
})
|
||||
-----------------------------------------------------
|
||||
-- Roasted Fish
|
||||
-----------------------------------------------------
|
||||
minetest.register_craftitem("fishing:fish", {
|
||||
description = "Roasted Fish",
|
||||
groups = {},
|
||||
inventory_image = "fishing_fish_cooked.png",
|
||||
on_use = minetest.item_eat(4),
|
||||
})
|
||||
-----------------------------------------------------
|
||||
-- Sushi
|
||||
-----------------------------------------------------
|
||||
minetest.register_craftitem("fishing:sushi", {
|
||||
description = "Sushi (Hoso Maki)",
|
||||
groups = {},
|
||||
inventory_image = "fishing_sushi.png",
|
||||
on_use = minetest.item_eat(8),
|
||||
})
|
||||
|
||||
-----------------------------------------------------------------------------------------------
|
||||
-- Whatthef... it's a freakin' Shark!
|
||||
-----------------------------------------------------------------------------------------------
|
||||
minetest.register_craftitem("fishing:shark", {
|
||||
description = "Shark",
|
||||
groups = {},
|
||||
inventory_image = "fishing_shark.png",
|
||||
on_use = minetest.item_eat(4),
|
||||
})
|
||||
-----------------------------------------------------
|
||||
-- Roasted Shark
|
||||
-----------------------------------------------------
|
||||
minetest.register_craftitem("fishing:shark_cooked", {
|
||||
description = "Roasted Shark",
|
||||
groups = {},
|
||||
inventory_image = "fishing_shark_cooked.png",
|
||||
on_use = minetest.item_eat(8),
|
||||
})
|
||||
|
||||
-----------------------------------------------------------------------------------------------
|
||||
-- Pike
|
||||
-----------------------------------------------------------------------------------------------
|
||||
minetest.register_craftitem("fishing:pike", {
|
||||
description = "Northern Pike",
|
||||
groups = {},
|
||||
inventory_image = "fishing_pike.png",
|
||||
on_use = minetest.item_eat(4),
|
||||
})
|
||||
-----------------------------------------------------
|
||||
-- Roasted Pike
|
||||
-----------------------------------------------------
|
||||
minetest.register_craftitem("fishing:pike_cooked", {
|
||||
description = "Roasted Northern Pike",
|
||||
groups = {},
|
||||
inventory_image = "fishing_pike_cooked.png",
|
||||
on_use = minetest.item_eat(8),
|
||||
})
|
|
@ -1,121 +0,0 @@
|
|||
-----------------------------------------------------------------------------------------------
|
||||
local title = "Fishing - Mossmanikin's version"
|
||||
local version = "0.2.2"
|
||||
local mname = "fishing"
|
||||
-----------------------------------------------------------------------------------------------
|
||||
-- original by wulfsdad (http://forum.minetest.net/viewtopic.php?id=4375)
|
||||
-- this version by Mossmanikin (https://forum.minetest.net/viewtopic.php?id=6480)
|
||||
-- License (code & textures): WTFPL
|
||||
-- Contains code from: animal_clownfish, animal_fish_blue_white, fishing (original), stoneage
|
||||
-- Looked at code from: default, farming
|
||||
-- Dependencies: default
|
||||
-- Supports: animal_clownfish, animal_fish_blue_white, animal_rat, mobs
|
||||
-----------------------------------------------------------------------------------------------
|
||||
|
||||
-- todo: item wear done
|
||||
-- automatic re-baiting option done (but not optional)
|
||||
-- different types of fish, done, but not finished
|
||||
-- add sound done
|
||||
-- bobber done
|
||||
-- change rainworms filling inv & make 'em disappear done
|
||||
|
||||
-- placable fishing rod for decoration done
|
||||
-- make bobber move slowly while fish on hook done
|
||||
-- catch bigger fish with smaller done, but not finished
|
||||
-- change color of bobber when fish on hook done
|
||||
|
||||
-----------------------------------------------------------------------------------------------
|
||||
--------------------------------------------------------------------------------
|
||||
-- some additions made by 4aiman to make a pole be usable w/o clicking on a bobbler,
|
||||
-- to make bobblers "dissapear" other bobblers only of their "owner"
|
||||
-- also 1 man = 1 bobbler... or so it would seem ;)
|
||||
-- Moreover, I've fixed node_drops to be compatible with enchantments.
|
||||
--------------------------------------------------------------------------------
|
||||
dofile(minetest.get_modpath("fishing").."/settings.txt")
|
||||
dofile(minetest.get_modpath("fishing").."/bobber.lua")
|
||||
dofile(minetest.get_modpath("fishing").."/bobber_shark.lua")
|
||||
dofile(minetest.get_modpath("fishing").."/crafting.lua")
|
||||
dofile(minetest.get_modpath("fishing").."/fishes.lua")
|
||||
dofile(minetest.get_modpath("fishing").."/worm.lua")
|
||||
|
||||
-----------------------------------------------------------------------------------------------
|
||||
-- Fishing Pole
|
||||
-----------------------------------------------------------------------------------------------
|
||||
|
||||
local function rod_wear(itemstack, user, pointed_thing, uses)
|
||||
itemstack:add_wear(65535/(uses-1))
|
||||
return itemstack
|
||||
end
|
||||
|
||||
pused = {}
|
||||
placed_bobbler = {}
|
||||
|
||||
minetest.register_tool("fishing:pole", {
|
||||
|
||||
description = "Fishing Pole",
|
||||
groups = {},
|
||||
inventory_image = "fishing_pole.png",
|
||||
wield_image = "fishing_pole.png^[transformFXR270",
|
||||
stack_max = 1,
|
||||
liquids_pointable = true,
|
||||
range = 7.5,
|
||||
on_place = function (itemstack, user, pointed_thing)
|
||||
if placed_bobbler[player]==true then return itemstack end
|
||||
if pointed_thing and pointed_thing.under then
|
||||
local pt = pointed_thing
|
||||
local node = minetest.get_node(pt.under)
|
||||
if string.find(node.name, "default:water") then
|
||||
local player = user:get_player_name()
|
||||
pused[player]=true
|
||||
local inv = user:get_inventory()
|
||||
if inv:get_stack("main", user:get_wield_index()+1):get_name() == "fishing:bait_worm" then
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
inv:remove_item("main", "fishing:bait_worm")
|
||||
end
|
||||
minetest.sound_play("fishing_bobber2", {
|
||||
pos = pt.under,
|
||||
gain = 0.5,
|
||||
})
|
||||
local ent = minetest.add_entity({interval = 1,x=pt.under.x, y=pt.under.y+(45/64), z=pt.under.z}, "fishing:bobber_entity")
|
||||
ent:get_luaentity().owner=player
|
||||
placed_bobbler[player] = true
|
||||
if WEAR_OUT == true
|
||||
and not minetest.setting_getbool("creative_mode") then
|
||||
return rod_wear(itemstack, user, pointed_thing, 60)
|
||||
else
|
||||
return {name="fishing:pole", count=1, wear=0, metadata=""}
|
||||
end
|
||||
end
|
||||
if inv:get_stack("main", user:get_wield_index()+1):get_name() == "fishing:fish_raw" then
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
inv:remove_item("main", "fishing:fish_raw")
|
||||
end
|
||||
minetest.sound_play("fishing_bobber2", {
|
||||
pos = pt.under,
|
||||
gain = 0.5,
|
||||
})
|
||||
minetest.add_entity({interval = 1,x=pt.under.x, y=pt.under.y+(45/64), z=pt.under.z}, "fishing:bobber_entity_shark")
|
||||
placed_bobbler[player] = true
|
||||
if WEAR_OUT == true
|
||||
and not minetest.setting_getbool("creative_mode") then
|
||||
return rod_wear(itemstack, user, pointed_thing, 60)
|
||||
else
|
||||
return {name="fishing:pole", count=1, wear=0, metadata=""}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
on_use = function(itemstack, placer, pointed_thing)
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
local players = minetest.get_connected_players()
|
||||
for i,player in ipairs(players) do
|
||||
local pll = player:get_player_name()
|
||||
local control = player:get_player_control()
|
||||
if not control.RMB then pused[pll]=nil end
|
||||
end
|
||||
end)
|
|
@ -1,4 +0,0 @@
|
|||
-- original by wulfsdad (http://forum.minetest.net/viewtopic.php?id=4375)
|
||||
-- edited version by Mossmanikin (https://forum.minetest.net/viewtopic.php?id=6480)
|
||||
-- License (code & textures): CC-BY-SA (3.0)
|
||||
-- May contain leftover code from: animal_clownfish, animal_fish_blue_white, stoneage
|
|
@ -1,2 +0,0 @@
|
|||
name = fishing
|
||||
depends = default, farming
|
|
@ -1,19 +0,0 @@
|
|||
-----------------------------------------------------------------------------------------------
|
||||
local title = "Fishing - 4aiman's version"
|
||||
local version = "0.2.2.1"
|
||||
local mname = "fishing"
|
||||
-----------------------------------------------------------------------------------------------
|
||||
-- original by wulfsdad (http://forum.minetest.net/viewtopic.php?id=4375)
|
||||
-- edited version by Mossmanikin (https://forum.minetest.net/viewtopic.php?id=6480)
|
||||
-- License (code & textures): CC-BY-SA (3.0)
|
||||
-- May contain leftover code from: animal_clownfish, animal_fish_blue_white, stoneage
|
||||
-- Mossmanikin has looked at the code from: default, farming
|
||||
-- Dependencies: default
|
||||
-----------------------------------------------------------------------------------------------
|
||||
--
|
||||
-----------------------------------------------------------------------------------------------
|
||||
-- some additions were made by 4aiman to make a pole be usable w/o clicking on a bobbler,
|
||||
-- to make bobblers "dissapear" other bobblers only of their "owner"
|
||||
-- also 1 man = 1 bobbler... or so it would seem ;)
|
||||
-- Moreover, node_drops were fixed to be compatible with the "enchantment" mod.
|
||||
-----------------------------------------------------------------------------------------------
|
|
@ -1,9 +0,0 @@
|
|||
MESSAGES = true
|
||||
FISH_CHANCE = 70
|
||||
NEW_WORM_SOURCE = false
|
||||
WORM_IS_MOB = false
|
||||
WORM_CHANCE = 40
|
||||
WEAR_OUT = true
|
||||
BOBBER_CHECK_RADIUS = 5
|
||||
SIMPLE_DECO_FISHING_POLE = true
|
||||
SHARK_CHANCE = 10
|
Before Width: | Height: | Size: 352 B |
Before Width: | Height: | Size: 317 B |
Before Width: | Height: | Size: 580 B |
Before Width: | Height: | Size: 205 B |
Before Width: | Height: | Size: 352 B |
Before Width: | Height: | Size: 205 B |
Before Width: | Height: | Size: 508 B |
Before Width: | Height: | Size: 486 B |
Before Width: | Height: | Size: 846 B |
Before Width: | Height: | Size: 297 B |
Before Width: | Height: | Size: 702 B |
Before Width: | Height: | Size: 265 B |
Before Width: | Height: | Size: 235 B |
Before Width: | Height: | Size: 215 B |
Before Width: | Height: | Size: 354 B |
Before Width: | Height: | Size: 214 B |
Before Width: | Height: | Size: 303 B |
Before Width: | Height: | Size: 197 B |
Before Width: | Height: | Size: 389 B |
Before Width: | Height: | Size: 763 B |
Before Width: | Height: | Size: 590 B |
Before Width: | Height: | Size: 201 B |
Before Width: | Height: | Size: 280 B |
|
@ -1,6 +0,0 @@
|
|||
minetest.register_craftitem("fishing:bait_worm", {
|
||||
description = "Worm",
|
||||
groups = { fishing_bait=1 },
|
||||
inventory_image = "fishing_worm.png",
|
||||
on_place = minetest.item_eat(1),
|
||||
})
|
|
@ -450,7 +450,8 @@ minetest.register_globalstep(function(dtime)
|
|||
end
|
||||
end
|
||||
-- healing
|
||||
if hp < 50 and player:get_breath() >= 1 and hbhunger.hunger[name] >= 1 then
|
||||
local max_hp = player:get_properties().hp_max
|
||||
if hp < max_hp and player:get_breath() >= 1 and hbhunger.hunger[name] >= 1 then
|
||||
local heal = armor.def[name].heal
|
||||
if heal >= 1 then
|
||||
local new_hp = math.floor(hp + heal)
|
||||
|
|
|
@ -1,108 +0,0 @@
|
|||
# radiant_damage
|
||||
|
||||
This mod allows registered nodes to damage a player if the player is simply near them, rather than having to be immersed in them directly. For example, in real life simply being close to lava would burn you. Or perhaps being near a highly radioactive material would be damaging.
|
||||
|
||||
This mod comes with a set of predefined radiant damage types, all of which can be enabled and disabled independently, and allows other mods to make use of its system to register their own.
|
||||
|
||||
## Configurable Presets
|
||||
|
||||
**Important note:** none of these predefined radiant damage types are enabled by default. This is because one of this mod's intended uses is as a library for other mods to use to enable their own radiant damage types. There is no way to de-register a globalstep callback (the mechanism used by this mod to deliver damage) once it has been registered, so to keep the mod maximally flexible nothing is registered by default.
|
||||
|
||||
Set one or more of the following types to enabled if you want this mod to have an effect out-of-the-box.
|
||||
|
||||
The following settings exist for predefined radiant damage types:
|
||||
|
||||
radiant_damage_enable_heat_damage (Enable radiant heat damage) bool false
|
||||
radiant_damage_lava_damage (Damage dealt per second when standing directly adjacent to one lava node) int 8
|
||||
radiant_damage_fire_damage (Damage dealt per second when standing directly adjacent to one fire node) int 2
|
||||
|
||||
radiant_damage_enable_mese_damage (Enable mese ore radiation damage) bool false
|
||||
radiant_damage_mese_interval (Number of seconds between mese radiation damage checks) int 5
|
||||
radiant_damage_mese_damage (Damage dealt per second when standing directly adjacent to one mese ore node) int 2
|
||||
|
||||
Mese radiation is attenuated by a factor of 0.9 when passing through most materials, by 0.5 when passing through anything with group:stone, by 0.1 when passing through anything with group:mese_radiation_shield (all default metal blocks are given this group), and is _amplified_ by a factor of 4 when passing through nodes with group:mese_radiation_amplifier (default coal and diamond blocks). Note that these fine-grained attenuation factors only work in Minetest 0.5 and higher, for 0.4.16 any non-air node will block all damage.
|
||||
|
||||
## API
|
||||
|
||||
### Registering a damage type
|
||||
|
||||
Call:
|
||||
|
||||
```
|
||||
radiant_damage.register_radiant_damage(damage_name, damage_def)
|
||||
```
|
||||
|
||||
where damage_name is a string used to identify this damage type and damage_def is a table such as:
|
||||
|
||||
```
|
||||
{
|
||||
interval = 1, -- number of seconds between each damage check. Defaults to 1 when undefined.
|
||||
range = 3, -- range of the damage. Can be omitted if inverse_square_falloff is true,
|
||||
-- in that case it defaults to the range at which 0.125 points of damage is done
|
||||
-- by the most damaging emitter node type.
|
||||
emitted_by = {}, -- nodes that emit this damage. At least one emission node type
|
||||
-- and damage value pair is required.
|
||||
attenuated_by = {} -- This allows certain intervening node types to modify the damage
|
||||
-- that radiates through it. This parameter is optional.
|
||||
-- Note: Only works in Minetest version 0.5 and above.
|
||||
default_attenuation = 1, -- the amount the damage is multiplied by when passing
|
||||
-- through any other non-air nodes. Defaults to 0 when undefined. Note that
|
||||
-- in versions before Minetest 0.5 any value other than 1 will result in total
|
||||
-- occlusion (ie, any non-air node will block all damage)
|
||||
inverse_square_falloff = true, -- if true, damage falls off with the inverse square
|
||||
-- of the distance. If false, damage is constant within the range. Defaults to
|
||||
-- true when undefined.
|
||||
above_only = false, -- if true, damage only propagates directly upward. Useful for
|
||||
-- when you want to damage players only when they stand on the node.
|
||||
-- Defaults to false when undefined.
|
||||
on_damage = function(player_object, damage_value, pos), -- An optional callback to allow mods
|
||||
-- to do custom behaviour. If this is set to non-nil then the default damage will
|
||||
-- *not* be done to the player, it's up to the callback to handle that. If it's left
|
||||
-- undefined then damage_value is dealt to the player.
|
||||
}
|
||||
```
|
||||
|
||||
emitted_by has the following format:
|
||||
```
|
||||
{["default:stone_with_mese"] = 2, ["default:mese"] = 9}
|
||||
```
|
||||
where the value associated with each entry is the amount of damage dealt. Groups are permitted. Note that negative damage represents "healing" radiation.
|
||||
|
||||
attenuated_by has the following similar format:
|
||||
|
||||
```
|
||||
{["group:stone"] = 0.25, ["default:steelblock"] = 0}
|
||||
```
|
||||
|
||||
where the value is a multiplier that is applied to the damage passing through it. Groups are permitted. Note that you can use values greater than one to make a node type magnify damage instead of attenuating it.
|
||||
|
||||
### Updating/overriding a registered damage type
|
||||
|
||||
To modify or add new parameters to an existing already-registered damage type use the following function:
|
||||
|
||||
```
|
||||
radiant_damage.override_radiant_damage(damage_name, damage_def)
|
||||
```
|
||||
|
||||
Where damage_def is a table as above but which only includes the new information. For example, a mod could add a new type of mese radiation emitter with the following:
|
||||
|
||||
```
|
||||
radiant_damage.override_radiant_damage("mese", {
|
||||
emitted_by = {
|
||||
["dfcaverns:glow_mese"] = radiant_damage.config.mese_damage * 12,
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
To remove an emission source set its emitted damage to 0.
|
||||
|
||||
To remove an attenuation node type, set its attenuation factor to equal the default attenuation factor.
|
||||
|
||||
If you wish to "disable" a registered damage type, use this override function to set its range to 1 and its interval to an enormous value (millions of seconds) to neutralize the damage type's global callback most efficiently.
|
||||
|
||||
## Further reading
|
||||
|
||||
These wiki pages may be of interest regarding the principles behind some of this mods' functions:
|
||||
|
||||
* [Inverse-square law](https://en.wikipedia.org/wiki/Inverse-square_law)
|
||||
* [Half-value layer](https://en.wikipedia.org/wiki/Half-value_layer)
|
|
@ -1,32 +0,0 @@
|
|||
local CONFIG_FILE_PREFIX = "radiant_damage_"
|
||||
|
||||
radiant_damage.config = {}
|
||||
|
||||
local print_settingtypes = false
|
||||
|
||||
local function setting(stype, name, default, description)
|
||||
local value
|
||||
if stype == "bool" then
|
||||
value = minetest.settings:get_bool(CONFIG_FILE_PREFIX..name, default)
|
||||
elseif stype == "string" then
|
||||
value = minetest.settings:get(CONFIG_FILE_PREFIX..name)
|
||||
elseif stype == "int" or stype == "float" then
|
||||
value = tonumber(minetest.settings:get(CONFIG_FILE_PREFIX..name))
|
||||
end
|
||||
if value == nil then
|
||||
value = default
|
||||
end
|
||||
radiant_damage.config[name] = value
|
||||
|
||||
if print_settingtypes then
|
||||
minetest.debug(CONFIG_FILE_PREFIX..name.." ("..description..") "..stype.." "..tostring(default))
|
||||
end
|
||||
end
|
||||
|
||||
setting("bool", "enable_heat_damage", true, "Enable radiant lava damage")
|
||||
setting("int", "lava_damage", 2, "Damage dealt per second when standing directly adjacent to one lava node")
|
||||
setting("int", "fire_damage", .25, "Damage dealt per second when standing directly adjacent to one fire node")
|
||||
|
||||
setting("bool", "enable_mese_damage", false, "Enable mese ore radiation damage")
|
||||
setting("int", "mese_interval", 5, "Number of seconds between mese radiation damage checks")
|
||||
setting("int", "mese_damage", 2, "Damage dealt per interval when standing directly adjacent to one mese ore node")
|
|
@ -1,441 +0,0 @@
|
|||
radiant_damage = {} --create a container for functions and constants
|
||||
|
||||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
|
||||
dofile(modpath.."/config.lua")
|
||||
|
||||
-- damage_def:
|
||||
--{
|
||||
-- interval = 1, -- number of seconds between each damage check
|
||||
-- range = 3, -- range of the damage. Can be omitted if inverse_square_falloff is true, in that case it defaults to the range at which 1 point of damage is done by the most damaging emitter node type.
|
||||
-- emitted_by = {}, -- nodes that emit this damage. At least one is required.
|
||||
-- attenuated_by = {} -- This allows certain intervening node types to modify the damage that radiates through it. Note: Only works in Minetest version 0.5 and above.
|
||||
-- default_attenuation = 1, -- the amount the damage is multiplied by when passing through any other non-air nodes. Note that in versions before Minetest 0.5 any value other than 1 will result in total occlusion (ie, any non-air node will block all damage)
|
||||
-- inverse_square_falloff = true, -- if true, damage falls off with the inverse square of the distance. If false, damage is constant within the range.
|
||||
-- above_only = false, -- if true, damage only propagates directly upward. Useful for when you want to damage players that stand on the node.
|
||||
-- on_damage = function(player_object, damage_value, pos) -- An optional callback to allow mods to do custom behaviour. If this is set to non-nil then the default damage will *not* be done to the player, it's up to the callback to handle that.
|
||||
--}
|
||||
|
||||
-- emitted_by has the following format:
|
||||
-- {["default:stone_with_mese"] = 2, ["default:mese"] = 9}
|
||||
-- where the value associated with each entry is the amount of damage dealt. Groups are permitted. Note that negative damage represents "healing" radiation.
|
||||
-- attenuated_by has the following similar format:
|
||||
-- {["group:stone"] = 0.25, ["default:steelblock"] = 0}
|
||||
-- where the value is a multiplier that is applied to the damage passing through it. Groups are permitted. Note that you can use values greater than one to make a node type magnify damage instead of attenuating it.
|
||||
|
||||
|
||||
-- Commmon function for looking up an emitted_by or attenuated_by value for a node
|
||||
local get_val = function(node_name, target_names, target_groups)
|
||||
if target_names then
|
||||
local name_val = target_names[node_name]
|
||||
if name_val ~= nil then return name_val end
|
||||
end
|
||||
|
||||
if target_groups then
|
||||
local node_def = minetest.registered_nodes[node_name]
|
||||
local node_groups = node_def.groups
|
||||
if node_groups then
|
||||
for group, _ in pairs(node_groups) do
|
||||
local group_val = target_groups[group]
|
||||
if group_val ~= nil then return group_val end -- returns the first group value it finds, if multiple apply it's undefined which will be selected
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
||||
local attenuation_check
|
||||
|
||||
if Raycast ~= nil then -- version 0.5 of Minetest adds the Raycast class, use that.
|
||||
|
||||
-- Gets three raycasts from the faces of the nodes facing the player.
|
||||
local get_raycasts = function(node_pos, player_pos)
|
||||
local results = {}
|
||||
if player_pos.x > node_pos.x then
|
||||
table.insert(results, Raycast({x=node_pos.x+0.51, y=node_pos.y, z=node_pos.z}, player_pos, false, true))
|
||||
else
|
||||
table.insert(results, Raycast({x=node_pos.x-0.51, y=node_pos.y, z=node_pos.z}, player_pos, false, true))
|
||||
end
|
||||
|
||||
if player_pos.y > node_pos.y then
|
||||
table.insert(results, Raycast({y=node_pos.y+0.51, x=node_pos.x, z=node_pos.z}, player_pos, false, true))
|
||||
else
|
||||
table.insert(results, Raycast({y=node_pos.y-0.51, x=node_pos.x, z=node_pos.z}, player_pos, false, true))
|
||||
end
|
||||
|
||||
if player_pos.z > node_pos.z then
|
||||
table.insert(results, Raycast({z=node_pos.z+0.51, x=node_pos.x, y=node_pos.y}, player_pos, false, true))
|
||||
else
|
||||
table.insert(results, Raycast({z=node_pos.z-0.51, x=node_pos.x, y=node_pos.y}, player_pos, false, true))
|
||||
end
|
||||
return results
|
||||
end
|
||||
|
||||
attenuation_check = function(node_pos, player_pos, default_attenuation, attenuation_nodes, attenuation_groups)
|
||||
|
||||
-- First check a simple degenerate case; if there are no special modifier nodes and the default attenuation
|
||||
-- is 1 then we don't need to bother with any detailed checking, the damage goes through unmodified.
|
||||
if default_attenuation == 1 and attenuation_nodes == nil and attenuation_groups == nil then return 1 end
|
||||
|
||||
local raycasts = get_raycasts(node_pos, player_pos)
|
||||
|
||||
local farthest_from_zero = 0
|
||||
for _, raycast in pairs(raycasts) do
|
||||
local current_attenuation = 1
|
||||
for ray_node in raycast do
|
||||
local ray_node_name = minetest.get_node(ray_node.under).name
|
||||
local ray_node_val = get_val(ray_node_name, attenuation_nodes, attenuation_groups)
|
||||
if ray_node_val == nil then ray_node_val = default_attenuation end
|
||||
current_attenuation = current_attenuation * ray_node_val
|
||||
if current_attenuation == 0 then break end -- once we hit zero no further checks are needed, it will never change.
|
||||
end
|
||||
|
||||
-- By always selecting the farthest value from zero we accomodate both "healing" and "harmful" radiation
|
||||
-- and always let the most impactful value of either type through.
|
||||
-- If you've got both positive and negative modifiers (for example, if you've got a magical node that turns
|
||||
-- harmful radiation into healing radiation when it passes through) this could result in somewhat erratic effects.
|
||||
-- But that's part of the fun, eh? Players will just need to design and use their healing ray carefully.
|
||||
if math.abs(current_attenuation) > math.abs(farthest_from_zero) then
|
||||
farthest_from_zero = current_attenuation
|
||||
end
|
||||
end
|
||||
return farthest_from_zero
|
||||
end
|
||||
|
||||
else
|
||||
|
||||
-- Pre-Minetest 0.5 version. Attenuation_nodes and attenuation_groups are ignored
|
||||
attenuation_check = function(node_pos, player_pos, default_attenuation, attenuation_nodes, attenuation_groups)
|
||||
|
||||
if default_attenuation == 1 then return 1 end -- if default_attenuation is 1, don't attenuate.
|
||||
|
||||
-- otherwise, it's all-or-nothing:
|
||||
if player_pos.y > node_pos.y then
|
||||
if minetest.line_of_sight({y=node_pos.y+0.51, x=node_pos.x, z=node_pos.z}, player_pos) then return 1 end
|
||||
else
|
||||
if minetest.line_of_sight({y=node_pos.y-0.51, x=node_pos.x, z=node_pos.z}, player_pos) then return 1 end
|
||||
end
|
||||
|
||||
if player_pos.x > node_pos.x then
|
||||
if minetest.line_of_sight({x=node_pos.x+0.51, y=node_pos.y, z=node_pos.z}, player_pos) then return 1 end
|
||||
else
|
||||
if minetest.line_of_sight({x=node_pos.x-0.51, y=node_pos.y, z=node_pos.z}, player_pos) then return 1 end
|
||||
end
|
||||
|
||||
if player_pos.z > node_pos.z then
|
||||
if minetest.line_of_sight({z=node_pos.z+0.51, x=node_pos.x, y=node_pos.y}, player_pos) then return 1 end
|
||||
else
|
||||
if minetest.line_of_sight({z=node_pos.z-0.51, x=node_pos.x, y=node_pos.y}, player_pos) then return 1 end
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
radiant_damage.registered_damage_types = {}
|
||||
|
||||
-- This method will update the registered_damage_types table with new values, keeping all the parameters
|
||||
-- consistent and in proper relation to each other.
|
||||
local update_damage_type = function(damage_name, new_def)
|
||||
|
||||
if radiant_damage.registered_damage_types[damage_name] == nil then
|
||||
radiant_damage.registered_damage_types[damage_name] = {}
|
||||
end
|
||||
local damage_def = radiant_damage.registered_damage_types[damage_name]
|
||||
|
||||
-- Interval
|
||||
if new_def.interval ~= nil then
|
||||
damage_def.interval = new_def.interval
|
||||
elseif damage_def.interval == nil then
|
||||
damage_def.interval = 1
|
||||
end
|
||||
|
||||
-- Inverse square falloff
|
||||
if new_def.inverse_square_falloff ~= nil then
|
||||
damage_def.inverse_square_falloff = new_def.inverse_square_falloff
|
||||
elseif damage_def.inverse_square_falloff == nil then
|
||||
damage_def.inverse_square_falloff = true
|
||||
end
|
||||
|
||||
-- Default attenuation value
|
||||
if new_def.default_attenuation ~= nil then
|
||||
damage_def.default_attenuation = new_def.default_attenuation
|
||||
elseif damage_def.default_attenuation == nil then
|
||||
damage_def.default_attenuation = 0
|
||||
end
|
||||
|
||||
-- Above Only
|
||||
damage_def.above_only = new_def.above_only -- default to false
|
||||
|
||||
-- on_damage callback
|
||||
damage_def.on_damage = new_def.on_damage
|
||||
|
||||
-- it is efficient to split the emission and attenuation data into separate node and group maps.
|
||||
|
||||
-- Emitted by
|
||||
damage_def.emission_nodes = damage_def.emission_nodes or {}
|
||||
damage_def.emission_groups = damage_def.emission_groups or {}
|
||||
for nodename, damage in pairs(new_def.emitted_by) do
|
||||
if damage == 0 then damage = nil end -- causes removal of damage-0 node types
|
||||
if string.sub(nodename, 1, 6) == "group:" then
|
||||
damage_def.emission_groups[string.sub(nodename, 7)] = damage -- omit the "group:" prefix
|
||||
else
|
||||
damage_def.emission_nodes[nodename] = damage
|
||||
end
|
||||
end
|
||||
|
||||
damage_def.nodenames = damage_def.nodenames or {} -- for use with minetest.find_nodes_in_area
|
||||
for nodename, damage in pairs(new_def.emitted_by) do
|
||||
local handled = false
|
||||
for i, v in ipairs(damage_def.nodenames) do
|
||||
if v == nodename then
|
||||
if damage == 0 then
|
||||
table.remove(damage_def.nodenames, i)
|
||||
end
|
||||
handled = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not handled then
|
||||
table.insert(damage_def.nodenames, nodename)
|
||||
end
|
||||
end
|
||||
|
||||
-- These remain nil unless some valid data is provided.
|
||||
if new_def.attenuated_by and Raycast then
|
||||
for nodename, attenuation in pairs(new_def.attenuated_by) do
|
||||
damage_def.attenuation_nodes = damage_def.attenuation_nodes or {}
|
||||
damage_def.attenuation_groups = damage_def.attenuation_groups or {}
|
||||
if string.sub(nodename, 1, 6) == "group:" then
|
||||
damage_def.attenuation_groups[string.sub(nodename, 7)] = attenuation -- omit the "group:" prefix
|
||||
else
|
||||
damage_def.attenuation_nodes[nodename] = attenuation
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- remove any attenuation nodes or groups that match the default attenuation, they're pointless.
|
||||
if damage_def.attenuation_groups then
|
||||
for node, attenuation in pairs(damage_def.attenuation_groups) do
|
||||
if attenuation == damage_def.default_attenuation then
|
||||
damage_def.attenuation_groups[node] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
if damage_def.attenuation_nodes then
|
||||
for node, attenuation in pairs(damage_def.attenuation_nodes) do
|
||||
if attenuation == damage_def.default_attenuation then
|
||||
damage_def.attenuation_nodes[node] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Range
|
||||
if new_def.range ~= nil then
|
||||
damage_def.absolute_range = true
|
||||
damage_def.range = new_def.range
|
||||
elseif damage_def.inverse_square_falloff and not damage_def.absolute_range then
|
||||
damage_def.range = 0
|
||||
for _, damage in pairs(damage_def.emission_nodes) do
|
||||
damage_def.range = math.max(math.sqrt(math.abs(damage*8)), damage_def.range) -- use the maximum damage-dealer to determine range.
|
||||
end
|
||||
for _, damage in pairs(damage_def.emission_groups) do
|
||||
damage_def.range = math.max(math.sqrt(math.abs(damage*8)), damage_def.range) -- use the maximum damage-dealer to determine range.
|
||||
end
|
||||
end
|
||||
|
||||
return damage_def
|
||||
end
|
||||
|
||||
radiant_damage.override_radiant_damage = function(damage_name, damage_def)
|
||||
if radiant_damage.registered_damage_types[damage_name] then
|
||||
update_damage_type(damage_name, damage_def)
|
||||
elseif minetest.settings:get_bool("enable_damage") then
|
||||
minetest.log("error", "Attempt was made to override unregistered radiant_damage type " .. damage_name)
|
||||
end
|
||||
end
|
||||
|
||||
radiant_damage.register_radiant_damage = function(damage_name, damage_def)
|
||||
if not minetest.settings:get_bool("enable_damage") then return end -- don't bother if enable_damage isn't set.
|
||||
|
||||
if radiant_damage.registered_damage_types[damage_name] then
|
||||
minetest.log("error", "Attempt was made to register the already-registered radiant_damage type " .. damage_name)
|
||||
return
|
||||
end
|
||||
|
||||
local damage_def = update_damage_type(damage_name, damage_def)
|
||||
|
||||
local range = damage_def.range
|
||||
local above_only = damage_def.above_only
|
||||
local nodenames = damage_def.nodenames
|
||||
local default_attenuation = damage_def.default_attenuation
|
||||
local attenuation_nodes = damage_def.attenuation_nodes
|
||||
local attenuation_groups = damage_def.attenuation_groups
|
||||
local emission_nodes = damage_def.emission_nodes
|
||||
local emission_groups = damage_def.emission_groups
|
||||
local inverse_square_falloff = damage_def.inverse_square_falloff
|
||||
local on_damage = damage_def.on_damage
|
||||
local interval = damage_def.interval
|
||||
|
||||
local timer = 0
|
||||
|
||||
minetest.register_globalstep(function(dtime)
|
||||
timer = timer + dtime
|
||||
if timer >= interval then
|
||||
timer = timer - interval
|
||||
|
||||
for _, player in pairs(minetest.get_connected_players()) do
|
||||
local player_pos = player:get_pos() -- node player's feet are in this location. Add 1 to y to get chest height, more intuitive that way
|
||||
player_pos.y = player_pos.y + 1
|
||||
|
||||
local rounded_pos = vector.round(player_pos)
|
||||
local nearby_nodes
|
||||
if above_only then
|
||||
nearby_nodes = minetest.find_nodes_in_area(vector.add(rounded_pos, {x=0, y= -range, z=0}), rounded_pos, nodenames)
|
||||
else
|
||||
nearby_nodes = minetest.find_nodes_in_area(vector.add(rounded_pos, -range), vector.add(rounded_pos, range), nodenames)
|
||||
end
|
||||
|
||||
local total_damage = 0
|
||||
|
||||
for _, node_pos in ipairs(nearby_nodes) do
|
||||
local distance
|
||||
if above_only then
|
||||
distance = math.max(player_pos.y - node_pos.y, 1)
|
||||
else
|
||||
distance = math.max(vector.distance(player_pos, node_pos), 1) -- clamp to 1 to avoid inverse falloff causing crazy huge damage when standing inside a node
|
||||
end
|
||||
|
||||
if distance <= range then
|
||||
local attenuation = attenuation_check(node_pos, player_pos, default_attenuation, attenuation_nodes, attenuation_groups)
|
||||
if attenuation ~= 0 then
|
||||
local damage = get_val(minetest.get_node(node_pos).name, emission_nodes, emission_groups)
|
||||
if inverse_square_falloff then
|
||||
total_damage = total_damage + (damage / (distance * distance)) * attenuation
|
||||
else
|
||||
total_damage = total_damage + damage * attenuation
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if on_damage == nil then
|
||||
total_damage = math.floor(total_damage)
|
||||
if total_damage ~= 0 then
|
||||
minetest.log("action", player:get_player_name() .. " takes " .. tostring(total_damage) .. " damage from " .. damage_name .. " radiant damage at " .. minetest.pos_to_string(rounded_pos))
|
||||
player:set_hp(player:get_hp() - total_damage)
|
||||
end
|
||||
else
|
||||
on_damage(player, total_damage, rounded_pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
if radiant_damage.config.enable_heat_damage then
|
||||
local on_fire_damage
|
||||
if minetest.get_modpath("3d_armor") and armor ~= nil then
|
||||
-- 3d_armor uses a strange fire protection system different from all the rest, wherein
|
||||
-- its armor protects wholly against some heat sources and not at all against others
|
||||
-- based on how "hot" they are and how strong against fire the armor is.
|
||||
-- Level 1 protects against a wall torch, level 3 protects against a basic fire, and level 5 protects against lava.
|
||||
|
||||
-- Converting this into a standard armor type is going to require some arbitrary decisions.
|
||||
-- My decision is: level 5 protection should reduce the default damage from lava immersion from 8 to 0.5 hp (0.0625 multiplier).
|
||||
-- Level 3 protection reduces the default damage from basic flame from 4 to 0.5 hp (0.125 multiplier)
|
||||
-- Torches don't do damage in default so I will ignore that.
|
||||
-- Level 0 has a damage multiplier of 1.
|
||||
|
||||
-- That gives us three data points: (0,1), (3,0.125), (5,0.0625). Fitting that to an exponential curve gives us:
|
||||
-- y = 0.0481417 + 0.9518583*e^(-0.8388176*x)
|
||||
-- Which looks about right on a graph, and "looks about right on a graph" is good enough for me.
|
||||
on_fire_damage = function(player, damage, pos)
|
||||
local fire_protection = armor.def[player:get_player_name()].fire
|
||||
local fire_multiplier = 1
|
||||
if fire_protection then
|
||||
fire_multiplier = math.min(1, 0.0481417 + 0.9518583 * math.exp(-0.8388176*fire_protection))
|
||||
end
|
||||
-- If the player also has conventional fire armor, use whatever's better.
|
||||
local fire_armor = player:get_armor_groups().fire
|
||||
if fire_armor then
|
||||
fire_multiplier = math.min(fire_multiplier, fire_armor/100)
|
||||
end
|
||||
damage = math.floor(damage * fire_multiplier)
|
||||
if damage > 0 then
|
||||
minetest.log("action", player:get_player_name() .. " takes " .. tostring(damage) .. " damage from heat radiant damage at " .. minetest.pos_to_string(pos))
|
||||
player:set_hp(player:get_hp() - damage)
|
||||
minetest.sound_play("radiant_damage_sizzle", {gain = math.min(1, damage/10), pos=pos})
|
||||
end
|
||||
end
|
||||
else
|
||||
on_fire_damage = function(player, damage, pos)
|
||||
local fire_armor = player:get_armor_groups().fire
|
||||
if fire_armor then
|
||||
damage = damage * fire_armor / 100
|
||||
end
|
||||
damage = math.floor(damage)
|
||||
if damage > 0 then
|
||||
minetest.log("action", player:get_player_name() .. " takes " .. tostring(damage) .. " damage from heat radiant damage at " .. minetest.pos_to_string(pos))
|
||||
player:set_hp(player:get_hp() - damage)
|
||||
minetest.sound_play("radiant_damage_sizzle", {gain = math.min(1, damage/10), pos=pos})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
radiant_damage.register_radiant_damage("heat", {
|
||||
interval = 1,
|
||||
emitted_by = {["group:lava"] = radiant_damage.config.lava_damage, ["fire:basic_flame"] = radiant_damage.config.fire_damage,
|
||||
["fire:permanent_flame"] = radiant_damage.config.fire_damage, ['nether:lava_crust'] = .25,},
|
||||
inverse_square_falloff = true,
|
||||
default_attenuation = 0, -- heat is blocked by anything.
|
||||
on_damage = on_fire_damage,
|
||||
})
|
||||
end
|
||||
|
||||
if radiant_damage.config.enable_mese_damage then
|
||||
|
||||
local shields = {"default:steelblock", "default:copperblock", "default:tinblock", "default:bronzeblock", "default:goldblock"}
|
||||
local amplifiers = {"default:diamondblock", "default:coalblock"}
|
||||
|
||||
for _, shielding_node in ipairs(shields) do
|
||||
local node_def = minetest.registered_nodes[shielding_node]
|
||||
if node_def then
|
||||
local new_groups = node_def.groups or {}
|
||||
new_groups.mese_radiation_shield = 1
|
||||
minetest.override_item(shielding_node, {groups=new_groups})
|
||||
end
|
||||
end
|
||||
for _, amp_node in ipairs(amplifiers) do
|
||||
local node_def = minetest.registered_nodes[amp_node]
|
||||
if node_def then
|
||||
local new_groups = node_def.groups or {}
|
||||
new_groups.mese_radiation_amplifier = 1
|
||||
minetest.override_item(amp_node, {groups=new_groups})
|
||||
end
|
||||
end
|
||||
|
||||
local on_radiation_damage = function(player, damage, pos)
|
||||
local radiation_multiplier = player:get_armor_groups().radiation
|
||||
if radiation_multiplier then
|
||||
damage = damage * radiation_multiplier / 100
|
||||
end
|
||||
damage = math.floor(damage)
|
||||
if damage > 0 then
|
||||
minetest.log("action", player:get_player_name() .. " takes " .. tostring(damage) .. " damage from mese radiation damage at " .. minetest.pos_to_string(pos))
|
||||
player:set_hp(player:get_hp() - damage)
|
||||
minetest.sound_play({name = "radiant_damage_geiger", gain = math.min(1, damage/10)}, {to_player=player:get_player_name()})
|
||||
end
|
||||
end
|
||||
|
||||
radiant_damage.register_radiant_damage("mese", {
|
||||
interval = radiant_damage.config.mese_interval,
|
||||
inverse_square_falloff = true,
|
||||
emitted_by = {["default:stone_with_mese"] = radiant_damage.config.mese_damage, ["default:mese"] = radiant_damage.config.mese_damage * 9},
|
||||
attenuated_by = {["group:stone"] = 0.5, ["group:mese_radiation_shield"] = 0.1, ["group:mese_radiation_amplifier"] = 4},
|
||||
default_attenuation = 0.9,
|
||||
on_damage = on_radiation_damage,
|
||||
})
|
||||
end
|
|
@ -1,19 +0,0 @@
|
|||
Copyright 2018 by FaceDeer
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
|
@ -1,3 +0,0 @@
|
|||
name = radiant_damage
|
||||
optional_depends = default, fire, 3d_armor
|
||||
description = Allows nodes to damage players at a distance.
|
|
@ -1,7 +0,0 @@
|
|||
radiant_damage_enable_heat_damage (Enable radiant heat damage) bool true
|
||||
radiant_damage_lava_damage (Damage dealt per second when standing directly adjacent to one lava node) int 1
|
||||
radiant_damage_fire_damage (Damage dealt per second when standing directly adjacent to one fire node) int .1
|
||||
|
||||
radiant_damage_enable_mese_damage (Enable mese ore radiation damage) bool false
|
||||
radiant_damage_mese_interval (Number of seconds between mese radiation damage checks) int 5
|
||||
radiant_damage_mese_damage (Damage dealt per second when standing directly adjacent to one mese ore node) int 2
|
|
@ -1,2 +0,0 @@
|
|||
radiant_damage_geiger.ogg is from https://freesound.org/people/tim.kahn/sounds/188791/ by tim.kahn under the CC-BY-SA 3.0 license, 2013
|
||||
radiant_damage_sizzle.ogg is from https://freesound.org/people/roboroo/sounds/436791/ by roboroo under the CC0 public domain license, 2018
|
|
@ -1,4 +1,7 @@
|
|||
local news = {
|
||||
'7/8/20',
|
||||
'Removed playeranim, added headanim.',
|
||||
'',
|
||||
'7/7/20',
|
||||
'Added pedestals.',
|
||||
'',
|
||||
|
|
|
@ -21,6 +21,7 @@ local rules = {
|
|||
"",
|
||||
'You can request custom skins via email (minetest@nathansalapat.com)',
|
||||
'English is the primary language here. You may not get responses if you chat in other languages.',
|
||||
'If you need/want more help use the /helpform command.',
|
||||
'Please report bugs. Minetest@nathansalapat.com, or the discord channel.',
|
||||
'',
|
||||
'Breaking these rules could result in you being sent to jail or banned.'}
|
||||
|
|
|
@ -60,12 +60,16 @@ stations.dual_register_recipe('spinning_wheel', {
|
|||
|
||||
--- Rope
|
||||
|
||||
stations.dual_register_recipe('spinning_wheel', {
|
||||
input = {
|
||||
['farming:string'] = 5,
|
||||
},
|
||||
output = 'ropes:ropesegment',
|
||||
})
|
||||
local rope_items = {'farming:cotton', 'farming:hemp_fibre', 'bakedclay:mannagrass', 'default:junglegrass', 'xdecor:cobweb', 'farming:string'}
|
||||
|
||||
for i = 1, 6 do
|
||||
stations.dual_register_recipe('spinning_wheel', {
|
||||
input = {
|
||||
[(rope_items[i])] = 5,
|
||||
},
|
||||
output = 'ropes:ropesegment',
|
||||
})
|
||||
end
|
||||
|
||||
stations.dual_register_recipe('spinning_wheel', {
|
||||
input = {
|
||||
|
|
|
@ -102,7 +102,7 @@ minetest.register_globalstep(function(dtime)
|
|||
-- (since the scheduling is a bit behind)
|
||||
-- experimentally this also works nicely
|
||||
local pos = vector.add (
|
||||
vector.add({x = 0, y = 1, z = 0}, vector.round(player:getpos())),
|
||||
vector.add({x = 0, y = 1, z = 0}, vector.round(player:get_pos())),
|
||||
vector.round(vector.multiply(player:get_player_velocity(), update_interval * 1.5))
|
||||
)
|
||||
|
||||
|
@ -134,4 +134,3 @@ minetest.register_entity(":__builtin:item", item)
|
|||
|
||||
---TEST
|
||||
--wielded_light.register_item_light('default:dirt', 14)
|
||||
|
||||
|
|