From 3a92505c5ee7622db6598796039e46bcd9a8310c Mon Sep 17 00:00:00 2001 From: DawnFire42 Date: Thu, 26 Feb 2026 18:29:51 -0500 Subject: [PATCH] feat(command-zone): add foundational type definitions Add core type definitions and constants for the command zone feature: - zone_names.h: Add command zone name constants (command, partner, companion, background) for protocol and lookup operations - command_zone_types.h: Define CommandZoneType enum, ZoneVisibility enum, and StateChangeResult struct for state machine logic - counter_ids.h: Define shared counter IDs and names for commander tax tracking (IDs 8-9 reserved to avoid conflicts with user counters) These headers are intentionally minimal and dependency-free to enable inclusion in both production code and isolated unit tests. --- .../src/game/zones/command_zone_types.h | 87 +++++++++++++++++++ cockatrice/src/game/zones/zone_names.h | 4 + .../libcockatrice/common/counter_ids.h | 29 +++++++ 3 files changed, 120 insertions(+) create mode 100644 cockatrice/src/game/zones/command_zone_types.h create mode 100644 libcockatrice_network/libcockatrice/common/counter_ids.h diff --git a/cockatrice/src/game/zones/command_zone_types.h b/cockatrice/src/game/zones/command_zone_types.h new file mode 100644 index 000000000..3704a7a3d --- /dev/null +++ b/cockatrice/src/game/zones/command_zone_types.h @@ -0,0 +1,87 @@ +/** + * @file command_zone_types.h + * @ingroup GameGraphicsZones + * @brief Type definitions for command zone state management. + * + * This header is intentionally minimal and dependency-free so it can be + * included in both production code and isolated unit tests. + */ + +#ifndef COCKATRICE_COMMAND_ZONE_TYPES_H +#define COCKATRICE_COMMAND_ZONE_TYPES_H + +/** + * @enum CommandZoneType + * @brief Identifies the type of command zone. + * + * Each zone type has different behavior: + * - Primary: Always visible, never collapsible, has tax counter + * - Partner: Collapsible, has tax counter + * - Companion: Collapsible, no tax counter + * - Background: Collapsible, no tax counter + */ +enum class CommandZoneType +{ + Primary, ///< Main commander - always visible, never collapsible + Partner, ///< Partner commander + Companion, ///< Companion + Background ///< Background +}; + +/** + * @enum ZoneVisibility + * @brief Represents the visual display state of a zone. + */ +enum class ZoneVisibility +{ + Expanded, ///< Full height, cards visible + Minimized, ///< 25% height, cards clipped + Collapsed ///< Zero height, only toggle button visible (not valid for Primary) +}; + +/** + * @namespace CommandZoneConstants + * @brief Constants for command zone sizing. + */ +namespace CommandZoneConstants +{ +constexpr double MINIMIZED_HEIGHT_RATIO = 0.25; +} + +/** + * @brief Returns whether the given zone type supports multiple cards. + * + * Primary and Partner zones hold exactly one card (commander rules, + * tax counter positioning). Companion and Background zones support + * multiple cards to handle rare mechanics like multiple companions. + * + * @param type The command zone type to check + * @return true if the zone can hold multiple cards, false for single-card zones + */ +inline bool supportsMultipleCards(CommandZoneType type) +{ + return type == CommandZoneType::Companion || type == CommandZoneType::Background; +} + +/** + * @struct StateChangeResult + * @brief Result of a state mutation. Use the boolean flags to determine side effects; + * do not interpret visibility transitions directly (information hiding principle). + */ +struct StateChangeResult +{ + bool geometryChanged; ///< Caller should call prepareGeometryChange() and update layout + bool shouldEmitExpanded; ///< Caller should emit expandedChanged(isExpanded()) + bool shouldEmitMinimized; ///< Caller should emit minimizedChanged(isMinimized()) + + /** + * @brief Returns a result indicating no changes occurred. + * @return StateChangeResult with all flags false + */ + static StateChangeResult noChange() + { + return {false, false, false}; + } +}; + +#endif // COCKATRICE_COMMAND_ZONE_TYPES_H diff --git a/cockatrice/src/game/zones/zone_names.h b/cockatrice/src/game/zones/zone_names.h index 53b85459c..8143f1d15 100644 --- a/cockatrice/src/game/zones/zone_names.h +++ b/cockatrice/src/game/zones/zone_names.h @@ -23,6 +23,10 @@ constexpr const char *HAND = "hand"; constexpr const char *DECK = "deck"; constexpr const char *SIDEBOARD = "sb"; constexpr const char *STACK = "stack"; +constexpr const char *COMMAND = "command"; +constexpr const char *PARTNER = "partner"; +constexpr const char *COMPANION = "companion"; +constexpr const char *BACKGROUND = "background"; } // namespace ZoneNames #endif // ZONE_NAMES_H diff --git a/libcockatrice_network/libcockatrice/common/counter_ids.h b/libcockatrice_network/libcockatrice/common/counter_ids.h new file mode 100644 index 000000000..aada29391 --- /dev/null +++ b/libcockatrice_network/libcockatrice/common/counter_ids.h @@ -0,0 +1,29 @@ +#ifndef COUNTER_IDS_H +#define COUNTER_IDS_H + +/** + * Shared counter IDs used by both client and server. + * These must match between server_player.cpp and player_event_handler.cpp. + * + * Reserved counter IDs for system counters: + * IDs 0-7: Standard player counters (life, mana colors, storm) + * IDs 8-9: Commander tax counters (reserved, do not use for custom counters) + * IDs 10+: Available for user-created counters + * + * The server's newCounterId() starts from the highest existing ID + 1, + * so these reserved IDs won't conflict as long as they're created first + * during setupZones(). + */ +namespace CounterIds +{ +constexpr int CommanderTax = 8; +constexpr int PartnerTax = 9; +} // namespace CounterIds + +namespace CounterNames +{ +constexpr const char *CommanderTax = "commander_tax_counter"; +constexpr const char *PartnerTax = "partner_tax_counter"; +} // namespace CounterNames + +#endif // COUNTER_IDS_H