Add working mob armor api

TODO: make mobs only put on a piece if they don't already have it.
This commit is contained in:
epCode 2022-10-27 01:08:36 +00:00
parent 6c0e29891d
commit 86eef8827a
1 changed files with 99 additions and 14 deletions

View File

@ -406,6 +406,7 @@ end
-- set and return valid yaw -- set and return valid yaw
local set_yaw = function(self, yaw, delay, dtime) local set_yaw = function(self, yaw, delay, dtime)
@ -1273,6 +1274,7 @@ local do_env_damage = function(self)
end end
local _, dim = mcl_worlds.y_to_layer(pos.y) 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.sunlight_damage ~= 0 or self.ignited_by_sunlight) and (sunlight or 0) >= minetest.LIGHT_MAX and dim == "overworld" then
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 if self.ignited_by_sunlight then
mcl_burning.set_on_fire(self.object, 10) mcl_burning.set_on_fire(self.object, 10)
else else
@ -1280,6 +1282,7 @@ local do_env_damage = function(self)
return true return true
end end
end end
end
local y_level = self.collisionbox[2] local y_level = self.collisionbox[2]
@ -2529,7 +2532,7 @@ local function go_to_pos(entity,b)
local v = { x = b.x - s.x, z = b.z - s.z } local v = { x = b.x - s.x, z = b.z - s.z }
local yaw = (atann(v.z / v.x) + pi / 2) - entity.rotate local yaw = (atann(v.z / v.x) + pi / 2) - entity.rotate
if b.x > s.x then yaw = yaw + pi end 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) set_velocity(entity,entity.follow_velocity)
mcl_mobs:set_animation(entity, "walk") mcl_mobs:set_animation(entity, "walk")
end end
@ -3254,12 +3257,81 @@ local function player_near(pos)
end end
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) 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() local p = self.object:get_pos()
for _,o in pairs(minetest.get_objects_inside_radius(p,2)) do for _,o in pairs(minetest.get_objects_inside_radius(p,2)) do
local l=o:get_luaentity() local l=o:get_luaentity()
if l and l.name == "__builtin:item" then if l and l.name == "__builtin:item" then
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 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 if not player_near(p) and self.on_pick_up and l.itemstring:find(v) then
local r = self.on_pick_up(self,l) local r = self.on_pick_up(self,l)
@ -3274,6 +3346,7 @@ local function check_item_pickup(self)
end end
end end
end end
end
local check_herd_timer = 0 local check_herd_timer = 0
local function check_herd(self,dtime) local function check_herd(self,dtime)
@ -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 self.on_spawn_run = true -- if true, set flag to run once only
end end
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 -- run after_activate
if def.after_activate then if def.after_activate then
def.after_activate(self, staticdata, def, dtime) def.after_activate(self, staticdata, def, dtime)
end end
end end
@ -4261,6 +4341,8 @@ local mob_step = function(self, dtime)
do_jump(self) do_jump(self)
set_armor_texture(self)
runaway_from(self) runaway_from(self)
if is_at_water_danger(self) and self.state ~= "attack" then 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 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 head_yaw = def.head_yaw or "y", -- axis to rotate head on
horrizonatal_head_height = def.horrizonatal_head_height or 0, 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, stepheight = def.stepheight or 0.6,
name = name, name = name,
description = def.description, description = def.description,
@ -4470,6 +4553,7 @@ minetest.register_entity(name, {
nofollow = def.nofollow, nofollow = def.nofollow,
can_open_doors = def.can_open_doors, can_open_doors = def.can_open_doors,
jump = def.jump ~= false, jump = def.jump ~= false,
automatic_face_movement_max_rotation_per_sec = 300,
walk_chance = def.walk_chance or 50, walk_chance = def.walk_chance or 50,
attacks_monsters = def.attacks_monsters or false, attacks_monsters = def.attacks_monsters or false,
group_attack = def.group_attack or false, group_attack = def.group_attack or false,
@ -4579,6 +4663,7 @@ minetest.register_entity(name, {
self.object:set_properties({ self.object:set_properties({
collide_with_objects = false, collide_with_objects = false,
}) })
return mob_activate(self, staticdata, def, dtime) return mob_activate(self, staticdata, def, dtime)
end, end,