From 5d4940f754a4b6c4c251720aca87f0be2e722b82 Mon Sep 17 00:00:00 2001 From: DeLiss <96916811+deliss-btw@users.noreply.github.com> Date: Thu, 11 Jun 2026 12:05:36 +0500 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=20=D0=B8=D0=BD=D0=B2=D0=B5=D0=BD=D1=82=D0=B0=D1=80=D1=8C?= =?UTF-8?q?,=20=D0=B2=20=D1=81=D1=83=D0=BD=D0=B4=D1=83=D0=BA=D0=B0=D1=85?= =?UTF-8?q?=20=D0=BC=D0=BE=D0=B3=D1=83=D1=82=20=D1=81=D0=BE=D0=B4=D0=B5?= =?UTF-8?q?=D1=80=D0=B6=D0=B0=D1=82=D1=8C=D1=81=D1=8F=20=D0=BF=D1=80=D0=B5?= =?UTF-8?q?=D0=B4=D0=BC=D0=B5=D1=82=D1=8B.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ASCII-G.vcxproj | 3 ++ ASCII-G.vcxproj.filters | 9 ++++ data/items.txt | 31 ++++++++++++++ include/game.h | 9 ++++ include/inventory.h | 21 +++++++++ include/item.h | 18 ++++++++ include/location.h | 2 +- include/player.h | 12 ++++-- src/game.cpp | 95 ++++++++++++++++++++++++++++++++++++++++- src/inventory.cpp | 63 +++++++++++++++++++++++++++ src/location.cpp | 2 +- src/player.cpp | 55 ++++++++++++++++++++++++ 12 files changed, 312 insertions(+), 8 deletions(-) create mode 100644 data/items.txt create mode 100644 include/inventory.h create mode 100644 include/item.h create mode 100644 src/inventory.cpp diff --git a/ASCII-G.vcxproj b/ASCII-G.vcxproj index a433f61..603b553 100644 --- a/ASCII-G.vcxproj +++ b/ASCII-G.vcxproj @@ -123,6 +123,7 @@ + @@ -130,8 +131,10 @@ + + diff --git a/ASCII-G.vcxproj.filters b/ASCII-G.vcxproj.filters index 52d2269..bba9111 100644 --- a/ASCII-G.vcxproj.filters +++ b/ASCII-G.vcxproj.filters @@ -27,6 +27,9 @@ Исходные файлы + + Исходные файлы + @@ -38,5 +41,11 @@ Файлы заголовков + + Файлы заголовков + + + Файлы заголовков + \ No newline at end of file diff --git a/data/items.txt b/data/items.txt new file mode 100644 index 0000000..eefea51 --- /dev/null +++ b/data/items.txt @@ -0,0 +1,31 @@ +ID=101 +NAME=Small Healing Potion +DESCRIPTION=Restores 25 HP. +TYPE=POTION +HEAL=25 +DAMAGE=0 +END + +ID=102 +NAME=Big Healing Potion +DESCRIPTION=Restores 50 HP. +TYPE=POTION +HEAL=50 +DAMAGE=0 +END + +ID=201 +NAME=Rusty Sword +DESCRIPTION=Old sword. Better than fists. +TYPE=WEAPON +HEAL=0 +DAMAGE=10 +END + +ID=202 +NAME=Iron Axe +DESCRIPTION=Heavy axe with good damage. +TYPE=WEAPON +HEAL=0 +DAMAGE=18 +END \ No newline at end of file diff --git a/include/game.h b/include/game.h index 609eac8..32d5cb3 100644 --- a/include/game.h +++ b/include/game.h @@ -1,7 +1,9 @@ #pragma once #include "player.h" #include "location.h" +#include "item.h" #include +#include class Game { public: @@ -12,10 +14,15 @@ private: Player player; std::vector locations; + std::vector itemDatabase; void showMainMenu(); + void loadItems(); void loadLocations(); + + ItemType parseItemType(const std::string& type); + Location* getCurrentLocation(); void render(); @@ -24,5 +31,7 @@ private: void movePlayer(int dx, int dy); void handleTile(char tile); + void openChest(Location& location); + bool solveRiddle(Location& location); }; \ No newline at end of file diff --git a/include/inventory.h b/include/inventory.h new file mode 100644 index 0000000..2a068af --- /dev/null +++ b/include/inventory.h @@ -0,0 +1,21 @@ +#pragma once +#include +#include "Item.h" + +struct InventorySlot { + int itemId = 0; + int count = 0; +}; + +class Inventory { +public: + void addItem(int itemId, int count = 1); + bool removeItem(int itemId, int count = 1); + + void show(const std::vector& itemDatabase) const; + + bool hasItem(int itemId) const; + +private: + std::vector items; +}; \ No newline at end of file diff --git a/include/item.h b/include/item.h new file mode 100644 index 0000000..3073aca --- /dev/null +++ b/include/item.h @@ -0,0 +1,18 @@ +#pragma once +#include + +enum class ItemType { + Potion, + Weapon, + Unknown +}; + +struct Item { + int id = 0; + std::string name; + std::string description; + ItemType type = ItemType::Unknown; + + int heal = 0; + int damage = 0; +}; \ No newline at end of file diff --git a/include/location.h b/include/location.h index e2c9f4e..7c30718 100644 --- a/include/location.h +++ b/include/location.h @@ -9,8 +9,8 @@ struct Point { struct Chest { Point pos; - int gold = 0; bool opened = false; + std::vector itemIds; }; struct Enemy { diff --git a/include/player.h b/include/player.h index 15f23ec..78c9ebd 100644 --- a/include/player.h +++ b/include/player.h @@ -2,23 +2,27 @@ #include #include #include "location.h" +#include "inventory.h" +#include "item.h" class Player { public: std::string name = "Character Name"; int hp = 100; + int maxHp = 100; int atk = 10; int gold = 0; - int currentLocation = 1; Point position; - - int weaponId = 101; - std::vector items; + Inventory inventory; + int equippedWeaponId = 0; Player() = default; Player(std::string name); + int getDamage(const std::vector& itemDatabase) const; + void usePotion(int itemId, const std::vector& itemDatabase); + void equipWeapon(int itemId, const std::vector& itemDatabase); void showStats() const; }; \ No newline at end of file diff --git a/src/game.cpp b/src/game.cpp index 4d907a4..aa352af 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -1,8 +1,10 @@ #include "../include/game.h" #include #include +#include void Game::run() { + loadItems(); loadLocations(); showMainMenu(); @@ -96,6 +98,9 @@ void Game::render() { std::cout << "WASD - move\n"; std::cout << "stats - show stats\n"; std::cout << "exit - exit game\n"; + std::cout << "inventory - show inventory\n"; + std::cout << "use - use potion\n"; + std::cout << "equip - equip weapon\n"; } void Game::processCommand() { @@ -122,6 +127,19 @@ void Game::processCommand() { else if (command == "d" || command == "D") { movePlayer(1, 0); } + else if (command == "inventory") { + player.inventory.show(itemDatabase); + } + else if (command == "use") { + int itemId; + std::cin >> itemId; + player.usePotion(itemId, itemDatabase); + } + else if (command == "equip") { + int itemId; + std::cin >> itemId; + player.equipWeapon(itemId, itemDatabase); + } else { std::cout << "Unknown command.\n"; } @@ -158,8 +176,7 @@ void Game::handleTile(char tile) { } if (tile == 'C') { - std::cout << "You found a chest. For now it gives you 25 gold.\n"; - player.gold += 25; + openChest(*location); } else if (tile == 'E') { std::cout << "Enemy encountered. Combat will be added later.\n"; @@ -223,4 +240,78 @@ bool Game::solveRiddle(Location& location) { } return false; +} + +ItemType Game::parseItemType(const std::string& type) { + if (type == "POTION") return ItemType::Potion; + if (type == "WEAPON") return ItemType::Weapon; + + return ItemType::Unknown; +} + +void Game::loadItems() { + itemDatabase.clear(); + + std::ifstream file("data/items.txt"); + + if (!file.is_open()) { + std::cout << "Cannot open items file: data/items.txt\n"; + return; + } + + Item item; + std::string line; + + while (std::getline(file, line)) { + if (line.empty()) { + continue; + } + + if (line == "END") { + itemDatabase.push_back(item); + item = Item(); + continue; + } + + size_t pos = line.find('='); + + if (pos == std::string::npos) { + continue; + } + + std::string key = line.substr(0, pos); + std::string value = line.substr(pos + 1); + + if (key == "ID") item.id = std::stoi(value); + else if (key == "NAME") item.name = value; + else if (key == "DESCRIPTION") item.description = value; + else if (key == "TYPE") item.type = parseItemType(value); + else if (key == "HEAL") item.heal = std::stoi(value); + else if (key == "DAMAGE") item.damage = std::stoi(value); + } + + std::cout << "Loaded items: " << itemDatabase.size() << "\n"; +} + +void Game::openChest(Location& location) { + for (auto& chest : location.chests) { + if (chest.pos.x == player.position.x && chest.pos.y == player.position.y) { + if (chest.opened) { + std::cout << "Chest is already opened.\n"; + return; + } + + std::cout << "You opened the chest.\n"; + + for (int itemId : chest.itemIds) { + player.inventory.addItem(itemId); + std::cout << "Received item ID: " << itemId << "\n"; + } + + chest.opened = true; + return; + } + } + + std::cout << "Chest not found. Something went wrong.\n"; } \ No newline at end of file diff --git a/src/inventory.cpp b/src/inventory.cpp new file mode 100644 index 0000000..2659212 --- /dev/null +++ b/src/inventory.cpp @@ -0,0 +1,63 @@ +#include "../include/inventory.h" +#include + +void Inventory::addItem(int itemId, int count) { + for (auto& slot : items) { + if (slot.itemId == itemId) { + slot.count += count; + return; + } + } + + items.push_back({ itemId, count }); +} + +bool Inventory::removeItem(int itemId, int count) { + for (auto it = items.begin(); it != items.end(); ++it) { + if (it->itemId == itemId) { + if (it->count < count) { + return false; + } + + it->count -= count; + + if (it->count <= 0) { + items.erase(it); + } + + return true; + } + } + + return false; +} + +bool Inventory::hasItem(int itemId) const { + for (const auto& slot : items) { + if (slot.itemId == itemId) { + return true; + } + } + + return false; +} + +void Inventory::show(const std::vector& itemDatabase) const { + std::cout << "\n=== INVENTORY ===\n"; + + if (items.empty()) { + std::cout << "Inventory is empty.\n"; + return; + } + + for (const auto& slot : items) { + for (const auto& item : itemDatabase) { + if (item.id == slot.itemId) { + std::cout << item.id << " | " + << item.name << " x" << slot.count + << " | " << item.description << "\n"; + break; + } + } + } +} \ No newline at end of file diff --git a/src/location.cpp b/src/location.cpp index b468753..f8b8ed7 100644 --- a/src/location.cpp +++ b/src/location.cpp @@ -64,7 +64,7 @@ bool Location::loadFromFile(const std::string& path) { if (tile == 'C') { Chest chest; chest.pos = { x, y }; - chest.gold = 25; + chest.itemIds = { 101, 102 }; chests.push_back(chest); } else if (tile == 'E') { diff --git a/src/player.cpp b/src/player.cpp index f07fef3..5e9d779 100644 --- a/src/player.cpp +++ b/src/player.cpp @@ -16,4 +16,59 @@ void Player::showStats() const { std::cout << "\nGOLD: " << gold; std::cout << "\nLOCATION: " << currentLocation; std::cout << "\nPOSITION: " << position.x << ", " << position.y << "\n"; +} + +int Player::getDamage(const std::vector& itemDatabase) const { + int damage = atk; + + for (const auto& item : itemDatabase) { + if (item.id == equippedWeaponId && item.type == ItemType::Weapon) { + damage += item.damage; + break; + } + } + + return damage; +} + +void Player::usePotion(int itemId, const std::vector& itemDatabase) { + for (const auto& item : itemDatabase) { + if (item.id == itemId && item.type == ItemType::Potion) { + if (!inventory.hasItem(itemId)) { + std::cout << "You don't have this potion.\n"; + return; + } + + hp += item.heal; + + if (hp > maxHp) { + hp = maxHp; + } + + inventory.removeItem(itemId, 1); + + std::cout << "You used " << item.name << ". HP: " << hp << "\n"; + return; + } + } + + std::cout << "This item is not a potion.\n"; +} + +void Player::equipWeapon(int itemId, const std::vector& itemDatabase) { + for (const auto& item : itemDatabase) { + if (item.id == itemId && item.type == ItemType::Weapon) { + if (!inventory.hasItem(itemId)) { + std::cout << "You don't have this weapon.\n"; + return; + } + + equippedWeaponId = itemId; + + std::cout << "Equipped weapon: " << item.name << "\n"; + return; + } + } + + std::cout << "This item is not a weapon.\n"; } \ No newline at end of file