I'd decided to break the mold and make my first game based on RPG mechanics (note sarcasm). An RPG style action bar would be a reasonable and fun way to get started as it's limited in scope but still challenging.
I have my spell bar and three targets. I click a target, cast a spell, start the cast, put the spell on recovery cooldown, set the global cooldown, the spell goes through a casting phase then casts, the effect is applied to the target, mana is spent, the spell goes on cooldown or is removed depending. Casting is animated, cooldowns are typical gray shading. Then the other rules start to come into play.
- When a spell is being the cast the target cannot be changed.
- When a spell is on cool down we want a standard global cool down effect.
- When a target has an effect we put a smaller version of the icon near it which also has the same cooldown effect based on remaining duration.
- When the effect expires we need to remove it.
- When something is on cooldown and another cooldown is triggered the cooldown must become the longer of the two.
- Each spell on a target has an effect such as damage or shield
- Some effects, like shield, mitigate other effects, like damage
I've ended up with too many UI concerns checking the same pieces of data. So my buttons have states, I tried the State Pattern, but ended up with the same type of crappy code in determining what state to set my objects to.
Take the example that a spell can't be cast if it's on cooldown. Pretty straight forward as that's information the spell has about itself. You can't cast if you have insufficient mana, getting more complicated because now I need to know about the state of the player to properly render the spell as shaded cause it's not available, can't cast on player if effect already exists, getting ugly now I need knowledge about the target and their effects as well. Every one of these new situations resulted in my code bloating or getting stringy.
I'm event driven enough to detect clicks but should I go farther and be creating events for everything such as OnSpellCastBegin, OnSpellCastInProgress, OnSpellCastComplete, OnManaChanged, OnTargetChanged?
I would think it's the spell classes responsibility to answer if it can be cast but this requires it have a reference to the Player, and the PlayersTarget, and whatever else in the game in the future can effect a spell cast. What kind of design approach would support future adjustments to if a spell could be cast that followed the open/closed principal where I didn't have to modify the spell class every time?