# Unit 6 – Advanced Practice: GameCharacter, Warrior, Mage

Building on the basic character hierarchy, this practice makes combat 
functional: a warrior's armour soaks up part of every hit, a mage burns 
through mana to cast damaging spells, and a set of party functions lets 
you inspect or act on any group of characters regardless of what mix of 
types it contains.

## Instructions

### GameCharacter

1. `GameCharacter` now has a `takeDamage()` method — Warrior needs to 
   replace it with armoured behaviour. What does `takeDamage()` need to 
   become so that Warrior can replace it?
2. What do `role()` and `status()` need so that Warrior and Mage can 
   each provide their own versions?

### Warrior

3. `Warrior` is a `GameCharacter` — what does it add, and should that 
   value be changeable?
4. Give the warrior its own role name.
5. When a warrior takes a hit, armour absorbs some of the damage. 
   Effective damage = `amount - armour`, but always at least 1 — a hit 
   always hurts a little. Print: 
   `"Warrior armour absorbs <absorbed> damage."`
6. Give the warrior its own status line showing the armour rating.
   Expected format: `"Warrior: Thor — HP 80/100, Armour: 15"`.

### Mage

7. `Mage` is a `GameCharacter` with a mana pool — what values does it 
   need, and which one changes during a fight?
8. Give the mage its own role name.
9. Casting a spell costs mana and damages the target. If there is not 
   enough mana, print `"<characterName> has insufficient mana."` and 
   stop. Otherwise spend the mana, deal the damage, and print 
   `"<characterName> has <mana>/<maxMana> mana remaining."`.
10. Give the mage its own status line showing current and maximum mana.
    Expected format: `"Mage: Merlin — HP 60/80, Mana: 30/50"`.

### Party

11. `Party` holds a group of characters — what does it need to store 
    them?
12. `add(character)` — adds a character to the party.
13. `printParty()` — show the status of every character in the group.
14. `aliveCount()` — how many characters in the group are still standing?
15. `isWarrior(character)` — is this character a warrior?
16. `tryCastSpell(character, target)` — if the character is a mage, cast 
    a spell at the target (`manaCost=10, damage=25`); otherwise print
    `"<characterName> cannot cast spells."`.
    Once you confirm a character is a mage, can you call `castSpell` on 
    them directly?

### Testing

1. Create `Warrior("Thor", 100, 15)` and call `status()` — expect role, 
   HP, and armour.
2. Create `Mage("Merlin", 80, 50)` and call `status()` — expect role, 
   HP, and mana.
3. Call `thor.takeDamage(20)` — armour absorbs 15, effective damage is 5.
4. Call `merlin.castSpell(thor, 10, 25)` — `castSpell` calls
   `thor.takeDamage(25)`; Thor's armour absorbs 15, effective damage is
   10. Merlin spends 10 mana.
5. Call `merlin.castSpell(thor, 100, 999)` — Merlin does not have 100 
   mana; the insufficient mana message appears.
6. Create a `Party`. Call `add(thor)` and `add(merlin)` on it.
7. Call `party.isWarrior(thor)` — the result is `true`.
8. Call `party.tryCastSpell(thor, merlin)` — Thor cannot cast spells; 
   expect the message.
9. Call `party.aliveCount()` — count how many characters are still 
   standing.
10. Call `party.printParty()` — every character's status, in order.
