Skip to content
Snippets Groups Projects
Commit 6c3839e7 authored by Julius Fredrik Einum's avatar Julius Fredrik Einum
Browse files

Merge branch 'main' into JuliusesNyeSuperBranch

parents 44deff48 9b810e1a
No related branches found
No related tags found
2 merge requests!33Updating master branch.,!32util bar merge
Showing
with 3703 additions and 17 deletions
......@@ -48,7 +48,16 @@ namespace BigSock {
set => baseHP = value;
}
public float baseHP = 10;
/*
Mana of the character.
*/
public float Mana { get; set; }
/*
Stamina of the character.
*/
public float Stamina { get; set; }
/*
Maximum hit points of the character.
......@@ -114,20 +123,39 @@ namespace BigSock {
// Set the base stats.
BaseStats = new CharacterStats {
MaxHP = baseMaxHP,
MaxMana = 20,
MaxStamina = 20,
RegenMana = 2,
RegenStamina = 2,
Damage = baseDamage,
MoveSpeed = baseMovementSpeed,
Knockback = knockbackForce,
Range = 1,
AttackSpeed = baseAttackSpeed,
CritChance = 1,
CritDamageModifier = 1,
ProjectileSpeed = 1,
};
UpdateModifiers();
Mana = Stats.MaxMana;
Stamina = Stats.MaxStamina;
}
/*
Regenerates mana and stamina.
*/
protected virtual void Regenerate() {
Mana = Math.Min(Stats.MaxMana, Mana + Time.fixedDeltaTime * Stats.RegenMana);
Stamina = Math.Min(Stats.MaxStamina, Stamina + Time.fixedDeltaTime * Stats.RegenStamina);
}
/*
Updates the modifiers to the character's stats.
*/
public void UpdateModifiers(ICharacterStats modifiers = null) {
public virtual void UpdateModifiers(ICharacterStats modifiers = null) {
modifiers ??= Inventory.Modifier;
Stats = BaseStats.Modify(modifiers);
}
......@@ -162,6 +190,9 @@ namespace BigSock {
Adds damage to the character if they don't have IFrames.
*/
public virtual bool TakeDamage(AttackStats attack) {
if(attack == null) throw new ArgumentNullException(nameof(attack));
if(!attack.IsCalculated) throw new ArgumentException("Attack needs to be calculated.", nameof(attack));
// Check if player has IFrames
if(NextTimeCanTakeDamage > DateTime.Now)
return false;
......@@ -239,7 +270,7 @@ namespace BigSock {
Method for what to do when the character takes damage.
*/
protected virtual void AfterDamage(IAttackStats attack) {
print($"[Character.AfterDamage()] {HP + attack.Damage:N1} - {attack.Damage:N1} = {HP:N1}");
print($"[Character.AfterDamage()] {HP + attack.Damage:N1} - {attack.Damage:N1} = {HP:N1} {(attack.IsCrit ? "[CRIT]":"")}");
KnockBack(attack);
}
......
......@@ -43,6 +43,23 @@ namespace BigSock {
/*
The mana cost of the ability.
*/
public float ManaCost { get; protected set; }
/*
The stamina cost of the ability.
*/
public float StaminaCost { get; protected set; }
/*
The hp cost of the ability.
*/
public float HPCost { get; protected set; }
/*
......@@ -54,6 +71,9 @@ namespace BigSock {
// Check that the ability is cooled down.
if(Ready) {
//> Handle checking costs here.
if(ManaCost > 0f && actor.Mana < ManaCost) return false;
if(StaminaCost > 0f && actor.Stamina < StaminaCost) return false;
if(HPCost > 0f && actor.HP < HPCost) return false;
// Activate the ability.
var res = Activate(actor, target);
......@@ -62,6 +82,9 @@ namespace BigSock {
if(res) {
NextTimeCanUse = DateTime.Now + Cooldown;
//> Handle paying the cost (HP, mana, stamina) here.
if(ManaCost > 0f) actor.Mana -= ManaCost;
if(StaminaCost > 0f) actor.Stamina -= StaminaCost;
if(HPCost > 0f) actor.HP -= HPCost;
}
return res;
......
......@@ -42,6 +42,24 @@ namespace BigSock {
bool Ready { get; }
/*
The mana cost of the ability.
*/
float ManaCost { get; }
/*
The stamina cost of the ability.
*/
float StaminaCost { get; }
/*
The hp cost of the ability.
*/
float HPCost { get; }
/*
-----------------------------
Add in something for costs.
......
......@@ -28,7 +28,10 @@ namespace BigSock {
Range = 10f,
ProjectileSpeed = 10f,
AttackSpeed = 1f,
CritChance = 0.1f,
CritDamageModifier = 2f,
};
ManaCost = 1;
}
......@@ -42,7 +45,8 @@ namespace BigSock {
protected override bool Activate(Character actor, Vector3? target) {
if(target == null) return false;
var attack = (AttackStats) AttackStats.Apply(actor.Stats);
var attack = (AttackStats) AttackStats.Calculate(actor.Stats);
//var attack = (AttackStats) AttackStats.Apply(actor.Stats);
attack.Actor = actor;
......
......@@ -28,9 +28,13 @@ namespace BigSock {
Range = 5f,
ProjectileSpeed = 3f,
AttackSpeed = 1f,
CritChance = 0.25f,
CritDamageModifier = 3f,
DamageVariance = 0.5f,
};
Cooldown = new TimeSpan(0, 0, 0, 2, 0);
ManaCost = 5;
}
......@@ -44,7 +48,8 @@ namespace BigSock {
protected override bool Activate(Character actor, Vector3? target) {
if(target == null) return false;
var attack = (AttackStats) AttackStats.Apply(actor.Stats);
var attack = (AttackStats) AttackStats.Calculate(actor.Stats);
//var attack = (AttackStats) AttackStats.Apply(actor.Stats);
attack.Actor = actor;
......
......@@ -11,6 +11,8 @@ namespace BigSock {
Represents the stats of an attack.
*/
public class AttackStats : IAttackStats {
public static readonly System.Random RND = new System.Random();
/*
The damage of the attack.
*/
......@@ -36,6 +38,24 @@ namespace BigSock {
*/
public float AttackSpeed { get; set; } = 1f;
/*
The crit chance of the character.
*/
public float CritChance { get; set; }
/*
The how much to modify damage by when critting.
*/
public float CritDamageModifier { get; set; } = 1;
/*
How much the damage can vary in percent.
*/
public float DamageVariance { get; set; } = 0.2f;
/*
The source of the attack.
*/
......@@ -46,5 +66,69 @@ namespace BigSock {
*/
public Character Actor { get; set; }
/*
Indicates if the attack stats have been calculated.
*/
public bool IsCalculated { get; set; }
/*
Indicates if the attack was a critical hit.
*/
public bool IsCrit { get; set; }
/*
Calculates the final attack stats.
(Takes crit and damage spread and calculates the final values)
Cannot calculate a calculated attack.
*/
public IAttackStats Calculate(ICharacterStats charStats = null) {
// Check that this attack hasn't been calculated already.
if(IsCalculated) throw new InvalidOperationException("This attack has already been calculated!");
// Creates return object.
AttackStats res;
if(charStats != null) res = (AttackStats) this.Apply(charStats);
else res = Clone();
// Mark the calculated attack as calculated.
res.IsCalculated = true;
// Calculate damage variety.
var mod = (1-DamageVariance) + RND.NextDouble() * DamageVariance * 2;
Damage *= (float) mod;
// Check for crits.
if(RND.NextDouble() <= CritChance) {
Damage *= CritDamageModifier;
IsCrit = true;
}
return res;
}
/*
Creates a clone of this object.
*/
public AttackStats Clone() {
return new AttackStats{
Damage = Damage,
Knockback = Knockback,
Range = Range,
ProjectileSpeed = ProjectileSpeed,
AttackSpeed = AttackSpeed,
CritChance = CritChance,
CritDamageModifier = CritDamageModifier,
Source = Source,
Actor = Actor,
DamageVariance = DamageVariance,
IsCalculated = IsCalculated,
IsCrit = IsCrit,
};
}
}
}
\ No newline at end of file
......@@ -16,6 +16,28 @@ namespace BigSock {
*/
public float MaxHP { get; set; }
/*
The max mana of the character.
*/
public float MaxMana { get; set; }
/*
The max stamina of the character.
*/
public float MaxStamina { get; set; }
/*
The regeneration rate of the character's mana.
*/
public float RegenMana { get; set; }
/*
The regeneration rate of the character's stamina.
*/
public float RegenStamina { get; set; }
/*
The damage of the character.
*/
......@@ -25,6 +47,11 @@ namespace BigSock {
The movement speed of the character.
*/
public float MoveSpeed { get; set; }
/*
The projectile speed of the attack.
*/
public float ProjectileSpeed { get; set; }
/*
The knockback of the character.
......@@ -41,5 +68,14 @@ namespace BigSock {
*/
public float AttackSpeed { get; set; }
/*
The crit chance of the character.
*/
public float CritChance { get; set; }
/*
The how much to modify damage by when critting.
*/
public float CritDamageModifier { get; set; }
}
}
\ No newline at end of file
......@@ -36,6 +36,23 @@ namespace BigSock {
*/
float AttackSpeed { get; }
/*
The crit chance of the character.
*/
float CritChance { get; }
/*
The how much to modify damage by when critting.
*/
float CritDamageModifier { get; }
/*
How much the damage can vary in percent.
*/
float DamageVariance { get; }
/*
The source of the attack.
*/
......@@ -45,6 +62,24 @@ namespace BigSock {
The character that activated the attack.
*/
Character Actor { get; }
/*
Indicates if the attack stats have been calculated.
*/
bool IsCalculated { get; }
/*
Indicates if the attack was a critical hit.
*/
bool IsCrit { get; }
/*
Calculates the final attack stats.
(Takes crit and damage spread and calculates the final values)
*/
IAttackStats Calculate(ICharacterStats charStats = null);
}
......@@ -62,10 +97,17 @@ namespace BigSock {
Damage = a.Damage * b.Damage,
Knockback = a.Knockback * b.Knockback,
Range = a.Range * b.Range,
ProjectileSpeed = a.ProjectileSpeed,
ProjectileSpeed = a.ProjectileSpeed * b.ProjectileSpeed,
AttackSpeed = a.AttackSpeed * b.AttackSpeed,
CritChance = a.CritChance * b.CritChance,
CritDamageModifier = a.CritDamageModifier * b.CritDamageModifier,
Source = a.Source,
Actor = a.Actor,
DamageVariance = a.DamageVariance,
IsCalculated = a.IsCalculated,
IsCrit = a.IsCrit,
};
}
}
......
......@@ -12,10 +12,31 @@ namespace BigSock {
*/
public interface ICharacterStats {
/*
The hp of the character.
The max hp of the character.
*/
float MaxHP { get; }
/*
The max mana of the character.
*/
float MaxMana { get; }
/*
The max stamina of the character.
*/
float MaxStamina { get; }
/*
The regeneration rate of the character's mana.
*/
float RegenMana { get; }
/*
The regeneration rate of the character's stamina.
*/
float RegenStamina { get; }
/*
The damage of the character.
*/
......@@ -41,6 +62,21 @@ namespace BigSock {
*/
float AttackSpeed { get; }
/*
The crit chance of the character.
*/
float CritChance { get; }
/*
The how much to modify damage by when critting.
*/
float CritDamageModifier { get; }
/*
The projectile speed of the attack.
*/
float ProjectileSpeed { get; }
}
/*
......@@ -52,11 +88,19 @@ namespace BigSock {
*/
public static readonly ICharacterStats IDENTITY = new CharacterStats{
MaxHP = 1,
MaxMana = 1,
MaxStamina = 1,
RegenMana = 1,
RegenStamina = 1,
Damage = 1,
MoveSpeed = 1,
Knockback = 1,
Range = 1,
AttackSpeed = 1,
CritChance = 1,
CritDamageModifier = 1,
ProjectileSpeed = 1,
};
/*
......@@ -65,11 +109,19 @@ namespace BigSock {
public static ICharacterStats Add(this ICharacterStats a, ICharacterStats b) {
return new CharacterStats{
MaxHP = a.MaxHP + b.MaxHP,
MaxMana = a.MaxMana + b.MaxMana,
MaxStamina = a.MaxStamina + b.MaxStamina,
RegenMana = a.RegenMana + b.RegenMana,
RegenStamina = a.RegenStamina + b.RegenStamina,
Damage = a.Damage + b.Damage,
MoveSpeed = a.MoveSpeed + b.MoveSpeed,
Knockback = a.Knockback + b.Knockback,
Range = a.Range + b.Range,
AttackSpeed = a.AttackSpeed + b.AttackSpeed,
CritChance = a.CritChance + b.CritChance,
CritDamageModifier = a.CritDamageModifier + b.CritDamageModifier,
ProjectileSpeed = a.ProjectileSpeed + b.ProjectileSpeed,
};
}
......@@ -80,11 +132,19 @@ namespace BigSock {
public static ICharacterStats Remove(this ICharacterStats a, ICharacterStats b) {
return new CharacterStats{
MaxHP = a.MaxHP - b.MaxHP,
MaxMana = a.MaxMana - b.MaxMana,
MaxStamina = a.MaxStamina - b.MaxStamina,
RegenMana = a.RegenMana - b.RegenMana,
RegenStamina = a.RegenStamina - b.RegenStamina,
Damage = a.Damage - b.Damage,
MoveSpeed = a.MoveSpeed - b.MoveSpeed,
Knockback = a.Knockback - b.Knockback,
Range = a.Range - b.Range,
AttackSpeed = a.AttackSpeed - b.AttackSpeed,
CritChance = a.CritChance - b.CritChance,
CritDamageModifier = a.CritDamageModifier - b.CritDamageModifier,
ProjectileSpeed = a.ProjectileSpeed - b.ProjectileSpeed,
};
}
......@@ -94,11 +154,19 @@ namespace BigSock {
public static ICharacterStats Multiply(this ICharacterStats a, ICharacterStats b) {
return new CharacterStats{
MaxHP = a.MaxHP * b.MaxHP,
MaxMana = a.MaxMana * b.MaxMana,
MaxStamina = a.MaxStamina * b.MaxStamina,
RegenMana = a.RegenMana * b.RegenMana,
RegenStamina = a.RegenStamina * b.RegenStamina,
Damage = a.Damage * b.Damage,
MoveSpeed = a.MoveSpeed * b.MoveSpeed,
Knockback = a.Knockback * b.Knockback,
Range = a.Range * b.Range,
AttackSpeed = a.AttackSpeed * b.AttackSpeed,
CritChance = a.CritChance * b.CritChance,
CritDamageModifier = a.CritDamageModifier * b.CritDamageModifier,
ProjectileSpeed = a.ProjectileSpeed * b.ProjectileSpeed,
};
}
......
using System.Collections;
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;
namespace BigSock.Item {
/*
A passive item that increases user's running speed by 50%.
*/
public class ItemPremature : PassiveItemBase {
public override ulong Id => 104;
public override string Name => "Premature";
public override string Description => "Increases projectile speed by 50%";
public ItemPremature() {
Modifier = new CharacterStats{
ProjectileSpeed = 0.5f,
};
}
}
}
\ No newline at end of file
fileFormatVersion: 2
guid: 1376b5ed2e6b68949be4690ddc930187
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
......@@ -18,6 +18,8 @@ namespace BigSock {
public HPBar hpBar;
public XpBar xpBar;
public XpBar manaBar;
public XpBar staminaBar;
public float collisionOffset = 0.05f;
......@@ -48,18 +50,19 @@ namespace BigSock {
{
base.Start();
xpBar.SetMaxXp(maxXp);
xpBar.SetXp(xp);
xpBar?.SetMaxXp(maxXp);
xpBar?.SetXp(xp);
animator = GetComponent<Animator>();
spriteRenderer = GetComponent<SpriteRenderer>();
hpBar.SetMaxHealth(Convert.ToInt32(MaxHP));
hpBar.SetHealth(Convert.ToInt32(HP));
hpBar?.SetMaxHealth(Convert.ToInt32(MaxHP));
hpBar?.SetHealth(Convert.ToInt32(HP));
//!! DEBUG: Add item to player at start to test if it works.
TryPickUpItem(ItemService.SINGLETON.Get(201));
TryPickUpItem(ItemService.SINGLETON.Get(201));
TryPickUpItem(ItemService.SINGLETON.Get(202));
TryPickUpItem(ItemService.SINGLETON.Get(101));
var tmp = PrefabService.SINGLETON;
_testAttack = (IAttack) AbilityService.SINGLETON.Get(101);
_testAttack2 = (IAttack) AbilityService.SINGLETON.Get(102);
......@@ -105,6 +108,8 @@ namespace BigSock {
}
private void Update() {
Regenerate();
if (Input.GetKeyDown(KeyCode.Space) || Input.GetMouseButton(0)) {
// Manage attack cooldown.
if(NextTimeCanAttack <= DateTime.Now) {
......@@ -129,8 +134,24 @@ namespace BigSock {
}
}
/*
Updates the modifiers to the character's stats.
*/
public override void UpdateModifiers(ICharacterStats modifiers = null) {
base.UpdateModifiers(modifiers);
manaBar?.SetMaxXp(Stats.MaxMana);
staminaBar?.SetMaxXp(Stats.MaxStamina);
}
/*
Regenerates mana and stamina.
*/
protected override void Regenerate() {
base.Regenerate();
manaBar?.SetXp(Mana);
staminaBar?.SetXp(Stamina);
}
private bool TryMove_OLD(Vector2 direction) {
if(direction != Vector2.zero) {
......@@ -173,13 +194,13 @@ namespace BigSock {
*/
protected override void AfterDamage(IAttackStats attack) {
base.AfterDamage(attack);
hpBar.SetHealth(Convert.ToInt32(HP));
hpBar?.SetHealth(Convert.ToInt32(HP));
}
public void GainXp(float xp){
GiveXp(xp);
CheckXp();
xpBar.SetXp(this.xp);
xpBar?.SetXp(this.xp);
}
private void CheckXp(){
......@@ -187,7 +208,7 @@ namespace BigSock {
level += 1;
xp -= maxXp;
maxXp = (level + 1) * 100;
xpBar.SetMaxXp(maxXp);
xpBar?.SetMaxXp(maxXp);
}
}
......
......@@ -61,6 +61,8 @@ namespace BigSock {
}
protected virtual void Update() {
Regenerate();
if (target != null && !isInMelee){
/* //walk
......@@ -98,13 +100,14 @@ namespace BigSock {
var player = other.gameObject.GetComponent<PlayerController>();
if(player != null) {
// Create attack object.
var attack = new AttackStats{
var attack = (AttackStats) new AttackStats{
Damage = Damage,
Knockback = KnockbackForce,
Range = 0,
AttackSpeed = AttackSpeed,
Source = transform.position,
};
Actor = this,
}.Calculate(Stats);
// Get the player to take the damage.
if(player.TakeDamage(attack)){
......
fileFormatVersion: 2
guid: af58fad506f36bf4e99a1ca592acc21f
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
This diff is collapsed.
fileFormatVersion: 2
guid: db99dfa54d3802846864ffc3208d2986
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
......@@ -19,7 +19,7 @@ namespace BigSock.UI{
public void SetXp(float xp){
slider.value = xp;
xpText.SetText($"{xp}/{slider.maxValue}");
xpText.SetText($"{xp:N0}/{slider.maxValue:N0}");
}
public void SetMaxXp(float xp){
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment