Добавлен инвентарь, в сундуках могут содержаться предметы.
This commit is contained in:
@@ -123,6 +123,7 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="src\inventory.cpp" />
|
||||
<ClCompile Include="src\location.cpp" />
|
||||
<ClCompile Include="src\game.cpp" />
|
||||
<ClCompile Include="src\main.cpp" />
|
||||
@@ -130,8 +131,10 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\game.h" />
|
||||
<ClInclude Include="include\inventory.h" />
|
||||
<ClInclude Include="include\player.h" />
|
||||
<ClInclude Include="include\location.h" />
|
||||
<ClInclude Include="item.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
<ClCompile Include="src\location.cpp">
|
||||
<Filter>Исходные файлы</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\inventory.cpp">
|
||||
<Filter>Исходные файлы</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="include\location.h">
|
||||
@@ -38,5 +41,11 @@
|
||||
<ClInclude Include="include\player.h">
|
||||
<Filter>Файлы заголовков</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="item.h">
|
||||
<Filter>Файлы заголовков</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="include\inventory.h">
|
||||
<Filter>Файлы заголовков</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
31
data/items.txt
Normal file
31
data/items.txt
Normal 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
|
||||
@@ -1,7 +1,9 @@
|
||||
#pragma once
|
||||
#include "player.h"
|
||||
#include "location.h"
|
||||
#include "item.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
class Game {
|
||||
public:
|
||||
@@ -12,10 +14,15 @@ private:
|
||||
|
||||
Player player;
|
||||
std::vector<Location> locations;
|
||||
std::vector<Item> 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);
|
||||
};
|
||||
21
include/inventory.h
Normal file
21
include/inventory.h
Normal 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
18
include/item.h
Normal 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;
|
||||
};
|
||||
@@ -9,8 +9,8 @@ struct Point {
|
||||
|
||||
struct Chest {
|
||||
Point pos;
|
||||
int gold = 0;
|
||||
bool opened = false;
|
||||
std::vector<int> itemIds;
|
||||
};
|
||||
|
||||
struct Enemy {
|
||||
|
||||
@@ -2,23 +2,27 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#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<int> items;
|
||||
Inventory inventory;
|
||||
int equippedWeaponId = 0;
|
||||
|
||||
Player() = default;
|
||||
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;
|
||||
};
|
||||
95
src/game.cpp
95
src/game.cpp
@@ -1,8 +1,10 @@
|
||||
#include "../include/game.h"
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <fstream>
|
||||
|
||||
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 <id> - use potion\n";
|
||||
std::cout << "equip <id> - 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";
|
||||
@@ -224,3 +241,77 @@ 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";
|
||||
}
|
||||
63
src/inventory.cpp
Normal file
63
src/inventory.cpp
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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') {
|
||||
|
||||
@@ -17,3 +17,58 @@ void Player::showStats() const {
|
||||
std::cout << "\nLOCATION: " << currentLocation;
|
||||
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";
|
||||
}
|
||||
Reference in New Issue
Block a user