commit e590f637b2aa449dbae0f7e7e16cb74a33d6140f Author: TenPlus1 Date: Fri Apr 15 15:01:56 2016 +0100 Initial NPC upload diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..cc03398 --- /dev/null +++ b/depends.txt @@ -0,0 +1,2 @@ +default +mobs diff --git a/description.txt b/description.txt new file mode 100644 index 0000000..3936b7f --- /dev/null +++ b/description.txt @@ -0,0 +1 @@ +Adds simple NPC and Trader. diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..4f3267b --- /dev/null +++ b/init.lua @@ -0,0 +1,8 @@ + +local path = minetest.get_modpath("mobs_npc") + +-- NPC +dofile(path .. "/npc.lua") -- TenPlus1 +dofile(path .. "/trader.lua") + +print ("[MOD] Mobs Redo 'NPCs' loaded") diff --git a/mod.conf b/mod.conf new file mode 100644 index 0000000..9646cf7 --- /dev/null +++ b/mod.conf @@ -0,0 +1 @@ +name = mobs_npc diff --git a/npc.lua b/npc.lua new file mode 100644 index 0000000..01e9251 --- /dev/null +++ b/npc.lua @@ -0,0 +1,116 @@ + +-- Npc by TenPlus1 + +mobs.npc_drops = { + "default:pick_steel", "mobs:meat", "default:sword_steel", + "default:shovel_steel", "farming:bread", "bucket:bucket_water" +} + +mobs:register_mob("mobs_npc:npc", { + type = "npc", + passive = false, + damage = 3, + attack_type = "dogfight", + attacks_monsters = true, + pathfinding = true, + hp_min = 10, + hp_max = 20, + armor = 100, + collisionbox = {-0.35,-1.0,-0.35, 0.35,0.8,0.35}, + visual = "mesh", + mesh = "character.b3d", + drawtype = "front", + textures = { + {"mobs_npc.png"}, + {"mobs_npc2.png"}, -- female by nuttmeg20 + }, + child_texture = { + {"mobs_npc_baby.png"}, -- derpy baby by AmirDerAssassine + }, + makes_footstep_sound = true, + sounds = {}, + walk_velocity = 2, + run_velocity = 3, + jump = true, + drops = { + {name = "default:wood", chance = 1, min = 1, max = 3}, + {name = "default:apple", chance = 2, min = 1, max = 2}, + {name = "default:axe_stone", chance = 5, min = 1, max = 1}, + }, + water_damage = 0, + lava_damage = 2, + light_damage = 0, + follow = {"farming:bread", "mobs:meat", "default:diamond"}, + view_range = 15, + owner = "", + order = "follow", + 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) + + -- feed to heal npc + if mobs:feed_tame(self, clicker, 8, true, true) then + return + end + + local item = clicker:get_wielded_item() + local name = clicker:get_player_name() + + -- right clicking with gold lump drops random item from mobs.npc_drops + if item:get_name() == "default:gold_lump" then + + if not minetest.setting_getbool("creative_mode") then + item:take_item() + clicker:set_wielded_item(item) + end + + local pos = self.object:getpos() + + pos.y = pos.y + 0.5 + + minetest.add_item(pos, { + name = mobs.npc_drops[math.random(1, #mobs.npc_drops)] + }) + + minetest.chat_send_player(name, "NPC dropped you an item for gold!") + + return + end + + -- capture npc with net or lasso + mobs:capture_mob(self, clicker, 0, 5, 80, false, nil) + + -- by right-clicking owner can switch npc between follow and stand + if self.owner and self.owner == name then + + if self.order == "follow" then + self.order = "stand" + + minetest.chat_send_player(name, "NPC stands still.") + else + self.order = "follow" + + minetest.chat_send_player(name, "NPC will follow you.") + end + end + + end, +}) + +--mobs:register_spawn("mobs:npc", {"default:dirt_with_grass"}, 20, 0, 7000, 1, 31000) +--mobs:spawn_specific("mobs:npc", {"default:brick"}, {"air"}, 0, 15, 1, 1, 1, 0, 200, true) + +mobs:register_egg("mobs_npc:npc", "Npc", "default_brick.png", 1) + +minetest.register_alias("mobs:npc", "mobs_npc:npc") diff --git a/textures/mobs_npc.png b/textures/mobs_npc.png new file mode 100644 index 0000000..9356398 Binary files /dev/null and b/textures/mobs_npc.png differ diff --git a/textures/mobs_npc2.png b/textures/mobs_npc2.png new file mode 100644 index 0000000..a9d1a2c Binary files /dev/null and b/textures/mobs_npc2.png differ diff --git a/textures/mobs_npc_baby.png b/textures/mobs_npc_baby.png new file mode 100644 index 0000000..e26e450 Binary files /dev/null and b/textures/mobs_npc_baby.png differ diff --git a/textures/mobs_trader.png b/textures/mobs_trader.png new file mode 100644 index 0000000..4c469c9 Binary files /dev/null and b/textures/mobs_trader.png differ diff --git a/trader.lua b/trader.lua new file mode 100644 index 0000000..16b4081 --- /dev/null +++ b/trader.lua @@ -0,0 +1,352 @@ + +mobs.human = { + 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}, + }, + names = { + "Bob", "Duncan", "Bill", "Tom", "James", "Ian", "Lenny" + } +} + +-- 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, + 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 = "character.b3d", + textures = { + {"mobs_trader.png"}, -- by Frerin + }, + 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) + mobs_trader(self, clicker, entity, mobs.human) + 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 +------------------------------------------------------------------------------- + +function mobs.allow_move(inv, from_list, from_index, to_list, to_index, count, player) + + if to_list ~= "selection" + or from_list == "price" + or from_list == "payment" + or from_list == "takeaway" + or from_list == "identifier" then + + return 0 + end + + -- forbid moving split stacks + local old_stack = inv.get_stack(inv, from_list, from_index) + + if count ~= old_stack.get_count(old_stack) then + return 0 + end + + return count +end + +function mobs.allow_put(inv, listname, index, stack, player) + + if listname == "payment" then + return 99 + end + + return 0 +end + +function mobs.allow_take(inv, listname, index, stack, player) + + if listname == "takeaway" + or listname == "payment" then + + return 99 + else + return 0 + end +end + +function mobs.on_put(inv, listname, index, stack) + + if listname == "payment" then + mobs.update_takeaway(inv) + end +end + +function mobs.on_take(inv, listname, count, index, stack, player) + + if listname == "takeaway" then + + local amount = inv:get_stack("payment", 1):get_count() + local price = inv:get_stack("price", 1):get_count() + local thing = inv:get_stack("payment", 1):get_name() + + inv.set_stack(inv,"selection", 1, nil) + inv.set_stack(inv,"price", 1, nil) + inv.set_stack(inv,"takeaway", 1, nil) + inv.set_stack(inv,"payment", 1, thing .. " " .. amount - price) + end + + if listname == "payment" then + + if mobs.check_pay(inv, false) then + + local selection = inv.get_stack(inv, "selection", 1) + + if selection ~= nil then + inv.set_stack(inv,"takeaway", 1, selection) + end + else + inv.set_stack(inv, "takeaway", 1, nil) + end + end +end + +function mobs.update_takeaway(inv) + + if mobs.check_pay(inv,false) then + + local selection = inv.get_stack(inv,"selection", 1) + + if selection ~= nil then + inv.set_stack(inv,"takeaway", 1, selection) + end + else + inv.set_stack(inv,"takeaway", 1, nil) + end +end + +function mobs.check_pay(inv, paynow) + + local now_at_pay = inv.get_stack(inv,"payment", 1) + local count = now_at_pay.get_count(now_at_pay) + local name = now_at_pay.get_name(now_at_pay) + local price = inv.get_stack(inv, "price", 1) + + if price:get_name() == name then + + local price = price:get_count() + + if price > 0 + and price <= count then + + if paynow then + + now_at_pay.take_item(now_at_pay, price) + + inv.set_stack(inv,"payment", 1, now_at_pay) + + return true + else + return true + end + else + if paynow then + inv.set_stack(inv, "payment", 1, nil) + end + end + end + + return false +end + +mobs.trader_inventories = {} + +function mobs.add_goods(entity, race) + + local goods_to_add = nil + + for i = 1, 15 do + + if math.random(0, 100) > race.items[i][3] then + mobs.trader_inventory.set_stack(mobs.trader_inventory, + "goods", i, race.items[i][1]) + end + end +end + +function mobs_trader(self, clicker, entity, race) + + local player = clicker:get_player_name() + + 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 = "Trader " .. self.game_name + + self.object:set_properties({ + nametag = self.nametag, + nametag_color = "#00FF00" + }) + + end + + local unique_entity_id = self.id + local is_inventory = minetest.get_inventory({ + type = "detached", name = unique_entity_id}) + + local move_put_take = { + + allow_move = mobs.allow_move, + allow_put = mobs.allow_put, + allow_take = mobs.allow_take, + + on_move = function(inventory, from_list, from_index, to_list, to_index, count, player) + + if from_list == "goods" + and to_list == "selection" then + + local inv = inventory + local moved = inv.get_stack(inv,to_list, to_index) + local goodname = moved.get_name(moved) + local elements = moved.get_count(moved) + + if elements > count then + + -- remove the surplus parts + inv.set_stack(inv,"selection", 1, + goodname .. " " .. tostring(count)) + + -- the slot we took from is now free + inv.set_stack(inv,"goods",from_index, + goodname .. " " .. tostring(elements - count)) + + -- update the real amount of items in the slot now + elements = count + end + + local good = nil + + for i = 1, #race.items, 1 do + + local stackstring = goodname .." " .. count + + if race.items[i][1] == stackstring then + good = race.items[i] + end + end + + if good ~= nil then + inventory.set_stack(inventory,"price", 1, good[2]) + else + inventory.set_stack(inventory,"price", 1, nil) + end + + mobs.update_takeaway(inv) + + end + end, + + on_put = mobs.on_put, + on_take = mobs.on_take + } + + if is_inventory == nil then + + mobs.trader_inventory = minetest.create_detached_inventory(unique_entity_id, move_put_take) + mobs.trader_inventory.set_size(mobs.trader_inventory,"goods", 15) + mobs.trader_inventory.set_size(mobs.trader_inventory,"takeaway", 1) + mobs.trader_inventory.set_size(mobs.trader_inventory,"selection", 1) + mobs.trader_inventory.set_size(mobs.trader_inventory,"price", 1) + mobs.trader_inventory.set_size(mobs.trader_inventory,"payment", 1) + mobs.add_goods(entity, race) + end + + minetest.chat_send_player(player, "[NPC] Hello, " .. player .. ", have a look at my wares.") + + minetest.show_formspec(player, "trade", "size[8,10;]" + .. default.gui_bg_img + .. default.gui_slots + .. "label[0,0;Trader " .. self.game_name .. "'s stock:]" + .. "list[detached:" .. unique_entity_id .. ";goods;.5,.5;3,5;]" + .. "label[4.5,0.5;Selection]" + .. "list[detached:" .. unique_entity_id .. ";selection;4.5,1;5.5,2;]" + .. "label[6,0.5;Price]" + .. "list[detached:" .. unique_entity_id .. ";price;6,1;7,2;]" + .. "label[4.5,3.5;Payment]" + .. "list[detached:" .. unique_entity_id .. ";payment;4.5,4;5.5,5;]" + .. "label[6,3.5;Bought items]" + .. "list[detached:" .. unique_entity_id .. ";takeaway;6,4;7.5,5.5;]" + .. "list[current_player;main;0,6;8,4;]" + ) +end + +mobs:register_egg("mobs_npc:trader", "Trader", "default_sandstone.png", 1) + +minetest.register_alias("mobs:trader", "mobs_npc:trader")