NPC: Cleaned up debugging logs.
Standarized logs to have different levels. Show by default only INFO, ERROR log messages. Dialogues: Standarized function for NPC chat messages. Removed trader.lua and trader_test.lua which are part of old 'mobs_npc' mod.
This commit is contained in:
parent
bf0f643e3e
commit
a91160ecc6
@ -141,8 +141,8 @@ end
|
|||||||
-- and the NPC is allowed to roam freely.
|
-- and the NPC is allowed to roam freely.
|
||||||
function npc.actions.freeze(self, args)
|
function npc.actions.freeze(self, args)
|
||||||
local freeze_mobs_api = args.freeze
|
local freeze_mobs_api = args.freeze
|
||||||
minetest.log("Received: "..dump(freeze_mobs_api))
|
--minetest.log("Received: "..dump(freeze_mobs_api))
|
||||||
minetest.log("Returning: "..dump(not(freeze_mobs_api)))
|
--minetest.log("Returning: "..dump(not(freeze_mobs_api)))
|
||||||
return not(freeze_mobs_api)
|
return not(freeze_mobs_api)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -333,7 +333,7 @@ function npc.actions.take_item_from_external_inventory(self, args)
|
|||||||
else
|
else
|
||||||
inv = minetest.get_inventory({type="node", pos=pos})
|
inv = minetest.get_inventory({type="node", pos=pos})
|
||||||
end
|
end
|
||||||
-- Create ItemSTack to take from external inventory
|
-- Create ItemStack to take from external inventory
|
||||||
local item = ItemStack(item_name.." "..count)
|
local item = ItemStack(item_name.." "..count)
|
||||||
-- Check if there is enough of the item to take
|
-- Check if there is enough of the item to take
|
||||||
if inv:contains_item(inv_list, item) then
|
if inv:contains_item(inv_list, item) then
|
||||||
@ -369,7 +369,7 @@ end
|
|||||||
-- TODO: Refactor this function so that it uses a table to check
|
-- TODO: Refactor this function so that it uses a table to check
|
||||||
-- for doors instead of having separate logic for each door type
|
-- for doors instead of having separate logic for each door type
|
||||||
function npc.actions.get_openable_node_state(node, npc_dir)
|
function npc.actions.get_openable_node_state(node, npc_dir)
|
||||||
minetest.log("Node name: "..dump(node.name))
|
--minetest.log("Node name: "..dump(node.name))
|
||||||
local state = npc.actions.const.doors.state.CLOSED
|
local state = npc.actions.const.doors.state.CLOSED
|
||||||
-- Check for default doors and gates
|
-- Check for default doors and gates
|
||||||
local a_i1, a_i2 = string.find(node.name, "_a")
|
local a_i1, a_i2 = string.find(node.name, "_a")
|
||||||
@ -383,7 +383,7 @@ function npc.actions.get_openable_node_state(node, npc_dir)
|
|||||||
if a_i1 == nil and open_i1 == nil and not half_door_is_closed then
|
if a_i1 == nil and open_i1 == nil and not half_door_is_closed then
|
||||||
state = npc.actions.const.doors.state.OPEN
|
state = npc.actions.const.doors.state.OPEN
|
||||||
end
|
end
|
||||||
minetest.log("Door state: "..dump(state))
|
--minetest.log("Door state: "..dump(state))
|
||||||
return state
|
return state
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -412,10 +412,10 @@ end
|
|||||||
-- items from a chest, are provided here.
|
-- items from a chest, are provided here.
|
||||||
|
|
||||||
local function get_pos_argument(self, pos)
|
local function get_pos_argument(self, pos)
|
||||||
minetest.log("Type of pos: "..dump(type(pos)))
|
--minetest.log("Type of pos: "..dump(type(pos)))
|
||||||
-- Check which type of position argument we received
|
-- Check which type of position argument we received
|
||||||
if type(pos) == "table" then
|
if type(pos) == "table" then
|
||||||
minetest.log("Received table pos: "..dump(pos))
|
--minetest.log("Received table pos: "..dump(pos))
|
||||||
-- Check if table is position
|
-- Check if table is position
|
||||||
if pos.x ~= nil and pos.y ~= nil and pos.z ~= nil then
|
if pos.x ~= nil and pos.y ~= nil and pos.z ~= nil then
|
||||||
-- Position received, return position
|
-- Position received, return position
|
||||||
@ -468,7 +468,7 @@ end
|
|||||||
function npc.actions.use_furnace(self, args)
|
function npc.actions.use_furnace(self, args)
|
||||||
local pos = get_pos_argument(self, args.pos)
|
local pos = get_pos_argument(self, args.pos)
|
||||||
if pos == nil then
|
if pos == nil then
|
||||||
minetest.log("[advanced_npc] WARNING Got nil position in 'use_furnace' using args.pos: "..dump(args.pos))
|
npc.log("WARNING", "Got nil position in 'use_furnace' using args.pos: "..dump(args.pos))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -478,14 +478,14 @@ function npc.actions.use_furnace(self, args)
|
|||||||
-- will mainly use this as fuels to avoid getting useful
|
-- will mainly use this as fuels to avoid getting useful
|
||||||
-- items (such as coal lumps) for burning
|
-- items (such as coal lumps) for burning
|
||||||
local fuels = {"default:leaves",
|
local fuels = {"default:leaves",
|
||||||
"default:pine_needles",
|
"default:pine_needles",
|
||||||
"default:tree",
|
"default:tree",
|
||||||
"default:acacia_tree",
|
"default:acacia_tree",
|
||||||
"default:aspen_tree",
|
"default:aspen_tree",
|
||||||
"default:jungletree",
|
"default:jungletree",
|
||||||
"default:pine_tree",
|
"default:pine_tree",
|
||||||
"default:coalblock",
|
"default:coalblock",
|
||||||
"farming:straw"}
|
"farming:straw"}
|
||||||
|
|
||||||
-- Check if NPC has item to cook
|
-- Check if NPC has item to cook
|
||||||
local src_item = npc.inventory_contains(self, npc.get_item_name(item))
|
local src_item = npc.inventory_contains(self, npc.get_item_name(item))
|
||||||
@ -503,15 +503,15 @@ function npc.actions.use_furnace(self, args)
|
|||||||
local fuel_time =
|
local fuel_time =
|
||||||
minetest.get_craft_result({method="fuel", width=1, items={ItemStack(fuel_item.item_string)}}).time
|
minetest.get_craft_result({method="fuel", width=1, items={ItemStack(fuel_item.item_string)}}).time
|
||||||
local total_fuel_time = fuel_time * npc.get_item_count(fuel_item.item_string)
|
local total_fuel_time = fuel_time * npc.get_item_count(fuel_item.item_string)
|
||||||
minetest.log("Fuel time: "..dump(fuel_time))
|
npc.log("DEBUG", "Fuel time: "..dump(fuel_time))
|
||||||
|
|
||||||
-- Get item to cook's cooking time
|
-- Get item to cook's cooking time
|
||||||
local cook_result =
|
local cook_result =
|
||||||
minetest.get_craft_result({method="cooking", width=1, items={ItemStack(src_item.item_string)}})
|
minetest.get_craft_result({method="cooking", width=1, items={ItemStack(src_item.item_string)}})
|
||||||
local total_cook_time = cook_result.time * npc.get_item_count(item)
|
local total_cook_time = cook_result.time * npc.get_item_count(item)
|
||||||
minetest.log("Cook: "..dump(cook_result))
|
npc.log("DEBUG", "Cook: "..dump(cook_result))
|
||||||
|
|
||||||
minetest.log("Total cook time: "..total_cook_time
|
npc.log("DEBUG", "Total cook time: "..total_cook_time
|
||||||
..", total fuel burn time: "..dump(total_fuel_time))
|
..", total fuel burn time: "..dump(total_fuel_time))
|
||||||
|
|
||||||
-- Check if there is enough fuel to cook all items
|
-- Check if there is enough fuel to cook all items
|
||||||
@ -531,7 +531,7 @@ function npc.actions.use_furnace(self, args)
|
|||||||
fuel_amount = 1
|
fuel_amount = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.log("Amount of fuel needed: "..fuel_amount)
|
npc.log("DEBUG", "Amount of fuel needed: "..fuel_amount)
|
||||||
|
|
||||||
-- Put this item on the fuel inventory list of the furnace
|
-- Put this item on the fuel inventory list of the furnace
|
||||||
local args = {
|
local args = {
|
||||||
@ -554,7 +554,7 @@ function npc.actions.use_furnace(self, args)
|
|||||||
npc.add_action(self, npc.actions.cmd.PUT_ITEM, args)
|
npc.add_action(self, npc.actions.cmd.PUT_ITEM, args)
|
||||||
|
|
||||||
-- Now, set NPC to wait until furnace is done.
|
-- Now, set NPC to wait until furnace is done.
|
||||||
minetest.log("Setting wait action for "..dump(total_cook_time))
|
npc.log("DEBUG", "Setting wait action for "..dump(total_cook_time))
|
||||||
npc.add_action(self, npc.actions.cmd.SET_INTERVAL, {interval=total_cook_time, freeze=freeze})
|
npc.add_action(self, npc.actions.cmd.SET_INTERVAL, {interval=total_cook_time, freeze=freeze})
|
||||||
|
|
||||||
-- Reset timer
|
-- Reset timer
|
||||||
@ -563,7 +563,7 @@ function npc.actions.use_furnace(self, args)
|
|||||||
-- If freeze is false, then we will have to find the way back to the furnace
|
-- If freeze is false, then we will have to find the way back to the furnace
|
||||||
-- once cooking is done.
|
-- once cooking is done.
|
||||||
if freeze == false then
|
if freeze == false then
|
||||||
minetest.log("Adding walk to position to wandering: "..dump(pos))
|
npc.log("DEBUG", "Adding walk to position to wandering: "..dump(pos))
|
||||||
npc.add_task(self, npc.actions.cmd.WALK_TO_POS, {end_pos=pos, walkable={}})
|
npc.add_task(self, npc.actions.cmd.WALK_TO_POS, {end_pos=pos, walkable={}})
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -577,10 +577,10 @@ function npc.actions.use_furnace(self, args)
|
|||||||
count = npc.get_item_count(item),
|
count = npc.get_item_count(item),
|
||||||
is_furnace = false
|
is_furnace = false
|
||||||
}
|
}
|
||||||
minetest.log("Taking item back: "..minetest.pos_to_string(pos))
|
npc.log("DEBUG", "Taking item back: "..minetest.pos_to_string(pos))
|
||||||
npc.add_action(self, npc.actions.cmd.TAKE_ITEM, args)
|
npc.add_action(self, npc.actions.cmd.TAKE_ITEM, args)
|
||||||
|
|
||||||
minetest.log("Inventory: "..dump(self.inventory))
|
npc.log("DEBUG", "Inventory: "..dump(self.inventory))
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
@ -594,7 +594,7 @@ end
|
|||||||
function npc.actions.use_bed(self, args)
|
function npc.actions.use_bed(self, args)
|
||||||
local pos = get_pos_argument(self, args.pos)
|
local pos = get_pos_argument(self, args.pos)
|
||||||
if pos == nil then
|
if pos == nil then
|
||||||
minetest.log("[advanced_npc] WARNING Got nil position in 'use_bed' using args.pos: "..dump(args.pos))
|
npc.log("WARNING", "Got nil position in 'use_bed' using args.pos: "..dump(args.pos))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local action = args.action
|
local action = args.action
|
||||||
@ -654,7 +654,7 @@ end
|
|||||||
function npc.actions.use_sittable(self, args)
|
function npc.actions.use_sittable(self, args)
|
||||||
local pos = get_pos_argument(self, args.pos)
|
local pos = get_pos_argument(self, args.pos)
|
||||||
if pos == nil then
|
if pos == nil then
|
||||||
minetest.log("[advanced_npc] WARNING Got nil position in 'use_sittable' using args.pos: "..dump(args.pos))
|
npc.log("WARNING", "Got nil position in 'use_sittable' using args.pos: "..dump(args.pos))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local action = args.action
|
local action = args.action
|
||||||
@ -727,7 +727,7 @@ function npc.actions.walk_to_pos(self, args)
|
|||||||
-- Get arguments for this task
|
-- Get arguments for this task
|
||||||
local end_pos = get_pos_argument(self, args.end_pos)
|
local end_pos = get_pos_argument(self, args.end_pos)
|
||||||
if end_pos == nil then
|
if end_pos == nil then
|
||||||
minetest.log("[advanced_npc] WARNING Got nil position in 'walk_to_pos' using args.pos: "..dump(args.end_pos))
|
npc.log("WARNING", "Got nil position in 'walk_to_pos' using args.pos: "..dump(args.end_pos))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local enforce_move = args.enforce_move or true
|
local enforce_move = args.enforce_move or true
|
||||||
@ -737,8 +737,8 @@ function npc.actions.walk_to_pos(self, args)
|
|||||||
local start_pos = vector.round(self.object:getpos())
|
local start_pos = vector.round(self.object:getpos())
|
||||||
-- Use y of end_pos (this can only be done assuming flat terrain)
|
-- Use y of end_pos (this can only be done assuming flat terrain)
|
||||||
--start_pos.y = self.object:getpos().y
|
--start_pos.y = self.object:getpos().y
|
||||||
minetest.log("[advanced_npc] INFO walk_to_pos: Start pos: "..minetest.pos_to_string(start_pos))
|
npc.log("DEBUG", "walk_to_pos: Start pos: "..minetest.pos_to_string(start_pos))
|
||||||
minetest.log("[advanced_npc] INFO walk_to_pos: End pos: "..minetest.pos_to_string(end_pos))
|
npc.log("DEBUG", "walk_to_pos: End pos: "..minetest.pos_to_string(end_pos))
|
||||||
|
|
||||||
-- Set walkable nodes to empty if the parameter hasn't been used
|
-- Set walkable nodes to empty if the parameter hasn't been used
|
||||||
if walkable_nodes == nil then
|
if walkable_nodes == nil then
|
||||||
@ -759,11 +759,8 @@ function npc.actions.walk_to_pos(self, args)
|
|||||||
end
|
end
|
||||||
path = path_detail
|
path = path_detail
|
||||||
|
|
||||||
--minetest.log("Found path: "..dump(path))
|
npc.log("DEBUG", "Detailed path: "..dump(path))
|
||||||
|
npc.log("INFO", "walk_to_pos Found path to node: "..minetest.pos_to_string(end_pos))
|
||||||
--minetest.log("Path detail: "..dump(path_detail))
|
|
||||||
--minetest.log("New path: "..dump(path))
|
|
||||||
minetest.log("[advanced_npc] INFO walk_to_pos Found path to node: "..minetest.pos_to_string(end_pos))
|
|
||||||
-- Store path
|
-- Store path
|
||||||
self.actions.walking.path = path
|
self.actions.walking.path = path
|
||||||
|
|
||||||
@ -784,6 +781,8 @@ function npc.actions.walk_to_pos(self, args)
|
|||||||
if (i+1) == #path then
|
if (i+1) == #path then
|
||||||
-- Add direction to last node
|
-- Add direction to last node
|
||||||
local dir = npc.actions.get_direction(path[i].pos, end_pos)
|
local dir = npc.actions.get_direction(path[i].pos, end_pos)
|
||||||
|
-- Add the last step
|
||||||
|
npc.add_action(self, npc.actions.cmd.WALK_STEP, {dir = dir, speed = speed, target_pos = path[i+1].pos})
|
||||||
-- Add stand animation at end
|
-- Add stand animation at end
|
||||||
npc.add_action(self, npc.actions.cmd.STAND, {dir = dir})
|
npc.add_action(self, npc.actions.cmd.STAND, {dir = dir})
|
||||||
break
|
break
|
||||||
@ -823,7 +822,7 @@ function npc.actions.walk_to_pos(self, args)
|
|||||||
-- end
|
-- end
|
||||||
-- local pos_on_close = {x=path[i+1].pos.x + x_adj, y=path[i+1].pos.y + 1, z=path[i+1].pos.z + z_adj}
|
-- local pos_on_close = {x=path[i+1].pos.x + x_adj, y=path[i+1].pos.y + 1, z=path[i+1].pos.z + z_adj}
|
||||||
-- Add extra walk step to ensure that one is standing at other side of openable node
|
-- Add extra walk step to ensure that one is standing at other side of openable node
|
||||||
npc.add_action(self, npc.actions.cmd.WALK_STEP, {dir = dir, speed = speed, target_pos = path[i+2].pos})
|
-- npc.add_action(self, npc.actions.cmd.WALK_STEP, {dir = dir, speed = speed, target_pos = path[i+2].pos})
|
||||||
-- Stop to close the door
|
-- Stop to close the door
|
||||||
npc.add_action(self, npc.actions.cmd.STAND, {dir=(dir + 2) % 4 })--, pos=pos_on_close})
|
npc.add_action(self, npc.actions.cmd.STAND, {dir=(dir + 2) % 4 })--, pos=pos_on_close})
|
||||||
-- Close door
|
-- Close door
|
||||||
@ -840,7 +839,7 @@ function npc.actions.walk_to_pos(self, args)
|
|||||||
|
|
||||||
else
|
else
|
||||||
-- Unable to find path
|
-- Unable to find path
|
||||||
minetest.log("[advanced_npc] INFO walk_to_pos Unable to find path. Teleporting to: "..minetest.pos_to_string(end_pos))
|
npc.log("WARNING", "walk_to_pos Unable to find path. Teleporting to: "..minetest.pos_to_string(end_pos))
|
||||||
-- Check if movement is enforced
|
-- Check if movement is enforced
|
||||||
if enforce_move then
|
if enforce_move then
|
||||||
-- Move to end pos
|
-- Move to end pos
|
||||||
|
@ -124,7 +124,7 @@ function npc.places.find_node_orthogonally(pos, nodes, y_adjustment)
|
|||||||
local result = {}
|
local result = {}
|
||||||
for _,point in pairs(points) do
|
for _,point in pairs(points) do
|
||||||
local node = minetest.get_node(point)
|
local node = minetest.get_node(point)
|
||||||
minetest.log("Found node: "..dump(node)..", at pos: "..dump(point))
|
--minetest.log("Found node: "..dump(node)..", at pos: "..dump(point))
|
||||||
for _,node_name in pairs(nodes) do
|
for _,node_name in pairs(nodes) do
|
||||||
if node.name == node_name then
|
if node.name == node_name then
|
||||||
table.insert(result, {name=node.name, pos=point, param2=node.param2})
|
table.insert(result, {name=node.name, pos=point, param2=node.param2})
|
||||||
@ -194,8 +194,8 @@ function npc.places.find_entrance_from_openable_nodes(all_openable_nodes, marker
|
|||||||
--local path = pathfinder.find_path(start_pos, end_pos, 20, {})
|
--local path = pathfinder.find_path(start_pos, end_pos, 20, {})
|
||||||
local entity = {}
|
local entity = {}
|
||||||
entity.collisionbox = {-0.20,-1.0,-0.20, 0.20,0.8,0.20}
|
entity.collisionbox = {-0.20,-1.0,-0.20, 0.20,0.8,0.20}
|
||||||
minetest.log("Start pos: "..minetest.pos_to_string(start_pos))
|
--minetest.log("Start pos: "..minetest.pos_to_string(start_pos))
|
||||||
minetest.log("End pos: "..minetest.pos_to_string(end_pos))
|
--minetest.log("End pos: "..minetest.pos_to_string(end_pos))
|
||||||
local path = pathfinder.find_path(start_pos, end_pos, entity)
|
local path = pathfinder.find_path(start_pos, end_pos, entity)
|
||||||
--minetest.log("Found path: "..dump(path))
|
--minetest.log("Found path: "..dump(path))
|
||||||
if path ~= nil then
|
if path ~= nil then
|
||||||
@ -217,13 +217,13 @@ function npc.places.find_entrance_from_openable_nodes(all_openable_nodes, marker
|
|||||||
-- Check if min-distance door is a cottages door
|
-- Check if min-distance door is a cottages door
|
||||||
-- while we have a MTG door
|
-- while we have a MTG door
|
||||||
if min_node_name == "cottages:half_door" and doors_st ~= nil then
|
if min_node_name == "cottages:half_door" and doors_st ~= nil then
|
||||||
minetest.log("Assigned new door...")
|
--minetest.log("Assigned new door...")
|
||||||
min = #path
|
min = #path
|
||||||
result = openable_nodes[i]
|
result = openable_nodes[i]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
minetest.log("Path not found to marker from "..minetest.pos_to_string(start_pos))
|
npc.log("ERROR", "Path not found to marker from "..minetest.pos_to_string(start_pos))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -302,7 +302,7 @@ function npc.places.is_in_staircase(pos)
|
|||||||
-- Get next node
|
-- Get next node
|
||||||
local upper_node = minetest.get_node(upper_pos)
|
local upper_node = minetest.get_node(upper_pos)
|
||||||
local lower_node = minetest.get_node(lower_pos)
|
local lower_node = minetest.get_node(lower_pos)
|
||||||
minetest.log("Next node: "..dump(upper_pos))
|
--minetest.log("Next node: "..dump(upper_pos))
|
||||||
-- Check if next node is also a stairs node
|
-- Check if next node is also a stairs node
|
||||||
local up_p1, up_p2 = string.find(upper_node.name, "stairs:")
|
local up_p1, up_p2 = string.find(upper_node.name, "stairs:")
|
||||||
local lo_p1, lo_p2 = string.find(lower_node.name, "stairs:")
|
local lo_p1, lo_p2 = string.find(lower_node.name, "stairs:")
|
||||||
@ -351,7 +351,7 @@ end
|
|||||||
-- front of a door. Used to make NPCs exit buildings.
|
-- front of a door. Used to make NPCs exit buildings.
|
||||||
function npc.places.find_node_in_front_of_door(door_pos)
|
function npc.places.find_node_in_front_of_door(door_pos)
|
||||||
local door = minetest.get_node(door_pos)
|
local door = minetest.get_node(door_pos)
|
||||||
minetest.log("Param2 of door: "..dump(door.param2))
|
--minetest.log("Param2 of door: "..dump(door.param2))
|
||||||
if door.param2 == 0 then
|
if door.param2 == 0 then
|
||||||
-- Looking south
|
-- Looking south
|
||||||
return {x=door_pos.x, y=door_pos.y, z=door_pos.z - 1}
|
return {x=door_pos.x, y=door_pos.y, z=door_pos.z - 1}
|
||||||
|
@ -296,7 +296,7 @@ function npc.dialogue.process_dialogue(self, dialogue, player_name)
|
|||||||
|
|
||||||
-- Send dialogue line
|
-- Send dialogue line
|
||||||
if dialogue.text then
|
if dialogue.text then
|
||||||
minetest.chat_send_player(player_name, self.npc_name..": "..dialogue.text)
|
npc.chat(self.npc_name, player_name, dialogue.text)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check if dialogue has responses. If it doesn't, unlock the actions
|
-- Check if dialogue has responses. If it doesn't, unlock the actions
|
||||||
|
1
init.lua
1
init.lua
@ -23,7 +23,6 @@ else
|
|||||||
end
|
end
|
||||||
mobs.intllib = S
|
mobs.intllib = S
|
||||||
|
|
||||||
-- NPC
|
|
||||||
dofile(path .. "/npc.lua")
|
dofile(path .. "/npc.lua")
|
||||||
dofile(path .. "/spawner.lua")
|
dofile(path .. "/spawner.lua")
|
||||||
dofile(path .. "/relationships.lua")
|
dofile(path .. "/relationships.lua")
|
||||||
|
46
npc.lua
46
npc.lua
@ -42,9 +42,27 @@ npc.action_state = {
|
|||||||
interrupted = 2
|
interrupted = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
npc.log_level = {
|
||||||
|
INFO = true,
|
||||||
|
WARNING = false,
|
||||||
|
ERROR = true,
|
||||||
|
DEBUG = false
|
||||||
|
}
|
||||||
|
|
||||||
---------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------
|
||||||
-- General functions
|
-- General functions
|
||||||
---------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------
|
||||||
|
-- Logging
|
||||||
|
function npc.log(level, message)
|
||||||
|
if npc.log_level[level] then
|
||||||
|
minetest.log("[advanced_npc] "..type..": "..message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- NPC chat
|
||||||
|
function npc.chat(npc_name, player_name, message)
|
||||||
|
minetest.chat_send_player(player_name, npc_name..": "..message)
|
||||||
|
|
||||||
-- Gets name of player or NPC
|
-- Gets name of player or NPC
|
||||||
function npc.get_entity_name(entity)
|
function npc.get_entity_name(entity)
|
||||||
if entity:is_player() then
|
if entity:is_player() then
|
||||||
@ -176,7 +194,7 @@ end
|
|||||||
-- Spawn function. Initializes all variables that the
|
-- Spawn function. Initializes all variables that the
|
||||||
-- NPC will have and choose random, starting values
|
-- NPC will have and choose random, starting values
|
||||||
function npc.initialize(entity, pos, is_lua_entity, npc_stats)
|
function npc.initialize(entity, pos, is_lua_entity, npc_stats)
|
||||||
minetest.log("[advanced_npc] INFO: Initializing NPC at "..minetest.pos_to_string(pos))
|
npc.log("INFO", "Initializing NPC at "..minetest.pos_to_string(pos))
|
||||||
|
|
||||||
-- Get variables
|
-- Get variables
|
||||||
local ent = entity
|
local ent = entity
|
||||||
@ -426,7 +444,7 @@ function npc.initialize(entity, pos, is_lua_entity, npc_stats)
|
|||||||
table.insert(ent.trader_data.custom_trades, offer2)
|
table.insert(ent.trader_data.custom_trades, offer2)
|
||||||
|
|
||||||
--minetest.log(dump(ent))
|
--minetest.log(dump(ent))
|
||||||
minetest.log("[advanced_npc] INFO Successfully initialized NPC with name "..dump(ent.npc_name))
|
npc.log("INFO", "Successfully initialized NPC with name "..dump(ent.npc_name))
|
||||||
-- Refreshes entity
|
-- Refreshes entity
|
||||||
ent.object:set_properties(ent)
|
ent.object:set_properties(ent)
|
||||||
end
|
end
|
||||||
@ -596,7 +614,7 @@ end
|
|||||||
function npc.execute_action(self)
|
function npc.execute_action(self)
|
||||||
-- Check if an action was interrupted
|
-- Check if an action was interrupted
|
||||||
if self.actions.current_action_state == npc.action_state.interrupted then
|
if self.actions.current_action_state == npc.action_state.interrupted then
|
||||||
minetest.log("[advanced_npc] DEBUG Re-inserting interrupted action for NPC: '"..dump(self.npc_name).."': "..dump(self.actions.state_before_lock.interrupted_action))
|
npc.log("DEBUG", "Re-inserting interrupted action for NPC: '"..dump(self.npc_name).."': "..dump(self.actions.state_before_lock.interrupted_action))
|
||||||
-- Insert into queue the interrupted action
|
-- Insert into queue the interrupted action
|
||||||
table.insert(self.actions.queue, 1, self.actions.state_before_lock.interrupted_action)
|
table.insert(self.actions.queue, 1, self.actions.state_before_lock.interrupted_action)
|
||||||
-- Clear the action
|
-- Clear the action
|
||||||
@ -618,7 +636,7 @@ function npc.execute_action(self)
|
|||||||
-- If the entry is a task, then push all this new operations in
|
-- If the entry is a task, then push all this new operations in
|
||||||
-- stack fashion
|
-- stack fashion
|
||||||
if action_obj.is_task == true then
|
if action_obj.is_task == true then
|
||||||
minetest.log("[advanced_npc] DEBUG Executing task for NPC '"..dump(self.npc_name).."': "..dump(action_obj))
|
npc.log("DEBUG", "Executing task for NPC '"..dump(self.npc_name).."': "..dump(action_obj))
|
||||||
-- Backup current queue
|
-- Backup current queue
|
||||||
local backup_queue = self.actions.queue
|
local backup_queue = self.actions.queue
|
||||||
-- Remove this "task" action from queue
|
-- Remove this "task" action from queue
|
||||||
@ -634,7 +652,7 @@ function npc.execute_action(self)
|
|||||||
table.insert(self.actions.queue, backup_queue[i])
|
table.insert(self.actions.queue, backup_queue[i])
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
minetest.log("[advanced_npc] DEBUG Executing action for NPC '"..dump(self.npc_name).."': "..dump(action_obj))
|
npc.log("DEBUG", "Executing action for NPC '"..dump(self.npc_name).."': "..dump(action_obj))
|
||||||
-- Store the action that is being executed
|
-- Store the action that is being executed
|
||||||
self.actions.state_before_lock.interrupted_action = action_obj
|
self.actions.state_before_lock.interrupted_action = action_obj
|
||||||
-- Store current position
|
-- Store current position
|
||||||
@ -689,7 +707,7 @@ function npc.lock_actions(self)
|
|||||||
-- Freeze mobs_redo API
|
-- Freeze mobs_redo API
|
||||||
self.freeze = false
|
self.freeze = false
|
||||||
|
|
||||||
minetest.log("Locking")
|
npc.log("DEBUG", "Locking NPC "..dump(self.npc_id).." actions")
|
||||||
end
|
end
|
||||||
|
|
||||||
function npc.unlock_actions(self)
|
function npc.unlock_actions(self)
|
||||||
@ -703,7 +721,7 @@ function npc.unlock_actions(self)
|
|||||||
self.freeze = true
|
self.freeze = true
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.log("Unlocked")
|
npc.log("DEBUG", "Unlocked NPC "..dump(self.npc_id).." actions")
|
||||||
end
|
end
|
||||||
|
|
||||||
---------------------------------------------------------------------------------------
|
---------------------------------------------------------------------------------------
|
||||||
@ -863,7 +881,7 @@ mobs:register_mob("advanced_npc:npc", {
|
|||||||
{"npc_female1.png"}, -- female by nuttmeg20
|
{"npc_female1.png"}, -- female by nuttmeg20
|
||||||
},
|
},
|
||||||
child_texture = {
|
child_texture = {
|
||||||
{"npc_baby_male1.png"}, -- derpy baby by AmirDerAssassine
|
{"npc_baby_male1.png"},
|
||||||
{"npc_baby_female1.png"},
|
{"npc_baby_female1.png"},
|
||||||
},
|
},
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
@ -915,11 +933,7 @@ mobs:register_mob("advanced_npc:npc", {
|
|||||||
--self.base_texture = "mobs_npc_child_male1.png"
|
--self.base_texture = "mobs_npc_child_male1.png"
|
||||||
--self.object:set_properties(self)
|
--self.object:set_properties(self)
|
||||||
|
|
||||||
minetest.log(dump(self))
|
npc.log("DEBUG", "Right-clicked NPC: "..dump(self))
|
||||||
|
|
||||||
minetest.log("Child: "..dump(self.is_child))
|
|
||||||
minetest.log("Sex: "..dump(self.sex))
|
|
||||||
minetest.log("Textures: "..dump(self.textures))
|
|
||||||
|
|
||||||
-- Receive gift or start chat. If player has no item in hand
|
-- Receive gift or start chat. If player has no item in hand
|
||||||
-- then it is going to start chat directly
|
-- then it is going to start chat directly
|
||||||
@ -952,7 +966,7 @@ mobs:register_mob("advanced_npc:npc", {
|
|||||||
-- Initialize NPC if spawned using the spawn egg built in from
|
-- Initialize NPC if spawned using the spawn egg built in from
|
||||||
-- mobs_redo. This functionality will be removed in the future in
|
-- mobs_redo. This functionality will be removed in the future in
|
||||||
-- favor of a better manual spawning method with customization
|
-- favor of a better manual spawning method with customization
|
||||||
minetest.log("[advanced_npc] WARNING: Initializing NPC from entity step. This message should only be appearing if an NPC is being spawned from inventory with egg!")
|
npc.log("WARNING", "Initializing NPC from entity step. This message should only be appearing if an NPC is being spawned from inventory with egg!")
|
||||||
npc.initialize(self, self.object:getpos(), true)
|
npc.initialize(self, self.object:getpos(), true)
|
||||||
else
|
else
|
||||||
self.tamed = false
|
self.tamed = false
|
||||||
@ -1049,7 +1063,7 @@ mobs:register_mob("advanced_npc:npc", {
|
|||||||
-- to action queue. This is for jobs.
|
-- to action queue. This is for jobs.
|
||||||
-- TODO: Need to implement
|
-- TODO: Need to implement
|
||||||
else
|
else
|
||||||
minetest.log("Adding actions to action queue")
|
npc.log("DEBUG", "Adding actions to action queue")
|
||||||
-- Add to action queue all actions on schedule
|
-- Add to action queue all actions on schedule
|
||||||
for i = 1, #schedule[time] do
|
for i = 1, #schedule[time] do
|
||||||
if schedule[time][i].action == nil then
|
if schedule[time][i].action == nil then
|
||||||
@ -1060,7 +1074,7 @@ mobs:register_mob("advanced_npc:npc", {
|
|||||||
npc.add_action(self, schedule[time][i].action, schedule[time][i].args)
|
npc.add_action(self, schedule[time][i].action, schedule[time][i].args)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
minetest.log("New action queue: "..dump(self.actions))
|
npc.log("DEBUG", "New action queue: "..dump(self.actions))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
50
spawner.lua
50
spawner.lua
@ -209,7 +209,7 @@ function spawner.assign_places(self, pos)
|
|||||||
-- Find unowned bed
|
-- Find unowned bed
|
||||||
for i = 1, #node_data.bed_type do
|
for i = 1, #node_data.bed_type do
|
||||||
-- Check if bed has owner
|
-- Check if bed has owner
|
||||||
minetest.log("Node: "..dump(node_data.bed_type[i]))
|
--minetest.log("Node: "..dump(node_data.bed_type[i]))
|
||||||
if node_data.bed_type[i].owner == "" then
|
if node_data.bed_type[i].owner == "" then
|
||||||
-- If bed has no owner, check if it is accessible
|
-- If bed has no owner, check if it is accessible
|
||||||
local empty_nodes = npc.places.find_node_orthogonally(
|
local empty_nodes = npc.places.find_node_orthogonally(
|
||||||
@ -223,7 +223,7 @@ function spawner.assign_places(self, pos)
|
|||||||
npc.places.PLACE_TYPE.BED.PRIMARY, node_data.bed_type[i].node_pos, empty_nodes[1].pos)
|
npc.places.PLACE_TYPE.BED.PRIMARY, node_data.bed_type[i].node_pos, empty_nodes[1].pos)
|
||||||
-- Store changes to node_data
|
-- Store changes to node_data
|
||||||
meta:set_string("node_data", minetest.serialize(node_data))
|
meta:set_string("node_data", minetest.serialize(node_data))
|
||||||
minetest.log("Added bed at "..minetest.pos_to_string(node_data.bed_type[i].node_pos)
|
npc.log("DEBUG", "Added bed at "..minetest.pos_to_string(node_data.bed_type[i].node_pos)
|
||||||
.." to NPC "..dump(self.npc_name))
|
.." to NPC "..dump(self.npc_name))
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
@ -233,7 +233,7 @@ function spawner.assign_places(self, pos)
|
|||||||
|
|
||||||
--local plot_info = minetest.deserialize(meta:get_string("plot_info"))
|
--local plot_info = minetest.deserialize(meta:get_string("plot_info"))
|
||||||
--minetest.log("Plot info:"..dump(plot_info))
|
--minetest.log("Plot info:"..dump(plot_info))
|
||||||
minetest.log("places: "..dump(self.places_map))
|
npc.log("DEBUG", "Places for NPC "..self.npc_name..": "..dump(self.places_map))
|
||||||
|
|
||||||
-- Make NPC go into their house
|
-- Make NPC go into their house
|
||||||
npc.add_task(self,
|
npc.add_task(self,
|
||||||
@ -274,9 +274,9 @@ function npc.spawner.spawn_npc(pos)
|
|||||||
-- Check amount of NPCs that should be spawned
|
-- Check amount of NPCs that should be spawned
|
||||||
local npc_count = meta:get_int("npc_count")
|
local npc_count = meta:get_int("npc_count")
|
||||||
local spawned_npc_count = meta:get_int("spawned_npc_count")
|
local spawned_npc_count = meta:get_int("spawned_npc_count")
|
||||||
minetest.log("[advanced_npc] INFO Currently spawned "..dump(spawned_npc_count).." of "..dump(npc_count).." NPCs")
|
npc.log("INFO", "Currently spawned "..dump(spawned_npc_count).." of "..dump(npc_count).." NPCs")
|
||||||
if spawned_npc_count < npc_count then
|
if spawned_npc_count < npc_count then
|
||||||
minetest.log("[advanced_npc] INFO Spawning NPC at "..minetest.pos_to_string(pos))
|
npc.log("INFO", "Spawning NPC at "..minetest.pos_to_string(pos))
|
||||||
-- Spawn a NPC
|
-- Spawn a NPC
|
||||||
local ent = minetest.add_entity({x=pos.x, y=pos.y+1, z=pos.z}, "advanced_npc:npc")
|
local ent = minetest.add_entity({x=pos.x, y=pos.y+1, z=pos.z}, "advanced_npc:npc")
|
||||||
if ent and ent:get_luaentity() then
|
if ent and ent:get_luaentity() then
|
||||||
@ -324,21 +324,21 @@ function npc.spawner.spawn_npc(pos)
|
|||||||
meta:set_string("npc_stats", minetest.serialize(npc_stats))
|
meta:set_string("npc_stats", minetest.serialize(npc_stats))
|
||||||
-- Temp
|
-- Temp
|
||||||
--meta:set_string("infotext", meta:get_string("infotext")..", "..spawned_npc_count)
|
--meta:set_string("infotext", meta:get_string("infotext")..", "..spawned_npc_count)
|
||||||
minetest.log("[advanced_npc] INFO Spawning successful!")
|
npc.log("INFO", "Spawning successful!")
|
||||||
-- Check if there are more NPCs to spawn
|
-- Check if there are more NPCs to spawn
|
||||||
if spawned_npc_count >= npc_count then
|
if spawned_npc_count >= npc_count then
|
||||||
-- Stop timer
|
-- Stop timer
|
||||||
minetest.log("[advanced_npc] INFO No more NPCs to spawn at this location")
|
npc.log("INFO", "No more NPCs to spawn at this location")
|
||||||
timer:stop()
|
timer:stop()
|
||||||
else
|
else
|
||||||
-- Start another timer to spawn more NPC
|
-- Start another timer to spawn more NPC
|
||||||
local new_delay = math.random(npc.spawner.spawn_delay)
|
local new_delay = math.random(npc.spawner.spawn_delay)
|
||||||
minetest.log("[advanced_npc] INFO Spawning one more NPC in "..dump(npc.spawner.spawn_delay).."s")
|
npc.log("INFO", "Spawning one more NPC in "..dump(npc.spawner.spawn_delay).."s")
|
||||||
timer:start(new_delay)
|
timer:start(new_delay)
|
||||||
end
|
end
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
minetest.log("[advanced_npc] Spawning failed!")
|
npc.log("ERROR", "Spawning failed!")
|
||||||
ent:remove()
|
ent:remove()
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
@ -358,13 +358,13 @@ function spawner.calculate_npc_spawning(pos)
|
|||||||
-- Get nodes for this building
|
-- Get nodes for this building
|
||||||
local node_data = minetest.deserialize(meta:get_string("node_data"))
|
local node_data = minetest.deserialize(meta:get_string("node_data"))
|
||||||
if node_data == nil then
|
if node_data == nil then
|
||||||
minetest.log("[advanced_npc] ERROR: Mis-configured advanced_npc:plotmarker_auto_spawner at position: "..minetest.pos_to_string(pos))
|
npc.log("ERROR", "Mis-configured advanced_npc:plotmarker_auto_spawner at position: "..minetest.pos_to_string(pos))
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
-- Check number of beds
|
-- Check number of beds
|
||||||
local beds_count = #node_data.bed_type--#spawner.filter_first_floor_nodes(node_data.bed_type, pos)
|
local beds_count = #node_data.bed_type--#spawner.filter_first_floor_nodes(node_data.bed_type, pos)
|
||||||
|
|
||||||
minetest.log("[advanced_npc] INFO: Found "..dump(beds_count).." beds in the building at "..minetest.pos_to_string(pos))
|
npc.log("DEBUG", "Found "..dump(beds_count).." beds in the building at "..minetest.pos_to_string(pos))
|
||||||
local npc_count = 0
|
local npc_count = 0
|
||||||
-- If number of beds is zero or beds/2 is less than one, spawn
|
-- If number of beds is zero or beds/2 is less than one, spawn
|
||||||
-- a single NPC.
|
-- a single NPC.
|
||||||
@ -375,7 +375,7 @@ function spawner.calculate_npc_spawning(pos)
|
|||||||
-- Spawn (beds_count/2) NPCs
|
-- Spawn (beds_count/2) NPCs
|
||||||
npc_count = ((beds_count / 2) - ((beds_count / 2) % 1))
|
npc_count = ((beds_count / 2) - ((beds_count / 2) % 1))
|
||||||
end
|
end
|
||||||
minetest.log("[advanced_npc] INFO: Will spawn "..dump(npc_count).." NPCs at "..minetest.pos_to_string(pos))
|
npc.log("INFO", "Will spawn "..dump(npc_count).." NPCs at "..minetest.pos_to_string(pos))
|
||||||
-- Store amount of NPCs to spawn
|
-- Store amount of NPCs to spawn
|
||||||
meta:set_int("npc_count", npc_count)
|
meta:set_int("npc_count", npc_count)
|
||||||
-- Store amount of NPCs spawned
|
-- Store amount of NPCs spawned
|
||||||
@ -435,14 +435,14 @@ function spawner.scan_mg_villages_building(pos, building_data)
|
|||||||
--minetest.set_node({x=pos.x,y=pos.y,z=pos.z + (z_sign * z_size)}, {name = "wool:blue"})
|
--minetest.set_node({x=pos.x,y=pos.y,z=pos.z + (z_sign * z_size)}, {name = "wool:blue"})
|
||||||
--minetest.get_meta({x=pos.x,y=pos.y,z=pos.z + (z_sign * z_size)}):set_string("infotext", minetest.get_meta(pos):get_string("infotext")..", Axis: z, Sign: "..dump(z_sign))
|
--minetest.get_meta({x=pos.x,y=pos.y,z=pos.z + (z_sign * z_size)}):set_string("infotext", minetest.get_meta(pos):get_string("infotext")..", Axis: z, Sign: "..dump(z_sign))
|
||||||
|
|
||||||
minetest.log("Start pos: "..minetest.pos_to_string(start_pos))
|
npc.log("DEBUG", "Start pos: "..minetest.pos_to_string(start_pos))
|
||||||
minetest.log("Plot: "..dump(minetest.get_meta(start_pos):get_string("infotext")))
|
npc.log("DEBUG", "Plot: "..dump(minetest.get_meta(start_pos):get_string("infotext")))
|
||||||
|
|
||||||
minetest.log("Brotate: "..dump(brotate))
|
npc.log("DEBUG", "Brotate: "..dump(brotate))
|
||||||
minetest.log("X_sign: "..dump(x_sign))
|
npc.log("DEBUG", "X_sign: "..dump(x_sign))
|
||||||
minetest.log("X_adj: "..dump(x_sign*x_size))
|
npc.log("DEBUG", "X_adj: "..dump(x_sign*x_size))
|
||||||
minetest.log("Z_sign: "..dump(z_sign))
|
npc.log("DEBUG", "Z_sign: "..dump(z_sign))
|
||||||
minetest.log("Z_adj: "..dump(z_sign*z_size))
|
npc.log("DEBUG", "Z_adj: "..dump(z_sign*z_size))
|
||||||
|
|
||||||
local end_pos = {x=pos.x + (x_sign * x_size), y=pos.y + y_size, z=pos.z + (z_sign * z_size)}
|
local end_pos = {x=pos.x + (x_sign * x_size), y=pos.y + y_size, z=pos.z + (z_sign * z_size)}
|
||||||
|
|
||||||
@ -451,7 +451,7 @@ function spawner.scan_mg_villages_building(pos, building_data)
|
|||||||
--minetest.set_node(end_pos, {name="default:mese_block"})
|
--minetest.set_node(end_pos, {name="default:mese_block"})
|
||||||
--minetest.get_meta(end_pos):set_string("infotext", minetest.get_meta(start_pos):get_string("infotext"))
|
--minetest.get_meta(end_pos):set_string("infotext", minetest.get_meta(start_pos):get_string("infotext"))
|
||||||
|
|
||||||
minetest.log("Calculated end pos: "..minetest.pos_to_string(end_pos))
|
npc.log("DEBUG", "Calculated end pos: "..minetest.pos_to_string(end_pos))
|
||||||
|
|
||||||
return spawner.scan_area(start_pos, end_pos)
|
return spawner.scan_area(start_pos, end_pos)
|
||||||
end
|
end
|
||||||
@ -477,7 +477,7 @@ function spawner.replace_mg_villages_plotmarker(pos)
|
|||||||
|
|
||||||
if building_type == value then
|
if building_type == value then
|
||||||
|
|
||||||
minetest.log("Replacing mg_villages:plotmarker at "..minetest.pos_to_string(pos))
|
npc.log("INFO", "Replacing mg_villages:plotmarker at "..minetest.pos_to_string(pos))
|
||||||
-- Replace the plotmarker for auto-spawner
|
-- Replace the plotmarker for auto-spawner
|
||||||
minetest.set_node(pos, {name="advanced_npc:plotmarker_auto_spawner"})
|
minetest.set_node(pos, {name="advanced_npc:plotmarker_auto_spawner"})
|
||||||
-- Store old plotmarker metadata again
|
-- Store old plotmarker metadata again
|
||||||
@ -498,9 +498,9 @@ function spawner.replace_mg_villages_plotmarker(pos)
|
|||||||
--minetest.log("Found "..dump(#doors).." openable nodes")
|
--minetest.log("Found "..dump(#doors).." openable nodes")
|
||||||
local entrance = npc.places.find_entrance_from_openable_nodes(doors, pos)
|
local entrance = npc.places.find_entrance_from_openable_nodes(doors, pos)
|
||||||
if entrance then
|
if entrance then
|
||||||
minetest.log("Found building entrance at: "..minetest.pos_to_string(entrance.node_pos))
|
npc.log("INFO", "Found building entrance at: "..minetest.pos_to_string(entrance.node_pos))
|
||||||
else
|
else
|
||||||
minetest.log("Unable to find building entrance!")
|
npc.log("ERROR", "Unable to find building entrance!")
|
||||||
end
|
end
|
||||||
-- Store building entrance
|
-- Store building entrance
|
||||||
meta:set_string("entrance", minetest.serialize(entrance))
|
meta:set_string("entrance", minetest.serialize(entrance))
|
||||||
@ -569,7 +569,7 @@ if minetest.get_modpath("mg_villages") ~= nil then
|
|||||||
-- end
|
-- end
|
||||||
-- minetest.get_meta(pos):set_string("node_data", minetest.serialize(nodedata))
|
-- minetest.get_meta(pos):set_string("node_data", minetest.serialize(nodedata))
|
||||||
-- minetest.log("Cleared bed owners")
|
-- minetest.log("Cleared bed owners")
|
||||||
minetest.log("NPC stats: "..dump(minetest.deserialize(minetest.get_meta(pos):get_string("npc_stats"))))
|
--minetest.log("NPC stats: "..dump(minetest.deserialize(minetest.get_meta(pos):get_string("npc_stats"))))
|
||||||
|
|
||||||
return mg_villages.plotmarker_formspec( pos, nil, {}, clicker )
|
return mg_villages.plotmarker_formspec( pos, nil, {}, clicker )
|
||||||
end,
|
end,
|
||||||
@ -610,7 +610,7 @@ if minetest.get_modpath("mg_villages") ~= nil then
|
|||||||
-- end
|
-- end
|
||||||
-- })
|
-- })
|
||||||
|
|
||||||
-- ABM Registration... for when LBM fails.
|
-- ABM Registration
|
||||||
minetest.register_abm({
|
minetest.register_abm({
|
||||||
label = "Replace mg_villages:plotmarker with Advanced NPC auto spawners",
|
label = "Replace mg_villages:plotmarker with Advanced NPC auto spawners",
|
||||||
nodenames = {"mg_villages:plotmarker"},
|
nodenames = {"mg_villages:plotmarker"},
|
||||||
|
@ -415,8 +415,8 @@ function npc.trade.get_dedicated_trade_offers(self)
|
|||||||
-- If item found, create a buy offer for this item
|
-- If item found, create a buy offer for this item
|
||||||
-- Again, offers are created for one item only. Buy offers should be removed
|
-- Again, offers are created for one item only. Buy offers should be removed
|
||||||
-- after the NPC has bought a certain quantity, say, 5 items.
|
-- after the NPC has bought a certain quantity, say, 5 items.
|
||||||
minetest.log("Item: "..item_name)
|
--minetest.log("Item: "..item_name)
|
||||||
minetest.log("Trade info: "..dump(trade_info))
|
--minetest.log("Trade info: "..dump(trade_info))
|
||||||
--minetest.log("Logic: "..dump(trade_info.item_bought_count == nil
|
--minetest.log("Logic: "..dump(trade_info.item_bought_count == nil
|
||||||
-- or (trade_info.item_bought_count ~= nil and trade_info.item_bought_count <= npc.trade.DEDICATED_MAX_BUY_AMOUNT)))
|
-- or (trade_info.item_bought_count ~= nil and trade_info.item_bought_count <= npc.trade.DEDICATED_MAX_BUY_AMOUNT)))
|
||||||
if trade_info.item_bought_count == nil
|
if trade_info.item_bought_count == nil
|
||||||
@ -537,16 +537,17 @@ function npc.trade.perform_trade(self, player_name, offer)
|
|||||||
inv:add_item("main", price_stacks[j])
|
inv:add_item("main", price_stacks[j])
|
||||||
end
|
end
|
||||||
-- Send message to player
|
-- Send message to player
|
||||||
minetest.chat_send_player(player_name, "Thank you!")
|
npc.chat(self.npc_name, player_name, "Thank you!")
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
minetest.chat_send_player(player_name,
|
npc.chat(self.npc_name, player_name,
|
||||||
"Looks like you can't get what I'm giving you for payment!")
|
"Looks like you can't get what I'm giving you for payment!")
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
minetest.chat_send_player(player_name, "Looks like you don't have what I want to buy...")
|
npc.chat(self.npc_name, player_name,
|
||||||
|
"Looks like you don't have what I want to buy...")
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@ -570,14 +571,16 @@ function npc.trade.perform_trade(self, player_name, offer)
|
|||||||
-- Add item items to player
|
-- Add item items to player
|
||||||
inv:add_item("main", item_stack)
|
inv:add_item("main", item_stack)
|
||||||
-- Send message to player
|
-- Send message to player
|
||||||
minetest.chat_send_player(player_name, "Thank you!")
|
npc.chat(self.npc_name, player_name, "Thank you!")
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
minetest.chat_send_player(player_name, "Looks like you can't carry anything else...")
|
npc.chat(self.npc_name, player_name,
|
||||||
|
"Looks like you can't carry anything else...")
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
minetest.chat_send_player(player_name, "Looks like you don't have what I'm asking for!")
|
npc.chat(self.npc_name, player_name,
|
||||||
|
"Looks like you don't have what I'm asking for!")
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -624,8 +627,8 @@ minetest.register_on_player_receive_fields(function (player, formname, fields)
|
|||||||
if player_response.offers_type == npc.trade.OFFER_BUY then
|
if player_response.offers_type == npc.trade.OFFER_BUY then
|
||||||
-- Increase the item bought count
|
-- Increase the item bought count
|
||||||
local offer_item_name = npc.get_item_name(trade_offers[i].item)
|
local offer_item_name = npc.get_item_name(trade_offers[i].item)
|
||||||
minetest.log("Bought item name: "..dump(offer_item_name))
|
--minetest.log("Bought item name: "..dump(offer_item_name))
|
||||||
minetest.log(dump(player_response.npc.trader_data.trade_list.both[offer_item_name]))
|
--minetest.log(dump(player_response.npc.trader_data.trade_list.both[offer_item_name]))
|
||||||
-- Check if this item has been bought before
|
-- Check if this item has been bought before
|
||||||
if player_response.npc.trader_data.trade_list.both[offer_item_name].item_bought_count == nil then
|
if player_response.npc.trader_data.trade_list.both[offer_item_name].item_bought_count == nil then
|
||||||
-- Set first count to 1
|
-- Set first count to 1
|
||||||
|
355
trader.lua
355
trader.lua
@ -1,355 +0,0 @@
|
|||||||
|
|
||||||
local S = mobs.intllib
|
|
||||||
|
|
||||||
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.npc_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.npc_nametag = S("Trader @1", self.game_name)
|
|
||||||
|
|
||||||
self.object:set_properties({
|
|
||||||
nametag = self.npc_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, S("[NPC] <Trader @1 > Hello, @2, have a look at my wares.",
|
|
||||||
self.game_name, player))
|
|
||||||
|
|
||||||
minetest.show_formspec(player, "trade", "size[8,10;]"
|
|
||||||
.. default.gui_bg_img
|
|
||||||
.. default.gui_slots
|
|
||||||
.. "label[0,0;" .. S("Trader @1's stock:", self.game_name) .. "]"
|
|
||||||
.. "list[detached:" .. unique_entity_id .. ";goods;.5,.5;3,5;]"
|
|
||||||
.. "label[4.5,0.5;" .. S("Selection") .. "]"
|
|
||||||
.. "list[detached:" .. unique_entity_id .. ";selection;4.5,1;5.5,2;]"
|
|
||||||
.. "label[6,0.5;" .. S("Price") .. "]"
|
|
||||||
.. "list[detached:" .. unique_entity_id .. ";price;6,1;7,2;]"
|
|
||||||
.. "label[4.5,3.5;" .. S("Payment") .. "]"
|
|
||||||
.. "list[detached:" .. unique_entity_id .. ";payment;4.5,4;5.5,5;]"
|
|
||||||
.. "label[6,3.5;" .. S("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", S("Trader"), "default_sandstone.png", 1)
|
|
||||||
|
|
||||||
-- compatibility
|
|
||||||
mobs:alias_mob("mobs:trader", "mobs_npc:trader")
|
|
264
trader_test.lua
264
trader_test.lua
@ -1,264 +0,0 @@
|
|||||||
|
|
||||||
if not minetest.get_modpath("shop") then
|
|
||||||
minetest.register_alias("shop:coin", "default:gold_ingot")
|
|
||||||
end
|
|
||||||
|
|
||||||
local S = mobs.intllib
|
|
||||||
|
|
||||||
mobs.human = {
|
|
||||||
items = {
|
|
||||||
-- item, price, chance
|
|
||||||
{"default:apple 10", "shop:coin 2", 40},
|
|
||||||
{"farming:bread 10", "shop:coin 4", 50},
|
|
||||||
{"default:clay 10", "shop:coin 2", 14},
|
|
||||||
{"default:brick 10", "shop:coin 4", 17},
|
|
||||||
{"default:glass 10", "shop:coin 4", 17},
|
|
||||||
{"default:obsidian 10", "shop:coin 15", 50},
|
|
||||||
{"default:diamond 1", "default:goldblock 1", 7},
|
|
||||||
{"default:goldblock 1", "default:diamond 1", 7},
|
|
||||||
{"farming:wheat 10", "shop:coin 2", 17},
|
|
||||||
{"default:tree 5", "shop:coin 4", 20},
|
|
||||||
{"default:stone 10", "shop:coin 8", 17},
|
|
||||||
{"default:desert_stone 10", "shop:coin 8", 27},
|
|
||||||
{"default:sapling 1", "shop:coin 1", 7},
|
|
||||||
{"default:pick_steel 1", "shop:coin 2", 7},
|
|
||||||
{"default:sword_steel 1", "shop:coin 2", 17},
|
|
||||||
{"default:shovel_steel 1", "shop:coin 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
|
|
||||||
{"mobs_trader2.png"}, -- re-coloured by amhadinger
|
|
||||||
{"mobs_trader3.png"}, -- re-coloured by amhadinger
|
|
||||||
},
|
|
||||||
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, 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
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
-- Modifications Copyright 2016 by James Stevenson
|
|
||||||
|
|
||||||
local trader_inventory = {}
|
|
||||||
|
|
||||||
local function add_goods(race)
|
|
||||||
local goods_to_add = nil
|
|
||||||
for i = 1, 16 do
|
|
||||||
if math.random(0, 100) > race.items[i][3] then
|
|
||||||
trader_inventory.set_stack(trader_inventory,
|
|
||||||
"goods", i, race.items[i][1])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function mobs_trader(self, clicker, race)
|
|
||||||
local player = clicker:get_player_name()
|
|
||||||
|
|
||||||
if not self.id then
|
|
||||||
self.id = (math.random(1, 1000) * math.random(1, 10000))
|
|
||||||
.. self.npc_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.npc_nametag = S("Trader @1", self.game_name)
|
|
||||||
self.object:set_properties({
|
|
||||||
nametag = self.npc_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 = function(inv, from_list, from_index, to_list, to_index, count, player)
|
|
||||||
if (from_list == "goods" and
|
|
||||||
to_list == "selection") or
|
|
||||||
(from_list == "selection" and
|
|
||||||
to_list == "goods") then
|
|
||||||
return count
|
|
||||||
else
|
|
||||||
return 0
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
allow_put = function(inv, listname, index, stack, player)
|
|
||||||
return 0
|
|
||||||
end,
|
|
||||||
allow_take = function(inv, listname, index, stack, player)
|
|
||||||
return 0
|
|
||||||
end,
|
|
||||||
on_move = function(inv, from_list, from_index, to_list, to_index, count, player)
|
|
||||||
if from_list == "goods" and
|
|
||||||
to_list == "selection" then
|
|
||||||
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
|
|
||||||
inv.set_stack(inv, "price", 1, good[2])
|
|
||||||
else
|
|
||||||
inv.set_stack(inv, "price", 1, nil)
|
|
||||||
end
|
|
||||||
elseif from_list == "selection" and
|
|
||||||
to_list == "goods" then
|
|
||||||
inv.set_stack(inv, "price", 1, nil)
|
|
||||||
end
|
|
||||||
end,
|
|
||||||
on_put = function(inv, listname, index, stack, player)
|
|
||||||
end,
|
|
||||||
on_take = function(inv, listname, index, stack, player)
|
|
||||||
end,
|
|
||||||
}
|
|
||||||
|
|
||||||
if is_inventory == nil then
|
|
||||||
trader_inventory = minetest.create_detached_inventory(unique_entity_id, move_put_take)
|
|
||||||
trader_inventory.set_size(trader_inventory, "goods", 16)
|
|
||||||
trader_inventory.set_size(trader_inventory, "selection", 1)
|
|
||||||
trader_inventory.set_size(trader_inventory, "price", 1)
|
|
||||||
add_goods(race)
|
|
||||||
--print("added stuff")
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.chat_send_player(player, S("[NPC] <Trader @1> Hello, @2, have a look at my wares.",
|
|
||||||
self.game_name, player))
|
|
||||||
|
|
||||||
minetest.show_formspec(player, "mobs_npc:trader", "size[8,9]" ..
|
|
||||||
default.gui_bg ..
|
|
||||||
default.gui_bg_img ..
|
|
||||||
default.gui_slots ..
|
|
||||||
"list[detached:" .. unique_entity_id .. ";goods;0,0;8,2]" ..
|
|
||||||
"label[0,3;Selection]" ..
|
|
||||||
"list[detached:" .. unique_entity_id .. ";selection;2,3;1,1]" ..
|
|
||||||
"label[4,3;Price]" ..
|
|
||||||
"list[detached:" .. unique_entity_id .. ";price;6,3;1,1]" ..
|
|
||||||
"button[4,4;2,1;purchase;Purchase]" ..
|
|
||||||
"list[current_player;main;0,5;8,1;]" ..
|
|
||||||
"list[current_player;main;0,6.25;8,3;8]" ..
|
|
||||||
default.get_hotbar_bg(0, 5))
|
|
||||||
end
|
|
||||||
|
|
||||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|
||||||
if formname ~= "mobs_npc:trader" then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
--print(dump(trader_inventory:get_lists()))
|
|
||||||
|
|
||||||
local selection_name = trader_inventory:get_stack("selection", 1):get_name()
|
|
||||||
local selection_count = trader_inventory:get_stack("selection", 1):get_count()
|
|
||||||
local selection_string = selection_name .. " " .. tostring(selection_count)
|
|
||||||
|
|
||||||
local price_name = trader_inventory:get_stack("price", 1):get_name()
|
|
||||||
local price_count = trader_inventory:get_stack("price", 1):get_count()
|
|
||||||
local price_string = price_name .. " " .. tostring(price_count)
|
|
||||||
|
|
||||||
--print(selection_string .. "\nfor:\n" .. price_string)
|
|
||||||
|
|
||||||
if player:get_inventory():contains_item("main", price_string) then
|
|
||||||
--print("you got it!")
|
|
||||||
trader_inventory:set_stack("selection", 1, nil)
|
|
||||||
trader_inventory:set_stack("price", 1, nil)
|
|
||||||
|
|
||||||
player:get_inventory():remove_item("main", price_string)
|
|
||||||
local adder = player:get_inventory():add_item("main", selection_string)
|
|
||||||
if adder then
|
|
||||||
minetest.add_item(player:getpos(), adder)
|
|
||||||
end
|
|
||||||
else
|
|
||||||
minetest.chat_send_player(player:get_player_name(),
|
|
||||||
"Not enough credits!")
|
|
||||||
end
|
|
||||||
|
|
||||||
end)
|
|
||||||
|
|
||||||
mobs:register_egg("mobs_npc:trader", S("Trader"), "default_sandstone.png", 1)
|
|
||||||
|
|
||||||
-- compatibility
|
|
||||||
mobs:alias_mob("mobs:trader", "mobs_npc:trader")
|
|
Loading…
Reference in New Issue
Block a user