Merge branch 'master' into credits
|
@ -410,7 +410,7 @@ function mcl_util.get_color(colorstr)
|
||||||
local mc_color = mcl_colors[colorstr:upper()]
|
local mc_color = mcl_colors[colorstr:upper()]
|
||||||
if mc_color then
|
if mc_color then
|
||||||
colorstr = mc_color
|
colorstr = mc_color
|
||||||
elseif #colorstr ~= 7 or colorstr:sub(1, 1) ~= "#"then
|
elseif #colorstr ~= 7 or colorstr:sub(1, 1) ~= "#" then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local hex = tonumber(colorstr:sub(2, 7), 16)
|
local hex = tonumber(colorstr:sub(2, 7), 16)
|
||||||
|
|
|
@ -3526,14 +3526,6 @@ local mob_step = function(self, dtime)
|
||||||
|
|
||||||
-- end rotation
|
-- end rotation
|
||||||
|
|
||||||
-- knockback timer
|
|
||||||
if self.pause_timer > 0 then
|
|
||||||
|
|
||||||
self.pause_timer = self.pause_timer - dtime
|
|
||||||
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
-- run custom function (defined in mob lua file)
|
-- run custom function (defined in mob lua file)
|
||||||
if self.do_custom then
|
if self.do_custom then
|
||||||
|
|
||||||
|
@ -3543,6 +3535,14 @@ local mob_step = function(self, dtime)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- knockback timer
|
||||||
|
if self.pause_timer > 0 then
|
||||||
|
|
||||||
|
self.pause_timer = self.pause_timer - dtime
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
-- attack timer
|
-- attack timer
|
||||||
self.timer = self.timer + dtime
|
self.timer = self.timer + dtime
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,8 @@ mobs:register_mob("mobs_mc:enderdragon", {
|
||||||
arrow = "mobs_mc:dragon_fireball",
|
arrow = "mobs_mc:dragon_fireball",
|
||||||
shoot_interval = 0.5,
|
shoot_interval = 0.5,
|
||||||
shoot_offset = -1.0,
|
shoot_offset = -1.0,
|
||||||
xp_min = 12000,
|
xp_min = 500,
|
||||||
xp_max = 12000,
|
xp_max = 500,
|
||||||
animation = {
|
animation = {
|
||||||
fly_speed = 8, stand_speed = 8,
|
fly_speed = 8, stand_speed = 8,
|
||||||
stand_start = 0, stand_end = 20,
|
stand_start = 0, stand_end = 20,
|
||||||
|
@ -59,15 +59,18 @@ mobs:register_mob("mobs_mc:enderdragon", {
|
||||||
run_start = 0, run_end = 20,
|
run_start = 0, run_end = 20,
|
||||||
},
|
},
|
||||||
ignores_nametag = true,
|
ignores_nametag = true,
|
||||||
on_die = function(self, own_pos)
|
do_custom = function(self)
|
||||||
if self._egg_spawn_pos then
|
mcl_bossbars.update_boss(self, "Ender Dragon", "light_purple")
|
||||||
local pos = minetest.string_to_pos(self._egg_spawn_pos)
|
end,
|
||||||
--if minetest.get_node(pos).buildable_to then
|
on_die = function(self, pos)
|
||||||
minetest.set_node(pos, {name = mobs_mc.items.dragon_egg})
|
if self._portal_pos then
|
||||||
return
|
local portal_pos = minetest.string_to_pos(self._portal_pos)
|
||||||
--end
|
mcl_structures.call_struct(portal_pos, "end_exit_portal_open")
|
||||||
|
if self._initial then
|
||||||
|
mcl_experience.throw_experience(pos, 11500) -- 500 + 11500 = 12000
|
||||||
|
minetest.set_node(vector.add(portal_pos, vector.new(3, 5, 3)), {name = mobs_mc.items.dragon_egg})
|
||||||
|
end
|
||||||
end
|
end
|
||||||
minetest.add_item(own_pos, mobs_mc.items.dragon_egg)
|
|
||||||
end,
|
end,
|
||||||
fire_resistant = true,
|
fire_resistant = true,
|
||||||
})
|
})
|
||||||
|
|
|
@ -73,6 +73,7 @@ mobs:register_mob("mobs_mc:wither", {
|
||||||
self.object:set_properties({textures={self.base_texture}})
|
self.object:set_properties({textures={self.base_texture}})
|
||||||
self.armor = {undead = 80, fleshy = 80}
|
self.armor = {undead = 80, fleshy = 80}
|
||||||
end
|
end
|
||||||
|
mcl_bossbars.update_boss(self, "Wither", "dark_purple")
|
||||||
end,
|
end,
|
||||||
on_spawn = function(self)
|
on_spawn = function(self)
|
||||||
minetest.sound_play("mobs_mc_wither_spawn", {object=self.object, gain=1.0, max_hear_distance=64})
|
minetest.sound_play("mobs_mc_wither_spawn", {object=self.object, gain=1.0, max_hear_distance=64})
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
mcl_bossbars = {
|
||||||
|
bars = {},
|
||||||
|
huds = {},
|
||||||
|
colors = {"light_purple", "blue", "red", "green", "yellow", "dark_purple", "white"},
|
||||||
|
}
|
||||||
|
|
||||||
|
function mcl_bossbars.recalculate_colors()
|
||||||
|
local sorted = {}
|
||||||
|
local colors = mcl_bossbars.colors
|
||||||
|
local color_count = #colors
|
||||||
|
local frame_count = color_count * 2
|
||||||
|
for i, color in ipairs(colors) do
|
||||||
|
local idx = i * 2 - 1
|
||||||
|
local image = "mcl_bossbars.png"
|
||||||
|
.. "^[transformR270"
|
||||||
|
.. "^[verticalframe:" .. frame_count .. ":" .. (idx - 1)
|
||||||
|
.. "^(mcl_bossbars_empty.png"
|
||||||
|
.. "^[lowpart:%d:mcl_bossbars.png"
|
||||||
|
.. "^[transformR270"
|
||||||
|
.. "^[verticalframe:" .. frame_count .. ":" .. idx .. ")"
|
||||||
|
local _, hex = mcl_util.get_color(color)
|
||||||
|
sorted[color] = {
|
||||||
|
image = image,
|
||||||
|
hex = hex,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
mcl_bossbars.colors_sorted = sorted
|
||||||
|
end
|
||||||
|
|
||||||
|
function mcl_bossbars.update_bar(player, text, color, percentage)
|
||||||
|
local cdef = mcl_bossbars.colors_sorted[color]
|
||||||
|
table.insert(mcl_bossbars.bars[player:get_player_name()], {color = cdef.hex, text = text, image = string.format(cdef.image, percentage)})
|
||||||
|
end
|
||||||
|
|
||||||
|
function mcl_bossbars.update_boss(luaentity, name, color)
|
||||||
|
local object = luaentity.object
|
||||||
|
local text = luaentity.nametag
|
||||||
|
if not text or text == "" then
|
||||||
|
text = name
|
||||||
|
end
|
||||||
|
local percentage = math.floor(luaentity.health / luaentity.hp_max * 100)
|
||||||
|
for _, obj in pairs(minetest.get_objects_inside_radius(object:get_pos(), 128)) do
|
||||||
|
if obj:is_player() then
|
||||||
|
mcl_bossbars.update_bar(obj, text, color, percentage)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_on_joinplayer(function(player)
|
||||||
|
local name = player:get_player_name()
|
||||||
|
mcl_bossbars.huds[name] = {}
|
||||||
|
mcl_bossbars.bars[name] = {}
|
||||||
|
end)
|
||||||
|
|
||||||
|
minetest.register_on_leaveplayer(function(player)
|
||||||
|
local name = player:get_player_name()
|
||||||
|
mcl_bossbars.huds[name] = nil
|
||||||
|
mcl_bossbars.bars[name] = nil
|
||||||
|
end)
|
||||||
|
|
||||||
|
minetest.register_globalstep(function()
|
||||||
|
for _, player in pairs(minetest.get_connected_players()) do
|
||||||
|
local name = player:get_player_name()
|
||||||
|
local bars = mcl_bossbars.bars[name]
|
||||||
|
local huds = mcl_bossbars.huds[name]
|
||||||
|
local huds_new = {}
|
||||||
|
local i = 0
|
||||||
|
|
||||||
|
while #huds > 0 or #bars > 0 do
|
||||||
|
local bar = table.remove(bars, 1)
|
||||||
|
local hud = table.remove(huds, 1)
|
||||||
|
|
||||||
|
if bar and not hud then
|
||||||
|
hud = {
|
||||||
|
color = bar.color,
|
||||||
|
image = bar.image,
|
||||||
|
text = bar.text,
|
||||||
|
text_id = player:hud_add({
|
||||||
|
hud_elem_type = "text",
|
||||||
|
text = bar.text,
|
||||||
|
number = bar.color,
|
||||||
|
position = {x = 0.5, y = 0},
|
||||||
|
alignment = {x = 0, y = 1},
|
||||||
|
offset = {x = 0, y = i * 40},
|
||||||
|
}),
|
||||||
|
image_id = player:hud_add({
|
||||||
|
hud_elem_type = "image",
|
||||||
|
text = bar.image,
|
||||||
|
position = {x = 0.5, y = 0},
|
||||||
|
alignment = {x = 0, y = 1},
|
||||||
|
offset = {x = 0, y = i * 40 + 25},
|
||||||
|
scale = {x = 3, y = 3},
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
elseif hud and not bar then
|
||||||
|
player:hud_remove(hud.text_id)
|
||||||
|
player:hud_remove(hud.image_id)
|
||||||
|
hud = nil
|
||||||
|
else
|
||||||
|
if bar.text ~= hud.text then
|
||||||
|
player:hud_change(hud.text_id, "text", bar.text)
|
||||||
|
hud.text = bar.text
|
||||||
|
end
|
||||||
|
|
||||||
|
if bar.color ~= hud.color then
|
||||||
|
player:hud_change(hud.text_id, "number", bar.color)
|
||||||
|
hud.color = bar.color
|
||||||
|
end
|
||||||
|
|
||||||
|
if bar.image ~= hud.image then
|
||||||
|
player:hud_change(hud.image_id, "text", bar.image)
|
||||||
|
hud.image = bar.image
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.insert(huds_new, hud)
|
||||||
|
i = i + 1
|
||||||
|
end
|
||||||
|
|
||||||
|
mcl_bossbars.huds[name] = huds_new
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
mcl_bossbars.recalculate_colors()
|
|
@ -0,0 +1,4 @@
|
||||||
|
name = mcl_bossbars
|
||||||
|
author = Fleckenstein
|
||||||
|
description = Show enderdragon & wither boss bars. Also allows custom bars.
|
||||||
|
depends = mcl_util, mcl_colors
|
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 689 B After Width: | Height: | Size: 672 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 961 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 674 B |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 965 B |
|
@ -58,8 +58,9 @@ local function spawn_crystal(pos)
|
||||||
for _, crystal in pairs(crystals) do
|
for _, crystal in pairs(crystals) do
|
||||||
crystal_explode(crystal)
|
crystal_explode(crystal)
|
||||||
end
|
end
|
||||||
local dragon = minetest.add_entity(vector.add(portal_center, {x = 0, y = 10, z = 0}), "mobs_mc:enderdragon")
|
local portal_pos = vector.add(portal_center, vector.new(-3, -1, -3))
|
||||||
dragon:get_luaentity()._egg_spawn_pos = minetest.pos_to_string(vector.add(portal_center, {x = 0, y = 4, z = 0}))
|
mcl_structures.call_struct(portal_pos, "end_exit_portal")
|
||||||
|
minetest.add_entity(vector.add(portal_pos, vector.new(3, 11, 3)), "mobs_mc:enderdragon"):get_luaentity()._portal_pos = minetest.pos_to_string(portal_pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_entity("mcl_end:crystal", {
|
minetest.register_entity("mcl_end:crystal", {
|
||||||
|
|
|
@ -54,8 +54,7 @@ local superflat = mg_name == "flat" and minetest.get_mapgen_setting("mcl_superfl
|
||||||
|
|
||||||
local WITCH_HUT_HEIGHT = 3 -- Exact Y level to spawn witch huts at. This height refers to the height of the floor
|
local WITCH_HUT_HEIGHT = 3 -- Exact Y level to spawn witch huts at. This height refers to the height of the floor
|
||||||
|
|
||||||
-- End exit portal position. This is temporary.
|
-- End exit portal position
|
||||||
-- TODO: Remove the exit portal generation when the ender dragon has been implemented.
|
|
||||||
local END_EXIT_PORTAL_POS = table.copy(mcl_vars.mg_end_platform_pos)
|
local END_EXIT_PORTAL_POS = table.copy(mcl_vars.mg_end_platform_pos)
|
||||||
END_EXIT_PORTAL_POS.x = END_EXIT_PORTAL_POS.x - 30
|
END_EXIT_PORTAL_POS.x = END_EXIT_PORTAL_POS.x - 30
|
||||||
END_EXIT_PORTAL_POS.z = END_EXIT_PORTAL_POS.z - 3
|
END_EXIT_PORTAL_POS.z = END_EXIT_PORTAL_POS.z - 3
|
||||||
|
@ -1251,6 +1250,13 @@ local function generate_clay(minp, maxp, blockseed, voxelmanip_data, voxelmanip_
|
||||||
return lvm_used
|
return lvm_used
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function generate_end_exit_portal(pos)
|
||||||
|
local dragon_entity = minetest.add_entity(vector.add(pos, vector.new(3, 11, 3)), "mobs_mc:enderdragon"):get_luaentity()
|
||||||
|
dragon_entity._initial = true
|
||||||
|
dragon_entity._portal_pos = minetest.pos_to_string(pos)
|
||||||
|
mcl_structures.call_struct(pos, "end_exit_portal")
|
||||||
|
end
|
||||||
|
|
||||||
-- TODO: Try to use more efficient structure generating code
|
-- TODO: Try to use more efficient structure generating code
|
||||||
local function generate_structures(minp, maxp, blockseed, biomemap)
|
local function generate_structures(minp, maxp, blockseed, biomemap)
|
||||||
local chunk_has_desert_well = false
|
local chunk_has_desert_well = false
|
||||||
|
@ -1490,11 +1496,11 @@ local function generate_structures(minp, maxp, blockseed, biomemap)
|
||||||
for y=maxp.y, minp.y, -1 do
|
for y=maxp.y, minp.y, -1 do
|
||||||
local p = {x=END_EXIT_PORTAL_POS.x, y=y, z=END_EXIT_PORTAL_POS.z}
|
local p = {x=END_EXIT_PORTAL_POS.x, y=y, z=END_EXIT_PORTAL_POS.z}
|
||||||
if minetest.get_node(p).name == "mcl_end:end_stone" then
|
if minetest.get_node(p).name == "mcl_end:end_stone" then
|
||||||
mcl_structures.call_struct(p, "end_exit_portal")
|
generate_end_exit_portal(p)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
mcl_structures.call_struct(END_EXIT_PORTAL_POS, "end_exit_portal")
|
generate_end_exit_portal(END_EXIT_PORTAL_POS)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -87,6 +87,8 @@ mcl_structures.call_struct = function(pos, struct_style, rotation, pr)
|
||||||
return mcl_structures.generate_fossil(pos, rotation, pr)
|
return mcl_structures.generate_fossil(pos, rotation, pr)
|
||||||
elseif struct_style == "end_exit_portal" then
|
elseif struct_style == "end_exit_portal" then
|
||||||
return mcl_structures.generate_end_exit_portal(pos, rotation)
|
return mcl_structures.generate_end_exit_portal(pos, rotation)
|
||||||
|
elseif struct_style == "end_exit_portal_open" then
|
||||||
|
return mcl_structures.generate_end_exit_portal_open(pos, rotation)
|
||||||
elseif struct_style == "end_portal_shrine" then
|
elseif struct_style == "end_portal_shrine" then
|
||||||
return mcl_structures.generate_end_portal_shrine(pos, rotation, pr)
|
return mcl_structures.generate_end_portal_shrine(pos, rotation, pr)
|
||||||
end
|
end
|
||||||
|
@ -313,11 +315,15 @@ mcl_structures.generate_fossil = function(pos, rotation, pr)
|
||||||
end
|
end
|
||||||
|
|
||||||
mcl_structures.generate_end_exit_portal = function(pos, rot)
|
mcl_structures.generate_end_exit_portal = function(pos, rot)
|
||||||
minetest.add_entity(vector.add(pos, vector.new(3, 11, 3)), "mobs_mc:enderdragon")
|
|
||||||
local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_exit_portal.mts"
|
local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_exit_portal.mts"
|
||||||
return mcl_structures.place_schematic(pos, path, rot or "0", nil, true)
|
return mcl_structures.place_schematic(pos, path, rot or "0", nil, true)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
mcl_structures.generate_end_exit_portal_open = function(pos, rot)
|
||||||
|
local path = minetest.get_modpath("mcl_structures").."/schematics/mcl_structures_end_exit_portal_open.mts"
|
||||||
|
return mcl_structures.place_schematic(pos, path, rot or "0", nil, true)
|
||||||
|
end
|
||||||
|
|
||||||
local function shrine_placement_callback(p1, p2, size, rotation, pr)
|
local function shrine_placement_callback(p1, p2, size, rotation, pr)
|
||||||
-- Find and setup spawner with silverfish
|
-- Find and setup spawner with silverfish
|
||||||
local spawners = minetest.find_nodes_in_area(p1, p2, "mcl_mobspawners:spawner")
|
local spawners = minetest.find_nodes_in_area(p1, p2, "mcl_mobspawners:spawner")
|
||||||
|
@ -535,7 +541,7 @@ end
|
||||||
|
|
||||||
-- Debug command
|
-- Debug command
|
||||||
minetest.register_chatcommand("spawnstruct", {
|
minetest.register_chatcommand("spawnstruct", {
|
||||||
params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_portal_shrine | nether_portal | dungeon",
|
params = "desert_temple | desert_well | igloo | witch_hut | boulder | ice_spike_small | ice_spike_large | fossil | end_exit_portal | end_exit_portal_opens | end_portal_shrine | nether_portal | dungeon",
|
||||||
description = S("Generate a pre-defined structure near your position."),
|
description = S("Generate a pre-defined structure near your position."),
|
||||||
privs = {debug = true},
|
privs = {debug = true},
|
||||||
func = function(name, param)
|
func = function(name, param)
|
||||||
|
@ -567,6 +573,8 @@ minetest.register_chatcommand("spawnstruct", {
|
||||||
mcl_structures.generate_ice_spike_large(pos, rot, pr)
|
mcl_structures.generate_ice_spike_large(pos, rot, pr)
|
||||||
elseif param == "end_exit_portal" then
|
elseif param == "end_exit_portal" then
|
||||||
mcl_structures.generate_end_exit_portal(pos, rot, pr)
|
mcl_structures.generate_end_exit_portal(pos, rot, pr)
|
||||||
|
elseif param == "end_exit_portal_open" then
|
||||||
|
mcl_structures.generate_end_exit_portal_open(pos, rot, pr)
|
||||||
elseif param == "end_portal_shrine" then
|
elseif param == "end_portal_shrine" then
|
||||||
mcl_structures.generate_end_portal_shrine(pos, rot, pr)
|
mcl_structures.generate_end_portal_shrine(pos, rot, pr)
|
||||||
elseif param == "dungeon" and mcl_dungeons and mcl_dungeons.spawn_dungeon then
|
elseif param == "dungeon" and mcl_dungeons and mcl_dungeons.spawn_dungeon then
|
||||||
|
|
|
@ -70,6 +70,10 @@ minetest.register_on_joinplayer(function(player)
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
wieldview.wielded_item[name] = ""
|
wieldview.wielded_item[name] = ""
|
||||||
minetest.after(0, function(player)
|
minetest.after(0, function(player)
|
||||||
|
-- if the player left :is_player() will return nil
|
||||||
|
if not player:is_player() then
|
||||||
|
return
|
||||||
|
end
|
||||||
wieldview:update_wielded_item(player)
|
wieldview:update_wielded_item(player)
|
||||||
local itementity = minetest.add_entity(player:get_pos(), "wieldview:wieldnode")
|
local itementity = minetest.add_entity(player:get_pos(), "wieldview:wieldnode")
|
||||||
itementity:set_attach(player, "Hand_Right", vector.new(0, 1, 0), vector.new(90, 0, 45))
|
itementity:set_attach(player, "Hand_Right", vector.new(0, 1, 0), vector.new(90, 0, 45))
|
||||||
|
@ -111,10 +115,11 @@ minetest.register_entity("wieldview:wieldnode", {
|
||||||
local def = minetest.registered_items[itemstring]
|
local def = minetest.registered_items[itemstring]
|
||||||
self.object:set_properties({glow = def and def.light_source or 0})
|
self.object:set_properties({glow = def and def.light_source or 0})
|
||||||
|
|
||||||
-- wield item as cubic
|
-- wield item as cubic
|
||||||
if armor.textures[self.wielder].wielditem == "blank.png" then
|
if armor.textures[self.wielder].wielditem == "blank.png" then
|
||||||
self.object:set_properties({textures = {itemstring}})
|
self.object:set_properties({textures = {itemstring}})
|
||||||
else -- wield item as flat
|
-- wield item as flat
|
||||||
|
else
|
||||||
self.object:set_properties({textures = {""}})
|
self.object:set_properties({textures = {""}})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|