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