Добавлен инвентарь, в сундуках могут содержаться предметы.

This commit is contained in:
DeLiss
2026-06-11 12:05:36 +05:00
parent cba2274630
commit 5d4940f754
12 changed files with 312 additions and 8 deletions

View File

@@ -123,6 +123,7 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\inventory.cpp" />
<ClCompile Include="src\location.cpp" /> <ClCompile Include="src\location.cpp" />
<ClCompile Include="src\game.cpp" /> <ClCompile Include="src\game.cpp" />
<ClCompile Include="src\main.cpp" /> <ClCompile Include="src\main.cpp" />
@@ -130,8 +131,10 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="include\game.h" /> <ClInclude Include="include\game.h" />
<ClInclude Include="include\inventory.h" />
<ClInclude Include="include\player.h" /> <ClInclude Include="include\player.h" />
<ClInclude Include="include\location.h" /> <ClInclude Include="include\location.h" />
<ClInclude Include="item.h" />
</ItemGroup> </ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">

View File

@@ -27,6 +27,9 @@
<ClCompile Include="src\location.cpp"> <ClCompile Include="src\location.cpp">
<Filter>Исходные файлы</Filter> <Filter>Исходные файлы</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\inventory.cpp">
<Filter>Исходные файлы</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="include\location.h"> <ClInclude Include="include\location.h">
@@ -38,5 +41,11 @@
<ClInclude Include="include\player.h"> <ClInclude Include="include\player.h">
<Filter>Файлы заголовков</Filter> <Filter>Файлы заголовков</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="item.h">
<Filter>Файлы заголовков</Filter>
</ClInclude>
<ClInclude Include="include\inventory.h">
<Filter>Файлы заголовков</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

31
data/items.txt Normal file
View File

@@ -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

View File

@@ -1,7 +1,9 @@
#pragma once #pragma once
#include "player.h" #include "player.h"
#include "location.h" #include "location.h"
#include "item.h"
#include <vector> #include <vector>
#include <string>
class Game { class Game {
public: public:
@@ -12,10 +14,15 @@ private:
Player player; Player player;
std::vector<Location> locations; std::vector<Location> locations;
std::vector<Item> itemDatabase;
void showMainMenu(); void showMainMenu();
void loadItems();
void loadLocations(); void loadLocations();
ItemType parseItemType(const std::string& type);
Location* getCurrentLocation(); Location* getCurrentLocation();
void render(); void render();
@@ -24,5 +31,7 @@ private:
void movePlayer(int dx, int dy); void movePlayer(int dx, int dy);
void handleTile(char tile); void handleTile(char tile);
void openChest(Location& location);
bool solveRiddle(Location& location); bool solveRiddle(Location& location);
}; };

21
include/inventory.h Normal file
View File

@@ -0,0 +1,21 @@
#pragma once
#include <vector>
#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<Item>& itemDatabase) const;
bool hasItem(int itemId) const;
private:
std::vector<InventorySlot> items;
};

18
include/item.h Normal file
View File

@@ -0,0 +1,18 @@
#pragma once
#include <string>
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;
};

View File

@@ -9,8 +9,8 @@ struct Point {
struct Chest { struct Chest {
Point pos; Point pos;
int gold = 0;
bool opened = false; bool opened = false;
std::vector<int> itemIds;
}; };
struct Enemy { struct Enemy {

View File

@@ -2,23 +2,27 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "location.h" #include "location.h"
#include "inventory.h"
#include "item.h"
class Player { class Player {
public: public:
std::string name = "Character Name"; std::string name = "Character Name";
int hp = 100; int hp = 100;
int maxHp = 100;
int atk = 10; int atk = 10;
int gold = 0; int gold = 0;
int currentLocation = 1; int currentLocation = 1;
Point position; Point position;
Inventory inventory;
int weaponId = 101; int equippedWeaponId = 0;
std::vector<int> items;
Player() = default; Player() = default;
Player(std::string name); Player(std::string name);
int getDamage(const std::vector<Item>& itemDatabase) const;
void usePotion(int itemId, const std::vector<Item>& itemDatabase);
void equipWeapon(int itemId, const std::vector<Item>& itemDatabase);
void showStats() const; void showStats() const;
}; };

View File

@@ -1,8 +1,10 @@
#include "../include/game.h" #include "../include/game.h"
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <fstream>
void Game::run() { void Game::run() {
loadItems();
loadLocations(); loadLocations();
showMainMenu(); showMainMenu();
@@ -96,6 +98,9 @@ void Game::render() {
std::cout << "WASD - move\n"; std::cout << "WASD - move\n";
std::cout << "stats - show stats\n"; std::cout << "stats - show stats\n";
std::cout << "exit - exit game\n"; std::cout << "exit - exit game\n";
std::cout << "inventory - show inventory\n";
std::cout << "use <id> - use potion\n";
std::cout << "equip <id> - equip weapon\n";
} }
void Game::processCommand() { void Game::processCommand() {
@@ -122,6 +127,19 @@ void Game::processCommand() {
else if (command == "d" || command == "D") { else if (command == "d" || command == "D") {
movePlayer(1, 0); 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 { else {
std::cout << "Unknown command.\n"; std::cout << "Unknown command.\n";
} }
@@ -158,8 +176,7 @@ void Game::handleTile(char tile) {
} }
if (tile == 'C') { if (tile == 'C') {
std::cout << "You found a chest. For now it gives you 25 gold.\n"; openChest(*location);
player.gold += 25;
} }
else if (tile == 'E') { else if (tile == 'E') {
std::cout << "Enemy encountered. Combat will be added later.\n"; std::cout << "Enemy encountered. Combat will be added later.\n";
@@ -223,4 +240,78 @@ bool Game::solveRiddle(Location& location) {
} }
return false; 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";
} }

63
src/inventory.cpp Normal file
View File

@@ -0,0 +1,63 @@
#include "../include/inventory.h"
#include <iostream>
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<Item>& 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;
}
}
}
}

View File

@@ -64,7 +64,7 @@ bool Location::loadFromFile(const std::string& path) {
if (tile == 'C') { if (tile == 'C') {
Chest chest; Chest chest;
chest.pos = { x, y }; chest.pos = { x, y };
chest.gold = 25; chest.itemIds = { 101, 102 };
chests.push_back(chest); chests.push_back(chest);
} }
else if (tile == 'E') { else if (tile == 'E') {

View File

@@ -16,4 +16,59 @@ void Player::showStats() const {
std::cout << "\nGOLD: " << gold; std::cout << "\nGOLD: " << gold;
std::cout << "\nLOCATION: " << currentLocation; std::cout << "\nLOCATION: " << currentLocation;
std::cout << "\nPOSITION: " << position.x << ", " << position.y << "\n"; std::cout << "\nPOSITION: " << position.x << ", " << position.y << "\n";
}
int Player::getDamage(const std::vector<Item>& 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<Item>& 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<Item>& 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";
} }