added inventory to npc which is stored to disk
This commit is contained in:
		
							parent
							
								
									5fe7991599
								
							
						
					
					
						commit
						0efa7f4f63
					
				| @ -6,6 +6,9 @@ yl_speak_up.talk_after_spawn = true | ||||
| 
 | ||||
| yl_speak_up.path = "yl_speak_up_dialogs" | ||||
| 
 | ||||
| -- What shall we call the folder all the inventories of the NPC will reside in? | ||||
| yl_speak_up.inventory_path = "yl_speak_up_inventories" | ||||
| 
 | ||||
| -- Texts | ||||
| 
 | ||||
| yl_speak_up.message_button_option_exit = "Farewell!" | ||||
|  | ||||
| @ -1457,6 +1457,14 @@ local function get_fs_talkdialog(player, n_id, d_id) | ||||
| 			"a conversation is started.]") | ||||
|             end | ||||
| 
 | ||||
| 	    -- access the inventory of the NPC | ||||
| 	    h = h + 1 | ||||
|             table.insert(formspec, "button[0.5," .. h .. ";53.8,0.9;show_inventory;]") | ||||
|             table.insert(formspec, "tooltip[show_inventory;Access and manage the inventory of the NPC. ".. | ||||
| 			"This is used for adding trade items, getting collected payments and managing ".. | ||||
| 			"quest items.]") | ||||
|             table.insert(formspec, "label[0.7,"..(h+0.45)..";I am your owner. Show me your inventory!]") | ||||
| 
 | ||||
| 	    -- chat option: Mute/Unmute NPC | ||||
|             h = h + 1 | ||||
|             local obj = yl_speak_up.speak_to[pname].obj | ||||
| @ -1717,10 +1725,26 @@ minetest.register_on_player_receive_fields( function(player, formname, fields) | ||||
| 	elseif formname == "yl_speak_up:fashion" then | ||||
| 		yl_speak_up.input_fashion(player, formname, fields) | ||||
| 		return true | ||||
| 	elseif formname == "yl_speak_up:inventory" then | ||||
| 		yl_speak_up.input_inventory(player, formname, fields) | ||||
| 		return true | ||||
| 	end | ||||
| end) | ||||
| 
 | ||||
| 
 | ||||
| -- the player has closed the inventory formspec of the NPC - save it | ||||
| yl_speak_up.input_inventory = function(player, formname, fields) | ||||
|         local pname = player:get_player_name() | ||||
| 	local d_id = yl_speak_up.speak_to[pname].d_id | ||||
| 	local n_id = yl_speak_up.speak_to[pname].n_id | ||||
| 	-- after closing the inventory formspec: | ||||
| 	-- ..save the (very probably) modified inventory | ||||
| 	yl_speak_up.save_npc_inventory(n_id) | ||||
| 	-- ..and go back to the normal talk formspec | ||||
| 	minetest.show_formspec(pname, "yl_speak_up:talk", get_fs_talkdialog(player, n_id, d_id)) | ||||
| end | ||||
| 
 | ||||
| 
 | ||||
| yl_speak_up.input_optiondialog = function(player, formname, fields) | ||||
|         if formname ~= "yl_speak_up:optiondialog" then | ||||
|             return | ||||
| @ -2742,6 +2766,14 @@ yl_speak_up.input_talk = function(player, formname, fields) | ||||
| 		return | ||||
| 	end | ||||
| 
 | ||||
| 	-- the player wants to access the inventory of the NPC | ||||
| 	if(edit_mode and fields.show_inventory) then | ||||
| 		local dialog = yl_speak_up.speak_to[pname].dialog | ||||
| 		-- the inventory is just an inventory with a back button; come back to this dialog here | ||||
| 		minetest.show_formspec(pname, "yl_speak_up:inventory", yl_speak_up.get_fs_inventory(player, n_id, dialog.n_npc)) | ||||
| 		return | ||||
| 	end | ||||
| 
 | ||||
| 	-- change skin, cape and wielded items | ||||
| 	if(edit_mode and fields.edit_skin) then | ||||
| 		local dialog = yl_speak_up.speak_to[pname].dialog | ||||
| @ -3147,6 +3179,9 @@ function yl_speak_up.after_activate(self, staticdata, def, dtime) | ||||
|     end | ||||
| 
 | ||||
