Skip to content

Instantly share code, notes, and snippets.

@mrkybe
Created March 8, 2024 04:03
Show Gist options
  • Save mrkybe/e085d8caffa354b85c37934baeb55099 to your computer and use it in GitHub Desktop.
Save mrkybe/e085d8caffa354b85c37934baeb55099 to your computer and use it in GitHub Desktop.
using UnityEngine;
namespace Assets.Resources
{
[CreateAssetMenu(fileName = "Card", menuName = "ScriptableObjects/New Card", order = 1)]
public class Card : ScriptableObject
{
public GameObject AttackPrefab;
[Header("Card Settings")]
public string CardName;
public string Description;
public Sprite Artwork;
public int ManaCost;
public int EffectDuration = 1;
public bool AllowMovement;
public bool EndsTurn;
public bool EndsTurnImmediately;
public bool RequiresCastDirection;
public float MinMovementSpeedToCast;
public float MaxMovementSpeedToCast;
[Header("Type Settings")]
[Range(0, 5)]
[SerializeField]
private float ScalingStrength = 1;
[Range(0, 100)]
[SerializeField]
private float PhysicalScaling = 100; // Earth
[Range(0, 100)]
[SerializeField]
private float ElementalScaling = 0; // Fire
[Range(0, 100)]
[SerializeField]
private float MentalScaling = 0; // Air
[Range(0, 100)]
[SerializeField]
private float LifeScaling = 0; // Water
[Header("Debug Settings")]
public int NumberInDeck = 1;
public bool ShouldLoad;
[Header("Attack Settings")]
[SerializeField]
private int Damage = 0;
public DamageOutput GetDamageOutput(IContributeOffensiveStats CharacterStats)
{
return DamageOutput.From(this, CharacterStats);
}
public int KnockBack;
public bool AttachedToOwner;
public bool HitsColliders;
[Header("Timing Settings")]
public int NumberOfTurnsConsumed;
public bool UseTimingSettings;
// In percent of turn
[Range(0, 2)]
public float LiveTimeStart;
[Range(0, 20)]
public float LiveTimeStop;
public bool HideOnLiveTimeStopIfNoHitHappened;
public bool HideOnLiveTimeStop;
[Header("Misc Settings")]
public CardHelp CardHelp;
private void OnValidate()
{
if (UseTimingSettings)
{
if (LiveTimeStop < LiveTimeStart)
{
LiveTimeStop = LiveTimeStart;
}
}
else
{
LiveTimeStart = 0;
LiveTimeStop = 0;
}
}
public bool DontDiscardOnCast;
[HideInInspector]
public bool Unequipped = false;
[HideInInspector]
public bool Charged = true;
[HideInInspector]
public bool IsClone { get; private set; }
public Card CreateInstance()
{
var clone = ScriptableObject.Instantiate(this);
clone.name = clone.name.Substring(0, clone.name.Length - 7); // Remove (Clone) from name
clone.IsClone = true;
return clone;
}
public class DamageOutput
{
public int GetFinalDamage(IContributeDefensiveStats defense)
{
float finalPhysicalDamage = ArmorCalculation(PhysicalDamage, defense.PhysicalArmor);
float finalElementalDamage = ArmorCalculation(ElementalDamage, defense.ElementalArmor);
float finalMentalDamage = ArmorCalculation(MentalDamage, defense.MentalArmor);
float finalLifeDamage = ArmorCalculation(LifeDamage, defense.LifeArmor);
return Mathf.RoundToInt(finalPhysicalDamage + finalElementalDamage + finalMentalDamage + finalLifeDamage);
}
public int TotalPotentialDamage
{
get
{
return PhysicalDamage + ElementalDamage + MentalDamage + LifeDamage;
}
}
public int PhysicalDamage { get; private set; }
public int ElementalDamage { get; private set; }
public int MentalDamage { get; private set; }
public int LifeDamage { get; private set; }
public static DamageOutput From(Card card, IContributeOffensiveStats CharacterStats)
{
var result = new DamageOutput();
result.PhysicalDamage = DamageCalculation(card.Damage, card.ScalingStrength, card.PhysicalScaling, CharacterStats.PhysicalPower);
result.ElementalDamage = DamageCalculation(card.Damage, card.ScalingStrength, card.ElementalScaling, CharacterStats.ElementalPower);
result.MentalDamage = DamageCalculation(card.Damage, card.ScalingStrength, card.MentalScaling, CharacterStats.MentalPower);
result.LifeDamage = DamageCalculation(card.Damage, card.ScalingStrength, card.LifeScaling, CharacterStats.LifePower);
return result;
}
private static float ArmorCalculation(int DamageInput, int Armor)
{
float totalDamage = (DamageInput - Armor);
return Mathf.Max(totalDamage, 0);
}
private static int DamageCalculation(int ScalingDamage, float ScalingStat, float StatStrength, int CharacterPower)
{
return Mathf.RoundToInt((ScalingDamage * (ScalingStat * StatStrength) * Mathf.Log(1 + Mathf.Max(0, CharacterPower), 1.75f)) / 100f);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment