284 lines
8.0 KiB
Lua
Executable File
284 lines
8.0 KiB
Lua
Executable File
--
|
|
-- This file adds function to complete the mobs_redo api
|
|
--
|
|
|
|
-- Translator
|
|
local S = mobs.translator
|
|
|
|
local modname = minetest.get_current_modname()
|
|
local modpath = minetest.get_modpath(modname)
|
|
local vlog = mobs.vlog or "action" --"info"
|
|
local vlog = "action" --"info"
|
|
local cooldown_mult = 9
|
|
|
|
if not mobs.npcs then mobs.npcs = {} end
|
|
if not mobs.npcs.messages then mobs.npcs.messages = {} end
|
|
if not mobs.npcs.messages.random then mobs.npcs.messages.random = {} end
|
|
|
|
---------------------------------------------------------------------------------------------
|
|
-- turn towards the player and stand
|
|
-- (based on function from mobf_trader)
|
|
---------------------------------------------------------------------------------------------
|
|
|
|
function get_face_direction(v1, v2)
|
|
if v1 and v2 then
|
|
if v1.x and v2.x and v1.z and v2.z then
|
|
local dx = v1.x - v2.x
|
|
local dz = v2.z - v1.z
|
|
return math.atan2(dx, dz)
|
|
end
|
|
end
|
|
end
|
|
|
|
mobs.npcs.turn_to_player = function( self, player )
|
|
-- Stand sill and pretend to listen
|
|
self.timer = 0
|
|
self.object:setvelocity({x = 0, y = 0, z = 0})
|
|
self.state = "stand"
|
|
mobs:set_animation(self, "stand")
|
|
|
|
-- Turn to player
|
|
if( self.object and self.object.setyaw ) then
|
|
self.object:setyaw( get_face_direction( self.object:getpos(), player:getpos() ));
|
|
end
|
|
end
|
|
|
|
|
|
string.lines_to_table = function(s)
|
|
if not s then s = '' end
|
|
local t = {}
|
|
local n = 1
|
|
for line in s:gmatch("[^\r\n]+") do
|
|
t[n] = line
|
|
n = n + 1
|
|
end
|
|
return t
|
|
end
|
|
|
|
|
|
mobs.npcs.get_textures_array = function(prefix,modfrom)
|
|
|
|
local n = 0
|
|
local tn, tf, fp
|
|
local tx = {}
|
|
|
|
while true do
|
|
tn = prefix .. n .. ".png"
|
|
tf = minetest.get_modpath(modname) .. "/textures/".. tn
|
|
fp = io.open(tf)
|
|
if not fp then break end
|
|
fp:close()
|
|
tx[#tx+1]={tn}
|
|
n = n + 1
|
|
end
|
|
|
|
if #tx > 0 then return tx end
|
|
end
|
|
|
|
mobs.npcs.get_mobname = function(self,generic)
|
|
local mobname = generic or 'npc'
|
|
if self and self._mobname and self._mobname ~= '' then
|
|
return self._mobname
|
|
end
|
|
return mobname
|
|
end
|
|
|
|
mobs.npcs.send_chat_message = function(playername,msg,mobname)
|
|
if not mobname then mobname = 'npc' end
|
|
if not msg then msg = "" end
|
|
return minetest.chat_send_player(playername,'<'..mobname..'> '..msg)
|
|
end
|
|
|
|
mobs.npcs.random_message_on_rightclick = function(self,player,data)
|
|
|
|
-- Get mob name
|
|
local mobname = mobs.npcs.get_mobname(self)
|
|
-- Get player name
|
|
local playername = player:get_player_name()
|
|
|
|
-- Say smething
|
|
local msg = mobs.npcs.messages.get_random()
|
|
mobs.npcs.send_chat_message(playername,msg,mobname)
|
|
end
|
|
|
|
|
|
mobs.npcs.message_on_rightclick = function(self,player,data,varname)
|
|
-- Get things to say
|
|
local str = ""
|
|
if not data then data = {} end
|
|
if not varname then varname = 'message' end
|
|
if data.action then
|
|
-- print(dump(data))
|
|
-- print(dump(varname))
|
|
-- print(data.action[varname])
|
|
str = data.action[varname] or "bof"
|
|
end
|
|
-- Get mobname
|
|
local mobname = mobs.npcs.get_mobname(self)
|
|
-- Get player name
|
|
local playername = player:get_player_name()
|
|
-- Say something
|
|
local msg = mobs.npcs.messages.get_random_from_string(str)
|
|
mobs.npcs.send_chat_message(playername,msg,mobname)
|
|
end
|
|
|
|
local function heal_loop(player,hp_max,c)
|
|
|
|
local hp = player:get_hp()
|
|
local hp = hp + 1
|
|
if hp > hp_max then hp = hp_max end
|
|
-- Set new hp
|
|
player:set_hp(hp)
|
|
|
|
-- Start couning in case to avoid endless loop in case the player is hurting while healing...
|
|
if not c then
|
|
c = 1
|
|
else
|
|
c = c+1
|
|
end
|
|
|
|
-- Start again if health is not maxed
|
|
-- And loop as not reached its limit (30)
|
|
if ( c <= 30 ) and ( hp < hp_max ) then
|
|
minetest.after(1,heal_loop,player,hp_max,c)
|
|
end
|
|
-- Return diff between hp and hp_max
|
|
return hp_max - hp
|
|
end
|
|
|
|
mobs.npcs.heal_on_rightclick = function(self,player,data)
|
|
if self._cooldown and self._cooldown > 0 then
|
|
mobs.npcs.message_on_rightclick(self,player,data,'message_cooldown')
|
|
return
|
|
end
|
|
-- Get current HP and HP_MAX
|
|
-- local hp = player:get_hp()
|
|
local hp_max = player:get_properties().hp_max
|
|
|
|
-- Send message and start healing
|
|
mobs.npcs.message_on_rightclick(self,player,data,'message_heal')
|
|
dmg = heal_loop(player,hp_max)
|
|
|
|
-- TODO: Add some effects
|
|
|
|
self._cooldown = cooldown_mult * dmg
|
|
-- Then rest for some time, depending on how much damage were healed
|
|
minetest.log(vlog, '['..modname..'] '..'Player '.. player:get_player_name() .. ' was healed by NPC mob at '.. minetest.pos_to_string(player:get_pos()).. '. Cooldown was set to '..self._cooldown..'.' )
|
|
end
|
|
|
|
|
|
-- Register messages
|
|
-- Input must be either a string or a table of indexed values
|
|
-- Non-indexed values in tables will be ignored
|
|
mobs.npcs.messages.register_random = function(var)
|
|
local t
|
|
if type(var) == "table" then
|
|
t = var
|
|
elseif type(var) == "string" then
|
|
t = string.lines_to_table(var)
|
|
else
|
|
return false
|
|
end
|
|
local glob = mobs.npcs.messages.random
|
|
for _,v in ipairs(t) do
|
|
glob[#glob+1]= v
|
|
end
|
|
mobs.npcs.messages.random = glob
|
|
return true
|
|
end
|
|
|
|
|
|
|
|
|
|
-- Define langage (code from intllib mod)
|
|
local LANG = minetest.settings:get("language")
|
|
if not (LANG and (LANG ~= "")) then LANG = os.getenv("LANG") end
|
|
if not (LANG and (LANG ~= "")) then LANG = "en" end
|
|
LANG = LANG:sub(1, 2)
|
|
|
|
-- Reused from mod random_messages
|
|
mobs.npcs.messages.get_list_from_file = function(basename)
|
|
if not basename then return end
|
|
local line_number = 1
|
|
local messages = {}
|
|
|
|
-- Look into the world folder first
|
|
local input = io.open(minetest.get_worldpath()..'/'..basename..'.txt',"r")
|
|
|
|
-- If it fails, try looking elswhere
|
|
if not input then
|
|
|
|
-- Localized default file in the mod folder
|
|
local default_input = io.open(minetest.get_modpath(modname)..'/'..basename..'.'..LANG..'.txt',"r")
|
|
local output = io.open(minetest.get_worldpath()..'/'..basename..'.txt',"w")
|
|
if not default_input then
|
|
-- localised file not found, look for a generic default file in the mod folder
|
|
default_input = io.open(minetest.get_modpath(modname)..'/'..basename..'.txt',"r")
|
|
end
|
|
|
|
if not default_input then
|
|
-- Now we're out of options, blame the admin
|
|
-- output:write("Blame the server admin! He/She has probably not edited the random messages yet.\n")
|
|
-- output:write("Tell your dumb admin that this line is in (worldpath)/random_messages \n")
|
|
-- As fun a the above would be, using default files or leaving this the output empty is now more convenient
|
|
minetest.log(vlog, '['..modname..'] '..'No input message file found for "'..basename.. '"... ignoring. Place a file named '.. basename .. '.txt' .. ' in world directory to add messages to the random messages list.' )
|
|
|
|
else
|
|
-- or write default_input content in worldpath message file
|
|
minetest.log(vlog, '['..modname..'] '..'No input message file found for "'..basename.. '"... updating world folder data' )
|
|
local content = default_input:read("*all")
|
|
output:write(content)
|
|
end
|
|
io.close(output)
|
|
|
|
if default_input then io.close(default_input) end
|
|
input = io.open(minetest.get_worldpath()..'/'..basename..'.txt',"r")
|
|
|
|
end
|
|
|
|
-- we should have input by now, so lets read it
|
|
for line in input:lines() do
|
|
messages[line_number] = line
|
|
line_number = line_number + 1
|
|
end
|
|
-- close it
|
|
io.close(input)
|
|
return messages
|
|
end
|
|
|
|
-- Fill messages array when server start.
|
|
--
|
|
local default_messages_file_name = "mobs_npc_messages"
|
|
|
|
local messages_default = mobs.npcs.messages.get_list_from_file("mobs_npc_messages")
|
|
local messages_extra = mobs.npcs.messages.get_list_from_file("mobs_npc_messages_extra")
|
|
|
|
mobs.npcs.messages.register_random(messages_default)
|
|
mobs.npcs.messages.register_random(messages_extra)
|
|
|
|
|
|
|
|
function table.count( t )
|
|
local i = 0
|
|
for k in pairs( t ) do i = i + 1 end
|
|
return i
|
|
end
|
|
|
|
function table.random( t )
|
|
local rk = math.random( 1, table.count( t ) )
|
|
local i = 1
|
|
for k, v in pairs( t ) do
|
|
if ( i == rk ) then return v, k end
|
|
i = i + 1
|
|
end
|
|
end
|
|
|
|
mobs.npcs.messages.get_random = function()
|
|
return table.random(mobs.npcs.messages.random)
|
|
end
|
|
|
|
mobs.npcs.messages.get_random_from_string = function(str)
|
|
local arr = string.lines_to_table(str)
|
|
return table.random(arr)
|
|
end
|