diff --git a/mods/CORE/mcl_util/init.lua b/mods/CORE/mcl_util/init.lua index a43c3d5d0..ac913de39 100644 --- a/mods/CORE/mcl_util/init.lua +++ b/mods/CORE/mcl_util/init.lua @@ -410,7 +410,7 @@ function mcl_util.get_color(colorstr) local mc_color = mcl_colors[colorstr:upper()] if mc_color then colorstr = mc_color - elseif #colorstr ~= 7 or colorstr:sub(1, 1) ~= "#"then + elseif #colorstr ~= 7 or colorstr:sub(1, 1) ~= "#" then return end local hex = tonumber(colorstr:sub(2, 7), 16) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 6e932ed5e..e599f2127 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -3526,14 +3526,6 @@ local mob_step = function(self, dtime) -- 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) if self.do_custom then @@ -3543,6 +3535,14 @@ local mob_step = function(self, dtime) end end + -- knockback timer + if self.pause_timer > 0 then + + self.pause_timer = self.pause_timer - dtime + + return + end + -- attack timer self.timer = self.timer + dtime diff --git a/mods/ENTITIES/mobs_mc/ender_dragon.lua b/mods/ENTITIES/mobs_mc/ender_dragon.lua index e62b0d16b..50aaacd4b 100644 --- a/mods/ENTITIES/mobs_mc/ender_dragon.lua +++ b/mods/ENTITIES/mobs_mc/ender_dragon.lua @@ -50,8 +50,8 @@ mobs:register_mob("mobs_mc:enderdragon", { arrow = "mobs_mc:dragon_fireball", shoot_interval = 0.5, shoot_offset = -1.0, - xp_min = 12000, - xp_max = 12000, + xp_min = 500, + xp_max = 500, animation = { fly_speed = 8, stand_speed = 8, stand_start = 0, stand_end = 20, @@ -59,15 +59,18 @@ mobs:register_mob("mobs_mc:enderdragon", { run_start = 0, run_end = 20, }, ignores_nametag = true, - on_die = function(self, own_pos) - if self._egg_spawn_pos then - local pos = minetest.string_to_pos(self._egg_spawn_pos) - --if minetest.get_node(pos).buildable_to then - minetest.set_node(pos, {name = mobs_mc.items.dragon_egg}) - return - --end + do_custom = function(self) + mcl_bossbars.update_boss(self, "Ender Dragon", "light_purple") + end, + on_die = function(self, pos) + if self._portal_pos then + local portal_pos = minetest.string_to_pos(self._portal_pos) + 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 - minetest.add_item(own_pos, mobs_mc.items.dragon_egg) end, fire_resistant = true, }) diff --git a/mods/ENTITIES/mobs_mc/wither.lua b/mods/ENTITIES/mobs_mc/wither.lua index caf5a248d..8e7f7eb95 100644 --- a/mods/ENTITIES/mobs_mc/wither.lua +++ b/mods/ENTITIES/mobs_mc/wither.lua @@ -73,6 +73,7 @@ mobs:register_mob("mobs_mc:wither", { self.object:set_properties({textures={self.base_texture}}) self.armor = {undead = 80, fleshy = 80} end + mcl_bossbars.update_boss(self, "Wither", "dark_purple") end, on_spawn = function(self) minetest.sound_play("mobs_mc_wither_spawn", {object=self.object, gain=1.0, max_hear_distance=64}) @@ -115,4 +116,4 @@ mobs:register_arrow("mobs_mc:wither_skull", { --Spawn egg mobs:register_egg("mobs_mc:wither", S("Wither"), "mobs_mc_spawn_icon_wither.png", 0, true) -mcl_wip.register_wip_item("mobs_mc:wither") \ No newline at end of file +mcl_wip.register_wip_item("mobs_mc:wither") diff --git a/mods/HUD/mcl_bossbars/init.lua b/mods/HUD/mcl_bossbars/init.lua new file mode 100644 index 000000000..38dbbe376 --- /dev/null +++ b/mods/HUD/mcl_bossbars/init.lua @@ -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() diff --git a/mods/HUD/mcl_bossbars/mod.conf b/mods/HUD/mcl_bossbars/mod.conf new file mode 100644 index 000000000..64cbd4c9f --- /dev/null +++ b/mods/HUD/mcl_bossbars/mod.conf @@ -0,0 +1,4 @@ +name = mcl_bossbars +author = Fleckenstein +description = Show enderdragon & wither boss bars. Also allows custom bars. +depends = mcl_util, mcl_colors diff --git a/mods/HUD/mcl_bossbars/textures/mcl_bossbars.png b/mods/HUD/mcl_bossbars/textures/mcl_bossbars.png new file mode 100644 index 000000000..55bf36dc2 Binary files /dev/null and b/mods/HUD/mcl_bossbars/textures/mcl_bossbars.png differ diff --git a/mods/HUD/mcl_bossbars/textures/mcl_bossbars_empty.png b/mods/HUD/mcl_bossbars/textures/mcl_bossbars_empty.png new file mode 100644 index 000000000..1e50b6afc Binary files /dev/null and b/mods/HUD/mcl_bossbars/textures/mcl_bossbars_empty.png differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_normal.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_normal.png index 5133f53ff..9974f60d5 100644 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_normal.png and b/mods/ITEMS/mcl_chests/textures/mcl_chests_normal.png differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_normal_double.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_normal_double.png index a8793f600..f7357ddaa 100644 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_normal_double.png and b/mods/ITEMS/mcl_chests/textures/mcl_chests_normal_double.png differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_trapped.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_trapped.png index de21d8f2f..ebbca8a6a 100644 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_trapped.png and b/mods/ITEMS/mcl_chests/textures/mcl_chests_trapped.png differ diff --git a/mods/ITEMS/mcl_chests/textures/mcl_chests_trapped_double.png b/mods/ITEMS/mcl_chests/textures/mcl_chests_trapped_double.png index 95f768f97..88ff45825 100644 Binary files a/mods/ITEMS/mcl_chests/textures/mcl_chests_trapped_double.png and b/mods/ITEMS/mcl_chests/textures/mcl_chests_trapped_double.png differ diff --git a/mods/ITEMS/mcl_end/end_crystal.lua b/mods/ITEMS/mcl_end/end_crystal.lua index d089c3cdf..63a37d3c6 100644 --- a/mods/ITEMS/mcl_end/end_crystal.lua +++ b/mods/ITEMS/mcl_end/end_crystal.lua @@ -58,8 +58,9 @@ local function spawn_crystal(pos) for _, crystal in pairs(crystals) do crystal_explode(crystal) end - local dragon = minetest.add_entity(vector.add(portal_center, {x = 0, y = 10, z = 0}), "mobs_mc:enderdragon") - dragon:get_luaentity()._egg_spawn_pos = minetest.pos_to_string(vector.add(portal_center, {x = 0, y = 4, z = 0})) + local portal_pos = vector.add(portal_center, vector.new(-3, -1, -3)) + 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 minetest.register_entity("mcl_end:crystal", { diff --git a/mods/MAPGEN/mcl_mapgen_core/init.lua b/mods/MAPGEN/mcl_mapgen_core/init.lua index e08b55ba3..237579dbe 100644 --- a/mods/MAPGEN/mcl_mapgen_core/init.lua +++ b/mods/MAPGEN/mcl_mapgen_core/init.lua @@ -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 --- End exit portal position. This is temporary. --- TODO: Remove the exit portal generation when the ender dragon has been implemented. +-- End exit portal position 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.z = END_EXIT_PORTAL_POS.z - 3 @@ -1251,6 +1250,13 @@ local function generate_clay(minp, maxp, blockseed, voxelmanip_data, voxelmanip_ return lvm_used 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 local function generate_structures(minp, maxp, blockseed, biomemap) 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 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 - mcl_structures.call_struct(p, "end_exit_portal") + generate_end_exit_portal(p) return end end - mcl_structures.call_struct(END_EXIT_PORTAL_POS, "end_exit_portal") + generate_end_exit_portal(END_EXIT_PORTAL_POS) end end diff --git a/mods/MAPGEN/mcl_structures/init.lua b/mods/MAPGEN/mcl_structures/init.lua index 6a7f44dfb..d75854352 100644 --- a/mods/MAPGEN/mcl_structures/init.lua +++ b/mods/MAPGEN/mcl_structures/init.lua @@ -87,6 +87,8 @@ mcl_structures.call_struct = function(pos, struct_style, rotation, pr) return mcl_structures.generate_fossil(pos, rotation, pr) elseif struct_style == "end_exit_portal" then 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 return mcl_structures.generate_end_portal_shrine(pos, rotation, pr) end @@ -313,11 +315,15 @@ mcl_structures.generate_fossil = function(pos, rotation, pr) end 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" return mcl_structures.place_schematic(pos, path, rot or "0", nil, true) 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) -- Find and setup spawner with silverfish local spawners = minetest.find_nodes_in_area(p1, p2, "mcl_mobspawners:spawner") @@ -535,7 +541,7 @@ end -- Debug command 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."), privs = {debug = true}, func = function(name, param) @@ -567,6 +573,8 @@ minetest.register_chatcommand("spawnstruct", { mcl_structures.generate_ice_spike_large(pos, rot, pr) elseif param == "end_exit_portal" then 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 mcl_structures.generate_end_portal_shrine(pos, rot, pr) elseif param == "dungeon" and mcl_dungeons and mcl_dungeons.spawn_dungeon then diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_exit_portal.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_exit_portal.mts index bc24f800a..30d145bd7 100644 Binary files a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_exit_portal.mts and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_exit_portal.mts differ diff --git a/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_exit_portal_open.mts b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_exit_portal_open.mts new file mode 100644 index 000000000..bc24f800a Binary files /dev/null and b/mods/MAPGEN/mcl_structures/schematics/mcl_structures_end_exit_portal_open.mts differ diff --git a/mods/PLAYER/wieldview/init.lua b/mods/PLAYER/wieldview/init.lua index 48f3f99bd..7a349f2f3 100644 --- a/mods/PLAYER/wieldview/init.lua +++ b/mods/PLAYER/wieldview/init.lua @@ -70,6 +70,10 @@ minetest.register_on_joinplayer(function(player) local name = player:get_player_name() wieldview.wielded_item[name] = "" 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) 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)) @@ -111,10 +115,11 @@ minetest.register_entity("wieldview:wieldnode", { local def = minetest.registered_items[itemstring] 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 self.object:set_properties({textures = {itemstring}}) - else -- wield item as flat + -- wield item as flat + else self.object:set_properties({textures = {""}}) end