mirror of
				https://gitea.your-land.de/Sokomine/yl_speak_up.git
				synced 2025-10-31 20:33:07 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			396 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			396 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| -- ###
 | |
| -- Fashion
 | |
| -- ###
 | |
| 
 | |
| local function cape2texture(t)
 | |
|     return "yl_speak_up_mask_cape.png^[combine:32x64:56,20=" .. t
 | |
| end
 | |
| 
 | |
| local function shield2texture(t)
 | |
|     return "yl_speak_up_mask_shield.png^[combine:32x64:0,0=(" .. t .. ")"
 | |
| end
 | |
| 
 | |
| local function textures2skin(textures)
 | |
|     local temp = {}
 | |
|     -- Cape
 | |
| 
 | |
|     local cape = cape2texture(textures[1])
 | |
| 
 | |
|     -- Main
 | |
| 
 | |
|     local main = textures[2]
 | |
| 
 | |
|     -- left (Shield)
 | |
| 
 | |
|     local left = shield2texture(textures[3])
 | |
| 
 | |
|     -- right (Sword)
 | |
| 
 | |
|     local right = textures[4]
 | |
| 
 | |
|     temp = {cape, main, left, right}
 | |
| 
 | |
|     return temp
 | |
| end
 | |
| 
 | |
| local function set_textures(obj, textures) -- this function takes the base name of the textures, converts them to usable textures and stores those on the NPC
 | |
|     local skins = textures2skin(textures)
 | |
| 
 | |
|     local ent = obj:get_luaentity()
 | |
|     ent.yl_speak_up.skin = skins
 | |
| 
 | |
|     obj:set_properties({textures = skins})
 | |
| end
 | |
| 
 | |
| local function get_npc_skins(skin)
 | |
|     local retstring = "yl_speak_up_main_default.png"
 | |
|     local rettable = {"yl_speak_up_main_default.png"}
 | |
|     local temp = {}
 | |
| 
 | |
|     -- get the files out of modpath
 | |
|     local mp_list = minetest.get_dir_list(yl_speak_up.modpath .. DIR_DELIM .. "textures", false)
 | |
| 
 | |
|     -- get the files out of worlddir
 | |
|     local wp_list =
 | |
|         minetest.get_dir_list(
 | |
|         yl_speak_up.worldpath .. DIR_DELIM .. "worldmods" .. DIR_DELIM .. "yl_npc" .. DIR_DELIM .. "textures",
 | |
|         false
 | |
|     )
 | |
| 
 | |
|     -- Let's join both lists.
 | |
|     table.insert_all(temp, mp_list)
 | |
|     table.insert_all(temp, wp_list)
 | |
| 
 | |
|     --[[ Let's see if the files are the ones we want. Format is 
 | |
|     yl_npc_main_name.png <-- Those are the ones we want
 | |
|     yl_npc_cape_name.png
 | |
|     yl_npc_item_name.png
 | |
|     ]]--
 | |
|     local index = 1
 | |
|     local retindex = 1
 | |
| 
 | |
|     for _, v in pairs(temp) do
 | |
|         local s = string.split(v, "_")
 | |
|         if s[1] == "yl" and s[2] == "npc" and s[3] == "main" then
 | |
|             index = index + 1
 | |
|             retstring = retstring .. "," .. v
 | |
|             table.insert(rettable, v)
 | |
|             if v == skin then
 | |
|                 retindex = index
 | |
|             end
 | |
|         end
 | |
|     end
 | |
| 
 | |
|     return rettable, retstring, retindex
 | |
| end
 | |
| 
 | |
| local function get_npc_capes(cape)
 | |
|     local retstring = "yl_npc_cape_default.png"
 | |
|     local rettable = {"yl_npc_cape_default.png"}
 | |
|     local temp = {}
 | |
| 
 | |
|     -- get the files out of modpath
 | |
|     local mp_list = minetest.get_dir_list(yl_speak_up.modpath .. DIR_DELIM .. "textures", false)
 | |
| 
 | |
|     -- get the files out of worlddir
 | |
|     local wp_list =
 | |
