Encounter / Assets / Scripts / BattleLogic / ActionTextBox.cs
ActionTextBox.cs
Raw
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using TMPro;
using UnityEngine;

public class ActionTextBox : MonoBehaviour
{
    public enum ActionType
    {
        Melee,
        Ranged,
        Misses,
        DamagingSpell,
        HealingSpell,
        RefillingSpell,
        BuffingSpell,
        DebuffingSpell,
        Run,
        DamagingItemOnSingle,
        DamagingItemOnType,
        DamagingItemOnAll,
        HealingItemOnSingle,
        HealingItemOnType,
        HealingItemOnAll,
        RefillingItemOnSingle,
        RefillingItemOnType,
        RefillingItemOnAll,
        BuffingItemOnSingle,
        BuffingItemOnType,
        BuffingItemOnAll,
        DebuffingItemOnSingle,
        DebuffingItemOnType,
        DebuffingItemOnAll,
        SpellFailed,
        ReviveOne,
        ReviveAll
    }

    [SerializeField] private float timeShown;   // How much time the text should be shown on the screen before disappearing

    private TextMeshProUGUI actionText;        // The text container for the actions that are currently being performed
    private string currentText;                // The text to input into the container
    private readonly float delta = .2f;
    private float time;
    private bool textShown;

    private void Awake()
    {
        actionText = GetComponentInChildren<TextMeshProUGUI>();
        actionText.text = string.Empty;
        actionText.enabled = false;
        timeShown = Mathf.Clamp(timeShown, .5f, float.MaxValue);
    }
    private void Update()
    {
        if (time > 0.0f)
            time -= delta * Time.deltaTime;
        else if (time < 0.0f && actionText.enabled)
        {
            actionText.enabled = false;
            textShown = true;
        }
    }

    public void UpdateActionTextBasic(string activeUser, string target, ActionType action, int damage = 0)
    {
        switch (action)
        {
            case ActionType.Melee:
                currentText = $"{activeUser} swings at {target} for {damage}!";
                break;
            case ActionType.Ranged:
                if (activeUser.Equals("Blizzard"))
                {
                    if (damage is not 0)
                        currentText = $"{activeUser} freezes {target} for {damage}!";
                    else
                        currentText = $"{target} did not succumb to the {activeUser}!";
                    break;
                }

                currentText = $"{activeUser} shoots at {target} for {damage}!";
                break;
            case ActionType.Misses:
                currentText = $"{activeUser} missed {target}!";
                break;
            case ActionType.Run:
                currentText = $"{activeUser} runs away!";
                break;
        }

        ActivateText();
    }
    public void UpdateActionTextSpell(string activeUser, string target, ActionType action, Spell spell, int value = 0)
    {
        switch (action)
        {
            case ActionType.DamagingSpell:
                if (value <= 0)
                    currentText = $"{activeUser} casted {spell.SpellName} on {target}, but it failed!";
                else
                    currentText = $"{activeUser} casted {spell.SpellName} on {target} for {value} {spell.SpellType} damage!";
                break;
            case ActionType.HealingSpell:
                if (value <= 0)
                    currentText = $"{activeUser} casted {spell.SpellName} on {target}, but it failed!";
                else
                    currentText = $"{activeUser} casted {spell.SpellName} on {target} to heal for {value}!";
                break;
            case ActionType.RefillingSpell:
                if (value <= 0)
                    currentText = $"{activeUser} casted {spell.SpellName} on {target}, but it failed!";
                else
                    currentText = $"{activeUser} casted {spell.SpellName} on {target} to refill for {value}!";
                break;
            case ActionType.BuffingSpell:
                currentText = $"{activeUser} casted {spell.SpellName} to empower {target}!";
                break;
            case ActionType.DebuffingSpell:
                currentText = $"{activeUser} casted {spell.SpellName} to debilitate {target}!";
                break;
            case ActionType.SpellFailed:
                currentText = $"{activeUser} atttempted to cast {spell.SpellName} on {target} but failed!";
                break;
            case ActionType.ReviveOne:
                currentText = $"{activeUser} has revived {target} using {spell.SpellName}!";
                break;
            case ActionType.ReviveAll:
                currentText = $"{activeUser} has revived all of their allies using {spell.SpellName}!";
                break;
        }

        ActivateText();
    }
    public void UpdateActionTextItem(string activeUser, Entity entity, Consumable con, ActionType action, int value = 0)
    {
        switch (action)
        {
            case ActionType.DamagingItemOnSingle:
                currentText = $"{activeUser} used {con.ItemName} on {entity.GetName()} to damage for {value} points!";
                break;
            case ActionType.DamagingItemOnType:
                if (entity is Ally)
                    currentText = $"{activeUser} used {con.ItemName} on all allies to damage for {value} points!";
                else
                    currentText = $"{activeUser} used {con.ItemName} on all enemies to damage for {value} points!";
                break;
            case ActionType.DamagingItemOnAll:
                currentText = $"{activeUser} used {con.ItemName} on everyone to damage for {value} points!";
                break;
            case ActionType.HealingItemOnSingle:
                currentText = $"{activeUser} used {con.ItemName} on {entity.GetName()} to heal for {value} points!";
                break;
            case ActionType.HealingItemOnType:
                if (entity is Ally)
                    currentText = $"{activeUser} used {con.ItemName} on all allies to heal for {value} points!";
                else
                    currentText = $"{activeUser} used {con.ItemName} on all enemies to heal for {value} points!";
                break;
            case ActionType.HealingItemOnAll:
                currentText = $"{activeUser} used {con.ItemName} on everyone to heal for {value} points!";
                break;
            case ActionType.RefillingItemOnSingle:
                currentText = $"{activeUser} used {con.ItemName} on {entity.GetName()} to refill for {value} Mana points!";
                break;
            case ActionType.RefillingItemOnType:
                if (entity is Ally)
                    currentText = $"{activeUser} used {con.ItemName} on all allies to refill for {value} Mana points!";
                else
                    currentText = $"{activeUser} used {con.ItemName} on all enemies to refill for {value} Mana points!";
                break;
            case ActionType.RefillingItemOnAll:
                currentText = $"{activeUser} used {con.ItemName} on everyone to refill for {value} Mana points!";
                break;
            case ActionType.BuffingItemOnSingle:
                currentText = $"{activeUser} used {con.ItemName} to empower {entity.GetName()}!";
                break;
            case ActionType.BuffingItemOnType:
                if (entity is Ally)
                    currentText = $"{activeUser} used {con.ItemName} to empower all allies!";
                else
                    currentText = $"{activeUser} used {con.ItemName} to empower all enemies!";
                break;
            case ActionType.BuffingItemOnAll:
                currentText = $"{activeUser} used {con.ItemName} to empower everyone!";
                break;
            case ActionType.DebuffingItemOnSingle:
                currentText = $"{activeUser} used {con.ItemName} to debilitate {entity.GetName()}!";
                break;
            case ActionType.DebuffingItemOnType:
                if (entity is Ally)
                    currentText = $"{activeUser} used {con.ItemName} to debilitate all allies!";
                else
                    currentText = $"{activeUser} used {con.ItemName} to debilitate all enemies!";
                break;
            case ActionType.DebuffingItemOnAll:
                currentText = $"{activeUser} used {con.ItemName} to debilitate everyone!";
                break;
        }

        ActivateText();
    }
    public async Task UpdateActionTextFlee(string activeUser, bool isSuccessful)
    {
        await DotText();

        if (isSuccessful)
            currentText = $"{activeUser} was successful in running from battle!";
        else
            currentText = $"{activeUser} was unsuccessful in running away from battle!";

        ActivateText(.75f);

        await Task.CompletedTask;
    }

