Run Re-Do
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ProjectM.Simulation;
|
||||
using Unity.Collections;
|
||||
using Unity.Entities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ProjectM.Authoring
|
||||
{
|
||||
/// <summary>
|
||||
/// Authoring for the boon-catalog config singleton (place ONE in the gameplay subscene). Designers can author
|
||||
/// rows in the inspector; an EMPTY list bakes the code-default v1 table (<see cref="BoonCatalogData.BuildDefault"/>)
|
||||
/// verbatim — so the subscene object needs zero property assignment through the tooling (the
|
||||
/// component_properties enum/array-drop hazard). Ids are APPEND-ONLY (they ride the replicated BoonOffer bytes
|
||||
/// and, later, per-run analytics).
|
||||
/// </summary>
|
||||
public class BoonCatalogAuthoring : MonoBehaviour
|
||||
{
|
||||
[Serializable]
|
||||
public struct BoonRow
|
||||
{
|
||||
public byte Id;
|
||||
public StatTarget Target;
|
||||
public ModOp Op;
|
||||
public float Value;
|
||||
[Tooltip("Rarity draw weight: common 100 / rare 30 / epic 10. 0 removes the boon from the pool.")]
|
||||
public byte Weight;
|
||||
[Tooltip("bit0 = Warrior, bit1 = Ranger, 3 = both.")]
|
||||
public byte ClassMask;
|
||||
public string Name;
|
||||
public string Desc;
|
||||
}
|
||||
|
||||
[Tooltip("Leave EMPTY to bake the code-default v1 table; fill to fully replace it.")]
|
||||
public List<BoonRow> Rows = new List<BoonRow>();
|
||||
|
||||
private class BoonCatalogBaker : Baker<BoonCatalogAuthoring>
|
||||
{
|
||||
public override void Bake(BoonCatalogAuthoring authoring)
|
||||
{
|
||||
var entity = GetEntity(authoring, TransformUsageFlags.None);
|
||||
|
||||
BlobAssetReference<BoonCatalogBlob> blob;
|
||||
if (authoring.Rows == null || authoring.Rows.Count == 0)
|
||||
{
|
||||
blob = BoonCatalogData.BuildDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
var builder = new BlobBuilder(Allocator.Temp);
|
||||
ref var root = ref builder.ConstructRoot<BoonCatalogBlob>();
|
||||
var defs = builder.Allocate(ref root.Defs, authoring.Rows.Count);
|
||||
for (int i = 0; i < authoring.Rows.Count; i++)
|
||||
{
|
||||
var r = authoring.Rows[i];
|
||||
defs[i] = new BoonDefBlob
|
||||
{
|
||||
Id = r.Id,
|
||||
Target = (byte)r.Target,
|
||||
Op = (byte)r.Op,
|
||||
Value = r.Value,
|
||||
Weight = r.Weight,
|
||||
ClassMask = r.ClassMask,
|
||||
Name = new FixedString64Bytes(r.Name ?? string.Empty),
|
||||
Desc = new FixedString128Bytes(r.Desc ?? string.Empty),
|
||||
};
|
||||
}
|
||||
blob = builder.CreateBlobAssetReference<BoonCatalogBlob>(Allocator.Persistent);
|
||||
builder.Dispose();
|
||||
}
|
||||
|
||||
AddBlobAsset(ref blob, out _);
|
||||
AddComponent(entity, new BoonCatalog { Value = blob });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 075a570afb8ef9541b6307280b53f4e7
|
||||
@@ -1,51 +0,0 @@
|
||||
using ProjectM.Simulation;
|
||||
using Unity.Entities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ProjectM.Authoring
|
||||
{
|
||||
/// <summary>
|
||||
/// Authoring for the home-base mining field (<see cref="BaseFieldSpawner"/>). Place ONE in the gameplay
|
||||
/// subscene. <see cref="NodePrefab"/> = the SAME ResourceNode ghost prefab the expedition uses; the server
|
||||
/// system overrides each instance to RegionTag{Base} + ResourceId.Ore and scatters them in the
|
||||
/// [<see cref="InnerRadius"/>, <see cref="OuterRadius"/>] annulus around the base plot center. Defaults are
|
||||
/// sized to the baked 32x32 plot (square corner reach ~22.6) inside the ~28.7 boundary ring, so nodes form a
|
||||
/// reachable perimeter ring that never sits on a build cell.
|
||||
/// </summary>
|
||||
public class BaseFieldSpawnerAuthoring : MonoBehaviour
|
||||
{
|
||||
[Tooltip("Resource-node ghost prefab (ResourceNodeAuthoring + GhostAuthoring). Reuse the expedition node prefab.")]
|
||||
public GameObject NodePrefab;
|
||||
|
||||
[Tooltip("Live base-node target; the field refills toward this each respawn pass.")]
|
||||
[Min(1)] public int TargetCount = 10;
|
||||
|
||||
[Tooltip("Inner scatter radius — clears the build plot corner reach (~22.6) + spawn ring.")]
|
||||
[Min(0f)] public float InnerRadius = 23.5f;
|
||||
|
||||
[Tooltip("Outer scatter radius — stays inside the walkable boundary ring (~28.7).")]
|
||||
[Min(0f)] public float OuterRadius = 27f;
|
||||
|
||||
[Tooltip("Server ticks (@60) between top-up passes.")]
|
||||
[Min(1)] public int RespawnIntervalTicks = 600;
|
||||
|
||||
private class BaseFieldSpawnerBaker : Baker<BaseFieldSpawnerAuthoring>
|
||||
{
|
||||
public override void Bake(BaseFieldSpawnerAuthoring authoring)
|
||||
{
|
||||
var entity = GetEntity(authoring, TransformUsageFlags.None);
|
||||
AddComponent(entity, new BaseFieldSpawner
|
||||
{
|
||||
Prefab = authoring.NodePrefab != null
|
||||
? GetEntity(authoring.NodePrefab, TransformUsageFlags.Dynamic)
|
||||
: Entity.Null,
|
||||
TargetCount = authoring.TargetCount,
|
||||
InnerRadius = authoring.InnerRadius,
|
||||
OuterRadius = authoring.OuterRadius,
|
||||
RespawnIntervalTicks = authoring.RespawnIntervalTicks,
|
||||
});
|
||||
AddComponent(entity, new BaseFieldRuntime { Epoch = 0, NextSpawnTick = 0u });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c4055a6a779d06949ae23b16334b810e
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d0503ff85f3b39f49af750a451d44e00
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,85 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using ProjectM.Simulation;
|
||||
using Unity.Collections;
|
||||
using Unity.Entities;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ProjectM.Authoring
|
||||
{
|
||||
/// <summary>
|
||||
/// Authoring for the PERMANENT meta-upgrade catalog singleton (place ONE in the gameplay subscene — the
|
||||
/// BoonCatalogAuthoring pattern). An EMPTY row list bakes the code-default v1 table
|
||||
/// (<see cref="MetaCatalogData.BuildDefault"/>) verbatim, so the subscene object needs zero property assignment
|
||||
/// through the tooling. Ids are APPEND-ONLY (persisted in SaveData v6; a removed id's saved rows are preserved
|
||||
/// and skipped, never crashed on).
|
||||
/// </summary>
|
||||
public class MetaCatalogAuthoring : MonoBehaviour
|
||||
{
|
||||
[Serializable]
|
||||
public struct MetaRow
|
||||
{
|
||||
public byte Id;
|
||||
[Tooltip("bit0 = Warrior, bit1 = Ranger, 3 = both.")]
|
||||
public byte ClassMask;
|
||||
public StatTarget Target;
|
||||
public ModOp Op;
|
||||
public byte MaxTier;
|
||||
public float ValuePerTier;
|
||||
public int BaseCost;
|
||||
public int CostGrowth;
|
||||
[Tooltip("0xFF (255) = no prerequisite.")]
|
||||
public byte PrereqId;
|
||||
public byte PrereqTier;
|
||||
public string Name;
|
||||
public string Desc;
|
||||
}
|
||||
|
||||
[Tooltip("Leave EMPTY to bake the code-default v1 table; fill to fully replace it.")]
|
||||
public List<MetaRow> Rows = new List<MetaRow>();
|
||||
|
||||
private class MetaCatalogBaker : Baker<MetaCatalogAuthoring>
|
||||
{
|
||||
public override void Bake(MetaCatalogAuthoring authoring)
|
||||
{
|
||||
var entity = GetEntity(authoring, TransformUsageFlags.None);
|
||||
|
||||
BlobAssetReference<MetaUpgradeCatalogBlob> blob;
|
||||
if (authoring.Rows == null || authoring.Rows.Count == 0)
|
||||
{
|
||||
blob = MetaCatalogData.BuildDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
var builder = new BlobBuilder(Allocator.Temp);
|
||||
ref var root = ref builder.ConstructRoot<MetaUpgradeCatalogBlob>();
|
||||
var defs = builder.Allocate(ref root.Defs, authoring.Rows.Count);
|
||||
for (int i = 0; i < authoring.Rows.Count; i++)
|
||||
{
|
||||
var r = authoring.Rows[i];
|
||||
defs[i] = new MetaUpgradeDefBlob
|
||||
{
|
||||
Id = r.Id,
|
||||
ClassMask = r.ClassMask,
|
||||
Target = (byte)r.Target,
|
||||
Op = (byte)r.Op,
|
||||
MaxTier = r.MaxTier,
|
||||
ValuePerTier = r.ValuePerTier,
|
||||
BaseCost = r.BaseCost,
|
||||
CostGrowth = r.CostGrowth,
|
||||
PrereqId = r.PrereqId,
|
||||
PrereqTier = r.PrereqTier,
|
||||
Name = new FixedString64Bytes(r.Name ?? string.Empty),
|
||||
Desc = new FixedString128Bytes(r.Desc ?? string.Empty),
|
||||
};
|
||||
}
|
||||
blob = builder.CreateBlobAssetReference<MetaUpgradeCatalogBlob>(Allocator.Persistent);
|
||||
builder.Dispose();
|
||||
}
|
||||
|
||||
AddBlobAsset(ref blob, out _);
|
||||
AddComponent(entity, new MetaUpgradeCatalog { Value = blob });
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4f007f7870c0afd4e93ea5b86fd21c8b
|
||||
@@ -100,6 +100,11 @@ namespace ProjectM.Authoring
|
||||
|
||||
AddComponent(entity, new RespawnState { RespawnTick = 0, DelayTicks = authoring.RespawnDelayTicks, InvulnTicks = authoring.RespawnInvulnTicks });
|
||||
AddComponent(entity, new RespawnInvuln { UntilTick = 0 });
|
||||
|
||||
// Expedition redesign (the ONE player-ghost re-bake, front-loaded): the send-to-all ready-check
|
||||
// flag + the owner-only choice-of-3 boon offer (inert until Step 9's BoonOfferSystem lights it up).
|
||||
AddComponent<PlayerReady>(entity);
|
||||
AddComponent<BoonOffer>(entity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,6 +78,13 @@ namespace ProjectM.Authoring
|
||||
// runtime-spawned director ghost (server + client bake the same prefab -> hash matches), like CoreIntegrity.
|
||||
AddComponent(entity, new ExpeditionObjective { State = ExpeditionObjectiveState.Idle, Remaining = 0 });
|
||||
|
||||
// Expedition redesign: the replicated run-lifecycle FSM (RunInfo, 17 [GhostField]s) + the per-class
|
||||
// permanent-meta tier buffer (MetaTierState) BOTH land in this ONE coordinated re-bake (front-loaded
|
||||
// ghost layout — the writer systems arrive across Steps 2–13 while the state sits inert/default).
|
||||
// Born Staging/empty; server RunDirectorSystem / MetaSpendSystem are the sole writers.
|
||||
AddComponent(entity, new RunInfo { Lifecycle = RunLifecycle.Staging });
|
||||
AddBuffer<MetaTierState>(entity);
|
||||
|
||||
|
||||
AddComponent(entity, new ThreatConfig
|
||||
{
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
using ProjectM.Simulation;
|
||||
using Unity.Entities;
|
||||
using Unity.Mathematics;
|
||||
using UnityEngine;
|
||||
|
||||
namespace ProjectM.Authoring
|
||||
{
|
||||
/// <summary>
|
||||
/// Authoring for a walk-in <see cref="ExpeditionGate"/>. Place on a visible gate object in the gameplay
|
||||
/// subscene; baked into both worlds at the gate's position (the server reads its LocalTransform for the
|
||||
/// overlap test, the client renders the mesh). Set From/To regions + the arrival point in the destination
|
||||
/// region (offset from that region's gate so the player doesn't immediately re-trigger).
|
||||
/// </summary>
|
||||
public class ExpeditionGateAuthoring : MonoBehaviour
|
||||
{
|
||||
public enum Region : byte { Base = 0, Expedition = 1 }
|
||||
|
||||
[Tooltip("Region a player must be in for this gate to act on them.")]
|
||||
public Region From = Region.Base;
|
||||
|
||||
[Tooltip("Region the player is transited to.")]
|
||||
public Region To = Region.Expedition;
|
||||
|
||||
[Min(0.5f)] public float Radius = 2.5f;
|
||||
|
||||
[Tooltip("Where the player arrives in the destination region (offset from that region's gate).")]
|
||||
public Vector3 ArrivalPos = new Vector3(1000f, 1f, 0f);
|
||||
|
||||
private class ExpeditionGateBaker : Baker<ExpeditionGateAuthoring>
|
||||
{
|
||||
public override void Bake(ExpeditionGateAuthoring authoring)
|
||||
{
|
||||
// Dynamic so the baked entity carries a LocalTransform the server can read for the overlap test.
|
||||
var entity = GetEntity(authoring, TransformUsageFlags.Dynamic);
|
||||
AddComponent(entity, new ExpeditionGate
|
||||
{
|
||||
FromRegion = (byte)authoring.From,
|
||||
ToRegion = (byte)authoring.To,
|
||||
Radius = authoring.Radius,
|
||||
ArrivalPos = new float3(authoring.ArrivalPos.x, authoring.ArrivalPos.y, authoring.ArrivalPos.z),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 22f744b59ad23834abe28fc09b661005
|
||||
Reference in New Issue
Block a user