diff --git a/src/dusk/rpg/CMakeLists.txt b/src/dusk/rpg/CMakeLists.txt index 51db8064..519e13eb 100644 --- a/src/dusk/rpg/CMakeLists.txt +++ b/src/dusk/rpg/CMakeLists.txt @@ -11,10 +11,7 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME} ) # Subdirs -add_subdirectory(battle) add_subdirectory(cutscene) add_subdirectory(entity) add_subdirectory(overworld) - -add_subdirectory(story) add_subdirectory(item) \ No newline at end of file diff --git a/src/dusk/rpg/battle/CMakeLists.txt b/src/dusk/rpg/battle/CMakeLists.txt deleted file mode 100644 index 5b0a546c..00000000 --- a/src/dusk/rpg/battle/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (c) 2026 Dominic Masters -# -# This software is released under the MIT License. -# https://opensource.org/licenses/MIT - -# Sources -target_sources(${DUSK_LIBRARY_TARGET_NAME} - PUBLIC - battle.c - battlefighter.c - party.c -) diff --git a/src/dusk/rpg/battle/battle.c b/src/dusk/rpg/battle/battle.c deleted file mode 100644 index cdba1b95..00000000 --- a/src/dusk/rpg/battle/battle.c +++ /dev/null @@ -1,223 +0,0 @@ -/** - * Copyright (c) 2026 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "battle.h" -#include "assert/assert.h" -#include "util/memory.h" - -battle_t BATTLE; - -void battleInit(void) { - memoryZero(&BATTLE, sizeof(battle_t)); - for(uint8_t i = 0; i < BATTLE_FIGHTER_COUNT_MAX; i++) { - BATTLE.fighters[i].id = i; - } -} - -uint8_t battleGetAvailableFighter(void) { - for(uint8_t i = 0; i < BATTLE_FIGHTER_COUNT_MAX; i++) { - if(BATTLE.fighters[i].status == BATTLE_FIGHTER_STATUS_NULL) return i; - } - - return 0xFF; -} - -battlefighter_t *battleAddFighter( - const battlefighterteam_t team, - const battlefightercontroller_t controller, - const battlefighterstats_t stats, - const uint16_t healthMax, - const uint16_t mpMax -) { - const uint8_t index = battleGetAvailableFighter(); - if(index == 0xFF) return NULL; - - battlefighter_t *fighter = &BATTLE.fighters[index]; - battleFighterInit(fighter, team, controller, stats, healthMax, mpMax); - return fighter; -} - -void battleStart( - const battleencountertype_t encounterType, - const bool_t fleeAvailable -) { - assertTrue(encounterType < BATTLE_ENCOUNTER_COUNT, "Invalid encounter type"); - - BATTLE.encounterType = encounterType; - BATTLE.fleeAvailable = fleeAvailable; - BATTLE.result = BATTLE_RESULT_NONE; - BATTLE.round = 1; - BATTLE.turnIndex = 0; - battleBuildTurnOrder(true); - - BATTLE.active = true; -} - -void battleDispose(void) { - battleInit(); -} - -battlefighter_t *battleGetCurrentFighter(void) { - if(!BATTLE.active) return NULL; - if(BATTLE.turnIndex >= BATTLE.turnCount) return NULL; - return &BATTLE.fighters[BATTLE.turnOrder[BATTLE.turnIndex]]; -} - -uint8_t battleGetAliveCount(const battlefighterteam_t team) { - uint8_t count = 0; - for(uint8_t i = 0; i < BATTLE_FIGHTER_COUNT_MAX; i++) { - if(BATTLE.fighters[i].team != team) continue; - if(!battleFighterIsAlive(&BATTLE.fighters[i])) continue; - count++; - } - return count; -} - -void battleResolveAttack( - battlefighter_t *attacker, - battlefighter_t *defender -) { - assertNotNull(attacker, "Attacker cannot be NULL"); - assertNotNull(defender, "Defender cannot be NULL"); - - const int32_t rawDamage = - (int32_t)attacker->stats.attack - (int32_t)defender->stats.defense; - const uint16_t damage = rawDamage > 0 ? (uint16_t)rawDamage : 1; - - defender->health = damage >= defender->health ? 0 : defender->health - damage; - if(defender->health == 0) defender->status = BATTLE_FIGHTER_STATUS_DEAD; -} - -void battleNextTurn(void) { - BATTLE.turnIndex++; - if(BATTLE.turnIndex < BATTLE.turnCount) return; - - BATTLE.round++; - BATTLE.turnIndex = 0; - battleBuildTurnOrder(false); -} - -battleresult_t battleCheckResult(void) { - if(BATTLE.result != BATTLE_RESULT_NONE) return BATTLE.result; - - if(battleGetAliveCount(BATTLE_FIGHTER_TEAM_ALLY) == 0) { - BATTLE.result = BATTLE_RESULT_LOSS; - } else if(battleGetAliveCount(BATTLE_FIGHTER_TEAM_ENEMY) == 0) { - BATTLE.result = BATTLE_RESULT_WIN; - } - - return BATTLE.result; -} - -void battlePlayerAttack(const uint8_t targetIndex) { - battlefighter_t *attacker = battleGetCurrentFighter(); - if(attacker == NULL) return; - if(attacker->controller != BATTLE_FIGHTER_CONTROLLER_PLAYER) return; - if(targetIndex >= BATTLE_FIGHTER_COUNT_MAX) return; - - battlefighter_t *defender = &BATTLE.fighters[targetIndex]; - if(!battleFighterIsAlive(defender)) return; - - battleResolveAttack(attacker, defender); - battleCheckResult(); - if(BATTLE.result == BATTLE_RESULT_NONE) battleNextTurn(); -} - -void battlePlayerFlee(void) { - battlefighter_t *fighter = battleGetCurrentFighter(); - if(fighter == NULL) return; - if(fighter->controller != BATTLE_FIGHTER_CONTROLLER_PLAYER) return; - if(!BATTLE.fleeAvailable) return; - - BATTLE.result = BATTLE_RESULT_FLED; -} - -void battleUpdate(void) { - if(!BATTLE.active) return; - if(BATTLE.result != BATTLE_RESULT_NONE) return; - - battlefighter_t *current = battleGetCurrentFighter(); - if(current == NULL) return; - - if(!battleFighterIsAlive(current)) { - battleNextTurn(); - return; - } - - if(current->controller != BATTLE_FIGHTER_CONTROLLER_AI) return; - - battlefighter_t *target = battleAIChooseTarget(current); - if(target != NULL) battleResolveAttack(current, target); - - battleCheckResult(); - if(BATTLE.result == BATTLE_RESULT_NONE) battleNextTurn(); -} - -void battleBuildTurnOrder(const bool_t applyEncounterBias) { - BATTLE.turnCount = 0; - for(uint8_t i = 0; i < BATTLE_FIGHTER_COUNT_MAX; i++) { - if(!battleFighterIsAlive(&BATTLE.fighters[i])) continue; - BATTLE.turnOrder[BATTLE.turnCount++] = i; - } - - // Insertion sort by speed descending -- fine for BATTLE_FIGHTER_COUNT_MAX. - for(uint8_t i = 1; i < BATTLE.turnCount; i++) { - const uint8_t key = BATTLE.turnOrder[i]; - const uint16_t keySpeed = BATTLE.fighters[key].stats.speed; - - int8_t j = (int8_t)i - 1; - while( - j >= 0 && BATTLE.fighters[BATTLE.turnOrder[j]].stats.speed < keySpeed - ) { - BATTLE.turnOrder[j + 1] = BATTLE.turnOrder[j]; - j--; - } - BATTLE.turnOrder[j + 1] = key; - } - - if(!applyEncounterBias) return; - - if(BATTLE.encounterType == BATTLE_ENCOUNTER_PLAYER_ADVANTAGE) { - battleMoveTeamFirst(BATTLE_FIGHTER_TEAM_ALLY); - } else if(BATTLE.encounterType == BATTLE_ENCOUNTER_BACK_ATTACK) { - battleMoveTeamFirst(BATTLE_FIGHTER_TEAM_ENEMY); - } -} - -void battleMoveTeamFirst(const battlefighterteam_t team) { - uint8_t sorted[BATTLE_FIGHTER_COUNT_MAX]; - uint8_t count = 0; - - for(uint8_t i = 0; i < BATTLE.turnCount; i++) { - if(BATTLE.fighters[BATTLE.turnOrder[i]].team != team) continue; - sorted[count++] = BATTLE.turnOrder[i]; - } - for(uint8_t i = 0; i < BATTLE.turnCount; i++) { - if(BATTLE.fighters[BATTLE.turnOrder[i]].team == team) continue; - sorted[count++] = BATTLE.turnOrder[i]; - } - - memoryCopy(BATTLE.turnOrder, sorted, sizeof(uint8_t) * BATTLE.turnCount); -} - -battlefighter_t *battleAIChooseTarget(const battlefighter_t *fighter) { - const battlefighterteam_t enemyTeam = - fighter->team == BATTLE_FIGHTER_TEAM_ALLY ? - BATTLE_FIGHTER_TEAM_ENEMY : BATTLE_FIGHTER_TEAM_ALLY; - - battlefighter_t *weakest = NULL; - for(uint8_t i = 0; i < BATTLE_FIGHTER_COUNT_MAX; i++) { - battlefighter_t *candidate = &BATTLE.fighters[i]; - if(candidate->team != enemyTeam) continue; - if(!battleFighterIsAlive(candidate)) continue; - if(weakest == NULL || candidate->health < weakest->health) { - weakest = candidate; - } - } - - return weakest; -} diff --git a/src/dusk/rpg/battle/battle.h b/src/dusk/rpg/battle/battle.h deleted file mode 100644 index 786a874e..00000000 --- a/src/dusk/rpg/battle/battle.h +++ /dev/null @@ -1,194 +0,0 @@ -/** - * Copyright (c) 2026 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "battlefighter.h" - -#define BATTLE_FIGHTER_COUNT_MAX 8 - -typedef enum { - BATTLE_ENCOUNTER_REGULAR, - BATTLE_ENCOUNTER_PLAYER_ADVANTAGE, - BATTLE_ENCOUNTER_BACK_ATTACK, - - BATTLE_ENCOUNTER_COUNT -} battleencountertype_t; - -typedef enum { - BATTLE_RESULT_NONE, - BATTLE_RESULT_WIN, - BATTLE_RESULT_LOSS, - BATTLE_RESULT_FLED, - - BATTLE_RESULT_COUNT -} battleresult_t; - -typedef struct { - bool_t active; - battlefighter_t fighters[BATTLE_FIGHTER_COUNT_MAX]; - - battleencountertype_t encounterType; - bool_t fleeAvailable; - battleresult_t result; - - // Fighter indices (into fighters[]), sorted for the current round. - uint8_t turnOrder[BATTLE_FIGHTER_COUNT_MAX]; - uint8_t turnCount; - uint8_t turnIndex; - uint16_t round; -} battle_t; - -extern battle_t BATTLE; - -/** - * Initializes the battle system. Marks it as inactive with no fighters. - */ -void battleInit(void); - -/** - * Gets an available (unused) fighter slot index. - * - * @return The index of an available fighter slot, or 0xFF if none are - * available. - */ -uint8_t battleGetAvailableFighter(void); - -/** - * Adds a fighter to the battle in the next available slot. - * - * @param team The team the fighter belongs to. - * @param controller Who makes decisions for the fighter. - * @param stats The fighter's base combat stats. - * @param healthMax The fighter's maximum health. - * @param mpMax The fighter's maximum mp. - * @return Pointer to the newly added fighter, or NULL if the battle is - * already full. - */ -battlefighter_t *battleAddFighter( - const battlefighterteam_t team, - const battlefightercontroller_t controller, - const battlefighterstats_t stats, - const uint16_t healthMax, - const uint16_t mpMax -); - -/** - * Starts the battle: builds the opening turn order (biased by - * encounterType for the first round only) and marks the battle active. - * Call once every fighter has been added via battleAddFighter. - * - * @param encounterType Determines the opening round's turn order. - * @param fleeAvailable Whether the party may attempt to flee this battle. - */ -void battleStart( - const battleencountertype_t encounterType, - const bool_t fleeAvailable -); - -/** - * Disposes of the battle, clearing all fighters and marking it inactive. - */ -void battleDispose(void); - -/** - * Returns the fighter whose turn it currently is. - * - * @return Pointer to the active fighter, or NULL if the battle isn't - * active or has no living fighters left to act. - */ -battlefighter_t *battleGetCurrentFighter(void); - -/** - * Returns the number of living fighters on a team. - * - * @param team The team to count. - * @return Count of living fighters on that team. - */ -uint8_t battleGetAliveCount(const battlefighterteam_t team); - -/** - * Resolves a physical attack from attacker onto defender: damage is the - * attacker's attack stat minus the defender's defense stat (minimum 1), - * subtracted from the defender's health. The defender is marked dead - * once health reaches 0. - * - * @param attacker The attacking fighter. - * @param defender The defending fighter. - */ -void battleResolveAttack( - battlefighter_t *attacker, - battlefighter_t *defender -); - -/** - * Ends the current fighter's turn and advances to the next fighter in - * the turn order, starting a new round (rebuilding turn order purely by - * speed) once every fighter in the current round has acted. - */ -void battleNextTurn(void); - -/** - * Checks whether the battle has been won or lost, updating and - * returning BATTLE.result. Does nothing if a result has already been - * set (e.g. by a successful flee). - * - * @return The battle's current result. - */ -battleresult_t battleCheckResult(void); - -/** - * Submits the current fighter's attack against a target, if it is - * currently a player-controlled fighter's turn. Resolves the attack, - * checks for a battle result, and advances the turn. - * - * @param targetIndex Index into BATTLE.fighters of the target. - */ -void battlePlayerAttack(const uint8_t targetIndex); - -/** - * Submits a flee attempt for the current fighter's turn, if it is - * currently a player-controlled fighter's turn and fleeing is - * available for this battle. Always succeeds, ending the battle with - * BATTLE_RESULT_FLED. - */ -void battlePlayerFlee(void); - -/** - * Updates the battle simulation for one frame: resolves the current - * fighter's turn automatically if AI-controlled, otherwise waits for a - * player action via battlePlayerAttack/battlePlayerFlee. No-op if the - * battle isn't active or already has a result. - */ -void battleUpdate(void); - -/** - * Rebuilds BATTLE.turnOrder/turnCount from every currently living - * fighter, sorted by speed descending. - * - * @param applyEncounterBias If true, reorders the freshly speed-sorted - * queue so BATTLE.encounterType's favoured team goes first (used only - * for the opening round). - */ -void battleBuildTurnOrder(const bool_t applyEncounterBias); - -/** - * Stably partitions BATTLE.turnOrder so every fighter on the given team - * comes first, preserving each side's relative (speed-sorted) order. - * - * @param team The team to move to the front of the turn order. - */ -void battleMoveTeamFirst(const battlefighterteam_t team); - -/** - * Picks an AI target for fighter: the lowest-health living fighter on - * the opposing team. - * - * @param fighter The AI-controlled fighter choosing a target. - * @return The chosen target, or NULL if the opposing team has no - * living fighters. - */ -battlefighter_t *battleAIChooseTarget(const battlefighter_t *fighter); diff --git a/src/dusk/rpg/battle/battlefighter.c b/src/dusk/rpg/battle/battlefighter.c deleted file mode 100644 index 8d72d552..00000000 --- a/src/dusk/rpg/battle/battlefighter.c +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Copyright (c) 2026 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "battlefighter.h" -#include "assert/assert.h" -#include "util/memory.h" - -void battleFighterInit( - battlefighter_t *fighter, - const battlefighterteam_t team, - const battlefightercontroller_t controller, - const battlefighterstats_t stats, - const uint16_t healthMax, - const uint16_t mpMax -) { - assertNotNull(fighter, "Fighter pointer cannot be NULL"); - assertTrue(team < BATTLE_FIGHTER_TEAM_COUNT, "Invalid fighter team"); - assertTrue( - controller < BATTLE_FIGHTER_CONTROLLER_COUNT, - "Invalid fighter controller" - ); - - const uint8_t id = fighter->id; - memoryZero(fighter, sizeof(battlefighter_t)); - fighter->id = id; - fighter->status = BATTLE_FIGHTER_STATUS_NORMAL; - fighter->team = team; - fighter->controller = controller; - fighter->stats = stats; - fighter->healthMax = healthMax; - fighter->health = healthMax; - fighter->mpMax = mpMax; - fighter->mp = mpMax; -} - -bool_t battleFighterIsAlive(const battlefighter_t *fighter) { - assertNotNull(fighter, "Fighter pointer cannot be NULL"); - return fighter->status == BATTLE_FIGHTER_STATUS_NORMAL; -} diff --git a/src/dusk/rpg/battle/battlefighter.h b/src/dusk/rpg/battle/battlefighter.h deleted file mode 100644 index af032331..00000000 --- a/src/dusk/rpg/battle/battlefighter.h +++ /dev/null @@ -1,87 +0,0 @@ -/** - * Copyright (c) 2026 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "error/error.h" - -// An empty status means the slot in BATTLE.fighters is unused. -typedef enum { - BATTLE_FIGHTER_STATUS_NULL, - - BATTLE_FIGHTER_STATUS_NORMAL, - BATTLE_FIGHTER_STATUS_DEAD, - - BATTLE_FIGHTER_STATUS_COUNT -} battlefighterstatus_t; - -typedef enum { - BATTLE_FIGHTER_TEAM_ALLY, - BATTLE_FIGHTER_TEAM_ENEMY, - - BATTLE_FIGHTER_TEAM_COUNT -} battlefighterteam_t; - -typedef enum { - BATTLE_FIGHTER_CONTROLLER_PLAYER, - BATTLE_FIGHTER_CONTROLLER_AI, - - BATTLE_FIGHTER_CONTROLLER_COUNT -} battlefightercontroller_t; - -// Base combat stats, kept separate from the resource pools (health/mp) on -// battlefighter_t so that equipment/buffs can later modify them without -// touching current health/mp state. -typedef struct { - uint16_t attack; - uint16_t defense; - uint16_t magic; - uint16_t speed; - uint16_t luck; -} battlefighterstats_t; - -typedef struct { - uint8_t id; - battlefighterstatus_t status; - battlefighterteam_t team; - battlefightercontroller_t controller; - - uint16_t health; - uint16_t healthMax; - uint16_t mp; - uint16_t mpMax; - - battlefighterstats_t stats; -} battlefighter_t; - -/** - * Initializes a battle fighter in place, filling health/mp to their maximum - * values and setting its status to normal. - * - * @param fighter Pointer to the fighter to initialize. - * @param team The team the fighter belongs to. - * @param controller Who makes decisions for the fighter. - * @param stats The fighter's base combat stats. - * @param healthMax The fighter's maximum health. - * @param mpMax The fighter's maximum mp. - */ -void battleFighterInit( - battlefighter_t *fighter, - const battlefighterteam_t team, - const battlefightercontroller_t controller, - const battlefighterstats_t stats, - const uint16_t healthMax, - const uint16_t mpMax -); - -/** - * Returns true if the fighter is in a state where it can still act (i.e. - * is not dead). - * - * @param fighter Pointer to the fighter to check. - * @returns True if the fighter can act. - */ -bool_t battleFighterIsAlive(const battlefighter_t *fighter); diff --git a/src/dusk/rpg/battle/party.c b/src/dusk/rpg/battle/party.c deleted file mode 100644 index 0350949d..00000000 --- a/src/dusk/rpg/battle/party.c +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Copyright (c) 2026 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "party.h" -#include "assert/assert.h" -#include "util/memory.h" - -party_t PARTY; - -void partyInit(void) { - memoryZero(&PARTY, sizeof(party_t)); - for(uint8_t i = 0; i < PARTY_MEMBER_COUNT_MAX; i++) { - PARTY.members[i].id = i; - } - for(uint8_t i = 0; i < PARTY_ACTIVE_SIZE_MAX; i++) { - PARTY.order[i] = PARTY_ORDER_EMPTY; - } -} - -uint8_t partyGetAvailableMember(void) { - for(uint8_t i = 0; i < PARTY_MEMBER_COUNT_MAX; i++) { - if(PARTY.members[i].status == BATTLE_FIGHTER_STATUS_NULL) return i; - } - - return 0xFF; -} - -battlefighter_t *partyAddMember( - const battlefighterstats_t stats, - const uint16_t healthMax, - const uint16_t mpMax -) { - const uint8_t index = partyGetAvailableMember(); - if(index == 0xFF) return NULL; - - battlefighter_t *member = &PARTY.members[index]; - battleFighterInit( - member, BATTLE_FIGHTER_TEAM_ALLY, BATTLE_FIGHTER_CONTROLLER_PLAYER, - stats, healthMax, mpMax - ); - - for(uint8_t i = 0; i < PARTY_ACTIVE_SIZE_MAX; i++) { - if(PARTY.order[i] != PARTY_ORDER_EMPTY) continue; - PARTY.order[i] = index; - break; - } - - return member; -} - -battlefighter_t *partyGetOrderMember(const uint8_t slot) { - assertTrue(slot < PARTY_ACTIVE_SIZE_MAX, "Invalid party order slot"); - - const uint8_t index = PARTY.order[slot]; - if(index == PARTY_ORDER_EMPTY) return NULL; - return &PARTY.members[index]; -} - -void partySetOrder(const uint8_t slot, const uint8_t memberIndex) { - assertTrue(slot < PARTY_ACTIVE_SIZE_MAX, "Invalid party order slot"); - assertTrue( - memberIndex == PARTY_ORDER_EMPTY || memberIndex < PARTY_MEMBER_COUNT_MAX, - "Invalid party member index" - ); - - PARTY.order[slot] = memberIndex; -} diff --git a/src/dusk/rpg/battle/party.h b/src/dusk/rpg/battle/party.h deleted file mode 100644 index 5f958169..00000000 --- a/src/dusk/rpg/battle/party.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Copyright (c) 2026 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "battlefighter.h" - -#define PARTY_MEMBER_COUNT_MAX 4 -#define PARTY_ACTIVE_SIZE_MAX 3 -#define PARTY_ORDER_EMPTY 0xFF - -typedef struct { - battlefighter_t members[PARTY_MEMBER_COUNT_MAX]; - - // Maps an active battle slot to the roster member filling it, or - // PARTY_ORDER_EMPTY if the slot is unfilled. Only the first - // PARTY_ACTIVE_SIZE_MAX of the PARTY_MEMBER_COUNT_MAX roster members - // can be in the active lineup at once. - uint8_t order[PARTY_ACTIVE_SIZE_MAX]; -} party_t; - -extern party_t PARTY; - -/** - * Initializes the party system with an empty roster and order. - */ -void partyInit(void); - -/** - * Gets an available (unused) party member slot index. - * - * @return The index of an available slot, or 0xFF if the party is full. - */ -uint8_t partyGetAvailableMember(void); - -/** - * Adds a member to the party roster in the next available slot. Party - * members are always allies controlled by the player. If there is a - * free active order slot, the new member is placed into it. - * - * @param stats The member's base combat stats. - * @param healthMax The member's maximum health. - * @param mpMax The member's maximum mp. - * @return Pointer to the newly added party member, or NULL if the party is - * already full. - */ -battlefighter_t *partyAddMember( - const battlefighterstats_t stats, - const uint16_t healthMax, - const uint16_t mpMax -); - -/** - * Gets the roster member currently occupying an active order slot. - * - * @param slot The active order slot to query. - * @return Pointer to the member in that slot, or NULL if the slot is - * empty. - */ -battlefighter_t *partyGetOrderMember(const uint8_t slot); - -/** - * Assigns a roster member to an active order slot, replacing whatever - * was there. Use PARTY_ORDER_EMPTY to clear a slot. - * - * @param slot The active order slot to assign. - * @param memberIndex The roster member index to place there, or - * PARTY_ORDER_EMPTY to clear the slot. - */ -void partySetOrder(const uint8_t slot, const uint8_t memberIndex); diff --git a/src/dusk/rpg/cutscene/item/CMakeLists.txt b/src/dusk/rpg/cutscene/item/CMakeLists.txt index 5a0f884f..a3ce80fe 100755 --- a/src/dusk/rpg/cutscene/item/CMakeLists.txt +++ b/src/dusk/rpg/cutscene/item/CMakeLists.txt @@ -14,4 +14,3 @@ add_subdirectory(entity) add_subdirectory(item) add_subdirectory(maparea) add_subdirectory(ui) -add_subdirectory(battle) diff --git a/src/dusk/rpg/cutscene/item/battle/CMakeLists.txt b/src/dusk/rpg/cutscene/item/battle/CMakeLists.txt deleted file mode 100644 index 8c48be10..00000000 --- a/src/dusk/rpg/cutscene/item/battle/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2026 Dominic Masters -# -# This software is released under the MIT License. -# https://opensource.org/licenses/MIT - -target_sources(${DUSK_LIBRARY_TARGET_NAME} - PUBLIC - cutscenestartbattle.c -) diff --git a/src/dusk/rpg/cutscene/item/battle/cutscenestartbattle.c b/src/dusk/rpg/cutscene/item/battle/cutscenestartbattle.c deleted file mode 100644 index 8d8aab55..00000000 --- a/src/dusk/rpg/cutscene/item/battle/cutscenestartbattle.c +++ /dev/null @@ -1,71 +0,0 @@ -/** - * Copyright (c) 2026 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "rpg/cutscene/item/cutsceneitem.h" -#include "rpg/battle/party.h" -#include "scene/scene.h" - -void cutsceneStartBattleStart( - const cutsceneitem_t *item, - cutsceneitemdata_t *data -) { - const cutscenestartbattle_t *config = &item->startBattle; - - battleInit(); - - for(uint8_t i = 0; i < PARTY_ACTIVE_SIZE_MAX; i++) { - battlefighter_t *member = partyGetOrderMember(i); - if(member == NULL) continue; - - battlefighter_t *fighter = battleAddFighter( - BATTLE_FIGHTER_TEAM_ALLY, BATTLE_FIGHTER_CONTROLLER_PLAYER, - member->stats, member->healthMax, member->mpMax - ); - if(fighter == NULL) continue; - - fighter->health = member->health; - fighter->mp = member->mp; - fighter->status = member->status; - } - - for(uint8_t i = 0; i < config->enemyCount; i++) { - const cutscenestartbattleenemy_t *enemy = &config->enemies[i]; - battleAddFighter( - BATTLE_FIGHTER_TEAM_ENEMY, BATTLE_FIGHTER_CONTROLLER_AI, - enemy->stats, enemy->healthMax, enemy->mpMax - ); - } - - battleStart(config->encounterType, config->fleeAvailable); - sceneSet(SCENE_TYPE_BATTLE); -} - -bool_t cutsceneStartBattleUpdate( - const cutsceneitem_t *item, - cutsceneitemdata_t *data -) { - if(BATTLE.result == BATTLE_RESULT_NONE) return false; - - // Sync ally HP/MP back to the persistent party roster. Relies on - // ally fighters having been added to BATTLE.fighters in the same - // order partyGetOrderMember() iterates, starting at index 0 (see - // cutsceneStartBattleStart). - uint8_t allySlot = 0; - for(uint8_t i = 0; i < PARTY_ACTIVE_SIZE_MAX; i++) { - battlefighter_t *member = partyGetOrderMember(i); - if(member == NULL) continue; - - battlefighter_t *fighter = &BATTLE.fighters[allySlot++]; - member->health = fighter->health; - member->mp = fighter->mp; - member->status = fighter->status; - } - - sceneSet(SCENE_TYPE_OVERWORLD); - battleDispose(); - return true; -} diff --git a/src/dusk/rpg/cutscene/item/battle/cutscenestartbattle.h b/src/dusk/rpg/cutscene/item/battle/cutscenestartbattle.h deleted file mode 100644 index 770d1690..00000000 --- a/src/dusk/rpg/cutscene/item/battle/cutscenestartbattle.h +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Copyright (c) 2026 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "rpg/battle/battle.h" - -#define CUTSCENE_START_BATTLE_ENEMY_COUNT_MAX 4 - -typedef struct { - battlefighterstats_t stats; - uint16_t healthMax; - uint16_t mpMax; -} cutscenestartbattleenemy_t; - -typedef struct cutsceneitem_s cutsceneitem_t; -typedef union cutsceneitemdata_u cutsceneitemdata_t; - -typedef struct { - battleencountertype_t encounterType; - bool_t fleeAvailable; - uint8_t enemyCount; - cutscenestartbattleenemy_t enemies[CUTSCENE_START_BATTLE_ENEMY_COUNT_MAX]; -} cutscenestartbattle_t; - -/** - * Starts a battle: seeds BATTLE with the party's active order members - * and the item's configured enemies, then switches to the battle - * scene. - * - * @param item The cutscene item. - * @param data Runtime data storage. - */ -void cutsceneStartBattleStart( - const cutsceneitem_t *item, - cutsceneitemdata_t *data -); - -/** - * Waits for the battle to produce a result, syncs ally HP/MP back to - * the party roster, then returns to the overworld scene. - * - * @param item The cutscene item. - * @param data Runtime data storage. - * @returns true once the battle has ended. - */ -bool_t cutsceneStartBattleUpdate( - const cutsceneitem_t *item, - cutsceneitemdata_t *data -); diff --git a/src/dusk/rpg/cutscene/item/cutsceneitem.c b/src/dusk/rpg/cutscene/item/cutsceneitem.c index 348de65f..120b37ae 100644 --- a/src/dusk/rpg/cutscene/item/cutsceneitem.c +++ b/src/dusk/rpg/cutscene/item/cutsceneitem.c @@ -105,11 +105,6 @@ cutsceneitemcallbacks_t CUTSCENE_ITEM_CALLBACKS[CUTSCENE_ITEM_TYPE_COUNT] = { .update = cutsceneMapAreaWaitUpdate }, - [CUTSCENE_ITEM_TYPE_START_BATTLE] = { - .init = cutsceneStartBattleStart, - .update = cutsceneStartBattleUpdate - }, - [CUTSCENE_ITEM_TYPE_EMOJI] = { .init = cutsceneEmojiStart, .update = cutsceneEmojiUpdate diff --git a/src/dusk/rpg/cutscene/item/cutsceneitem.h b/src/dusk/rpg/cutscene/item/cutsceneitem.h index 46ee3be1..6f1ab772 100644 --- a/src/dusk/rpg/cutscene/item/cutsceneitem.h +++ b/src/dusk/rpg/cutscene/item/cutsceneitem.h @@ -26,7 +26,6 @@ #include "maparea/cutscenemapareaadd.h" #include "maparea/cutscenemaparearemove.h" #include "maparea/cutscenemapareawait.h" -#include "battle/cutscenestartbattle.h" typedef struct cutscene_s cutscene_t; @@ -52,7 +51,6 @@ typedef enum { CUTSCENE_ITEM_TYPE_MAP_AREA_ADD, CUTSCENE_ITEM_TYPE_MAP_AREA_REMOVE, CUTSCENE_ITEM_TYPE_MAP_AREA_WAIT, - CUTSCENE_ITEM_TYPE_START_BATTLE, CUTSCENE_ITEM_TYPE_EMOJI, CUTSCENE_ITEM_TYPE_SHAKE, @@ -82,7 +80,6 @@ struct cutsceneitem_s { cutscenemapareaadd_t mapAreaAdd; cutscenemaparearemove_t mapAreaRemove; cutscenemapareawait_t mapAreaWait; - cutscenestartbattle_t startBattle; cutsceneemoji_t emoji; cutsceneshake_t shake; }; diff --git a/src/dusk/rpg/rpg.c b/src/dusk/rpg/rpg.c index 6e04ae7b..08d7cd1a 100644 --- a/src/dusk/rpg/rpg.c +++ b/src/dusk/rpg/rpg.c @@ -14,7 +14,6 @@ #include "rpg/cutscene/cutscenesystem.h" #include "rpg/cutscene/scene/testcutscene.h" #include "rpg/item/backpack.h" -#include "rpg/battle/party.h" #include "ui/rpg/textbox/uitextboxminilist.h" #include "time/time.h" #include "rpgcamera.h" @@ -34,7 +33,6 @@ errorret_t rpgInit(void) { memoryZero(MAP_AREAS, sizeof(MAP_AREAS)); backpackInit(); - partyInit(); cutsceneSystemInit(); errorChain(mapInit()); diff --git a/src/dusk/rpg/story/CMakeLists.txt b/src/dusk/rpg/story/CMakeLists.txt deleted file mode 100644 index 6aace3e7..00000000 --- a/src/dusk/rpg/story/CMakeLists.txt +++ /dev/null @@ -1,19 +0,0 @@ -# Copyright (c) 2026 Dominic Masters -# -# This software is released under the MIT License. -# https://opensource.org/licenses/MIT - -# Sources -target_sources(${DUSK_LIBRARY_TARGET_NAME} - PUBLIC - storyflag.c -) - -# Story Flag Definitions -dusk_run_python( - dusk_story_defs - tools.story - --csv ${CMAKE_CURRENT_SOURCE_DIR}/storyflag.csv - --output ${DUSK_GENERATED_HEADERS_DIR}/rpg/story/storyflagvalue.h -) -add_dependencies(${DUSK_LIBRARY_TARGET_NAME} dusk_story_defs) \ No newline at end of file diff --git a/src/dusk/rpg/story/storyflag.c b/src/dusk/rpg/story/storyflag.c deleted file mode 100644 index e83ba3a8..00000000 --- a/src/dusk/rpg/story/storyflag.c +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Copyright (c) 2026 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "storyflag.h" -#include "assert/assert.h" - -void storyFlagSet(const storyflag_t flag, const storyflagvalue_t value) { - assertTrue(flag > STORY_FLAG_NULL && flag < STORY_FLAG_COUNT, "Bad Flag"); - STORY_FLAG_VALUES[flag] = value; -} \ No newline at end of file diff --git a/src/dusk/rpg/story/storyflag.csv b/src/dusk/rpg/story/storyflag.csv deleted file mode 100644 index ac5197d1..00000000 --- a/src/dusk/rpg/story/storyflag.csv +++ /dev/null @@ -1,2 +0,0 @@ -id,description,initial -test,"Test flag for debugging purposes",1 diff --git a/src/dusk/rpg/story/storyflag.h b/src/dusk/rpg/story/storyflag.h deleted file mode 100644 index 00fb88e0..00000000 --- a/src/dusk/rpg/story/storyflag.h +++ /dev/null @@ -1,25 +0,0 @@ -/** - * Copyright (c) 2026 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "rpg/story/storyflagvalue.h" - -/** - * Gets the value of a story flag. - * - * @param flag The story flag to get. - * @return The value of the story flag. - */ -#define storyFlagGet(flag) (STORY_FLAG_VALUES[(flag)]) - -/** - * Sets the value of a story flag. - * - * @param flag The story flag to set. - * @param value The value to set the story flag to. - */ -void storyFlagSet(const storyflag_t flag, const storyflagvalue_t value); \ No newline at end of file diff --git a/src/dusk/rpg/story/storyflagdefs.h b/src/dusk/rpg/story/storyflagdefs.h deleted file mode 100644 index 2dd81c3f..00000000 --- a/src/dusk/rpg/story/storyflagdefs.h +++ /dev/null @@ -1,11 +0,0 @@ -/** - * Copyright (c) 2026 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "dusk.h" - -typedef uint8_t storyflagvalue_t; \ No newline at end of file diff --git a/src/dusk/scene/CMakeLists.txt b/src/dusk/scene/CMakeLists.txt index b8480d21..9444af7b 100644 --- a/src/dusk/scene/CMakeLists.txt +++ b/src/dusk/scene/CMakeLists.txt @@ -10,5 +10,4 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME} ) # Subdirs -add_subdirectory(overworld) -add_subdirectory(battle) \ No newline at end of file +add_subdirectory(overworld) \ No newline at end of file diff --git a/src/dusk/scene/battle/CMakeLists.txt b/src/dusk/scene/battle/CMakeLists.txt deleted file mode 100644 index a743129d..00000000 --- a/src/dusk/scene/battle/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2026 Dominic Masters -# -# This software is released under the MIT License. -# https://opensource.org/licenses/MIT - -target_sources(${DUSK_LIBRARY_TARGET_NAME} - PUBLIC - scenebattle.c -) diff --git a/src/dusk/scene/battle/scenebattle.c b/src/dusk/scene/battle/scenebattle.c deleted file mode 100644 index 0fabef58..00000000 --- a/src/dusk/scene/battle/scenebattle.c +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright (c) 2026 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "scenebattle.h" -#include "rpg/battle/battle.h" - -errorret_t sceneBattleInit(scenedata_t *sceneData) { - errorOk(); -} - -errorret_t sceneBattleUpdate(scenedata_t *sceneData) { - battleUpdate(); - errorOk(); -} - -errorret_t sceneBattleRender(scenedata_t *sceneData) { - errorOk(); -} - -errorret_t sceneBattleDispose(scenedata_t *sceneData) { - errorOk(); -} diff --git a/src/dusk/scene/battle/scenebattle.h b/src/dusk/scene/battle/scenebattle.h deleted file mode 100644 index 17046a35..00000000 --- a/src/dusk/scene/battle/scenebattle.h +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Copyright (c) 2026 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "scene/scenebase.h" - -typedef struct { - -} scenebattle_t; - -/** - * Initializes the battle scene. The battle itself (BATTLE global) is - * expected to already be started, e.g. by a StartBattle cutscene item. - * - * @param sceneData The scene data used for this scene. - * @return An error if the init failed, or errorOk() if it succeeded. - */ -errorret_t sceneBattleInit(scenedata_t *sceneData); - -/** - * Updates the battle scene, ticking the battle simulation. - * - * @param sceneData The scene data used for this scene. - * @return An error if the update failed, or errorOk() if it succeeded. - */ -errorret_t sceneBattleUpdate(scenedata_t *sceneData); - -/** - * Renders the battle scene. - * - * @param sceneData The scene data used for this scene. - * @return An error if the render failed, or errorOk() if it succeeded. - */ -errorret_t sceneBattleRender(scenedata_t *sceneData); - -/** - * Disposes the battle scene. - * - * @param sceneData The scene data used for this scene. - * @return An error if the dispose failed, or errorOk() if it succeeded. - */ -errorret_t sceneBattleDispose(scenedata_t *sceneData); diff --git a/src/dusk/scene/scenetype.c b/src/dusk/scene/scenetype.c index da285e33..e2e76d7e 100644 --- a/src/dusk/scene/scenetype.c +++ b/src/dusk/scene/scenetype.c @@ -16,12 +16,5 @@ scenecallbacks_t SCENE_TYPES[SCENE_TYPE_COUNT] = { .render = sceneOverworldRender, .dispose = sceneOverworldDispose }, - - [SCENE_TYPE_BATTLE] = { - .init = sceneBattleInit, - .update = sceneBattleUpdate, - .render = sceneBattleRender, - .dispose = sceneBattleDispose - }, }; diff --git a/src/dusk/scene/scenetype.h b/src/dusk/scene/scenetype.h index f3dd88bf..9e981678 100644 --- a/src/dusk/scene/scenetype.h +++ b/src/dusk/scene/scenetype.h @@ -8,11 +8,9 @@ #pragma once #include "scene/scenebase.h" #include "scene/overworld/sceneoverworld.h" -#include "scene/battle/scenebattle.h" typedef union scenedata_u { sceneoverworld_t overworld; - scenebattle_t battle; } scenedata_t; typedef errorret_t (*scenecallback_t)(scenedata_t *); @@ -28,7 +26,6 @@ typedef enum { SCENE_TYPE_NULL, SCENE_TYPE_OVERWORLD, - SCENE_TYPE_BATTLE, SCENE_TYPE_COUNT } scenetype_t; diff --git a/src/dusk/ui/frame/CMakeLists.txt b/src/dusk/ui/frame/CMakeLists.txt index 906cf620..fde94df5 100644 --- a/src/dusk/ui/frame/CMakeLists.txt +++ b/src/dusk/ui/frame/CMakeLists.txt @@ -11,5 +11,4 @@ target_sources(${DUSK_LIBRARY_TARGET_NAME} add_subdirectory(game) add_subdirectory(settings) -add_subdirectory(battle) add_subdirectory(backpack) diff --git a/src/dusk/ui/frame/battle/CMakeLists.txt b/src/dusk/ui/frame/battle/CMakeLists.txt deleted file mode 100644 index 4b6bd9e2..00000000 --- a/src/dusk/ui/frame/battle/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2026 Dominic Masters -# -# This software is released under the MIT License. -# https://opensource.org/licenses/MIT - -target_sources(${DUSK_LIBRARY_TARGET_NAME} - PUBLIC - uibattlemenu.c -) diff --git a/src/dusk/ui/frame/battle/uibattlemenu.c b/src/dusk/ui/frame/battle/uibattlemenu.c deleted file mode 100644 index af947c1f..00000000 --- a/src/dusk/ui/frame/battle/uibattlemenu.c +++ /dev/null @@ -1,137 +0,0 @@ -/** - * Copyright (c) 2026 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#include "uibattlemenu.h" -#include "ui/frame/uiframe.h" -#include "assert/assert.h" -#include "util/memory.h" -#include "util/string.h" -#include "display/spritebatch/spritebatch.h" -#include "display/screen/screen.h" - -uibattlemenu_t UI_BATTLE_MENU; - -void uiBattleMenuTargetSelected( - const uimenu_t *menu, - const uint8_t index, - const uimenuitem_t *item -) { - battlePlayerAttack(UI_BATTLE_MENU.targetFighterIndex[index]); - uiMenuClose(&UI_BATTLE_MENU.targetMenu); - uiMenuClose(&UI_BATTLE_MENU.actionMenu); -} - -void uiBattleMenuOpenTargets(void) { - battlefighter_t *current = battleGetCurrentFighter(); - if(current == NULL) return; - - const battlefighterteam_t enemyTeam = - current->team == BATTLE_FIGHTER_TEAM_ALLY ? - BATTLE_FIGHTER_TEAM_ENEMY : BATTLE_FIGHTER_TEAM_ALLY; - - MENU_BEGIN( - &UI_BATTLE_MENU.targetMenu, UI_BATTLE_MENU.targetItems, - uiBattleMenuTargetSelected, NULL, NULL - ); - - for(uint8_t i = 0; i < BATTLE_FIGHTER_COUNT_MAX; i++) { - battlefighter_t *candidate = &BATTLE.fighters[i]; - if(candidate->team != enemyTeam) continue; - if(!battleFighterIsAlive(candidate)) continue; - - stringFormat( - UI_BATTLE_MENU.targetLabels[menuIndex], - UI_BATTLE_MENU_TARGET_LABEL_MAX - 1, - "Enemy %u (%u/%u HP)", - candidate->id, candidate->health, candidate->healthMax - ); - UI_BATTLE_MENU.targetFighterIndex[menuIndex] = i; - MENU_BUTTON(UI_BATTLE_MENU.targetLabels[menuIndex]); - } - - MENU_END(UI_BATTLE_MENU.targetItems, 1); - - uiMenuOpen(&UI_BATTLE_MENU.targetMenu); -} - -void uiBattleMenuActionSelected( - const uimenu_t *menu, - const uint8_t index, - const uimenuitem_t *item -) { - switch(index) { - case UI_BATTLE_MENU_ACTION_INDEX_ATTACK: - uiBattleMenuOpenTargets(); - break; - - case UI_BATTLE_MENU_ACTION_INDEX_FLEE: - battlePlayerFlee(); - uiMenuClose(&UI_BATTLE_MENU.actionMenu); - break; - - default: - break; - } -} - -errorret_t uiBattleMenuInit(void) { - memoryZero(&UI_BATTLE_MENU, sizeof(uibattlemenu_t)); - - MENU_BEGIN( - &UI_BATTLE_MENU.actionMenu, UI_BATTLE_MENU.actionItems, - uiBattleMenuActionSelected, NULL, NULL - ); - MENU_BUTTON("Attack"); - MENU_BUTTON("Flee"); - MENU_END(UI_BATTLE_MENU.actionItems, 1); - - errorOk(); -} - -errorret_t uiBattleMenuUpdate(void) { - if(uiMenuIsActive(&UI_BATTLE_MENU.actionMenu)) errorOk(); - - battlefighter_t *current = battleGetCurrentFighter(); - if(current == NULL) errorOk(); - if(current->controller != BATTLE_FIGHTER_CONTROLLER_PLAYER) errorOk(); - - uiMenuOpen(&UI_BATTLE_MENU.actionMenu); - errorOk(); -} - -errorret_t uiBattleMenuDraw(void) { - if(!uiMenuIsActive(&UI_BATTLE_MENU.actionMenu)) errorOk(); - - const float_t width = UI_BATTLE_MENU_WIDTH; - const float_t height = UI_BATTLE_MENU_HEIGHT; - const float_t x = (float_t)(SCREEN.scanX + SCREEN.scanWidth) - width; - const float_t y = (float_t)(SCREEN.scanY + SCREEN.scanHeight) - height; - - errorChain(uiFrameDraw(x, y, width, height)); - errorChain(uiMenuDraw( - &UI_BATTLE_MENU.actionMenu, - x + UI_FRAME_START_X, - y + UI_FRAME_START_Y, - width - (UI_FRAME_START_X * 2), - height - (UI_FRAME_START_Y * 2) - )); - - if(uiMenuIsActive(&UI_BATTLE_MENU.targetMenu)) { - const float_t targetY = y - height; - errorChain(uiFrameDraw(x, targetY, width, height)); - errorChain(uiMenuDraw( - &UI_BATTLE_MENU.targetMenu, - x + UI_FRAME_START_X, - targetY + UI_FRAME_START_Y, - width - (UI_FRAME_START_X * 2), - height - (UI_FRAME_START_Y * 2) - )); - } - - errorChain(spriteBatchFlush()); - errorOk(); -} diff --git a/src/dusk/ui/frame/battle/uibattlemenu.h b/src/dusk/ui/frame/battle/uibattlemenu.h deleted file mode 100644 index 024d5d6e..00000000 --- a/src/dusk/ui/frame/battle/uibattlemenu.h +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Copyright (c) 2026 Dominic Masters - * - * This software is released under the MIT License. - * https://opensource.org/licenses/MIT - */ - -#pragma once -#include "error/error.h" -#include "ui/widget/uimenu.h" -#include "rpg/battle/battle.h" - -#define UI_BATTLE_MENU_ACTION_ITEM_COUNT 2 -#define UI_BATTLE_MENU_ACTION_INDEX_ATTACK 0 -#define UI_BATTLE_MENU_ACTION_INDEX_FLEE 1 - -#define UI_BATTLE_MENU_TARGET_ITEM_COUNT BATTLE_FIGHTER_COUNT_MAX -#define UI_BATTLE_MENU_TARGET_LABEL_MAX 32 - -#define UI_BATTLE_MENU_WIDTH 160.0f -#define UI_BATTLE_MENU_HEIGHT 96.0f - -typedef struct { - uimenu_t actionMenu; - uimenuitem_t actionItems[UI_BATTLE_MENU_ACTION_ITEM_COUNT]; - - uimenu_t targetMenu; - uimenuitem_t targetItems[UI_BATTLE_MENU_TARGET_ITEM_COUNT]; - uint8_t targetFighterIndex[UI_BATTLE_MENU_TARGET_ITEM_COUNT]; - char_t targetLabels[UI_BATTLE_MENU_TARGET_ITEM_COUNT] - [UI_BATTLE_MENU_TARGET_LABEL_MAX]; -} uibattlemenu_t; - -extern uibattlemenu_t UI_BATTLE_MENU; - -/** - * Initializes the battle action/target menus. - * - * @return Any error that occurs. - */ -errorret_t uiBattleMenuInit(void); - -/** - * Updates the battle menu: opens the action menu whenever it becomes a - * player-controlled fighter's turn. - * - * @return Any error that occurs. - */ -errorret_t uiBattleMenuUpdate(void); - -/** - * Draws the battle action menu, and the target menu above it when - * open. No-op when the action menu isn't active. - * - * @return Any error that occurs. - */ -errorret_t uiBattleMenuDraw(void); diff --git a/src/dusk/ui/uielement.c b/src/dusk/ui/uielement.c index ce39a599..fd3e48f1 100644 --- a/src/dusk/ui/uielement.c +++ b/src/dusk/ui/uielement.c @@ -18,7 +18,6 @@ #include "ui/debug/uiconsole.h" #include "ui/frame/settings/uisettings.h" #include "ui/frame/game/uigamemenu.h" -#include "ui/frame/battle/uibattlemenu.h" #include "ui/frame/backpack/uibackpack.h" #include "ui/frame/uiconfirm.h" #include "ui/rpg/textbox/uitextboxmain.h" @@ -53,12 +52,6 @@ uielement_t UI_ELEMENTS[] = { .dispose = uiGameMenuDispose }, - { - .init = uiBattleMenuInit, - .update = uiBattleMenuUpdate, - .draw = uiBattleMenuDraw - }, - { .init = uiBackpackInit, .draw = uiBackpackDraw, diff --git a/tools/story.py b/tools/story.py deleted file mode 100644 index c1f9bcfc..00000000 --- a/tools/story.py +++ /dev/null @@ -1,56 +0,0 @@ -import argparse -import csv -import os - -parser = argparse.ArgumentParser(description="Story CSV to .h defines") -parser.add_argument("--csv", required=True, help="Path to story CSV file") -parser.add_argument("--output", required=True, help="Path to output .h file") -args = parser.parse_args() - -def flag_enum(name): - return "STORY_FLAG_" + name.upper().replace(" ", "_") - -# Load flags -flags = [] -with open(args.csv, newline="", encoding="utf-8") as f: - reader = csv.DictReader(f) - if "id" not in reader.fieldnames: - raise ValueError("CSV must have an 'id' column") - for row in reader: - flags.append({ - "id": row["id"].strip(), - "initial": (row.get("initial") or "0").strip(), - }) - -# Build output -out = [ - "#pragma once", - '#include "rpg/story/storyflagdefs.h"', - "", - "typedef enum {", - " STORY_FLAG_NULL,", - "", -] -for flag in flags: - out.append(f" {flag_enum(flag['id'])},") -out += [ - "", - " STORY_FLAG_COUNT", - "} storyflag_t;", - "", - "static storyflagvalue_t STORY_FLAG_VALUES[STORY_FLAG_COUNT] = {", -] -for flag in flags: - out.append(f" [{flag_enum(flag['id'])}] = {flag['initial']},") -out += [ - "};", - "", - "static const char_t *STORY_FLAG_SCRIPT =", -] -for i, flag in enumerate(flags): - out.append(f" \"{flag_enum(flag['id'])} = {i + 1}\\n\"") -out += [";", ""] - -os.makedirs(os.path.dirname(args.output), exist_ok=True) -with open(args.output, "w", encoding="utf-8") as f: - f.write("\n".join(out))