    public void UpdateActionTextUnique(int idFlag, int damage = -1, Entity target = null, Entity attacker = null, object extraInfo = null)
    {
        switch (idFlag)
        {
            // Blizzard Summoning Flag
            case 1:
                currentText = $"A blizzard has begun to rage!";
                break;
            // Golem Successful Summoning Flag
            case 2:
                currentText = $"A Golem has been summoned!";
                break;
            // Golem Unsuccessful Summoning Flag
            case 3:
                currentText = $"A Golem failed to be summoned!";
                break;
            // Life Contract was successfully made
            case 4:
                currentText = $"A pact has been made...";
                break;
            // Order: Rupture has failed
            case 5:
                currentText = $"All entities are unaffected by your order...";
                break;
            // Order: Rupture has succeeded
            case 6:
                currentText = $"Affected entities writhe in agony, maximum damage inflicted was {damage}!";
                break;
            // Single Target Cure
            case 7:
                currentText = $"{target.GetName()} was cured of all status ailments!";
                break;
            // Multi Target Cure
            case 8:
                currentText = $"All entities were cured of all status ailments!";
                break;
            // Normal Impalement Damage
            case 9:
                currentText = $"The rod digs deeper inside {target.GetName()}... dealing {damage} damage...";
                break;
            // Snow Impalement Damage
            case 10:
                currentText = $"The rod grows frigid inside {target.GetName()}... dealing {damage} damage...";
                break;
            // Blizzard Impalement Damage
            case 11:
                currentText = $"The rod burns icily inside {target.GetName()}... dealing {damage} damage...";
                break;
            // Rainy Impalement Damage
            case 12:
                currentText = $"The rod sparks randomly inside {target.GetName()}... dealing {damage} damage...";
                break;
            // Monsoon Impalement Damage
            case 13:
                currentText = $"{target.GetName()} is struck by lightning due to the rod! Dealing {damage} damage...";
                break;
            // Impalement does no damage
            case 14:
                currentText = $"{target.GetName()} remains unaffected by the rod.";
                break;
            // Failed to accumulate damage from Life Contract
            case 15:
                currentText = $"A debt must be repaid... {target.GetName()} suffered {damage} from its failed pact...";
                break;
            // Succeeded to accumulate damage from Life Contract
            case 16:
                currentText = $"{target.GetName()} has been inflicted {damage} from a successful contract...";
                break;
            // Entity has been executed
            case 17:
                currentText = $"{target.GetName()} has been executed...";
                break;
            // Successful Demon Soldier Summoning
            case 18:
                currentText = $"Demonic forces have been summoned!";
                break;
            // Unsuccessful Demon Soldier Summoning
            case 19:
                currentText = $"The forces of hell do not heed {attacker.GetName()}'s call...";
                break;
            // Successful Rain transition
            case 20:
                currentText = $"Water drips from the heavens...";
                break;
            // Mind Control, not other allies
            case 21:
                currentText = $"{attacker.GetName()} is in a daze...";
                break;
            // Sacrificial Rite Failure
            case 22:
                currentText = $"The ritual is unable to be performed...";
                break;
            // Sacrificial Rite Success
            case 23:
                currentText = $"{attacker.GetName()} split their veins in an offering to dark entities...";
                break;
            // Rampage
            case 24:
                currentText = $"{attacker.GetName()} went on a rampage and did {damage} total!"; 
                break;
            // Engorge Success
            case 25:
                currentText = $"{attacker.GetName()} devoured {target.GetName()}...";
                break;
            // Engorge Failure
            case 26:
                currentText = $"{target.GetName()} evaded {attacker.GetName()}'s hunger...";
                break;
            // Psionic Overload
            case 27:
                currentText = $"{attacker.GetName()} flooded their allies with psychic energy...";
                break;
            // Standoff Preparation
            case 28:
                currentText = $"{attacker.GetName()} breathes deeply and places their hand near their holster...";
                break;
            // Standoff Firing!
            case 29:
                currentText = $"{target.GetName()} is dealt a suprising blow from {attacker.GetName()} for {damage}!";
                break;
            // Preparing Precise Shot
            case 30:
                currentText = $"{attacker.GetName()} breathes deeply...";
                break;
            // Firing Precise Shot
            case 31:
                currentText = $"{target.GetName()} was inflicted with a lethal blow for {damage} by {attacker.GetName()}!";
                break;
            // Erratic Bursts
            case 32:
                currentText = $"Crackling Energy bursts from {attacker.GetName()}, dealing {damage}!";
                break;
            // Indominatable Roar
            case 33:
                currentText = $"A chilling roar from {attacker.GetName()} echoes throughout the battlefield...";
                break;
            // Successful Pillage
            case 34:
                currentText = $"YARRR! The bilgerat, {target.GetName()}, was plundered for {damage}! We acquired {((Item)extraInfo).ItemName}!";
                break;
            // Unsuccessful Pillage
            case 35:
                currentText = $"Ayyee... the landlubber, {target.GetName()}, evaded your pillaging...";
                break;
            // Afterimage
            case 36:
                currentText = $"An afterimage from {attacker.GetName()} deals {damage} more damage to {target.GetName()}!";
                break;
            // Summon Drought
            case 37:
                currentText = $"The sun shines brightly over the battlefield...";
                break;
            // Successful Damned Soul summoning
            case 38:
                currentText = $"Screams echo from hell as a Damned Soul is summoned to the field...";
                break;
            // Unsuccessful Damned Soul summoning
            case 39:
                currentText = $"Screams echo around you in frustration...";
                break;
            // Chain Lightning Initial
            case 40:
                currentText = $"Lightning flashes erratically and hits {target.GetName()} for {damage}!";
                break;
            // Chain Lightning Secondary
            case 41:
                currentText = $"Lightning arcs to {target.GetName()} for {damage}...";
                break;
        }

        ActivateText();
    }

