Implement saving monster definitions to XML
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
<monster id="7">
|
||||
<!-- The monster's name -->
|
||||
<name>Cave Cow</name>
|
||||
<!-- Species -->
|
||||
<race>beast</race>
|
||||
<!-- Monster picture -->
|
||||
<pic w='1' h='1'>5</pic>
|
||||
<!-- Experience level -->
|
||||
@@ -18,17 +20,32 @@
|
||||
<attacks>
|
||||
<attack type='0'>1d4</attack>
|
||||
</attacks>
|
||||
<!-- Breath weapon -->
|
||||
<breath type='dark'>1</breath>
|
||||
<!-- Special abilities -->
|
||||
<abilities>
|
||||
<ability>
|
||||
<type>0</type>
|
||||
<param>4</param>
|
||||
</ability>
|
||||
<!-- A breath weapon; 12 = damage2, 3 = breath, 4 = unblockable damage -->
|
||||
<general type='12'>
|
||||
<type>3</type>
|
||||
<missile>8</missile>
|
||||
<strength>1</strength>
|
||||
<range>8</range>
|
||||
<chance>37.5</chance>
|
||||
<extra>4</extra>
|
||||
</general>
|
||||
<!-- Archery; 1 = missile, 1 = arrow -->
|
||||
<missile type='1'>
|
||||
<type>1</type>
|
||||
<missile>3</missile>
|
||||
<strength>8d7</strength>
|
||||
<skill>16</skill>
|
||||
<range>10</range>
|
||||
<chance>87.5</chance>
|
||||
</missile>
|
||||
<!-- Radiate fire fields; 22 = radiate, 2 = fire -->
|
||||
<radiate type='22'>
|
||||
<type>2</type>
|
||||
<chance>100</chance>
|
||||
</radiate>
|
||||
</abilities>
|
||||
<!-- Actions on sighting -->
|
||||
<onsight/>
|
||||
<!-- Ambient sound (eg cow mooing) -->
|
||||
<voice>17</voice>
|
||||
<!-- Summon class -->
|
||||
@@ -37,7 +54,7 @@
|
||||
<attitude>2</attitude>
|
||||
<!-- Immunities (empty element for none) -->
|
||||
<immunity>
|
||||
<fire resist='true'/>
|
||||
<fire>50</fire>
|
||||
</immunity>
|
||||
</monster>
|
||||
</monsters>
|
@@ -11,16 +11,90 @@
|
||||
<xs:pattern value="\d*d\d+"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:complexType name="immunity">
|
||||
<xs:attribute name="immune" type="bool"/>
|
||||
<xs:attribute name="resist" type="bool"/>
|
||||
</xs:complexType>
|
||||
<xs:element name="ability">
|
||||
<xs:simpleType name="species">
|
||||
<xs:restriction base="xs:token">
|
||||
<xs:enumeration value="human"/>
|
||||
<xs:enumeration value="nephil"/>
|
||||
<xs:enumeration value="slith"/>
|
||||
<xs:enumeration value="vahnatai"/>
|
||||
<xs:enumeration value="reptile"/>
|
||||
<xs:enumeration value="beast"/>
|
||||
<xs:enumeration value="important"/>
|
||||
<xs:enumeration value="mage"/>
|
||||
<xs:enumeration value="priest"/>
|
||||
<xs:enumeration value="humanoid"/>
|
||||
<xs:enumeration value="demon"/>
|
||||
<xs:enumeration value="undead"/>
|
||||
<xs:enumeration value="giant"/>
|
||||
<xs:enumeration value="slime"/>
|
||||
<xs:enumeration value="stone"/>
|
||||
<xs:enumeration value="bug"/>
|
||||
<xs:enumeration value="dragon"/>
|
||||
<xs:enumeration value="magic"/>
|
||||
<xs:enumeration value="plant"/>
|
||||
<xs:enumeration value="bird"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="permille">
|
||||
<xs:restriction base="xs:decimal">
|
||||
<xs:fractionDigits value="1"/>
|
||||
<xs:maxInclusive value="100"/>
|
||||
<xs:minInclusive value="0"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:element name="general">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="type" type="xs:integer"/>
|
||||
<xs:element name="missile" type="xs:integer" minOccurs="0"/>
|
||||
<xs:element name="strength" type="xs:integer"/>
|
||||
<xs:element name="range" type="xs:integer" minOccurs="0"/>
|
||||
<xs:element name="chance" type="permille"/>
|
||||
<xs:element name="extra" type="xs:integer" minOccurs="0"/>
|
||||
</xs:all>
|
||||
<xs:attribute name="type" type="xs:integer" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="missile">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="type" type="xs:integer"/>
|
||||
<xs:element name="missile" type="xs:integer"/>
|
||||
<xs:element name="strength" type="dice"/>
|
||||
<xs:element name="skill" type="xs:integer"/>
|
||||
<xs:element name="range" type="xs:integer"/>
|
||||
<xs:element name="chance" type="permille"/>
|
||||
</xs:all>
|
||||
<xs:attribute name="type" type="xs:integer" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="summon">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="type" type="xs:integer"/>
|
||||
<xs:element name="min" type="xs:integer"/>
|
||||
<xs:element name="max" type="xs:integer"/>
|
||||
<xs:element name="duration" type="xs:integer"/>
|
||||
<xs:element name="chance" type="permille"/>
|
||||
</xs:all>
|
||||
<xs:attribute name="type" type="xs:integer" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="radiate">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="type" type="xs:integer"/>
|
||||
<xs:element name="chance" type="permille"/>
|
||||
</xs:all>
|
||||
<xs:attribute name="type" type="xs:integer" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="special">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="type" type="xs:integer"/>
|
||||
<xs:element name="param" type="xs:integer" minOccurs="0" maxOccurs="2"/>
|
||||
<xs:element name="param" type="xs:integer" minOccurs="0" maxOccurs="3"/>
|
||||
</xs:sequence>
|
||||
<xs:attribute name="type" type="xs:integer" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="attack">
|
||||
@@ -44,31 +118,25 @@
|
||||
<xs:element name="treasure" minOccurs="0" type="xs:integer"/>
|
||||
<xs:element name="mage" minOccurs="0" type="xs:integer"/>
|
||||
<xs:element name="priest" minOccurs="0" type="xs:integer"/>
|
||||
<xs:element name="breath" minOccurs="0">
|
||||
<xs:complexType>
|
||||
<xs:simpleContent>
|
||||
<xs:extension base="xs:integer">
|
||||
<xs:attribute name="type" use="required">
|
||||
<xs:simpleType>
|
||||
<xs:restriction base="xs:token">
|
||||
<xs:enumeration value="fire"/>
|
||||
<xs:enumeration value="cold"/>
|
||||
<xs:enumeration value="shock"/>
|
||||
<xs:enumeration value="dark"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
</xs:attribute>
|
||||
</xs:extension>
|
||||
</xs:simpleContent>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="poison" minOccurs="0" type="xs:integer"/>
|
||||
<xs:element name="race" type="species"/>
|
||||
<xs:element name="abilities" minOccurs="0">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element ref="ability" maxOccurs="2"/>
|
||||
<xs:element name="invisible" minOccurs="0"/>
|
||||
<xs:element name="guard" minOccurs="0"/>
|
||||
<xs:choice maxOccurs="unbounded">
|
||||
<xs:element ref="general" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:element ref="missile" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:element ref="summon" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:element ref="radiate" minOccurs="0" maxOccurs="unbounded"/>
|
||||
<xs:element ref="special" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:choice>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
<xs:unique name="abilsPerMonst">
|
||||
<xs:selector xpath="general|missile|summon|radiate|special"/>
|
||||
<xs:field xpath="@type"/>
|
||||
</xs:unique>
|
||||
</xs:element>
|
||||
<xs:element name="attacks">
|
||||
<xs:complexType>
|
||||
@@ -89,31 +157,19 @@
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="default-face" minOccurs="0" type="xs:integer"/>
|
||||
<xs:element name="onsight" minOccurs="0">
|
||||
<xs:complexType>
|
||||
<xs:all minOccurs="1">
|
||||
<xs:element name="sound" minOccurs="0" type="xs:integer"/>
|
||||
<xs:element name="special" minOccurs="0" type="xs:integer"/>
|
||||
<xs:element name="message" minOccurs="0">
|
||||
<xs:complexType>
|
||||
<xs:sequence>
|
||||
<xs:element name="text" maxOccurs="2" type="xs:string"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="onsight" minOccurs="0" type="xs:integer"/>
|
||||
<xs:element name="voice" minOccurs="0" type="xs:integer"/>
|
||||
<xs:element name="summon" minOccurs="0" type="xs:integer"/>
|
||||
<xs:element name="attitude" type="xs:integer"/>
|
||||
<xs:element name="immunity">
|
||||
<xs:complexType>
|
||||
<xs:all>
|
||||
<xs:element name="fire" type="immunity" minOccurs="0"/>
|
||||
<xs:element name="cold" type="immunity" minOccurs="0"/>
|
||||
<xs:element name="poison" type="immunity" minOccurs="0"/>
|
||||
<xs:element name="magic" type="immunity" minOccurs="0"/>
|
||||
<xs:element name="fire" type="xs:integer" minOccurs="0"/>
|
||||
<xs:element name="cold" type="xs:integer" minOccurs="0"/>
|
||||
<xs:element name="poison" type="xs:integer" minOccurs="0"/>
|
||||
<xs:element name="magic" type="xs:integer" minOccurs="0"/>
|
||||
<xs:element name="all" type="bool" minOccurs="0"/>
|
||||
<xs:element name="fear" type="bool" minOccurs="0"/>
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
@@ -135,5 +191,9 @@
|
||||
<xs:element ref="monster" minOccurs="0" maxOccurs="unbounded"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
<xs:unique name='monsterIds'>
|
||||
<xs:selector xpath='monster'/>
|
||||
<xs:field xpath='@id'/>
|
||||
</xs:unique>
|
||||
</xs:element>
|
||||
</xs:schema>
|
||||
|
@@ -11,6 +11,7 @@
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "classes.h"
|
||||
#include "oldstructs.h"
|
||||
@@ -467,15 +468,82 @@ std::istream& operator >> (std::istream& in, eStatus& e){
|
||||
}
|
||||
|
||||
std::ostream& operator << (std::ostream& out, eRace e){
|
||||
return out << (int) e;
|
||||
switch(e) {
|
||||
case eRace::HUMAN: out << "human"; break;
|
||||
case eRace::NEPHIL: out << "nephil"; break;
|
||||
case eRace::SLITH: out << "slith"; break;
|
||||
case eRace::VAHNATAI: out << "vahnatai"; break;
|
||||
case eRace::HUMANOID: out << "humanoid"; break;
|
||||
case eRace::BEAST: out << "beast"; break;
|
||||
case eRace::BIRD: out << "bird"; break;
|
||||
case eRace::BUG: out << "bug"; break;
|
||||
case eRace::DEMON: out << "demon"; break;
|
||||
case eRace::DRAGON: out << "dragon"; break;
|
||||
case eRace::GIANT: out << "giant"; break;
|
||||
case eRace::IMPORTANT: out << "important"; break;
|
||||
case eRace::MAGE: out << "mage"; break;
|
||||
case eRace::PRIEST: out << "priest"; break;
|
||||
case eRace::MAGICAL: out << "magic"; break;
|
||||
case eRace::PLANT: out << "plant"; break;
|
||||
case eRace::REPTILE: out << "reptile"; break;
|
||||
case eRace::SLIME: out << "slime"; break;
|
||||
case eRace::STONE: out << "stone"; break;
|
||||
case eRace::UNDEAD: out << "undead"; break;
|
||||
case eRace::UNKNOWN: out << "humanoid"; break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
std::istream& operator >> (std::istream& in, eRace& e){
|
||||
int i;
|
||||
in >> i;
|
||||
if(i > 0 && i < 20)
|
||||
e = (eRace) i;
|
||||
else e = eRace::HUMAN;
|
||||
std::string key;
|
||||
in >> key;
|
||||
e = eRace::HUMANOID;
|
||||
try {
|
||||
int i = boost::lexical_cast<int>(key);
|
||||
if(i > 0 && i < 20)
|
||||
e = (eRace) i;
|
||||
} catch(boost::bad_lexical_cast) {
|
||||
if(key == "human")
|
||||
e = eRace::HUMAN;
|
||||
else if(key == "nephil")
|
||||
e = eRace::NEPHIL;
|
||||
else if(key == "slith")
|
||||
e = eRace::SLITH;
|
||||
else if(key == "vahnatai")
|
||||
e = eRace::VAHNATAI;
|
||||
else if(key == "humanoid")
|
||||
e = eRace::HUMANOID;
|
||||
else if(key == "beast")
|
||||
e = eRace::BEAST;
|
||||
else if(key == "bird")
|
||||
e = eRace::BIRD;
|
||||
else if(key == "bug")
|
||||
e = eRace::BUG;
|
||||
else if(key == "demon")
|
||||
e = eRace::DEMON;
|
||||
else if(key == "dragon")
|
||||
e = eRace::DRAGON;
|
||||
else if(key == "giant")
|
||||
e = eRace::GIANT;
|
||||
else if(key == "important")
|
||||
e = eRace::IMPORTANT;
|
||||
else if(key == "mage")
|
||||
e = eRace::MAGE;
|
||||
else if(key == "priest")
|
||||
e = eRace::PRIEST;
|
||||
else if(key == "magic")
|
||||
e = eRace::MAGICAL;
|
||||
else if(key == "plant")
|
||||
e = eRace::PLANT;
|
||||
else if(key == "reptile")
|
||||
e = eRace::REPTILE;
|
||||
else if(key == "slime")
|
||||
e = eRace::SLIME;
|
||||
else if(key == "stone")
|
||||
e = eRace::STONE;
|
||||
else if(key == "undead")
|
||||
e = eRace::UNDEAD;
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
|
@@ -116,17 +116,17 @@ public:
|
||||
unsigned short dice, sides;
|
||||
eMonstMelee type;
|
||||
};
|
||||
unsigned char level;
|
||||
unsigned int level;
|
||||
std::string m_name;
|
||||
short m_health;
|
||||
unsigned char armor;
|
||||
unsigned char skill;
|
||||
unsigned int armor;
|
||||
unsigned int skill;
|
||||
cAttack a[3];
|
||||
eRace m_type;
|
||||
unsigned char speed;
|
||||
unsigned char mu;
|
||||
unsigned char cl;
|
||||
unsigned char treasure;
|
||||
unsigned int speed;
|
||||
unsigned int mu;
|
||||
unsigned int cl;
|
||||
unsigned int treasure;
|
||||
std::map<eMonstAbil, uAbility> abil;
|
||||
item_num_t corpse_item;
|
||||
short corpse_item_chance;
|
||||
@@ -139,9 +139,9 @@ public:
|
||||
bool invisible : 1;
|
||||
bool guard : 1;
|
||||
char : 4;
|
||||
unsigned char x_width,y_width;
|
||||
unsigned char default_attitude;
|
||||
unsigned char summon_type;
|
||||
unsigned int x_width,y_width;
|
||||
unsigned int default_attitude;
|
||||
unsigned int summon_type;
|
||||
pic_num_t default_facial_pic;
|
||||
pic_num_t picture_num;
|
||||
snd_num_t ambient_sound; // has a chance of being played every move
|
||||
|
@@ -30,6 +30,10 @@ void Printer::CloseElement(std::string tagName) {
|
||||
PushNode(top);
|
||||
}
|
||||
|
||||
void Printer::PushElement(std::string tagName) {
|
||||
PushNode(new Element(tagName));
|
||||
}
|
||||
|
||||
void Printer::PushComment(std::string comment) {
|
||||
PushNode(new Comment(comment));
|
||||
}
|
||||
|
@@ -25,6 +25,7 @@ namespace ticpp {
|
||||
~Printer();
|
||||
void OpenElement(std::string tagName);
|
||||
void CloseElement(std::string tagName);
|
||||
void PushElement(std::string tagName);
|
||||
void PushComment(std::string comment);
|
||||
void PushStylesheet(std::string value, std::string href);
|
||||
void PushNode(Node* node);
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#include "classes.h"
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <iomanip>
|
||||
#include "scen.fileio.h"
|
||||
#include "scen.keydlgs.h"
|
||||
#include "graphtool.hpp"
|
||||
@@ -60,6 +61,15 @@ template<> void ticpp::Printer::PushElement(std::string tagName, location pos) {
|
||||
CloseElement(tagName);
|
||||
}
|
||||
|
||||
template<> void ticpp::Printer::PushElement(std::string tagName, cMonster::cAttack attack) {
|
||||
OpenElement(tagName);
|
||||
PushAttribute("type", attack.type);
|
||||
std::ostringstream strength;
|
||||
strength << attack.dice << 'd' << attack.sides;
|
||||
PushText(strength.str());
|
||||
CloseElement(tagName);
|
||||
}
|
||||
|
||||
static bool is_minmax(int lo, int hi, int val) {
|
||||
return minmax(lo, hi, val) == val;
|
||||
}
|
||||
@@ -291,6 +301,150 @@ void writeItemsToXml(ticpp::Printer&& data) {
|
||||
data.CloseElement("items");
|
||||
}
|
||||
|
||||
void writeMonstersToXml(ticpp::Printer&& data) {
|
||||
std::ostringstream str;
|
||||
data.OpenElement("monsters");
|
||||
for(size_t i = 1; i < scenario.scen_monsters.size(); i++) {
|
||||
data.OpenElement("monster");
|
||||
data.PushAttribute("id", i);
|
||||
cMonster& monst = scenario.scen_monsters[i];
|
||||
data.PushElement("name", monst.m_name);
|
||||
if(monst.default_facial_pic >= 0)
|
||||
data.PushElement("default-face", monst.default_facial_pic);
|
||||
|
||||
data.OpenElement("pic");
|
||||
data.PushAttribute("w", monst.x_width);
|
||||
data.PushAttribute("h", monst.y_width);
|
||||
data.PushText(monst.picture_num);
|
||||
data.CloseElement("pic");
|
||||
|
||||
data.PushElement("race", monst.m_type);
|
||||
data.PushElement("level", monst.level);
|
||||
data.PushElement("armor", monst.armor);
|
||||
data.PushElement("skill", monst.skill);
|
||||
data.PushElement("hp", monst.m_health);
|
||||
data.PushElement("speed", monst.speed);
|
||||
data.PushElement("attitude", monst.default_attitude);
|
||||
data.PushElement("summon", monst.summon_type);
|
||||
data.PushElement("treasure", monst.treasure);
|
||||
if(monst.mu > 0)
|
||||
data.PushElement("mage", monst.mu);
|
||||
if(monst.cl > 0)
|
||||
data.PushElement("priest", monst.cl);
|
||||
if(monst.ambient_sound > 0)
|
||||
data.PushElement("voice", monst.ambient_sound);
|
||||
if(monst.see_spec >= 0)
|
||||
data.PushElement("onsight", monst.see_spec);
|
||||
|
||||
data.OpenElement("attacks");
|
||||
data.PushElement("attack", monst.a[0]);
|
||||
if(monst.a[1].dice > 0 || monst.a[2].dice > 0)
|
||||
data.PushElement("attack", monst.a[1]);
|
||||
if(monst.a[2].dice > 0)
|
||||
data.PushElement("attack", monst.a[2]);
|
||||
data.CloseElement("attacks");
|
||||
|
||||
data.OpenElement("immunity");
|
||||
if(monst.magic_res != 100)
|
||||
data.PushElement("magic", monst.magic_res);
|
||||
if(monst.fire_res != 100)
|
||||
data.PushElement("fire", monst.magic_res);
|
||||
if(monst.cold_res != 100)
|
||||
data.PushElement("cold", monst.magic_res);
|
||||
if(monst.poison_res != 100)
|
||||
data.PushElement("poison", monst.magic_res);
|
||||
if(monst.mindless) data.PushElement("fear", true);
|
||||
if(monst.invuln) data.PushElement("all", true);
|
||||
data.CloseElement("immunity");
|
||||
|
||||
if(monst.corpse_item_chance > 0) {
|
||||
data.OpenElement("loot");
|
||||
data.PushElement("type", monst.corpse_item);
|
||||
data.PushElement("chance", monst.corpse_item_chance);
|
||||
data.CloseElement("loot");
|
||||
}
|
||||
|
||||
if(monst.invisible || monst.guard || !monst.abil.empty()) {
|
||||
data.OpenElement("abilities");
|
||||
if(monst.invisible) data.PushElement("invisible");
|
||||
if(monst.guard) data.PushElement("guard");
|
||||
for(auto& p : monst.abil) {
|
||||
if(p.first == eMonstAbil::NO_ABIL || !p.second.active) continue;
|
||||
str.str("");
|
||||
eMonstAbil abil = p.first;
|
||||
uAbility& param = p.second;
|
||||
switch(getMonstAbilCategory(abil)) {
|
||||
case eMonstAbilCat::GENERAL:
|
||||
data.OpenElement("general");
|
||||
data.PushAttribute("type", abil);
|
||||
data.PushElement("type", param.gen.type);
|
||||
if(param.gen.type != eMonstGen::TOUCH) {
|
||||
data.PushElement("missile", param.gen.pic);
|
||||
data.PushElement("range", param.gen.range);
|
||||
}
|
||||
data.PushElement("strength", param.gen.strength);
|
||||
str << std::fixed << std::setprecision(1) << float(param.gen.odds)/10;
|
||||
data.PushElement("chance", str.str());
|
||||
if(abil == eMonstAbil::DAMAGE || abil == eMonstAbil::DAMAGE2)
|
||||
data.PushElement("extra", param.gen.dmg);
|
||||
else if(abil == eMonstAbil::STATUS || abil == eMonstAbil::STATUS2 || abil == eMonstAbil::STUN)
|
||||
data.PushElement("extra", param.gen.stat);
|
||||
else if(abil == eMonstAbil::FIELD)
|
||||
data.PushElement("extra", param.gen.fld);
|
||||
data.CloseElement("general");
|
||||
break;
|
||||
case eMonstAbilCat::MISSILE:
|
||||
data.OpenElement("missile");
|
||||
data.PushAttribute("type", abil);
|
||||
data.PushElement("type", param.missile.type);
|
||||
data.PushElement("missile", param.missile.pic);
|
||||
data.OpenElement("strength");
|
||||
data.PushText(std::to_string(param.missile.dice) + 'd' + std::to_string(param.missile.sides));
|
||||
data.CloseElement("strength");
|
||||
data.PushElement("skill", param.missile.skill);
|
||||
data.PushElement("range", param.missile.range);
|
||||
str << std::fixed << std::setprecision(1) << float(param.missile.odds)/10;
|
||||
data.PushElement("chance", str.str());
|
||||
data.CloseElement("missile");
|
||||
break;
|
||||
case eMonstAbilCat::SUMMON:
|
||||
data.OpenElement("summon");
|
||||
data.PushAttribute("type", abil);
|
||||
data.PushElement("type", param.summon.type);
|
||||
data.PushElement("min", param.summon.min);
|
||||
data.PushElement("max", param.summon.max);
|
||||
data.PushElement("duration", param.summon.len);
|
||||
data.PushElement("chance", param.summon.chance);
|
||||
data.CloseElement("summon");
|
||||
break;
|
||||
case eMonstAbilCat::RADIATE:
|
||||
data.OpenElement("radiate");
|
||||
data.PushAttribute("type", abil);
|
||||
data.PushElement("type", param.radiate.type);
|
||||
data.PushElement("chance", param.radiate.chance);
|
||||
data.CloseElement("radiate");
|
||||
break;
|
||||
case eMonstAbilCat::SPECIAL:
|
||||
data.OpenElement("special");
|
||||
data.PushAttribute("type", abil);
|
||||
data.PushElement("param", param.special.extra1);
|
||||
if(abil != eMonstAbil::SPLITS && abil != eMonstAbil::DEATH_TRIGGER) {
|
||||
data.PushElement("param", param.special.extra2);
|
||||
if(abil == eMonstAbil::RAY_HEAT)
|
||||
data.PushElement("param", param.special.extra3);
|
||||
}
|
||||
data.CloseElement("special");
|
||||
break;
|
||||
case eMonstAbilCat::INVALID: break;
|
||||
}
|
||||
}
|
||||
data.CloseElement("abilities");
|
||||
}
|
||||
data.CloseElement("monster");
|
||||
}
|
||||
data.CloseElement("monsters");
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -316,6 +470,7 @@ void save_scenario(fs::path toFile) {
|
||||
|
||||
// ...and monsters
|
||||
std::ostream& monsters = scen_file.newFile("scenario/monsters.xml");
|
||||
writeMonstersToXml(ticpp::Printer("monsters.xml", monsters));
|
||||
|
||||
// And the special nodes.
|
||||
std::ostream& scen_spec = scen_file.newFile("scenario/scenario.spec");
|
||||
|
Reference in New Issue
Block a user