This commit is contained in:
root 2021-06-12 20:20:04 +02:00
parent f36efacca8
commit 6f3c3f8b60
103 changed files with 4143 additions and 4353 deletions

View File

@ -18,5 +18,6 @@ Based on Immersive Sounds .36 mod by Neuromancer and optimized to run on servers
- 1.3 - Added API for use with other mods, code rewrite - 1.3 - Added API for use with other mods, code rewrite
- 1.4 - Re-ordered water sets to come before fire and lava, day/night sounds play when leaves around and above ground - 1.4 - Re-ordered water sets to come before fire and lava, day/night sounds play when leaves around and above ground
- 1.5 - Added 'flame_sound' and fire redo check, code tidy and tweak, added ephemeral flag for background sounds. - 1.5 - Added 'flame_sound' and fire redo check, code tidy and tweak, added ephemeral flag for background sounds.
- 1.6 - Finding env_sounds disables water and lava sets, added 'ambience_water_move' flag to override water walking sounds, use eye level for head node.
Code license: MIT Code license: MIT

View File

@ -1,13 +1,6 @@
ambience = {} ambience = {}
-- override default water sounds
minetest.override_item("default:water_source", { sounds = {} })
minetest.override_item("default:water_flowing", { sounds = {} })
minetest.override_item("default:river_water_source", { sounds = {} })
minetest.override_item("default:river_water_flowing", { sounds = {} })
-- settings -- settings
local SOUNDVOLUME = 1.0 local SOUNDVOLUME = 1.0
local MUSICVOLUME = 1.0 local MUSICVOLUME = 1.0
@ -132,13 +125,14 @@ local get_ambience = function(player, tod, name)
-- get foot and head level nodes at player position -- get foot and head level nodes at player position
local pos = player:get_pos() ; if not pos then return end local pos = player:get_pos() ; if not pos then return end
local prop = player:get_properties()
pos.y = pos.y + 1.4 -- head level pos.y = pos.y + prop.eye_height -- eye level
local nod_head = pplus and name and playerplus[name] local nod_head = pplus and name and playerplus[name]
and playerplus[name].nod_head or minetest.get_node(pos).name and playerplus[name].nod_head or minetest.get_node(pos).name
pos.y = pos.y - 1.2 -- foot level pos.y = (pos.y - prop.eye_height) + 0.2 -- foot level
local nod_feet = pplus and name and playerplus[name] local nod_feet = pplus and name and playerplus[name]
and playerplus[name].nod_feet or minetest.get_node(pos).name and playerplus[name].nod_feet or minetest.get_node(pos).name
@ -190,19 +184,17 @@ minetest.register_globalstep(function(dtime)
if timer < 1 then return end if timer < 1 then return end
timer = 0 timer = 0
-- get list of players and set some variables
local players = minetest.get_connected_players()
local player_name, number, chance, ambience, handler, ok local player_name, number, chance, ambience, handler, ok
local tod = minetest.get_timeofday() local tod = minetest.get_timeofday()
-- loop through players -- loop through players
for n = 1, #players do for _, player in ipairs(minetest.get_connected_players()) do
player_name = players[n]:get_player_name() player_name = player:get_player_name()
--local t1 = os.clock() --local t1 = os.clock()
local set_name, MORE_GAIN = get_ambience(players[n], tod, player_name) local set_name, MORE_GAIN = get_ambience(player, tod, player_name)
--print(string.format("elapsed time: %.4f\n", os.clock() - t1)) --print(string.format("elapsed time: %.4f\n", os.clock() - t1))
@ -258,25 +250,24 @@ minetest.register_globalstep(function(dtime)
playing[player_name].handler = handler playing[player_name].handler = handler
-- set timer to stop sound -- set timer to stop sound
minetest.after(ambience.length, function() minetest.after(ambience.length, function(handler, player_name)
--print("-- after", set_name, handler)
-- make sure we are stopping same sound we started
if playing[player_name]
and playing[player_name].handler
and playing[player_name].handler == handler then
--print("-- timed stop", set_name, handler) --print("-- timed stop", set_name, handler)
if handler then
minetest.sound_stop(handler) minetest.sound_stop(handler)
end
-- reset variables if handlers match
if playing[player_name]
and playing[player_name].handler == handler then
--print("-- timed reset", handler, player_name)
-- reset player variables
playing[player_name].set = nil playing[player_name].set = nil
playing[player_name].gain = nil playing[player_name].gain = nil
playing[player_name].handler = nil playing[player_name].handler = nil
end end
end) end, handler, player_name)
end end
end end
end end

View File

@ -1,2 +1,5 @@
# If enabled will play a random music file from ./minetest/sounds at midnight # If enabled will play a random music file from ./minetest/sounds at midnight
ambience_music (Ambience music) bool true ambience_music (Ambience music) bool true
# If enabled then ambience will take over sounds when moving in water
ambience_water_move (Ambience water movement) bool true

View File

@ -25,7 +25,15 @@ ambience.add_set("underwater", {
end end
}) })
-- Splashing sound plays when player walks inside water nodes -- Splashing sound plays when player walks inside water nodes (if enabled)
if minetest.settings:get_bool("ambience_water_move") ~= false then
-- override default water sounds
minetest.override_item("default:water_source", { sounds = {} })
minetest.override_item("default:water_flowing", { sounds = {} })
minetest.override_item("default:river_water_source", { sounds = {} })
minetest.override_item("default:river_water_flowing", { sounds = {} })
ambience.add_set("splash", { ambience.add_set("splash", {
@ -49,7 +57,9 @@ ambience.add_set("splash", {
end end
}) })
-- check for env_sounds mod, if not found enable water flowing sounds end
-- check for env_sounds mod, if not found enable water flowing and lava sounds
if not minetest.get_modpath("env_sounds") then if not minetest.get_modpath("env_sounds") then
-- Water sound plays when near flowing water -- Water sound plays when near flowing water
@ -102,6 +112,32 @@ ambience.add_set("river", {
end end
}) })
-- Lava sound plays when near lava
ambience.add_set("lava", {
frequency = 1000,
sounds = {
{name = "lava", length = 7}
},
nodes = {"default:lava_source", "default:lava_flowing"},
sound_check = function(def)
local c = (def.totals["default:lava_source"] or 0)
+ (def.totals["default:lava_flowing"] or 0)
if c > 20 then
return "lava", 0.5
elseif c > 5 then
return "lava"
end
end
})
else else
print ("[Ambience] found env_sounds, flowing water sounds disabled.") print ("[Ambience] found env_sounds, flowing water sounds disabled.")
end end
@ -170,32 +206,6 @@ ambience.add_set("largefire", {
end end
-- Lava sound plays when near lava
ambience.add_set("lava", {
frequency = 1000,
sounds = {
{name = "lava", length = 7}
},
nodes = {"default:lava_source", "default:lava_flowing"},
sound_check = function(def)
local c = (def.totals["default:lava_source"] or 0)
+ (def.totals["default:lava_flowing"] or 0)
if c > 20 then
return "lava", 0.5
elseif c > 5 then
return "lava"
end
end
})
-- Beach sounds play when below y-pos 6 and 150+ water source found -- Beach sounds play when below y-pos 6 and 150+ water source found
ambience.add_set("beach", { ambience.add_set("beach", {

View File

@ -6,18 +6,17 @@ local bridger_colors = {
} }
for _, color in pairs(bridger_colors) do for _, color in pairs(bridger_colors) do
local oldname = color local oldname = color
local newname = string.lower(color) local newname = string.lower(color)
if minetest.get_modpath("moreblocks") then if minetest.get_modpath("moreblocks") then
stairsplus:register_alias_all("bridges", "block_"..oldname, "bridger", "block_"..newname) stairsplus:register_alias_all("bridges", "block_" .. oldname, "bridger", "block_" .. newname)
minetest.register_alias("bridges:step_"..oldname, "bridger:panel_block_"..newname) minetest.register_alias("bridges:step_" .. oldname, "bridger:panel_block_" .. newname)
elseif minetest.get_modpath("stairs") then elseif minetest.get_modpath("stairs") then
minetest.register_alias("stairs:slab_block_"..oldname, "stairs:slab_block_"..newname) minetest.register_alias("stairs:slab_block_" .. oldname, "stairs:slab_block_" .. newname)
minetest.register_alias("stairs:stair_block_"..oldname, "stairs:stair_block_"..newname) minetest.register_alias("stairs:stair_block_" .. oldname, "stairs:stair_block_" .. newname)
end end
local bridger_error1 = { local bridger_error1 = {
"block_", "block_",
"step_", "step_",
@ -41,12 +40,11 @@ for _, color in pairs(bridger_colors) do
"truss_substructure_end_left_slant_", "truss_substructure_end_left_slant_",
"truss_substructure_end_right_slant_" "truss_substructure_end_right_slant_"
} }
for _, prefix in pairs (bridger_error1) do for _, prefix in pairs (bridger_error1) do
minetest.register_alias("bridges:"..prefix..oldname, "bridger:"..prefix..newname) minetest.register_alias("bridges:" .. prefix .. oldname, "bridger:" .. prefix .. newname)
end end
local bridger_error2 = { local bridger_error2 = {
"truss_substructure_mid", "truss_substructure_mid",
"truss_substructure_simple", "truss_substructure_simple",
@ -58,18 +56,18 @@ for _, color in pairs(bridger_colors) do
"truss_superstructure_simple", "truss_superstructure_simple",
"truss_superstructure_simple_end_right" "truss_superstructure_simple_end_right"
} }
for _, prefix in pairs (bridger_error2) do for _, prefix in pairs (bridger_error2) do
minetest.register_alias("bridges:"..prefix..oldname, "bridger:"..prefix.."_"..newname) minetest.register_alias("bridges:" .. prefix .. oldname, "bridger:" .. prefix .. "_" .. newname)
end end
minetest.register_alias("bridges:truss_superstructure_simple_end"..oldname, "bridger:truss_superstructure_simple_end_left_"..newname) minetest.register_alias("bridges:truss_superstructure_simple_end" .. oldname, "bridger:truss_superstructure_simple_end_left_" .. newname)
minetest.register_alias("bridges:girder_left_end"..oldname, "bridger:girder_left_"..newname) minetest.register_alias("bridges:girder_left_end" .. oldname, "bridger:girder_left_" .. newname)
end end
minetest.register_alias("bridges:corrugated_steel", "bridger:corrugated_steel_steel") minetest.register_alias("bridges:corrugated_steel", "bridger:corrugated_steel_steel")
minetest.register_alias("bridges:corrugated_steel_ceiling", "bridger:corrugated_steel_ceiling_steel") minetest.register_alias("bridges:corrugated_steel_ceiling", "bridger:corrugated_steel_ceiling_steel")
minetest.register_alias("bridges:scaffolding", "bridger:scaffolding") minetest.register_alias("bridges:scaffolding", "bridger:scaffolding")
minetest.register_alias("bridges:zbridges_diagonal_steel_rod", "bridger:bridges_diagonal_steel_rod") minetest.register_alias("bridges:zbridges_diagonal_steel_rod", "bridger:bridges_diagonal_steel_rod")
minetest.register_alias("bridges:zbridges_steel_rod", "bridger:bridges_steel_rod") minetest.register_alias("bridges:zbridges_steel_rod", "bridger:bridges_steel_rod")

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,6 @@ minetest.register_node("bridger:scaffolding", {
drawtype = "glasslike_framed_optional", drawtype = "glasslike_framed_optional",
tiles = {"bridges_scaffolding.png", "bridges_scaffolding_detail.png"}, tiles = {"bridges_scaffolding.png", "bridges_scaffolding_detail.png"},
paramtype = "light", paramtype = "light",
paramtype2 = "glasslikeliquidlevel",
sunlight_propagates = true, sunlight_propagates = true,
walkable = false, walkable = false,
climbable = true, climbable = true,
@ -12,9 +11,9 @@ minetest.register_node("bridger:scaffolding", {
}) })
dofile(minetest.get_modpath("bridger").."/nodes.lua") dofile(minetest.get_modpath("bridger") .. "/nodes.lua")
dofile(minetest.get_modpath("bridger").."/crafts.lua") dofile(minetest.get_modpath("bridger") .. "/crafts.lua")
if minetest.settings:get_bool("Bridger_enable_alias") then if minetest.settings:get_bool("Bridger_enable_alias") then
dofile(minetest.get_modpath("bridger").."/alias.lua") dofile(minetest.get_modpath("bridger") .. "/alias.lua")
end end

View File

@ -1 +1,4 @@
name = bridger name = bridger
depends = default
optional_depends = stairs, moreblocks, mesecons
description = Adds a large number of advanced nodes conducive to building large, industrial bridges.

File diff suppressed because it is too large Load Diff

View File

@ -10,15 +10,17 @@ Features:
- Particle effects added - Particle effects added
- Dropped items slide on nodes with {slippery} groups - Dropped items slide on nodes with {slippery} groups
- Items stuck inside solid nodes move to nearest empty space - Items stuck inside solid nodes move to nearest empty space
- Added 'dropped_step(self, pos, dtime)' custom on_step for dropped items - Added 'dropped_step(self, pos, dtime, moveresult)' custom on_step for dropped items
'self.node_inside' contains node table that item is inside 'self.node_inside' contains node table that item is inside
'self.def_inside' contains node definition for above 'self.def_inside' contains node definition for above
'self.node_under' contains node table that is below item 'self.node_under' contains node table that is below item
'self.def_under' contains node definition for above 'self.def_under' contains node definition for above
'self.age' holds age of dropped item in seconds 'self.age' holds age of dropped item in seconds
'self.itemstring' contains itemstring e.g. "default:dirt", "default:ice 20" 'self.itemstring' contains itemstring e.g. "default:dirt", "default:ice 20"
'self.is_moving' true if dropped item is moving
'pos' holds position of dropped item 'pos' holds position of dropped item
'dtime' used for timers 'dtime' used for timers
'moveresult' table containing collision info
return false to skip further checks by builtin_item return false to skip further checks by builtin_item

View File

@ -271,7 +271,7 @@ core.register_entity(":__builtin:item", {
pos.y = pos.y + ((total_count - count) / max_count) * 0.15 pos.y = pos.y + ((total_count - count) / max_count) * 0.15
self.object:move_to(pos) self.object:move_to(pos)
self.age = 0 -- Handle as new entity self.age = 0 -- Reset age
-- Merge velocities -- Merge velocities
local vel_a = self.object:get_velocity() local vel_a = self.object:get_velocity()
@ -300,35 +300,49 @@ core.register_entity(":__builtin:item", {
-- get nodes every 1/4 second -- get nodes every 1/4 second
self.timer = (self.timer or 0) + dtime self.timer = (self.timer or 0) + dtime
if self.timer > 0.25 or not self.node_inside then if self.timer < 0.25 and self.node_inside then
return
end
self.node_inside = minetest.get_node_or_nil(pos) self.node_inside = minetest.get_node_or_nil(pos)
self.def_inside = self.node_inside self.def_inside = self.node_inside
and core.registered_nodes[self.node_inside.name] and core.registered_nodes[self.node_inside.name]
-- get ground node for collision -- get ground node for collision
self.node_under = nil self.node_under = nil
self.falling_state = true self.falling_state = true
if moveresult and moveresult.touching_ground then --[[ new ground check (glitchy)
if moveresult and moveresult.touching_ground then
for _, info in ipairs(moveresult.collisions) do for _, info in ipairs(moveresult.collisions) do
if info.axis == "y" then if info.axis == "y" then
self.node_under = core.get_node(info.node_pos) self.node_under = core.get_node_or_nil(info.node_pos)
self.falling_state = false self.falling_state = false
break break
end
end end
end end
end]]
self.def_under = self.node_under -- old ground check (stable)
and core.registered_nodes[self.node_under.name] self.node_under = minetest.get_node_or_nil({
x = pos.x,
y = pos.y + self.object:get_properties().collisionbox[2] - 0.05,
z = pos.z
})
self.timer = 0 self.def_under = self.node_under
and core.registered_nodes[self.node_under.name]
-- part of old ground check
if self.def_under and self.def_under.walkable then
self.falling_state = false
end end
self.timer = 0
end, end,
step_node_inside_checks = function(self) step_node_inside_checks = function(self)
@ -336,7 +350,8 @@ core.register_entity(":__builtin:item", {
local pos = self.object:get_pos() local pos = self.object:get_pos()
-- Delete in 'ignore' nodes -- Delete in 'ignore' nodes
if self.node_inside and self.node_inside.name == "ignore" then if (self.node_inside and self.node_inside.name == "ignore")
or self.itemstring == "" then
self.itemstring = "" self.itemstring = ""
self.object:remove() self.object:remove()
@ -382,8 +397,7 @@ core.register_entity(":__builtin:item", {
step_check_slippery = function(self) step_check_slippery = function(self)
-- don't check for slippery ground if we're not on -- don't check for slippery if we're not on the ground
-- any ground to begin with
if self.falling_state or not self.node_under then if self.falling_state or not self.node_under then
self.slippery_state = false self.slippery_state = false
@ -441,6 +455,21 @@ core.register_entity(":__builtin:item", {
local vel = self.object:get_velocity() local vel = self.object:get_velocity()
-- this stops the entity drift glitch by re-setting entity pos when not moving
if vel.x == 0 and vel.y == 0 and vel.z == 0 then
if self.is_moving == true then
self.is_moving = false
local pos = self.object:get_pos()
self.object:set_pos(pos)
end
else
self.is_moving = true
end
if self.slippery_state then if self.slippery_state then
-- apply slip factor (tiny friction that depends on the actual block type) -- apply slip factor (tiny friction that depends on the actual block type)
@ -572,17 +601,16 @@ core.register_entity(":__builtin:item", {
return -- destroyed return -- destroyed
end end
self:step_check_slippery()
-- do physics checks, then apply -- do physics checks, then apply
self:step_water_physics() self:step_water_physics()
self:step_check_slippery()
self:step_ground_friction() self:step_ground_friction()
self:step_gravity()
self:step_air_drag_physics() self:step_air_drag_physics()
self:step_gravity()
self:step_apply_forces() self:step_apply_forces()
-- do item checks self:step_try_collect() -- merge
self:step_try_collect()
end, end,
on_punch = function(self, hitter) on_punch = function(self, hitter)

View File

@ -1,541 +0,0 @@
-- Minetest: builtin/item_entity.lua
-- override ice to make slippery for 0.4.16
if not minetest.raycast then
minetest.override_item("default:ice", {
groups = {cracky = 3, puts_out_fire = 1, cools_lava = 1, slippery = 3}})
end
function core.spawn_item(pos, item)
local stack = ItemStack(item)
local obj = core.add_entity(pos, "__builtin:item")
if obj then
obj:get_luaentity():set_item(stack:to_string())
end
return obj
end
-- If item_entity_ttl is not set, enity will have default life time
-- Setting it to -1 disables the feature
local time_to_live = tonumber(core.settings:get("item_entity_ttl")) or 900
local gravity = tonumber(core.settings:get("movement_gravity")) or 9.81
local destroy_item = core.settings:get_bool("destroy_item") ~= false
-- water flow functions by QwertyMine3, edited by TenPlus1
local inv_roots = {
[0] = 1
}
local function to_unit_vector(dir_vector)
local sum = dir_vector.x * dir_vector.x + dir_vector.z * dir_vector.z
local invr_sum = 0
-- find inverse square root if possible
if inv_roots[sum] ~= nil then
invr_sum = inv_roots[sum]
else
-- not found, compute and save the inverse square root
invr_sum = 1.0 / math.sqrt(sum)
inv_roots[sum] = invr_sum
end
return {
x = dir_vector.x * invr_sum,
y = dir_vector.y,
z = dir_vector.z * invr_sum
}
end
local function node_ok(pos)
local node = minetest.get_node_or_nil(pos)
if node and minetest.registered_nodes[node.name] then
return node
end
return minetest.registered_nodes["default:dirt"]
end
local function quick_flow_logic(node, pos_testing, direction)
local node_testing = node_ok(pos_testing)
local param2 = node.param2
if not minetest.registered_nodes[node.name].groups.liquid then
param2 = 0
end
if minetest.registered_nodes[node_testing.name].liquidtype ~= "flowing"
and minetest.registered_nodes[node_testing.name].liquidtype ~= "source" then
return 0
end
local param2_testing = node_testing.param2
if param2_testing < param2 then
if (param2 - param2_testing) > 6 then
return -direction
else
return direction
end
elseif param2_testing > param2 then
if (param2_testing - param2) > 6 then
return direction
else
return -direction
end
end
return 0
end
-- reciprocal of the length of an unit square's diagonal
local DIAG_WEIGHT = 2 / math.sqrt(2)
local function quick_flow(pos, node)
local x, z = 0.0, 0.0
x = x + quick_flow_logic(node, {x = pos.x - 1, y = pos.y, z = pos.z},-1)
x = x + quick_flow_logic(node, {x = pos.x + 1, y = pos.y, z = pos.z}, 1)
z = z + quick_flow_logic(node, {x = pos.x, y = pos.y, z = pos.z - 1},-1)
z = z + quick_flow_logic(node, {x = pos.x, y = pos.y, z = pos.z + 1}, 1)
return to_unit_vector({x = x, y = 0, z = z})
end
-- END water flow functions
-- particle effects for when item is destroyed
local function add_effects(pos)
minetest.add_particlespawner({
amount = 1,
time = 0.25,
minpos = pos,
maxpos = pos,
minvel = {x = -1, y = 2, z = -1},
maxvel = {x = 1, y = 4, z = 1},
minacc = {x = 0, y = 0, z = 0},
maxacc = {x = 0, y = 0, z = 0},
minexptime = 1,
maxexptime = 3,
minsize = 1,
maxsize = 4,
texture = "tnt_smoke.png",
})
end
local water_force = 0.8
local water_friction = 0.8
local dry_friction = 2.5
core.register_entity(":__builtin:item", {
initial_properties = {
hp_max = 1,
physical = true,
collide_with_objects = false,
collisionbox = {-0.3, -0.3, -0.3, 0.3, 0.3, 0.3},
visual = "wielditem",
visual_size = {x = 0.4, y = 0.4},
textures = {""},
spritediv = {x = 1, y = 1},
initial_sprite_basepos = {x = 0, y = 0},
is_visible = false,
infotext = "",
},
itemstring = "",
moving_state = true,
slippery_state = false,
age = 0,
set_item = function(self, item)
local stack = ItemStack(item or self.itemstring)
self.itemstring = stack:to_string()
if self.itemstring == "" then
return
end
local itemname = stack:is_known() and stack:get_name() or "unknown"
local max_count = stack:get_stack_max()
local count = math.min(stack:get_count(), max_count)
local size = 0.2 + 0.1 * (count / max_count) ^ (1 / 3)
local col_height = size * 0.75
local def = core.registered_nodes[itemname]
local glow = def and def.light_source
local c1, c2 = "",""
if not(stack:get_count() == 1) then
c1 = " x"..tostring(stack:get_count())
c2 = " "..tostring(stack:get_count())
end
local name1 = stack:get_meta():get_string("description")
local name
if name1 == "" then
name = core.registered_items[itemname].description
else
name = name1
end
self.object:set_properties({
is_visible = true,
visual = "wielditem",
textures = {itemname},
visual_size = {x = size, y = size},
collisionbox = {-size, -col_height, -size, size, col_height, size},
selectionbox = {-size, -size, -size, size, size, size},
automatic_rotate = 0.314 / size,
wield_item = self.itemstring,
glow = glow,
infotext = name .. c1 .. "\n(" .. itemname .. c2 .. ")"
})
end,
get_staticdata = function(self)
return core.serialize({
itemstring = self.itemstring,
age = self.age,
dropped_by = self.dropped_by
})
end,
on_activate = function(self, staticdata, dtime_s)
if string.sub(staticdata, 1, string.len("return")) == "return" then
local data = core.deserialize(staticdata)
if data and type(data) == "table" then
self.itemstring = data.itemstring
self.age = (data.age or 0) + dtime_s
self.dropped_by = data.dropped_by
end
else
self.itemstring = staticdata
end
self.object:set_armor_groups({immortal = 1})
self.object:set_velocity({x = 0, y = 2, z = 0})
self.object:set_acceleration({x = 0, y = -gravity, z = 0})
self:set_item()
end,
try_merge_with = function(self, own_stack, object, entity)
if self.age == entity.age then
return false -- Can not merge with itself
end
local stack = ItemStack(entity.itemstring)
local name = stack:get_name()
if own_stack:get_name() ~= name
or own_stack:get_meta() ~= stack:get_meta()
or own_stack:get_wear() ~= stack:get_wear()
or own_stack:get_free_space() == 0 then
return false -- Can not merge different or full stack
end
local count = own_stack:get_count()
local total_count = stack:get_count() + count
local max_count = stack:get_stack_max()
if total_count > max_count then
return false
end
-- Merge the remote stack into this one
local pos = object:get_pos()
pos.y = pos.y + ((total_count - count) / max_count) * 0.15
self.object:move_to(pos)
self.age = 0 -- Handle as new entity
own_stack:set_count(total_count)
self:set_item(own_stack)
entity.itemstring = ""
object:remove()
return true
end,
on_step = function(self, dtime, moveresult)
local pos = self.object:get_pos()
self.age = self.age + dtime
if time_to_live > 0 and self.age > time_to_live then
self.itemstring = ""
self.object:remove()
add_effects(pos)
return
end
-- get nodes every 1/4 second
self.timer = (self.timer or 0) + dtime
if self.timer > 0.25 or not self.node_inside then
self.node_inside = minetest.get_node_or_nil(pos)
self.def_inside = self.node_inside
and core.registered_nodes[self.node_inside.name]
-- get ground node for collision
self.node_under = nil
if moveresult.touching_ground then
for _, info in ipairs(moveresult.collisions) do
if info.axis == "y" then
self.node_under = core.get_node(info.node_pos)
break
end
end
end
self.def_under = self.node_under
and core.registered_nodes[self.node_under.name]
self.timer = 0
end
local node = self.node_inside
-- Delete in 'ignore' nodes
if node and node.name == "ignore" then
self.itemstring = ""
self.object:remove()
return
end
-- do custom step function
local name = ItemStack(self.itemstring):get_name() or ""
local custom = core.registered_items[name]
and core.registered_items[name].dropped_step
if custom and custom(self, pos, dtime) == false then
return -- skip further checks if false
end
local vel = self.object:get_velocity()
local def = self.def_inside
local is_slippery = false
local is_moving = (def and not def.walkable) or
vel.x ~= 0 or vel.y ~= 0 or vel.z ~= 0
-- destroy item when dropped into lava (if enabled)
if destroy_item and def and def.groups and def.groups.lava then
minetest.sound_play("builtin_item_lava", {
pos = pos,
max_hear_distance = 6,
gain = 0.5
})
self.itemstring = ""
self.object:remove()
add_effects(pos)
return
end
-- water flowing
if def and def.liquidtype == "flowing" then
-- force applies on acceleration over time, thus multiply
local force = water_force * dtime
-- friction applies on velocity over time, thus exponentiate
local friction = (1.0 + water_friction) ^ dtime
-- get flow velocity and current vel/acc state
local vec = quick_flow(pos, node)
local a = self.object:get_acceleration()
self.object:set_acceleration({
x = a.x + vec.x * force,
y = a.y,
z = a.z + vec.z * force
})
-- apply friction to prevent items going too fast, and also to make
-- water flow override previous horizontal momentum more quickly
local v = self.object:get_velocity()
-- adjust friction for going against the current
local v_horz = { x = v.x, y = 0, z = v.z }
local v_dir = to_unit_vector(v_horz)
local flow_dot = v_dir.x * vec.x + v_dir.y * vec.y
-- also maps flow_dot from [-1,0] to [0.5,2.5]
friction = 1.0 + ((friction - 1.0) * (flow_dot + 1.5))
self.object:set_velocity({
x = v.x / friction,
y = v.y / friction,
z = v.z / friction
})
return
end
-- item inside block, move to vacant space
if def and (def.walkable == nil or def.walkable == true)
and (def.collision_box == nil or def.collision_box.type == "regular")
and (def.node_box == nil or def.node_box.type == "regular") then
local npos = minetest.find_node_near(pos, 1, "air")
if npos then
self.object:move_to(npos)
end
self.node_inside = nil -- force get_node
return
end
-- Switch locals to node under
node = self.node_under
def = self.def_under
-- Slippery node check
if def and def.walkable then
local slippery = core.get_item_group(node.name, "slippery")
is_slippery = slippery ~= 0
if is_slippery and (math.abs(vel.x) > 0.2 or math.abs(vel.z) > 0.2) then
-- Horizontal deceleration
local slip_factor = 4.0 / (slippery + 4)
self.object:set_acceleration({
x = -vel.x * slip_factor,
y = 0,
z = -vel.z * slip_factor
})
elseif vel.y == 0 then
is_moving = false
end
end
if self.moving_state == is_moving
and self.slippery_state == is_slippery then
return -- No further updates until moving state changes
end
self.moving_state = is_moving
self.slippery_state = is_slippery
local a_curr = self.object:get_acceleration()
local v_curr = self.object:get_velocity()
if is_moving then
self.object:set_acceleration({
x = a_curr.x,
y = a_curr.y - gravity,
z = a_curr.z
})
else
self.object:set_acceleration({x = 0, y = 0, z = 0})
-- preserve *some* velocity so items don't get stuck on the very ledges
-- of nodes once they move just enough to leave the hitbox of flowing water
self.object:set_velocity({
x = v_curr.x / dry_friction,
y = v_curr.y / dry_friction,
z = v_curr.z / dry_friction
})
end
--Only collect items if not moving
if is_moving then
return
end
-- Collect the items around to merge with
local own_stack = ItemStack(self.itemstring)
if own_stack:get_free_space() == 0 then
return
end
local objects = core.get_objects_inside_radius(pos, 1.0)
for k, obj in pairs(objects) do
local entity = obj:get_luaentity()
if entity and entity.name == "__builtin:item" then
if self:try_merge_with(own_stack, obj, entity) then
own_stack = ItemStack(self.itemstring)
if own_stack:get_free_space() == 0 then
return
end
end
end
end
end,
on_punch = function(self, hitter)
local inv = hitter:get_inventory()
if inv and self.itemstring ~= "" then
local left = inv:add_item("main", self.itemstring)
if left and not left:is_empty() then
self:set_item(left)
return
end
end
self.itemstring = ""
self.object:remove()
end,
})

View File

@ -15,13 +15,6 @@ minetest.override_item("default:apple", {
leafdecay = 3, leafdecay_drop = 1} leafdecay = 3, leafdecay_drop = 1}
}) })
if minetest.registered_nodes["flowers:mushroom_brown"] then
minetest.override_item("flowers:mushroom_brown", {
light_source = 1,
groups = {food_mushroom = 1, snappy = 3, attached_node = 1, flammable = 2}
})
end
--= Aliases --= Aliases
-- Banana -- Banana

View File

@ -71,22 +71,22 @@ def.tiles = {"farming_melon_7.png"}
minetest.register_node("farming:melon_7", table.copy(def)) minetest.register_node("farming:melon_7", table.copy(def))
-- stage 8 (final) -- stage 8 (final)
def.drawtype = "nodebox" minetest.register_node("farming:melon_8", {
def.description = S("Melon") description = S("Melon"),
def.tiles = { tiles = {
"farming_melon_top.png", "farming_melon_bottom.png", "farming_melon_side.png" "farming_melon_top.png",
} "farming_melon_bottom.png",
def.selection_box = {-.5, -.5, -.5, .5, .5, .5} "farming_melon_side.png"
def.walkable = true },
def.buildable_to = false groups = {
def.paramtype2 = "facedir" food_melon = 1, snappy = 2, oddly_breakable_by_hand = 1,
def.groups = { flammable = 2, plant = 1
food_melon = 1, snappy = 2, oddly_breakable_by_hand = 1, },
flammable = 2, plant = 1 drop = "farming:melon_8",
} sounds = default.node_sound_wood_defaults(),
def.drop = "farming:melon_8" paramtype2 = "facedir",
def.on_place = minetest.rotate_node on_place = minetest.rotate_node
minetest.register_node("farming:melon_8", table.copy(def)) })
-- add to registered_plants -- add to registered_plants
farming.registered_plants["farming:melon"] = { farming.registered_plants["farming:melon"] = {

View File

@ -183,7 +183,7 @@ minetest.register_node("farming:pumpkin_8", {
description = S("Pumpkin"), description = S("Pumpkin"),
tiles = { tiles = {
"farming_pumpkin_top.png", "farming_pumpkin_top.png",
"farming_pumpkin_top.png", "farming_pumpkin_bottom.png",
"farming_pumpkin_side.png" "farming_pumpkin_side.png"
}, },
groups = { groups = {
@ -191,7 +191,9 @@ minetest.register_node("farming:pumpkin_8", {
flammable = 2, plant = 1 flammable = 2, plant = 1
}, },
drop = "farming:pumpkin_8", drop = "farming:pumpkin_8",
sounds = default.node_sound_wood_defaults() sounds = default.node_sound_wood_defaults(),
paramtype2 = "facedir",
on_place = minetest.rotate_node
}) })
minetest.register_alias("farming:pumpkin", "farming:pumpkin_8") minetest.register_alias("farming:pumpkin", "farming:pumpkin_8")

View File

@ -361,7 +361,7 @@ farming.add_to_scythe_not_drops = function(item)
end end
minetest.register_tool("farming:scythe_mithril", { minetest.register_tool("farming:scythe_mithril", {
description = S("Mithril Scythe (Right-click to harvest and replant crops)"), description = S("Mithril Scythe (Use to harvest and replant crops)"),
inventory_image = "farming_scythe_mithril.png", inventory_image = "farming_scythe_mithril.png",
sound = {breaks = "default_tool_breaks"}, sound = {breaks = "default_tool_breaks"},

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 B

View File

@ -77,6 +77,7 @@ mobs:register_mob("mob_horse:horse", {
self.terrain_type = 3 self.terrain_type = 3
self.driver_attach_at = {x = 0, y = y_off, z = -2} self.driver_attach_at = {x = 0, y = y_off, z = -2}
self.driver_eye_offset = {x = 0, y = 3, z = 0} self.driver_eye_offset = {x = 0, y = 3, z = 0}
self.driver_scale = {x = 0.8, y = 0.8} -- shrink driver to fit model
end end
-- if driver present allow control of horse -- if driver present allow control of horse
@ -92,22 +93,20 @@ mobs:register_mob("mob_horse:horse", {
on_die = function(self, pos) on_die = function(self, pos)
-- drop saddle when horse is killed while riding -- detach player from horse properly
-- also detach from horse properly
if self.driver then if self.driver then
minetest.add_item(pos, "mobs:saddle")
mobs.detach(self.driver, {x = 1, y = 0, z = 1}) mobs.detach(self.driver, {x = 1, y = 0, z = 1})
end
self.saddle = nil -- drop saddle if found
if self.saddle then
minetest.add_item(pos, "mobs:saddle")
end end
-- drop any horseshoes added -- drop any horseshoes added
if self.shoed then if self.shoed then
minetest.add_item(pos, self.shoed) minetest.add_item(pos, self.shoed)
end end
end, end,
do_punch = function(self, hitter) do_punch = function(self, hitter)
@ -149,29 +148,27 @@ mobs:register_mob("mob_horse:horse", {
mobs.detach(clicker, {x = 1, y = 0, z = 1}) mobs.detach(clicker, {x = 1, y = 0, z = 1})
-- add saddle back to inventory return
if inv:room_for_item("main", "mobs:saddle") then end
inv:add_item("main", "mobs:saddle")
else
minetest.add_item(clicker:get_pos(), "mobs:saddle")
end
self.saddle = nil -- attach saddle to horse
if not self.driver
-- attach player to horse and not self.child
elseif (not self.driver and not self.child and clicker:get_wielded_item():get_name() == "mobs:saddle"
and clicker:get_wielded_item():get_name() == "mobs:saddle") and not self.saddle then
or self.saddle then
self.object:set_properties({stepheight = 1.1})
mobs.attach(self, clicker)
-- take saddle from inventory
if not self.saddle then
inv:remove_item("main", "mobs:saddle")
end
self.saddle = true self.saddle = true
self.order = "stand"
self.object:set_properties({stepheight = 1.1})
-- take saddle from inventory
inv:remove_item("main", "mobs:saddle")
self.texture_mods = self.texture_mods .. "^mobs_saddle_overlay.png"
self.object:set_texture_mod(self.texture_mods)
return
end end
-- apply horseshoes -- apply horseshoes
@ -196,6 +193,12 @@ mobs:register_mob("mob_horse:horse", {
-- apply horseshoe overlay to current horse texture -- apply horseshoe overlay to current horse texture
if overlay then if overlay then
self.texture_mods = "^" .. overlay self.texture_mods = "^" .. overlay
if self.saddle then
self.texture_mods = self.texture_mods
.. "^mobs_saddle_overlay.png"
end
self.object:set_texture_mod(self.texture_mods) self.object:set_texture_mod(self.texture_mods)
end end
@ -215,8 +218,13 @@ mobs:register_mob("mob_horse:horse", {
end end
-- used to capture horse with magic lasso -- used to capture horse with magic lasso
mobs:capture_mob(self, clicker, 0, 0, 80, false, nil) if mobs:capture_mob(self, clicker, nil, nil, 100, false, nil) then return end
end,
-- ride horse if saddled
if self.saddle and self.owner == player_name then
mobs.attach(self, clicker)
end
end
}) })
mobs:spawn({ mobs:spawn({

View File

@ -7,6 +7,10 @@ There are three different horse textures (white, brown, black) which will spawn
### Taming ### Taming
Horses can be tamed with 10x wheat, apple, barley, oats of corn which then allows the player to pick up the horse using a lasso and ride by right-clicking with a saddle. Horses can be tamed with 10x wheat, apple, barley, oats of corn which then allows the player to pick up the horse using a lasso and ride by right-clicking with a saddle.
---
### Saddle
Right clicking a horse with a saddle equips it and the horse will be ordered to stand still until you wish to ride.
--- ---
### Horseshoes ### Horseshoes
Horseshoes can be crafted using steel, bronze, mese, diamond and crystal (4x ingots - 2 down either side with 1x block top middle) and placed on a horse by right clicking with the item. These can make horses run faster or jump higher while riding depending on tier. Horseshoes can be crafted using steel, bronze, mese, diamond and crystal (4x ingots - 2 down either side with 1x block top middle) and placed on a horse by right clicking with the item. These can make horses run faster or jump higher while riding depending on tier.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1,6 +1,16 @@
local S = mobs.intllib local S = mobs.intllib
local mob_drops = {
{name = "fireflies:firefly", chance = 1, min = 1, max = 1}
}
if minetest.get_modpath("ethereal") then
table.insert(mob_drops,
{name = "ethereal:fire_dust", chance = 1, min = 1, max = 1})
end
-- Fire Spirit -- Fire Spirit
mobs:register_mob("mobs_monster:fire_spirit", { mobs:register_mob("mobs_monster:fire_spirit", {
@ -22,6 +32,8 @@ mobs:register_mob("mobs_monster:fire_spirit", {
glow = 14, glow = 14,
blood_texture = "fire_basic_flame.png", blood_texture = "fire_basic_flame.png",
immune_to = { immune_to = {
{"bucket:bucket_water", 1},
{"bucket:bucket_river_water", 1},
{"all"} {"all"}
}, },
makes_footstep_sound = false, makes_footstep_sound = false,
@ -34,9 +46,8 @@ mobs:register_mob("mobs_monster:fire_spirit", {
walk_velocity = 2, walk_velocity = 2,
run_velocity = 3, run_velocity = 3,
jump = true, jump = true,
drops = { jump_height = 6,
{name = "fireflies:firefly", chance = 2, min = 1, max = 1} drops = mob_drops,
},
water_damage = 1, water_damage = 1,
lava_damage = 0, lava_damage = 0,
fire_damage = 0, fire_damage = 0,
@ -56,7 +67,7 @@ mobs:register_mob("mobs_monster:fire_spirit", {
self.flame_timer = (self.flame_timer or 0) + dtime self.flame_timer = (self.flame_timer or 0) + dtime
if self.flame_timer < 0.5 then if self.flame_timer < 0.25 then
return return
end end
@ -65,24 +76,23 @@ mobs:register_mob("mobs_monster:fire_spirit", {
local pos = self.object:get_pos() local pos = self.object:get_pos()
-- pos, amount, texture, min_size, max_size, radius, gravity, glow, fall -- pos, amount, texture, min_size, max_size, radius, gravity, glow, fall
mobs:effect(pos, 5, "fire_basic_flame.png", 1, 2, 0.5, 0.5, 14, nil) mobs:effect(pos, 5, "fire_basic_flame.png", 1, 2, 0.1, 0.2, 14, nil)
end end
}) })
--[[
if not mobs.custom_spawn_monster then if not mobs.custom_spawn_monster then
mobs:spawn({ mobs:spawn({
name = "mobs_monster:dirt_monster", name = "mobs_monster:fire_spirit",
nodes = {"default:dirt_with_grass", "ethereal:gray_dirt", "ethereal:dry_dirt"}, nodes = {"default:obsidian", "caverealms:hot_cobble"},
min_light = 0, neighbors = {"group:fire"},
max_light = 7, min_light = 12,
chance = 6000, max_light = 15,
active_object_count = 2, chance = 1500,
min_height = 0, active_object_count = 1,
day_toggle = false, max_height = -150
}) })
end end
]]
mobs:register_egg("mobs_monster:fire_spirit", S("Fire Spirit"), "fire_basic_flame.png", 1) mobs:register_egg("mobs_monster:fire_spirit", S("Fire Spirit"), "fire_basic_flame.png", 1)

View File

@ -41,4 +41,8 @@ Land Guard
- These huge monsters roam the land in cold, hot and temperate areas and don't like players wandering around their domain. - These huge monsters roam the land in cold, hot and temperate areas and don't like players wandering around their domain.
Fire Spirit
- Fire Spirits will not tolerate players roaming around their domain and will fiercely attack until their dying puff of smoke. Will drop it's spirit and some fire dust when using ethereal.
Lucky Blocks: 11 Lucky Blocks: 11

View File

@ -8,7 +8,7 @@ local use_cmi = minetest.global_exists("cmi")
mobs = { mobs = {
mod = "redo", mod = "redo",
version = "20210601", version = "20210610",
intllib = S, intllib = S,
invis = minetest.global_exists("invisibility") and invisibility or {} invis = minetest.global_exists("invisibility") and invisibility or {}
} }
@ -3553,6 +3553,13 @@ function mobs:register_mob(name, def)
mobs.spawning_mobs[name] = {} mobs.spawning_mobs[name] = {}
local collisionbox = def.collisionbox or {-0.25, -0.25, -0.25, 0.25, 0.25, 0.25}
-- quick fix to stop mobs glitching through nodes if too small
if -collisionbox[2] + collisionbox[5] < 1.01 then
collisionbox[5] = collisionbox[2] + 0.99
end
minetest.register_entity(name, setmetatable({ minetest.register_entity(name, setmetatable({
stepheight = def.stepheight, stepheight = def.stepheight,
@ -3574,8 +3581,8 @@ minetest.register_entity(name, setmetatable({
lifetimer = def.lifetimer, lifetimer = def.lifetimer,
hp_min = max(1, (def.hp_min or 5) * difficulty), hp_min = max(1, (def.hp_min or 5) * difficulty),
hp_max = max(1, (def.hp_max or 10) * difficulty), hp_max = max(1, (def.hp_max or 10) * difficulty),
collisionbox = def.collisionbox, collisionbox = collisionbox, --def.collisionbox,
selectionbox = def.selectionbox or def.collisionbox, selectionbox = def.selectionbox or collisionbox, --def.collisionbox,
visual = def.visual, visual = def.visual,
visual_size = def.visual_size, visual_size = def.visual_size,
mesh = def.mesh, mesh = def.mesh,

View File

@ -22,6 +22,7 @@ end
local function node_is(pos) local function node_is(pos)
local node = node_ok(pos) local node = node_ok(pos)
if node.name == "air" then if node.name == "air" then
@ -69,6 +70,7 @@ end
local function force_detach(player) local function force_detach(player)
local attached_to = player:get_attach() local attached_to = player:get_attach()
if not attached_to then if not attached_to then
@ -97,7 +99,9 @@ minetest.register_on_leaveplayer(function(player)
end) end)
minetest.register_on_shutdown(function() minetest.register_on_shutdown(function()
local players = minetest.get_connected_players() local players = minetest.get_connected_players()
for i = 1, #players do for i = 1, #players do
force_detach(players[i]) force_detach(players[i])
end end
@ -112,6 +116,7 @@ end)
-- Just for correct detaching -- Just for correct detaching
local function find_free_pos(pos) local function find_free_pos(pos)
local check = { local check = {
{x = 1, y = 0, z = 0}, {x = 1, y = 0, z = 0},
{x = 1, y = 1, z = 0}, {x = 1, y = 1, z = 0},
@ -124,10 +129,14 @@ local function find_free_pos(pos)
} }
for _, c in pairs(check) do for _, c in pairs(check) do
local npos = {x = pos.x + c.x, y = pos.y + c.y, z = pos.z + c.z} local npos = {x = pos.x + c.x, y = pos.y + c.y, z = pos.z + c.z}
local node = minetest.get_node_or_nil(npos) local node = minetest.get_node_or_nil(npos)
if node and node.name then if node and node.name then
local def = minetest.registered_nodes[node.name] local def = minetest.registered_nodes[node.name]
if def and not def.walkable and if def and not def.walkable and
def.liquidtype == "none" then def.liquidtype == "none" then
return npos return npos
@ -141,6 +150,7 @@ end
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
function mobs.attach(entity, player) function mobs.attach(entity, player)
entity.player_rotation = entity.player_rotation or {x = 0, y = 0, z = 0} entity.player_rotation = entity.player_rotation or {x = 0, y = 0, z = 0}
entity.driver_attach_at = entity.driver_attach_at or {x = 0, y = 0, z = 0} entity.driver_attach_at = entity.driver_attach_at or {x = 0, y = 0, z = 0}
entity.driver_eye_offset = entity.driver_eye_offset or {x = 0, y = 0, z = 0} entity.driver_eye_offset = entity.driver_eye_offset or {x = 0, y = 0, z = 0}
@ -154,6 +164,7 @@ function mobs.attach(entity, player)
local attach_at = entity.driver_attach_at local attach_at = entity.driver_attach_at
local eye_offset = entity.driver_eye_offset local eye_offset = entity.driver_eye_offset
entity.driver = player entity.driver = player
force_detach(player) force_detach(player)
@ -170,6 +181,7 @@ function mobs.attach(entity, player)
}) })
minetest.after(0.2, function() minetest.after(0.2, function()
if player and player:is_player() then if player and player:is_player() then
player_api.set_animation(player, "sit", 30) player_api.set_animation(player, "sit", 30)
end end
@ -183,9 +195,13 @@ function mobs.detach(player)
force_detach(player) force_detach(player)
minetest.after(0.1, function() minetest.after(0.1, function()
if player and player:is_player() then if player and player:is_player() then
local pos = find_free_pos(player:get_pos()) local pos = find_free_pos(player:get_pos())
pos.y = pos.y + 0.5 pos.y = pos.y + 0.5
player:set_pos(pos) player:set_pos(pos)
end end
end) end)
@ -193,8 +209,8 @@ end
function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime) function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
local yaw = entity.object:get_yaw() or 0
local yaw = entity.object:get_yaw() or 0
local rot_view = 0 local rot_view = 0
if entity.player_rotation.y == 90 then if entity.player_rotation.y == 90 then
@ -208,14 +224,17 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
-- process controls -- process controls
if entity.driver then if entity.driver then
local ctrl = entity.driver:get_player_control() local ctrl = entity.driver:get_player_control()
-- move forwards -- move forwards
if ctrl.up then if ctrl.up then
entity.v = entity.v + entity.accel / 10 entity.v = entity.v + entity.accel / 10
-- move backwards -- move backwards
elseif ctrl.down then elseif ctrl.down then
if entity.max_speed_reverse == 0 and entity.v == 0 then if entity.max_speed_reverse == 0 and entity.v == 0 then
return return
end end
@ -225,7 +244,9 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
-- mob rotation -- mob rotation
local horz local horz
if entity.alt_turn == true then if entity.alt_turn == true then
horz = yaw horz = yaw
if ctrl.left then if ctrl.left then
@ -243,21 +264,29 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
if can_fly then if can_fly then
-- fly up -- fly up
if ctrl.jump then if ctrl.jump then
velo.y = velo.y + 1 velo.y = velo.y + 1
if velo.y > entity.accel then velo.y = entity.accel end if velo.y > entity.accel then velo.y = entity.accel end
elseif velo.y > 0 then elseif velo.y > 0 then
velo.y = velo.y - 0.1 velo.y = velo.y - 0.1
if velo.y < 0 then velo.y = 0 end if velo.y < 0 then velo.y = 0 end
end end
-- fly down -- fly down
if ctrl.sneak then if ctrl.sneak then
velo.y = velo.y - 1 velo.y = velo.y - 1
if velo.y < -entity.accel then velo.y = -entity.accel end if velo.y < -entity.accel then velo.y = -entity.accel end
elseif velo.y < 0 then elseif velo.y < 0 then
velo.y = velo.y + 0.1 velo.y = velo.y + 0.1
if velo.y > 0 then velo.y = 0 end if velo.y > 0 then velo.y = 0 end
end end
else else
@ -274,6 +303,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
-- if not moving then set animation and return -- if not moving then set animation and return
if entity.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then if entity.v == 0 and velo.x == 0 and velo.y == 0 and velo.z == 0 then
if stand_anim then if stand_anim then
mobs:set_animation(entity, stand_anim) mobs:set_animation(entity, stand_anim)
end end
@ -292,8 +322,10 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
entity.v = entity.v - 0.02 * s entity.v = entity.v - 0.02 * s
if s ~= get_sign(entity.v) then if s ~= get_sign(entity.v) then
entity.object:set_velocity({x = 0, y = 0, z = 0}) entity.object:set_velocity({x = 0, y = 0, z = 0})
entity.v = 0 entity.v = 0
return return
end end
@ -310,6 +342,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
-- Set position, velocity and acceleration -- Set position, velocity and acceleration
local p = entity.object:get_pos() local p = entity.object:get_pos()
if not p then return end if not p then return end
local new_acce = {x = 0, y = -9.81, z = 0} local new_acce = {x = 0, y = -9.81, z = 0}
@ -320,18 +353,23 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
local v = entity.v local v = entity.v
if ni == "air" then if ni == "air" then
if can_fly == true then if can_fly == true then
new_acce.y = 0 new_acce.y = 0
end end
elseif ni == "liquid" or ni == "lava" then elseif ni == "liquid" or ni == "lava" then
if ni == "lava" and entity.lava_damage ~= 0 then if ni == "lava" and entity.lava_damage ~= 0 then
entity.lava_counter = (entity.lava_counter or 0) + dtime entity.lava_counter = (entity.lava_counter or 0) + dtime
if entity.lava_counter > 1 then if entity.lava_counter > 1 then
minetest.sound_play("default_punch", { minetest.sound_play("default_punch", {
object = entity.object, object = entity.object,
max_hear_distance = 5 max_hear_distance = 5
}) }, true)
entity.object:punch(entity.object, 1.0, { entity.object:punch(entity.object, 1.0, {
full_punch_interval = 1.0, full_punch_interval = 1.0,
@ -343,11 +381,14 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
end end
local terrain_type = entity.terrain_type local terrain_type = entity.terrain_type
if terrain_type == 2 or terrain_type == 3 then if terrain_type == 2 or terrain_type == 3 then
new_acce.y = 0 new_acce.y = 0
p.y = p.y + 1 p.y = p.y + 1
if node_is(p) == "liquid" then if node_is(p) == "liquid" then
if velo.y >= 5 then if velo.y >= 5 then
velo.y = 5 velo.y = 5
elseif velo.y < 0 then elseif velo.y < 0 then
@ -357,7 +398,9 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
end end
else else
if abs(velo.y) < 1 then if abs(velo.y) < 1 then
local pos = entity.object:get_pos() local pos = entity.object:get_pos()
if not pos then return end if not pos then return end
pos.y = floor(pos.y) + 0.5 pos.y = floor(pos.y) + 0.5
@ -371,6 +414,7 @@ function mobs.drive(entity, moving_anim, stand_anim, can_fly, dtime)
end end
local new_velo = get_velocity(v, yaw - rot_view, velo.y) local new_velo = get_velocity(v, yaw - rot_view, velo.y)
new_acce.y = new_acce.y + acce_y new_acce.y = new_acce.y + acce_y
entity.object:set_velocity(new_velo) entity.object:set_velocity(new_velo)
@ -382,6 +426,7 @@ end
-- directional flying routine by D00Med (edited by TenPlus1) -- directional flying routine by D00Med (edited by TenPlus1)
function mobs.fly(entity, _, speed, shoots, arrow, moving_anim, stand_anim) function mobs.fly(entity, _, speed, shoots, arrow, moving_anim, stand_anim)
local ctrl = entity.driver:get_player_control() local ctrl = entity.driver:get_player_control()
local velo = entity.object:get_velocity() local velo = entity.object:get_velocity()
local dir = entity.driver:get_look_dir() local dir = entity.driver:get_look_dir()
@ -397,6 +442,7 @@ if not ctrl or not velo then return end
}) })
elseif ctrl.down then elseif ctrl.down then
entity.object:set_velocity({ entity.object:set_velocity({
x = -dir.x * speed, x = -dir.x * speed,
y = dir.y * speed + 2, y = dir.y * speed + 2,
@ -411,6 +457,7 @@ if not ctrl or not velo then return end
-- firing arrows -- firing arrows
if ctrl.LMB and ctrl.sneak and shoots then if ctrl.LMB and ctrl.sneak and shoots then
local pos = entity.object:get_pos() local pos = entity.object:get_pos()
local obj = minetest.add_entity({ local obj = minetest.add_entity({
x = pos.x + 0 + dir.x * 2.5, x = pos.x + 0 + dir.x * 2.5,
@ -418,11 +465,15 @@ if not ctrl or not velo then return end
z = pos.z + 0 + dir.z * 2.5}, arrow) z = pos.z + 0 + dir.z * 2.5}, arrow)
local ent = obj:get_luaentity() local ent = obj:get_luaentity()
if ent then if ent then
ent.switch = 1 -- for mob specific arrows ent.switch = 1 -- for mob specific arrows
ent.owner_id = tostring(entity.object) -- so arrows dont hurt entity you are riding ent.owner_id = tostring(entity.object) -- so arrows dont hurt entity you are riding
local vec = {x = dir.x * 6, y = dir.y * 6, z = dir.z * 6} local vec = {x = dir.x * 6, y = dir.y * 6, z = dir.z * 6}
yaw = entity.driver:get_look_horizontal() yaw = entity.driver:get_look_horizontal()
obj:set_yaw(yaw + pi / 2) obj:set_yaw(yaw + pi / 2)
obj:set_velocity(vec) obj:set_velocity(vec)
else else

View File

@ -12,65 +12,65 @@ minetest.register_node("cavestuff:pebble_1",{
description = S("Pebble"), description = S("Pebble"),
drawtype = "mesh", drawtype = "mesh",
mesh = "cavestuff_pebble.obj", mesh = "cavestuff_pebble.obj",
tiles = {"undergrowth_pebble.png"}, tiles = {"undergrowth_pebble.png"},
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {cracky=3, stone=1}, groups = {cracky=3, stone=1},
selection_box = cbox, selection_box = cbox,
collision_box = cbox, collision_box = cbox,
on_place = function(itemstack, placer, pointed_thing) on_place = function(itemstack, placer, pointed_thing)
-- place a random pebble node -- place a random pebble node
local stack = ItemStack("cavestuff:pebble_"..math.random(1,2)) local stack = ItemStack("cavestuff:pebble_"..math.random(1,2))
local ret = minetest.item_place(stack, placer, pointed_thing) local ret = minetest.item_place(stack, placer, pointed_thing)
return ItemStack("cavestuff:pebble_1 "..itemstack:get_count()-(1-ret:get_count())) return ItemStack("cavestuff:pebble_1 "..itemstack:get_count()-(1-ret:get_count()))
end, end,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
}) })
minetest.register_node("cavestuff:pebble_2",{ minetest.register_node("cavestuff:pebble_2",{
drawtype = "mesh", drawtype = "mesh",
mesh = "cavestuff_pebble.obj", mesh = "cavestuff_pebble.obj",
tiles = {"undergrowth_pebble.png"}, tiles = {"undergrowth_pebble.png"},
drop = "cavestuff:pebble_1", drop = "cavestuff:pebble_1",
tiles = {"undergrowth_pebble.png"}, tiles = {"undergrowth_pebble.png"},
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {cracky=3, stone=1, not_in_creative_inventory=1}, groups = {cracky=3, stone=1, not_in_creative_inventory=1},
selection_box = cbox, selection_box = cbox,
collision_box = cbox, collision_box = cbox,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
}) })
minetest.register_node("cavestuff:desert_pebble_1",{ minetest.register_node("cavestuff:desert_pebble_1",{
description = S("Desert Pebble"), description = S("Desert Pebble"),
drawtype = "mesh", drawtype = "mesh",
mesh = "cavestuff_pebble.obj", mesh = "cavestuff_pebble.obj",
tiles = {"default_desert_stone.png"}, tiles = {"default_desert_stone.png"},
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {cracky=3, stone=1}, groups = {cracky=3, stone=1},
selection_box = cbox, selection_box = cbox,
collision_box = cbox, collision_box = cbox,
on_place = function(itemstack, placer, pointed_thing) on_place = function(itemstack, placer, pointed_thing)
-- place a random pebble node -- place a random pebble node
local stack = ItemStack("cavestuff:desert_pebble_"..math.random(1,2)) local stack = ItemStack("cavestuff:desert_pebble_"..math.random(1,2))
local ret = minetest.item_place(stack, placer, pointed_thing) local ret = minetest.item_place(stack, placer, pointed_thing)
return ItemStack("cavestuff:desert_pebble_1 "..itemstack:get_count()-(1-ret:get_count())) return ItemStack("cavestuff:desert_pebble_1 "..itemstack:get_count()-(1-ret:get_count()))
end, end,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
}) })
minetest.register_node("cavestuff:desert_pebble_2",{ minetest.register_node("cavestuff:desert_pebble_2",{
drawtype = "mesh", drawtype = "mesh",
mesh = "cavestuff_pebble.obj", mesh = "cavestuff_pebble.obj",
drop = "cavestuff:desert_pebble_1", drop = "cavestuff:desert_pebble_1",
tiles = {"default_desert_stone.png"}, tiles = {"default_desert_stone.png"},
paramtype = "light", paramtype = "light",
paramtype2 = "facedir", paramtype2 = "facedir",
groups = {cracky=3, stone=1, not_in_creative_inventory=1}, groups = {cracky=3, stone=1, not_in_creative_inventory=1},
selection_box = cbox, selection_box = cbox,
collision_box = cbox, collision_box = cbox,
sounds = default.node_sound_stone_defaults(), sounds = default.node_sound_stone_defaults(),
}) })
--Staclactites --Staclactites
@ -85,19 +85,34 @@ minetest.register_node("cavestuff:stalactite_1",{
node_box = { node_box = {
type = "fixed", type = "fixed",
fixed = { fixed = {
{-0.187500,0.425000,-0.150003,0.162500,0.500000,0.162500}, {-0.187500,-0.425000,-0.150003,0.162500,-0.500000,0.162500},
{-0.112500,0.162500,-0.100000,0.087500,0.475000,0.087500}, {-0.112500,-0.162500,-0.100000,0.087500,-0.475000,0.087500},
{-0.062500,-0.275000,-0.062500,0.062500,0.500000,0.062500}, {-0.062500,0.275000,-0.062500,0.062500,-0.500000,0.062500},
{-0.037500,-0.837500,0.037500,0.037500,0.500000,-0.025000}, {-0.037500,0.837500,0.037500,0.037500,-0.500000,-0.025000},
} }
}, },
on_place = function(itemstack, placer, pointed_thing) on_place = function(itemstack, placer, pointed_thing)
local pt = pointed_thing local dir = vector.subtract(pointed_thing.above, pointed_thing.under)
if minetest.get_node(pt.under).name=="default:stone" local base = pointed_thing.under
and minetest.get_node({x=pt.under.x, y=pt.under.y-1, z=pt.under.z}).name=="air" local place = vector.add(base, dir)
and minetest.get_node({x=pt.under.x, y=pt.under.y-2, z=pt.under.z}).name=="air" then local above = vector.add(place, dir)
minetest.swap_node({x=pt.under.x, y=pt.under.y-1, z=pt.under.z}, {name="cavestuff:stalactite_"..math.random(1,3)})
if not placer then return end
local playername = placer:get_player_name()
if minetest.is_protected(place, playername)
or minetest.is_protected(above, playername) then
minetest.record_protection_violation(place, playername)
return
end
if minetest.get_node(base).name == "default:stone"
and minetest.get_node(place).name == "air"
and minetest.get_node(above).name == "air"
then
minetest.swap_node(place, {
name = "cavestuff:stalactite_"..math.random(1,3),
param2 = minetest.dir_to_wallmounted(vector.multiply(dir, -1))
})
if not minetest.setting_getbool("creative_mode") then if not minetest.setting_getbool("creative_mode") then
itemstack:take_item() itemstack:take_item()
end end
@ -116,10 +131,10 @@ minetest.register_node("cavestuff:stalactite_2",{
node_box = { node_box = {
type = "fixed", type = "fixed",
fixed = { fixed = {
{-0.187500,0.387500,-0.150003,0.162500,0.500000,0.162500}, {-0.187500,-0.387500,-0.150003,0.162500,-0.500000,0.162500},
{-0.112500,0.112500,-0.100000,0.087500,0.475000,0.087500}, {-0.112500,-0.112500,-0.100000,0.087500,-0.475000,0.087500},
{-0.062500,-0.675000,-0.062500,0.062500,0.500000,0.062500}, {-0.062500,0.675000,-0.062500,0.062500,-0.500000,0.062500},
{-0.037500,-0.975000,0.037500,0.037500,0.500000,-0.025000}, {-0.037500,0.975000,0.037500,0.037500,-0.500000,-0.025000},
} }
}, },
}) })
@ -132,14 +147,14 @@ minetest.register_node("cavestuff:stalactite_3",{
paramtype = "light", paramtype = "light",
paramtype2 = "wallmounted", paramtype2 = "wallmounted",
node_box = { node_box = {
type = "fixed", type = "fixed",
fixed = { fixed = {
{-0.187500,0.387500,-0.150003,0.162500,0.500000,0.162500}, {-0.187500,-0.387500,-0.150003,0.162500,-0.500000,0.162500},
{-0.112500,0.037500,-0.100000,0.087500,0.475000,0.087500}, {-0.112500,-0.037500,-0.100000,0.087500,-0.475000,0.087500},
{-0.062500,-0.437500,-0.062500,0.062500,0.500000,0.062500}, {-0.062500,0.437500,-0.062500,0.062500,-0.500000,0.062500},
{-0.037500,-1.237500,0.037500,0.037500,0.500000,-0.025000}, {-0.037500,1.237500,0.037500,0.037500,-0.500000,-0.025000},
} }
}, },
}) })
--Stalagmites --Stalagmites

View File

@ -22,7 +22,7 @@ That said, there are some basic text formatting options:
Writing "^" followed by a letter "a" through "h" will produce double-wide versions of these arrows, in the same order. These wide arrows occupy 0x89 to 0x91 in the character set. Writing "^" followed by a letter "a" through "h" will produce double-wide versions of these arrows, in the same order. These wide arrows occupy 0x89 to 0x91 in the character set.
* A color may be specified in the sign text by using "#" followed by a single hexadcimal digit (0-9 or a-f). These colors come from the standard Linux/IRC/CGA color set, and are shown in the sign's formspec. Any color change will remain in effect until changed again, or until the next line break. Any number of color changes in any arbitrary arrangement is allowed. * A color may be specified in the sign text by using "#" followed by a single hexadcimal digit (0-9 or a-f). These colors come from the standard Linux/IRC/CGA color set, and are shown in the sign's formspec. Any color change will remain in effect until changed again, or until the next line break. Any number of color changes in any arbitrary arrangement is allowed. To write "#" on a sign, write "##".
* Most writable signs can display double-wide text by flipping a switch in the sign's formspec. * Most writable signs can display double-wide text by flipping a switch in the sign's formspec.

View File

@ -555,8 +555,9 @@ local function make_line_texture(line, lineno, pos, line_width, line_height, cwi
end end
end end
local c = word:sub(i, i) local c = word:sub(i, i)
if c == "#" then local c2 = word:sub(i+1, i+1)
local cc = tonumber(word:sub(i+1, i+1), 16) if c == "#" and c2 ~= "#" then
local cc = tonumber(c2, 16)
if cc then if cc then
i = i + 1 i = i + 1
cur_color = cc cur_color = cc

View File

@ -0,0 +1,3 @@
Plagegeist
Phill
CC BY-SA 3.0

View File

@ -0,0 +1,3 @@
FBI Agent
Phill
CC BY-SA 3.0

View File

@ -0,0 +1,3 @@
Cyber bot
Phill
CC BY-SA 3.0

View File

@ -0,0 +1,3 @@
The dead
Phill
CC BY-SA 3.0

View File

@ -0,0 +1,3 @@
ICE Knight
Phill
CC BY-SA 3.0

View File

@ -0,0 +1,3 @@
Nothing
Phill
CC BY-SA 3.0

View File

@ -0,0 +1,3 @@
Endermann
Phill
CC BY-SA 3.0

View File

@ -0,0 +1,3 @@
Sandzombie
Phill
CC BY-SA 3.0

View File

@ -0,0 +1,3 @@
Nebel man
Phill
CC BY-SA 3.0

View File

@ -0,0 +1,3 @@
Cyber Huhn
Phill
CC BY-SA 3.0

View File

@ -0,0 +1,3 @@
Green glas
Phill
CC BY-SA 3.0

View File

@ -0,0 +1,3 @@
X Kost&uuml;m
Phill
CC BY-SA 3.0

View File

@ -0,0 +1,3 @@
Neon Knight
Phill
CC BY-SA 3.0

View File

@ -0,0 +1,3 @@
Elf Woman
Phill
CC BY-SA 3.0

View File

@ -0,0 +1,3 @@
pacman
Phill
CC BY-SA 3.0

View File

@ -0,0 +1,3 @@
killer woman
Phill
CC BY-SA 3.0

View File

@ -0,0 +1,3 @@
gohst
Phill
CC BY-SA 3.0

View File

@ -0,0 +1,3 @@
rainbow man
Phill
CC BY-SA 3.0

View File

@ -0,0 +1,3 @@
Green Gohst
Phill
CC BY-SA 3.0

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 475 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 303 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 875 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 991 B

View File

@ -1,5 +1,5 @@
stamina = {players = {}} stamina = {players = {}, mod = "redo"}
STAMINA_TICK = tonumber(minetest.settings:get("stamina_tick")) or 800 STAMINA_TICK = tonumber(minetest.settings:get("stamina_tick")) or 800
-- time in seconds after that 1 stamina point is taken -- time in seconds after that 1 stamina point is taken
@ -681,3 +681,43 @@ end
minetest.register_on_leaveplayer(function(player) minetest.register_on_leaveplayer(function(player)
stamina.players[player:get_player_name()] = nil stamina.players[player:get_player_name()] = nil
end) end)
--lucky blocks (if damage and stamina active)
if minetest.get_modpath("lucky_block")
and minetest.settings:get_bool("enable_damage")
and minetest.settings:get_bool("enable_stamina") ~= false then
local effect_me = function(pos, player, def)
local green = minetest.get_color_escape_sequence("#bada55")
local name = player:get_player_name()
if def.poison or def.drunk then
player:hud_change(stamina.players[name].hud_id,
"text", "stamina_hud_poison.png")
end
if def.poison and def.poison > 0 then
stamina.players[name].poisoned = def.poison
minetest.chat_send_player(name,
green .. "Seems you have been poisoned!")
elseif def.drunk and def.drunk > 0 then
stamina.players[name].drunk = def.drunk
minetest.chat_send_player(name,
green .. "You seem a little tipsy!")
end
end
lucky_block:add_blocks({
{"cus", effect_me, {poison = 5} },
{"cus", effect_me, {poison = 10} },
{"cus", effect_me, {drunk = 30} },
})
end

View File

@ -1,4 +1,4 @@
name = stamina name = stamina
depends = default depends = default
optional_depends = 3d_armor, player_monoids, pova optional_depends = 3d_armor, player_monoids, pova, lucky_block
description = Adds stamina, hunger and drunk effects. description = Adds stamina, hunger and drunk effects.

View File

@ -1,4 +1,4 @@
# TechPack V2.05 # TechPack V2.06
TechPack, a Mining, Crafting, &amp; Farming Modpack for Minetest. TechPack, a Mining, Crafting, &amp; Farming Modpack for Minetest.
@ -27,6 +27,7 @@ TechPack is a collection of following Mods:
**The moved/copied nodes will not have valid node numbers, which could lead to a server crash.** **The moved/copied nodes will not have valid node numbers, which could lead to a server crash.**
TechPack provides: TechPack provides:
- lumber tubes to connect 2 nodes - lumber tubes to connect 2 nodes
- a Pusher node to pull/push items through tubes - a Pusher node to pull/push items through tubes
- a Distributor node with 4 output channels to sort incoming items - a Distributor node with 4 output channels to sort incoming items
@ -64,9 +65,11 @@ TechPack provides:
- a Display node for text outputs of the Controller - a Display node for text outputs of the Controller
- Metal ladders, stairways, and bridges - Metal ladders, stairways, and bridges
- Warehouse Boxes in steel, copper, and gold - Warehouse Boxes in steel, copper, and gold
- A chest cart for the mod minecart
TechPack supports the following mods: TechPack supports the following mods:
- Farming Redo (Harvester, Fermenter) - Farming Redo (Harvester, Fermenter)
- Ethereal (Harvester, Quarry, Fermenter) - Ethereal (Harvester, Quarry, Fermenter)
- Pipeworks (Gravel Sieve) - Pipeworks (Gravel Sieve)
@ -75,12 +78,14 @@ TechPack supports the following mods:
### Configuration ### Configuration
The following can be changed in the minetest menu (Settings -> Advanced Settings -> Mods -> tubelib) or directly in 'minetest.conf' The following can be changed in the minetest menu (Settings -> Advanced Settings -> Mods -> tubelib) or directly in 'minetest.conf'
- Maximum number of Forceload Blocks per player - Maximum number of Forceload Blocks per player
- Enable Basalt Stone (and disable ore generation via Cobblestone generator) - Enable Basalt Stone (and disable ore generation via Cobblestone generator)
- Machine aging value to calculate the lifetime of machines - Machine aging value to calculate the lifetime of machines
Example for 'minetest.conf': Example for 'minetest.conf':
```LUA ```LUA
tubelib_basalt_stone_enabled = false tubelib_basalt_stone_enabled = false
tubelib_max_num_forceload_blocks = 12 tubelib_max_num_forceload_blocks = 12
@ -88,6 +93,7 @@ tubelib_machine_aging_value = 200
``` ```
Example for a v1 compatible 'minetest.conf': Example for a v1 compatible 'minetest.conf':
```LUA ```LUA
tubelib_basalt_stone_enabled = false tubelib_basalt_stone_enabled = false
tubelib_max_num_forceload_blocks = 0 tubelib_max_num_forceload_blocks = 0
@ -96,24 +102,30 @@ tubelib_machine_aging_value = 999999
#### Maximum number of Forceload Blocks per player #### Maximum number of Forceload Blocks per player
Default value is 12.
Default value is 12.
I higher number allows to build larger farms and machines which keep loaded, but increases the server load, too. I higher number allows to build larger farms and machines which keep loaded, but increases the server load, too.
But the areas are only loaded when the player is online. But the areas are only loaded when the player is online.
To be able to use e.g. 12 forceloaded blocks per player, the pararamter 'max_forceloaded_blocks' in 'minetest.conf' has to be ajusted. To be able to use e.g. 12 forceloaded blocks per player, the pararamter 'max_forceloaded_blocks' in 'minetest.conf' has to be ajusted.
#### Enable Basalt Stone (and disable ore generation via Cobblestone generator) #### Enable Basalt Stone (and disable ore generation via Cobblestone generator)
The lava/water Cobblestone generator allows to produce infinite Cobblestone. By means of Quarry,
The lava/water Cobblestone generator allows to produce infinite Cobblestone. By means of Quarry,
Grinder, and Gravel Sieve it allows to infinite generate ores. Grinder, and Gravel Sieve it allows to infinite generate ores.
This can be disabled by means of the setting parameter. If enabled, the Cobblestone This can be disabled by means of the setting parameter. If enabled, the Cobblestone
generator generates Basalt instead, which only can be used for building purposes. generator generates Basalt instead, which only can be used for building purposes.
#### Machine aging value to calculate the lifetime of machines #### Machine aging value to calculate the lifetime of machines
Default value is 200.
Default value is 200.
This aging value is used to calculate the lifetime of machines before they go defect. This aging value is used to calculate the lifetime of machines before they go defect.
The value 200 (default) results in a lifetime for standard machines of about 2000 - 8000 item processing cycles (~2-4 hours). The value 200 (default) results in a lifetime for standard machines of about 2000 - 8000 item processing cycles (~2-4 hours).
### License ### License
Copyright (C) 2017-2021 Joachim Stolberg Copyright (C) 2017-2021 Joachim Stolberg
Code: Licensed under the GNU AGPL version 3 or later. See LICENSE.txt Code: Licensed under the GNU AGPL version 3 or later. See LICENSE.txt
Textures: CC BY-SA 3.0 Textures: CC BY-SA 3.0
@ -121,26 +133,33 @@ Textures: CC BY-SA 3.0
## Credits ## Credits
### Contributors ### Contributors
- oversword (PR #43, #57, #58, #59, #60, #62, #68, #74, #76) - oversword (PR #43, #57, #58, #59, #60, #62, #68, #74, #76, and many more)
- afkplayer5000 (PR #70, #71) - afkplayer5000 (PR #70, #71)
- andrenete (PR #37, #66) - andrenete (PR #37, #66)
- fluxionary (PR #27, #28, #30, #31, #34, #54) - fluxionary (PR #27, #28, #30, #31, #34, #54)
- Arigatas (PR #51, #53) - Arigatas (PR #51, #53)
- realmicu (PR #6, #8, #12) - realmicu (PR #6, #8, #12)
- theFox6 (PR #3, #4) - theFox6 (PR #3, #4)
- superfloh247 (PR #89, #88, #87)
- SciFurz (via forum)
### Dependencies ### Dependencies
default, doors, intllib, basic_materials
default, doors, intllib, basic_materials
tubelib2 (![GitHub](https://github.com/joe7575/tubelib2)) tubelib2 (![GitHub](https://github.com/joe7575/tubelib2))
Tubelib Color Lamps optional: unifieddyes Tubelib Color Lamps optional: unifieddyes
SmartLine Controller optional: mail SmartLine Controller optional: mail
Gravelsieve optional: moreores, hopper, pipeworks Gravelsieve optional: moreores, hopper, pipeworks
tubelib_addons1 optional: unified_inventory tubelib_addons1 optional: unified_inventory
tubelib_addons13 optional: minecart
### History ### History
- 2018-03-18 V1.00 * Tubelib, tubelib_addons1, tubelib_addons2, smartline, and gravelsieve combined to one modpack. - 2018-03-18 V1.00 * Tubelib, tubelib_addons1, tubelib_addons2, smartline, and gravelsieve combined to one modpack.
- 2018-03-24 V1.01 * Support for Ethereal added - 2018-03-24 V1.01 * Support for Ethereal added
- 2018-03-27 V1.02 * Timer improvements for unloaded areas - 2018-03-27 V1.02 * Timer improvements for unloaded areas
@ -166,8 +185,11 @@ tubelib_addons1 optional: unified_inventory
- 2019-04-23 V2.03 * Piston/WorldEdit/replacer detection added, farming and grinder recipes added - 2019-04-23 V2.03 * Piston/WorldEdit/replacer detection added, farming and grinder recipes added
- 2020-11-20 V2.04 * Switch to AGPL v3, adapt to minetest 5.3, add translation support, fix minor bugs - 2020-11-20 V2.04 * Switch to AGPL v3, adapt to minetest 5.3, add translation support, fix minor bugs
- 2021-01-24 V2.05 * PR #74, #76: Implement checks for valid connection sides for many nodes - 2021-01-24 V2.05 * PR #74, #76: Implement checks for valid connection sides for many nodes
- 2021-06-06 V2.06 * PR #78 - #89, chest cart added
## New in v2 (from players point of view) ## New in v2 (from players point of view)
- Almost all machines break after a certain amount of time (switch into the state 'defect') and have to be repaired. - Almost all machines break after a certain amount of time (switch into the state 'defect') and have to be repaired.
- A Repair Kit is available to repair defect machines. - A Repair Kit is available to repair defect machines.
- A Forceload block (16x16x16) is added which keeps the corresponding area loaded and the machines operational as far as the player is logged in. - A Forceload block (16x16x16) is added which keeps the corresponding area loaded and the machines operational as far as the player is logged in.
@ -178,6 +200,7 @@ tubelib_addons1 optional: unified_inventory
## New in v2 (from admins point of view) ## New in v2 (from admins point of view)
- settingtypes introduced with the following settings: tubelib_max_num_forceload_blocks, tubelib_basalt_stone_enabled, tubelib_machine_aging_value - settingtypes introduced with the following settings: tubelib_max_num_forceload_blocks, tubelib_basalt_stone_enabled, tubelib_machine_aging_value
- the new mods 'techpack_stairway' and 'techpack_warehouse' have to be enabled - the new mods 'techpack_stairway' and 'techpack_warehouse' have to be enabled
- TechPack depends now on the mod 'basic_materials' and 'tubelib2' (![GitHub](https://github.com/joe7575/tubelib2)) - TechPack depends now on the mod 'basic_materials' and 'tubelib2' (![GitHub](https://github.com/joe7575/tubelib2))

View File

@ -1,6 +1,22 @@
# Release Notes for ModPack TechPack [techpack] # Release Notes for ModPack TechPack [techpack]
## V2.06.00 (2021-06-06)
### Additions
- Add chest cart for the mod minecart (optional)
- Add support for the mod "underch" (#88)
### Removals
### Changes
- Account for new red & yellow pepper varieties (#86)
- Pusher improvements (#84, #83)
### Fixes
- Fix crash with "ethereal:strawberry" (#89)
## V2.05.00 (2021-01-24) ## V2.05.00 (2021-01-24)
### Additions ### Additions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 305 B

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 301 B

After

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 488 B

After

Width:  |  Height:  |  Size: 419 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 499 B

After

Width:  |  Height:  |  Size: 444 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 480 B

After

Width:  |  Height:  |  Size: 414 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 479 B

After

Width:  |  Height:  |  Size: 408 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 819 B

After

Width:  |  Height:  |  Size: 751 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 655 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 456 B

After

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 381 B

After

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 477 B

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 402 B

After

Width:  |  Height:  |  Size: 359 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 361 B

After

Width:  |  Height:  |  Size: 311 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 348 B

After

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 444 B

After

Width:  |  Height:  |  Size: 359 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 649 B

After

Width:  |  Height:  |  Size: 545 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 878 B

View File

@ -57,6 +57,13 @@ tn("default:pine_tree", "default:pine_tree", "default:pine_sapling")
tn("default:acacia_tree", "default:acacia_tree", "default:acacia_sapling") tn("default:acacia_tree", "default:acacia_tree", "default:acacia_sapling")
tn("default:jungletree", "default:jungletree", "default:junglesapling") tn("default:jungletree", "default:jungletree", "default:junglesapling")
tn("default:bush_stem", "default:bush_stem", "default:bush_sapling")
tn("default:acacia_bush_stem", "default:acacia_bush_stem", "default:acacia_bush_sapling")
tn("default:pine_bush_stem", "default:pine_bush_stem", "default:pine_bush_sapling")
fn("default:pine_bush_needles")
tubelib_addons1.FarmingNodes["default:pine_bush_needles"].leaves = true -- accepted as leaves
fn("default:leaves") fn("default:leaves")
fn("default:aspen_leaves") fn("default:aspen_leaves")
fn("default:pine_needles") fn("default:pine_needles")
@ -118,7 +125,7 @@ end
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- Ethereal Farming -- Ethereal Farming
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
fn("ethereal:strawberry_8", "ethereal:strawberry 2", "ethereal:strawberry 1") fn("ethereal:strawberry_8", "ethereal:strawberry 2", "ethereal:strawberry_1")
fn("ethereal:onion_5", "ethereal:wild_onion_plant 2", "ethereal:onion_1") fn("ethereal:onion_5", "ethereal:wild_onion_plant 2", "ethereal:onion_1")

View File

@ -1,6 +1,7 @@
# textdomain: tubelib_addons2 # textdomain: tubelib_addons2
### accesscontrol.lua ### ### accesscontrol.lua ###
Access code (4 digits):= Access code (4 digits):=

View File

@ -0,0 +1,171 @@
--[[
Tubelib Addons 3
================
Copyright (C) 2017-2020 Joachim Stolberg
AGPL v3
See LICENSE.txt for more information
chest.lua
A high performance chest
]]--
-- Load support for I18n
local S = tubelib_addons3.S
local P2S = function(pos) if pos then return minetest.pos_to_string(pos) end end
local S2P = minetest.string_to_pos
local M = minetest.get_meta
local function on_rightclick(pos, node, clicker)
if clicker and clicker:is_player() then
if M(pos):get_int("userID") == 0 then
minecart.show_formspec(pos, clicker)
end
end
end
local function formspec()
return "size[8,6]"..
default.gui_bg..
default.gui_bg_img..
default.gui_slots..
"list[context;main;3,0;2,2;]"..
"list[current_player;main;0,2.3;8,4;]"..
"listring[context;main]"..
"listring[current_player;main]"
end
local function allow_metadata_inventory_put(pos, listname, index, stack, player)
local owner = M(pos):get_string("owner")
if owner ~= "" and owner ~= player:get_player_name() then
return 0
end
return stack:get_count()
end
local function allow_metadata_inventory_take(pos, listname, index, stack, player)
local owner = M(pos):get_string("owner")
if owner ~= "" and owner ~= player:get_player_name() then
return 0
end
return stack:get_count()
end
minetest.register_node("tubelib_addons3:chest_cart", {
description = S("TA Chest Cart"),
tiles = {
-- up, down, right, left, back, front
"tubelib_addons3_chest_cart_top.png",
"tubelib_addons3_chest_cart_bottom.png",
"tubelib_addons3_chest_cart_side.png",
"tubelib_addons3_chest_cart_side.png",
"tubelib_addons3_chest_cart_front.png",
"tubelib_addons3_chest_cart_front.png",
},
drawtype = "nodebox",
node_box = {
type = "fixed",
fixed = {
{-7/16, 3/16, -7/16, 7/16, 8/16, 7/16},
{-8/16, -8/16, -8/16, 8/16, 3/16, 8/16},
},
},
paramtype2 = "facedir",
paramtype = "light",
use_texture_alpha = true,
sunlight_propagates = true,
is_ground_content = false,
groups = {cracky = 2, crumbly = 2, choppy = 2},
node_placement_prediction = "",
diggable = false,
on_place = minecart.on_nodecart_place,
on_punch = minecart.on_nodecart_punch,
allow_metadata_inventory_put = allow_metadata_inventory_put,
allow_metadata_inventory_take = allow_metadata_inventory_take,
on_rightclick = on_rightclick,
after_place_node = function(pos, placer)
local inv = M(pos):get_inventory()
inv:set_size('main', 4)
if placer and placer:is_player() then
minecart.show_formspec(pos, placer)
else
M(pos):set_string("formspec", formspec())
end
end,
set_cargo = function(pos, data)
local inv = M(pos):get_inventory()
for idx, stack in ipairs(data) do
inv:set_stack("main", idx, stack)
end
end,
get_cargo = function(pos)
local inv = M(pos):get_inventory()
local data = {}
for idx = 1, 4 do
local stack = inv:get_stack("main", idx)
data[idx] = {name = stack:get_name(), count = stack:get_count()}
end
return data
end,
has_cargo = function(pos)
local inv = minetest.get_meta(pos):get_inventory()
return not inv:is_empty("main")
end
})
minecart.register_cart_entity("tubelib_addons3:chest_cart_entity", "tubelib_addons3:chest_cart", "chest", {
initial_properties = {
physical = false,
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
visual = "wielditem",
textures = {"tubelib_addons3:chest_cart"},
visual_size = {x=0.66, y=0.66, z=0.66},
static_save = false,
},
})
tubelib.register_node("tubelib_addons3:chest_cart", {}, {
on_pull_stack = function(pos, side)
local meta = minetest.get_meta(pos)
return tubelib.get_stack(meta, "main")
end,
on_pull_item = function(pos, side)
local meta = minetest.get_meta(pos)
return tubelib.get_item(meta, "main")
end,
on_push_item = function(pos, side, item)
local meta = minetest.get_meta(pos)
return tubelib.put_item(meta, "main", item)
end,
on_unpull_item = function(pos, side, item)
local meta = minetest.get_meta(pos)
return tubelib.put_item(meta, "main", item)
end,
on_recv_message = function(pos, topic, payload)
if topic == "state" then
local meta = minetest.get_meta(pos)
return tubelib.get_inv_state(meta, "main")
else
return "unsupported"
end
end,
})
minetest.register_craft({
output = "tubelib_addons3:chest_cart",
recipe = {
{"default:junglewood", "default:chest_locked", "default:junglewood"},
{"default:steel_ingot", "default:steel_ingot", "default:steel_ingot"},
},
})

View File

@ -21,3 +21,7 @@ dofile(minetest.get_modpath("tubelib_addons3") .. '/distributor.lua')
dofile(minetest.get_modpath("tubelib_addons3") .. '/pushing_chest.lua') dofile(minetest.get_modpath("tubelib_addons3") .. '/pushing_chest.lua')
dofile(minetest.get_modpath("tubelib_addons3") .. '/teleporter.lua') dofile(minetest.get_modpath("tubelib_addons3") .. '/teleporter.lua')
dofile(minetest.get_modpath("tubelib_addons3") .. '/funnel.lua') dofile(minetest.get_modpath("tubelib_addons3") .. '/funnel.lua')
if minetest.global_exists("minecart") then
dofile(minetest.get_modpath("tubelib_addons3") .. '/chest_cart.lua')
end

View File

@ -7,6 +7,10 @@
HighPerf Chest= HighPerf Chest=
connected with= connected with=
### chest_cart.lua ###
TA Chest Cart=
### distributor.lua ### ### distributor.lua ###
HighPerf Distributor= HighPerf Distributor=

View File

@ -7,6 +7,10 @@
HighPerf Chest=HighPerf Kiste HighPerf Chest=HighPerf Kiste
connected with=verbunden mit connected with=verbunden mit
### chest_cart.lua ###
TA Chest Cart=TA Kistenwagen
### distributor.lua ### ### distributor.lua ###
HighPerf Distributor=HighPerf Verteiler HighPerf Distributor=HighPerf Verteiler

View File

@ -1,3 +1,4 @@
name=tubelib_addons3 name=tubelib_addons3
description=Tubelib Extension with High Performance nodes description=Tubelib Extension with High Performance nodes
depends=tubelib,tubelib_addons1,default depends=tubelib,tubelib_addons1,default
optional_depends=minecart

Binary file not shown.

Before

Width:  |  Height:  |  Size: 752 B

After

Width:  |  Height:  |  Size: 470 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 737 B

After

Width:  |  Height:  |  Size: 587 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

Some files were not shown because too many files have changed in this diff Show More