From 86eef8827a8404dff5833360a5ff3471a31861ca Mon Sep 17 00:00:00 2001 From: epCode Date: Thu, 27 Oct 2022 01:08:36 +0000 Subject: [PATCH] Add working mob armor api TODO: make mobs only put on a piece if they don't already have it. --- mods/ENTITIES/mcl_mobs/api.lua | 113 +++++++++++++++++++++++++++++---- 1 file changed, 99 insertions(+), 14 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index b8802fff00..303bce8c13 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -406,6 +406,7 @@ end -- set and return valid yaw + local set_yaw = function(self, yaw, delay, dtime) @@ -1273,11 +1274,13 @@ local do_env_damage = function(self) end local _, dim = mcl_worlds.y_to_layer(pos.y) if (self.sunlight_damage ~= 0 or self.ignited_by_sunlight) and (sunlight or 0) >= minetest.LIGHT_MAX and dim == "overworld" then - if self.ignited_by_sunlight then - mcl_burning.set_on_fire(self.object, 10) - else - deal_light_damage(self, pos, self.sunlight_damage) - return true + if self.armor_list and not self.armor_list.helmet or not self.armor_list or self.armor_list and self.armor_list.helmet and self.armor_list.helmet == "" then + if self.ignited_by_sunlight then + mcl_burning.set_on_fire(self.object, 10) + else + deal_light_damage(self, pos, self.sunlight_damage) + return true + end end end @@ -2529,7 +2532,7 @@ local function go_to_pos(entity,b) local v = { x = b.x - s.x, z = b.z - s.z } local yaw = (atann(v.z / v.x) + pi / 2) - entity.rotate if b.x > s.x then yaw = yaw + pi end - entity.object:set_yaw(yaw) + --entity.object:set_yaw(yaw) set_velocity(entity,entity.follow_velocity) mcl_mobs:set_animation(entity, "walk") end @@ -3254,19 +3257,89 @@ local function player_near(pos) end end +local function get_armor_texture(armor_name) + if armor_name == "" then + return "" + end + if armor_name=="blank.png" then + return "blank.png" + end + local seperator = string.find(armor_name, ":") + return "mcl_armor_"..string.sub(armor_name, seperator+1, -1)..".png^" +end + +local function set_armor_texture(self) + if self.armor_list then + local chestplate=minetest.registered_items[self.armor_list.chestplate] or {name=""} + local boots=minetest.registered_items[self.armor_list.boots] or {name=""} + local leggings=minetest.registered_items[self.armor_list.leggings] or {name=""} + local helmet=minetest.registered_items[self.armor_list.helmet] or {name=""} + + if helmet.name=="" and chestplate.name=="" and leggings.name=="" and boots.name=="" then + helmet={name="blank.png"} + end + local texture = get_armor_texture(chestplate.name)..get_armor_texture(helmet.name)..get_armor_texture(boots.name)..get_armor_texture(leggings.name) + if string.sub(texture, -1,-1) == "^" then + texture=string.sub(texture,1,-2) + end + if self.textures[self.wears_armor] then + self.textures[self.wears_armor]=texture + end + self.object:set_properties({textures=self.textures}) + + local armor_ + if type(self.armor) == "table" then + armor_ = table.copy(self.armor) + armor_.immortal = 1 + else + armor_ = {immortal=1, fleshy = self.armor} + end + + for _,item in pairs(self.armor_list) do + if not item then return end + if type(minetest.get_item_group(item, "mcl_armor_points")) == "number" then + armor_.fleshy=armor_.fleshy-(minetest.get_item_group(item, "mcl_armor_points")*3.5) + end + end + self.object:set_armor_groups(armor_) + end +end + local function check_item_pickup(self) - if self.pick_up and #self.pick_up > 0 then + if self.pick_up and #self.pick_up > 0 or self.wears_armor then local p = self.object:get_pos() for _,o in pairs(minetest.get_objects_inside_radius(p,2)) do local l=o:get_luaentity() if l and l.name == "__builtin:item" then - for k,v in pairs(self.pick_up) do - if not player_near(p) and self.on_pick_up and l.itemstring:find(v) then - local r = self.on_pick_up(self,l) - if r and r.is_empty and not r:is_empty() then - l.itemstring = r:to_string() - elseif r and r.is_empty and r:is_empty() then - o:remove() + if not player_near(p) and l.itemstring:find("mcl_armor") and self.wears_armor then + local armor_type + if l.itemstring:find("chestplate") then + armor_type = "chestplate" + elseif l.itemstring:find("boots") then + armor_type = "boots" + elseif l.itemstring:find("leggings") then + armor_type = "leggings" + elseif l.itemstring:find("helmet") then + armor_type = "helmet" + end + if not armor_type then + return + end + if not self.armor_list then + self.armor_list={helmet="",chestplate="",boots="",leggings=""} + end + self.armor_list[armor_type]=ItemStack(l.itemstring):get_name() + o:remove() + end + if self.pick_up then + for k,v in pairs(self.pick_up) do + if not player_near(p) and self.on_pick_up and l.itemstring:find(v) then + local r = self.on_pick_up(self,l) + if r and r.is_empty and not r:is_empty() then + l.itemstring = r:to_string() + elseif r and r.is_empty and r:is_empty() then + o:remove() + end end end end @@ -3943,9 +4016,16 @@ local mob_activate = function(self, staticdata, def, dtime) self.on_spawn_run = true -- if true, set flag to run once only end end + if not self._run_armor_init then + self.armor_list={helmet="",chestplate="",boots="",leggings=""} + set_armor_texture(self) + self._run_armor_init = true + end + -- run after_activate if def.after_activate then + def.after_activate(self, staticdata, def, dtime) end end @@ -4261,6 +4341,8 @@ local mob_step = function(self, dtime) do_jump(self) + set_armor_texture(self) + runaway_from(self) if is_at_water_danger(self) and self.state ~= "attack" then @@ -4417,6 +4499,7 @@ minetest.register_entity(name, { curiosity = def.curiosity or 1, -- how often mob will look at player on idle head_yaw = def.head_yaw or "y", -- axis to rotate head on horrizonatal_head_height = def.horrizonatal_head_height or 0, + wears_armor = def.wears_armor, -- a number value used to index texture slot for armor stepheight = def.stepheight or 0.6, name = name, description = def.description, @@ -4470,6 +4553,7 @@ minetest.register_entity(name, { nofollow = def.nofollow, can_open_doors = def.can_open_doors, jump = def.jump ~= false, + automatic_face_movement_max_rotation_per_sec = 300, walk_chance = def.walk_chance or 50, attacks_monsters = def.attacks_monsters or false, group_attack = def.group_attack or false, @@ -4579,6 +4663,7 @@ minetest.register_entity(name, { self.object:set_properties({ collide_with_objects = false, }) + return mob_activate(self, staticdata, def, dtime) end,