769 lines
34 KiB
C#
769 lines
34 KiB
C#
//#define Applyforalicense
|
|
|
|
using BrewMonster.Assets.PerfectWorld.Scripts.UI.GamePlay;
|
|
using BrewMonster.Network;
|
|
using BrewMonster.Scripts;
|
|
using BrewMonster.Scripts.Managers;
|
|
using BrewMonster.Scripts.Skills;
|
|
using BrewMonster.UI;
|
|
using CSNetwork.GPDataType;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using static BrewMonster.PET_EGG_ESSENCE;
|
|
|
|
namespace BrewMonster
|
|
{
|
|
public class CDlgQuickBar : AUIDialog
|
|
{
|
|
//[SerializeField] List<Image> m_aSkillImage = new List<Image>();
|
|
//[SerializeField] List<Button> m_aSkillButton = new List<Button>();
|
|
[SerializeField] List<AUIImagePicture> AUIImagePictureList = new List<AUIImagePicture>();
|
|
[SerializeField] AUIImageHPMPItem HpItemButton = new AUIImageHPMPItem();
|
|
[SerializeField] AUIImageHPMPItem MpItemButton = new AUIImageHPMPItem();
|
|
|
|
private bool _hpmpReselectDirty = true;
|
|
|
|
int currentListIndex = 0;
|
|
CECSkill assignedSkill = null;
|
|
public override void OnEnable()
|
|
{
|
|
base.OnEnable();
|
|
EventBus.Subscribe<InventoryChangedEvent>(OnInventoryChanged);
|
|
EventBus.Subscribe<CECHostPlayer.HostPlayerLevelUpUIEvent>(OnHostLevelUp);
|
|
_hpmpReselectDirty = true;
|
|
}
|
|
|
|
public override void OnDisable()
|
|
{
|
|
EventBus.Unsubscribe<InventoryChangedEvent>(OnInventoryChanged);
|
|
EventBus.Unsubscribe<CECHostPlayer.HostPlayerLevelUpUIEvent>(OnHostLevelUp);
|
|
base.OnDisable();
|
|
}
|
|
|
|
private void OnInventoryChanged(InventoryChangedEvent _)
|
|
{
|
|
_hpmpReselectDirty = true;
|
|
}
|
|
|
|
private void OnHostLevelUp(CECHostPlayer.HostPlayerLevelUpUIEvent _)
|
|
{
|
|
_hpmpReselectDirty = true;
|
|
}
|
|
/// <summary>
|
|
/// Apply for a license remove later
|
|
/// </summary>
|
|
/// <returns></returns>
|
|
|
|
public int m_nCurPanel1 = 1;
|
|
public int m_nCurPanel2 = 1;
|
|
public bool m_bShowAll1 = false;
|
|
public bool m_bShowAll2 = false;
|
|
public int m_nDisplayPanels1 = 0;
|
|
public int m_nDisplayPanels2 = 0;
|
|
|
|
|
|
[ContextMenu("SwitchShowSkillShortcut")]
|
|
public void SwitchShowSkillShortcut()
|
|
{
|
|
currentListIndex += 1;
|
|
if(currentListIndex == DlgAssignSlots.MAX_SKILL_GROUP)
|
|
{
|
|
currentListIndex = 0;
|
|
}
|
|
UpdateShortcuts();
|
|
}
|
|
public bool UpdateShortcuts()
|
|
{
|
|
if(AUIImagePictureList == null || AUIImagePictureList.Count == 0)
|
|
{
|
|
return false;
|
|
}
|
|
CECShortcut pSC;
|
|
CECSCSkill pSCSkill;
|
|
AUIImagePicture pCell;
|
|
CECSkill pSkill = new CECSkill(-1, -1);
|
|
AUIClockIcon pClock;
|
|
int iIconFile = 0, nMax = 0;
|
|
|
|
int nCurPanel9 = GetCurPanel1();
|
|
int nCurPanel8 = GetCurPanel2();
|
|
CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer();
|
|
if (pHost == null)
|
|
return false;
|
|
var a_pSCS = new List<CECShortcutSet>();
|
|
var a_pszPanel = new List<string>();
|
|
GetQuickBarNameAndSC(pHost, a_pszPanel, a_pSCS, nCurPanel9, nCurPanel8);
|
|
if (a_pSCS == null || a_pSCS.Count < 2)
|
|
return false;
|
|
|
|
|
|
if(currentListIndex >= a_pSCS.Count )
|
|
{
|
|
currentListIndex = 0;
|
|
}
|
|
// currentOffsetIndex = 0;
|
|
// for(int i = 0; i < currentListIndex; i++)
|
|
// {
|
|
// if(i == currentListIndex)
|
|
// {
|
|
// break;
|
|
// }
|
|
// currentOffsetIndex += a_pSCS[i].GetShortcutNum();
|
|
// }
|
|
var shortcutNum = a_pSCS[currentListIndex]?.GetShortcutNum() ?? 0;
|
|
if(shortcutNum <= 0)
|
|
{
|
|
return false;
|
|
}
|
|
int nSlots = Mathf.Min(shortcutNum, AUIImagePictureList.Count);
|
|
for (int j = 0; j < nSlots; j++)
|
|
{
|
|
pCell = AUIImagePictureList[j];
|
|
pSkill = null;
|
|
pCell.SetSlotIndex(j);
|
|
if (pCell == null || !pCell.gameObject.activeInHierarchy) continue;
|
|
pCell.SetInteract(true);
|
|
pSC = a_pSCS[currentListIndex].GetShortcut(j);
|
|
pClock = pCell.GetClockIcon();
|
|
pClock.SetProgressRange(0, 1);
|
|
pClock.SetProgressPos(1);
|
|
pClock.ClearSkillGroupBinding();
|
|
if (pSC != null)
|
|
{
|
|
if (pSC.GetType() == (int)CECShortcut.ShortcutType.SCT_SKILL)
|
|
{
|
|
pSCSkill = (CECSCSkill)pSC;
|
|
pSkill = pSCSkill.GetSkill();
|
|
if (false/*m_bDelGoblinSkillSC && GNET::ElementSkill::IsGoblinSkill(pSkill->GetSkillID())*/)
|
|
{
|
|
/* a_pSCS[i]->SetShortcut(j, NULL);
|
|
pSC = NULL;*/
|
|
}
|
|
else
|
|
{
|
|
if (pSkill != null && pSkill.ReadyToCast() && pHost.GetPrepSkill() != pSkill)
|
|
{
|
|
if (ElementSkill.IsGoblinSkill((uint)pSkill.GetSkillID()))
|
|
{
|
|
/* if (pHostGoblin && !pHostGoblin->CheckSkillCastCondition(pSkill))
|
|
{
|
|
pCell->SetColor(A3DCOLORRGB(255, 255, 255));
|
|
}
|
|
else
|
|
{
|
|
pCell->SetColor(A3DCOLORRGB(128, 128, 128));
|
|
}*/
|
|
}
|
|
else
|
|
{
|
|
if (pHost.CheckSkillCastCondition(pSkill) == 0)
|
|
{
|
|
pCell.SetInteract(true);
|
|
}
|
|
else
|
|
{
|
|
pCell.SetInteract(false);
|
|
}
|
|
}
|
|
}
|
|
/*else
|
|
pClock.SetColor(A3DCOLORRGBA(0, 0, 0, 128));*/
|
|
if (pSkill != null && (pSkill.GetCoolingTime() > 0 ||
|
|
pHost.GetPrepSkill() == pSkill))
|
|
{
|
|
pClock.SetProgressRange(0, pSkill.GetCoolingTime());
|
|
if (pHost.GetPrepSkill() == pSkill)
|
|
{
|
|
pClock.SetProgressPos(0);
|
|
}
|
|
else
|
|
{
|
|
pClock.SetProgressPos(pSkill.GetCoolingTime() - pSkill.GetCoolingCnt());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/*else if (pSC->GetType() == CECShortcut::SCT_ITEM)
|
|
{
|
|
iIconFile = CECGameUIMan::ICONS_INVENTORY;
|
|
pCell->SetColor(A3DCOLORRGB(255, 255, 255));
|
|
pSCItem = (CECSCItem*)pSC;
|
|
pIvtr = GetHostPlayer()->GetPack(pSCItem->GetInventory());
|
|
pItem = pIvtr->GetItem(pSCItem->GetIvtrSlot());
|
|
if (pItem && pItem->GetCoolTime(&nMax) > 0)
|
|
{
|
|
pClock->SetProgressRange(0, nMax);
|
|
pClock->SetProgressPos(nMax - pItem->GetCoolTime());
|
|
pClock->SetColor(A3DCOLORRGBA(0, 0, 0, 128));
|
|
}
|
|
if (pSCItem->GetInventory() == IVTRTYPE_EQUIPPACK)
|
|
pCell->SetColor(A3DCOLORRGBA(128, 128, 255, 128));
|
|
}
|
|
else if (pSC->GetType() == CECShortcut::SCT_PET)
|
|
{
|
|
pSCPet = (CECSCPet*)pSC;
|
|
CECPetData* pPet = pPetCorral->GetPetData(pSCPet->GetPetIndex());
|
|
iIconFile = CECGameUIMan::ICONS_INVENTORY;
|
|
pCell->SetColor(A3DCOLORRGB(255, 255, 255));
|
|
if (pPet)
|
|
{
|
|
// dead combat pet
|
|
if ((pPet->GetClass() == GP_PET_CLASS_COMBAT || pPet->GetClass() == GP_PET_CLASS_EVOLUTION) && pPet->GetHPFactor() == 0.0f)
|
|
{
|
|
pCell->SetColor(A3DCOLORRGB(128, 128, 128));
|
|
}
|
|
// current active pet
|
|
else if (pSCPet->IsActivePet())
|
|
{
|
|
pCell->SetColor(A3DCOLORRGB(255, 255, 0));
|
|
}
|
|
}
|
|
}
|
|
else if (pSC->GetType() == CECShortcut::SCT_AUTOFASHION)
|
|
{
|
|
iIconFile = CECGameUIMan::ICONS_SUITE;
|
|
fashionCoolTime = pHost->GetCoolTime(GP_CT_EQUIP_FASHION_ITEM, &fashionCoolTimeMax);
|
|
pCell->SetColor(A3DCOLORRGB(255, 255, 255));
|
|
if (fashionCoolTimeMax > 0)
|
|
{
|
|
pClock->SetProgressRange(0, fashionCoolTimeMax);
|
|
pClock->SetProgressPos(fashionCoolTimeMax - fashionCoolTime);
|
|
pClock->SetColor(A3DCOLORRGBA(0, 0, 0, 175));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iIconFile = CECGameUIMan::ICONS_ACTION;
|
|
if (pSC->GetType() == CECShortcut::SCT_COMMAND)
|
|
{
|
|
CECSCCommand* pCommandSC = (CECSCCommand*)pSC;
|
|
if (GetHostPlayer()->IsInvisible())
|
|
{
|
|
if (pCommandSC->GetCommandID() == CECSCCommand::CMD_STARTTRADE ||
|
|
pCommandSC->GetCommandID() == CECSCCommand::CMD_SELLBOOTH ||
|
|
pCommandSC->GetCommandID() == CECSCCommand::CMD_BINDBUDDY)
|
|
{
|
|
pCell->SetColor(A3DCOLORRGB(128, 128, 128));
|
|
}
|
|
else
|
|
{
|
|
pCell->SetColor(A3DCOLORRGB(255, 255, 255));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pCell->SetColor(A3DCOLORRGB(255, 255, 255));
|
|
}
|
|
}
|
|
|
|
if (pSC->GetCoolTime(&nMax) > 0)
|
|
{
|
|
pClock->SetProgressRange(0, nMax);
|
|
pClock->SetProgressPos(nMax - pSC->GetCoolTime());
|
|
pClock->SetColor(A3DCOLORRGBA(0, 0, 0, 128));
|
|
}
|
|
}*/
|
|
else if (pSC.GetType() == (int)CECShortcut.ShortcutType.SCT_ITEM)
|
|
{
|
|
iIconFile = (int)EC_GAMEUI_ICONS.ICONS_INVENTORY;
|
|
pCell.SetColor(new Color(1f, 1f, 1f));
|
|
CECSCItem pSCItem = (CECSCItem)pSC;
|
|
EC_Inventory pIvtr = pHost.GetPack(pSCItem.GetInventory());
|
|
EC_IvtrItem pItem = pIvtr?.GetItem(pSCItem.GetIvtrSlot());
|
|
|
|
if (pItem != null)
|
|
{
|
|
int maxNullable = -1;
|
|
int coolTime = pItem.GetCoolTime(out maxNullable);
|
|
nMax = maxNullable > 0 ? maxNullable : 0;
|
|
|
|
if (coolTime > 0)
|
|
{
|
|
pClock.SetProgressRange(0, nMax);
|
|
pClock.SetProgressPos(nMax - coolTime);
|
|
pClock.SetColor(new Color32(0, 0, 0, 128));
|
|
}
|
|
}
|
|
|
|
//if (pSCItem.GetInventory == InventoryConst.IVTRTYPE_EQUIPPACK)
|
|
//{
|
|
// pCell.SetColor(new Color(128, 128, 255, 128));
|
|
//}
|
|
|
|
if (pItem != null)
|
|
{
|
|
string itemIcon = pItem.GetIconFile();
|
|
GetGameUIMan().SetCover(pCell, itemIcon, EC_GAMEUI_ICONS.ICONS_INVENTORY);
|
|
}
|
|
}
|
|
|
|
else if (pSC.GetType() == (int)CECShortcut.ShortcutType.SCT_COMMAND)
|
|
{
|
|
iIconFile = (int)EC_GAMEUI_ICONS.ICONS_ACTION;
|
|
if (pSC.GetType() == (int)CECShortcut.ShortcutType.SCT_COMMAND)
|
|
{
|
|
CECSCCommand pCommandSC = (CECSCCommand)pSC;
|
|
if (pHost.IsInvisible())
|
|
{
|
|
if (pCommandSC.GetCommandID() == (int)CECSCCommand.CommandID.CMD_STARTTRADE ||
|
|
pCommandSC.GetCommandID() == (int)CECSCCommand.CommandID.CMD_SELLBOOTH ||
|
|
pCommandSC.GetCommandID() == (int)CECSCCommand.CommandID.CMD_BINDBUDDY)
|
|
{
|
|
pCell.SetColor(new Color(128, 128, 128, 255));
|
|
}
|
|
else
|
|
{
|
|
pCell.SetColor(new Color(255, 255, 255, 255));
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pCell.SetColor(new Color(255, 255, 255, 255));
|
|
}
|
|
|
|
pCell.SetInteract(true);
|
|
}
|
|
}
|
|
//else if(pSC.GetType() == (int)CECShortcut.ShortcutType.SCT_PET)
|
|
//{
|
|
// // Pet shortcut handling
|
|
// CECSCPet pSCPet = (CECSCPet)pSC;
|
|
// EC_PetCorral pPetCorral = pHost.GetPetCorral();
|
|
// CECPetData pPet = pPetCorral?.GetPetData(pSCPet.GetPetIndex());
|
|
|
|
// iIconFile = (int)EC_GAMEUI_ICONS.ICONS_INVENTORY;
|
|
// //pCell.SetColor(new Color(1f, 1f, 1f)); // RGB(255, 255, 255)
|
|
|
|
// if (pPet != null)
|
|
// {
|
|
// // Dead combat pet - grayscale
|
|
// if ((pPet.GetClass() == (int)PetClass.GP_PET_CLASS_COMBAT ||
|
|
// pPet.GetClass() == (int)PetClass.GP_PET_CLASS_EVOLUTION) &&
|
|
// pPet.GetHPFactor() == 0.0f)
|
|
// {
|
|
// //pCell.SetColor(new Color32(128, 128, 128, 255));
|
|
// }
|
|
// // Current active pet - yellow highlight
|
|
// else if (pSCPet.IsActivePet())
|
|
// {
|
|
// //pCell.SetColor(new Color32(255, 255, 0, 255));
|
|
// }
|
|
// }
|
|
|
|
// // Set pet icon
|
|
// if (pPet != null)
|
|
// {
|
|
// slotIndex++;
|
|
// string petIcon = pSCPet.GetIconFile();
|
|
// GetGameUIMan().SetCover(pCell, petIcon, EC_GAMEUI_ICONS.ICONS_INVENTORY);
|
|
// }
|
|
//}
|
|
else if (pSC.GetType() == (int)CECShortcut.ShortcutType.SCT_AUTOFASHION)
|
|
{
|
|
iIconFile = (int)EC_GAMEUI_ICONS.ICONS_SUITE;
|
|
|
|
int fashionCoolTime = pHost.GetCoolTime((int)CoolTimeIndex.GP_CT_EQUIP_FASHION_ITEM, out int fashionCoolTimeMax);
|
|
pCell.SetColor(new Color(1f, 1f, 1f));
|
|
|
|
if (fashionCoolTimeMax > 0)
|
|
{
|
|
pClock.SetProgressRange(0, fashionCoolTimeMax);
|
|
pClock.SetProgressPos(fashionCoolTimeMax - fashionCoolTime);
|
|
pClock.SetColor(new Color32(0, 0, 0, 175));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
iIconFile = (int)EC_GAMEUI_ICONS.ICONS_ACTION;
|
|
if (pSC.GetType() == (int)CECShortcut.ShortcutType.SCT_COMMAND)
|
|
{
|
|
CECSCCommand pCommandSC = (CECSCCommand)pSC;
|
|
if (pHost.IsInvisible())
|
|
{
|
|
if (pCommandSC.GetCommandID() == (int)CECSCCommand.CommandID.CMD_STARTTRADE ||
|
|
pCommandSC.GetCommandID() == (int)CECSCCommand.CommandID.CMD_SELLBOOTH ||
|
|
pCommandSC.GetCommandID() == (int)CECSCCommand.CommandID.CMD_BINDBUDDY)
|
|
{
|
|
pCell.SetColor(new Color(128, 128, 128, 255));
|
|
}
|
|
else
|
|
{
|
|
pCell.SetColor(new Color(1f, 1f, 1f));
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pCell.SetColor(new Color(1f, 1f, 1f));
|
|
}
|
|
}
|
|
nMax = 0;
|
|
int cmdCoolTime = pSC.GetCoolTime(ref nMax);
|
|
if (cmdCoolTime > 0)
|
|
{
|
|
pClock.SetProgressRange(0, nMax);
|
|
pClock.SetProgressPos(nMax - cmdCoolTime);
|
|
pClock.SetColor(new Color32(0, 0, 0, 128));
|
|
}
|
|
|
|
string cmdIcon = pSC.GetIconFile();
|
|
GetGameUIMan().SetCover(pCell, cmdIcon, EC_GAMEUI_ICONS.ICONS_ACTION);
|
|
}
|
|
|
|
|
|
if (pSC != null)
|
|
{
|
|
int scType = pSC.GetType();
|
|
bool isSkillGroupShortcut = scType == (int)CECShortcut.ShortcutType.SCT_SKILLGRP;
|
|
if (pCell.GetDataPtr() == pSC && !isSkillGroupShortcut)
|
|
{
|
|
continue;
|
|
}
|
|
pCell.SetDataPtr(pSC);
|
|
if (isSkillGroupShortcut)
|
|
{
|
|
EC_VIDEO_SETTING setting = EC_Game.GetConfigs().GetVideoSettings();
|
|
int groupIndex = ((CECSCSkillGrp)pSC).GetGroupIndex();
|
|
if (setting.comboSkill == null)
|
|
{
|
|
pCell.Clear();
|
|
continue;
|
|
}
|
|
|
|
var groupIndexes = new List<int>();
|
|
if (groupIndex >= 0 && groupIndex < setting.comboSkill.Length)
|
|
{
|
|
groupIndexes.Add(groupIndex);
|
|
}
|
|
for (int idx = 0; idx < setting.comboSkill.Length; idx++)
|
|
{
|
|
if (setting.comboSkill[idx].nIcon > 0 && !groupIndexes.Contains(idx))
|
|
{
|
|
groupIndexes.Add(idx);
|
|
}
|
|
}
|
|
|
|
pCell.SetSkillGroupIcons(groupIndexes, groupIndex);
|
|
}
|
|
else if (pSC.GetType() == (int)CECShortcut.ShortcutType.SCT_COMMAND)
|
|
{
|
|
GetGameUIMan().SetCover(pCell, ((CECSCCommand)pSC).GetIconFile(), EC_GAMEUI_ICONS.ICONS_ACTION);
|
|
}
|
|
else
|
|
{
|
|
if (pSkill != null)
|
|
{
|
|
pCell.gameObject.SetActive(true);
|
|
var nameskill = ElementSkill.GetIcon((uint)pSkill.GetSkillID());
|
|
var slot = GetGameUIMan().SetCover(pCell, nameskill, EC_GAMEUI_ICONS.ICONS_SKILL);
|
|
if (slot is AUIImagePicture picture)
|
|
{
|
|
picture.SetSkillId(pSkill.GetSkillID());
|
|
}
|
|
}
|
|
/* af_GetFileTitle(pSC->GetIconFile(), strFile);
|
|
strFile.MakeLower();
|
|
pCell->SetCover(GetGameUIMan()->m_pA2DSpriteIcons[iIconFile],
|
|
GetGameUIMan()->m_IconMap[iIconFile][strFile]); */
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* pCell->SetCover(NULL, -1);
|
|
pCell->SetText(_AL(""));
|
|
pCell->SetDataPtr(NULL);
|
|
pCell->SetColor(A3DCOLORRGB(255, 255, 255)); */
|
|
pCell.Clear();
|
|
}
|
|
}
|
|
UpdateHpMpItem();
|
|
return true;
|
|
}
|
|
public void UpdateHpMpItem()
|
|
{
|
|
const int HP_MAJOR_TYPE_ID = 1794;
|
|
const int MP_MAJOR_TYPE_ID = 1802;
|
|
|
|
CECHostPlayer pHost = EC_Game.GetGameRun().GetHostPlayer();
|
|
if (pHost == null)
|
|
return;
|
|
|
|
bool forceReselect = _hpmpReselectDirty;
|
|
_hpmpReselectDirty = false;
|
|
|
|
// Pick the first level-usable medicine with the lowest required level.
|
|
// Prefer highest heal amount first, then lowest required level.
|
|
// 优先选择“回复量最高”的药品,其次选择需求等级最低的 (Prefer max heal, tie-break by level).
|
|
static bool TryFindBestMedicine(CECHostPlayer host, int majorTypeId, out int pack, out int slot, out EC_IvtrMedicine med)
|
|
{
|
|
pack = -1;
|
|
slot = -1;
|
|
med = null;
|
|
|
|
int bestHeal = int.MinValue;
|
|
int bestReqLevel = int.MaxValue;
|
|
|
|
int[] packsToSearch = new int[]
|
|
{
|
|
InventoryConst.IVTRTYPE_PACK,
|
|
InventoryConst.IVTRTYPE_TASKPACK,
|
|
};
|
|
|
|
for (int p = 0; p < packsToSearch.Length; p++)
|
|
{
|
|
int curPack = packsToSearch[p];
|
|
EC_Inventory inv = host.GetPack(curPack);
|
|
if (inv == null)
|
|
continue;
|
|
|
|
int size = inv.GetSize();
|
|
for (int i = 0; i < size; i++)
|
|
{
|
|
EC_IvtrItem item = inv.GetItem(i);
|
|
if (item is not EC_IvtrMedicine m)
|
|
continue;
|
|
|
|
if (m.GetMajorTypeId() != majorTypeId)
|
|
continue;
|
|
|
|
if (!m.CheckUseCondition())
|
|
continue;
|
|
|
|
int heal = 0;
|
|
// HP potion: use hp_add_total; MP potion: use mp_add_total.
|
|
// 回血药用 hp_add_total;回蓝药用 mp_add_total。
|
|
if (majorTypeId == 1794)
|
|
heal = m.GetHpAddTotal();
|
|
else if (majorTypeId == 1802)
|
|
heal = m.GetMpAddTotal();
|
|
|
|
int req = m.GetLevelReq();
|
|
if (heal > bestHeal || (heal == bestHeal && req < bestReqLevel))
|
|
{
|
|
bestHeal = heal;
|
|
bestReqLevel = req;
|
|
pack = curPack;
|
|
slot = i;
|
|
med = m;
|
|
}
|
|
}
|
|
}
|
|
|
|
return med != null && pack >= 0 && slot >= 0;
|
|
}
|
|
|
|
static bool TryGetShortcutItem(CECHostPlayer host, CECShortcut sc, out EC_IvtrItem item)
|
|
{
|
|
item = null;
|
|
if (host == null || sc is not CECSCItem scItem)
|
|
return false;
|
|
|
|
EC_Inventory inv = host.GetPack(scItem.GetInventory());
|
|
if (inv == null)
|
|
return false;
|
|
|
|
item = inv.GetItem(scItem.GetIvtrSlot());
|
|
return item != null;
|
|
}
|
|
|
|
static int GetHealScore(EC_IvtrMedicine med, int majorTypeId)
|
|
{
|
|
if (med == null) return 0;
|
|
return majorTypeId == 1794 ? med.GetHpAddTotal() : med.GetMpAddTotal();
|
|
}
|
|
|
|
void ApplyItemToButton(AUIImageHPMPItem button, CECShortcut sc, EC_IvtrItem item)
|
|
{
|
|
if (button == null)
|
|
return;
|
|
|
|
if (sc == null || item == null)
|
|
{
|
|
button.ResetRenderCache();
|
|
button.Clear();
|
|
button.SetText(string.Empty);
|
|
return;
|
|
}
|
|
|
|
// Skill-slot logic pattern: if the shortcut ptr hasn't changed and we're not forced to reselect,
|
|
// avoid re-applying icon/text every frame.
|
|
// 复用技能格的思路:快捷键指针没变且非强制刷新时,不要每帧重刷图标/数量。
|
|
if (button.GetDataPtr() != sc)
|
|
{
|
|
button.SetDataPtr(sc);
|
|
button.ResetRenderCache();
|
|
}
|
|
|
|
int tid = item.GetTemplateID();
|
|
if (button.TrySetTemplateId(tid))
|
|
{
|
|
// Inventory UI path is more reliable than icon-file string matching.
|
|
// 背包UI的路径更稳定:按模板ID解析Sprite,而不是匹配图标文件名字符串
|
|
var sp = EC_IvtrItemUtils.Instance.ResolveItemIconSprite(tid);
|
|
if (sp != null)
|
|
button.SetImage(sp);
|
|
else
|
|
button.Clear();
|
|
}
|
|
|
|
// Amount text / 数量文本
|
|
int count = Mathf.Max(0, item.GetCount());
|
|
if (button.TrySetCount(count))
|
|
{
|
|
button.SetText(count > 0 ? count.ToString() : string.Empty);
|
|
}
|
|
|
|
// Cooldown overlay / 冷却遮罩
|
|
var clock = button.GetClockIcon();
|
|
int max = -1;
|
|
int cool = 0;
|
|
if (clock != null)
|
|
{
|
|
cool = item.GetCoolTime(out max);
|
|
if (cool > 0 && max > 0)
|
|
{
|
|
clock.SetProgressRange(0, max);
|
|
clock.SetProgressPos(max - cool);
|
|
clock.SetColor(new Color32(0, 0, 0, 128));
|
|
}
|
|
else
|
|
{
|
|
clock.SetProgressRange(0, 1);
|
|
clock.SetProgressPos(1);
|
|
}
|
|
}
|
|
|
|
// Interactable state should reflect usability.
|
|
// 可交互状态应该反映物品是否可使用
|
|
// Mirror host-side restrictions like `UseItemInPack` uses (CANDO_USEITEM etc.)
|
|
// 同步宿主侧限制(例如 CANDO_USEITEM),与 UseItemInPack 的限制保持一致
|
|
bool hostCanUseItem = pHost.CanDo(CECHostPlayer.ActionCanDo.CANDO_USEITEM);
|
|
bool usable = hostCanUseItem && item.CheckUseCondition() && !item.IsFrozen();
|
|
bool cooling = (cool > 0 && max > 0);
|
|
bool interact = usable && !cooling;
|
|
button.SetInteract(interact);
|
|
}
|
|
|
|
void EnsureAssignedAndRefresh(AUIImageHPMPItem button, int majorTypeId)
|
|
{
|
|
if (button == null)
|
|
return;
|
|
|
|
CECShortcut sc = button.GetDataPtr();
|
|
|
|
// Resolve current shortcut item (if any).
|
|
bool hasCurrent = TryGetShortcutItem(pHost, sc, out EC_IvtrItem item);
|
|
|
|
// Find best candidate (used both for initial assign and reselect-on-change).
|
|
bool hasBest = TryFindBestMedicine(pHost, majorTypeId, out int bestPack, out int bestSlot, out EC_IvtrMedicine bestMed);
|
|
|
|
// If there is no valid shortcut item, auto assign the best available potion.
|
|
if (!hasCurrent)
|
|
{
|
|
if (hasBest)
|
|
{
|
|
var newSc = new CECSCItem();
|
|
newSc.Init(bestPack, bestSlot, bestMed);
|
|
sc = newSc;
|
|
item = bestMed;
|
|
hasCurrent = true;
|
|
}
|
|
}
|
|
else if (forceReselect && hasBest)
|
|
{
|
|
// Upgrade to best potion when inventory changes or level changes.
|
|
// 背包变化或升级时,自动切换到“最优药品”
|
|
var curMed = item as EC_IvtrMedicine;
|
|
if (curMed == null || curMed.GetMajorTypeId() != majorTypeId || !curMed.CheckUseCondition())
|
|
{
|
|
var newSc = new CECSCItem();
|
|
newSc.Init(bestPack, bestSlot, bestMed);
|
|
sc = newSc;
|
|
item = bestMed;
|
|
}
|
|
else
|
|
{
|
|
int curHeal = GetHealScore(curMed, majorTypeId);
|
|
int bestHeal = GetHealScore(bestMed, majorTypeId);
|
|
int curReq = curMed.GetLevelReq();
|
|
int bestReq = bestMed.GetLevelReq();
|
|
|
|
if (bestHeal > curHeal || (bestHeal == curHeal && bestReq < curReq))
|
|
{
|
|
var newSc = new CECSCItem();
|
|
newSc.Init(bestPack, bestSlot, bestMed);
|
|
sc = newSc;
|
|
item = bestMed;
|
|
}
|
|
}
|
|
}
|
|
|
|
ApplyItemToButton(button, sc, item);
|
|
}
|
|
|
|
EnsureAssignedAndRefresh(HpItemButton, HP_MAJOR_TYPE_ID);
|
|
EnsureAssignedAndRefresh(MpItemButton, MP_MAJOR_TYPE_ID);
|
|
}
|
|
private void GetQuickBarNameAndSC(CECHostPlayer pHost, List<string> pszPanel, List<CECShortcutSet> pSCS, int panel9, int panel8)
|
|
{
|
|
string dlgName;
|
|
|
|
dlgName = $"Win_Quickbar{Shortcut.SIZE_HOSTSCSET1}Ha";
|
|
pszPanel.Add(dlgName);
|
|
|
|
for (int i = 0; i < (int)Shortcut.NUM_HOSTSCSETS1; i++)
|
|
{
|
|
dlgName = $"Win_Quickbar{(int)Shortcut.SIZE_HOSTSCSET1}Hb_{i + 1}";
|
|
pSCS?.Add(pHost.GetShortcutSet1(i));
|
|
pszPanel.Add(dlgName);
|
|
}
|
|
|
|
/*// ----- Quickbar 1 Vertical A -----
|
|
dlgName = $"Win_Quickbar{(int)Shortcut.SIZE_HOSTSCSET1}Va";
|
|
pszPanel.Add(dlgName);
|
|
|
|
for (int i = 0; i < (int)Shortcut.NUM_HOSTSCSETS1; i++)
|
|
{
|
|
dlgName = $"Win_Quickbar{(int)Shortcut.SIZE_HOSTSCSET1}Vb_{i + 1}";
|
|
pSCS?.Add(pHost.GetShortcutSet1(i));
|
|
pszPanel.Add(dlgName);
|
|
}*/
|
|
|
|
// ----- Quickbar 2 Horizontal A -----
|
|
dlgName = $"Win_Quickbar{(int)Shortcut.SIZE_HOSTSCSET2}Ha";
|
|
pszPanel.Add(dlgName);
|
|
|
|
for (int i = 0; i < (int)Shortcut.NUM_HOSTSCSETS2; i++)
|
|
{
|
|
dlgName = $"Win_Quickbar{(int)Shortcut.SIZE_HOSTSCSET2}Hb_{i + 1}";
|
|
pSCS?.Add(pHost.GetShortcutSet2(i));
|
|
pszPanel.Add(dlgName);
|
|
}
|
|
|
|
/* // ----- Quickbar 2 Vertical A -----
|
|
dlgName = $"Win_Quickbar{(int)Shortcut.SIZE_HOSTSCSET2}Va";
|
|
pszPanel.Add(dlgName);
|
|
|
|
for (int i = 0; i < (int)Shortcut.NUM_HOSTSCSETS2; i++)
|
|
{
|
|
dlgName = $"Win_Quickbar{(int)Shortcut.SIZE_HOSTSCSET2}Vb_{i + 1}";
|
|
pSCS?.Add(pHost.GetShortcutSet2(i));
|
|
pszPanel.Add(dlgName);
|
|
}*/
|
|
}
|
|
|
|
|
|
public int GetCurPanel1()
|
|
{
|
|
return m_nCurPanel1;
|
|
}
|
|
public int GetCurPanel2()
|
|
{
|
|
return m_nCurPanel2;
|
|
}
|
|
}
|
|
}
|