From ee27e5341dcc3403aacf9f2c42d190ac4a7f0795 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Thu, 22 Jan 2015 11:23:44 -0500 Subject: [PATCH] Implement writing terrain definitions to XML --- src/classes/special.cpp | 2 +- src/classes/special.h | 2 +- src/classes/terrain.cpp | 107 +++++++++++++++++++++++-- src/classes/terrain.h | 21 ++--- src/dialogxml/xml-parser/tinyprint.hpp | 8 ++ src/scenedit/scen.fileio.cpp | 45 +++++++++++ 6 files changed, 167 insertions(+), 18 deletions(-) diff --git a/src/classes/special.cpp b/src/classes/special.cpp index 7b85a7ae..cd746298 100644 --- a/src/classes/special.cpp +++ b/src/classes/special.cpp @@ -329,7 +329,7 @@ void cSpecial::append(legacy::special_node_type& old){ } } -std::ostream& operator << (std::ostream& out, eSpecType& e) { +std::ostream& operator << (std::ostream& out, eSpecType e) { return out << (int) e; } diff --git a/src/classes/special.h b/src/classes/special.h index df6b96e8..fd341857 100644 --- a/src/classes/special.h +++ b/src/classes/special.h @@ -64,7 +64,7 @@ struct node_properties_t { node_properties_t(std::initializer_list>); }; -std::ostream& operator << (std::ostream& out, eSpecType& e); +std::ostream& operator << (std::ostream& out, eSpecType e); std::istream& operator >> (std::istream& in, eSpecType& e); const node_properties_t& operator* (eSpecType t); diff --git a/src/classes/terrain.cpp b/src/classes/terrain.cpp index 218f6a9e..5691dd3c 100644 --- a/src/classes/terrain.cpp +++ b/src/classes/terrain.cpp @@ -355,7 +355,7 @@ void cTerrain::append(legacy::terrain_type_type& old){ else map_pic = NO_PIC; } -std::ostream& operator << (std::ostream& out, eTerSpec& e){ +std::ostream& operator << (std::ostream& out, eTerSpec e){ return out << (int) e; } @@ -368,15 +368,108 @@ std::istream& operator >> (std::istream& in, eTerSpec& e){ return in; } -std::ostream& operator << (std::ostream& out, eTerObstruct& e){ - return out << (int) e; +std::ostream& operator << (std::ostream& out, eTrimType e){ + switch(e) { + case eTrimType::NONE: out << "none"; break; + case eTrimType::WALL: out << "wall"; break; + case eTrimType::S: out << "s"; break; + case eTrimType::N: out << "n"; break; + case eTrimType::E: out << "e"; break; + case eTrimType::W: out << "w"; break; + case eTrimType::SW: out << "sw"; break; + case eTrimType::NE: out << "ne"; break; + case eTrimType::SE: out << "se"; break; + case eTrimType::NW: out << "nw"; break; + case eTrimType::SW_INNER: out << "sw-inner"; break; + case eTrimType::NE_INNER: out << "ne-inner"; break; + case eTrimType::SE_INNER: out << "se-inner"; break; + case eTrimType::NW_INNER: out << "nw-inner"; break; + case eTrimType::FRILLS: out << "frills"; break; + case eTrimType::ROAD: out << "road"; break; + case eTrimType::WALKWAY: out << "walkway"; break; + case eTrimType::WATERFALL: out << "waterfall"; break; + case eTrimType::CITY: out << "city"; break; + } + return out; +} + +std::istream& operator >> (std::istream& in, eTrimType& e){ + std::string key; + in >> key; + e = eTrimType::NONE; + if(key.empty()) return in; + if(key[0] == 'n') { + if(key.length() == 1) + e = eTrimType::N; + else if(key[1] == 'w') { + if(key.length() == 2) + e = eTrimType::NW; + else if(key == "nw-inner") + e = eTrimType::NW_INNER; + } else if(key[1] == 'e') { + if(key.length() == 2) + e = eTrimType::NE; + else if(key == "ne-inner") + e = eTrimType::NE_INNER; + } + } else if(key[0] == 's') { + if(key.length() == 1) + e = eTrimType::S; + else if(key[1] == 'w') { + if(key.length() == 2) + e = eTrimType::SW; + else if(key == "sw-inner") + e = eTrimType::SW_INNER; + } else if(key[1] == 'e') { + if(key.length() == 2) + e = eTrimType::SE; + else if(key == "se-inner") + e = eTrimType::SE_INNER; + } + } else if(key == "e") + e = eTrimType::E; + else if(key == "w") + e = eTrimType::W; + else if(key == "wall") + e = eTrimType::WALL; + else if(key == "walkway") + e = eTrimType::WALKWAY; + else if(key == "waterfall") + e = eTrimType::WATERFALL; + else if(key == "frills") + e = eTrimType::FRILLS; + else if(key == "road") + e = eTrimType::ROAD; + else if(key == "city") + e = eTrimType::CITY; + return in; +} + +std::ostream& operator<< (std::ostream& out, eTerObstruct block) { + switch(block) { + case eTerObstruct::CLEAR: out << "none"; break; + case eTerObstruct::BLOCK_MOVE: out << "move"; break; + case eTerObstruct::BLOCK_MONSTERS: out << "monsters"; break; + case eTerObstruct::BLOCK_SIGHT: out << "sight"; break; + case eTerObstruct::BLOCK_MOVE_AND_SHOOT: out << "move-and-shoot"; break; + case eTerObstruct::BLOCK_MOVE_AND_SIGHT: out << "move-and-sight"; break; + } + return out; } std::istream& operator >> (std::istream& in, eTerObstruct& e){ - int i; - in >> i; - if(i > 0 && i < 6) - e = (eTerObstruct) i; + std::string key; + in >> key; + if(key == "move") + e = eTerObstruct::BLOCK_MOVE; + else if(key == "monsters") + e = eTerObstruct::BLOCK_MONSTERS; + else if(key == "sight") + e = eTerObstruct::BLOCK_SIGHT; + else if(key == "move-and-shoot") + e = eTerObstruct::BLOCK_MOVE_AND_SHOOT; + else if(key == "move-and-sight") + e = eTerObstruct::BLOCK_MOVE_AND_SIGHT; else e = eTerObstruct::CLEAR; return in; } diff --git a/src/classes/terrain.h b/src/classes/terrain.h index 24c0e28a..55c1affe 100644 --- a/src/classes/terrain.h +++ b/src/classes/terrain.h @@ -15,6 +15,7 @@ #include "simpletypes.h" #include "pictypes.hpp" #include "location.h" +#include "soundtool.hpp" // for snd_num_t namespace legacy { struct terrain_type_type; }; @@ -31,14 +32,14 @@ public: ter_flag_t flag3; // new additional flag for special properties eTerSpec special; ter_num_t trans_to_what; - unsigned char fly_over; - unsigned char boat_over; - unsigned char block_horse; - unsigned char light_radius; - unsigned char step_sound; + bool fly_over; + bool boat_over; + bool block_horse; + unsigned int light_radius; + snd_num_t step_sound; unsigned char shortcut_key; // for editor use only - unsigned char obj_num = 0; // ditto (formerly res1) - unsigned char ground_type; // ditto (formerly res2) + unsigned int obj_num = 0; // ditto (formerly res1) + unsigned int ground_type; // ditto (formerly res2) eTrimType trim_type; // ditto, mostly (formerly res3) unsigned short trim_ter; // ditto unsigned short combat_arena; @@ -51,9 +52,11 @@ public: void writeTo(std::ostream& file) const; }; -std::ostream& operator << (std::ostream& out, eTerSpec& e); +std::ostream& operator << (std::ostream& out, eTerSpec e); std::istream& operator >> (std::istream& in, eTerSpec& e); -std::ostream& operator << (std::ostream& out, eTerObstruct& e); +std::ostream& operator << (std::ostream& out, eTrimType e); +std::istream& operator >> (std::istream& in, eTrimType& e); +std::ostream& operator << (std::ostream& out, eTerObstruct e); std::istream& operator >> (std::istream& in, eTerObstruct& e); #endif diff --git a/src/dialogxml/xml-parser/tinyprint.hpp b/src/dialogxml/xml-parser/tinyprint.hpp index 6a8325bc..ab4d28a3 100644 --- a/src/dialogxml/xml-parser/tinyprint.hpp +++ b/src/dialogxml/xml-parser/tinyprint.hpp @@ -42,4 +42,12 @@ namespace ticpp { }; } +template<> inline void ticpp::Printer::PushAttribute(std::string attrName, bool attrVal) { + PushAttribute(attrName, attrVal ? "true" : "false"); +} + +template<> inline void ticpp::Printer::PushText(bool textVal) { + PushText(textVal ? "true" : "false"); +} + #endif diff --git a/src/scenedit/scen.fileio.cpp b/src/scenedit/scen.fileio.cpp index 3d752129..0a0e01d3 100644 --- a/src/scenedit/scen.fileio.cpp +++ b/src/scenedit/scen.fileio.cpp @@ -197,6 +197,50 @@ void writeScenarioToXml(ticpp::Printer&& data) { data.CloseElement("scenario"); } +void writeTerrainToXml(ticpp::Printer&& data) { + data.OpenElement("terrains"); + for(size_t i = 0; i < scenario.ter_types.size(); i++) { + data.OpenElement("terrain"); + data.PushAttribute("id", i); + cTerrain& ter = scenario.ter_types[i]; + data.PushElement("name", ter.name); + data.PushElement("pic", ter.picture); + data.PushElement("map", ter.map_pic); + data.PushElement("blockage", ter.blockage); + data.PushElement("transform", ter.trans_to_what); + data.PushElement("fly", ter.fly_over); + data.PushElement("boat", ter.boat_over); + data.PushElement("ride", !ter.block_horse); + data.PushElement("light", ter.light_radius); + data.PushElement("step-sound", ter.step_sound); + data.PushElement("trim", ter.trim_type); + data.PushElement("arena", ter.combat_arena); + + data.OpenElement("special"); + data.PushElement("type", ter.special); + data.PushElement("flag", ter.flag1.u); + data.PushElement("flag", ter.flag2.u); + data.PushElement("flag", ter.flag3.u); + data.CloseElement("special"); + + data.OpenElement("editor"); + if(ter.shortcut_key > 0) + data.PushElement("shortcut", ter.shortcut_key); + data.PushElement("ground", ter.ground_type); + data.PushElement("trim-for", ter.trim_ter); + if(ter.obj_num > 0) { + data.OpenElement("object"); + data.PushElement("num", ter.obj_num); + data.PushElement("pos", ter.obj_pos); + data.PushElement("size", ter.obj_size); + data.CloseElement("object"); + } + data.CloseElement("editor"); + data.CloseElement("terrain"); + } + data.CloseElement("terrains"); +} + void save_scenario(fs::path toFile) { // TODO: I'm not certain 1.0.0 is the correct version here? scenario.format.prog_make_ver[0] = 1; @@ -214,6 +258,7 @@ void save_scenario(fs::path toFile) { // Then the terrains... std::ostream& terrain = scen_file.newFile("scenario/terrain.xml"); + writeTerrainToXml(ticpp::Printer("terrain.xml", terrain)); // ...items... std::ostream& items = scen_file.newFile("scenario/items.xml");