378 lines
14 KiB
C#
378 lines
14 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using Cielonos.MainGame.Inventory;
|
||
using Cielonos.MainGame.Inventory.Collection;
|
||
using Cielonos.MainGame.Inventory.Collections;
|
||
using UnityEngine;
|
||
|
||
namespace Cielonos.MainGame.Characters
|
||
{
|
||
public partial class PlayerInventorySubcontroller : SubcontrollerBase<Player>
|
||
{
|
||
public Player player => owner;
|
||
private PlayerInputSubcontroller inputSc => player.inputSc;
|
||
private PlayerOperationSubcontroller operationSc => player.operationSc;
|
||
public BackpackSubmodule backpackSm;
|
||
public EquipmentSubmodule equipmentSm;
|
||
|
||
public Transform mainWeaponContainer;
|
||
public Transform supportEquipmentContainer;
|
||
public Transform passiveEquipmentContainer;
|
||
public Transform consumableContainer;
|
||
|
||
public override void Initialize()
|
||
{
|
||
base.Initialize();
|
||
RegisterOperations();
|
||
backpackSm ??= new BackpackSubmodule(this);
|
||
equipmentSm ??= new EquipmentSubmodule(this);
|
||
|
||
// 首次初始化时(如不经过存档还原的新关卡直接生成Player),赋予默认设定的初始装备
|
||
GrantInitialEquipments();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 赋予玩家默认硬编码的初始装备。
|
||
/// 抽离于 Initialize 之外,以便在跨场景恢复背包数据并清空装备后,能重新将这些常驻初始装备追加给玩家。
|
||
/// </summary>
|
||
public void GrantInitialEquipments()
|
||
{
|
||
backpackSm.ObtainItem<Polychrome>();
|
||
backpackSm.ObtainItem<FutureWand>();
|
||
backpackSm.ObtainItem<Ascension>();
|
||
backpackSm.ObtainItem<Passion>();
|
||
backpackSm.ObtainItem<ThermalDetonator>();
|
||
backpackSm.ObtainItem<SpatialWarpCaliper>();
|
||
|
||
foreach (MainWeaponBase mainWeapon in backpackSm.mainWeapons)
|
||
{
|
||
equipmentSm.PrepareMainWeapon(mainWeapon);
|
||
}
|
||
}
|
||
}
|
||
|
||
#region Functions
|
||
|
||
public partial class PlayerInventorySubcontroller
|
||
{
|
||
public void ApplyAttributeChange(string attributeName, ref float numeric, ref float percentageAccumulation, ref float percentageMultiplication)
|
||
{
|
||
foreach (var mainWeapon in backpackSm.mainWeapons.Where(mainWeapon => mainWeapon.passiveAttributeSm != null))
|
||
{
|
||
mainWeapon.passiveAttributeSm.ApplyCharacterAttributeChanges(attributeName, ref numeric, ref percentageAccumulation, ref percentageMultiplication);
|
||
}
|
||
|
||
foreach (var supportEquipment in backpackSm.supportEquipments.Where(supportEquipment => supportEquipment.passiveAttributeSm != null))
|
||
{
|
||
supportEquipment.passiveAttributeSm.ApplyCharacterAttributeChanges(attributeName, ref numeric, ref percentageAccumulation, ref percentageMultiplication);
|
||
}
|
||
|
||
foreach (var passiveEquipment in backpackSm.passiveEquipments.Where(passiveEquipment => passiveEquipment.passiveAttributeSm != null))
|
||
{
|
||
passiveEquipment.passiveAttributeSm.ApplyCharacterAttributeChanges(attributeName, ref numeric, ref percentageAccumulation, ref percentageMultiplication);
|
||
}
|
||
|
||
foreach (var consumable in backpackSm.consumables.Where(consumable => consumable.passiveAttributeSm != null))
|
||
{
|
||
consumable.passiveAttributeSm.ApplyCharacterAttributeChanges(attributeName, ref numeric, ref percentageAccumulation, ref percentageMultiplication);
|
||
}
|
||
|
||
currentMainWeapon?.activeAttributeSm?.ApplyCharacterAttributeChanges(attributeName, ref numeric, ref percentageAccumulation, ref percentageMultiplication);
|
||
|
||
foreach (SupportEquipmentBase supportEquipment in currentSupportEquipments)
|
||
{
|
||
supportEquipment?.activeAttributeSm?.ApplyCharacterAttributeChanges(attributeName, ref numeric, ref percentageAccumulation, ref percentageMultiplication);
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Rare Materials
|
||
|
||
public partial class PlayerInventorySubcontroller
|
||
{
|
||
/// <summary>
|
||
/// 获取玩家当前持有的 RareMaterial。
|
||
/// </summary>
|
||
public RareMaterial GetRareMaterial()
|
||
{
|
||
return backpackSm.consumables.Find(c => c is RareMaterial) as RareMaterial;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取玩家当前持有的 RareMaterial 数量。
|
||
/// </summary>
|
||
public int GetRareMaterialAmount()
|
||
{
|
||
RareMaterial rm = GetRareMaterial();
|
||
return rm != null ? rm.stackAmount : 0;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
public partial class PlayerInventorySubcontroller
|
||
{
|
||
private MainWeaponBase currentMainWeapon => equipmentSm.currentMainWeapon;
|
||
private List<SupportEquipmentBase> currentSupportEquipments => equipmentSm.currentSupportEquipments;
|
||
|
||
private void RegisterOperations()
|
||
{
|
||
//operationSc.OnMainWeaponSpecialPress += MainWeaponSpecialPress;
|
||
//operationSc.OnMainWeaponSpecialRelease += MainWeaponSpecialRelease;
|
||
|
||
operationSc.OnMainWeaponPrimaryPress += MainWeaponPrimaryPress;
|
||
operationSc.OnMainWeaponPrimaryRelease += MainWeaponPrimaryRelease;
|
||
operationSc.OnMainWeaponSecondaryPress += MainWeaponSecondaryPress;
|
||
operationSc.OnMainWeaponSecondaryRelease += MainWeaponSecondaryRelease;
|
||
operationSc.OnMainWeaponSpecialAPress += MainWeaponSpecialAPress;
|
||
operationSc.OnMainWeaponSpecialARelease += MainWeaponSpecialARelease;
|
||
operationSc.OnMainWeaponSpecialBPress += MainWeaponSpecialBPress;
|
||
operationSc.OnMainWeaponSpecialBRelease += MainWeaponSpecialBRelease;
|
||
operationSc.OnMainWeaponSpecialCPress += MainWeaponSpecialCPress;
|
||
operationSc.OnMainWeaponSpecialCRelease += MainWeaponSpecialCRelease;
|
||
|
||
operationSc.OnSwitchMainWeapon += SwitchMainWeapon;
|
||
|
||
operationSc.OnSupportEquipment0Press += () => SupportEquipmentPress(0);
|
||
operationSc.OnSupportEquipment1Press += () => SupportEquipmentPress(1);
|
||
operationSc.OnSupportEquipment2Press += () => SupportEquipmentPress(2);
|
||
operationSc.OnSupportEquipment3Press += () => SupportEquipmentPress(3);
|
||
operationSc.OnSupportEquipment0Release += () => SupportEquipmentRelease(0);
|
||
operationSc.OnSupportEquipment1Release += () => SupportEquipmentRelease(1);
|
||
operationSc.OnSupportEquipment2Release += () => SupportEquipmentRelease(2);
|
||
operationSc.OnSupportEquipment3Release += () => SupportEquipmentRelease(3);
|
||
}
|
||
|
||
public virtual void Update()
|
||
{
|
||
if (inputSc.IsHoldingPrimary)
|
||
{
|
||
currentMainWeapon?.OnPrimaryHold();
|
||
}
|
||
|
||
if (inputSc.IsHoldingSecondary)
|
||
{
|
||
currentMainWeapon?.OnSecondaryHold();
|
||
}
|
||
|
||
if (inputSc.IsHoldingSpecialA)
|
||
{
|
||
currentMainWeapon?.OnSpecialAHold();
|
||
}
|
||
|
||
if (inputSc.IsHoldingSpecialB)
|
||
{
|
||
currentMainWeapon?.OnSpecialBHold();
|
||
}
|
||
|
||
if (inputSc.IsHoldingSpecialC)
|
||
{
|
||
currentMainWeapon?.OnSpecialCHold();
|
||
}
|
||
}
|
||
}
|
||
|
||
public partial class PlayerInventorySubcontroller
|
||
{
|
||
private void SwitchMainWeapon(int direction)
|
||
{
|
||
int currentIndex = equipmentSm.preparedMainWeapons.IndexOf(currentMainWeapon);
|
||
currentMainWeapon?.OnSwitchOut();
|
||
equipmentSm.RemoveMainWeapon();
|
||
|
||
int newIndex = (currentIndex + direction + equipmentSm.preparedMainWeapons.Count) % equipmentSm.preparedMainWeapons.Count;
|
||
MainWeaponBase newWeapon = equipmentSm.preparedMainWeapons[newIndex];
|
||
equipmentSm.EquipMainWeapon(newWeapon);
|
||
newWeapon.OnSwitchIn();
|
||
}
|
||
|
||
private void MainWeaponPrimaryPress()
|
||
{
|
||
if (currentMainWeapon != null)
|
||
{
|
||
currentMainWeapon.OnPrimaryPress();
|
||
player.movementSc.isSprinting = false;
|
||
}
|
||
}
|
||
|
||
private void MainWeaponPrimaryRelease()
|
||
{
|
||
if (currentMainWeapon != null)
|
||
{
|
||
currentMainWeapon.OnPrimaryRelease();
|
||
}
|
||
}
|
||
|
||
private void MainWeaponSecondaryPress()
|
||
{
|
||
if (currentMainWeapon != null)
|
||
{
|
||
currentMainWeapon.OnSecondaryPress();
|
||
player.movementSc.isSprinting = false;
|
||
}
|
||
}
|
||
|
||
private void MainWeaponSecondaryRelease()
|
||
{
|
||
if (currentMainWeapon != null)
|
||
{
|
||
currentMainWeapon.OnSecondaryRelease();
|
||
}
|
||
}
|
||
|
||
private void MainWeaponSpecialAPress()
|
||
{
|
||
if (currentMainWeapon != null)
|
||
{
|
||
currentMainWeapon.OnSpecialAPress();
|
||
player.movementSc.isSprinting = false;
|
||
}
|
||
}
|
||
|
||
private void MainWeaponSpecialARelease()
|
||
{
|
||
if (currentMainWeapon != null)
|
||
{
|
||
currentMainWeapon.OnSpecialARelease();
|
||
}
|
||
}
|
||
|
||
private void MainWeaponSpecialBPress()
|
||
{
|
||
if (currentMainWeapon != null)
|
||
{
|
||
currentMainWeapon.OnSpecialBPress();
|
||
player.movementSc.isSprinting = false;
|
||
}
|
||
}
|
||
|
||
private void MainWeaponSpecialBRelease()
|
||
{
|
||
if (currentMainWeapon != null)
|
||
{
|
||
currentMainWeapon.OnSpecialBRelease();
|
||
}
|
||
}
|
||
|
||
private void MainWeaponSpecialCPress()
|
||
{
|
||
if (currentMainWeapon != null)
|
||
{
|
||
currentMainWeapon.OnSpecialCPress();
|
||
player.movementSc.isSprinting = false;
|
||
}
|
||
}
|
||
|
||
private void MainWeaponSpecialCRelease()
|
||
{
|
||
if (currentMainWeapon != null)
|
||
{
|
||
currentMainWeapon.OnSpecialCRelease();
|
||
}
|
||
}
|
||
}
|
||
|
||
public partial class PlayerInventorySubcontroller
|
||
{
|
||
private void SupportEquipmentPress(int slotIndex)
|
||
{
|
||
if (currentSupportEquipments.Count > slotIndex)
|
||
{
|
||
var equipment = currentSupportEquipments[slotIndex];
|
||
if (equipment != null)
|
||
{
|
||
equipment.OnPress();
|
||
}
|
||
}
|
||
}
|
||
|
||
private void SupportEquipmentRelease(int slotIndex)
|
||
{
|
||
if (currentSupportEquipments.Count > slotIndex)
|
||
{
|
||
var equipment = currentSupportEquipments[slotIndex];
|
||
if (equipment != null)
|
||
{
|
||
equipment.OnRelease();
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
public partial class PlayerInventorySubcontroller
|
||
{
|
||
/// <summary>
|
||
/// 彻底清空并注销玩家身上当前的全部装备和游戏实体。
|
||
/// </summary>
|
||
private void ClearInventory()
|
||
{
|
||
// A. 注销当前手持主武器(解绑事件、停止动画、卸下表现层模型)
|
||
if (equipmentSm.currentMainWeapon != null)
|
||
{
|
||
equipmentSm.RemoveMainWeapon();
|
||
}
|
||
|
||
// B. 注销各个槽位上的辅助装备
|
||
for (int i = 0; i < equipmentSm.currentSupportEquipments.Count; i++)
|
||
{
|
||
if (equipmentSm.currentSupportEquipments[i] != null)
|
||
{
|
||
equipmentSm.RemoveSupportEquipment(i);
|
||
}
|
||
}
|
||
|
||
// C. 卸下并触发背包内所有物品的 OnDiscarded 回调以更新属性
|
||
var mainWeaponsCopy = new List<MainWeaponBase>(backpackSm.mainWeapons);
|
||
foreach (var item in mainWeaponsCopy) { backpackSm.DiscardItem(item); }
|
||
|
||
var supportCopy = new List<SupportEquipmentBase>(backpackSm.supportEquipments);
|
||
foreach (var item in supportCopy) { backpackSm.DiscardItem(item); }
|
||
|
||
var passiveCopy = new List<PassiveEquipmentBase>(backpackSm.passiveEquipments);
|
||
foreach (var item in passiveCopy) { backpackSm.DiscardItem(item); }
|
||
|
||
var consumablesCopy = new List<ConsumableBase>(backpackSm.consumables);
|
||
foreach (var item in consumablesCopy) { backpackSm.DiscardItem(item); }
|
||
|
||
// D. 摧毁玩家挂载点下生成的所有武器物体实例
|
||
if (mainWeaponContainer != null)
|
||
{
|
||
foreach (Transform child in mainWeaponContainer) { Destroy(child.gameObject); }
|
||
}
|
||
if (supportEquipmentContainer != null)
|
||
{
|
||
foreach (Transform child in supportEquipmentContainer) { Destroy(child.gameObject); }
|
||
}
|
||
if (passiveEquipmentContainer != null)
|
||
{
|
||
foreach (Transform child in passiveEquipmentContainer) { Destroy(child.gameObject); }
|
||
}
|
||
if (consumableContainer != null)
|
||
{
|
||
foreach (Transform child in consumableContainer) { Destroy(child.gameObject); }
|
||
}
|
||
|
||
// E. 清空列表并重新初始化底层集合
|
||
backpackSm.mainWeapons.Clear();
|
||
backpackSm.supportEquipments.Clear();
|
||
backpackSm.passiveEquipments.Clear();
|
||
backpackSm.consumables.Clear();
|
||
|
||
equipmentSm.preparedMainWeapons.Clear();
|
||
equipmentSm.currentMainWeapon = null;
|
||
for (int i = 0; i < equipmentSm.currentSupportEquipments.Count; i++)
|
||
{
|
||
equipmentSm.currentSupportEquipments[i] = null;
|
||
}
|
||
}
|
||
|
||
private ItemSaveData CreateSaveDataFromItem(ItemBase item)
|
||
{
|
||
if (item == null) return null;
|
||
return item.CreateSaveDataFromItem(item);
|
||
}
|
||
}
|
||
} |