186 lines
5.3 KiB
C#
186 lines
5.3 KiB
C#
// Система сохранения инвентаря для s&box
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using Sandbox;
|
||
using System.Text.Json;
|
||
|
||
namespace Sasalka;
|
||
|
||
public class InventorySaveData
|
||
{
|
||
public List<SavedInventoryItem> Items { get; set; } = new();
|
||
public Dictionary<string, string> 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";
|
||
|
||
/// <summary>
|
||
/// Сохраняет инвентарь игрока в файл
|
||
/// </summary>
|
||
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}" );
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Загружает инвентарь игрока из файла
|
||
/// </summary>
|
||
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<InventorySaveData>( json );
|
||
|
||
if ( saveData == null )
|
||
{
|
||
Log.Error( "Не удалось десериализовать данные сохранения" );
|
||
return;
|
||
}
|
||
|
||
// Очищаем текущий инвентарь
|
||
inventory.ClearInventory();
|
||
|
||
// Словарь для связи ID предметов с объектами InventoryItem
|
||
var itemIdMap = new Dictionary<string, InventoryItem>();
|
||
|
||
// Загружаем предметы в инвентарь
|
||
foreach ( var savedItem in saveData.Items )
|
||
{
|
||
var itemDefinition = ResourceLibrary.Get<BaseItemDefinition>( 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<Inventar.InventorySlot>( slotName, out var slot ) &&
|
||
itemIdMap.TryGetValue( itemId, out var item ) )
|
||
{
|
||
inventory.EquipItem( item );
|
||
}
|
||
}
|
||
|
||
// Уведомляем об изменениях
|
||
inventory.NotifyChanged();
|
||
|
||
Log.Info( "Инвентарь успешно загружен" );
|
||
}
|
||
catch ( Exception ex )
|
||
{
|
||
Log.Error( $"Ошибка при загрузке инвентаря: {ex.Message}" );
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// Проверяет, существует ли файл сохранения
|
||
/// </summary>
|
||
public static bool HasSaveFile()
|
||
{
|
||
return FileSystem.Data.FileExists( SAVE_FILE_NAME );
|
||
}
|
||
|
||
/// <summary>
|
||
/// Удаляет файл сохранения
|
||
/// </summary>
|
||
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}" );
|
||
}
|
||
}
|
||
} |