Remove a bunch of HUD stuff
|
@ -1,23 +0,0 @@
|
|||
# mcl_boats
|
||||
This mod adds drivable boats.
|
||||
|
||||
# Credits
|
||||
## Mesh
|
||||
Boat mesh (`models/mcl_boats_boat.b3d`) created by 22i.
|
||||
Source: https://github.com/22i/minecraft-voxel-blender-models
|
||||
|
||||
License of boat model:
|
||||
GNU GPLv3 <https://www.gnu.org/licenses/gpl-3.0.html>
|
||||
|
||||
## Textures
|
||||
See the main MineClone 2 README.md file to learn more.
|
||||
|
||||
## Code
|
||||
Code based on Minetest Game, licensed under the MIT License (MIT).
|
||||
|
||||
Authors include:
|
||||
* PilzAdam (2012-2016)
|
||||
* Various Minetest / Minetest Game developers and contributors (2012-2016)
|
||||
* maikerumine (2017)
|
||||
* Wuzzy (2017)
|
||||
* Fleckenstein (2020-2021)
|
|
@ -1,484 +0,0 @@
|
|||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
|
||||
local boat_visual_size = {x = 1, y = 1, z = 1}
|
||||
local paddling_speed = 22
|
||||
local boat_y_offset = 0.35
|
||||
local boat_y_offset_ground = boat_y_offset + 0.6
|
||||
local boat_side_offset = 1.001
|
||||
local boat_max_hp = 4
|
||||
|
||||
local function is_group(pos, group)
|
||||
local nn = minetest.get_node(pos).name
|
||||
return minetest.get_item_group(nn, group) ~= 0
|
||||
end
|
||||
|
||||
local is_water = flowlib.is_water
|
||||
|
||||
local function is_ice(pos)
|
||||
return is_group(pos, "ice")
|
||||
end
|
||||
|
||||
local function get_sign(i)
|
||||
if i == 0 then
|
||||
return 0
|
||||
else
|
||||
return i / math.abs(i)
|
||||
end
|
||||
end
|
||||
|
||||
local function get_velocity(v, yaw, y)
|
||||
local x = -math.sin(yaw) * v
|
||||
local z = math.cos(yaw) * v
|
||||
return {x = x, y = y, z = z}
|
||||
end
|
||||
|
||||
local function get_v(v)
|
||||
return math.sqrt(v.x ^ 2 + v.z ^ 2)
|
||||
end
|
||||
|
||||
local function check_object(obj)
|
||||
return obj and (obj:is_player() or obj:get_luaentity()) and obj
|
||||
end
|
||||
|
||||
local function get_visual_size(obj)
|
||||
return obj:is_player() and {x = 1, y = 1, z = 1} or obj:get_luaentity()._old_visual_size or obj:get_properties().visual_size
|
||||
end
|
||||
|
||||
local function set_attach(boat)
|
||||
boat._driver:set_attach(boat.object, "",
|
||||
{x = 0, y = 0.42, z = -1}, {x = 0, y = 0, z = 0})
|
||||
end
|
||||
|
||||
local function set_double_attach(boat)
|
||||
boat._driver:set_attach(boat.object, "",
|
||||
{x = 0, y = 0.42, z = 0.8}, {x = 0, y = 0, z = 0})
|
||||
boat._passenger:set_attach(boat.object, "",
|
||||
{x = 0, y = 0.42, z = -2.2}, {x = 0, y = 0, z = 0})
|
||||
end
|
||||
|
||||
local function attach_object(self, obj)
|
||||
if self._driver then
|
||||
if self._driver:is_player() then
|
||||
self._passenger = obj
|
||||
else
|
||||
self._passenger = self._driver
|
||||
self._driver = obj
|
||||
end
|
||||
set_double_attach(self)
|
||||
else
|
||||
self._driver = obj
|
||||
set_attach(self)
|
||||
end
|
||||
|
||||
local visual_size = get_visual_size(obj)
|
||||
local yaw = self.object:get_yaw()
|
||||
obj:set_properties({visual_size = vector.divide(visual_size, boat_visual_size)})
|
||||
|
||||
if obj:is_player() then
|
||||
local name = obj:get_player_name()
|
||||
mcl_player.player_attached[name] = true
|
||||
minetest.after(0.2, function(name)
|
||||
local player = minetest.get_player_by_name(name)
|
||||
if player then
|
||||
mcl_player.player_set_animation(player, "sit" , 30)
|
||||
end
|
||||
end, name)
|
||||
obj:set_look_horizontal(yaw)
|
||||
mcl_title.set(obj, "actionbar", {text=S("Sneak to dismount"), color="white", stay=60})
|
||||
else
|
||||
obj:get_luaentity()._old_visual_size = visual_size
|
||||
end
|
||||
end
|
||||
|
||||
local function detach_object(obj, change_pos)
|
||||
obj:set_detach()
|
||||
obj:set_properties({visual_size = get_visual_size(obj)})
|
||||
if obj:is_player() then
|
||||
mcl_player.player_attached[obj:get_player_name()] = false
|
||||
mcl_player.player_set_animation(obj, "stand" , 30)
|
||||
else
|
||||
obj:get_luaentity()._old_visual_size = nil
|
||||
end
|
||||
if change_pos then
|
||||
obj:set_pos(vector.add(obj:get_pos(), vector.new(0, 0.2, 0)))
|
||||
end
|
||||
end
|
||||
|
||||
--
|
||||
-- Boat entity
|
||||
--
|
||||
|
||||
local boat = {
|
||||
physical = true,
|
||||
pointable = true,
|
||||
-- Warning: Do not change the position of the collisionbox top surface,
|
||||
-- lowering it causes the boat to fall through the world if underwater
|
||||
collisionbox = {-0.5, -0.35, -0.5, 0.5, 0.3, 0.5},
|
||||
selectionbox = {-0.7, -0.35, -0.7, 0.7, 0.3, 0.7},
|
||||
visual = "mesh",
|
||||
mesh = "mcl_boats_boat.b3d",
|
||||
textures = {"mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png", "mcl_boats_texture_oak_boat.png"},
|
||||
visual_size = boat_visual_size,
|
||||
hp_max = boat_max_hp,
|
||||
damage_texture_modifier = "^[colorize:white:0",
|
||||
|
||||
_driver = nil, -- Attached driver (player) or nil if none
|
||||
_passenger = nil,
|
||||
_v = 0, -- Speed
|
||||
_last_v = 0, -- Temporary speed variable
|
||||
_removed = false, -- If true, boat entity is considered removed (e.g. after punch) and should be ignored
|
||||
_itemstring = "mcl_boats:boat", -- Itemstring of the boat item (implies boat type)
|
||||
_animation = 0, -- 0: not animated; 1: paddling forwards; -1: paddling forwards
|
||||
_regen_timer = 0,
|
||||
_damage_anim = 0,
|
||||
}
|
||||
|
||||
minetest.register_on_respawnplayer(detach_object)
|
||||
|
||||
function boat.on_rightclick(self, clicker)
|
||||
if self._passenger or not clicker or clicker:get_attach() then
|
||||
return
|
||||
end
|
||||
attach_object(self, clicker)
|
||||
end
|
||||
|
||||
|
||||
function boat.on_activate(self, staticdata, dtime_s)
|
||||
self.object:set_armor_groups({fleshy = 100})
|
||||
local data = minetest.deserialize(staticdata)
|
||||
if type(data) == "table" then
|
||||
self._v = data.v
|
||||
self._last_v = self._v
|
||||
self._itemstring = data.itemstring
|
||||
|
||||
while #data.textures < 5 do
|
||||
table.insert(data.textures, data.textures[1])
|
||||
end
|
||||
|
||||
self.object:set_properties({textures = data.textures})
|
||||
end
|
||||
end
|
||||
|
||||
function boat.get_staticdata(self)
|
||||
return minetest.serialize({
|
||||
v = self._v,
|
||||
itemstring = self._itemstring,
|
||||
textures = self.object:get_properties().textures
|
||||
})
|
||||
end
|
||||
|
||||
function boat.on_death(self, killer)
|
||||
mcl_burning.extinguish(self.object)
|
||||
|
||||
if killer and killer:is_player() and minetest.is_creative_enabled(killer:get_player_name()) then
|
||||
local inv = killer:get_inventory()
|
||||
if not inv:contains_item("main", self._itemstring) then
|
||||
inv:add_item("main", self._itemstring)
|
||||
end
|
||||
else
|
||||
minetest.add_item(self.object:get_pos(), self._itemstring)
|
||||
end
|
||||
if self._driver then
|
||||
detach_object(self._driver)
|
||||
end
|
||||
if self._passenger then
|
||||
detach_object(self._passenger)
|
||||
end
|
||||
self._driver = nil
|
||||
self._passenger = nil
|
||||
end
|
||||
|
||||
function boat.on_punch(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)
|
||||
if damage > 0 then
|
||||
self._regen_timer = 0
|
||||
end
|
||||
end
|
||||
|
||||
function boat.on_step(self, dtime, moveresult)
|
||||
mcl_burning.tick(self.object, dtime, self)
|
||||
|
||||
self._v = get_v(self.object:get_velocity()) * get_sign(self._v)
|
||||
local v_factor = 1
|
||||
local v_slowdown = 0.02
|
||||
local p = self.object:get_pos()
|
||||
local on_water = true
|
||||
local on_ice = false
|
||||
local in_water = is_water({x=p.x, y=p.y-boat_y_offset+1, z=p.z})
|
||||
local waterp = {x=p.x, y=p.y-boat_y_offset - 0.1, z=p.z}
|
||||
if not is_water(waterp) then
|
||||
on_water = false
|
||||
if not in_water and is_ice(waterp) then
|
||||
on_ice = true
|
||||
else
|
||||
v_slowdown = 0.04
|
||||
v_factor = 0.5
|
||||
end
|
||||
elseif in_water then
|
||||
on_water = false
|
||||
in_water = true
|
||||
v_factor = 0.75
|
||||
v_slowdown = 0.05
|
||||
end
|
||||
|
||||
local hp = self.object:get_hp()
|
||||
local regen_timer = self._regen_timer + dtime
|
||||
if hp >= boat_max_hp then
|
||||
regen_timer = 0
|
||||
elseif regen_timer >= 0.5 then
|
||||
hp = hp + 1
|
||||
self.object:set_hp(hp)
|
||||
regen_timer = 0
|
||||
end
|
||||
self._regen_timer = regen_timer
|
||||
|
||||
if moveresult and moveresult.collides then
|
||||
for _, collision in pairs(moveresult.collisions) do
|
||||
local pos = collision.node_pos
|
||||
if collision.type == "node" and minetest.get_item_group(minetest.get_node(pos).name, "dig_by_boat") > 0 then
|
||||
minetest.dig_node(pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local had_passenger = self._passenger
|
||||
|
||||
self._driver = check_object(self._driver)
|
||||
self._passenger = check_object(self._passenger)
|
||||
|
||||
if self._passenger then
|
||||
if not self._driver then
|
||||
self._driver = self._passenger
|
||||
self._passenger = nil
|
||||
else
|
||||
local ctrl = self._passenger:get_player_control()
|
||||
if ctrl and ctrl.sneak then
|
||||
detach_object(self._passenger, true)
|
||||
self._passenger = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if self._driver then
|
||||
if had_passenger and not self._passenger then
|
||||
set_attach(self)
|
||||
end
|
||||
local ctrl = self._driver:get_player_control()
|
||||
if ctrl and ctrl.sneak then
|
||||
detach_object(self._driver, true)
|
||||
self._driver = nil
|
||||
return
|
||||
end
|
||||
local yaw = self.object:get_yaw()
|
||||
if ctrl and ctrl.up then
|
||||
-- Forwards
|
||||
self._v = self._v + 0.1 * v_factor
|
||||
|
||||
-- Paddling animation
|
||||
if self._animation ~= 1 then
|
||||
self.object:set_animation({x=0, y=40}, paddling_speed, 0, true)
|
||||
self._animation = 1
|
||||
end
|
||||
elseif ctrl and ctrl.down then
|
||||
-- Backwards
|
||||
self._v = self._v - 0.1 * v_factor
|
||||
|
||||
-- Paddling animation, reversed
|
||||
if self._animation ~= -1 then
|
||||
self.object:set_animation({x=0, y=40}, -paddling_speed, 0, true)
|
||||
self._animation = -1
|
||||
end
|
||||
else
|
||||
-- Stop paddling animation if no control pressed
|
||||
if self._animation ~= 0 then
|
||||
self.object:set_animation({x=0, y=40}, 0, 0, true)
|
||||
self._animation = 0
|
||||
end
|
||||
end
|
||||
if ctrl and ctrl.left then
|
||||
if self._v < 0 then
|
||||
self.object:set_yaw(yaw - (1 + dtime) * 0.03 * v_factor)
|
||||
else
|
||||
self.object:set_yaw(yaw + (1 + dtime) * 0.03 * v_factor)
|
||||
end
|
||||
elseif ctrl and ctrl.right then
|
||||
if self._v < 0 then
|
||||
self.object:set_yaw(yaw + (1 + dtime) * 0.03 * v_factor)
|
||||
else
|
||||
self.object:set_yaw(yaw - (1 + dtime) * 0.03 * v_factor)
|
||||
end
|
||||
end
|
||||
else
|
||||
-- Stop paddling without driver
|
||||
if self._animation ~= 0 then
|
||||
self.object:set_animation({x=0, y=40}, 0, 0, true)
|
||||
self._animation = 0
|
||||
end
|
||||
|
||||
for _, obj in pairs(minetest.get_objects_inside_radius(self.object:get_pos(), 1.3)) do
|
||||
local entity = obj:get_luaentity()
|
||||
if entity and entity.is_mob then
|
||||
attach_object(self, obj)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
local s = get_sign(self._v)
|
||||
if not on_ice and not on_water and not in_water and math.abs(self._v) > 2.0 then
|
||||
v_slowdown = math.min(math.abs(self._v) - 2.0, v_slowdown * 5)
|
||||
elseif not on_ice and in_water and math.abs(self._v) > 1.5 then
|
||||
v_slowdown = math.min(math.abs(self._v) - 1.5, v_slowdown * 5)
|
||||
end
|
||||
self._v = self._v - v_slowdown * s
|
||||
if s ~= get_sign(self._v) then
|
||||
self._v = 0
|
||||
end
|
||||
|
||||
p.y = p.y - boat_y_offset
|
||||
local new_velo
|
||||
local new_acce
|
||||
if not is_water(p) and not on_ice then
|
||||
-- Not on water or inside water: Free fall
|
||||
--local nodedef = minetest.registered_nodes[minetest.get_node(p).name]
|
||||
new_acce = {x = 0, y = -9.8, z = 0}
|
||||
new_velo = get_velocity(self._v, self.object:get_yaw(),
|
||||
self.object:get_velocity().y)
|
||||
else
|
||||
p.y = p.y + 1
|
||||
local is_obsidian_boat = self.object:get_luaentity()._itemstring == "mcl_boats:boat_obsidian"
|
||||
if is_water(p) or is_obsidian_boat then
|
||||
-- Inside water: Slowly sink
|
||||
local y = self.object:get_velocity().y
|
||||
y = y - 0.01
|
||||
if y < -0.2 then
|
||||
y = -0.2
|
||||
end
|
||||
new_acce = {x = 0, y = 0, z = 0}
|
||||
new_velo = get_velocity(self._v, self.object:get_yaw(), y)
|
||||
else
|
||||
-- On top of water
|
||||
new_acce = {x = 0, y = 0, z = 0}
|
||||
if math.abs(self.object:get_velocity().y) < 0 then
|
||||
new_velo = get_velocity(self._v, self.object:get_yaw(), 0)
|
||||
else
|
||||
new_velo = get_velocity(self._v, self.object:get_yaw(),
|
||||
self.object:get_velocity().y)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Terminal velocity: 8 m/s per axis of travel
|
||||
local terminal_velocity = on_ice and 57.1 or 8.0
|
||||
for _,axis in pairs({"z","y","x"}) do
|
||||
if math.abs(new_velo[axis]) > terminal_velocity then
|
||||
new_velo[axis] = terminal_velocity * get_sign(new_velo[axis])
|
||||
end
|
||||
end
|
||||
|
||||
local yaw = self.object:get_yaw()
|
||||
local anim = (boat_max_hp - hp - regen_timer * 2) / boat_max_hp * math.pi / 4
|
||||
|
||||
self.object:set_rotation(vector.new(anim, yaw, anim))
|
||||
self.object:set_velocity(new_velo)
|
||||
self.object:set_acceleration(new_acce)
|
||||
end
|
||||
|
||||
-- Register one entity for all boat types
|
||||
minetest.register_entity("mcl_boats:boat", boat)
|
||||
|
||||
local boat_ids = { "boat", "boat_spruce", "boat_birch", "boat_jungle", "boat_acacia", "boat_dark_oak", "boat_obsidian" }
|
||||
local names = { S("Oak Boat"), S("Spruce Boat"), S("Birch Boat"), S("Jungle Boat"), S("Acacia Boat"), S("Dark Oak Boat"), S("Obsidian Boat") }
|
||||
local craftstuffs = {}
|
||||
if minetest.get_modpath("mcl_core") then
|
||||
craftstuffs = { "mcl_core:wood", "mcl_core:sprucewood", "mcl_core:birchwood", "mcl_core:junglewood", "mcl_core:acaciawood", "mcl_core:darkwood", "mcl_core:obsidian" }
|
||||
end
|
||||
local images = { "oak", "spruce", "birch", "jungle", "acacia", "dark_oak", "obsidian" }
|
||||
|
||||
for b=1, #boat_ids do
|
||||
local itemstring = "mcl_boats:"..boat_ids[b]
|
||||
|
||||
local longdesc, usagehelp, tt_help, help, helpname
|
||||
help = false
|
||||
-- Only create one help entry for all boats
|
||||
if b == 1 then
|
||||
help = true
|
||||
longdesc = S("Boats are used to travel on the surface of water.")
|
||||
usagehelp = S("Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Use [Sneak] to leave the boat, punch the boat to make it drop as an item.")
|
||||
helpname = S("Boat")
|
||||
end
|
||||
tt_help = S("Water vehicle")
|
||||
|
||||
minetest.register_craftitem(itemstring, {
|
||||
description = names[b],
|
||||
_tt_help = tt_help,
|
||||
_doc_items_create_entry = help,
|
||||
_doc_items_entry_name = helpname,
|
||||
_doc_items_longdesc = longdesc,
|
||||
_doc_items_usagehelp = usagehelp,
|
||||
inventory_image = "mcl_boats_"..images[b].."_boat.png",
|
||||
liquids_pointable = true,
|
||||
groups = { boat = 1, transport = 1},
|
||||
stack_max = 1,
|
||||
on_place = function(itemstack, placer, pointed_thing)
|
||||
if pointed_thing.type ~= "node" then
|
||||
return itemstack
|
||||
end
|
||||
|
||||
-- Call on_rightclick if the pointed node defines it
|
||||
local node = minetest.get_node(pointed_thing.under)
|
||||
if placer and not placer:get_player_control().sneak then
|
||||
if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then
|
||||
return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack
|
||||
end
|
||||
end
|
||||
|
||||
local pos = table.copy(pointed_thing.under)
|
||||
local dir = vector.subtract(pointed_thing.above, pointed_thing.under)
|
||||
|
||||
if math.abs(dir.x) > 0.9 or math.abs(dir.z) > 0.9 then
|
||||
pos = vector.add(pos, vector.multiply(dir, boat_side_offset))
|
||||
elseif is_water(pos) then
|
||||
pos = vector.add(pos, vector.multiply(dir, boat_y_offset))
|
||||
else
|
||||
pos = vector.add(pos, vector.multiply(dir, boat_y_offset_ground))
|
||||
end
|
||||
local boat = minetest.add_entity(pos, "mcl_boats:boat")
|
||||
local texture = "mcl_boats_texture_"..images[b].."_boat.png"
|
||||
boat:get_luaentity()._itemstring = itemstring
|
||||
boat:set_properties({textures = { texture, texture, texture, texture, texture }})
|
||||
boat:set_yaw(placer:get_look_horizontal())
|
||||
if not minetest.is_creative_enabled(placer:get_player_name()) then
|
||||
itemstack:take_item()
|
||||
end
|
||||
return itemstack
|
||||
end,
|
||||
_on_dispense = function(stack, pos, droppos, dropnode, dropdir)
|
||||
local below = {x=droppos.x, y=droppos.y-1, z=droppos.z}
|
||||
local belownode = minetest.get_node(below)
|
||||
-- Place boat as entity on or in water
|
||||
if minetest.get_item_group(dropnode.name, "water") ~= 0 or (dropnode.name == "air" and minetest.get_item_group(belownode.name, "water") ~= 0) then
|
||||
minetest.add_entity(droppos, "mcl_boats:boat")
|
||||
else
|
||||
minetest.add_item(droppos, stack)
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
local c = craftstuffs[b]
|
||||
minetest.register_craft({
|
||||
output = itemstring,
|
||||
recipe = {
|
||||
{c, "", c},
|
||||
{c, c, c},
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
minetest.register_craft({
|
||||
type = "fuel",
|
||||
recipe = "group:boat",
|
||||
burntime = 20,
|
||||
})
|
||||
|
||||
if minetest.get_modpath("doc_identifier") then
|
||||
doc.sub.identifier.register_object("mcl_boats:boat", "craftitems", "mcl_boats:boat")
|
||||
end
|
|
@ -1,12 +0,0 @@
|
|||
# textdomain: mcl_boats
|
||||
Acacia Boat=Akazienboot
|
||||
Birch Boat=Birkenboot
|
||||
Boat=Boot
|
||||
Boats are used to travel on the surface of water.=Boote werden benutzt, um sich auf der Wasseroberfläche zu bewegen.
|
||||
Dark Oak Boat=Schwarzeichenboot
|
||||
Jungle Boat=Dschungelboot
|
||||
Oak Boat=Eichenboot
|
||||
Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Use [Sneak] to leave the boat, punch the boat to make it drop as an item.=Rechtsklicken Sie auf eine Wasserquelle, um das Boot zu platzieren. Rechtsklicken Sie auf das Boot, um es zu betreten. Mit [Links] und [Rechts] lenken, mit [Vorwärts] und [Rückwärts] Geschwindigkeit regeln oder rückwärts fahren. Nutzen sie [Schleichen], um das Boot zu verlassen, schlagen Sie das Boot, um es als Gegenstand fallen zu lassen.
|
||||
Spruce Boat=Fichtenboot
|
||||
Water vehicle=Wasserfahrzeug
|
||||
Sneak to dismount=Zum Aussteigen schleichen
|
|
@ -1,10 +0,0 @@
|
|||
# textdomain: mcl_boats
|
||||
Acacia Boat=Barca de acacia
|
||||
Birch Boat=Barca de abedul
|
||||
Boat=Barca
|
||||
Boats are used to travel on the surface of water.=Las barcas se utilizan para viajar en la superficie del agua.
|
||||
Dark Oak Boat=Barca de roble oscuro
|
||||
Jungle Boat=Barca de la selva
|
||||
Oak Boat=Barca de roble
|
||||
Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Rightclick the boat again to leave it, punch the boat to make it drop as an item.=Haga clic derecho en una fuente de agua para colocar el barco. Haga clic derecho en el barco para entrar. Utilice [Izquierda] y [Derecha] para dirigir, [Adelante] para acelerar y [Atrás] para reducir la velocidad o retroceder. Haga clic derecho en el barco nuevamente para dejarlo, golpee el barco para que se caiga como un artículo.
|
||||
Spruce Boat=Barca de abeto
|
|
@ -1,12 +0,0 @@
|
|||
# textdomain: mcl_boats
|
||||
Acacia Boat=Bateau en Acacia
|
||||
Birch Boat=Bateau en Bouleau
|
||||
Boat=Bateau
|
||||
Boats are used to travel on the surface of water.=Les bateaux sont utilisés pour voyager à la surface de l'eau.
|
||||
Dark Oak Boat=Bateau en Chêne Noir
|
||||
Jungle Boat=Bateau en Acajou
|
||||
Oak Boat=Bateau en Chêne
|
||||
Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Use [Sneak] to leave the boat, punch the boat to make it drop as an item.=Faites un clic droit sur une source d'eau pour placer le bateau. Faites un clic droit sur le bateau pour y entrer. Utilisez [Gauche] et [Droite] pour diriger, [Avant] pour accélérer et [Arrière] pour ralentir ou reculer. Utilisez [Sneak] pour le quitter, frappez le bateau pour le faire tomber en tant qu'objet.
|
||||
Spruce Boat=Bateau en Sapin
|
||||
Water vehicle=Véhicule aquatique
|
||||
Sneak to dismount=
|
|
@ -1,12 +0,0 @@
|
|||
# textdomain: mcl_boats
|
||||
Acacia Boat=Akacjowa łódź
|
||||
Birch Boat=Brzozowa łódź
|
||||
Boat=Łódź
|
||||
Boats are used to travel on the surface of water.=Łodzie są wykorzystywane do podróżowania po powierzchni wody.
|
||||
Dark Oak Boat=Ciemno-dębowa łódź
|
||||
Jungle Boat=Tropikalna łódź
|
||||
Oak Boat=Dębowa łódź
|
||||
Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Use [Sneak] to leave the boat, punch the boat to make it drop as an item.=Kliknij prawym przyciskiem myszy na źródło wody by postawić łódź. Kliknij prawym przyciskiem myszy by w nią wsiąść. Użyj przycisków [Lewy] oraz [Prawy] by sterować, [Naprzód] by przyspieszyć i [W tył] by zwolnić lub się cofać. Kliknij [Skradanie] by z niej wyjść, uderz ją by wziąć ją jako przedmiot.
|
||||
Spruce Boat=Świerkowa łódź
|
||||
Water vehicle=Pojazd wodny
|
||||
Sneak to dismount=Skradaj się by opuścić łódź
|
|
@ -1,11 +0,0 @@
|
|||
# textdomain: mcl_boats
|
||||
Acacia Boat=Лодка из акации
|
||||
Birch Boat=Берёзовая лодка
|
||||
Boat=Лодка
|
||||
Boats are used to travel on the surface of water.=С помощью лодки можно путешествовать по водной поверхности.
|
||||
Dark Oak Boat=Лодка из тёмного дуба
|
||||
Jungle Boat=Лодка из дерева джунглей
|
||||
Oak Boat=Дубовая лодка
|
||||
Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Rightclick the boat again to leave it, punch the boat to make it drop as an item.=Правый клик по воде спустит лодку на воду. Правый клик по лодке разместит вас в ней. [Влево] и [Вправо] - рулить, [Вперед] - разгоняться, [Назад] - тормозить или плыть назад. Правый клик по лодке, когда вы в ней, позволит выйти из неё. Удар по лодке превратит её обратно в предмет.
|
||||
Spruce Boat=Еловая лодка
|
||||
Water vehicle=Водный транспорт
|
|
@ -1,11 +0,0 @@
|
|||
# textdomain: mcl_boats
|
||||
Acacia Boat=相思木船
|
||||
Birch Boat=白樺木船
|
||||
Boat=船
|
||||
Boats are used to travel on the surface of water.=船是用來在水上行走的交通工具。
|
||||
Dark Oak Boat=黑橡木船
|
||||
Jungle Boat=叢林木船
|
||||
Oak Boat=橡木船
|
||||
Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Rightclick the boat again to leave it, punch the boat to make it drop as an item.=右鍵單擊水源以放置船。右鍵單擊船以搭乘它。使用[左]和[右]進行轉向,[向前]加快速度,[向後]減速或向後移動。再次右鍵單擊船以離開它,打擊船以使其掉落為物品。
|
||||
Spruce Boat=杉木船
|
||||
Water vehicle=水上交通工具
|
|
@ -1,12 +0,0 @@
|
|||
# textdomain: mcl_boats
|
||||
Acacia Boat=
|
||||
Birch Boat=
|
||||
Boat=
|
||||
Boats are used to travel on the surface of water.=
|
||||
Dark Oak Boat=
|
||||
Jungle Boat=
|
||||
Oak Boat=
|
||||
Rightclick on a water source to place the boat. Rightclick the boat to enter it. Use [Left] and [Right] to steer, [Forwards] to speed up and [Backwards] to slow down or move backwards. Use [Sneak] to leave the boat, punch the boat to make it drop as an item.=
|
||||
Spruce Boat=
|
||||
Water vehicle=
|
||||
Sneak to dismount=
|
|
@ -1,7 +0,0 @@
|
|||
name = mcl_boats
|
||||
author = PilzAdam
|
||||
description = Adds drivable boats.
|
||||
depends = mcl_player, flowlib, mcl_title
|
||||
optional_depends = mcl_core, doc_identifier
|
||||
|
||||
|
Before Width: | Height: | Size: 265 B |
Before Width: | Height: | Size: 264 B |
Before Width: | Height: | Size: 261 B |
Before Width: | Height: | Size: 271 B |
Before Width: | Height: | Size: 267 B |
Before Width: | Height: | Size: 264 B |
Before Width: | Height: | Size: 267 B |
Before Width: | Height: | Size: 969 B |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 535 B |
Before Width: | Height: | Size: 1.1 KiB |
|
@ -1,211 +0,0 @@
|
|||
API documentation for the HUD bars mod
|
||||
======================================
|
||||
|
||||
## Introduction
|
||||
This API allows you to add, change, hide and unhide custom HUD bars for this mod.
|
||||
|
||||
## Overview
|
||||
To give you a *very* brief overview over this API, here is the basic workflow on how to add your own custom HUD bar:
|
||||
|
||||
* Create images for your HUD bar
|
||||
* Call `hb.register_hudbar` to make the definition of the HUD bar known to this mod
|
||||
* Call `hb.init_hudbar` for each player for which you want to use previously defined HUD bar
|
||||
* Use `hb.change_hudbar` whenever you need to change the values of a HUD bar of a certain player
|
||||
* If you need it: Use `hb.hide_hudbar` and `hb.unhide_hudbar` to hide or unhide HUD bars of a certain player
|
||||
|
||||
## The basic rules
|
||||
In order to use this API, you should be aware of a few basic rules in order to understand it:
|
||||
|
||||
* A HUD bar is an approximate graphical representation of the ratio of a current value and a maximum value, i.e. current health of 15 and maximum health of 20. A full HUD bar represents 100%, an empty HUD bar represents 0%.
|
||||
* The current value must always be equal to or smaller then the maximum
|
||||
* Both current value and maximum must not be smaller than 0
|
||||
* Both current value and maximum must be real numbers. So no NaN, infinity, etc.
|
||||
* The HUD bar will be hidden if the maximum equals 0. This is intentional.
|
||||
* The health and breath HUD bars are hardcoded.
|
||||
|
||||
These are soft rules, the HUD bars mod will not enforce all of these.
|
||||
But this mod has been programmed under the assumption that these rules are followed, for integrity.
|
||||
|
||||
## Adding a HUD bar
|
||||
To make a new HUD bar known to this mod, you need …
|
||||
|
||||
* … an image of size 2×16 for the bar
|
||||
* … an icon of size 16×16 (optional)
|
||||
* … to register it with `hb.register_hudbar`
|
||||
|
||||
### Bar image
|
||||
The image for the bar will be repeated horizontally to denote the “value” of the HUD bar.
|
||||
It **must** be of size 2×16.
|
||||
If neccessary, the image will be split vertically in half, and only the left half of the image
|
||||
is displayed. So the final HUD bar will always be displayed on a per-pixel basis.
|
||||
|
||||
The default bar images are single-colored, but you can use other styles as well, for instance,
|
||||
a vertical gradient.
|
||||
|
||||
### Icon
|
||||
A 16×16 image shown left of the HUD bar. This is optional.
|
||||
|
||||
### `hb.register_hudbar(identifier, text_color, label, textures, direction, default_start_value, default_start_max, default_start_hidden, format_string, format_string_config)`
|
||||
This function registers a new custom HUD bar definition to the HUD bars mod, so it can be later used to be displayed, changed, hidden
|
||||
and unhidden on a per-player basis.
|
||||
Note this does not yet display the HUD bar.
|
||||
|
||||
The HUD bars will be displayed in a “first come, first serve” order. This API does not allow fow a custom order or a way to set it
|
||||
manually in a reliable way. However, you can use the setting `hudbars_sorting` for this. See the advanced setting menu in Minetest
|
||||
for more information.
|
||||
|
||||
|
||||
#### Parameters
|
||||
* `identifier`: A globally unique internal name for the HUD bar, will be used later to refer to it. Please only rely on alphanumeric characters for now. The identifiers “`health`” and “`breath`” are used internally for the built-in health and breath bar, respectively. Please do not use these names.
|
||||
* `text_color`: A 3-octet number defining the color of the text. The octets denote, in this order red, green and blue and range from `0x00` (complete lack of this component) to `0xFF` (full intensity of this component). Example: `0xFFFFFF` for white.
|
||||
* `label`: A string which is displayed on the HUD bar itself to describe the HUD bar. Try to keep this string short.
|
||||
* `textures`: A table with the following fields:
|
||||
* `bar`: The file name of the bar image (as string). This is only used for the `progress_bar` bar type (see `README.txt`, settings section).
|
||||
* `icon`: The file name of the icon, as string. For the `progress_bar` type, it is shown as single image left of the bar, for the two statbar bar types, it is used as the statbar icon and will be repeated. This field can be `nil`, in which case no icon will be used, but this is not recommended, because the HUD bar will be invisible if the one of the statbar bar types is used.
|
||||
* `bgicon`: The file name of the background icon, it is used as the background for the modern statbar mode only. This field can be `nil`, in which case no background icon will be displayed in this mode.
|
||||
* `direction`: Either left to right(0), or right to left(1).
|
||||
* `default_start_value`: If this HUD bar is added to a player, and no initial value is specified, this value will be used as initial current value
|
||||
* `default_max_value`: If this HUD bar is added to a player, and no initial maximum value is specified, this value will be used as initial maximum value
|
||||
* `default_start_hidden`: The HUD bar will be initially start hidden by default when added to a player. Use `hb.unhide_hudbar` to unhide it.
|
||||
* `format_string`: Optional; You can specify an alternative format string to use for the final text on the HUD bar. The default format string is “`@1: @2/@3`” (The “@” numbers are placeholders that have a meaning in this order: @1 = Label, @2 = current value, @3 = maximum value). Do *not* use minetest.translator on this string, the string will be translated by `hudbars`, but you still must put this string into the translation catalogue file.
|
||||
* `format_string_config`: Required if `format_string` is set. This allows to change which parameters to use in the format string. It's a table with these fields:
|
||||
* `textdomain`: Text domain of the format string, used by `minetest.translate`
|
||||
* `order`: Table that contains the order of the placeholders. It's also possible to remove placeholders. Default order: `{ "label", "value", "max_value" }`
|
||||
* `format_value`: Format string to apply when displaying `value`. Syntax is same as in `string.format`. Default: `"%d"`
|
||||
* `format_max_value`: Same as `format_value` but is applied to `max_value`
|
||||
|
||||
#### Example
|
||||
Example (mostly) from `hbarmor` mod:
|
||||
|
||||
```
|
||||
hb.register_hudbar("armor", 0xFFFFFF, minetest.translator("hbarmor", "Armor"), { icon = "hbarmor_icon.png", bgicon = "hbarmor_bgicon.png", bar = "hbarmor_bar.png" }, 0, 100, hbarmor.autohide, N("@1: @2%"), { order = { "label", "value" }, textdomain = "hbarmor" } )
|
||||
```
|
||||
|
||||
Displays an armor HUD bar with a label of the form „Armor: 53%“. (`N` is a dummy function that returns its argument, used to make the string visible for translator scripts.)
|
||||
|
||||
#### Return value
|
||||
Always `nil`.
|
||||
|
||||
|
||||
## Displaying a HUD bar
|
||||
After a HUD bar has been registered, they are not yet displayed yet for any player. HUD bars must be
|
||||
explicitly initialized on a per-player basis.
|
||||
|
||||
You probably want to do this in the `minetest.register_on_joinplayer`.
|
||||
|
||||
### `hb.init_hudbar(player, identifier, start_value, start_max, start_hidden)`
|
||||
This function initialzes and activates a previously registered HUD bar and assigns it to a
|
||||
certain client/player. This has only to be done once per player and after that, you can change
|
||||
the values using `hb.change_hudbar`.
|
||||
|
||||
However, if `start_hidden` was set to `true` for the HUD bar (in `hb.register_hudbar`), the HUD bar
|
||||
will initially be hidden, but the HUD elements are still sent to the client. Otherwise,
|
||||
the HUD bar will be initially be shown to the player.
|
||||
|
||||
#### Parameters
|
||||
* `player`: `ObjectRef` of the player to which the new HUD bar should be displayed to.
|
||||
* `identifier`: The identifier of the HUD bar type, as specified in `hb.register_hudbar`.
|
||||
* `start_value`: The initial current value of the HUD bar. This is optional, `default_start_value` of the registration function will be used, if this is `nil`.
|
||||
* `start_max`: The initial maximum value of the HUD bar. This is optional, `default_start_max` of the registration function will be used, if this is `nil`
|
||||
* `start_hidden`: Whether the HUD bar is initially hidden. This is optional, `default_start_hidden` of the registration function will be used as default
|
||||
|
||||
#### Return value
|
||||
`true` on success, `false` otherwise.
|
||||
|
||||
|
||||
## Modifying a HUD bar
|
||||
After a HUD bar has been added, you can change the current and maximum value and other attributes on a per-player basis.
|
||||
You use the function `hb.change_hudbar` for this.
|
||||
|
||||
### `hb.change_hudbar(player, identifier, new_value, new_max_value, new_icon, new_bgicon, new_bar, new_label, new_text_color)`
|
||||
Changes the values and the appearance of an initialized HUD bar for a certain player. `new_value`
|
||||
and `new_max_value` are the most important parameters as they specify the new current and maximum new values, you do not need
|
||||
to worry too much about the other parameters.
|
||||
|
||||
The following parameters are less important and provided for styling the HUD bar after registration (if
|
||||
this is desired). The “styling” parameters parallel the parameters of `hb.register_hudbar`. It is
|
||||
recommended to not change the style of a HUD bar too often as this can be distracting or confusing
|
||||
for players.
|
||||
|
||||
`new_value`, `new_max_value` `new_icon`, `new_bgicon`, `new_bar`, `new_label` and `new_text_color` can be
|
||||
`nil`; if one of them is `nil`, that means the value is unchanged. If all those values are `nil`, this
|
||||
function is a no-op.
|
||||
|
||||
This function tries to minimize the amount of calls to `hud_change` of the Minetest Lua API
|
||||
(and thus, network traffic), when you only change the value and/or maximum value. In this case,
|
||||
`hud_change` is only called if it is actually needed, e.g. when the actual length of the bar
|
||||
or the displayed string changed, so you do not have to worry about it. There is, however, no
|
||||
such network optimization for the “styling” parameters, so keep this in mind.
|
||||
|
||||
#### Parameters
|
||||
* `player`: `ObjectRef` of the player to which the HUD bar belongs to
|
||||
* `identifier`: The identifier of the HUD bar type to change, as specified in `hb.register_hudbar`.
|
||||
* `new_value`: The new current value of the HUD bar
|
||||
* `new_max_value`: The new maximum value of the HUD bar
|
||||
* `new_icon`: File name of the new icon
|
||||
* `new_bgicon`: File name of the new background icon for the modern-style statbar
|
||||
* `new_bar`: File name of the new bar segment image
|
||||
* `new_label`: A new text label of the HUD bar. Note the format string still applies
|
||||
* `new_text_color`: A 3-octet number defining the new color of the text.
|
||||
|
||||
#### Return value
|
||||
`true` on success, `false` otherwise.
|
||||
|
||||
|
||||
## Hiding and unhiding a HUD bar
|
||||
You can also hide custom HUD bars, meaning they will not be displayed for a certain player. You can still
|
||||
use `hb.change_hudbar` on a hidden HUD bar, the new values will be correctly displayed after the HUD bar
|
||||
has been unhidden. Both functions will only call `hud_change` if there has been an actual change to avoid
|
||||
unneccessary traffic.
|
||||
|
||||
Note that the hidden state of a HUD bar will *not* be saved by this mod on server shutdown, so you may need
|
||||
to write your own routines for this or by setting the correct value for `start_hidden` when calling
|
||||
`hb.init_hudbar`.
|
||||
|
||||
### `hb.hide_hudbar(player, identifier)`
|
||||
Hides the specified HUD bar from the screen of the specified player.
|
||||
|
||||
#### Parameters
|
||||
* `player`: `ObjectRef` of the player to which the HUD bar belongs to
|
||||
* `identifier`: The identifier of the HUD bar type to hide, as specified in `hb.register_hudbar`.
|
||||
|
||||
#### Return value
|
||||
`true` on success, `false` otherwise.
|
||||
|
||||
|
||||
### `hb.unhide_hudbar(player, identifier)`
|
||||
Makes a previously hidden HUD bar visible again to a player.
|
||||
|
||||
#### Parameters
|
||||
* `player`: `ObjectRef` of the player to which the HUD bar belongs to
|
||||
* `identifier`: The identifier of the HUD bar type to unhide, as specified in `hb.register_hudbar`.
|
||||
|
||||
#### Return value
|
||||
`true` on success, `false` otherwise.
|
||||
|
||||
|
||||
## Reading HUD bar information
|
||||
It is also possible to read information about existing HUD bars.
|
||||
|
||||
### `hb.get_hudbar_state(player, identifier)`
|
||||
Returns the current state of the active player's HUD bar.
|
||||
|
||||
#### Parameters
|
||||
* `player`: `ObjectRef` of the player to which the HUD bar belongs to
|
||||
* `identifier`: The identifier of the HUD bar type to hide, as specified in `hb.register_hudbar`.
|
||||
|
||||
#### Return value
|
||||
On success, returns a table which holds information on the current state of the HUD bar. Note
|
||||
the table is a deep copy of the internal HUD bar state, it is *not* a reference; the information
|
||||
hold by the table is only true for the moment you called this function. The fields of this table are:
|
||||
|
||||
* `value`: Current value of HUD bar.
|
||||
* `max`: Current maximum value of HUD bar.
|
||||
* `hidden`: Boolean denoting whether the HUD bar is hidden.
|
||||
* `barlength`: The length of the HUD bar in pixels. This field is meaningless if the HUD bar is currently hidden.
|
||||
* `text`: The text shown on the HUD bar. This fiels is meaningless if the HUD bar is currently hidden.
|
||||
|
||||
If the player does not exist, returns `nil` instead.
|
||||
|
||||
### `hb.get_hudbar_identifiers()`
|
||||
Returns a table of all currently registered HUD bar identifiers.
|
|
@ -1,62 +0,0 @@
|
|||
# HUD bars
|
||||
|
||||
## Description
|
||||
This mod changes the HUD of Minetest. It replaces the default health and breath
|
||||
symbols by horizontal colored bars with text showing the number.
|
||||
|
||||
Furthermore, it enables other mods to add their own custom bars to the HUD,
|
||||
this mod will place them accordingly.
|
||||
|
||||
**Important**: Keep in mind if running a server with this mod, that the custom
|
||||
position should be displayed correctly on every screen size.
|
||||
|
||||
## Current version
|
||||
The current version is 2.3.2.
|
||||
It works for Minetest 5.3.0.
|
||||
|
||||
This software uses [semantic versioning](http://semver.org), as defined by version 2.0.0 of the SemVer
|
||||
standard.
|
||||
|
||||
## Settings
|
||||
This mod can be configured quite a bit. You can change HUD bar appearance, offsets, ordering, and more.
|
||||
Use the advanced settings menu in Minetest for detailed configuration.
|
||||
|
||||
## API
|
||||
The API is used to add your own custom HUD bars.
|
||||
Documentation for the API of this mod can be found in `API.md`.
|
||||
|
||||
## Legal
|
||||
### License of source code
|
||||
Author: Wuzzy (2015)
|
||||
|
||||
Also: This mod was forked from the “Better HUD” [hud] mod by BlockMen.
|
||||
|
||||
Translations:
|
||||
|
||||
* German: Wuzzy
|
||||
* Portuguese: BrunoMine
|
||||
* Turkish: admicos
|
||||
* Dutch: kingoscargames
|
||||
* Italian: Hamlet
|
||||
* Malay: muhdnurhidayat
|
||||
* Russian: Imk
|
||||
* Spanish: wuniversales
|
||||
|
||||
This program is free software. It comes without any warranty, to
|
||||
the extent permitted by applicable law. You can redistribute it
|
||||
and/or modify it under the terms of the MIT License.
|
||||
|
||||
### Licenses of textures
|
||||
|
||||
* `hudbars_icon_health.png`—celeron55 (CC BY-SA 3.0), modified by BlockMen
|
||||
* `hudbars_bgicon_health.png`—celeron55 (CC BY-SA 3.0), modified by BlockMen
|
||||
* `hudbars_icon_breath.png`—kaeza (MIT License), modified by BlockMen, modified again by Wuzzy
|
||||
* `hudbars_bgicon_breath.png`—based on previous image, edited by Wuzzy (MIT License)
|
||||
* `hudbars_bar_health.png`—Wuzzy (MIT License)
|
||||
* `hudbars_bar_breath.png`—Wuzzy (MIT License)
|
||||
* `hudbars_bar_background.png`—Wuzzy (MIT License)
|
||||
|
||||
### License references
|
||||
|
||||
* [CC-BY-SA 3.0](https://creativecommons.org/licenses/by-sa/3.0/)
|
||||
* [MIT License](https://opensource.org/licenses/MIT)
|
|
@ -1,54 +0,0 @@
|
|||
-- (Hardcoded) default settings
|
||||
|
||||
hb.settings.max_bar_length = 160
|
||||
hb.settings.statbar_length = 20
|
||||
|
||||
-- Statbar positions
|
||||
hb.settings.pos_left = {}
|
||||
hb.settings.pos_right = {}
|
||||
hb.settings.start_offset_left = {}
|
||||
hb.settings.start_offset_right= {}
|
||||
hb.settings.pos_left.x = hb.load_setting("hudbars_pos_left_x", "number", 0.5)
|
||||
hb.settings.pos_left.y = hb.load_setting("hudbars_pos_left_y", "number", 1)
|
||||
hb.settings.pos_right.x = hb.load_setting("hudbars_pos_right_x", "number", 0.5)
|
||||
hb.settings.pos_right.y = hb.load_setting("hudbars_pos_right_y", "number", 1)
|
||||
-- Modified in MCL2!
|
||||
hb.settings.bar_type = hb.load_setting("hudbars_bar_type", "string", "statbar_modern", {"progress_bar", "statbar_classic", "statbar_modern"})
|
||||
if hb.settings.bar_type == "progress_bar" then
|
||||
hb.settings.start_offset_left.x = hb.load_setting("hudbars_start_offset_left_x", "number", -175)
|
||||
hb.settings.start_offset_left.y = hb.load_setting("hudbars_start_offset_left_y", "number", -86)
|
||||
hb.settings.start_offset_right.x = hb.load_setting("hudbars_start_offset_right_x", "number", 15)
|
||||
hb.settings.start_offset_right.y = hb.load_setting("hudbars_start_offset_right_y", "number", -86)
|
||||
else
|
||||
hb.settings.start_offset_left.x = hb.load_setting("hudbars_start_statbar_offset_left_x", "number", -258)
|
||||
hb.settings.start_offset_left.y = hb.load_setting("hudbars_start_statbar_offset_left_y", "number", -90)
|
||||
hb.settings.start_offset_right.x = hb.load_setting("hudbars_start_statbar_offset_right_x", "number", 16)
|
||||
hb.settings.start_offset_right.y = hb.load_setting("hudbars_start_statbar_offset_right_y", "number", -90)
|
||||
end
|
||||
-- Modified in MCL2!
|
||||
hb.settings.vmargin = hb.load_setting("hudbars_vmargin", "number", 28)
|
||||
hb.settings.tick = hb.load_setting("hudbars_tick", "number", 0.1)
|
||||
|
||||
-- Experimental setting: Changing this setting is not officially supported, do NOT rely on it!
|
||||
hb.settings.forceload_default_hudbars = hb.load_setting("hudbars_forceload_default_hudbars", "bool", true)
|
||||
|
||||
-- Misc. settings
|
||||
hb.settings.alignment_pattern = hb.load_setting("hudbars_alignment_pattern", "string", "zigzag", {"zigzag", "stack_up", "stack_down"})
|
||||
hb.settings.autohide_breath = hb.load_setting("hudbars_autohide_breath", "bool", true)
|
||||
|
||||
local sorting = minetest.settings:get("hudbars_sorting")
|
||||
if sorting then
|
||||
hb.settings.sorting = {}
|
||||
hb.settings.sorting_reverse = {}
|
||||
for k,v in string.gmatch(sorting, "(%w+)=(%w+)") do
|
||||
hb.settings.sorting[k] = tonumber(v)
|
||||
hb.settings.sorting_reverse[tonumber(v)] = k
|
||||
end
|
||||
else
|
||||
-- Modified in MCL2!
|
||||
hb.settings.sorting = { ["health"] = 0, ["hunger"] = 1, ["armor"] = 2, ["breath"] = 3, ["exhaustion"] = 4, ["saturation"] = 5 }
|
||||
hb.settings.sorting_reverse = {}
|
||||
for k,v in pairs(hb.settings.sorting) do
|
||||
hb.settings.sorting_reverse[tonumber(v)] = k
|
||||
end
|
||||
end
|
|
@ -1,590 +0,0 @@
|
|||
local modname = minetest.get_current_modname()
|
||||
local modpath = minetest.get_modpath(modname)
|
||||
|
||||
local S = minetest.get_translator(modname)
|
||||
local N = function(s) return s end
|
||||
|
||||
local math = math
|
||||
local table = table
|
||||
|
||||
hb = {
|
||||
hudtables = {},
|
||||
-- number of registered HUD bars
|
||||
hudbars_count = 0,
|
||||
-- table which records which HUD bar slots have been “registered” so far; used for automatic positioning
|
||||
registered_slots = {},
|
||||
settings = {},
|
||||
-- Table which contains all players with active default HUD bars (only for internal use)
|
||||
players = {},
|
||||
}
|
||||
|
||||
function hb.load_setting(sname, stype, defaultval, valid_values)
|
||||
local sval
|
||||
if stype == "string" then
|
||||
sval = minetest.settings:get(sname)
|
||||
elseif stype == "bool" then
|
||||
sval = minetest.settings:get_bool(sname)
|
||||
elseif stype == "number" then
|
||||
sval = tonumber(minetest.settings:get(sname))
|
||||
end
|
||||
if sval then
|
||||
if valid_values then
|
||||
local valid = false
|
||||
for i = 1, #valid_values do
|
||||
if sval == valid_values[i] then
|
||||
valid = true
|
||||
end
|
||||
end
|
||||
if not valid then
|
||||
minetest.log("error", "[hudbars] Invalid value for "..sname.."! Using default value ("..tostring(defaultval)..").")
|
||||
return defaultval
|
||||
else
|
||||
return sval
|
||||
end
|
||||
else
|
||||
return sval
|
||||
end
|
||||
else
|
||||
return defaultval
|
||||
end
|
||||
end
|
||||
|
||||
-- Load default settings
|
||||
dofile(modpath.."/default_settings.lua")
|
||||
|
||||
if minetest.get_modpath("mcl_experience") and not minetest.is_creative_enabled("") then
|
||||
-- reserve some space for experience bar:
|
||||
hb.settings.start_offset_left.y = hb.settings.start_offset_left.y - 20
|
||||
hb.settings.start_offset_right.y = hb.settings.start_offset_right.y - 20
|
||||
end
|
||||
|
||||
local function player_exists(player)
|
||||
return player ~= nil and player:is_player()
|
||||
end
|
||||
|
||||
local function make_label(format_string, format_string_config, label, start_value, max_value)
|
||||
local params = {}
|
||||
local order = format_string_config.order
|
||||
for o=1, #order do
|
||||
if order[o] == "label" then
|
||||
table.insert(params, label)
|
||||
elseif order[o] == "value" then
|
||||
if format_string_config.format_value then
|
||||
table.insert(params, string.format(format_string_config.format_value, start_value))
|
||||
else
|
||||
table.insert(params, start_value)
|
||||
end
|
||||
elseif order[o] == "max_value" then
|
||||
if format_string_config.format_max_value then
|
||||
table.insert(params, string.format(format_string_config.format_max_value, max_value))
|
||||
else
|
||||
table.insert(params, max_value)
|
||||
end
|
||||
end
|
||||
end
|
||||
local ret
|
||||
if format_string_config.textdomain then
|
||||
ret = minetest.translate(format_string_config.textdomain, format_string, unpack(params))
|
||||
else
|
||||
ret = S(format_string, unpack(params))
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
function hb.value_to_barlength(value, max)
|
||||
if max == 0 then
|
||||
return 0
|
||||
else
|
||||
if hb.settings.bar_type == "progress_bar" then
|
||||
local x
|
||||
if value < 0 then x=-0.5 else x = 0.5 end
|
||||
local ret = math.modf((value/max) * hb.settings.max_bar_length + x)
|
||||
return ret
|
||||
else
|
||||
local x
|
||||
if value < 0 then x=-0.5 else x = 0.5 end
|
||||
local ret = math.modf((value/max) * hb.settings.statbar_length + x)
|
||||
return ret
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function hb.get_hudtable(identifier)
|
||||
return hb.hudtables[identifier]
|
||||
end
|
||||
|
||||
function hb.get_hudbar_position_index(identifier)
|
||||
if hb.settings.sorting[identifier] then
|
||||
return hb.settings.sorting[identifier]
|
||||
else
|
||||
local i = 0
|
||||
while true do
|
||||
if hb.registered_slots[i] ~= true and hb.settings.sorting_reverse[i] == nil then
|
||||
return i
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function hb.register_hudbar(identifier, text_color, label, textures, direction, default_start_value, default_start_max, default_start_hidden, format_string, format_string_config)
|
||||
minetest.log("action", "hb.register_hudbar: "..tostring(identifier))
|
||||
local hudtable = {}
|
||||
local pos, offset
|
||||
local index = math.floor(hb.get_hudbar_position_index(identifier))
|
||||
hb.registered_slots[index] = true
|
||||
if hb.settings.alignment_pattern == "stack_up" then
|
||||
pos = hb.settings.pos_left
|
||||
offset = {
|
||||
x = direction == 0 and hb.settings.start_offset_left.x or -hb.settings.start_offset_right.x,
|
||||
y = hb.settings.start_offset_left.y - hb.settings.vmargin * index
|
||||
}
|
||||
elseif hb.settings.alignment_pattern == "stack_down" then
|
||||
pos = hb.settings.pos_left
|
||||
offset = {
|
||||
x = direction == 0 and hb.settings.start_offset_right.x or -hb.settings.start_offset_left.x,
|
||||
y = hb.settings.start_offset_left.y + hb.settings.vmargin * index
|
||||
}
|
||||
else -- zigzag
|
||||
if index % 2 == 0 then
|
||||
pos = hb.settings.pos_left
|
||||
offset = {
|
||||
-- -(24+18) = -42. using linear eq, -42 = -258m - 24.
|
||||
x = direction == 0 and hb.settings.start_offset_left.x or (-42+24)/(-258.0) * hb.settings.start_offset_left.x - 24,
|
||||
y = hb.settings.start_offset_left.y - hb.settings.vmargin * (index/2)
|
||||
}
|
||||
else
|
||||
pos = hb.settings.pos_right
|
||||
offset = {
|
||||
-- 24*10+30 - 24 = 234. using linear eq, 234 = 16m - 24.
|
||||
x = direction == 0 and hb.settings.start_offset_right.x or (234+24)/(16) * hb.settings.start_offset_right.x - 24,
|
||||
y = hb.settings.start_offset_right.y - hb.settings.vmargin * ((index-1)/2)
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
if format_string == nil then
|
||||
format_string = N("@1: @2/@3")
|
||||
end
|
||||
if format_string_config == nil then
|
||||
format_string_config = {}
|
||||
end
|
||||
if format_string_config.order == nil then
|
||||
format_string_config.order = { "label", "value", "max_value" }
|
||||
end
|
||||
if format_string_config.format_value == nil then
|
||||
format_string_config.format_value = "%d"
|
||||
end
|
||||
if format_string_config.format_max_value == nil then
|
||||
format_string_config.format_max_value = "%d"
|
||||
end
|
||||
|
||||
function hudtable.add_all(player, hudtable, start_value, start_max, start_hidden)
|
||||
if start_value == nil then start_value = hudtable.default_start_value end
|
||||
if start_max == nil then start_max = hudtable.default_start_max end
|
||||
if start_hidden == nil then start_hidden = hudtable.default_start_hidden end
|
||||
local ids = {}
|
||||
local state = {}
|
||||
local name = player:get_player_name()
|
||||
local bgscale, iconscale, text, barnumber, bgiconnumber
|
||||
|
||||
if start_max == 0 or start_hidden then
|
||||
bgscale = { x=0, y=0 }
|
||||
else
|
||||
bgscale = { x=1, y=1 }
|
||||
end
|
||||
if start_hidden then
|
||||
iconscale = { x=0, y=0 }
|
||||
barnumber = 0
|
||||
bgiconnumber = 0
|
||||
text = ""
|
||||
else
|
||||
iconscale = { x=1, y=1 }
|
||||
barnumber = hb.value_to_barlength(start_value, start_max)
|
||||
bgiconnumber = hb.settings.statbar_length
|
||||
text = make_label(format_string, format_string_config, label, start_value, start_max)
|
||||
end
|
||||
|
||||
if hb.settings.bar_type == "progress_bar" then
|
||||
ids.bg = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = pos,
|
||||
scale = bgscale,
|
||||
text = "hudbars_bar_background.png",
|
||||
alignment = {x=1,y=1},
|
||||
offset = { x = offset.x - 1, y = offset.y - 1 },
|
||||
z_index = 0,
|
||||
})
|
||||
if textures.icon then
|
||||
ids.icon = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = pos,
|
||||
scale = iconscale,
|
||||
text = textures.icon,
|
||||
alignment = {x=-1,y=1},
|
||||
offset = { x = offset.x - 3, y = offset.y },
|
||||
z_index = 1,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
local bar_image, bgicon, bar_size
|
||||
if hb.settings.bar_type == "progress_bar" then
|
||||
bar_image = textures.bar
|
||||
-- NOTE: Intentionally set to nil. For some reason, on some systems,
|
||||
-- the progress bar is displaced when the bar_size is set explicitly here.
|
||||
-- On the other hand, setting this to nil is deprecated in MT 5.0.0 due to
|
||||
-- a debug log warning, but nothing is explained in lua_api.txt.
|
||||
-- This section is a potential bug magnet, please watch with care!
|
||||
-- The size of the bar image is expected to be exactly 2×16 pixels.
|
||||
bar_size = nil
|
||||
elseif hb.settings.bar_type == "statbar_classic" or hb.settings.bar_type == "statbar_modern" then
|
||||
bar_image = textures.icon
|
||||
bgicon = textures.bgicon
|
||||
bar_size = {x=24, y=24}
|
||||
end
|
||||
|
||||
local text2
|
||||
if hb.settings.bar_type == "statbar_modern" then
|
||||
text2 = bgicon
|
||||
end
|
||||
|
||||
ids.bar = player:hud_add({
|
||||
hud_elem_type = "statbar",
|
||||
position = pos,
|
||||
text = bar_image,
|
||||
text2 = text2,
|
||||
number = barnumber,
|
||||
item = bgiconnumber,
|
||||
alignment = {x=-1,y=-1},
|
||||
offset = offset,
|
||||
direction = direction,
|
||||
size = bar_size,
|
||||
z_index = 1,
|
||||
})
|
||||
if hb.settings.bar_type == "progress_bar" then
|
||||
ids.text = player:hud_add({
|
||||
hud_elem_type = "text",
|
||||
position = pos,
|
||||
text = text,
|
||||
alignment = {x=1,y=1},
|
||||
number = text_color,
|
||||
direction = direction,
|
||||
offset = { x = offset.x + 2, y = offset.y - 1},
|
||||
z_index = 2,
|
||||
})
|
||||
end
|
||||
-- Do not forget to update hb.get_hudbar_state if you add new fields to the state table
|
||||
state.hidden = start_hidden
|
||||
state.value = start_value
|
||||
state.max = start_max
|
||||
state.text = text
|
||||
state.barlength = hb.value_to_barlength(start_value, start_max)
|
||||
|
||||
local main_error_text =
|
||||
"[hudbars] Bad initial values of HUD bar identifier “"..tostring(identifier).."” for player "..name..". "
|
||||
|
||||
if start_max < start_value then
|
||||
minetest.log("error", main_error_text.."start_max ("..start_max..") is smaller than start_value ("..start_value..")!")
|
||||
end
|
||||
if start_max < 0 then
|
||||
minetest.log("error", main_error_text.."start_max ("..start_max..") is smaller than 0!")
|
||||
end
|
||||
if start_value < 0 then
|
||||
minetest.log("error", main_error_text.."start_value ("..start_value..") is smaller than 0!")
|
||||
end
|
||||
|
||||
hb.hudtables[identifier].hudids[name] = ids
|
||||
hb.hudtables[identifier].hudstate[name] = state
|
||||
end
|
||||
|
||||
hudtable.identifier = identifier
|
||||
hudtable.format_string = format_string
|
||||
hudtable.format_string_config = format_string_config
|
||||
hudtable.label = label
|
||||
hudtable.hudids = {}
|
||||
hudtable.hudstate = {}
|
||||
hudtable.default_start_hidden = default_start_hidden
|
||||
hudtable.default_start_value = default_start_value
|
||||
hudtable.default_start_max = default_start_max
|
||||
|
||||
hb.hudbars_count= hb.hudbars_count + 1
|
||||
|
||||
hb.hudtables[identifier] = hudtable
|
||||
end
|
||||
|
||||
function hb.init_hudbar(player, identifier, start_value, start_max, start_hidden)
|
||||
if not player_exists(player) then return false end
|
||||
local hudtable = hb.get_hudtable(identifier)
|
||||
hb.hudtables[identifier].add_all(player, hudtable, start_value, start_max, start_hidden)
|
||||
return true
|
||||
end
|
||||
|
||||
function hb.change_hudbar(player, identifier, new_value, new_max_value, new_icon, new_bgicon, new_bar, new_label, new_text_color)
|
||||
if new_value == nil and new_max_value == nil and new_icon == nil and new_bgicon == nil and new_bar == nil and new_label == nil and new_text_color == nil then
|
||||
return true
|
||||
end
|
||||
if not player_exists(player) then
|
||||
return false
|
||||
end
|
||||
|
||||
local name = player:get_player_name()
|
||||
local hudtable = hb.get_hudtable(identifier)
|
||||
if not hudtable.hudstate[name] then
|
||||
return false
|
||||
end
|
||||
local value_changed, max_changed = false, false
|
||||
|
||||
if new_value then
|
||||
if new_value ~= hudtable.hudstate[name].value then
|
||||
hudtable.hudstate[name].value = new_value
|
||||
value_changed = true
|
||||
end
|
||||
else
|
||||
new_value = hudtable.hudstate[name].value
|
||||
end
|
||||
if new_max_value then
|
||||
if new_max_value ~= hudtable.hudstate[name].max then
|
||||
hudtable.hudstate[name].max = new_max_value
|
||||
max_changed = true
|
||||
end
|
||||
else
|
||||
new_max_value = hudtable.hudstate[name].max
|
||||
end
|
||||
|
||||
if hb.settings.bar_type == "progress_bar" then
|
||||
if new_icon and hudtable.hudids[name].icon then
|
||||
player:hud_change(hudtable.hudids[name].icon, "text", new_icon)
|
||||
end
|
||||
if new_bgicon and hudtable.hudids[name].bgicon then
|
||||
player:hud_change(hudtable.hudids[name].bgicon, "text", new_bgicon)
|
||||
end
|
||||
if new_bar then
|
||||
player:hud_change(hudtable.hudids[name].bar , "text", new_bar)
|
||||
end
|
||||
if new_label then
|
||||
hudtable.label = new_label
|
||||
local new_text = make_label(hudtable.format_string, hudtable.format_string_config, new_label, hudtable.hudstate[name].value, hudtable.hudstate[name].max)
|
||||
player:hud_change(hudtable.hudids[name].text, "text", new_text)
|
||||
end
|
||||
if new_text_color then
|
||||
player:hud_change(hudtable.hudids[name].text, "number", new_text_color)
|
||||
end
|
||||
|
||||
else
|
||||
if new_icon and hudtable.hudids[name].bar then
|
||||
player:hud_change(hudtable.hudids[name].bar, "text", new_icon)
|
||||
end
|
||||
if new_bgicon and hudtable.hudids[name].bg then
|
||||
player:hud_change(hudtable.hudids[name].bg, "text", new_bgicon)
|
||||
end
|
||||
end
|
||||
|
||||
local main_error_text =
|
||||
"[hudbars] Bad call to hb.change_hudbar, identifier: “"..tostring(identifier).."”, player name: “"..name.."”. "
|
||||
if new_max_value < new_value then
|
||||
minetest.log("error", main_error_text.."new_max_value ("..new_max_value..") is smaller than new_value ("..new_value..")!")
|
||||
end
|
||||
if new_max_value < 0 then
|
||||
minetest.log("error", main_error_text.."new_max_value ("..new_max_value..") is smaller than 0!")
|
||||
end
|
||||
if new_value < 0 then
|
||||
minetest.log("error", main_error_text.."new_value ("..new_value..") is smaller than 0!")
|
||||
end
|
||||
|
||||
if hudtable.hudstate[name].hidden == false then
|
||||
if max_changed and hb.settings.bar_type == "progress_bar" then
|
||||
if hudtable.hudstate[name].max == 0 then
|
||||
player:hud_change(hudtable.hudids[name].bg, "scale", {x=0,y=0})
|
||||
else
|
||||
player:hud_change(hudtable.hudids[name].bg, "scale", {x=1,y=1})
|
||||
end
|
||||
end
|
||||
|
||||
if value_changed or max_changed then
|
||||
local new_barlength = hb.value_to_barlength(new_value, new_max_value)
|
||||
if new_barlength ~= hudtable.hudstate[name].barlength then
|
||||
player:hud_change(hudtable.hudids[name].bar, "number", hb.value_to_barlength(new_value, new_max_value))
|
||||
hudtable.hudstate[name].barlength = new_barlength
|
||||
end
|
||||
|
||||
if hb.settings.bar_type == "progress_bar" then
|
||||
local new_text = make_label(hudtable.format_string, hudtable.format_string_config, hudtable.label, new_value, new_max_value)
|
||||
if new_text ~= hudtable.hudstate[name].text then
|
||||
player:hud_change(hudtable.hudids[name].text, "text", new_text)
|
||||
hudtable.hudstate[name].text = new_text
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function hb.hide_hudbar(player, identifier)
|
||||
if not player_exists(player) then return false end
|
||||
local name = player:get_player_name()
|
||||
local hudtable = hb.get_hudtable(identifier)
|
||||
if hudtable == nil then return false end
|
||||
if hudtable.hudstate[name].hidden == true then return true end
|
||||
if hb.settings.bar_type == "progress_bar" then
|
||||
if hudtable.hudids[name].icon then
|
||||
player:hud_change(hudtable.hudids[name].icon, "scale", {x=0,y=0})
|
||||
end
|
||||
player:hud_change(hudtable.hudids[name].bg, "scale", {x=0,y=0})
|
||||
player:hud_change(hudtable.hudids[name].text, "text", "")
|
||||
end
|
||||
player:hud_change(hudtable.hudids[name].bar, "number", 0)
|
||||
player:hud_change(hudtable.hudids[name].bar, "item", 0)
|
||||
hudtable.hudstate[name].hidden = true
|
||||
return true
|
||||
end
|
||||
|
||||
function hb.unhide_hudbar(player, identifier)
|
||||
if not player_exists(player) then return false end
|
||||
local name = player:get_player_name()
|
||||
local hudtable = hb.get_hudtable(identifier)
|
||||
if hudtable == nil then return false end
|
||||
if hudtable.hudstate[name].hidden == false then return true end
|
||||
local value = hudtable.hudstate[name].value
|
||||
local max = hudtable.hudstate[name].max
|
||||
if hb.settings.bar_type == "progress_bar" then
|
||||
if hudtable.hudids[name].icon then
|
||||
player:hud_change(hudtable.hudids[name].icon, "scale", {x=1,y=1})
|
||||
end
|
||||
if hudtable.hudstate[name].max ~= 0 then
|
||||
player:hud_change(hudtable.hudids[name].bg, "scale", {x=1,y=1})
|
||||
end
|
||||
player:hud_change(hudtable.hudids[name].text, "text", make_label(hudtable.format_string, hudtable.format_string_config, hudtable.label, value, max))
|
||||
elseif hb.settings.bar_type == "statbar_modern" then
|
||||
player:hud_change(hudtable.hudids[name].bar, "scale", {x=1,y=1})
|
||||
end
|
||||
player:hud_change(hudtable.hudids[name].bar, "number", hb.value_to_barlength(value, max))
|
||||
player:hud_change(hudtable.hudids[name].bar, "item", hb.value_to_barlength(max, max))
|
||||
hudtable.hudstate[name].hidden = false
|
||||
return true
|
||||
end
|
||||
|
||||
function hb.get_hudbar_state(player, identifier)
|
||||
if not player_exists(player) then return nil end
|
||||
local ref = hb.get_hudtable(identifier).hudstate[player:get_player_name()]
|
||||
-- Do not forget to update this chunk of code in case the state changes
|
||||
local copy = {
|
||||
hidden = ref.hidden,
|
||||
value = ref.value,
|
||||
max = ref.max,
|
||||
text = ref.text,
|
||||
barlength = ref.barlength,
|
||||
}
|
||||
return copy
|
||||
end
|
||||
|
||||
function hb.get_hudbar_identifiers()
|
||||
local ids = {}
|
||||
for id, _ in pairs(hb.hudtables) do
|
||||
table.insert(ids, id)
|
||||
end
|
||||
return ids
|
||||
end
|
||||
|
||||
--register built-in HUD bars
|
||||
if minetest.settings:get_bool("enable_damage") or hb.settings.forceload_default_hudbars then
|
||||
hb.register_hudbar("health", 0xFFFFFF, S("Health"), { bar = "hudbars_bar_health.png", icon = "hudbars_icon_health.png", bgicon = "hudbars_bgicon_health.png" }, 0, 20, 20, false)
|
||||
hb.register_hudbar("breath", 0xFFFFFF, S("Breath"), { bar = "hudbars_bar_breath.png", icon = "hudbars_icon_breath.png", bgicon = "hudbars_bgicon_breath.png" }, 1, 10, 10, true)
|
||||
end
|
||||
|
||||
local function hide_builtin(player)
|
||||
local flags = player:hud_get_flags()
|
||||
flags.healthbar = false
|
||||
flags.breathbar = false
|
||||
player:hud_set_flags(flags)
|
||||
end
|
||||
|
||||
|
||||
local function custom_hud(player)
|
||||
if minetest.settings:get_bool("enable_damage") or hb.settings.forceload_default_hudbars then
|
||||
local hide
|
||||
if minetest.settings:get_bool("enable_damage") then
|
||||
hide = false
|
||||
else
|
||||
hide = true
|
||||
end
|
||||
local hp = player:get_hp()
|
||||
local hp_max = player:get_properties().hp_max
|
||||
hb.init_hudbar(player, "health", math.min(hp, hp_max), hp_max, hide)
|
||||
local breath = player:get_breath()
|
||||
local breath_max = player:get_properties().breath_max
|
||||
local hide_breath
|
||||
if breath >= breath_max and hb.settings.autohide_breath == true then hide_breath = true else hide_breath = false end
|
||||
hb.init_hudbar(player, "breath", math.min(breath, breath_max), breath_max, hide_breath or hide)
|
||||
end
|
||||
end
|
||||
|
||||
local function update_health(player)
|
||||
local hp_max = player:get_properties().hp_max
|
||||
hb.change_hudbar(player, "health", player:get_hp(), hp_max)
|
||||
end
|
||||
|
||||
-- update built-in HUD bars
|
||||
local function update_hud(player, has_damage)
|
||||
if not player_exists(player) then return end
|
||||
if has_damage then
|
||||
if hb.settings.forceload_default_hudbars then
|
||||
hb.unhide_hudbar(player, "health")
|
||||
end
|
||||
--air
|
||||
local breath_max = player:get_properties().breath_max
|
||||
local breath = player:get_breath()
|
||||
|
||||
if breath >= breath_max and hb.settings.autohide_breath == true then
|
||||
hb.hide_hudbar(player, "breath")
|
||||
else
|
||||
hb.unhide_hudbar(player, "breath")
|
||||
hb.change_hudbar(player, "breath", math.min(breath, breath_max), breath_max)
|
||||
end
|
||||
--health
|
||||
update_health(player)
|
||||
elseif hb.settings.forceload_default_hudbars then
|
||||
hb.hide_hudbar(player, "health")
|
||||
hb.hide_hudbar(player, "breath")
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_on_player_hpchange(function(player)
|
||||
if hb.players[player:get_player_name()] then
|
||||
update_health(player)
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_respawnplayer(function(player)
|
||||
update_health(player)
|
||||
hb.hide_hudbar(player, "breath")
|
||||
end)
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
hide_builtin(player)
|
||||
custom_hud(player)
|
||||
hb.players[player:get_player_name()] = player
|
||||
end)
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
hb.players[player:get_player_name()] = nil
|
||||
end)
|
||||
|
||||
local main_timer = 0
|
||||
local timer = 0
|
||||
minetest.register_globalstep(function(dtime)
|
||||
main_timer = main_timer + dtime
|
||||
timer = timer + dtime
|
||||
if main_timer > hb.settings.tick or timer > 4 then
|
||||
if main_timer > hb.settings.tick then main_timer = 0 end
|
||||
-- only proceed if damage is enabled
|
||||
local has_dmg = minetest.settings:get_bool("enable_damage")
|
||||
if has_dmg or hb.settings.forceload_default_hudbars then
|
||||
for _, player in pairs(hb.players) do
|
||||
-- update all hud elements
|
||||
update_hud(player, has_dmg)
|
||||
end
|
||||
end
|
||||
end
|
||||
if timer > 4 then timer = 0 end
|
||||
end)
|
|
@ -1,4 +0,0 @@
|
|||
# textdomain: hudbars
|
||||
Health=Leben
|
||||
Breath=Atem
|
||||
@1: @2/@3=@1: @2/@3
|
|
@ -1,4 +0,0 @@
|
|||
# textdomain: hudbars
|
||||
Health=Salud
|
||||
Breath=Aliento
|
||||
@1: @2/@3=@1: @2/@3
|
|
@ -1,6 +0,0 @@
|
|||
# textdomain: hudbars
|
||||
Health=Santé
|
||||
Breath=Breath
|
||||
|
||||
# Default format string for progress bar-style HUD bars, e.g. “Health 5/20”
|
||||
@1: @2/@3=@1: @2/@3
|
|
@ -1,6 +0,0 @@
|
|||
# textdomain: hudbars
|
||||
Health=Salute
|
||||
Breath=Ossigeno
|
||||
|
||||
# Default format string for progress bar-style HUD bars, e.g. “Health 5/20”
|
||||
@1: @2/@3=@1: @2/@3
|
|
@ -1,4 +0,0 @@
|
|||
# textdomain: hudbars
|
||||
Health=Kesihatan
|
||||
Breath=Nafas
|
||||
@1: @2/@3=@1: @2/@3
|
|
@ -1,6 +0,0 @@
|
|||
# textdomain: hudbars
|
||||
Health=Gezondheid
|
||||
Breath=Adem
|
||||
|
||||
# Default format string for progress bar-style HUD bars, e.g. “Health 5/20”
|
||||
@1: @2/@3=@1: @2/@3
|
|
@ -1,7 +0,0 @@
|
|||
# textdomain: hudbars
|
||||
Health=Życie
|
||||
Breath=Tlen
|
||||
|
||||
# Default format string for progress bar-style HUD bars, e.g. “Health 5/20”
|
||||
@1: @2/@3=@1: @2/@3
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
# textdomain: hudbars
|
||||
Health=Saude
|
||||
Breath=Folego
|
||||
|
||||
# Formato de string padrão para progresso bar-style de barras do HUD, por exemplo “Saude 5/20”
|
||||
@1: @2/@3=@1: @2/@3
|
|
@ -1,4 +0,0 @@
|
|||
# textdomain: hudbars
|
||||
Health=HP
|
||||
Breath=дыхание
|
||||
@1: @2/@3=@1: @2/@3
|
|
@ -1,4 +0,0 @@
|
|||
# textdomain: hudbars
|
||||
Health=Can
|
||||
Breath=Nefes
|
||||
@1: @2/@3=@1: @2/@3
|
|
@ -1,6 +0,0 @@
|
|||
# textdomain: hudbars
|
||||
Health=生命
|
||||
Breath=氧氣
|
||||
|
||||
# Default format string for progress bar-style HUD bars, e.g. “Health 5/20”
|
||||
@1: @2/@3=
|
|
@ -1,6 +0,0 @@
|
|||
# textdomain: hudbars
|
||||
Health=
|
||||
Breath=
|
||||
|
||||
# Default format string for progress bar-style HUD bars, e.g. “Health 5/20”
|
||||
@1: @2/@3=
|
|
@ -1,3 +0,0 @@
|
|||
name = hudbars
|
||||
author = Wuzzy
|
||||
description = Replaces the health and breath symbols in the HUD by “progress bars” and shows exact values. Other mods can add more progress bars for custom player stats.
|
|
@ -1,119 +0,0 @@
|
|||
[Appearance]
|
||||
# Specifies how the value indicators (i.e. health, breah, etc.) look. There are 3 styles
|
||||
# available. You can choose between the default progress-bar-like bars and the good
|
||||
# old statbars like you know from vanilla Minetest.
|
||||
# These values are possible:
|
||||
# - progress_bar: A horizontal progress-bar-like bar with a label, showing numerical value
|
||||
# (current, maximum), and an icon. These bars usually convey the most
|
||||
# information. This is the default and recommended value.
|
||||
# - statbar_classic: Classic statbar, like in vanilla Minetest. Made out of up to 20
|
||||
# half-symbols. Those bars represent the vague ratio between
|
||||
# the current value and the maximum value. 1 half-symbol stands for
|
||||
# approximately 5% of the maximum value.
|
||||
# - statbar_modern: Like the classic statbar, but also supports background images, this
|
||||
# kind of statbar may be considered to be more user-friendly than the
|
||||
# classic statbar. This bar type closely resembles the mod
|
||||
# “Better HUD” [hud] by BlockMen.
|
||||
hudbars_bar_type (HUD bars style) enum progress_bar progress_bar,statbar_classic,statbar_modern
|
||||
|
||||
|
||||
# If enabled (default), the breath indicators in the HUD will be automatically hidden shortly
|
||||
# after the breath has been filled up. Otherwise, the breath will always be displayed.
|
||||
hudbars_autohide_breath (Automatically hide breath indicators) bool true
|
||||
|
||||
# This setting changes the way the HUD bars are ordered on the display. You can choose
|
||||
# between a zig-zag pattern (default) or a vertically stacked pattern.
|
||||
# The following values are allowed:
|
||||
# - zigzag: Starting from the left bottom, the next is right from the first,
|
||||
# the next is above the first, the next is right of the third, etc.
|
||||
# - stack_up: The HUD bars are stacked vertically, going upwards.
|
||||
# - stack_down: The HUD bars are stacked vertically, going downwards.
|
||||
hudbars_alignment_pattern (HUD bars alignment pattern) enum zigzag zigzag,stack_up,stack_down
|
||||
|
||||
# This setting allows you to specify the order of the HUD bars explicitly. If left empty
|
||||
# (the default), the health and breath indicators come first, additional indicators
|
||||
# may appear in any order. This setting is quite technical and normal users probably do not
|
||||
# need to worry about it.
|
||||
#
|
||||
# Syntax:
|
||||
# The setting has to be specified as a comma-seperated list of key=value pairs, where a key
|
||||
# refers to the identifier of a HUD bar and the value refers to the slot number of where the
|
||||
# HUD bar should be placed. The slot number must be an integer greater of equal to 0. Where
|
||||
# the HUD bars will be displayed exactly depends on the alignment pattern being used.
|
||||
# All HUD bars to which no order value has been applied will fill in all slots which have
|
||||
# not been occupied by the HUD bars specified in this setting, the slots will be filled in
|
||||
# from the lowest slot number.
|
||||
# Note that the order of those remaining HUD bars is not fixed, it basically just boils
|
||||
# down on which mod “came” first. Don't worry, the mod will still work perfectly fine, this
|
||||
# setting is entirely optional.
|
||||
# The identifier for the health bar is “health” and the identifier for the breath bar is
|
||||
# “breath”. For other HUD bars, you have to learn it from the mod which is supplying them.
|
||||
#
|
||||
# Be careful not to use slot indices twice, or else different HUD bars will be drawn over
|
||||
# each other!
|
||||
#
|
||||
# Example: “breath=0, health=1”
|
||||
# This makes the breath bar first and the health bar second, which is the opposite order
|
||||
# of the default one.
|
||||
hudbars_sorting (HUD bars order) string
|
||||
|
||||
[Positions and offsets]
|
||||
# Horizontal (x) main position of the HUD bars over the entire screen.
|
||||
# 0.0 is left-most, 1.0 is right-most.
|
||||
# For the zig-zag alignment pattern, this is for the left HUD bars.
|
||||
hudbars_pos_left_x (Left HUD bar screen x position) float 0.5 0.0 1.0
|
||||
# Vertical (y) main position of the HUD bars over the entire screen.
|
||||
# 0.0 is top, 1.0 is bottom.
|
||||
# For the zig-zag alignment pattern, this is for the left HUD bars.
|
||||
hudbars_pos_left_y (Left HUD bar screen y position) float 1.0 0.0 1.0
|
||||
# Horizontal (x) main position of the right HUD bars over the entire screen.
|
||||
# 0.0 is left-most, 1.0 is right-most.
|
||||
# Only used for the zig-zag alignment pattern.
|
||||
hudbars_pos_right_x (Right HUD bar screen x position) float 0.5 0.0 1.0
|
||||
# Vertical main position (y) of the right HUD bars over the entire screen.
|
||||
# 0.0 is top, 1.0 is bottom.
|
||||
# Only used for the zig-zag alignment pattern.
|
||||
hudbars_pos_right_y (Right HUD bar screen y position) float 1.0 0.0 1.0
|
||||
|
||||
# Precise x offset in pixels from the basic screen x position of the HUD bars.
|
||||
# For the zig-zag alignment pattern, this is for the left HUD bars.
|
||||
# This setting is used for the progress bar HUD bar style.
|
||||
hudbars_start_offset_left_x (Left HUD bar x offset) int -175
|
||||
# Precise y offset in pixels from the basic screen y position of the HUD bars.
|
||||
# For the zig-zag alignment pattern, this is for the left HUD bars.
|
||||
# This setting is used for the progress bar HUD bar style.
|
||||
hudbars_start_offset_left_y (Left HUD bar y offset) int -86
|
||||
# Precise x offset in pixels from the basic screen x position of the right HUD bars.
|
||||
# Only used for the zig-zag alignment pattern.
|
||||
# This setting is used for the progress bar HUD bar style.
|
||||
hudbars_start_offset_right_x (Right HUD bar x offset) int 15
|
||||
# Precise y offset in pixels from the basic screen y position of the right HUD bars.
|
||||
# Only used for the zig-zag alignment pattern.
|
||||
# This setting is used for the progress bar HUD bar style.
|
||||
hudbars_start_offset_right_y (Right HUD bar y offset) int -86
|
||||
|
||||
# Precise x offset in pixels from the basic screen x position of the HUD statbars.
|
||||
# For the zig-zag alignment pattern, this is for the left HUD statbars.
|
||||
# This setting is used for the classic and modern statbar styles.
|
||||
hudbars_start_statbar_offset_left_x (Left HUD statbar x offset) int -265
|
||||
# Precise y offset in pixels from the basic screen y position of the HUD statbars.
|
||||
# For the zig-zag alignment pattern, this is for the left HUD statbars.
|
||||
# This setting is used for the classic and modern statbar styles.
|
||||
hudbars_start_statbar_offset_left_y (Left HUD statbar y offset) int -90
|
||||
# Precise x offset in pixels from the basic screen x position of the right HUD statbars.
|
||||
# Only used for the zig-zag alignment pattern.
|
||||
# This setting is used for the classic and modern statbar styles.
|
||||
hudbars_start_statbar_offset_right_x (Right HUD statbar x offset) int 25
|
||||
# Precise y offset in pixels from the basic screen y position of the right HUD statbars.
|
||||
# Only used for the zig-zag alignment pattern.
|
||||
# This setting is used for the classic and modern statbar styles.
|
||||
hudbars_start_statbar_offset_right_y (Right HUD statbar y offset) int -90
|
||||
|
||||
# The vertical distance between two HUD bars, in pixels.
|
||||
hudbars_vmargin (Vertical distance between HUD bars) int 24 0
|
||||
|
||||
[Performance]
|
||||
# The of seconds which need to pass before the server updates the default HUD bars
|
||||
# (health and breath). Increase this number if you have a slow server or a slow network
|
||||
# connection and experience performance problems.
|
||||
hudbars_tick (Default HUD bars update interval) float 0.1 0.0 4.0
|
Before Width: | Height: | Size: 140 B |
Before Width: | Height: | Size: 80 B |
Before Width: | Height: | Size: 93 B |
Before Width: | Height: | Size: 118 B |
Before Width: | Height: | Size: 895 B |
Before Width: | Height: | Size: 902 B |
Before Width: | Height: | Size: 903 B |
|
@ -1,26 +0,0 @@
|
|||
# MineClone 2 HUD bar for `mcl_armor` [`mcl_hbarmor`]
|
||||
|
||||
## Description
|
||||
This mod adds a simple HUD bar which displays the player's armor points.
|
||||
The players has 0-20 armor points.
|
||||
|
||||
The armor bar is hidden if the player wears no armor.
|
||||
|
||||
## Licensing
|
||||
This mod is entirly free softare.
|
||||
|
||||
### Source code
|
||||
License: MIT License (see below)
|
||||
|
||||
### Textures
|
||||
|
||||
See MineClone 2 license.
|
||||
|
||||
### MIT License
|
||||
Everything else is under the MIT License:
|
||||
© Copyright BlockMen (2013-2014)
|
||||
|
||||
This program is free software. It comes without any warranty, to
|
||||
the extent permitted by applicable law. You can redistribute it
|
||||
and/or modify it under the terms of the MIT License.
|
||||
See <https://opensource.org/licenses/MIT> for more details.
|
|
@ -1,132 +0,0 @@
|
|||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
|
||||
local math = math
|
||||
local tonumber = tonumber
|
||||
|
||||
local get_connected_players = minetest.get_connected_players
|
||||
|
||||
local mcl_hbarmor = {
|
||||
-- HUD statbar values
|
||||
armor = {},
|
||||
-- Stores if player's HUD bar has been initialized so far.
|
||||
player_active = {},
|
||||
-- Time difference in seconds between updates to the HUD armor bar.
|
||||
-- Increase this number for slow servers.
|
||||
tick = 0.1,
|
||||
-- If true, the armor bar is hidden when the player does not wear any armor
|
||||
autohide = true,
|
||||
}
|
||||
|
||||
local tick_config = minetest.settings:get("mcl_hbarmor_tick")
|
||||
|
||||
if tonumber(tick_config) then
|
||||
mcl_hbarmor.tick = tonumber(tick_config)
|
||||
end
|
||||
|
||||
|
||||
local function must_hide(playername, arm)
|
||||
return arm == 0
|
||||
end
|
||||
|
||||
local function arm_printable(arm)
|
||||
return math.ceil(math.floor(arm+0.5))
|
||||
end
|
||||
|
||||
local function custom_hud(player)
|
||||
local name = player:get_player_name()
|
||||
|
||||
if minetest.settings:get_bool("enable_damage") then
|
||||
local ret = mcl_hbarmor.get_armor(player)
|
||||
if ret == false then
|
||||
minetest.log("error", "[mcl_hbarmor] Call to mcl_hbarmor.get_armor in custom_hud returned with false!")
|
||||
return
|
||||
end
|
||||
local arm = tonumber(mcl_hbarmor.armor[name])
|
||||
if not arm then
|
||||
arm = 0
|
||||
end
|
||||
local hide
|
||||
if mcl_hbarmor.autohide then
|
||||
hide = must_hide(name, arm)
|
||||
else
|
||||
hide = false
|
||||
end
|
||||
hb.init_hudbar(player, "armor", arm_printable(arm), nil, hide)
|
||||
end
|
||||
end
|
||||
|
||||
--register and define armor HUD bar
|
||||
hb.register_hudbar("armor", 0xFFFFFF, S("Armor"), { icon = "hbarmor_icon.png", bgicon = "hbarmor_bgicon.png", bar = "hbarmor_bar.png" }, 0, 0, 20, mcl_hbarmor.autohide)
|
||||
|
||||
function mcl_hbarmor.get_armor(player)
|
||||
local name = player:get_player_name()
|
||||
local pts = player:get_meta():get_int("mcl_armor:armor_points")
|
||||
if not pts then
|
||||
return false
|
||||
else
|
||||
mcl_hbarmor.set_armor(name, pts)
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function mcl_hbarmor.set_armor(player_name, pts)
|
||||
mcl_hbarmor.armor[player_name] = math.max(0, math.min(20, pts))
|
||||
end
|
||||
|
||||
-- update hud elemtens if value has changed
|
||||
local function update_hud(player)
|
||||
local name = player:get_player_name()
|
||||
--armor
|
||||
local arm = tonumber(mcl_hbarmor.armor[name])
|
||||
if not arm then
|
||||
arm = 0
|
||||
mcl_hbarmor.armor[name] = 0
|
||||
end
|
||||
if mcl_hbarmor.autohide then
|
||||
-- hide armor bar completely when there is none
|
||||
if must_hide(name, arm) then
|
||||
hb.hide_hudbar(player, "armor")
|
||||
else
|
||||
hb.change_hudbar(player, "armor", arm_printable(arm))
|
||||
hb.unhide_hudbar(player, "armor")
|
||||
end
|
||||
else
|
||||
hb.change_hudbar(player, "armor", arm_printable(arm))
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_on_joinplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
custom_hud(player)
|
||||
mcl_hbarmor.player_active[name] = true
|
||||
end)
|
||||
|
||||
minetest.register_on_leaveplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
mcl_hbarmor.player_active[name] = false
|
||||
end)
|
||||
|
||||
local main_timer = 0
|
||||
local timer = 0
|
||||
minetest.register_globalstep(function(dtime)
|
||||
--TODO: replace this by playerglobalstep API then implemented
|
||||
main_timer = main_timer + dtime
|
||||
timer = timer + dtime
|
||||
if main_timer > mcl_hbarmor.tick or timer > 4 then
|
||||
if minetest.settings:get_bool("enable_damage") then
|
||||
if main_timer > mcl_hbarmor.tick then main_timer = 0 end
|
||||
for _,player in pairs(get_connected_players()) do
|
||||
local name = player:get_player_name()
|
||||
if mcl_hbarmor.player_active[name] == true then
|
||||
local ret = mcl_hbarmor.get_armor(player)
|
||||
if ret == false then
|
||||
minetest.log("error", "[mcl_hbarmor] Call to mcl_hbarmor.get_armor in globalstep returned with false!")
|
||||
end
|
||||
-- update all hud elements
|
||||
update_hud(player)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if timer > 4 then timer = 0 end
|
||||
end)
|
|
@ -1,2 +0,0 @@
|
|||
# textdomain:hbarmor
|
||||
Armor=Panzerung
|
|
@ -1,2 +0,0 @@
|
|||
# textdomain:hbarmor
|
||||
Armor=Armadura
|
|
@ -1,2 +0,0 @@
|
|||
# textdomain:hbarmor
|
||||
Armor=Armure
|
|
@ -1,2 +0,0 @@
|
|||
# textdomain:hbarmor
|
||||
Armor=Armatura
|
|
@ -1,2 +0,0 @@
|
|||
# textdomain:hbarmor
|
||||
Armor=Защита
|
|
@ -1,3 +0,0 @@
|
|||
# textdomain:hbarmor
|
||||
Armor=Zbroja
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
# textdomain:hbarmor
|
||||
Armor=防禦點數
|
|
@ -1,2 +0,0 @@
|
|||
# textdomain:hbarmor
|
||||
Armor=
|
|
@ -1,4 +0,0 @@
|
|||
name = mcl_hbarmor
|
||||
author = BlockMen
|
||||
description = Adds a HUD bar displaying the current damage of the player's armor.
|
||||
depends = hudbars, mcl_armor
|
|
@ -1,3 +0,0 @@
|
|||
#Time difference in seconds between updates to the armor HUD bar.
|
||||
#Increase this number for slow servers.
|
||||
hbarmor_tick (Armor HUD bar update frequency) float 0.1 0.0 4.0
|
Before Width: | Height: | Size: 91 B |
Before Width: | Height: | Size: 896 B |
Before Width: | Height: | Size: 904 B |
|
@ -1,27 +0,0 @@
|
|||
# API documentation for dispensers
|
||||
|
||||
The dispensers API allows you to add custom code which is called when a
|
||||
particular item is dispensed.
|
||||
Just add the `_on_dispense` function to the item definition.
|
||||
By default, items are just thrown out as item entities.
|
||||
|
||||
## Additional fields for item definitions
|
||||
|
||||
### `_on_dispense(stack, pos, droppos, dropnode, dropdir)`
|
||||
|
||||
This is a function which is called when an item is dispensed by the dispenser.
|
||||
These are the parameters:
|
||||
|
||||
* stack: Itemstack which is dispense. This is always exactly 1 item
|
||||
* pos: Position of dispenser
|
||||
* droppos: Position to which to dispense item
|
||||
* dropnode: Node of droppos
|
||||
* dropdir: Drop direction
|
||||
|
||||
By default (return value: `nil`), the itemstack is consumed by the dispenser afterwards.
|
||||
Optionally, you can explicitly set the return value to a custom leftover itemstack.
|
||||
|
||||
### `_dispense_into_walkable`
|
||||
|
||||
By default, items will only be dispensed into non-walkable nodes.
|
||||
But if this value is set If `true`, the item can be dispensed into walkable nodes.
|
|
@ -1,369 +0,0 @@
|
|||
--[[ This mod registers 3 nodes:
|
||||
- One node for the horizontal-facing dispensers (mcl_dispensers:dispenser)
|
||||
- One node for the upwards-facing dispensers (mcl_dispenser:dispenser_up)
|
||||
- One node for the downwards-facing dispensers (mcl_dispenser:dispenser_down)
|
||||
|
||||
3 node definitions are needed because of the way the textures are defined.
|
||||
All node definitions share a lot of code, so this is the reason why there
|
||||
are so many weird tables below.
|
||||
]]
|
||||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
|
||||
-- For after_place_node
|
||||
local function setup_dispenser(pos)
|
||||
-- Set formspec and inventory
|
||||
local form = "size[9,8.75]"..
|
||||
"label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]"..
|
||||
"list[current_player;main;0,4.5;9,3;9]"..
|
||||
mcl_formspec.get_itemslot_bg(0,4.5,9,3)..
|
||||
"list[current_player;main;0,7.74;9,1;]"..
|
||||
mcl_formspec.get_itemslot_bg(0,7.74,9,1)..
|
||||
"label[3,0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Dispenser"))).."]"..
|
||||
"list[context;main;3,0.5;3,3;]"..
|
||||
mcl_formspec.get_itemslot_bg(3,0.5,3,3)..
|
||||
"listring[context;main]"..
|
||||
"listring[current_player;main]"
|
||||
local meta = minetest.get_meta(pos)
|
||||
meta:set_string("formspec", form)
|
||||
local inv = meta:get_inventory()
|
||||
inv:set_size("main", 9)
|
||||
end
|
||||
|
||||
local function orientate_dispenser(pos, placer)
|
||||
-- Not placed by player
|
||||
if not placer then return end
|
||||
|
||||
-- Pitch in degrees
|
||||
local pitch = placer:get_look_vertical() * (180 / math.pi)
|
||||
|
||||
local node = minetest.get_node(pos)
|
||||
if pitch > 55 then
|
||||
minetest.swap_node(pos, {name="mcl_dispensers:dispenser_up", param2 = node.param2})
|
||||
elseif pitch < -55 then
|
||||
minetest.swap_node(pos, {name="mcl_dispensers:dispenser_down", param2 = node.param2})
|
||||
end
|
||||
end
|
||||
|
||||
local on_rotate
|
||||
if minetest.get_modpath("screwdriver") then
|
||||
on_rotate = screwdriver.rotate_simple
|
||||
end
|
||||
|
||||
-- Shared core definition table
|
||||
local dispenserdef = {
|
||||
is_ground_content = false,
|
||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
|
||||
local name = player:get_player_name()
|
||||
if minetest.is_protected(pos, name) then
|
||||
minetest.record_protection_violation(pos, name)
|
||||
return 0
|
||||
else
|
||||
return count
|
||||
end
|
||||
end,
|
||||
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||
local name = player:get_player_name()
|
||||
if minetest.is_protected(pos, name) then
|
||||
minetest.record_protection_violation(pos, name)
|
||||
return 0
|
||||
else
|
||||
return stack:get_count()
|
||||
end
|
||||
end,
|
||||
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||
local name = player:get_player_name()
|
||||
if minetest.is_protected(pos, name) then
|
||||
minetest.record_protection_violation(pos, name)
|
||||
return 0
|
||||
else
|
||||
return stack:get_count()
|
||||
end
|
||||
end,
|
||||
after_dig_node = function(pos, oldnode, oldmetadata, digger)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local meta2 = meta:to_table()
|
||||
meta:from_table(oldmetadata)
|
||||
local inv = meta:get_inventory()
|
||||
for i=1, inv:get_size("main") do
|
||||
local stack = inv:get_stack("main", i)
|
||||
if not stack:is_empty() then
|
||||
local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5}
|
||||
minetest.add_item(p, stack)
|
||||
end
|
||||
end
|
||||
meta:from_table(meta2)
|
||||
end,
|
||||
_mcl_blast_resistance = 3.5,
|
||||
_mcl_hardness = 3.5,
|
||||
mesecons = {
|
||||
effector = {
|
||||
-- Dispense random item when triggered
|
||||
action_on = function(pos, node)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local inv = meta:get_inventory()
|
||||
local droppos, dropdir
|
||||
if node.name == "mcl_dispensers:dispenser" then
|
||||
dropdir = vector.multiply(minetest.facedir_to_dir(node.param2), -1)
|
||||
droppos = vector.add(pos, dropdir)
|
||||
elseif node.name == "mcl_dispensers:dispenser_up" then
|
||||
dropdir = {x=0, y=1, z=0}
|
||||
droppos = {x=pos.x, y=pos.y+1, z=pos.z}
|
||||
elseif node.name == "mcl_dispensers:dispenser_down" then
|
||||
dropdir = {x=0, y=-1, z=0}
|
||||
droppos = {x=pos.x, y=pos.y-1, z=pos.z}
|
||||
end
|
||||
local dropnode = minetest.get_node(droppos)
|
||||
local dropnodedef = minetest.registered_nodes[dropnode.name]
|
||||
local stacks = {}
|
||||
for i=1,inv:get_size("main") do
|
||||
local stack = inv:get_stack("main", i)
|
||||
if not stack:is_empty() then
|
||||
table.insert(stacks, {stack = stack, stackpos = i})
|
||||
end
|
||||
end
|
||||
if #stacks >= 1 then
|
||||
local r = math.random(1, #stacks)
|
||||
local stack = stacks[r].stack
|
||||
local dropitem = ItemStack(stack)
|
||||
dropitem:set_count(1)
|
||||
local stack_id = stacks[r].stackpos
|
||||
local stackdef = stack:get_definition()
|
||||
|
||||
if not stackdef then
|
||||
return
|
||||
end
|
||||
|
||||
local iname = stack:get_name()
|
||||
local igroups = stackdef.groups
|
||||
|
||||
--[===[ Dispense item ]===]
|
||||
|
||||
-- Hardcoded dispensions --
|
||||
|
||||
-- Armor, mob heads and pumpkins
|
||||
if igroups.armor then
|
||||
local droppos_below = {x = droppos.x, y = droppos.y - 1, z = droppos.z}
|
||||
|
||||
for _, objs in ipairs({minetest.get_objects_inside_radius(droppos, 1), minetest.get_objects_inside_radius(droppos_below, 1)}) do
|
||||
for _, obj in ipairs(objs) do
|
||||
stack = mcl_armor.equip(stack, obj)
|
||||
if stack:is_empty() then
|
||||
break
|
||||
end
|
||||
end
|
||||
if stack:is_empty() then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
-- Place head or pumpkin as node, if equipping it as armor has failed
|
||||
if not stack:is_empty() then
|
||||
if igroups.head or iname == "mcl_farming:pumpkin_face" then
|
||||
if dropnodedef.buildable_to then
|
||||
minetest.set_node(droppos, {name = iname, param2 = node.param2})
|
||||
stack:take_item()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
inv:set_stack("main", stack_id, stack)
|
||||
|
||||
-- Use shears on sheeps
|
||||
elseif igroups.shears then
|
||||
for _, obj in pairs(minetest.get_objects_inside_radius(droppos, 1)) do
|
||||
local entity = obj:get_luaentity()
|
||||
if entity and not entity.child and not entity.gotten then
|
||||
local entname = entity.name
|
||||
local pos = obj:get_pos()
|
||||
local used, texture = false
|
||||
if entname == "mobs_mc:sheep" then
|
||||
minetest.add_item(pos, entity.drops[2].name .. " " .. math.random(1, 3))
|
||||
if not entity.color then
|
||||
entity.color = "unicolor_white"
|
||||
end
|
||||
entity.base_texture = { "blank.png", "mobs_mc_sheep.png" }
|
||||
texture = entity.base_texture
|
||||
entity.drops = {
|
||||
{ name = "mcl_mobitems:mutton", chance = 1, min = 1, max = 2 },
|
||||
}
|
||||
used = true
|
||||
elseif entname == "mobs_mc:snowman" then
|
||||
texture = {
|
||||
"mobs_mc_snowman.png",
|
||||
"blank.png", "blank.png",
|
||||
"blank.png", "blank.png",
|
||||
"blank.png", "blank.png",
|
||||
}
|
||||
used = true
|
||||
elseif entname == "mobs_mc:mooshroom" then
|
||||
local droppos = vector.offset(pos, 0, 1.4, 0)
|
||||
if entity.base_texture[1] == "mobs_mc_mooshroom_brown.png" then
|
||||
minetest.add_item(droppos, "mcl_mushrooms:mushroom_brown 5")
|
||||
else
|
||||
minetest.add_item(droppos, "mcl_mushrooms:mushroom_red 5")
|
||||
end
|
||||
obj = mcl_util.replace_mob(obj, "mobs_mc:cow")
|
||||
entity = obj:get_luaentity()
|
||||
used = true
|
||||
end
|
||||
if used then
|
||||
obj:set_properties({ textures = texture })
|
||||
entity.gotten = true
|
||||
minetest.sound_play("mcl_tools_shears_cut", { pos = pos }, true)
|
||||
stack:add_wear(65535 / stackdef._mcl_diggroups.shearsy.uses)
|
||||
inv:set_stack("main", stack_id, stack)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Spawn Egg
|
||||
elseif igroups.spawn_egg then
|
||||
-- Spawn mob
|
||||
if not dropnodedef.walkable then
|
||||
--pointed_thing = { above = droppos, under = { x=droppos.x, y=droppos.y-1, z=droppos.z } }
|
||||
minetest.add_entity(droppos, stack:get_name())
|
||||
|
||||
stack:take_item()
|
||||
inv:set_stack("main", stack_id, stack)
|
||||
end
|
||||
|
||||
-- Generalized dispension
|
||||
elseif (not dropnodedef.walkable or stackdef._dispense_into_walkable) then
|
||||
--[[ _on_dispense(stack, pos, droppos, dropnode, dropdir)
|
||||
* stack: Itemstack which is dispense
|
||||
* pos: Position of dispenser
|
||||
* droppos: Position to which to dispense item
|
||||
* dropnode: Node of droppos
|
||||
* dropdir: Drop direction
|
||||
|
||||
_dispense_into_walkable: If true, can dispense into walkable nodes
|
||||
]]
|
||||
if stackdef._on_dispense then
|
||||
-- Item-specific dispension (if defined)
|
||||
local od_ret = stackdef._on_dispense(dropitem, pos, droppos, dropnode, dropdir)
|
||||
if od_ret then
|
||||
local newcount = stack:get_count() - 1
|
||||
stack:set_count(newcount)
|
||||
inv:set_stack("main", stack_id, stack)
|
||||
if newcount == 0 then
|
||||
inv:set_stack("main", stack_id, od_ret)
|
||||
elseif inv:room_for_item("main", od_ret) then
|
||||
inv:add_item("main", od_ret)
|
||||
else
|
||||
minetest.add_item(droppos, dropitem)
|
||||
end
|
||||
else
|
||||
stack:take_item()
|
||||
inv:set_stack("main", stack_id, stack)
|
||||
end
|
||||
else
|
||||
-- Drop item otherwise
|
||||
minetest.add_item(droppos, dropitem)
|
||||
stack:take_item()
|
||||
inv:set_stack("main", stack_id, stack)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end,
|
||||
rules = mesecon.rules.alldirs,
|
||||
},
|
||||
},
|
||||
on_rotate = on_rotate,
|
||||
}
|
||||
|
||||
-- Horizontal dispenser
|
||||
|
||||
local horizontal_def = table.copy(dispenserdef)
|
||||
horizontal_def.description = S("Dispenser")
|
||||
horizontal_def._tt_help = S("9 inventory slots").."\n"..S("Launches item when powered by redstone power")
|
||||
horizontal_def._doc_items_longdesc = S("A dispenser is a block which acts as a redstone component which, when powered with redstone power, dispenses an item. It has a container with 9 inventory slots.")
|
||||
horizontal_def._doc_items_usagehelp = S("Place the dispenser in one of 6 possible directions. The “hole” is where items will fly out of the dispenser. Use the dispenser to access its inventory. Insert the items you wish to dispense. Supply the dispenser with redstone energy once to dispense a random item.").."\n\n"..
|
||||
|
||||
S("The dispenser will do different things, depending on the dispensed item:").."\n\n"..
|
||||
|
||||
S("• Arrows: Are launched").."\n"..
|
||||
S("• Eggs and snowballs: Are thrown").."\n"..
|
||||
S("• Fire charges: Are fired in a straight line").."\n"..
|
||||
S("• Armor: Will be equipped to players and armor stands").."\n"..
|
||||
S("• Boats: Are placed on water or are dropped").."\n"..
|
||||
S("• Minecart: Are placed on rails or are dropped").."\n"..
|
||||
S("• Bone meal: Is applied on the block it is facing").."\n"..
|
||||
S("• Empty buckets: Are used to collect a liquid source").."\n"..
|
||||
S("• Filled buckets: Are used to place a liquid source").."\n"..
|
||||
S("• Heads, pumpkins: Equipped to players and armor stands, or placed as a block").."\n"..
|
||||
S("• Shulker boxes: Are placed as a block").."\n"..
|
||||
S("• TNT: Is placed and ignited").."\n"..
|
||||
S("• Flint and steel: Is used to ignite a fire in air and to ignite TNT").."\n"..
|
||||
S("• Spawn eggs: Will summon the mob they contain").."\n"..
|
||||
S("• Other items: Are simply dropped")
|
||||
|
||||
function horizontal_def.after_place_node(pos, placer, itemstack, pointed_thing)
|
||||
setup_dispenser(pos)
|
||||
orientate_dispenser(pos, placer)
|
||||
end
|
||||
|
||||
horizontal_def.tiles = {
|
||||
"default_furnace_top.png", "default_furnace_bottom.png",
|
||||
"default_furnace_side.png", "default_furnace_side.png",
|
||||
"default_furnace_side.png", "mcl_dispensers_dispenser_front_horizontal.png"
|
||||
}
|
||||
horizontal_def.paramtype2 = "facedir"
|
||||
horizontal_def.groups = {pickaxey=1, container=2, material_stone=1}
|
||||
|
||||
minetest.register_node("mcl_dispensers:dispenser", horizontal_def)
|
||||
|
||||
-- Down dispenser
|
||||
local down_def = table.copy(dispenserdef)
|
||||
down_def.description = S("Downwards-Facing Dispenser")
|
||||
down_def.after_place_node = setup_dispenser
|
||||
down_def.tiles = {
|
||||
"default_furnace_top.png", "mcl_dispensers_dispenser_front_vertical.png",
|
||||
"default_furnace_side.png", "default_furnace_side.png",
|
||||
"default_furnace_side.png", "default_furnace_side.png"
|
||||
}
|
||||
down_def.groups = {pickaxey=1, container=2,not_in_creative_inventory=1, material_stone=1}
|
||||
down_def._doc_items_create_entry = false
|
||||
down_def.drop = "mcl_dispensers:dispenser"
|
||||
minetest.register_node("mcl_dispensers:dispenser_down", down_def)
|
||||
|
||||
-- Up dispenser
|
||||
-- The up dispenser is almost identical to the down dispenser , it only differs in textures
|
||||
local up_def = table.copy(down_def)
|
||||
up_def.description = S("Upwards-Facing Dispenser")
|
||||
up_def.tiles = {
|
||||
"mcl_dispensers_dispenser_front_vertical.png", "default_furnace_bottom.png",
|
||||
"default_furnace_side.png", "default_furnace_side.png",
|
||||
"default_furnace_side.png", "default_furnace_side.png"
|
||||
}
|
||||
minetest.register_node("mcl_dispensers:dispenser_up", up_def)
|
||||
|
||||
|
||||
minetest.register_craft({
|
||||
output = "mcl_dispensers:dispenser",
|
||||
recipe = {
|
||||
{"mcl_core:cobble", "mcl_core:cobble", "mcl_core:cobble",},
|
||||
{"mcl_core:cobble", "mcl_bows:bow", "mcl_core:cobble",},
|
||||
{"mcl_core:cobble", "mesecons:redstone", "mcl_core:cobble",},
|
||||
}
|
||||
})
|
||||
|
||||
-- Add entry aliases for the Help
|
||||
if minetest.get_modpath("doc") then
|
||||
doc.add_entry_alias("nodes", "mcl_dispensers:dispenser", "nodes", "mcl_dispensers:dispenser_down")
|
||||
doc.add_entry_alias("nodes", "mcl_dispensers:dispenser", "nodes", "mcl_dispensers:dispenser_up")
|
||||
end
|
||||
|
||||
-- Legacy
|
||||
minetest.register_lbm({
|
||||
label = "Update dispenser formspecs (0.60.0)",
|
||||
name = "mcl_dispensers:update_formspecs_0_60_0",
|
||||
nodenames = { "mcl_dispensers:dispenser", "mcl_dispensers:dispenser_down", "mcl_dispensers:dispenser_up" },
|
||||
action = function(pos, node)
|
||||
setup_dispenser(pos)
|
||||
minetest.log("action", "[mcl_dispenser] Node formspec updated at "..minetest.pos_to_string(pos))
|
||||
end,
|
||||
})
|
|
@ -1,25 +0,0 @@
|
|||
# textdomain: mcl_dispensers
|
||||
Dispenser=Werfer
|
||||
A dispenser is a block which acts as a redstone component which, when powered with redstone power, dispenses an item. It has a container with 9 inventory slots.=Ein Werfer ist ein Block, der als eine Redstonekomponente fungiert, die, wenn sie mit Redstoneenergie versorgt ist, einen Gegenstand auswirft. Er hat einen Behälter mit 9 Inventarplätzen.
|
||||
Place the dispenser in one of 6 possible directions. The “hole” is where items will fly out of the dispenser. Use the dispenser to access its inventory. Insert the items you wish to dispense. Supply the dispenser with redstone energy once to dispense a random item.=Platzieren Sie den Werfer in einer von 6 möglichen Richtungen. Das „Loch“ ist die Stelle, aus der Dinge aus dem Werfer fliegen. Benutzen Sie den Werfer, um auf das Inventar zuzugreifen.
|
||||
The dispenser will do different things, depending on the dispensed item:=Der Werfer wird, abhängig vom geworfenem Gegenstand, unterschiedliche Dinge tun:
|
||||
• Arrows: Are launched=• Pfeile: Werden gefeuert
|
||||
• Eggs and snowballs: Are thrown=• Eier und Schneebälle: Werden geworfen
|
||||
• Fire charges: Are fired in a straight line=• Feuerkugeln: Werden schnurgerade abgefeuert
|
||||
• Armor: Will be equipped to players and armor stands=• Rüstung: Spieler und Rüstungsständer werden ausgerüstet
|
||||
• Boats: Are placed on water or are dropped=• Boote: Werden auf Wasser platziert oder abgeworfen
|
||||
• Minecart: Are placed on rails or are dropped=• Loren: Werden auf Schienen platziert oder abgeworfen
|
||||
• Bone meal: Is applied on the block it is facing=• Knochenmehl: Wird auf den Block, auf den er zeigt, angewandt
|
||||
• Empty buckets: Are used to collect a liquid source=• Leere Eimer: Sammeln Flüssigkeitsquelle auf
|
||||
• Filled buckets: Are used to place a liquid source=• Volle Eimer: Platzieren eine Flüssigkeitsquelle
|
||||
• Heads, pumpkins: Equipped to players and armor stands, or placed as a block=• Köpfe, Kürbisse: Spieler und Rüstungsständer werden ausgerüstet, alternativ werden diese Gegenstände als Block platziert
|
||||
• Shulker boxes: Are placed as a block=• Schulkerkisten: Werden als Block platziert
|
||||
• TNT: Is placed and ignited=• TNT: Wird platziert und angezündet
|
||||
• Flint and steel: Is used to ignite a fire in air and to ignite TNT=• Feuerzeuge: Endzündet ein Feuer in der Luft und zündet TNT an
|
||||
• Spawn eggs: Will summon the mob they contain=• Spawn-Eier: Beschwören einen Mob
|
||||
• Other items: Are simply dropped=• Andere Gegenstände: Werden fallen gelassen
|
||||
Downwards-Facing Dispenser=Nach unten zeigender Werfer
|
||||
Upwards-Facing Dispenser=Nach oben zeigender Werfer
|
||||
Inventory=Inventar
|
||||
9 inventory slots=9 Inventarplätze
|
||||
Launches item when powered by redstone power=Wirft Gegenstand aus, wenn mit Redstoneenergie versorgt
|
|
@ -1,22 +0,0 @@
|
|||
# textdomain: mcl_dispensers
|
||||
Dispenser=Dispensador
|
||||
A dispenser is a block which acts as a redstone component which, when powered with redstone power, dispenses an item. It has a container with 9 inventory slots.=Un dispensador es un bloque que actúa como un componente de redstone que, cuando se alimenta con energía de redstone, dispensa un artículo. Tiene un contenedor con 9 ranuras de inventario.
|
||||
Place the dispenser in one of 6 possible directions. The “hole” is where items will fly out of the dispenser. Use the dispenser to access its inventory. Insert the items you wish to dispense. Supply the dispenser with redstone energy once to dispense a random item.=Coloque el dispensador en una de las 6 direcciones posibles. El "agujero" es donde los artículos saldrán volando del dispensador. Use el dispensador para acceder a su inventario. Inserte los artículos que desea dispensar. Proporcione al dispensador energía de redstone una vez para dispensar un elemento aleatorio:
|
||||
• Arrows: Are launched=• Flechas: Se lanzan
|
||||
• Eggs and snowballs: Are thrown=• Huevos y bolas de nieve: Son lanzados
|
||||
• Fire charges: Are fired in a straight line=• Cargas de fuego: Se disparan en línea recta
|
||||
• Armor: Will be equipped to players and armor stands=• Armadura: Estará equipada para jugadores y armaduras
|
||||
• Boats: Are placed on water or are dropped=• Barcas: Se colocan en el agua o se dejan caer
|
||||
• Minecart: Are placed on rails or are dropped=• Carro de minas: Se colocan sobre rieles o se dejan caer =
|
||||
• Bone meal: Is applied on the block it is facing=• Harina de hueso: Se aplica en el bloque que está enfrentando
|
||||
• Empty buckets: Are used to collect a liquid source=• Cubos vacíos: Se utilizan para recolectar una fuente líquida
|
||||
• Filled buckets: Are used to place a liquid source=• Cubos llenos: Se utilizan para colocar una fuente de líquido
|
||||
• Heads, pumpkins: Equipped to players and armor stands, or placed as a block=• Cabezas, calabazas: Equipadas para jugadores y armaduras, o colocadas como un bloque
|
||||
• Shulker boxes: Are placed as a block=• Cajas de Shulker: Se colocan como un bloque
|
||||
• TNT: Is placed and ignited=• TNT: Se coloca y se enciende
|
||||
• Flint and steel: Is used to ignite a fire in air and to ignite TNT=• Mechero: Se usa para encender un fuego en el aire y para encender TNT
|
||||
• Spawn eggs: Will summon the mob they contain=• Huevos de desove: Convocarán al animal que contienen
|
||||
• Other items: Are simply dropped=• Otros artículos: Simplemente se dejan caer
|
||||
Downwards-Facing Dispenser=Dispensador orientado hacia abajo
|
||||
Upwards-Facing Dispenser=Dispensador orientado hacia arriba
|
||||
Inventory=Inventario
|
|
@ -1,25 +0,0 @@
|
|||
# textdomain: mcl_dispensers
|
||||
Dispenser=Dispenser
|
||||
A dispenser is a block which acts as a redstone component which, when powered with redstone power, dispenses an item. It has a container with 9 inventory slots.=Un distributeur est un bloc qui agit comme un composant redstone qui, lorsqu'il est alimenté avec une puissance redstone, distribue un article. Il a un conteneur avec 9 emplacements d'inventaire.
|
||||
Place the dispenser in one of 6 possible directions. The “hole” is where items will fly out of the dispenser. Use the dispenser to access its inventory. Insert the items you wish to dispense. Supply the dispenser with redstone energy once to dispense a random item.=Placez le distributeur dans l'une des 6 directions possibles. Le "trou" est l'endroit où les articles sortiront du distributeur. Utilisez le distributeur pour accéder à son inventaire. Insérez les articles que vous souhaitez distribuer. Fournissez au distributeur de l'énergie de redstone une fois pour distribuer un objet aléatoire.
|
||||
The dispenser will do different things, depending on the dispensed item:=Le distributeur fera différentes choses, selon l'article distribué:
|
||||
• Arrows: Are launched=• Flèches: Sont lancées
|
||||
• Eggs and snowballs: Are thrown=• Oeufs et boules de neige: Sont jetés
|
||||
• Fire charges: Are fired in a straight line=• Feu d'artifice: Sont tirés en ligne droite
|
||||
• Armor: Will be equipped to players and armor stands=• Armure: Sera équipée pour les joueurs et les porte-armures
|
||||
• Boats: Are placed on water or are dropped=• Bateaux: Sont placés sur l'eau ou sont lâchés
|
||||
• Minecart: Are placed on rails or are dropped=• Minecart: Sont placés sur des rails ou sont lâchés
|
||||
• Bone meal: Is applied on the block it is facing=• Farine d'os: Est appliquée sur le bloc auquel elle fait face
|
||||
• Empty buckets: Are used to collect a liquid source=• Seaux vides: Sont utilisés pour collecter une source de liquide
|
||||
• Filled buckets: Are used to place a liquid source=• Seaux remplis: Sont utilisés pour placer une source de liquide
|
||||
• Heads, pumpkins: Equipped to players and armor stands, or placed as a block=• Têtes, citrouilles: Seront équipées pour les joueurs et les armures, ou placées en bloc
|
||||
• Shulker boxes: Are placed as a block=• Boîtes de Shulker: Sont placées comme un bloc
|
||||
• TNT: Is placed and ignited=• TNT: Est placé et allumé
|
||||
• Flint and steel: Is used to ignite a fire in air and to ignite TNT=• Briquet: Sert à allumer un feu dans l'air et à allumer du TNT
|
||||
• Spawn eggs: Will summon the mob they contain=• Silex et acier: Sert à allumer un feu dans l'air et à allumer du TNT
|
||||
• Other items: Are simply dropped=• Autres articles: Sont simplement lâchés
|
||||
Downwards-Facing Dispenser=Distributeur orienté vers le bas
|
||||
Upwards-Facing Dispenser=Distributeur orienté vers le haut
|
||||
Inventory=Inventaire
|
||||
9 inventory slots=9 emplacements d'inventaire
|
||||
Launches item when powered by redstone power=Lance un objet lorsqu'il est alimenté par la puissance Redstone
|
|
@ -1,25 +0,0 @@
|
|||
# textdomain: mcl_dispensers
|
||||
Dispenser=Dozownik
|
||||
A dispenser is a block which acts as a redstone component which, when powered with redstone power, dispenses an item. It has a container with 9 inventory slots.=Dozownik jest mechanizmem czerwienitowym, który po zasileniu wystrzeli lub wyrzuci przedmiot. Jest on pojemnikiem z 9 miejscami.
|
||||
Place the dispenser in one of 6 possible directions. The “hole” is where items will fly out of the dispenser. Use the dispenser to access its inventory. Insert the items you wish to dispense. Supply the dispenser with redstone energy once to dispense a random item.=Postaw dozownik w jednym z 6 możliwych kierunków. "Dziura" wskazuje z której strony przedmioty będą dozowane. Użyj dozownika, aby zarządzać jego ekwipunkiem. Zasil dozownik czerwienitem aby wyrzucić losowy przedmiot.
|
||||
The dispenser will do different things, depending on the dispensed item:=Dozownik będzie zachowywał się inaczej w zależności od przedmiotu:
|
||||
• Arrows: Are launched=• Strzały: są wystrzelone
|
||||
• Eggs and snowballs: Are thrown=• Jaja i śnieżki: są wyrzucane
|
||||
• Fire charges: Are fired in a straight line=• Ładunki ogniowe: Są wystrzelone w linii prostej
|
||||
• Armor: Will be equipped to players and armor stands=• Zbroja: będzie ekwipowana graczom, lub stojakom na zbroję
|
||||
• Boats: Are placed on water or are dropped=• Łódki: Będą postawione na wodzie, lub wypuszczone
|
||||
• Minecart: Are placed on rails or are dropped=• Wagoniki: będą postawione na torach, lub upuszczone
|
||||
• Bone meal: Is applied on the block it is facing=• Mączka kostna: będzie zaaplikowana do bloku
|
||||
• Empty buckets: Are used to collect a liquid source=• Puste wiadra: będą wykorzystane do zebrania źródła płynu
|
||||
• Filled buckets: Are used to place a liquid source=• Pełne wiadra: będą wykorzystane do postawienia źródła płynu
|
||||
• Heads, pumpkins: Equipped to players and armor stands, or placed as a block=• Głowy, dynie: będą ekwipowane graczom i stojakom na zbroję, lub postawione jako bloki
|
||||
• Shulker boxes: Are placed as a block=Shulkerowe skrzynie: są postawione jako blok
|
||||
• TNT: Is placed and ignited=• Trotyl: będzie postawiony i zapalony
|
||||
• Flint and steel: Is used to ignite a fire in air and to ignite TNT=• Krzesiwo: będzie wykorzystane do rozpalenia ognia w powietrzu i zapalenia trotylu
|
||||
• Spawn eggs: Will summon the mob they contain=• Jaja przywołujące: przywołają moba, którego zawierają
|
||||
• Other items: Are simply dropped=• Inne przedmioty: zostaną upuszczone
|
||||
Downwards-Facing Dispenser=Dozownik skierowany w dół
|
||||
Upwards-Facing Dispenser=Dozownik skierowany w górę
|
||||
Inventory=Ekwipunek
|
||||
9 inventory slots=9 miejsc ekwipunku
|
||||
Launches item when powered by redstone power=Wystrzela przedmiot gdy zasilony czerwienitem
|
|
@ -1,25 +0,0 @@
|
|||
# textdomain: mcl_dispensers
|
||||
Dispenser=Диспенсер
|
||||
A dispenser is a block which acts as a redstone component which, when powered with redstone power, dispenses an item. It has a container with 9 inventory slots.=Диспенсер это элемент редстоуна, который при подаче энергии редстоуна выбрасывает предмет. В нём есть контейнер из 9 отсеков инвентаря.
|
||||
Place the dispenser in one of 6 possible directions. The “hole” is where items will fly out of the dispenser. Use the dispenser to access its inventory. Insert the items you wish to dispense. Supply the dispenser with redstone energy once to dispense a random item.=Направьте диспенсер в одном из 6 возможных направлений. Предметы будут вылетать из отверстия. [Используйте] диспенсер для доступа к его инвентарю. Загрузите туда предметы, которые должны из него выбрасываться. Подайте однократно на диспенсер энергию редстоуна, чтобы выпал случайный предмет.
|
||||
The dispenser will do different things, depending on the dispensed item:=Диспенсер будет делать разные вещи, в зависимости от выдаваемых предметов:
|
||||
• Arrows: Are launched=• Стрелы: выстреливают
|
||||
• Eggs and snowballs: Are thrown=• Яйца и снежки: происходит бросок
|
||||
• Fire charges: Are fired in a straight line=• Огненные шары: стреляют по прямой линии
|
||||
• Armor: Will be equipped to players and armor stands=• Защита: экипирует игроков или стенд защиты
|
||||
• Boats: Are placed on water or are dropped=• Лодки: спускаются на воду
|
||||
• Minecart: Are placed on rails or are dropped=• Вагонетка: помещается на рельсы
|
||||
• Bone meal: Is applied on the block it is facing=• Костная мука: применяется к блоку перед диспенсером
|
||||
• Empty buckets: Are used to collect a liquid source=• Пустые вёдра: используются для набора источника жидкости
|
||||
• Filled buckets: Are used to place a liquid source=• Полные вёдра: используются для размещения источника жидкости
|
||||
• Heads, pumpkins: Equipped to players and armor stands, or placed as a block=• Головы, тыквы: экипирует игроков, или стенд защиты, или устанавливаются как блоки
|
||||
• Shulker boxes: Are placed as a block=• Ящик шалкера: устанавливается как блок
|
||||
• TNT: Is placed and ignited=• Тротил: устанавливается и поджигается
|
||||
• Flint and steel: Is used to ignite a fire in air and to ignite TNT=• Огниво: используется для зажигания огня в воздухе и для подрыва тротила
|
||||
• Spawn eggs: Will summon the mob they contain=• Порождающие яйца: будут вызывать мобов, содержащихся в них
|
||||
• Other items: Are simply dropped=• Другие предметы: просто выдаются
|
||||
Downwards-Facing Dispenser=• Диспенсер, направленный вниз
|
||||
Upwards-Facing Dispenser=• Диспенсер, направленный вверх
|
||||
Inventory=Инвентарь
|
||||
9 inventory slots=9 отсеков инвентаря
|
||||
Launches item when powered by redstone power=Выбрасывает предметы при подаче энергии редстоуна
|
|
@ -1,25 +0,0 @@
|
|||
# textdomain: mcl_dispensers
|
||||
Dispenser=
|
||||
A dispenser is a block which acts as a redstone component which, when powered with redstone power, dispenses an item. It has a container with 9 inventory slots.=
|
||||
Place the dispenser in one of 6 possible directions. The “hole” is where items will fly out of the dispenser. Use the dispenser to access its inventory. Insert the items you wish to dispense. Supply the dispenser with redstone energy once to dispense a random item.=
|
||||
The dispenser will do different things, depending on the dispensed item:=
|
||||
• Arrows: Are launched=
|
||||
• Eggs and snowballs: Are thrown=
|
||||
• Fire charges: Are fired in a straight line=
|
||||
• Armor: Will be equipped to players and armor stands=
|
||||
• Boats: Are placed on water or are dropped=
|
||||
• Minecart: Are placed on rails or are dropped=
|
||||
• Bone meal: Is applied on the block it is facing=
|
||||
• Empty buckets: Are used to collect a liquid source=
|
||||
• Filled buckets: Are used to place a liquid source=
|
||||
• Heads, pumpkins: Equipped to players and armor stands, or placed as a block=
|
||||
• Shulker boxes: Are placed as a block=
|
||||
• TNT: Is placed and ignited=
|
||||
• Flint and steel: Is used to ignite a fire in air and to ignite TNT=
|
||||
• Spawn eggs: Will summon the mob they contain=
|
||||
• Other items: Are simply dropped=
|
||||
Downwards-Facing Dispenser=
|
||||
Upwards-Facing Dispenser=
|
||||
Inventory=
|
||||
9 inventory slots=
|
||||
Launches item when powered by redstone power=
|
|
@ -1,3 +0,0 @@
|
|||
name = mcl_dispensers
|
||||
depends = mcl_init, mcl_formspec, mesecons, mcl_sounds, mcl_tnt, mcl_worlds, mcl_core, mcl_nether, mcl_armor_stand, mcl_armor
|
||||
optional_depends = doc, screwdriver
|
Before Width: | Height: | Size: 252 B |
Before Width: | Height: | Size: 243 B |
|
@ -1,904 +0,0 @@
|
|||
local S = minetest.get_translator(minetest.get_current_modname())
|
||||
|
||||
local PISTON_MAXIMUM_PUSH = 12
|
||||
|
||||
--Get mesecon rules of pistons
|
||||
|
||||
--everything apart from z- (pusher side)
|
||||
local piston_rules = {
|
||||
{x=0, y=0, z=1},
|
||||
{x=1, y=0, z=0},
|
||||
{x=-1, y=0, z=0},
|
||||
{x=0, y=1, z=0},
|
||||
{x=0, y=-1, z=0},
|
||||
}
|
||||
|
||||
--everything apart from y+ (pusher side)
|
||||
local piston_up_rules = {
|
||||
{x=0, y=0, z=-1},
|
||||
{x=0, y=0, z=1},
|
||||
{x=-1, y=0, z=0},
|
||||
{x=1, y=0, z=0},
|
||||
{x=0, y=-1, z=0},
|
||||
}
|
||||
|
||||
--everything apart from y- (pusher side)
|
||||
local piston_down_rules = {
|
||||
{x=0, y=0, z=-1},
|
||||
{x=0, y=0, z=1},
|
||||
{x=-1, y=0, z=0},
|
||||
{x=1, y=0, z=0},
|
||||
{x=0, y=1, z=0},
|
||||
}
|
||||
|
||||
local function piston_get_rules(node)
|
||||
local rules = piston_rules
|
||||
for i = 1, node.param2 do
|
||||
rules = mesecon.rotate_rules_left(rules)
|
||||
end
|
||||
return rules
|
||||
end
|
||||
|
||||
local function piston_facedir_direction(node)
|
||||
local rules = {{x = 0, y = 0, z = -1}}
|
||||
for i = 1, node.param2 do
|
||||
rules = mesecon.rotate_rules_left(rules)
|
||||
end
|
||||
return rules[1]
|
||||
end
|
||||
|
||||
local function piston_get_direction(dir, node)
|
||||
if type(dir) == "function" then
|
||||
return dir(node)
|
||||
else
|
||||
return dir
|
||||
end
|
||||
end
|
||||
|
||||
-- Remove pusher of piston.
|
||||
-- To be used when piston was destroyed or dug.
|
||||
local function piston_remove_pusher(pos, oldnode)
|
||||
local pistonspec = minetest.registered_nodes[oldnode.name].mesecons_piston
|
||||
|
||||
local dir = piston_get_direction(pistonspec.dir, oldnode)
|
||||
local pusherpos = vector.add(pos, dir)
|
||||
local pushername = minetest.get_node(pusherpos).name
|
||||
|
||||
if pushername == pistonspec.pusher then -- make sure there actually is a pusher
|
||||
minetest.remove_node(pusherpos)
|
||||
minetest.check_for_falling(pusherpos)
|
||||
minetest.sound_play("piston_retract", {
|
||||
pos = pos,
|
||||
max_hear_distance = 31,
|
||||
gain = 0.3,
|
||||
}, true)
|
||||
end
|
||||
end
|
||||
|
||||
-- Remove base node of piston.
|
||||
-- To be used when pusher was destroyed.
|
||||
local function piston_remove_base(pos, oldnode)
|
||||
local basenodename = minetest.registered_nodes[oldnode.name].corresponding_piston
|
||||
local pistonspec = minetest.registered_nodes[basenodename].mesecons_piston
|
||||
|
||||
local dir = piston_get_direction(pistonspec.dir, oldnode)
|
||||
local basepos = vector.subtract(pos, dir)
|
||||
local basename = minetest.get_node(basepos).name
|
||||
|
||||
if basename == pistonspec.onname then -- make sure there actually is a base node
|
||||
minetest.remove_node(basepos)
|
||||
minetest.check_for_falling(basepos)
|
||||
minetest.sound_play("piston_retract", {
|
||||
pos = pos,
|
||||
max_hear_distance = 31,
|
||||
gain = 0.3,
|
||||
}, true)
|
||||
end
|
||||
end
|
||||
|
||||
local function piston_on(pos, node)
|
||||
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
|
||||
|
||||
local dir = piston_get_direction(pistonspec.dir, node)
|
||||
local np = vector.add(pos, dir)
|
||||
local meta = minetest.get_meta(pos)
|
||||
local success, stack, oldstack = mesecon.mvps_push(np, dir, PISTON_MAXIMUM_PUSH, meta:get_string("owner"), pos)
|
||||
if success then
|
||||
minetest.swap_node(pos, {param2 = node.param2, name = pistonspec.onname})
|
||||
minetest.set_node(np, {param2 = node.param2, name = pistonspec.pusher})
|
||||
local below = minetest.get_node({x=np.x,y=np.y-1,z=np.z})
|
||||
if below.name == "mcl_farming:soil" or below.name == "mcl_farming:soil_wet" then
|
||||
minetest.set_node({x=np.x,y=np.y-1,z=np.z}, {name = "mcl_core:dirt"})
|
||||
end
|
||||
mesecon.mvps_process_stack(stack)
|
||||
mesecon.mvps_move_objects(np, dir, oldstack)
|
||||
minetest.sound_play("piston_extend", {
|
||||
pos = pos,
|
||||
max_hear_distance = 31,
|
||||
gain = 0.3,
|
||||
}, true)
|
||||
end
|
||||
end
|
||||
|
||||
local function piston_off(pos, node)
|
||||
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
|
||||
minetest.swap_node(pos, {param2 = node.param2, name = pistonspec.offname})
|
||||
piston_remove_pusher (pos, node)
|
||||
if not pistonspec.sticky then
|
||||
return
|
||||
end
|
||||
|
||||
local dir = piston_get_direction(pistonspec.dir, node)
|
||||
local pullpos = vector.add(pos, vector.multiply(dir, 2))
|
||||
local meta = minetest.get_meta(pos)
|
||||
local success, stack = mesecon.mvps_pull_single(pullpos, vector.multiply(dir, -1), PISTON_MAXIMUM_PUSH, meta:get_string("owner"), pos)
|
||||
if success then
|
||||
mesecon.mvps_process_stack(pos, dir, stack)
|
||||
end
|
||||
end
|
||||
|
||||
local function piston_orientate(pos, placer)
|
||||
mesecon.mvps_set_owner(pos, placer)
|
||||
|
||||
-- not placed by player
|
||||
if not placer then return end
|
||||
|
||||
-- placer pitch in degrees
|
||||
local pitch = placer:get_look_vertical() * (180 / math.pi)
|
||||
|
||||
local node = minetest.get_node(pos)
|
||||
local pistonspec = minetest.registered_nodes[node.name].mesecons_piston
|
||||
if pitch > 55 then
|
||||
minetest.add_node(pos, {name=pistonspec.piston_up})
|
||||
elseif pitch < -55 then
|
||||
minetest.add_node(pos, {name=pistonspec.piston_down})
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- Horizontal pistons
|
||||
|
||||
local pt = 4/16 -- pusher thickness
|
||||
|
||||
local piston_pusher_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-2/16, -2/16, -.5 + pt, 2/16, 2/16, .5 + pt},
|
||||
{-.5 , -.5 , -.5 , .5 , .5 , -.5 + pt},
|
||||
},
|
||||
}
|
||||
|
||||
local piston_on_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-.5, -.5, -.5 + pt, .5, .5, .5}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
-- Normal (non-sticky) ones:
|
||||
|
||||
local pistonspec_normal = {
|
||||
offname = "mesecons_pistons:piston_normal_off",
|
||||
onname = "mesecons_pistons:piston_normal_on",
|
||||
dir = piston_facedir_direction,
|
||||
pusher = "mesecons_pistons:piston_pusher_normal",
|
||||
piston_down = "mesecons_pistons:piston_down_normal_off",
|
||||
piston_up = "mesecons_pistons:piston_up_normal_off",
|
||||
}
|
||||
|
||||
local usagehelp_piston = S("This block can have one of 6 possible orientations.")
|
||||
|
||||
-- offstate
|
||||
minetest.register_node("mesecons_pistons:piston_normal_off", {
|
||||
description = S("Piston"),
|
||||
_tt_help = S("Pushes block when powered by redstone power"),
|
||||
_doc_items_longdesc = S("A piston is a redstone component with a pusher which pushes the block or blocks in front of it when it is supplied with redstone power. Not all blocks can be pushed, however."),
|
||||
_doc_items_usagehelp = usagehelp_piston,
|
||||
tiles = {
|
||||
"mesecons_piston_bottom.png^[transformR180",
|
||||
"mesecons_piston_bottom.png",
|
||||
"mesecons_piston_bottom.png^[transformR90",
|
||||
"mesecons_piston_bottom.png^[transformR270",
|
||||
"mesecons_piston_back.png",
|
||||
"mesecons_piston_pusher_front.png"
|
||||
},
|
||||
groups = {handy=1, piston=1},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
after_place_node = piston_orientate,
|
||||
mesecons_piston = pistonspec_normal,
|
||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
mesecons = {
|
||||
effector = {
|
||||
action_on = piston_on,
|
||||
rules = piston_get_rules
|
||||
},
|
||||
},
|
||||
_mcl_blast_resistance = 0.5,
|
||||
_mcl_hardness = 0.5,
|
||||
on_rotate = function(pos, node, user, mode)
|
||||
if mode == screwdriver.ROTATE_AXIS then
|
||||
minetest.set_node(pos, {name="mesecons_pistons:piston_up_normal_off"})
|
||||
return true
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
-- onstate
|
||||
minetest.register_node("mesecons_pistons:piston_normal_on", {
|
||||
drawtype = "nodebox",
|
||||
tiles = {
|
||||
"mesecons_piston_bottom.png^[transformR180",
|
||||
"mesecons_piston_bottom.png",
|
||||
"mesecons_piston_bottom.png^[transformR90",
|
||||
"mesecons_piston_bottom.png^[transformR270",
|
||||
"mesecons_piston_back.png",
|
||||
"mesecons_piston_on_front.png"
|
||||
},
|
||||
groups = {handy=1, piston=1, not_in_creative_inventory=1},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
drop = "mesecons_pistons:piston_normal_off",
|
||||
after_destruct = piston_remove_pusher,
|
||||
node_box = piston_on_box,
|
||||
selection_box = piston_on_box,
|
||||
mesecons_piston = pistonspec_normal,
|
||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
mesecons = {
|
||||
effector = {
|
||||
action_off = piston_off,
|
||||
rules = piston_get_rules
|
||||
},
|
||||
},
|
||||
_mcl_blast_resistance = 0.5,
|
||||
_mcl_hardness = 0.5,
|
||||
on_rotate = false,
|
||||
})
|
||||
|
||||
-- pusher
|
||||
minetest.register_node("mesecons_pistons:piston_pusher_normal", {
|
||||
drawtype = "nodebox",
|
||||
tiles = {
|
||||
"mesecons_piston_pusher_top.png",
|
||||
"mesecons_piston_pusher_bottom.png",
|
||||
"mesecons_piston_pusher_left.png",
|
||||
"mesecons_piston_pusher_right.png",
|
||||
"mesecons_piston_pusher_back.png",
|
||||
"mesecons_piston_pusher_front.png"
|
||||
},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {piston_pusher=1},
|
||||
is_ground_content = false,
|
||||
after_destruct = piston_remove_base,
|
||||
diggable = false,
|
||||
drop = "",
|
||||
corresponding_piston = "mesecons_pistons:piston_normal_on",
|
||||
selection_box = piston_pusher_box,
|
||||
node_box = piston_pusher_box,
|
||||
sounds = mcl_sounds.node_sound_wood_defaults(),
|
||||
_mcl_blast_resistance = 0.5,
|
||||
on_rotate = false,
|
||||
})
|
||||
|
||||
-- Sticky ones
|
||||
|
||||
local pistonspec_sticky = {
|
||||
offname = "mesecons_pistons:piston_sticky_off",
|
||||
onname = "mesecons_pistons:piston_sticky_on",
|
||||
dir = piston_facedir_direction,
|
||||
pusher = "mesecons_pistons:piston_pusher_sticky",
|
||||
sticky = true,
|
||||
piston_down = "mesecons_pistons:piston_down_sticky_off",
|
||||
piston_up = "mesecons_pistons:piston_up_sticky_off",
|
||||
}
|
||||
|
||||
-- offstate
|
||||
minetest.register_node("mesecons_pistons:piston_sticky_off", {
|
||||
description = S("Sticky Piston"),
|
||||
_tt_help = S("Pushes or pulls block when powered by redstone power"),
|
||||
_doc_items_longdesc = S("A sticky piston is a redstone component with a sticky pusher which can be extended and retracted. It extends when it is supplied with redstone power. When the pusher extends, it pushes the block or blocks in front of it. When it retracts, it pulls back the single block in front of it. Note that not all blocks can be pushed or pulled."),
|
||||
_doc_items_usagehelp = usagehelp_piston,
|
||||
|
||||
tiles = {
|
||||
"mesecons_piston_bottom.png^[transformR180",
|
||||
"mesecons_piston_bottom.png",
|
||||
"mesecons_piston_bottom.png^[transformR90",
|
||||
"mesecons_piston_bottom.png^[transformR270",
|
||||
"mesecons_piston_back.png",
|
||||
"mesecons_piston_pusher_front_sticky.png"
|
||||
},
|
||||
groups = {handy=1, piston=2},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
after_place_node = piston_orientate,
|
||||
mesecons_piston = pistonspec_sticky,
|
||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
mesecons = {
|
||||
effector = {
|
||||
action_on = piston_on,
|
||||
rules = piston_get_rules
|
||||
},
|
||||
},
|
||||
_mcl_blast_resistance = 0.5,
|
||||
_mcl_hardness = 0.5,
|
||||
on_rotate = function(pos, node, user, mode)
|
||||
if mode == screwdriver.ROTATE_AXIS then
|
||||
minetest.set_node(pos, {name="mesecons_pistons:piston_up_sticky_off"})
|
||||
return true
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
-- onstate
|
||||
minetest.register_node("mesecons_pistons:piston_sticky_on", {
|
||||
drawtype = "nodebox",
|
||||
tiles = {
|
||||
"mesecons_piston_bottom.png^[transformR180",
|
||||
"mesecons_piston_bottom.png",
|
||||
"mesecons_piston_bottom.png^[transformR90",
|
||||
"mesecons_piston_bottom.png^[transformR270",
|
||||
"mesecons_piston_back.png",
|
||||
"mesecons_piston_on_front.png"
|
||||
},
|
||||
groups = {handy=1, piston=2, not_in_creative_inventory=1},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
drop = "mesecons_pistons:piston_sticky_off",
|
||||
after_destruct = piston_remove_pusher,
|
||||
node_box = piston_on_box,
|
||||
selection_box = piston_on_box,
|
||||
mesecons_piston = pistonspec_sticky,
|
||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
mesecons = {
|
||||
effector = {
|
||||
action_off = piston_off,
|
||||
rules = piston_get_rules
|
||||
},
|
||||
},
|
||||
_mcl_blast_resistance = 0.5,
|
||||
_mcl_hardness = 0.5,
|
||||
on_rotate = false,
|
||||
})
|
||||
|
||||
-- pusher
|
||||
minetest.register_node("mesecons_pistons:piston_pusher_sticky", {
|
||||
drawtype = "nodebox",
|
||||
tiles = {
|
||||
"mesecons_piston_pusher_top.png",
|
||||
"mesecons_piston_pusher_bottom.png",
|
||||
"mesecons_piston_pusher_left.png",
|
||||
"mesecons_piston_pusher_right.png",
|
||||
"mesecons_piston_pusher_back.png",
|
||||
"mesecons_piston_pusher_front_sticky.png"
|
||||
},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {piston_pusher=2},
|
||||
is_ground_content = false,
|
||||
after_destruct = piston_remove_base,
|
||||
diggable = false,
|
||||
drop = "",
|
||||
corresponding_piston = "mesecons_pistons:piston_sticky_on",
|
||||
selection_box = piston_pusher_box,
|
||||
node_box = piston_pusher_box,
|
||||
sounds = mcl_sounds.node_sound_wood_defaults(),
|
||||
_mcl_blast_resistance = 0.5,
|
||||
on_rotate = false,
|
||||
})
|
||||
|
||||
--
|
||||
--
|
||||
-- UP
|
||||
--
|
||||
--
|
||||
|
||||
local piston_up_pusher_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-2/16, -.5 - pt, -2/16, 2/16, .5 - pt, 2/16},
|
||||
{-.5 , .5 - pt, -.5 , .5 , .5 , .5},
|
||||
},
|
||||
}
|
||||
|
||||
local piston_up_on_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-.5, -.5, -.5 , .5, .5-pt, .5}
|
||||
},
|
||||
}
|
||||
|
||||
-- Normal
|
||||
|
||||
local pistonspec_normal_up = {
|
||||
offname = "mesecons_pistons:piston_up_normal_off",
|
||||
onname = "mesecons_pistons:piston_up_normal_on",
|
||||
dir = {x = 0, y = 1, z = 0},
|
||||
pusher = "mesecons_pistons:piston_up_pusher_normal",
|
||||
}
|
||||
|
||||
-- offstate
|
||||
minetest.register_node("mesecons_pistons:piston_up_normal_off", {
|
||||
tiles = {
|
||||
"mesecons_piston_pusher_front.png",
|
||||
"mesecons_piston_back.png",
|
||||
"mesecons_piston_bottom.png",
|
||||
"mesecons_piston_bottom.png",
|
||||
"mesecons_piston_bottom.png",
|
||||
"mesecons_piston_bottom.png",
|
||||
},
|
||||
groups = {handy=1, piston=1, not_in_creative_inventory=1},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
drop = "mesecons_pistons:piston_normal_off",
|
||||
mesecons_piston = pistonspec_normal_up,
|
||||
mesecons = {
|
||||
effector = {
|
||||
action_on = piston_on,
|
||||
rules = piston_up_rules,
|
||||
},
|
||||
},
|
||||
sounds = mcl_sounds.node_sound_stone_defaults({
|
||||
footstep = mcl_sounds.node_sound_wood_defaults().footstep
|
||||
}),
|
||||
_mcl_blast_resistance = 0.5,
|
||||
_mcl_hardness = 0.5,
|
||||
on_rotate = function(pos, node, user, mode)
|
||||
if mode == screwdriver.ROTATE_AXIS then
|
||||
minetest.set_node(pos, {name="mesecons_pistons:piston_down_normal_off"})
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
})
|
||||
|
||||
-- onstate
|
||||
minetest.register_node("mesecons_pistons:piston_up_normal_on", {
|
||||
drawtype = "nodebox",
|
||||
tiles = {
|
||||
"mesecons_piston_on_front.png",
|
||||
"mesecons_piston_back.png",
|
||||
"mesecons_piston_bottom.png",
|
||||
"mesecons_piston_bottom.png",
|
||||
"mesecons_piston_bottom.png",
|
||||
"mesecons_piston_bottom.png",
|
||||
},
|
||||
groups = {handy=1, piston_=1, not_in_creative_inventory=1},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
drop = "mesecons_pistons:piston_normal_off",
|
||||
after_destruct = piston_remove_pusher,
|
||||
node_box = piston_up_on_box,
|
||||
selection_box = piston_up_on_box,
|
||||
mesecons_piston = pistonspec_normal_up,
|
||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
mesecons = {
|
||||
effector = {
|
||||
action_off = piston_off,
|
||||
rules = piston_up_rules,
|
||||
},
|
||||
},
|
||||
_mcl_blast_resistance = 0.5,
|
||||
_mcl_hardness = 0.5,
|
||||
on_rotate = false,
|
||||
})
|
||||
|
||||
-- pusher
|
||||
minetest.register_node("mesecons_pistons:piston_up_pusher_normal", {
|
||||
drawtype = "nodebox",
|
||||
tiles = {
|
||||
"mesecons_piston_pusher_front.png",
|
||||
"mesecons_piston_pusher_back.png",
|
||||
"mesecons_piston_pusher_left.png^[transformR270",
|
||||
"mesecons_piston_pusher_right.png^[transformR90",
|
||||
"mesecons_piston_pusher_bottom.png",
|
||||
"mesecons_piston_pusher_top.png^[transformR180",
|
||||
},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {piston_pusher=1},
|
||||
is_ground_content = false,
|
||||
after_destruct = piston_remove_base,
|
||||
diggable = false,
|
||||
drop = "",
|
||||
corresponding_piston = "mesecons_pistons:piston_up_normal_on",
|
||||
selection_box = piston_up_pusher_box,
|
||||
node_box = piston_up_pusher_box,
|
||||
sounds = mcl_sounds.node_sound_wood_defaults(),
|
||||
_mcl_blast_resistance = 0.5,
|
||||
on_rotate = false,
|
||||
})
|
||||
|
||||
|
||||
|
||||
-- Sticky
|
||||
|
||||
|
||||
local pistonspec_sticky_up = {
|
||||
offname = "mesecons_pistons:piston_up_sticky_off",
|
||||
onname = "mesecons_pistons:piston_up_sticky_on",
|
||||
dir = {x = 0, y = 1, z = 0},
|
||||
pusher = "mesecons_pistons:piston_up_pusher_sticky",
|
||||
sticky = true,
|
||||
}
|
||||
|
||||
-- offstate
|
||||
minetest.register_node("mesecons_pistons:piston_up_sticky_off", {
|
||||
tiles = {
|
||||
"mesecons_piston_pusher_front_sticky.png",
|
||||
"mesecons_piston_back.png",
|
||||
"mesecons_piston_bottom.png",
|
||||
"mesecons_piston_bottom.png",
|
||||
"mesecons_piston_bottom.png",
|
||||
"mesecons_piston_bottom.png",
|
||||
},
|
||||
groups = {handy=1, piston=2, not_in_creative_inventory=1},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
drop = "mesecons_pistons:piston_sticky_off",
|
||||
mesecons_piston = pistonspec_sticky_up,
|
||||
sounds = mcl_sounds.node_sound_stone_defaults({
|
||||
footstep = mcl_sounds.node_sound_wood_defaults().footstep
|
||||
}),
|
||||
mesecons = {
|
||||
effector = {
|
||||
action_on = piston_on,
|
||||
rules = piston_up_rules,
|
||||
},
|
||||
},
|
||||
_mcl_blast_resistance = 0.5,
|
||||
_mcl_hardness = 0.5,
|
||||
on_rotate = function(pos, node, user, mode)
|
||||
if mode == screwdriver.ROTATE_AXIS then
|
||||
minetest.set_node(pos, {name="mesecons_pistons:piston_down_sticky_off"})
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
})
|
||||
|
||||
-- onstate
|
||||
minetest.register_node("mesecons_pistons:piston_up_sticky_on", {
|
||||
drawtype = "nodebox",
|
||||
tiles = {
|
||||
"mesecons_piston_on_front.png",
|
||||
"mesecons_piston_back.png",
|
||||
"mesecons_piston_bottom.png",
|
||||
"mesecons_piston_bottom.png",
|
||||
"mesecons_piston_bottom.png",
|
||||
"mesecons_piston_bottom.png",
|
||||
},
|
||||
groups = {handy=1, piston=2, not_in_creative_inventory=1},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
drop = "mesecons_pistons:piston_sticky_off",
|
||||
after_destruct = piston_remove_pusher,
|
||||
node_box = piston_up_on_box,
|
||||
selection_box = piston_up_on_box,
|
||||
mesecons_piston = pistonspec_sticky_up,
|
||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
mesecons = {
|
||||
effector = {
|
||||
action_off = piston_off,
|
||||
rules = piston_up_rules,
|
||||
},
|
||||
},
|
||||
_mcl_blast_resistance = 0.5,
|
||||
_mcl_hardness = 0.5,
|
||||
on_rotate = false,
|
||||
})
|
||||
|
||||
-- pusher
|
||||
minetest.register_node("mesecons_pistons:piston_up_pusher_sticky", {
|
||||
drawtype = "nodebox",
|
||||
tiles = {
|
||||
"mesecons_piston_pusher_front_sticky.png",
|
||||
"mesecons_piston_pusher_back.png",
|
||||
"mesecons_piston_pusher_left.png^[transformR270",
|
||||
"mesecons_piston_pusher_right.png^[transformR90",
|
||||
"mesecons_piston_pusher_bottom.png",
|
||||
"mesecons_piston_pusher_top.png^[transformR180",
|
||||
},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {piston_pusher=2},
|
||||
is_ground_content = false,
|
||||
after_destruct = piston_remove_base,
|
||||
diggable = false,
|
||||
drop = "",
|
||||
corresponding_piston = "mesecons_pistons:piston_up_sticky_on",
|
||||
selection_box = piston_up_pusher_box,
|
||||
node_box = piston_up_pusher_box,
|
||||
sounds = mcl_sounds.node_sound_wood_defaults(),
|
||||
_mcl_blast_resistance = 0.5,
|
||||
on_rotate = false,
|
||||
})
|
||||
|
||||
--
|
||||
--
|
||||
-- DOWN
|
||||
--
|
||||
--
|
||||
|
||||
local piston_down_pusher_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-2/16, -.5 + pt, -2/16, 2/16, .5 + pt, 2/16},
|
||||
{-.5 , -.5 , -.5 , .5 , -.5 + pt, .5},
|
||||
},
|
||||
}
|
||||
|
||||
local piston_down_on_box = {
|
||||
type = "fixed",
|
||||
fixed = {
|
||||
{-.5, -.5+pt, -.5 , .5, .5, .5}
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
||||
-- Normal
|
||||
|
||||
local pistonspec_normal_down = {
|
||||
offname = "mesecons_pistons:piston_down_normal_off",
|
||||
onname = "mesecons_pistons:piston_down_normal_on",
|
||||
dir = {x = 0, y = -1, z = 0},
|
||||
pusher = "mesecons_pistons:piston_down_pusher_normal",
|
||||
}
|
||||
|
||||
-- offstate
|
||||
minetest.register_node("mesecons_pistons:piston_down_normal_off", {
|
||||
tiles = {
|
||||
"mesecons_piston_back.png",
|
||||
"mesecons_piston_pusher_front.png",
|
||||
"mesecons_piston_bottom.png^[transformR180",
|
||||
"mesecons_piston_bottom.png^[transformR180",
|
||||
"mesecons_piston_bottom.png^[transformR180",
|
||||
"mesecons_piston_bottom.png^[transformR180",
|
||||
},
|
||||
groups = {handy=1, piston=1, not_in_creative_inventory=1},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
drop = "mesecons_pistons:piston_normal_off",
|
||||
mesecons_piston = pistonspec_normal_down,
|
||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
mesecons = {
|
||||
effector = {
|
||||
action_on = piston_on,
|
||||
rules = piston_down_rules,
|
||||
},
|
||||
},
|
||||
_mcl_blast_resistance = 0.5,
|
||||
_mcl_hardness = 0.5,
|
||||
on_rotate = function(pos, node, user, mode)
|
||||
if mode == screwdriver.ROTATE_AXIS then
|
||||
minetest.set_node(pos, {name="mesecons_pistons:piston_normal_off"})
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
})
|
||||
|
||||
-- onstate
|
||||
minetest.register_node("mesecons_pistons:piston_down_normal_on", {
|
||||
drawtype = "nodebox",
|
||||
tiles = {
|
||||
"mesecons_piston_back.png",
|
||||
"mesecons_piston_on_front.png",
|
||||
"mesecons_piston_bottom.png^[transformR180",
|
||||
"mesecons_piston_bottom.png^[transformR180",
|
||||
"mesecons_piston_bottom.png^[transformR180",
|
||||
"mesecons_piston_bottom.png^[transformR180",
|
||||
},
|
||||
groups = {handy=1, piston=1, not_in_creative_inventory=1},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
drop = "mesecons_pistons:piston_normal_off",
|
||||
after_destruct = piston_remove_pusher,
|
||||
node_box = piston_down_on_box,
|
||||
selection_box = piston_down_on_box,
|
||||
mesecons_piston = pistonspec_normal_down,
|
||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
mesecons = {
|
||||
effector = {
|
||||
action_off = piston_off,
|
||||
rules = piston_down_rules,
|
||||
},
|
||||
},
|
||||
_mcl_blast_resistance = 0.5,
|
||||
_mcl_hardness = 0.5,
|
||||
on_rotate = false,
|
||||
})
|
||||
|
||||
-- pusher
|
||||
minetest.register_node("mesecons_pistons:piston_down_pusher_normal", {
|
||||
drawtype = "nodebox",
|
||||
tiles = {
|
||||
"mesecons_piston_pusher_back.png",
|
||||
"mesecons_piston_pusher_front.png",
|
||||
"mesecons_piston_pusher_left.png^[transformR90",
|
||||
"mesecons_piston_pusher_right.png^[transformR270",
|
||||
"mesecons_piston_pusher_bottom.png^[transformR180",
|
||||
"mesecons_piston_pusher_top.png",
|
||||
},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {piston_pusher=1},
|
||||
is_ground_content = false,
|
||||
after_destruct = piston_remove_base,
|
||||
diggable = false,
|
||||
drop = "",
|
||||
corresponding_piston = "mesecons_pistons:piston_down_normal_on",
|
||||
selection_box = piston_down_pusher_box,
|
||||
node_box = piston_down_pusher_box,
|
||||
sounds = mcl_sounds.node_sound_wood_defaults(),
|
||||
_mcl_blast_resistance = 0.5,
|
||||
on_rotate = false,
|
||||
})
|
||||
|
||||
-- Sticky
|
||||
|
||||
local pistonspec_sticky_down = {
|
||||
onname = "mesecons_pistons:piston_down_sticky_on",
|
||||
offname = "mesecons_pistons:piston_down_sticky_off",
|
||||
dir = {x = 0, y = -1, z = 0},
|
||||
pusher = "mesecons_pistons:piston_down_pusher_sticky",
|
||||
sticky = true,
|
||||
}
|
||||
|
||||
-- offstate
|
||||
minetest.register_node("mesecons_pistons:piston_down_sticky_off", {
|
||||
tiles = {
|
||||
"mesecons_piston_back.png",
|
||||
"mesecons_piston_pusher_front_sticky.png",
|
||||
"mesecons_piston_bottom.png^[transformR180",
|
||||
"mesecons_piston_bottom.png^[transformR180",
|
||||
"mesecons_piston_bottom.png^[transformR180",
|
||||
"mesecons_piston_bottom.png^[transformR180",
|
||||
},
|
||||
groups = {handy=1, piston=2, not_in_creative_inventory = 1},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
drop = "mesecons_pistons:piston_sticky_off",
|
||||
mesecons_piston = pistonspec_sticky_down,
|
||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
mesecons = {
|
||||
effector = {
|
||||
action_on = piston_on,
|
||||
rules = piston_down_rules,
|
||||
},
|
||||
},
|
||||
_mcl_blast_resistance = 0.5,
|
||||
_mcl_hardness = 0.5,
|
||||
on_rotate = function(pos, node, user, mode)
|
||||
if mode == screwdriver.ROTATE_AXIS then
|
||||
minetest.set_node(pos, {name="mesecons_pistons:piston_sticky_off"})
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end,
|
||||
})
|
||||
|
||||
-- onstate
|
||||
minetest.register_node("mesecons_pistons:piston_down_sticky_on", {
|
||||
drawtype = "nodebox",
|
||||
tiles = {
|
||||
"mesecons_piston_back.png",
|
||||
"mesecons_piston_on_front.png",
|
||||
"mesecons_piston_bottom.png^[transformR180",
|
||||
"mesecons_piston_bottom.png^[transformR180",
|
||||
"mesecons_piston_bottom.png^[transformR180",
|
||||
"mesecons_piston_bottom.png^[transformR180",
|
||||
},
|
||||
groups = {handy=1, piston=1, not_in_creative_inventory=1},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
is_ground_content = false,
|
||||
drop = "mesecons_pistons:piston_sticky_off",
|
||||
after_destruct = piston_remove_pusher,
|
||||
node_box = piston_down_on_box,
|
||||
selection_box = piston_down_on_box,
|
||||
mesecons_piston = pistonspec_sticky_down,
|
||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||
mesecons = {
|
||||
effector = {
|
||||
action_off = piston_off,
|
||||
rules = piston_down_rules,
|
||||
},
|
||||
},
|
||||
_mcl_blast_resistance = 0.5,
|
||||
_mcl_hardness = 0.5,
|
||||
on_rotate = false,
|
||||
})
|
||||
|
||||
-- pusher
|
||||
minetest.register_node("mesecons_pistons:piston_down_pusher_sticky", {
|
||||
drawtype = "nodebox",
|
||||
tiles = {
|
||||
"mesecons_piston_pusher_back.png",
|
||||
"mesecons_piston_pusher_front_sticky.png",
|
||||
"mesecons_piston_pusher_left.png^[transformR90",
|
||||
"mesecons_piston_pusher_right.png^[transformR270",
|
||||
"mesecons_piston_pusher_bottom.png^[transformR180",
|
||||
"mesecons_piston_pusher_top.png",
|
||||
},
|
||||
paramtype = "light",
|
||||
paramtype2 = "facedir",
|
||||
groups = {piston_pusher=2},
|
||||
is_ground_content = false,
|
||||
after_destruct = piston_remove_base,
|
||||
diggable = false,
|
||||
drop = "",
|
||||
corresponding_piston = "mesecons_pistons:piston_down_sticky_on",
|
||||
selection_box = piston_down_pusher_box,
|
||||
node_box = piston_down_pusher_box,
|
||||
sounds = mcl_sounds.node_sound_wood_defaults(),
|
||||
_mcl_blast_resistance = 0.5,
|
||||
on_rotate = false,
|
||||
})
|
||||
|
||||
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_pusher_normal")
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_pusher_sticky")
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_up_pusher_normal")
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_up_pusher_sticky")
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_down_pusher_normal")
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_down_pusher_sticky")
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_normal_on")
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_sticky_on")
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_up_normal_on")
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_up_sticky_on")
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_down_normal_on")
|
||||
mesecon.register_mvps_stopper("mesecons_pistons:piston_down_sticky_on")
|
||||
|
||||
--craft recipes
|
||||
minetest.register_craft({
|
||||
output = "mesecons_pistons:piston_normal_off",
|
||||
recipe = {
|
||||
{"group:wood", "group:wood", "group:wood"},
|
||||
{"mcl_core:cobble", "mcl_core:iron_ingot", "mcl_core:cobble"},
|
||||
{"mcl_core:cobble", "mesecons:redstone", "mcl_core:cobble"},
|
||||
},
|
||||
})
|
||||
|
||||
minetest.register_craft({
|
||||
output = "mesecons_pistons:piston_sticky_off",
|
||||
recipe = {
|
||||
{"mcl_mobitems:slimeball"},
|
||||
{"mesecons_pistons:piston_normal_off"},
|
||||
},
|
||||
})
|
||||
|
||||
-- Add entry aliases for the Help
|
||||
if minetest.get_modpath("doc") then
|
||||
doc.add_entry_alias("nodes", "mesecons_pistons:piston_normal_off", "nodes", "mesecons_pistons:piston_normal_on")
|
||||
doc.add_entry_alias("nodes", "mesecons_pistons:piston_normal_off", "nodes", "mesecons_pistons:piston_up_normal_off")
|
||||
doc.add_entry_alias("nodes", "mesecons_pistons:piston_normal_off", "nodes", "mesecons_pistons:piston_up_normal_on")
|
||||
doc.add_entry_alias("nodes", "mesecons_pistons:piston_normal_off", "nodes", "mesecons_pistons:piston_down_normal_off")
|
||||
doc.add_entry_alias("nodes", "mesecons_pistons:piston_normal_off", "nodes", "mesecons_pistons:piston_down_normal_on")
|
||||
doc.add_entry_alias("nodes", "mesecons_pistons:piston_normal_off", "nodes", "mesecons_pistons:piston_pusher_normal")
|
||||
doc.add_entry_alias("nodes", "mesecons_pistons:piston_normal_off", "nodes", "mesecons_pistons:piston_up_pusher_normal")
|
||||
doc.add_entry_alias("nodes", "mesecons_pistons:piston_normal_off", "nodes", "mesecons_pistons:piston_down_pusher_normal")
|
||||
|
||||
doc.add_entry_alias("nodes", "mesecons_pistons:piston_sticky_off", "nodes", "mesecons_pistons:piston_sticky_on")
|
||||
doc.add_entry_alias("nodes", "mesecons_pistons:piston_sticky_off", "nodes", "mesecons_pistons:piston_up_sticky_off")
|
||||
doc.add_entry_alias("nodes", "mesecons_pistons:piston_sticky_off", "nodes", "mesecons_pistons:piston_up_sticky_on")
|
||||
doc.add_entry_alias("nodes", "mesecons_pistons:piston_sticky_off", "nodes", "mesecons_pistons:piston_down_sticky_off")
|
||||
doc.add_entry_alias("nodes", "mesecons_pistons:piston_sticky_off", "nodes", "mesecons_pistons:piston_down_sticky_on")
|
||||
doc.add_entry_alias("nodes", "mesecons_pistons:piston_sticky_off", "nodes", "mesecons_pistons:piston_pusher_sticky")
|
||||
doc.add_entry_alias("nodes", "mesecons_pistons:piston_sticky_off", "nodes", "mesecons_pistons:piston_up_pusher_sticky")
|
||||
doc.add_entry_alias("nodes", "mesecons_pistons:piston_sticky_off", "nodes", "mesecons_pistons:piston_down_pusher_sticky")
|
||||
end
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
# textdomain: mesecons_pistons
|
||||
This block can have one of 6 possible orientations.=Dieser Block kann eine von 6 möglichen Richtungen annehmen.
|
||||
Piston=Kolben
|
||||
A piston is a redstone component with a pusher which pushes the block or blocks in front of it when it is supplied with redstone power. Not all blocks can be pushed, however.=Ein Kolben ist eine Redstonekomponente mit einem Schieber den Block oder die Blöcke vor ihm schieben wird, wenn er mit Redstoneenergie versorgt wird. Allerdings können nicht alle Blöcke können geschoben werden.
|
||||
Sticky Piston=Klebriger Kolben
|
||||
A sticky piston is a redstone component with a sticky pusher which can be extended and retracted. It extends when it is supplied with redstone power. When the pusher extends, it pushes the block or blocks in front of it. When it retracts, it pulls back the single block in front of it. Note that not all blocks can be pushed or pulled.=Ein klebriger Kolben ist eine Redstonekomponente mit einem klebrigen Schieber, der ein- und ausgefahren werden kann. Er fährt aus, wenn er mit Redstoneenergie versorgt wird. Wenn der Schieber ausgefahren wird, schiebt er den Block oder die Blöcke vor ihm. Wird er eingefahren, zieht er den Block vor ihm zu sich. Nicht alle Blöcke können geschoben oder gezogen werden.
|
||||
Pushes block when powered by redstone power=Schiebt Block, wenn mit Redstoneenergie versorgt
|
||||
Pushes or pulls block when powered by redstone power=Schiebt oder zieht Block, wenn mit Redstoneenergie versorgt
|
|
@ -1,6 +0,0 @@
|
|||
# textdomain: mesecons_pistons
|
||||
This block can have one of 6 possible orientations.=Este bloque puede tener una de las 6 orientaciones posibles.
|
||||
Piston=Pistón
|
||||
A piston is a redstone component with a pusher which pushes the block or blocks in front of it when it is supplied with redstone power. Not all blocks can be pushed, however.=Un pistón es un componente de redstone con un empujador que empuja el bloque o bloques frente a él cuando se le suministra energía de redstone. Sin embargo, no todos los bloques se pueden empujar.
|
||||
Sticky Piston=Pistón pegajoso
|
||||
A sticky piston is a redstone component with a sticky pusher which can be extended and retracted. It extends when it is supplied with redstone power. When the pusher extends, it pushes the block or blocks in front of it. When it retracts, it pulls back the single block in front of it. Note that not all blocks can be pushed or pulled.=Un pistón pegajoso es un componente de redstone con un empujador pegajoso que se puede extender y retraer. Se extiende cuando se le suministra energía de redstone. Cuando el empujador se extiende, empuja el bloque o bloques frente a él. Cuando se retrae, tira hacia atrás el bloque único que está frente a él. Tenga en cuenta que no todos los bloques se pueden empujar o tirar.
|
|
@ -1,8 +0,0 @@
|
|||
# textdomain: mesecons_pistons
|
||||
This block can have one of 6 possible orientations.=Ce bloc peut avoir l'une des 6 orientations possibles.
|
||||
Piston=Piston
|
||||
A piston is a redstone component with a pusher which pushes the block or blocks in front of it when it is supplied with redstone power. Not all blocks can be pushed, however.=Un piston est un composant de redstone avec un poussoir qui pousse le ou les blocs devant lui lorsqu'il est alimenté en redstone. Cependant, tous les blocs ne peuvent pas être poussés.
|
||||
Sticky Piston=Piston collant
|
||||
A sticky piston is a redstone component with a sticky pusher which can be extended and retracted. It extends when it is supplied with redstone power. When the pusher extends, it pushes the block or blocks in front of it. When it retracts, it pulls back the single block in front of it. Note that not all blocks can be pushed or pulled.=Un piston collant est un composant de redstone avec un poussoir collant qui peut être étendu et rétracté. Il se prolonge lorsqu'il est alimenté en redstone. Lorsque le poussoir s'étend, il pousse le ou les blocs devant lui. Quand il se rétracte, il recule le bloc unique devant lui. Notez que tous les blocs ne peuvent pas être poussés ou tirés.
|
||||
Pushes block when powered by redstone power=Pousse le bloc lorsqu'il est alimenté par la puissance Redstone
|
||||
Pushes or pulls block when powered by redstone power=Pousse ou tire le bloc lorsqu'il est alimenté par une puissance redstone
|
|
@ -1,9 +0,0 @@
|
|||
# textdomain: mesecons_pistons
|
||||
This block can have one of 6 possible orientations.=Ten blok może mieć 6 możliwych orientacji.
|
||||
Piston=Tłok
|
||||
A piston is a redstone component with a pusher which pushes the block or blocks in front of it when it is supplied with redstone power. Not all blocks can be pushed, however.=Tłoki są mechanizmami czerwienitowymi które popycha blok lub bloki stojące przed nim gdy dostarczy się mu energię czerwienitową, jednak nie wszystkie bloki mogą zostać popchnięte.
|
||||
Sticky Piston=Lepki tłok
|
||||
A sticky piston is a redstone component with a sticky pusher which can be extended and retracted. It extends when it is supplied with redstone power. When the pusher extends, it pushes the block or blocks in front of it. When it retracts, it pulls back the single block in front of it. Note that not all blocks can be pushed or pulled.=Lepki tłok jest mechanizmem czerwienitowym z lepkim wysięgnikiem, który można wysuwać i wsuwać. Wysuwa się gdy dostarczana jest energia czerwienitowa. Gdy się wysuwa popycha on blok lub bloki znajdujące się przed nim. Gdy się wsuwa przyciąga on pojedynczy blok przed nim. Nie wszystkie bloki mogą być przesuwane i przyciągane.
|
||||
Pushes block when powered by redstone power=Popycha blok gdy jest zasilony czerwienitem
|
||||
Pushes or pulls block when powered by redstone power=Popycha lub przyciąga blok gdy jest zasilany czerwienitem
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
# textdomain: mesecons_pistons
|
||||
This block can have one of 6 possible orientations.=Этот блок быть ориентирован в одном из 6 возможных направлений.
|
||||
Piston=Поршень
|
||||
A piston is a redstone component with a pusher which pushes the block or blocks in front of it when it is supplied with redstone power. Not all blocks can be pushed, however.=Поршень это компонент редстоуна с толкателем, который толкает блок или блоки перед собой при подаче энергии редстоуна. Следует отметить, что не все блоки могут быть сдвинуты.
|
||||
Sticky Piston=Липкий поршень
|
||||
A sticky piston is a redstone component with a sticky pusher which can be extended and retracted. It extends when it is supplied with redstone power. When the pusher extends, it pushes the block or blocks in front of it. When it retracts, it pulls back the single block in front of it. Note that not all blocks can be pushed or pulled.=Липкий поршень представляет собой компонент редстоуна с липким толкателем, который можно удлинять и втягивать обратно. Он расширяется, когда на него подается энергия красного камня. Когда толкатель выдвигается, он толкает блок или блоки перед собой. Когда он втягивается, он возвращает обратно один блок перед собой. Следует отметить, что не все блоки могут быть сдвинуты. или втянуты.
|
||||
Pushes block when powered by redstone power=Толкает блок при подаче энергии редстоуна
|
||||
Pushes or pulls block when powered by redstone power=Толкает или тянет блок при подаче энергии редстоуна
|
|
@ -1,8 +0,0 @@
|
|||
# textdomain: mesecons_pistons
|
||||
This block can have one of 6 possible orientations.=
|
||||
Piston=
|
||||
A piston is a redstone component with a pusher which pushes the block or blocks in front of it when it is supplied with redstone power. Not all blocks can be pushed, however.=
|
||||
Sticky Piston=
|
||||
A sticky piston is a redstone component with a sticky pusher which can be extended and retracted. It extends when it is supplied with redstone power. When the pusher extends, it pushes the block or blocks in front of it. When it retracts, it pulls back the single block in front of it. Note that not all blocks can be pushed or pulled.=
|
||||
Pushes block when powered by redstone power=
|
||||
Pushes or pulls block when powered by redstone power=
|
|
@ -1,3 +0,0 @@
|
|||
name = mesecons_pistons
|
||||
depends = mesecons, mesecons_mvps, mcl_mobitems
|
||||
optional_depends = doc, screwdriver
|
Before Width: | Height: | Size: 252 B |
Before Width: | Height: | Size: 272 B |
Before Width: | Height: | Size: 221 B |
Before Width: | Height: | Size: 245 B |
Before Width: | Height: | Size: 245 B |
Before Width: | Height: | Size: 245 B |
Before Width: | Height: | Size: 267 B |
Before Width: | Height: | Size: 245 B |
Before Width: | Height: | Size: 245 B |
Before Width: | Height: | Size: 245 B |
|
@ -1,288 +0,0 @@
|
|||
# mcl_armor
|
||||
|
||||
This mod implements the ability of registering armors.
|
||||
|
||||
## Registering an Armor Set
|
||||
|
||||
The `mcl_armor.register_set()` function aims to simplify the process of registering a full set of armor.
|
||||
|
||||
This function register four pieces of armor (head, torso, leggings, feets) based on a definition table:
|
||||
|
||||
```lua
|
||||
mcl_armor.register_set({
|
||||
--name of the armor material (used for generating itemstrings)
|
||||
name = "dummy_armor",
|
||||
|
||||
--description of the armor material
|
||||
--do NOT translate this string, it will be concatenated will each piece of armor's description and result will be automatically fetched from your mod's translation files
|
||||
description = "Dummy Armor",
|
||||
|
||||
--overide description of each armor piece
|
||||
--do NOT localize this string
|
||||
descriptions = {
|
||||
head = "Cap", --default: "Helmet"
|
||||
torso = "Tunic", --default: "Chestplate"
|
||||
legs = "Pants", --default: "Leggings"
|
||||
feet = "Shoes", --default: "Boots"
|
||||
},
|
||||
|
||||
--this is used to calculate each armor piece durability with the minecraft algorithm
|
||||
--head durability = durability * 0.6857 + 1
|
||||
--torso durability = durability * 1.0 + 1
|
||||
--legs durability = durability * 0.9375 + 1
|
||||
--feet durability = durability * 0.8125 + 1
|
||||
durability = 80,
|
||||
|
||||
--this is used then you need to specify the durability of each piece of armor
|
||||
--this field have the priority over the durability one
|
||||
--if the durability of some pieces of armor isn't specified in this field, the durability field will be used insteed
|
||||
durabilities = {
|
||||
head = 200,
|
||||
torso = 500,
|
||||
legs = 400,
|
||||
feet = 300,
|
||||
},
|
||||
|
||||
--this define how good enchants you will get then enchanting one piece of the armor in an enchanting table
|
||||
--if set to zero or nil, the armor will not be enchantable
|
||||
enchantability = 15,
|
||||
|
||||
--this define how much each piece of armor protect the player
|
||||
--these points will be shown in the HUD (chestplate bar above the health bar)
|
||||
points = {
|
||||
head = 1,
|
||||
torso = 3,
|
||||
legs = 2,
|
||||
feet = 1,
|
||||
},
|
||||
|
||||
--this attribute reduce strong damage even more
|
||||
--See https://minecraft.fandom.com/wiki/Armor#Armor_toughness for more explanations
|
||||
--default: 0
|
||||
toughness = 2,
|
||||
|
||||
--this field is used to specify some items groups that will be added to each piece of armor
|
||||
--please note that some groups do NOT need to be added by hand, because they are already handeled by the register function:
|
||||
--(armor, combat_armor, armor_<element>, combat_armor_<element>, mcl_armor_points, mcl_armor_toughness, mcl_armor_uses, enchantability)
|
||||
groups = {op_armor = 1},
|
||||
|
||||
--specify textures that will be overlayed on the entity wearing the armor
|
||||
--these fields have default values and its recommanded to keep the code clean by just using the default name for your textures
|
||||
textures = {
|
||||
head = "dummy_texture.png", --default: "<modname>_helmet_<material>.png"
|
||||
torso = "dummy_texture.png", --default: "<modname>_chestplate_<material>.png"
|
||||
legs = "dummy_texture.png", --default: "<modname>_leggings_<material>.png"
|
||||
feet = "dummy_texture.png", --default: "<modname>_boots_<material>.png"
|
||||
},
|
||||
--you can also define these fields as functions, that will be called each time the API function mcl_armor.update(obj) is called (every time you equip/unequip some armor piece, take damage, and more)
|
||||
--note that the enchanting overlay will not appear unless you implement it in the function
|
||||
--this allow to make armors where the textures change whitout needing to register many other armors with different textures
|
||||
textures = {
|
||||
head = function(obj, itemstack)
|
||||
if mcl_enchanting.is_enchanted(itemstack) then
|
||||
return "dummy_texture.png^"..mcl_enchanting.overlay
|
||||
else
|
||||
return "dummy_texture.png"
|
||||
end
|
||||
end,
|
||||
},
|
||||
|
||||
--inventory textures aren't definable using a table similar to textures or previews
|
||||
--you are forced to use the default texture names which are:
|
||||
--head: "<modname>_inv_helmet_<material>.png
|
||||
--torso: "<modname>_inv_chestplate_<material>.png
|
||||
--legs: "<modname>_inv_leggings_<material>.png
|
||||
--feet: "<modname>_inv_boots_<material>.png
|
||||
|
||||
--this callback table allow you to define functions that will be called each time an entity equip an armor piece or the mcl_armor.on_equip() function is called
|
||||
--the functions accept two arguments: obj and itemstack
|
||||
on_equip_callbacks = {
|
||||
head = function(obj, itemstack)
|
||||
--do stuff
|
||||
end,
|
||||
},
|
||||
|
||||
--this callback table allow you to define functions that will be called each time an entity unequip an armor piece or the mcl_armor.on_unequip() function is called
|
||||
--the functions accept two arguments: obj and itemstack
|
||||
on_unequip_callbacks = {
|
||||
head = function(obj, itemstack)
|
||||
--do stuff
|
||||
end,
|
||||
},
|
||||
|
||||
--this callback table allow you to define functions that will be called then an armor piece break
|
||||
--the functions accept one arguments: obj
|
||||
--the itemstack isn't sended due to how minetest handle items which have a zero durability
|
||||
on_break_callbacks = {
|
||||
head = function(obj)
|
||||
--do stuff
|
||||
end,
|
||||
},
|
||||
|
||||
--this is used to generate automaticaly armor crafts based on each element type folowing the regular minecraft pattern
|
||||
--if set to nil no craft will be added
|
||||
craft_material = "mcl_mobitems:leather",
|
||||
|
||||
--this is used to generate cooking crafts for each piece of armor
|
||||
--if set to nil no craft will be added
|
||||
cook_material = "mcl_core:gold_nugget", --cooking any piece of this armor will output a gold nugged
|
||||
|
||||
--this is used for allowing each piece of the armor to be repaired by using an anvil with repair_material as aditionnal material
|
||||
--it basicaly set the _repair_material item field of each piece of the armor
|
||||
--if set to nil no repair material will be added
|
||||
repair_material = "mcl_core:iron_ingot",
|
||||
})
|
||||
```
|
||||
|
||||
## Creating an Armor Piece
|
||||
|
||||
If you don't want to register a full set of armor, then you will need to manually register your own single item.
|
||||
|
||||
```lua
|
||||
minetest.register_tool("dummy_mod:random_armor", {
|
||||
description = S("Random Armor"),
|
||||
|
||||
--these two item fields are used for ingame documentation
|
||||
--the mcl_armor.longdesc and mcl_armor.usage vars contains the basic usage and purpose of a piece of armor
|
||||
--these vars may not be enough for that you want to do, so you may add some extra informations like that:
|
||||
--_doc_items_longdesc = mcl_armor.longdesc.." "..S("Some extra informations.")
|
||||
_doc_items_longdesc = mcl_armor.longdesc,
|
||||
_doc_items_usagehelp = mcl_armor.usage,
|
||||
|
||||
--this field is similar to any item definition in minetest
|
||||
--it just set the image shown then the armor is dropped as an item or inside an inventory
|
||||
inventory_image = "mcl_armor_inv_elytra.png",
|
||||
|
||||
--this field is used by minetest internally and also by some helper functions
|
||||
--in order for the tool to be shown is the right creative inventory tab, the right groups should be added
|
||||
--"mcl_armor_uses" is required to give your armor a durability
|
||||
--in that case, the armor can be worn by 10 points before breaking
|
||||
--if you want the armor to be enchantable, you should also add the "enchantability" group, with the highest number the better enchants you can apply
|
||||
groups = {armor = 1, non_combat_armor = 1, armor_torso = 1, non_combat_torso = 1, mcl_armor_uses = 10},
|
||||
|
||||
--this table is used by minetest for seraching item specific sounds
|
||||
--the _mcl_armor_equip and _mcl_armor_unequip are used by the armor implementation to play sounds on equip and unequip
|
||||
--note that you don't need to provide any file extention
|
||||
sounds = {
|
||||
_mcl_armor_equip = "mcl_armor_equip_leather",
|
||||
_mcl_armor_unequip = "mcl_armor_unequip_leather",
|
||||
},
|
||||
|
||||
--these fields should be initialised like that in most cases
|
||||
--mcl_armor.equip_on_use is a function that try to equip the piece of armor you have in hand inside the right armor slot if the slot is empty
|
||||
on_place = mcl_armor.equip_on_use,
|
||||
on_secondary_use = mcl_armor.equip_on_use,
|
||||
|
||||
--this field define that the tool is ACTUALLY an armor piece and in which armor slot you can put it
|
||||
--it should be set to "head", "torso", "legs" or "feet"
|
||||
_mcl_armor_element = "torso",
|
||||
|
||||
|
||||
--this field is used to provide the texture that will be overlayed on the object (player or mob) skin
|
||||
--this field can be a texture name or a function that will be called each time the mcl_armor.update(obj) function is called
|
||||
--see the mcl_armor.register_set() documentation for more explanations
|
||||
_mcl_armor_texture = "mcl_armor_elytra.png"
|
||||
|
||||
--callbacks
|
||||
--see the mcl_armor.register_set() documentation for more explanations
|
||||
|
||||
_on_equip = function(obj, itemstack)
|
||||
end,
|
||||
_on_unequip = function(obj, itemstack)
|
||||
end,
|
||||
_on_break = function(obj)
|
||||
end,
|
||||
})
|
||||
```
|
||||
|
||||
## Interacting with Armor of an Entity
|
||||
|
||||
Mods may want to interact with armor of an entity.
|
||||
|
||||
Most global functions not described here may not be stable or may be for internal use only.
|
||||
|
||||
You can equip a piece of armor on an entity inside a mod by using `mcl_armor.equip()`.
|
||||
|
||||
```lua
|
||||
--itemstack: an itemstack containing the armor piece to equip
|
||||
--obj: the entity you want to equip the armor on
|
||||
--swap: boolean, force equiping the armor piece, even if the entity already have one of the same type
|
||||
mcl_armor.equip(itemstack, obj, swap)
|
||||
```
|
||||
|
||||
You can update the entity apparence by using `mcl_armor.update()`.
|
||||
|
||||
This function put the armor overlay on the object's base texture.
|
||||
If the object is player it will update his displayed armor points count in HUD.
|
||||
|
||||
This function will work both on players and mobs.
|
||||
|
||||
```lua
|
||||
--obj: the entity you want the apparence to be updated
|
||||
mcl_armor.update(obj)
|
||||
```
|
||||
|
||||
## Handling Enchantments
|
||||
|
||||
Armors can be enchanted in most cases.
|
||||
|
||||
The enchanting part of MineClone2 is separated from the armor part, but closely linked.
|
||||
|
||||
Existing armor enchantments in Minecraft improve most of the time how the armor protect the entity from damage.
|
||||
|
||||
The `mcl_armor.register_protection_enchantment()` function aims to simplificate the creation of such enchants.
|
||||
|
||||
```lua
|
||||
mcl_armor.register_protection_enchantment({
|
||||
--this field is the id that will be used for registering enchanted book and store the enchant inside armor metadata.
|
||||
--(his internal name)
|
||||
id = "magic_protection",
|
||||
|
||||
--visible name of the enchant
|
||||
--this field is used as the name of registered enchanted book and inside armor tooltip
|
||||
--translation should be added
|
||||
name = S("Magic Protection"),
|
||||
|
||||
--this field is used to know that the enchant currently do
|
||||
--translation should be added
|
||||
description = S("Reduces magic damage."),
|
||||
|
||||
--how many levels can the enchant have
|
||||
--ex: 4 => I, II, III, IV
|
||||
--default: 4
|
||||
max_level = 4,
|
||||
|
||||
--which enchants this enchant will not be compatible with
|
||||
--each of these values is a enchant id
|
||||
incompatible = {blast_protection = true, fire_protection = true, projectile_protection = true},
|
||||
|
||||
--how much will the enchant consume from the enchantability group of the armor item
|
||||
--default: 5
|
||||
weight = 5,
|
||||
|
||||
--false => the enchant can be obtained in an enchanting table
|
||||
--true => the enchant isn't obtainable in the enchanting table
|
||||
--is true, you will probably need to implement some ways to obtain it
|
||||
--even it the field is named "treasure", it will be no way to find it
|
||||
--default: false
|
||||
treasure = false,
|
||||
|
||||
--how much will damage be reduced
|
||||
--see Minecraft Wiki for more informations
|
||||
--https://minecraft.gamepedia.com/Armor#Damage_protection
|
||||
--https://minecraft.gamepedia.com/Armor#Enchantments
|
||||
factor = 1,
|
||||
|
||||
--restrict damage to one type
|
||||
--allow the enchant to only protect of one type of damage
|
||||
damage_type = "magic",
|
||||
|
||||
--restrict damage to one category
|
||||
--allow to protect from many type of damage at once
|
||||
--this is much less specific than damage_type and also much more customisable
|
||||
--the "is_magic" flag is used in the "magic", "dragon_breath", "wither_skull" and "thorns" damage types
|
||||
--you can checkout the mcl_damage source code for a list of availlable damage types and associated flags
|
||||
--but be warned that mods can register additionnal damage types
|
||||
damage_flag = "is_magic",
|
||||
})
|
||||
```
|
|
@ -1,30 +0,0 @@
|
|||
[mod] Visible Player Armor [mcl_armor]
|
||||
======================================
|
||||
|
||||
Adds craftable armor that is visible to other players. Each armor item worn contributes to
|
||||
a player's armor group level making them less vulnerable to some forms of damage.
|
||||
|
||||
Armor takes damage when a player is hurt.
|
||||
|
||||
This mod is based on 3D Armor mod by stu.
|
||||
|
||||
Media credits
|
||||
-------------
|
||||
* mcl_armor_equip_diamond.ogg
|
||||
* mcl_armor_unequip_diamond.ogg
|
||||
Licensed CC0, by Freesound.org user juryduty.
|
||||
Source: <https://freesound.org/people/juryduty/sounds/180231/>
|
||||
|
||||
* mcl_armor_equip_iron.ogg
|
||||
* mcl_armor_unequip_iron.ogg
|
||||
Licensed CC0, by Freesound.org user mtchanary.
|
||||
Source: <https://freesound.org/people/mitchanary/sounds/506148/>
|
||||
|
||||
* mcl_armor_equip_generic.ogg
|
||||
* mcl_armor_unequip_generic.ogg
|
||||
Licensed (CC BY-SA 3.0) by Mito551
|
||||
|
||||
All other sounds licensed CC0 by OpenGameArt.org user artisticdude.
|
||||
Source: <https://opengameart.org/content/rpg-sound-pack>
|
||||
|
||||
Other media files: See MineClone 2 license.
|
|
@ -1,23 +0,0 @@
|
|||
minetest.register_alias("3d_armor:helmet_leather", "mcl_armor:helmet_leather")
|
||||
minetest.register_alias("3d_armor:helmet_iron", "mcl_armor:helmet_iron")
|
||||
minetest.register_alias("3d_armor:helmet_chain", "mcl_armor:helmet_chain")
|
||||
minetest.register_alias("3d_armor:helmet_gold", "mcl_armor:helmet_gold")
|
||||
minetest.register_alias("3d_armor:helmet_diamond", "mcl_armor:helmet_diamond")
|
||||
|
||||
minetest.register_alias("3d_armor:chestplate_leather", "mcl_armor:chestplate_leather")
|
||||
minetest.register_alias("3d_armor:chestplate_iron", "mcl_armor:chestplate_iron")
|
||||
minetest.register_alias("3d_armor:chestplate_chain", "mcl_armor:chestplate_chain")
|
||||
minetest.register_alias("3d_armor:chestplate_gold", "mcl_armor:chestplate_gold")
|
||||
minetest.register_alias("3d_armor:chestplate_diamond", "mcl_armor:chestplate_diamond")
|
||||
|
||||
minetest.register_alias("3d_armor:leggings_leather", "mcl_armor:leggings_leather")
|
||||
minetest.register_alias("3d_armor:leggings_iron", "mcl_armor:leggings_iron")
|
||||
minetest.register_alias("3d_armor:leggings_chain", "mcl_armor:leggings_chain")
|
||||
minetest.register_alias("3d_armor:leggings_gold", "mcl_armor:leggings_gold")
|
||||
minetest.register_alias("3d_armor:leggings_diamond", "mcl_armor:leggings_diamond")
|
||||
|
||||
minetest.register_alias("3d_armor:boots_leather", "mcl_armor:boots_leather")
|
||||
minetest.register_alias("3d_armor:boots_iron", "mcl_armor:boots_iron")
|
||||
minetest.register_alias("3d_armor:boots_chain", "mcl_armor:boots_chain")
|
||||
minetest.register_alias("3d_armor:boots_gold", "mcl_armor:boots_gold")
|
||||
minetest.register_alias("3d_armor:boots_diamond", "mcl_armor:boots_diamond")
|
|
@ -1,253 +0,0 @@
|
|||
function mcl_armor.play_equip_sound(stack, obj, pos, unequip)
|
||||
local def = stack:get_definition()
|
||||
local estr = "equip"
|
||||
if unequip then
|
||||
estr = "unequip"
|
||||
end
|
||||
local snd = def.sounds and def.sounds["_mcl_armor_" .. estr]
|
||||
if not snd then
|
||||
-- Fallback sound
|
||||
snd = { name = "mcl_armor_" .. estr .. "_generic" }
|
||||
end
|
||||
if snd then
|
||||
local dist = 8
|
||||
if pos then
|
||||
dist = 16
|
||||
end
|
||||
minetest.sound_play(snd, {object = obj, pos = pos, gain = 0.5, max_hear_distance = dist}, true)
|
||||
end
|
||||
end
|
||||
|
||||
function mcl_armor.on_equip(itemstack, obj)
|
||||
local def = itemstack:get_definition()
|
||||
mcl_armor.play_equip_sound(itemstack, obj)
|
||||
if def._on_equip then
|
||||
def._on_equip(obj, itemstack)
|
||||
end
|
||||
mcl_armor.update(obj)
|
||||
end
|
||||
|
||||
function mcl_armor.on_unequip(itemstack, obj)
|
||||
local def = itemstack:get_definition()
|
||||
mcl_armor.play_equip_sound(itemstack, obj, nil, true)
|
||||
if def._on_unequip then
|
||||
def._on_unequip(obj, itemstack)
|
||||
end
|
||||
mcl_armor.update(obj)
|
||||
end
|
||||
|
||||
function mcl_armor.equip(itemstack, obj, swap)
|
||||
local def = itemstack:get_definition()
|
||||
|
||||
if not def then
|
||||
return itemstack
|
||||
end
|
||||
|
||||
local inv = mcl_util.get_inventory(obj, true)
|
||||
|
||||
if not inv or inv:get_size("armor") == 0 then
|
||||
return itemstack
|
||||
end
|
||||
|
||||
local element = mcl_armor.elements[def._mcl_armor_element or ""]
|
||||
|
||||
if element then
|
||||
local old_stack = inv:get_stack("armor", element.index)
|
||||
|
||||
if swap or old_stack:is_empty() then
|
||||
local new_stack
|
||||
|
||||
if swap then
|
||||
new_stack = itemstack
|
||||
itemstack = old_stack
|
||||
else
|
||||
new_stack = itemstack:take_item()
|
||||
end
|
||||
|
||||
inv:set_stack("armor", element.index, new_stack)
|
||||
mcl_armor.on_equip(new_stack, obj)
|
||||
end
|
||||
end
|
||||
|
||||
return itemstack
|
||||
end
|
||||
|
||||
function mcl_armor.equip_on_use(itemstack, player, pointed_thing)
|
||||
if not player or not player:is_player() then
|
||||
return itemstack
|
||||
end
|
||||
|
||||
local new_stack = mcl_util.call_on_rightclick(itemstack, player, pointed_thing)
|
||||
if new_stack then
|
||||
return new_stack
|
||||
end
|
||||
|
||||
return mcl_armor.equip(itemstack, player)
|
||||
end
|
||||
|
||||
function mcl_armor.register_set(def)
|
||||
local modname = minetest.get_current_modname()
|
||||
local S = minetest.get_translator(modname)
|
||||
local descriptions = def.descriptions or {}
|
||||
local groups = def.groups or {}
|
||||
local on_equip_callbacks = def.on_equip_callbacks or {}
|
||||
local on_unequip_callbacks = def.on_unequip_callbacks or {}
|
||||
local on_break_callbacks = def.on_break_callbacks or {}
|
||||
local textures = def.textures or {}
|
||||
local durabilities = def.durabilities or {}
|
||||
local element_groups = def.element_groups or {}
|
||||
|
||||
for name, element in pairs(mcl_armor.elements) do
|
||||
local itemname = element.name .. "_" .. def.name
|
||||
local itemstring = modname .. ":" .. itemname
|
||||
|
||||
local groups = table.copy(groups)
|
||||
groups["armor_" .. name] = 1
|
||||
groups["combat_armor_" .. name] = 1
|
||||
groups.armor = 1
|
||||
groups.combat_armor = 1
|
||||
groups.mcl_armor_points = def.points[name]
|
||||
groups.mcl_armor_toughness = def.toughness
|
||||
groups.mcl_armor_uses = (durabilities[name] or math.floor(def.durability * element.durability)) + 1
|
||||
groups.enchantability = def.enchantability
|
||||
|
||||
for k, v in pairs(element_groups) do
|
||||
groups[k] = v
|
||||
end
|
||||
|
||||
minetest.register_tool(itemstring, {
|
||||
description = S(def.description .. " " .. (descriptions[name] or element.description)),
|
||||
_doc_items_longdesc = mcl_armor.longdesc,
|
||||
_doc_items_usagehelp = mcl_armor.usage,
|
||||
inventory_image = modname .. "_inv_" .. itemname .. ".png",
|
||||
_repair_material = def.repair_material or def.craft_material,
|
||||
groups = groups,
|
||||
sounds = {
|
||||
_mcl_armor_equip = def.sound_equip or modname .. "_equip_" .. def.name,
|
||||
_mcl_armor_unequip = def.sound_unequip or modname .. "_unequip_" .. def.name,
|
||||
},
|
||||
on_place = mcl_armor.equip_on_use,
|
||||
on_secondary_use = mcl_armor.equip_on_use,
|
||||
_on_equip = on_equip_callbacks[name] or def.on_equip,
|
||||
_on_unequip = on_unequip_callbacks[name] or def.on_unequip,
|
||||
_on_break = on_break_callbacks[name] or def.on_break,
|
||||
_mcl_armor_element = name,
|
||||
_mcl_armor_texture = textures[name] or modname .. "_" .. itemname .. ".png",
|
||||
})
|
||||
|
||||
if def.craft_material then
|
||||
minetest.register_craft({
|
||||
output = itemstring,
|
||||
recipe = element.craft(def.craft_material),
|
||||
})
|
||||
end
|
||||
|
||||
if def.cook_material then
|
||||
minetest.register_craft({
|
||||
type = "cooking",
|
||||
output = def.cook_material,
|
||||
recipe = itemstring,
|
||||
cooktime = 10,
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
mcl_armor.protection_enchantments = {
|
||||
flags = {},
|
||||
types = {},
|
||||
wildcard = {},
|
||||
}
|
||||
|
||||
function mcl_armor.register_protection_enchantment(def)
|
||||
local prot_def = {id = def.id, factor = def.factor}
|
||||
if def.damage_flag then
|
||||
local tbl = mcl_armor.protection_enchantments.flags[def.damage_flag] or {}
|
||||
table.insert(tbl, prot_def)
|
||||
mcl_armor.protection_enchantments.flags = tbl
|
||||
elseif def.damage_type then
|
||||
local tbl = mcl_armor.protection_enchantments.types[def.damage_type] or {}
|
||||
table.insert(tbl, prot_def)
|
||||
mcl_armor.protection_enchantments.types = tbl
|
||||
else
|
||||
table.insert(mcl_armor.protection_enchantments.wildcard, prot_def)
|
||||
end
|
||||
mcl_enchanting.enchantments[def.id] = {
|
||||
name = def.name,
|
||||
max_level = def.max_level or 4,
|
||||
primary = def.primary or {combat_armor = true},
|
||||
secondary = {},
|
||||
disallow = {},
|
||||
incompatible = def.incompatible or {},
|
||||
weight = def.weight or 5,
|
||||
description = def.description,
|
||||
curse = false,
|
||||
on_enchant = function() end,
|
||||
requires_tool = false,
|
||||
treasure = def.treasure or false,
|
||||
power_range_table = def.power_range_table,
|
||||
inv_combat_tab = true,
|
||||
inv_tool_tab = false,
|
||||
}
|
||||
end
|
||||
|
||||
function mcl_armor.update(obj)
|
||||
local info = {points = 0, view_range_factors = {}}
|
||||
|
||||
local inv = mcl_util.get_inventory(obj)
|
||||
|
||||
if inv then
|
||||
for i = 2, 5 do
|
||||
local itemstack = inv:get_stack("armor", i)
|
||||
|
||||
local itemname = itemstack:get_name()
|
||||
if minetest.registered_aliases[itemname] then
|
||||
itemname = minetest.registered_aliases[itemname]
|
||||
end
|
||||
|
||||
if not itemstack:is_empty() then
|
||||
local def = itemstack:get_definition()
|
||||
|
||||
local texture = def._mcl_armor_texture
|
||||
|
||||
if texture then
|
||||
if type(texture) == "function" then
|
||||
texture = texture(obj, itemstack)
|
||||
end
|
||||
if texture then
|
||||
info.texture = "(" .. texture .. ")" .. (info.texture and "^" .. info.texture or "")
|
||||
end
|
||||
end
|
||||
|
||||
info.points = info.points + minetest.get_item_group(itemname, "mcl_armor_points")
|
||||
|
||||
local mob_range_mob = def._mcl_armor_mob_range_mob
|
||||
|
||||
if mob_range_mob then
|
||||
local factor = info.view_range_factors[mob_range_mob]
|
||||
|
||||
if factor then
|
||||
if factor > 0 then
|
||||
info.view_range_factors[mob_range_mob] = factor * def._mcl_armor_mob_range_factor
|
||||
end
|
||||
else
|
||||
info.view_range_factors[mob_range_mob] = def._mcl_armor_mob_range_factor
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
info.texture = info.texture or "blank.png"
|
||||
|
||||
if obj:is_player() then
|
||||
mcl_armor.update_player(obj, info)
|
||||
else
|
||||
local luaentity = obj:get_luaentity()
|
||||
|
||||
if luaentity.update_armor then
|
||||
luaentity:update_armor(info)
|
||||
end
|
||||
end
|
||||
end
|
||||
|