-- Configurable NPC -- This is a configurable NPC -- -- Translator local S = mobs.translator local vlog = mobs.vlog or "action" --"info" local vlog = "action" --"info" -- Mod related infos local modname = minetest.get_current_modname() local modpath = minetest.get_modpath(modname) local mob_name = "npc_idler" local icprefix=modname..'_icon_' local mod_storage = minetest.get_mod_storage() local serialized_mob_data = mod_storage:get_string('mob_data') mobs.npcs.mob_data = minetest.deserialize(serialized_mob_data) or {} -- ------------------ -- -- helper function -- local function find_in_array(needle,stack) if needle and stack then for k,v in ipairs(stack) do if v == needle then return k end end end return nil end data_values = { "nametag_color", "nametag", "infotext", "textures", "infotext", "wield_item", "visual_size", "action", } data_serialize = { textures = true, action = true, } local function save_node_meta(pos,data) local meta = minetest.get_meta(pos) for _,v in ipairs(data_values) do if data_serialize[v] then local szv = minetest.serialize(data[v]) meta:set_string(v,szv) else meta:set_string(v,data[v]) end end end local function get_data_from_node_meta(pos) local meta = minetest.get_meta(pos) local data = {} for _,v in ipairs(data_values) do if data_serialize[v] then data[v] = minetest.deserialize(meta:get_string(v)) else data[v] = meta:get_string(v) end end return data end local function get_mob_data(pos) local key = minetest.pos_to_string(pos) return mobs.npcs.mob_data[key] or get_data_from_node_meta(pos) end local function set_mob_data(pos,data) local key = minetest.pos_to_string(pos) mobs.npcs.mob_data[key] = data save_node_meta(pos,data) -- local sz = minetest.serialize(mobs.npcs.mob_data) -- mod_storage:set_string('mob_data',sz) end -- ------------------ -- -- helper function -- -- ------------------ -- -- helper function -- mobs.npcs.interactions = { default = { icon = icprefix..'chat_random.png', desc = S("Say one of the default random chat message strings"), on_rightclick = mobs.npcs.random_message_on_rightclick }, say = { icon = icprefix..'chat.png', desc = S("Say one of the lines below as a chat message"), formfields = { {'textarea','message','',4}, }, on_rightclick = mobs.npcs.message_on_rightclick, }, -- 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 = { {'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 -- dialog = { icon = icprefix..'dialog.png', desc = S("Open a dialog menu with a text and a choice of answers"), disabled = true, }, ai = { icon = icprefix..'ai.png', desc = S("Try to mimic an intercation with the player"), disabled = true, }, craft = { icon = icprefix..'crafter.png', desc = S("Open a special inventory where the player can give item and received some transformed output"), disabled = true, }, give = { icon = icprefix..'giver.png', desc = S("Give something to the player"), disabled = true, }, alert_owner = { icon = icprefix..'giver.png', desc = S("Send an alert to the owner (allowing)"), hidden = true, }, } -- -- Specific mob informations -- local mob_id = modname..':'..mob_name local spawner_id = modname..':'..mob_name..'_spawner' -- Get base defintion local mob_def = mobs.npcs.base_def mob_def._spawner_pos = nil local textures_string -- Get textures -- local textures = mobs.npcs.get_textures_array("character_lambda_",modname) -- if textures then -- mob_def.textures = textures -- end -- -- Register Spawn condition and egg -- -- More usable texture array local ta = {} for k,v in ipairs(mob_def.textures) do ta[k] = v[1] end local function get_npc_formspec(pos,n) local spos = pos.x .. "," .. pos.y .. "," .. pos.z local ww=8 -- window width local wh=9 -- window height local fw=5 -- field_width local iy=0.5 -- index y -- Texture list as a sring local ts = table.concat(ta,',') local data = get_mob_data(pos) or {} if data.last_tab then n = data.last_tab end if not n then n = 1 end local n = tonumber(n) minetest.log(vlog, '['..modname..'] '..'Showing formspec '..n) -- print(dump(data)) local ti = 1 -- Get texture index if data.textures then ti = find_in_array(data.textures[1],ta) or 1 end local forms = {} -- Not empty data values local dv = { nametag = data.nametag or '', nametag_color = data.nametag_color or '', infotext = data.infotext or '', texture = ts or '', wield_item = data.wield_item or '', nametag = data.nametag or '', } forms[1] = -- 'label[0,'.. iy - 0.5 ..';'..S('-- Menu de configuration --')..']' .. -- 'container[0,0]'.. -- tooltip[;;;] 'field[0.3,'.. iy+1 ..';'..fw..',0.3;nametag;'..S('Nom')..';'..dv.nametag..']' .. -- 'textarea[0.3,'.. iy+1.6 ..';'..fw..',1.6;infotext;'..S('InfoText')..';'..dv.infotext..']'.. -- 'field[0.3,'.. iy+2.5 ..';'..fw..',0.5;nametag_color;'..S('Nametag Color')..';#61ff0170]' .. -- 'label[0,'.. iy+1.5 ..';'..S('Nametag Color')..']' .. -- 'dropdown[0,'.. iy+2 ..';'..fw..';nametag_color;,,;1]' .. 'label[0,'.. iy+3 ..';'..S('Texture')..']' .. 'dropdown[0,'.. iy+3.5 ..';'..fw..';texture;'..dv.texture..';'..ti..']' .. -- 'field[0.3,'.. iy+5 ..';'..fw..',0.3;wield_item;'..S('wield_item')..';'..dv.wield_item..']' .. --~ 'button[0.1,2;2,1;form01;'..S('Look')..']' .. --~ 'button[0.1,3;2,1;form01;'..S('Actions')..']' .. -- 'button[0,'.. iy+5 ..';'..fw..',0.5;action;'..S('configurer les interactions')..']' .. 'button_exit['.. ww - 1 ..','.. wh - 1 ..';1,1;ok;ok]'.. '' forms[2] = default.gui_slots .. "list[nodemeta:" .. spos .. ";main;0,0.3;8,4;]" .. "list[current_player;main;0,4.85;8,1;]" .. "list[current_player;main;0,6.08;8,3;8]" .. "listring[nodemeta:" .. spos .. ";main]" .. "listring[current_player;main]" .. default.get_hotbar_bg(0,4.85) .. '' -- local action_buttons='' -- local l = 0.1 -- for k,v in pairs(mobs.npcs.interactions) do -- action_buttons = action_buttons..'image_button['..l..',0;1,1;'..v.icon..';'..k..';]' -- l = l + 1 -- end local acts={} for k,v in pairs(mobs.npcs.interactions) do if not ( v.disabled or v.hidden ) then acts[#acts+1] = k end end local action = data.action or {} if not data.action then data.action = {} end action.id = data.action.id or "default" action.desc = mobs.npcs.interactions[action.id].desc local actstr=table.concat(acts,',') local ai = find_in_array(action.id,acts) or 1 local actionf = '' local ayi = iy+2 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 + 0.5 elseif v[1] == 'textarea' then -- {'textarea','message_cooldown','',2}, local aname = v[2] 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 end forms[3] = 'label[0,'.. iy-0.5 ..';'..S('When a player interact with this character :')..']' .. 'dropdown[0,'.. iy+0.5 ..';'..fw..';action_id;'..actstr..';'..ai..']' .. 'label[0,'.. iy+1.5 ..';'..action.desc..']' .. actionf.. -- textlist[,;,;;,,...,;;] -- 'textlist[0,0;'..ww - 3*(ww/4)..','.. wh-1 ..';stagelist;action_1,stage_2,stage_3;1;false]'.. -- 'container['..ww - 3*(ww/4)..',0]'.. -- image_button[,;,;;;