diff --git a/Assets/PerfectWorld/Scene/Bootstrap.unity b/Assets/PerfectWorld/Scene/Bootstrap.unity
index 05360e0fde..141d371899 100644
--- a/Assets/PerfectWorld/Scene/Bootstrap.unity
+++ b/Assets/PerfectWorld/Scene/Bootstrap.unity
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:543e09f5571b2d48dd57646eee06f8efbc71e6aaa62d6e8a98a529dec44b7364
-size 322591
+oid sha256:f85e6e6bc4d5b6af2e103cf46a846213439f86c209bed0512839f28b8c23a7c6
+size 326984
diff --git a/Assets/PerfectWorld/Scripts/Managers/A3DSkillGfxMan.cs b/Assets/PerfectWorld/Scripts/Managers/A3DSkillGfxMan.cs
index 0a5ce5450e..85b15e413c 100644
--- a/Assets/PerfectWorld/Scripts/Managers/A3DSkillGfxMan.cs
+++ b/Assets/PerfectWorld/Scripts/Managers/A3DSkillGfxMan.cs
@@ -151,6 +151,8 @@ namespace BrewMonster
pEvent.SetIsCluster(bCluster);
pEvent.SetFadeOut(bFadeOut);
pEvent.SetGoblinSkill(bIsGoblinSkill);
+ pEvent.SetShowFlyGfx(!string.IsNullOrEmpty(szFlyGfx));
+ pEvent.SetShowHitGfx(!string.IsNullOrEmpty(szHitGfx));
ECMODEL_GFX_PROPERTY Prop = new ECMODEL_GFX_PROPERTY();
if (GetPropertyById(nHostID, ref Prop))
@@ -192,7 +194,9 @@ namespace BrewMonster
protected long m_nHostID;
protected long m_nTargetID;
protected uint m_dwModifier;
- protected bool m_bIsGoblinSkill;
+ protected bool m_bIsGoblinSkill;
+ protected bool m_bShowFlyGfx;
+ protected bool m_bShowHitGfx;
protected Vector3 m_vHostPos;
protected Vector3 m_vTargetPos;
@@ -222,6 +226,8 @@ namespace BrewMonster
m_enumState = GfxSkillEventState.enumWait;
m_bHitGfxInfinite = false;
m_bIsGoblinSkill = false;
+ m_bShowFlyGfx = true;
+ m_bShowHitGfx = true;
m_bTargetDirAndUpExist = false;
m_bGfxUseLod = true;
m_bGfxDisableCamShake = false;
@@ -336,12 +342,16 @@ namespace BrewMonster
public void SetModifier(uint dwModifier) { m_dwModifier = dwModifier; }
public void SetGoblinSkill(bool bGoblinSkill) { m_bIsGoblinSkill = bGoblinSkill; }
public bool GetGoblinSkill() { return m_bIsGoblinSkill; }
+ public void SetShowFlyGfx(bool b) { m_bShowFlyGfx = b; }
+ public void SetShowHitGfx(bool b) { m_bShowHitGfx = b; }
public void Resume()
{
//ReleaseGfx();
m_enumState = GfxSkillEventState.enumWait;
m_dwCurSpan = 0;
+ m_bShowFlyGfx = true;
+ m_bShowHitGfx = true;
}
// Virtual functions
diff --git a/Assets/PerfectWorld/Scripts/Managers/CECSkillGfxMan.cs b/Assets/PerfectWorld/Scripts/Managers/CECSkillGfxMan.cs
index ac8cc94512..fcfc388899 100644
--- a/Assets/PerfectWorld/Scripts/Managers/CECSkillGfxMan.cs
+++ b/Assets/PerfectWorld/Scripts/Managers/CECSkillGfxMan.cs
@@ -329,6 +329,7 @@ namespace BrewMonster
///
private void SpawnFlyGfx()
{
+ if (!m_bShowFlyGfx) return;
if (m_pComposer == null)
{
@@ -411,6 +412,7 @@ namespace BrewMonster
///
private void SpawnHitGfx(Vector3 vTarget)
{
+ if (!m_bShowHitGfx) return;
if (m_pComposer == null)
{
diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_HostInputFilter.cs b/Assets/PerfectWorld/Scripts/Managers/EC_HostInputFilter.cs
index 658a7992c9..edfce9b093 100644
--- a/Assets/PerfectWorld/Scripts/Managers/EC_HostInputFilter.cs
+++ b/Assets/PerfectWorld/Scripts/Managers/EC_HostInputFilter.cs
@@ -3,6 +3,7 @@ using BrewMonster.Network;
using BrewMonster.Scripts;
using CSNetwork.GPDataType;
using PerfectWorld.Scripts;
+using PerfectWorld.Scripts.Managers;
using CSNetwork;
using UnityEngine;
using static BrewMonster.Scripts.CECHPWork;
@@ -610,6 +611,36 @@ namespace BrewMonster
return bOK;
}
+ ///
+ /// HUD / shortcut: walk to and pick up the nearest ground item or money (not mines) within range.
+ ///
+ /// Max horizontal distance to search (meters).
+ /// True if a matter was found and started.
+ public bool TryPickupNearestGroundMatter(float maxSearchRadiusH = 80f)
+ {
+ if (IsDead() || m_pWorkMan == null)
+ return false;
+
+ if (m_pWorkMan.IsSitting())
+ {
+ UnityGameSession.c2s_CmdStandUp();
+ return false;
+ }
+
+ if (!CanDo(ActionCanDo.CANDO_MOVETO))
+ return false;
+
+ EC_ManMatter matterMan = EC_ManMessageMono.Instance?.EC_ManMatter;
+ if (matterMan == null)
+ return false;
+
+ CECMatter nearest = matterMan.GetNearestPickupableMatter(GetPos(), maxSearchRadiusH);
+ if (nearest == null)
+ return false;
+
+ return PickupObject(nearest.GetMatterID(), false);
+ }
+
// Check whether host can gather specified matter / Check whether host can gather specified matter
public bool CanGatherMatter(CECMatter pMatter)
{
diff --git a/Assets/PerfectWorld/Scripts/Managers/EC_ManMatter.cs b/Assets/PerfectWorld/Scripts/Managers/EC_ManMatter.cs
index 1275ab4198..6860f41640 100644
--- a/Assets/PerfectWorld/Scripts/Managers/EC_ManMatter.cs
+++ b/Assets/PerfectWorld/Scripts/Managers/EC_ManMatter.cs
@@ -314,6 +314,31 @@ namespace PerfectWorld.Scripts.Managers
}
return null;
}
+
+ ///
+ /// Nearest ground item or money matter within horizontal of .
+ /// Mines (gather nodes) are excluded — use direct click / gather flow for those.
+ ///
+ public CECMatter GetNearestPickupableMatter(A3DVECTOR3 hostPos, float maxRadiusH)
+ {
+ CECMatter best = null;
+ float bestDist = float.MaxValue;
+ foreach (var kv in m_MatterTab)
+ {
+ CECMatter m = kv.Value;
+ if (m == null || !m)
+ continue;
+ if (m.IsMine())
+ continue;
+
+ float d = m.CalcDist(hostPos, false);
+ if (d > maxRadiusH || d >= bestDist)
+ continue;
+ bestDist = d;
+ best = m;
+ }
+ return best;
+ }
public CECMatter CreateMatter(info_matter info)
{
diff --git a/Assets/PerfectWorld/Scripts/UI/PickupNearestButtonHandler.cs b/Assets/PerfectWorld/Scripts/UI/PickupNearestButtonHandler.cs
new file mode 100644
index 0000000000..877241503e
--- /dev/null
+++ b/Assets/PerfectWorld/Scripts/UI/PickupNearestButtonHandler.cs
@@ -0,0 +1,44 @@
+using UnityEngine;
+using UnityEngine.UI;
+
+namespace BrewMonster.UI
+{
+ ///
+ /// HUD button: pick up the nearest ground item or money (host trace + TryPickupNearestGroundMatter).
+ /// Assign to a Button or leave unassigned to use the component's own Button.
+ ///
+ public class PickupNearestButtonHandler : MonoBehaviour
+ {
+ [SerializeField] private Button button;
+ [Tooltip("Horizontal search radius around the player (meters).")]
+ [SerializeField] private float maxSearchRadius = 80f;
+
+ private void Start()
+ {
+ if (button == null)
+ button = GetComponent