This commit is contained in:
2026-04-30 19:33:16 +08:00
commit fb2252f688
556 changed files with 69721 additions and 0 deletions
+82
View File
@@ -0,0 +1,82 @@
using System;
using GeometryTD.DataTable;
using GeometryTD.Definition;
namespace GeometryTD.Factory
{
public static class ComponentItemFactory
{
public static MuzzleCompItemData CreateMuzzle(
DRMuzzleComp config,
long instanceId,
RarityType rarity,
InventoryTagRandomContext randomContext)
{
RarityType normalizedRarity = InventoryRarityRuleService.NormalizeComponentRarity(rarity);
return new MuzzleCompItemData
{
InstanceId = instanceId,
ConfigId = config.Id,
Name = config.Name,
Rarity = normalizedRarity,
Endurance = 100f,
Constraint = config.Constraint,
Tags = ComponentTagGenerationService.ResolveComponentTags(
config.PossibleTag,
normalizedRarity,
randomContext),
AttackDamage = config.AttackDamage != null ? (int[])config.AttackDamage.Clone() : Array.Empty<int>(),
DamageRandomRate = config.DamageRandomRate,
AttackMethodType = config.AttackMethodType
};
}
public static BearingCompItemData CreateBearing(
DRBearingComp config,
long instanceId,
RarityType rarity,
InventoryTagRandomContext randomContext)
{
RarityType normalizedRarity = InventoryRarityRuleService.NormalizeComponentRarity(rarity);
return new BearingCompItemData
{
InstanceId = instanceId,
ConfigId = config.Id,
Name = config.Name,
Rarity = normalizedRarity,
Endurance = 100f,
Constraint = config.Constraint,
Tags = ComponentTagGenerationService.ResolveComponentTags(
config.PossibleTag,
normalizedRarity,
randomContext),
RotateSpeed = config.RotateSpeed != null ? (float[])config.RotateSpeed.Clone() : Array.Empty<float>(),
AttackRange = config.AttackRange != null ? (float[])config.AttackRange.Clone() : Array.Empty<float>()
};
}
public static BaseCompItemData CreateBase(
DRBaseComp config,
long instanceId,
RarityType rarity,
InventoryTagRandomContext randomContext)
{
RarityType normalizedRarity = InventoryRarityRuleService.NormalizeComponentRarity(rarity);
return new BaseCompItemData
{
InstanceId = instanceId,
ConfigId = config.Id,
Name = config.Name,
Rarity = normalizedRarity,
Endurance = 100f,
Constraint = config.Constraint,
Tags = ComponentTagGenerationService.ResolveComponentTags(
config.PossibleTag,
normalizedRarity,
randomContext),
AttackSpeed = config.AttackSpeed != null ? (float[])config.AttackSpeed.Clone() : Array.Empty<float>(),
AttackPropertyType = config.AttackPropertyType
};
}
}
}
+104
View File
@@ -0,0 +1,104 @@
using GeometryTD.CustomUtility;
using GeometryTD.Definition;
using Newtonsoft.Json.Linq;
using UnityGameFramework.Runtime;
namespace GeometryTD.Factory
{
public static class EventEffectFactory
{
public static EventEffectBase Create(string rawType, JObject param, float? probability = null)
{
if (string.IsNullOrWhiteSpace(rawType))
{
return null;
}
EventEffectType type = EnumUtility<EventEffectType>.Get(rawType);
switch (type)
{
case EventEffectType.AddGold:
{
int count = GetInt(param, "Count");
return new AddGoldEffect(new AddGoldParam(count), probability);
}
case EventEffectType.RemoveRandomComps:
{
int count = GetInt(param, "Count");
RarityType rarity = EnumUtility<RarityType>.Get(GetString(param, "Rarity"));
return new RemoveRandomCompsEffect(new RemoveRandomCompsParam(count, rarity), probability);
}
case EventEffectType.AddRandomComps:
{
int count = GetInt(param, "Count");
bool hasMinRarity = TryGetString(param, "MinRarity", out string minRarityRaw);
bool hasMaxRarity = TryGetString(param, "MaxRarity", out string maxRarityRaw);
if (hasMinRarity || hasMaxRarity)
{
if (!hasMinRarity || !hasMaxRarity)
{
throw new System.InvalidOperationException(
"AddRandomComps requires both MinRarity and MaxRarity when using ranged rarity config.");
}
RarityType minRarity = EnumUtility<RarityType>.Get(minRarityRaw);
RarityType maxRarity = EnumUtility<RarityType>.Get(maxRarityRaw);
return new AddRandomCompsEffect(new AddRandomCompsParam(count, minRarity, maxRarity), probability);
}
RarityType rarity = EnumUtility<RarityType>.Get(GetString(param, "Rarity"));
return new AddRandomCompsEffect(new AddRandomCompsParam(count, rarity), probability);
}
case EventEffectType.DamageRandomTowersEndurance:
{
int count = GetInt(param, "Count");
int amount = GetInt(param, "Amount");
return new DamageRandomTowerEnduranceEffect(new DamageRandomTowerEnduranceParam(count, amount), probability);
}
default:
Log.Warning("Unsupported EventEffectType '{0}'.", rawType);
return null;
}
}
private static int GetInt(JObject param, params string[] keys)
{
if (param == null)
{
return 0;
}
foreach (string key in keys)
{
if (param.TryGetValue(key, out JToken token) && token.Type != JTokenType.Null)
{
return token.Value<int>();
}
}
return 0;
}
private static string GetString(JObject param, string key)
{
if (param == null || !param.TryGetValue(key, out JToken token) || token.Type == JTokenType.Null)
{
return string.Empty;
}
return token.Value<string>();
}
private static bool TryGetString(JObject param, string key, out string value)
{
value = string.Empty;
if (param == null || !param.TryGetValue(key, out JToken token) || token.Type == JTokenType.Null)
{
return false;
}
value = token.Value<string>();
return !string.IsNullOrWhiteSpace(value);
}
}
}
@@ -0,0 +1,75 @@
using GeometryTD.CustomUtility;
using GeometryTD.Definition;
using Newtonsoft.Json.Linq;
using UnityGameFramework.Runtime;
namespace GeometryTD.Factory
{
public static class EventRequirementFactory
{
public static EventRequirementBase Create(string rawType, JObject param)
{
if (string.IsNullOrWhiteSpace(rawType))
{
return null;
}
EventRequirementType type = EnumUtility<EventRequirementType>.Get(rawType);
switch (type)
{
case EventRequirementType.GoldAtLeast:
{
int count = GetInt(param, "Count", "Gold");
return new GoldAtLeastRequirement(new GoldAtLeastParam(count));
}
case EventRequirementType.CompCountAtLeast:
{
int count = GetInt(param, "Count");
RarityType rarity = EnumUtility<RarityType>.Get(GetString(param, "Rarity"));
return new CompCountAtLeastRequirement(new CompCountAtLeastParam(count, rarity));
}
case EventRequirementType.TowerCountAtLeast:
{
int count = GetInt(param, "Count");
return new TowerCountAtLeastRequirement(new TowerCountAtLeastParam(count));
}
case EventRequirementType.HasRelic:
{
int relicId = GetInt(param, "RelicId", "Id");
return new HasRelicRequirement(new HasRelicParam(relicId));
}
default:
Log.Warning("Unsupported EventRequirementType '{0}'.", rawType);
return null;
}
}
private static int GetInt(JObject param, params string[] keys)
{
if (param == null)
{
return 0;
}
foreach (string key in keys)
{
if (param.TryGetValue(key, out JToken token) && token.Type != JTokenType.Null)
{
return token.Value<int>();
}
}
return 0;
}
private static string GetString(JObject param, string key)
{
if (param == null || !param.TryGetValue(key, out JToken token) || token.Type == JTokenType.Null)
{
return string.Empty;
}
return token.Value<string>();
}
}
}
+88
View File
@@ -0,0 +1,88 @@
using System;
using GameFramework.DataTable;
using GeometryTD.DataTable;
using GeometryTD.Definition;
namespace GeometryTD.Factory
{
public sealed class OutGameDropItemBuilder
{
private readonly IDataTable<DRMuzzleComp> _muzzleCompTable;
private readonly IDataTable<DRBearingComp> _bearingCompTable;
private readonly IDataTable<DRBaseComp> _baseCompTable;
public OutGameDropItemBuilder(
IDataTable<DRMuzzleComp> muzzleCompTable,
IDataTable<DRBearingComp> bearingCompTable,
IDataTable<DRBaseComp> baseCompTable)
{
_muzzleCompTable = muzzleCompTable;
_bearingCompTable = bearingCompTable;
_baseCompTable = baseCompTable;
}
public bool TryBuildItem(
DROutGameDropPool row,
RarityType rarity,
InventoryGenerationRandomContext randomContext,
out TowerCompItemData droppedItem)
{
droppedItem = null;
if (row.ItemId <= 0 || string.IsNullOrWhiteSpace(row.ItemType))
{
return false;
}
string itemType = row.ItemType.Trim();
if (itemType.Equals("MuzzleComp", StringComparison.OrdinalIgnoreCase))
{
DRMuzzleComp config = _muzzleCompTable.GetDataRow(row.ItemId);
if (config == null)
{
return false;
}
droppedItem = ComponentItemFactory.CreateMuzzle(
config,
randomContext.CreateStableItemInstanceId(),
rarity,
randomContext.CreateTagRandomContext(config.Id));
return true;
}
if (itemType.Equals("BearingComp", StringComparison.OrdinalIgnoreCase))
{
DRBearingComp config = _bearingCompTable.GetDataRow(row.ItemId);
if (config == null)
{
return false;
}
droppedItem = ComponentItemFactory.CreateBearing(
config,
randomContext.CreateStableItemInstanceId(),
rarity,
randomContext.CreateTagRandomContext(config.Id));
return true;
}
if (itemType.Equals("BaseComp", StringComparison.OrdinalIgnoreCase))
{
DRBaseComp config = _baseCompTable.GetDataRow(row.ItemId);
if (config == null)
{
return false;
}
droppedItem = ComponentItemFactory.CreateBase(
config,
randomContext.CreateStableItemInstanceId(),
rarity,
randomContext.CreateTagRandomContext(config.Id));
return true;
}
return false;
}
}
}
@@ -0,0 +1,25 @@
using GeometryTD.CustomComponent;
using GeometryTD.Definition;
namespace GeometryTD.Factory
{
internal static class PhaseEndConditionFactory
{
private static readonly IPhaseEndCondition None = new NonePhaseEndCondition();
private static readonly IPhaseEndCondition TimeElapsed = new TimeElapsedPhaseEndCondition();
private static readonly IPhaseEndCondition EnemiesCleared = new EnemiesClearedPhaseEndCondition();
private static readonly IPhaseEndCondition BossDead = new BossDeadPhaseEndCondition();
public static IPhaseEndCondition Create(PhaseEndType endType)
{
return endType switch
{
PhaseEndType.TimeElapsed => TimeElapsed,
PhaseEndType.EnemiesCleared => EnemiesCleared,
PhaseEndType.BossDead => BossDead,
PhaseEndType.None => None,
_ => None
};
}
}
}
+59
View File
@@ -0,0 +1,59 @@
using System.Collections.Generic;
using GeometryTD.Definition;
using GeometryTD.Procedure;
namespace GeometryTD.Factory
{
public static class RunStateFactory
{
public static RunState CreateFixedRun(
LevelThemeType themeType,
BackpackInventoryData initialInventorySnapshot,
string runId = null,
int runSeed = 0)
{
IReadOnlyList<RunNodeSeed> fixedNodeSeeds = FixedRunNodeSequenceBuilder.Build(themeType);
return Create(themeType, initialInventorySnapshot, fixedNodeSeeds, runId, runSeed);
}
public static RunState Create(
LevelThemeType themeType,
BackpackInventoryData initialInventorySnapshot,
IEnumerable<RunNodeSeed> nodeSeeds,
string runId = null,
int runSeed = 0)
{
List<RunNodeState> nodes = new List<RunNodeState>();
if (nodeSeeds != null)
{
int sequenceIndex = 0;
foreach (RunNodeSeed seed in nodeSeeds)
{
if (seed == null)
{
continue;
}
nodes.Add(new RunNodeState
{
NodeId = seed.NodeId > 0 ? seed.NodeId : sequenceIndex + 1,
NodeType = seed.NodeType,
ThemeType = seed.ThemeType == LevelThemeType.None ? themeType : seed.ThemeType,
LinkedLevelId = seed.LinkedLevelId,
SequenceIndex = seed.SequenceIndex >= 0 ? seed.SequenceIndex : sequenceIndex,
Status = sequenceIndex == 0 ? RunNodeStatus.Available : RunNodeStatus.Locked
});
sequenceIndex++;
}
}
return new RunState(runId, runSeed, themeType, nodes, initialInventorySnapshot);
}
public static int CreateRunSeed()
{
int seed = System.Guid.NewGuid().GetHashCode();
return seed == 0 ? 1 : seed;
}
}
}