Run Re-Do
This commit is contained in:
@@ -38,13 +38,14 @@ namespace ProjectM.Client
|
||||
UnityEngine.Camera _camera; // cursor -> ground re-raycast for click-to-place (resolved lazily)
|
||||
GameObject _ghost; // translucent ground preview cube
|
||||
Material _ghostMat;
|
||||
MeshFilter _ghostMf; // ghost mesh swaps to the selected structure's preview mesh (HudTheme)
|
||||
MeshRenderer _ghostMr;
|
||||
Mesh _cubeMesh; // procedural fallback (the original preview cube)
|
||||
byte _ghostType = 255; // last-applied preview type (255 = unset)
|
||||
byte _lastSelected; // skip placing on the frame a palette click changes the selection
|
||||
|
||||
// DR-042 C6a: the ability-upgrade send is RUNTIME (the HUD Aether button calls UpgradeAbility); only the
|
||||
// execute_code PLACE statics stay editor-gated. Mirrors EquipSendSystem's unconditional queue + drain.
|
||||
static int s_PendingUpgrades = 0;
|
||||
/// <summary>Runtime hook (HUD Aether button) + execute_code: queue an ability-damage upgrade.</summary>
|
||||
public static void UpgradeAbility() => s_PendingUpgrades++;
|
||||
// (Step 11: UpgradeAbility/s_PendingUpgrades RETIRED with the AbilityUpgradeRequest wire — in-run boons +
|
||||
// the base meta-shop replaced the Aether damage upgrade.)des++;
|
||||
|
||||
#if UNITY_EDITOR
|
||||
struct PendingBuild { public byte Type; public int CellX; public int CellZ; public byte Direction; }
|
||||
@@ -113,17 +114,8 @@ namespace ProjectM.Client
|
||||
foreach (var (key, type) in s_BuildHotkeys)
|
||||
if (keyboard[key].wasPressedThisFrame && TryGetLocalPlayerCell(out int2 cell))
|
||||
SendBuild(connection, type, cell.x, cell.y, type == StructureType.Conveyor ? s_ConveyorDir : (byte)0);
|
||||
if (keyboard.uKey.wasPressedThisFrame)
|
||||
SendUpgrade(connection);
|
||||
}
|
||||
|
||||
// DR-042 C6a: the ability-upgrade drain runs at RUNTIME (the HUD Aether button enqueues via UpgradeAbility);
|
||||
// only the execute_code PLACE drain stays editor-gated.
|
||||
while (s_PendingUpgrades > 0)
|
||||
{
|
||||
s_PendingUpgrades--;
|
||||
SendUpgrade(connection);
|
||||
}
|
||||
#if UNITY_EDITOR
|
||||
while (s_PendingBuild.Count > 0)
|
||||
{
|
||||
@@ -185,7 +177,7 @@ namespace ProjectM.Client
|
||||
byte reason = BuildPreviewMath.Evaluate(anchor, targetCell, occupied, LedgerOre(), cost);
|
||||
bool valid = reason == BuildPreviewMath.Valid;
|
||||
|
||||
ShowGhost(BaseGridMath.CellToWorld(anchor, targetCell), anchor.CellSize, valid);
|
||||
ShowGhost(BaseGridMath.CellToWorld(anchor, targetCell), anchor.CellSize, valid, sel);;
|
||||
|
||||
// Place on a left-click (valid, not the selecting click).
|
||||
if (valid && !justSelected && mouse.leftButton.wasPressedThisFrame)
|
||||
@@ -208,16 +200,44 @@ namespace ProjectM.Client
|
||||
return int.MaxValue;
|
||||
}
|
||||
|
||||
// ---- Ground ghost preview (procedural translucent cube, like AimReticleSystem's reticle) ----
|
||||
void ShowGhost(float3 center, float cellSize, bool valid)
|
||||
// ---- Ground ghost preview: the selected structure's REAL mesh (HudTheme, build-safe serialized refs)
|
||||
// tinted translucent green/red; falls back to the original procedural cube when no mesh is authored. ----
|
||||
void ShowGhost(float3 center, float cellSize, bool valid, byte type)
|
||||
{
|
||||
EnsureGhost();
|
||||
_ghost.transform.position = (Vector3)center + Vector3.up * 0.5f;
|
||||
_ghost.transform.localScale = new Vector3(cellSize * 0.9f, 1f, cellSize * 0.9f);
|
||||
ApplyGhostMesh(type);
|
||||
if (_ghostMf.sharedMesh == _cubeMesh)
|
||||
{
|
||||
_ghost.transform.position = (Vector3)center + Vector3.up * 0.5f;
|
||||
_ghost.transform.localScale = new Vector3(cellSize * 0.9f, 1f, cellSize * 0.9f);
|
||||
}
|
||||
else
|
||||
{
|
||||
// preview meshes are authored real-size with a ground pivot (SM_Turret_01 / SM_Wall_01 / SM_Fabricator_01)
|
||||
_ghost.transform.position = (Vector3)center;
|
||||
_ghost.transform.localScale = Vector3.one;
|
||||
}
|
||||
_ghostMat.color = valid ? new Color(0.3f, 1f, 0.45f, 0.35f) : new Color(1f, 0.32f, 0.26f, 0.35f);
|
||||
if (!_ghost.activeSelf) _ghost.SetActive(true);
|
||||
}
|
||||
|
||||
// Swap the ghost's mesh when the palette selection changes (255 = unset sentinel; no selection is 0 -> cube).
|
||||
void ApplyGhostMesh(byte type)
|
||||
{
|
||||
if (type == _ghostType) return;
|
||||
_ghostType = type;
|
||||
var theme = HudTheme.Get();
|
||||
Mesh mesh = theme != null ? theme.StructureGhostMesh(type) : null;
|
||||
if (mesh == null) mesh = _cubeMesh;
|
||||
_ghostMf.sharedMesh = mesh;
|
||||
if (_ghostMr.sharedMaterials.Length != mesh.subMeshCount)
|
||||
{
|
||||
var mats = new Material[mesh.subMeshCount]; // one translucent mat per submesh so the whole preview tints
|
||||
for (int i = 0; i < mats.Length; i++) mats[i] = _ghostMat;
|
||||
_ghostMr.sharedMaterials = mats;
|
||||
}
|
||||
}
|
||||
|
||||
void HideGhost()
|
||||
{
|
||||
if (_ghost != null && _ghost.activeSelf) _ghost.SetActive(false);
|
||||
@@ -233,10 +253,13 @@ namespace ProjectM.Client
|
||||
_ghost.name = "~BuildGhost";
|
||||
var col = _ghost.GetComponent<Collider>();
|
||||
if (col != null) Object.Destroy(col);
|
||||
var mr = _ghost.GetComponent<MeshRenderer>();
|
||||
mr.sharedMaterial = _ghostMat;
|
||||
mr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
|
||||
mr.receiveShadows = false;
|
||||
_ghostMf = _ghost.GetComponent<MeshFilter>();
|
||||
_cubeMesh = _ghostMf.sharedMesh;
|
||||
_ghostType = 255;
|
||||
_ghostMr = _ghost.GetComponent<MeshRenderer>();
|
||||
_ghostMr.sharedMaterial = _ghostMat;
|
||||
_ghostMr.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.Off;
|
||||
_ghostMr.receiveShadows = false;
|
||||
_ghost.SetActive(false);
|
||||
}
|
||||
|
||||
@@ -270,12 +293,6 @@ namespace ProjectM.Client
|
||||
EntityManager.AddComponentData(e, new BuildPlaceRequest { StructureType = type, CellX = cellX, CellZ = cellZ, Direction = direction });
|
||||
EntityManager.AddComponentData(e, new SendRpcCommandRequest { TargetConnection = connection });
|
||||
}
|
||||
|
||||
void SendUpgrade(Entity connection)
|
||||
{
|
||||
var e = EntityManager.CreateEntity();
|
||||
EntityManager.AddComponentData(e, new AbilityUpgradeRequest());
|
||||
EntityManager.AddComponentData(e, new SendRpcCommandRequest { TargetConnection = connection });
|
||||
}
|
||||
// (Step 11: the Aether ability-upgrade sender was RETIRED with AbilityUpgradeRequest — boons replaced it.)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user