    private async Task DotText()
    {
        currentText = ".";
        ActivateText(.5f);
        await Task.Delay(500);

        currentText = ". .";
        ActivateText(.5f);
        await Task.Delay(500);

        currentText = ". . .";
        ActivateText(.5f);
        await Task.Delay(500);

        await Task.CompletedTask;
    }

    private void ActivateText()
    {
        actionText.text = currentText;
        actionText.enabled = true;
        time = timeShown;
        textShown = false;
    }
    private void ActivateText(float timeToShow)
    {
        actionText.text = currentText;
        actionText.enabled = true;
        time = timeToShow;
        textShown = false;
    }
    public async Task GetTextShownStatus()
    {
        try
        {
            while (!textShown && time > -.5f)
            {
                if (time < float.Epsilon)
                    time -= Time.deltaTime;

                await Task.Yield();
            }

            await Task.CompletedTask;
        }
        catch (Exception ex)
        {
            throw new Exception("Exception was caught", ex);
        }
    }
    /// <summary>
    /// Signals when a saving throw leads to spell failure
    /// </summary>
    /// <param name="spellFailure">The spell that failed</param>
    public void SignalFailedSpellText(Spell spellFailure)
    {
        currentText = $"{spellFailure.SpellName} was used but its effects failed!";

        ActivateText();
    }
}