From 0598aa35c0550945db6662a29b10673a435259d2 Mon Sep 17 00:00:00 2001 From: cora Date: Fri, 13 May 2022 21:28:56 +0200 Subject: [PATCH 01/35] add simple jobsite logic --- mods/ENTITIES/mobs_mc/villager.lua | 222 +++++++++++++++++++---------- 1 file changed, 146 insertions(+), 76 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index c7049919e..3c9ea5a80 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -64,12 +64,18 @@ end local professions = { unemployed = { name = N("Unemployed"), - texture = "mobs_mc_villager.png", + textures = { + "mobs_mc_villager.png", + "mobs_mc_villager.png", + }, trades = nil, }, farmer = { name = N("Farmer"), - texture = "mobs_mc_villager_farmer.png", + textures = { + "mobs_mc_villager_farmer.png", + "mobs_mc_villager_farmer.png", + }, jobsite = "mcl_composters:composter", trades = { { @@ -103,7 +109,10 @@ local professions = { }, fisherman = { name = N("Fisherman"), - texture = "mobs_mc_villager_farmer.png", + textures = { + "mobs_mc_villager_farmer.png", + "mobs_mc_villager_farmer.png", + }, jobsite = "mcl_barrels:barrel_closed", trades = { { @@ -138,7 +147,10 @@ local professions = { }, fletcher = { name = N("Fletcher"), - texture = "mobs_mc_villager_farmer.png", + texture = { + "mobs_mc_villager_farmer.png", + "mobs_mc_villager_farmer.png", + }, jobsite = "mcl_fletching_table:fletching_table", trades = { { @@ -177,7 +189,10 @@ local professions = { }, shepherd ={ name = N("Shepherd"), - texture = "mobs_mc_villager_farmer.png", + texture = { + "mobs_mc_villager_farmer.png", + "mobs_mc_villager_farmer.png", + }, jobsite = "mcl_loom:loom", trades = { { @@ -207,7 +222,10 @@ local professions = { }, librarian = { name = N("Librarian"), - texture = "mobs_mc_villager_librarian.png", + textures = { + "mobs_mc_villager_librarian.png", + "mobs_mc_villager_librarian.png", + }, jobsite = "mcl_villages:stonebrickcarved", --FIXME: lectern trades = { { @@ -242,7 +260,10 @@ local professions = { }, cartographer = { name = N("Cartographer"), - texture = "mobs_mc_villager_librarian.png", + textures = { + "mobs_mc_villager_librarian.png", + "mobs_mc_villager_librarian.png", + }, jobsite = "mcl_cartography_table:cartography_table", trades = { { @@ -285,7 +306,10 @@ local professions = { }, armorer = { name = N("Armorer"), - texture = "mobs_mc_villager_smith.png", + textures = { + "mobs_mc_villager_smith.png", + "mobs_mc_villager_smith.png", + }, jobsite = "mcl_blast_furnace:blast_furnace", trades = { { @@ -322,7 +346,10 @@ local professions = { }, leatherworker = { name = N("Leatherworker"), - texture = "mobs_mc_villager_butcher.png", + textures = { + "mobs_mc_villager_butcher.png", + "mobs_mc_villager_butcher.png", + }, jobsite = "mcl_cauldrons:cauldron", trades = { { @@ -351,7 +378,10 @@ local professions = { }, butcher = { name = N("Butcher"), - texture = "mobs_mc_villager_butcher.png", + textures = { + "mobs_mc_villager_butcher.png", + "mobs_mc_villager_butcher.png", + }, jobsite = "mcl_smoker:smoker", trades = { { @@ -381,7 +411,10 @@ local professions = { }, weapon_smith = { name = N("Weapon Smith"), - texture = "mobs_mc_villager_smith.png", + textures = { + "mobs_mc_villager_smith.png", + "mobs_mc_villager_smith.png", + }, jobsite = "mcl_villages:stonebrickcarved", --FIXME: grindstone trades = { { @@ -409,7 +442,10 @@ local professions = { }, tool_smith = { name = N("Tool Smith"), - texture = "mobs_mc_villager_smith.png", + textures = { + "mobs_mc_villager_smith.png", + "mobs_mc_villager_smith.png", + }, jobsite = "mcl_villages:stonebrickcarved", --FIXME: smithing table trades = { { @@ -443,8 +479,11 @@ local professions = { }, cleric = { name = N("Cleric"), - texture = "mobs_mc_villager_priest.png", - jobsite = "mcl_brewing:stand", + textures = { + "mobs_mc_villager_priest.png", + "mobs_mc_villager_priest.png", + }, + jobsite = "mcl_brewing:stand_000", trades = { { { { "mcl_mobitems:rotten_flesh", 32, 32 }, E1 }, @@ -472,7 +511,10 @@ local professions = { }, nitwit = { name = N("Nitwit"), - texture = "mobs_mc_villager.png", + textures = { + "mobs_mc_villager.png", + "mobs_mc_villager.png", + }, -- No trades for nitwit trades = nil, } @@ -483,11 +525,31 @@ for id, _ in pairs(professions) do table.insert(profession_names, id) end +local jobsites={} +for _,n in pairs(profession_names) do + table.insert(jobsites,professions[n].jobsite) +end + local stand_still = function(self) self.walk_chance = 0 self.jump = false end +local init_trader_vars = function(self) + self.object:set_properties({textures=professions[self._profession].textures}) + if not self._max_trade_tier then + self._max_trade_tier = 1 + end + if not self._locked_trades then + self._locked_trades = 0 + end + if not self._trading_players then + self._trading_players = {} + end +end + +----- JOBSITE LOGIC + local function set_velocity(self, v) local yaw = (self.object:get_yaw() or 0) + self.rotate self.object:set_velocity({ @@ -499,14 +561,15 @@ end local function go_to_pos(entity,b) local s=entity.object:get_pos() + if vector.distance(b,s) < 5 then + set_velocity(entity,0) + return true + end local v = { x = b.x - s.x, z = b.z - s.z } local yaw = (math.atan(v.z / v.x) + math.pi / 2) - entity.rotate if b.x > s.x then yaw = yaw + math.pi end entity.object:set_yaw(yaw) set_velocity(entity,entity.follow_velocity) - if vector.distance(b,s) < 5 then - return true - end end local function go_home(entity) @@ -524,6 +587,49 @@ local function go_home(entity) end end +local function get_profession_by_jobsite(js) + for k,v in pairs(professions) do + if v.jobsite == js then return k end + end +end + +local function employ(self,jobsite_pos) + local n = minetest.get_node(jobsite_pos) + local m = minetest.get_meta(jobsite_pos) + local p = get_profession_by_jobsite(n.name) + if p and m:get_string("villager") == "" then + self._profession=p + m:set_string("villager",self._id) + self._jobsite = jobsite_pos + init_trader_vars(self) + return true + end +end + +local function unemploy(self) + self._profession="unemployed" + self._jobsite = nil + self.object:set_properties({textures=professions[self._profession].textures}) +end + +local function get_a_job(self) + local p = self.object:get_pos() + local nn = minetest.find_nodes_in_area(vector.offset(p,-8,-8,-8),vector.offset(p,8,8,8),jobsites) + for _,n in pairs(nn) do + if n and employ(self,n) then return end + end +end + +local function check_jobsite(self) + local n = minetest.get_node(self._jobsite) + local m = minetest.get_meta(self._jobsite) + if n.name ~= professions[self._profession].jobsite or m:get_string("villager") ~= self._id then + unemploy(self) + return false + end + return true +end + local update_max_tradenum = function(self) if not self._trades then return @@ -539,30 +645,6 @@ local update_max_tradenum = function(self) self._max_tradenum = #trades end -local init_trader_vars = function(self) - if not self._profession then - -- Select random profession from all professions with matching clothing - local texture = self.base_texture[1] - local matches = {} - for prof_id, prof in pairs(professions) do - if texture == prof.texture then - table.insert(matches, prof_id) - end - end - local p = math.random(1, #matches) - self._profession = matches[p] - end - if not self._max_trade_tier then - self._max_trade_tier = 1 - end - if not self._locked_trades then - self._locked_trades = 0 - end - if not self._trading_players then - self._trading_players = {} - end -end - local init_trades = function(self, inv) local profession = professions[self._profession] local trade_tiers = profession.trades @@ -1113,31 +1195,9 @@ mobs:register_mob("mobs_mc:villager", { visual = "mesh", mesh = "mobs_mc_villager.b3d", textures = { - { "mobs_mc_villager.png", "mobs_mc_villager.png", --hat }, - { - "mobs_mc_villager_farmer.png", - "mobs_mc_villager_farmer.png", --hat - }, - { - "mobs_mc_villager_priest.png", - "mobs_mc_villager_priest.png", --hat - }, - { - "mobs_mc_villager_librarian.png", - "mobs_mc_villager_librarian.png", --hat - }, - { - "mobs_mc_villager_butcher.png", - "mobs_mc_villager_butcher.png", --hat - }, - { - "mobs_mc_villager_smith.png", - "mobs_mc_villager_smith.png", --hat - }, - }, visual_size = {x=2.75, y=2.75}, makes_footstep_sound = true, walk_velocity = 1.2, @@ -1169,19 +1229,22 @@ mobs:register_mob("mobs_mc:villager", { fear_height = 4, jump = true, walk_chance = DEFAULT_WALK_CHANCE, + bed = nil, + _id = nil, + _profession = "unemployed", on_rightclick = function(self, clicker) if clicker:get_wielded_item():get_name() == "mcl_farming:bread" then if mobs:feed_tame(self, clicker, 1, true, true) then return end if mobs:protect(self, clicker) then return end end - if self.child then + if self.child or self._profession == "unemployed" then return end -- Initiate trading + --init_trader_vars(self) local name = clicker:get_player_name() self._trading_players[name] = true - init_trader_vars(self) if self._trades == nil then init_trades(self) end @@ -1219,10 +1282,6 @@ mobs:register_mob("mobs_mc:villager", { self._player_scan_timer = 0 end - if self.bed and ( self.state == "go_home" or vector.distance(self.object:get_pos(),self.bed) > 50 ) then - go_home(self) - end - self._player_scan_timer = self._player_scan_timer + dtime -- Check infrequently to keep CPU load low if self._player_scan_timer > PLAYER_SCAN_INTERVAL then @@ -1244,20 +1303,31 @@ mobs:register_mob("mobs_mc:villager", { self.walk_chance = DEFAULT_WALK_CHANCE self.jump = true end + if self.bed and ( self.state == "go_home" or vector.distance(self.object:get_pos(),self.bed) > 50 ) then + go_home(self) + end + if self._profession == "unemployed" then + get_a_job(self) + else + check_jobsite(self) + end end end, on_spawn = function(self) - init_trader_vars(self) + self._id=minetest.sha1(minetest.get_gametime()..minetest.pos_to_string(self.object:get_pos())..tostring(math.random())) + self._profession = "unemployed" end, on_die = function(self, pos) -- Close open trade formspecs and give input back to players local trading_players = self._trading_players - for name, _ in pairs(trading_players) do - minetest.close_formspec(name, "mobs_mc:trade_"..name) - local player = minetest.get_player_by_name(name) - if player then - return_fields(player) + if trading_players then + for name, _ in pairs(trading_players) do + minetest.close_formspec(name, "mobs_mc:trade_"..name) + local player = minetest.get_player_by_name(name) + if player then + return_fields(player) + end end end end, From 12bc8f1a3b15b11a89de487aa91da23a957ae973 Mon Sep 17 00:00:00 2001 From: cora Date: Mon, 16 May 2022 19:22:59 +0200 Subject: [PATCH 02/35] initial pathfinding experiments to test rightclick a villager and it will try to path find to 0,9,0 (i'm using flat mapgen for testing for now). --- mods/ENTITIES/mobs_mc/villager.lua | 74 ++++++++++++++++++++++-------- 1 file changed, 56 insertions(+), 18 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 3c9ea5a80..a1721ec62 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -535,7 +535,7 @@ local stand_still = function(self) self.jump = false end -local init_trader_vars = function(self) +local function init_trader_vars(self) self.object:set_properties({textures=professions[self._profession].textures}) if not self._max_trade_tier then self._max_trade_tier = 1 @@ -548,8 +548,7 @@ local init_trader_vars = function(self) end end ------ JOBSITE LOGIC - +--movement stuff - to be abstracted to mcl_mobs local function set_velocity(self, v) local yaw = (self.object:get_yaw() or 0) + self.rotate self.object:set_velocity({ @@ -560,8 +559,9 @@ local function set_velocity(self, v) end local function go_to_pos(entity,b) + if not entity then return end local s=entity.object:get_pos() - if vector.distance(b,s) < 5 then + if vector.distance(b,s) < 1 then set_velocity(entity,0) return true end @@ -572,21 +572,51 @@ local function go_to_pos(entity,b) set_velocity(entity,entity.follow_velocity) end +local function check_gowp(self) + if not self.waypoints or not self._target then return end + local p = self.object:get_pos() + if vector.distance(p,self._target) < 1 then + self.waypoints = nil + self._target = nil + self.current_target = nil + if self.callback_arrived then return self.callback_arrived(self) end + return true + end + if not self.current_target or go_to_pos(self,self.current_target) then + self.current_target = table.remove(self.waypoints, 1) + end + if not minetest.line_of_sight(self.object:get_pos(),self.current_target) then + self.waypoints=minetest.find_path(p,self._target,150,1,4) + self.current_target = nil + end +end + +local function go_wplist(self,target,wps,callback_arrived) + self.waypoints = wps + self._target = target + self.callback_arrived = callback_arrived +end + local function go_home(entity) entity.state = "go_home" local b=entity.bed if not b then return end - if go_to_pos(entity,b) then - entity.state = "stand" - set_velocity(entity,0) - entity.object:set_pos(b) - local n=minetest.get_node(b) - if n and n.name ~= "mcl_beds:bed_red_bottom" then - entity.bed=nil --the stormtroopers have killed uncle owen + go_wplist(entity,b,minetest.find_path(entity.object:get_pos(),b,50,1,4),function(entity,b) + if vector.distance(entity.object:get_pos(),b) < 2 then + entity.state = "stand" + set_velocity(entity,0) + entity.object:set_pos(b) + local n=minetest.get_node(b) + if n and n.name ~= "mcl_beds:bed_red_bottom" then + entity.bed=nil --the stormtroopers have killed uncle owen + return false + end + return true end - end + end) end +----- JOBSITE LOGIC local function get_profession_by_jobsite(js) for k,v in pairs(professions) do if v.jobsite == js then return k end @@ -616,7 +646,7 @@ local function get_a_job(self) local p = self.object:get_pos() local nn = minetest.find_nodes_in_area(vector.offset(p,-8,-8,-8),vector.offset(p,8,8,8),jobsites) for _,n in pairs(nn) do - if n and employ(self,n) then return end + if n and employ(self,n) then return true end end end @@ -624,7 +654,7 @@ local function check_jobsite(self) local n = minetest.get_node(self._jobsite) local m = minetest.get_meta(self._jobsite) if n.name ~= professions[self._profession].jobsite or m:get_string("villager") ~= self._id then - unemploy(self) + --unemploy(self) return false end return true @@ -1233,6 +1263,9 @@ mobs:register_mob("mobs_mc:villager", { _id = nil, _profession = "unemployed", on_rightclick = function(self, clicker) + go_wplist(self,minetest.find_path(self.object:get_pos(),vector.new(0,9,0),50,1,4),function(self,b) + minetest.log("arrived at 0,0") + end) if clicker:get_wielded_item():get_name() == "mcl_farming:bread" then if mobs:feed_tame(self, clicker, 1, true, true) then return end if mobs:protect(self, clicker) then return end @@ -1241,7 +1274,7 @@ mobs:register_mob("mobs_mc:villager", { return end -- Initiate trading - --init_trader_vars(self) + init_trader_vars(self) local name = clicker:get_player_name() self._trading_players[name] = true @@ -1280,6 +1313,8 @@ mobs:register_mob("mobs_mc:villager", { -- Stand still if player is nearby. if not self._player_scan_timer then self._player_scan_timer = 0 + else + check_gowp(self) end self._player_scan_timer = self._player_scan_timer + dtime @@ -1303,18 +1338,21 @@ mobs:register_mob("mobs_mc:villager", { self.walk_chance = DEFAULT_WALK_CHANCE self.jump = true end - if self.bed and ( self.state == "go_home" or vector.distance(self.object:get_pos(),self.bed) > 50 ) then + if self.bed and ( self.state ~= "go_home" and vector.distance(self.object:get_pos(),self.bed) > 50 ) then go_home(self) end if self._profession == "unemployed" then get_a_job(self) - else - check_jobsite(self) + -- else + -- check_jobsite(self) end end end, on_spawn = function(self) + if self._id then + return + end self._id=minetest.sha1(minetest.get_gametime()..minetest.pos_to_string(self.object:get_pos())..tostring(math.random())) self._profession = "unemployed" end, From ce7a882c86dfdf4cbbdc557757725135f79496c1 Mon Sep 17 00:00:00 2001 From: cora Date: Tue, 17 May 2022 19:40:20 +0200 Subject: [PATCH 03/35] Show trade tier in formspec --- mods/ENTITIES/mobs_mc/villager.lua | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index a1721ec62..2927807d2 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -61,6 +61,14 @@ if minetest.get_mapgen_setting("mg_name") == "v6" then TRADE_V6_BIRCH_SAPLING = { { "mcl_core:emerald", 8, 11 }, { "mcl_core:birchsapling", 1, 1 } } end +local tiernames = { + "Novice", + "Apprentice", + "Journeyman", + "Expert", + "Master", +} + local professions = { unemployed = { name = N("Unemployed"), @@ -536,7 +544,6 @@ local stand_still = function(self) end local function init_trader_vars(self) - self.object:set_properties({textures=professions[self._profession].textures}) if not self._max_trade_tier then self._max_trade_tier = 1 end @@ -562,7 +569,7 @@ local function go_to_pos(entity,b) if not entity then return end local s=entity.object:get_pos() if vector.distance(b,s) < 1 then - set_velocity(entity,0) + --set_velocity(entity,0) return true end local v = { x = b.x - s.x, z = b.z - s.z } @@ -631,7 +638,7 @@ local function employ(self,jobsite_pos) self._profession=p m:set_string("villager",self._id) self._jobsite = jobsite_pos - init_trader_vars(self) + self.object:set_properties({textures=professions[self._profession].textures}) return true end end @@ -805,7 +812,7 @@ local function show_trade_formspec(playername, trader, tradenum) "size[9,8.75]" .."background[-0.19,-0.25;9.41,9.49;mobs_mc_trading_formspec_bg.png]" ..disabled_img - .."label[4,0;"..F(minetest.colorize("#313131", S(profession))).."]" +.."label[3,0;"..F(minetest.colorize("#313131", S(profession).." - "..S(tiernames[trader._max_trade_tier]))) .."]" .."list[current_player;main;0,4.5;9,3;9]" .."list[current_player;main;0,7.74;9,1;]" ..b_prev..b_next @@ -1351,10 +1358,12 @@ mobs:register_mob("mobs_mc:villager", { on_spawn = function(self) if self._id then + self.object:set_properties({textures=professions[self._profession].textures}) return end self._id=minetest.sha1(minetest.get_gametime()..minetest.pos_to_string(self.object:get_pos())..tostring(math.random())) self._profession = "unemployed" + self.object:set_properties({textures=professions[self._profession].textures}) end, on_die = function(self, pos) -- Close open trade formspecs and give input back to players From dbc5564d02670095095329428c3001d94bd37186 Mon Sep 17 00:00:00 2001 From: cora Date: Tue, 17 May 2022 23:35:56 +0200 Subject: [PATCH 04/35] move movement code to mcl_mobs --- mods/ENTITIES/mcl_mobs/api.lua | 53 ++++++++++++++++++++---- mods/ENTITIES/mobs_mc/villager.lua | 65 +++++------------------------- 2 files changed, 57 insertions(+), 61 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index a046a1205..cebb4aaff 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -2317,17 +2317,28 @@ local dogswitch = function(self, dtime) return self.dogshoot_switch end +local function go_to_pos(entity,b) + if not entity then return end + local s=entity.object:get_pos() + if vector.distance(b,s) < 1 then + --set_velocity(entity,0) + return true + end + local v = { x = b.x - s.x, z = b.z - s.z } + local yaw = (math.atan(v.z / v.x) + math.pi / 2) - entity.rotate + if b.x > s.x then yaw = yaw + math.pi end + entity.object:set_yaw(yaw) + set_velocity(entity,entity.follow_velocity) +end + -- execute current state (stand, walk, run, attacks) -- returns true if mob has died local do_states = function(self, dtime) - local yaw = self.object:get_yaw() or 0 if self.state == "stand" then - if random(1, 4) == 1 then - local lp = nil local s = self.object:get_pos() local objs = minetest.get_objects_inside_radius(s, 3) @@ -2340,7 +2351,7 @@ local do_states = function(self, dtime) end -- look at any players nearby, otherwise turn randomly - if lp then + if self.look_at_players then local vec = { x = lp.x - s.x, @@ -2375,8 +2386,29 @@ local do_states = function(self, dtime) end end - elseif self.state == "walk" then + elseif self.state == "gowp" then + if not self.waypoints or not self._target then return end + local p = self.object:get_pos() + if vector.distance(p,self._target) < 1 then + self.waypoints = nil + self._target = nil + self.current_target = nil + self.state = "walk" + if self.callback_arrived then return self.callback_arrived(self) end + return true + end + if not self.current_target or vector.distance(p,self.current_target) < 1.5 then + self.current_target = table.remove(self.waypoints, 1) + else + go_to_pos(self,self.current_target) + end + + if self.current_target and not minetest.line_of_sight(self.object:get_pos(),self.current_target) then + self.waypoints=minetest.find_path(p,self._target,150,1,4) + self.current_target = nil + end + elseif self.state == "walk" then local s = self.object:get_pos() local lp = nil @@ -2880,6 +2912,14 @@ local do_states = function(self, dtime) end end +function mobs:go_wplist(self,target,callback_arrived) + if not target then return end + self._target = target + self.waypoints = minetest.find_path(self.object:get_pos(),target,150,1,4) + self.callback_arrived = callback_arrived + self.state = "gowp" +end + -- falling and fall damage -- returns true if mob died @@ -3576,8 +3616,7 @@ local mob_step = function(self, dtime) -- attack timer self.timer = self.timer + dtime - if self.state ~= "attack" then - + if self.state ~= "attack" and self.state ~= "gowp" then if self.timer < 1 then return end diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 2927807d2..64712971e 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -555,60 +555,19 @@ local function init_trader_vars(self) end end ---movement stuff - to be abstracted to mcl_mobs -local function set_velocity(self, v) - local yaw = (self.object:get_yaw() or 0) + self.rotate - self.object:set_velocity({ - x = (math.sin(yaw) * -v), - y = self.object:get_velocity().y, - z = (math.cos(yaw) * v), - }) -end - -local function go_to_pos(entity,b) - if not entity then return end - local s=entity.object:get_pos() - if vector.distance(b,s) < 1 then - --set_velocity(entity,0) - return true - end - local v = { x = b.x - s.x, z = b.z - s.z } - local yaw = (math.atan(v.z / v.x) + math.pi / 2) - entity.rotate - if b.x > s.x then yaw = yaw + math.pi end - entity.object:set_yaw(yaw) - set_velocity(entity,entity.follow_velocity) -end - -local function check_gowp(self) - if not self.waypoints or not self._target then return end - local p = self.object:get_pos() - if vector.distance(p,self._target) < 1 then - self.waypoints = nil - self._target = nil - self.current_target = nil - if self.callback_arrived then return self.callback_arrived(self) end - return true - end - if not self.current_target or go_to_pos(self,self.current_target) then - self.current_target = table.remove(self.waypoints, 1) - end - if not minetest.line_of_sight(self.object:get_pos(),self.current_target) then - self.waypoints=minetest.find_path(p,self._target,150,1,4) - self.current_target = nil - end -end - -local function go_wplist(self,target,wps,callback_arrived) - self.waypoints = wps - self._target = target - self.callback_arrived = callback_arrived +local function set_texture(self) + local t = table.copy(professions[self._profession].textures) + --t[1] = "[combine:x:,="..t[1]..":30,50="..badges[self._max_trade_tier].."^[resize:16x16" + + + self.object:set_properties({textures=t}) end local function go_home(entity) entity.state = "go_home" local b=entity.bed if not b then return end - go_wplist(entity,b,minetest.find_path(entity.object:get_pos(),b,50,1,4),function(entity,b) + mobs:go_wplist(entity,b,function(entity,b) if vector.distance(entity.object:get_pos(),b) < 2 then entity.state = "stand" set_velocity(entity,0) @@ -1269,9 +1228,11 @@ mobs:register_mob("mobs_mc:villager", { bed = nil, _id = nil, _profession = "unemployed", + look_at_player = true, on_rightclick = function(self, clicker) - go_wplist(self,minetest.find_path(self.object:get_pos(),vector.new(0,9,0),50,1,4),function(self,b) - minetest.log("arrived at 0,0") + local trg=vector.new(0,9,0) + mobs:go_wplist(self,trg,function() + minetest.log("arrived at "..minetest.pos_to_string(trg)) end) if clicker:get_wielded_item():get_name() == "mcl_farming:bread" then if mobs:feed_tame(self, clicker, 1, true, true) then return end @@ -1320,8 +1281,6 @@ mobs:register_mob("mobs_mc:villager", { -- Stand still if player is nearby. if not self._player_scan_timer then self._player_scan_timer = 0 - else - check_gowp(self) end self._player_scan_timer = self._player_scan_timer + dtime @@ -1350,8 +1309,6 @@ mobs:register_mob("mobs_mc:villager", { end if self._profession == "unemployed" then get_a_job(self) - -- else - -- check_jobsite(self) end end end, From f8fc111b4a23568d2b5814bc517a493f347474e0 Mon Sep 17 00:00:00 2001 From: cora Date: Wed, 18 May 2022 00:03:40 +0200 Subject: [PATCH 05/35] pathfind to jobsites --- mods/ENTITIES/mcl_mobs/api.lua | 31 ++++++++++++++----- mods/ENTITIES/mobs_mc/villager.lua | 48 +++++++++++++++++++----------- 2 files changed, 53 insertions(+), 26 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index cebb4aaff..5a4873438 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -2329,6 +2329,7 @@ local function go_to_pos(entity,b) if b.x > s.x then yaw = yaw + math.pi end entity.object:set_yaw(yaw) set_velocity(entity,entity.follow_velocity) + mobs:set_animation(entity, "walk") end -- execute current state (stand, walk, run, attacks) @@ -2387,9 +2388,9 @@ local do_states = function(self, dtime) end elseif self.state == "gowp" then - if not self.waypoints or not self._target then return end local p = self.object:get_pos() - if vector.distance(p,self._target) < 1 then + if not p or not self._target then return end + if vector.distance(p,self._target) < 2 or #self.waypoints == 0 then self.waypoints = nil self._target = nil self.current_target = nil @@ -2399,13 +2400,19 @@ local do_states = function(self, dtime) end if not self.current_target or vector.distance(p,self.current_target) < 1.5 then self.current_target = table.remove(self.waypoints, 1) - else + --minetest.log("nextwp:".. tostring(self.current_target) ) + elseif self.current_target then go_to_pos(self,self.current_target) end if self.current_target and not minetest.line_of_sight(self.object:get_pos(),self.current_target) then self.waypoints=minetest.find_path(p,self._target,150,1,4) self.current_target = nil + return + end + if not self.current_target then + --minetest.log("no path") + self.state = "walk" end elseif self.state == "walk" then @@ -2913,11 +2920,19 @@ local do_states = function(self, dtime) end function mobs:go_wplist(self,target,callback_arrived) - if not target then return end - self._target = target - self.waypoints = minetest.find_path(self.object:get_pos(),target,150,1,4) - self.callback_arrived = callback_arrived - self.state = "gowp" + local p = self.object:get_pos() + local t = vector.offset(target,0,1,0) + if not target or not p then return end + local wp = minetest.find_path(p,t,150,1,4) + if wp and #wp > 0 then + self._target = t + self.callback_arrived = callback_arrived + self.waypoints = wp + self.state = "gowp" + return true + else + --minetest.log("no path found") + end end diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 64712971e..76fc76415 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -69,6 +69,14 @@ local tiernames = { "Master", } +local badges = { + "mcl_core:wood", + "mcl_core:stone", + "mcl_core:goldblock", + "mcl_core:emeraldblock", + "mcl_core:diamondblock", +} + local professions = { unemployed = { name = N("Unemployed"), @@ -454,7 +462,7 @@ local professions = { "mobs_mc_villager_smith.png", "mobs_mc_villager_smith.png", }, - jobsite = "mcl_villages:stonebrickcarved", --FIXME: smithing table + jobsite = "mcl_anvils:anvil", --FIXME: smithing table trades = { { { { "mcl_core:coal_lump", 15, 15 }, E1 }, @@ -602,10 +610,21 @@ local function employ(self,jobsite_pos) end end -local function unemploy(self) - self._profession="unemployed" - self._jobsite = nil - self.object:set_properties({textures=professions[self._profession].textures}) +local function look_for_job(self) + local p = self.object:get_pos() + local nn = minetest.find_nodes_in_area(vector.offset(p,-48,-48,-48),vector.offset(p,48,48,48),jobsites) + for _,n in pairs(nn) do + local m=minetest.get_meta(n) + if m:get_string("villager") == "" then + --minetest.log("goingt to jobsite "..minetest.pos_to_string(n) ) + minetest.after(0,function() + mobs:go_wplist(self,n,function() + --minetest.log("arrived jobsite "..minetest.pos_to_string(n) ) + end) + end) + return + end + end end local function get_a_job(self) @@ -614,16 +633,7 @@ local function get_a_job(self) for _,n in pairs(nn) do if n and employ(self,n) then return true end end -end - -local function check_jobsite(self) - local n = minetest.get_node(self._jobsite) - local m = minetest.get_meta(self._jobsite) - if n.name ~= professions[self._profession].jobsite or m:get_string("villager") ~= self._id then - --unemploy(self) - return false - end - return true + if self.state ~= "gowp" then look_for_job(self) end end local update_max_tradenum = function(self) @@ -1231,9 +1241,11 @@ mobs:register_mob("mobs_mc:villager", { look_at_player = true, on_rightclick = function(self, clicker) local trg=vector.new(0,9,0) - mobs:go_wplist(self,trg,function() - minetest.log("arrived at "..minetest.pos_to_string(trg)) - end) + if self._jobsite then + mobs:go_wplist(self,self._jobsite,function() + --minetest.log("arrived at jobsite") + end) + end if clicker:get_wielded_item():get_name() == "mcl_farming:bread" then if mobs:feed_tame(self, clicker, 1, true, true) then return end if mobs:protect(self, clicker) then return end From e3bb7fe4befefce04c817fe32f27358cb11d7f75 Mon Sep 17 00:00:00 2001 From: cora Date: Wed, 18 May 2022 13:50:48 +0200 Subject: [PATCH 06/35] codestyle: replace inline functions --- mods/ENTITIES/mobs_mc/villager.lua | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 76fc76415..334bed23f 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -546,7 +546,7 @@ for _,n in pairs(profession_names) do table.insert(jobsites,professions[n].jobsite) end -local stand_still = function(self) +local function stand_still(self) self.walk_chance = 0 self.jump = false end @@ -636,7 +636,7 @@ local function get_a_job(self) if self.state ~= "gowp" then look_for_job(self) end end -local update_max_tradenum = function(self) +local function update_max_tradenum(self) if not self._trades then return end @@ -651,7 +651,7 @@ local update_max_tradenum = function(self) self._max_tradenum = #trades end -local init_trades = function(self, inv) +local function init_trades(self, inv) local profession = professions[self._profession] local trade_tiers = profession.trades if trade_tiers == nil then @@ -702,7 +702,7 @@ local init_trades = function(self, inv) minetest.deserialize(self._trades) end -local set_trade = function(trader, player, inv, concrete_tradenum) +local function set_trade(trader, player, inv, concrete_tradenum) local trades = minetest.deserialize(trader._trades) if not trades then init_trades(trader) @@ -801,7 +801,7 @@ local function show_trade_formspec(playername, trader, tradenum) minetest.show_formspec(playername, tradeinv_name, formspec) end -local update_offer = function(inv, player, sound) +local function update_offer(inv, player, sound) local name = player:get_player_name() local trader = player_trading_with[name] local tradenum = player_tradenum[name] @@ -825,12 +825,12 @@ local update_offer = function(inv, player, sound) -- compass. -- TODO: Remove these check functions when compass and clock are implemented -- as single items. - local check_special = function(special_item, group, wanted1, wanted2, input1, input2) + local function check_special(special_item, group, wanted1, wanted2, input1, input2) if minetest.registered_aliases[special_item] then special_item = minetest.registered_aliases[special_item] end if wanted1:get_name() == special_item then - local check_input = function(input, wanted, group) + local function check_input(input, wanted, group) return minetest.get_item_group(input:get_name(), group) ~= 0 and input:get_count() >= wanted:get_count() end if check_input(input1, wanted1, group) then @@ -845,7 +845,7 @@ local update_offer = function(inv, player, sound) end -- Apply above function to all items which we consider special. -- This function succeeds if ANY item check succeeds. - local check_specials = function(wanted1, wanted2, input1, input2) + local function check_specials(wanted1, wanted2, input1, input2) return check_special(COMPASS, "compass", wanted1, wanted2, input1, input2) end -- END OF SPECIAL HANDLING OF COMPASS @@ -899,7 +899,7 @@ local function return_item(itemstack, dropper, pos, inv_p) return itemstack end -local return_fields = function(player) +local function return_fields(player) local name = player:get_player_name() local inv_t = minetest.get_inventory({type="detached", name = "mobs_mc:trade_"..name}) local inv_p = player:get_inventory() @@ -965,7 +965,7 @@ minetest.register_on_leaveplayer(function(player) end) -- Return true if player is trading with villager, and the villager entity exists -local trader_exists = function(playername) +local function trader_exists(playername) local trader = player_trading_with[playername] return trader ~= nil and trader.object:get_luaentity() ~= nil end @@ -992,7 +992,7 @@ local trade_inventory = { wanted1:set_count(wanted1:get_count()*2) wanted2:set_count(wanted2:get_count()*2) -- BEGIN OF SPECIAL HANDLING FOR COMPASS - local special_checks = function(wanted1, input1, input2) + local function special_checks(wanted1, input1, input2) if wanted1:get_name() == COMPASS then local compasses = 0 if (minetest.get_item_group(input1:get_name(), "compass") ~= 0) then From 98231f15ae27d661239ee40a70cf7c225e21c422 Mon Sep 17 00:00:00 2001 From: cora Date: Thu, 19 May 2022 00:50:46 +0200 Subject: [PATCH 07/35] change function name go_wplist -> gopath --- mods/ENTITIES/mcl_mobs/api.lua | 2 +- mods/ENTITIES/mobs_mc/villager.lua | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 5a4873438..71fa681e3 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -2919,7 +2919,7 @@ local do_states = function(self, dtime) end end -function mobs:go_wplist(self,target,callback_arrived) +function mobs:gopath(self,target,callback_arrived) local p = self.object:get_pos() local t = vector.offset(target,0,1,0) if not target or not p then return end diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 334bed23f..e96cd99b4 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -575,7 +575,7 @@ local function go_home(entity) entity.state = "go_home" local b=entity.bed if not b then return end - mobs:go_wplist(entity,b,function(entity,b) + mobs:gopath(entity,b,function(entity,b) if vector.distance(entity.object:get_pos(),b) < 2 then entity.state = "stand" set_velocity(entity,0) @@ -618,7 +618,7 @@ local function look_for_job(self) if m:get_string("villager") == "" then --minetest.log("goingt to jobsite "..minetest.pos_to_string(n) ) minetest.after(0,function() - mobs:go_wplist(self,n,function() + mobs:gopath(self,n,function() --minetest.log("arrived jobsite "..minetest.pos_to_string(n) ) end) end) @@ -1242,7 +1242,7 @@ mobs:register_mob("mobs_mc:villager", { on_rightclick = function(self, clicker) local trg=vector.new(0,9,0) if self._jobsite then - mobs:go_wplist(self,self._jobsite,function() + mobs:gopath(self,self._jobsite,function() --minetest.log("arrived at jobsite") end) end From 4ac41a793ecfff4025d28a4c97b40ee65949288b Mon Sep 17 00:00:00 2001 From: cora Date: Thu, 19 May 2022 02:03:28 +0200 Subject: [PATCH 08/35] fix two crashes in pathfinding --- mods/ENTITIES/mcl_mobs/api.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 71fa681e3..bbcbefb0a 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -2390,7 +2390,7 @@ local do_states = function(self, dtime) elseif self.state == "gowp" then local p = self.object:get_pos() if not p or not self._target then return end - if vector.distance(p,self._target) < 2 or #self.waypoints == 0 then + if vector.distance(p,self._target) < 2 or ( self.waypoints and #self.waypoints == 0 ) then self.waypoints = nil self._target = nil self.current_target = nil @@ -2398,7 +2398,7 @@ local do_states = function(self, dtime) if self.callback_arrived then return self.callback_arrived(self) end return true end - if not self.current_target or vector.distance(p,self.current_target) < 1.5 then + if self.waypoints and ( not self.current_target or vector.distance(p,self.current_target) < 1.5 ) then self.current_target = table.remove(self.waypoints, 1) --minetest.log("nextwp:".. tostring(self.current_target) ) elseif self.current_target then From e6b65af3b458dae8bae30642f1a7105a7b9166fc Mon Sep 17 00:00:00 2001 From: cora Date: Thu, 19 May 2022 05:43:37 +0200 Subject: [PATCH 09/35] add mobs item pickup --- mods/ENTITIES/mcl_mobs/api.lua | 21 +++++++++++++++++++-- mods/ENTITIES/mobs_mc/villager.lua | 4 ++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index bbcbefb0a..c5d5916ac 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -2935,6 +2935,20 @@ function mobs:gopath(self,target,callback_arrived) end end +local function check_item_pickup(self) + if self.pick_up and #self.pick_up > 0 then + for _,o in pairs(minetest.get_objects_inside_radius(self.object:get_pos(),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 self.on_pick_up and l.itemstring:find(v) then + if self.on_pick_up(self,l) == nil then o:remove() end + end + end + end + end + end +end -- falling and fall damage -- returns true if mob died @@ -3536,7 +3550,7 @@ end -- main mob function local mob_step = function(self, dtime) - + check_item_pickup(self) if not self.fire_resistant then mcl_burning.tick(self.object, dtime, self) end @@ -3964,7 +3978,8 @@ minetest.register_entity(name, { child = def.child or false, texture_mods = {}, shoot_arrow = def.shoot_arrow, - sounds_child = def.sounds_child, + sounds_child = def.sounds_child, + pick_up = def.pick_up, explosion_strength = def.explosion_strength, suffocation_timer = 0, follow_velocity = def.follow_velocity or 2.4, @@ -3988,6 +4003,8 @@ minetest.register_entity(name, { on_grown = def.on_grown, + on_pick_up = def.on_pick_up, + on_detach_child = mob_detach_child, on_activate = function(self, staticdata, dtime) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index e96cd99b4..463a62d80 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -1239,6 +1239,10 @@ mobs:register_mob("mobs_mc:villager", { _id = nil, _profession = "unemployed", look_at_player = true, + pick_up = {"mcl_farming:bread"}, + on_pick_up = function(self,itementity) + minetest.log("picked up "..itementity.itemstring) + end, on_rightclick = function(self, clicker) local trg=vector.new(0,9,0) if self._jobsite then From 9a866e873eead4baafea6ad796586ccf2d11f5d3 Mon Sep 17 00:00:00 2001 From: cora Date: Thu, 19 May 2022 13:58:59 +0200 Subject: [PATCH 10/35] breed by throwing bread at villagers --- mods/ENTITIES/mobs_mc/villager.lua | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 463a62d80..f0a3ca088 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -1241,7 +1241,18 @@ mobs:register_mob("mobs_mc:villager", { look_at_player = true, pick_up = {"mcl_farming:bread"}, on_pick_up = function(self,itementity) - minetest.log("picked up "..itementity.itemstring) + local clicker + for _,p in pairs(minetest.get_connected_players()) do + if vector.distance(p:get_pos(),self.object:get_pos()) < 10 then + clicker = p + end + end + if not clicker then minetest.log("no clicker") end + if clicker then + mobs:feed_tame(self, clicker, 1, true, true) + return + end + return true --do not pick up end, on_rightclick = function(self, clicker) local trg=vector.new(0,9,0) @@ -1250,10 +1261,6 @@ mobs:register_mob("mobs_mc:villager", { --minetest.log("arrived at jobsite") end) end - if clicker:get_wielded_item():get_name() == "mcl_farming:bread" then - if mobs:feed_tame(self, clicker, 1, true, true) then return end - if mobs:protect(self, clicker) then return end - end if self.child or self._profession == "unemployed" then return end From dfb74cf9e9cbd5987c2fe19c4a04832afd346189 Mon Sep 17 00:00:00 2001 From: cora Date: Thu, 19 May 2022 14:13:59 +0200 Subject: [PATCH 11/35] mobs: add nofollow option so v. dont follow bread --- mods/ENTITIES/mcl_mobs/api.lua | 6 ++++-- mods/ENTITIES/mobs_mc/villager.lua | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index c5d5916ac..e5e3063a2 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -1438,7 +1438,8 @@ end -- should mob follow what I'm holding ? local follow_holding = function(self, clicker) - + if self.nofollow then return false end + if mobs.invis[clicker:get_player_name()] then return false end @@ -3913,6 +3914,7 @@ minetest.register_entity(name, { sounds = def.sounds or {}, animation = def.animation, follow = def.follow, + nofollow = def.nofollow, jump = def.jump ~= false, walk_chance = def.walk_chance or 50, attacks_monsters = def.attacks_monsters or false, @@ -4321,7 +4323,7 @@ function mobs:feed_tame(self, clicker, feed_count, breed, tame) end -- can eat/tame with item in hand - if follow_holding(self, clicker) then + if self.nofollow or follow_holding(self, clicker) then -- if not in creative then take item if not mobs.is_creative(clicker:get_player_name()) then diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index f0a3ca088..07126db97 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -1231,6 +1231,7 @@ mobs:register_mob("mobs_mc:villager", { die_loop = false, }, follow = mobs_mc.follow.villager, + nofollow = true, view_range = 16, fear_height = 4, jump = true, @@ -1247,7 +1248,6 @@ mobs:register_mob("mobs_mc:villager", { clicker = p end end - if not clicker then minetest.log("no clicker") end if clicker then mobs:feed_tame(self, clicker, 1, true, true) return From 9ccbf91706e53ce7f3cc8cb8ccd7a0d49acd8f0d Mon Sep 17 00:00:00 2001 From: cora Date: Thu, 19 May 2022 14:19:57 +0200 Subject: [PATCH 12/35] mobs api: document api additions --- mods/ENTITIES/mcl_mobs/api.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mods/ENTITIES/mcl_mobs/api.txt b/mods/ENTITIES/mcl_mobs/api.txt index eda74aeb4..1ae6ee53f 100644 --- a/mods/ENTITIES/mcl_mobs/api.txt +++ b/mods/ENTITIES/mcl_mobs/api.txt @@ -253,6 +253,12 @@ functions needed for the mob to work properly which contains the following: 'fire_resistant' If true, the mob can't burn 'fire_damage_resistant' If true the mob will not take damage when burning 'ignited_by_sunlight' If true the mod will burn at daytime. (Takes sunlight_damage per second) + 'nofollow' Do not follow players when they wield the "follow" item. For mobs (like villagers) + that are bred in a different way. + 'pick_up' table of itemstrings the mob will pick up (e.g. for breeding) + 'on_pick_up' function that will be called on item pickup - return true to not pickup the item + + mobs:gopath(self,target,callback_arrived) pathfind a way to target and run callback on arrival From 67939f7b7a57d0cf2eca92c31b48ed187d16a933 Mon Sep 17 00:00:00 2001 From: cora Date: Thu, 19 May 2022 14:45:12 +0200 Subject: [PATCH 13/35] pathfinding: find doors close to target as well --- mods/ENTITIES/mcl_mobs/api.lua | 21 ++++++++++++++++++++- mods/ENTITIES/mobs_mc/villager.lua | 8 +++----- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index e5e3063a2..3fb2bcc9e 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -2920,11 +2920,30 @@ local do_states = function(self, dtime) end end +local plane_adjacents = { + vector.new(1,0,0), + vector.new(-1,0,0), + vector.new(0,0,1), + vector.new(0,0,-1), +} + function mobs:gopath(self,target,callback_arrived) local p = self.object:get_pos() local t = vector.offset(target,0,1,0) - if not target or not p then return end local wp = minetest.find_path(p,t,150,1,4) + if not wp then + local d = minetest.find_node_near(target,16,{"group:door"}) + if d then + for _,v in pairs(plane_adjacents) do + local pos = vector.add(d,v) + local n = minetest.get_node(pos) + if n.name == "air" then + wp = minetest.find_path(p,pos,150,1,4) + if wp then break end + end + end + end + end if wp and #wp > 0 then self._target = t self.callback_arrived = callback_arrived diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 07126db97..0e3236a84 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -617,12 +617,10 @@ local function look_for_job(self) local m=minetest.get_meta(n) if m:get_string("villager") == "" then --minetest.log("goingt to jobsite "..minetest.pos_to_string(n) ) - minetest.after(0,function() - mobs:gopath(self,n,function() - --minetest.log("arrived jobsite "..minetest.pos_to_string(n) ) - end) + local gp = mobs:gopath(self,n,function() + --minetest.log("arrived jobsite "..minetest.pos_to_string(n) ) end) - return + if gp then return end end end end From 0d56ef1a9055f9f3b937f3cd566562d4aa1b349f Mon Sep 17 00:00:00 2001 From: cora Date: Thu, 19 May 2022 16:16:44 +0200 Subject: [PATCH 14/35] add jobsites to villagegen schematics --- mods/ENTITIES/mobs_mc/villager.lua | 4 ++-- .../mcl_villages/schematics/blacksmith.mts | Bin 986 -> 988 bytes .../mcl_villages/schematics/butcher.mts | Bin 813 -> 804 bytes .../MAPGEN/mcl_villages/schematics/church.mts | Bin 956 -> 949 bytes mods/MAPGEN/mcl_villages/schematics/farm.mts | Bin 347 -> 379 bytes mods/MAPGEN/mcl_villages/schematics/lamp.mts | Bin 209 -> 176 bytes .../mcl_villages/schematics/large_house.mts | Bin 1137 -> 1179 bytes .../mcl_villages/schematics/library.mts | Bin 816 -> 802 bytes .../mcl_villages/schematics/medium_house.mts | Bin 760 -> 801 bytes .../mcl_villages/schematics/small_house.mts | Bin 593 -> 572 bytes .../MAPGEN/mcl_villages/schematics/tavern.mts | Bin 1005 -> 1003 bytes mods/MAPGEN/mcl_villages/schematics/well.mts | Bin 476 -> 444 bytes 12 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 0e3236a84..035bb3d71 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -242,7 +242,7 @@ local professions = { "mobs_mc_villager_librarian.png", "mobs_mc_villager_librarian.png", }, - jobsite = "mcl_villages:stonebrickcarved", --FIXME: lectern + jobsite = "mcl_books:bookshelf", --FIXME: lectern trades = { { { { "mcl_core:paper", 24, 36 }, E1 }, @@ -431,7 +431,7 @@ local professions = { "mobs_mc_villager_smith.png", "mobs_mc_villager_smith.png", }, - jobsite = "mcl_villages:stonebrickcarved", --FIXME: grindstone + jobsite = "mcl_furnaces:furnace", --FIXME: grindstone trades = { { { { "mcl_core:coal_lump", 15, 15 }, E1 }, diff --git a/mods/MAPGEN/mcl_villages/schematics/blacksmith.mts b/mods/MAPGEN/mcl_villages/schematics/blacksmith.mts index d7fb66593dba1636ba133681520ae16721d276b8..dab65afa47314919237e6abc50d80bd51d3690dd 100644 GIT binary patch delta 330 zcmcb`eusU6xG-;Sa!!15eo?AbN@h_B19M_#(MFdxMvKI}vdo-fD=@_%09KTdT3k|W zl?+jGT3nO8 zn|*d);>m6$v;bbo@%z(s^#4>lQzG z8app#<+aq=!%sZiZ|n~U`UO0k z(Yk8=#OHpwFY8k+)-yKd+W04YJ^DGc!1Yq3bZD}$%E@0YxBqGOC%1lmZM!>hQD}LE zKxlQfawlpC5`JCI(X%B7WAF}%kw_z??1jzYV&2%ikeTqI)CTqB$X%C&Qori WKl8r#&mfHaYgqJA* delta 328 zcmcb^ev5sAxUNKQa!!15eo?AbN@h_>e0gR`MtpivVsSA8b7E!@122m7My)nR>Ew*m z;*w%3FvTDOl20ow%1ca6Ewe@%Q6* z3pO9xRHVVca`8z@%bWt%jn0dOQr>(Gygy^lmW5x|UhUv1y76F6RPNQQ8Yh)J;%+_j ze3lh^ZK_4>MV87ESF80Llhk)QFU$J>&0@MtX@GTEPRNrt@f|jYea@CP8BeJ=f8_^P zW#-hpe__8qX9?W+W1~>X;ofAHH^7AZ>?e8b| U^Z)qs>U;CXzI>f~-O^UC047A8Gynhq diff --git a/mods/MAPGEN/mcl_villages/schematics/butcher.mts b/mods/MAPGEN/mcl_villages/schematics/butcher.mts index 251033b1ec0a3e7bf299f833ab1ffd90e35c18b3..1786599dcc23fbdd8d08d351c9eeb6b9eb1ff2df 100644 GIT binary patch delta 340 zcmZ3>wuEhhq%d!8a!!15eo?AbN@h_B19M_#(L}d1k`gGw@#UE%8S&{wiN(c}1sPL> z1VOUJx%t_tMOF}M@+8K2^&y;mhZF>2__nq`a{aioF7_1fQmN{U%Oz^NW^2APxWq7l zHH!7~0ZAo=K8Y1ctKZ#O6Lwen>L-D8@mCl)d)aazZ^>VGE-?OZ4tIj@a*SpzpYTnG7>t6j9OTGNHUheEB zt@EomW*xkFBj@I>=gW*cpXlrezFfX(cUZdc&77oX#nJC$KfRse`e|q4;kNk;pX>b; zpR}8|KJKWceEL!?Pu@=PiTU!MF7tdibgq{rPbEmbKzXKK&e<(;=0+N`=Qtd`b~7@R i>&otn6aO!nE4=8r?m?k4bEl4lX_p_dZqwYycn<(zjG%}B delta 332 zcmV-S0ki(32CW8=87&xXV{BhzZ*pZiWNC7AUw3JAXkTY?VRLf;17T@$01a(pY+qw< za%DPXX>xRtEXCilV1T92VZ1wbz*E~lZOGGe^rYTf*=q)gfbt|3+Z$F^^iA+ z)hJfucsqJGE8eogAV4zEDo`WVc|Ut)4)cWG{CI&*Yk zZe(9DFffzA0e*j0!yphOP)V$|(R%)^zix_2VL_TT~~ z%;;lFZ|mCBquYg@g@aeQ(sE3$Jl9~G0H?9l>Wy{rV}|R%7Gj&iaviEtc)3o$+j-Ag@5Hjctznc zDYN;VtKk9_l?`#>C}?wG7A)%mtUP%YlR3`$UD(#$bQjoiv}cE>C&9hpf*S8kUaZPV z$@JCG--^~6R^Gh|?2j#9*#&w3Ywf~}F5rr!C?uHMced5q@52ANQ~gl-Kk-gg zaRFBFsjYmh3w4P9VD#X^&GQR^Kp+qZ1OkER5{~DE+kxw;=}I7_z}iItfn@~6&u?pb z4x@NNBL+DsWFsvFy;{Xm7{Ep#l2eHM4IC%~8`;UZVu%MEXi6gul$Cx3FjDe7pj(kCc7%eufu zuH}M%Md52=Msqv2g$tBd*2jf2r^$sk&b%(b%DYq1nc|$=g=O7!yI}HQa)FJreONrb za2_=md+&Y?=J&q!-N zss2d)zxbpoxqkpFcxsDr0sp}$%^F;Ic>W;}2m}IwKp+rR!g5}C9N11xJAse_D;EU> zmJn1sz0K)ajA|nqAxKFf8F4A7)ykGa12#MnokAesKpEIbPR?+~l12$BjGUC&V5{ru`R%F)&cXKr;@XU#d{Ji-0*JWwCY8qc0PFU~kH9WRZ*ukN3 zUx1+Rg~q3Wp$iYa)K-4|@TX^g=M0ly8;@A7xc6JkA!x~r*^`!+M5L{i&pFqxTzW86 zy6!{4)u#Dd?BnnFzy1Gca{RCO?Bn_qZyuJ?SSDn~mi%XDquq1Oj_@2`XL4b4bCDJ{5)o}_WbddoAifqJv zNTd3)8Ero^s5QDjjliJO^NeB}lD2gdSdyjYcF8*>yml!MSI6TdU7)IihYzY6c=q@6 i#rah9zviZ23iqV{QYyO^B0nCe?emtB`&s~@g#TMxTT(0l diff --git a/mods/MAPGEN/mcl_villages/schematics/lamp.mts b/mods/MAPGEN/mcl_villages/schematics/lamp.mts index c8d907ebad7a6bbd63574e62b695f22ba428e4b6..8da0e83557a435ab483c56f74ba72ad80e6fbd60 100644 GIT binary patch delta 90 zcmcb}xPei_Hze4XfrWvYfsKKs9t?mi-rVGz_~iVeRI8NCq7nw?#LS|JPVt)CrPO## p&m_n-r6eUVu1-=tH>XOAk?oHIORU2jN0E098UoCM4B3}dVga5v8%_WK delta 123 zcmdnMc#+Y`Hze4XfrWvYfsKKs9t;@R86BF>Q!%YLvvRpm!U2Al3#>;ZT^{na OFc}IkGL$r{WB>q>hADIa diff --git a/mods/MAPGEN/mcl_villages/schematics/large_house.mts b/mods/MAPGEN/mcl_villages/schematics/large_house.mts index 36be603f448f4473c9db7904518f25ab78a5a459..3939a2c4342ea3895e8a89c67851b6dcfa0354ee 100644 GIT binary patch delta 398 zcmey!F`ILOxPSr!Z*Fo)Ax$^J}k z>gr(SiA5#(=|zbJ8I|!RiAg!BR>^20lP5Fnt`EH_)MUWJ)83#kkAq8Y{;T!T(Nh+^ zJZNilw^rlqlAAiR91L99VmXh`s{QG;df@lY?fmUW?K=0F=Py3)%ItJ^#SW&^)1T`p zKH2f+?Ckh^GW%DDN%!u1Bq(&W`0B+C*TQdHxb5{oSMT+D&HGuaGF(oU%`Uoo=}dT@ z%k>4z6^T(Idzo%tZ6{~+drslvGz9aJ=r^~%B+C7hR`HUUhYRc~aPb)j$ zz|RZc%B`PPc$eJ`}lw>XGo_F>5+`3sS`7AQ-s%1@6(CS;bd)BgmYSS$&4q;Ez ie_WKi@`7=yd8AYFR=*9BCRZ<&+{kM?F3hhtza0Q<8oW6G delta 358 zcmV-s0h#`r3GoP!7aJb{7;R&0Ut@1_WjbVOa&%vJX>@2`XL4b4bCD-z4h?N%Y+qw< za%DPXX>xS2jH>~YO#(!dx&pa>me~@5FbqXoPyxXmQE~ZIf8Ele6iC{FEXwrWhe9Sa zIWQ0i0YxX_Hf#=aJ?fI#=rmQfdCeKyqGplr5nr+=MFVEjD87TpSLZHCD0$f#o1Z^9 z`K(wSFq*|9APVQ|qhYD9up!$DVO!_>Z@AypbkT@goNe=U$1}6sh_69^sjGnO2Vgre z%g-$as~weh9b%&zwq$U&HCRm-#n?{F7~8owHud|K-SG>zsFw21u9Y6rProu7HDsHO z!X_rbh1|&9@JoQPneQ+R+kee~u4eb+2WR(W|GA!4R#sM4N+B~~aK-W19W)U(It|jX zWBuiBH_a3mxZu7`s!=2*4(a=9P1LFyqLT|9_E3%La8(KI*xJewGOU&){dUv8UTE~9 E68cQ3&Hw-a diff --git a/mods/MAPGEN/mcl_villages/schematics/library.mts b/mods/MAPGEN/mcl_villages/schematics/library.mts index b47e0b4138f53fbb43aa1887249002d9c1082149..521ee9fb60fcd3fb459bd09bced589d811a84366 100644 GIT binary patch delta 337 zcmV-X0j~bA2BHR#7!wU`V{BhzZ*pZiWNC7A00UuZa*;(`7Zz<}Y+qwxb!=pEZ*Frs zV_|h{WO8qAv7m1Oe^!eQgCGn zLvu+(TUP>*Dni%Da2*WYmFLK*xeg?kLb|y?6iC+>$VjQl7@~9U$=iM4lZBrbm&@lNl|=Ip*9J$(bn{mbk2ddBszzA@)s-Ynk<2?+@aE!aN4cSyPP3YG)F(kmE+ j`|~0BDI2dj7hV}V^LsCXkW!5FnpNJBUVFj^%b1Rg8pESV delta 351 zcmV-l0igb(2CxQ@7%doWV{BhzZ*pZiWNC7AUw3JAXkTY?VRLf;17T@$01a(pY+qw< za%DPXX>xRtD_pUkZUKLn4-bMM5XBJzt?a*BAGfdGX=n&{2H}P|-rL-IG>;!1Sd0-W z{@k{>w*9?Q+s*}(U=ffjuzxPK-I-V5CAb9G<&vxhyLF{;HLZ-RPfp#Z>eqoLi|4}Y zu9M5%Uo_W_;Mxar9l*s%CSEc%b?CH?9*q z>t|%T)O9cH3ak@jmR>nH0uUr@v2dX<5=W2+$M^O?{6&W*75@k(6{AV-$3Wyq%$18YUKcVMk8=>_#!kZO7DuaE!$ diff --git a/mods/MAPGEN/mcl_villages/schematics/medium_house.mts b/mods/MAPGEN/mcl_villages/schematics/medium_house.mts index 43ce2391b9d1952596c3ec5028d0d66dd7105926..fa859ac4840297477d37598a40a5f6338049c2b2 100644 GIT binary patch delta 320 zcmeytx{z&xn1BQWZ*FoJt?i+{gf`dX+^ zbqjCArM8(zEOxE&XJwe-lKA}D#4|5#dY`AaetJ`sEqkuWB<@kIZ&+l7RK$(PLSfsI z=ij{%FzwsQY#-@I7ZVJmSCzLU?kcZ1c0NDy+JVZLGMmR$jXI}x%RPQMAvyc*XNmRu zmu-K2x$onf&gk?9=MNSq*f8~lR4(FszW!6moBElD{%f1m>wUOcvoC4aS(EwR>%W^k zzt7+OD=swDbhg^-zxk=#550W%%+n#^d-t^c6AV2MKdx=5S5lDoPm<4>_}TjZ4!MaF Hw@2`XL4b4bCD(>4h?N%Y+qw< za%DPXX>xRtMM|-%P63l00xEx%i4KDx42BCEvIBQ-ue(I z7s|X+h1;Y&rI;@_^L(XP&v$f>k=FCn`+aHW;iCQ*&m1{&j24~!{>P!ZryFmD$m!Rc e{wACo)V;rs;x`J?@eHhkB~pIpACDKhLA6eg5{H8T diff --git a/mods/MAPGEN/mcl_villages/schematics/small_house.mts b/mods/MAPGEN/mcl_villages/schematics/small_house.mts index d7b62529cb804c5fa99a9a99a8677c4f5cc46b9f..a3789504eedee18849ec211439fa09659c898b5f 100644 GIT binary patch delta 202 zcmV;*05$*71iS>07_l-R0S*mqV{Bh+Z*OfnY;SLElTZOne^c!a!ypI*%4FSlpLnl6 z;<^rTThpq^e)KM&5+o-Mgxszd0M6LJfrZn`=#(5;Uud~4=-?q+h6rCpF?qT zI2U=&Vc%p9ENhWrP(L^Yi+=Wf!-nPfFxYKD`9CT^H(FKHDTp`~tFF)^Yiese0N5iP EzZOSY#{d8T delta 223 zcmV<503iRo1knVL7#SFCV{BhzZ*pZiWNC7AUw3JAXkTY?VRLh_7a#$XMgdEIRP7Ff zAPg*YjLv=f#C!E!m^eP%3*k~4B4ngf*ON8(*=^iqqyhvOX?j;vTAsX*SyBe?{naRCxyIja(G*D=y$&y zeljMi>UD;9di>QH=5r{?9Ijvk^tE6hW Z@ua3`(@?3oS#yUemi|v&@d8H6AH!8qXXyX{ diff --git a/mods/MAPGEN/mcl_villages/schematics/tavern.mts b/mods/MAPGEN/mcl_villages/schematics/tavern.mts index 5eae8ae237646505300fbfebea88c59d98e4ede9..c26c14dbccb6acadb9f4838d01dcb900aba03a74 100644 GIT binary patch delta 444 zcmV;t0Ym=n2kQrr91{&~V{BhzZ*pZiWNC7A00UuZaZHIP!0kMVmTsu^GsPeKE(1u^l=tf6wbu$w?wVP=wE`gox z01pN&UB8O3Qvj+64}EqpN9}0Ic3MrwJNFGa8Vix>?0mC*V(oBtfIN>V!wyv*S`qAY zwwN7^(zci#K9U_dY5&o(2WCzIJ7<`AL3#cJUJbfJd4E?{Lw0JC9lw4GotvGZwbQTd zNLHcVik)ZftR{ABXVo^6Ibp7-iss~@&tD1bg#6Zk{-Uh5A8;z?8$HfWR{obIOO`BI z-bf;M)~ARdUtbm1-1xF-+vt&>06sJt`*E0(l=S`eUGrqbW>DT0I$c7+Q%J}I4aAS%YB^+!(xS2FCqee5^ZB_Uw2__Y;!teZ(?F>WnVUUob6VLa)Tfc<uqpCf2vfe zQl-ibN#@MD7h&k@R&n)-&xh7U&s+lNRB!I$uqG)U`b%BYV#J}7FA7~QA!AVv^XGIx o#T2*r?{rvkZeA&!av&_ms`-ZxVn&v+GfVbb==;b8FWm;yAGi(P`~Uy| diff --git a/mods/MAPGEN/mcl_villages/schematics/well.mts b/mods/MAPGEN/mcl_villages/schematics/well.mts index 6ea47fea435da769b2144cac8b0dfcfa9fb1a15c..ff8785fdee376e75739005a4b668afb4ea646271 100644 GIT binary patch delta 136 zcmV;30C)e~1H1!}6c7#o4Q*p=Ut@1_WjbVOa&(a|N0Ei+YGYtP0*q9G=w>o8FjLt~ z7AOSCurja#Av>7OfrI3PLfmFD!OaA@m5qT52-)zuh?9XE2=ST8Oan7f{mujSJ1>QP q2l1Jy9!FGx^`n5QfME~-a6(}QVs>IxvJ+HE3SeTQo>>5$W2s%hEjWY# delta 178 zcmdnPe2000h!Q`8L~e3Ud~$wKs#Qv6QAvDxW=TeTdQoC=F#~gAW)XwZM1SdtZmN8| zD9R>gy(oA)=`~k_0#B=d^wv$MwZFgeop{1w_l5=XbDNbc?86TA@9d9DE>nE Date: Thu, 19 May 2022 17:43:45 +0200 Subject: [PATCH 15/35] villagers open doors in daytime and close at night --- mods/ENTITIES/mcl_mobs/api.lua | 22 ++++++++++++++++++++++ mods/ENTITIES/mobs_mc/villager.lua | 1 + 2 files changed, 23 insertions(+) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index 3fb2bcc9e..c5340c472 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -2333,9 +2333,30 @@ local function go_to_pos(entity,b) mobs:set_animation(entity, "walk") end +local function check_doors(self) + local p = self.object:get_pos() + local t = minetest.get_timeofday() + local dd = minetest.find_nodes_in_area(vector.offset(p,-1,-1,-1),vector.offset(p,1,1,1),{"group:door"}) + for _,d in pairs(dd) do + local n = minetest.get_node(d) + if n.name:find("_b_") then + local def = minetest.registered_nodes[n.name] + local closed = n.name:find("_b_1") + if t < 0.3 or t > 0.8 then + if not closed then def.on_rightclick(d,n,self) end + else + if closed then def.on_rightclick(d,n,self) end + end + + end + end +end + -- execute current state (stand, walk, run, attacks) -- returns true if mob has died local do_states = function(self, dtime) + if self.can_open_doors then check_doors(self) end + local yaw = self.object:get_yaw() or 0 if self.state == "stand" then @@ -3934,6 +3955,7 @@ minetest.register_entity(name, { animation = def.animation, follow = def.follow, nofollow = def.nofollow, + can_open_doors = def.can_open_doors, jump = def.jump ~= false, walk_chance = def.walk_chance or 50, attacks_monsters = def.attacks_monsters or false, diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 035bb3d71..2db389328 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -1239,6 +1239,7 @@ mobs:register_mob("mobs_mc:villager", { _profession = "unemployed", look_at_player = true, pick_up = {"mcl_farming:bread"}, + can_open_doors = true, on_pick_up = function(self,itementity) local clicker for _,p in pairs(minetest.get_connected_players()) do From 539c31e8d6ea1d003e62e97b564b21006ef154bd Mon Sep 17 00:00:00 2001 From: cora Date: Thu, 19 May 2022 18:25:31 +0200 Subject: [PATCH 16/35] fix trading crash --- mods/ENTITIES/mobs_mc/villager.lua | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 2db389328..492e558dd 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -774,12 +774,17 @@ local function show_trade_formspec(playername, trader, tradenum) w2_formspec = "item_image[3,1;1,1;"..wanted2:to_string().."]" .."tooltip[3,1;0.8,0.8;"..F(wanted2:get_description()).."]" end - + local tiername = tiernames[trader._max_trade_tier] + if tiername then + tiername = S(tiername) + else + tiername = S("Master") + end local formspec = "size[9,8.75]" .."background[-0.19,-0.25;9.41,9.49;mobs_mc_trading_formspec_bg.png]" ..disabled_img -.."label[3,0;"..F(minetest.colorize("#313131", S(profession).." - "..S(tiernames[trader._max_trade_tier]))) .."]" +.."label[3,0;"..F(minetest.colorize("#313131", S(profession).." - "..tiername)) .."]" .."list[current_player;main;0,4.5;9,3;9]" .."list[current_player;main;0,7.74;9,1;]" ..b_prev..b_next From 3ff4ea576d8d3b7500a672d98ea720ccfbea5a24 Mon Sep 17 00:00:00 2001 From: cora Date: Thu, 19 May 2022 18:36:54 +0200 Subject: [PATCH 17/35] spawn iron golem on villagegen --- mods/MAPGEN/mcl_villages/init.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mods/MAPGEN/mcl_villages/init.lua b/mods/MAPGEN/mcl_villages/init.lua index 3eed2cbbb..34a355f55 100644 --- a/mods/MAPGEN/mcl_villages/init.lua +++ b/mods/MAPGEN/mcl_villages/init.lua @@ -59,6 +59,8 @@ local function spawn_villagers(minp,maxp) v:get_luaentity().bed = bed end end + local p = minetest.find_node_near(minp,50,"mcl_core:grass_path") + minetest.add_entity(p,"mobs_mc:iron_golem") end -- From b58422a584d18689fad289bd4721cb8823645dee Mon Sep 17 00:00:00 2001 From: cora Date: Thu, 19 May 2022 21:36:11 +0200 Subject: [PATCH 18/35] write villager id into bed nodemeta --- mods/ENTITIES/mobs_mc/villager.lua | 8 ++++---- mods/MAPGEN/mcl_villages/init.lua | 17 ++++++++++++----- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 492e558dd..72dc8ad7e 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -573,7 +573,7 @@ end local function go_home(entity) entity.state = "go_home" - local b=entity.bed + local b=entity._bed if not b then return end mobs:gopath(entity,b,function(entity,b) if vector.distance(entity.object:get_pos(),b) < 2 then @@ -582,7 +582,7 @@ local function go_home(entity) entity.object:set_pos(b) local n=minetest.get_node(b) if n and n.name ~= "mcl_beds:bed_red_bottom" then - entity.bed=nil --the stormtroopers have killed uncle owen + entity._bed=nil --the stormtroopers have killed uncle owen return false end return true @@ -1239,7 +1239,7 @@ mobs:register_mob("mobs_mc:villager", { fear_height = 4, jump = true, walk_chance = DEFAULT_WALK_CHANCE, - bed = nil, + _bed = nil, _id = nil, _profession = "unemployed", look_at_player = true, @@ -1331,7 +1331,7 @@ mobs:register_mob("mobs_mc:villager", { self.walk_chance = DEFAULT_WALK_CHANCE self.jump = true end - if self.bed and ( self.state ~= "go_home" and vector.distance(self.object:get_pos(),self.bed) > 50 ) then + if self._bed and ( self.state ~= "go_home" and vector.distance(self.object:get_pos(),self._bed) > 50 ) then go_home(self) end if self._profession == "unemployed" then diff --git a/mods/MAPGEN/mcl_villages/init.lua b/mods/MAPGEN/mcl_villages/init.lua index 34a355f55..4bea6ab3c 100644 --- a/mods/MAPGEN/mcl_villages/init.lua +++ b/mods/MAPGEN/mcl_villages/init.lua @@ -53,14 +53,21 @@ end local function spawn_villagers(minp,maxp) local beds=minetest.find_nodes_in_area(minp,maxp,{"mcl_beds:bed_red_bottom"}) for _,bed in pairs(beds) do - minetest.get_meta(bed):set_string("villagebed","true") - local v=minetest.add_entity(bed,"mobs_mc:villager") - if v then - v:get_luaentity().bed = bed + local m = minetest.get_meta(bed) + if m:get_string("villager") == "" then + local v=minetest.add_entity(bed,"mobs_mc:villager") + if v then + local l=v:get_luaentity() + l._bed = bed + m:set_string("villager",l._id) + end end + end local p = minetest.find_node_near(minp,50,"mcl_core:grass_path") - minetest.add_entity(p,"mobs_mc:iron_golem") + if p then + minetest.add_entity(p,"mobs_mc:iron_golem") + end end -- From 873e018faf957f654486d07be2ccd0bab833a00d Mon Sep 17 00:00:00 2001 From: cora Date: Fri, 20 May 2022 00:02:36 +0200 Subject: [PATCH 19/35] Dynamically add trading tier badge to texture --- mods/ENTITIES/mobs_mc/villager.lua | 42 ++++++++++++++++++------------ 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 72dc8ad7e..68e6fb1e7 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -70,11 +70,11 @@ local tiernames = { } local badges = { - "mcl_core:wood", - "mcl_core:stone", - "mcl_core:goldblock", - "mcl_core:emeraldblock", - "mcl_core:diamondblock", + "default_wood.png", + "default_stone.png", + "default_gold_block.png", + "mcl_core_emerald_block.png", + "default_diamond_block.png", } local professions = { @@ -163,7 +163,7 @@ local professions = { }, fletcher = { name = N("Fletcher"), - texture = { + textures = { "mobs_mc_villager_farmer.png", "mobs_mc_villager_farmer.png", }, @@ -205,7 +205,7 @@ local professions = { }, shepherd ={ name = N("Shepherd"), - texture = { + textures = { "mobs_mc_villager_farmer.png", "mobs_mc_villager_farmer.png", }, @@ -563,12 +563,18 @@ local function init_trader_vars(self) end end -local function set_texture(self) - local t = table.copy(professions[self._profession].textures) - --t[1] = "[combine:x:,="..t[1]..":30,50="..badges[self._max_trade_tier].."^[resize:16x16" - - - self.object:set_properties({textures=t}) +local function get_badge_textures(self) + local t = professions[self._profession].textures + if self._profession == "unemployed" or self._profession == "nitwit" then return t end + local tier = self._max_trade_tier or 1 + return { + "[combine:64x64:0,0="..t[1]..":11,55=".. badges[tier].."\\^[resize\\:2x2", + t[2] + } +end + +local function set_textures(self) + self.object:set_properties({textures=get_badge_textures(self)}) end local function go_home(entity) @@ -605,7 +611,7 @@ local function employ(self,jobsite_pos) self._profession=p m:set_string("villager",self._id) self._jobsite = jobsite_pos - self.object:set_properties({textures=professions[self._profession].textures}) + set_textures(self) return true end end @@ -1112,6 +1118,10 @@ local trade_inventory = { -- First-time trade unlock all trades and unlock next trade tier if trade.tier + 1 > trader._max_trade_tier then trader._max_trade_tier = trader._max_trade_tier + 1 + if trader._max_trade_tier > #professions[trader._profession].trades then + trader._max_trade_tier = #professions[trader._profession].trades + end + set_textures(trader) update_max_tradenum(trader) update_formspec = true end @@ -1342,12 +1352,12 @@ mobs:register_mob("mobs_mc:villager", { on_spawn = function(self) if self._id then - self.object:set_properties({textures=professions[self._profession].textures}) + set_textures(self) return end self._id=minetest.sha1(minetest.get_gametime()..minetest.pos_to_string(self.object:get_pos())..tostring(math.random())) self._profession = "unemployed" - self.object:set_properties({textures=professions[self._profession].textures}) + set_textures(self) end, on_die = function(self, pos) -- Close open trade formspecs and give input back to players From 53df441c1b3b03173dd3a55dd465e49ace0f587f Mon Sep 17 00:00:00 2001 From: cora Date: Fri, 20 May 2022 01:52:20 +0200 Subject: [PATCH 20/35] Don't pick up near player, add more breeding stuff --- mods/ENTITIES/mcl_mobs/api.lua | 11 +++++++++-- mods/ENTITIES/mobs_mc/0_gameconfig.lua | 2 +- mods/ENTITIES/mobs_mc/villager.lua | 2 +- 3 files changed, 11 insertions(+), 4 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.lua b/mods/ENTITIES/mcl_mobs/api.lua index c5340c472..7fb4e6a32 100644 --- a/mods/ENTITIES/mcl_mobs/api.lua +++ b/mods/ENTITIES/mcl_mobs/api.lua @@ -2976,13 +2976,20 @@ function mobs:gopath(self,target,callback_arrived) end end +local function player_near(pos) + for _,o in pairs(minetest.get_objects_inside_radius(pos,2)) do + if o:is_player() then return true end + end +end + local function check_item_pickup(self) if self.pick_up and #self.pick_up > 0 then - for _,o in pairs(minetest.get_objects_inside_radius(self.object:get_pos(),2)) do + 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 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 if self.on_pick_up(self,l) == nil then o:remove() end end end diff --git a/mods/ENTITIES/mobs_mc/0_gameconfig.lua b/mods/ENTITIES/mobs_mc/0_gameconfig.lua index 17451aeb6..c36b88475 100644 --- a/mods/ENTITIES/mobs_mc/0_gameconfig.lua +++ b/mods/ENTITIES/mobs_mc/0_gameconfig.lua @@ -169,7 +169,7 @@ mobs_mc.follow = { dog = { mobs_mc.items.rabbit_raw, mobs_mc.items.rabbit_cooked, mobs_mc.items.mutton_raw, mobs_mc.items.mutton_cooked, mobs_mc.items.beef_raw, mobs_mc.items.beef_cooked, mobs_mc.items.chicken_raw, mobs_mc.items.chicken_cooked, mobs_mc.items.rotten_flesh, -- Mobs Redo items "mobs:meat", "mobs:meat_raw" }, - villager = { "mcl_farming:bread" }, + villager = { "mcl_farming:bread", "mcl_farming:carrot_item", "mcl_farming:beetroot_item" , "mcl_farming:potato_item" }, } -- Contents for replace_what diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 68e6fb1e7..deaee72af 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -1253,7 +1253,7 @@ mobs:register_mob("mobs_mc:villager", { _id = nil, _profession = "unemployed", look_at_player = true, - pick_up = {"mcl_farming:bread"}, + pick_up = mobs_mc.follow.villager, can_open_doors = true, on_pick_up = function(self,itementity) local clicker From 08b36e3eb381a4e337c9b53606c839323e1d805c Mon Sep 17 00:00:00 2001 From: cora Date: Fri, 20 May 2022 02:44:27 +0200 Subject: [PATCH 21/35] Add textures for all professions --- .../textures/mobs_mc_villager_armorer.png | Bin 0 -> 971 bytes .../textures/mobs_mc_villager_butcher.png | Bin 866 -> 989 bytes .../mobs_mc_villager_cartographer.png | Bin 0 -> 1145 bytes .../textures/mobs_mc_villager_farmer.png | Bin 848 -> 1091 bytes .../textures/mobs_mc_villager_fisherman.png | Bin 0 -> 1054 bytes .../textures/mobs_mc_villager_fletcher.png | Bin 0 -> 950 bytes .../mobs_mc_villager_leatherworker.png | Bin 0 -> 933 bytes .../textures/mobs_mc_villager_librarian.png | Bin 896 -> 1098 bytes .../textures/mobs_mc_villager_nitwit.png | Bin 0 -> 1008 bytes .../textures/mobs_mc_villager_priest.png | Bin 768 -> 921 bytes .../textures/mobs_mc_villager_sheperd.png | Bin 0 -> 983 bytes .../textures/mobs_mc_villager_smith.png | Bin 866 -> 941 bytes .../textures/mobs_mc_villager_toolsmith.png | Bin 0 -> 964 bytes .../textures/mobs_mc_villager_weaponsmith.png | Bin 0 -> 967 bytes mods/ENTITIES/mobs_mc/villager.lua | 39 ++++++++++-------- 15 files changed, 21 insertions(+), 18 deletions(-) create mode 100644 mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_armorer.png create mode 100644 mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_cartographer.png create mode 100644 mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_fisherman.png create mode 100644 mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_fletcher.png create mode 100644 mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_leatherworker.png create mode 100644 mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_nitwit.png create mode 100644 mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_sheperd.png create mode 100644 mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_toolsmith.png create mode 100644 mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_weaponsmith.png diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_armorer.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_armorer.png new file mode 100644 index 0000000000000000000000000000000000000000..6d0eb39b16ced3523c9dd5f71d3a0b9ebdc8143e GIT binary patch literal 971 zcmV;+12p`JP)&S&MaDeqB19hHaREXqSO!oQ7_pk$*QgH-vCndu&^^wY9jF z37&mfl!9(@WK@E3U|UZ^g>+$0TPZ$9AWc{(KSm%+RzyfuKT~2#UTaf8Mj$~;BSTFi zKS?1}VJk*aB{Di1NKz(cc35wJV`_R{IYl#$7%FK10004WQchCXOKT1z&*ZNtvs&nK?t0t16B^;`(Fm|ZvZ?>BC`195Qa&d zDL3J58M~75AjCn+fguaY^)LtutspRcW}h=VER|vl37Pf*7|L*4dk}Qj+|($e%z2Qh zt^m;24PYP8MNI>sC~yw|cCuCoZhix>j%HGbEE7UzgAk0GRSUwdTn-@D_6jKEl&&E7 zqZI^{I!>m1yDzZUtV8dwlU+IjZe@uiSy?rj7R|p4j>HB6!gv_l}n_HCwg ztI!o0Z$&I=Q)ZFfm_xwv=m^?->YcQbD2iesL`;Aboo1uAi&52hFBP8RRU0`_!3+BbkRG!;;43vz!M67Q|G%9Xz<7?15wiGj2-75P ze^h8Z=xw8~VTOiTm|MBNd#(atYKYVG{XWn4X`WHn+}L;k=*sduO_7n=0UCrRNlvE| zHCFhJ$;DUr3*3U%gMHSm?*LZLyeI4hnH7Y;Hy#YN>^ph@o6ItX=?V|ONC)h|5QqWr zE+7f8N?>w)JhJeKKc7y|{CCKX#~7h|e-vZuB@B@QAUg}vIRiilgU8rh>${LK+Of0v zBjE2$NknQK;*kjb3JK<)U!H_`dN~7&3dmG+7zh8Wic*5gqO#f!kTpmaRY6($zUc&`H%LYM_iLvW5xlQ;!OXa)83F-v_7~0oc^5fUDA4U5gH9m~{<+1{ee|c~B)uxu=_a z)%tofB?smKW%&szm3@|-jn@7Ap?yK&QwY5rsF6B%A%tRf7YsnbbvJ~O2a|2=0OJr8 z9z(1(t<4kLx%wYh)=dV0AxPV~e+wv<)C=M6p`Kb&!nF189Fu4&2Vd z$><;+0H}z%svrkdElJ=H44P6_Eyqc`H9f`g!PNv%R8kjXfVy1N4M05rf56!o0Za&( zgJB3@0X8jfK>(nh;thx^uWyhs5&WlZf4DHclHA<-s!2E;A-HQ<00J9-r77l82 z4n!Y-Z{Bq<@W6az=za*$HvdZb*1>1O6MnK+|10I~!L5?16t{a|K8oGSTRm8okNsbv WV8O|r=_0x$jD2jT{hBn5s@OjJdYFMfZrQrW@)0004WQchC$Z5%piJ6Qk!Q|B-uO?x3-k1s;z;Uolx1`^4XFpgoyaTqR@p__Ct228vz zU}DZWF|ZStM!z68LBziWd_#~DO-h}w&~b>bf<*J{Gxh?}2<4#lc0UyefINR?no5~+ zQLV=%phvJrrQ}>4a%u6L3)+Im4koqrdj&cu#R@z0hf@LNkhp&ATx$_!XkmvyRLnE6 z-0qLZ{q_mYb5!Y6Av<;;SfF*=S!Dqz&GD0tGavw2@U?kX$+cR;@$~&j64vLkZOe0o z_6G!LQ9IOzB;fEj&+(}Ap;u`;HT+gmhLcli z>=&RqNF@cI1jp0q_;Wu0%ml!yfQ^~pAm^Kt*=kM`W~ySGPlO`O&VVnZ2F;jOZ$Se3dKW=&uz8IVtVSRl5-^MEaN@8A z7f3)eLd|=yv2r5H-72sjJ`^eJ-^sADS&K`OBHD&XZp z-otRetMmETD-mF?5qNQ2Ak^_TI5!@8m;?`h9!-#MLGBYMg3pgzoeY_s0!IReA_si} zomfn}MV$=n6l8}n?n|B6C5UO~8$oav4+?z;dj*eg4^a_xkI_Ip|H1Bh1KlHM^a^BH z&i6-PBQvYj?iV<1DA;+3(}^+j^;hcGyumg-^Zx+tExj`MysnY}0000*mw{)ThHjyee>XQbgm7AWY+JRp zwYZfDo_$%Af^KqTRDyC~TTerUbYalY(8a~Y&(F`x%ga<+P*GS+U1eBjZehsC$j8UW z&CSix(b2B1u5fv2dxUg$e{VoXJ=N9K($dn-&d#y1vD4Gj%*@Q?Paxd@0004WQchC< zK<3zH000A&Nkl=}G42C^~$milB#cq#1^s@i||22tVRmRzw?Sq2E@FoNu zh6*S|R0_sX6XQ4xhH0s1`g%K%JR9;Riucls)2tAIJx%%^1+aQdEA%f{wTl9 zl3RL%AP|Lp=tJEC5{=-XsU&3otLrcfVuhOML%$wHyq({fgUF&EDE!eMpDzLbRiYuu z3+p^Ul3oGYu4}J-e|-laSU&(Asz?1DKy3hd3k@p|F#~wxdT@nY0ZAyx z03z0Vh%CVSM6!KG4!&LmKq^u^Vl zH#!I0g;}BoKtLqD2cb1T1{iGF*6_^QQ!)^U&HyxL-q3zfPuADJBY>)kz`wCpg$e!#Nuoyl9*b*;$<3`s-snaolf9%C(D>?x4il843#ZN-n&K8!4 zL8GeI6+@7cBS4KL&P1a6&;fbxCV2G-;9i%WXBXv+Ujugp_;-B+aPZZIVU6t*lFw3?)_hMUjlUPoZ6qe(o`s1W1!Ae$TPF|Bocs#bDh$D zb}|{__V5)61j0rzRdxmJImYPO*2B;>egrWd3t|(5@TVY};aI?jg5wOl77B2<0()#UNCTTkefwp=eYIK-NIz9J&&V9_uy5*xm z)KDx>E|E44fn6!*7}b&LfDIy`jM7aSY(64x4LES?+5>9_eR@2<2-Zefwf@GX3SPf2 z8NA}o;KW)kx_lTH?O+Hngl`BiISd2Se|Wu3)9w06JPbjly~6xP28kd@^J2^i0>a=B z%5|PWV%xEKSr@d~im28=`j?QHNKqPJVfC~#vz}Z4h^jyS~1r01)ToU3es5Q&VsLLbH`dk3K&jia}M~kTq7!Jw+ zNb8pX3JTCyxCJc4ObhI|$P7UMt1t{ey&Ay6y!?e)0?z=zT-HzH!R(ubZVghpVgZ`F z5CJ4l7jVenw2eDpd%w4`kzPYRe{0OK*LUmuXKkO)RyK=~ms-Fy=mOwMg@x{=K1W)? z_ic=$*meF0RCOli^Q?7cTvv6&SX**ccLhK%0KdwgLIDB40U$>J@;3mnfE+Cd;GqQ# z!dQd6vvMz>%07*qoM6N<$f;^V0%>V!Z delta 705 zcmV;y0zUo22+#(QBn5j=OjJdYFMEI2P@CHT0004WQchC$Z5%piJ6Qk!Q|B-uO?x3-k1s;z;Uolx1`^4XFpgoyaTqR@p__Ct228vz zU}DZWF|ZStM!z68LBziWd_#~DO-dcF(0hn4f<*J{Gxh?}2<4#lc0UyefINR?no5~+ zQLV=%phvJrrQ}>4a%u6L3)+Im4koqrdj&cu#R@z0hf@LNkhp&ATx$_!XkmvyRLnE6 z-0qLZ{q_mYb5!Y6Av<;;SfF*=S!Dqz&GD0tGavw2@U?kX$+cR;@$~&j64vLkZOe0o z_6GII<@A-c;&HM~$x&H~*;93HfQi!Ck_C>a_B%U&+`(G&r$4dR; zx&Xa{Qp?Owg16i4?frg#UkQL+0RyfCH|Or05&-l%A#e@_#}OE?21gO57nfB6&XhF` zAUHL&>GzGG)-?Et?J=`2c-xSILYA$7J&3vWKMEd{_((zEf}Y^uj#+=egB!R(n%>XN zxhN=7%rtl-GQ!~v0!l0!+Csp_BSHLweF4^j=f}r$S%gCZQcQqJx5xAI^SLZC1eAza zjs<0(RfPIAP6^`R`5AMI(R~k>Bapf+90p++=m_gbmg7)>I>-y?DX_;Y0w@H~WkE!M zA_80OsW9QIfquE?L z5uj}ZHitG+;%KpP9GsEe2}0n_Bx@~oGj>kE)~0Hbx7fm9JSmuHZIs5=7}&&VfyL>h zIH#q7Ck5uvB7(&hToc$7!Cn$LiwJ?)R96HU;l(4aBXHUrvvV&S&MaDeqB19hHaREXqSO!oQ7_pk$*QgH-vCndu&^^wY9jF z37&mfl!9(@WK@E3U|UZ^g>+$0TPZ$9AWc{(KSm%+RzyfuKT~2#UTaf8Mj$~;BSTFi zKS?1}VJk*aB{Di1NKz(cc35wJW96%h0RR910d!JMQvg8b*k%9#14~InK~z}7&6nYJ zqA(DJIp!c)6fC7mDNAXHCZ4|k1MZzkup%na{@IHV5;I?BCJ{*#c}ZD9QZAPXv|LgP z6a`C`AmFl01e81ja2~Kd2y##;p!5U)lH@6X*KYy82*KHxKS_L0-u`SFAB=q}^1m!+ z0la|x40tExU`~WtKs7H}Ip&XRJPv(PRgn;>pmVieuU6|n>(o{0#BC~+YMMq~2u+Pr z%37tO)N2KEVx$+E4Ixf(#IeY7Rz?*xK{0><0CY|^n^?RQuVwjKyoq?TNeH?o#c_ZK zsQ@6|?pWIt0D;C$;*NO_(wH&^K()hX%Sj|^BIqX}W&whOPQ~{9Ww(2I--1OA!mVgA z@4^47`h!(BUQYo2LIBjPIY9gQ+1iC&i~veq1@vAcz$XNI8wAk0r*i_BcyJ?xs{jgN z?7@fEG>MZCy05S9{B%POvoO{kBWoI7>pdMe08KLx*n6rSSl0pVg$6+F$3F-3h5&Ri zvw%ZyZGWgwI96{A07ozw(BI2JeX#cMW6BOZ2B@t)&mY;>96pC|o&&4!lvMPH^dWe6 z5yHhJ_#`?&kAnfq$+|+S8y-xi@f=_mkOwJz>DHRHuB7X=^*@M=t%s1<1{VrJ`^sH_ zrGE$M|0R@KTnpjukJ{S7dAcJjPWWjWUCkADo(OVOc=DuIe>_@!JW@1Pk3$Lr=mvo1 zsI?)0(a!+1bpUOj0U!izT?ha?7y=n-mxEzu@yj?t0svSMrfHCa#%LD&L1Q#}nHydp z+z4_4s2gqTOF+Nh_b}m3a;RMaxDY4@;}GN?Qqs`UHBwPcDszO4ibBLDO6>_iCD#lq z5I|0op|xb{YCYNap#TT~W33?o*IbN`0elEk!1){EEx=pb<`e>z4+C2C#F%9)h@g&HV%&AK*6;<2ZJs?^S7?#(K5bh`lz?(IU+@V9pN0~_!r~b15sQAvi zMP8D5QJ~0hQw^{B0RUO$UDpvHD`Z&|QUVbU;Ovpe0|^ggL1BagDv8na{2RU_@~VI& z-TdU>{xs5dr08<8D#-zfhAeZNl%R!#jSC2Th1dZ~0Pk~x0d8kR_H1`*i9&R5w-sXl Y4?JegOLfWt2LJ#707*qoM6N<$f(l`|bpQYW literal 0 HcmV?d00001 diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_fletcher.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_fletcher.png new file mode 100644 index 0000000000000000000000000000000000000000..d9875ec10c0313c2ddad9fbeb49c468d00d923e1 GIT binary patch literal 950 zcmV;n14;aeP)&S&MaDeqB19hHaREXqSO!oQ7_pk$*QgH-vCndu&^^wY9jF z37&mfl!9(@WK@E3U|UZ^g>+$0TPZ$9AWc{(KSm%+RzyfuKT~2#UTaf8Mj$~;BSTFi zKS?1}VJk*aB{Di1NKz(cc35wJV`_R{IYl#$7%FK10004WQchCq-FSrYxPDn3a? z>GcHQHwXX)X$o*WosM5s_0<7LISNo-9l!}xfo1`;R=7_C?pPQF3@vIG?u^H=^&fQo`MI`tih%=K(7y8!@TaFS3lAUaA%F_rOrz_$(}QmW)j9d!yy2+2 zwz{s-jn!RC^8mU8Kv`>T5McB(0Bs#W+h+h^L0e}501GW(kajf)GYd~f1DOGU6=BK} zYET+Yf_&g&)LA2{s{x=WwJipK^EnL0v+IojoCT~w*8)UfjKQUAROr+==5N7S!wOn?X-%J2G7e-jq_J8;3y9W@$suuuCaAEuL^8lQ?!Q5KoTU>|* zZ~D^zTOfI!`(_RRk@4~Ou$bK1yIVz%6_NP?Kg>nuQstRt5x^o58)cC8HN4=Pn}9 YUxwY_%9BYYT>t<807*qoM6N<$g02CKNB{r; literal 0 HcmV?d00001 diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_leatherworker.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_leatherworker.png new file mode 100644 index 0000000000000000000000000000000000000000..ea491713ebb1f1754e013573df0fa5f7fad2e98b GIT binary patch literal 933 zcmV;W16urvP)&S&MaDeqB19hHaREXqSO!oQ7_pk$*QgH-vCndu&^^wY9jF z37&mfl!9(@WK@E3U|UZ^g>+$0TPZ$9AWc{(KSm%+RzyfuKT~2#UTaf8Mj$~;BSTFi zKS?1}VJk*aB{Di1NKz(cc35wJV`_R{IYl#$7%FK10004WQchCu2qsT1f)*jer_%3>wW^I9K*$mU!(#Xa0|o%7yy9I@oL4{dh=A4Pn+M2uU0Waa}?(R z7NiUS=~j}qDF7JUT*dYXhykY++sZ!@K3fVRQe%c&f`ug#^xrqGn&PV zpQ`GGRPCG|0Q?03pd#G^><@?i>+$&711L2L&`v$T0dxcf0qR;~xexfng;BuJg%_t` z5C<;cz;3Zq`c>%b1T)t-eO;gM_yn-qc>-CFtutvHu)mQ9RBrw*KsN}$s<{g|Yh(1e zYH=jpGyu2&g8+Ie2G!Y^^T$v!U>=|{rW-#TUy=Ld!ek7bx!^)Ix(XJc;g|&6STI<| z7I1xgyLJnFX>-jOd&YV!|Glp7@7HdjF;JlkwQEcQ{@rNIg~?4l1W>@+Wwb4Ons_1z zp+LR231bGmpo37hE2-OCDE!_80_Y@q0BWdj1c=!HWrOq)19$y(fK3q_f1zB)kc~=@ z07_L30H>4Ig#>~qq-_yF=@CF#iUHsRQnJ7~WudU8b#nnVI_NjZ0)PtwxC4*^0cbSZ zh61~-3ou;iP=Ixr#GRNNf7I0Jf72enh!;Z;ZF#t)C_1u)Ec_Z z5M8H~W!mRDS{wH0na%)V4gy&yV+}tW#7Lc$V8y0nZIa+iCl=KL&KX3%#IFMDDje#&QCIYMUvDP>pDP@{sMG;-`$7d{s};T zu-*VYYC!!TKo@|z1<9&ItN_8753Z0aAnE-icB$}b0*o+YBy2vNFlf}O0Ca_f5#b1g z%{4{>`ax)=0e=J)P;J2GSH@aRgfX=t0Pu_eMF9P421Kw{l|n$6UC?*MK~@06O+-M7 zP*MB@&<7c?pIXoyVoV_dv^oNC6I4Nebn>;ejMF?%`7lvfL8;~+X?i@Se4GY+7ut)= zR$=7Jhk&is)-oRK2)tkCySBB}Ti~1oXAA&H98d$E*`wF126zPc;J*qm4y1Pw3D*EF z^>7M6(^3Wws0r37fbkwP@X<@P+@6~#_hnh6we!3z>0v70;NdX?Pc7gL)pC1(nsw!u z5g=!=TH6F{bA}Ayr`R%9VHk#i=-jD$FPlLY7@7S4*Y!?HX`w^4RfI$_==m(kPCku* zF-SOKZ!lhOhNVf4XnlhUKo#2n<2F1`*ur4rH35$?f&eNfKwf}eFun%n|zDYO<~mEnp zbrGxukXFlO@a99EC`6XD1(-@=CQ{v}!#mWB5TV%zvuy8p8^w6Dk^XKKPc*UMXQ39I QR{#J207*qoM6N<$f{`(=`~Uy| delta 738 zcmV<80v-Lz2!IEWBn664OjJdYGKznylo;m#0004WQchC$Z5%piJ6Qk!Q|B-uO?x3-k1s;z;Uolx1`^4XFpgoyaTqR@p__Ct228vz zU}DZWF|ZStM!z68LBziWd_#~DO-h}w&~b>bf<*J{Gxh?}2<4#lc0UyefINR?no5~+ zQLV=%phvJrrQ}>4a%u6L3)+Im4koqrdj&cu#R@z0hf@LNkhp&ATx$_!XkmvyRLnE6 z-0qLZ{q_mYb5!Y6Av<;;SfF*=S!Dqz&GD0tGavw2@U?kX$+cR;@$~&j64vLkZOe0o z_6GEvrB zx-LK@kp(FRgD8a{-KjyudkXUtuagCd?+Bc@K}7m|tBtR3Z?ENtjNM>ObB)*c_t)av zF8EkMnW77)m?{O#bfb;UZ9a=B=(=W&^nEKmAR?_8%@U0bV~Gc7x*?e9 zy#`WZ0>ENehrtFcI|4*ln+ifOO(w9BK$8goFxLtQPz#-g!3I@N2vCc!6sWp@hk>UF zTChprDG*8lY6Xs`02dHw5ujG!C(kJ?p#Zj};33h4tiv_|0ZURBG((_TK^*2O=otW9 zEdY5Vh9M5#d;@|SF39zZal@ae&S&MaDeqB19hHaREXqSO!oQ7_pk$*QgH-vCndu&^^wY9jF z37&mfl!9(@WK@E3U|UZ^g>+$0TPZ$9AWc{(KSm%+RzyfuKT~2#UTaf8Mj$~;BSTFi zKS?1}VJk*aB{Di1NKz(cc35wJV`_R{IYl!IeIAkk0004WQchCFI2AN&!G%@DSPJkppUW>~#KhhM$v3B2puQSAzH*B$$7Cc{-n;UQWO=2gsgi z5(WRO%2%VZa(V#p8w7yTXbtej*jwE+^#s8AB0xAz01VWCyZ}-Ptm}YpLRbXMLwI$X zCvg@68jh=7vfqWN-eF~l%S-u=Jb7mxJ=6)aA?6IIs;+DmBg@+LtDL6T;mbICmk0a&Z?dKtQ<*xba}N zjRWBN@o^nj_@zB-O4$~lOXt7W_4D&OuEqu)7=m=2y8wNor4a63>N&t9eAq_Yv(241 zf}S)+O3h}8u2Zt>Fd8MNA+bsG9Y9t9s5&WI1hn!IfK(PB)gu51K`I*p05*nzM$+b> z-&wdB1B9(65l=*0RgiJ*32CSgg{*g z0dp`7!I{*xQcc~TrW)VTwf6c34JIQ1tBu$e07F0@fhDjl9xw~|%7ICyC%|T`2Uy5> zYt{f}?f`JxXypmu@HahU$77y91n4^6%0IswNN<}9;*Th4k!>; z+&76}!B}2EAhBjPkp*re+mHk9l32vJ|11V;?}JpE|BUQO1hb;Zt>n^G)>KxZh%fe-6OzQYe6UixIYNFoe}8ooHM2d&~>W-Hw@1H3Sg)P ze{8tmsK0q3h;vQGxvC(3r*Q$;O5?sD${r_h!xjOS(r5XKAf`{TGut8{4?X^5{6yEA zOBF6S3Li}a&LcO;1;_WB{h77jvQ0^Ck5}6Y`N5LZz%8gf91eY71mNNBcx=T<>GN5u zLA1wXN6-VQZ7W953jq4dm38R>5V(2lf8wh=g1*Jf>j4$TlAVz!t)y!-GFpI`B z<`E_ntaR@H!XbyQjx##Eg_xr+)xxdh;K zzudYv0cp@K1gb=HD;7|70K-lXAq;t)--^gOK#W)hM96(=N&tTL2Ke4?eav42tjFMC z9{kxL&RsCEJa)En9;BHW0X$#LY7MXnaNg771R#qR&X2+S;lAK_B5S?pKNA4Z9}2YS z^Z{U~1ZeLyddLtY`cMl1>AkE3XzjnWmfDBlVe}Wbz93y!9r`Q)mij-6;-B4bxR|eh RixU6<002ovPDHLkV1o4lXmbDn delta 633 zcmV-<0*3vW2Y?2UBn5I%OjJdYFLHm-E6$q$0004WQchC$Z5%piJ6Qk!Q|B-uO?x3-k1s;z;Uolx1`^4XFpgoyaTqR@p__Ct228vz zU}DZWF|ZStM!z68LBziWd_#~DO-h}w&~b>bf<*J{Gxh?}2<4#lc0UyefINR?no5~+ zQLV=%phvJrrQ}>4a%u6L3)+Im4koqrdj&cu#R@z0hf@LNkhp&ATx$_!XkmvyRLnE6 z-0qLZ{q_mYb5!Y6Av<;;SfF*=S!Dqz&GD0tGavw2@U?kX$+cR;@$~&j64vLkZOe0o z_6G7zm;C^QcJ09um;g>xwQBE)GG-t4h;jZ^!l@GC zjpKq)`6T!{pT92G>t#d$hzG&hxjI7v5+HxG;JL!-MilQVl*Riui23Bq;gN*|QG!c( zUI=2W2JLHFE8Bt}9ZeACIrIV~f;G}d!3s01O(0y5KxB7R0bU5iYF2;t+vJQ3gqhA} z@Bmfe!yO2iA#^Nv0{Aod4|)OL3qS{+W;#6^Q_rRV62J`9@Luqi^ZEpntr0#%3B_)q>0m&4j zF~-CSat1j`)&!3{2|{V4g(tzXz-jxM#6|^LUjd8b1LoPIP1#A929Ur5W}Zz@7!#;M z*)#LdBm+hTYM#uJmK!?-s&H5URlsopN(JCQs<7`f3Nv(kCqZ%~(9b`6iGQD8D3r2s Tj6^Dx00000NkvXXu0mjfvUVDl diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_sheperd.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_sheperd.png new file mode 100644 index 0000000000000000000000000000000000000000..db322696972145cff4f32bd59fc74d28476c0bb7 GIT binary patch literal 983 zcmV;|11S87P)&S&MaDeqB19hHaREXqSO!oQ7_pk$*QgH-vCndu&^^wY9jF z37&mfl!9(@WK@E3U|UZ^g>+$0TPZ$9AWc{(KSm%+RzyfuKT~2#UTaf8Mj$~;BSTFi zKS?1}VJk*aB{Di1NKz(cc35wJV`_R{IYl#$7%FK10004WQchC>xLKY)KCFX5*!- zviMPPoS@=(vyr6DYFR6ll-9p}oieU=WT^mXZP(VsPO>2f9h-@30n$C+S9eLas$BC6Bmp)Gf#y?g7w|pUyfeJW zDa(~@M;d?%MC+e#YpI=^{ z^PeKx?Gl1+Nl~;2z{vyx(qhjlQUnMb+$HW>UO^h+&Px&SYmc7-d4d2U5%fxkMS$R- zQ&AkA_WP$pfh-yjZbyq`^IcWGvdYTq0l;q*0!r2r;O%&Pdq17tdjO?I0otnvIHFFd zRRCi&wPnCW2%~^u2(MnlBo0C#$8K{|hAQ-R#+eOGZ_Jsl2|!f^0UH~qwD=*+aKnc*zANiLYK8G-y1HW7h zp&YG(18BTv0XHicl(7L^KR&MAhJSQ>4Zz*0AKU*y*U!&ux3Ld)6oT=_Ea1%K%dV#4`mG2 z2*8CvIp~Lg9?l2A`F9Ab{s(;>K#Ohx!MX=PY60H*w*Wky0ksYwV?dTS7JsJvtv|{_ z2asg|*fkbw%HN+Br6mGSng@Wh=tw&aP&OP!`6yl#MI6W5Z5(yG!0M=VEZBT0Q38xO`>E##x?f@@m2r;002ovPDHLk FV1hM?nRfsH literal 0 HcmV?d00001 diff --git a/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_smith.png b/mods/ENTITIES/mobs_mc/textures/mobs_mc_villager_smith.png index 53a0e3888bbd84d504faa36b6eb3b8e6411a5d0d..8afdc6b29f4025f4ccbbbee2817d339e46051dfc 100644 GIT binary patch delta 796 zcmV+%1LOSS2CWB>BnyO4OjJe8sM7!dpphwle_!XXrvLx|0d!JMQvg8b*k%9#0@q1I zK~z}7)s^d#qA(DJsS1$+oYk3G+zA04qrqK$|M%OzB*;w-?vJTGh^bKNFMT=*M3Iw- zrIc|j7K;S5SVYkaDhgKYv`7RfnGcY$Ow%-$6c20ZH;SK>h+xy4I``b?;SE~e} zOO%uW8Ds(gS+OA%82|)4TqS%3)IidTe-)cw8~7DeM5HDHkAw)@NHD(mTyHk(&jMJq zfp|xYB>G>aN)0Mi#l`C2BT$c0YeK0k0I_gYq`b$sr^6PSywRtEoj%d3sASzv2gcL zk0Ytz?J{zYn>%lW-@S%p?bvS9e^}i#=*H^4r7(c508lmXra(Zgp8;sg0B!q#KfUIT z1#Q^^0D2bAy=DqP>&rFpD+?#1g#-X#N7PjXHK=M$f_&g1Z)M{F+%v8j0aT@}8UoDW zV9c2a=QH;VpA9o%0c+5=01*&#cH*8nHK3CT`UZKx1%4L?pmPN$D-6IEe;^)jZ-Gx} zAOJ-Gw7_!jhCl#TjKjeK^`=(gHh`Cr!Y}PI-Z}p_02em#41jCkJhU|!?SlZo<@q9_ z1ztzvUeNr4ot43*yNvT|V9pcqbM}F=ZpyZRW>yWZLA|e3=ss|tr1tAHw}{`L!EJ@a a{{>fd%_;=^e!l0x$io2jT{hBn5s@OjJdYFMfZy@6a*;0004WQchC$Z5%piJ6Qk!Q|B-uO?x3-k1s;z;Uolx1`^4XFpgoyaTqR@p__Ct228vz zU}DZWF|ZStM!z68LBziWd_#~DO-h}w&~b>bf<*J{Gxh?}2<4#lc0UyefINR?no5~+ zQLV=%phvJrrQ}>4a%u6L3)+Im4koqrdj&cu#R@z0hf@LNkhp&ATx$_!XkmvyRLnE6 z-0qLZ{q_mYb5!Y6Av<;;SfF*=S!Dqz&GD0tGavw2@U?kX$+cR;@$~&j64vLkZOe0o z_6G!LQ9IOzB;fEj&+(}Ap;u`;HT+gmhLcli z>=&RqNF@cI1jp0q_;Wu0%ml!yfQ^~pAm^Kt*=kM`W~ySGPlO`O&VVnZ2F;jOZ$Se3dKW=&uz8IVtVSRl5-^MEaN@8A z7f3)eLd|=yv2r5H-72sjJ`^eJ-^sADS&K`OBHD&XZp z-otRetMmETD-mF?5qNQ2Ak^_TI5!@8m;?`h9!-#MLGBYMg3pgzoeY_s0!IReA_si} zomfn}MV$=n6l8}n?n|B6C5UO~8$oav4+?z;dj*eg4^a_xkI_Ip|H1Bh1KlHM^a^BH z&i6-PBQvYj?iV<1DA;+3(}^+j^;hcGyumg-^Zx+tExj`MysnY}0000&S&MaDeqB19hHaREXqSO!oQ7_pk$*QgH-vCndu&^^wY9jF z37&mfl!9(@WK@E3U|UZ^g>+#+M?EzZGsg!ZDRq7 z*8^lElO%~G*#lwc6%I%|AdX)K$bSGtm_*3p%OT8@xKe^W7#w4$VTy*S$ejGx_fG+^ zRN(S#zt6ILlBG1{2VVgIYH5}w2{KYQL6aiD1HYm3V4rsT2Le(j2!GEWjP<;LQiE!1kidBV4OyPZ_pJK1kl>x^Biy|ghjwS1n=lPiL(&UaQN_+1+OZ`y1~vG zx7YfH?GB(UJ%PN(QA1h=)Dw9?;r1T_Ooae^RZjtpvDP$2hht_{0iXp20XPpvk&N&C z;>OyhHzfy_0ZRRXlySZ4Y^)vT5A6#IpF$Yqz)aM+3n3JXr@#OM?O_NL4`#>M0j41s zyoOk7)^d;UrTU*%Rxbu%2-*!E0*ZSYgz)fE&n+q8-7)fry9ZwcYy0(OZcE(Mg|G@h8G!9`1Xv!c1Lzb8P?WtKM7dN5IGjLr5Ww~aV0)e5 z``k3)fRmkw0|^Dxe2A&S&MaDeqB19hHaREXqSO!oQ7_pk$*QgH-vCndu&^^wY9jF z37&mfl!9(@WK@E3U|UZ^g>+#+M?EzcyLU_@vqEsU8WAU&N~rxXDpUOdG5aPMtr0>BywUa`|TKjY`bMI>q* z(v}z&v4w?3!uwBOZ|C#d*9lqNK)R#DIQU;x$Py)si_v;Oc}11QrC>b+RNvp#?dRt< z0F>n{Kp71H->4sy7oaQ^eV+psQkVryQ?P+fi#SPv4BfAGS?Ifpp=$J8lKZl(=~w_< zE|$R2)2w051FDfMpfLVjfVvWZPS>Y^Mggd%=x~~Oy&|AR1_N{*lw>J8+M64IrZ?pP z<^fXvMM-5w+1UWN^&|U&)8`bN8mN)Fa505qb`>;0;qfqqQ3R7^>;U5w6m3K5H2^)* zd9MG*oz+VND238Y9s-IbIVn8c)Kg0?c(;striTYl1c3fLxHQn6-$?j&FnS%p1H2A^ z-vcgisq1wBPTH-3`MnANHg*@lEvziS&S)4Cv`t+@JqD<{Rtk*ljP}M1psp$T5uio^ zRAgR}3nbXTAztqw1IWoF?*O#1d;zL+Nlr})s{mX9bf5E|Cq0*Y)X@_lxq3N@Ybgn^ zKcXrx0Q3t0y^i>NZkly~fpj8Xfa-X>xu!VB)l_Zk4FI_HKDievw8x6H-Vs#O2y{g} zS79!HrE*w!h%N&tZU>;&0b1(it`TrYZk1dC;G*SRI0KMd@C8WI$PR$sQuIt%T}0KV pzz-JB2;^`PocE;nZd{U&{XZ>w+e8BO#c2Ql002ovPDHLkV1l^hmk Date: Fri, 20 May 2022 03:06:07 +0200 Subject: [PATCH 22/35] fix possible crash --- mods/ENTITIES/mobs_mc/villager.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 5b71dd3a9..e6bf9c356 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -1118,8 +1118,8 @@ local trade_inventory = { -- First-time trade unlock all trades and unlock next trade tier if trade.tier + 1 > trader._max_trade_tier then trader._max_trade_tier = trader._max_trade_tier + 1 - if trader._max_trade_tier > #professions[trader._profession].trades then - trader._max_trade_tier = #professions[trader._profession].trades + if trader._max_trade_tier > 5 then + trader._max_trade_tier = 5 end set_textures(trader) update_max_tradenum(trader) From e51ea1e07935233a064354d1d7351585f5f9ea2f Mon Sep 17 00:00:00 2001 From: cora Date: Fri, 20 May 2022 18:50:18 +0200 Subject: [PATCH 23/35] initialize inventory nodes on mapgen --- mods/MAPGEN/mcl_villages/buildings.lua | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mods/MAPGEN/mcl_villages/buildings.lua b/mods/MAPGEN/mcl_villages/buildings.lua index c014bb07a..2b78155c4 100644 --- a/mods/MAPGEN/mcl_villages/buildings.lua +++ b/mods/MAPGEN/mcl_villages/buildings.lua @@ -193,6 +193,10 @@ local function init_nodes(p1, p2, size, rotation, pr) construct_node(p1, p2, "mcl_furnaces:furnace") construct_node(p1, p2, "mcl_anvils:anvil") + construct_node(p1, p2, "mcl_smoker:smoker") + construct_node(p1, p2, "mcl_barrels:barrel_closed") + construct_node(p1, p2, "mcl_blast_furnace:blast_furnace") + construct_node(p1, p2, "mcl_brewing:stand_000") local nodes = construct_node(p1, p2, "mcl_chests:chest") if nodes and #nodes > 0 then for p=1, #nodes do From a74fcab06bee43b152e67350e05fe413da8db756 Mon Sep 17 00:00:00 2001 From: cora Date: Fri, 20 May 2022 23:43:19 +0200 Subject: [PATCH 24/35] Make iron golem stay near set _home position --- mods/ENTITIES/mobs_mc/iron_golem.lua | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/mods/ENTITIES/mobs_mc/iron_golem.lua b/mods/ENTITIES/mobs_mc/iron_golem.lua index 0d3e74645..8b3278e51 100644 --- a/mods/ENTITIES/mobs_mc/iron_golem.lua +++ b/mods/ENTITIES/mobs_mc/iron_golem.lua @@ -9,7 +9,7 @@ local S = minetest.get_translator("mobs_mc") --################### IRON GOLEM --################### - +local etime = 0 mobs:register_mob("mobs_mc:iron_golem", { description = S("Iron Golem"), @@ -41,6 +41,7 @@ mobs:register_mob("mobs_mc:iron_golem", { group_attack = true, attacks_monsters = true, attack_type = "dogfight", + pick_up = {"mcl_flowers:poppy"}, drops = { {name = mobs_mc.items.iron_ingot, chance = 1, @@ -60,6 +61,14 @@ mobs:register_mob("mobs_mc:iron_golem", { punch_start = 40, punch_end = 50, }, jump = true, + on_step = function(self,dtime) + etime = etime + dtime + if etime > 10 then + if self._home and vector.distance(self._home,self.object:get_pos()) > 50 then + mobs:gopath(self,self._home) + end + end + end, }) From 27d0d778e28e04e50b5a1d9f72f8faba23ca755e Mon Sep 17 00:00:00 2001 From: cora Date: Fri, 20 May 2022 23:44:33 +0200 Subject: [PATCH 25/35] Update TODO list --- mods/ENTITIES/mobs_mc/villager.lua | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index e6bf9c356..596ba430f 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -10,14 +10,10 @@ -- TODO: Particles -- TODO: 4s Regeneration I after trade unlock --- TODO: Breeding --- TODO: Baby villagers --- TODO: Spawning in villages -- TODO: Behaviour: --- TODO: Walk around village, but do not leave it intentionally --- TODO: Run into house on rain or danger, open doors --- TODO: Internal inventory, pick up items, trade with other villagers --- TODO: Farm stuff +-- TODO: Run into house on rain or danger, open doors +-- TODO: Internal inventory, trade with other villagers +-- TODO: Schedule stuff (work,sleep,father) local S = minetest.get_translator("mobs_mc") local N = function(s) return s end From 2b63866c1433944fa0d72bb5730b0de5a3750f36 Mon Sep 17 00:00:00 2001 From: cora Date: Fri, 20 May 2022 23:44:58 +0200 Subject: [PATCH 26/35] spawn villagers (and golem) immediately after mg --- mods/MAPGEN/mcl_villages/buildings.lua | 37 +++++++++++++++++++++++++- mods/MAPGEN/mcl_villages/init.lua | 21 --------------- 2 files changed, 36 insertions(+), 22 deletions(-) diff --git a/mods/MAPGEN/mcl_villages/buildings.lua b/mods/MAPGEN/mcl_villages/buildings.lua index 2b78155c4..928d37b37 100644 --- a/mods/MAPGEN/mcl_villages/buildings.lua +++ b/mods/MAPGEN/mcl_villages/buildings.lua @@ -188,6 +188,32 @@ local function construct_node(p1, p2, name) end minetest.log("warning", "[mcl_villages] Attempt to 'construct' inexistant nodes: " .. name) end + +local function spawn_iron_golem(pos) + local p = minetest.find_node_near(pos,50,"mcl_core:grass_path") + if p then + local l=minetest.add_entity(p,"mobs_mc:iron_golem"):get_luaentity() + if l then + l._home = p + end + end +end + +local function spawn_villagers(minp,maxp) + local beds=minetest.find_nodes_in_area(minp,maxp,{"mcl_beds:bed_red_bottom"}) + for _,bed in pairs(beds) do + local m = minetest.get_meta(bed) + if m:get_string("villager") == "" then + local v=minetest.add_entity(bed,"mobs_mc:villager") + if v then + local l=v:get_luaentity() + l._bed = bed + m:set_string("villager",l._id) + end + end + end +end + local function init_nodes(p1, p2, size, rotation, pr) construct_node(p1, p2, "mcl_itemframes:item_frame") construct_node(p1, p2, "mcl_furnaces:furnace") @@ -205,9 +231,12 @@ local function init_nodes(p1, p2, size, rotation, pr) end end end + function settlements.place_schematics(settlement_info, pr) local building_all_info for i, built_house in ipairs(settlement_info) do + local is_last = i == #settlement_info + for j, schem in ipairs(settlements.schematic_table) do if settlement_info[i]["name"] == schem["name"] then building_all_info = schem @@ -275,7 +304,13 @@ function settlements.place_schematics(settlement_info, pr) nil, true, nil, - init_nodes, + function(p1, p2, size, rotation, pr) + init_nodes(p1, p2, size, rotation, pr) + spawn_villagers(p1,p2) + if is_last then + spawn_iron_golem(p1) + end + end, pr ) end diff --git a/mods/MAPGEN/mcl_villages/init.lua b/mods/MAPGEN/mcl_villages/init.lua index 4bea6ab3c..6dd7d26eb 100644 --- a/mods/MAPGEN/mcl_villages/init.lua +++ b/mods/MAPGEN/mcl_villages/init.lua @@ -21,7 +21,6 @@ minetest.register_node("mcl_villages:stonebrickcarved", { description = ("Chiseled Stone Village Bricks"), _doc_items_longdesc = doc.sub.items.temp.build, tiles = {"mcl_core_stonebrick_carved.png"}, - stack_max = 64, drop = "mcl_core:stonebrickcarved", groups = {pickaxey=1, stone=1, stonebrick=1, building_block=1, material_stone=1}, sounds = mcl_sounds.node_sound_stone_defaults(), @@ -50,26 +49,6 @@ if minetest.get_modpath("mobs_mc") then end --]] -local function spawn_villagers(minp,maxp) - local beds=minetest.find_nodes_in_area(minp,maxp,{"mcl_beds:bed_red_bottom"}) - for _,bed in pairs(beds) do - local m = minetest.get_meta(bed) - if m:get_string("villager") == "" then - local v=minetest.add_entity(bed,"mobs_mc:villager") - if v then - local l=v:get_luaentity() - l._bed = bed - m:set_string("villager",l._id) - end - end - - end - local p = minetest.find_node_near(minp,50,"mcl_core:grass_path") - if p then - minetest.add_entity(p,"mobs_mc:iron_golem") - end -end - -- -- on map generation, try to build a settlement -- From 5dafeaadc63c893e7f63c607f9188464cd2d9998 Mon Sep 17 00:00:00 2001 From: cora Date: Sat, 21 May 2022 00:14:42 +0200 Subject: [PATCH 27/35] Fix indentation in mcl_mobs/api.txt --- mods/ENTITIES/mcl_mobs/api.txt | 876 +++++++++++++++++---------------- 1 file changed, 439 insertions(+), 437 deletions(-) diff --git a/mods/ENTITIES/mcl_mobs/api.txt b/mods/ENTITIES/mcl_mobs/api.txt index 1ae6ee53f..b9b6613b6 100644 --- a/mods/ENTITIES/mcl_mobs/api.txt +++ b/mods/ENTITIES/mcl_mobs/api.txt @@ -12,253 +12,255 @@ Registering Mobs To register a mob and have it ready for use requires the following function: - mobs:register_mob(name, definition) + mobs:register_mob(name, definition) The 'name' of a mob usually starts with the mod name it's running from followed by it's own name e.g. - "mobs_monster:sand_monster" or "mymod:totally_awesome_beast" + "mobs_monster:sand_monster" or "mymod:totally_awesome_beast" ... and the 'definition' is a table which holds all of the settings and functions needed for the mob to work properly which contains the following: - 'nametag' contains the name which is shown above mob. - 'type' holds the type of mob that inhabits your world e.g. - "animal" usually docile and walking around. - "monster" attacks player or npc on sight. - "npc" walk around and will defend themselves if hit first, they - kill monsters. - 'hp_min' the minimum health value the mob can spawn with. - 'hp_max' the maximum health value the mob can spawn with. - 'breath_max' The maximum breath value the mob can spawn with and can have. - If -1 (default), mob does not take drowning damage. - 'breathes_in_water' If true, mob loses breath when not in water. Otherwise, - mob loses breath when inside a node with `drowning` attribute - set (default: false). - 'armor' entity armor groups (see lua_api.txt). If table, a list of - armor groups like for entities. If number, set value of - 'fleshy' armor group only. - Note: The 'immortal=1' armor group will automatically be added - since this mod handles health and damage manually. - Default: 100 (mob will take full dmg from 'fleshy' hits) - 'passive' when true allows animals to defend themselves when hit, - otherwise they amble onwards. - 'walk_velocity' is the speed that your mob can walk around. - 'run_velocity' is the speed your mob can run with, usually when attacking. - 'walk_chance' has a 0-100 chance value your mob will walk from standing, - set to 0 for jumping mobs only. - 'jump' when true allows your mob to jump updwards. - 'jump_height' holds the height your mob can jump, 0 to disable jumping. - 'stepheight' height of a block that your mob can easily walk up onto, - defaults to 0.6. - 'fly' when true allows your mob to fly around instead of walking. - 'fly_in' holds the node name or a table of node names in which the - mob flies (or swims) around in. The special name - '__airlike' stands for all nodes with 'walkable=false' - that are not liquids - 'runaway' if true causes animals to turn and run away when hit. - 'view_range' how many nodes in distance the mob can see a player. - 'damage' how many health points the mob does to a player or another - mob when melee attacking. - 'knock_back' when true has mobs falling backwards when hit, the greater - the damage the more they move back. - 'fear_height' is how high a cliff or edge has to be before the mob stops - walking, 0 to turn off height fear. - 'fall_speed' has the maximum speed the mob can fall at, default is -10. - 'fall_damage' when true causes falling to inflict damage. - 'water_damage' holds the damage per second infliced to mobs when standing in - water (default: 0). - 'lava_damage' holds the damage per second inflicted to mobs when standing - in lava (default: 8). - 'fire_damage' holds the damage per second inflicted to mobs when standing - in fire (default: 1). - 'light_damage' holds the damage per second inflicted to mobs when it's too - bright (above 13 light). - 'suffocation' when true causes mobs to suffocate inside solid blocks (2 damage per second). - 'floats' when set to 1 mob will float in water, 0 has them sink. - 'follow' mobs follow player when holding any of the items which appear - on this table, the same items can be fed to a mob to tame or - breed e.g. {"farming:wheat", "default:apple"} + 'nametag' contains the name which is shown above mob. + 'type' holds the type of mob that inhabits your world e.g. + "animal" usually docile and walking around. + "monster" attacks player or npc on sight. + "npc" walk around and will defend themselves if hit first, they + kill monsters. + 'hp_min' the minimum health value the mob can spawn with. + 'hp_max' the maximum health value the mob can spawn with. + 'breath_max' The maximum breath value the mob can spawn with and can have. + If -1 (default), mob does not take drowning damage. + 'breathes_in_water' If true, mob loses breath when not in water. Otherwise, + mob loses breath when inside a node with `drowning` attribute + set (default: false). + 'armor' entity armor groups (see lua_api.txt). If table, a list of + armor groups like for entities. If number, set value of + 'fleshy' armor group only. + Note: The 'immortal=1' armor group will automatically be added + since this mod handles health and damage manually. + Default: 100 (mob will take full dmg from 'fleshy' hits) + 'passive' when true allows animals to defend themselves when hit, + otherwise they amble onwards. + 'walk_velocity' is the speed that your mob can walk around. + 'run_velocity'is the speed your mob can run with, usually when attacking. + 'walk_chance' has a 0-100 chance value your mob will walk from standing, + set to 0 for jumping mobs only. + 'jump' when true allows your mob to jump updwards. + 'jump_height' holds the height your mob can jump, 0 to disable jumping. + 'stepheight' height of a block that your mob can easily walk up onto, + defaults to 0.6. + 'fly' when true allows your mob to fly around instead of walking. + 'fly_in' holds the node name or a table of node names in which the + mob flies (or swims) around in. The special name + '__airlike' stands for all nodes with 'walkable=false' + that are not liquids + 'runaway' if true causes animals to turn and run away when hit. + 'view_range' how many nodes in distance the mob can see a player. + 'damage' how many health points the mob does to a player or another + mob when melee attacking. + 'knock_back' when true has mobs falling backwards when hit, the greater + the damage the more they move back. + 'fear_height' is how high a cliff or edge has to be before the mob stops + walking, 0 to turn off height fear. + 'fall_speed' has the maximum speed the mob can fall at, default is -10. + 'fall_damage' when true causes falling to inflict damage. + 'water_damage'holds the damage per second infliced to mobs when standing in + water (default: 0). + 'lava_damage' holds the damage per second inflicted to mobs when standing + in lava (default: 8). + 'fire_damage' holds the damage per second inflicted to mobs when standing + in fire (default: 1). + 'light_damage'holds the damage per second inflicted to mobs when it's too + bright (above 13 light). + 'suffocation' when true causes mobs to suffocate inside solid blocks (2 damage per second). + 'floats' when set to 1 mob will float in water, 0 has them sink. + 'follow' mobs follow player when holding any of the items which appear + on this table, the same items can be fed to a mob to tame or + breed e.g. {"farming:wheat", "default:apple"} - 'reach' is how far the mob can attack player when standing - nearby, default is 3 nodes. - 'docile_by_day' when true has mobs wandering around during daylight - hours and only attacking player at night or when - provoked. - 'attacks_monsters' when true has npc's attacking monsters or not. - 'attack_animals' when true will have monsters attacking animals. - 'owner_loyal' when true will have tamed mobs attack anything player - punches when nearby. - 'group_attack' when true has same mob type grouping together to attack - offender. - [MCL2 extension:] When a table, this is a list of - mob types that will get alerted as well (besides same mob type) - 'attack_type' tells the api what a mob does when attacking the player - or another mob: - 'dogfight' is a melee attack when player is within mob reach. - 'shoot' has mob shoot pre-defined arrows at player when inside - view_range. - 'dogshoot' has melee attack when inside reach and shoot attack - when inside view_range. - 'explode' causes mob to stop and explode when inside reach. - 'explosion_radius' the radius of explosion node destruction, - defaults to 1 - 'explosion_damage_radius' the radius of explosion entity & player damage, - defaults to explosion_radius * 2 - 'explosion_timer' number of seconds before mob explodes while its target - is still inside reach or explosion_damage_radius, - defaults to 3. - 'explosiontimer_reset_radius' The distance you must travel before the timer will be reset. - 'allow_fuse_reset' Allow 'explode' attack_type to reset fuse and resume - chasing if target leaves the blast radius or line of - sight. Defaults to true. - 'stop_to_explode' When set to true (default), mob must stop and wait for - explosion_timer in order to explode. If false, mob will - continue chasing. - 'arrow' holds the pre-defined arrow object to shoot when - attacking. - 'dogshoot_switch' allows switching between attack types by using timers - (1 for shoot, 2 for dogfight) - 'dogshoot_count_max' contains how many seconds before switching from - dogfight to shoot. - 'dogshoot_count2_max' contains how many seconds before switching from shoot - to dogfight. - 'shoot_interval' has the number of seconds between shots. - 'shoot_offset' holds the y position added as to where the - arrow/fireball appears on mob. - 'specific_attack' has a table of entity names that mob can also attack - e.g. {"player", "mobs_animal:chicken"}. - 'runaway_from' contains a table with mob names to run away from, add - "player" to list to runaway from player also. - 'pathfinding' set to 1 for mobs to use pathfinder feature to locate - player, set to 2 so they can build/break also (only - works with dogfight attack and when 'mobs_griefing' - in minetest.conf is not false). - 'immune_to' is a table that holds specific damage when being hit by - certain items e.g. - {"default:sword_wood", 0} -- causes no damage. - {"default:gold_lump", -10} -- heals by 10 health points. - {"default:coal_block", 20} -- 20 damage when hit on head with coal blocks. + 'reach' is how far the mob can attack player when standing + nearby, default is 3 nodes. + 'docile_by_day' when true has mobs wandering around during daylight + hours and only attacking player at night or when + provoked. + 'attacks_monsters' when true has npc's attacking monsters or not. + 'attack_animals' when true will have monsters attacking animals. + 'owner_loyal' when true will have tamed mobs attack anything player + punches when nearby. + 'group_attack' when true has same mob type grouping together to attack + offender. + [MCL2 extension:] When a table, this is a list of + mob types that will get alerted as well (besides same mob type) + 'attack_type' tells the api what a mob does when attacking the player + or another mob: + 'dogfight' is a melee attack when player is within mob reach. + 'shoot' has mob shoot pre-defined arrows at player when inside + view_range. + 'dogshoot' has melee attack when inside reach and shoot attack + when inside view_range. + 'explode' causes mob to stop and explode when inside reach. + 'explosion_radius' the radius of explosion node destruction, + defaults to 1 + 'explosion_damage_radius' the radius of explosion entity & player damage, + defaults to explosion_radius * 2 + 'explosion_timer' number of seconds before mob explodes while its target + is still inside reach or explosion_damage_radius, + defaults to 3. + 'explosiontimer_reset_radius' The distance you must travel before the timer will be reset. + 'allow_fuse_reset' Allow 'explode' attack_type to reset fuse and resume + chasing if target leaves the blast radius or line of + sight. Defaults to true. + 'stop_to_explode' When set to true (default), mob must stop and wait for + explosion_timer in order to explode. If false, mob will + continue chasing. + 'arrow' holds the pre-defined arrow object to shoot when + attacking. + 'dogshoot_switch' allows switching between attack types by using timers + (1 for shoot, 2 for dogfight) + 'dogshoot_count_max'contains how many seconds before switching from + dogfight to shoot. + 'dogshoot_count2_max' contains how many seconds before switching from shoot + to dogfight. + 'shoot_interval' has the number of seconds between shots. + 'shoot_offset' holds the y position added as to where the + arrow/fireball appears on mob. + 'specific_attack' has a table of entity names that mob can also attack + e.g. {"player", "mobs_animal:chicken"}. + 'runaway_from' contains a table with mob names to run away from, add + "player" to list to runaway from player also. + 'pathfinding' set to 1 for mobs to use pathfinder feature to locate + player, set to 2 so they can build/break also (only + works with dogfight attack and when 'mobs_griefing' + in minetest.conf is not false). + 'immune_to' is a table that holds specific damage when being hit by + certain items e.g. + {"default:sword_wood",0} -- causes no damage. + {"default:gold_lump", -10} -- heals by 10 health points. + {"default:coal_block", 20} -- 20 damage when hit on head with coal blocks. - 'makes_footstep_sound' when true you can hear mobs walking. - 'sounds' this is a table with sounds of the mob - 'distance' maximum distance sounds can be heard, default is 10. - 'base_pitch' base pitch to use adult mobs, default is 1.0 (MCL2 extension) - 'random' played randomly from time to time. - also played for overfeeding animal. - 'eat' played when mob eats something - 'war_cry' what you hear when mob starts to attack player. (currently disabled) - 'attack' what you hear when being attacked. - 'shoot_attack' sound played when mob shoots. - 'damage' sound heard when mob is hurt. - 'death' played when mob is killed. - 'jump' played when mob jumps. There's a built-in cooloff timer to avoid sound spam - 'flop' played when mob flops (like a stranded fish) - 'fuse' sound played when mob explode timer starts. - 'explode' sound played when mob explodes. + 'makes_footstep_sound' when true you can hear mobs walking. + 'sounds' this is a table with sounds of the mob + 'distance' maximum distance sounds can be heard, default is 10. + 'base_pitch' base pitch to use adult mobs, default is 1.0 (MCL2 extension) + 'random' played randomly from time to time. + also played for overfeeding animal. + 'eat' played when mob eats something + 'war_cry' what you hear when mob starts to attack player. (currently disabled) + 'attack' what you hear when being attacked. + 'shoot_attack' sound played when mob shoots. + 'damage' sound heard when mob is hurt. + 'death' played when mob is killed. + 'jump' played when mob jumps. There's a built-in cooloff timer to avoid sound spam + 'flop' played when mob flops (like a stranded fish) + 'fuse' sound played when mob explode timer starts. + 'explode' sound played when mob explodes. - Note: For all sounds except fuse and explode, the pitch is slightly randomized from the base pitch - The pitch of children is 50% higher. + Note: For all sounds except fuse and explode, the pitch is slightly randomized from the base pitch + The pitch of children is 50% higher. - 'drops' table of items that are dropped when mob is killed, fields are: - 'name' name of item to drop. - 'chance' chance of drop, 1 for always, 2 for 1-in-2 chance etc. - 'min' minimum number of items dropped. - 'max' maximum number of items dropped. + 'drops' table of items that are dropped when mob is killed, fields are: + 'name' name of item to drop. + 'chance' chance of drop, 1 for always, 2 for 1-in-2 chance etc. + 'min' minimum number of items dropped. + 'max' maximum number of items dropped. - 'visual' holds the look of the mob you wish to create: - 'cube' looks like a normal node - 'sprite' sprite which looks same from all angles. - 'upright_sprite' flat model standing upright. - 'wielditem' how it looks when player holds it in hand. - 'mesh' uses separate object file to define mob. - 'visual_size' has the size of the mob, defaults to {x = 1, y = 1} - 'collisionbox' has the box in which mob can be interacted with the - world e.g. {-0.5, -0.5, -0.5, 0.5, 0.8, 0.5}. - NOTE: Due to a workaround, the upper Y coordinate will be forced - to a minimum value of 0.79. - 'selectionbox' has the box in which player can interact with mob - 'textures' holds a table list of textures to be used for mob, or you - could use multiple lists inside another table for random - selection e.g. { {"texture1.png"}, {"texture2.png"} } - 'child_texture' holds the texture table for when baby mobs are used. - 'gotten_texture' holds the texture table for when self.gotten value is - true, used for milking cows or shearing sheep. - 'mesh' holds the name of the external object used for mob model - e.g. "mobs_cow.b3d" - 'gotten_mesh" holds the name of the external object used for when - self.gotten is true for mobs. - 'rotate' custom model rotation, 0 = front, 90 = side, 180 = back, - 270 = other side. - 'double_melee_attack' when true has the api choose between 'punch' and - 'punch2' animations. + 'visual' holds the look of the mob you wish to create: + 'cube' looks like a normal node + 'sprite' sprite which looks same from all angles. + 'upright_sprite' flat model standing upright. + 'wielditem' how it looks when player holds it in hand. + 'mesh' uses separate object file to define mob. + 'visual_size' has the size of the mob, defaults to {x = 1, y = 1} + 'collisionbox' has the box in which mob can be interacted with the + world e.g. {-0.5, -0.5, -0.5, 0.5, 0.8, 0.5}. + NOTE: Due to a workaround, the upper Y coordinate will be forced + to a minimum value of 0.79. + 'selectionbox' has the box in which player can interact with mob + 'textures' holds a table list of textures to be used for mob, or you + could use multiple lists inside another table for random + selection e.g. { {"texture1.png"}, {"texture2.png"} } + 'child_texture' holds the texture table for when baby mobs are used. + 'gotten_texture' holds the texture table for when self.gotten value is + true, used for milking cows or shearing sheep. + 'mesh' holds the name of the external object used for mob model + e.g. "mobs_cow.b3d" + 'gotten_mesh" holds the name of the external object used for when + self.gotten is true for mobs. + 'rotate' custom model rotation, 0 = front, 90 = side, 180 = back, + 270 = other side. + 'double_melee_attack' when true has the api choose between 'punch' and + 'punch2' animations. - 'animation' holds a table containing animation names and settings for use with mesh models: - 'stand_start' start frame for when mob stands still. - 'stand_end' end frame of stand animation. - 'stand_speed' speed of animation in frames per second. - 'walk_start' when mob is walking around. - 'walk_end' - 'walk_speed' - 'run_start' when a mob runs or attacks. - 'run_end' - 'run_speed' - 'fly_start' when a mob is flying. - 'fly_end' - 'fly_speed' - 'punch_start' when a mob melee attacks. - 'punch_end' - 'punch_speed' - 'punch2_start' alternative melee attack animation. - 'punch2_end' - 'punch2_speed' - 'shoot_start' shooting animation. - 'shoot_end' - 'shoot_speed' - 'die_start' death animation - 'die_end' - 'die_speed' - 'die_loop' when set to false stops the animation looping. + 'animation' holds a table containing animation names and settings for use with mesh models: + { + 'stand_start'start frame for when mob stands still. + 'stand_end' end frame of stand animation. + 'stand_speed'speed of animation in frames per second. + 'walk_start' when mob is walking around. + 'walk_end' + 'walk_speed' + 'run_start' when a mob runs or attacks. + 'run_end' + 'run_speed' + 'fly_start' when a mob is flying. + 'fly_end' + 'fly_speed' + 'punch_start'when a mob melee attacks. + 'punch_end' + 'punch_speed' + 'punch2_start' alternative melee attack animation. + 'punch2_end' + 'punch2_speed' + 'shoot_start'shooting animation. + 'shoot_end' + 'shoot_speed' + 'die_start' death animation + 'die_end' + 'die_speed' + 'die_loop' when set to false stops the animation looping. + } - Using '_loop = false' setting will stop any of the above animations from - looping. + Using '_loop = false' setting will stop any of the above animations from + looping. - 'speed_normal' is used for animation speed for compatibility with some - older mobs. - 'pushable' Allows players, & other mobs to push the mob. + 'speed_normal' is used for animation speed for compatibility with some + older mobs. + 'pushable' Allows players, & other mobs to push the mob. - MineClone 2 extensions: + MineClone 2 extensions: - 'spawn_class' Classification of mod for the spawning algorithm: - "hostile", "passive", "ambient" or "water" - 'ignores_nametag' if true, mob cannot be named by nametag - 'rain_damage' damage per second if mob is standing in rain (default: 0) - 'sunlight_damage' holds the damage per second inflicted to mobs when they - are in direct sunlight - 'spawn_small_alternative': name of a smaller mob to use as replacement if - spawning fails due to space requirements - 'glow' same as in entity definition - 'child' if true, spawn mob as child - 'shoot_arrow(self, pos, dir)' function that is called when mob wants to shoot an arrow. - You can spawn your own arrow here. pos is mob position, - dir is mob's aiming direction - 'sounds_child' same as sounds, but for childs. If not defined, childs will use same - sound as adults but with higher pitch - 'follow_velocity' The speed at which a mob moves toward the player when they're holding the appropriate follow item. - 'instant_death' If true, mob dies instantly (no death animation or delay) (default: false) - 'xp_min' the minimum XP it drops on death (default: 0) - 'xp_max' the maximum XP it drops on death (default: 0) - 'fire_resistant' If true, the mob can't burn - 'fire_damage_resistant' If true the mob will not take damage when burning - 'ignited_by_sunlight' If true the mod will burn at daytime. (Takes sunlight_damage per second) - 'nofollow' Do not follow players when they wield the "follow" item. For mobs (like villagers) - that are bred in a different way. - 'pick_up' table of itemstrings the mob will pick up (e.g. for breeding) - 'on_pick_up' function that will be called on item pickup - return true to not pickup the item + 'spawn_class' Classification of mod for the spawning algorithm: + "hostile", "passive", "ambient" or "water" + 'ignores_nametag' if true, mob cannot be named by nametag + 'rain_damage' damage per second if mob is standing in rain (default: 0) + 'sunlight_damage' holds the damage per second inflicted to mobs when they + are in direct sunlight + 'spawn_small_alternative' name of a smaller mob to use as replacement if + spawning fails due to space requirements + 'glow' same as in entity definition + 'child' if true, spawn mob as child + 'shoot_arrow(self, pos, dir)' function that is called when mob wants to shoot an arrow. + You can spawn your own arrow here. pos is mob position, + dir is mob's aiming direction + 'sounds_child' same as sounds, but for childs. If not defined, childs will use same + sound as adults but with higher pitch + 'follow_velocity' The speed at which a mob moves toward the player when they're holding the appropriate follow item. + 'instant_death' If true, mob dies instantly (no death animation or delay) (default: false) + 'xp_min' the minimum XP it drops on death (default: 0) + 'xp_max' the maximum XP it drops on death (default: 0) + 'fire_resistant' If true, the mob can't burn + 'fire_damage_resistant' If true the mob will not take damage when burning + 'ignited_by_sunlight' If true the mod will burn at daytime. (Takes sunlight_damage per second) + 'nofollow' Do not follow players when they wield the "follow" item. For mobs (like villagers) + that are bred in a different way. + 'pick_up' table of itemstrings the mob will pick up (e.g. for breeding) + 'on_pick_up' function that will be called on item pickup - return true to not pickup the item - mobs:gopath(self,target,callback_arrived) pathfind a way to target and run callback on arrival + mobs:gopath(self,target,callback_arrived) pathfind a way to target and run callback on arrival @@ -268,30 +270,30 @@ Node Replacement Mobs can look around for specific nodes as they walk and replace them to mimic eating. - 'replace_what' group of items to replace e.g. - {"farming:wheat_8", "farming:carrot_8"} - or you can use the specific options of what, with and - y offset by using this instead: - { - {"group:grass", "air", 0}, - {"default:dirt_with_grass", "default:dirt", -1} - } - 'replace_with' replace with what e.g. "air" or in chickens case "mobs:egg" - 'replace_rate' how random should the replace rate be (typically 10) - 'replace_offset' +/- value to check specific node to replace + 'replace_what' group of items to replace e.g. + {"farming:wheat_8", "farming:carrot_8"} + or you can use the specific options of what, with and + y offset by using this instead: + { + {"group:grass", "air", 0}, + {"default:dirt_with_grass", "default:dirt", -1} + } + 'replace_with' replace with what e.g. "air" or in chickens case "mobs:egg" + 'replace_rate' how random should the replace rate be (typically 10) + 'replace_offset' +/- value to check specific node to replace - 'on_replace(self, pos, oldnode, newnode)' - is called when mob is about to replace a node. Also called - when not actually replacing due to mobs_griefing setting being false. - 'self' ObjectRef of mob - 'pos' Position of node to replace - 'oldnode' Current node - 'newnode' What the node will become after replacing + 'on_replace(self, pos, oldnode, newnode)' + is called when mob is about to replace a node. Also called + when not actually replacing due to mobs_griefing setting being false. + 'self' ObjectRef of mob + 'pos' Position of node to replace + 'oldnode' Current node + 'newnode' What the node will become after replacing - If false is returned, the mob will not replace the node. + If false is returned, the mob will not replace the node. - By default, replacing sets self.gotten to true and resets the object - properties. + By default, replacing sets self.gotten to true and resets the object + properties. Custom Definition Functions @@ -300,33 +302,33 @@ Custom Definition Functions Along with the above mob registry settings we can also use custom functions to enhance mob functionality and have them do many interesting things: - 'on_die' a function that is called when the mob is killed; the - parameters are (self, pos). Return true to skip the builtin - death animation and death effects - 'on_rightclick' its same as in minetest.register_entity() - 'on_blast' is called when an explosion happens near mob when using TNT - functions, parameters are (object, damage) and returns - (do_damage, do_knockback, drops) - 'on_spawn' is a custom function that runs on mob spawn with 'self' as - variable, return true at end of function to run only once. - 'after_activate' is a custom function that runs once mob has been activated - with these paramaters (self, staticdata, def, dtime) - 'on_breed' called when two similar mobs breed, paramaters are - (parent1, parent2) objects, return false to stop child from - being resized and owner/tamed flags and child textures being - applied. Function itself must spawn new child mob. - 'on_grown' is called when a child mob has grown up, only paramater is - (self). - 'do_punch' called when mob is punched with paramaters (self, hitter, - time_from_last_punch, tool_capabilities, direction), return - false to stop punch damage and knockback from taking place. - 'custom_attack' when set this function is called instead of the normal mob - melee attack, parameters are (self, to_attack). - 'on_die' a function that is called when mob is killed (self, pos) - 'do_custom' a custom function that is called every tick while mob is - active and which has access to all of the self.* variables - e.g. (self.health for health or self.standing_in for node - status), return with 'false' to skip remainder of mob API. + 'on_die' a function that is called when the mob is killed; the + parameters are (self, pos). Return true to skip the builtin + death animation and death effects + 'on_rightclick'its same as in minetest.register_entity() + 'on_blast' is called when an explosion happens near mob when using TNT + functions, parameters are (object, damage) and returns + (do_damage, do_knockback, drops) + 'on_spawn' is a custom function that runs on mob spawn with 'self' as + variable, return true at end of function to run only once. + 'after_activate' is a custom function that runs once mob has been activated + with these paramaters (self, staticdata, def, dtime) + 'on_breed' called when two similar mobs breed, paramaters are + (parent1, parent2) objects, return false to stop child from + being resized and owner/tamed flags and child textures being + applied.Function itself must spawn new child mob. + 'on_grown' is called when a child mob has grown up, only paramater is + (self). + 'do_punch' called when mob is punched with paramaters (self, hitter, + time_from_last_punch, tool_capabilities, direction), return + false to stop punch damage and knockback from taking place. + 'custom_attack'when set this function is called instead of the normal mob + melee attack, parameters are (self, to_attack). + 'on_die' a function that is called when mob is killed (self, pos) + 'do_custom' a custom function that is called every tick while mob is + active and which has access to all of the self.* variables + e.g. (self.health for health or self.standing_in for node + status), return with 'false' to skip remainder of mob API. Internal Variables @@ -335,84 +337,84 @@ Internal Variables The mob api also has some preset variables and functions that it will remember for each mob. - 'self.health' contains current health of mob (cannot exceed - self.hp_max) - 'self.breath' contains current breath of mob, if mob takes drowning - damage at all (cannot exceed self.breath_max). Breath - decreases by 1 each second while in a node with drowning - damage and increases by 1 each second otherwise. - 'self.texture_list' contains list of all mob textures - 'self.child_texture' contains mob child texture when growing up - 'self.base_texture' contains current skin texture which was randomly - selected from textures list - 'self.gotten' this is used to track whether some special item has been - gotten from the mob, for example, wool from sheep. - Initialized as false, and the mob must set this value - manually. - 'self.horny' when animal fed enough it is set to true and animal can - breed with same animal - 'self.hornytimer' background timer that controls breeding functions and - mob childhood timings - 'self.child' used for when breeding animals have child, will use - child_texture and be half size - 'self.owner' string used to set owner of npc mobs, typically used for - dogs - 'self.order' set to "follow" or "stand" so that npc will follow owner - or stand it's ground - 'self.state' Current mob state. - "stand": no movement (except turning around) - "walk": walk or move around aimlessly - "attack": chase and attack enemy - "runaway": flee from target - "flop": bounce around aimlessly - (for swimming mobs that have stranded) - "die": during death - 'self.nametag' contains the name of the mob which it can show above + 'self.health' contains current health of mob (cannot exceed + self.hp_max) + 'self.breath' contains current breath of mob, if mob takes drowning + damage at all (cannot exceed self.breath_max). Breath + decreases by 1 each second while in a node with drowning + damage and increases by 1 each second otherwise. + 'self.texture_list'contains list of all mob textures + 'self.child_texture' contains mob child texture when growing up + 'self.base_texture'contains current skin texture which was randomly + selected from textures list + 'self.gotten' this is used to track whether some special item has been + gotten from the mob, for example, wool from sheep. + Initialized as false, and the mob must set this value + manually. + 'self.horny' when animal fed enough it is set to true and animal can + breed with same animal + 'self.hornytimer' background timer that controls breeding functions and + mob childhood timings + 'self.child' used for when breeding animals have child, will use + child_texture and be half size + 'self.owner' string used to set owner of npc mobs, typically used for + dogs + 'self.order' set to "follow" or "stand" so that npc will follow owner + or stand it's ground + 'self.state' Current mob state. + "stand": no movement (except turning around) + "walk": walk or move around aimlessly + "attack": chase and attack enemy + "runaway": flee from target + "flop": bounce around aimlessly + (for swimming mobs that have stranded) + "die": during death + 'self.nametag' contains the name of the mob which it can show above Spawning Mobs in World ---------------------- mobs:register_spawn(name, nodes, max_light, min_light, chance, - active_object_count, max_height, day_toggle) + active_object_count, max_height, day_toggle) mobs:spawn_specfic(name, nodes, neighbors, min_light, max_light, interval, - chance, active_object_count, min_height, max_height, day_toggle, on_spawn) + chance, active_object_count, min_height, max_height, day_toggle, on_spawn) These functions register a spawn algorithm for the mob. Without this function the call the mobs won't spawn. - 'name' is the name of the animal/monster - 'nodes' is a list of nodenames on that the animal/monster can - spawn on top of - 'neighbors' is a list of nodenames on that the animal/monster will - spawn beside (default is {"air"} for - mobs:register_spawn) - 'max_light' is the maximum of light - 'min_light' is the minimum of light - 'interval' is same as in register_abm() (default is 30 for - mobs:register_spawn) - 'chance' is same as in register_abm() - 'active_object_count' number of this type of mob to spawn at one time inside - map area - 'min_height' is the minimum height the mob can spawn - 'max_height' is the maximum height the mob can spawn - 'day_toggle' true for day spawning, false for night or nil for - anytime - 'on_spawn' is a custom function which runs after mob has spawned - and gives self and pos values. + 'name' is the name of the animal/monster + 'nodes' is a list of nodenames on that the animal/monster can + spawn on top of + 'neighbors' is a list of nodenames on that the animal/monster will + spawn beside (default is {"air"} for + mobs:register_spawn) + 'max_light' is the maximum of light + 'min_light' is the minimum of light + 'interval' is same as in register_abm() (default is 30 for + mobs:register_spawn) + 'chance' is same as in register_abm() + 'active_object_count' number of this type of mob to spawn at one time inside + map area + 'min_height' is the minimum height the mob can spawn + 'max_height' is the maximum height the mob can spawn + 'day_toggle' true for day spawning, false for night or nil for + anytime + 'on_spawn' is a custom function which runs after mob has spawned + and gives self and pos values. A simpler way to handle mob spawns has been added with the mobs:spawn(def) command which uses above names to make settings clearer: - mobs:spawn({name = "mobs_monster:tree_monster", - nodes = {"group:leaves"}, - max_light = 7, - }) + mobs:spawn({name = "mobs_monster:tree_monster", + nodes = {"group:leaves"}, + max_light = 7, + }) For each mob that spawns with this function is a field in mobs.spawning_mobs. -It tells if the mob should spawn or not. Default is true. So other mods can +It tells if the mob should spawn or not.Default is true.So other mods can only use the API of this mod by disabling the spawning of the default mobs in this mod. @@ -420,12 +422,12 @@ this mod. mobs:spawn_abm_check(pos, node, name) This global function can be changed to contain additional checks for mobs to -spawn e.g. mobs that spawn only in specific areas and the like. By returning +spawn e.g. mobs that spawn only in specific areas and the like.By returning true the mob will not spawn. - 'pos' holds the position of the spawning mob - 'node' contains the node the mob is spawning on top of - 'name' is the name of the animal/monster + 'pos' holds the position of the spawning mob + 'node' contains the node the mob is spawning on top of + 'name' is the name of the animal/monster MineClone 2 extensions @@ -449,34 +451,34 @@ mobs:register_arrow(name, definition) This function registers a arrow for mobs with the attack type shoot. - 'name' is the name of the arrow - 'definition' is a table with the following values: - 'visual' same is in minetest.register_entity() - 'visual_size' same is in minetest.register_entity() - 'textures' same is in minetest.register_entity() - 'velocity' the velocity of the arrow - 'drop' if set to true any arrows hitting a node will drop as item - 'hit_player' a function that is called when the arrow hits a player; - this function should hurt the player, the parameters are - (self, player) - 'hit_mob' a function that is called when the arrow hits a mob; - this function should hurt the mob, the parameters are - (self, mob) - 'hit_object' a function that is called when the arrow hits an object - that is neither a player nor a mob. this function should - hurt the object, the parameters are (self, object) - 'hit_node' a function that is called when the arrow hits a node, the - parameters are (self, pos, node) - 'tail' when set to 1 adds a trail or tail to mob arrows - 'tail_texture' texture string used for above effect - 'tail_size' has size for above texture (defaults to between 5 and 10) - 'expire' contains float value for how long tail appears for - (defaults to 0.25) - 'glow' has value for how brightly tail glows 1 to 10 (default is - 0 for no glow) - 'rotate' integer value in degrees to rotate arrow - 'on_step' is a custom function when arrow is active, nil for - default. + 'name' is the name of the arrow + 'definition' is a table with the following values: + 'visual' same is in minetest.register_entity() + 'visual_size'same is in minetest.register_entity() + 'textures' same is in minetest.register_entity() + 'velocity' the velocity of the arrow + 'drop' if set to true any arrows hitting a node will drop as item + 'hit_player' a function that is called when the arrow hits a player; + this function should hurt the player, the parameters are + (self, player) + 'hit_mob' a function that is called when the arrow hits a mob; + this function should hurt the mob, the parameters are + (self, mob) + 'hit_object' a function that is called when the arrow hits an object + that is neither a player nor a mob. this function should + hurt the object, the parameters are (self, object) + 'hit_node' a function that is called when the arrow hits a node, the + parameters are (self, pos, node) + 'tail' when set to 1 adds a trail or tail to mob arrows + 'tail_texture' texture string used for above effect + 'tail_size' has size for above texture (defaults to between 5 and 10) + 'expire' contains float value for how long tail appears for + (defaults to 0.25) + 'glow' has value for how brightly tail glows 1 to 10 (default is + 0 for no glow) + 'rotate' integer value in degrees to rotate arrow + 'on_step' is a custom function when arrow is active, nil for + default. Spawn Eggs @@ -486,25 +488,25 @@ mobs:register_egg(name, description, background, addegg, no_creative) This function registers a spawn egg which can be used by admin to properly spawn in a mob. - 'name' this is the name of your new mob to spawn e.g. "mob:sheep" - 'description' the name of the new egg you are creating e.g. "Spawn Sheep" - 'background' the texture displayed for the egg in inventory - 'addegg' would you like an egg image in front of your texture (1 = yes, - 0 = no) - 'no_creative' when set to true this stops spawn egg appearing in creative - mode for destructive mobs like Dungeon Masters. + 'name' this is the name of your new mob to spawn e.g. "mob:sheep" + 'description' the name of the new egg you are creating e.g. "Spawn Sheep" + 'background'the texture displayed for the egg in inventory + 'addegg' would you like an egg image in front of your texture (1 = yes, + 0 = no) + 'no_creative' when set to true this stops spawn egg appearing in creative + mode for destructive mobs like Dungeon Masters. Explosion Function ------------------ mobs:boom(self, pos, radius) - 'self' mob entity - 'pos' centre position of explosion - 'radius' radius of explosion (typically set to 3) + 'self' mob entity + 'pos' centre position of explosion + 'radius' radius of explosion (typically set to 3) This function generates an explosion which removes nodes in a specific radius -and damages any entity caught inside the blast radius. Protection will limit +and damages any entity caught inside the blast radius.Protection will limit node destruction but not entity damage. @@ -532,13 +534,13 @@ This function allows the mob to be fed the item inside self.follow be it apple, wheat or whatever a set number of times and be tamed or bred as a result. Will return true when mob is fed with item it likes. - 'self' mob information - 'clicker' player information - 'feed_count' number of times mob must be fed to tame or breed - 'breed' true or false stating if mob can be bred and a child created - afterwards - 'tame' true or false stating if mob can be tamed so player can pick - them up + 'self' mob information + 'clicker' player information + 'feed_count' number of times mob must be fed to tame or breed + 'breed' true or false stating if mob can be bred and a child created + afterwards + 'tame' true or false stating if mob can be tamed so player can pick + them up Protecting Mobs @@ -548,10 +550,10 @@ mobs:protect(self, clicker) This function can be used to right-click any tamed mob with mobs:protector item, this will protect the mob from harm inside of a protected area from other -players. Will return true when mob right-clicked with mobs:protector item. +players.Will return true when mob right-clicked with mobs:protector item. - 'self' mob information - 'clicker' player information + 'self' mob information + 'clicker' player information Riding Mobs @@ -565,8 +567,8 @@ mobs:attach(self, player) This function attaches a player to the mob so it can be ridden. - 'self' mob information - 'player' player information + 'self' mob information + 'player' player information mobs:detach(player, offset) @@ -574,8 +576,8 @@ mobs:detach(player, offset) This function will detach the player currently riding a mob to an offset position. - 'player' player information - 'offset' position table containing offset values + 'player' player information + 'offset' position table containing offset values mobs:drive(self, move_animation, stand_animation, can_fly, dtime) @@ -583,12 +585,12 @@ mobs:drive(self, move_animation, stand_animation, can_fly, dtime) This function allows an attached player to move the mob around and animate it at same time. - 'self' mob information - 'move_animation' string containing movement animation e.g. "walk" - 'stand_animation' string containing standing animation e.g. "stand" - 'can_fly' if true then jump and sneak controls will allow mob to fly - up and down - 'dtime' tick time used inside drive function + 'self' mob information + 'move_animation'string containing movement animation e.g. "walk" + 'stand_animation' string containing standing animation e.g. "stand" + 'can_fly' if true then jump and sneak controls will allow mob to fly + up and down + 'dtime' tick time used inside drive function mobs:fly(self, dtime, speed, can_shoot, arrow_entity, move_animation, stand_animation) @@ -596,16 +598,16 @@ mobs:fly(self, dtime, speed, can_shoot, arrow_entity, move_animation, stand_anim This function allows an attached player to fly the mob around using directional controls. - 'self' mob information - 'dtime' tick time used inside fly function - 'speed' speed of flight - 'can_shoot' true if mob can fire arrow (sneak and left mouse button - fires) - 'arrow_entity' name of arrow entity used for firing - 'move_animation' string containing name of pre-defined animation e.g. "walk" - or "fly" etc. - 'stand_animation' string containing name of pre-defined animation e.g. - "stand" or "blink" etc. + 'self' mob information + 'dtime' tick time used inside fly function + 'speed' speed of flight + 'can_shoot' true if mob can fire arrow (sneak and left mouse button + fires) + 'arrow_entity' name of arrow entity used for firing + 'move_animation'string containing name of pre-defined animation e.g. "walk" + or "fly" etc. + 'stand_animation' string containing name of pre-defined animation e.g. + "stand" or "blink" etc. Note: animation names above are from the pre-defined animation lists inside mob registry without extensions. @@ -616,46 +618,46 @@ mobs:set_animation(self, name) This function sets the current animation for mob, defaulting to "stand" if not found. - 'self' mob information - 'name' name of animation + 'self' mob information + 'name' name of animation Certain variables need to be set before using the above functions: - 'self.v2' toggle switch used to define below values for the - first time - 'self.max_speed_forward' max speed mob can move forward - 'self.max_speed_reverse' max speed mob can move backwards - 'self.accel' acceleration speed - 'self.terrain_type' integer containing terrain mob can walk on - (1 = water, 2 or 3 = land) - 'self.driver_attach_at' position offset for attaching player to mob - 'self.driver_eye_offset' position offset for attached player view - 'self.driver_scale' sets driver scale for mobs larger than {x=1, y=1} + 'self.v2' toggle switch used to define below values for the + first time + 'self.max_speed_forward' max speed mob can move forward + 'self.max_speed_reverse' max speed mob can move backwards + 'self.accel' acceleration speed + 'self.terrain_type' integer containing terrain mob can walk on + (1 = water, 2 or 3 = land) + 'self.driver_attach_at'position offset for attaching player to mob + 'self.driver_eye_offset' position offset for attached player view + 'self.driver_scale' sets driver scale for mobs larger than {x=1, y=1} External Settings for "minetest.conf" ------------------------------------ - 'enable_damage' if true monsters will attack players (default is true) - 'only_peaceful_mobs' if true only animals will spawn in game (default is - false) - 'mobs_disable_blood' if false, damage effects appear when mob is hit (default - is false) - 'mobs_spawn_protected' if set to false then mobs will not spawn in protected - areas (default is true) - 'mob_difficulty' sets difficulty level (health and hit damage - multiplied by this number), defaults to 1.0. - 'mob_spawn_chance' multiplies chance of all mobs spawning and can be set - to 0.5 to have mobs spawn more or 2.0 to spawn less. - e.g. 1 in 7000 * 0.5 = 1 in 3500 so better odds of - spawning. - 'mobs_spawn' if false then mobs no longer spawn without spawner or - spawn egg. - 'mobs_drop_items' when false mobs no longer drop items when they die. - 'mobs_griefing' when false mobs cannot break blocks when using either - pathfinding level 2, replace functions or mobs:boom - function. + 'enable_damage' if true monsters will attack players (default is true) + 'only_peaceful_mobs' if true only animals will spawn in game (default is + false) + 'mobs_disable_blood' if false, damage effects appear when mob is hit (default + is false) + 'mobs_spawn_protected' if set to false then mobs will not spawn in protected + areas (default is true) + 'mob_difficulty' sets difficulty level (health and hit damage + multiplied by this number), defaults to 1.0. + 'mob_spawn_chance' multiplies chance of all mobs spawning and can be set + to 0.5 to have mobs spawn more or 2.0 to spawn less. + e.g.1 in 7000 * 0.5 = 1 in 3500 so better odds of + spawning. + 'mobs_spawn' if false then mobs no longer spawn without spawner or + spawn egg. + 'mobs_drop_items' when false mobs no longer drop items when they die. + 'mobs_griefing' when false mobs cannot break blocks when using either + pathfinding level 2, replace functions or mobs:boom + function. Players can override the spawn chance for each mob registered by adding a line to their minetest.conf file with a new value, the lower the value the more each From e353ec3b163fc1344c7d8e0bc1d39115e8c0c3f2 Mon Sep 17 00:00:00 2001 From: cora Date: Sat, 21 May 2022 00:37:20 +0200 Subject: [PATCH 28/35] Iron golems pick and pick up one (stack of) poppy --- mods/ENTITIES/mobs_mc/iron_golem.lua | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/mods/ENTITIES/mobs_mc/iron_golem.lua b/mods/ENTITIES/mobs_mc/iron_golem.lua index 8b3278e51..51c69ac5e 100644 --- a/mods/ENTITIES/mobs_mc/iron_golem.lua +++ b/mods/ENTITIES/mobs_mc/iron_golem.lua @@ -41,7 +41,26 @@ mobs:register_mob("mobs_mc:iron_golem", { group_attack = true, attacks_monsters = true, attack_type = "dogfight", + _got_poppy = false, pick_up = {"mcl_flowers:poppy"}, + on_pick_up = function(self,n) + if n.itemstring:find("mcl_flowers:poppy") then + if not self._got_poppy then + self._got_poppy=true + return + end + return true + end + end, + replace_what = {"mcl_flowers:poppy"}, + replace_with = {"air"}, + on_replace = function(self, pos, oldnode, newnode) + if not self.got_poppy and oldnode.name == "mcl_flowers:poppy" then + self._got_poppy=true + return + end + return false + end, drops = { {name = mobs_mc.items.iron_ingot, chance = 1, From d67dd0577f46f33a6f23f8441e04000efbc35a68 Mon Sep 17 00:00:00 2001 From: cora Date: Sat, 21 May 2022 04:39:09 +0200 Subject: [PATCH 29/35] fix crash through forgotten function call --- mods/MAPGEN/mcl_villages/init.lua | 4 ---- 1 file changed, 4 deletions(-) diff --git a/mods/MAPGEN/mcl_villages/init.lua b/mods/MAPGEN/mcl_villages/init.lua index 6dd7d26eb..9eb9bfba8 100644 --- a/mods/MAPGEN/mcl_villages/init.lua +++ b/mods/MAPGEN/mcl_villages/init.lua @@ -67,10 +67,6 @@ local function build_a_settlement(minp, maxp, blockseed) -- evaluate settlement_info and place schematics settlements.place_schematics(settlement_info, pr) - - minetest.after(60,function() - spawn_villagers(minp,maxp) - end) --give the village some time to fully generate end local function ecb_village(blockpos, action, calls_remaining, param) From 7379d5bee8eece730aeb93434556b4e7a3397781 Mon Sep 17 00:00:00 2001 From: cora Date: Sat, 21 May 2022 13:43:28 +0200 Subject: [PATCH 30/35] Add Belltower to villages --- mods/MAPGEN/mcl_villages/buildings.lua | 21 ++++++++++++++---- .../mcl_villages/schematics/belltower.mts | Bin 0 -> 211 bytes 2 files changed, 17 insertions(+), 4 deletions(-) create mode 100644 mods/MAPGEN/mcl_villages/schematics/belltower.mts diff --git a/mods/MAPGEN/mcl_villages/buildings.lua b/mods/MAPGEN/mcl_villages/buildings.lua index 928d37b37..c9fc87ed4 100644 --- a/mods/MAPGEN/mcl_villages/buildings.lua +++ b/mods/MAPGEN/mcl_villages/buildings.lua @@ -200,7 +200,7 @@ local function spawn_iron_golem(pos) end local function spawn_villagers(minp,maxp) - local beds=minetest.find_nodes_in_area(minp,maxp,{"mcl_beds:bed_red_bottom"}) + local beds=minetest.find_nodes_in_area(vector.offset(minp,-20,-20,-20),vector.offset(maxp,20,20,20),{"mcl_beds:bed_red_bottom"}) for _,bed in pairs(beds) do local m = minetest.get_meta(bed) if m:get_string("villager") == "" then @@ -234,6 +234,22 @@ end function settlements.place_schematics(settlement_info, pr) local building_all_info + + --attempt to place one belltower in the center of the village - this doesn't always work out great but it's a lot better than doing it first or last. + local belltower = table.remove(settlement_info,math.floor(#settlement_info/2)) + mcl_structures.place_schematic( + vector.offset(belltower["pos"],0,1,0), + settlements.modpath.."/schematics/belltower.mts", + belltower["rotation"], + nil, + true, + nil, + function(p1, p2, size, rotation, pr) + spawn_iron_golem(p1) + end, + pr + ) + for i, built_house in ipairs(settlement_info) do local is_last = i == #settlement_info @@ -307,9 +323,6 @@ function settlements.place_schematics(settlement_info, pr) function(p1, p2, size, rotation, pr) init_nodes(p1, p2, size, rotation, pr) spawn_villagers(p1,p2) - if is_last then - spawn_iron_golem(p1) - end end, pr ) diff --git a/mods/MAPGEN/mcl_villages/schematics/belltower.mts b/mods/MAPGEN/mcl_villages/schematics/belltower.mts new file mode 100644 index 0000000000000000000000000000000000000000..8eb524312cc98c62899ef6d7714398c5ef869d4e GIT binary patch literal 211 zcmeYb3HD`RVPIuoV_>ZZ0|s^m;oRh$_~iVeRIB2W{JhkpqRixM2Ij=fA_g&#OnG8X zPBD^Hya9sAc0LZz9heZfe$2;lnOEjL^240_&JGrC8 Date: Sun, 22 May 2022 01:51:03 +0200 Subject: [PATCH 31/35] fix crash during (artificial) village creation when using the village tool doing that on an unsuitable location would result in no position for the belltower being available this checks for that and ... doesn't crash then ^^ --- mods/MAPGEN/mcl_villages/buildings.lua | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/mods/MAPGEN/mcl_villages/buildings.lua b/mods/MAPGEN/mcl_villages/buildings.lua index c9fc87ed4..9038769fd 100644 --- a/mods/MAPGEN/mcl_villages/buildings.lua +++ b/mods/MAPGEN/mcl_villages/buildings.lua @@ -237,18 +237,20 @@ function settlements.place_schematics(settlement_info, pr) --attempt to place one belltower in the center of the village - this doesn't always work out great but it's a lot better than doing it first or last. local belltower = table.remove(settlement_info,math.floor(#settlement_info/2)) - mcl_structures.place_schematic( - vector.offset(belltower["pos"],0,1,0), - settlements.modpath.."/schematics/belltower.mts", - belltower["rotation"], - nil, - true, - nil, - function(p1, p2, size, rotation, pr) - spawn_iron_golem(p1) - end, - pr - ) + if belltower then + mcl_structures.place_schematic( + vector.offset(belltower["pos"],0,0,0), + settlements.modpath.."/schematics/belltower.mts", + belltower["rotation"], + nil, + true, + nil, + function(p1, p2, size, rotation, pr) + spawn_iron_golem(p1) + end, + pr + ) + end for i, built_house in ipairs(settlement_info) do local is_last = i == #settlement_info From ec73afd21ae7136287803f9afedeeb434e37dbcb Mon Sep 17 00:00:00 2001 From: cora Date: Sun, 22 May 2022 01:52:26 +0200 Subject: [PATCH 32/35] use iron texture for apprentice badge, not stone --- mods/ENTITIES/mobs_mc/villager.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 596ba430f..32714cdd9 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -67,7 +67,7 @@ local tiernames = { local badges = { "default_wood.png", - "default_stone.png", + "default_steel_block.png", "default_gold_block.png", "mcl_core_emerald_block.png", "default_diamond_block.png", From d34191f00c0ee9d36f18d46dbf3de3e3e6b4c92b Mon Sep 17 00:00:00 2001 From: cora Date: Sun, 22 May 2022 01:53:10 +0200 Subject: [PATCH 33/35] villagers go to the bell if it's rung(for now) this will help with further testing pathfinding until villagers get a proper schedule and do more things --- mods/ITEMS/mcl_bells/init.lua | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/mods/ITEMS/mcl_bells/init.lua b/mods/ITEMS/mcl_bells/init.lua index d4bbe6325..e2f4fe667 100644 --- a/mods/ITEMS/mcl_bells/init.lua +++ b/mods/ITEMS/mcl_bells/init.lua @@ -5,7 +5,13 @@ mcl_bells = {} local has_mcl_wip = minetest.get_modpath("mcl_wip") function mcl_bells.ring_once(pos) - minetest.sound_play( "mcl_bells_bell_stroke", { pos = pos, gain = 1.5, max_hear_distance = 300,}); + minetest.sound_play( "mcl_bells_bell_stroke", { pos = pos, gain = 1.5, max_hear_distance = 150,}) + local vv=minetest.get_objects_inside_radius(pos,150) + for _,o in pairs(vv) do + if o.type == "npc" then + mobs:gopath(o:get_luaentity(),pos,function() end) + end + end end minetest.register_node("mcl_bells:bell", { From a5ba8f739f2adcfd5e872eb06dc19fef4b11c87e Mon Sep 17 00:00:00 2001 From: cora Date: Sun, 22 May 2022 01:59:06 +0200 Subject: [PATCH 34/35] Add bell to villager trades --- mods/ENTITIES/mobs_mc/villager.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 32714cdd9..52511dfa7 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -334,7 +334,7 @@ local professions = { { { { "mcl_core:iron_ingot", 4, 4 }, E1 }, - --{ { "mcl_core:emerald", 36, 36 }, { "FIXME: Bell", 1, 1 } }, + { { "mcl_core:emerald", 36, 36 }, { "mcl_bells:bell", 1, 1 } }, { { "mcl_core:emerald", 3, 3 }, { "mcl_armor:leggings_chain", 1, 1 } }, { { "mcl_core:emerald", 1, 1 }, { "mcl_armor:boots_chain", 1, 1 } }, }, @@ -437,7 +437,7 @@ local professions = { { { { "mcl_core:iron_ingot", 4, 4 }, E1 }, - --{ { "mcl_core:emerald", 36, 36 }, { "FIXME: Bell", 1, 1 } }, + { { "mcl_core:emerald", 36, 36 }, { "mcl_bells:bell", 1, 1 } }, }, { { { "mcl_core:flint", 7, 9 }, E1 }, @@ -470,7 +470,7 @@ local professions = { { { { "mcl_core:iron_ingot", 4, 4 }, E1 }, - --{ { "mcl_core:emerald", 36, 36 }, { "FIXME: Bell", 1, 1 } }, + { { "mcl_core:emerald", 36, 36 }, { "mcl_bells:bell", 1, 1 } }, }, { { { "mcl_core:flint", 30, 30 }, E1 }, From 028d1c1f4f3a8c4876a109b1df5e1dcb4b5f2310 Mon Sep 17 00:00:00 2001 From: cora Date: Sun, 22 May 2022 14:43:11 +0200 Subject: [PATCH 35/35] do not tame villagers --- mods/ENTITIES/mobs_mc/villager.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mods/ENTITIES/mobs_mc/villager.lua b/mods/ENTITIES/mobs_mc/villager.lua index 52511dfa7..669ef5cf5 100644 --- a/mods/ENTITIES/mobs_mc/villager.lua +++ b/mods/ENTITIES/mobs_mc/villager.lua @@ -1259,7 +1259,7 @@ mobs:register_mob("mobs_mc:villager", { end end if clicker then - mobs:feed_tame(self, clicker, 1, true, true) + mobs:feed_tame(self, clicker, 1, true, false) return end return true --do not pick up