|         minetest.get_dir_list(
 | |
|         yl_speak_up.worldpath .. DIR_DELIM .. "worldmods" .. DIR_DELIM .. "yl_npc" .. DIR_DELIM .. "textures",
 | |
|         false
 | |
|     )
 | |
| 
 | |
|     -- Let's join both lists.
 | |
|     table.insert_all(temp, mp_list)
 | |
|     table.insert_all(temp, wp_list)
 | |
| 
 | |
|     --[[ Let's see if the files are the ones we want. Format is 
 | |
|     yl_npc_main_name.png
 | |
|     yl_npc_cape_name.png <-- Those are the ones we want
 | |
|     yl_npc_item_name.png
 | |
|     ]]--
 | |
|     local index = 1
 | |
|     local retindex = 1
 | |
| 
 | |
|     for _, v in pairs(temp) do
 | |
|         local s = string.split(v, "_")
 | |
| 
 | |
|         if s[1] == "yl" and s[2] == "npc" and s[3] == "cape" then
 | |
|             index = index + 1
 | |
|             retstring = retstring .. "," .. v
 | |
|             table.insert(rettable, v)
 | |
|             if cape ~= "" and v == cape then
 | |
|                 retindex = index
 | |
|             end
 | |
|         end
 | |
|     end
 | |
| 
 | |
|     return rettable, retstring, retindex
 | |
| end
 | |
| 
 | |
| local function create_preview(main_skin)
 | |
|     if main_skin == nil or main_skin == "" then
 | |
|         main_skin = "default_greyscale.png"
 | |
|     end
 | |
| 
 | |
|     local player_skin = "(" .. main_skin .. ")"
 | |
|     local skin = ""
 | |
| 
 | |
|     -- Consistent on both sizes:
 | |
|     --Chest
 | |
|     skin = skin .. "([combine:16x32:-16,-12=" .. player_skin .. "^[mask:yl_speak_up_mask_chest.png)^"
 | |
| 
 | |
|     --Head
 | |
|     skin = skin .. "([combine:16x32:-4,-8=" .. player_skin .. "^[mask:yl_speak_up_mask_head.png)^"
 | |
| 
 | |
|     --Hat
 | |
|     skin = skin .. "([combine:16x32:-36,-8=" .. player_skin .. "^[mask:yl_speak_up_mask_head.png)^"
 | |
|     --Right Arm
 | |
|     skin = skin .. "([combine:16x32:-44,-12=" .. player_skin .. "^[mask:yl_speak_up_mask_rarm.png)^"
 | |
|     --Right Leg
 | |
|     skin = skin .. "([combine:16x32:0,0=" .. player_skin .. "^[mask:yl_speak_up_mask_rleg.png)^"
 | |
| 
 | |
|     -- Left Arm
 | |
|     skin = skin .. "([combine:16x32:-24,-44=" .. player_skin .. "^[mask:(yl_speak_up_mask_rarm.png^[transformFX))^"
 | |
|     --Left Leg
 | |
|     skin = skin .. "([combine:16x32:-12,-32=" .. player_skin .. "^[mask:(yl_speak_up_mask_rleg.png^[transformFX))^"
 | |
| 
 | |
|     -- Add overlays for 64x skins. these wont appear if skin is 32x because it will be cropped out
 | |
|     --Chest Overlay
 | |
|     skin = skin .. "([combine:16x32:-16,-28=" .. player_skin .. "^[mask:yl_speak_up_mask_chest.png)^"
 | |
|     --Right Arm Overlay
 | |
|     skin = skin .. "([combine:16x32:-44,-28=" .. player_skin .. "^[mask:yl_speak_up_mask_rarm.png)^"
 | |
|     --Right Leg Overlay
 | |
|     skin = skin .. "([combine:16x32:0,-16=" .. player_skin .. "^[mask:yl_speak_up_mask_rleg.png)^"
 | |
|     --Left Arm Overlay
 | |
|     skin = skin .. "([combine:16x32:-40,-44=" .. player_skin .. "^[mask:(yl_speak_up_mask_rarm.png^[transformFX))^"
 | |
|     --Left Leg Overlay
 | |
|     skin = skin .. "([combine:16x32:4,-32=" .. player_skin .. "^[mask:(yl_speak_up_mask_rleg.png^[transformFX))"
 | |
