Update from Classic's repository (mods part)

- For #57
master
LeMagnesium 2016-02-16 14:53:35 +01:00
parent 68d087fdee
commit 3c2783fe67
85 changed files with 2391 additions and 1015 deletions

View File

@ -64,3 +64,6 @@ alias("advertising:pepso", "default:stone")
alias("advertising:mineyoshi", "default:stone")
alias("advertising:michel", "default:stone")
alias("advertising:avivas", "default:stone")
-- Remove "xmas_tree" from snow mod
alias("snow:xmas_tree", "default:dirt")

View File

@ -1,12 +1,13 @@
minetest.register_on_newplayer(function(player)
print("Un nouveau joueur vient de nous rejoindre !")
if minetest.setting_getbool("give_initial_stuff") then
local pinv = player:get_inventory()
minetest.log("action", "Giving initial stuff to player "..player:get_player_name())
player:get_inventory():add_item('main', 'default:cobble 99')
player:get_inventory():add_item('main', 'colored_steel:block_blue 99')
player:get_inventory():add_item('main', 'default:torch 99')
player:get_inventory():add_item('main', 'default:cherry_plank 99')
player:get_inventory():add_item('main', 'bakedclay:magenta 99')
player:get_inventory():add_item('main', 'moreblocks:all_faces_tree 99')
pinv:add_item('main', 'default:cobble 99')
pinv:add_item('main', 'colored_steel:block_blue 99')
pinv:add_item('main', 'default:torch 99')
pinv:add_item('main', 'default:cherry_plank 99')
pinv:add_item('main', 'bakedclay:magenta 99')
pinv:add_item('main', 'moreblocks:all_faces_tree 99')
end
end)

View File

