Repixture/mods/mobs/mob_npc.lua
2023-02-19 00:47:39 +01:00

491 lines
24 KiB
Lua
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- Npc by TenPlus1
-- Modded by KaadmY
local S = minetest.get_translator("mobs")
-- How many different trades an NPC offers
local NPC_TRADES_COUNT = 4
local get_item_fuel_burntime = function(itemstring)
local input = {
method = "fuel",
items = { itemstring },
}
local res = minetest.get_craft_result(input)
return res.time
end
local get_item_cooking_result = function(itemstring)
local input = {
method = "cooking",
items = { itemstring },
}
local res = minetest.get_craft_result(input)
return res.item
end
local npc_types = {
{ "farmer", S("Farmer") },
{ "tavernkeeper", S("Tavern Keeper") },
{ "blacksmith", S("Blacksmith") },
{ "butcher", S("Butcher") },
{ "carpenter", S("Carpenter") },
}
local msgs = {
npc = {
farmer = S("Hi! I'm a farmer. I sell farming goods."),
tavernkeeper = S("Hi! I'm a tavernkeeper. I trade with assorted goods."),
blacksmith = S("Hi! I'm a blacksmith. I sell metal products."),
butcher = S("Hi! I'm a butcher. Want to buy something?"),
carpenter = S("Hi! I'm a carpenter. Making things out of wood is my job."),
},
trade = {
S("If you want to trade, show me a trading book."),
},
happy = {
S("Hello!"),
S("Nice to see you."),
S("Life is beautiful."),
S("I feel good."),
S("Have a nice day!"),
},
exhausted = {
S("I'm not in a good mood."),
S("I'm tired."),
S("I need to rest."),
S("Life could be better."),
},
hurt = {
S("I don't feel so good."),
S("I ... I am hurt."),
S("I feel weak."),
S("My head hurts."),
S("I have a bad day today."),
},
hostile = {
S("Screw you!"),
}
}
local function say(text, to_player)
minetest.chat_send_player(to_player, S("Villager says: “@1”", text))
end
local function say_random(mtype, to_player)
local r = math.random(1, #msgs[mtype])
local text = msgs[mtype][r]
say(text, to_player)
end
for _, npc_type_table in pairs(npc_types) do
local npc_type = npc_type_table[1]
local npc_name = npc_type_table[2]
mobs:register_mob(
"mobs:npc_" .. npc_type,
{
type = "npc",
mob_name = S("Villager"),
passive = false,
collides_with_objects = false,
damage = 3,
attack_type = "dogfight",
attacks_monsters = true,
hp_min = 10,
hp_max = 20,
breath_max = 11,
armor = 80,
collisionbox = {-0.35,-1.0,-0.35, 0.35,0.8,0.35},
visual = "mesh",
mesh = "mobs_npc.b3d",
drawtype = "front",
textures = {
{"mobs_npc1.png"},
{"mobs_npc2.png"},
{"mobs_npc3.png"},
{"mobs_npc4.png"},
{"mobs_npc5.png"},
{"mobs_npc6.png"},
},
makes_footstep_sound = true,
sounds = {},
walk_velocity = 2,
run_velocity = 3,
jump = true,
walk_chance = 50,
drops = {
{name = "rp_default:planks_oak",
chance = 1, min = 1, max = 3},
{name = "rp_default:apple",
chance = 2, min = 1, max = 2},
{name = "rp_default:axe_stone",
chance = 5, min = 1, max = 1},
},
water_damage = 0,
lava_damage = 2,
light_damage = 0,
group_attack = true,
follow = "rp_gold:ingot_gold",
view_range = 16,
owner = "",
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,
},
do_custom = function(self)
-- Slowly heal NPC over time
self.healing_counter = self.healing_counter + 1
if self.healing_counter >= 7 then
mobs:heal(self, 1)
self.healing_counter = 0
end
end,
on_spawn = function(self)
self.npc_type = npc_type
self.healing_counter = 0
end,
on_rightclick = function(self, clicker)
local item = clicker:get_wielded_item()
local name = clicker:get_player_name()
-- Reject all interaction when hostile
if self.attack and self.attack.player == clicker then
say_random("hostile", name)
return
end
local npc_type = self.npc_type
local iname = item:get_name()
if npc_type ~= "blacksmith" and (minetest.get_item_group(iname, "sword") > 0 or minetest.get_item_group(iname, "spear") > 0) then
say(S("Get this thing out of my face!"), name)
return
end
achievements.trigger_achievement(clicker, "smalltalk")
local hp = self.object:get_hp()
do
-- No trading if low health
if hp < 5 then
say_random("hurt", name)
return
end
if not self.npc_trades or not self.npc_trade or not self.npc_trade_index then
self.npc_trades = {}
local possible_trades = table.copy(gold.trades[npc_type])
for t=1, NPC_TRADES_COUNT do
if #possible_trades == 0 then
break
end
local index = util.choice(possible_trades, gold.pr)
local trade = possible_trades[index]
table.insert(self.npc_trades, trade)
table.remove(possible_trades, index)
end
self.npc_trade_index = 1
if not self.npc_trade then
self.npc_trade = self.npc_trades[self.npc_trade_index]
end
minetest.log("action", "[mobs] NPC trades of NPC at "..minetest.pos_to_string(self.object:get_pos(), 1).." initialized")
end
if not gold.trade(self.npc_trade, npc_type, clicker, self, self.npc_trade_index, self.npc_trades) then
-- Good mood: Give hint or funny text
if hp >= self.hp_max-7 then
-- Fuel time / cooking hint by blacksmith
if npc_type == "blacksmith" then
-- First some hardcoded texts
if iname == "rp_default:cactus" then
say(S("Ah, a cactus. You'd be surprised how well they burn in a furnace."), name)
return
elseif iname == "rp_default:torch_dead" or iname == "rp_default:torch_weak" then
say(S("You can quickly kindle it in the furnace."), name)
return
elseif iname == "rp_jewels:jewel_ore" then
say(S("A truly amazing block!"), name)
return
elseif minetest.get_item_group(iname, "tree") > 0 then
say(S("Trees are a classic furnace fuel, but you can also cook them to get coal lumps."), name)
return
end
local cook = get_item_cooking_result(iname)
local fuel = get_item_fuel_burntime(iname)
if cook and not cook:is_empty() then
local dname = cook:get_short_description()
if fuel > 0 then
say(S("You can cook it in the furnace to get: @1. But you can also use it as a furnace fuel.", dname), name)
else
say(S("Cook it in the furnace to get: @1.", dname), name)
end
return
end
if fuel > 0 then
if fuel >= 180 then
say(S("This is an amazing furnace fuel, it burns for a very, very, very long time."), name)
elseif fuel >= 120 then
say(S("This is a great furnace fuel, and it burns for a very, very long time."), name)
elseif fuel >= 60 then
say(S("This is a very good furnace fuel, and it burns for a very long time."), name)
elseif fuel >= 30 then
say(S("This is a good furnace fuel, it burns for a long time."), name)
elseif fuel >= 20 then
say(S("This is a nice furnace fuel."), name)
elseif fuel >= 15 then
say(S("You can use this as a furnace fuel, but it's meh."), name)
elseif fuel >= 9 then
say(S("You can use this as a furnace fuel, but it is gone quickly."), name)
elseif fuel >= 3 then
say(S("You can use this as a furnace fuel, but it is gone very quickly."), name)
else
say(S("You can theoretically use this as a furnace fuel, but it is gone almost instantly. You will need a large amount of these to cook anything."), name)
end
return
end
end
if iname == "rp_gold:ingot_gold" then
say_random("trade", name)
elseif iname == "rp_jewels:serrated_broadsword" then
if npc_type == "blacksmith" then
say(S("I'm impressed! Your weapon is a true masterpiece."), name)
else
say_random("happy", name)
end
elseif iname == "rp_default:broadsword" then
say(S("This is a mighty weapon, but have you considered upgrading it with jewels?"), name)
elseif (minetest.get_item_group(iname, "sword") > 0) or (minetest.get_item_group(iname, "spear") > 0) then
say(S("Offense is the best defense."), name)
elseif minetest.get_item_group(iname, "is_armor") == 1 then
say(S("If you equip a full set of armor made from the same material, you'll get a protection bonus."), name)
elseif iname == "rp_default:bookshelf" then
say(S("You can put anything inside a bookshelf, not just books.", name))
elseif iname == "rp_default:fertilizer" then
if npc_type == "farmer" then
say(S("This makes seeds grow faster. Place the fertilizer on soil, then plant the seed on top of it."), name)
else
say(S("Sorry, I don't know how to use this. Maybe ask a farmer."), name)
end
elseif minetest.get_item_group(iname, "bucket") > 0 then
if npc_type == "farmer" then
say(S("Remember to put water near to your seeds."), name)
else
say_random("happy", name)
end
elseif minetest.get_item_group(iname, "nav_compass") == 1 then
say(S("Try magnetizing it on iron."), name)
elseif minetest.get_item_group(iname, "nav_compass") == 2 then
local r = math.random(1,3)
if r == 1 then
say(S("If you use it on a cotton bale, it will point to the North again."), name)
else
say(S("If you use it on wool, it will point to the North again."), name)
end
elseif iname == "rp_nav:map" then
say(S("We live in a lovely place, don't we?"), name)
elseif iname == "mobs:lasso" then
say(S("It's used to capture large animals."), name)
elseif iname == "rp_locks:pick" then
say(S("Why are you carrying this around? Do you want crack open our locked chests?"), name)
elseif iname == "mobs:net" then
say(S("It's used to capture small animals."), name)
elseif iname == "rp_farming:wheat_1" then
say(S("Every kid knows seeds need soil, water and sunlight."), name)
elseif iname == "rp_farming:wheat" then
if npc_type == "farmer" then
say(S("Sheep love to eat wheat. Give them enough wheat and they'll multiply!"), name)
else
say(S("We use wheat to make flour and bake bread."), name)
end
elseif iname == "rp_farming:flour" then
say(S("Put it in a furnace to bake tasty bread."), name)
elseif iname == "rp_farming:cotton_1" then
if npc_type == "farmer" then
say(S("Did you know cotton seed not only grow on dirt, but also on sand? But it still needs water."), name)
elseif npc_type == "carpenter" then
say(S("If you have grown a cotton plant, try using scissors to perform a precise cut."), name)
else
say(S("Every kid knows seeds need soil, water and sunlight."), name)
end
elseif iname == "rp_farming:cotton" then
say(S("This can be used to make cotton bales.", name))
elseif iname == "rp_default:book" then
say(S("A truly epic story!"), name)
elseif iname == "rp_default:pearl" then
if npc_type == "tavernkeeper" then
say(S("Ooh, a shiny pearl! It's beautiful."), name)
else
say(S("I heard the tavernkeeper likes these."), name)
end
elseif minetest.get_item_group(iname, "sapling") > 0 then
local r = math.random(1,3)
if r == 1 then
say(S("Just place it on the ground and it will grow after a while."), name)
elseif r == 2 then
say(S("If the sapling refuses to grow, make sure it has enough open space above it."), name)
else
say(S("Try placing it on different grounds. It might grow differently."), name)
end
elseif minetest.get_item_group(iname, "shears") > 0 then
say(S("Use this to trim plants and get wool from sheep."), name)
elseif iname == "rp_default:papyrus" then
if npc_type == "farmer" then
say(S("Papyrus grows best on fertilized swamp dirt."), name)
elseif npc_type == "carpenter" then
say(S("Papyrus likes to grow next to water."), name)
elseif npc_type == "tavernkeeper" then
say(S("The papyrus grows tall in the swamp. But it can grow even taller."), name)
else
say(S("When I was I kid, I always liked to climb on the papyrus."), name)
end
elseif iname == "rp_default:cactus" then
if npc_type == "farmer" then
say(S("Cacti grow best on sand. They are also a food source, if you're really desperate."), name)
elseif npc_type == "tavernkeeper" then
say(S("This is the secret ingredient for my special drink. But don't tell anyone!"), name)
else
say(S("Now what can you possibly do with a cactus? I don't know!"), name)
end
elseif iname == "jewels:jewel" then
if npc_type == "blacksmith" then
say(S("Jewels are great! If you have a jeweller's workbench, you can enhance your tools."), name)
else
say(S("Did you know we sometimes sell jewels?"), name)
end
elseif iname == "rp_lumien:crystal_off" then
say(S("This looks like it could be a good wall decoration."), name)
elseif iname == "rp_default:torch_dead" then
say(S("Its burned out. Use flint and steel to kindle it."), name)
elseif iname == "rp_default:torch_weak" then
say(S("With flint and steel you could stabilize the flame."), name)
elseif iname == "rp_default:torch" then
say(S("Lets light up some caves!"), name)
elseif iname == "rp_default:flower" then
say(S("A flower? I love flowers! Let's make the world bloom!"), name)
elseif iname == "rp_default:flint_and_steel" then
if minetest.settings:get_bool("tnt_enable", true) then
say(S("You can use this to light up torches and bonfires and ignite TNT."), name)
else
say(S("You can use this to light up torches and bonfires."), name)
end
elseif iname == "rp_tnt:tnt" then
if minetest.settings:get_bool("tnt_enable", true) then
say(S("TNT needs to be ignited by a flint and steel."), name)
else
say(S("For some reason, TNT can't be ignited. Strange."), name)
end
elseif iname == "rp_fire:bonfire" then
say(S("You need flint and steel to light the fire. But don't walk into the flame!"), name)
elseif iname == "rp_bed:bed_foot" then
if npc_type == "carpenter" then
say(S("Isn't it stressful to carry this heavy bed around?"), name)
else
say(S("Sleeping makes the night go past in the blink of an eye."), name)
end
elseif iname == "rp_default:lump_bronze" then
-- Classic parody of Friedrich Schillers “Das Lied von der Glocke” (works best in German)
say(S("Hole in dirt, put bronze in. Bells complete, bim, bim, bim!"), name)
elseif iname == "rp_default:apple" then
say(S("Apples are so tasty!"), name)
elseif iname == "rp_default:acorn" then
if npc_type == "farmer" then
say(S("Boars love to eat acorns! If you feed enough of these to them, they will multiply."), name)
else
say(S("Apples are so tasty!"), name)
end
elseif iname == "rp_default:reed_block" then
say(S("Did you try to dry it in the furnace?"), name)
elseif minetest.get_item_group(iname, "airweed") > 0 then
if npc_type == "carpenter" then
say(S("Airweed is an underwater plant with little capsules filled with air. Use it underwater to release air bubbles and catch some breath."), name)
elseif npc_type == "butcher" then
say(S("If you use the airweed plant, you will catch some breath. Other people near the plant will also benefit."), name)
elseif npc_type == "farmer" then
say(S("Airweed is very useful, but it can't give you breath from your hand. You must place it on the ground first."), name)
else
say(S("Airweed needs a moment to refill after you used it. The time it needs depends on the surface."), name)
end
elseif iname == "rp_default:alga" then
if npc_type == "farmer" then
say(S("If you fertilize the ground, an alga will grow higher."), name)
elseif npc_type == "tavernkeeper" then
say(S("The tallest algae always grow on alga blocks.", name))
elseif npc_type == "carpenter" then
say(S("If an alga tries to grow but something blocks its path, it'll stop growing, even if the barrier is removed later.", name))
else
say(S("Algae grow underwater in different heights."), name)
end
elseif iname == "rp_default:vine" then
if npc_type == "farmer" then
say(S("Place it at the ceiling and watch it grow."), name)
elseif npc_type == "carpenter" then
say(S("If you want the vine to stops growing, make a precise cut using scissors."), name)
else
say(S("It's climbing time!"), name)
end
elseif iname == "rp_default:dirt" then
if npc_type == "farmer" then
say(S("Many wild plants as well as wheat and cotton grow on dirt, but they grow better when it's fertilized."), name)
else
say(S("You're dirty!"), name)
end
elseif iname == "rp_default:swamp_dirt" then
if npc_type == "farmer" then
say(S("Swamp dirt is really interesting. The famous swamp oak grows on it, and papyrus also grows exceptionally well."), name)
else
say(S("Disgusting!"), name)
end
elseif iname == "rp_default:dry_dirt" then
if npc_type == "farmer" then
say(S("Not much grows on dry dirt."), name)
else
say(S("This dirt is as dry as my jokes."), name)
end
elseif iname == "rp_default:sand" then
if npc_type == "farmer" then
say(S("You can use sand to grow cacti."), name)
else
say(S("Be careful not to let it fall on your head!"), name)
end
elseif minetest.get_item_group(iname, "stone") > 0 then
if npc_type == "butcher" then
say(S("This is like my ex-lover's heart. Made out of stone."), name)
else
say_random("happy", name)
end
elseif minetest.get_item_group(iname, "food") > 0 then
say(S("Stay healthy!"), name)
else
local r = math.random(1,3)
if r == 1 then
say_random("trade", name)
elseif r == 2 then
say(msgs.npc[npc_type], name)
else
say_random("happy", name)
end
end
elseif hp >= 5 then
say_random("exhausted", name)
else
say_random("hurt", name)
end
end
end
end,
})
mobs:register_egg("mobs:npc_" .. npc_type, npc_name, "mobs_npc_"..npc_type.."_inventory.png")
end