|     yl_speak_up.update_nametag(self) | ||||
| 
 | ||||
|     -- create a detached inventory for the npc and load its inventory | ||||
|     yl_speak_up.load_npc_inventory("n_"..tostring(self.yl_speak_up.id)) | ||||
| end | ||||
| 
 | ||||
| function yl_speak_up.talk(self, clicker) | ||||
|  | ||||
							
								
								
									
										6
									
								
								init.lua
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								init.lua
									
									
									
									
									
								
							| @ -17,12 +17,16 @@ yl_speak_up.speak_to = {} | ||||
| 
 | ||||
| dofile(modpath .. "config.lua") | ||||
| dofile(modpath .. "privs.lua") | ||||
| -- inventory management, trading and handling of quest items: | ||||
| dofile(modpath .. "inventory.lua") | ||||
| dofile(modpath .. "functions.lua") | ||||
| dofile(modpath .. "tools.lua") | ||||
| dofile(modpath .. "mobs.lua") | ||||
| --dofile(modpath .. "debug.lua") | ||||
| 
 | ||||
| minetest.mkdir(yl_speak_up.worldpath..yl_speak_up.path) | ||||
| minetest.mkdir(yl_speak_up.worldpath..yl_speak_up.inventory_path) | ||||
| 
 | ||||
| yl_speak_up.mob_table = yl_speak_up.init_mob_table() or {} | ||||
| 
 | ||||
| minetest.log("action","[MOD] yl_speak_up loaded") | ||||
| minetest.log("action","[MOD] yl_speak_up loaded") | ||||
|  | ||||
							
								
								
									
										126
									
								
								inventory.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										126
									
								
								inventory.lua
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,126 @@ | ||||
| -- inventory management, trading and handling of quest items for talking to NPCs | ||||
| 
 | ||||
| -- cache the inventory of NPCs for easier access | ||||
| yl_speak_up.npc_inventory = {} | ||||
| 
 | ||||
| -- where are they stored on the disk? | ||||
| yl_speak_up.get_inventory_save_path = function(n_id) | ||||
|     return yl_speak_up.worldpath .. yl_speak_up.inventory_path .. DIR_DELIM .. "inv_" .. n_id .. ".json" | ||||
| end | ||||
| 
 | ||||
| 
 | ||||
| -- access the inventory of the NPC (only possible for players with the right priv) | ||||
| yl_speak_up.get_fs_inventory = function(player, n_id, npc_name) | ||||
| 	return "size[12,11]" .. | ||||
| 		"label[2,-0.2;Inventory of "..minetest.formspec_escape(npc_name).. | ||||
| 			" (ID: "..tostring(n_id).."):]".. | ||||
| 		"list[detached:yl_npc_"..tostring(n_id)..";npc_main;0,0.3;12,6;]" .. | ||||
| 		"list[current_player;main;2,6.85;8,1;]" .. | ||||
| 		"list[current_player;main;2,8.08;8,3;8]" .. | ||||
| 		"listring[detached:yl_npc_"..tostring(n_id)..";npc_main]" .. | ||||
| 		"listring[current_player;main]" .. | ||||
| 		"button[10.0,10.2;2,0.9;back_from_inventory;Back]" | ||||
| end | ||||
| 
 | ||||
| 
 | ||||
| -- save the inventory of the NPC with the id n_id | ||||
| yl_speak_up.save_npc_inventory = function( n_id ) | ||||
| 	-- only save something if we actually can | ||||
| 	if(not(n_id) or not(yl_speak_up.npc_inventory[ n_id ])) then | ||||
| 		return | ||||
| 	end | ||||
| 	-- convert the inventory data to something we can actually store | ||||
| 	local inv = yl_speak_up.npc_inventory[ n_id ] | ||||
| 	local inv_as_table = {} | ||||
| 	for i=1, inv:get_size("npc_main") do | ||||
| 		local stack = inv:get_stack("npc_main", i) | ||||
| 		-- only save those slots that are not empty | ||||
| 		if(not(stack:is_empty())) then | ||||
| 			inv_as_table[ i ] = stack:to_table() | ||||
| 		end | ||||
| 	end | ||||
| 	-- convert the table into json | ||||
| 	local json = minetest.write_json( inv_as_table ) | ||||
| 	-- get a file name for storing the data | ||||
| 	local file_name = yl_speak_up.get_inventory_save_path(n_id) | ||||
| 	-- actually store it on disk | ||||
| 	minetest.safe_file_write(file_name, json) | ||||
| end | ||||
| 
 | ||||
