Iteration 1

have some art, didn't really do much there
I did spend a lot more time on the code, it's more iteresting.
Player is in it's own file.
All Players use the same code.
Refactored how turns are processed.
Added a defend and counter ability, have code for "Blood Counter" that I
might revisit. Want to change defend to a "Holy Shield" and add a magic
ability that is countered by it. This is to stop the counter until you
win strategy.
This commit is contained in:
2021-02-16 21:10:46 -06:00
parent c56a139556
commit b2eb3ca9a5
21 changed files with 3467 additions and 61 deletions
+98 -45
View File
@@ -1,90 +1,143 @@
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class BattleMenu : MonoBehaviour
{
private class Player
{
public int Health;
public int Damage;
public Action UpdateHealth;
}
private Player _user;
private Player _enemy;
{
private EnemyAi _enemyLogic;
private readonly List<Action> _turnOrder = new List<Action>();
private int _currentTurnIndex = 0;
private readonly List<Player> _players = new List<Player>();
private int _currentPlayerIndex;
private Player CurrentPlayer => _players[_currentPlayerIndex];
public Button attackButton;
public Button bloodCounterButton;
public Button counterButton;
public Button defendButton;
public Text userHealth;
public Text enemyHealth;
private void Awake()
{
_user = new Player {Health = 10, Damage = 1, UpdateHealth = UpdateUserHealth};
_enemy = new Player {Health = 10, Damage = 1, UpdateHealth = UpdateEnemyHealth};
_players.Add(new Player {health = 100, damage = 5, updateHealth = UpdateUserHealth, isHumanControlled = true});
_players.Add(new Player {health = 100, damage = 5, updateHealth = UpdateEnemyHealth, isHumanControlled = false});
_enemyLogic = new EnemyAi();
_enemyLogic.AttackCallback += EnemyAttack;
_enemyLogic.attackCallback += Attack;
_enemyLogic.defendCallback += Defend;
_enemyLogic.counterCallback += Counter;
}
private void Start()
{
attackButton.onClick.AddListener(PlayerAttack);
attackButton.onClick.AddListener(Attack);
bloodCounterButton.onClick.AddListener(BloodCounter);
defendButton.onClick.AddListener(Defend);
counterButton.onClick.AddListener(Counter);
foreach (var player in _players)
{
player.updateHealth(player.health);
}
_turnOrder.Add(UserTakeTurn);
_turnOrder.Add(_enemyLogic.TakeTurn);
_turnOrder[_currentTurnIndex]();
UpdateUserHealth();
UpdateEnemyHealth();
Debug.Log(CurrentPlayer.isHumanControlled ? "Start user turn" : "Start enemy turn");
StartTurn();
}
private void UpdateUserHealth()
private void UpdateUserHealth(int health)
{
userHealth.text = $"Health: {_user.Health}";
userHealth.text = $"Health: {health}";
}
private void UpdateEnemyHealth()
private void UpdateEnemyHealth(int health)
{
enemyHealth.text = $"Health: {_enemy.Health}";
enemyHealth.text = $"Health: {health}";
}
private void FinishTurn()
{
_currentTurnIndex = ++_currentTurnIndex % _turnOrder.Count;
_turnOrder[_currentTurnIndex]();
}
private void PlayerAttack()
{
Attack(_user, _enemy);
// TODO: disable hud
attackButton.interactable = false;
attackButton.interactable = !CurrentPlayer.isHumanControlled;
bloodCounterButton.interactable = !CurrentPlayer.isHumanControlled;
defendButton.interactable = !CurrentPlayer.isHumanControlled;
counterButton.interactable = !CurrentPlayer.isHumanControlled;
_currentPlayerIndex = ++_currentPlayerIndex % _players.Count;
StartTurn();
}
private void Attack()
{
// TODO: when target selection is a thing this will need to be changed.
var victimIndex = (_currentPlayerIndex + 1) % _players.Count;
Attack(CurrentPlayer, _players[victimIndex]);
FinishTurn();
}
private void EnemyAttack()
private void BloodCounter()
{
Attack(_enemy, _user);
CurrentPlayer.isBloodCounter = true;
FinishTurn();
}
private void UserTakeTurn()
private void Defend()
{
CurrentPlayer.damageReduction = 0.4f;
CurrentPlayer.startTurnEffects = ResetDamageReduction;
FinishTurn();
}
private void Counter()
{
CurrentPlayer.isCounter = true;
FinishTurn();
}
private void StartTurn()
{
CurrentPlayer.isCounter = false;
if (CurrentPlayer.isStunned)
{
Debug.Log("stunned, skipping turn");
CurrentPlayer.isStunned = false;
FinishTurn();
return;
}
// TODO: enable hud.
attackButton.interactable = true;
attackButton.interactable = CurrentPlayer.isHumanControlled;
bloodCounterButton.interactable = CurrentPlayer.isHumanControlled;
defendButton.interactable = CurrentPlayer.isHumanControlled;
counterButton.interactable = CurrentPlayer.isHumanControlled;
CurrentPlayer.startTurnEffects?.Invoke(CurrentPlayer);
CurrentPlayer.startTurnEffects = null;
// TODO: controller.
if (!CurrentPlayer.isHumanControlled)
{
_enemyLogic.TakeTurn();
}
}
private void ResetDamageReduction(Player p)
{
p.damageReduction = 1f;
}
private void Attack(Player attacker, Player victim)
{
victim.Health -= attacker.Damage;
victim.UpdateHealth();
if (victim.Health <= 0)
if (victim.isCounter)
{
attacker.isStunned = true;
Debug.Log("COUNTER");
return;
}
victim.TakeDamage((int)(attacker.damage * attacker.damageModification));
// damage mod is spent whenever they attack.
attacker.damageModification = 1;
attacker.isBloodCounter = false;
if (victim.health <= 0)
{
Debug.Log("The victim died!");
}
+30 -2
View File
@@ -1,11 +1,39 @@
using System;
using UnityEngine;
using Random = System.Random;
public class EnemyAi
{
public Action AttackCallback;
public Action attackCallback;
public Action defendCallback;
public Action counterCallback;
private Random rng;
public EnemyAi()
{
rng = new Random(1337);
}
// TODO: will need more information, not sure what info should be exposed.
public void TakeTurn()
{
AttackCallback();
var number = rng.Next(1, 4);
Debug.Log($"enemy rolled {number}");
switch (number)
{
case 1:
attackCallback();
break;
case 2:
defendCallback();
break;
case 3:
counterCallback();
break;
default:
Debug.LogWarning($"Enemy rolled something that it can't do {number}");
break;
}
}
}
+29
View File
@@ -0,0 +1,29 @@
using System;
public class Player
{
public int health;
public int damage;
public float damageReduction = 1.0f;
public float damageModification = 1.0f;
public bool isBloodCounter;
public bool isCounter;
public bool isStunned;
public bool isHumanControlled;
public Action<int> updateHealth;
public Action<Player> startTurnEffects;
public void TakeDamage(int incomingDamage)
{
var modifiedDamage = (int) (incomingDamage * damageReduction);
// Not sure if blood counter should negate damage or not...
if (isBloodCounter)
{
damageModification += (modifiedDamage * 0.15F);
}
health -= modifiedDamage;
updateHealth(health);
}
}
+11
View File
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 374046a0afc221d459f369d95fc41b42
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: