Last active
June 2, 2021 02:52
-
-
Save CoffeeVampir3/59319b7e09f9047645e2f18507dd5ca0 to your computer and use it in GitHub Desktop.
Overcomplicated Command Thingy
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class EffectsSystem | |
{ | |
private static readonly Dictionary<Type, List<IEffectRule>> allRules = new(); | |
public static void RegisterRule<T>(this IEffectRule<T> rule, Type ruleType) | |
where T : IEffect | |
{ | |
if(!allRules.TryGetValue(ruleType, out var specificRules)) | |
{ | |
specificRules = new List<IEffectRule>(); | |
allRules.Add(ruleType, specificRules); | |
} | |
specificRules.Add(rule); | |
Debug.Log("Command: " + ruleType + " was registered by " + rule); | |
} | |
public static void UnregisterRule<T>(this IEffectRule<T> rule, Type ruleType) | |
where T : IEffect | |
{ | |
if(!allRules.TryGetValue(ruleType, out var rules)) | |
return; | |
if(rules.Contains(rule)) | |
rules.Remove(rule); | |
Debug.Log("Command: " + ruleType + " was unregistered by " + rule); | |
} | |
public static bool SystemCheck(this IEffect effect) | |
=> ValidateWithMutation(effect.Clone()); | |
private static bool ValidateWithMutation(IEffect clonedEffect) | |
{ | |
if (!allRules.TryGetValue(clonedEffect.GetType(), out var rules)) | |
return clonedEffect.Validate(); | |
for (var i = rules.Count - 1; i >= 0; i--) | |
{ | |
var rule = rules[i]; | |
clonedEffect.TryMutate(rule); | |
} | |
return clonedEffect.Validate(); | |
} | |
public static void SystemKickoff(this IEffect effect) | |
=> KickoffWithMutations(effect.Clone()); | |
private static void KickoffWithMutations(IEffect clonedEffect) | |
{ | |
if (!allRules.TryGetValue(clonedEffect.GetType(), out var rules)) | |
{ | |
clonedEffect.Run(); | |
return; | |
} | |
for (var i = rules.Count - 1; i >= 0; i--) | |
{ | |
var rule = rules[i]; | |
if (clonedEffect.TryMutate(rule) && rule is IOnRuleUsedReceiver limitedRule) | |
limitedRule.OnRuleUsed(); | |
} | |
clonedEffect.Run(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Serializable] | |
public class ChangeStatEffect : IEffect | |
{ | |
public int Id => 0; | |
public ScriptableStat targetStat; | |
public int changeAmount = 0; | |
[OdinSerialize] | |
public IEffectTarget EffectTarget; | |
private StatBlock targetStatBlock; | |
private int actualChange = 0; | |
IEffect IEffect.Clone() | |
{ | |
return new ChangeStatEffect | |
{ | |
targetStat = targetStat, | |
changeAmount = changeAmount, | |
EffectTarget = EffectTarget | |
}; | |
} | |
void IEffect.Run() | |
{ | |
targetStatBlock ??= EffectTarget.CurrentTarget.GetComponent<StatBlock>(); | |
var stat = targetStatBlock[targetStat]; | |
if (stat == null) | |
return; | |
stat.Current += changeAmount; | |
actualChange = stat.GetLastActualChange(); | |
} | |
void IEffect.Undo() | |
{ | |
var stat = targetStatBlock[targetStat]; | |
if (stat == null) | |
return; | |
stat.Current -= actualChange; | |
actualChange = -actualChange; | |
} | |
bool IEffect.TryMutate(IEffectRule mutator) => mutator.TryRule(this); | |
bool IEffect.Validate() | |
{ | |
targetStatBlock ??= EffectTarget.CurrentTarget.GetComponent<StatBlock>(); | |
var stat = targetStatBlock[targetStat]; | |
if (stat == null) | |
return false; | |
return (stat.Current + changeAmount) >= stat.min; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ChangeStatRule : MonoBehaviour, | |
IEffectRule<ChangeStatEffect>, IOnRuleUsedReceiver | |
{ | |
public int changeMutation = 0; | |
public int limitedUses = 3; | |
bool IEffectRule<ChangeStatEffect>.RunIfValid(ChangeStatEffect cmd) | |
{ | |
if (!(cmd.EffectTarget.CurrentTarget == gameObject)) | |
return false; | |
Debug.Log("Mutation: " + this.name + " applied to command " + cmd); | |
cmd.changeAmount += changeMutation; | |
return true; | |
} | |
void IOnRuleUsedReceiver.OnRuleUsed() | |
{ | |
limitedUses--; | |
if (limitedUses > 0) return; | |
Destroy(this); | |
} | |
public void OnEnable() => this.RegisterRule(typeof(ChangeStatEffect)); | |
public void OnDisable() => this.UnregisterRule(typeof(ChangeStatEffect)); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface IEffectRule<in Command> : IEffectRule | |
where Command : IEffect | |
{ | |
/// <summary> | |
/// Tries to run this specific rule. | |
/// </summary> | |
/// <returns>Returns true if the rule ran on this command.</returns> | |
bool RunIfValid(Command cmd); | |
} | |
public interface IEffectRule | |
{ | |
} | |
public static class IEffectRuleHelper | |
{ | |
public static bool TryRule<T>(this IEffectRule mutator, T cmd) | |
where T : IEffect | |
=> mutator is IEffectRule<T> cscMutator && cscMutator.RunIfValid(cmd); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface IEffect | |
{ | |
int Id { get; } | |
bool Validate(); | |
void Run(); | |
void Undo(); | |
bool TryMutate(IEffectRule mutator); | |
IEffect Clone(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment