Symbolic I/O for more enums

- Nearly every enum that gets written to a file now uses a symbolic form rather than a numeric form. Input supports both forms.
- The special node type enum, however, no longer has a symbolic form output operator, as the only place it's output is in the special nodes file which uses the opcode.
- Collected some enums scattered around the files into one place in simpletypes.hpp
This commit is contained in:
2015-06-13 15:43:29 -04:00
parent a990921e90
commit 0798f98523
25 changed files with 849 additions and 926 deletions

View File

@@ -91,7 +91,13 @@
<xs:element name="ability" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="type" type="xs:integer"/>
<xs:element name="type">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[a-z-]+"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="strength" type="xs:integer"/>
<xs:element name="data" type="xs:integer"/>
<xs:element name="use-flag" type="useFlag" minOccurs="0"/>

View File

@@ -47,48 +47,205 @@
<xs:element name="general">
<xs:complexType>
<xs:all>
<xs:element name="type" type="xs:integer"/>
<xs:element name="type">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="ray"/>
<xs:enumeration value="touch"/>
<xs:enumeration value="gaze"/>
<xs:enumeration value="breath"/>
<xs:enumeration value="spit"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<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:element name="extra" minOccurs="0">
<xs:simpleType>
<xs:restriction base="xs:string">
<!-- Status effects -->
<xs:enumeration value="poison-weap"/>
<xs:enumeration value="bless-curse"/>
<xs:enumeration value="poison"/>
<xs:enumeration value="haste-slow"/>
<xs:enumeration value="magic"/>
<xs:enumeration value="web"/>
<xs:enumeration value="disease"/>
<xs:enumeration value="invis"/>
<xs:enumeration value="dumb-smart"/>
<xs:enumeration value="martyr"/>
<xs:enumeration value="sleep"/>
<xs:enumeration value="paralysis"/>
<xs:enumeration value="acid"/>
<xs:enumeration value="cage"/>
<xs:enumeration value="charm"/>
<!-- Fields -->
<xs:enumeration value="wall-force"/>
<xs:enumeration value="wall-fire"/>
<xs:enumeration value="field-antimagic"/>
<xs:enumeration value="cloud-stink"/>
<xs:enumeration value="wall-ice"/>
<xs:enumeration value="wall-blades"/>
<xs:enumeration value="cloud-sleep"/>
<xs:enumeration value="obj-block"/>
<xs:enumeration value="field-web"/>
<xs:enumeration value="obj-crate"/>
<xs:enumeration value="obj-barrel"/>
<xs:enumeration value="barr-fire"/>
<xs:enumeration value="barr-force"/>
<xs:enumeration value="field-quickfire"/>
<xs:enumeration value="sfx-sm-bld"/>
<xs:enumeration value="sfx-med-bld"/>
<xs:enumeration value="sfx-lg-bld"/>
<xs:enumeration value="sfx-sm-slm"/>
<xs:enumeration value="sfx-lg-slm"/>
<xs:enumeration value="sfx-ash"/>
<xs:enumeration value="sfx-bone"/>
<xs:enumeration value="sfx-rock"/>
<xs:enumeration value="barr-cage"/>
<!-- Not sure if these special pseudo-fields should be allowed -->
<xs:enumeration value="dispel"/>
<xs:enumeration value="smash"/>
<!-- Damage types -->
<xs:enumeration value="weap"/>
<xs:enumeration value="fire"/>
<xs:enumeration value="poison"/>
<xs:enumeration value="magic"/>
<xs:enumeration value="unblockable"/>
<xs:enumeration value="cold"/>
<xs:enumeration value="undead"/>
<xs:enumeration value="demon"/>
<xs:enumeration value="spec"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
</xs:all>
<xs:attribute name="type" type="xs:integer" use="required"/>
<xs:attribute name="type" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="dmg"/>
<xs:enumeration value="dmg2"/>
<xs:enumeration value="status"/>
<xs:enumeration value="status2"/>
<xs:enumeration value="field"/>
<xs:enumeration value="petrify"/>
<xs:enumeration value="drain-sp"/>
<xs:enumeration value="drain-xp"/>
<xs:enumeration value="steal-food"/>
<xs:enumeration value="steal-gold"/>
<xs:enumeration value="kill"/>
<xs:enumeration value="stun"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="missile">
<xs:complexType>
<xs:all>
<xs:element name="type" type="xs:integer"/>
<xs:element name="type">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="arrow"/>
<xs:enumeration value="arrow++"/>
<xs:enumeration value="dart"/>
<xs:enumeration value="spear"/>
<xs:enumeration value="stone"/>
<xs:enumeration value="star"/>
<xs:enumeration value="spine"/>
<xs:enumeration value="knife"/>
<xs:enumeration value="bolt"/>
<xs:enumeration value="boulder"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<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:attribute name="type" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="missile"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="summon">
<xs:complexType>
<xs:all>
<xs:element name="type" type="xs:integer"/>
<xs:element name="type">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="type"/>
<xs:enumeration value="lvl"/>
<xs:enumeration value="race"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<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:attribute name="type" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="summon"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="radiate">
<xs:complexType>
<xs:all>
<xs:element name="type" type="xs:integer"/>
<xs:element name="type">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="wall-force"/>
<xs:enumeration value="wall-fire"/>
<xs:enumeration value="field-antimagic"/>
<xs:enumeration value="cloud-stink"/>
<xs:enumeration value="wall-ice"/>
<xs:enumeration value="wall-blades"/>
<xs:enumeration value="cloud-sleep"/>
<xs:enumeration value="obj-block"/>
<xs:enumeration value="field-web"/>
<xs:enumeration value="obj-crate"/>
<xs:enumeration value="obj-barrel"/>
<xs:enumeration value="barr-fire"/>
<xs:enumeration value="barr-force"/>
<xs:enumeration value="field-quickfire"/>
<xs:enumeration value="sfx-sm-bld"/>
<xs:enumeration value="sfx-med-bld"/>
<xs:enumeration value="sfx-lg-bld"/>
<xs:enumeration value="sfx-sm-slm"/>
<xs:enumeration value="sfx-lg-slm"/>
<xs:enumeration value="sfx-ash"/>
<xs:enumeration value="sfx-bone"/>
<xs:enumeration value="sfx-rock"/>
<xs:enumeration value="barr-cage"/>
<!-- Not sure if these special pseudo-fields should be allowed -->
<xs:enumeration value="dispel"/>
<xs:enumeration value="smash"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="chance" type="permille"/>
</xs:all>
<xs:attribute name="type" type="xs:integer" use="required"/>
<xs:attribute name="type" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="radiate"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="special">
@@ -96,14 +253,42 @@
<xs:sequence>
<xs:element name="param" type="xs:integer" minOccurs="0" maxOccurs="3"/>
</xs:sequence>
<xs:attribute name="type" type="xs:integer" use="required"/>
<xs:attribute name="type" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="splits"/>
<xs:enumeration value="martyr"/>
<xs:enumeration value="absorb"/>
<xs:enumeration value="old-web"/>
<xs:enumeration value="old-heat"/>
<xs:enumeration value="spec-act"/>
<xs:enumeration value="spec-hit"/>
<xs:enumeration value="spec-death"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:complexType>
</xs:element>
<xs:element name="attack">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="dice">
<xs:attribute name="type" type="xs:integer" use="required"/>
<xs:attribute name="type" use="required">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="swing"/>
<xs:enumeration value="claw"/>
<xs:enumeration value="bite"/>
<xs:enumeration value="slime"/>
<xs:enumeration value="punch"/>
<xs:enumeration value="sting"/>
<xs:enumeration value="club"/>
<xs:enumeration value="burn"/>
<xs:enumeration value="harm"/>
<xs:enumeration value="stab"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
</xs:extension>
</xs:simpleContent>
</xs:complexType>

