Skip to content
Snippets Groups Projects
Commit 6ecc5c51 authored by Lorenz Martin Diel's avatar Lorenz Martin Diel
Browse files

Merge branch 'xml' into 'units+xml'

Xml

See merge request !8
parents c3aeb3d7 60811ac6
No related branches found
No related tags found
1 merge request!8Xml
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <unordered_map>
#include <string>
#include <iostream>
#include <stdexcept> // Für die Ausnahmebehandlung
#include "unit.hpp" // Include für UnitId
#include "config.hpp"
namespace pt = boost::property_tree;
namespace advanced_wars
{
Config::Config(MatchupTabel_secondaryweapon& secWeapon, MatchupTabel_primaryweapon& primWeapon)
: secondary_weapon_damage(secWeapon), primary_weapon_damage(primWeapon)
{
// Initialisierung hier wenn nötig
}
void Config::loadFromXML(const char *filename)
{
pt::ptree tree;
pt::read_xml(filename, tree);
for (const auto &unit : tree.get_child("Units"))
{
if (unit.first == "Unit")
{
std::string unitKey = unit.second.get<std::string>("<xmlattr>.key");
UnitId unitId;
if (unitKey == "infantry")
{
unitId = UnitId::INFANTERY;
}
else if (unitKey == "Mech")
{
unitId = UnitId::MECHANIZED_INFANTERY;
}
else
{
continue; // Überspringt nicht unterstützte Einheiten
}
int cost = unit.second.get<int>("Cost");
int movementPoints = unit.second.get<int>("MovementPoints");
int ammo = unit.second.get<int>("Ammo");
int minRange = unit.second.get<int>("minRange", 0);
int maxRange = unit.second.get<int>("maxRange", 0);
unit_costs[unitId] = cost;
unit_movementPoints[unitId] = movementPoints;
unit_ammo[unitId] = ammo;
unit_minRange[unitId] = minRange;
unit_maxRange[unitId] = maxRange;
/*
for (const auto &weapon : unit.second.get_child("Weapons"))
{
if (weapon.first == "PrimaryWeapon")
{
std::string weaponName = weapon.second.get<std::string>("<xmlattr>.name");
unit_primaryweapon[unitId] = weaponName;
}
else if (weapon.first == "SecondaryWeapon")
{
std::string weaponName = weapon.second.get<std::string>("<xmlattr>.name");
unit_secondaryweapon[unitId] = weaponName;
}
}*/
for (const auto &weapon : unit.second.get_child("Weapons"))
{
if (weapon.first == "PrimaryWeapon")
{
std::string weaponName = weapon.second.get<std::string>("<xmlattr>.name");
unit_primaryweapon[unitId] = weaponName;
for (const auto &damage_entry : weapon.second.get_child("DamageTable"))
{
if (damage_entry.first == "Damage")
{
std::string targetUnitId = damage_entry.second.get<std::string>("<xmlattr>.unitId");
int damageValue = damage_entry.second.get<int>("<xmlattr>.value");
UnitId targetId;
if (targetUnitId == "infantry")
{
targetId = UnitId::INFANTERY;
}
else if (targetUnitId == "Mech")
{
targetId = UnitId::MECHANIZED_INFANTERY;
}
else
{
continue; // Überspringt nicht unterstützte Ziele
}
primary_weapon_damage[unitId][targetId] = damageValue;
}
}
}
else if (weapon.first == "SecondaryWeapon")
{
for (const auto &damage_entry : weapon.second.get_child("DamageTable"))
{
std::string weaponName = weapon.second.get<std::string>("<xmlattr>.name");
unit_secondaryweapon[unitId] = weaponName;
if (damage_entry.first == "Damage")
{
std::string targetUnitId = damage_entry.second.get<std::string>("<xmlattr>.unitId");
int damageValue = damage_entry.second.get<int>("<xmlattr>.value");
UnitId targetId;
if (targetUnitId == "infantry")
{
targetId = UnitId::INFANTERY;
}
else if (targetUnitId == "Mech")
{
targetId = UnitId::MECHANIZED_INFANTERY;
}
else
{
continue; // Überspringt nicht unterstützte Ziele
}
secondary_weapon_damage[unitId][targetId] = damageValue;
}
}
}
}
}
}
}
// Definitions for the accessor methods
int Config::get_unit_cost(UnitId id) const
{
auto it = unit_costs.find(id);
if (it != unit_costs.end())
return it->second;
throw std::runtime_error("Cost for unit ID not found");
}
int Config::get_unit_movementPoints(UnitId id) const
{
auto it = unit_movementPoints.find(id);
if (it != unit_movementPoints.end())
return it->second;
throw std::runtime_error("Movement points for unit ID not found");
}
int Config::get_unit_ammo(UnitId id) const
{
auto it = unit_ammo.find(id);
if (it != unit_ammo.end())
return it->second;
throw std::runtime_error("Ammo for unit ID not found");
}
int Config::get_unit_minRange(UnitId id) const
{
auto it = unit_minRange.find(id);
if (it != unit_minRange.end())
return it->second;
throw std::runtime_error("Min range for unit ID not found");
}
int Config::get_unit_maxRange(UnitId id) const
{
auto it = unit_maxRange.find(id);
if (it != unit_maxRange.end())
return it->second;
throw std::runtime_error("Max range for unit ID not found");
}
std::string Config::get_unit_secondaryweapon(UnitId id) const
{
auto it = unit_secondaryweapon.find(id);
if (it != unit_secondaryweapon.end())
return it->second;
throw std::runtime_error("Secondary weapon for unit ID not found");
}
std::string Config::get_unit_primaryweapon(UnitId id) const
{
auto it = unit_primaryweapon.find(id);
if (it != unit_primaryweapon.end())
return it->second;
throw std::runtime_error("Primary weapon for unit ID not found");
}
} // namespace advanced_wars
#ifndef CONFIG_HPP
#define CONFIG_HPP
#include <unordered_map>
#include <string>
#include <stdexcept>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include "unit.hpp" // Include für UnitId
namespace advanced_wars {
class Config {
public:
Config(MatchupTabel_secondaryweapon& secWeapon, MatchupTabel_primaryweapon& primWeapon);
void loadFromXML(const char* filename);
int get_unit_cost(UnitId id) const;
int get_unit_movementPoints(UnitId id) const;
int get_unit_ammo(UnitId id) const;
int get_unit_minRange(UnitId id) const;
int get_unit_maxRange(UnitId id) const;
std::string get_unit_secondaryweapon(UnitId id) const;
std::string get_unit_primaryweapon(UnitId id) const;
private:
std::unordered_map<UnitId, int> unit_costs;
std::unordered_map<UnitId, int> unit_movementPoints;
std::unordered_map<UnitId, int> unit_ammo;
std::unordered_map<UnitId, int> unit_minRange;
std::unordered_map<UnitId, int> unit_maxRange;
std::unordered_map<UnitId, std::string> unit_secondaryweapon;
std::unordered_map<UnitId, std::string> unit_primaryweapon;
MatchupTabel_secondaryweapon& secondary_weapon_damage;
MatchupTabel_primaryweapon& primary_weapon_damage;
};
} // namespace advanced_wars
#endif // CONFIG_HPP
\ No newline at end of file
......@@ -30,6 +30,8 @@ void Level::render(Engine &engine, std::vector<SDL_Event> &events) {
events.erase(events.begin());
}
// Tiles
for (Tile &tile : tiles) {
tile.render(engine, RENDERING_SCALE);
......
......@@ -8,25 +8,33 @@
#include "window.hpp"
#include <cstddef>
#include <vector>
#include "config.hpp"
#include <iostream>
using namespace advanced_wars;
int main() {
int main()
{
Window window("Advanced Wars", 960, 960);
Engine engine(window);
Unit::readXML();
// Construct a level
std::vector<Tile> tiles;
for (int y = 0; y < 20; y++) {
for (int x = 0; x < 20; x++) {
for (int y = 0; y < 20; y++)
{
for (int x = 0; x < 20; x++)
{
tiles.push_back(Tile(TileId::PLAIN, x, y));
}
}
// Fill the edges with water
for (size_t n = 0; n < 20; n++) {
for (size_t n = 0; n < 20; n++)
{
// Vertical
tiles.at(n * 20) = Tile(TileId::WATER, 0, n);
tiles.at(n * 20 + 19) = Tile(TileId::WATER, 19, n);
......@@ -36,7 +44,8 @@ int main() {
}
// Make the edges cliffs
for (size_t n = 1; n < 19; n++) {
for (size_t n = 1; n < 19; n++)
{
// Vertical
tiles.at(n * 20 + 1) = Tile(TileId::CLIFF_RIGHT, 1, n);
tiles.at(n * 20 + 18) = Tile(TileId::CLIFF_LEFT, 18, n);
......@@ -55,8 +64,10 @@ int main() {
// Buildings
std::vector<Building> buildings;
for (int y = 0; y < 6; y++) {
for (int x = 0; x < 5; x++) {
for (int y = 0; y < 6; y++)
{
for (int x = 0; x < 5; x++)
{
BuildingId id = static_cast<BuildingId>(x);
BuildingFaction faction = static_cast<BuildingFaction>(y);
......@@ -67,8 +78,10 @@ int main() {
// Units
std::vector<Unit> units;
for (int y = 0; y < 19; y++) {
for (int x = 0; x < 6; x++) {
for (int y = 0; y < 19; y++)
{
for (int x = 0; x < 6; x++)
{
units.push_back(Unit(x + 9, y + 2, UnitFaction::URED,
static_cast<UnitId>(y), static_cast<UnitState>(x)));
}
......@@ -82,12 +95,13 @@ int main() {
engine.set_scene(level);
Spritesheet spritesheet("/media/data/rust/sprite-extractor/spritesheet.h5",
Spritesheet spritesheet("/home/lorenz/Hochschule/5.Semester/C++/Projekt2/spritesheet.h5",
engine);
engine.set_spritesheet(spritesheet);
while (!engine.exited()) {
while (!engine.exited())
{
engine.pump();
engine.render();
}
......
#include "unit.hpp"
#include <tinyxml2.h>
#include <iostream>
#include "config.hpp"
namespace advanced_wars
{
MatchupTabel_secondaryweapon secWeapon;
MatchupTabel_secondaryweapon primWeapon;
Unit::Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state)
: x(x), y(y), faction(faction), id(id), state(state)
{
......@@ -174,6 +178,85 @@ namespace advanced_wars
}
return false;
}
// Config test start
void Unit::readXML()
{
Config config(secWeapon, primWeapon);
// Lade Konfigurationsdaten von XML
try
{
config.loadFromXML("../xml/config.xml");
}
catch (const std::exception &e)
{
std::cerr << "Error loading XML: " << e.what() << std::endl;
}
// Liste der zu testenden UnitIds
std::vector<UnitId> testUnits = {UnitId::INFANTERY, UnitId::MECHANIZED_INFANTERY};
for (auto id : testUnits)
{
try
{
int cost = config.get_unit_cost(id);
int movement = config.get_unit_movementPoints(id);
int ammo = config.get_unit_ammo(id);
int minRange = config.get_unit_minRange(id);
int maxRange = config.get_unit_maxRange(id);
std::string primaryWeapon = "None";
std::string secondaryWeapon = "None";
if (id == UnitId::INFANTERY || id == UnitId::MECHANIZED_INFANTERY)
{ // Bsp.-Fall, hier müssten je nach Wunschbedingungen ID's ergänzt werden
try
{
primaryWeapon = config.get_unit_primaryweapon(id);
}
catch (...)
{
// Es passiert nichts, wenn die Primärwaffe fehlt
}
try
{
secondaryWeapon = config.get_unit_secondaryweapon(id);
}
catch (...)
{
// Es passiert nichts, wenn die Sekundärwaffe fehlt
}
}
std::cout << "Unit ID: " << static_cast<int>(id) << std::endl;
std::cout << " Cost: " << cost << std::endl;
std::cout << " Movement Points: " << movement << std::endl;
std::cout << " Ammo: " << ammo << std::endl;
std::cout << " Primary Weapon: " << primaryWeapon << "; Range: " << minRange << "-" << maxRange << std::endl;
std::cout << " Secondary Weapon: " << secondaryWeapon << std::endl;
}
catch (const std::exception &e)
{
std::cerr << "Error retrieving unit data for ID " << static_cast<int>(id) << ": " << e.what() << std::endl;
}
}
std::cout << "Debug secWeapon Inhalt:" << std::endl;
for (const auto &outer : secWeapon)
{
std::cout << "Einheit ID: " << static_cast<int>(outer.first) << std::endl;
for (const auto &inner : outer.second)
{
std::cout << " Ziel ID: " << static_cast<int>(inner.first)
<< " Schaden: " << inner.second << std::endl;
}
}
}
// Config test end
/*
void Unit::loadXML(const char *filename)
{
......
......@@ -5,6 +5,7 @@
#include "weapon.hpp"
#include <optional>
namespace advanced_wars {
enum class UnitFaction {
......@@ -37,6 +38,29 @@ enum class UnitId {
SUBMARINE = 18,
};
/*
enum class UnitId {
INFANTERY,
MECH,
RECON,
MEDIUM_TANK,
HEAVY_TANK,
NEO_TANK,
APC,
ANTI_AIR_TANK,
ARTILLERY,
ROCKET_ARTILLERY,
ANTI_AIR_MISSILE_LAUNCHER,
FIGHTER,
BOMBER,
BATTLE_HELICOPTER,
TRANSPORT_HELICOPTER,
BATTLESHIP,
CRUISER,
LANDER,
SUBMARINE,
};*/
enum class UnitState {
IDLE = 0,
UNAVAILABLE = 1,
......@@ -58,6 +82,9 @@ enum class MovementType {
//Fill the MatchupTabel
using MatchupTabel = std::unordered_map<u_int8_t, std::unordered_map<u_int8_t, int>>;
using MatchupTabel_secondaryweapon = std::unordered_map<UnitId, std::unordered_map<UnitId, int>>;
using MatchupTabel_primaryweapon = std::unordered_map<UnitId, std::unordered_map<UnitId, int>>;
class Unit {
public:
Unit(int x, int y, UnitFaction faction, UnitId id, UnitState state);
......@@ -104,6 +131,8 @@ public:
*/
void loadXML(const char* filename);
static void readXML();
/*
This function will be called by an external event-handler, eventually.
......
<?xml version="1.0" encoding="UTF-8"?>
<Units>
<Unit key="infantry">
<Cost>1000</Cost>
<MovementPoints>3</MovementPoints>
<MovementType>Foot</MovementType>
<minRange>1</minRange>
<maxRange>1</maxRange>
<Ammo>0</Ammo>
<Weapons>
<SecondaryWeapon name="Machine-Gun">
<DamageTable>
<Damage unitId="infantry" value="55"/>
<Damage unitId="Mech" value="45"/>
</DamageTable>
</SecondaryWeapon>
</Weapons>
</Unit>
<Unit key="Mech">
<Cost>3000</Cost>
<MovementPoints>2</MovementPoints>
<MovementType>Foot</MovementType>
<Ammo>9</Ammo>
<minRange>1</minRange>
<maxRange>1</maxRange>
<Weapons>
<PrimaryWeapon name="Rockets">
<DamageTable>
<Damage unitId="infantry" value="65"/>
<Damage unitId="Mech" value="55"/>
</DamageTable>
</PrimaryWeapon>
<SecondaryWeapon name="Machine-Gun">
<DamageTable>
<Damage unitId="infantry" value="65"/>
<Damage unitId="Mech" value="55"/>
</DamageTable>
</SecondaryWeapon>
</Weapons>
</Unit>
</Units>
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment