made usable for mobs_npc and mobs_animals
This commit is contained in:
parent
31f0afb102
commit
e9041d39ca
80
add_skins_and_capes.lua
Normal file
80
add_skins_and_capes.lua
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
|
||||||
|
-- Dynamicly read textures at start of mod
|
||||||
|
-- Create a folder textures/ inside this mod to use this function.
|
||||||
|
-- Add skins in files named textures/npc_talk_main_SKIN_NAME.png
|
||||||
|
|
||||||
|
local function read_skins_and_capes_from_folders()
|
||||||
|
local temp = {}
|
||||||
|
|
||||||
|
-- get the files out of modpath
|
||||||
|
local mp_list = minetest.get_dir_list(minetest.get_modpath("npc_talk") .. DIR_DELIM .. "textures", false)
|
||||||
|
|
||||||
|
-- get the files out of worlddir
|
||||||
|
local wp_list =
|
||||||
|
minetest.get_dir_list(
|
||||||
|
yl_speak_up.worldpath .. DIR_DELIM .. "worldmods" .. DIR_DELIM .. "npc_talk" .. DIR_DELIM .. "textures",
|
||||||
|
false
|
||||||
|
)
|
||||||
|
|
||||||
|
-- Let's join both lists.
|
||||||
|
table.insert_all(temp, mp_list)
|
||||||
|
table.insert_all(temp, wp_list)
|
||||||
|
|
||||||
|
return temp
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
-- taken from yl_speak_up from yl
|
||||||
|
local function add_skins_and_capes(temp, races, modname)
|
||||||
|
--[[ Let's see if the files are the ones we want. Format is
|
||||||
|
npc_talk_main_name.png <-- Those are the ones we want
|
||||||
|
npc_talk_cape_name.png
|
||||||
|
npc_talk_item_name.png
|
||||||
|
]]--
|
||||||
|
|
||||||
|
for _, race in ipairs(races) do
|
||||||
|
if(not(yl_speak_up.mob_skins[modname..race])) then
|
||||||
|
yl_speak_up.mob_skins[modname..race] = {}
|
||||||
|
end
|
||||||
|
if(not(yl_speak_up.mob_capes[modname..race])) then
|
||||||
|
yl_speak_up.mob_capes[modname..race] = {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, v in pairs(temp) do
|
||||||
|
local s = string.split(v, "_")
|
||||||
|
if s[1] == "npc" and s[2] == "talk" and s[3] == "main" then
|
||||||
|
for i, race in ipairs(races) do
|
||||||
|
table.insert(yl_speak_up.mob_skins[modname..race], v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if s[1] == "npc" and s[2] == "talk" and s[3] == "cape" then
|
||||||
|
for i, race in ipairs(races) do
|
||||||
|
table.insert(yl_speak_up.mob_capes[modname..race], v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for _, race in ipairs(races) do
|
||||||
|
if(#yl_speak_up.mob_skins[modname..race] < 1) then
|
||||||
|
yl_speak_up.mob_skins[modname..race] = {"npc_talk_main_default.png"}
|
||||||
|
end
|
||||||
|
if(#yl_speak_up.mob_capes[modname..race] < 1) then
|
||||||
|
yl_speak_up.mob_capes[modname..race] = {"npc_talk_cape_default.png"}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- called at startup and on reload of yl_speak_up
|
||||||
|
npc_talk.add_textures = function()
|
||||||
|
-- do all the things that have to be done when yl_speak_up is initialized or reloaded
|
||||||
|
add_skins_and_capes(npc_talk.file_list, {"npc"}, "npc_talk:")
|
||||||
|
minetest.log("action","[MOD] npc_talk loaded textures for yl_speak_up")
|
||||||
|
end
|
||||||
|
|
||||||
|
-- this has to be called *once* when the file is initialized
|
||||||
|
npc_talk.file_list = read_skins_and_capes_from_folders()
|
||||||
|
|
||||||
|
-- make sure it gets called once now and in the future whenever yl_speak_up is reloaded
|
||||||
|
-- (via /npc_talk_reload)
|
||||||
|
yl_speak_up.register_on_reload(npc_talk.add_textures, "npc_talk.add_textures()")
|
71
example_npc.lua
Normal file
71
example_npc.lua
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
|
||||||
|
npc_talk.register_example_npc = function()
|
||||||
|
-- register the new mob
|
||||||
|
mobs:register_mob("npc_talk:npc", {
|
||||||
|
type = "npc",
|
||||||
|
passive = true,
|
||||||
|
damage = 9,
|
||||||
|
attack_type = "dogfight",
|
||||||
|
attacks_monsters = true,
|
||||||
|
attack_npcs = false,
|
||||||
|
owner_loyal = false,
|
||||||
|
pathfinding = false,
|
||||||
|
hp_min = 100,
|
||||||
|
hp_max = 100,
|
||||||
|
armor = 0,
|
||||||
|
collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3},
|
||||||
|
visual = "mesh",
|
||||||
|
visual_size = {x = 1, y = 1},
|
||||||
|
-- TODO: mesh, textures
|
||||||
|
mesh = "skinsdb_3d_armor_character_5.b3d",
|
||||||
|
drawtype = "front",
|
||||||
|
textures = {{
|
||||||
|
"blank.png", -- cape?
|
||||||
|
"yl_speak_up_main_default.png", -- 64x64 skin
|
||||||
|
"3d_armor_trans.png", -- shield?!
|
||||||
|
"3d_armor_trans.png", -- item right hand
|
||||||
|
}},
|
||||||
|
makes_footstep_sound = true,
|
||||||
|
sounds = {},
|
||||||
|
walk_velocity = 2,
|
||||||
|
run_velocity = 3,
|
||||||
|
jump = false,
|
||||||
|
water_damage = 0,
|
||||||
|
lava_damage = 0,
|
||||||
|
light_damage = 0,
|
||||||
|
suffocation = 0,
|
||||||
|
view_range = 4,
|
||||||
|
owner = "Server",
|
||||||
|
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 = yl_speak_up.mobs_on_rightclick,
|
||||||
|
after_activate = yl_speak_up.mobs_after_activate
|
||||||
|
})
|
||||||
|
|
||||||
|
mobs:register_egg("npc_talk:npc", "NPC", "wool_blue.png", 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
npc_talk.enable_talk_to_example_npc = function()
|
||||||
|
end
|
||||||
|
|
||||||
|
-- TODO: may require 3darmor?
|
||||||
|
if(minetest.get_modpath("mobs_npc")) then
|
||||||
|
-- register the NPC once
|
||||||
|
npc_talk.register_example_npc()
|
||||||
|
-- make sure it gets called once now and in the future whenever yl_speak_up is reloaded
|
||||||
|
-- (via /npc_talk_reload)
|
||||||
|
yl_speak_up.register_on_reload(npc_talk.enable_talk_to_example_npc, "npc_talk.enable_talk_to_example_npc()")
|
||||||
|
end
|
46
example_talk_sign.lua
Normal file
46
example_talk_sign.lua
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
|
||||||
|
minetest.register_node("npc_talk:talk_sign", {
|
||||||
|
description = "Place this sign and then right-click it to start talk interface.",
|
||||||
|
drawtype = "nodebox",
|
||||||
|
tiles = {"default_mese_block.png"},
|
||||||
|
paramtype = "light",
|
||||||
|
paramtype2 = "wallmounted",
|
||||||
|
sunlight_propagates = true,
|
||||||
|
is_ground_content = false,
|
||||||
|
walkable = false,
|
||||||
|
use_texture_alpha = "opaque",
|
||||||
|
node_box = {
|
||||||
|
type = "wallmounted",
|
||||||
|
wall_top = {-0.4375, 0.4375, -0.3125, 0.4375, 0.5, 0.3125},
|
||||||
|
wall_bottom = {-0.4375, -0.5, -0.3125, 0.4375, -0.4375, 0.3125},
|
||||||
|
wall_side = {-0.5, -0.3125, -0.4375, -0.4375, 0.3125, 0.4375},
|
||||||
|
},
|
||||||
|
groups = {choppy = 2, oddly_breakable_by_hand = 3},
|
||||||
|
legacy_wallmounted = true,
|
||||||
|
on_construct = function(pos)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
meta:set_string("infotext", "Right-click me to start talk interface.")
|
||||||
|
meta:set_string("talk_name", "Sign")
|
||||||
|
end,
|
||||||
|
after_place_node = function(pos, placer)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
meta:set_string("owner", placer:get_player_name() or "")
|
||||||
|
meta:set_string("infotext", "Right-click me to start talk interface! My owner is "..tostring(meta:get_string("owner")))
|
||||||
|
end,
|
||||||
|
on_rightclick = function(pos, node, clicker, itemstack, pointed_thing)
|
||||||
|
if(minetest.global_exists("yl_speak_up") and yl_speak_up.talk) then
|
||||||
|
yl_speak_up.talk({is_block = true, pos = pos}, clicker)
|
||||||
|
end
|
||||||
|
return itemstack
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "npc_talk:talk_sign",
|
||||||
|
recipe = {
|
||||||
|
{"default:mese"},
|
||||||
|
{"default:sign_wall_wood"},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
23
init.lua
Normal file
23
init.lua
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
DIR_DELIM = "/"
|
||||||
|
|
||||||
|
local modpath = minetest.get_modpath("npc_talk")..DIR_DELIM
|
||||||
|
|
||||||
|
npc_talk = {}
|
||||||
|
|
||||||
|
-- register an example mob and a spawn egg
|
||||||
|
dofile(modpath .. "example_npc.lua")
|
||||||
|
|
||||||
|
-- add textures from textures/npc_talk_main_TEXTURE_NAME.png for the example npc
|
||||||
|
dofile(modpath .. "add_skins_and_capes.lua")
|
||||||
|
|
||||||
|
-- demonstration that a node can be used for starting talking as well
|
||||||
|
dofile(modpath .. "example_talk_sign.lua")
|
||||||
|
|
||||||
|
-- make mobs_npc from mobs_redo ready to be talked to
|
||||||
|
dofile(modpath .. "talk_to_mobs_npc.lua")
|
||||||
|
|
||||||
|
-- mostly a demonstration for mobs_animal (allows to talk to white and red sheep and a cow)
|
||||||
|
-- you need to craft a special book/tool to talk to them as they don't offer a suitable interface;
|
||||||
|
-- punch them with npc_talk:talk_tool
|
||||||
|
dofile(modpath .. "talk_tool.lua")
|
||||||
|
dofile(modpath .. "talk_to_animals.lua")
|
7
mod.conf
Normal file
7
mod.conf
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
name = npc_talk
|
||||||
|
author = Bastrabun/AliasAlreadyTaken, Sokomine
|
||||||
|
description = NPC for yl_speak_up
|
||||||
|
release = 202309030000
|
||||||
|
title = NPC you can talk to (in combination with yl_speak_up)
|
||||||
|
depends = yl_speak_up
|
||||||
|
optional_depends = mobs, mobs_npc, mobs_animal, default
|
65
talk_to_animals.lua
Normal file
65
talk_to_animals.lua
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
|
||||||
|
npc_talk.enable_talk_to_animals = function()
|
||||||
|
|
||||||
|
-- the following information is needed in order to handle skin changes
|
||||||
|
yl_speak_up.mesh_data["mobs_sheep.b3d"] = {
|
||||||
|
texture_index = 1,
|
||||||
|
animation = {
|
||||||
|
-- {x = start_frame, y = end_frame, collisionbox}
|
||||||
|
stand_still = {x = 0, y = 0},
|
||||||
|
stand = {x = 0, y = 79},
|
||||||
|
walk = {x = 81, y = 100},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
yl_speak_up.mesh_data["mobs_cow.b3d"] = {
|
||||||
|
texture_index = 1,
|
||||||
|
animation = {
|
||||||
|
-- {x = start_frame, y = end_frame, collisionbox}
|
||||||
|
stand_still = {x = 0, y = 0},
|
||||||
|
stand = {x = 0, y = 30},
|
||||||
|
stand1 = {x = 35, y = 75},
|
||||||
|
walk = {x = 85, y = 114},
|
||||||
|
run = {x = 120, y = 140},
|
||||||
|
punch = {x = 145, y = 160},
|
||||||
|
die = {x = 165, y = 185},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
yl_speak_up.mob_skins["mobs_animal:sheep_white"] = {
|
||||||
|
"mobs_sheep_base.png^(mobs_sheep_wool.png^[multiply:#ffffffc0)"}
|
||||||
|
yl_speak_up.mob_skins["mobs_animal:sheep_red"] = {
|
||||||
|
"mobs_sheep_base.png^(mobs_sheep_wool.png^[multiply:#ff0000a0)"}
|
||||||
|
yl_speak_up.mob_skins["mobs_animal:cow"] = {
|
||||||
|
"mobs_cow.png", "mobs_cow2.png"}
|
||||||
|
|
||||||
|
table.insert(yl_speak_up.emulate_orders_on_rightclick, "mobs_animal:sheep_white")
|
||||||
|
table.insert(yl_speak_up.emulate_orders_on_rightclick, "mobs_animal:sheep_red")
|
||||||
|
table.insert(yl_speak_up.emulate_orders_on_rightclick, "mobs_animal:cow")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if(minetest.get_modpath("mobs_animal")) then
|
||||||
|
-- make sure it gets called once now and in the future whenever yl_speak_up is reloaded
|
||||||
|
-- (via /npc_talk_reload)
|
||||||
|
yl_speak_up.register_on_reload(npc_talk.enable_talk_to_animals, "npc_talk.enable_talk_to_animals()")
|
||||||
|
|
||||||
|
-- The aniamals have too many functions in on_rightclick - they would need new code
|
||||||
|
-- for talking to them in on_rightclick.
|
||||||
|
-- As a workaround, you need to wield this tool and punch or right-click them with it.
|
||||||
|
minetest.register_craftitem("npc_talk:talk_tool", {
|
||||||
|
description = "Punch a suitable animal (white or red sheep, cow) with this tool to talk to it",
|
||||||
|
inventory_image = "default_book.png^mobs_magic_lasso.png",
|
||||||
|
groups = {book = 1},
|
||||||
|
on_use = npc_talk.talk_tool,
|
||||||
|
on_place = npc_talk.talk_tool,
|
||||||
|
})
|
||||||
|
|
||||||
|
-- add a suitable craft receipe
|
||||||
|
minetest.register_craft({
|
||||||
|
output = "npc_talk:talk_tool",
|
||||||
|
recipe = {
|
||||||
|
{"mobs:lasso"},
|
||||||
|
{"default:book"},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
end
|
59
talk_to_mobs_npc.lua
Normal file
59
talk_to_mobs_npc.lua
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
|
||||||
|
npc_talk.enable_talk_to_mobs_npc = function()
|
||||||
|
|
||||||
|
-- the following information is needed in order to handle skin changes
|
||||||
|
|
||||||
|
-- this model is used by mobs_npc
|
||||||
|
yl_speak_up.mesh_data["mobs_character.b3d"] = {
|
||||||
|
-- the first texture is the skin
|
||||||
|
texture_index = 1,
|
||||||
|
-- there is no support for capes or wielded items
|
||||||
|
can_show_wielded_items = false,
|
||||||
|
-- textures are applied directly
|
||||||
|
textures_to_skin = false,
|
||||||
|
-- this information needed so that the animation of the mob can be set (i.e. them sitting)
|
||||||
|
animation = {
|
||||||
|
-- {x = start_frame, y = end_frame, collisionbox}
|
||||||
|
stand_still = {x = 0, y = 0, collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3}},
|
||||||
|
stand = {x = 0, y = 79, collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3}},
|
||||||
|
sit = {x = 81, y = 160, collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.0, 0.3}},
|
||||||
|
lay = {x = 162, y = 166, collisionbox = {-0.6, 0.0, -0.6, 0.6, 0.3, 0.6}},
|
||||||
|
walk = {x = 168, y = 187, collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3}},
|
||||||
|
mine = {x = 189, y = 198, collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3}},
|
||||||
|
walk_mine = {x = 200, y = 219, collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
-- list all textures that shall be available as skins for this particular npc:
|
||||||
|
-- the normal NPC (can be fed and tamed with bread)
|
||||||
|
yl_speak_up.mob_skins["mobs_npc:npc"] = {
|
||||||
|
"mobs_npc.png", "mobs_npc2.png", "mobs_npc3.png", "mobs_npc4.png", "mobs_npc_baby.png"}
|
||||||
|
-- the Igor mob
|
||||||
|
yl_speak_up.mob_skins["mobs_npc:igor"] = {
|
||||||
|
"mobs_igor.png", "mobs_igor2.png", "mobs_igor3.png", "mobs_igor4.png",
|
||||||
|
"mobs_igor5.png", "mobs_igor6.png", "mobs_igor7.png", "mobs_igor8.png"}
|
||||||
|
-- the trader mob
|
||||||
|
yl_speak_up.mob_skins["mobs_npc:trader"] = {
|
||||||
|
"mobs_trader.png", "mobs_trader2.png", "mobs_trader3.png"}
|
||||||
|
|
||||||
|
-- some mobs (in particular from mobs_redo) can switch between follow (their owner),
|
||||||
|
-- stand and walking when they're right-clicked; emulate this behaviour for NPC in
|
||||||
|
-- this list
|
||||||
|
table.insert(yl_speak_up.emulate_orders_on_rightclick, "mobs_npc:npc")
|
||||||
|
table.insert(yl_speak_up.emulate_orders_on_rightclick, "mobs_npc:igor")
|
||||||
|
table.insert(yl_speak_up.emulate_orders_on_rightclick, "mobs_npc:trader")
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
if(minetest.get_modpath("mobs_npc")) then
|
||||||
|
-- make sure it gets called once now and in the future whenever yl_speak_up is reloaded
|
||||||
|
-- (via /npc_talk_reload)
|
||||||
|
yl_speak_up.register_on_reload(npc_talk.enable_talk_to_mobs_npc, "npc_talk.enable_talk_to_mobs_npc()")
|
||||||
|
|
||||||
|
-- mobs_npc now provides us with a nice function for overriding :-)
|
||||||
|
npc_talk.old_mobs_npc_npc_talk = mobs_npc.npc_talk
|
||||||
|
mobs_npc.npc_talk = function(self, player, message_list)
|
||||||
|
yl_speak_up.talk(self, player)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
29
talk_tool.lua
Normal file
29
talk_tool.lua
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
-- we need to initiate talk to a mob somehow
|
||||||
|
npc_talk.talk_tool = function(itemstack, player, pointed_thing)
|
||||||
|
if(not(player) or not(pointed_thing) or pointed_thing.type ~= 'object') then
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
local pname = player:get_player_name()
|
||||||
|
|
||||||
|
local ref = pointed_thing.ref
|
||||||
|
if(not(ref)) then
|
||||||
|
return
|
||||||
|
elseif(ref:is_player()) then
|
||||||
|
minetest.chat_send_player(pname, "You can talk to other players via /msg <playername> <text>")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local luaob = ref:get_luaentity();
|
||||||
|
if(not(luaob)
|
||||||
|
or not(luaob.name)
|
||||||
|
-- we can only talk to NPC for which we have information for skin configuration
|
||||||
|
or not(yl_speak_up.mob_skins[luaob.name])) then
|
||||||
|
minetest.chat_send_player(pname, "Sorry. This entity hasn't been taught how to talk ("..
|
||||||
|
tostring(luaob.name)..").")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
-- actually talk
|
||||||
|
minetest.chat_send_player(pname, "Talking to entity of type "..tostring(luaob.name)..".")
|
||||||
|
yl_speak_up.talk(luaob, player)
|
||||||
|
|
||||||
|
return nil -- no item shall be removed from inventory
|
||||||
|
end
|
Loading…
Reference in New Issue
Block a user