Fix a few scenario load/save issues
- More uninitialized data issues - Some values incorrectly loaded (monster radiate chance, terrain horse blockage, town lighting type) - Some values incorrectly saved (item magic-use flag)
This commit is contained in:
@@ -186,7 +186,7 @@ X coordinate of space to place
|
|||||||
Y coordinate of space to place
|
Y coordinate of space to place
|
||||||
Unused
|
Unused
|
||||||
Number of creature to place
|
Number of creature to place
|
||||||
Unused
|
1 - force placement
|
||||||
Unused
|
Unused
|
||||||
Special to Jump To
|
Special to Jump To
|
||||||
--------------------
|
--------------------
|
||||||
|
|||||||
@@ -1444,6 +1444,7 @@ void cast_town_spell(location where) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Currently, the node is called before any spell-specific behaviour (eg missiles) occurs.
|
||||||
bool cast_spell_on_space(location where, eSpell spell) {
|
bool cast_spell_on_space(location where, eSpell spell) {
|
||||||
short s1 = 0,s2 = 0,s3 = 0;
|
short s1 = 0,s2 = 0,s3 = 0;
|
||||||
|
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ cItem::cItem(){
|
|||||||
ability = eItemAbil::NONE;
|
ability = eItemAbil::NONE;
|
||||||
abil_data[0] = 0;
|
abil_data[0] = 0;
|
||||||
abil_data[1] = 0;
|
abil_data[1] = 0;
|
||||||
|
missile = 0;
|
||||||
type_flag = 0;
|
type_flag = 0;
|
||||||
is_special = 0;
|
is_special = 0;
|
||||||
value = 0;
|
value = 0;
|
||||||
@@ -1378,8 +1379,8 @@ std::ostream& operator << (std::ostream& out, eItemType e){
|
|||||||
std::ostream& operator << (std::ostream& out, eItemUse e){
|
std::ostream& operator << (std::ostream& out, eItemUse e){
|
||||||
switch(e) {
|
switch(e) {
|
||||||
case eItemUse::HELP_ONE: out << "help-one"; break;
|
case eItemUse::HELP_ONE: out << "help-one"; break;
|
||||||
case eItemUse::HELP_ALL: out << "harm-one"; break;
|
case eItemUse::HELP_ALL: out << "help-all"; break;
|
||||||
case eItemUse::HARM_ONE: out << "help-all"; break;
|
case eItemUse::HARM_ONE: out << "harm-one"; break;
|
||||||
case eItemUse::HARM_ALL: out << "harm-all"; break;
|
case eItemUse::HARM_ALL: out << "harm-all"; break;
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
|
|||||||
@@ -43,14 +43,7 @@ public:
|
|||||||
std::string full_name;
|
std::string full_name;
|
||||||
std::string name;
|
std::string name;
|
||||||
unsigned int treas_class;
|
unsigned int treas_class;
|
||||||
bool ident : 1;
|
bool ident, property, magic, contained, cursed, concealed, enchanted, unsellable;
|
||||||
bool property : 1;
|
|
||||||
bool magic : 1;
|
|
||||||
bool contained : 1;
|
|
||||||
bool cursed : 1;
|
|
||||||
bool concealed : 1;
|
|
||||||
bool enchanted : 1;
|
|
||||||
bool unsellable : 1;
|
|
||||||
std::string desc;
|
std::string desc;
|
||||||
unsigned char rec_treas_class() const;
|
unsigned char rec_treas_class() const;
|
||||||
short item_weight() const;
|
short item_weight() const;
|
||||||
|
|||||||
@@ -380,10 +380,17 @@ std::map<eMonstAbil,uAbility>::iterator cMonster::addAbil(eMonstAbilTemplate wha
|
|||||||
|
|
||||||
cMonster::cMonster(){
|
cMonster::cMonster(){
|
||||||
magic_res = poison_res = fire_res = cold_res = 100;
|
magic_res = poison_res = fire_res = cold_res = 100;
|
||||||
// TODO: Fill in
|
mindless = invuln = guard = invisible = false;
|
||||||
level = m_health = armor = skill = speed = 0;
|
level = m_health = armor = skill = speed = 0;
|
||||||
|
default_facial_pic = default_attitude = 0;
|
||||||
|
ambient_sound = 0;
|
||||||
|
corpse_item = corpse_item_chance = treasure = 0;
|
||||||
mu = cl = 0;
|
mu = cl = 0;
|
||||||
|
summon_type = 0;
|
||||||
|
picture_num = 0;
|
||||||
|
x_width = y_width = 1;
|
||||||
see_spec = -1;
|
see_spec = -1;
|
||||||
|
m_type = eRace::UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
cTownperson::cTownperson() {
|
cTownperson::cTownperson() {
|
||||||
|
|||||||
@@ -334,6 +334,10 @@ inline bool isWeaponType(eItemType type) {
|
|||||||
return (code >= 1 && code <= 6 && code != 3) || (code >= 23 && code <= 25);
|
return (code >= 1 && code <= 6 && code != 3) || (code >= 23 && code <= 25);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool isMissileType(eItemType type) {
|
||||||
|
return type == eItemType::ARROW || type == eItemType::BOLTS || type == eItemType::THROWN_MISSILE || type == eItemType::MISSILE_NO_AMMO;
|
||||||
|
}
|
||||||
|
|
||||||
/* items[i].ability */
|
/* items[i].ability */
|
||||||
enum class eItemAbil {
|
enum class eItemAbil {
|
||||||
// Weapon abilities
|
// Weapon abilities
|
||||||
|
|||||||
@@ -24,25 +24,25 @@ enum class eStepSnd {STEP, SQUISH, CRUNCH, NONE, SPLASH};
|
|||||||
class cTerrain {
|
class cTerrain {
|
||||||
public:
|
public:
|
||||||
std::string name;
|
std::string name;
|
||||||
pic_num_t picture;
|
pic_num_t picture = 0;
|
||||||
eTerObstruct blockage;
|
eTerObstruct blockage = eTerObstruct::CLEAR;
|
||||||
int flag1, flag2, flag3;
|
int flag1 = 0, flag2 = 0, flag3 = 0;
|
||||||
eTerSpec special;
|
eTerSpec special = eTerSpec::NONE;
|
||||||
ter_num_t trans_to_what;
|
ter_num_t trans_to_what = 0;
|
||||||
bool fly_over;
|
bool fly_over = false;
|
||||||
bool boat_over;
|
bool boat_over = false;
|
||||||
bool block_horse;
|
bool block_horse = false;
|
||||||
unsigned int light_radius;
|
unsigned int light_radius = 0;
|
||||||
eStepSnd step_sound;
|
eStepSnd step_sound = eStepSnd::STEP;
|
||||||
unsigned char shortcut_key; // for editor use only
|
unsigned char shortcut_key = 0; // for editor use only
|
||||||
unsigned int obj_num = 0; // ditto (formerly res1)
|
unsigned int obj_num = 0; // ditto
|
||||||
unsigned int ground_type; // ditto (formerly res2)
|
unsigned int ground_type = 0; // ditto
|
||||||
eTrimType trim_type; // ditto, mostly (formerly res3)
|
eTrimType trim_type = eTrimType::NONE; // ditto, mostly
|
||||||
long trim_ter; // ditto
|
long trim_ter = 0; // ditto
|
||||||
unsigned short combat_arena;
|
unsigned short combat_arena = 0;
|
||||||
location obj_pos; // editor use only
|
location obj_pos; // editor use only
|
||||||
location obj_size; // editor use only
|
location obj_size; // editor use only
|
||||||
pic_num_t map_pic;
|
pic_num_t map_pic = -1;
|
||||||
unsigned short i; // for temporary use in porting
|
unsigned short i; // for temporary use in porting
|
||||||
|
|
||||||
void append(legacy::terrain_type_type& old);
|
void append(legacy::terrain_type_type& old);
|
||||||
|
|||||||
@@ -278,6 +278,7 @@ std::ostream& operator<< (std::ostream& out, eLighting light) {
|
|||||||
|
|
||||||
std::istream& operator>> (std::istream& in, eLighting& light) {
|
std::istream& operator>> (std::istream& in, eLighting& light) {
|
||||||
std::string key;
|
std::string key;
|
||||||
|
in >> key;
|
||||||
if(key == "lit") light = LIGHT_NORMAL;
|
if(key == "lit") light = LIGHT_NORMAL;
|
||||||
else if(key == "dark") light = LIGHT_DARK;
|
else if(key == "dark") light = LIGHT_DARK;
|
||||||
else if(key == "drains") light = LIGHT_DRAINS;
|
else if(key == "drains") light = LIGHT_DRAINS;
|
||||||
|
|||||||
@@ -403,7 +403,8 @@ static void writeItemsToXml(ticpp::Printer&& data) {
|
|||||||
data.PushElement("charges", item.charges);
|
data.PushElement("charges", item.charges);
|
||||||
if(isWeaponType(item.variety) && item.variety != eItemType::ARROW && item.variety != eItemType::BOLTS)
|
if(isWeaponType(item.variety) && item.variety != eItemType::ARROW && item.variety != eItemType::BOLTS)
|
||||||
data.PushElement("weapon-type", item.weap_type);
|
data.PushElement("weapon-type", item.weap_type);
|
||||||
data.PushElement("missile-type", item.missile);
|
if(item.missile > 0 || isMissileType(item.variety))
|
||||||
|
data.PushElement("missile-type", item.missile);
|
||||||
data.PushElement("pic", item.graphic_num);
|
data.PushElement("pic", item.graphic_num);
|
||||||
if(item.type_flag > 0)
|
if(item.type_flag > 0)
|
||||||
data.PushElement("flag", item.type_flag);
|
data.PushElement("flag", item.type_flag);
|
||||||
@@ -447,7 +448,7 @@ static void writeMonstersToXml(ticpp::Printer&& data) {
|
|||||||
data.PushAttribute("id", i);
|
data.PushAttribute("id", i);
|
||||||
cMonster& monst = scenario.scen_monsters[i];
|
cMonster& monst = scenario.scen_monsters[i];
|
||||||
data.PushElement("name", monst.m_name);
|
data.PushElement("name", monst.m_name);
|
||||||
if(monst.default_facial_pic >= 0)
|
if(monst.default_facial_pic > 0)
|
||||||
data.PushElement("default-face", monst.default_facial_pic);
|
data.PushElement("default-face", monst.default_facial_pic);
|
||||||
|
|
||||||
data.OpenElement("pic");
|
data.OpenElement("pic");
|
||||||
@@ -486,11 +487,11 @@ static void writeMonstersToXml(ticpp::Printer&& data) {
|
|||||||
if(monst.magic_res != 100)
|
if(monst.magic_res != 100)
|
||||||
data.PushElement("magic", monst.magic_res);
|
data.PushElement("magic", monst.magic_res);
|
||||||
if(monst.fire_res != 100)
|
if(monst.fire_res != 100)
|
||||||
data.PushElement("fire", monst.magic_res);
|
data.PushElement("fire", monst.fire_res);
|
||||||
if(monst.cold_res != 100)
|
if(monst.cold_res != 100)
|
||||||
data.PushElement("cold", monst.magic_res);
|
data.PushElement("cold", monst.cold_res);
|
||||||
if(monst.poison_res != 100)
|
if(monst.poison_res != 100)
|
||||||
data.PushElement("poison", monst.magic_res);
|
data.PushElement("poison", monst.poison_res);
|
||||||
if(monst.mindless) data.PushElement("fear", true);
|
if(monst.mindless) data.PushElement("fear", true);
|
||||||
if(monst.invuln) data.PushElement("all", true);
|
if(monst.invuln) data.PushElement("all", true);
|
||||||
data.CloseElement("immunity");
|
data.CloseElement("immunity");
|
||||||
|
|||||||
@@ -836,6 +836,7 @@ static void readTerrainFromXml(ticpp::Document&& data, cScenario& scenario) {
|
|||||||
int which_ter;
|
int which_ter;
|
||||||
elem->GetAttribute("id", &which_ter);
|
elem->GetAttribute("id", &which_ter);
|
||||||
cTerrain& the_ter = scenario.ter_types[which_ter];
|
cTerrain& the_ter = scenario.ter_types[which_ter];
|
||||||
|
the_ter = cTerrain();
|
||||||
Iterator<Element> ter;
|
Iterator<Element> ter;
|
||||||
for(ter = ter.begin(elem.Get()); ter != ter.end(); ter++) {
|
for(ter = ter.begin(elem.Get()); ter != ter.end(); ter++) {
|
||||||
ter->GetValue(&type);
|
ter->GetValue(&type);
|
||||||
@@ -878,7 +879,7 @@ static void readTerrainFromXml(ticpp::Document&& data, cScenario& scenario) {
|
|||||||
} else if(type == "ride") {
|
} else if(type == "ride") {
|
||||||
ter->GetText(&val);
|
ter->GetText(&val);
|
||||||
if(val != "true")
|
if(val != "true")
|
||||||
the_ter.block_horse = true;
|
the_ter.block_horse = false;
|
||||||
} else if(type == "light") {
|
} else if(type == "light") {
|
||||||
ter->GetText(&the_ter.light_radius);
|
ter->GetText(&the_ter.light_radius);
|
||||||
} else if(type == "step-sound") {
|
} else if(type == "step-sound") {
|
||||||
@@ -932,6 +933,7 @@ static void readItemsFromXml(ticpp::Document&& data, cScenario& scenario) {
|
|||||||
int which_item;
|
int which_item;
|
||||||
elem->GetAttribute("id", &which_item);
|
elem->GetAttribute("id", &which_item);
|
||||||
cItem& the_item = scenario.scen_items[which_item];
|
cItem& the_item = scenario.scen_items[which_item];
|
||||||
|
the_item = cItem();
|
||||||
Iterator<Element> item;
|
Iterator<Element> item;
|
||||||
for(item = item.begin(elem.Get()); item != item.end(); item++) {
|
for(item = item.begin(elem.Get()); item != item.end(); item++) {
|
||||||
item->GetValue(&type);
|
item->GetValue(&type);
|
||||||
@@ -1120,9 +1122,7 @@ static void readMonstAbilFromXml(ticpp::Element& data, cMonster& monst) {
|
|||||||
if(type == "type") {
|
if(type == "type") {
|
||||||
elem->GetText(&radiate.type);
|
elem->GetText(&radiate.type);
|
||||||
} else if(type == "chance") {
|
} else if(type == "chance") {
|
||||||
long double percent;
|
elem->GetText(&radiate.chance);
|
||||||
elem->GetText(&percent);
|
|
||||||
radiate.chance = percent * 10;
|
|
||||||
} else throw xBadNode(type, elem->Row(), elem->Column(), fname);
|
} else throw xBadNode(type, elem->Row(), elem->Column(), fname);
|
||||||
}
|
}
|
||||||
} else if(type == "special") {
|
} else if(type == "special") {
|
||||||
@@ -1160,6 +1160,7 @@ static void readMonstersFromXml(ticpp::Document&& data, cScenario& scenario) {
|
|||||||
if(which_monst == 0)
|
if(which_monst == 0)
|
||||||
throw xBadVal(type, "id", "0", elem->Row(), elem->Column(), fname);
|
throw xBadVal(type, "id", "0", elem->Row(), elem->Column(), fname);
|
||||||
cMonster& the_mon = scenario.scen_monsters[which_monst];
|
cMonster& the_mon = scenario.scen_monsters[which_monst];
|
||||||
|
the_mon = cMonster();
|
||||||
Iterator<Attribute> attr;
|
Iterator<Attribute> attr;
|
||||||
Iterator<Element> monst;
|
Iterator<Element> monst;
|
||||||
for(monst = monst.begin(elem.Get()); monst != monst.end(); monst++) {
|
for(monst = monst.begin(elem.Get()); monst != monst.end(); monst++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user