| 
 | |
|     -- Full Preview
 | |
|     skin = "(((" .. skin .. ")^[resize:64x128)^[mask:yl_speak_up_transform.png)"
 | |
| 
 | |
|     return skin
 | |
| end
 | |
| 
 | |
| yl_speak_up.get_fs_fashion = function(pname)
 | |
|     local textures = yl_speak_up.speak_to[pname].textures
 | |
| 
 | |
|     local maintable, mainlist, mainindex = get_npc_skins(textures[2])
 | |
|     local capetable, capelist, capeindex = get_npc_capes(textures[1])
 | |
|     local preview = create_preview(textures[2])
 | |
| 
 | |
|     local button_cancel = "Cancel"
 | |
|     -- is this player editing this particular NPC? then rename the button
 | |
|     if(   yl_speak_up.edit_mode[pname]
 | |
|       and yl_speak_up.edit_mode[pname] == yl_speak_up.speak_to[pname].n_id) then
 | |
|         button_cancel = "Back"
 | |
|     end
 | |
|     local formspec = {
 | |
| 	"size[13.4,15]",
 | |
|         "dropdown[0.3,0.2;4,0.75;set_skin;",
 | |
|         mainlist,
 | |
|         ";",
 | |
|         mainindex,
 | |
|         "]",
 | |
|         "label[4.6,0.45;",
 | |
|         yl_speak_up.speak_to[pname].n_id,
 | |
|         "]",
 | |
|         "label[6,0.45;",
 | |
|         (yl_speak_up.speak_to[pname].n_npc or "- nameless -"),
 | |
|         "]",
 | |
|         "dropdown[9.1,0.2;4,0.75;set_cape;",
 | |
|         capelist,
 | |
|         ";",
 | |
|         capeindex,
 | |
|         "]",
 | |
| 	"label[0.3,3.2;",
 | |
|         textures[4],
 | |
|         "]",
 | |
| 	"label[9.1,3.2;",
 | |
|         textures[3],
 | |
|         "]",
 | |
|         "field_close_on_enter[set_sword;false]",
 | |
|         "field_close_on_enter[set_shield;false]",
 | |
|         "image[0.3,1;4,2;",
 | |
|         textures[2],
 | |
|         "]", -- Main
 | |
|         "image[9.1,1;4,2;",
 | |
|         textures[1],
 | |
|         "]", -- Cape
 | |
|         "image[0.3,4.2;4,4;",
 | |
|         textures[4],
 | |
|         "]", -- Sword
 | |
|         "image[9.1,4.2;4,4;",
 | |
|         textures[3],
 | |
|         "]", --textures[3],"]", -- Shield
 | |
|         "image[4.7,1;4,8;",
 | |
|         preview,
 | |
|         "]",
 | |
|         "button_exit[0.3,8.4;3,0.75;button_cancel;"..button_cancel.."]",
 | |
|         "button[10.1,8.4;3,0.75;button_save;Save]",
 | |
| 	"list[current_player;main;1.8,10;8,4;]",
 | |
| 	-- set wielded items
 | |
| 	"label[0.3,9.7;Wield\nleft:]",
 | |
| 	"label[12.0,9.7;Wield\nright:]",
 | |
| 	"list[detached:yl_speak_up_player_"..tostring(pname)..";wield;0.3,10.5;1,1;]",
 | |
| 	"list[detached:yl_speak_up_player_"..tostring(pname)..";wield;12.0,10.5;1,1;1]",
 | |
| 	"button[0.3,11.7;1,0.6;button_wield_left;Set]",
 | |
| 	"button[12.0,11.7;1,0.6;button_wield_right;Set]",
 | |
| 	"tooltip[button_wield_left;Set and store what your NPC shall wield in its left hand.]",
 | |
| 	"tooltip[button_wield_right;Set and store what your NPC shall wield in its right hand.]",
 | |
|     }
 | |
|     return table.concat(formspec, "")
 | |
| end
 | |
| 
 | |
| 
 | |
| yl_speak_up.fashion_wield_give_items_back = function(player, pname)
 | |
