Implement writing item definitions to XML
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<items>
|
||||
<item>
|
||||
<item id='0'>
|
||||
<variety>shield</variety>
|
||||
<level>3</level>
|
||||
<pic>12</pic>
|
||||
|
@@ -21,6 +21,7 @@
|
||||
<xs:enumeration value="tool"/>
|
||||
<xs:enumeration value="food"/>
|
||||
<xs:enumeration value="shield"/>
|
||||
<xs:enumeration value="shield2"/>
|
||||
<xs:enumeration value="armor"/>
|
||||
<xs:enumeration value="helm"/>
|
||||
<xs:enumeration value="gloves"/>
|
||||
@@ -28,20 +29,22 @@
|
||||
<xs:enumeration value="ring"/>
|
||||
<xs:enumeration value="necklace"/>
|
||||
<xs:enumeration value="poison"/>
|
||||
<xs:enumeration value="non-usable"/>
|
||||
<xs:enumeration value="object"/>
|
||||
<xs:enumeration value="pants"/>
|
||||
<xs:enumeration value="crossbow"/>
|
||||
<xs:enumeration value="bolts"/>
|
||||
<xs:enumeration value="missile"/>
|
||||
<xs:enumeration value="special"/>
|
||||
</xs:restriction>
|
||||
</xs:simpleType>
|
||||
<xs:simpleType name="weaponType">
|
||||
<xs:restriction base="xs:token">
|
||||
<xs:enumeration value="str"/>
|
||||
<xs:enumeration value="dex"/>
|
||||
<xs:enumeration value="int"/>
|
||||
<xs:enumeration value="edged"/>
|
||||
<xs:enumeration value="bashing"/>
|
||||
<xs:enumeration value="pole"/>
|
||||
<!-- The rest of these values are for potential expansion -->
|
||||
<!-- Each corresponds to a skill/stat -->
|
||||
<xs:enumeration value="thrown"/>
|
||||
<xs:enumeration value="archery"/>
|
||||
<xs:enumeration value="defense"/>
|
||||
@@ -66,7 +69,8 @@
|
||||
<xs:element name="bonus" type="xs:integer" minOccurs="0"/>
|
||||
<xs:element name="protection" type="xs:integer" minOccurs="0"/>
|
||||
<xs:element name="charges" type="xs:integer" minOccurs="0"/>
|
||||
<xs:element name="melee-type" type="weaponType" minOccurs="0"/>
|
||||
<xs:element name="weapon-type" type="weaponType" minOccurs="0"/>
|
||||
<xs:element name="missile-type" type="xs:integer" minOccurs="0"/>
|
||||
<xs:element name="pic" type="xs:integer"/>
|
||||
<xs:element name="flag" type="xs:integer" minOccurs="0"/>
|
||||
<xs:element name="value" type="xs:integer"/>
|
||||
@@ -80,6 +84,7 @@
|
||||
<xs:sequence>
|
||||
<xs:element name="type" type="xs:integer"/>
|
||||
<xs:element name="strength" type="xs:integer"/>
|
||||
<xs:element name="data" type="xs:integer"/>
|
||||
<xs:element name="use-flag" type="xs:integer" minOccurs="0"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
@@ -96,7 +101,9 @@
|
||||
</xs:all>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="description" type="xs:string" minOccurs="0"/>
|
||||
</xs:all>
|
||||
<xs:attribute name="id" type="xs:integer" use="required"/>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
<xs:element name="items">
|
||||
|
@@ -10,6 +10,7 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <sstream>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
|
||||
#include "classes.h"
|
||||
#include "boe.consts.h" // TODO: If this is needed here, maybe it shouldn't be in the "boe" namespace
|
||||
@@ -1295,34 +1296,182 @@ void cItem::readFrom(std::istream& sin){
|
||||
}
|
||||
|
||||
std::ostream& operator << (std::ostream& out, eSkill e){
|
||||
return out << (int) e;
|
||||
switch(e) {
|
||||
case eSkill::STRENGTH: out << "str"; break;
|
||||
case eSkill::DEXTERITY: out << "dex"; break;
|
||||
case eSkill::INTELLIGENCE: out << "int"; break;
|
||||
case eSkill::EDGED_WEAPONS: out << "edged"; break;
|
||||
case eSkill::BASHING_WEAPONS: out << "bashing"; break;
|
||||
case eSkill::POLE_WEAPONS: out << "pole"; break;
|
||||
case eSkill::THROWN_MISSILES: out << "thrown"; break;
|
||||
case eSkill::ARCHERY: out << "archery"; break;
|
||||
case eSkill::DEFENSE: out << "defense"; break;
|
||||
case eSkill::MAGE_SPELLS: out << "mage"; break;
|
||||
case eSkill::PRIEST_SPELLS: out << "priest"; break;
|
||||
case eSkill::MAGE_LORE: out << "mage-lore"; break;
|
||||
case eSkill::ALCHEMY: out << "alchemy"; break;
|
||||
case eSkill::ITEM_LORE: out << "item-lore"; break;
|
||||
case eSkill::DISARM_TRAPS: out << "traps"; break;
|
||||
case eSkill::LOCKPICKING: out << "lockpick"; break;
|
||||
case eSkill::ASSASSINATION: out << "assassin"; break;
|
||||
case eSkill::POISON: out << "poison"; break;
|
||||
case eSkill::LUCK: out << "luck"; break;
|
||||
default: out << "edged"; break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream& operator << (std::ostream& out, eItemType e){
|
||||
return out << (int) e;
|
||||
switch(e) {
|
||||
case eItemType::NO_ITEM: out << "none"; break;
|
||||
case eItemType::ONE_HANDED: out << "weapon-1hand"; break;
|
||||
case eItemType::TWO_HANDED: out << "weapon-2hand"; break;
|
||||
case eItemType::BOW: out << "bow"; break;
|
||||
case eItemType::ARROW: out << "arrow"; break;
|
||||
case eItemType::CROSSBOW: out << "crossbow"; break;
|
||||
case eItemType::BOLTS: out << "bolts"; break;
|
||||
case eItemType::THROWN_MISSILE: out << "thrown-missile"; break;
|
||||
case eItemType::MISSILE_NO_AMMO: out << "missile"; break;
|
||||
case eItemType::ARMOR: out << "armor"; break;
|
||||
case eItemType::HELM: out << "helm"; break;
|
||||
case eItemType::GLOVES: out << "gloves"; break;
|
||||
case eItemType::BOOTS: out << "boots"; break;
|
||||
case eItemType::SHIELD: out << "shield"; break;
|
||||
case eItemType::SHIELD_2: out << "shield2"; break;
|
||||
case eItemType::PANTS: out << "pants"; break;
|
||||
case eItemType::TOOL: out << "tool"; break;
|
||||
case eItemType::NECKLACE: out << "necklace"; break;
|
||||
case eItemType::RING: out << "ring"; break;
|
||||
case eItemType::POTION: out << "potion"; break;
|
||||
case eItemType::SCROLL: out << "scroll"; break;
|
||||
case eItemType::WAND: out << "wand"; break;
|
||||
case eItemType::WEAPON_POISON: out << "poison"; break;
|
||||
case eItemType::FOOD: out << "food"; break;
|
||||
case eItemType::GOLD: out << "gold"; break;
|
||||
case eItemType::SPECIAL: out << "special"; break;
|
||||
case eItemType::NON_USE_OBJECT: out << "object"; break;
|
||||
case eItemType::UNUSED1: out << "none"; break;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
std::ostream& operator << (std::ostream& out, eItemAbil e){
|
||||
return out << (int) e;
|
||||
}
|
||||
|
||||
// TODO: Perhaps this should understand symbolic names as well?
|
||||
std::istream& operator >> (std::istream& in, eSkill& e){
|
||||
int i;
|
||||
in >> i;
|
||||
if(i >= 0 && i < 19)
|
||||
e = (eSkill) i;
|
||||
else e = eSkill::INVALID;
|
||||
std::string key;
|
||||
in >> key;
|
||||
e = eSkill::INVALID;
|
||||
try {
|
||||
int i = boost::lexical_cast<int>(key);
|
||||
if(i >= 0 && i < 19)
|
||||
e = (eSkill) i;
|
||||
} catch(boost::bad_lexical_cast) {
|
||||
if(key == "str")
|
||||
e = eSkill::STRENGTH;
|
||||
else if(key == "dex")
|
||||
e = eSkill::DEXTERITY;
|
||||
else if(key == "int")
|
||||
e = eSkill::INTELLIGENCE;
|
||||
else if(key == "edged")
|
||||
e = eSkill::EDGED_WEAPONS;
|
||||
else if(key == "bashing")
|
||||
e = eSkill::BASHING_WEAPONS;
|
||||
else if(key == "pole")
|
||||
e = eSkill::POLE_WEAPONS;
|
||||
else if(key == "thrown")
|
||||
e = eSkill::THROWN_MISSILES;
|
||||
else if(key == "archery")
|
||||
e = eSkill::ARCHERY;
|
||||
else if(key == "defense")
|
||||
e = eSkill::DEFENSE;
|
||||
else if(key == "mage")
|
||||
e = eSkill::MAGE_SPELLS;
|
||||
else if(key == "priest")
|
||||
e = eSkill::PRIEST_SPELLS;
|
||||
else if(key == "mage-lore")
|
||||
e = eSkill::MAGE_LORE;
|
||||
else if(key == "alchemy")
|
||||
e = eSkill::ALCHEMY;
|
||||
else if(key == "item-lore")
|
||||
e = eSkill::ITEM_LORE;
|
||||
else if(key == "traps")
|
||||
e = eSkill::DISARM_TRAPS;
|
||||
else if(key == "lockpick")
|
||||
e = eSkill::LOCKPICKING;
|
||||
else if(key == "assassin")
|
||||
e = eSkill::ASSASSINATION;
|
||||
else if(key == "poison")
|
||||
e = eSkill::POISON;
|
||||
else if(key == "luck")
|
||||
e = eSkill::LUCK;
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
// TODO: Perhaps this should understand symbolic names as well?
|
||||
std::istream& operator >> (std::istream& in, eItemType& e){
|
||||
int i;
|
||||
in >> i;
|
||||
if(i > 0 && i < 28)
|
||||
e = (eItemType) i;
|
||||
else e = eItemType::NO_ITEM;
|
||||
std::string key;
|
||||
in >> key;
|
||||
e = eItemType::NO_ITEM;
|
||||
try {
|
||||
int i = boost::lexical_cast<int>(key);
|
||||
if(i > 0 && i < 28)
|
||||
e = (eItemType) i;
|
||||
} catch(boost::bad_lexical_cast) {
|
||||
if(key == "weapon-1hand")
|
||||
e = eItemType::ONE_HANDED;
|
||||
else if(key == "weapon-2hand")
|
||||
e = eItemType::TWO_HANDED;
|
||||
else if(key == "gold")
|
||||
e = eItemType::GOLD;
|
||||
else if(key == "bow")
|
||||
e = eItemType::BOW;
|
||||
else if(key == "arrow")
|
||||
e = eItemType::ARROW;
|
||||
else if(key == "thrown-missile")
|
||||
e = eItemType::THROWN_MISSILE;
|
||||
else if(key == "potion")
|
||||
e = eItemType::POTION;
|
||||
else if(key == "scroll")
|
||||
e = eItemType::SCROLL;
|
||||
else if(key == "wand")
|
||||
e = eItemType::WAND;
|
||||
else if(key == "tool")
|
||||
e = eItemType::TOOL;
|
||||
else if(key == "food")
|
||||
e = eItemType::FOOD;
|
||||
else if(key == "shield")
|
||||
e = eItemType::SHIELD;
|
||||
else if(key == "shield2")
|
||||
e = eItemType::SHIELD_2;
|
||||
else if(key == "armor")
|
||||
e = eItemType::ARMOR;
|
||||
else if(key == "helm")
|
||||
e = eItemType::HELM;
|
||||
else if(key == "gloves")
|
||||
e = eItemType::GLOVES;
|
||||
else if(key == "boots")
|
||||
e = eItemType::BOOTS;
|
||||
else if(key == "ring")
|
||||
e = eItemType::RING;
|
||||
else if(key == "necklace")
|
||||
e = eItemType::NECKLACE;
|
||||
else if(key == "poison")
|
||||
e = eItemType::WEAPON_POISON;
|
||||
else if(key == "object")
|
||||
e = eItemType::NON_USE_OBJECT;
|
||||
else if(key == "pants")
|
||||
e = eItemType::PANTS;
|
||||
else if(key == "crossbow")
|
||||
e = eItemType::CROSSBOW;
|
||||
else if(key == "bolts")
|
||||
e = eItemType::BOLTS;
|
||||
else if(key == "missile")
|
||||
e = eItemType::MISSILE_NO_AMMO;
|
||||
else if(key == "special")
|
||||
e = eItemType::SPECIAL;
|
||||
}
|
||||
return in;
|
||||
}
|
||||
|
||||
|
@@ -48,7 +48,6 @@ public:
|
||||
bool concealed : 1;
|
||||
bool enchanted : 1;
|
||||
bool unsellable : 1;
|
||||
public:
|
||||
std::string desc;
|
||||
unsigned char rec_treas_class() const;
|
||||
short item_weight() const;
|
||||
|
@@ -241,6 +241,56 @@ void writeTerrainToXml(ticpp::Printer&& data) {
|
||||
data.CloseElement("terrains");
|
||||
}
|
||||
|
||||
void writeItemsToXml(ticpp::Printer&& data) {
|
||||
data.OpenElement("items");
|
||||
for(size_t i = 0; i < scenario.scen_items.size(); i++) {
|
||||
data.OpenElement("item");
|
||||
data.PushAttribute("id", i);
|
||||
cItem& item = scenario.scen_items[i];
|
||||
data.PushElement("variety", item.variety);
|
||||
data.PushElement("level", item.item_level);
|
||||
data.PushElement("awkward", item.awkward);
|
||||
data.PushElement("bonus", item.bonus);
|
||||
data.PushElement("protection", item.protection);
|
||||
if(item.charges > 0)
|
||||
data.PushElement("charges", item.charges);
|
||||
if(isWeaponType(item.variety) && item.variety != eItemType::ARROW && item.variety != eItemType::BOLTS)
|
||||
data.PushElement("weapon-type", item.weap_type);
|
||||
data.PushElement("missile-type", item.missile);
|
||||
data.PushElement("pic", item.graphic_num);
|
||||
if(item.type_flag > 0)
|
||||
data.PushElement("flag", item.type_flag);
|
||||
data.PushElement("name", item.name);
|
||||
data.PushElement("full-name", item.full_name);
|
||||
data.PushElement("treasure", item.treas_class);
|
||||
data.PushElement("value", item.value);
|
||||
data.PushElement("weight", item.weight);
|
||||
if(item.special_class > 0)
|
||||
data.PushElement("class", item.special_class);
|
||||
|
||||
data.OpenElement("properties");
|
||||
if(item.ident) data.PushElement("identified", "true");
|
||||
if(item.magic) data.PushElement("magic", "true");
|
||||
if(item.cursed) data.PushElement("cursed", "true");
|
||||
if(item.concealed) data.PushElement("concealed", "true");
|
||||
if(item.enchanted) data.PushElement("enchanted", "true");
|
||||
if(item.unsellable) data.PushElement("unsellable", "true");
|
||||
data.CloseElement("properties");
|
||||
|
||||
if(item.ability != eItemAbil::NONE) {
|
||||
data.OpenElement("ability");
|
||||
data.PushElement("type", item.ability);
|
||||
data.PushElement("strength", item.abil_data[0]);
|
||||
data.PushElement("data", item.abil_data[1]);
|
||||
data.PushElement("use-flag", item.magic_use_type);
|
||||
data.CloseElement("ability");
|
||||
}
|
||||
if(!item.desc.empty()) data.PushElement("description", item.desc);
|
||||
data.CloseElement("item");
|
||||
}
|
||||
data.CloseElement("items");
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -262,6 +312,7 @@ void save_scenario(fs::path toFile) {
|
||||
|
||||
// ...items...
|
||||
std::ostream& items = scen_file.newFile("scenario/items.xml");
|
||||
writeItemsToXml(ticpp::Printer("items.xml", items));
|
||||
|
||||
// ...and monsters
|
||||
std::ostream& monsters = scen_file.newFile("scenario/monsters.xml");
|
||||
|
Reference in New Issue
Block a user