View File

@@ -144,7 +144,13 @@
<xs:element name="special">
<xs:complexType>
<xs:sequence>
<xs:element name="type" type="xs:integer"/>
<xs:element name="type">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[a-z-]+"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
<xs:element name="flag" minOccurs="0" maxOccurs="3" type="xs:string"/>
</xs:sequence>
</xs:complexType>

View File

@@ -71,6 +71,7 @@
<ItemGroup>
<ClCompile Include="..\..\classes\creatlist.cpp" />
<ClCompile Include="..\..\classes\creature.cpp" />
<ClCompile Include="..\..\classes\estreams.cpp" />
<ClCompile Include="..\..\classes\item.cpp" />
<ClCompile Include="..\..\classes\living.cpp" />
<ClCompile Include="..\..\classes\location.cpp" />

View File

@@ -214,6 +214,9 @@
<ClCompile Include="..\..\classes\creatlist.cpp">
<Filter>Classes\Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\classes\estreams.cpp">
<Filter>Classes\Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\classes\item.cpp">
<Filter>Classes\Source Files</Filter>
</ClCompile>

View File

@@ -252,6 +252,9 @@
91C749BA1A2D670D008E0E10 /* dialogs in Copy Dialog Definitions */ = {isa = PBXBuildFile; fileRef = 91C749B91A2D66F7008E0E10 /* dialogs */; };
91D634560F8FD77800674AB3 /* BoE.icns in Resources */ = {isa = PBXBuildFile; fileRef = 2B8F435C0C0973680012E4A8 /* BoE.icns */; };
91DBE9A81A873D3900ED006C /* specials_parse.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 915325181A2E37EE000A9A1C /* specials_parse.cpp */; };
91E1862D1B2B2C22006A99EA /* estreams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91E1862B1B2B2AC0006A99EA /* estreams.cpp */; };
91E1862E1B2B2C26006A99EA /* estreams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91E1862B1B2B2AC0006A99EA /* estreams.cpp */; };
91E1862F1B2B2C29006A99EA /* estreams.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91E1862B1B2B2AC0006A99EA /* estreams.cpp */; };
91E30F2B1A74819C0057C54A /* fileio_party.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91E30F2A1A74819B0057C54A /* fileio_party.cpp */; };
91E30F2C1A74819D0057C54A /* fileio_party.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91E30F2A1A74819B0057C54A /* fileio_party.cpp */; };
91E30F2E1A7481C40057C54A /* fileio.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91E30F2D1A7481C20057C54A /* fileio.cpp */; };
@@ -707,6 +710,7 @@
91D635AD0F90E7B500674AB3 /* valleydy.meg */ = {isa = PBXFileReference; lastKnownFileType = file; path = valleydy.meg; sourceTree = "<group>"; };
91D635AE0F90E7B500674AB3 /* zakhazi.exs */ = {isa = PBXFileReference; lastKnownFileType = file; path = zakhazi.exs; sourceTree = "<group>"; };
91D635AF0F90E7B500674AB3 /* zakhazi.meg */ = {isa = PBXFileReference; lastKnownFileType = file; path = zakhazi.meg; sourceTree = "<group>"; };
91E1862B1B2B2AC0006A99EA /* estreams.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = estreams.cpp; sourceTree = "<group>"; };
91E30F2A1A74819B0057C54A /* fileio_party.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fileio_party.cpp; sourceTree = "<group>"; };
91E30F2D1A7481C20057C54A /* fileio.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = fileio.cpp; sourceTree = "<group>"; };
91E5C5A10F9EACE200C21460 /* oldstructs.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = oldstructs.hpp; path = ../oldstructs.hpp; sourceTree = "<group>"; };
@@ -923,6 +927,7 @@
91E5C7980F9F60EC00C21460 /* town.cpp */,
91AC61C50FA2729900EEAE67 /* universe.cpp */,
91279C750F9D15E5007B0D52 /* vehicle.cpp */,
91E1862B1B2B2AC0006A99EA /* estreams.cpp */,
);
name = src;
sourceTree = "<group>";
@@ -1537,6 +1542,7 @@
91E30F2B1A74819C0057C54A /* fileio_party.cpp in Sources */,
91E30F2E1A7481C40057C54A /* fileio.cpp in Sources */,
91034D1F1B21DAC6008F01C1 /* undo.cpp in Sources */,
91E1862D1B2B2C22006A99EA /* estreams.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1600,6 +1606,7 @@
9117A4111A7EC06700CD6EB4 /* living.cpp in Sources */,
91DBE9A81A873D3900ED006C /* specials_parse.cpp in Sources */,
91034D1D1B21DAC5008F01C1 /* undo.cpp in Sources */,
91E1862E1B2B2C26006A99EA /* estreams.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1660,6 +1667,7 @@
919086E01A65CA300071F7A0 /* tinyprint.cpp in Sources */,
91E30F301A7481C50057C54A /* fileio.cpp in Sources */,
91034D211B225E4A008F01C1 /* scen.appleevents.mm in Sources */,
91E1862F1B2B2C29006A99EA /* estreams.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

553
src/classes/estreams.cpp Normal file
View File

@@ -0,0 +1,553 @@
//
// estreams.cpp
// BoE
//
// Created by Celtic Minstrel on 15-06-12.
//
//
#include <string>
#include <iostream>
#include <memory>
#include <queue>
#include <boost/optional.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/ptr_container/ptr_set.hpp>
#include "simpletypes.hpp"
// A simple lookup map based on the concept of a trie
class cEnumLookup {
struct node {
char c;
mutable boost::ptr_set<node> next;
mutable boost::optional<unsigned long> value;
node(char c) : c(c) {}
node(char c, unsigned long v) : c(c), value(v) {}
bool find(unsigned long val, std::string& result) const {
if(value && *value == val) {
if(c >= ' ') result.push_back(c);
return true;
}
for(const node& n : next) {
if(n.find(val, result)) {
if(c >= ' ') result.push_back(c);
return true;
}
}
return false;
}
friend bool operator<(const node& a, const node& b) {
return a.c < b.c;
}
};
node root;
mutable size_t sz;
mutable bool size_cached = false;
public:
cEnumLookup(const std::initializer_list<const char*> strings) : root(0) {
size_t i = 0;
for(std::string str : strings)
if(!str.empty())
insert(str, i++);
}
void insert(const std::string& str, unsigned long val) {
size_t i = 0;
const node* cur = &root;
while(i < str.size()) {
auto check = cur->next.find(str[i]);
if(check == cur->next.end())
check = cur->next.insert(new node(str[i])).first;
cur = &*check;
i++;
}
if(cur->value)
throw std::string("Duplicate value in enum lookup: " + str);
cur->value = val;
size_cached = false;
}
unsigned long get(const std::string& str, unsigned long def = 0) const {
size_t i = 0;
const node* cur = &root;
while(i < str.size()) {
auto check = cur->next.find(str[i]);
if(check == cur->next.end())
return def;
cur = &*check;
i++;
}
if(cur->value)
return *cur->value;
return def;
}
std::string find(unsigned long val, std::string def = "") const {
std::string result;
if(root.find(val,result)) {
std::reverse(result.begin(), result.end());
return result;
}
return def;
}
bool contains(unsigned long val) const {
if(find(val).empty()) return false;
return true;
}
size_t size() const {
if(size_cached) return sz;
sz = 0;
std::queue<const node*> to_check;
to_check.push(&root);
while(!to_check.empty()) {
const node* cur = to_check.front();
to_check.pop();
if(cur->value) sz++;
for(const node& n : cur->next)
to_check.push(&n);
}
size_cached = true;
return sz;
}
};
template<typename E> void writeEnum(std::ostream& out, E val, cEnumLookup& tbl, std::string def = "") {
out << tbl.find(int(val), def);
}
template<typename E> void readEnum(std::istream& in, E& to, cEnumLookup& tbl, E def = E()) {
std::string key;
in >> key;
bool have_num = true;
for(char c : key) {
if(!isdigit(c)) {
have_num = false;
break;
}
}
if(have_num) {
int n = boost::lexical_cast<int>(key);
to = tbl.contains(n) ? E(n) : def;
} else to = E(tbl.get(key, int(def)));
}
// These operators have their prototypes declared all over the place, but I'm not including those headers, so silence the warnings
#ifdef __clang__
#pragma clang diagnostic ignored "-Wmissing-prototypes"
#endif
// MARK: eSkill
cEnumLookup skill_names = {
"str", "dex", "int", "edged", "bashing", "pole", "thrown", "archery", "defense",
"mage", "priest", "mage-lore", "alchemy", "item-lore", "traps", "lockpick", "assassin", "poison", "luck",
};
std::ostream& operator << (std::ostream& out, eSkill e) {
writeEnum(out, e, skill_names, "edged");
return out;
}
std::istream& operator >> (std::istream& in, eSkill& e){
readEnum(in, e, skill_names, eSkill::EDGED_WEAPONS);
return in;
}
// MARK: eItemType
cEnumLookup item_types = {
"none", "weapon-1hand", "weapon-2hand", "gold", "bow", "arrow", "thrown-missile", "potion", "scroll", "wand",
"tool", "food", "shield", "armor", "helm", "gloves", "shield2", "boots", "ring", "necklace",
"poison", "object", "pants", "crossbow", "bolts", "missile", "special", "quest",
};
std::ostream& operator << (std::ostream& out, eItemType e) {
writeEnum(out, e, item_types, "none");
return out;
}
std::istream& operator >> (std::istream& in, eItemType& e) {
readEnum(in, e, item_types, eItemType::NO_ITEM);
return in;
}
// MARK: eItemUse
cEnumLookup item_uses = {"help-one", "harm-one", "help-all", "harm-all"};
std::ostream& operator << (std::ostream& out, eItemUse e) {
writeEnum(out, e, item_uses, "help-one");
return out;
}
std::istream& operator >> (std::istream& in, eItemUse& e){
readEnum(in, e, item_uses, eItemUse::HELP_ONE);
return in;
}
// MARK: eItemAbil
cEnumLookup item_abils = {
"none", "weap-dmg", "weap-slay", "weap-heal", "weap-explode", "weap-return", "weap-dist", "weap-seek", "weap-antimagic", "weap-status",
"weap-soulsuck", "", "weap-weak", "weap-fear", "spec-weap", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "",
"prot-dmg", "prot-full", "prot-melee", "evade", "martyr", "encumber", "prot-status", "skill", "boost-stat", "boost-war",
"boost-magic", "accuracy", "thief", "giant", "light", "heavy", "status", "spec-hit", "save-life", "prot-petrify",
"regen", "poison-aug", "radiant", "will", "freedom", "speed", "slow", "prot-race", "lockpick", "missile-drain",
"spec-drop", "", "", "", "", "", "", "", "", "",
"use-poison", "use-status", "use-spell", "bliss-doom", "use-xp", "use-skillpt", "use-hp", "use-sp", "use-light", "use-party-stat",
"major-heal", "spec-use", "use-summon", "use-summon-mass", "use-quickfire", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "",
"holly", "comfrey", "nettle", "wormgrass", "asptongue", "ember", "graymold", "mandrake", "sapphire", "smoky",
"balm",
};
std::ostream& operator << (std::ostream& out, eItemAbil e) {
writeEnum(out, e, item_abils, "none");
return out;
}
std::istream& operator >> (std::istream& in, eItemAbil& e){
readEnum(in, e, item_abils, eItemAbil::NONE);
return in;
}
// MARK: eStatus
cEnumLookup pc_status = {
"poison-weap", "bless-curse", "poison", "haste-slow", "magic", "web", "disease", "invis", "dumb-smart",
"martyr", "sleep", "paralysis", "acid", "cage", "charm",
};
std::ostream& operator << (std::ostream& out, eStatus e){
writeEnum(out, e, pc_status, "main");
return out;
}
std::istream& operator >> (std::istream& in, eStatus& e){
readEnum(in, e, pc_status, eStatus::MAIN);
return in;
}
// MARK: eRace
cEnumLookup race_names = {
"human", "nephil", "slith", "vahnatai", "reptile", "beast", "important", "mage", "priest", "humanoid",
"demon", "undead", "giant", "slime", "stone", "bug", "dragon", "magic", "plant", "bird",
"skeletal", "goblin",
};
std::ostream& operator << (std::ostream& out, eRace e){
writeEnum(out, e, race_names, "humanoid");
return out;
}
std::istream& operator >> (std::istream& in, eRace& e){
readEnum(in, e, race_names, eRace::HUMANOID);
return in;
}
// MARK: eMonstTime
cEnumLookup monst_times = {
"always", "after-day", "until-day",
"travel-a", "travel-b", "travel-c",
"after-event", "until-event", "after-death",
};
std::ostream& operator << (std::ostream& out, eMonstTime e){
writeEnum(out, e, monst_times, "always");
return out;
}
std::istream& operator >> (std::istream& in, eMonstTime& e){
readEnum(in, e, monst_times, eMonstTime::ALWAYS);
return in;
}
// MARK: eDirection
cEnumLookup dirs = {"n", "ne", "e", "se", "s", "sw", "w", "nw", "?"};
std::ostream& operator<<(std::ostream& out, eDirection dir) {
writeEnum(out, dir, dirs, "?");
return out;
}
std::istream& operator>>(std::istream& in, eDirection& dir) {
readEnum(in, dir, dirs, DIR_HERE);
return in;
}
// MARK: eFieldType
cEnumLookup field_names = {
"explored", "wall-force", "wall-fire", "field-antimagic", "cloud-stink", "wall-ice", "wall-blades", "cloud-sleep",
"obj-block", "spec-spot", "field-web", "obj-crate", "obj-barrel", "barr-fire", "barr-force", "field-quickfire",
"sfx-sm-bld", "sfx-med-bld", "sfx-lg-bld", "sfx-sm-slm", "sfx-lg-slm", "sfx-ash", "sfx-bone", "sfx-rock",
"barr-cage", "", "", "", "", "", "", "",
"dispel", "smash",
};
std::ostream& operator << (std::ostream& out, eFieldType e) {
writeEnum(out, e, field_names, "dispel");
return out;
}
std::istream& operator >> (std::istream& in, eFieldType& e) {
readEnum(in, e, field_names, FIELD_DISPEL);
return in;
}
// MARK: eDamageType
cEnumLookup dmg_names = {
"weap", "fire", "poison", "magic", "unblockable", "cold", "undead", "demon", "spec",
};
std::ostream& operator << (std::ostream& out, eDamageType e) {
writeEnum(out, e, dmg_names);
return out;
}
std::istream& operator >> (std::istream& in, eDamageType& e) {
readEnum(in, e, dmg_names, eDamageType::MARKED);
return in;
}
// MARK: eMonstAbil
cEnumLookup monst_abils = {
"none", "missile", "dmg", "status", "field", "petrify", "drain-sp", "drain-xp", "kill", "steal-food",
"steal-gold", "stun", "dmg2", "status2", "splits", "martyr", "absorb", "old-web", "old-heat", "spec-act",
"spec-hit", "spec-death", "radiate", "summon",
};
std::ostream& operator << (std::ostream& out, eMonstAbil e) {
writeEnum(out, e, monst_abils, "none");
return out;
}
std::istream& operator >> (std::istream& in, eMonstAbil& e) {
readEnum(in, e, monst_abils, eMonstAbil::NO_ABIL);
return in;
}
// MARK: eMonstGen
cEnumLookup monst_abil_types = {"ray", "touch", "gaze", "breath", "spit"};
std::ostream& operator << (std::ostream& out, eMonstGen e) {
writeEnum(out, e, monst_abil_types, "touch");
return out;
}
std::istream& operator >> (std::istream& in, eMonstGen& e) {
readEnum(in, e, monst_abil_types, eMonstGen::TOUCH);
return in;
}
// MARK: eMonstMelee
cEnumLookup monst_melee = {"swing", "claw", "bite", "slime", "punch", "sting", "club", "burn", "harm", "stab"};
std::ostream& operator << (std::ostream& out, eMonstMelee e) {
writeEnum(out, e, monst_melee, "punch");
return out;
}
std::istream& operator >> (std::istream& in, eMonstMelee& e) {
readEnum(in, e, monst_melee, eMonstMelee::PUNCH);
return in;
}
// MARK: eMonstMissile
cEnumLookup monst_missiles = {"dart", "arrow", "spear", "stone", "star", "spine", "knife", "bolt", "boulder", "arrow++"};
std::ostream& operator << (std::ostream& out, eMonstMissile e) {
writeEnum(out, e, monst_missiles, "arrow");
return out;
}
std::istream& operator >> (std::istream& in, eMonstMissile& e) {
readEnum(in, e, monst_missiles, eMonstMissile::ARROW);
return in;
}
// MARK: eMonstSummon
cEnumLookup monst_summons = {"type", "lvl", "race"};
std::ostream& operator << (std::ostream& out, eMonstSummon e) {
writeEnum(out, e, monst_summons, "type");
return out;
}
std::istream& operator >> (std::istream& in, eMonstSummon& e) {
readEnum(in, e, monst_summons, eMonstSummon::TYPE);
return in;
}
// MARK: eEncNoteType
cEnumLookup note_types = {"SCEN", "OUT", "TOWN"};
std::istream& operator>>(std::istream& in, eEncNoteType& type) {
readEnum(in, type, note_types, NOTE_SCEN);
return in;
}
std::ostream& operator<<(std::ostream& out, eEncNoteType type) {
writeEnum(out, type, note_types, "SCEN");
return out;
}
// MARK: ePartyStatus
cEnumLookup party_status = {"STEALTH", "FLIGHT", "DETECT", "FIREWALK"};
std::istream& operator>>(std::istream& in, ePartyStatus& type) {
readEnum(in, type, party_status, ePartyStatus::STEALTH);
return in;
}
std::ostream& operator<<(std::ostream& out, ePartyStatus type) {
writeEnum(out, type, party_status, "STEALTH");
return out;
}
// MARK: eQuestStatus
cEnumLookup quest_status = {"avail", "start", "done", "fail"};
std::istream& operator>>(std::istream& in, eQuestStatus& type) {
readEnum(in, type, quest_status, eQuestStatus::AVAILABLE);
return in;
}
std::ostream& operator<<(std::ostream& out, eQuestStatus type) {
writeEnum(out, type, quest_status, "avail");
return out;
}
// MARK: eMainStatus
cEnumLookup main_status = {
"empty", "alive", "dead", "dust", "stone", "fled", "surface", "won", "", "",
"split", "split-alive", "split-dead", "split-dust", "split-stone", "split-fled", "split-surface", "split-won",
};
std::ostream& operator << (std::ostream& out, eMainStatus e){
writeEnum(out, e, main_status, "empty");
return out;
}
std::istream& operator >> (std::istream& in, eMainStatus& e){
readEnum(in, e, main_status, eMainStatus::ABSENT);
return in;
}
// MARK: eShopType
cEnumLookup shop_types = {"live", "dead", "rand"};
std::istream& operator>>(std::istream& in, eShopType& type) {
readEnum(in, type, shop_types, eShopType::NORMAL);
return in;
}
std::ostream& operator<<(std::ostream& out, eShopType type) {
writeEnum(out, type, shop_types, "live");
return out;
}
// MARK: eShopPrompt
cEnumLookup shop_prompts = {"shop", "heal", "mage", "priest", "spell", "alch", "train"};
std::istream& operator>>(std::istream& in, eShopPrompt& type) {
readEnum(in, type, shop_prompts, eShopPrompt::SHOPPING);
return in;
}
std::ostream& operator<<(std::ostream& out, eShopPrompt type) {
writeEnum(out, type, shop_prompts, "shop");
return out;
}
// MARK: eTerSpec
cEnumLookup ter_types = {
"none", "step-change", "dmg", "bridge", "bed", "danger", "", "fragile", "lock", "unlock",
"", "sign", "step-spec", "", "box", "wild-cave", "wild-wood", "falls-cave", "falls-mntn", "belt",
"monst-block", "town", "use-change", "use-spec",
};
std::ostream& operator << (std::ostream& out, eTerSpec e){
writeEnum(out, e, ter_types, "none");
return out;
}
std::istream& operator >> (std::istream& in, eTerSpec& e){
readEnum(in, e, ter_types, eTerSpec::NONE);
return in;
}
// MARK: eTrimType
cEnumLookup ter_trims = {
"none", "wall", "s", "se", "e", "ne", "n", "nw", "w", "sw",
"ne-inner", "se-inner", "sw-inner", "nw-inner", "frills", "road", "walkway", "waterfall", "city",
};
std::ostream& operator << (std::ostream& out, eTrimType e){
writeEnum(out, e, ter_trims, "none");
return out;
}
std::istream& operator >> (std::istream& in, eTrimType& e){
readEnum(in, e, ter_trims, eTrimType::NONE);
return in;
}
// MARK: eTerObstruct
cEnumLookup ter_blocks = {"none", "sight", "monsters", "move", "move-and-shoot", "move-and-sight"};
std::ostream& operator<< (std::ostream& out, eTerObstruct block) {
writeEnum(out, block, ter_blocks, "none");
return out;
}
std::istream& operator >> (std::istream& in, eTerObstruct& e){
readEnum(in, e, ter_blocks, eTerObstruct::CLEAR);
return in;
}
// MARK: eStepSnd
cEnumLookup step_snds = {"step", "squish", "crunch", "none", "splash"};
std::ostream& operator<< (std::ostream& out, eStepSnd snd) {
writeEnum(out, snd, step_snds, "step");
return out;
}
std::istream& operator >> (std::istream& in, eStepSnd& e){
readEnum(in, e, step_snds, eStepSnd::STEP);
return in;
}
// MARK: eLighting
cEnumLookup light_types = {"lit", "dark", "drains", "none"};
std::ostream& operator<< (std::ostream& out, eLighting light) {
writeEnum(out, light, light_types, "lit");
return out;
}
std::istream& operator>> (std::istream& in, eLighting& light) {
readEnum(in, light, light_types, LIGHT_NORMAL);
return in;
}

View File

@@ -1315,227 +1315,3 @@ void cItem::readFrom(std::istream& sin){
else if(cur == "UNSELLABLE") unsellable = true;
}
}
std::ostream& operator << (std::ostream& out, eSkill 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){
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::QUEST: out << "quest"; break;
case eItemType::NON_USE_OBJECT: out << "object"; break;
}
return out;
}
std::ostream& operator << (std::ostream& out, eItemUse e){
switch(e) {
case eItemUse::HELP_ONE: out << "help-one"; break;
case eItemUse::HELP_ALL: out << "help-all"; break;
case eItemUse::HARM_ONE: out << "harm-one"; break;
case eItemUse::HARM_ALL: out << "harm-all"; break;
}
return out;
}
std::ostream& operator << (std::ostream& out, eItemAbil e){
return out << (int) e;
}
std::istream& operator >> (std::istream& in, eSkill& e){
std::string key;
in >> key;
e = eSkill::INVALID;
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;
else try {
int i = boost::lexical_cast<int>(key);
if(i >= 0 && i < 19)
e = (eSkill) i;
} catch(boost::bad_lexical_cast) {}
return in;
}
std::istream& operator >> (std::istream& in, eItemType& e){
std::string key;
in >> key;
e = eItemType::NO_ITEM;
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;
else if(key == "quest")
e = eItemType::QUEST;
else if(key == "none")
e = eItemType::NO_ITEM;
else try {
int i = boost::lexical_cast<int>(key);
if(i > 0 && i < 28)
e = (eItemType) i;
} catch(boost::bad_lexical_cast) {}
return in;
}
std::istream& operator >> (std::istream& in, eItemUse& e){
std::string key;
in >> key;
e = eItemUse::HELP_ONE;
if(key == "help-one")
e = eItemUse::HELP_ONE;
else if(key == "harm-one")
e = eItemUse::HARM_ONE;
else if(key == "help-all")
e = eItemUse::HELP_ALL;
else if(key == "harm-all")
e = eItemUse::HARM_ALL;
else try {
int i = boost::lexical_cast<int>(key);
if(i > 0 && i < 4)
e = (eItemUse) i;
} catch(boost::bad_lexical_cast) {}
return in;
}
// TODO: Perhaps this should understand symbolic names as well?
std::istream& operator >> (std::istream& in, eItemAbil& e){
int i;
in >> i;
if((i > 0 && i < 15) || (i > 29 && i < 63) ||
(i > 69 && i < 95) || (i > 109 && i < 136) ||
(i > 149 && i < 162) || (i > 169 && i < 177))
e = (eItemAbil) i;
else e = eItemAbil::NONE;
return in;
}

View File

@@ -17,9 +17,6 @@
namespace legacy { struct item_record_type; };
enum class eItemUse {HELP_ONE, HARM_ONE, HELP_ALL, HARM_ALL};
enum class eEnchant {PLUS_ONE, PLUS_TWO, PLUS_THREE, SHOOT_FLAME, FLAMING, PLUS_FIVE, BLESSED};
class cItem {
public:
eItemType variety;

View File

@@ -451,278 +451,6 @@ std::ostream& operator<<(std::ostream& out, const cMonster::cAttack& att) {
return out;
}
std::ostream& operator << (std::ostream& out, eStatus e){
return out << (int) e;
}
// TODO: This should probably understand symbolic names as well as the numbers?
std::istream& operator >> (std::istream& in, eStatus& e){
int i;
in >> i;
if(i >= 0 && i < 14)
e = (eStatus) i;
else e = eStatus::MAIN;
return in;
}
std::ostream& operator << (std::ostream& out, eRace 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::SKELETAL: out << "skeletal"; break;
case eRace::GOBLIN: out << "goblin"; break;
case eRace::UNKNOWN: out << "humanoid"; break;
}
return out;
}
std::istream& operator >> (std::istream& in, eRace& e){
std::string key;
in >> key;
e = eRace::HUMANOID;
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;
else if(key == "skeletal")
e = eRace::SKELETAL;
else if(key == "goblin")
e = eRace::GOBLIN;
else try {
int i = boost::lexical_cast<int>(key);
if(i >= 0 && i < 20)
e = (eRace) i;
} catch(boost::bad_lexical_cast) {}
return in;
}
std::ostream& operator << (std::ostream& out, eMonstTime e){
switch(e) {
case eMonstTime::ALWAYS: out << "always"; break;
case eMonstTime::APPEAR_ON_DAY: out << "after-day"; break;
case eMonstTime::DISAPPEAR_ON_DAY: out << "until-day"; break;
case eMonstTime::SOMETIMES_A: out << "travel-a"; break;
case eMonstTime::SOMETIMES_B: out << "travel-b"; break;
case eMonstTime::SOMETIMES_C: out << "travel-c"; break;
case eMonstTime::APPEAR_WHEN_EVENT: out << "after-event"; break;
case eMonstTime::DISAPPEAR_WHEN_EVENT: out << "until-event"; break;
case eMonstTime::APPEAR_AFTER_CHOP: out << "after-death"; break;
}
return out;
}
std::istream& operator >> (std::istream& in, eMonstTime& e){
std::string key;
in >> key;
e = eMonstTime::ALWAYS;
if(key == "always")
e = eMonstTime::ALWAYS;
else if(key == "after-day")
e = eMonstTime::APPEAR_ON_DAY;
else if(key == "until-day")
e = eMonstTime::DISAPPEAR_ON_DAY;
else if(key == "travel-a")
e = eMonstTime::SOMETIMES_A;
else if(key == "travel-b")
e = eMonstTime::SOMETIMES_B;
else if(key == "travel-c")
e = eMonstTime::SOMETIMES_C;
else if(key == "after-event")
e = eMonstTime::APPEAR_WHEN_EVENT;
else if(key == "until-event")
e = eMonstTime::DISAPPEAR_WHEN_EVENT;
else if(key == "after-death")
e = eMonstTime::APPEAR_AFTER_CHOP;
else try {
int i = boost::lexical_cast<int>(key);
if(i >= 0 && i != 3 && i < 6)
e = eMonstTime(i);
else if(i > 6 && i <= 8)
e = eMonstTime(i - 1);
} catch(boost::bad_lexical_cast) {}
return in;
}
std::ostream& operator<<(std::ostream& out, eDirection dir) {
switch(dir) {
case DIR_N: out << "n"; break;
case DIR_NE: out << "ne"; break;
case DIR_E: out << "e"; break;
case DIR_SE: out << "se"; break;
case DIR_S: out << "s"; break;
case DIR_SW: out << "sw"; break;
case DIR_W: out << "w"; break;
case DIR_NW: out << "nw"; break;
case DIR_HERE: out << "?"; break;
}
return out;
}
std::istream& operator>>(std::istream& in, eDirection& dir) {
std::string str;
in >> str;
if(str == "n") dir = DIR_N;
else if(str == "ne") dir = DIR_NE;
else if(str == "e") dir = DIR_E;
else if(str == "se") dir = DIR_SE;
else if(str == "s") dir = DIR_S;
else if(str == "sw") dir = DIR_SW;
else if(str == "w") dir = DIR_W;
else if(str == "nw") dir = DIR_NW;
else if(str == "?") dir = DIR_HERE;
else if(str.length() == 1 && str[0] >= 0 && str[0] < 8)
dir = eDirection(str[0]);
else in.setstate(std::ios::failbit);
return in;
}
// TODO: Turn all of these into symbolic enumerators!
std::ostream& operator << (std::ostream& out, eFieldType e) {
return out << (int)e;
}
std::istream& operator >> (std::istream& in, eFieldType& e) {
int i;
in >> i;
if(i >= 0 && i <= 24)
e = (eFieldType)i;
else if(i == 33) e = eFieldType::FIELD_SMASH;
else e = eFieldType::FIELD_DISPEL;
return in;
}
std::ostream& operator << (std::ostream& out, eDamageType e) {
return out << (int)e;
}
std::istream& operator >> (std::istream& in, eDamageType& e) {
int i;
in >> i;
if(i >= 0 && i < 8)
e = (eDamageType)i;
else e = eDamageType::MARKED;
return in;
}
std::ostream& operator << (std::ostream& out, eMonstAbil e) {
return out << (int)e;
}
std::istream& operator >> (std::istream& in, eMonstAbil& e) {
int i;
in >> i;
if(i > 0 && i <= int(eMonstAbil::SUMMON))
e = (eMonstAbil)i;
else e = eMonstAbil::NO_ABIL;
return in;
}
std::ostream& operator << (std::ostream& out, eMonstGen e) {
return out << (int)e;
}
std::istream& operator >> (std::istream& in, eMonstGen& e) {
int i;
in >> i;
if(i >= 0 && i <= int(eMonstGen::SPIT))
e = (eMonstGen)i;
else e = eMonstGen::TOUCH;
return in;
}
std::ostream& operator << (std::ostream& out, eMonstMelee e) {
return out << (int)e;
}
std::istream& operator >> (std::istream& in, eMonstMelee& e) {
int i;
in >> i;
if(i >= 0 && i <= int(eMonstMelee::STAB))
e = (eMonstMelee)i;
else e = eMonstMelee::PUNCH;
return in;
}
std::ostream& operator << (std::ostream& out, eMonstMissile e) {
return out << (int)e;
}
std::istream& operator >> (std::istream& in, eMonstMissile& e) {
int i;
in >> i;
if(i >= 0 && i <= int(eMonstMissile::RAPID_ARROW))
e = (eMonstMissile)i;
else e = eMonstMissile::ARROW;
return in;
}
std::ostream& operator << (std::ostream& out, eMonstSummon e) {
return out << (int)e;
}
std::istream& operator >> (std::istream& in, eMonstSummon& e) {
int i;
in >> i;
if(i >= 0 && i <= int(eMonstSummon::SPECIES))
e = (eMonstSummon)i;
else e = eMonstSummon::TYPE;
return in;
}
std::string uAbility::to_string(eMonstAbil key) const {
std::ostringstream sout;
switch(getMonstAbilCategory(key)){

View File

@@ -49,19 +49,6 @@ enum class eMonstAbilTemplate {
CUSTOM_DAMAGE2,
};
enum class eMonstMelee {SWING, CLAW, BITE, SLIME, PUNCH, STING, CLUB, BURN, HARM, STAB};
enum class eMonstMissile {DART, ARROW, SPEAR, ROCK, RAZORDISK, SPINE, KNIFE, BOLT, BOULDER, RAPID_ARROW};
enum class eMonstGen {RAY, TOUCH, GAZE, BREATH, SPIT};
enum class eMonstSummon {TYPE, LEVEL, SPECIES};
inline eDirection& operator++ (eDirection& me, int) {
if(me == DIR_HERE) return me = DIR_N;
else return me = (eDirection)(1 + (int)me);
}
union uAbility {
bool active;
struct {
@@ -143,14 +130,6 @@ public:
void readFrom(std::istream& file);
};
enum class eMonstTime {
ALWAYS,
APPEAR_ON_DAY, DISAPPEAR_ON_DAY,
SOMETIMES_C, SOMETIMES_A, SOMETIMES_B,
APPEAR_WHEN_EVENT, DISAPPEAR_WHEN_EVENT,
APPEAR_AFTER_CHOP,
};
class cTownperson {
public:
mon_num_t number;

View File

@@ -1128,86 +1128,3 @@ bool operator==(const cParty::cEncNote& one, const cParty::cEncNote& two) {
return true;
}
std::istream& operator>>(std::istream& in, eEncNoteType& type) {
std::string name;
in >> name;
if(name == "SCEN") type = NOTE_SCEN;
else if(name == "OUT") type = NOTE_OUT;
else if(name == "TOWN") type = NOTE_TOWN;
else in.setstate(std::ios_base::failbit);
return in;
}
std::ostream& operator<<(std::ostream& out, eEncNoteType type) {
switch(type) {
case NOTE_SCEN:
out << "SCEN";
break;
case NOTE_OUT:
out << "OUT";
break;
case NOTE_TOWN:
out << "TOWN";
break;
}
return out;
}
std::istream& operator>>(std::istream& in, ePartyStatus& type) {
std::string name;
in >> name;
if(name == "STEALTH") type = ePartyStatus::STEALTH;
else if(name == "FLIGHT") type = ePartyStatus::FLIGHT;
else if(name == "DETECT") type = ePartyStatus::DETECT_LIFE;
else if(name == "FIREWALK") type = ePartyStatus::FIREWALK;
else in.setstate(std::ios_base::failbit);
return in;
}
std::ostream& operator<<(std::ostream& out, ePartyStatus type) {
switch(type) {
case ePartyStatus::STEALTH:
out << "STEALTH";
break;
case ePartyStatus::FLIGHT:
out << "FLIGHT";
break;
case ePartyStatus::FIREWALK:
out << "FIREWALK";
break;
case ePartyStatus::DETECT_LIFE:
out << "DETECT";
break;
}
return out;
}
std::istream& operator>>(std::istream& in, eQuestStatus& type) {
std::string name;
in >> name;
if(name == "avail") type = eQuestStatus::AVAILABLE;
else if(name == "start") type = eQuestStatus::STARTED;
else if(name == "done") type = eQuestStatus::COMPLETED;
else if(name == "fail") type = eQuestStatus::FAILED;
else in.setstate(std::ios_base::failbit);
return in;
}
std::ostream& operator<<(std::ostream& out, eQuestStatus type) {
switch(type) {
case eQuestStatus::AVAILABLE:
out << "avail";
break;
case eQuestStatus::STARTED:
out << "start";
break;
case eQuestStatus::COMPLETED:
out << "done";
break;
case eQuestStatus::FAILED:
out << "fail";
break;
}
return out;
}

View File

@@ -42,8 +42,6 @@ struct job_bank_t {
bool inited = false;
};
enum class eQuestStatus {AVAILABLE, STARTED, COMPLETED, FAILED};
class cUniverse;
class cParty : public iLiving {

View File

@@ -1030,18 +1030,4 @@ void cPlayer::readFrom(std::istream& file){
}
}
std::ostream& operator << (std::ostream& out, eMainStatus e){
return out << (int) e;
}
// TODO: This should probably understand symbolic names as well as the numbers?
std::istream& operator >> (std::istream& in, eMainStatus& e){
int i;
in >> i;
if(i > 0 && i < 18 && i !=8 && i != 9)
e = (eMainStatus) i;
else e = eMainStatus::ABSENT;
return in;
}
void(* cPlayer::give_help)(short,short) = nullptr;

View File

@@ -314,69 +314,3 @@ int cShopItem::getCost(int adj) {
cost /= 10;
return cost;
}
std::istream& operator>>(std::istream& in, eShopType& type) {
std::string name;
in >> name;
if(name == "live") type = eShopType::NORMAL;
else if(name == "dead") type = eShopType::ALLOW_DEAD;
else if(name == "rand") type = eShopType::RANDOM;
else in.setstate(std::ios_base::failbit);
return in;
}
std::ostream& operator<<(std::ostream& out, eShopType type) {
switch(type) {
case eShopType::NORMAL:
out << "live";
break;
case eShopType::ALLOW_DEAD:
out << "dead";
break;
case eShopType::RANDOM:
out << "rand";
break;
}
return out;
}
std::istream& operator>>(std::istream& in, eShopPrompt& type) {
std::string name;
in >> name;
if(name == "shop") type = eShopPrompt::SHOPPING;
else if(name == "heal") type = eShopPrompt::HEALING;
else if(name == "mage") type = eShopPrompt::MAGE;
else if(name == "priest") type = eShopPrompt::PRIEST;
else if(name == "spell") type = eShopPrompt::SPELLS;
else if(name == "alch") type = eShopPrompt::ALCHEMY;
else if(name == "train") type = eShopPrompt::TRAINING;
else in.setstate(std::ios_base::failbit);
return in;
}
std::ostream& operator<<(std::ostream& out, eShopPrompt type) {
switch(type) {
case eShopPrompt::SHOPPING:
out << "shop";
break;
case eShopPrompt::HEALING:
out << "heal";
break;
case eShopPrompt::MAGE:
out << "mage";
break;
case eShopPrompt::PRIEST:
out << "priest";
break;
case eShopPrompt::SPELLS:
out << "spell";
break;
case eShopPrompt::ALCHEMY:
out << "alch";
break;
case eShopPrompt::TRAINING:
out << "train";
break;
}
return out;
}

View File

@@ -20,35 +20,6 @@
#undef INFINITE
#endif
enum class eShopType {NORMAL, ALLOW_DEAD, RANDOM};
enum class eShopPrompt {SHOPPING, HEALING, MAGE, PRIEST, SPELLS, ALCHEMY, TRAINING};
enum class eShopItemType {
EMPTY,
// These ones must have these numbers in order for old scenarios to be ported correctly
ITEM = 1,
MAGE_SPELL = 2,
PRIEST_SPELL = 3,
ALCHEMY = 4,
SKILL,
TREASURE,
CLASS,
OPT_ITEM,
CALL_SPECIAL,
// All non-healing types must be above here and all healing types below, with HEAL_WOUNDS kept first
HEAL_WOUNDS,
CURE_POISON,
CURE_DISEASE,
CURE_ACID,
CURE_PARALYSIS,
REMOVE_CURSE,
DESTONE,
RAISE_DEAD,
RESURRECT,
CURE_DUMBFOUNDING,
};
struct cShopItem {
eShopItemType type = eShopItemType::EMPTY;
size_t quantity, index;

View File

@@ -16,7 +16,7 @@ typedef signed short spec_num_t;
typedef signed short item_num_t;
typedef unsigned short str_num_t;
// Directions!
// MARK: Directions!
enum eDirection {
DIR_N = 0,
DIR_NE = 1,
@@ -29,6 +29,13 @@ enum eDirection {
DIR_HERE = 8,
};
inline eDirection& operator++ (eDirection& me, int) {
if(me == DIR_HERE) return me = DIR_N;
else return me = (eDirection)(1 + (int)me);
}
enum class eQuestStatus {AVAILABLE, STARTED, COMPLETED, FAILED};
enum class eMainStatus {
ABSENT = 0, // absent, empty slot
ALIVE = 1,
@@ -190,6 +197,14 @@ enum class eMonstAbil {
SUMMON,
};
enum class eMonstMelee {SWING, CLAW, BITE, SLIME, PUNCH, STING, CLUB, BURN, HARM, STAB};
enum class eMonstMissile {DART, ARROW, SPEAR, ROCK, RAZORDISK, SPINE, KNIFE, BOLT, BOULDER, RAPID_ARROW};
enum class eMonstGen {RAY, TOUCH, GAZE, BREATH, SPIT};
enum class eMonstSummon {TYPE, LEVEL, SPECIES};
enum class eMonstAbilCat {
INVALID, MISSILE, GENERAL, SUMMON, RADIATE, SPECIAL
};
@@ -210,6 +225,14 @@ inline eMonstAbilCat getMonstAbilCategory(eMonstAbil what) {
return eMonstAbilCat::INVALID;
}
enum class eMonstTime {
ALWAYS,
APPEAR_ON_DAY, DISAPPEAR_ON_DAY,
SOMETIMES_C, SOMETIMES_A, SOMETIMES_B,
APPEAR_WHEN_EVENT, DISAPPEAR_WHEN_EVENT,
APPEAR_AFTER_CHOP,
};
/* Terrains Special Properties : scenario.ter_types[i].special */ //complete
enum class eTerSpec {
@@ -288,6 +311,8 @@ inline bool blocksMove(eTerObstruct block) {
return code > 2;
}
enum class eStepSnd {STEP, SQUISH, CRUNCH, NONE, SPLASH};
/* items[i].variety a.k.a item type (in editor) */
enum class eItemType {
NO_ITEM = 0,
@@ -338,6 +363,10 @@ inline bool isMissileType(eItemType type) {
return type == eItemType::ARROW || type == eItemType::BOLTS || type == eItemType::THROWN_MISSILE || type == eItemType::MISSILE_NO_AMMO;
}
enum class eItemUse {HELP_ONE, HARM_ONE, HELP_ALL, HARM_ALL};
enum class eEnchant {PLUS_ONE, PLUS_TWO, PLUS_THREE, SHOOT_FLAME, FLAMING, PLUS_FIVE, BLESSED};
/* items[i].ability */
enum class eItemAbil {
// Weapon abilities
@@ -763,6 +792,36 @@ enum class eTalkNode {
CALL_SCEN_SPEC = 30,
};
enum class eShopType {NORMAL, ALLOW_DEAD, RANDOM};
enum class eShopPrompt {SHOPPING, HEALING, MAGE, PRIEST, SPELLS, ALCHEMY, TRAINING};
enum class eShopItemType {
EMPTY,
// These ones must have these numbers in order for old scenarios to be ported correctly
ITEM = 1,
MAGE_SPELL = 2,
PRIEST_SPELL = 3,
ALCHEMY = 4,
SKILL,
TREASURE,
CLASS,
OPT_ITEM,
CALL_SPECIAL,
// All non-healing types must be above here and all healing types below, with HEAL_WOUNDS kept first
HEAL_WOUNDS,
CURE_POISON,
CURE_DISEASE,
CURE_ACID,
CURE_PARALYSIS,
REMOVE_CURSE,
DESTONE,
RAISE_DEAD,
RESURRECT,
CURE_DUMBFOUNDING,
};
// MARK: eEncNoteType
enum eEncNoteType {
NOTE_SCEN,
NOTE_OUT,
@@ -1045,4 +1104,12 @@ enum class eAlchemy {
POWER_STRONG = 19,
};
// MARK: eLighting
enum eLighting {
LIGHT_NORMAL = 0,
LIGHT_DARK = 1,
LIGHT_DRAINS = 2,
LIGHT_NONE = 3,
};
#endif

View File

@@ -333,20 +333,6 @@ void cSpecial::append(legacy::special_node_type& old){
}
}
std::ostream& operator << (std::ostream& out, eSpecType e) {
return out << (int) e;
}
// TODO: This should probably understand symbolic names as well?
std::istream& operator >> (std::istream& in, eSpecType& e) {
int i;
in >> i;
e = (eSpecType) i;
if(getNodeCategory(e) == eSpecCat::INVALID)
e = eSpecType::INVALID;
return in;
}
// Key:
// space - no button
// m - Create/Edit button to edit message pair (covers msg1 and msg2 together)

View File

@@ -71,8 +71,6 @@ struct node_properties_t {
node_properties_t(std::initializer_list<std::function<void(node_properties_t)>>);
};
std::ostream& operator << (std::ostream& out, eSpecType e);
std::istream& operator >> (std::istream& in, eSpecType& e);
const node_properties_t& operator* (eSpecType t);
#endif

View File

@@ -363,150 +363,3 @@ void cTerrain::append(legacy::terrain_type_type& old){
if(picture < 1000) map_pic = picture;
else map_pic = NO_PIC;
}
std::ostream& operator << (std::ostream& out, eTerSpec e){
return out << (int) e;
}
std::istream& operator >> (std::istream& in, eTerSpec& e){
int i;
in >> i;
if(i > 0 && i < 24)
e = (eTerSpec) i;
else e = eTerSpec::NONE;
return in;
}
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){
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;
}
std::ostream& operator<< (std::ostream& out, eStepSnd snd) {
switch(snd) {
case eStepSnd::CRUNCH: out << "crunch"; break;
case eStepSnd::NONE: out << "none"; break;
case eStepSnd::SPLASH: out << "splash"; break;
case eStepSnd::SQUISH: out << "squish"; break;
case eStepSnd::STEP: out << "step"; break;
}
return out;
}
std::istream& operator >> (std::istream& in, eStepSnd& e){
std::string key;
in >> key;
if(key == "crunch")
e = eStepSnd::CRUNCH;
else if(key == "none")
e = eStepSnd::NONE;
else if(key == "splash")
e = eStepSnd::SPLASH;
else if(key == "squish")
e = eStepSnd::SQUISH;
else if(key == "step")
e = eStepSnd::STEP;
return in;
}

View File

@@ -19,8 +19,6 @@
namespace legacy { struct terrain_type_type; };
enum class eStepSnd {STEP, SQUISH, CRUNCH, NONE, SPLASH};
class cTerrain {
public:
std::string name;

View File

@@ -240,24 +240,3 @@ cTown::cItem::cItem(location loc, short num, ::cItem& item) : cItem() {
if(item.variety == eItemType::GOLD || item.variety == eItemType::FOOD)
charges = get_ran(1,4,6);
}
std::ostream& operator<< (std::ostream& out, eLighting light) {
switch(light) {
case LIGHT_NORMAL: out << "lit"; break;
case LIGHT_DARK: out << "dark"; break;
case LIGHT_DRAINS: out << "drains"; break;
case LIGHT_NONE: out << "none"; break;
}
return out;
}
std::istream& operator>> (std::istream& in, eLighting& light) {
std::string key;
in >> key;
if(key == "lit") light = LIGHT_NORMAL;
else if(key == "dark") light = LIGHT_DARK;
else if(key == "drains") light = LIGHT_DRAINS;
else if(key == "none") light = LIGHT_NONE;
else in.fail();
return in;
}

View File

@@ -30,13 +30,6 @@ namespace legacy {
struct preset_field_type;
};
enum eLighting {
LIGHT_NORMAL = 0,
LIGHT_DARK = 1,
LIGHT_DRAINS = 2,
LIGHT_NONE = 3,
};
class cScenario;
class cTown { // formerly town_record_type

View File

@@ -1085,10 +1085,11 @@ static void readMonstAbilFromXml(ticpp::Element& data, cMonster& monst) {
} else if(type == "range") {
elem->GetText(&general.range);
} else if(type == "extra") {
int n;
elem->GetText(&n);
// Even though it's cast to eFieldType here, it should work correctly if later retrieved as eDamageType or eStatus.
general.fld = eFieldType(n);
if(abil_type == eMonstAbil::DAMAGE || abil_type == eMonstAbil::DAMAGE2)
elem->GetText(&general.dmg);
else if(abil_type == eMonstAbil::FIELD)
elem->GetText(&general.fld);
else elem->GetText(&general.stat);
} else if(type == "chance") {
long double percent;
elem->GetText(&percent);

View File

@@ -244,7 +244,7 @@ void test_special_parse(std::string file) {
std::ofstream fout(file + ".out");
for(auto p : specials) {
fout << "Special node ID " << p.first << ":\n";
fout << " Type: " << p.second.type << '\n';
fout << " Type: " << (*p.second.type).opcode() << '\n';
fout << " SDF: (" << p.second.sd1 << ',' << p.second.sd2 << ")\n";
fout << " Message: (" << p.second.m1 << ',' << p.second.m2 << ',' << p.second.m3 << ")\n";
fout << " Pic: " << p.second.pic << '@' << p.second.pictype << '\n';