diff --git a/mods/mobs_npc/screenshot.png b/mods/mobs_npc/screenshot.png new file mode 100644 index 00000000..631f73b1 Binary files /dev/null and b/mods/mobs_npc/screenshot.png differ diff --git a/mods/mobs_npc/spawn_example.lua b/mods/mobs_npc/spawn_example.lua new file mode 100644 index 00000000..6e472f4f --- /dev/null +++ b/mods/mobs_npc/spawn_example.lua @@ -0,0 +1,98 @@ + +--[[ Spawn Template, defaults to values shown if line not provided + +mobs:spawn({ + + name = "", + + - Name of mob, must be provided e.g. "mymod:my_mob" + + nodes = {"group:soil, "group:stone"}, + + - Nodes to spawn on top of. + + neighbors = {"air"}, + + - Nodes to spawn beside. + + min_light = 0, + + - Minimum light level. + + max_light = 15, + + - Maximum light level, 15 is sunlight only. + + interval = 30, + + - Spawn interval in seconds. + + chance = 5000, + + - Spawn chance, 1 in every 5000 nodes. + + active_object_count = 1, + + - Active mobs of this type in area. + + min_height = -31000, + + - Minimum height level. + + max_height = 31000, + + - Maximum height level. + + day_toggle = nil, + + - Daytime toggle, true to spawn during day, false for night, nil for both + + on_spawn = nil, + + - On spawn function to run when mob spawns in world + + on_map_load = nil, + + - On map load, when true mob only spawns in newly generated map areas +}) +]]-- + + +-- NPC + +mobs:spawn({ + name = "mobs_npc:npc", + nodes = {"default:brick"}, + neighbors = {"default:grass_3"}, + min_light = 10, + chance = 10000, + active_object_count = 1, + min_height = 0, + day_toggle = true, +}) + +-- Igor + +mobs:spawn({ + name = "mobs_npc:igor", + nodes = {"mobs:meatblock"}, + neighbors = {"default:brick"}, + min_light = 10, + chance = 10000, + active_object_count = 1, + min_height = 0, + day_toggle = true, +}) + +-- Trader + +mobs:spawn({ + name = "mobs_npc:trader", + nodes = {"default:diamondblock"}, + neighbors = {"default:brick"}, + min_light = 10, + chance = 10000, + active_object_count = 1, + min_height = 0, + day_toggle = true, +}) diff --git a/mods/mobs_npc/trader.lua b/mods/mobs_npc/trader.lua new file mode 100644 index 00000000..c7c9679d --- /dev/null +++ b/mods/mobs_npc/trader.lua @@ -0,0 +1,304 @@ + +local S = mobs.intllib + +-- define table containing names for use and shop items for sale + +mobs.human = { + + names = { + "Bob", "Duncan", "Bill", "Tom", "James", "Ian", "Lenny", + "Dylan", "Ethan" + }, + + items = { + --{item for sale, price, chance of appearing in trader's inventory} + {"default:apple 10", "default:gold_ingot 2", 10}, + {"farming:bread 10", "default:gold_ingot 4", 5}, + {"default:clay 10", "default:gold_ingot 2", 12}, + {"default:brick 10", "default:gold_ingot 4", 17}, + {"default:glass 10", "default:gold_ingot 4", 17}, + {"default:obsidian 10", "default:gold_ingot 15", 50}, + {"default:diamond 1", "default:gold_ingot 5", 40}, + {"farming:wheat 10", "default:gold_ingot 2", 17}, + {"default:tree 5", "default:gold_ingot 4", 20}, + {"default:stone 10", "default:gold_ingot 8", 17}, + {"default:desert_stone 10", "default:gold_ingot 8", 27}, + {"default:sapling 1", "default:gold_ingot 1", 7}, + {"default:pick_steel 1", "default:gold_ingot 2", 7}, + {"default:sword_steel 1", "default:gold_ingot 2", 17}, + {"default:shovel_steel 1", "default:gold_ingot 1", 17}, + {"default:cactus 2", "default:gold_ingot 2", 40}, + {"default:papyrus 2", "default:gold_ingot 2", 40}, + {"default:mese_crystal_fragment 1", "default:dirt_with_grass 10", 90}, + {"default:mese_crystal_fragment 1", "default:gold_ingot 5", 90}, + } +} + +-- Trader ( same as NPC but with right-click shop ) + +mobs:register_mob("mobs_npc:trader", { + type = "npc", + passive = false, + damage = 3, + attack_type = "dogfight", + attacks_monsters = true, + attack_animals = false, + attack_npcs = false, + pathfinding = false, + hp_min = 10, + hp_max = 20, + armor = 100, + collisionbox = {-0.35,-1.0,-0.35, 0.35,0.8,0.35}, + visual = "mesh", + mesh = "mobs_character.b3d", + textures = { + {"mobs_trader.png"}, -- by Frerin + {"mobs_trader2.png"}, + {"mobs_trader3.png"}, + }, + makes_footstep_sound = true, + sounds = {}, + walk_velocity = 2, + run_velocity = 3, + jump = false, + drops = {}, + water_damage = 0, + lava_damage = 4, + light_damage = 0, + follow = {"default:diamond"}, + view_range = 15, + owner = "", + order = "stand", + fear_height = 3, + animation = { + speed_normal = 30, + speed_run = 30, + stand_start = 0, + stand_end = 79, + walk_start = 168, + walk_end = 187, + run_start = 168, + run_end = 187, + punch_start = 200, + punch_end = 219, + }, + + on_rightclick = function(self, clicker) + self.attack = nil + mobs_trader(self, clicker, mobs.human) + end, + + on_spawn = function(self) + + self.nametag = S("Trader") + + self.object:set_properties({ + nametag = self.nametag, + nametag_color = "#FFFFFF" + }) + + return true -- return true so on_spawn is run once only + end, +}) + +--This code comes almost exclusively from the trader and inventory of mobf, by Sapier. +--The copyright notice below is from mobf: +------------------------------------------------------------------------------- +-- Mob Framework Mod by Sapier +-- +-- You may copy, use, modify or do nearly anything except removing this +-- copyright notice. +-- And of course you are NOT allow to pretend you have written it. +-- +--! @file inventory.lua +--! @brief component containing mob inventory related functions +--! @copyright Sapier +--! @author Sapier +--! @date 2013-01-02 +-- +--! @defgroup Inventory Inventory subcomponent +--! @brief Component handling mob inventory +--! @ingroup framework_int +--! @{ +-- +-- Contact sapier a t gmx net +------------------------------------------------------------------------------- + +-- This code has been heavily modified by isaiah658. +-- Trades are saved in entity metadata so they always stay the same after +-- initially being chosen. Also the formspec uses item image buttons instead of +-- inventory slots. + +function mobs.add_goods(self, race) + + local trade_index = 1 + local trades_already_added = {} + local trader_pool_size = 10 + local item_pool_size = #race.items -- get number of items on list + + self.trades = {} + + if item_pool_size < trader_pool_size then + trader_pool_size = item_pool_size + end + + for i = 1, trader_pool_size do + + -- If there are more trades than the amount being added, they are + -- randomly selected. If they are equal, there is no reason to randomly + -- select them + local random_trade = nil + + if item_pool_size == trader_pool_size then + random_trade = i + else + while random_trade == nil do + + local num = math.random(item_pool_size) + + if trades_already_added[num] == nil then + trades_already_added[num] = true + random_trade = num + end + end + end + + if math.random(0, 100) > race.items[random_trade][3] then + + self.trades[trade_index] = { + race.items[random_trade][1], + race.items[random_trade][2] + } + + trade_index = trade_index + 1 + end + end +end + + +function mobs_trader(self, clicker, race) + + if not self.id then + self.id = (math.random(1, 1000) * math.random(1, 10000)) + .. self.name .. (math.random(1, 1000) ^ 2) + end + + if not self.game_name then + + self.game_name = tostring(race.names[math.random(1, #race.names)]) + self.nametag = S("Trader @1", self.game_name) + + self.object:set_properties({ + nametag = self.nametag, + nametag_color = "#00FF00" + }) + end + + if self.trades == nil then + mobs.add_goods(self, race) + end + + local player = clicker:get_player_name() or "" + + minetest.chat_send_player(player, + S("[NPC] Hello, @2, have a look at my wares.", + self.game_name, player)) + + -- Make formspec trade list + local formspec_trade_list = "" + local x, y + + for i = 1, 10 do + + if self.trades[i] and self.trades[i] ~= "" then + + if i < 6 then + x = 0.5 + y = i - 0.5 + else + x = 4.5 + y = i - 5.5 + end + + formspec_trade_list = formspec_trade_list + .. "item_image_button[".. x ..",".. y ..";1,1;" + .. self.trades[i][2] .. ";prices#".. i .."#".. self.id ..";]" + .. "item_image_button[".. x + 2 ..",".. y ..";1,1;" + .. self.trades[i][1] .. ";goods#".. i .."#".. self.id ..";]" + .. "image[".. x + 1 ..",".. y ..";1,1;gui_arrow_blank.png]" + end + end + + minetest.show_formspec(player, "mobs_npc:trade", "size[8,10]" + .. default.gui_bg_img + .. default.gui_slots + .. "label[0.5,-0.1;" .. S("Trader @1's stock:", self.game_name) .. "]" + .. formspec_trade_list + .. "list[current_player;main;0,6;8,4;]" + ) +end + + +minetest.register_on_player_receive_fields(function(player, formname, fields) + + if formname ~= "mobs_npc:trade" then return end + + if fields then + + local trade = "" + + for k, v in pairs(fields) do + trade = tostring(k) + end + + local id = trade:split("#")[3] + local self = nil + + if id ~= nil then + + for k, v in pairs(minetest.luaentities) do + + if v.object and v.id and v.id == id then + self = v + break + end + end + end + + if self ~= nil then + + local trade_number = tonumber(trade:split("#")[2]) + + if trade_number ~= nil and self.trades[trade_number] ~= nil then + + local price = self.trades[trade_number][2] + local goods = self.trades[trade_number][1] + local inv = player:get_inventory() + + if inv:contains_item("main", price) then + + inv:remove_item("main", price) + + local leftover = inv:add_item("main", goods) + + if leftover:get_count() > 0 then + + -- drop item(s) in front of player + local droppos = player:get_pos() + local dir = player:get_look_dir() + + droppos.x = droppos.x + dir.x + droppos.z = droppos.z + dir.z + + minetest.add_item(droppos, leftover) + end + end + end + end + end +end) + +mobs:register_egg("mobs_npc:trader", S("Trader"), "default_sandstone.png", 1) + +-- compatibility +mobs:alias_mob("mobs:trader", "mobs_npc:trader")