Battle UML - UQcsse3200/2026-studio-3 GitHub Wiki
classDiagram
class CardConfigLoader {
+loadCards() List~CardConfig~
+loadCards(String filename) List~CardConfig~
}
class CardValidator {
+validate(CardConfig) List~String~
+isValid(CardConfig) boolean
}
class CardCooldown {
+roundsFor(CardConfig) int
}
class CardConfig {
+id String
+name String
+cost int
+type CardType
+effects EffectConfig[]
+upgrade CardUpgradeConfig
}
class CardUpgradeConfig {
+name String
+cost int
+effects EffectConfig[]
}
class CardInstance {
<<record>>
+instanceId String
+cardId String
+upgradeLevel int
+isUpgraded() boolean
+upgrade() CardInstance
}
class CardInstanceFactory {
+create(String cardId) CardInstance
+createUpgraded(String cardId) CardInstance
}
class CardResolver {
+resolve(CardConfig, CardInstance) ResolvedCard
}
class ResolvedCard {
<<record>>
+instanceId String
+cost int
+effects List~EffectConfig~
+upgraded boolean
}
class PlayerDeck {
+addCard(String)
+removeCard(String) boolean
+getCards() List~CardInstance~
+copy() PlayerDeck
}
class PlayerDeckFactory {
+createStarterDeck() PlayerDeck
+getStarterDeckCardIds() List~String~
}
class BattleDeck {
+drawPile List~CardInstance~
+hand List~CardInstance~
+discardPile List~CardInstance~
+drawOne() String
+playCard(String) boolean
+discardCardInstance(String) CardInstance
+reshuffleDiscardIntoDrawPile() boolean
}
class CardCooldownTracker {
+trackDiscard(CardInstance, int)
+isOnCooldown(CardInstance) boolean
+tickRoundAndRetrieve() List~String~
}
class CardPlayRequest {
<<record>>
+cardId String
+target CardPlayTarget
+self(String)$ CardPlayRequest
+singleEnemy(String,String)$ CardPlayRequest
}
class CardPlayResult {
<<record>>
+success boolean
+energyCost int
+enemyEffects() List~ResolvedCardEffect~
+playerEffects() List~ResolvedCardEffect~
+success(...)$ CardPlayResult
+failure(...)$ CardPlayResult
}
class EffectExecutor {
+resolve(String, EffectConfig, TargetType, int, PlayerEffectState) ResolvedCardEffect
}
class CardPlayService {
+canPlay(CardPlayRequest) boolean
+playCard(CardPlayRequest) CardPlayResult
+onPlayerRoundStart() List~String~
+handInstances() List~CardInstance~
+rearrangeHand(List~CardInstance~) boolean
}
class CardEffectHandler {
+applyEnemyEffects(List~Entity~, List~ResolvedCardEffect~)
+applyPlayerEffects(List~ResolvedCardEffect~, Entity)
+getLivingEnemyTargets(CardPlayRequest, List~Entity~) List~Entity~
}
class Team3CardPlayAdapter {
+create()
}
class Team7PlayerStateAdapter {
+currentEnergy() int
+statusValue(EffectType) int
+applyPlayerEffects(List~ResolvedCardEffect~)
}
class BattleController { <<see Battle UML>> }
class CombatStatsComponent { <<see Battle UML>> }
class EnergyComponent { <<see Battle UML>> }
CardConfigLoader --> CardConfig : loads
CardConfigLoader --> CardValidator : validates with
CardValidator --> CardConfig
CardValidator --> CardUpgradeConfig
CardConfig *-- CardUpgradeConfig : upgrade
CardInstanceFactory --> CardInstance : creates
CardResolver --> CardInstance
CardResolver --> CardConfig
CardResolver --> ResolvedCard : produces
PlayerDeck --> CardInstanceFactory
PlayerDeck o-- CardInstance : owns
PlayerDeckFactory --> PlayerDeck : builds
BattleDeck --> PlayerDeck : seeded from
BattleDeck o-- CardInstance : draw/hand/discard
CardCooldownTracker --> BattleDeck
CardCooldownTracker --> CardInstance
CardPlayService --> BattleDeck
CardPlayService --> CardCooldownTracker
CardPlayService --> CardValidator
CardPlayService --> CardCooldown
CardPlayService --> CardPlayRequest
CardPlayService --> CardPlayResult : produces
CardPlayService --> EnergyComponent
EffectExecutor --> CardPlayResult
CardEffectHandler --> CardPlayRequest
CardEffectHandler --> CombatStatsComponent
Team3CardPlayAdapter --> CardPlayRequest
Team3CardPlayAdapter --> BattleController
Team7PlayerStateAdapter --> EnergyComponent
Team7PlayerStateAdapter --> CombatStatsComponent
class BattleController:::ref
class CombatStatsComponent:::ref
class EnergyComponent:::ref
class CardInstance:::rec
class ResolvedCard:::rec
class CardPlayRequest:::rec
class CardPlayResult:::rec
classDef ref fill:#dfe9e2,stroke:#2b5d59,stroke-dasharray: 4 3,color:#173936;
classDef rec fill:#e6e2f2,stroke:#4a4470,color:#2a2545;
classDiagram
class BattlePhase {
<<enum>>
SETUP
PLAYER_TURN
CARD_RESOLVING
ENEMY_TURN
VICTORY
DEFEAT
}
class BattleEvent {
<<enum>>
CARD_PLAY_REQUESTED
CARD_RESOLVED
PLAYER_END_REQUESTED
ENEMY_ACTION_RESOLVED
ENEMIES_DEFEATED
PLAYER_DEFEATED
}
class BattleTransitions {
+getNextPhase(BattlePhase, BattleEvent) BattlePhase
}
class BattleController {
+handle(BattleEvent)
+start()
+endPlayerTurn()
+submitCardPlayRequest(CardPlayRequest) boolean
+getCurrentPhase() BattlePhase
+addPhaseChangeListener(...)
+addEnemyEffectsListener(...)
}
class BattleActions {
+isPlayerTurn() boolean
+create()
}
class DeckEditorComponent {
+open()
+create()
}
class CombatStatsComponent {
+health int
+armour int
+block int
+takeDamage(int)
+applyStatusEffect(StatusEffect)
+absorbDamageWithArmour(int) int
}
class EnemyStatsDisplay {
+updateEnemyHealthUI(int,int)
+updateEnemyArmourUI(int)
}
class PlayerStatsDisplay {
+updatePlayerHealthUI(int,int)
+updatePlayerEnergyUI(int,int)
}
class PlayerStatsTopDisplay {
+updatePlayerPietyUI(int)
+updatePlayerMoneyUI(int)
}
class CombatBackgroundComponent {
+getLayer() int
+getZIndex() float
}
class CombatBackgroundConfig {
+id String
+texture String
}
class CombatBackgroundConfigs {
+get(String) CombatBackgroundConfig
}
class GamePauseService { <<external>> }
class BattleScreen {
+createUI()
+render(float)
}
class CardPlayService { <<see Cards UML>> }
class CardPlayRequest { <<see Cards UML>> }
class CardPlayResult { <<see Cards UML>> }
class CardEffectHandler { <<see Cards UML>> }
class Team3CardPlayAdapter { <<see Cards UML>> }
class ClickableFactory { <<see UI Framework UML>> }
class PopupDisplay { <<see UI Framework UML>> }
class ForestGameArea { <<core game area, background hook added here>> }
BattleController --> BattleTransitions
BattleController --> BattleEvent
BattleController --> BattlePhase
BattleController --> CombatStatsComponent
BattleController --> CardPlayService
BattleController --> CardPlayRequest
BattleController --> CardPlayResult
BattleController --> CardEffectHandler
BattleActions --> BattleController
BattleActions --> BattleEvent
BattleActions --> BattlePhase
DeckEditorComponent --> CardPlayService
DeckEditorComponent --> ClickableFactory
DeckEditorComponent --> PopupDisplay
EnemyStatsDisplay --> CombatStatsComponent
PlayerStatsDisplay --> CombatStatsComponent
CombatBackgroundConfigs o-- CombatBackgroundConfig
BattleScreen --> BattleController : builds
BattleScreen --> CardPlayService : builds
BattleScreen --> Team3CardPlayAdapter : builds
BattleScreen --> GamePauseService
BattleScreen --> ForestGameArea
BattleScreen --> CombatBackgroundComponent
class CardPlayService:::ref
class CardPlayRequest:::ref
class CardPlayResult:::ref
class CardEffectHandler:::ref
class Team3CardPlayAdapter:::ref
class ClickableFactory:::ref
class PopupDisplay:::ref
class ForestGameArea:::ref
class GamePauseService:::ext
class BattlePhase:::enm
class BattleEvent:::enm
classDef ref fill:#dfe9e2,stroke:#2b5d59,stroke-dasharray: 4 3,color:#173936;
classDef ext fill:#f1e3d3,stroke:#8a5a34,stroke-dasharray: 4 3,color:#3a2a1a;
classDef enm fill:#e6e2f2,stroke:#4a4470,color:#2a2545;
classDiagram
class Clickable {
<<abstract>>
#disabled boolean
#x float
#y float
#trigger String
#args Object[]
#label String
+getTrigger() String
+getBtn() Button
+showNow()
+hideNow()
+remove()
#onEnter()
#onExit()
#onClick()
}
class InOutOnTrigger {
#targetX float
#targetY float
#isAnimating boolean
+slideUp()
#slideDown()
+setAnimationDuration(float)
}
class DragNDrop {
+dragSource Source
#onClick()
+createDragVisual(Button) Button
}
class GatedClickable {
+create()
}
class ClickableRecord {
<<record>>
+text String
+trigger String
+variant String
+width float
+height float
+disabled boolean
+builder(String)$ Builder
}
class ClickableFactory {
+records List~ClickableRecord~
+clickables List~Clickable~
+loadRecordsFromJson(Path)$ List~ClickableRecord~
+registerVariant(String, ClickableSupplier)$
+registerInstanceVariant(String, ClickableSupplier)
+rebuildHand(List~ClickableRecord~)
+rebuildByTrigger(String, List~ClickableRecord~)
+getByTrigger(String) List~Clickable~
+bringToFront()
}
class CardImageSkins {
+forTexturePath(String)$ Skin
}
class PopupDisplay {
+title String
+window Window
+content Table
+show()
+hide()
+isShowing() boolean
+getContentTable() Table
+setOnShow(Runnable)
+setOnHide(Runnable)
}
class DeckEditorComponent { <<see Battle UML>> }
class BattleScreen { <<see Battle UML>> }
InOutOnTrigger --|> Clickable
GatedClickable --|> Clickable
DragNDrop --|> InOutOnTrigger
Clickable --> ClickableRecord : built from
ClickableFactory --> Clickable : builds
ClickableFactory --> ClickableRecord
ClickableFactory --> InOutOnTrigger
ClickableFactory --> DragNDrop
ClickableFactory --> GatedClickable
Clickable ..> CardImageSkins : image-button skins
DeckEditorComponent --> ClickableFactory
DeckEditorComponent --> PopupDisplay
BattleScreen --> ClickableFactory
BattleScreen --> PopupDisplay
class DeckEditorComponent:::ref
class BattleScreen:::ref
class ClickableRecord:::rec
classDef ref fill:#dfe9e2,stroke:#2b5d59,stroke-dasharray: 4 3,color:#173936;
classDef rec fill:#e6e2f2,stroke:#4a4470,color:#2a2545;