| 	-- move the item back to the player's inventory (if possible)
 | |
| 	local trade_inv = minetest.get_inventory({type="detached", name="yl_speak_up_player_"..pname})
 | |
| 	local player_inv = player:get_inventory()
 | |
| 	local left_stack  = trade_inv:get_stack("wield", 1)
 | |
| 	local right_stack = trade_inv:get_stack("wield", 2)
 | |
| 	if(left_stack and not(left_stack:is_empty())
 | |
| 	  and player_inv:add_item("main", left_stack)) then
 | |
| 		trade_inv:set_stack("wield", 1, "")
 | |
| 	end
 | |
| 	if(right_stack and not(right_stack:is_empty())
 | |
| 	  and player_inv:add_item("main", right_stack)) then
 | |
| 		trade_inv:set_stack("wield", 2, "")
 | |
| 	end
 | |
| end
 | |
| 
 | |
| 
 | |
| yl_speak_up.input_fashion = function(player, formname, fields)
 | |
|         if formname ~= "yl_speak_up:fashion" then
 | |
|             return
 | |
|         end
 | |
| 
 | |
|         local pname = player:get_player_name()
 | |
|         local textures = yl_speak_up.speak_to[pname].textures
 | |
| 
 | |
| 	local n_id = yl_speak_up.speak_to[pname].n_id
 | |
| 
 | |
| 	-- is the player editing this npc? if not: abort
 | |
| 	if(not(yl_speak_up.edit_mode[pname])
 | |
| 	  or (yl_speak_up.edit_mode[pname] ~= n_id)) then
 | |
| 		return ""
 | |
| 	end
 | |
| 
 | |
| 	-- catch ESC as well
 | |
| 	if(not(fields) or (fields.quit or fields.button_cancel or fields.button_exit)) then
 | |
| 		yl_speak_up.fashion_wield_give_items_back(player, pname)
 | |
| 		yl_speak_up.show_fs(player, "talk", {n_id = yl_speak_up.speak_to[pname].n_id,
 | |
| 						     d_id = yl_speak_up.speak_to[pname].d_id})
 | |
| 		return
 | |
| 
 | |
| 	elseif(fields.button_wield_left
 | |
| 	    or fields.button_wield_right) then
 | |
| 		local trade_inv = minetest.get_inventory({type="detached", name="yl_speak_up_player_"..pname})
 | |
| 		local player_inv = player:get_inventory()
 | |
| 		local left_stack  = trade_inv:get_stack("wield", 1)
 | |
| 		local right_stack = trade_inv:get_stack("wield", 2)
 | |
| 		if(left_stack and left_stack:get_name() and fields.button_wield_left) then
 | |
| 			textures[4] = yl_speak_up.get_wield_texture(left_stack:get_name())
 | |
| 			yl_speak_up.log_change(pname, n_id,
 | |
| 				"(fashion) sword changed to "..tostring(fields.set_sword)..".")
 | |
| 		end
 | |
| 		if(right_stack and right_stack:get_name() and fields.button_wield_right) then
 | |
| 			textures[3] = yl_speak_up.get_wield_texture(right_stack:get_name())
 | |
| 			yl_speak_up.log_change(pname, n_id,
 | |
| 				"(fashion) shield changed to "..tostring(fields.set_shield)..".")
 | |
| 		end
 | |
| 		yl_speak_up.fashion_wield_give_items_back(player, pname)
 | |
| 
 | |
| 	-- only change cape if there really is a diffrent one selected
 | |
| 	elseif(fields.set_cape and fields.set_cape ~= textures[1]) then
 | |
| 		-- only set the cape if it is part of the list of allowed capes
 | |
| 		local capetable, capelist, capeindex = get_npc_capes(textures[1])
 | |
| 		for _, v in pairs(capetable) do
 | |
| 			if(v == fields.set_cape) then
 | |
| 				textures[1] = fields.set_cape
 | |
| 				yl_speak_up.log_change(pname, n_id,
 | |
| 					"(fashion) cape changed to "..tostring(fields.set_cape)..".")
 | |
| 				-- we have found it
 | |
| 				break
 | |
| 			end
 | |
| 		end
 | |
| 
 | |
