diff --git a/mobs_api.lua b/mobs_api.lua index 7d7e0ec..e54789f 100755 --- a/mobs_api.lua +++ b/mobs_api.lua @@ -8,6 +8,8 @@ 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 @@ -83,6 +85,7 @@ 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 @@ -99,12 +102,16 @@ mobs.npcs.random_message_on_rightclick = function(self,player,data) end -mobs.npcs.message_on_rightclick = function(self,player,data) +mobs.npcs.message_on_rightclick = function(self,player,data,varname) -- Get things to say local str = "" if not data then data = {} end - if data.action and data.action.message then - str = data.action.message or "" + 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) @@ -135,17 +142,28 @@ local function heal_loop(player,hp_max,c) 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 - -- Calculate new hp - heal_loop(player,hp_max) - mobs.npcs.message_on_rightclick(self,player,data) + + -- 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 diff --git a/npc_custom.lua b/npc_custom.lua index ce8c437..5fcae24 100755 --- a/npc_custom.lua +++ b/npc_custom.lua @@ -121,14 +121,26 @@ mobs.npcs.interactions = { }, on_rightclick = mobs.npcs.message_on_rightclick, }, - -- TODO: Set a timeout between heals with a different message too + -- DONE: Set a timeout between heals with a different message too -- TODO: Or set a limit per player per days heal = { icon = icprefix..'healer.png', desc = S("Heal the player"), formfields = { - {'textarea','message','',4}, + {'label','Say one of theses sentences while healing',0.5}, + {'textarea','message_heal','',3}, + {'label','Say one of theses sentences during cooldown',0.5}, + {'textarea','message_cooldown','',2}, }, + message_heal = S("There you go... good as new !") + .. "\n" .. S("Oh you look bad, let fix you...") + .. "\n" .. S("Not what I was expecting but... good for you !") + .. '', + message_cooldown = S("I'm tired.") + .. "\n" .. S("I'm resting for a bit...") + .. "\n" .. S("I can't help you now.") + .. "\n" .. S("Come back later.") + .. '', on_rightclick = mobs.npcs.heal_on_rightclick, }, -- Following actions are planned but do not exist at the moment @@ -285,15 +297,18 @@ local function get_npc_formspec(pos,n) local ai = find_in_array(action.id,acts) or 1 local actionf = '' local ayi = iy+2 - if mobs.npcs.interactions[action.id] and mobs.npcs.interactions[action.id].formfields then - for _,v in ipairs(mobs.npcs.interactions[action.id].formfields) do + local action_arr = mobs.npcs.interactions[action.id] + if action_arr and action_arr.formfields then + for _,v in ipairs(action_arr.formfields) do if v[1] == 'label' then actionf = actionf .. 'label[0,'.. ayi ..';'..v[2]..']' - ayi = ayi + 1 + ayi = ayi + 0.5 elseif v[1] == 'textarea' then + -- {'textarea','message_cooldown','',2}, local aname = v[2] - local dstr = action[aname] or S("Hello").."\n"..S("Hi").."\n"..S("Hey") + local dstr = action_arr[aname] or S("Hello").."\n"..S("Hi").."\n"..S("Hey") actionf = actionf .. 'textarea[0.3,'.. ayi ..';'..fw..','..v[4]..';action_'..v[2]..';'..v[3]..';'..dstr..']' + -- print(dump(actionf)) ayi = ayi + v[4] + 0.1 end end @@ -538,7 +553,30 @@ end mob_def.walk_chance = 0 mob_def.jump = false +local dtstep = 15 +local dt = 0 mob_def.do_custom = function(self, dtime) + + -- Save memory by runing only 1/dtstep times + if dt < dtstep then + dt = dt + 1 + return false + else + dt = 0 + end + + + -- Make sure that cooldown is a number + if type(self._cooldown) ~= 'number' + or self._cooldown <= 0 + then + self._cooldown = 0 + -- Cooldown if needed + else + self._cooldown = self._cooldown - ( dtstep * dtime ) + -- print('Cooldown : '..dump(self._cooldown)) + end + --- Get mob pos local pos = self.object:get_pos() local spawner_pos = self._spawner_pos @@ -558,8 +596,8 @@ mob_def.do_custom = function(self, dtime) --- Spawner pos is not set... if ( not spawner_pos ) - --- Or mob if too far from spawner - or ( vector.distance(pos, spawner_pos) > 2 ) + --- Or mob is away from spawner + or ( vector.distance(pos, spawner_pos) > 1 ) --- Or spawner has been removed or ( minetest.get_node(spawner_pos).name ~= spawner_id ) then @@ -574,14 +612,14 @@ mob_def.do_custom = function(self, dtime) mobs.npcs.add_cmob(spawner_pos, data.owner) end -- set_mob_data(spawner_pos,data) - -- mobs.npcs.update_cmob_properties(spawner_pos, _, self.obj) + -- mobs.npcs.update_cmob_properties(spawner_pos, nil, self.obj) -- Make sure that it is still on the spawner (or at least 'in' it, or 'above' it) -- for i=-1,1 do -- local spos = { x= pos.x, y= pos.y + i, z= pos.z, } -- if ( minetest.get_node(spos).name == spawner_id ) then -- --- Stop function when spawner is found - -- mobs.npcs.update_cmob_properties(pos, _, self.obj) + -- mobs.npcs.update_cmob_properties(pos, nil, self.obj) -- return false -- end -- end @@ -639,7 +677,7 @@ mob_def.after_activate = function(self, staticdata, def, dtime) player = minetest.get_player_by_name(playername) end local mob = self.object - cmob_data_update(pos,player,_,mob) + cmob_data_update(pos,player,nil,mob) end end @@ -729,16 +767,15 @@ local on_receive_fields = function(player, formname, fields) if fields.action_id then -- if fields.action_id and (( not data.action ) or ( fields.action_id ~= data.action.id )) then data.action = data.action or {} - data.action.id = fields.action_id - data.action.message = fields.action_message or data.action.message + -- data.action.id = fields.action_id + -- data.action.message = fields.action_message or data.action.message -- data.action = mobs.npcs.interactions[fields.action_id] - -- for k,v in pairs(fields) do - -- for l in string.gmatch(k,"action_(%w+)") do - -- print(dump('action :')) - -- print(dump(l)) - -- data.action[l] = v - -- end - -- end + for k,v in pairs(fields) do + for l in string.gmatch(k,"action_([A-Za-z0-9_]+)") do + -- print('action '..dump(l)..' : '..dump(v)) + data.action[l] = v or data.action[l] + end + end end local fk = { 'nametag','nametag_color','allowed','infotext','wield_item', @@ -750,10 +787,9 @@ local on_receive_fields = function(player, formname, fields) -- data.visual_size = {x = 1, y = 1.1} - -- print('-------- DATA ------------') - -- print(dump(data)) - - + -- print('-------- DATA ------------') + -- print(dump(data)) + set_mob_data(pos,data) mobs.npcs.update_cmob_properties(pos,player,data.obj)