| 
 | ||||
| -- create and load the detached inventory in yl_speak_up.after_activate; | ||||
| -- direct access to this inventory is only possible for players with the right privs | ||||
| yl_speak_up.load_npc_inventory = function(n_id) | ||||
| 	if(not(n_id)) then | ||||
| 		return | ||||
| 	end | ||||
| 	-- the inventory is already loaded | ||||
| 	if( yl_speak_up.npc_inventory[ n_id ]) then | ||||
| 		return | ||||
| 	end | ||||
| 	-- create the detached inventory (it is empty for now) | ||||
| 	local npc_inv = minetest.create_detached_inventory("yl_npc_"..tostring(n_id), { | ||||
| 		allow_move = function(inv, from_list, from_index, to_list, to_index, count, player) | ||||
| 			if(not(yl_speak_up.may_edit_npc(player, n_id))) then | ||||
| 				return 0 | ||||
| 			end | ||||
| 			return count | ||||
| 		end, | ||||
| 	        -- Called when a player wants to move items inside the inventory. | ||||
| 	        -- Return value: number of items allowed to move. | ||||
| 
 | ||||
| 	        allow_put = function(inv, listname, index, stack, player) | ||||
| 			if(not(yl_speak_up.may_edit_npc(player, n_id))) then | ||||
| 				return 0 | ||||
| 			end | ||||
| 			return stack:get_count() | ||||
| 		end, | ||||
| 	        -- Called when a player wants to put something into the inventory. | ||||
| 	        -- Return value: number of items allowed to put. | ||||
| 	        -- Return value -1: Allow and don't modify item count in inventory. | ||||
| 
 | ||||
| 	        allow_take = function(inv, listname, index, stack, player) | ||||
| 			if(not(yl_speak_up.may_edit_npc(player, n_id))) then | ||||
| 				return 0 | ||||
| 			end | ||||
| 			return stack:get_count() | ||||
| 		end | ||||
| 	        -- Called when a player wants to take something out of the inventory. | ||||
| 	        -- Return value: number of items allowed to take. | ||||
| 	        -- Return value -1: Allow and don't modify item count in inventory. | ||||
| 
 | ||||
| --	        on_move = function(inv, from_list, from_index, to_list, to_index, count, player) end, | ||||
| --	        on_put = function(inv, listname, index, stack, player) end, | ||||
| --	        on_take = function(inv, listname, index, stack, player) end, | ||||
| 	        -- Called after the actual action has happened, according to what was | ||||
| 	        -- allowed. | ||||
| 	        -- No return value. | ||||
| 	}) | ||||
| 	-- the NPC needs enough room for trade items, payment and questitems | ||||
| 	npc_inv:set_size("npc_main", 6*12) | ||||
| 
 | ||||
| 	-- cache a pointer to this inventory for easier access | ||||
| 	yl_speak_up.npc_inventory[ n_id ] = npc_inv | ||||
| 
 | ||||
| 	-- find out where the inventory of the NPC is stored | ||||
| 	local file_name = yl_speak_up.get_inventory_save_path(n_id) | ||||
| 
 | ||||
| 	-- load the data from the file | ||||
| 	local file, err = io.open(file_name, "r") | ||||
| 	if err then | ||||
| 		return | ||||
| 	end | ||||
| 	io.input(file) | ||||
| 	local text = io.read() | ||||
| 	local inv_as_table = minetest.parse_json(text) | ||||
| 	io.close(file) | ||||
| 
 | ||||
| 	if(type(inv_as_table) ~= "table") then | ||||
| 		return | ||||
| 	end | ||||
| 
 | ||||
| 	-- restore the inventory | ||||
| 	for i=1, npc_inv:get_size("npc_main") do | ||||
| 		npc_inv:set_stack("npc_main", i, ItemStack( inv_as_table[ i ])) | ||||
| 	end | ||||
| end | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user