(Feat) Add Build

This commit is contained in:
2026-07-22 12:56:13 +02:00
parent 3657b870d8
commit 0052b0d98e
244 changed files with 35752 additions and 3112 deletions
@@ -29,6 +29,10 @@ namespace Ashwild.Player
public static bool IsPlacingBuild { get; private set; }
// True while the build hammer is in demolition mode (right-click held, menu closed, not placing).
public static bool IsDemolishing { get; private set; }
// Composite "the player is actively building" flag — true whenever the construction menu is open,
// a ghost is being positioned, or the hammer is demolishing. Recomputed from those three states
// (never set directly) and used to widen the crosshair and to suppress item pickup while building.
public static bool IsBuilding { get; private set; }
public static bool IsPaused { get; private set; }
// True when a networked session is live (host or client).
@@ -103,7 +107,11 @@ namespace Ashwild.Player
public static event Action<int> InventorySlotChanged;
public static event Action<int> SelectedHotbarSlotChanged;
public static event Action<ItemData, int> ItemAdded;
// (item, quantity, isTransfer) — isTransfer is true when the stack merely moved between the
// player's own containers (a chest withdrawal, a refund) instead of being newly acquired from
// the world. Consumers that announce a gain (notifications) skip transfers; consumers that only
// track "the player has held this" (craft discovery) treat both the same.
public static event Action<ItemData, int, bool> ItemAdded;
public static event Action<ItemData, int> ItemDropped;
public static event Action<ItemData> ItemConsumed;
public static event Action<ItemData, int> ItemPickedUp;
@@ -134,9 +142,11 @@ namespace Ashwild.Player
// ============================================================
public static event Action BuildMenuToggleRequested; // the build hammer asks to open/close the construction menu
public static event Action BuildCancelRequested; // the build hammer asks to cancel/exit the current ghost placement (right-click while placing)
public static event Action<bool> BuildMenuOpenChanged; // the construction menu opened (true) or closed (false)
public static event Action<bool> BuildPlacingChanged; // a build ghost started (true) / stopped (false) being positioned
public static event Action<bool> DemolishModeChanged; // the hammer entered (true) / left (false) demolition mode (right-click held)
public static event Action<bool> BuildModeChanged; // the composite build mode turned on (true) / off (false) — see IsBuilding
public static event Action<IReadOnlyList<BuildCostView>> BuildCostChanged; // the active build's cost to display near the crosshair (null/empty = clear)
// ============================================================
@@ -256,7 +266,7 @@ namespace Ashwild.Player
public static void RaiseInventorySlotChanged(int i) { InventorySlotChanged?.Invoke(i); }
public static void RaiseSelectedHotbarSlotChanged(int i) { Log(nameof(SelectedHotbarSlotChanged)); SelectedHotbarSlotChanged?.Invoke(i); }
public static void RaiseItemAdded(ItemData d, int q) { Log(nameof(ItemAdded)); ItemAdded?.Invoke(d, q); }
public static void RaiseItemAdded(ItemData d, int q, bool isTransfer = false) { Log(nameof(ItemAdded)); ItemAdded?.Invoke(d, q, isTransfer); }
public static void RaiseItemDropped(ItemData d, int q) { Log(nameof(ItemDropped)); ItemDropped?.Invoke(d, q); }
public static void RaiseItemConsumed(ItemData d) { Log(nameof(ItemConsumed)); ItemConsumed?.Invoke(d); }
public static void RaiseItemPickedUp(ItemData d, int q) { Log(nameof(ItemPickedUp)); ItemPickedUp?.Invoke(d, q); }
@@ -295,17 +305,20 @@ namespace Ashwild.Player
public static void RaiseUnequipAnimComplete() { UnequipAnimComplete?.Invoke(); }
public static void RaiseBuildMenuToggleRequested() { Log(nameof(BuildMenuToggleRequested)); BuildMenuToggleRequested?.Invoke(); }
public static void RaiseBuildCancelRequested() { Log(nameof(BuildCancelRequested)); BuildCancelRequested?.Invoke(); }
public static void RaiseBuildMenuOpenChanged(bool open)
{
IsBuildMenuOpen = open;
Log(nameof(BuildMenuOpenChanged));
BuildMenuOpenChanged?.Invoke(open);
RefreshBuildMode();
}
public static void RaiseBuildPlacingChanged(bool placing)
{
IsPlacingBuild = placing;
Log(nameof(BuildPlacingChanged));
BuildPlacingChanged?.Invoke(placing);
RefreshBuildMode();
}
/// <summary>
@@ -328,6 +341,21 @@ namespace Ashwild.Player
IsDemolishing = on;
Log(nameof(DemolishModeChanged));
DemolishModeChanged?.Invoke(on);
RefreshBuildMode();
}
/// <summary>
/// Recomputes the composite build-mode flag from its three sub-states and raises BuildModeChanged
/// only when it actually flips, so consumers (crosshair spacing, pickup gating) react exactly once
/// per transition instead of on every sub-state change.
/// </summary>
private static void RefreshBuildMode()
{
bool building = IsBuildMenuOpen || IsPlacingBuild || IsDemolishing;
if (building == IsBuilding) return;
IsBuilding = building;
Log(nameof(BuildModeChanged));
BuildModeChanged?.Invoke(building);
}
public static void RaiseFoodPlacedToCook(ItemData raw) { Log(nameof(FoodPlacedToCook)); FoodPlacedToCook?.Invoke(raw); }
@@ -413,6 +441,7 @@ namespace Ashwild.Player
IsBuildMenuOpen = false;
IsPlacingBuild = false;
IsDemolishing = false;
IsBuilding = false;
IsPaused = false;
HoveredInteractable = null;
}