From 6d84a139d6064d2f0420c0ccf967dad1a5a3f45b Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Wed, 23 Aug 2017 03:50:22 +0200 Subject: [PATCH] Render enderman's carried block --- mods/ENTITIES/mobs_mc/0_gameconfig.lua | 4 +- mods/ENTITIES/mobs_mc/enderman.lua | 180 ++++++++++++++++-- .../mobs_mc/models/mobs_mc_enderman.b3d | Bin 108266 -> 683474 bytes 3 files changed, 171 insertions(+), 13 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/0_gameconfig.lua b/mods/ENTITIES/mobs_mc/0_gameconfig.lua index 410719f67..5e47ecbe0 100644 --- a/mods/ENTITIES/mobs_mc/0_gameconfig.lua +++ b/mods/ENTITIES/mobs_mc/0_gameconfig.lua @@ -228,7 +228,9 @@ mobs_mc.enderman_takable = { "default:dirt_with_snow", "default:dirt_with_rainforest_litter", "default:dirt_with_grass_footsteps", - "default:cactus", +-- FIXME: For some reason, Minetest has a Lua error when an enderman tries to place a Minetest Game cactus. +-- Maybe this is because default:cactus has rotate_and_place? +-- "default:cactus", -- TODO: Re-enable cactus when it works again "default:gravel", "default:clay", "flowers:mushroom_red", diff --git a/mods/ENTITIES/mobs_mc/enderman.lua b/mods/ENTITIES/mobs_mc/enderman.lua index 80381ea8c..ceaddbf7e 100644 --- a/mods/ENTITIES/mobs_mc/enderman.lua +++ b/mods/ENTITIES/mobs_mc/enderman.lua @@ -18,6 +18,139 @@ local pr = PseudoRandom(os.time()*(-334)) local take_frequency = 10 local place_frequency = 10 +-- Create the textures table for the enderman, depending on which kind of block +-- the enderman holds (if any). +local create_enderman_textures = function(block_type, itemstring) + local base = "mobs_mc_enderman.png^mobs_mc_enderman_eyes.png" + + --[[ Order of the textures in the texture table: + Flower, 90 degrees + Flower, 45 degrees + Held block, backside + Held block, bottom + Held block, front + Held block, left + Held block, right + Held block, top + Enderman texture (base) + ]] + -- Regular cube + if block_type == "cube" then + local tiles = minetest.registered_nodes[itemstring].tiles + local textures = {} + local last + for i = 1, 6 do + if type(tiles[i]) == "string" then + last = tiles[i] + elseif type(tiles[i]) == "table" then + if tiles[i].name then + last = tiles[i].name + end + end + table.insert(textures, last) + end + return { + "blank.png", + "blank.png", + textures[5], + textures[2], + textures[6], + textures[3], + textures[4], + textures[1], + base, -- Enderman texture + } + -- Node of plantlike drawtype, 45° (recommended) + elseif block_type == "plantlike45" then + local textures = minetest.registered_nodes[itemstring].tiles + return { + "blank.png", + textures[1], + "blank.png", + "blank.png", + "blank.png", + "blank.png", + "blank.png", + "blank.png", + base, + } + -- Node of plantlike drawtype, 90° + elseif block_type == "plantlike90" then + local textures = minetest.registered_nodes[itemstring].tiles + return { + textures[1], + "blank.png", + "blank.png", + "blank.png", + "blank.png", + "blank.png", + "blank.png", + "blank.png", + base, + } + elseif block_type == "unknown" then + return { + "blank.png", + "blank.png", + "unknown_node.png", + "unknown_node.png", + "unknown_node.png", + "unknown_node.png", + "unknown_node.png", + "unknown_node.png", + base, -- Enderman texture + } + -- No block held (for initial texture) + elseif block_type == "nothing" or block_type == nil then + return { + "blank.png", + "blank.png", + "blank.png", + "blank.png", + "blank.png", + "blank.png", + "blank.png", + "blank.png", + base, -- Enderman texture + } + end +end + +-- Select a new animation definition. +local select_enderman_animation = function(animation_type) + -- Enderman holds a block + if animation_type == "block" then + return { + walk_speed = 25, + run_speed = 50, + stand_speed = 25, + stand_start = 200, + stand_end = 200, + walk_start = 161, + walk_end = 200, + run_start = 161, + run_end = 200, + punch_start = 121, + punch_end = 160, + } + -- Enderman doesn't hold a block + elseif animation_type == "normal" or animation_type == nil then + return { + walk_speed = 25, + run_speed = 50, + stand_speed = 25, + stand_start = 40, + stand_end = 80, + walk_start = 0, + walk_end = 40, + run_start = 0, + run_end = 40, + punch_start = 81, + punch_end = 120, + } + end +end + mobs:register_mob("mobs_mc:enderman", { type = "monster", runaway = true, @@ -28,9 +161,7 @@ mobs:register_mob("mobs_mc:enderman", { collisionbox = {-0.3, -0.01, -0.3, 0.3, 2.89, 0.3}, visual = "mesh", mesh = "mobs_mc_enderman.b3d", - textures = { - {"mobs_mc_enderman.png^(mobs_mc_enderman_eyes.png^[makealpha:0,0,0)"}, - }, + textures = create_enderman_textures(), visual_size = {x=3, y=3}, makes_footstep_sound = true, sounds = { @@ -49,12 +180,7 @@ mobs:register_mob("mobs_mc:enderman", { min = 0, max = 1,}, }, - animation = { - speed_normal = 25, speed_run = 50, - stand_start = 40, stand_end = 80, - walk_start = 0, walk_end = 40, - run_start = 0, run_end = 40, - }, + animation = select_enderman_animation("normal"), _taken_node = "", do_custom = function(self, dtime) -- Take and put nodes @@ -63,7 +189,7 @@ mobs:register_mob("mobs_mc:enderman", { return end self._take_place_timer = self._take_place_timer + dtime - if (self._taken_node == nil or self._taken_node == "") and self._take_place_timer >= take_frequency then + if (self._taken_node == nil or self._taken_node == "") and self._take_place_timer >= take_frequency then -- Take random node self._take_place_timer = 0 local pos = self.object:getpos() @@ -75,8 +201,35 @@ mobs:register_mob("mobs_mc:enderman", { local dug = minetest.dig_node(take_pos) if dug then self._taken_node = node.name - -- TODO: Update enderman model (enderman holding block) local def = minetest.registered_nodes[self._taken_node] + -- Update animation and texture accordingly (adds visibly carried block) + local block_type + -- Cube-shaped + if def.drawtype == "normal" or + def.drawtype == "nodebox" or + def.drawtype == "liquid" or + def.drawtype == "flowingliquid" or + def.drawtype == "glasslike" or + def.drawtype == "glasslike_framed" or + def.drawtype == "glasslike_framed_optional" or + def.drawtype == "allfaces" or + def.drawtype == "allfaces_optional" or + def.drawtype == nil then + block_type = "cube" + elseif def.drawtype == "plantlike" then + -- Flowers and stuff + block_type = "plantlike45" + elseif def.drawtype == "airlike" then + -- Just air + block_type = nil + else + -- Fallback for complex drawtypes + block_type = "unknown" + end + self.base_texture = create_enderman_textures(block_type, self._taken_node) + self.object:set_properties({ textures = self.base_texture }) + self.animation = select_enderman_animation("block") + mobs:set_animation(self, self.animation.current) if def.sounds and def.sounds.dug then minetest.sound_play(def.sounds.dug, {pos = take_pos, max_hear_distance = 16}) end @@ -93,6 +246,9 @@ mobs:register_mob("mobs_mc:enderman", { -- ... but only if there's a free space minetest.place_node(place_pos, {name = self._taken_node}) local def = minetest.registered_nodes[self._taken_node] + -- Update animation accordingly (removes visible block) + self.animation = select_enderman_animation("normal") + mobs:set_animation(self, self.animation.current) if def.sounds and def.sounds.place then minetest.sound_play(def.sounds.place, {pos = place_pos, max_hear_distance = 16}) end @@ -147,7 +303,7 @@ mobs:register_mob("mobs_mc:enderman", { -- End spawn -mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 3000, 18, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) +mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, minetest.LIGHT_MAX+1, 30, 3000, 12, mobs_mc.spawn_height.end_min, mobs_mc.spawn_height.end_max) -- Overworld spawn mobs:spawn_specific("mobs_mc:enderman", mobs_mc.spawn.solid, {"air"}, 0, 7, 30, 9000, 4, mobs_mc.spawn_height.overworld_min, mobs_mc.spawn_height.overworld_max) -- Nether spawn (rare) diff --git a/mods/ENTITIES/mobs_mc/models/mobs_mc_enderman.b3d b/mods/ENTITIES/mobs_mc/models/mobs_mc_enderman.b3d index ac92259907e6b11363dca2372006ba7107780bcc..30f42632b6d9b3b1710f08003de3a3da2e1b4d62 100644 GIT binary patch delta 39533 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 Jk5yIfe*s^U!$$xB delta 16542 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 hgWb-@2A