made usable for mobs_npc and mobs_animals

This commit is contained in:
Sokomine 2023-09-04 02:36:33 +02:00
parent 31f0afb102
commit e9041d39ca
8 changed files with 380 additions and 0 deletions

80
add_skins_and_capes.lua Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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