Skip to content

Commit

Permalink
Aura refactor (#51)
Browse files Browse the repository at this point in the history
* feat: initial aura refactor

* feat: aura ids

* feat: pool aura test

* feat: modifier generator aura id, improved aura handling in modifier controller

* feat: readme aura update
  • Loading branch information
Chillu1 authored Aug 17, 2024
1 parent d3cb4a6 commit 1c4a332
Show file tree
Hide file tree
Showing 12 changed files with 154 additions and 69 deletions.
94 changes: 72 additions & 22 deletions ModiBuff/ModiBuff.Tests/AuraTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,37 @@ public sealed class AuraTests : ModifierTests
private readonly RecipeAddFunc[] _defaultAuraRecipeAddFuncs =
{
add => add("InitAddDamageBuff")
.OneTimeInit()
.Effect(new AddDamageEffect(5, EffectState.IsRevertible), EffectOn.Init)
.Effect(new AddDamageEffect(5, EffectState.IsRevertibleAndTogglable), EffectOn.Init)
//TODO standardized aura time & aura effects should always be refreshable
.Remove(1.05f).Refresh(),
add => add("InitAddDamageBuff_Interval")
.Aura()
.Interval(1)
.Effect(new ApplierEffect("InitAddDamageBuff"), EffectOn.Interval)
.Effect(new ApplierEffect("InitAddDamageBuff"), EffectOn.Interval),
add => add("InitAddDamageBuff_2")
.Effect(new AddDamageEffect(5, EffectState.IsRevertibleAndTogglable), EffectOn.Init)
//TODO standardized aura time & aura effects should always be refreshable
.Remove(1.05f).Refresh(),
add => add("InitAddDamageBuff_Interval_2")
.Aura(id: 1)
.Interval(1)
.Effect(new ApplierEffect("InitAddDamageBuff_2"), EffectOn.Interval)
};

[Test]
public void AuraInterval()
private void SetupAuraTest()
{
for (int i = 0; i < _defaultAuraRecipeAddFuncs.Length; i++)
AddRecipe(_defaultAuraRecipeAddFuncs[i]);
Setup();
}

Unit.AddCloseTargets(Ally);
Unit.AddAuraModifier(IdManager.GetId("InitAddDamageBuff_Interval"));
[Test]
public void AuraInterval()
{
SetupAuraTest();

Unit.AddAuraTargets(0, Ally);
Unit.AddModifierSelf("InitAddDamageBuff_Interval");
Assert.AreEqual(UnitDamage, Unit.Damage);

Unit.Update(1f);
Expand All @@ -41,12 +52,10 @@ public void AuraInterval()
[Test]
public void Aura_AddDamage_Timeout()
{
for (int i = 0; i < _defaultAuraRecipeAddFuncs.Length; i++)
AddRecipe(_defaultAuraRecipeAddFuncs[i]);
Setup();
SetupAuraTest();

Unit.AddCloseTargets(Ally);
Unit.AddAuraModifier(IdManager.GetId("InitAddDamageBuff_Interval"));
Unit.AddAuraTargets(0, Ally);
Unit.AddModifierSelf("InitAddDamageBuff_Interval");

Unit.Update(1f);

Expand All @@ -61,12 +70,10 @@ public void Aura_AddDamage_Timeout()
[Test]
public void AuraAddedDamageRefresh()
{
for (int i = 0; i < _defaultAuraRecipeAddFuncs.Length; i++)
AddRecipe(_defaultAuraRecipeAddFuncs[i]);
Setup();
SetupAuraTest();

Unit.AddCloseTargets(Ally);
Unit.AddAuraModifier(IdManager.GetId("InitAddDamageBuff_Interval"));
Unit.AddAuraTargets(0, Ally);
Unit.AddModifierSelf("InitAddDamageBuff_Interval");

Unit.Update(1f);

Expand All @@ -82,12 +89,10 @@ public void AuraAddedDamageRefresh()
[Test]
public void Aura_AddDamage_Timeout_AddAgain()
{
for (int i = 0; i < _defaultAuraRecipeAddFuncs.Length; i++)
AddRecipe(_defaultAuraRecipeAddFuncs[i]);
Setup();
SetupAuraTest();

Unit.AddCloseTargets(Ally);
Unit.AddAuraModifier(IdManager.GetId("InitAddDamageBuff_Interval"));
Unit.AddAuraTargets(0, Ally);
Unit.AddModifierSelf("InitAddDamageBuff_Interval");

Unit.Update(1f);

Expand All @@ -101,5 +106,50 @@ public void Aura_AddDamage_Timeout_AddAgain()

Assert.AreEqual(AllyDamage + 5, Ally.Damage);
}

[Test]
public void Two_Auras_Two_Ids()
{
SetupAuraTest();

Unit.AddAuraTargets(0, Ally);
Unit.AddAuraTargets(0, Enemy);
Unit.AddAuraTargets(1, Enemy);
Unit.AddModifierSelf("InitAddDamageBuff_Interval");
Unit.AddModifierSelf("InitAddDamageBuff_Interval_2");
Assert.AreEqual(UnitDamage, Unit.Damage);

Unit.Update(1f);

Assert.AreEqual(UnitDamage + 5 + 5, Unit.Damage);
Assert.AreEqual(AllyDamage + 5, Ally.Damage);
Assert.AreEqual(EnemyDamage + 5 + 5, Enemy.Damage);
}

[Test]
public void Aura_Pool_ClearTargets()
{
SetupAuraTest();

int id = IdManager.GetId("InitAddDamageBuff_Interval");
Pool.Clear();
Pool.Allocate(id, 1);

Unit.AddAuraTargets(0, Ally);
Unit.AddModifierSelf("InitAddDamageBuff_Interval");
Unit.Update(1f);

Assert.AreEqual(AllyDamage + 5, Ally.Damage);

Unit.ModifierController.Remove(new ModifierReference(id, -1));
Enemy.AddModifierSelf("InitAddDamageBuff_Interval");
Enemy.Update(1f);
Unit.Update(1.05f);
Ally.Update(1.05f);

Assert.AreEqual(EnemyDamage + 5, Enemy.Damage);
Assert.AreEqual(AllyDamage, Ally.Damage);
Assert.AreEqual(UnitDamage, Unit.Damage);
}
}
}
33 changes: 10 additions & 23 deletions ModiBuff/ModiBuff.Units/Unit/Unit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ public partial class Unit : IUpdatable, IModifierOwner, IModifierApplierOwner, I
ICallbackUnitRegistrable<CallbackUnitType>, IPosition<Vector2>, IMovable<Vector2>, IUnitEntity,
IStatusEffectModifierOwnerLegalTarget<LegalAction, StatusEffectType>, IPoisonable,
ISingleInstanceStatusEffectOwner<LegalAction, StatusEffectType>, ICallbackRegistrable<CallbackType>,
IAllNonGeneric, ICaster, IStateReset, IIdOwner, IDurationLessStatusEffectOwner<LegalAction, StatusEffectType>
IAllNonGeneric, ICaster, IStateReset, IIdOwner, IDurationLessStatusEffectOwner<LegalAction, StatusEffectType>,
IAuraOwner
{
public int Id { get; }
public UnitTag UnitTag { get; private set; }
Expand Down Expand Up @@ -54,8 +55,7 @@ public partial class Unit : IUpdatable, IModifierOwner, IModifierApplierOwner, I
IDurationLessStatusEffectOwner<LegalAction, StatusEffectType>.StatusEffectController =>
_durationLessStatusEffectController;

private readonly List<IUnit> _targetsInRange;
private readonly List<Modifier> _auraModifiers;
private readonly List<IUnit>[] _auraTargets;

private readonly MultiInstanceStatusEffectController _statusEffectController;
private readonly StatusEffectController _singleInstanceStatusEffectController;
Expand Down Expand Up @@ -103,9 +103,9 @@ public Unit(float health = 500, float damage = 10, float healValue = 5, float ma

_updateTimerCallbacks = new List<UpdateTimerEvent>();

_targetsInRange = new List<IUnit>();
_targetsInRange.Add(this);
_auraModifiers = new List<Modifier>();
_auraTargets = new List<IUnit>[2];
for (int i = 0; i < _auraTargets.Length; i++)
_auraTargets[i] = new List<IUnit> { this };

ModifierController = ModifierControllerPool.Instance.Rent();
ModifierApplierController = ModifierControllerPool.Instance.RentApplier();
Expand Down Expand Up @@ -136,8 +136,6 @@ public void Update(float deltaTime)
_singleInstanceStatusEffectController.Update(deltaTime);
ModifierController.Update(deltaTime);
ModifierApplierController.Update(deltaTime);
for (int i = 0; i < _auraModifiers.Count; i++)
_auraModifiers[i].Update(deltaTime);

_callbackTimer += deltaTime;
if (_callbackTimer >= CallbackTimerCooldown)
Expand Down Expand Up @@ -453,17 +451,8 @@ public void StrongDispel(IUnit source)

//---Aura---

public void AddCloseTargets(params Unit[] targets)
{
_targetsInRange.AddRange(targets);
}

public void AddAuraModifier(int id)
{
var modifier = ModifierPool.Instance.Rent(id);
modifier.UpdateTargets(_targetsInRange, this);
_auraModifiers.Add(modifier);
}
public void AddAuraTargets(int id, params Unit[] targets) => _auraTargets[id].AddRange(targets);
public IList<IUnit> GetAuraTargets(int auraId) => _auraTargets[auraId];

public void ResetState()
{
Expand All @@ -474,10 +463,8 @@ public void ResetState()
_dispelEvents, _strongDispelEvents, _healthChangedEvents, _damageChangedEvents,
_statusEffectAddedEvents, _statusEffectRemovedEvents, _onCastEvents, _updateTimerCallbacks);

_targetsInRange.Clear();
for (int i = 0; i < _auraModifiers.Count; i++)
ModifierPool.Instance.Return(_auraModifiers[i]);
_auraModifiers.Clear();
for (int i = 0; i < _auraTargets.Length; i++)
_auraTargets[i].Clear();
_callbackTimer = 0;
_statusEffectController.ResetState();
_singleInstanceStatusEffectController.ResetState();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,25 @@ namespace ModiBuff.Core
public sealed class MultiTargetComponent : ITargetComponent, ISavable<MultiTargetComponent.SaveData>
{
public IUnit Source { get; set; }
public List<IUnit> Targets { get; }
public IList<IUnit> Targets { get; private set; }

public MultiTargetComponent()
{
Targets = new List<IUnit>(Config.MultiTargetComponentInitialCapacity);
}

public MultiTargetComponent(List<IUnit> targets, IUnit source)
public MultiTargetComponent(IList<IUnit> targets, IUnit source)
{
Source = source;
Targets = targets;
}

public void UpdateTargets(List<IUnit> targets)
{
Targets.Clear();
Targets.AddRange(targets);
}
public void UpdateTargets(IList<IUnit> targets) => Targets = targets;

public void ResetState()
{
Source = null;
Targets.Clear();
Targets = null;
}

public object SaveState() =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ public sealed class ManualModifierGenerator : IModifierGenerator
public string DisplayName { get; }
public string Description { get; }
public TagType Tag { get; }
public int AuraId { get; }
private readonly ModifierGeneratorFunc _createFunc;

private int _genId;

public ManualModifierGenerator(int id, string name, string displayName, string description,
in ModifierGeneratorFunc createFunc, TagType tag)
in ModifierGeneratorFunc createFunc, TagType tag, int auraId)
{
Id = id;
Name = name;
Expand All @@ -23,6 +24,8 @@ public ManualModifierGenerator(int id, string name, string displayName, string d
//Updates tags based on modifier state
//Generates a dummy modifier, to check for state
tag.UpdateTagBasedOnModifierComponents(createFunc(Id, _genId, Name, tag));
if (auraId != -1)
tag |= TagType.IsAura;
Tag = tag;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public interface IModifierRecipe
IModifierGenerator CreateModifierGenerator();
ModifierInfo CreateModifierInfo();
TagType GetTag();
int GetAuraId();

//TODO Move/refactor
ModifierRecipe.SaveData SaveState();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public sealed partial class ModifierRecipe : IModifierRecipe, IEquatable<Modifie

private bool _isInstanceStackable;
private bool _isAura;
private int _auraId;
private TagType _tag;

private bool _oneTimeInit;
Expand Down Expand Up @@ -93,9 +94,10 @@ public ModifierRecipe InstanceStackable()
/// <summary>
/// Determines if the modifier should use <see cref="SingleTargetComponent"/> or <see cref="MultiTargetComponent"/>.
/// </summary>
public ModifierRecipe Aura()
public ModifierRecipe Aura(int id = 0)
{
_isAura = true;
_auraId = id;
_saveInstructions.Add(new SaveInstruction.Aura());
return this;
}
Expand Down Expand Up @@ -556,6 +558,8 @@ public IModifierGenerator CreateModifierGenerator()
_tag |= TagType.IsRefresh;
if (_isInstanceStackable)
_tag |= TagType.IsInstanceStackable;
if (_isAura)
_tag |= TagType.IsAura;

_dispelRegisterWrapper?.GetEffectAs<DispelRegisterEffect>().UpdateDispelType(dispel);

Expand All @@ -575,6 +579,8 @@ public ModifierInfo CreateModifierInfo()

public TagType GetTag() => _tag;

public int GetAuraId() => _auraId;

private ModifierRecipe DurationInternal(float duration)
{
_duration = duration;
Expand All @@ -585,8 +591,8 @@ private ModifierRecipe DurationInternal(float duration)
private static void ValidateTag(TagType tag)
{
if (tag.IsInternalRecipeTag())
Logger.LogWarning("[ModiBuff] Setting internal tags directly is not recommended for recipes, " +
"they're automatically set based on the recipe settings");
Logger.LogWarning($"[ModiBuff] Setting internal tags like {tag} directly is not recommended for " +
"recipes, they're automatically set based on the recipe settings");
}

private static void ValidateModifierAction(ModifierAction modifierAction, EffectOn effectOn)
Expand Down
12 changes: 10 additions & 2 deletions ModiBuff/ModiBuff/Core/Modifier/Creation/Recipe/ModifierRecipes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public class ModifierRecipes : IModifierRecipes

private ModifierInfo[] _modifierInfos;
private TagType[] _tags;
private int[] _auraIds;

public ModifierRecipes(ModifierIdManager idManager, EffectTypeIdManager effectTypeIdManager)
{
Expand Down Expand Up @@ -57,19 +58,25 @@ public void CreateGenerators()

_modifierInfos = new ModifierInfo[_recipes.Count + _manualGenerators.Count];
_tags = new TagType[_recipes.Count + _manualGenerators.Count];
_auraIds = new int[_recipes.Count + _manualGenerators.Count];
_auraIds.AsSpan().Fill(-1);
foreach (var generator in _manualGenerators.Values)
{
_modifierGenerators.Add(generator.Name, generator);
_modifierInfos[generator.Id] = new ModifierInfo(generator.Id, generator.Name, generator.DisplayName,
generator.Description);
_tags[generator.Id] = generator.Tag;
if (generator.Tag.HasFlag(TagType.IsAura))
_auraIds[generator.Id] = generator.AuraId;
}

foreach (var recipe in _recipes.Values)
{
_modifierGenerators.Add(recipe.Name, recipe.CreateModifierGenerator());
_modifierInfos[recipe.Id] = recipe.CreateModifierInfo();
_tags[recipe.Id] = recipe.GetTag();
if (recipe.GetTag().HasFlag(TagType.IsAura))
_auraIds[recipe.Id] = recipe.GetAuraId();
}

GeneratorCount = _modifierGenerators.Count;
Expand All @@ -90,6 +97,7 @@ public ModifierInfo GetModifierInfo(int id)
}

public static ref readonly TagType GetTag(int id) => ref _instance._tags[id];
public static int GetAuraId(int id) => _instance._auraIds[id];

public IModifierGenerator GetGenerator(string name) => _modifierGenerators[name];

Expand Down Expand Up @@ -127,7 +135,7 @@ public ModifierRecipe Add(string name, string displayName = "", string descripti
}

public void Add(string name, string displayName, string description,
in ModifierGeneratorFunc createFunc, TagType tag = TagType.Default)
in ModifierGeneratorFunc createFunc, TagType tag = TagType.Default, int auraId = -1)
{
if (_recipes.ContainsKey(name))
{
Expand Down Expand Up @@ -160,7 +168,7 @@ public void Add(string name, string displayName, string description,
id = _idManager.GetFreeId(name);

var modifierGenerator = new ManualModifierGenerator(id, name, displayName, description,
in createFunc, tag);
in createFunc, tag, auraId);
_manualGenerators.Add(name, modifierGenerator);
}

Expand Down
Loading

0 comments on commit 1c4a332

Please sign in to comment.