@ -3,9 +3,6 @@
local max_frequency_all = 1000 -- larger number means more frequent sounds (100-2000)
local SOUNDVOLUME = 1
local ambiences
local played_on_start = false
local tempy = {}
-- compatibility with soundset mod
local get_volume
@ -108,6 +105,14 @@ local largefire = {
{name="fire_large", length=8}
}
local get_num_nodes = function(pos, nodes)
return #minetest.find_nodes_in_area(
{x=pos.x-6,y=pos.y-2, z=pos.z-6},
{x=pos.x+6,y=pos.y+3, z=pos.z+6},
nodes
)
end
-- check where player is and which sounds are played
local get_ambience = function(player)
@ -115,46 +120,21 @@ local get_ambience = function(player)
local pos = player:getpos()
-- what is around me?
pos.y = pos.y + 1.4 -- head level
local nod_head = minetest.get_node(pos).name
pos.y = pos.y - 1.2 -- feet level
local nod_feet = minetest.get_node(pos).name
pos.y = pos.y - 0.2 -- reset pos
--= START Ambiance
if nod_head == "default:water_source"
or nod_head == "default:water_flowing" then
local nod_head = minetest.get_node({x=pos.x,y=pos.y+1.4, z=pos.z}).name
if string.find(nod_head, "water_") then
return {underwater=underwater}
end
if nod_feet == "default:water_source"
or nod_feet == "default:water_flowing" then
local nod_feet = minetest.get_node({x=pos.x,y=pos.y+0.2, z=pos.z}).name
if string.find(nod_feet, "water_") then
return {splash=splash}
end
local num_fire, num_lava, num_water_source, num_water_flowing, num_desert = 0,0,0,0,0
-- get block of nodes we need to check
tempy = minetest.find_nodes_in_area({x=pos.x-6,y=pos.y-2, z=pos.z-6},
{x=pos.x+6,y=pos.y+2, z=pos.z+6},
{"fire:basic_flame", "bakedclay:safe_fire", "default:lava_flowing", "default:lava_source",
"default:water_flowing", "default:water_source", "default:desert_sand", "default:desert_stone",})
-- count separate instances in block
for _, npos in ipairs(tempy) do
local node = minetest.get_node(npos).name
if node == "fire:basic_flame" or node == "bakedclay:safe_fire" then num_fire = num_fire + 1 end
if node == "default:lava_flowing" or node == "default:lava_source" then num_lava = num_lava + 1 end
if node == "default:water_flowing" then num_water_flowing = num_water_flowing + 1 end
if node == "default:water_source" then num_water_source = num_water_source + 1 end
if node == "default:desert_sand" or node == "default:desert_stone" then num_desert = num_desert + 1 end
end ; --print (num_fire, num_lava, num_water_flowing, num_water_source, num_desert)
--= START Ambiance
-- is fire redo mod active?
if fire and fire.mod and fire.mod == "redo" then
local num_fire = get_num_nodes(pos, {"fire:basic_flame", "bakedclay:safe_fire"})
--print("num_fire:"..dump(num_fire))
if num_fire > 8 then
return {largefire=largefire}
elseif num_fire > 0 then
@ -162,18 +142,28 @@ local get_ambience = function(player)
end
end
local num_lava = get_num_nodes(pos, {"default:lava_flowing", "default:lava_source"})
--print("num_lava:"..dump(num_lava))
if num_lava > 5 then
return {lava=lava}
end
local num_water_flowing = get_num_nodes(pos, {"default:water_flowing", "default:river_water_flowing"})
--print("num_water_flowing:"..dump(num_water_flowing))
if num_water_flowing > 30 then
return {flowing_water=flowing_water}
end
if pos.y < 7 and pos.y > 0 and num_water_source > 100 then
return {beach=beach}
if pos.y < 7 and pos.y > 0 then
local num_water_source = get_num_nodes(pos, {"default:water_source", "default:river_water_source"})
--print("num_water_source:"..dump(num_water_source))
if num_water_source > 100 then
return {beach=beach}
end
end
local num_desert = get_num_nodes(pos, {"default:desert_sand", "default:desert_stone"})
--print("num_desert:"..dump(num_desert))
if num_desert > 150 then
return {desert=desert}
end
@ -253,21 +243,18 @@ local still_playing = function(still_playing, player)
if not still_playing.largefire then stop_sound(largefire, player) end
end
local function tick()
for _,player in ipairs(minetest.get_connected_players()) do
--local t1 = os.clock()
ambiences = get_ambience(player)
--print ("[AMBIENCE] "..math.ceil((os.clock() - t1) * 1000).." ms")
still_playing(ambiences, player)
if get_volume(player:get_player_name(), "ambience") > 0 then
local playername = player:get_player_name()
local gain = get_volume(playername, "ambience")
if gain > 0 then
--local t1 = os.clock()
local ambiences = get_ambience(player)
--print ("[AMBIENCE] "..math.ceil((os.clock() - t1) * 1000).." ms")
still_playing(ambiences, player)
for _,ambience in pairs(ambiences) do
if math.random(1, 1000) <= ambience.frequency then
if ambience.on_start and played_on_start == false then
played_on_start = true
minetest.sound_play(ambience.on_start,
{to_player=player:get_player_name(),gain=get_volume(player:get_player_name(), "ambience")})
end
play_sound(player, ambience, math.random(1, #ambience))
end
end

View File

@ -136,6 +136,7 @@ end
--MFF DEBUT crabman(17/09/2015 ) respawn player in special area(event) if a spawn is set.
--1 party (2 party in beds mod)
local dead_players = {}
minetest.register_on_dieplayer(function(player)
local player_name = player:get_player_name()
@ -147,7 +148,7 @@ minetest.register_on_dieplayer(function(player)
end)
minetest.register_on_respawnplayer(function(player)
function areas:onRespawn(player)
local player_name = player:get_player_name()
if not player_name or not dead_players[player_name] then return false end
local pos = dead_players[player_name]
@ -161,5 +162,5 @@ minetest.register_on_respawnplayer(function(player)
end
end
return false
end)
end
--FIN

View File

@ -13,7 +13,23 @@
darkage:gneiss
--]]
local function generate_stratus(name, wherein, ceilin, ceil, minp, maxp, seed, stratus_chance, radius, radius_y, deep, height_min, height_max)
local getID = minetest.get_content_id
local function generate_stratus(data, varea, name, wherein, ceilin, ceil, minp, maxp, seed, stratus_chance, radius, radius_y, deep, height_min, height_max)
local c_ore = getID(name)
local c_wherein = {}
local c_ceilin = {}
for k, v in ipairs(wherein) do
c_wherein[k] = getID(v)
end
for k, v in ipairs(ceilin) do
c_ceilin[k] = getID(v)
end
local c_ceil
if ceil then
c_ceil = getID(ceil)
end
if maxp.y < height_min or minp.y > height_max then
return
end
@ -51,80 +67,86 @@ local function generate_stratus(name, wherein, ceilin, ceil, minp, maxp, seed, s
z0 = pr:next(minp.z, z0)
end
local p0 = {x=x0, y=y0, z=z0}
local n = minetest.get_node(p0).name
local n = data[varea:indexp(p0)]
local i = 0
x = 0
for k, v in ipairs(ceilin) do
for k, v in ipairs(c_ceilin) do
if n == v then
x = 1
break
end
end
if x == 1 then
for y1=y0-1,y_min,-1 do
p0.y=y1
n = minetest.get_node(p0).name
x = 0
for k, v in ipairs(wherein) do
if n == v then
x = 1
break
end
end
if x == 1 then
y0=y1-deep
if y0 < y_min then
y0 = y_min
end
break
end
end
local rx=pr:next(radius/2,radius)+1
local rz=pr:next(radius/2,radius)+1
local ry=pr:next(radius_y/2,radius_y)+1
for x1=0,rx do
rz = rz + 3 - pr:next(1,6)
if rz < 1 then
rz = 1
end
for z1=pr:next(1,3),rz do
local ry0=ry+ pr:next(1,3)
for y1=pr:next(1,3),ry0 do
local x2 = x0+x1
local y2 = y0+y1
local z2 = z0+z1
local p2 = {x=x2, y=y2, z=z2}
n = minetest.get_node(p2).name
for y1=y0-1,y_min,-1 do
p0.y=y1
n = data[varea:indexp(p0)]
x = 0
for k, v in ipairs(wherein) do
if n == v then
x = 1
for k, v in ipairs(c_wherein) do
if n == v then
x = 1
break
end
end
if x == 1 then
y0=y1-deep
if y0 < y_min then
y0 = y_min
end
break
end
end
if x == 1 then
if ceil == nil then
minetest.set_node(p2, {name=name})
i = i +1
else
local p3 = {p2.x,p2.y+1,p2}
if minetest.get_node(p3).name == ceil then
minetest.set_node(p2, {name=name})
i = i +1
local rx=pr:next(radius/2,radius)+1
local rz=pr:next(radius/2,radius)+1
local ry=pr:next(radius_y/2,radius_y)+1
for x1=0,rx do
rz = rz + 3 - pr:next(1,6)
if rz < 1 then
rz = 1
end
for z1=pr:next(1,3),rz do
local ry0=ry+ pr:next(1,3)
for y1=pr:next(1,3),ry0 do
local x2 = x0+x1
local y2 = y0+y1
local z2 = z0+z1
local p2 = {x=x2, y=y2, z=z2}
n = data[varea:indexp(p2)]
x = 0
for k, v in ipairs(c_wherein) do
if n == v then
x = 1
break
end
end
if x == 1 then
if c_ceil == nil then
data[varea:indexp(p2)] = c_ore
i = i +1
else
local p3 = {p2.x,p2.y+1,p2}
if data[varea:indexp(p3)] == c_ceil then
data[varea:indexp(p2)] = c_ore
i = i +1
end
end
end
end
end
end
print(" generated "..dump(i).." blocks in ("..dump(x0)..","..dump(y0)..","..dump(z0)..")")
end
end
end
print(" generated "..dump(i).." blocks in ("..dump(x0)..","..dump(y0)..","..dump(z0)..")")
-- end end end end!
end
end
end
end
local function generate_claylike(name, minp, maxp, seed, chance, minh, maxh, dirt)
local function generate_claylike(data, varea, name, minp, maxp, seed, chance, minh, maxh, dirt)
local c_ore = getID(name)
local c_sand = getID("default:sand")
local c_dirt = getID("default:dirt")
local c_lawn = getID("default:dirt_with_grass")
local c_water = getID("default:water_source")
local c_air = getID("air")
if maxp.y >= maxh+1 and minp.y <= minh-1 then
local pr = PseudoRandom(seed)
local divlen = 4
@ -136,33 +158,33 @@ local function generate_claylike(name, minp, maxp, seed, chance, minh, maxh, dir
for divz=0+1,divs-1-1 do
local cx = minp.x + math.floor((divx+0.5)*divlen)
local cz = minp.z + math.floor((divz+0.5)*divlen)
local up = minetest.get_node({x=cx,y=yy,z=cz}).name
local down = minetest.get_node({x=cx,y=yy-1,z=cz}).name
if ( up == "default:water_source" or up == "air" ) and ( down == "default:sand" or (dirt == 1 and (down == "default:dirt" or down == "default:dirt_with_grass" ))) then
local up = data[varea:index(cx,yy,cz)]
local down = data[varea:index(cx,yy-1,cz)]
if ( up == c_water or up == c_air ) and ( down == c_sand or (dirt == 1 and (down == c_dirt or down == c_lawn ))) then
local is_shallow = true
local num_water_around = 0
if minetest.get_node({x=cx-divlen*2,y=yy,z=cz}).name == "default:water_source" then
if data[varea:index(cx-divlen*2,yy,cz)] == c_water then
num_water_around = num_water_around + 1
end
if minetest.get_node({x=cx+divlen*2,y=yy,z=cz}).name == "default:water_source" then
if data[varea:index(cx+divlen*2,yy,cz)] == c_water then
num_water_around = num_water_around + 1
end
if minetest.get_node({x=cx,y=yy,z=cz-divlen*2}).name == "default:water_source" then
if data[varea:index(cx,yy,cz-divlen*2)] == c_water then
num_water_around = num_water_around + 1
end
if minetest.get_node({x=cx,y=yy,z=cz+divlen*2}).name == "default:water_source" then
if data[varea:index(cx,yy,cz+divlen*2)] == c_water then
num_water_around = num_water_around + 1
end
if num_water_around >= 3 then
is_shallow = false
end
end
if is_shallow then
for x1=-divlen,divlen do
for z1=-divlen,divlen do
local p={x=cx+x1,y=yy-1,z=cz+z1}
down = minetest.get_node(p).name
if down == "default:sand" or (dirt == 1 and (down == "default:dirt" or down == "default:dirt_with_grass")) then
minetest.set_node(p, {name=name})
down = data[varea:indexp(p)]
if down == c_sand or (dirt == 1 and (down == c_dirt or down == c_lawn)) then
data[varea:indexp(p)] = c_ore
end
end
end
@ -176,7 +198,10 @@ local function generate_claylike(name, minp, maxp, seed, chance, minh, maxh, dir
end
local function generate_ore(name, wherein, minp, maxp, seed, chunks_per_volume, chunk_size, ore_per_chunk, height_min, height_max)
local function generate_ore(data, varea, name, wherein, minp, maxp, seed, chunks_per_volume, chunk_size, ore_per_chunk, height_min, height_max)
local c_ore = getID(name)
local c_wherein = getID(wherein)
if maxp.y < height_min or minp.y > height_max then
return
end
@ -200,8 +225,9 @@ local function generate_ore(name, wherein, minp, maxp, seed, chunks_per_volume,
local y2 = y0+y1
local z2 = z0+z1
local p2 = {x=x2, y=y2, z=z2}
if minetest.get_node(p2).name == wherein then
minetest.set_node(p2, {name=name})
local indexp2 = varea:indexp(p2)
if data[indexp2] == c_wherein then
data[indexp2] = c_ore
end
end
end
@ -211,45 +237,65 @@ local function generate_ore(name, wherein, minp, maxp, seed, chunks_per_volume,
end
end
minetest.register_on_generated(function(minp, maxp, seed)
if minp.y < -19600 then return end
print("DARKAGE: Generate stratus");
generate_claylike("darkage:mud", minp, maxp, seed+1, 4, 0, 2, 0)
generate_claylike("darkage:silt", minp, maxp, seed+2, 4, -1, 1, 1)
generate_stratus("darkage:chalk",
function darkage_mapgen(data, area, minp, maxp, seed) -- public function, to be used by Lua mapgens
if minp.y < -19600 then return end
local t1 = os.clock()
generate_claylike(data, area, "darkage:mud", minp, maxp, seed+1, 4, 0, 2, 0)
generate_claylike(data, area, "darkage:silt", minp, maxp, seed+2, 4, -1, 1, 1)
generate_stratus(data, area, "darkage:chalk",
{"default:stone"},
{"default:stone","air"}, nil,
minp, maxp, seed+3, 4, 25, 8, 0, -20, 50)
generate_stratus("darkage:ors",
generate_stratus(data, area, "darkage:ors",
{"default:stone"},
{"default:stone","air","default:water_source"}, nil,
minp, maxp, seed+4, 4, 25, 7, 50, -200, 500)
generate_stratus("darkage:shale",
generate_stratus(data, area, "darkage:shale",
{"default:stone"},
{"default:stone","air"}, nil,
minp, maxp, seed+5, 4, 23, 7, 50, -50, 20)
generate_stratus("darkage:slate",
generate_stratus(data, area, "darkage:slate",
{"default:stone"},
{"default:stone","air"}, nil,
minp, maxp, seed+6, 6, 23, 5, 50, -500, 0)
generate_stratus("darkage:schist",
generate_stratus(data, area, "darkage:schist",
{"default:stone"},
{"default:stone","air"}, nil,
minp, maxp, seed+7, 6, 19, 6, 50, -31000, -10)
generate_stratus("darkage:basalt",
generate_stratus(data, area, "darkage:basalt",
{"default:stone"},
{"default:stone","air"}, nil,
minp, maxp, seed+8, 5, 20, 5, 20, -31000, -50)
generate_stratus("darkage:marble",
generate_stratus(data, area, "darkage:marble",
{"default:stone"},
{"default:stone","air"}, nil,
minp, maxp, seed+9, 4, 25, 6, 50, -31000, -75)
generate_stratus("darkage:serpentine",
generate_stratus(data, area, "darkage:serpentine",
{"default:stone"},
{"default:stone","air"}, nil,
minp, maxp, seed+10, 4, 28, 8, 50, -31000, -350)
generate_stratus("darkage:gneiss",
generate_stratus(data, area, "darkage:gneiss",
{"default:stone"},
{"default:stone","air"}, nil,
minp, maxp, seed+11, 4, 15, 5, 50, -31000, -250)
print("DARKAGE: calculating time : " .. os.clock() - t1)
end
minetest.register_on_mapgen_init(function(mgparams)
if mgparams.mgname ~= "singlenode" then
minetest.register_on_generated(function(minp, maxp, seed)
if minp.y < -19600 then return end
local t0 = os.clock()
local vm, emin, emax = minetest.get_mapgen_object("voxelmanip")
local area = VoxelArea:new({MinEdge = emin, MaxEdge = emax})
local data = vm:get_data()
darkage_mapgen(data, area, minp, maxp, seed)
vm:set_data(data)
vm:write_to_map()
print("DARKAGE: total time taken : " .. os.clock() - t0)
end)
end
end)

View File

@ -69,30 +69,30 @@ end
local p0 = {-2/16, -1/2, -2/16, 2/16, 1/2, 2/16}
local p1 = {-2/16, 1/2, -2/16, -2/16, 1/2+8/16, -2/16}
local p2 = {-2/16, 1/2, 2/16, -2/16, 1/2+8/16, 2/16}
local p1 = {-2/16, 1/2, -2/16, -2/16, 1/2--[[+8/16]], -2/16}
local p2 = {-2/16, 1/2, 2/16, -2/16, 1/2--[[+8/16]], 2/16}
local p3 = {0, 0, 0, 0, 0, 0}
local p4 = {2/16, 1/2, -2/16, 2/16, 1/2+8/16, -2/16}
local p5 = {2/16, 1/2, 2/16, 2/16, 1/2+8/16, 2/16}
local p4 = {2/16, 1/2, -2/16, 2/16, 1/2--[[+8/16]], -2/16}
local p5 = {2/16, 1/2, 2/16, 2/16, 1/2--[[+8/16]], 2/16}
local x1 = {-2/16, 1/2-4/16, 1/16, -1/2, 1/2-1/16, -1/16} --oben(quer) -x
local x12 = {-2/16, -1/2+6/16, 1/16, -1/2, -1/2+9/16, -1/16} --unten(quer) -x
local x12 = {-2/16, -1/2+6/16, 1/16, -1/2, -1/2--[[+9/16]], -1/16} --unten(quer) -x
local x2 = {2/16, 1/2-4/16, -1/16, 1/2, 1/2-1/16, 1/16} --oben(quer) x
local x22 = {2/16, -1/2+6/16, -1/16, 1/2, -1/2+9/16, 1/16} --unten(quer) x
local x22 = {2/16, -1/2+6/16, -1/16, 1/2, -1/2--[[+9/16]], 1/16} --unten(quer) x
local z1 = {1/16, 1/2-4/16, -2/16, -1/16, 1/2-1/16, -1/2} --oben(quer) -z
local z12 = {1/16, -1/2+6/16, -2/16, -1/16, -1/2+9/16, -1/2} --unten(quer) -z
local z12 = {1/16, -1/2+6/16, -2/16, -1/16, -1/2--[[+9/16]], -1/2} --unten(quer) -z
local z2 = {-1/16, 1/2-4/16, 2/16, 1/16, 1/2-1/16, 1/2} --oben(quer) z
local z22 = {-1/16, -1/2+6/16, 2/16, 1/16, -1/2+9/16, 1/2} --unten(quer) z
local z22 = {-1/16, -1/2+6/16, 2/16, 1/16, -1/2--[[+9/16]], 1/2} --unten(quer) z
local bz1 = {1/16, 1/2-1/16, -6/16, 1/16, 1/2+8/16, -6/16} --oben_block(quer) -z 1seite
local bz11 = {-1/16, 1/2-1/16, -6/16, -1/16, 1/2+8/16, -6/16} --oben_block(quer) -z 2seite
local bz2 = {1/16, 1/2-1/16, 5/16, 1/16, 1/2+8/16, 5/16} --oben_block(quer) z 1seite
local bz21 = {-1/16, 1/2-1/16, 5/16, -1/16, 1/2+8/16, 5/16} --oben_block(quer) z 2seite
local bz1 = {1/16, 1/2-1/16, -6/16, 1/16, 1/2--[[+8/16]], -6/16} --oben_block(quer) -z 1seite
local bz11 = {-1/16, 1/2-1/16, -6/16, -1/16, 1/2--[[+8/16]], -6/16} --oben_block(quer) -z 2seite
local bz2 = {1/16, 1/2-1/16, 5/16, 1/16, 1/2--[[+8/16]], 5/16} --oben_block(quer) z 1seite
local bz21 = {-1/16, 1/2-1/16, 5/16, -1/16, 1/2--[[+8/16]], 5/16} --oben_block(quer) z 2seite
local bx1 = {-6/16, 1/2-1/16, 1/16, -6/16, 1/2+8/16, 1/16} --oben_block(quer) -x 1seite
local bx11 = {-6/16, 1/2-1/16, -1/16, -6/16, 1/2+8/16, -1/16} --oben_block(quer) -x 2seite
local bx2 = {5/16, 1/2-1/16, 1/16, 5/16, 1/2+8/16, 1/16} --oben_block(quer) x 1seite
local bx21 = {5/16, 1/2-1/16, -1/16, 5/16, 1/2+8/16, -1/16} --oben_block(quer) x 2seite
local bx1 = {-6/16, 1/2-1/16, 1/16, -6/16, 1/2--[[+8/16]], 1/16} --oben_block(quer) -x 1seite
local bx11 = {-6/16, 1/2-1/16, -1/16, -6/16, 1/2--[[+8/16]], -1/16} --oben_block(quer) -x 2seite
local bx2 = {5/16, 1/2-1/16, 1/16, 5/16, 1/2--[[+8/16]], 1/16} --oben_block(quer) x 1seite
local bx21 = {5/16, 1/2-1/16, -1/16, 5/16, 1/2--[[+8/16]], -1/16} --oben_block(quer) x 2seite
minetest.register_node("fences:fence_wood", {

View File

@ -194,13 +194,15 @@ function refill(player, stck_name, index)
local inv = player:get_inventory()
local old_stack = inv:get_stack("main", index)
if old_stack:get_name() == stck_name then return end
for i,stack in ipairs(inv:get_list("main")) do
if i ~= index and stack:get_name() == stck_name then
inv:set_stack("main", index, stack)
stack:clear()
inv:set_stack("main", i, stack)
minetest.log("action", "Inventory Tweaks: refilled stack("..stck_name..") of " .. player:get_player_name() )
return
if inv:get_list("main") then
for i,stack in ipairs(inv:get_list("main")) do
if i ~= index and stack:get_name() == stck_name then
inv:set_stack("main", index, stack)
stack:clear()
inv:set_stack("main", i, stack)
minetest.log("action", "Inventory Tweaks: refilled stack("..stck_name..") of " .. player:get_player_name() )
return
end
end
end
end

View File

@ -1,6 +1,38 @@
item_drop = {}
local enable_damage = minetest.setting_getbool("enable_damage")
local creative_mode = minetest.setting_getbool("creative_mode")
local TICK_UPDATE = 0.1
local die_timeout = 20
local die_time = {}
local die_respawned = {}
minetest.register_on_joinplayer(function(player)
local player_name = player:get_player_name()
die_time[player_name] = 0
die_respawned[player_name] = false
end)
minetest.register_on_leaveplayer(function(player)
local player_name = player:get_player_name()
die_time[player_name] = nil
die_respawned[player_name] = nil
end)
minetest.register_on_dieplayer(function(player)
local player_name = player:get_player_name()
if not player_name then return end
die_respawned[player_name] = false
die_time[player_name] = die_timeout
end)
minetest.register_on_respawnplayer(function(player)
local player_name = player:get_player_name()
if not player_name then return end
die_respawned[player_name] = true
end)
-- Following edits by gravgun
@ -33,81 +65,88 @@ local pickup_duration = 0.1
local pickup_inv_duration = 1/pickup_duration*0.7
local function tick()
minetest.after(0.1, tick)
local tstamp = minetest.get_us_time()
for _,player in ipairs(minetest.get_connected_players()) do
if player:get_hp() > 0 or not enable_damage then
local pos = player:getpos()
pos.y = pos.y + player_half_height
local inv = player:get_inventory()
local player_name = player:get_player_name()
if die_time[player_name] and die_time[player_name] < 1 then
if player:get_hp() > 0 or not enable_damage then
local pos = player:getpos()
pos.y = pos.y + player_half_height
local inv = player:get_inventory()
if inv then
for _,object in ipairs(minetest.get_objects_inside_radius(pos, scan_range)) do
local luaEnt = object:get_luaentity()
if luaEnt and luaEnt.name == "__builtin:item" then
local ticky = luaEnt.item_drop_min_tstamp
if ticky then
if tstamp >= ticky then
luaEnt.item_drop_min_tstamp = nil
end
elseif not luaEnt.item_drop_nopickup then
-- Point-line distance computation, heavily simplified since the wanted line,
-- being the player, is completely upright (no variation on X or Z)
local pos2 = object:getpos()
-- No sqrt, avoid useless computation
-- (just take the radius, compare it to the square of what you want)
-- Pos order doesn't really matter, we're squaring the result
-- (but don't change it, we use the cached values afterwards)
local dX = pos.x-pos2.x
local dZ = pos.z-pos2.z
local playerDistance = dX*dX+dZ*dZ
if playerDistance <= pickup_range_squared then
local itemStack = ItemStack(luaEnt.itemstring)
if inv:room_for_item("main", itemStack) then
local vec = {x=dX, y=pos.y-pos2.y, z=dZ}
vec.x = vec.x*pickup_inv_duration
vec.y = vec.y*pickup_inv_duration
vec.z = vec.z*pickup_inv_duration
object:setvelocity(vec)
luaEnt.physical_state = false
luaEnt.object:set_properties({
physical = false
})
-- Mark the object as already picking up
luaEnt.item_drop_nopickup = true
if inv then
for _,object in ipairs(minetest.get_objects_inside_radius(pos, scan_range)) do
local luaEnt = object:get_luaentity()
if luaEnt and luaEnt.name == "__builtin:item" then
local ticky = luaEnt.item_drop_min_tstamp
if ticky then
if tstamp >= ticky then
luaEnt.item_drop_min_tstamp = nil
end
elseif not luaEnt.item_drop_nopickup then
-- Point-line distance computation, heavily simplified since the wanted line,
-- being the player, is completely upright (no variation on X or Z)
local pos2 = object:getpos()
-- No sqrt, avoid useless computation
-- (just take the radius, compare it to the square of what you want)
-- Pos order doesn't really matter, we're squaring the result
-- (but don't change it, we use the cached values afterwards)
local dX = pos.x-pos2.x
local dZ = pos.z-pos2.z
local playerDistance = dX*dX+dZ*dZ
if playerDistance <= pickup_range_squared then
local itemStack = ItemStack(luaEnt.itemstring)
if inv:room_for_item("main", itemStack) then
local vec = {x=dX, y=pos.y-pos2.y, z=dZ}
vec.x = vec.x*pickup_inv_duration
vec.y = vec.y*pickup_inv_duration
vec.z = vec.z*pickup_inv_duration
object:setvelocity(vec)
luaEnt.physical_state = false
luaEnt.object:set_properties({
physical = false
})
-- Mark the object as already picking up
luaEnt.item_drop_nopickup = true
minetest.after(pickup_duration, function()
local lua = luaEnt
if object == nil or lua == nil or lua.itemstring == nil then
return
end
if inv:room_for_item("main", itemStack) then
inv:add_item("main", itemStack)
if luaEnt.itemstring ~= "" then
minetest.sound_play("item_drop_pickup", {pos = pos, gain = 0.3, max_hear_distance = 8})
minetest.after(pickup_duration, function()
local lua = luaEnt
if object == nil or lua == nil or lua.itemstring == nil then
return
end
luaEnt.itemstring = ""
object:remove()
for i, cb in ipairs(item_drop.pickup_callbacks) do
cb(player, itemstack)
if inv:room_for_item("main", itemStack) then
inv:add_item("main", itemStack)
if luaEnt.itemstring ~= "" then
minetest.sound_play("item_drop_pickup", {pos = pos, gain = 0.3, max_hear_distance = 8})
end
luaEnt.itemstring = ""
object:remove()
for i, cb in ipairs(item_drop.pickup_callbacks) do
cb(player, itemstack)
end
else
object:setvelocity({x = 0,y = 0,z = 0})
luaEnt.physical_state = true
luaEnt.object:set_properties({
physical = true
})
luaEnt.item_drop_nopickup = nil
end
else
object:setvelocity({x = 0,y = 0,z = 0})
luaEnt.physical_state = true
luaEnt.object:set_properties({
physical = true
})
luaEnt.item_drop_nopickup = nil
end
end)
end)
end
end
end
end
end
end
end
else
if die_respawned[player_name] then
die_time[player_name] = (die_time[player_name] or die_timeout) - TICK_UPDATE
end
end
end
minetest.after(TICK_UPDATE, tick)
end
local mt_handle_node_drops = minetest.handle_node_drops
@ -149,7 +188,7 @@ end
local mt_item_drop = minetest.item_drop
function minetest.item_drop(itemstack, dropper, pos)
if dropper.is_player then
if dropper and dropper.is_player then
local v = dropper:get_look_dir()
local p = {x=pos.x, y=pos.y+1.2, z=pos.z}
local cs = itemstack:get_count()

View File

@ -360,6 +360,7 @@ local permafire = table.copy(minetest.registered_nodes["fire:basic_flame"])
permafire.stack_max = 10000
permafire.range = 12
permafire.description = S("Permanent Fire")
permafire.groups = {not_in_creative_inventory = maptools.creative}
minetest.register_node("maptools:permanent_fire", permafire)

View File

@ -10,7 +10,7 @@ minetest.register_node("mesecons:mesecon_off", {
type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, -0.45, 0.5},
},
groups = {dig_immediate=3, mesecon=1, mesecon_conductor_craftable=1},
groups = {dig_immediate=2, mesecon=1, mesecon_conductor_craftable=1}, --MFF
description="Mesecons",
mesecons = {conductor={
state = mesecon.state.off,
@ -28,7 +28,7 @@ minetest.register_node("mesecons:mesecon_on", {
type = "fixed",
fixed = {-0.5, -0.5, -0.5, 0.5, -0.45, 0.5},
},
groups = {dig_immediate=3, not_in_creaive_inventory=1, mesecon=1},
groups = {dig_immediate=2, not_in_creaive_inventory=1, mesecon=1}, --MFF
drop = "mesecons:mesecon_off 1",
light_source = default.LIGHT_MAX-11,
mesecons = {conductor={

View File

@ -197,9 +197,9 @@ register_wires = function()
offstate = "mesecons:wire_"..nodeid.."_off"
}}
local groups_on = {dig_immediate = 3, mesecon_conductor_craftable = 1,
not_in_creative_inventory = 1}
local groups_off = {dig_immediate = 3, mesecon_conductor_craftable = 1}
local groups_on = {dig_immediate = 2, mesecon_conductor_craftable = 1,
not_in_creative_inventory = 1} --MFF
local groups_off = {dig_immediate = 2, mesecon_conductor_craftable = 1} --MFF
if nodeid ~= "00000000" then
groups_off["not_in_creative_inventory"] = 1
end

View File

@ -7,8 +7,8 @@ local GET_COMMAND = "GET"
local object_detector_make_formspec = function (pos)
local meta = minetest.get_meta(pos)
meta:set_string("formspec", "size[9,2.5]" ..
"field[0.3, 0;9,2;scanname;Name of player to scan for (empty for any):;${scanname}]"..
"field[0.3,1.5;4,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]"..
"field[0.3, 0;12,2;scanname;Name of player(s) to scan for (empty for any, separate with comma):;${scanname}]"..
"field[0.3,1.5;4 ,2;digiline_channel;Digiline Channel (optional):;${digiline_channel}]"..
"button_exit[7,0.75;2,3;;Save]")
end
@ -26,11 +26,23 @@ local object_detector_scan = function (pos)
local objs = minetest.get_objects_inside_radius(pos, mesecon.setting("detector_radius", 6))
for k, obj in pairs(objs) do
local isname = obj:get_player_name() -- "" is returned if it is not a player; "" ~= nil!
local scanname = minetest.get_meta(pos):get_string("scanname")
if (isname == scanname and isname ~= "") or (isname ~= "" and scanname == "") then -- player with scanname found or not scanname specified
local scanname = minetest.get_meta(pos):get_string("scanname"):gsub(' ', "")
if (scanname == "" and isname ~= "") then
minetest.get_meta(pos):set_string("scanedname", "")
return true
end
local founds = {}
for _, name in pairs(scanname:split(',')) do
if (isname == name and isname ~= "") then
table.insert(founds, isname)
end
end
if #founds > 0 then
minetest.get_meta(pos):set_string("scannedname", table.concat(founds, ','))
return true
end
end
minetest.get_meta(pos):set_string("scanedname", "")
return false
end
@ -41,7 +53,7 @@ local object_detector_digiline = {
local meta = minetest.get_meta(pos)
local active_channel = meta:get_string("digiline_channel")
if channel == active_channel then
meta:set_string("scanname", msg)
meta:set_string("scanedname", msg)
object_detector_make_formspec(pos)
end
end,

View File

@ -37,7 +37,7 @@ minetest.register_node("mesecons_extrawires:corner_on", {
sunlight_propagates = true,
selection_box = corner_selectionbox,
node_box = corner_nodebox,
groups = {dig_immediate = 3, not_in_creative_inventory = 1},
groups = {dig_immediate = 2, not_in_creative_inventory = 1}, -- MFF
drop = "mesecons_extrawires:corner_off",
mesecons = {conductor =
{
@ -64,7 +64,7 @@ minetest.register_node("mesecons_extrawires:corner_off", {
sunlight_propagates = true,
selection_box = corner_selectionbox,
node_box = corner_nodebox,
groups = {dig_immediate = 3},
groups = {dig_immediate = 2}, --MFF
mesecons = {conductor =
{
state = mesecon.state.off,

View File

@ -41,7 +41,7 @@ minetest.register_node("mesecons_extrawires:crossover_off", {
{ -3/32, -17/32, 6/32, 3/32, -13/32, 16/32+0.001 },
},
},
groups = {dig_immediate=3, mesecon=3},
groups = {dig_immediate=2, mesecon=3}, --MFF
mesecons = {
conductor = {
states = crossover_states,
@ -77,7 +77,7 @@ minetest.register_node("mesecons_extrawires:crossover_01", {
{ -3/32, -17/32, 6/32, 3/32, -13/32, 16/32+0.001 },
},
},
groups = {dig_immediate=3, mesecon=3, not_in_creative_inventory=1},
groups = {dig_immediate=2, mesecon=3, not_in_creative_inventory=1}, --MFF
mesecons = {
conductor = {
states = crossover_states,

View File

@ -38,7 +38,7 @@ minetest.register_node("mesecons_extrawires:tjunction_on", {
sunlight_propagates = true,
selection_box = tjunction_selectionbox,
node_box = tjunction_nodebox,
groups = {dig_immediate = 3, not_in_creative_inventory = 1},
groups = {dig_immediate = 2, not_in_creative_inventory = 1}, --MFF
drop = "mesecons_extrawires:tjunction_off",
mesecons = {conductor =
{
@ -65,7 +65,7 @@ minetest.register_node("mesecons_extrawires:tjunction_off", {
sunlight_propagates = true,
selection_box = tjunction_selectionbox,
node_box = tjunction_nodebox,
groups = {dig_immediate = 3},
groups = {dig_immediate = 2}, --MFF
mesecons = {conductor =
{
state = mesecon.state.off,

View File

@ -86,7 +86,7 @@ mesecon.register_node("mesecons_extrawires:vertical", {
after_dig_node = vertical_update
},{
tiles = {"mesecons_wire_off.png"},
groups = {dig_immediate=3},
groups = {dig_immediate=2}, --MFF
vertical_conductor_state = "off",
mesecons = {conductor = {
state = mesecon.state.off,
@ -95,7 +95,7 @@ mesecon.register_node("mesecons_extrawires:vertical", {
}}
},{
tiles = {"mesecons_wire_on.png"},
groups = {dig_immediate=3, not_in_creative_inventory=1},
groups = {dig_immediate=2, not_in_creative_inventory=1}, --MFF
vertical_conductor_state = "on",
mesecons = {conductor = {
state = mesecon.state.on,
@ -111,7 +111,7 @@ mesecon.register_node("mesecons_extrawires:vertical_top", {
walkable = false,
paramtype = "light",
sunlight_propagates = true,
groups = {dig_immediate=3, not_in_creative_inventory=1},
groups = {dig_immediate=2, not_in_creative_inventory=1}, --MFF
selection_box = top_box,
node_box = top_box,
is_vertical_conductor = true,
@ -143,7 +143,7 @@ mesecon.register_node("mesecons_extrawires:vertical_bottom", {
walkable = false,
paramtype = "light",
sunlight_propagates = true,
groups = {dig_immediate = 3, not_in_creative_inventory = 1},
groups = {dig_immediate = 2, not_in_creative_inventory = 1}, --MFF
selection_box = bottom_box,
node_box = bottom_box,
is_vertical_conductor = true,

View File

@ -30,7 +30,7 @@ minetest.register_node("mesecons_insulated:insulated_on", {
type = "fixed",
fixed = { -16/32-0.001, -17/32, -3/32, 16/32+0.001, -13/32, 3/32 }
},
groups = {dig_immediate = 3, not_in_creative_inventory = 1},
groups = {dig_immediate = 2, not_in_creative_inventory = 1}, --MFF
drop = "mesecons_insulated:insulated_off",
mesecons = {conductor = {
state = mesecon.state.on,
@ -62,7 +62,7 @@ minetest.register_node("mesecons_insulated:insulated_off", {
type = "fixed",
fixed = { -16/32-0.001, -17/32, -3/32, 16/32+0.001, -13/32, 3/32 }
},
groups = {dig_immediate = 3},
groups = {dig_immediate = 2}, --MFF
mesecons = {conductor = {
state = mesecon.state.off,
onstate = "mesecons_insulated:insulated_on",

View File

@ -1,4 +1,4 @@
-- Mobs Api (8th February 2016)
-- Mobs Api (9th February 2016)
mobs = {}
mobs.mod = "redo"
@ -1986,7 +1986,7 @@ end -- END mobs:register_mob function
mobs.spawning_mobs = {}
function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
interval, chance, active_object_count, min_height, max_height, spawn_in_area) --MFF crabman
interval, chance, active_object_count, min_height, max_height, spawn_in_area, day_toggle) --MFF crabman "spawn_in_area"
mobs.spawning_mobs[name] = true
@ -1995,7 +1995,7 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
if new_chance ~= nil then
if chance == 0 then
if new_chance == 0 then
--print("[Mobs Redo] " .. name .. " has spawning disabled")
return
end
@ -2022,6 +2022,24 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
return
end
-- if toggle set to nil then ignore day/night check
if day_toggle ~= nil then
local tod = (minetest.get_timeofday() or 0) * 24000
if tod > 4500 and tod < 19500 then
-- daylight, but mob wants night
if day_toggle == false then
return
end
else
-- night time but mob wants day
if day_toggle == true then
return
end
end
end
-- spawn above node
pos.y = pos.y + 1
@ -2082,10 +2100,10 @@ function mobs:spawn_specific(name, nodes, neighbors, min_light, max_light,
end
-- compatibility with older mob registration
function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height)
function mobs:register_spawn(name, nodes, max_light, min_light, chance, active_object_count, max_height, spawn_in_area, day_toggle)
mobs:spawn_specific(name, nodes, {"air"}, min_light, max_light, 30,
chance, active_object_count, -31000, max_height)
chance, active_object_count, -31000, max_height, spawn_in_area, day_toggle)
end
-- set content id's
@ -2308,7 +2326,7 @@ function mobs:register_egg(mob, desc, background, addegg)
inventory_image = invimg,
groups = {not_in_creative_inventory = 1}, -- MFF creative (Mg|11/25/2015)
on_place = function(itemstack, placer, pointed_thing)
if not minetest.check_player_privs(placer:get_player_name(), {server=true}) then -- MFF creative
if not minetest.check_player_privs(placer:get_player_name(), {server=true}) then -- MFF
return
end
local pos = pointed_thing.above

View File

@ -49,7 +49,7 @@ mobs:register_mob("mobs:bee", {
end,
})
-- spawn on group:flowers between 4 and 20 light, 1 in 5000 chance, 1 bee in area up to 31000 in height
mobs:spawn_specific("mobs:bee", {"group:flower"}, {"air"}, 4, 20, 30, 5000, 1, -31000, 31000, true)
mobs:spawn_specific("mobs:bee", {"group:flower"}, {"air"}, 4, 20, 30, 5000, 2, -31000, 31000, true, true)
-- register spawn egg
mobs:register_egg("mobs:bee", "Bee", "mobs_bee_inv.png", 1)
@ -73,9 +73,13 @@ minetest.register_node("mobs:beehive", {
groups = {fleshy=3,dig_immediate=3},
on_use = minetest.item_eat(4),
sounds = default.node_sound_defaults(),
after_place_node = function(pos, placer, itemstack)
if placer:is_player() then
minetest.set_node(pos, {name = "mobs:beehive", param2 = 1})
if math.random(1, 5) == 1 then
minetest.add_entity(pos, "mobs:bee")
end
@ -113,4 +117,4 @@ minetest.register_craft({
recipe = {
{"mobs:honey_block"},
}
})
})

View File

@ -51,9 +51,9 @@ mobs:register_mob("mobs:bunny", {
},
-- follows carrot from farming redo
follow = {"farming:carrot", "farming_plus:carrot_item"},
view_range = 10,
view_range = 8,
-- eat carrots
replace_rate = 80,
replace_rate = 10,
replace_what = {"farming:carrot_7", "farming:carrot_8", "farming_plus:carrot"},
replace_with = "air",
-- right click to pick up rabbit
@ -90,5 +90,5 @@ mobs:register_mob("mobs:bunny", {
attack_type = "dogfight",
damage = 5,
})
mobs:spawn_specific("mobs:bunny", {"default:dirt_with_grass"}, {"air"}, 8, 20, 30, 10000, 1, -31000, 31000, true)
mobs:spawn_specific("mobs:bunny", {"default:dirt_with_grass"}, {"air"}, 8, 20, 30, 10000, 2, -31000, 31000, true, true)
mobs:register_egg("mobs:bunny", "Bunny", "mobs_bunny_inv.png", 1)

View File

@ -58,20 +58,26 @@ mobs:register_mob("mobs:chicken", {
},
-- follows wheat
follow = {"farming:seed_wheat", "farming:seed_cotton"},
view_range = 8,
view_range = 5,
on_rightclick = function(self, clicker)
if mobs:feed_tame(self, clicker, 8, true, true) then
return
end
mobs:capture_mob(self, clicker, 30, 50, 80, false, nil)
end,
do_custom = function(self)
if not self.child
and math.random(1, 500) == 1 then
local pos = self.object:getpos()
minetest.add_item(pos, "mobs:egg")
minetest.sound_play("default_place_node_hard", {
pos = pos,
gain = 1.0,
@ -81,7 +87,7 @@ mobs:register_mob("mobs:chicken", {
end,
})
-- spawn on default or bamboo grass between 8 and 20 light, 1 in 10000 change, 1 chicken in area up to 31000 in height
mobs:spawn_specific("mobs:chicken", {"default:dirt_with_grass"}, {"air"}, 8, 20, 30, 10000, 1, -31000, 31000, true)
mobs:spawn_specific("mobs:chicken", {"default:dirt_with_grass"}, {"air"}, 8, 20, 30, 10000, 2, -31000, 31000, true, true)
-- register spawn egg
mobs:register_egg("mobs:chicken", "Chicken", "mobs_chicken_inv.png", 1)
-- egg entity
@ -109,16 +115,22 @@ mobs:register_arrow("mobs:egg_entity", {
hit_node = function(self, pos, node)
local num = math.random(1, 10)
if num == 1 then
pos.y = pos.y + 1
local nod = minetest.get_node_or_nil(pos)
if not nod
or not minetest.registered_nodes[nod.name]
or minetest.registered_nodes[nod.name].walkable == true then
return
end
local mob = minetest.add_entity(pos, "mobs:chicken")
local ent2 = mob:get_luaentity()
mob:set_properties({
textures = ent2.child_texture[1],
visual_size = {
@ -134,6 +146,7 @@ mobs:register_arrow("mobs:egg_entity", {
ent2.base_colbox[6] / 2
},
})
ent2.child = true
ent2.tamed = true
ent2.owner = self.playername
@ -148,35 +161,45 @@ local egg_VELOCITY = 19
-- shoot egg
local mobs_shoot_egg = function (item, player, pointed_thing)
local playerpos = player:getpos()
minetest.sound_play("default_place_node_hard", {
pos = playerpos,
gain = 1.0,
max_hear_distance = 5,
})
local obj = minetest.add_entity({
x = playerpos.x,
y = playerpos.y +1.5,
z = playerpos.z
}, "mobs:egg_entity")
local ent = obj:get_luaentity()
local dir = player:get_look_dir()
ent.velocity = egg_VELOCITY -- needed for api internal timing
ent.switch = 1 -- needed so that egg doesn't despawn straight away
obj:setvelocity({
x = dir.x * egg_VELOCITY,
y = dir.y * egg_VELOCITY,
z = dir.z * egg_VELOCITY
})
obj:setacceleration({
x = dir.x * -3,
y = -egg_GRAVITY,
z = dir.z * -3
})
-- pass player name to egg for chick ownership
local ent2 = obj:get_luaentity()
ent2.playername = player:get_player_name()
item:take_item()
return item
end
@ -236,4 +259,4 @@ minetest.register_craft({
type = "cooking",
recipe = "mobs:chicken_raw",
output = "mobs:chicken_cooked",
})
})

View File

@ -60,8 +60,8 @@ mobs:register_mob("mobs:cow", {
punch_end = 100,
},
follow = "farming:wheat",
view_range = 8,
replace_rate = 50,
view_range = 7,
replace_rate = 10,
replace_what = {"default:grass_3", "default:grass_4", "default:grass_5", "farming:wheat_8"},
replace_with = "air",
fear_height = 2,
@ -110,7 +110,7 @@ mobs:register_mob("mobs:cow", {
})
-- spawn on default;green;prairie grass between 0 and 20 light, 1 in 11000 chance, 1 cow in area up to 31000 in height
mobs:spawn_specific("mobs:cow", {"default:dirt_with_grass"}, {"air"}, 8, 20, 30, 10000, 1, -31000, 31000, true)
mobs:spawn_specific("mobs:cow", {"default:dirt_with_grass"}, {"air"}, 8, 20, 30, 10000, 2, -31000, 31000, true, true)
-- register spawn egg
mobs:register_egg("mobs:cow", "Cow", "mobs_cow_inv.png", 1)

View File

@ -45,11 +45,16 @@ mobs:register_mob("mobs:creeper", {
light_damage = 0,
-- model animation
animation = {
stand_start = 0, stand_end = 24,
walk_start = 25, walk_end = 47,
run_start = 48, run_end = 62,
punch_start = 48, punch_end = 62,
speed_normal = 15, speed_run = 15,
stand_start = 0,
stand_end = 24,
walk_start = 25,
walk_end = 47,
run_start = 48,
run_end = 62,
punch_start = 48,
punch_end = 62,
speed_normal = 15,
speed_run = 15,
},
})
mobs:spawn_specific("mobs:creeper", {"default:dirt_with_grass"}, {"air"}, 8, 20, 30, 20000, 1, -31000, 31000, false)

View File

@ -33,25 +33,39 @@ mobs:register_mob("mobs:dirt_monster", {
jump = true,
-- drops dirt and coins when dead
drops = {
{name = "default:dirt",
chance = 1, min = 3, max = 5,},
{name = "maptools:silver_coin",
chance = 2, min = 1, max = 1,},
{name = "default:dirt", chance = 1, min = 3, max = 5,},
{name = "maptools:silver_coin", chance = 2, min = 1, max = 1,},
},
-- damaged by
water_damage = 1,
lava_damage = 5,
light_damage = 2,
fear_height = 3,
-- model animation
animation = {
speed_normal = 15, speed_run = 15,
stand_start = 0, stand_end = 14,
walk_start = 15, walk_end = 38,
run_start = 40, run_end = 63,
punch_start = 40, punch_end = 63,
speed_normal = 15,
speed_run = 15,
stand_start = 0,
stand_end = 14,
walk_start = 15,
walk_end = 38,
run_start = 40,
run_end = 63,
punch_start = 40,
punch_end = 63,
},
})
-- spawn on dirt_with_grass and drygrass between -1 and 5 light, 1 in 10000 change, 1 dirt monster in area up to 31000 in height
mobs:spawn_specific("mobs:dirt_monster", {"default:dirt_with_grass", "default:dirt_with_dry_grass"}, {"air"}, -1, 5, 30, 10000, 1, -31000, 31000, false)
mobs:spawn_specific("mobs:dirt_monster", {"default:dirt_with_grass", "default:dirt_with_dry_grass"}, {"air"}, -1, 5, 30, 10000, 1, -31000, 31000, false, false)
-- register spawn egg
mobs:register_egg("mobs:dirt_monster", "Dirt Monster", "mobs_dirt_monster_inv.png", 1)
minetest.register_craft({
output = "mobs:dirt_monster",
recipe = {
{"default:dirt", "default:dirt", "default:dirt"},
{"default:dirt", "default:nyancat_rainbow", "default:dirt"},
{"default:dirt", "default:dirt", "default:dirt"}
}
})

View File

@ -43,29 +43,28 @@ mobs:register_mob("mobs:dungeon_master", {
knock_back = 0.05, -- Very small knockback
-- drops mese or diamond when dead
drops = {
{name = "mobs:dungeon_master_blood",
chance = 2, min = 1, max = 2,},
{name = "default:diamond",
chance = 4, min = 1, max = 3,},
{name = "default:mese_crystal",
chance = 4, min = 3, max = 6,},
{name = "mobs:dungeon_master_diamond",
chance = 6, min = 1, max = 1,},
{name = "maptools:gold_coin",
chance = 20, min = 1, max = 1,},
{name = "default:diamondblock",
chance = 33, min = 1, max = 1,},
{name = "mobs:dungeon_master_blood", chance = 2, min = 1, max = 2,},
{name = "default:diamond", chance = 4, min = 1, max = 3,},
{name = "default:mese_crystal", chance = 4, min = 3, max = 6,},
{name = "mobs:dungeon_master_diamond", chance = 6, min = 1, max = 1,},
{name = "maptools:gold_coin", chance = 20, min = 1, max = 1,},
{name = "default:diamondblock", chance = 33, min = 1, max = 1,},
},
-- damaged by
water_damage = 1,
lava_damage = 1,
light_damage = 0,
fear_height = 3,
-- model animation
animation = {
stand_start = 0, stand_end = 19,
walk_start = 20, walk_end = 35,
punch_start = 36, punch_end = 48,
speed_normal = 15, speed_run = 15,
stand_start = 0,
stand_end = 19,
walk_start = 20,
walk_end = 35,
punch_start = 36,
punch_end = 48,
speed_normal = 15,
speed_run = 15,
},
})
-- spawn on stone between 20 and -1 light, 1 in 7000 chance, 1 dungeon master in area starting at -100 and below

106
mods/mobs/ent.lua Executable file
View File

@ -0,0 +1,106 @@
-- Ent from https://github.com/Minetest-LOTT/Lord-of-the-Test
mobs:register_mob("mobs:ent", {
type = "npc",
hp_min = 50,
hp_max = 70,
collisionbox = {-0.5, 0, -0.5, 0.5, 5, 0.5},
textures = {
{"mobs_ent.png"},
},
visual_size = {x=3.5,y=3.5},
visual = "mesh",
mesh = "mobs_ent.x",
view_range = 20,
makes_footstep_sound = true,
walk_velocity = 1,
run_velocity = 1.5,
armor = 100,
damage = 5,
drops = {
{name = "default:sapling",
chance = 5,
min = 1,
max = 3,},
{name = "moretrees:apple_tree_sapling",
chance = 5,
min = 1,
max = 3,},
{name = "moretrees:birch_sapling",
chance = 5,
min = 1,
max = 3,},
{name = "moretrees:beech_sapling",
chance = 5,
min = 1,
max = 3,},
{name = "moretrees:acacia_sapling",
chance = 5,
min = 1,
max = 3,},
{name = "moretrees:pine_sapling",
chance = 5,
min = 1,
max = 3,},
{name = "moretrees:fir_sapling",
chance = 5,
min = 1,
max = 3,},
{name = "moretrees:rubber_tree_sapling",
chance = 5,
min = 1,
max = 3,},
},
light_resistant = true,
drawtype = "front",
water_damage = 0,
lava_damage = 60,
light_damage = 0,
attack_type = "dogfight",
animation = {
speed_normal = 15,
speed_run = 15,
stand_start = 17,
stand_end = 17,
walk_start = 10,
walk_end = 80,
run_start = 10,
run_end = 80,
punch_start = 1,
punch_end = 1,
},
jump = true,
sounds = {
war_cry = "mobs_die_yell",
death = "mobs_yeti_death",
attack = "default_punch2",
},
attacks_monsters = true,
peaceful = true,
group_attack = true,
step = 1,
})
minetest.register_node("mobs:ent_spawner", {
description = "Ent Spawner",
tiles = {"default_tree_top.png", "default_tree_top.png", "default_tree.png^mobs_chicken_egg.png"},
is_ground_content = false,
groups = {unbreakable = 1, mob_spawner=1},
})
minetest.register_node("mobs:tree_monster_spawner", {
description = "Tree Monster Spawner",
tiles = {"default_wood.png^mobs_chicken_egg.png"},
is_ground_content = false,
groups = {unbreakable = 1, mob_spawner=1},
})
-- Boss
-- spawn on mobs:ent_spawner between 1 and 20 light, 4 interval, 1 chance, 1 ent in area up to 31000 in height
mobs:spawn_specific("mobs:ent", {"mobs:ent_spawner"}, {"air"}, 1, 20, 300, 1, 100, -31000, 31000, true)
mobs:register_egg("mobs:ent", "Ent", "mobs_ent_inv.png", 1)
-- Minions
-- spawn on mobs:pumpboom_spawner between 1 and 20 light, 4 interval, 1 chance, 1 pumpboom in area up to 31000 in height
mobs:spawn_specific("mobs:tree_monster", {"mobs:tree_monster_spawner"}, {"air"}, 1, 20, 10, 4, 100, -31000, 31000, true)

View File

@ -44,10 +44,8 @@ mobs:register_mob("mobs:greensmall", {
floats = 1,
-- chance of dropping glue and coins
drops = {
{name = "mesecons_materials:glue",
chance = 4, min = 1, max = 2},
{name = "maptools:silver_coin",
chance = 4, min = 1, max = 1,},
{name = "mesecons_materials:glue", chance = 4, min = 1, max = 2},
{name = "maptools:silver_coin", chance = 4, min = 1, max = 1,},
},
-- damaged by
water_damage = 0,

View File

@ -26,6 +26,7 @@ dofile(path.."/sandmonster.lua") -- PilzAdam
dofile(path.."/stonemonster.lua") -- PilzAdam
dofile(path.."/treemonster.lua") -- PilzAdam
dofile(path.."/wolf.lua") -- PilzAdam
dofile(path.."/dog.lua") -- CProgrammerRU
--dofile(path.."/lava_flan.lua") -- Zeg9 --Remplaced by Lava Slimes
dofile(path.."/mese_monster.lua") -- Zeg9
dofile(path.."/spider.lua") -- AspireMint
@ -34,6 +35,10 @@ dofile(path.."/lavaslimes.lua") -- davedevils/TomasJLuis/TenPlus1
dofile(path.."/zombie.lua") -- ???
dofile(path.."/yeti.lua") -- ???
dofile(path.."/minotaur.lua") -- Kalabasa
-- The bosses
dofile(path.."/pumpkins.lua")
dofile(path.."/ent.lua")
]]
-- begin slimes mobs compatibility changes

View File

@ -54,11 +54,13 @@ mobs:register_mob("mobs:kitten", {
view_range = 10,
-- feed with raw fish to tame or right click to pick up
on_rightclick = function(self, clicker)
if mobs:feed_tame(self, clicker, 4, true, true) then
return
end
mobs:capture_mob(self, clicker, 50, 50, 90, false, nil)
end
})
mobs:spawn_specific("mobs:kitten", {"default:dirt_with_grass"}, {"air"}, 0, 20, 30, 10000, 1, -31000, 31000, true)
mobs:spawn_specific("mobs:kitten", {"default:dirt_with_grass"}, {"air"}, 0, 20, 30, 10000, 1, -31000, 31000, true, true)
mobs:register_egg("mobs:kitten", "Kitten", "mobs_kitten_inv.png", 0)

View File

@ -7,6 +7,7 @@ mobs:register_mob("mobs:lava_flan", {
-- aggressive, deals 5 damage to player when hit
passive = false,
attack_type = "dogfight",
reach = 2,
damage = 5,
-- health and armor
hp_min = 20,
@ -35,8 +36,7 @@ mobs:register_mob("mobs:lava_flan", {
floats = 1,
-- chance of dropping lava orb when dead
drops = {
{name = "mobs:lava_orb",
chance = 15, min = 1, max = 1},
{name = "mobs:lava_orb", chance = 15, min = 1, max = 1},
},
-- damaged by
water_damage = 5,
@ -44,11 +44,16 @@ mobs:register_mob("mobs:lava_flan", {
light_damage = 0,
-- model animation
animation = {
speed_normal = 15, speed_run = 15,
stand_start = 0, stand_end = 8,
walk_start = 10, walk_end = 18,
run_start = 20, run_end = 28,
punch_start = 20, punch_end = 28,
speed_normal = 15,
speed_run = 15,
stand_start = 0,
stand_end = 8,
walk_start = 10,
walk_end = 18,
run_start = 20,
run_end = 28,
punch_start = 20,
punch_end = 28,
},
-- do things when die
on_die = function(self, pos)
@ -66,4 +71,4 @@ minetest.register_craftitem("mobs:lava_orb", {
inventory_image = "zmobs_lava_orb.png",
})
minetest.register_alias("zmobs:lava_orb", "mobs:lava_orb")
minetest.register_alias("zmobs:lava_orb", "mobs:lava_orb")

View File

@ -22,7 +22,8 @@ mobs:register_mob("mobs:lavasmall", {
attack_type = "dogfight",
attacks_monsters = true,
-- health and armor
hp_min = 4, hp_max = 8,
hp_min = 4,
hp_max = 8,
armor = 100,
-- textures and model
collisionbox = {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25},
@ -46,10 +47,8 @@ mobs:register_mob("mobs:lavasmall", {
floats = 1,
-- chance of dropping lava orb and coins
drops = {
{name = "mobs:lava_orb",
chance = 15, min = 1, max = 1,},
{name = "maptools:silver_coin",
chance = 4, min = 1, max = 1,},
{name = "mobs:lava_orb", chance = 15, min = 1, max = 1,},
{name = "maptools:silver_coin", chance = 4, min = 1, max = 1,},
},
-- damaged by
water_damage = 10,
@ -70,7 +69,8 @@ mobs:register_mob("mobs:lavamedium", {
attack_type = "dogfight",
attacks_monsters = true,
-- health and armor
hp_min = 16, hp_max = 32,
hp_min = 16,
hp_max = 32,
armor = 90,
-- textures and model
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
@ -162,6 +162,7 @@ mobs:register_mob("mobs:lavabig", {
end
end,
})
mobs:register_egg("mobs:lavabig", "Big Lava Slime", "mobs_lava_slime_big_inv.png", 1)
--mobs:spawn_specific(name, nodes, neighbors, min_light, max_light, interval, chance, active_object_count, min_height, max_height)

View File

@ -6,7 +6,7 @@ mobs:register_mob("mobs:mese_monster", {
type = "monster",
-- agressive, deals 9 damage to player when hit
passive = false,
damage = 8,
damage = 7,
attack_type = "shoot",
shoot_interval = 1.0,
arrow = "mobs:mese_arrow",
@ -37,16 +37,13 @@ mobs:register_mob("mobs:mese_monster", {
jump_height = 8,
fall_damage = 0,
fall_speed = -6,
stepheight = 2.1,
-- drops mese when dead
drops = {
{name = "default:mese_crystal",
chance = 9, min = 1, max = 3,},
{name = "default:mese_crystal_fragment",
chance = 1, min = 1, max = 9,},
{name = "maptools:silver_coin",
chance = 1, min = 1, max = 2,},
{name = "returnmirror:mirror_inactive",
chance = 50, min = 1, max = 1,},
{name = "default:mese_crystal", chance = 9, min = 1, max = 3,},
{name = "default:mese_crystal_fragment", chance = 1, min = 1, max = 9,},
{name = "maptools:silver_coin", chance = 1, min = 1, max = 2,},
{name = "returnmirror:mirror_inactive", chance = 50, min = 1, max = 1,},
},
-- damaged by
water_damage = 0,
@ -79,14 +76,14 @@ mobs:register_arrow("mobs:mese_arrow", {
velocity = 6,
hit_player = function(self, player)
player:punch(self.object, 1.0, {
player:punch(self.object, 1.0, {
full_punch_interval = 1.0,
damage_groups = {fleshy = 8}, --Modif MFF
}, nil)
end,
hit_mob = function(self, player)
player:punch(self.object, 1.0, {
player:punch(self.object, 1.0, {
full_punch_interval = 1.0,
damage_groups = {fleshy = 8}, --Modif MFF
}, nil)

View File

@ -7,11 +7,11 @@ mobs:register_mob("mobs:minotaur", {
-- aggressive, deals 11 damage to player when hit
passive = false,
attack_type = "dogfight",
damage = 10,
damage = 7,
-- health & armor
hp_min = 80,
hp_max = 100,
armor = 70,
hp_min = 60,
hp_max = 70,
armor = 90,
-- textures and model
collisionbox = {-0.9,-0.01,-0.9, 0.9,2.5,0.9},
visual = "mesh",
@ -30,22 +30,18 @@ mobs:register_mob("mobs:minotaur", {
-- death = "mobs_zombie_death",
-- },
-- speed and jump
walk_velocity = 3,
run_velocity = 4,
walk_velocity = 2.5,
run_velocity = 3.5,
jump = true,
floats = 1,
view_range = 16,
knock_back = 0.05, --this is a test
-- drops desert_sand and coins when dead
drops = {
{name = "maptools:gold_coin",
chance = 40, min = 1, max = 1,},
{name = "mobs:minotaur_eye",
chance = 2, min = 1, max = 2,},
{name = "mobs:minotaur_horn",
chance = 4, min = 1, max = 2,},
{name = "mobs:minotaur_fur",
chance = 1, min = 1, max = 3,},
{name = "maptools:gold_coin", chance = 40, min = 1, max = 1,},
{name = "mobs:minotaur_eye", chance = 2, min = 1, max = 2,},
{name = "mobs:minotaur_horn", chance = 4, min = 1, max = 2,},
{name = "mobs:minotaur_fur", chance = 1, min = 1, max = 3,},
},
water_damage = 0,
lava_damage = 5,

View File

@ -47,14 +47,10 @@ mobs:register_mob("mobs:npc", {
jump = true,
-- drops wood and chance of apples when dead
drops = {
{name = "default:wood",
chance = 1, min = 1, max = 3},
{name = "default:apple",
chance = 2, min = 1, max = 2},
{name = "default:axe_stone",
chance = 3, min = 1, max = 1},
-- {name = "maptools:silver_coin",
-- chance = 10, min = 1, max = 1,},
{name = "default:wood", chance = 1, min = 1, max = 3},
{name = "default:apple", chance = 2, min = 1, max = 2},
{name = "default:axe_stone", chance = 3, min = 1, max = 1},
{name = "maptools:silver_coin", chance = 10, min = 1, max = 1,},
},
-- damaged by
water_damage = 0,
@ -129,6 +125,6 @@ mobs:register_mob("mobs:npc", {
})
-- spawning enable for now
mobs:spawn_specific("mobs:npc", {"default:dirt_with_grass", "default:dirt", "default:junglegrass", "default:sand"}, {"air"}, -1, 20, 30, 300000, 1, -31000, 31000, true)
mobs:spawn_specific("mobs:npc", {"default:dirt_with_grass", "default:dirt", "default:junglegrass", "default:sand"}, {"air"}, -1, 20, 30, 300000, 1, -31000, 31000, true, true)
-- register spawn egg
mobs:register_egg("mobs:npc", "Npc", "mobs_npc_male_inv.png", 1)

View File

@ -8,7 +8,6 @@ mobs.npc_drops = { "farming:meat", "farming:donut", "farming:bread", "default:a
"default:cobble", "default:gravel", "default:clay_lump", "default:sand", "default:dirt_with_grass",
"default:dirt", "default:chest", "default:torch"}
mobs.npc_max_hp = 20
mobs:register_mob("mobs:npc_female", {
-- animal, monster, npc
@ -20,7 +19,9 @@ mobs:register_mob("mobs:npc_female", {
attack_type = "dogfight",
attacks_monsters = true,
-- health & armor
hp_min = 20, hp_max = 20, armor = 100,
hp_min = 20,
hp_max = 20,
armor = 100,
-- textures and model
collisionbox = {-0.35,-1.0,-0.35, 0.35,0.8,0.35},
visual = "mesh",
@ -46,18 +47,12 @@ mobs:register_mob("mobs:npc_female", {
jump = true,
-- drops wood and chance of apples when dead
drops = {
{name = "default:wood",
chance = 1, min = 1, max = 3},
{name = "default:apple",
chance = 2, min = 1, max = 2},
{name = "flowers:tulip",
chance = 4, min = 1, max = 2},
{name = "flowers:rose",
chance = 4, min = 1, max = 2},
{name = "default:axe_stone",
chance = 6, min = 1, max = 1},
-- {name = "maptools:silver_coin",
-- chance = 10, min = 1, max = 1,},
{name = "default:wood", chance = 1, min = 1, max = 3},
{name = "default:apple", chance = 2, min = 1, max = 2},
{name = "flowers:tulip", chance = 4, min = 1, max = 2},
{name = "flowers:rose", chance = 4, min = 1, max = 2},
{name = "default:axe_stone", chance = 6, min = 1, max = 1},
{name = "maptools:silver_coin", chance = 10, min = 1, max = 1,},
},
-- damaged by
water_damage = 0,
@ -110,6 +105,7 @@ mobs:register_mob("mobs:npc_female", {
item:take_item()
clicker:set_wielded_item(item)
end
local pos = self.object:getpos()
pos.y = pos.y + 0.5
minetest.add_item(pos, {
@ -126,10 +122,11 @@ mobs:register_mob("mobs:npc_female", {
end
mobs:capture_mob(self, clicker, 0, 5, 80, false, nil)
end
end,
})
-- spawning enable for now
mobs:spawn_specific("mobs:npc_female", {"default:dirt_with_grass", "default:dirt", "default:junglegrass", "default:sand"}, {"air"}, -1, 20, 30, 300000, 1, -31000, 31000, true)
mobs:spawn_specific("mobs:npc_female", {"default:dirt_with_grass", "default:dirt", "default:junglegrass", "default:sand"}, {"air"}, -1, 20, 30, 100000, 1, -31000, 31000, true, true)
-- register spawn egg
mobs:register_egg("mobs:npc_female", "Npc", "mobs_npc_female_inv.png", 1)

View File

@ -7,6 +7,7 @@ mobs:register_mob("mobs:oerkki", {
-- aggressive, deals 7 damage when player hit
passive = false,
attack_type = "dogfight",
reach = 2,
damage = 6,
-- health & armor
hp_min = 40,
@ -25,7 +26,7 @@ mobs:register_mob("mobs:oerkki", {
makes_footstep_sound = false,
sounds = {
random = "mobs_oerkki",
attack = "mobs_oerkki_attack",
shoot_attack = "mobs_oerkki_attack",
},
-- speed and jump
walk_velocity = 2,
@ -34,22 +35,26 @@ mobs:register_mob("mobs:oerkki", {
jump = true,
-- chance of dropping obsidian and coins
drops = {
{name = "default:obsidian",
chance = 3, min = 1, max = 2,},
{name = "maptools:silver_coin",
chance = 1, min = 1, max = 1},
{name = "default:obsidian", chance = 3, min = 1, max = 2,},
{name = "maptools:silver_coin", chance = 1, min = 1, max = 1},
},
-- damaged by
water_damage = 2,
lava_damage = 4,
light_damage = 1,
fear_height = 3,
-- model animation
animation = {
stand_start = 0, stand_end = 23,
walk_start = 24, walk_end = 36,
run_start = 37, run_end = 49,
punch_start = 37, punch_end = 49,
speed_normal = 15, speed_run = 15,
stand_start = 0,
stand_end = 23,
walk_start = 24,
walk_end = 36,
run_start = 37,
run_end = 49,
punch_start = 37,
punch_end = 49,
speed_normal = 15,
speed_run = 15,
},
-- replace torch with air (remove)
replace_rate = 50,

View File

@ -6,8 +6,8 @@ mobs:register_mob("mobs:pig", {
type = "animal",
-- aggressive, does 5 damage to player when threatened
passive = false,
group_attack = true,
attack_type = "dogfight",
group_attack = true,
reach = 2,
damage = 4,
-- health & armor
@ -39,10 +39,8 @@ mobs:register_mob("mobs:pig", {
view_range = 10,
-- drops raw pork when dead
drops = {
{name = "mobs:pork_raw",
chance = 1, min = 2, max = 3,},
{name = "maptools:silver_coin",
chance = 10, min = 1, max = 1,},
{name = "mobs:pork_raw", chance = 1, min = 2, max = 3,},
{name = "maptools:silver_coin", chance = 10, min = 1, max = 1,},
},
-- damaged by
water_damage = 1,
@ -52,18 +50,27 @@ mobs:register_mob("mobs:pig", {
-- model animation
animation = {
speed_normal = 15,
stand_start = 25, stand_end = 55,
walk_start = 60, walk_end = 100,
punch_start = 60, punch_end = 100,
stand_start = 25,
stand_end = 55,
walk_start = 60,
walk_end = 100,
punch_start = 60,
punch_end = 100,
},
-- can be tamed by feeding 8 wheat (will not attack when tamed)
on_rightclick = function(self, clicker)
mobs:feed_tame(self, clicker, 8, true, true)
if mobs:feed_tame(self, clicker, 8, true, true) then
return
end
mobs:capture_mob(self, clicker, 0, 5, 50, false, nil)
end,
})
-- spawns on dirt or junglegrass, between 8 and 20 light, 1 in 15000 chance, 1 in area up to 31000 in height
mobs:spawn_specific("mobs:pig", {"default:dirt", "default:junglegrass", "default:dirt_with_dry_grass"}, {"air"}, 8, 20, 30, 10000, 1, -31000, 31000, true)
mobs:spawn_specific("mobs:pig", {"default:dirt", "default:junglegrass", "default:dirt_with_dry_grass"}, {"air"}, 8, 20, 30, 10000, 1, -31000, 31000, true, true)
-- register spawn egg
mobs:register_egg("mobs:pig", "Pig", "mobs_pig_inv.png", 1)

138
mods/mobs/pumpkins.lua Executable file
View File

@ -0,0 +1,138 @@
-- PumpKing by Blert2112
mobs:register_mob("mobs:pumpking", {
type = "monster",
visual = "mesh",
mesh = "mobs_pumpking.x",
textures = {
{"mobs_pumpking.png"}
},
visual_size = {x=3, y=3},
collisionbox = {-0.85, 0.00, -0.85, 0.85, 5.3, 0.85},
animation = {
speed_normal = 15, speed_run = 30,
stand_start = 165, stand_end = 210,
walk_start = 61, walk_end = 110,
run_start = 0, run_end = 50,
punch_start = 150, punch_end = 165
},
makes_footstep_sound = true,
sounds = {
random = "mobs_king"
},
hp_min = 275,
hp_max = 300,
armor = 70,
knock_back = 0,
walk_velocity = 3,
run_velocity = 4,
light_damage = 0,
water_damage = 0,
lava_damage = 0,
fall_damage = 0,
damage = 9,
reach = 5,
attack_type = "dogfight",
view_range = 25,
stepheight = 1.1,
drops = {
-- Ressource & Decoration drops
{name = "farming:jackolantern", chance = 1, min = 1, max = 1},
{name = "default:diamondblock", chance = 2, min = 1, max = 3},
-- Hunter drops
{name = "3d_armor:helmet_hardenedleather", chance = 10, min = 1, max = 1},
{name = "3d_armor:chestplate_hardenedleather", chance = 10, min = 1, max = 1},
{name = "throwing:bow_minotaur_horn", chance = 33, min = 1, max = 1},
-- Warrior drops
{name = "3d_armor:helmet_mithril", chance = 10, min = 1, max = 1},
{name = "3d_armor:chestplate_mithril", chance = 10, min = 1, max = 1},
{name = "moreores:sword_mithril", chance = 33, min = 1, max = 1},
},
lifetimer = 300, -- 5 minutes
--shoot_interval = 1000, -- (lifetimer - (lifetimer / 4)), borrowed for do_custom timer
on_die = function(self)
minetest.chat_send_all("A group of players killed a PumpKing!")
end
})
mobs:register_mob("mobs:pumpboom", {
type = "monster",
visual = "mesh",
mesh = "mobs_pumpboom.x",
textures = {
{"mobs_pumpboom.png"}
},
visual_size = {x=3, y=3},
collisionbox = {-0.70, -0.3, -0.70, 0.70, 0.70, 0.70},
rotate = 270,
animation = {
speed_normal = 15, speed_run = 30,
stand_start = 0, stand_end = 30,
walk_start = 81, walk_end = 97,
run_start = 81, run_end = 97,
punch_start = 100, punch_end = 120
},
sounds = {
random = "mobs_pump"
},
hp_min = 5,
hp_max = 10,
armor = 100,
light_damage = 0,
water_damage = 0,
lava_damage = 0,
fall_damage = 0,
damage = 8,
attack_type = "explode",
group_attack = true,
do_not_project_items = true,
view_range = 15,
walk_velocity = 2,
run_velocity = 4,
drops = {
{name = "farming:pumpkin_seed", chance = 8, min = 4, max = 8}
}
})
minetest.register_node("mobs:pumpking_spawner", {
description = "Pumpkin King Spawner",
tiles = {
"farming_pumpkin_top.png",
"farming_pumpkin_top.png",
"farming_pumpkin_side.png",
"farming_pumpkin_side.png",
"farming_pumpkin_side.png",
"farming_pumpkin_face_on.png"
},
is_ground_content = false,
groups = {unbkreakable = 1, mob_spawner=1},
sounds = default.node_sound_stone_defaults({
dug = {name="mobs_king", gain=0.25}
})
})
minetest.register_node("mobs:pumpboom_spawner", {
description = "Pump Boom Spawner",
tiles = {
"farming_pumpkin_top.png",
"farming_pumpkin_top.png",
"farming_pumpkin_side.png",
"farming_pumpkin_side.png",
"farming_pumpkin_side.png",
"farming_pumpkin_face_off.png"
},
is_ground_content = false,
groups = {unbreakable = 1, mob_spawner=1},
sounds = default.node_sound_stone_defaults({
dug = {name="mobs_boom", gain=0.25}
})
})
--(name, nodes, neighbors, min_light, max_light, interval, chance, active_object_count, min_height, max_height, spawn_in_area)
-- spawn on mobs:pumpking_spawner between 1 and 20 light, interval 300, 1 chance, 1 pumpking_spawner in area up to 31000 in height
mobs:spawn_specific("mobs:pumpking", {"mobs:pumpking_spawner"}, {"air"}, 1, 20, 300, 1, 100, -31000, 31000, true)
mobs:register_egg("mobs:pumpking", "Pumpking", "mobs_pumpking_inv.png", 1)
-- spawn on mobs:pumpboom_spawner between 1 and 20 light, 4 interval, 1 chance, 100 pumpboom in area up to 31000 in height
mobs:spawn_specific("mobs:pumpboom", {"mobs:pumpboom_spawner"}, {"air"}, 1, 20, 10, 4, 100, -31000, 31000, true)
mobs:register_egg("mobs:pumpboom", "Pumpboom", "mobs_pumpboom_inv.png", 1)

View File

@ -47,8 +47,10 @@ mobs:register_mob("mobs:rat", {
end,
--]]
})
-- spawn on stone between 1 and 20 light, 1 in 7000 chance, 1 per area up to 31000 in height
mobs:spawn_specific("mobs:rat", {"default:stone", "default:sandstone"}, {"air"}, 0, 20, 30, 10000, 1, -31000, 31000, true)
-- register spawn egg
mobs:register_egg("mobs:rat", "Rat", "mobs_rat_inv.png", 1)

View File

@ -7,6 +7,7 @@ mobs:register_mob("mobs:sand_monster", {
-- aggressive, deals 5 damage to player when hit
passive = false,
attack_type = "dogfight",
reach = 2,
damage = 4,
-- health & armor
hp_min = 15,
@ -33,25 +34,40 @@ mobs:register_mob("mobs:sand_monster", {
floats = 0,
-- drops desert sand when dead
drops = {
{name = "default:desert_sand",
chance = 1, min = 3, max = 5,},
{name = "maptools:silver_coin",
chance = 10, min = 1, max = 1,},
{name = "default:desert_sand", chance = 1, min = 3, max = 5,},
{name = "maptools:silver_coin", chance = 10, min = 1, max = 1,},
},
-- damaged by
water_damage = 3,
lava_damage = 4,
light_damage = 0,
fear_height = 3,
-- model animation
animation = {
speed_normal = 15, speed_run = 15,
stand_start = 0, stand_end = 39,
walk_start = 41, walk_end = 72,
run_start = 74, run_end = 105,
punch_start = 74, punch_end = 105,
speed_normal = 15,
speed_run = 15,
stand_start = 0,
stand_end = 39,
walk_start = 41,
walk_end = 72,
run_start = 74,
run_end = 105,
punch_start = 74,
punch_end = 105,
},
})
-- spawns on desert sand between -1 and 20 light, 1 in 15000 chance, 1 sand monster in area up to 31000 in height
mobs:spawn_specific("mobs:sand_monster", {"default:desert_sand", "default:sand"}, {"air"}, -1, 20, 30, 20000, 1, -31000, 31000, false)
-- register spawn egg
mobs:register_egg("mobs:sand_monster", "Sand Monster", "mobs_sand_monster_inv.png", 1)
minetest.register_craft({
output = "mobs:sand_monster",
recipe = {
{"group:sand", "group:sand", "group:sand"},
{"group:sand", "default:nyancat_rainbow", "group:sand"},
{"group:sand", "group:sand", "group:sand"}
}
})

100
mods/mobs/shark.lua Executable file
View File

@ -0,0 +1,100 @@
-- local variables
local l_colors = {
"#111010:200", --dark_grey
"#101020:225", --dark_blue
"#404030:225", --cold_grey
"#404040:210", --light_grey
"#202020:210" --grey
}
local l_skins = {
{"(shark_first.png^[colorize:"..l_colors[1]..")^(shark_second.png^[colorize:"..l_colors[5]..")^shark_third.png"},
{"(shark_first.png^[colorize:"..l_colors[2]..")^(shark_second.png^[colorize:"..l_colors[5]..")^shark_third.png"},
{"(shark_first.png^[colorize:"..l_colors[3]..")^(shark_second.png^[colorize:"..l_colors[4]..")^shark_third.png"}
}
local l_anims = {
speed_normal = 24, speed_run = 24,
stand_start = 1, stand_end = 80,
walk_start = 80, walk_end = 160,
run_start = 80, run_end = 160
}
local l_model = "mobs_shark.b3d"
local l_egg_texture = "mobs_shark_shark_inv.png"
local l_spawn_in = {"default:water_source"}
local l_spawn_near = {"default:water_flowing","default:water_source","seawrecks:woodship","seawrecks:uboot"}
local l_spawn_chance = 500000
-- large
mobs:register_mob("mobs:shark_lg", {
type = "monster",
attack_type = "dogfight",
damage = 6,
reach = 3,
hp_min = 20,
hp_max = 30,
armor = 150,
collisionbox = {-0.75, -0.5, -0.75, 0.75, 0.5, 0.75},
visual = "mesh",
mesh = l_model,
textures = l_skins,
makes_footstep_sound = false,
walk_velocity = 4,
run_velocity = 6,
fly = true,
fly_in = "default:water_source",
fall_speed = 0,
rotate = 270,
view_range = 10,
water_damage = 0,
lava_damage = 10,
light_damage = 0,
animation = l_anims,
do_custom = function(self)
local p = self.object:getpos()
local a = self.object:getvelocity()
if p.y > 0 and a.y > 0 then
a.y = -1
else
local r = math.random(100)
if r >= 1 and r <=25 then a.y = 0.25
elseif r > 25 and r <= 50 then a.y = 0
elseif r > 50 and r <= 75 then a.y = -0.25
end
end
self.object:setvelocity(a)
end
})
--name, nodes, neighbours, minlight, maxlight, interval, chance, active_object_count, min_height, max_height
mobs:spawn_specific("mobs:shark_lg", l_spawn_in, l_spawn_near, -1, 20, 30, l_spawn_chance, 1, -50, -1)
mobs:register_egg("mobs:shark_lg", "Shark (large)", l_egg_texture, 1)
-- medium
mobs:register_mob("mobs:shark_md", {
type = "monster",
attack_type = "dogfight",
damage = 5,
reach = 2,
hp_min = 20,
hp_max = 25,
armor = 125,
collisionbox = {-0.57, -0.38, -0.57, 0.57, 0.38, 0.57},
visual = "mesh",
visual_size = {x=0.75, y=0.75},
mesh = l_model,
textures = l_skins,
makes_footstep_sound = false,
walk_velocity = 2,
run_velocity = 4,
fly = true,
fly_in = "default:water_source",
fall_speed = -1,
rotate = 270,
view_range = 10,
water_damage = 0,
lava_damage = 10,
light_damage = 0,
animation = l_anims
})
--name, nodes, neighbours, minlight, maxlight, interval, chance, active_object_count, min_height, max_height
mobs:spawn_specific("mobs:shark_md", l_spawn_in, l_spawn_near, -1, 20, 30, l_spawn_chance, 1, -50, -1)
mobs:register_egg("mobs:shark_md", "Shark (medium)", l_egg_texture, 1)

View File

@ -18,7 +18,6 @@ for _, col in pairs(all_colours) do
hp_max = 15,
armor = 200,
-- textures and model
--collisionbox = {-0.4, -1, -0.4, 0.4, 0.3, 0.4},
collisionbox = {-0.5, -1, -0.5, 0.5, 0.3, 0.5},
visual = "mesh",
mesh = "mobs_sheep.b3d",
@ -39,12 +38,10 @@ for _, col in pairs(all_colours) do
runaway = true,
jump = true,
-- drops raw meat and woll of its color when dead
-- drops = {
-- {name = "mobs:meat_raw",
-- chance = 1, min = 2, max = 3},
-- {name = "wool:"..col,
-- chance = 1, min = 1, max = 1},
-- },
drops = {
{name = "mobs:meat_raw", chance = 1, min = 2, max = 3},
{name = "wool:"..col, chance = 1, min = 1, max = 1},
},
-- damaged by
water_damage = 1,
lava_damage = 5,
@ -59,9 +56,9 @@ for _, col in pairs(all_colours) do
walk_end = 100,
},
follow = {"farming:wheat", "default:grass_5"},
view_range = 10,
view_range = 8,
-- replace grass/wheat with air (eat)
replace_rate = 50,
replace_rate = 10,
replace_what = {"default:grass_3", "default:grass_4", "default:grass_5", "farming:wheat_8"},
replace_with = "air",
-- right click sheep to shear sheep and get wood, feed 8 wheat for wool to grow back
@ -75,6 +72,7 @@ for _, col in pairs(all_colours) do
--are we feeding?
if mobs:feed_tame(self, clicker, 8, true, true) then
--if full grow fuzz
if self.gotten == false then
self.object:set_properties({
@ -82,6 +80,7 @@ for _, col in pairs(all_colours) do
mesh = "mobs_sheep.b3d",
})
end
return
end
@ -90,12 +89,18 @@ for _, col in pairs(all_colours) do
--are we giving a haircut>
if itemname == "mobs:shears" then
if self.gotten == false and self.child == false then
self.gotten = true -- shaved
if minetest.get_modpath("wool") then
local pos = self.object:getpos()
pos.y = pos.y + 0.5
local obj = minetest.add_item(pos, ItemStack("wool:"..shpcolor.." "..math.random(1,3)))
if obj then
obj:setvelocity({
x = math.random(-1,1),
@ -103,14 +108,18 @@ for _, col in pairs(all_colours) do
z = math.random(-1,1)
})
end
item:add_wear(650) -- 100 uses
clicker:set_wielded_item(item)
end
self.object:set_properties({
textures = {"mobs_sheep_shaved.png"},
mesh = "mobs_sheep_shaved.b3d",
})
end
return
end
@ -118,28 +127,39 @@ for _, col in pairs(all_colours) do
--are we coloring?
if itemname:find("dye:") then
if self.gotten == false
and self.child == false
and self.tamed == true
and name == self.owner then
local col = string.split(itemname,":")[2]
for _,c in pairs(all_colours) do
if c == col then
local pos = self.object:getpos()
self.object:remove()
local mob = minetest.add_entity(pos, "mobs:sheep_"..col)
local ent = mob:get_luaentity()
ent.owner = name
ent.tamed = true
-- take item
if not minetest.setting_getbool("creative_mode") then
item:take_item()
clicker:set_wielded_item(item)
end
break
end
end
end
return
end
@ -152,7 +172,7 @@ for _, col in pairs(all_colours) do
end
mobs:spawn_specific("mobs:sheep_white", {"default:dirt_with_grass"}, {"air"}, 8, 20, 30, 10000, 1, -31000, 31000, true)
mobs:spawn_specific("mobs:sheep_white", {"default:dirt_with_grass"}, {"air"}, 8, 20, 30, 10000, 2, -31000, 31000, true, true)
-- compatibility (item and entity)
minetest.register_alias("mobs:sheep", "mobs:sheep_white")
@ -168,25 +188,13 @@ minetest.register_entity("mobs:sheep", {
velocity = {x = 0, y = 0, z = 0},
collisionbox = {-0.4, -1, -0.4, 0.4, 0.3, 0.4},
is_visible = true,
speed = 0,
timer = 0,
on_rightclick = function(self, clicker)
clicker:get_inventory():add_item("main", "mobs:sheep_white")
on_activate = function(self, staticdata, dtime_s)
local pos = self.object:getpos()
self.object:remove()
end,
on_step = function(self, dtime)
self.timer = self.timer + dtime
if self.timer >= 1 then
self.timer = 0
self.object:setacceleration({
x = 0,
y = -10,
z = 0
})
end
end,
minetest.add_entity(pos, "mobs:sheep_white")
end
})

157
mods/mobs/spawner.lua Executable file
View File

@ -0,0 +1,157 @@
-- mob spawner
local spawner_default = "mobs:pig 10 15 0 0"
minetest.register_node("mobs:spawner", {
tiles = {"mob_spawner.png"},
drawtype = "glasslike",
paramtype = "light",
walkable = true,
description = "Mob Spawner",
groups = {cracky = 1},
on_construct = function(pos)
local meta = minetest.get_meta(pos)
-- text entry formspec
meta:set_string("formspec", "field[text;Mob MinLight MaxLight Amount PlayerDist;${command}]")
meta:set_string("infotext", "Spawner Not Active (enter settings)")
meta:set_string("command", spawner_default)
end,
on_right_click = function(pos, placer)
if minetest.is_protected(pos, placer:get_player_name()) then
return
end
-- local meta = minetest.get_meta(pos)
end,
on_receive_fields = function(pos, formname, fields, sender)
if not fields.text or fields.text == "" then
return
end
local meta = minetest.get_meta(pos)
local comm = fields.text:split(" ")
local name = sender:get_player_name()
if minetest.is_protected(pos, name) then
minetest.record_protection_violation(pos, name)
return
end
local mob = comm[1] -- mob to spawn
local mlig = tonumber(comm[2]) -- min light
local xlig = tonumber(comm[3]) -- max light
local num = tonumber(comm[4]) -- total mobs in area
local pla = tonumber(comm[5])-- player distance (0 to disable)
if mob and mob ~= "" and mobs.spawning_mobs[mob] == true
and num and num >= 0 and num <= 10
and mlig and mlig >= 0 and mlig <= 15
and xlig and xlig >= 0 and xlig <= 15
and pla and pla >=0 and pla <= 20 then
meta:set_string("command", fields.text)
meta:set_string("infotext", "Spawner Active (" .. mob .. ")")
else
minetest.chat_send_player(name, "Mob Spawner settings failed!")
end
end,
})
-- spawner abm
minetest.register_abm({
nodenames = {"mobs:spawner"},
interval = 10,
chance = 4,
catch_up = false,
action = function(pos, node, active_object_count, active_object_count_wider)
-- check objects inside 9x9 area around spawner
local objs = minetest.get_objects_inside_radius(pos, 9)
-- get meta and command
local meta = minetest.get_meta(pos)
local comm = meta:get_string("command"):split(" ")
-- get settings from command
local mob = comm[1]
local mlig = tonumber(comm[2])
local xlig = tonumber(comm[3])
local num = tonumber(comm[4])
local pla = tonumber(comm[5]) or 0
-- if amount is 0 then do nothing
if num == 0 then
return
end
local count = 0
local ent = nil
-- count mob objects of same type in area
for k, obj in pairs(objs) do
ent = obj:get_luaentity()
if ent and ent.name == mob then
count = count + 1
end
end
-- is there too many of same type?
if count >= num then
return
end
-- spawn mob if player detected and in range
if pla > 0 then
local in_range = 0
local objs = minetest.get_objects_inside_radius(pos, pla)
for _,oir in pairs(objs) do
if oir:is_player() then
in_range = 1
break
end
end
-- player not found
if in_range == 0 then
return
end
end
-- find air blocks within 5 nodes of spawner
local air = minetest.find_nodes_in_area(
{x = pos.x - 5, y = pos.y, z = pos.z - 5},
{x = pos.x + 5, y = pos.y, z = pos.z + 5},
{"air"})
-- spawn in random air block
if air and #air > 0 then
local pos2 = air[math.random(#air)]
local lig = minetest.get_node_light(pos2) or 0
pos2.y = pos2.y + 0.5
-- only if light levels are within range
if lig >= mlig and lig <= xlig then
minetest.add_entity(pos2, mob)
end
end
end
})

View File

@ -2,11 +2,12 @@
-- Spider by AspireMint (fishyWET (CC-BY-SA 3.0 license for texture)
mobs:register_mob("mobs:spider", {
-- animal, monster, npc, barbarian
docile_by_day = true,
type = "monster",
-- agressive, does 6 damage to player when hit
passive = false,
attack_type = "dogfight",
reach = 2,
damage = 5,
-- health & armor
hp_min = 30,
@ -19,7 +20,7 @@ mobs:register_mob("mobs:spider", {
textures = {
{"mobs_spider.png"},
},
visual_size = {x=7,y=7},
visual_size = {x = 7, y = 7},
blood_texture = "mobs_blood.png",
-- sounds
makes_footstep_sound = true,
@ -36,13 +37,10 @@ mobs:register_mob("mobs:spider", {
view_range = 16,
floats = 0,
-- drops string with a chance of sandstone or crystal spike if Ethereal installed
drops = {
{name = "farming:string",
chance = 2, min = 1, max = 3,},
{name = "mobs:meat_raw",
chance = 4, min = 1, max = 2,},
{name = "maptools:silver_coin",
chance = 3, min = 1, max = 1,},
drops = {
{name = "farming:string", chance = 2, min = 1, max = 3,},
{name = "mobs:meat_raw", chance = 4, min = 1, max = 2,},
{name = "maptools:silver_coin", chance = 3, min = 1, max = 1,},
},
-- damaged by
water_damage = 5,
@ -50,15 +48,22 @@ mobs:register_mob("mobs:spider", {
light_damage = 0,
-- model animation
animation = {
speed_normal = 15, speed_run = 15,
stand_start = 1, stand_end = 1,
walk_start = 20, walk_end = 40,
run_start = 20, run_end = 40,
punch_start = 50, punch_end = 90,
speed_normal = 15,
speed_run = 15,
stand_start = 1,
stand_end = 1,
walk_start = 20,
walk_end = 40,
run_start = 20,
run_end = 40,
punch_start = 50,
punch_end = 90,
},
})
-- spawn on jungleleaves/jungletree, between 0 and 5 light, 1 in 10000 chance, 1 in area up to 31000 in height
mobs:spawn_specific("mobs:spider", {"default:jungleleaves", "default:jungletree"}, {"air"}, -1, 20, 30, 7500, 1, -31000, 31000, false)
-- register spawn egg
mobs:register_egg("mobs:spider", "Spider", "mobs_spider_inv.png", 1)

View File

@ -7,10 +7,11 @@ mobs:register_mob("mobs:stone_monster", {
-- aggressive, deals 8 damage to player when hit
passive = false,
attack_type = "dogfight",
damage = 7,
reach = 2,
damage = 6,
-- health & armor
hp_min = 30,
hp_max = 35,
hp_min = 20,
hp_max = 25,
armor = 70,
-- textures and model
collisionbox = {-0.4, -1, -0.4, 0.4, 0.8, 0.4},
@ -36,12 +37,9 @@ mobs:register_mob("mobs:stone_monster", {
drops = {
{name = "default:torch",
chance = 10, min = 3, max = 5,},
{name = "default:iron_lump",
chance = 5, min = 1, max = 2,},
{name = "default:coal_lump",
chance = 3, min = 1, max = 3,},
{name = "maptools:silver_coin",
chance = 1, min = 1, max = 1,},
{name = "default:iron_lump", chance = 5, min = 1, max = 2,},
{name = "default:coal_lump", chance = 3, min = 1, max = 3,},
{name = "maptools:silver_coin", chance = 1, min = 1, max = 1,},
},
-- damaged by
water_damage = 0,
@ -49,14 +47,30 @@ mobs:register_mob("mobs:stone_monster", {
light_damage = 0,
-- model animation
animation = {
speed_normal = 15, speed_run = 15,
stand_start = 0, stand_end = 14,
walk_start = 15, walk_end = 38,
run_start = 40, run_end = 63,
punch_start = 40, punch_end = 63,
speed_normal = 15,
speed_run = 15,
stand_start = 0,
stand_end = 14,
walk_start = 15,
walk_end = 38,
run_start = 40,
run_end = 63,
punch_start = 40,
punch_end = 63,
},
})
-- spawns on stone between -1 and 5 light, 1 in 7000 chance, 1 in area below -25
mobs:spawn_specific("mobs:stone_monster", {"default:stone", "default:sandstone"}, {"air"}, -1, 5, 30, 7000, 1, -31000, -25, false)
-- register spawn egg
mobs:register_egg("mobs:stone_monster", "Stone Monster", "mobs_stone_monster_inv.png", 1)
minetest.register_craft({
output = "mobs:stone_monster",
recipe = {
{"default:stone", "default:stone", "default:stone"},
{"default:stone", "default:nyancat_rainbow", "default:stone"},
{"default:stone", "default:stone", "default:stone"}
}
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -7,6 +7,7 @@ mobs:register_mob("mobs:tree_monster", {
-- aggressive, deals 9 damage to player when hit
passive = false,
attack_type = "dogfight",
reach = 2,
damage = 8,
-- health & armor
hp_min = 40,
@ -32,16 +33,11 @@ mobs:register_mob("mobs:tree_monster", {
view_range = 16,
-- drops saplings, junglesapling, apple and/or silver coin
drops = {
{name = "default:sapling",
chance = 2, min = 1, max = 2},
{name = "default:junglesapling",
chance = 2, min = 1, max = 2},
{name = "default:apple",
chance = 2, min = 2, max = 3,},
{name = "maptools:superapple",
chance = 4, min = 1, max = 1,},
{name = "maptools:silver_coin",
chance = 3, min = 1, max = 1,},
{name = "default:sapling", chance = 2, min = 1, max = 2},
{name = "default:junglesapling", chance = 2, min = 1, max = 2},
{name = "default:apple", chance = 2, min = 2, max = 3,},
{name = "maptools:superapple", chance = 4, min = 1, max = 1,},
{name = "maptools:silver_coin", chance = 3, min = 1, max = 1,},
},
-- damaged by
water_damage = 1,
@ -50,15 +46,22 @@ mobs:register_mob("mobs:tree_monster", {
fall_damage = 0,
-- model animation
animation = {
speed_normal = 15, speed_run = 15,
stand_start = 0, stand_end = 24,
walk_start = 25, walk_end = 47,
run_start = 48, run_end = 62,
punch_start = 48, punch_end = 62,
speed_normal = 15,
speed_run = 15,
stand_start = 0,
stand_end = 24,
walk_start = 25,
walk_end = 47,
run_start = 48,
run_end = 62,
punch_start = 48,
punch_end = 62,
},
})
-- spawn on leaves and beech_leaves, between 0 and 5 light, 1 in 8000 chance, 1 in area up to 31000 in height
mobs:spawn_specific("mobs:tree_monster", {"default:leaves", "moretrees:beech_leaves"}, {"air"}, 0, 5, 30, 8000, 1, -31000, 31000, false)
mobs:spawn_specific("mobs:tree_monster", {"default:leaves", "moretrees:beech_leaves"}, {"air"}, 0, 5, 30, 8000, 1, -31000, 31000, false, false)
-- register spawn egg
mobs:register_egg("mobs:tree_monster", "Tree Monster", "mobs_tree_monster_inv.png", 1)
@ -66,4 +69,13 @@ mobs:register_egg("mobs:tree_monster", "Tree Monster", "mobs_tree_monster_inv.pn
if not minetest.get_modpath("ethereal") then
minetest.register_alias("ethereal:tree_sapling", "default:sapling")
minetest.register_alias("ethereal:jungle_tree_sapling", "default:junglesapling")
end
end
minetest.register_craft({
output = "mobs:tree_monster",
recipe = {
{"default:tree", "default:tree", "default:tree"},
{"default:tree", "default:nyancat_rainbow", "default:tree"},
{"default:tree", "default:tree", "default:tree"}
}
})

View File

@ -7,7 +7,8 @@ mobs:register_mob("mobs:yeti", {
-- agressive, deals 7 damage to player when hit
passive = false,
damage = 6,
attack_type = "shoot",
attack_type = "dogshoot",
reach = 2,
shoot_interval = .75,
arrow = "mobs:snowball",
shoot_offset = 2,
@ -28,7 +29,7 @@ mobs:register_mob("mobs:yeti", {
makes_footstep_sound = true,
sounds = {
random = "mobs_dirtmonster",
attack = "mobs_stonemonster_attack",
shoot_attack = "mobs_stonemonster_attack",
death = "mobs_zombie_death",
},
-- speed and jump
@ -70,16 +71,16 @@ mobs:register_arrow("mobs:snowball", {
velocity = 6,
hit_player = function(self, player)
player:punch(self.object, 1.0, {
full_punch_interval=1.0,
damage_groups = {fleshy=6},
player:punch(self.object, 1.0, {
full_punch_interval = 1.0,
damage_groups = {fleshy = 6},
}, 0)
end,
hit_mob = function(self, player)
player:punch(self.object, 1.0, {
full_punch_interval=1.0,
damage_groups = {fleshy=3},
player:punch(self.object, 1.0, {
full_punch_interval = 1.0,
damage_groups = {fleshy = 3},
}, 0)
end,

View File

@ -137,8 +137,7 @@ local nodes = {
["iron_glass"] = {
description = S("Iron Glass"),
drawtype = "glasslike_framed_optional",
--tiles = {"moreblocks_iron_glass.png", "moreblocks_iron_glass_detail.png"},
tiles = {"moreblocks_iron_glass.png"},
tiles = {"moreblocks_iron_glass.png", "moreblocks_iron_glass_detail.png"}, --MFF connected glass
paramtype = "light",
sunlight_propagates = true,
groups = {snappy = 2, cracky = 3, oddly_breakable_by_hand = 3},
@ -147,8 +146,7 @@ local nodes = {
["coal_glass"] = {
description = S("Coal Glass"),
drawtype = "glasslike_framed_optional",
--tiles = {"moreblocks_coal_glass.png", "moreblocks_coal_glass_detail.png"},
tiles = {"moreblocks_coal_glass.png"},
tiles = {"moreblocks_coal_glass.png", "moreblocks_coal_glass_detail.png"}, --MFF connected glass
paramtype = "light",
sunlight_propagates = true,
groups = {snappy = 2, cracky = 3, oddly_breakable_by_hand = 3},
@ -157,8 +155,7 @@ local nodes = {
["clean_glass"] = {
description = S("Clean Glass"),
drawtype = "glasslike_framed_optional",
--tiles = {"moreblocks_clean_glass.png", "moreblocks_clean_glass_detail.png"},
tiles = {"moreblocks_clean_glass.png"},
tiles = {"moreblocks_clean_glass.png", "moreblocks_clean_glass_detail.png"}, --MFF connected glass
paramtype = "light",
sunlight_propagates = true,
groups = {snappy = 2, cracky = 3, oddly_breakable_by_hand = 3},
@ -230,8 +227,7 @@ local nodes = {
["trap_glass"] = {
description = S("Trap Glass"),
drawtype = "glasslike_framed_optional",
--tiles = {"moreblocks_trap_glass.png", "default_glass_detail.png"},
tiles = {"moreblocks_trap_glass.png"},
tiles = {"moreblocks_trap_glass.png", "default_glass_detail.png"}, --MFF connected glass
paramtype = "light",
sunlight_propagates = true,
walkable = false,
@ -284,8 +280,7 @@ local nodes = {
["glow_glass"] = {
description = S("Glow Glass"),
drawtype = "glasslike_framed_optional",
--tiles = {"moreblocks_glow_glass.png", "moreblocks_glow_glass_detail.png"},
tiles = {"moreblocks_glow_glass.png"},
tiles = {"moreblocks_glow_glass.png", "moreblocks_glow_glass_detail.png"}, --MFF connected glass
paramtype = "light",
sunlight_propagates = true,
light_source = 11,
@ -295,8 +290,7 @@ local nodes = {
["trap_glow_glass"] = {
description = S("Trap Glow Glass"),
drawtype = "glasslike_framed_optional",
--tiles = {"moreblocks_trap_glass.png", "moreblocks_glow_glass_detail.png"},
tiles = {"moreblocks_trap_glass.png"},
tiles = {"moreblocks_trap_glass.png", "moreblocks_glow_glass_detail.png"}, --MFF connected glass
paramtype = "light",
sunlight_propagates = true,
light_source = 11,
@ -308,8 +302,7 @@ local nodes = {
["super_glow_glass"] = {
description = S("Super Glow Glass"),
drawtype = "glasslike_framed_optional",
--tiles = {"moreblocks_super_glow_glass.png", "moreblocks_super_glow_glass_detail.png"},
tiles = {"moreblocks_super_glow_glass.png"},
tiles = {"moreblocks_super_glow_glass.png", "moreblocks_super_glow_glass_detail.png"}, --MFF connected glass
paramtype = "light",
sunlight_propagates = true,
light_source = 15,
@ -319,8 +312,7 @@ local nodes = {
["trap_super_glow_glass"] = {
description = S("Trap Super Glow Glass"),
drawtype = "glasslike_framed_optional",
--tiles = {"moreblocks_trap_super_glow_glass.png", "moreblocks_super_glow_glass_detail.png"},
tiles = {"moreblocks_trap_super_glow_glass.png"},
tiles = {"moreblocks_trap_super_glow_glass.png", "moreblocks_super_glow_glass_detail.png"}, --MFF connected glass
paramtype = "light",
sunlight_propagates = true,
light_source = 15,

View File

@ -227,7 +227,8 @@ local oredefs = {
tools = {
pick = {
groupcaps = {
cracky = {times = {[1] = 3.0, [2] = 1.20, [3] = 0.70}, uses = 90, maxlevel= 2}
cracky = {times = {[1] = 3.0, [2] = 1.20, [3] = 0.70}, uses = 90, maxlevel= 2},
crumbly = {times = {[1] = 1.75, [2] = 0.80, [3] = 0.65}, uses = 90, maxlevel= 2}
},
damage_groups = {fleshy = 3},
full_punch_interval = 0.8,
@ -272,7 +273,8 @@ local oredefs = {
tools = {
pick = {
groupcaps = {
cracky = {times = {[1] = 1.50, [2] = 0.80, [3] = 0.35}, uses = 200, maxlevel= 3}
cracky = {times = {[1] = 1.50, [2] = 0.80, [3] = 0.35}, uses = 200, maxlevel= 3},
crumbly = {times = {[1] = 1.00, [2] = 0.60, [3] = 0.25}, uses = 200, maxlevel= 3}
},
damage_groups = {fleshy = 5},
full_punch_interval = 0.5,

View File

@ -18,4 +18,5 @@ If you got ideas or found bugs, please tell them to me.
TODO:
— find a way to get the perlin noise inside [-1; 1] or use another noise
— find a way to get the perlin noise inside [-1; 1] or use another noise
— add something containing items to that buildings

View File

@ -1,11 +0,0 @@
This is a modified version of lkjoel's nether mod.
Look here if you want to see the differences:
https://github.com/HybridDog/minetest-nether/compare/lkjoel:master...master
this happens really selden to me
http://i.imgur.com/pMZYqt9.png
TODO:
— care about nether torches
— find a way to get the perlin noise inside [-1; 1] or use another noise

View File

@ -2,5 +2,6 @@ default
glow
riesenpilz
stairs
vector_extras
fence_registration?
watershed?

View File

@ -55,6 +55,9 @@ local mushroom_rarity = 80
-- Frequency of trees in the nether forest (higher is less frequent)
local tree_rarity = 200
local abm_tree_interval = 864
local abm_tree_chance = 100
-- height of the nether generation's end
nether.start = f_h_max+100
@ -404,14 +407,14 @@ minetest.register_on_generated(function(minp, maxp, seed)
if forest_possible then
perlin_f_bottom = minetest.get_perlin(11, 3, 0.8, tmp2)
pmap_f_top = minetest.get_perlin_map(perlins.forest_top, map_lengths_xyz):get2dMap_flat({x=minp.x, y=minp.z})
strassx = get_ws_list(2, minp.x)
strassz = get_ws_list(2, minp.z)
strassx = get_ws_list(2, minp.x, side_length)
strassz = get_ws_list(2, minp.z, side_length)
end
local num2, tab2
if buildings >= 1 then
num2 = 1
tab2 = nether_weird_noise({x=minp.x, y=nether.buildings-79, z=minp.z}, pymg, 200, 8, 10, 79)
tab2 = nether_weird_noise({x=minp.x, y=nether.buildings-(maxp.y-minp.y), z=minp.z}, pymg, 200, 8, 10, maxp.y-minp.y)
end
local count = 0
@ -690,6 +693,10 @@ function nether.grow_netherstructure(pos, generated)
end
local set = vector.set_data_to_pos
local get = vector.get_data_from_pos
local remove = vector.remove_data_from_pos
local function soft_node(id)
return id == c.air or id == c.ignore
end
@ -699,7 +706,6 @@ local function update_minmax(min, max, p)
max.x = math.max(max.x, p.x)
min.z = math.min(min.z, p.z)
max.z = math.max(max.z, p.z)
return min, max
end
local fruit_chances = {}
@ -742,62 +748,69 @@ function nether.grow_tree(pos, generated)
local trunks = {}
local trunk_corners = {}
local h_stem = math.random(h_stem_min, h_stem_max)
local stems = {{x=pos.x, y=pos.y+h_stem, z=pos.z}}
local fi
while not fi do
for n,p in pairs(stems) do
local used_dirs = {}
for _,dir in pairs(dirs) do
if math.random(1,2) == 1 then
table.insert(used_dirs, dir)
end
local todo,n = {{x=pos.x, y=pos.y+h_stem, z=pos.z}},1
while n do
local p = todo[n]
todo[n] = nil
n = next(todo)
local used_dirs,u = {},1
for _,dir in pairs(dirs) do
if math.random(1,2) == 1 then
used_dirs[u] = dir
u = u+1
end
if not used_dirs[1] then
local dir1 = math.random(4)
local dir2 = math.random(3)
if dir1 <= dir2 then
dir2 = dir2+1
end
used_dirs[1] = dirs[dir1]
used_dirs[2] = dirs[dir2]
end
for _,dir in pairs(used_dirs) do
local p = vector.new(p)
local r = math.random(r_arm_min, r_arm_max)
for j = 1,r do
local x = p.x+j*dir[1]
local z = p.z+j*dir[2]
trunks[x.." "..p.y.." "..z] = dir[3]
end
r = r+1
p.x = p.x+r*dir[1]
p.z = p.z+r*dir[2]
trunk_corners[p.x.." "..p.y.." "..p.z] = dir[4] or dir[3]
local h = math.random(h_arm_min, h_arm_max)
for i = 1,h do
trunks[p.x.." "..p.y+i.." "..p.z] = true
end
p.y = p.y+h
table.insert(stems, p)
end
if p.y > pos.y+h_trunk_max then
fi = true
break
end
stems[n] = nil
end
if not used_dirs[1] then
local dir1 = math.random(4)
local dir2 = math.random(3)
if dir1 <= dir2 then
dir2 = dir2+1
end
used_dirs[1] = dirs[dir1]
used_dirs[2] = dirs[dir2]
end
for _,dir in pairs(used_dirs) do
local p = vector.new(p)
local r = math.random(r_arm_min, r_arm_max)
for j = 1,r do
local x = p.x+j*dir[1]
local z = p.z+j*dir[2]
set(trunks, z,p.y,x, dir[3])
end
r = r+1
p.x = p.x+r*dir[1]
p.z = p.z+r*dir[2]
set(trunk_corners, p.z,p.y,p.x, dir[4] or dir[3])
local h = math.random(h_arm_min, h_arm_max)
for i = 1,h do
set(trunks, p.z,p.y+i,p.x, true)
end
p.y = p.y+h
--n = #todo+1 -- caused small trees
todo[#todo+1] = p
end
if p.y > pos.y+h_trunk_max then
break
end
n = n or next(todo)
end
local leaves = {}
local fruits = {}
local trunk_ps = {}
local count = 0
for n,par in pairs(trunks) do
local p = {}
p.x, p.y, p.z = unpack(string.split(n, " "))
if par ~= true then
p.par = par
local ps, trmin, trmax, trunk_count = vector.get_data_pos_table(trunks)
update_minmax(min, max, trmin)
update_minmax(min, max, trmax)
for _,d in pairs(ps) do
if d[4] == true then
d[4] = nil
end
table.insert(trunk_ps, p)
trunk_ps[#trunk_ps+1] = d
local pz, py, px = unpack(d)
count = count+1
if count > leaf_thickness then
count = 0
@ -805,18 +818,21 @@ function nether.grow_tree(pos, generated)
local fruit_chance = fruit_chances[y]
for z = -2,2 do
for x = -2,2 do
local dist = math.sqrt(x*x+y*y+z*z)
if math.floor(dist) ~= 0
and math.random(1, dist) == 1 then
local pstr = p.x+x.." "..p.y+y.." "..p.z+z
if not trunks[pstr] then
if math.random(1, fruit_rarity) == 1
and fruit_chance
local distq = x*x+y*y+z*z
if distq ~= 0
and math.random(1, math.sqrt(distq)) == 1 then
local x = x+px
local y = y+py
local z = z+pz
if not get(trunks, z,y,x) then
if fruit_chance
and math.random(1, fruit_rarity) == 1
and math.random(1, fruit_chance) == 1 then
fruits[pstr] = true
set(fruits, z,y,x, true)
else
leaves[pstr] = true
set(leaves, z,y,x, true)
end
update_minmax(min, max, {x=x, z=z})
end
end
end
@ -825,37 +841,8 @@ function nether.grow_tree(pos, generated)
end
end
local leaf_ps = {}
for n,_ in pairs(leaves) do
local p = {}
p.x, p.y, p.z = unpack(string.split(n, " "))
table.insert(leaf_ps, p)
min, max = update_minmax(min, max, p)
end
for n,_ in pairs(trunks) do
local p = {}
p.x, _, p.z = unpack(string.split(n, " "))
min, max = update_minmax(min, max, p)
end
for i = -1,h_stem+1 do
table.insert(trunk_ps, {x=pos.x, y=pos.y+i, z=pos.z, par=0})
end
local trunk_corner_ps = {}
for n,par in pairs(trunk_corners) do
local p = {}
p.x, p.y, p.z = unpack(string.split(n, " "))
p.par = par
table.insert(trunk_corner_ps, p)
end
local fruit_ps = {}
for n,_ in pairs(fruits) do
local p = {}
p.x, p.y, p.z = unpack(string.split(n, " "))
table.insert(fruit_ps, p)
trunk_ps[#trunk_ps+1] = {pos.z, pos.y+i, pos.x, 0} -- par 0 because of leaves
end
local manip = minetest.get_voxel_manip()
@ -864,8 +851,8 @@ function nether.grow_tree(pos, generated)
local nodes = manip:get_data()
local param2s = manip:get_param2_data()
for _,p in pairs(leaf_ps) do
p = area:indexp(p)
for _,p in pairs(vector.get_data_pos_table(leaves)) do
p = area:index(p[3], p[2], p[1])
if soft_node(nodes[p]) then
nodes[p] = c.nether_leaves
param2s[p] = math.random(0,179)
@ -873,30 +860,28 @@ function nether.grow_tree(pos, generated)
end
end
for _,p in pairs(fruit_ps) do
p = area:indexp(p)
for _,p in pairs(vector.get_data_pos_table(fruits)) do
p = area:index(p[3], p[2], p[1])
if soft_node(nodes[p]) then
nodes[p] = c.nether_apple
end
end
for _,p in pairs(trunk_ps) do
local par = p.par
p = area:indexp(p)
local par = p[4]
p = area:index(p[3], p[2], p[1])
if par then
param2s[p] = par
end
nodes[p] = c.nether_tree
end
for _,p in pairs(trunk_corner_ps) do
local par = p.par
p = area:indexp(p)
nodes[p] = c.nether_tree_corner
param2s[p] = par
for _,p in pairs(vector.get_data_pos_table(trunk_corners)) do
local vi = area:index(p[3], p[2], p[1])
nodes[vi] = c.nether_tree_corner
param2s[vi] = p[4]
end
--calculating took ca. 0.07 - 0.18 [s]
manip:set_data(nodes)
manip:set_param2_data(param2s)
manip:write_to_map()
@ -904,7 +889,7 @@ function nether.grow_tree(pos, generated)
if generated then
spam = 3
end
nether:inform("a nether tree grew at ("..pos.x.."|"..pos.y.."|"..pos.z..")", spam, t1)
nether:inform("a nether tree with "..trunk_count.." branch trunk nodes grew at ("..pos.x.."|"..pos.y.."|"..pos.z..")", spam, t1)
if not generated then
local t1 = os.clock()
manip:update_map()
@ -933,8 +918,8 @@ minetest.register_abm({
minetest.register_abm({
nodenames = {"nether:tree_sapling"},
neighbors = {"group:nether_dirt"},
interval = 864,
chance = 100,
interval = abm_tree_interval,
chance = abm_tree_chance,
action = function(pos)
if minetest.get_node({x=pos.x, y=pos.y+2, z=pos.z}).name == "air"
and minetest.get_node({x=pos.x, y=pos.y+1, z=pos.z}).name == "air" then

View File

@ -539,6 +539,7 @@ minetest.register_node("nether:leaves", {
inventory_image = "nether_leaves.png",
wield_image = "nether_leaves.png",
paramtype = "light",
paramtype2 = "degrotate",
is_ground_content = false,
groups = {snappy=3, leafdecay=3, leaves=1},
drop = {

View File

@ -7,108 +7,192 @@ local function table_contains(t, v)
return false
end
local teleportball_player
local creative = minetest.setting_getbool("creative_mode")
local function throw_pearl(item, player)
local playerpos = player:getpos()
local obj = minetest.add_entity({x=playerpos.x,y=playerpos.y+1.625,z=playerpos.z}, "nether:pearl_entity")
playerpos.y = playerpos.y+1.625
local obj = minetest.add_entity(playerpos, "nether:pearl_entity")
local dir = player:get_look_dir()
obj:setvelocity({x=dir.x*30, y=dir.y*30, z=dir.z*30})
obj:setvelocity(vector.multiply(dir, 30))
obj:setacceleration({x=dir.x*-3, y=-dir.y^8*80-10, z=dir.z*-3})
if not minetest.setting_getbool("creative_mode") then
obj:get_luaentity().player = player:get_player_name()
if not creative then
item:take_item()
return item
end
teleportball_player = player
return item
end
local ENTITY = {
timer=0,
local function get_node(pos)
local name = minetest.get_node(pos).name
if name ~= "ignore" then
return name
end
minetest.get_voxel_manip():read_from_map(pos, pos)
name = minetest.get_node_or_nil(pos)
if not name then
return
end
return name.name
end
local softs = {}
local function is_soft(pos)
local name = get_node(pos)
if not name then
return false
end
local is_soft = softs[name]
if is_soft ~= nil then
return is_soft
end
if not minetest.registered_nodes[name] then
softs[name] = false
return false
end
is_soft = minetest.registered_nodes[name].walkable == false
softs[name] = is_soft
return is_soft
end
-- teleports the player there if there's free space
local function teleport_player(pos, player)
if not is_soft(pos) then
return false
end
if not is_soft({x=pos.x, y=pos.y+1, z=pos.z})
and not is_soft({x=pos.x, y=pos.y-1, z=pos.z}) then
return false
end
pos.y = pos.y+0.05
player:moveto(pos)
return true
end
--[[
local dg_ps = {}
local function forceload(pos)
dg_ps[#dg_ps+1] = pos
minetest.forceload_block(pos)
minetest.after(5, function(pos)
minetest.forceload_free_block(pos)
for i,p in pairs(dg_ps) do
if vector.equals(p, pos) then
dg_ps[i] = nil
return
end
end
end, pos)
end
minetest.register_on_shutdown(function()
for _,p in pairs(dg_ps) do
minetest.forceload_free_block(p)
end
end)--]]
minetest.register_entity("nether:pearl_entity", {
collisionbox = {0,0,0,0,0,0}, --not pointable
visual_size = {x=0.1, y=0.1},
physical = false, -- Collides with things
textures = {"nether_pearl.png"},
lastpos={},
player = "",
}
on_activate = function(self, staticdata)
if not staticdata
or staticdata == "" then
return
end
local tmp = minetest.deserialize(staticdata)
if not tmp then
minetest.log("error", "[nether] pearl: invalid staticdata ")
return
end
self.player = tmp.player
end,
get_staticdata = function(self)
--forceload(vector.round(self.object:getpos()))
return minetest.serialize({
player = self.player,
})
end,
timer = 0,
on_step = function(self, dtime)
self.timer = self.timer+dtime
local allowed_nodes = {"air", "default:water_source"}
local function teleport_player(pos, player)
local nd2 = minetest.get_node(pos).name
pos.y = pos.y+1
local nd3 = minetest.get_node(pos).name
if table_contains(allowed_nodes, nd2)
and table_contains(allowed_nodes, nd3) then
pos.y = pos.y-1.4
player:moveto(pos)
pos.y = pos.y-0.6
return true
end
return false
end
--[[
local delay = self.delay
if delay < 0.1 then
self.delay = delay+dtime
return
end
self.delay = 0--]]
ENTITY.on_step = function(self, dtime)
self.timer=self.timer+dtime
if self.timer > 20 then
self.object:remove()
return
end
local pos = self.object:getpos()
local rpos = vector.round(pos)
local lastpos = self.lastpos
if not lastpos then
self.lastpos = vector.new(rpos)
return
end
if lastpos.x
and vector.equals(vector.round(lastpos), rpos) then
return
end
local player = self.player
if not player then
minetest.log("error", "[nether] pearl: missing playername")
self.object:remove()
return
end
player = minetest.get_player_by_name(player)
if not player then
minetest.log("error", "[nether] pearl: missing player")
self.object:remove()
return
end
if not get_node(rpos) then
minetest.log("error", "[nether] pearl: missing node")
self.object:remove()
return
end
self.lastpos = vector.new(pos)
--[[ local delay = self.delay
if delay < 0.1 then
self.delay = delay+dtime
return
end
self.delay = 0]]
local pos = self.object:getpos()
local lastpos = self.lastpos
if lastpos.x
and vector.equals(vector.round(lastpos), vector.round(pos)) then
return
end
local player = self.player
if not player
or player == "" then
self.player = teleportball_player
player = teleportball_player
end
if not player then
self.object:remove()
return
end
if lastpos.x then --If there is no lastpos for some reason.
local free, p = minetest.line_of_sight(lastpos, pos)
if not free then
local nd1 = minetest.get_node(p).name
if not table_contains(allowed_nodes, nd1)
and nd1 ~= "ignore" then
self.object:remove()
minetest.after(0, function(p) --minetest.after us used that the sound is played after the teleportation
minetest.sound_play("nether_pearl", {pos=p, max_hear_distance=10})
end, p)
p.y = p.y+1
if teleport_player(p, player) then
if free then
return
end
if is_soft(p) then
return
end
self.object:remove()
minetest.after(0, function(p) --minetest.after is used that the sound is played after the teleportation
minetest.sound_play("nether_pearl", {pos=p, max_hear_distance=10})
end, p)
p.y = p.y+1
if teleport_player(vector.new(p), player) then
return
end
p.y = p.y-2
for i = -1,1,2 do
for _,j in pairs({{i, 0}, {0, i}}) do
if teleport_player({x=p.x+j[1], y=p.y, z=p.z+j[2]}, player) then
return
end
p.y = p.y-2
for i = -1,1,2 do
for _,j in pairs({{i, 0}, {0, i}}) do
if teleport_player({x=p.x+j[1], y=p.y, z=p.z+j[2]}, player) then
return
end
end
end
for i = -1,1,2 do
for j = -1,1,2 do
if teleport_player({x=p.x+j, y=p.y, z=p.z+i}, player) then
return
end
end
end
end
for i = -1,1,2 do
for j = -1,1,2 do
if teleport_player({x=p.x+j, y=p.y, z=p.z+i}, player) then
return
end
end
end
end
if self.timer > 20 then
self.object:remove()
return
end
self.lastpos = vector.new(pos)
end
minetest.register_entity("nether:pearl_entity", ENTITY)
})
minetest.override_item("nether:pearl", {on_use = throw_pearl})

View File

@ -1,6 +1,10 @@
--code copied from Pilzadam's nether mod and edited
-- kills the player if he uses PilzAdam portal
local portal_target = nether.buildings+1
local damage_enabled = minetest.setting_getbool("enable_damage")
local nether_prisons = minetest.setting_getbool("enable_damage")
local obsidian_portal_kills = nether_prisons and true
local mclike_portal = false
local abm_allowed
minetest.after(5, function()
@ -17,12 +21,15 @@ table.icontains = table.icontains or function(t, v)
end
local players_in_nether = {}
local file = io.open(minetest.get_worldpath()..'/nether_players', "r")
if file then
local contents = file:read('*all')
io.close(file)
if contents then
players_in_nether = string.split(contents, " ")
-- only get info from file if nether prisons
if nether_prisons then
local file = io.open(minetest.get_worldpath()..'/nether_players', "r")
if file then
local contents = file:read('*all')
io.close(file)
if contents then
players_in_nether = string.split(contents, " ")
end
end
end
@ -37,7 +44,7 @@ local function save_nether_players()
end
local update_background
--if damage_enabled then
--if nether_prisons then
function update_background(player, down)
if down then
player:set_sky({r=15, g=0, b=0}, "plain")
@ -49,16 +56,59 @@ local update_background
-- function update_background()end
--end
-- returns nodename if area is generated, else calls generation function
local function generated_or_generate(pos)
local name = minetest.get_node(pos).name
if name ~= "ignore" then
return name
end
minetest.get_voxel_manip():read_from_map(pos, pos)
name = minetest.get_node_or_nil(pos)
if not name then
minetest.emerge_area(vector.subtract(pos, 80), vector.add(pos, 80))
return false
end
return name.name
end
-- where the player appears after dying
local function get_player_died_target(player)
local target = vector.add(player:getpos(), {x=math.random(-100,100), y=0, z=math.random(-100,100)})
target.y = portal_target + math.random(4)
return target
end
-- used for obsidian portal
local function obsidian_teleport(player, pname)
minetest.chat_send_player(pname, "For any reason you arrived here. Type /nether_help to find out things like craft recipes.")
if obsidian_portal_kills then
player:set_hp(0)
return true
end
if not mclike_portal then
local target = vector.round(get_player_died_target(player))
if generated_or_generate(target) then
player:moveto(target)
return true
end
end
return false
end
-- teleports players to nether or helps it
function nether.player_to_nether(player, safe)
local pname = player:get_player_name()
if table.icontains(players_in_nether, pname) then
return
end
table.insert(players_in_nether, pname)
players_in_nether[#players_in_nether+1] = pname
save_nether_players()
if not safe then
minetest.chat_send_player(pname, "For any reason you arrived here. Type /nether_help to find out things like craft recipes.")
player:set_hp(0)
if not nether_prisons then
player:moveto(get_player_died_target(player))
end
end
update_background(player, true)
end
@ -79,7 +129,6 @@ function nether.player_from_nether(player)
end
--if damage_enabled then
local function player_exists(name)
for _,player in pairs(minetest.get_connected_players()) do
if player:get_player_name() == name then
@ -128,69 +177,96 @@ minetest.register_chatcommand("from_hell", {
end
minetest.chat_send_player(pname, "You are free now")
player_from_nether(player)
local pos_togo = {x = 0, y = 35, z = -7}
local pos = player:getpos()
local pos_togo = {x=pos.x, y=100, z=pos.z}
if minetest.setting_getbool("static_spawnpoint") ~= nil then
local stsp_conf = minetest.setting_get("static_spawnpoint")
pos_togo = {x = stsp_conf:split(",")[1]+0,y = stsp_conf:split(",")[2]+0,z = stsp_conf:split(",")[3]+0}
end
player:moveto(pos_togo)
return true
return true, pname.." is now out of the nether."
end
})]]
minetest.register_on_respawnplayer(function(player)
local pname = player:get_player_name()
if not table.icontains(players_in_nether, pname) then
return
end
local target = vector.add(player:getpos(), {x=math.random(-100,100), y=0, z=math.random(-100,100)})
target.y = portal_target + math.random(4)
player:moveto(target)
minetest.after(0, function(pname, target)
local player = minetest.get_player_by_name(pname)
if player then
player:moveto(target)
end
end, pname, target)
return true
end)
local function update_players()
for _,player in ipairs(minetest.get_connected_players()) do
if nether_prisons then
-- randomly set player position when he/she dies in nether
minetest.register_on_respawnplayer(function(player)
local pname = player:get_player_name()
local ppos = player:getpos()
if table.icontains(players_in_nether, pname) then
if ppos.y > nether.start then
player:moveto({x=ppos.x, y=portal_target, z=ppos.z})
update_background(player, true)
--[[minetest.kick_player(pname, "\n1. Maybe you were not allowed to teleport out of the nether."..
if not table.icontains(players_in_nether, pname) then
return
end
local target = get_player_died_target(player)
player:moveto(target)
minetest.after(0, function(pname, target)
-- fixes respawn bug
local player = minetest.get_player_by_name(pname)
if player then
player:moveto(target)
end
end, pname, target)
return true
end)
-- function for teleporting players where they belong to
local function update_players()
for _,player in pairs(minetest.get_connected_players()) do
local pname = player:get_player_name()
local ppos = player:getpos()
if table.icontains(players_in_nether, pname) then
if ppos.y > nether.start then
player:moveto({x=ppos.x, y=portal_target, z=ppos.z})
update_background(player, true)
--[[minetest.kick_player(pname, "\n1. Maybe you were not allowed to teleport out of the nether."..
"\n2. Maybe the server lagged."..
"\n3. please rejoin")]]
end
elseif ppos.y < nether.start then
update_background(player)
player:moveto({x=ppos.x, y=20, z=ppos.z})
--[[minetest.kick_player(pname, "\n1. Maybe you were not allowed to teleport to the nether."..
"\n2. Maybe the server lagged."..
"\n3. please rejoin")]]
end
elseif ppos.y < nether.start then
update_background(player)
player:moveto({x=ppos.x, y=20, z=ppos.z})
--[[minetest.kick_player(pname, "\n1. Maybe you were not allowed to teleport to the nether."..
"\n2. Maybe the server lagged."..
"\n3. please rejoin")]]
end
end
-- fix wrong player positions
local function tick()
update_players()
minetest.after(2, tick)
end
tick()
-- set background when player joins
minetest.register_on_joinplayer(function(player)
minetest.after(0, function(player)
if player:getpos().y < nether.start then
update_background(player, true)
end
end, player)
end)
else
-- test if player is in nether when he/she joins
minetest.register_on_joinplayer(function(player)
minetest.after(0, function(player)
if player:getpos().y < nether.start then
if not table.icontains(players_in_nether, pname) then
players_in_nether[#players_in_nether+1] = pname
end
return
end
for i,name in pairs(players_in_nether) do
if name == pname then
players_in_nether[i] = nil
return
end
end
end, player)
end)
end
local function tick()
update_players()
minetest.after(2, tick)
end
tick()
minetest.register_on_joinplayer(function(player)
minetest.after(0, function(player)
if player:getpos().y < nether.start then
update_background(player, true)
end
end, player)
end)
-- removes the violet stuff from the obsidian portal
local function remove_portal_essence(pos)
for z = -1,1 do
for y = -2,2 do
@ -204,6 +280,50 @@ local function remove_portal_essence(pos)
end
end
-- change parts of the particledefinition instead of recreating it every time
local particledef = {
amount = 32,
time = 4,
minvel = {x=0, y=1, z=0},
maxvel = {x=0, y=2, z=0},
minacc = {x=-0.5,y=-3,z=-0.3},
maxacc = {x=0.5,y=-0.4,z=0.3},
minexptime = 1,
maxexptime = 1,
minsize = 0.4,
maxsize = 3,
collisiondetection = true,
}
-- teleports player to neter (obsidian portal)
local function obsi_teleport_player(player, pos, target)
local pname = player:get_player_name()
if table.icontains(players_in_nether, pname) then
return
end
local objpos = player:getpos()
objpos.y = objpos.y+0.1 -- Fix some glitches at -8000
if minetest.get_node(vector.round(objpos)).name ~= "nether:portal" then
return
end
if not obsidian_teleport(player, pname) then
-- e.g. ungenerated area
return
end
players_in_nether[#players_in_nether+1] = pname
save_nether_players()
update_background(player, true)
remove_portal_essence(pos)
minetest.sound_play("nether_portal_usual", {to_player=pname, gain=1})
--obj:setpos(target)
end
-- abm for particles of the obsidian portal essence and for teleporting
minetest.register_abm({
nodenames = {"nether:portal"},
interval = 1,
@ -213,45 +333,16 @@ minetest.register_abm({
if not abm_allowed then
return
end
minetest.add_particlespawner({
amount = 32,
time = 4,
minpos = {x=pos.x-0.25, y=pos.y-0.5, z=pos.z-0.25},
maxpos = {x=pos.x+0.25, y=pos.y+0.34, z=pos.z+0.25},
minvel = {x=0, y=1, z=0},
maxvel = {x=0, y=2, z=0},
minacc = {x=-0.5,y=-3,z=-0.3},
maxacc = {x=0.5,y=-0.4,z=0.3},
minexptime = 1,
maxexptime = 1,
minsize = 0.4,
maxsize = 3,
collisiondetection = true,
texture = "nether_portal_particle.png^[transform"..math.random(0,7),
})
particledef.minpos = {x=pos.x-0.25, y=pos.y-0.5, z=pos.z-0.25}
particledef.maxpos = {x=pos.x+0.25, y=pos.y+0.34, z=pos.z+0.25}
particledef.texture = "nether_portal_particle.png^[transform"..math.random(0,7)
minetest.add_particlespawner(particledef)
for _,obj in pairs(minetest.get_objects_inside_radius(pos, 1)) do
if obj:is_player() then
local meta = minetest.get_meta(pos)
local target = minetest.string_to_pos(meta:get_string("target"))
if target then
minetest.after(3, function(obj, pos, target)
local pname = obj:get_player_name()
if table.icontains(players_in_nether, pname) then
return
end
local objpos = obj:getpos()
objpos.y = objpos.y+0.1 -- Fix some glitches at -8000
if minetest.get_node(vector.round(objpos)).name ~= "nether:portal" then
return
end
remove_portal_essence(pos)
minetest.sound_play("nether_portal_usual", {to_player=pname, gain=1})
nether.player_to_nether(obj)
--obj:setpos(target)
end, obj, pos, target)
minetest.after(3, obsi_teleport_player, obj, pos, target)
end
end
end
@ -299,6 +390,7 @@ local function check_portal(p1, p2)
return true
end
-- tests if it's an obsidian portal
local function is_portal(pos)
for d=-3,3 do
for y=-4,4 do
@ -314,6 +406,15 @@ local function is_portal(pos)
end
end
-- put here the function for creating a second portal
local create_second_portal
if mclike_portal then
function create_second_portal(target)
-- change target here
end
end
-- adds the violet portal essence
local function make_portal(pos)
local p1, p2 = is_portal(pos)
if not p1
@ -322,7 +423,10 @@ local function make_portal(pos)
return false
end
if p1.y < nether.start then
local in_nether = p1.y < nether.start
if in_nether
and not mclike_portal then
print("[nether] aborted, obsidian portals can't be used to get out")
return
end
@ -350,7 +454,17 @@ local function make_portal(pos)
local target = {x=p1.x, y=p1.y, z=p1.z}
target.x = target.x + 1
target.y = portal_target + math.random(4)
if in_nether then
target.y = 0
create_second_portal(target)
else
target.y = portal_target + math.random(4)
end
if not generated_or_generate(target)
and mclike_portal then
return false
end
for d=0,3 do
for y=p1.y,p2.y do
@ -373,6 +487,7 @@ local function make_portal(pos)
return true
end
-- destroy the portal when destroying obsidian
minetest.override_item("default:obsidian", {
on_destruct = function(pos)
local meta = minetest.get_meta(pos)
@ -426,12 +541,13 @@ minetest.override_item("default:obsidian", {
end
})
-- override mese crystal fragment for making an obsidian portal
minetest.after(0.1, function()
minetest.override_item("default:mese_crystal_fragment", {
on_place = function(stack, player, pt)
if pt.under
and minetest.get_node(pt.under).name == "default:obsidian" then
print("[nether] tries to enable a portal")
--print("[nether] tries to enable a portal")
local done = make_portal(pt.under)
if done then
minetest.chat_send_player(
@ -447,9 +563,9 @@ minetest.after(0.1, function()
end
})
end)
--end
-- a not filled square
vector.square = vector.square or
function(r)
local tab, n = {}, 1
@ -464,20 +580,21 @@ function(r)
return tab
end
-- detects if it's a portal
local function netherport(pos)
local x, y, z = pos.x, pos.y, pos.z
for _,i in ipairs({-1, 3}) do
for _,i in pairs({-1, 3}) do
if minetest.get_node({x=x, y=y+i, z=z}).name ~= "nether:white" then
return
end
end
for _,sn in ipairs(vector.square(1)) do
for _,sn in pairs(vector.square(1)) do
if minetest.get_node({x=x+sn[1], y=y-1, z=z+sn[2]}).name ~= "nether:netherrack"
or minetest.get_node({x=x+sn[1], y=y+3, z=z+sn[2]}).name ~= "nether:blood_cooked" then
return
end
end
for _,sn in ipairs(vector.square(2)) do
for _,sn in pairs(vector.square(2)) do
if minetest.get_node({x=x+sn[1], y=y-1, z=z+sn[2]}).name ~= "nether:netherrack_black"
or minetest.get_node({x=x+sn[1], y=y+3, z=z+sn[2]}).name ~= "nether:wood_empty" then
return
@ -520,6 +637,7 @@ local function set_portal(t, z,x, y)
t[z][x] = y
end
-- used when a player eats that fruit in a portal
function nether_port(player, pos)
if not player
or not pos
@ -532,17 +650,41 @@ function nether_port(player, pos)
end
minetest.sound_play("nether_teleporter", {to_player=player:get_player_name()}) --MFF crabman (5/09/2015) fix positional sound don't work to player
minetest.sound_play("nether_teleporter", {pos=pos})
local meta = minetest.get_meta({x=pos.x, y=pos.y-1, z=pos.z})
if pos.y < nether.start then
set_portal(known_portals_d, pos.z,pos.x, pos.y)
nether.player_from_nether(player)
local pos_togo = {x = 0, y = 35, z = -7}
if minetest.setting_getbool("static_spawnpoint") ~= nil then
if minetest.setting_getbool("static_spawnpoint") then
local stsp_conf = minetest.setting_get("static_spawnpoint")
pos_togo = minetest.string_to_pos(stsp_conf)
pos = minetest.string_to_pos(stsp_conf)
else
local my = tonumber(meta:get_string("y"))
local y = get_portal(known_portals_u, pos.z,pos.x)
if y then
if y ~= my then
meta:set_string("y", y)
end
else
y = my or 100
end
pos.y = y
end
player:moveto(pos_togo)
player:moveto(pos)
else
set_portal(known_portals_u, pos.z,pos.x, pos.y)
pos.y = get_portal(known_portals_d, pos.z,pos.x) or portal_target+math.random(4)
local my = tonumber(meta:get_string("y"))
local y = get_portal(known_portals_d, pos.z,pos.x)
if y then
if y ~= my then
meta:set_string("y", y)
end
else
y = my or portal_target+math.random(4)
end
pos.y = y
player:moveto(pos)
nether.player_to_nether(player, true)
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 B

View File

@ -112,7 +112,7 @@ minetest.register_abm({nodenames = {"group:vacuum_tube"},
chance = 1,
label = "Vacuum tubes",
action = function(pos, node, active_object_count, active_object_count_wider)
if node.name == "pipeworks:sand_tube" then
if node.name:find("pipeworks:sand_tube") then
vacuum(pos, 2)
else
local radius = minetest.get_meta(pos):get_int("dist")

View File

@ -44,6 +44,12 @@ minetest.register_node("dryplants:juncus", {
fixed = {-7/16, -1/2, -7/16, 7/16, 0, 7/16},
},
on_place = function(itemstack, placer, pointed_thing)
local playername = placer:get_player_name()
if minetest.is_protected(pointed_thing.above, playername) or
minetest.is_protected(pointed_thing.under, playername) then
minetest.chat_send_player(playername, "Someone else owns that spot.")
return
end
local pos = pointed_thing.under
local juncus_type = math.random(2,3)
local right_here = {x=pos.x, y=pos.y+1, z=pos.z}

View File

@ -242,13 +242,12 @@ minetest.register_node("ferns:fern_trunk_big", {
},
groups = {tree=1,choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1},
sounds = default.node_sound_wood_defaults(),
after_destruct = function(pos,oldnode)
local node = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z})
if node.name == "ferns:fern_trunk_big" or node.name == "ferns:fern_trunk_big_top" then
minetest.dig_node({x=pos.x,y=pos.y+1,z=pos.z})
minetest.add_item(pos,"ferns:fern_trunk_big")
end
end,
after_dig_node = function(pos, oldnode, oldmetadata, digger)
local node = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z})
if node.name == "ferns:fern_trunk_big" or node.name == "ferns:fern_trunk_big_top" then
minetest.node_dig({x=pos.x,y=pos.y+1,z=pos.z}, node, digger)
end
end,
})
-----------------------------------------------------------------------------------------------
@ -276,7 +275,7 @@ minetest.register_abm({
chance = 4,
action = function(pos, node, _, _)
abstract_ferns.grow_giant_tree_fern({x = pos.x, y = pos.y-1, z = pos.z})
end
end
})
-----------------------------------------------------------------------------------------------

View File

@ -67,9 +67,9 @@ minetest.register_node("ferns:tree_fern_leaves", {
{
items = {"ferns:sapling_tree_fern"},
},
{
items = {"ferns:tree_fern_leaves"},
}
-- {
-- items = {"ferns:tree_fern_leaves"},
-- }
}
},
sounds = default.node_sound_leaves_defaults(),
@ -98,9 +98,9 @@ minetest.register_node("ferns:tree_fern_leaves_02", {
{
items = {"ferns:sapling_tree_fern"},
},
{
items = {"ferns:tree_fern_leaves"},
}
-- {
-- items = {"ferns:tree_fern_leaves"},
-- }
}
},
sounds = default.node_sound_leaves_defaults(),
@ -131,11 +131,10 @@ minetest.register_node("ferns:fern_trunk", {
},
groups = {tree=1,choppy=2,oddly_breakable_by_hand=2,flammable=3,wood=1},
sounds = default.node_sound_wood_defaults(),
after_destruct = function(pos,oldnode)
after_dig_node = function(pos, oldnode, oldmetadata, digger)
local node = minetest.get_node({x=pos.x,y=pos.y+1,z=pos.z})
if node.name == "ferns:fern_trunk" then
minetest.dig_node({x=pos.x,y=pos.y+1,z=pos.z})
minetest.add_item(pos,"ferns:fern_trunk")
minetest.node_dig({x=pos.x,y=pos.y+1,z=pos.z}, node, digger)
end
end,
})

View File

@ -66,7 +66,7 @@ biome_lib:register_generate_plant({
rarity = Molehills_Rarity,
min_elevation = 1,
max_elevation = 40,
avoid_nodes = {"group:tree","group:liquid","group:stone","group:falling_node","air"},
avoid_nodes = {"group:tree","group:liquid","group:stone","group:falling_node"},--"air"},
avoid_radius = 4,
plantlife_limit = -0.3,
},
@ -79,7 +79,7 @@ biome_lib:register_generate_plant({
rarity = 97,
min_elevation = 1,
max_elevation = 40,
avoid_nodes = {"group:tree","group:liquid","group:stone","group:falling_node","air"},
avoid_nodes = {"group:tree","group:liquid","group:stone","group:falling_node"},--,"air"},
avoid_radius = 4,
plantlife_limit = -0.3,
},

View File

@ -8,8 +8,8 @@ minetest.register_tool("vines:shears", {
full_punch_interval = 1.0,
max_drop_level=0,
groupcaps={
snappy={times={[3]=0.2}, maxwear=0.05, maxlevel=3},
wool={times={[3]=0.2}, maxwear=0.05, maxlevel=3}
snappy={times={[3]=0.2}, uses = 1/0.05, maxlevel=3},
wool={times={[3]=0.2}, uses = 1/0.05, maxlevel=3}
}
},
})

View File

@ -1,145 +1,274 @@
--------------------------------------
-- Rollbacks, go Out of those FiLes!
-- ROFL
-- <put meaning here>
-- ROFLMAO
-- Licence : CC0
-- Last modified : 27/11/15
-- By : Mg
--
--
local filepath = minetest.get_worldpath() .. "/rollback/"
local patchsegs = 0
local patchtotp = 100
local bufferfiles = minetest.get_worldpath() .. "/roflmao/"
minetest.mkdir(bufferfiles)
local function none(v)
if not v or v == "None" then
return nil
else
return v
rofl = {}
rofl.version = "ROFLMAO"
rofl.files = {}
rofl.conf = {}
rofl.conf.Tick = 20 -- Tick interval
rofl.conf.Rpertick = 20000 -- Max reading operations per tick
rofl.conf.Wpertick = 50000 -- Max writing operations per tick
rofl.conf.Apertick = 10000 -- Max application operations per tick
rofl.conf.Lpertick = 75000 -- Max loading operations per tick
rofl.buffers = {}
rofl.buffers.RCache = {} -- Reading
rofl.buffers.WCache = {} -- Writing
rofl.buffers.LCache = {} -- Loading -- not in use
rofl.buffers.ACache = {} -- Application
-------------------------------------------------
-- ROFL Capture (not copter)
-- Queue nodes to be written in a buffer file
-------------------------------------------------
function rofl.capture(f, pos1, pos2)
local posU = {x = math.max(pos1.x, pos2.x), y = math.max(pos1.y, pos2.y), z = math.max(pos1.z, pos2.z)}
local posD = {x = math.min(pos1.x, pos2.x), y = math.min(pos1.y, pos2.y), z = math.min(pos1.z, pos2.z)}
local n = 0
for x = posD.x, posU.x do
for y = posD.y, posU.y do
for z = posD.z, posU.z do
local node = minetest.get_node({x = x, y = y, z = z})
if node.name == "ignore" then
-- return false, "Area unloaded : ~" .. minetest.pos_to_string({x = x, y = y, z = z})
else
table.insert(rofl.buffers.WCache, {f, x-posD.x .. ";" .. y-posD.y .. ";" .. z-posD.z .. "|" .. minetest.serialize(node) .. "\n"})
n = n + 1
end
end
end
end
return n
end
local function metaread(v)
--[[
Eg. : channel-in="keyboard",channel-out="terminal",formspec="field[text;;${command}]"
]]
if not v or v == "None" or v == "[]" then return nil end
v = string.sub(v,2,string.len(v)-1)
-- Meta extraction
local cursor = 0
local metas = {}
while cursor <= string.len(v) do
local key, value
local keybeg, keyend, valbeg, valend = cursor, cursor, cursor, cursor
keyend = string.find(v, "=\"", cursor)-1
key = string.sub(v,keybeg,keyend)
valbeg = keyend+3
valend = (string.find(v, "\",", valbeg) or string.len(v))-1
value = string.sub(v,valbeg,valend)
cursor = valend+3
metas[key] = value
end
return metas
end
local function parser(fields)
end
minetest.register_chatcommand("rofl", {
description = "Save MFF",
privs = {server = true},
minetest.register_chatcommand("roflCapture", {
params = "<name> <pos1> <pos2>",
description = "Capture nodes contained in area pos1 to pos2",
privs = {server=true},
func = function(name, param)
-- Alert
minetest.chat_send_all("*** Server Freezing")
local f, p1, p2 = unpack(param:split(" "))
-- The main loop
local i = 0
if tonumber(param) then
i = tonumber(param)
if not f then
return false, "Invalid buffer name"
elseif not minetest.string_to_pos(p1) then
return false, "Invalid pos1"
elseif not minetest.string_to_pos(p2) then
return false, "Invalid pos2"
end
local vm = minetest.get_voxel_manip()
while true do
local file = io.open(filepath .. "/database-output." .. i .. ".txt", "r")
if not file then
break
end
minetest.log("action", "[ROFL] Opened file database-output." .. i .. ".txt ... Extracting datas")
-- [
-- id=155,actor=Mg,type=1;
-- list=None,index=None,add=None,stacknode=None,stackquantity=None,nodemeta=None;
-- x=-18,y=29,z=31;
-- newnode=air,newparam1=13,newparam2=None,newmeta=None
-- ]
for fields in file:lines() do
local id = tonumber(string.sub(fields, string.find(fields, "id=")+string.len("id="), string.find(fields, ",actor")-1))
local actor = string.sub(fields, string.find(fields, "actor=")+string.len("actor="), string.find(fields, ",type")-1)
local action_type = tonumber(string.sub(fields, string.find(fields, "type=")+string.len("type="), string.find(fields, ";list")-1))
p1 = minetest.string_to_pos(p1)
p2 = minetest.string_to_pos(p2)
local list = none(string.sub(fields, string.find(fields, "list=")+string.len("list="), string.find(fields, ",index")-1))
local index = none(tonumber(string.sub(fields, string.find(fields, "index=")+string.len("index="), string.find(fields, ",add")-1)))
local add = none(tonumber(string.sub(fields, string.find(fields, "add=")+string.len("add="), string.find(fields, ",stacknode")-1)))
local stacknode = none(string.sub(fields, string.find(fields, "stacknode=")+string.len("stacknode="), string.find(fields, ",stackquantity")-1))
local stackquantity = none(tonumber(string.sub(fields, string.find(fields, "stackquantity=")+string.len("stackquantity="), string.find(fields, ";x=")-1)))
local x = none(tonumber(string.sub(fields, string.find(fields, ";x=")+string.len(";x="), string.find(fields, ",y=")-1)))
local y = none(tonumber(string.sub(fields, string.find(fields, ",y=")+string.len(",y="), string.find(fields, ",z=")-1)))
local z = none(tonumber(string.sub(fields, string.find(fields, ",z=")+string.len(",z="), string.find(fields, ";newnode=")-1)))
local newnode = none(string.sub(fields, string.find(fields, "newnode=")+string.len("newnode="), string.find(fields, ",newparam1")-1))
local newparam1 = none(tonumber(string.sub(fields, string.find(fields, "newparam1=")+string.len("newparam1="), string.find(fields, ",newparam2")-1)))
local newparam2 = none(tonumber(string.sub(fields, string.find(fields, "newparam2=")+string.len("newparam2="), string.find(fields, ",newmeta=")-1)))
local newmeta = none(metaread(string.sub(fields, string.find(fields, ",newmeta=")+string.len(",newmeta="), string.len(fields)-1)))
minetest.log("action","[ROFL] Applying id = " .. id)
if patchsegs % patchtotp == 0 then
minetest.get_player_by_name(name):setpos({x = x, y = y, z = z})
patchsegs = 0
end
if action_type == 1 then -- TYPE_SETNODE
local forced = minetest.forceload_block({x = x, y = y, z = z})
if forced then
minetest.set_node({x = x, y = y, z = z}, {name = newnode, param1 = newparam1, param2 = newparam2})
minetest.forceload_free_block({x = x, y = y, z = z})
else
minetest.log("error", "[ROFL] Couldn't forceplace block " .. minetest.pos_to_string({x = x, y = y, z = z}))
end
if newmeta then
local meta = minetest.get_meta({x = x, y = y, z = z})
for key,value in ipairs(newmeta) do
if tonumber(value) then
meta:set_int(key, value)
else
meta:set_string(key,value)
end
end
end
elseif action_type == 2 then -- TYPE_MODIFY_INVENTORY_STACK
local inv = minetest.get_meta({x = x, y = y, z = z}):get_inventory()
local stack = inv:get_stack(list, index)
if add == 1 then
stack:set_name(stacknode)
stack:set_count(stackquantity)
else
stack:take_item(stackquantity)
end
inv:set_stack(list, index, stack)
else -- TYPE_NOTHING
print("W.T.F. is type " .. (action_type or "nil"))
end
patchsegs = patchsegs + 1
end
i = i + 1
io.close(file)
if tonumber(param) then
break
end
local k, u = rofl.capture(f, p1, p2)
if k then
io.close(io.open(bufferfiles .. f .. ".buf", "w")) -- Remove any previous file that would have the same name
return true, "Successfully captured area from " ..
core.pos_to_string(p1, 1) .. " to " .. core.pos_to_string(p2, 1) ..
" in file " .. f .. " : " .. k .. " nodes"
else
return false, "Failed to capture the area : " .. u
end
minetest.chat_send_all("*** Server Up")
end,
})
----------------------
-- Node application
----------------------
function rofl.apply(pos, buf)
local f = io.open(bufferfiles .. buf .. ".buf")
if not f then
return false, "No such buffer : " .. buf
end
local l = 0
for line in f:lines() do
local t, node = unpack(line:split("|"))
t = t:split(";")
if table.getn(t) == 3 then
local pos2 = {x = t[1] + math.floor(pos.x), y = t[2] + math.floor(pos.y), z = t[3] + math.floor(pos.z)}
node = minetest.deserialize(node)
table.insert(rofl.buffers.ACache, {pos2, node})
l = l + 1
end
end
f:close()
return l
end
minetest.register_chatcommand("roflPaste", {
params = "<name> [<pos>]",
description = "Apply nodes present in buffer",
privs = {server=true},
func = function(name, param)
local bufname, pos = unpack(param:split(" "))
if not bufname or bufname == "" then
return false, "Invalid buffer name"
elseif not pos or pos == "" then
local p = minetest.get_player_by_name(name)
if not p then
return false, "Unable to get your position"
else
pos = minetest.pos_to_string(p:getpos())
end
end
if not minetest.string_to_pos(pos) then
return false, "Invalid pos"
end
local k, u = rofl.apply(minetest.string_to_pos(pos), bufname)
if not k then
return false, "Unable to apply nodes : " .. u
else
minetest.log("action", "{ROFL} " .. k .. " nodes queued")
return true, k .. " nodes are queued"
end
end
})
-----------------
-- Empty Caches
-----------------
minetest.register_chatcommand("roflFlush", {
params = "<W|A>",
description = "Empty Writing or Application buffers",
privs = {server=true},
func = function(name, param)
if param == "" then
return false, "Enter a letter, either W(riting) or A(pplication)"
elseif param == "W" then
rofl.buffers.WCache = {}
return true, "WCache flushed"
elseif param == "A" then
rofl.buffers.ACache = {}
return true, "ACache flushed"
else
return false, "Unknown cache name : " .. param
end
end
})
-------------------------
-- Delete buffer files
-------------------------
minetest.register_chatcommand("roflReset", {
params = "<name>",
description = "Empty a buffer file (or create the file if it doesn't exist)",
privs = {server=true},
func = function(name, param)
param = param:split(" ")[1]
if param == "" then
return false, "Enter a buffer name please"
else
io.close(io.open(bufferfiles .. param .. ".buf", "w"))
return true, "Done"
end
end
})
-------------------------------
-- Regularly work on queues
-------------------------------
function tick()
local t = os.time()
-- Writing
if table.getn(rofl.buffers.WCache) > 0 then
minetest.log("action", "{ROFL} WCache has " .. table.getn(rofl.buffers.WCache) .. " elements")
minetest.log("action", "{ROFL} Doing up to " .. rofl.conf.Wpertick .. " writing operations")
for x = 1, rofl.conf.Wpertick do
if not rofl.buffers.WCache[1] then break end
if not rofl.files[rofl.buffers.WCache[1][1]] then
rofl.files[rofl.buffers.WCache[1][1]] = io.open(bufferfiles .. rofl.buffers.WCache[1][1] .. ".buf", "w")
end
rofl.files[rofl.buffers.WCache[1][1]]:write(rofl.buffers.WCache[1][2])
table.remove(rofl.buffers.WCache, 1)
end
if table.getn(rofl.buffers.WCache) == 0 then
minetest.log("action", "{ROFL} Operations finished")
for fname, f in pairs(rofl.files) do
f:close()
minetest.log("action", "{ROFL} Closing filebuf " .. fname)
end
rofl.files = {}
end
end
--[[if table.getn(rofl.buffers.LCache) > 0 then
minetest.log("action", "{ROFL} LCache has " .. table.getn(rofl.buffers.LCache) .. " elements")
minetest.log("action", "{ROFL} Doing up to " .. rofl.conf.Lpertick .. " loading operations")
for x = 1, rofl.conf.Lpertick do
if not rofl.buffers.LCache[1] then break end
table.remove(rofl.buffers.LCache, 1)
end
if table.getn(rofl.buffers.LCache) == 0 then
minetest.log("action", "{ROFL} Loading operations finished")
end
end]]
-- Applying
if table.getn(rofl.buffers.ACache) > 0 then
minetest.log("action", "{ROFL} ACache has " .. table.getn(rofl.buffers.ACache) .. " elements")
minetest.log("action", "{ROFL} Doing up to " .. rofl.conf.Apertick .. " application operations")
for x = 1, rofl.conf.Apertick do
if not rofl.buffers.ACache[1] then break end
minetest.set_node(rofl.buffers.ACache[1][1], rofl.buffers.ACache[1][2])
table.remove(rofl.buffers.ACache, 1)
end
if table.getn(rofl.buffers.ACache) == 0 then
minetest.log("action", "{ROFL} Operations finished")
end
end
local t2 = os.time()
if os.difftime(t2, t) > 0 then
minetest.log("action", "{ROFL} Tick took " .. os.difftime(t2, t) .. "s")
end
minetest.after(rofl.conf.Tick, tick)
end
minetest.after(1, tick)
--------------------------------
-- Clean our mess on shutdown
--------------------------------
minetest.register_on_shutdown(function()
if table.getn(rofl.buffers.WCache) > 0 then
minetest.log("warning", "{ROFL} WCache is not empty! Canceling all pending writing operations")
rofl.buffers.WCache = {}
end
if table.getn(rofl.buffers.ACache) > 0 then
minetest.log("warning", "{ROFL} ACache is not empty! Canceling all pending application operations")
rofl.buffers.ACache = {}
end
for fname, f in pairs(rofl.files) do
f:close()
minetest.log("action", "{ROFL} Closing filebuf " .. fname)
end
end)

View File

@ -568,7 +568,6 @@ function signs_lib.determine_sign_type(itemstack, placer, pointed_thing, locked)
local fdir = minetest.dir_to_facedir(dir)
local pt_name = minetest.get_node(under).name
minetest.log("action", dump(pt_name))
local signname = itemstack:get_name()
if fences_with_sign[pt_name] and signname == "default:sign_wall" then
@ -858,22 +857,22 @@ function signs_lib.register_fence_with_sign(fencename, fencewithsignname)
def_sign = signs_lib.table_copy(def_sign)
fences_with_sign[fencename] = fencewithsignname
def.on_place = function(itemstack, placer, pointed_thing, ...)
local node_above = minetest.get_node(pointed_thing.above)
local node_under = minetest.get_node(pointed_thing.under)
local def_above = minetest.registered_nodes[node_above.name]
local def_under = minetest.registered_nodes[node_under.name]
def_sign.on_place = function(itemstack, placer, pointed_thing, ...)
local node_above = minetest.get_node_or_nil(pointed_thing.above)
local node_under = minetest.get_node_or_nil(pointed_thing.under)
local def_above = node_above and minetest.registered_nodes[node_above.name]
local def_under = node_under and minetest.registered_nodes[node_under.name]
local fdir = minetest.dir_to_facedir(placer:get_look_dir())
local playername = placer:get_player_name()
if minetest.is_protected(pointed_thing.under, playername) then
minetest.record_protection_violation(pointed_thing.under, playername)
return
return itemstack
end
if minetest.is_protected(pointed_thing.above, playername) then
minetest.record_protection_violation(pointed_thing.above, playername)
return
return itemstack
end
if def_under and def_under.on_rightclick then
@ -884,15 +883,14 @@ function signs_lib.register_fence_with_sign(fencename, fencewithsignname)
itemstack:take_item()
end
placer:set_wielded_item(itemstack)
return itemstack
elseif not def_above or def_above.buildable_to then
elseif def_above and def_above.buildable_to then
minetest.add_node(pointed_thing.above, {name = fencename, param2 = fdir})
if not signs_lib.expect_infinite_stacks then
itemstack:take_item()
end
placer:set_wielded_item(itemstack)
return itemstack
end
return itemstack
end
def_sign.on_construct = function(pos, ...)
signs_lib.construct_sign(pos)
@ -915,7 +913,7 @@ function signs_lib.register_fence_with_sign(fencename, fencewithsignname)
minetest.register_node(":"..fencename, def)
minetest.register_node(":"..fencewithsignname, def_sign)
table.insert(signs_lib.sign_node_list, fencewithsignname)
minetest.log("action", S("Registered %s and %s"):format(fencename, fencewithsignname))
minetest.log("verbose", S("Registered %s and %s"):format(fencename, fencewithsignname))
end
build_char_db()

BIN
mods/signs_lib/textures/signs_blue_front.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 B

After

Width:  |  Height:  |  Size: 175 B

BIN
mods/signs_lib/textures/signs_blue_inv.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 B

After

Width:  |  Height:  |  Size: 154 B

BIN
mods/signs_lib/textures/signs_brown_front.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 B

After

Width:  |  Height:  |  Size: 175 B

BIN
mods/signs_lib/textures/signs_brown_inv.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 B

After

Width:  |  Height:  |  Size: 155 B

BIN
mods/signs_lib/textures/signs_orange_front.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 112 B

After

Width:  |  Height:  |  Size: 170 B

BIN
mods/signs_lib/textures/signs_orange_inv.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 B

After

Width:  |  Height:  |  Size: 141 B

View File

@ -1,2 +1,2 @@
minetest.register_alias("snow:needles", "default:pine_needles")
minetest.register_alias("snow:leaves", "default:pine_needles")
minetest.register_alias("default:pine_needles", "snow:needles")
minetest.register_alias("default:pine_needles", "snow:leaves")

View File

@ -1,6 +1,7 @@
-- Some aliases for compatibility switches and some to make "/give" commands
-- a little easier
minetest.register_alias("snow:needles", "default:pine_needles")
minetest.register_alias("snow:snow", "default:snow")
minetest.register_alias("default_snow", "default:snow")
minetest.register_alias("snow:snowball", "default:snow")

View File

@ -363,7 +363,7 @@ minetest.register_on_generated(function(minp, maxp, seed)
break
end
end
elseif alpine then
--[[ elseif alpine then
-- make stone pillars out of trees and other stuff
for y = ground_y, math.max(-6, minp.y-6), -1 do
local stone = area:index(x, y, z)
@ -374,7 +374,7 @@ minetest.register_on_generated(function(minp, maxp, seed)
end
-- put snow onto it
snow_tab[num] = {ground_y, z, x, test}
num = num+1
num = num+1 --]] -- MFF (06/10/2015)
elseif c_ground ~= c.desert_sand then
if is_snowable(c_ground) then
-- put snow onto it

View File

@ -13,11 +13,6 @@ local nodedef = {
drop = {
max_items = 1,
items = {
{
-- player will get sapling with 1/20 chance
items = {'snow:sapling_pine'},
rarity = 20,
},
{
items = {'snow:needles'},
}
@ -32,7 +27,7 @@ If christmas_content is enabled, then this next part will override the pine need
The Xmas tree needles are registred and defined a farther down in this nodes.lua file.
~ LazyJ
]]
if snow.christmas_content then
table.insert(nodedef.drop.items, 1, {
-- player will get xmas tree with 1/120 chance
@ -40,7 +35,7 @@ if snow.christmas_content then
rarity = 120,
})
end
]]
minetest.register_node("snow:needles", table.copy(nodedef))
@ -75,7 +70,7 @@ nodedef.drop.items[#nodedef.drop.items] = {items = {'snow:needles_decorated'}}
minetest.register_node("snow:needles_decorated", nodedef)
-- Saplings
--[[ Saplings
nodedef = {
description = "Pine Sapling",
@ -101,7 +96,7 @@ nodedef.inventory_image = "snow_xmas_tree.png"
nodedef.wield_image = "snow_xmas_tree.png"
minetest.register_node("snow:xmas_tree", nodedef)
]]
nodedef = {
description = "Star",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

@ -1 +1 @@
Subproject commit d2866429a2882d685c1d9e01fc030cbb73579c4b
Subproject commit f8a50d985e767b9e732ae9a2150022d41637bae4

View File

@ -45,7 +45,7 @@ end
minetest.register_craftitem(":dye:lime", {
description = S("Lime Dye"),
inventory_image = "unifieddyes_lime.png",
groups = { dye=1, excolor_lime=1, unicolor_lime=1, not_in_creative_inventory=1 }
groups = { dye=1, excolor_lime=1, unicolor_lime=1 }
})
minetest.register_craft( {
@ -58,7 +58,7 @@ minetest.register_craft( {
minetest.register_craftitem(":dye:aqua", {
description = S("Aqua Dye"),
inventory_image = "unifieddyes_aqua.png",
groups = { dye=1, excolor_aqua=1, unicolor_aqua=1, not_in_creative_inventory=1 }
groups = { dye=1, excolor_aqua=1, unicolor_aqua=1 }
})
minetest.register_craft( {
@ -71,7 +71,7 @@ minetest.register_craft( {
minetest.register_craftitem(":dye:skyblue", {
description = S("Sky-blue Dye"),
inventory_image = "unifieddyes_skyblue.png",
groups = { dye=1, excolor_sky_blue=1, unicolor_sky_blue=1, not_in_creative_inventory=1 }
groups = { dye=1, excolor_sky_blue=1, unicolor_sky_blue=1 }
})
minetest.register_craft( {
@ -84,7 +84,7 @@ minetest.register_craft( {
minetest.register_craftitem(":dye:redviolet", {
description = S("Red-violet Dye"),
inventory_image = "unifieddyes_redviolet.png",
groups = { dye=1, excolor_red_violet=1, unicolor_red_violet=1, not_in_creative_inventory=1 }
groups = { dye=1, excolor_red_violet=1, unicolor_red_violet=1 }
})
minetest.register_craft( {
@ -98,7 +98,7 @@ minetest.register_craft( {
minetest.register_craftitem(":dye:light_grey", {
description = S("Light Grey Dye"),
inventory_image = "unifieddyes_lightgrey.png",
groups = { dye=1, excolor_lightgrey=1, unicolor_light_grey=1, not_in_creative_inventory=1 }
groups = { dye=1, excolor_lightgrey=1, unicolor_light_grey=1 }
})
minetest.register_craft( {
@ -287,40 +287,40 @@ for i = 1, 12 do
minetest.register_craftitem("unifieddyes:dark_" .. hue .. "_s50", {
description = S("Dark " .. hue2 .. " Dye (low saturation)"),
inventory_image = "unifieddyes_dark_" .. hue .. "_s50.png",
groups = { dye=1, ["unicolor_dark_"..hue.."_s50"]=1, not_in_creative_inventory=1 }
groups = { dye=1, ["unicolor_dark_"..hue.."_s50"]=1 }
})
if hue ~= "green" then
minetest.register_craftitem("unifieddyes:dark_" .. hue, {
description = S("Dark " .. hue2 .. " Dye"),
inventory_image = "unifieddyes_dark_" .. hue .. ".png",
groups = { dye=1, ["unicolor_dark_"..hue]=1, not_in_creative_inventory=1 }
groups = { dye=1, ["unicolor_dark_"..hue]=1 }
})
end
minetest.register_craftitem("unifieddyes:medium_" .. hue .. "_s50", {
description = S("Medium " .. hue2 .. " Dye (low saturation)"),
inventory_image = "unifieddyes_medium_" .. hue .. "_s50.png",
groups = { dye=1, ["unicolor_medium_"..hue.."_s50"]=1, not_in_creative_inventory=1 }
groups = { dye=1, ["unicolor_medium_"..hue.."_s50"]=1 }
})
minetest.register_craftitem("unifieddyes:medium_" .. hue, {
description = S("Medium " .. hue2 .. " Dye"),
inventory_image = "unifieddyes_medium_" .. hue .. ".png",
groups = { dye=1, ["unicolor_medium_"..hue]=1, not_in_creative_inventory=1 }
groups = { dye=1, ["unicolor_medium_"..hue]=1 }
})
minetest.register_craftitem("unifieddyes:" .. hue .. "_s50", {
description = S(hue2 .. " Dye (low saturation)"),
inventory_image = "unifieddyes_" .. hue .. "_s50.png",
groups = { dye=1, ["unicolor_"..hue.."_s50"]=1, not_in_creative_inventory=1 }
groups = { dye=1, ["unicolor_"..hue.."_s50"]=1 }
})
if hue ~= "red" then
minetest.register_craftitem("unifieddyes:light_" .. hue, {
description = S("Light " .. hue2 .. " Dye"),
inventory_image = "unifieddyes_light_" .. hue .. ".png",
groups = { dye=1, ["unicolor_light_"..hue]=1, not_in_creative_inventory=1 }
groups = { dye=1, ["unicolor_light_"..hue]=1 }
})
end
minetest.register_alias("unifieddyes:"..hue, "dye:"..hue)

View File

@ -0,0 +1 @@
WTFPL

View File

@ -1,2 +1,2 @@
TODO:
add things to this list
maybe make the explosion table function return a perlin explosion table

View File

@ -1,7 +1,9 @@
local load_time_start = os.clock()
function vector.pos_to_string(pos)
return "{x="..pos.x.."; y="..pos.y.."; z="..pos.z.."}"
local funcs = {}
function funcs.pos_to_string(pos)
return "("..pos.x.."|"..pos.y.."|"..pos.z..")"
end
local r_corr = 0.25 --remove a bit more nodes (if shooting diagonal) to let it look like a hole (sth like antialiasing)
@ -118,7 +120,7 @@ local function return_fine_line(pos, dir, range, scale)
return ps2
end
function vector.fine_line(pos, dir, range, scale)
function funcs.fine_line(pos, dir, range, scale)
--assert_vector(pos)
if not range then --dir = pos2
dir = vector.direction(pos, dir)
@ -127,7 +129,7 @@ function vector.fine_line(pos, dir, range, scale)
return return_fine_line(pos, dir, range, scale)
end
function vector.line(pos, dir, range, alt)
function funcs.line(pos, dir, range, alt)
--assert_vector(pos)
if alt then
if not range then --dir = pos2
@ -149,7 +151,7 @@ function vector.line(pos, dir, range, alt)
end
local twolines = {}
function vector.twoline(x, y)
function funcs.twoline(x, y)
local pstr = x.." "..y
local line = twolines[pstr]
if line then
@ -183,7 +185,7 @@ function vector.twoline(x, y)
end
local threelines = {}
function vector.threeline(x, y, z)
function funcs.threeline(x, y, z)
local pstr = x.." "..y.." "..z
local line = threelines[pstr]
if line then
@ -218,16 +220,104 @@ function vector.threeline(x, y, z)
return line
end
function vector.straightdelay(s, v, a)
function funcs.sort(ps, preferred_coords)
preferred_coords = preferred_coords or {"z", "y", "x"}
local a,b,c = unpack(preferred_coords)
local function ps_sorting(p1, p2)
if p1[a] == p2[a] then
if p1[b] == p2[a] then
if p1[c] < p2[c] then
return true
end
elseif p1[b] < p2[b] then
return true
end
elseif p1[a] < p2[a] then
return true
end
end
table.sort(ps, ps_sorting)
end
function funcs.scalar(v1, v2)
return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z
end
function funcs.cross(v1, v2)
return {
x = v1.y*v2.z - v1.z*v2.y,
y = v1.z*v2.x - v1.x*v2.z,
z = v1.x*v2.y - v1.y*v2.x
}
end
--not optimized
--local areas = {}
function funcs.plane(ps)
-- sort positions and imagine the first one (A) as vector.zero
ps = vector.sort(ps)
local pos = ps[1]
local B = vector.subtract(ps[2], pos)
local C = vector.subtract(ps[3], pos)
-- get the positions for the fors
local cube_p1 = {x=0, y=0, z=0}
local cube_p2 = {x=0, y=0, z=0}
for i in pairs(cube_p1) do
cube_p1[i] = math.min(B[i], C[i], 0)
cube_p2[i] = math.max(B[i], C[i], 0)
end
cube_p1 = vector.apply(cube_p1, math.floor)
cube_p2 = vector.apply(cube_p2, math.ceil)
local vn = vector.normalize(vector.cross(B, C))
local nAB = vector.normalize(B)
local nAC = vector.normalize(C)
local angle_BAC = math.acos(vector.scalar(nAB, nAC))
local nBA = vector.multiply(nAB, -1)
local nBC = vector.normalize(vector.subtract(C, B))
local angle_ABC = math.acos(vector.scalar(nBA, nBC))
for z = cube_p1.z, cube_p2.z do
for y = cube_p1.y, cube_p2.y do
for x = cube_p1.x, cube_p2.x do
local p = {x=x, y=y, z=z}
local n = -vector.scalar(p, vn)/vector.scalar(vn, vn)
if math.abs(n) <= 0.5 then
local ep = vector.add(p, vector.multiply(vn, n))
local nep = vector.normalize(ep)
local angle_BAep = math.acos(vector.scalar(nAB, nep))
local angle_CAep = math.acos(vector.scalar(nAC, nep))
local angldif = angle_BAC - (angle_BAep+angle_CAep)
if math.abs(angldif) < 0.001 then
ep = vector.subtract(ep, B)
nep = vector.normalize(ep)
local angle_ABep = math.acos(vector.scalar(nBA, nep))
local angle_CBep = math.acos(vector.scalar(nBC, nep))
local angldif = angle_ABC - (angle_ABep+angle_CBep)
if math.abs(angldif) < 0.001 then
table.insert(ps, vector.add(pos, p))
end
end
end
end
end
end
return ps
end
function funcs.straightdelay(s, v, a)
if not a then
return s/v
end
return (math.sqrt(v*v+2*a*s)-v)/a
end
vector.zero = {x=0, y=0, z=0}
vector.zero = vector.new()
function vector.sun_dir(time)
function funcs.sun_dir(time)
if not time then
time = minetest.get_timeofday()
end
@ -240,7 +330,7 @@ function vector.sun_dir(time)
return {x=tmp, y=math.sqrt(1-tmp*tmp), z=0}
end
function vector.inside(pos, minp, maxp)
function funcs.inside(pos, minp, maxp)
for _,i in pairs({"x", "y", "z"}) do
if pos[i] < minp[i]
or pos[i] > maxp[i] then
@ -250,8 +340,8 @@ function vector.inside(pos, minp, maxp)
return true
end
function vector.minmax(p1, p2)
local p1 = vector.new(p1) --Are these 2 redefinitions necessary?
function funcs.minmax(p1, p2)
local p1 = vector.new(p1)
local p2 = vector.new(p2)
for _,i in ipairs({"x", "y", "z"}) do
if p1[i] > p2[i] then
@ -261,7 +351,7 @@ function vector.minmax(p1, p2)
return p1, p2
end
function vector.move(p1, p2, s)
function funcs.move(p1, p2, s)
return vector.round(
vector.add(
vector.multiply(
@ -276,8 +366,12 @@ function vector.move(p1, p2, s)
)
end
function funcs.from_number(i)
return {x=i, y=i, z=i}
end
local explosion_tables = {}
function vector.explosion_table(r)
function funcs.explosion_table(r)
local table = explosion_tables[r]
if table then
return table
@ -308,8 +402,92 @@ function vector.explosion_table(r)
return tab
end
local default_nparams = {
offset = 0,
scale = 1,
seed = 1337,
octaves = 6,
persist = 0.6
}
function funcs.explosion_perlin(rmin, rmax, nparams)
local t1 = os.clock()
local r = math.ceil(rmax)
nparams = nparams or {}
for i,v in pairs(default_nparams) do
nparams[i] = nparams[i] or v
end
nparams.spread = nparams.spread or vector.from_number(r*5)
local pos = {x=math.random(-30000, 30000), y=math.random(-30000, 30000), z=math.random(-30000, 30000)}
local map = minetest.get_perlin_map(nparams, vector.from_number(r+r+1)):get3dMap_flat(pos)
local id = 1
local bare_maxdist = rmax*rmax
local bare_mindist = rmin*rmin
local mindist = math.sqrt(bare_mindist)
local dist_diff = math.sqrt(bare_maxdist)-mindist
mindist = mindist/dist_diff
local pval_min, pval_max
local tab, n = {}, 1
for z=-r,r do
local bare_dist = z*z
for y=-r,r do
local bare_dist = bare_dist+y*y
for x=-r,r do
local bare_dist = bare_dist+x*x
local add = bare_dist < bare_mindist
local pval, distdiv
if not add
and bare_dist <= bare_maxdist then
distdiv = math.sqrt(bare_dist)/dist_diff-mindist
pval = math.abs(map[id]) -- strange perlin values…
if not pval_min then
pval_min = pval
pval_max = pval
else
pval_min = math.min(pval, pval_min)
pval_max = math.max(pval, pval_max)
end
add = true--distdiv < 1-math.abs(map[id])
end
if add then
tab[n] = {{x=x, y=y, z=z}, pval, distdiv}
n = n+1
end
id = id+1
end
end
end
-- change strange values
local pval_diff = pval_max - pval_min
pval_min = pval_min/pval_diff
for n,i in pairs(tab) do
if i[2] then
local new_pval = math.abs(i[2]/pval_diff - pval_min)
if i[3]+0.33 < new_pval then
tab[n] = {i[1]}
elseif i[3] < new_pval then
tab[n] = {i[1], true}
else
tab[n] = nil
end
end
end
minetest.log("info", string.format("[vector_extras] table created after ca. %.2fs", os.clock() - t1))
return tab
end
local circle_tables = {}
function vector.circle(r)
function funcs.circle(r)
local table = circle_tables[r]
if table then
return table
@ -332,7 +510,7 @@ function vector.circle(r)
end
local ring_tables = {}
function vector.ring(r)
function funcs.ring(r)
local table = ring_tables[r]
if table then
return table
@ -373,10 +551,156 @@ function vector.ring(r)
return tab2
end
function vector.chunkcorner(pos)
function funcs.chunkcorner(pos)
return {x=pos.x-pos.x%16, y=pos.y-pos.y%16, z=pos.z-pos.z%16}
end
function funcs.point_distance_minmax(p1, p2)
local p1 = vector.new(p1)
local p2 = vector.new(p2)
local min, max, vmin, vmax, num
for _,i in ipairs({"x", "y", "z"}) do
num = math.abs(p1[i] - p2[i])
if not vmin or num < vmin then
vmin = num
min = i
end
if not vmax or num > vmax then
vmax = num
max = i
end
end
return min, max
end
function funcs.collision(p1, p2)
local clear, node_pos, collision_pos, max, min, dmax, dcmax, pt
clear, node_pos = minetest.line_of_sight(p1, p2)
if clear then
return false
end
collision_pos = {}
min, max = funcs.point_distance_minmax(node_pos, p2)
if node_pos[max] > p2[max] then
collision_pos[max] = node_pos[max] - 0.5
else
collision_pos[max] = node_pos[max] + 0.5
end
dmax = p2[max] - node_pos[max]
dcmax = p2[max] - collision_pos[max]
pt = dcmax/dmax
for _,i in ipairs({"x", "y", "z"}) do
collision_pos[i] = p2[i] - (p2[i] - node_pos[i]) * pt
end
return true, collision_pos, node_pos
end
function funcs.get_data_from_pos(tab, z,y,x)
local data = tab[z]
if data then
data = data[y]
if data then
return data[x]
end
end
end
function funcs.set_data_to_pos(tab, z,y,x, data)
if tab[z] then
if tab[z][y] then
tab[z][y][x] = data
return
end
tab[z][y] = {[x] = data}
return
end
tab[z] = {[y] = {[x] = data}}
end
function funcs.set_data_to_pos_optional(tab, z,y,x, data)
if vector.get_data_from_pos(tab, z,y,x) ~= nil then
return
end
funcs.set_data_to_pos(tab, z,y,x, data)
end
function funcs.remove_data_from_pos(tab, z,y,x)
if vector.get_data_from_pos(tab, z,y,x) == nil then
return
end
tab[z][y][x] = nil
if not next(tab[z][y]) then
tab[z][y] = nil
end
if not next(tab[z]) then
tab[z] = nil
end
end
function funcs.get_data_pos_table(tab)
local t,n = {},1
local minz, miny, minx, maxz, maxy, maxx
for z,yxs in pairs(tab) do
if not minz then
minz = z
maxz = z
else
minz = math.min(minz, z)
maxz = math.max(maxz, z)
end
for y,xs in pairs(yxs) do
if not miny then
miny = y
maxy = y
else
miny = math.min(miny, y)
maxy = math.max(maxy, y)
end
for x,v in pairs(xs) do
if not minx then
minx = x
maxx = x
else
minx = math.min(minx, x)
maxx = math.max(maxx, x)
end
t[n] = {z,y,x, v}
n = n+1
end
end
end
return t, {x=minx, y=miny, z=minz}, {x=maxx, y=maxy, z=maxz}, n-1
end
function funcs.update_minp_maxp(minp, maxp, pos)
for _,i in pairs({"z", "y", "x"}) do
minp[i] = math.min(minp[i], pos[i])
maxp[i] = math.max(maxp[i], pos[i])
end
end
function funcs.quickadd(pos, z,y,x)
if z then
pos.z = pos.z+z
end
if y then
pos.y = pos.y+y
end
if x then
pos.x = pos.x+x
end
end
function funcs.unpack(pos)
return pos.z, pos.y, pos.x
end
dofile(minetest.get_modpath("vector_extras").."/vector_meta.lua")
for name,func in pairs(funcs) do
vector[name] = vector[name] or func
end
minetest.log("info", string.format("[vector_extras] loaded after ca. %.2fs", os.clock() - load_time_start))

View File

@ -46,15 +46,17 @@ do_warp_queue = function()
local t = minetest.get_us_time()
for i = table.getn(warps_queue),1,-1 do
local e = warps_queue[i]
if e and e.p and e.p:getpos() and e.p:getpos().x == e.pos.x and e.p:getpos().y == e.pos.y and e.p:getpos().z == e.pos.z then
if t > e.t then
warp(e.p, e.w)
if e.p:getpos() then
if e.p:getpos().x == e.pos.x and e.p:getpos().y == e.pos.y and e.p:getpos().z == e.pos.z then
if t > e.t then
warp(e.p, e.w)
table.remove(warps_queue, i)
end
else
minetest.sound_stop(e.sh)
minetest.chat_send_player(e.p:get_player_name(), "You have to stand still for " .. warps_freeze .. " seconds!")
table.remove(warps_queue, i)
end
else
minetest.sound_stop(e.sh)
minetest.chat_send_player(e.p:get_player_name(), "You have to stand still for " .. warps_freeze .. " seconds!")
table.remove(warps_queue, i)
end
end
if table.getn(warps_queue) == 0 then

View File

@ -99,9 +99,9 @@ minetest.register_chatcommand("timeonline",{
description = "Shows the cumulative time a player has been online",
func = function (name, param)
if ( param ~= nil ) then
if param == "" then
param = name
end
if param == "" then
param = name
end
local t = whoison.getTimeOnline(param)
if ( t ~= nil ) then
minetest.chat_send_player(name,param.." has been online for "..breakdowntime(t))

View File

@ -140,12 +140,12 @@ function xban.get_record(player)
end
local record = { }
for _, rec in ipairs(e.record) do
local msg
local msg = rec.reason or "No reason given."
if rec.expires then
msg = ("%s, Expires: %s"):format(
rec.reason, os.date("%c", e.expires))
else
msg = rec.reason
msg = msg..(", Expires: %s"):format(os.date("%c", e.expires))
end
if rec.source then
msg = msg..", Source: "..rec.source
end
table.insert(record, ("[%s]: %s"):format(os.date("%c", e.time), msg))
end
@ -321,5 +321,7 @@ minetest.after(SAVE_INTERVAL, save_db)
load_db()
xban.db = db
minetest.after(1, check_temp_bans)
dofile(xban.MP.."/dbimport.lua")
dofile(xban.MP.."/gui.lua")