Merge branch 'develop' of ssh://git.pthub.vn:3222/Unity/perfect-world-unity into fix-ui

This commit is contained in:
Chomper9981
2026-04-08 13:47:00 +07:00
17 changed files with 7795 additions and 23875 deletions
+28 -120
View File
@@ -2771,8 +2771,8 @@ namespace BrewMonster
return m_idSelTarget;
}
// Auto select a attackable target / 自动选择一个可攻击的目标
// Auto select a attackable target / 自动选择一个可攻击目标
// Auto select a attackable target — cycle by distance (nearest → farthest, then repeat)
// 自动选择可攻击目标 — 按距离循环(从近到远,再回到最近)
public int AutoSelectTarget()
{
if (!CanDo(ActionCanDo.CANDO_CHANGESELECT))
@@ -2780,145 +2780,53 @@ namespace BrewMonster
int idCurSel = (m_idSelTarget != 0 && m_idSelTarget != m_PlayerInfo.cid) ? m_idSelTarget : 0;
// Clean up invalid targets from tab selection array / 清理无效目标
if (idCurSel == 0)
{
// Rebuild selected table / 重建选中表
m_aTabSels.Clear();
}
else
{
// Remove targets that are too far / 移除距离过远的目标
for (int i = m_aTabSels.Count - 1; i >= 0; i--)
{
CECObject pObject = m_aTabSels[i];
if (pObject == null)
{
m_aTabSels.RemoveAt(i);
continue;
}
float fDistToHost = 0.0f;
if (pObject is EC_ElsePlayer pPlayer)
fDistToHost = pPlayer.GetDistToHost();
else if (pObject is CECNPC pNPC)
fDistToHost = pNPC.GetDistToHost();
if (fDistToHost > EC_RoleTypes.EC_TABSEL_DIST || !CanSafelySelectWith(fDistToHost))
{
m_aTabSels.RemoveAt(i);
}
}
}
float fMinDist = 10000.0f;
CECObject pCand = null;
int idCandidate = 0;
// Get player candidates / 获取玩家候选列表
// idCurSel == 0 so TabSelectCandidates includes current target for index-based cycling
List<EC_ElsePlayer> aCandPlayers = new List<EC_ElsePlayer>();
EC_ManMessageMono.Instance.EC_ManPlayer.TabSelectCandidates(idCurSel, aCandPlayers);
EC_ManMessageMono.Instance.EC_ManPlayer.TabSelectCandidates(0, aCandPlayers);
List<CECNPC> aCandNPCs = new List<CECNPC>();
EC_ManMessageMono.Instance.CECNPCMan.TabSelectCandidates(0, aCandNPCs);
var sorted = new List<(float dist, int id, CECObject obj)>();
foreach (var pPlayer in aCandPlayers)
{
if (pPlayer == null)
continue;
// Check whether this player is in selected array / 检查此玩家是否已在选中数组中
if (m_aTabSels.Contains(pPlayer))
continue; // This player has been in selected array / 此玩家已在选中数组中
// Record the nearest one as candidate / 记录最近的一个作为候选
float fDist = pPlayer.GetDistToHost();
if (fDist < fMinDist)
{
fMinDist = fDist;
pCand = pPlayer;
idCandidate = pPlayer.GetCharacterID();
}
sorted.Add((pPlayer.GetDistToHost(), pPlayer.GetCharacterID(), pPlayer));
}
// Get NPC candidates / 获取NPC候选列表
List<CECNPC> aCandNPCs = new List<CECNPC>();
EC_ManMessageMono.Instance.CECNPCMan.TabSelectCandidates(idCurSel, aCandNPCs);
foreach (var pNPC in aCandNPCs)
{
if (pNPC == null)
continue;
// Check whether this npc is in selected array / 检查此NPC是否已在选中数组中
if (m_aTabSels.Contains(pNPC))
continue; // This npc has been in selected array / 此NPC已在选中数组中
// Record the nearest one as candidate / 记录最近的一个作为候选
float fDist = pNPC.GetDistToHost();
if (fDist < fMinDist)
{
fMinDist = fDist;
pCand = pNPC;
idCandidate = pNPC.GetNPCID();
}
sorted.Add((pNPC.GetDistToHost(), pNPC.GetNPCID(), pNPC));
}
sorted.Sort((a, b) =>
{
int c = a.dist.CompareTo(b.dist);
return c != 0 ? c : a.id.CompareTo(b.id);
});
m_aTabSels.Clear();
for (int i = 0; i < sorted.Count; i++)
m_aTabSels.Add(sorted[i].obj);
// Maximum number of candidates in tab selection array / 标签选择数组中的最大候选数
// Increased from 9 to 20 to allow more targets / 从9增加到20以允许更多目标
const int iMaxCand = 9;
int idNewSel = 0;
if (pCand != null && idCandidate != 0)
if (sorted.Count == 0)
{
// Add candidate to tab selection array / 将候选添加到标签选择数组
if (m_aTabSels.Count >= iMaxCand)
{
m_aTabSels.RemoveAt(m_aTabSels.Count - 1);
m_aTabSels.Insert(0, pCand);
}
else
{
m_aTabSels.Add(pCand);
}
idNewSel = idCandidate;
idNewSel = idCurSel;
}
else // No proper candidate was found / 未找到合适的候选
else
{
if (m_aTabSels.Count == 0)
int idx = -1;
for (int i = 0; i < sorted.Count; i++)
{
idNewSel = idCurSel;
}
else // Try to select one which has been in selected array / 尝试选择已在选中数组中的一个
{
int iIndex = -1;
for (int i = 0; i < m_aTabSels.Count; i++)
if (sorted[i].id == idCurSel)
{
CECObject pObject = m_aTabSels[i];
if (pObject == null)
continue;
int objId = 0;
if (pObject is EC_ElsePlayer pElsePlayer)
objId = pElsePlayer.GetCharacterID();
else if (pObject is CECNPC pNPC)
objId = pNPC.GetNPCID();
if (objId == idCurSel)
{
iIndex = i;
break;
}
}
iIndex = (iIndex + 1) % m_aTabSels.Count;
CECObject pSelectedObj = m_aTabSels[iIndex];
if (pSelectedObj != null)
{
if (pSelectedObj is EC_ElsePlayer pSelPlayer)
idNewSel = pSelPlayer.GetCharacterID();
else if (pSelectedObj is CECNPC pSelNPC)
idNewSel = pSelNPC.GetNPCID();
idx = i;
break;
}
}
int nextIdx = idx < 0 ? 0 : (idx + 1) % sorted.Count;
idNewSel = sorted[nextIdx].id;
}
// Select the target if found / 如果找到目标则选择它