// Система сохранения инвентаря для s&box using System; using System.Collections.Generic; using System.Linq; using Sandbox; using System.Text.Json; namespace Sasalka; public class InventorySaveData { public List Items { get; set; } = new(); public Dictionary EquippedItems { get; set; } = new(); // slot -> itemId } public class SavedInventoryItem { public string ItemDefinitionPath { get; set; } = ""; public int Count { get; set; } = 1; public int MagazineAmmo { get; set; } = 0; public string Id { get; set; } = ""; } public static class InventorySaveSystem { private const string SAVE_FILE_NAME = "inventory_save.json"; /// /// Сохраняет инвентарь игрока в файл /// public static void SaveInventory( Inventar inventory ) { if ( inventory == null ) return; try { var saveData = new InventorySaveData(); // Сохраняем предметы в инвентаре foreach ( var item in inventory.Items ) { if ( item.Definition == null ) continue; var savedItem = new SavedInventoryItem { ItemDefinitionPath = item.Definition.ResourcePath, Count = item.Count, MagazineAmmo = item.MagazineAmmo, Id = Guid.NewGuid().ToString() // Генерируем уникальный ID для предмета }; saveData.Items.Add( savedItem ); } // Сохраняем экипированные предметы foreach ( var kvp in inventory.EquippedItems ) { var slot = kvp.Key; var item = kvp.Value; // Находим соответствующий сохраненный предмет var savedItem = saveData.Items.FirstOrDefault( x => x.ItemDefinitionPath == item.Definition?.ResourcePath && x.Count == item.Count && x.MagazineAmmo == item.MagazineAmmo ); if ( savedItem != null ) { saveData.EquippedItems[slot.ToString()] = savedItem.Id; } } // Сериализуем и сохраняем в файл var json = JsonSerializer.Serialize( saveData, new JsonSerializerOptions { WriteIndented = true } ); FileSystem.Data.WriteAllText( SAVE_FILE_NAME, json ); Log.Info( "Инвентарь успешно сохранен" ); } catch ( Exception ex ) { Log.Error( $"Ошибка при сохранении инвентаря: {ex.Message}" ); } } /// /// Загружает инвентарь игрока из файла /// public static void LoadInventory( Inventar inventory ) { if ( inventory == null ) return; try { if ( !FileSystem.Data.FileExists( SAVE_FILE_NAME ) ) { Log.Info( "Файл сохранения инвентаря не найден" ); return; } var json = FileSystem.Data.ReadAllText( SAVE_FILE_NAME ); var saveData = JsonSerializer.Deserialize( json ); if ( saveData == null ) { Log.Error( "Не удалось десериализовать данные сохранения" ); return; } // Очищаем текущий инвентарь inventory.ClearInventory(); // Словарь для связи ID предметов с объектами InventoryItem var itemIdMap = new Dictionary(); // Загружаем предметы в инвентарь foreach ( var savedItem in saveData.Items ) { var itemDefinition = ResourceLibrary.Get( savedItem.ItemDefinitionPath ); if ( itemDefinition == null ) { Log.Warning( $"Не удалось загрузить определение предмета: {savedItem.ItemDefinitionPath}" ); continue; } var inventoryItem = new InventoryItem { Definition = itemDefinition, Count = savedItem.Count, MagazineAmmo = savedItem.MagazineAmmo }; inventory.Items.Add( inventoryItem ); itemIdMap[savedItem.Id] = inventoryItem; } // Экипируем предметы foreach ( var kvp in saveData.EquippedItems ) { var slotName = kvp.Key; var itemId = kvp.Value; if ( Enum.TryParse( slotName, out var slot ) && itemIdMap.TryGetValue( itemId, out var item ) ) { inventory.EquipItem( item ); } } // Уведомляем об изменениях inventory.NotifyChanged(); Log.Info( "Инвентарь успешно загружен" ); } catch ( Exception ex ) { Log.Error( $"Ошибка при загрузке инвентаря: {ex.Message}" ); } } /// /// Проверяет, существует ли файл сохранения /// public static bool HasSaveFile() { return FileSystem.Data.FileExists( SAVE_FILE_NAME ); } /// /// Удаляет файл сохранения /// public static void DeleteSaveFile() { try { if ( FileSystem.Data.FileExists( SAVE_FILE_NAME ) ) { FileSystem.Data.DeleteFile( SAVE_FILE_NAME ); Log.Info( "Файл сохранения инвентаря удален" ); } } catch ( Exception ex ) { Log.Error( $"Ошибка при удалении файла сохранения: {ex.Message}" ); } } }