S4-07 process 1
This commit is contained in:
@@ -4,24 +4,6 @@ using UnityEngine;
|
||||
|
||||
namespace GeometryTD.Definition
|
||||
{
|
||||
/// <summary>
|
||||
/// 防御塔独立属性快照。
|
||||
/// 注意:这里是塔实例的独立值,不通过组件引用实时计算。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public sealed class TowerStatsData
|
||||
{
|
||||
public int[] AttackDamage { get; set; }
|
||||
public float DamageRandomRate { get; set; }
|
||||
public float[] RotateSpeed { get; set; }
|
||||
public float[] AttackRange { get; set; }
|
||||
public float[] AttackSpeed { get; set; }
|
||||
public AttackMethodType AttackMethodType { get; set; }
|
||||
public AttackPropertyType AttackPropertyType { get; set; }
|
||||
public TagRuntimeData[] TagRuntimes { get; set; }
|
||||
public TagType[] Tags { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 背包内防御塔实例数据。
|
||||
/// </summary>
|
||||
@@ -69,4 +51,4 @@ namespace GeometryTD.Definition
|
||||
|
||||
[JsonIgnore] public string ComposedIconKey { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
using System;
|
||||
|
||||
namespace GeometryTD.Definition
|
||||
{
|
||||
/// <summary>
|
||||
/// 防御塔独立属性快照。
|
||||
/// 注意:这里是塔实例的独立值,不通过组件引用实时计算。
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public sealed class TowerStatsData
|
||||
{
|
||||
public int[] AttackDamage { get; set; }
|
||||
public float DamageRandomRate { get; set; }
|
||||
public float[] RotateSpeed { get; set; }
|
||||
public float[] AttackRange { get; set; }
|
||||
public float[] AttackSpeed { get; set; }
|
||||
public AttackMethodType AttackMethodType { get; set; }
|
||||
public AttackPropertyType AttackPropertyType { get; set; }
|
||||
public TagRuntimeData[] TagRuntimes { get; set; }
|
||||
public TagType[] Tags { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 33934c152fda4ff4827aabfbf6f65856
|
||||
timeCreated: 1773194446
|
||||
@@ -21,15 +21,19 @@ namespace GeometryTD.Definition
|
||||
}
|
||||
|
||||
FireTagState state = runtime.GetOrCreateState<FireTagState>(TagType);
|
||||
float burnDamagePerSecond = Mathf.Max(0f,
|
||||
config.BurnDamagePerSecondPerStack * runtimeData.TotalStack);
|
||||
int infernoStack = TagEffectResolver.GetTagStack(attackPayload?.TagRuntimes, TagType.Inferno);
|
||||
float burnDamagePerSecond = Mathf.Max(
|
||||
0f,
|
||||
config.BurnDamagePerSecondPerStack * runtimeData.TotalStack + GetInfernoBonusDamagePerSecond(infernoStack));
|
||||
|
||||
if (burnDamagePerSecond <= 0f)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
state.RemainingDuration = Mathf.Max(state.RemainingDuration, config.BurnDurationSeconds);
|
||||
state.RemainingDuration = Mathf.Max(
|
||||
state.RemainingDuration,
|
||||
config.BurnDurationSeconds + GetInfernoBonusDuration(infernoStack));
|
||||
state.DamagePerSecond = Mathf.Max(state.DamagePerSecond, burnDamagePerSecond);
|
||||
runtime.Activate(TagType);
|
||||
}
|
||||
@@ -64,5 +68,39 @@ namespace GeometryTD.Definition
|
||||
state.PendingDamage = 0f;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static float GetInfernoBonusDuration(int infernoStack)
|
||||
{
|
||||
if (infernoStack <= 0 ||
|
||||
!TagConfigRegistry.TryGetDefinition(TagType.Inferno, out TagDefinitionData definition))
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
InfernoTagConfig infernoConfig = definition.Config as InfernoTagConfig;
|
||||
if (infernoConfig == null || !infernoConfig.IsImplemented)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
return infernoStack * infernoConfig.BonusBurnDurationSeconds;
|
||||
}
|
||||
|
||||
private static float GetInfernoBonusDamagePerSecond(int infernoStack)
|
||||
{
|
||||
if (infernoStack <= 0 ||
|
||||
!TagConfigRegistry.TryGetDefinition(TagType.Inferno, out TagDefinitionData definition))
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
InfernoTagConfig infernoConfig = definition.Config as InfernoTagConfig;
|
||||
if (infernoConfig == null || !infernoConfig.IsImplemented)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
return infernoStack * infernoConfig.BonusBurnDamagePerSecondPerStack;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,9 +24,12 @@ namespace GeometryTD.Definition
|
||||
}
|
||||
|
||||
IceTagState state = runtime.GetOrCreateState<IceTagState>(TagType);
|
||||
float slowMultiplier = Mathf.Max(config.MinMoveSpeedMultiplier,
|
||||
1f - runtimeData.TotalStack * config.SlowRatioPerStack);
|
||||
state.RemainingDuration = Mathf.Max(state.RemainingDuration, config.SlowDurationSeconds);
|
||||
int absoluteZeroStack = TagEffectResolver.GetTagStack(attackPayload?.TagRuntimes, TagType.AbsoluteZero);
|
||||
float slowRatio = runtimeData.TotalStack * config.SlowRatioPerStack + GetAbsoluteZeroBonusSlowRatio(absoluteZeroStack);
|
||||
float slowMultiplier = Mathf.Max(config.MinMoveSpeedMultiplier, 1f - slowRatio);
|
||||
state.RemainingDuration = Mathf.Max(
|
||||
state.RemainingDuration,
|
||||
config.SlowDurationSeconds + GetAbsoluteZeroBonusDuration(absoluteZeroStack));
|
||||
state.SlowMultiplier = Mathf.Min(state.SlowMultiplier, slowMultiplier);
|
||||
runtime.Activate(TagType);
|
||||
}
|
||||
@@ -46,5 +49,39 @@ namespace GeometryTD.Definition
|
||||
IceTagState state = runtime.GetState<IceTagState>(TagType);
|
||||
return state == null ? 1f : state.SlowMultiplier;
|
||||
}
|
||||
|
||||
private static float GetAbsoluteZeroBonusDuration(int absoluteZeroStack)
|
||||
{
|
||||
if (absoluteZeroStack <= 0 ||
|
||||
!TagConfigRegistry.TryGetDefinition(TagType.AbsoluteZero, out TagDefinitionData definition))
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
AbsoluteZeroTagConfig absoluteZeroConfig = definition.Config as AbsoluteZeroTagConfig;
|
||||
if (absoluteZeroConfig == null || !absoluteZeroConfig.IsImplemented)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
return absoluteZeroStack * absoluteZeroConfig.BonusSlowDurationSeconds;
|
||||
}
|
||||
|
||||
private static float GetAbsoluteZeroBonusSlowRatio(int absoluteZeroStack)
|
||||
{
|
||||
if (absoluteZeroStack <= 0 ||
|
||||
!TagConfigRegistry.TryGetDefinition(TagType.AbsoluteZero, out TagDefinitionData definition))
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
AbsoluteZeroTagConfig absoluteZeroConfig = definition.Config as AbsoluteZeroTagConfig;
|
||||
if (absoluteZeroConfig == null || !absoluteZeroConfig.IsImplemented)
|
||||
{
|
||||
return 0f;
|
||||
}
|
||||
|
||||
return absoluteZeroStack * absoluteZeroConfig.BonusSlowRatioPerStack;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace GeometryTD.Definition
|
||||
{
|
||||
}
|
||||
|
||||
public float BonusSlowDurationSeconds { get; set; } = 0f;
|
||||
public float BonusSlowRatioPerStack { get; set; } = 0f;
|
||||
public float BonusSlowDurationSeconds { get; set; } = 1f;
|
||||
public float BonusSlowRatioPerStack { get; set; } = 0.1f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,5 +11,6 @@ namespace GeometryTD.Definition
|
||||
|
||||
public float BurnDurationSeconds { get; set; } = 3f;
|
||||
public float BurnDamagePerSecondPerStack { get; set; } = 20f;
|
||||
public int MaxEffectiveStack { get; set; } = 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@ namespace GeometryTD.Definition
|
||||
{
|
||||
}
|
||||
|
||||
public float BonusBurnDurationSeconds { get; set; } = 0f;
|
||||
public float BonusBurnDamagePerSecondPerStack { get; set; } = 0f;
|
||||
public float BonusBurnDurationSeconds { get; set; } = 2f;
|
||||
public float BonusBurnDamagePerSecondPerStack { get; set; } = 20f;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,6 @@ namespace GeometryTD.Definition
|
||||
{
|
||||
}
|
||||
|
||||
public int ExtraPierceCount { get; set; } = 0;
|
||||
public int ExtraPierceCount { get; set; } = 2;
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,6 @@ namespace GeometryTD.Definition
|
||||
}
|
||||
|
||||
public bool RequiresSlowedTarget { get; set; } = true;
|
||||
public float DamageBonusPerStack { get; set; } = 0f;
|
||||
public float DamageBonusPerStack { get; set; } = 0.25f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,103 +1,174 @@
|
||||
using System.Collections.Generic;
|
||||
using GeometryTD.DataTable;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace GeometryTD.Definition
|
||||
{
|
||||
public static class TagConfigRegistry
|
||||
{
|
||||
private static readonly Dictionary<TagType, TagDefinitionData> DefinitionsByTag =
|
||||
new Dictionary<TagType, TagDefinitionData>
|
||||
{
|
||||
[TagType.Fire] = new TagDefinitionData
|
||||
{
|
||||
TagType = TagType.Fire,
|
||||
Category = TagCategory.Status,
|
||||
TriggerPhase = TagTriggerPhase.OnAfterHit,
|
||||
Config = new FireTagConfig(true)
|
||||
},
|
||||
[TagType.BurnSpread] = new TagDefinitionData
|
||||
{
|
||||
TagType = TagType.BurnSpread,
|
||||
Category = TagCategory.AttackShape,
|
||||
TriggerPhase = TagTriggerPhase.OnKill,
|
||||
Config = new BurnSpreadTagConfig(false)
|
||||
},
|
||||
[TagType.IgniteBurst] = new TagDefinitionData
|
||||
{
|
||||
TagType = TagType.IgniteBurst,
|
||||
Category = TagCategory.AttackShape,
|
||||
TriggerPhase = TagTriggerPhase.OnKill,
|
||||
Config = new IgniteBurstTagConfig(false)
|
||||
},
|
||||
[TagType.Inferno] = new TagDefinitionData
|
||||
{
|
||||
TagType = TagType.Inferno,
|
||||
Category = TagCategory.Status,
|
||||
TriggerPhase = TagTriggerPhase.OnAfterHit,
|
||||
Config = new InfernoTagConfig(false)
|
||||
},
|
||||
[TagType.Ice] = new TagDefinitionData
|
||||
{
|
||||
TagType = TagType.Ice,
|
||||
Category = TagCategory.Status,
|
||||
TriggerPhase = TagTriggerPhase.OnAfterHit,
|
||||
Config = new IceTagConfig(true)
|
||||
},
|
||||
[TagType.FreezeMask] = new TagDefinitionData
|
||||
{
|
||||
TagType = TagType.FreezeMask,
|
||||
Category = TagCategory.AttackShape,
|
||||
TriggerPhase = TagTriggerPhase.OnAfterHit,
|
||||
Config = new FreezeMaskTagConfig(false)
|
||||
},
|
||||
[TagType.Shatter] = new TagDefinitionData
|
||||
{
|
||||
TagType = TagType.Shatter,
|
||||
Category = TagCategory.NumericModifier,
|
||||
TriggerPhase = TagTriggerPhase.OnBeforeHit,
|
||||
Config = new ShatterTagConfig(false)
|
||||
},
|
||||
[TagType.AbsoluteZero] = new TagDefinitionData
|
||||
{
|
||||
TagType = TagType.AbsoluteZero,
|
||||
Category = TagCategory.Status,
|
||||
TriggerPhase = TagTriggerPhase.OnAfterHit,
|
||||
Config = new AbsoluteZeroTagConfig(false)
|
||||
},
|
||||
[TagType.Pierce] = new TagDefinitionData
|
||||
{
|
||||
TagType = TagType.Pierce,
|
||||
Category = TagCategory.AttackShape,
|
||||
TriggerPhase = TagTriggerPhase.OnHit,
|
||||
Config = new PierceTagConfig(false)
|
||||
},
|
||||
[TagType.Crit] = new TagDefinitionData
|
||||
{
|
||||
TagType = TagType.Crit,
|
||||
Category = TagCategory.NumericModifier,
|
||||
TriggerPhase = TagTriggerPhase.OnBeforeHit,
|
||||
Config = new CritTagConfig(true)
|
||||
},
|
||||
[TagType.Overpenetrate] = new TagDefinitionData
|
||||
{
|
||||
TagType = TagType.Overpenetrate,
|
||||
Category = TagCategory.AttackShape,
|
||||
TriggerPhase = TagTriggerPhase.OnHit,
|
||||
Config = new OverpenetrateTagConfig(false)
|
||||
},
|
||||
[TagType.Execution] = new TagDefinitionData
|
||||
{
|
||||
TagType = TagType.Execution,
|
||||
Category = TagCategory.NumericModifier,
|
||||
TriggerPhase = TagTriggerPhase.OnBeforeHit,
|
||||
Config = new ExecutionTagConfig(true)
|
||||
}
|
||||
};
|
||||
private static readonly Dictionary<TagType, TagDefinitionData> DefinitionsByTag = CreateDefaultDefinitions();
|
||||
|
||||
public static IReadOnlyDictionary<TagType, TagDefinitionData> Definitions => DefinitionsByTag;
|
||||
|
||||
public static void ResetToDefaults()
|
||||
{
|
||||
DefinitionsByTag.Clear();
|
||||
foreach (KeyValuePair<TagType, TagDefinitionData> pair in CreateDefaultDefinitions())
|
||||
{
|
||||
DefinitionsByTag.Add(pair.Key, pair.Value);
|
||||
}
|
||||
}
|
||||
|
||||
public static void LoadFromRows(IEnumerable<DRTagConfig> rows)
|
||||
{
|
||||
ResetToDefaults();
|
||||
foreach (DRTagConfig row in rows)
|
||||
{
|
||||
ApplyRow(row);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool TryGetDefinition(TagType tagType, out TagDefinitionData definition)
|
||||
{
|
||||
return DefinitionsByTag.TryGetValue(tagType, out definition);
|
||||
}
|
||||
|
||||
private static Dictionary<TagType, TagDefinitionData> CreateDefaultDefinitions()
|
||||
{
|
||||
return new Dictionary<TagType, TagDefinitionData>
|
||||
{
|
||||
[TagType.Fire] = CreateDefinition(TagType.Fire, TagCategory.Status, TagTriggerPhase.OnAfterHit, new FireTagConfig(true)),
|
||||
[TagType.BurnSpread] = CreateDefinition(TagType.BurnSpread, TagCategory.AttackShape, TagTriggerPhase.OnKill, new BurnSpreadTagConfig(false)),
|
||||
[TagType.IgniteBurst] = CreateDefinition(TagType.IgniteBurst, TagCategory.AttackShape, TagTriggerPhase.OnKill, new IgniteBurstTagConfig(false)),
|
||||
[TagType.Inferno] = CreateDefinition(TagType.Inferno, TagCategory.Status, TagTriggerPhase.OnAfterHit, new InfernoTagConfig(true)),
|
||||
[TagType.Ice] = CreateDefinition(TagType.Ice, TagCategory.Status, TagTriggerPhase.OnAfterHit, new IceTagConfig(true)),
|
||||
[TagType.FreezeMask] = CreateDefinition(TagType.FreezeMask, TagCategory.AttackShape, TagTriggerPhase.OnAfterHit, new FreezeMaskTagConfig(false)),
|
||||
[TagType.Shatter] = CreateDefinition(TagType.Shatter, TagCategory.NumericModifier, TagTriggerPhase.OnBeforeHit, new ShatterTagConfig(true)),
|
||||
[TagType.AbsoluteZero] = CreateDefinition(TagType.AbsoluteZero, TagCategory.Status, TagTriggerPhase.OnAfterHit, new AbsoluteZeroTagConfig(true)),
|
||||
[TagType.Pierce] = CreateDefinition(TagType.Pierce, TagCategory.AttackShape, TagTriggerPhase.OnHit, new PierceTagConfig(false)),
|
||||
[TagType.Crit] = CreateDefinition(TagType.Crit, TagCategory.NumericModifier, TagTriggerPhase.OnBeforeHit, new CritTagConfig(true)),
|
||||
[TagType.Overpenetrate] = CreateDefinition(TagType.Overpenetrate, TagCategory.AttackShape, TagTriggerPhase.OnHit, new OverpenetrateTagConfig(false)),
|
||||
[TagType.Execution] = CreateDefinition(TagType.Execution, TagCategory.NumericModifier, TagTriggerPhase.OnBeforeHit, new ExecutionTagConfig(true))
|
||||
};
|
||||
}
|
||||
|
||||
private static TagDefinitionData CreateDefinition(
|
||||
TagType tagType,
|
||||
TagCategory category,
|
||||
TagTriggerPhase triggerPhase,
|
||||
TagConfigBase config)
|
||||
{
|
||||
return new TagDefinitionData
|
||||
{
|
||||
TagType = tagType,
|
||||
Category = category,
|
||||
TriggerPhase = triggerPhase,
|
||||
Description = string.Empty,
|
||||
Config = config
|
||||
};
|
||||
}
|
||||
|
||||
private static void ApplyRow(DRTagConfig row)
|
||||
{
|
||||
Debug.Assert(row != null);
|
||||
Debug.Assert(DefinitionsByTag.TryGetValue(row.TagType, out TagDefinitionData definition));
|
||||
|
||||
definition.TriggerPhase = row.TriggerPhase;
|
||||
definition.Description = row.Description ?? string.Empty;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(row.ParamJson))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
JObject param = JObject.Parse(row.ParamJson);
|
||||
switch (row.TagType)
|
||||
{
|
||||
case TagType.Fire:
|
||||
ApplyFireConfig((FireTagConfig)definition.Config, param);
|
||||
break;
|
||||
case TagType.Inferno:
|
||||
ApplyInfernoConfig((InfernoTagConfig)definition.Config, param);
|
||||
break;
|
||||
case TagType.Ice:
|
||||
ApplyIceConfig((IceTagConfig)definition.Config, param);
|
||||
break;
|
||||
case TagType.Shatter:
|
||||
ApplyShatterConfig((ShatterTagConfig)definition.Config, param);
|
||||
break;
|
||||
case TagType.AbsoluteZero:
|
||||
ApplyAbsoluteZeroConfig((AbsoluteZeroTagConfig)definition.Config, param);
|
||||
break;
|
||||
case TagType.Crit:
|
||||
ApplyCritConfig((CritTagConfig)definition.Config, param);
|
||||
break;
|
||||
case TagType.Execution:
|
||||
ApplyExecutionConfig((ExecutionTagConfig)definition.Config, param);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void ApplyFireConfig(FireTagConfig config, JObject param)
|
||||
{
|
||||
config.BurnDurationSeconds = ReadFloat(param, nameof(FireTagConfig.BurnDurationSeconds), config.BurnDurationSeconds);
|
||||
config.BurnDamagePerSecondPerStack = ReadFloat(param, nameof(FireTagConfig.BurnDamagePerSecondPerStack), config.BurnDamagePerSecondPerStack);
|
||||
config.MaxEffectiveStack = ReadInt(param, nameof(FireTagConfig.MaxEffectiveStack), config.MaxEffectiveStack);
|
||||
}
|
||||
|
||||
private static void ApplyInfernoConfig(InfernoTagConfig config, JObject param)
|
||||
{
|
||||
config.BonusBurnDurationSeconds = ReadFloat(param, nameof(InfernoTagConfig.BonusBurnDurationSeconds), config.BonusBurnDurationSeconds);
|
||||
config.BonusBurnDamagePerSecondPerStack = ReadFloat(param, nameof(InfernoTagConfig.BonusBurnDamagePerSecondPerStack), config.BonusBurnDamagePerSecondPerStack);
|
||||
}
|
||||
|
||||
private static void ApplyIceConfig(IceTagConfig config, JObject param)
|
||||
{
|
||||
config.SlowDurationSeconds = ReadFloat(param, nameof(IceTagConfig.SlowDurationSeconds), config.SlowDurationSeconds);
|
||||
config.SlowRatioPerStack = ReadFloat(param, nameof(IceTagConfig.SlowRatioPerStack), config.SlowRatioPerStack);
|
||||
config.MinMoveSpeedMultiplier = ReadFloat(param, nameof(IceTagConfig.MinMoveSpeedMultiplier), config.MinMoveSpeedMultiplier);
|
||||
}
|
||||
|
||||
private static void ApplyShatterConfig(ShatterTagConfig config, JObject param)
|
||||
{
|
||||
config.RequiresSlowedTarget = ReadBool(param, nameof(ShatterTagConfig.RequiresSlowedTarget), config.RequiresSlowedTarget);
|
||||
config.DamageBonusPerStack = ReadFloat(param, nameof(ShatterTagConfig.DamageBonusPerStack), config.DamageBonusPerStack);
|
||||
}
|
||||
|
||||
private static void ApplyAbsoluteZeroConfig(AbsoluteZeroTagConfig config, JObject param)
|
||||
{
|
||||
config.BonusSlowDurationSeconds = ReadFloat(param, nameof(AbsoluteZeroTagConfig.BonusSlowDurationSeconds), config.BonusSlowDurationSeconds);
|
||||
config.BonusSlowRatioPerStack = ReadFloat(param, nameof(AbsoluteZeroTagConfig.BonusSlowRatioPerStack), config.BonusSlowRatioPerStack);
|
||||
}
|
||||
|
||||
private static void ApplyCritConfig(CritTagConfig config, JObject param)
|
||||
{
|
||||
config.CritChancePerStack = ReadFloat(param, nameof(CritTagConfig.CritChancePerStack), config.CritChancePerStack);
|
||||
config.CritDamageMultiplier = ReadFloat(param, nameof(CritTagConfig.CritDamageMultiplier), config.CritDamageMultiplier);
|
||||
}
|
||||
|
||||
private static void ApplyExecutionConfig(ExecutionTagConfig config, JObject param)
|
||||
{
|
||||
config.TargetHealthThreshold = ReadFloat(param, nameof(ExecutionTagConfig.TargetHealthThreshold), config.TargetHealthThreshold);
|
||||
config.DamageBonusPerStack = ReadFloat(param, nameof(ExecutionTagConfig.DamageBonusPerStack), config.DamageBonusPerStack);
|
||||
}
|
||||
|
||||
private static float ReadFloat(JObject param, string key, float defaultValue)
|
||||
{
|
||||
JToken token = param[key];
|
||||
return token == null ? defaultValue : token.Value<float>();
|
||||
}
|
||||
|
||||
private static int ReadInt(JObject param, string key, int defaultValue)
|
||||
{
|
||||
JToken token = param[key];
|
||||
return token == null ? defaultValue : token.Value<int>();
|
||||
}
|
||||
|
||||
private static bool ReadBool(JObject param, string key, bool defaultValue)
|
||||
{
|
||||
JToken token = param[key];
|
||||
return token == null ? defaultValue : token.Value<bool>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ namespace GeometryTD.Definition
|
||||
public TagType TagType { get; set; }
|
||||
public TagCategory Category { get; set; }
|
||||
public TagTriggerPhase TriggerPhase { get; set; }
|
||||
public string Description { get; set; }
|
||||
public TagConfigBase Config { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,10 +98,18 @@ namespace GeometryTD.Definition
|
||||
|
||||
private static void ApplyShatter(HitContext hitContext, int stack, bool targetHasSlowStatus, ShatterTagConfig config)
|
||||
{
|
||||
_ = hitContext;
|
||||
_ = stack;
|
||||
_ = targetHasSlowStatus;
|
||||
_ = config;
|
||||
if (config == null || !config.IsImplemented || stack <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.RequiresSlowedTarget && !targetHasSlowStatus)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
float multiplier = 1f + stack * config.DamageBonusPerStack;
|
||||
hitContext.FinalDamage = Mathf.Max(0, Mathf.RoundToInt(hitContext.FinalDamage * multiplier));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,17 +10,15 @@ namespace GeometryTD.Definition
|
||||
Dictionary<TagType, int> stackByTag = new Dictionary<TagType, int>();
|
||||
if (componentTags != null)
|
||||
{
|
||||
for (int i = 0; i < componentTags.Length; i++)
|
||||
foreach (var tags in componentTags)
|
||||
{
|
||||
TagType[] tags = componentTags[i];
|
||||
if (tags == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (int j = 0; j < tags.Length; j++)
|
||||
foreach (var tagType in tags)
|
||||
{
|
||||
TagType tagType = tags[j];
|
||||
if (tagType == TagType.None || !Enum.IsDefined(typeof(TagType), tagType))
|
||||
{
|
||||
continue;
|
||||
@@ -44,7 +42,7 @@ namespace GeometryTD.Definition
|
||||
}
|
||||
|
||||
List<TagRuntimeData> runtimes = new List<TagRuntimeData>(stackByTag.Count);
|
||||
foreach (KeyValuePair<TagType, int> pair in stackByTag)
|
||||
foreach (var pair in stackByTag)
|
||||
{
|
||||
runtimes.Add(new TagRuntimeData
|
||||
{
|
||||
@@ -65,9 +63,8 @@ namespace GeometryTD.Definition
|
||||
}
|
||||
|
||||
HashSet<TagType> uniqueTags = new HashSet<TagType>();
|
||||
for (int i = 0; i < tags.Count; i++)
|
||||
foreach (var tagType in tags)
|
||||
{
|
||||
TagType tagType = tags[i];
|
||||
if (tagType == TagType.None || !Enum.IsDefined(typeof(TagType), tagType))
|
||||
{
|
||||
continue;
|
||||
@@ -106,9 +103,8 @@ namespace GeometryTD.Definition
|
||||
}
|
||||
|
||||
List<TagType> tags = new List<TagType>(tagRuntimes.Count);
|
||||
for (int i = 0; i < tagRuntimes.Count; i++)
|
||||
foreach (var runtime in tagRuntimes)
|
||||
{
|
||||
TagRuntimeData runtime = tagRuntimes[i];
|
||||
if (runtime == null || runtime.TagType == TagType.None || !Enum.IsDefined(typeof(TagType), runtime.TagType))
|
||||
{
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user