| 	-- only change the skin if there really is a diffrent new one selected
 | |
| 	elseif(fields.set_skin and fields.set_skin ~= textures[2]) then
 | |
| 		-- only set the skin if it is part of the list of allowed skins
 | |
| 		local maintable, mainlist, mainindex = get_npc_skins(textures[2])
 | |
| 		for _, v in pairs(maintable) do
 | |
| 			if(v == fields.set_skin) then
 | |
| 				textures[2] = fields.set_skin
 | |
| 				yl_speak_up.log_change(pname, n_id,
 | |
| 					"(fashion) skin changed to "..tostring(fields.set_skin)..".")
 | |
| 				-- we have found it
 | |
| 				break
 | |
| 			end
 | |
| 		end
 | |
| 	elseif fields.button_save then
 | |
| 		local obj = yl_speak_up.speak_to[pname].obj
 | |
| 		if obj ~= nil and obj:get_luaentity() ~= nil then
 | |
| 			-- save textures
 | |
| 			yl_speak_up.speak_to[pname].skins = textures2skin(textures)
 | |
| 			set_textures(obj, textures)
 | |
| 			yl_speak_up.log_change(pname, n_id,
 | |
| 				"(fashion) saved changes.")
 | |
| 		end
 | |
| 		yl_speak_up.fashion_wield_give_items_back(player, pname)
 | |
| 	end
 | |
| 	yl_speak_up.show_fs(player, "fashion")
 | |
| end
 | |
| 
 | |
| function yl_speak_up.fashion(player, obj)
 | |
|     local luaentity = obj:get_luaentity()
 | |
|     local pname = player:get_player_name()
 | |
|     local npc_id = luaentity.yl_speak_up.id
 | |
|     local skins = luaentity.yl_speak_up.skins
 | |
|     local n_id = "n_" .. npc_id
 | |
|     local t = luaentity.textures
 | |
| 
 | |
|     yl_speak_up.speak_to[pname] = {}
 | |
|     yl_speak_up.speak_to[pname].n_id = n_id
 | |
|     yl_speak_up.speak_to[pname].obj = obj
 | |
|     yl_speak_up.speak_to[pname].textures = t
 | |
|     yl_speak_up.speak_to[pname].skins = textures2skin(t)
 | |
| 
 | |
|     local dialog = yl_speak_up.load_dialog(n_id, false)
 | |
|     if next(dialog) then
 | |
|         yl_speak_up.speak_to[pname].n_npc = dialog.n_npc
 | |
|     else
 | |
|         yl_speak_up.speak_to[pname].n_npc = "Unknown"
 | |
|     end
 | |
| 
 | |
|     yl_speak_up.show_fs(player, "fashion")
 | |
| end
 | |
| 
 | |
| 
 | |
| 
 | |
| yl_speak_up.update_nametag = function(self)
 | |
|     if self.yl_speak_up.npc_name then
 | |
| 	-- the nametag is normal (green)
 | |
|         if(self.yl_speak_up.talk) then
 | |
|             self.object:set_nametag_attributes({color="#00ff00", text=self.yl_speak_up.npc_name})
 | |
| 	-- the nametag has the addition "[muted]" and is magenta when muted
 | |
|         else
 | |
| 	    self.object:set_nametag_attributes({color="#ff00ff", text=self.yl_speak_up.npc_name.." [muted]"})
 | |
|         end
 | |
|     end
 | |
| end
 | |
| 
 | |
| -- inspired/derived from the wieldview mod in 3darmor
 | |
| yl_speak_up.get_wield_texture = function(item)
 | |
| 	if(not(item) or not(minetest.registered_items[ item ])) then
 | |
| 		return "3d_armor_trans.png"
 | |
| 	end
 | |
| 	local def = minetest.registered_items[ item ]
 | |
| 	if(def.inventory_image ~= "") then
 | |
| 		return def.inventory_image
 | |
| 	elseif(def.tiles and type(def.tiles[1]) == "string" and def.tiles[1] ~= "") then
 | |
| 		return minetest.inventorycube(def.tiles[1])
 | |
| 	end
 | |
| 	return "3d_armor_trans.png"
 | |
| end
 |