Skip to content

Commit 973dfd3

Browse files
author
serg.morozov
committed
First commit
1 parent 2ad7a96 commit 973dfd3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1916
-0
lines changed

.gitignore

Lines changed: 403 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
using System;
2+
3+
namespace Nuclear.AbilitySystem
4+
{
5+
public enum AbilityActionTarget
6+
{
7+
FromSourceToTarget,
8+
FromTargetToSource,
9+
FromTargetToTarget,
10+
FromSourceToSource
11+
}
12+
13+
public static class AbilityActionTargetExtensions
14+
{
15+
public static void UpdateAbilityActionTarget(AbilityActionTarget skillActionTarget,
16+
IUnitId? source, IUnitId? target,
17+
out IUnitId? effectSource, out IUnitId? effectTarget)
18+
{
19+
switch (skillActionTarget)
20+
{
21+
case AbilityActionTarget.FromSourceToTarget:
22+
effectTarget = target;
23+
effectSource = source;
24+
return;
25+
case AbilityActionTarget.FromTargetToSource:
26+
effectTarget = source;
27+
effectSource = target;
28+
return;
29+
case AbilityActionTarget.FromTargetToTarget:
30+
effectTarget = target;
31+
effectSource = target;
32+
return;
33+
case AbilityActionTarget.FromSourceToSource:
34+
effectTarget = source;
35+
effectSource = source;
36+
return;
37+
default:
38+
throw new ArgumentOutOfRangeException();
39+
}
40+
}
41+
}
42+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace Nuclear.AbilitySystem
5+
{
6+
public sealed class AbilityContextHolder : IAbilityContextHolder
7+
{
8+
private readonly ICombatEventBus _combatEventsContext;
9+
private readonly Dictionary<Type, IAbilityContext> _contexts = new();
10+
11+
public AbilityContextHolder(ICombatEventBus combatEventsContext)
12+
{
13+
_combatEventsContext = combatEventsContext;
14+
_contexts.Add(typeof(ITimeAbilityContext), new TimeAbilityContext(0));
15+
_contexts.Add(typeof(IDistanceBetweenUnitsAbilityContext), new DistanceBetweenUnitsAbilityContext(_combatEventsContext));
16+
}
17+
18+
private AbilityContextHolder(AbilityContextHolder abilityContextHolder)
19+
{
20+
_combatEventsContext = abilityContextHolder._combatEventsContext;
21+
foreach (var (type, context) in abilityContextHolder._contexts)
22+
{
23+
_contexts.Add(type, context.DeepClone());
24+
}
25+
}
26+
public T GetContext<T>() where T : IAbilityContext
27+
{
28+
return (T)_contexts[typeof(T)];
29+
}
30+
31+
public IAbilityContextHolder DeepClone()
32+
{
33+
return new AbilityContextHolder(this);
34+
}
35+
}
36+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
using System;
2+
3+
namespace Nuclear.AbilitySystem
4+
{
5+
public sealed class CooldownAbilityCheck : ICooldownAbilityCheck
6+
{
7+
private readonly int _cooldown;
8+
private int _lastCastTime;
9+
10+
public CooldownAbilityCheck(int cooldown, int? startValue = null)
11+
{
12+
_cooldown = cooldown;
13+
_lastCastTime = -startValue ?? -cooldown;
14+
}
15+
16+
public bool CanExecute(IUnitId source, IUnitId? target, IAbilityContextHolder context)
17+
{
18+
var timeContext = context.GetContext<ITimeAbilityContext>();
19+
return GetCooldownTimer(timeContext) == 0;
20+
}
21+
22+
public void Execute(IUnitId source, IUnitId? target, IAbilityContextHolder context)
23+
{
24+
var timeContext = context.GetContext<ITimeAbilityContext>();
25+
_lastCastTime = timeContext.Time;
26+
}
27+
28+
public int GetCooldownTimer(ITimeAbilityContext timeContext)
29+
{
30+
return Math.Max(0, _lastCastTime + _cooldown + 1 - timeContext.Time);
31+
}
32+
33+
public IAbilityCheck DeepClone()
34+
{
35+
var result = new CooldownAbilityCheck(_cooldown);
36+
result._lastCastTime = _lastCastTime;
37+
return result;
38+
}
39+
}
40+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace Nuclear.AbilitySystem
2+
{
3+
public interface ICooldownAbilityCheck : IAbilityCheck
4+
{
5+
int GetCooldownTimer(ITimeAbilityContext context);
6+
}
7+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
namespace Nuclear.AbilitySystem
2+
{
3+
public interface ITimeAbilityContext : IAbilityContext
4+
{
5+
int Time { get; }
6+
void NextTurn();
7+
}
8+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
namespace Nuclear.AbilitySystem
2+
{
3+
public sealed class TimeAbilityContext : ITimeAbilityContext
4+
{
5+
public TimeAbilityContext(int time)
6+
{
7+
Time = time;
8+
}
9+
10+
public int Time { get; private set; }
11+
public void NextTurn()
12+
{
13+
Time++;
14+
}
15+
16+
public IAbilityContext DeepClone()
17+
{
18+
return new TimeAbilityContext(Time);
19+
}
20+
}
21+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
using System.Collections.Generic;
2+
3+
namespace Nuclear.AbilitySystem
4+
{
5+
public sealed class Bully : IStatusEffect
6+
{
7+
private readonly IUnitId _unitId;
8+
private ICombatEventBus? _combatEventBus;
9+
10+
public Bully(IUnitId unitId)
11+
{
12+
_unitId = unitId;
13+
}
14+
15+
public void Subscribe(ICombatEventBus combatEventBus)
16+
{
17+
_combatEventBus = combatEventBus;
18+
_combatEventBus.Subscribe<AfterDamageEvent, DamageEventResult>(OnAfterDamage);
19+
}
20+
21+
public void UnSubscribe()
22+
{
23+
if (_combatEventBus == null)
24+
{
25+
return;
26+
}
27+
_combatEventBus.Unsubscribe<AfterDamageEvent, DamageEventResult>(OnAfterDamage);
28+
_combatEventBus = null;
29+
}
30+
31+
public IStatusEffect DeepClone()
32+
{
33+
return new Bully(_unitId);
34+
}
35+
36+
private DamageEventResult? OnAfterDamage(AfterDamageEvent @event, DamageEventResult? previousResult)
37+
{
38+
if (previousResult is {ContinueExecution: false})
39+
{
40+
return previousResult;
41+
}
42+
if (_combatEventBus == null)
43+
{
44+
throw new();
45+
}
46+
47+
if (EqualityComparer<IUnitId>.Default.Equals(_unitId, @event.Source.Id) ||
48+
EqualityComparer<IUnitId>.Default.Equals(_unitId, @event.Target.Id))
49+
{
50+
return previousResult ?? new (true);
51+
}
52+
53+
var unit = _combatEventBus.GetUnit(_unitId);
54+
55+
unit.GetCombatFeature<IDamageable>().DealDamage(@event.Target, 1);
56+
return new(false);
57+
}
58+
}
59+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using System.Linq;
2+
3+
namespace Nuclear.AbilitySystem
4+
{
5+
public static class BullyExtensions
6+
{
7+
public static bool IsBully(this IUnit unit)
8+
{
9+
return unit.GetCombatFeature<IStatusEffectsHolder>().StatusEffects.Any(s => s is Bully);
10+
}
11+
12+
public static void AddBullyStatusEffect(this IUnit unit)
13+
{
14+
if (!unit.IsBully())
15+
{
16+
unit.GetCombatFeature<IStatusEffectsHolder>().AddStatusEffect(
17+
new Bully(unit.Id));
18+
}
19+
}
20+
}
21+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
namespace Nuclear.AbilitySystem
2+
{
3+
public record AttackCombatCommand(IUnitId AttackerId, IUnitId TargetId, int Damage, int Time) : ICombatCommand;
4+
}

0 commit comments

Comments
 (0)