2021-07-25 23:47:45 +02:00
-- ###
-- 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 = {
2021-07-26 01:25:29 +02:00
" size[13.4,15] " ,
2021-07-25 23:47:45 +02:00
" dropdown[0.3,0.2;4,0.75;set_skin; " ,
2022-07-12 21:07:21 +02:00
mainlist or " " ,
2021-07-25 23:47:45 +02:00
" ; " ,
2022-07-12 21:07:21 +02:00
mainindex or " " ,
2021-07-25 23:47:45 +02:00
" ] " ,
" label[4.6,0.45; " ,
yl_speak_up.speak_to [ pname ] . n_id ,
" ] " ,
" label[6,0.45; " ,
2022-05-27 19:49:37 +02:00
( yl_speak_up.speak_to [ pname ] . n_npc or " - nameless - " ) ,
2021-07-25 23:47:45 +02:00
" ] " ,
" dropdown[9.1,0.2;4,0.75;set_cape; " ,
2022-07-12 21:07:21 +02:00
capelist or " " ,
2021-07-25 23:47:45 +02:00
" ; " ,
2022-07-12 21:07:21 +02:00
capeindex or " " ,
2021-07-25 23:47:45 +02:00
" ] " ,
2021-07-26 01:25:29 +02:00
" label[0.3,3.2; " ,
2022-07-12 21:07:21 +02:00
textures [ 4 ] or " " ,
2021-07-25 23:47:45 +02:00
" ] " ,
2021-07-26 01:25:29 +02:00
" label[9.1,3.2; " ,
2022-07-12 21:07:21 +02:00
textures [ 3 ] or " " ,
2021-07-25 23:47:45 +02:00
" ] " ,
" field_close_on_enter[set_sword;false] " ,
" field_close_on_enter[set_shield;false] " ,
" image[0.3,1;4,2; " ,
2022-07-12 21:07:21 +02:00
textures [ 2 ] or " " ,
2021-07-25 23:47:45 +02:00
" ] " , -- Main
" image[9.1,1;4,2; " ,
2022-07-12 21:07:21 +02:00
textures [ 1 ] or " " ,
2021-07-25 23:47:45 +02:00
" ] " , -- Cape
" image[0.3,4.2;4,4; " ,
2022-07-12 21:07:21 +02:00
textures [ 4 ] or " " ,
2021-07-25 23:47:45 +02:00
" ] " , -- Sword
" image[9.1,4.2;4,4; " ,
2022-07-12 21:07:21 +02:00
textures [ 3 ] or " " ,
2021-07-25 23:47:45 +02:00
" ] " , --textures[3],"]", -- Shield
" image[4.7,1;4,8; " ,
2022-07-12 21:07:21 +02:00
preview or " " ,
2021-07-25 23:47:45 +02:00
" ] " ,
2022-05-29 19:30:04 +02:00
" button[0.3,8.4;3,0.75;button_cancel; " .. button_cancel .. " ] " ,
2021-07-26 01:25:29 +02:00
" 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 \n left:] " ,
" label[12.0,9.7;Wield \n right:] " ,
" 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.] " ,
2021-07-25 23:47:45 +02:00
}
return table.concat ( formspec , " " )
end
2021-07-27 19:28:45 +02:00
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
2021-07-25 23:47:45 +02:00
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
2021-07-26 01:25:29 +02:00
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
2021-07-27 19:28:45 +02:00
yl_speak_up.fashion_wield_give_items_back ( player , pname )
2021-07-26 01:25:29 +02:00
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 } )
2021-07-27 19:28:45 +02:00
local player_inv = player : get_inventory ( )
2021-07-26 01:25:29 +02:00
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 ( ) )
2021-07-25 23:47:45 +02:00
yl_speak_up.log_change ( pname , n_id ,
2021-07-26 01:25:29 +02:00
" (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 ( ) )
2021-07-25 23:47:45 +02:00
yl_speak_up.log_change ( pname , n_id ,
" (fashion) shield changed to " .. tostring ( fields.set_shield ) .. " . " )
2021-07-26 01:25:29 +02:00
end
2021-07-27 19:28:45 +02:00
yl_speak_up.fashion_wield_give_items_back ( player , pname )
2021-07-25 23:47:45 +02:00
2021-07-26 01:25:29 +02:00
-- 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
2021-07-27 00:35:46 +02:00
yl_speak_up.log_change ( pname , n_id ,
2021-07-26 01:25:29 +02:00
" (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 ,
2021-07-25 23:47:45 +02:00
" (fashion) saved changes. " )
2021-07-26 01:25:29 +02:00
end
2021-07-27 19:28:45 +02:00
yl_speak_up.fashion_wield_give_items_back ( player , pname )
2021-07-26 01:25:29 +02:00
end
2021-07-25 23:47:45 +02:00
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 )
2022-04-22 03:45:52 +02:00
local dialog = yl_speak_up.load_dialog ( n_id , false )
2021-07-25 23:47:45 +02:00
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
2021-07-26 01:25:29 +02:00
-- 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