2019-05-02 00:01:47 -07:00
--
-- This file adds function to complete the mobs_redo api
--
2020-01-13 07:53:32 -08:00
-- Translator
local S = mobs.translator
2019-05-02 00:01:47 -07:00
local modname = minetest.get_current_modname ( )
local modpath = minetest.get_modpath ( modname )
2020-01-13 11:27:16 -08:00
local vlog = mobs.vlog or " action " --"info"
2020-01-14 07:53:53 -08:00
local vlog = " action " --"info"
local cooldown_mult = 9
2019-05-02 00:01:47 -07:00
if not mobs.npcs then mobs.npcs = { } end
if not mobs.npcs . messages then mobs.npcs . messages = { } end
2020-01-13 11:27:16 -08:00
if not mobs.npcs . messages.random then mobs.npcs . messages.random = { } end
2019-05-02 00:01:47 -07:00
---------------------------------------------------------------------------------------------
-- 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
2020-01-13 11:27:16 -08:00
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
2019-05-02 00:01:47 -07:00
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
2020-01-14 07:53:53 -08:00
if not msg then msg = " " end
2019-05-02 00:01:47 -07:00
return minetest.chat_send_player ( playername , ' < ' .. mobname .. ' > ' .. msg )
end
2020-01-13 06:04:48 -08:00
mobs.npcs . random_message_on_rightclick = function ( self , player , data )
2019-05-02 00:01:47 -07:00
2020-01-13 06:04:48 -08:00
-- 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
2020-01-14 07:53:53 -08:00
mobs.npcs . message_on_rightclick = function ( self , player , data , varname )
2020-01-13 06:04:48 -08:00
-- Get things to say
local str = " "
if not data then data = { } end
2020-01-14 07:53:53 -08:00
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 "
2020-01-13 06:04:48 -08:00
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
2019-05-02 00:01:47 -07:00
2020-01-14 04:39:15 -08:00
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
2020-01-14 07:53:53 -08:00
-- Return diff between hp and hp_max
return hp_max - hp
2020-01-14 04:39:15 -08:00
end
mobs.npcs . heal_on_rightclick = function ( self , player , data )
2020-01-14 07:53:53 -08:00
if self._cooldown and self._cooldown > 0 then
mobs.npcs . message_on_rightclick ( self , player , data , ' message_cooldown ' )
return
end
2020-01-14 04:39:15 -08:00
-- Get current HP and HP_MAX
-- local hp = player:get_hp()
local hp_max = player : get_properties ( ) . hp_max
2020-01-14 07:53:53 -08:00
-- 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 .. ' . ' )
2020-01-14 04:39:15 -08:00
end
2019-05-02 00:01:47 -07:00
2020-01-13 11:27:16 -08:00
-- 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
2019-05-02 00:01:47 -07:00
-- 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
2020-01-13 11:27:16 -08:00
mobs.npcs . messages.get_list_from_file = function ( basename )
if not basename then return end
2019-05-02 00:01:47 -07:00
local line_number = 1
2020-01-13 11:27:16 -08:00
local messages = { }
2019-05-02 00:01:47 -07:00
-- Look into the world folder first
2020-01-13 11:27:16 -08:00
local input = io.open ( minetest.get_worldpath ( ) .. ' / ' .. basename .. ' .txt ' , " r " )
2019-05-02 00:01:47 -07:00
-- If it fails, try looking elswhere
if not input then
-- Localized default file in the mod folder
2020-01-13 11:27:16 -08:00
local default_input = io.open ( minetest.get_modpath ( modname ) .. ' / ' .. basename .. ' . ' .. LANG .. ' .txt ' , " r " )
local output = io.open ( minetest.get_worldpath ( ) .. ' / ' .. basename .. ' .txt ' , " w " )
2019-05-02 00:01:47 -07:00
if not default_input then
-- localised file not found, look for a generic default file in the mod folder
2020-01-13 11:27:16 -08:00
default_input = io.open ( minetest.get_modpath ( modname ) .. ' / ' .. basename .. ' .txt ' , " r " )
2019-05-02 00:01:47 -07:00
end
if not default_input then
-- Now we're out of options, blame the admin
2020-01-13 11:27:16 -08:00
-- 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. ' )
2019-05-02 00:01:47 -07:00
else
-- or write default_input content in worldpath message file
2020-01-13 11:27:16 -08:00
minetest.log ( vlog , ' [ ' .. modname .. ' ] ' .. ' No input message file found for " ' .. basename .. ' "... updating world folder data ' )
2019-05-02 00:01:47 -07:00
local content = default_input : read ( " *all " )
output : write ( content )
end
io.close ( output )
if default_input then io.close ( default_input ) end
2020-01-13 11:27:16 -08:00
input = io.open ( minetest.get_worldpath ( ) .. ' / ' .. basename .. ' .txt ' , " r " )
2019-05-02 00:01:47 -07:00
end
-- we should have input by now, so lets read it
for line in input : lines ( ) do
2020-01-13 11:27:16 -08:00
messages [ line_number ] = line
2019-05-02 00:01:47 -07:00
line_number = line_number + 1
end
-- close it
io.close ( input )
2020-01-13 11:27:16 -08:00
return messages
2019-05-02 00:01:47 -07:00
end
-- Fill messages array when server start.
2020-01-13 15:32:28 -08:00
--
2020-01-13 11:27:16 -08:00
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 )
2019-05-02 00:01:47 -07:00
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 ( )
2020-01-13 11:27:16 -08:00
return table.random ( mobs.npcs . messages.random )
2019-05-02 00:01:47 -07:00
end
mobs.npcs . messages.get_random_from_string = function ( str )
2020-01-13 15:32:28 -08:00
local arr = string.lines_to_table ( str )
2020-01-13 11:27:16 -08:00
return table.random ( arr )
2019-05-02 00:01:47 -07:00
end