# Gainax **Repository Path**: bpyhome/gainax ## Basic Information - **Project Name**: Gainax - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 3 - **Forks**: 1 - **Created**: 2025-04-08 - **Last Updated**: 2025-05-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # (Gainax)Saint's Corpse Pursuit: Johnny's Journey (SaintsLegacyRPG) A C++ text-based RPG adventure set in the Steel Ball Run universe. ## Authors - Ben - Kane - Kevin ## Story You play as Johnny Joestar, a former genius jockey now confined to a wheelchair, who embarks on a desperate quest to save his ill daughter. Your mission is to collect three sacred Saint's Corpse parts, each guarded by powerful Stand users, and confront the mysterious final boss. ## Features - **Pure Text Interface**: Navigate through a rich world using an intuitive menu system - **7 Distinct Areas**: Including the Starting Stable, Arizona Desert, Silent Oasis, Echo Canyon, Shadow Forest, Devil's Palm Mountains, and a hidden final area - **Turn-based Combat**: Strategic battles with various enemies, each with unique abilities - **Stand System**: Utilize Johnny's evolving Stand "Tusk" and its special abilities - **Item Collection**: Find and use various items to enhance your abilities - **Dynamic Environments**: Special room effects like healing oases and dangerous forests - **Hidden Boss**: A challenging final encounter that unlocks after collecting all Corpse parts ## Gameplay ### Core Mechanics 1. **Movement**: Use directional commands (north, south, east, west) to navigate between rooms 2. **Combat**: Engage in turn-based battles with normal enemies, elite guardians, and bosses 3. **Item Management**: Collect and manage equipment that enhances your stats 4. **Quest Items**: Hunt for three sacred Corpse parts (Head, Torso, Limbs) 5. **Special Abilities**: Use Stand powers in combat with a strategic cooldown system ### Key Characters - **Johnny Joestar**: The protagonist, seeking the Saint's Corpse to save his daughter - **Elite Guardians**: - Ringo Roadagain: Master of time manipulation (Mandom) - Blackmore: Controls raindrops (Catch the Rainbow) - Sandman: Transforms sound into attacks (In A Silent Way) - **Final Boss**: Funny Valentine with his dimension-hopping Stand D4C ## Technical Details ### Code Architecture The game is built using several key C++ classes: - `Game`: Main game controller managing the game loop and state - `Player`: Handles player stats, inventory, and abilities - `Room`: Manages room contents and connections - `Enemy`: Base class for all opponents with derived classes for elites/bosses - `Item`: Represents collectible items and their effects - `Stand`: Implements special abilities and their effects ### Memory Management - Dynamic allocation for game objects using smart pointers - AII principles for resource management - Clean memory handling for items and enemies ### Key Game Systems 1. **Combat System**: - Turn-based combat with attack/defense calculations - Special attacks for elite enemies - Stand ability integration - Status effect system 2. **Item System**: - Equipment with stat bonuses - Inventory management - Special item effects - Random item generation 3. **Room Management**: - Interconnected room navigation - Room state persistence - Special room effects - Dynamic enemy spawning ### Boss Room Mechanics The final boss room (President's Office) becomes accessible when: 1. All three Saint's Corpse parts are collected 2. Player returns to the Starting Stable 3. A secret passage appears, leading to the final confrontation ## Building and Running ### Prerequisites - C++11 compatible compiler - Make build system ### Compilation ```bash make ``` ### Running ```bash ./bin/saints_legacy ``` ## Controls - Use numbers (1-9) to select menu options - Type 'help' for game instructions - Common commands: - move/go [direction] - pickup/take [item] - attack [enemy] - status - help - quit ## Win/Loss Conditions - **Victory**: Collect all three Saint's Corpse parts and defeat the final boss - **Defeat**: Player's HP reaches 0 ## Tips 1. Visit the Silent Oasis to heal between battles 2. Elite enemies drop crucial Saint's Corpse parts 3. Collect equipment to improve your stats 4. Use your Stand abilities strategically 5. Remember to check your status and inventory regularly ## Class Design Details This game employs object-oriented design principles, with each class following the Canonical Class standard. Here's a detailed introduction to the main classes: ### Core Game Classes #### 1. Game Class - **Responsibility**: Acts as the core controller of the game - **Main Functions**: - Manages game loop and state - Handles player input and commands - Coordinates combat system - Manages room navigation - **Design Features**: - Implements Singleton pattern - Disabled copy construction and assignment - Centralized game resource management #### 2. Enemy Class - **Responsibility**: Implements the game's enemy system - **Main Functions**: - Manages enemy attributes (health, attack, defense) - Controls combat behavior - Handles special abilities and Stand system - Manages item drops - **Design Features**: - Complete resource management (deep copy) - Status effect system support - Extensible combat mechanics #### 3. EnemyType Class - **Responsibility**: Defines the enemy type system - **Main Functions**: - Classifies enemies (Normal, Elite, Boss) - Tracks enemy difficulty levels - Determines special abilities and drops - **Design Features**: - Simple and efficient type management - Supports type checking and conversion - Easy to extend with new enemy types ### Game System Classes #### 4. Room Class - **Responsibility**: Manages the game world's spatial structure - **Main Functions**: - Stores room contents (enemies, items) - Manages room connections - Handles special room effects - **Design Features**: - Flexible navigation system - Dynamic content management - Special event trigger support #### 5. Player Class - **Responsibility**: Manages the player character - **Main Functions**: - Handles player status - Manages inventory - Implements skill system - **Design Features**: - Complete attribute system - Flexible item management - Stand ability integration #### 6. Item Class - **Responsibility**: Implements the game's item system - **Main Functions**: - Defines item properties - Processes item effects - Manages item states - **Design Features**: - Supports multiple item types - Extensible effect system - Clean interface design ### Support System Classes #### 7. DisplayData Class - **Responsibility**: Handles game display-related data - **Main Functions**: - Formats display information - Manages UI elements - Processes display logic - **Design Features**: - Clear data presentation - Consistent interface style - Easy to maintain and extend ## Bonus Features Implementation This project successfully implements all the bonus features required in the assignment. Below are code samples demonstrating each feature: ### 1. Enhanced Menu System ```cpp // Clear screen implementation for better readability void Game::clearScreen() { #ifdef _WIN32 system("cls"); #else system("clear"); #endif } ``` ### 2. Random Loot System ```cpp // Random item generation system Item* Game::generateRandomItem() { std::random_device rd; std::mt19937 gen(rd()); // Define different rarity levels std::uniform_int_distribution<> rarity_dis(1, 100); int roll = rarity_dis(gen); std::vector rarityFiltered; // Select items based on rarity roll if (roll <= 60) { // Common (60%) rarityFiltered = commonItems; } else if (roll <= 90) { // Uncommon (30%) rarityFiltered = uncommonItems; } else { // Rare (10%) rarityFiltered = rareItems; } // Generate the random item from the selected pool std::uniform_int_distribution<> item_dis(0, rarityFiltered.size() - 1); int index = item_dis(gen); const ItemTemplate& tmpl = rarityFiltered[index]; return new Item(tmpl.name, tmpl.description, tmpl.atk, tmpl.def, tmpl.hp); } // Place random items in rooms void Game::placeRandomItemsInRooms() { std::random_device rd; std::mt19937 gen(rd()); for (size_t i = 1; i < rooms.size() - 1; i++) { std::uniform_int_distribution<> has_items_dis(1, 100); if (has_items_dis(gen) <= 70) { // 70% chance for items std::uniform_int_distribution<> item_count_dis(1, 100); int numItems = (item_count_dis(gen) <= 60) ? 1 : 2; // 60% for 1 item, 40% for 2 for (int j = 0; j < numItems; j++) { Item* item = generateRandomItem(); rooms[i]->addItem(item); } } } } ``` ### 3. Enemy Subclasses with Special Attacks ```cpp // Enemy type system class EnemyType { public: static const int NORMAL = 0; static const int ELITE = 1; static const int BOSS = 2; EnemyType(int type = NORMAL) : typeValue(type) {} bool isNormal() const { return typeValue == NORMAL; } bool isElite() const { return typeValue == ELITE; } bool isBoss() const { return typeValue == BOSS; } std::string getTypeName() const { switch (typeValue) { case NORMAL: return "Normal"; case ELITE: return "Elite"; case BOSS: return "Boss"; default: return "Unknown"; } } private: int typeValue; }; // Special attack implementation bool Enemy::specialAttack(ICharacter& target) { // Different attack based on enemy type if (type.isElite()) { // Elite special attack unsigned damage = getAttack() * 1.5; addMessage(getName() + " uses a powerful special attack!"); return target.takeDamage(damage); } else if (type.isBoss()) { // Boss special attack unsigned damage = getAttack() * 2; addMessage(getName() + " unleashes a devastating boss attack!"); return target.takeDamage(damage); } else { // Normal enemy regular attack return attack(target); } } ``` ### 4. Special Room Effects ```cpp // Room effects implementation void Room::setHealingEffect(bool hasHealing) { hasHealingEffect = hasHealing; } void Room::setDamageEffect(bool hasDamage) { hasDamageEffect = hasDamage; } bool Room::hasHealing() const { return hasHealingEffect; } bool Room::hasDamage() const { return hasDamageEffect; } // Room effects in action void Game::move(const std::string& direction) { // Movement code... if (currentRoom->hasHealing()) { player->heal(10); addMessage("The oasis's healing effect restored 10 health points!"); } if (currentRoom->hasDamage()) { player->takeDamage(5); addMessage("The forest's damaging effect caused 5 points of damage!"); } } ``` ### 5. Operator Overloading ```cpp // Item effect application operator void Item::operator+=(ICharacter& character) const { // Apply item effects to character character.takeDamage(-healthBonus); // Negative damage = healing } // Output operator for item information std::ostream& operator<<(std::ostream& os, const Item& item) { os << item.name << " - " << item.description; if (item.attackBonus > 0) os << " (+" << item.attackBonus << " Attack)"; if (item.defenseBonus > 0) os << " (+" << item.defenseBonus << " Defense)"; if (item.healthBonus > 0) os << " (+" << item.healthBonus << " Health)"; return os; } ``` ### 6. JOJO-themed Stand System (Custom Bonus Feature) ```cpp // Stand structure definition struct Stand { std::string name; std::string description; unsigned attackBonus; unsigned defenseBonus; std::vector skills; Stand(const std::string& n, const std::string& d, unsigned atk = 0, unsigned def = 0) : name(n), description(d), attackBonus(atk), defenseBonus(def) {} void addSkill(const Skill& skill) { skills.push_back(skill); } }; // Skill system implementation struct Skill { std::string name; std::string description; unsigned attackModifier; unsigned defenseModifier; unsigned healAmount; unsigned damageAmount; bool isBuff; bool isDebuff; Skill(const std::string& n, const std::string& d, unsigned atk = 0, unsigned def = 0, unsigned heal = 0, unsigned dmg = 0, bool buff = false, bool debuff = false) : name(n), description(d), attackModifier(atk), defenseModifier(def), healAmount(heal), damageAmount(dmg), isBuff(buff), isDebuff(debuff) {} }; // Stand usage in Player class bool Player::useSkill(const std::string& skillName, ICharacter& target) { // Find the skill in active skills for (const auto& skill : activeSkills) { if (skill.name == skillName) { // Apply skill effects if (skill.damageAmount > 0) { // Damage skill unsigned damage = skill.damageAmount + getAttack() * (skill.attackModifier / 100.0); return target.takeDamage(damage); } else if (skill.healAmount > 0) { // Healing skill heal(skill.healAmount); return true; } else if (skill.isBuff) { // Buff skill applyBuff(skill.attackModifier, skill.defenseModifier, 3); return true; } } } return false; } ``` ### 7. Virtual Function Override Implementation ```cpp // ICharacter interface with methods to be overridden class ICharacter { public: virtual ~ICharacter() = default; virtual bool isAlive() const = 0; virtual bool takeDamage(unsigned damage) = 0; virtual bool attack(ICharacter& target) = 0; virtual std::string getName() const = 0; virtual std::string getDescription() const = 0; virtual unsigned getHealth() const = 0; virtual unsigned getAttack() const = 0; virtual unsigned getDefense() const = 0; virtual std::string toString() const = 0; virtual void addToInventory(Item* item) = 0; }; // Player class implementation with override keyword class Player : public ICharacter { public: // ICharacter interface implementation bool isAlive() const override; bool takeDamage(unsigned damage) override; bool attack(ICharacter& target) override; std::string getName() const override; std::string getDescription() const override { return description; } unsigned getHealth() const override { return currentHealth; } unsigned getAttack() const override; unsigned getDefense() const override; std::string toString() const override; void addToInventory(Item* item) override; // Additional Player-specific methods... }; ``` These implementations showcase the advanced C++ features utilized in this project, demonstrating a comprehensive understanding of object-oriented programming concepts, memory management, and game design principles.