diff --git a/MrBigsock/Assets/Code/Core/Abilities/Base/BaseAbility.cs b/MrBigsock/Assets/Code/Core/Abilities/Base/BaseAbility.cs index dfc797c2f90ab87607ac90e2f58f1a99e70f2b47..f19870ede3fa73fcfbe58607883c12c150e678e4 100644 --- a/MrBigsock/Assets/Code/Core/Abilities/Base/BaseAbility.cs +++ b/MrBigsock/Assets/Code/Core/Abilities/Base/BaseAbility.cs @@ -19,22 +19,22 @@ namespace BigSock { /* The name of the ability. */ - public string Name { get; set; } + public abstract string Name { get;} /* The description of the ability. */ - public string Description { get; set; } + public abstract string Description { get; } /* The id of the ability. */ - public ulong Id { get; set; } + public abstract ulong Id { get; } /* The next time the ability has cooled down. */ - public DateTime NextTimeCanUse { get; set; } = DateTime.Now; + public DateTime NextTimeCanUse { get; protected set; } = DateTime.Now; /* Whether the ability is ready. diff --git a/MrBigsock/Assets/Code/Core/Abilities/Base/BaseAttack.cs b/MrBigsock/Assets/Code/Core/Abilities/Base/BaseAttack.cs index 99de155333fa836e121ffba90869c49a53a354b1..a0c6b44b35538b5b559b2f5edfab75d9361d5769 100644 --- a/MrBigsock/Assets/Code/Core/Abilities/Base/BaseAttack.cs +++ b/MrBigsock/Assets/Code/Core/Abilities/Base/BaseAttack.cs @@ -15,7 +15,7 @@ namespace BigSock { /* The attack stats of the ability. */ - public IAttackStats AttackStats { get; set; } + public IAttackStats AttackStats { get; protected set; } } diff --git a/MrBigsock/Assets/Code/Core/Abilities/BasicProjectile1.cs b/MrBigsock/Assets/Code/Core/Abilities/BasicProjectile1.cs index b7e1e8189da0a411a88414cca0d135d37c661840..15aa963ea6f4f5cf4d0eb06519d677547ee3beb8 100644 --- a/MrBigsock/Assets/Code/Core/Abilities/BasicProjectile1.cs +++ b/MrBigsock/Assets/Code/Core/Abilities/BasicProjectile1.cs @@ -16,17 +16,19 @@ namespace BigSock { //protected static readonly GameObject PROJECTILE_BASE = new AttackMovement(); public const string PROJECTILE_NAME = "attack"; - /* - The attack stats of the ability. - */ - public IAttackStats AttackStats { get; set; } - - + + public override ulong Id => 101; + public override string Name => "Basic Player Projectile Attack"; + public override string Description => "A basic projectile shooting attack the player has."; public BasicProjectile1() { - Name = "Basic Player Projectile Attack"; - Id = 101; - Description = "A basic projectile shooting attack the player has."; + AttackStats = new AttackStats{ + Damage = 1f, + Knockback = 1f, + Range = 10f, + ProjectileSpeed = 10f, + AttackSpeed = 1f, + }; } @@ -38,8 +40,21 @@ namespace BigSock { This should be overridden in sub-classes for the actual abilities. */ protected override bool Activate(Character actor, Vector3? target) { + if(target == null) return false; + + var attack = (AttackStats) AttackStats.Apply(actor.Stats); + attack.Actor = actor; + + + var temp = (target.Value - actor.transform.position); + temp.z = 0; + var bullet = PrefabService.SINGLETON.Instance(PROJECTILE_NAME, actor.transform.position); - bullet.GetComponent<AttackMovement>().Actor = actor; + var bulletScript = bullet.GetComponent<AttackMovement>(); + //bulletScript.Actor = actor; + bulletScript.Stats = attack; + bulletScript.Direction = temp.normalized; + //MonoBehaviour.Instantiate(PROJECTILE_BASE, (Vector3) actor.transform.position, PROJECTILE_BASE.transform.rotation); return true; diff --git a/MrBigsock/Assets/Code/Core/AttackStats.cs b/MrBigsock/Assets/Code/Core/AttackStats.cs index 6eac3a66344a0e6096c2d907d505c9bbc5cc2327..39cffac40b372ae2f66944dd8a783f5885cb86d0 100644 --- a/MrBigsock/Assets/Code/Core/AttackStats.cs +++ b/MrBigsock/Assets/Code/Core/AttackStats.cs @@ -14,22 +14,27 @@ namespace BigSock { /* The damage of the attack. */ - public float Damage { get; set; } + public float Damage { get; set; } = 1f; /* The knockback of the attack. */ - public float Knockback { get; set; } + public float Knockback { get; set; } = 1f; /* The range of the attack. */ - public float Range { get; set; } + public float Range { get; set; } = 1f; + + /* + The projectile speed of the attack. + */ + public float ProjectileSpeed { get; set; } = 1f; /* The attack speed of the attack. */ - public float AttackSpeed { get; set; } + public float AttackSpeed { get; set; } = 1f; /* The source of the attack. diff --git a/MrBigsock/Assets/Code/Core/IAttackStats.cs b/MrBigsock/Assets/Code/Core/IAttackStats.cs index ea103727f1cb17a22798b4392db54908a0772484..7b601071f61bd03241c074645bc7d521aa305268 100644 --- a/MrBigsock/Assets/Code/Core/IAttackStats.cs +++ b/MrBigsock/Assets/Code/Core/IAttackStats.cs @@ -26,6 +26,11 @@ namespace BigSock { */ float Range { get; } + /* + The projectile speed of the attack. + */ + float ProjectileSpeed { get; } + /* The attack speed of the attack. */ @@ -41,4 +46,27 @@ namespace BigSock { */ Character Actor { get; } } + + + /* + Holds extension methods for attack stat objects. + */ + public static class AttackStatsExtension { + + + /* + Applies the character's stats to the attack. + */ + public static IAttackStats Apply(this IAttackStats a, ICharacterStats b) { + return new AttackStats{ + Damage = a.Damage * b.Damage, + Knockback = a.Knockback * b.Knockback, + Range = a.Range * b.Range, + ProjectileSpeed = a.ProjectileSpeed, + AttackSpeed = a.AttackSpeed * b.AttackSpeed, + Source = a.Source, + Actor = a.Actor, + }; + } + } } \ No newline at end of file diff --git a/MrBigsock/Assets/Code/PlayerController.cs b/MrBigsock/Assets/Code/PlayerController.cs index d07507999d825f65ae26b8ebbcc9a6858d8fdbf2..300cedfbac1d53a86394b866607ddc3655d53b33 100644 --- a/MrBigsock/Assets/Code/PlayerController.cs +++ b/MrBigsock/Assets/Code/PlayerController.cs @@ -32,7 +32,7 @@ namespace BigSock { - protected IAttack _testAttack = new BasicProjectile1(); + protected IAttack _testAttack;// = new BasicProjectile1(); public DateTime NextTimeCanAttack { get; private set; } = DateTime.Now; @@ -53,6 +53,7 @@ namespace BigSock { TryPickUpItem(ItemService.SINGLETON.Get(201)); TryPickUpItem(ItemService.SINGLETON.Get(202)); var tmp = PrefabService.SINGLETON; + _testAttack = (IAttack) AbilityService.SINGLETON.Get(101); } diff --git a/MrBigsock/Assets/Code/Services/AbilityService.cs b/MrBigsock/Assets/Code/Services/AbilityService.cs new file mode 100644 index 0000000000000000000000000000000000000000..1849ecf96f6096928a9ca3abc4d406f12def88f7 --- /dev/null +++ b/MrBigsock/Assets/Code/Services/AbilityService.cs @@ -0,0 +1,85 @@ +using System.Collections; +using System; +using System.Linq; +using System.Collections.Generic; +using System.Reflection; + +using UnityEngine; +using UnityEngine.InputSystem; + +using BigSock.Item; + + +namespace BigSock.Service { + + /* + Service for handling abilities. + */ + public partial class AbilityService { + /* + The instance to use. + */ + public static readonly AbilityService SINGLETON = new AbilityService(); + + /* + Get an instance of the ability of the given id. + */ + public IAbility Get(ulong id) { + if(_abilities.TryGetValue(id, out var res)) return _new(res); + return null; + } + + /* + Get a random ability from the ability pool. + */ + public IAbility GetRandom() { + var num = _rnd.Next(_abilityList.Count); + return _new(_abilityList[num]); + } + } + + public partial class AbilityService { + private Dictionary<ulong, IAbility> _abilities = new Dictionary<ulong, IAbility>(); + private List<IAbility> _abilityList = new List<IAbility>(); + + private System.Random _rnd = new System.Random(); + + private AbilityService() { + _loadItems(); + } + + /* + Load the abilities into the dictionary. + Reflection code: https://stackoverflow.com/a/6944605 + */ + private void _loadItems() { + // Get the classs that inherit the item base class. + var types = Assembly + .GetAssembly(typeof(BaseAbility)) + .GetTypes() + .Where(myType => myType.IsClass + && !myType.IsAbstract + && myType.IsSubclassOf(typeof(BaseAbility))); + + // Create list of instances. + _abilityList = types + .Select(t => (IAbility) Activator.CreateInstance(t, new object[0])) + .ToList(); + + // Map to a dictionary by their ids. + _abilities = _abilityList + .ToDictionary(t => t.Id); + + foreach(var a in _abilityList) { + Debug.Log($"[AbilityService._loadItems()] {a.Id}"); + } + } + + /* + Creates a new instance of the object. + */ + private IAbility _new(IAbility obj) + => (IAbility) Activator.CreateInstance(obj.GetType(), new object[0]); + + } +} \ No newline at end of file diff --git a/MrBigsock/Assets/Code/Services/AbilityService.cs.meta b/MrBigsock/Assets/Code/Services/AbilityService.cs.meta new file mode 100644 index 0000000000000000000000000000000000000000..ba54c4ef9e433c501d67907a37c029f02b20f6f8 --- /dev/null +++ b/MrBigsock/Assets/Code/Services/AbilityService.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: accabe59812fa39448d6bd558041692d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MrBigsock/Assets/Code/attack/AttackMovement.cs b/MrBigsock/Assets/Code/attack/AttackMovement.cs index 37b53fa9705d5bfb24c47e4824e351bdf21de880..aa7795a3385fed211ac5008c6d464885cd9634fa 100644 --- a/MrBigsock/Assets/Code/attack/AttackMovement.cs +++ b/MrBigsock/Assets/Code/attack/AttackMovement.cs @@ -4,29 +4,44 @@ using UnityEngine; using UnityEngine.InputSystem; using static UnityEngine.GraphicsBuffer; +using BigSock.Service; + + namespace BigSock { public class AttackMovement : MonoBehaviour { public float speed = 10.0f; bool moved = false; - Vector3 direction; + //Vector3 direction; + Vector3 startingPos; /* Damage of the character. */ - public float Damage => baseDamage; - public float baseDamage = 1; + //public float Damage => baseDamage; + //public float baseDamage = 1; - public float KnockbackForce => knockbackForce; - public float knockbackForce = 1; + //public float KnockbackForce => knockbackForce; + //public float knockbackForce = 1; /* The character that activated the attack. */ - public Character Actor { get; set; } + //public Character Actor { get; set; } + + /* + The attack stats of the attack. + */ + public AttackStats Stats { get; set; } + + /* + The direction of the attack. + */ + public Vector3 Direction { get; set; } + - // Start is called before the first frame update + // Start is called before the first frame update void Start() { } @@ -36,18 +51,26 @@ namespace BigSock { { if (!moved) { - var mouse = Camera.main.ScreenToWorldPoint(Input.mousePosition); - var pos = transform.position; - var temp = (mouse - pos); - temp.z = 0; - direction = temp.normalized; + //var mouse = Camera.main.ScreenToWorldPoint(Input.mousePosition); + //var pos = transform.position; + //var temp = (mouse - pos); + //temp.z = 0; + //direction = temp.normalized; //print($"[AttackMovement.Update()] {mouse} - {pos} = {direction}"); + startingPos = transform.position; moved = true; } //transform.Translate(new Vector3(1 * horizontalInput, 1 * verticalInput, 0) * speed * Time.deltaTime); - transform.Translate(direction * speed * Time.deltaTime); - + transform.Translate(Direction * Stats.ProjectileSpeed * Time.deltaTime); + + var traveled = Vector2.Distance(transform.position, startingPos); + + // If we traveled passed our range: destroy this obj. + if(traveled > Stats.Range) { + PrefabService.SINGLETON.Destroy(gameObject); + } + } @@ -58,23 +81,24 @@ namespace BigSock { if(target != null) { - var attack = new AttackStats{ - Damage = Damage, - Knockback = KnockbackForce, - //Range = 0, - //AttackSpeed = AttackSpeed, - Source = transform.position, - Actor = Actor, - }; + //var attack = new AttackStats{ + // Damage = Damage, + // Knockback = KnockbackForce, + // //Range = 0, + // //AttackSpeed = AttackSpeed, + // Source = transform.position, + // Actor = Actor, + //}; + Stats.Source = transform.position; // If we have an actor: Apply their stat mods & trigger their OnHit. - if(Actor != null) { - attack.Damage *= Actor.Damage; - attack.Knockback *= Actor.KnockbackForce; - //Actor.TargetHit(target, attack); - } + //if(Actor != null) { + // attack.Damage *= Actor.Damage; + // attack.Knockback *= Actor.KnockbackForce; + // //Actor.TargetHit(target, attack); + //} - if(target.TakeDamage(attack)) { + if(target.TakeDamage(Stats)) { } }