Fix several crucial bits of data not being loaded
- Creature save data - Outdoor wandering encounters - Fix crash when entering outdoor combat after loading - Stop using char types in cItemRec - Move all pending attributes from cMonster to cCreature
This commit is contained in:
@@ -340,6 +340,7 @@ void start_outdoor_combat(cOutdoors::cCreature encounter,ter_num_t in_which_terr
|
||||
//univ.out.misc_i[i][j] = 0;
|
||||
//univ.out.sfx[i][j] = 0;
|
||||
}
|
||||
univ.town.prep_arena();
|
||||
univ.town->in_town_rect = town_rect;
|
||||
|
||||
create_out_combat_terrain((short) in_which_terrain,num_walls,0);////
|
||||
|
@@ -130,6 +130,22 @@ void finish_load_party(){
|
||||
if (!load_scenario(path))
|
||||
return;
|
||||
|
||||
// Saved creatures may not have had their monster attributes saved
|
||||
// Make sure that they know what they are!
|
||||
// Cast to cMonster base class and assign, to avoid clobbering other attributes
|
||||
for(int i = 0; i < 4; i++) {
|
||||
for(int j = 0; j < 60; j++) {
|
||||
int number = univ.party.creature_save[i][j].number;
|
||||
cMonster& monst = univ.party.creature_save[i][j];
|
||||
monst = scenario.scen_monsters[number];
|
||||
}
|
||||
}
|
||||
for(int j = 0; j < 60; j++) {
|
||||
int number = univ.town.monst[j].number;
|
||||
cMonster& monst = univ.town.monst[j];
|
||||
monst = scenario.scen_monsters[number];
|
||||
}
|
||||
|
||||
// if at this point, startup must be over, so make this call to make sure we're ready,
|
||||
// graphics wise
|
||||
end_startup();
|
||||
|
@@ -368,6 +368,8 @@ void cItemRec::readFrom(std::istream& sin){
|
||||
while(sin) {
|
||||
std::string cur;
|
||||
getline(sin, cur);
|
||||
std::istringstream sin(cur);
|
||||
sin >> cur;
|
||||
if(cur == "VARIETY") sin >> variety;
|
||||
else if(cur == "LEVEL") sin >> item_level;
|
||||
else if(cur == "AWKWARD") sin >> awkward;
|
||||
|
@@ -21,24 +21,24 @@ class cItemRec {
|
||||
public:
|
||||
eItemType variety;
|
||||
short item_level;
|
||||
char awkward;
|
||||
char bonus;
|
||||
char protection;
|
||||
char charges;
|
||||
int awkward;
|
||||
int bonus;
|
||||
int protection;
|
||||
int charges;
|
||||
eWeapType type;
|
||||
char magic_use_type;
|
||||
int magic_use_type;
|
||||
unsigned short graphic_num;
|
||||
eItemAbil ability;
|
||||
unsigned char ability_strength;
|
||||
unsigned int ability_strength;
|
||||
unsigned short type_flag;
|
||||
unsigned char is_special;
|
||||
unsigned int is_special;
|
||||
short value;
|
||||
unsigned char weight;
|
||||
unsigned char special_class;
|
||||
unsigned int weight;
|
||||
unsigned int special_class;
|
||||
location item_loc;
|
||||
std::string full_name;
|
||||
std::string name;
|
||||
unsigned char treas_class;
|
||||
unsigned int treas_class;
|
||||
//unsigned char item_properties;
|
||||
bool ident : 1;
|
||||
bool property : 1;
|
||||
@@ -49,8 +49,8 @@ public:
|
||||
bool enchanted : 1;
|
||||
bool unsellable : 1;
|
||||
private:
|
||||
unsigned char reserved1;
|
||||
unsigned char reserved2;
|
||||
unsigned int reserved1;
|
||||
unsigned int reserved2;
|
||||
public:
|
||||
//string desc; // for future use
|
||||
unsigned char rec_treas_class() const;
|
||||
|
@@ -15,22 +15,16 @@
|
||||
#include "oldstructs.h"
|
||||
|
||||
cMonster& cMonster::operator = (legacy::monster_record_type& old){
|
||||
int i;
|
||||
level = old.level;
|
||||
//m_name = old.m_name;
|
||||
health = old.health;
|
||||
m_health = old.m_health;
|
||||
mp = old.mp;
|
||||
max_mp = old.max_mp;
|
||||
armor = old.armor;
|
||||
skill = old.skill;
|
||||
for(i = 0; i < 3; i++) a[i] = old.a[i];
|
||||
// TODO: These two bits of data belong in a[]
|
||||
for(int i = 0; i < 3; i++) a[i] = old.a[i];
|
||||
a[0].type = old.a1_type;
|
||||
a[1].type = a[2].type = old.a23_type;
|
||||
m_type = (eMonsterType) old.m_type;
|
||||
speed = old.speed;
|
||||
ap = old.ap;
|
||||
mu = old.mu;
|
||||
cl = old.cl;
|
||||
breath = old.breath;
|
||||
@@ -38,12 +32,8 @@ cMonster& cMonster::operator = (legacy::monster_record_type& old){
|
||||
treasure = old.treasure;
|
||||
spec_skill = old.spec_skill;
|
||||
poison = old.poison;
|
||||
morale = old.morale;
|
||||
m_morale = old.m_morale;
|
||||
corpse_item = old.corpse_item;
|
||||
corpse_item_chance = old.corpse_item_chance;
|
||||
for(i = 0; i < 15; i++) status[i] = old.status[i];
|
||||
direction = old.direction;
|
||||
immunities = old.immunities;
|
||||
x_width = old.x_width;
|
||||
y_width = old.y_width;
|
||||
@@ -125,6 +115,14 @@ cCreature& cCreature::operator = (legacy::creature_data_type old){
|
||||
personality = old.monst_start.personality;
|
||||
special_on_kill = old.monst_start.special_on_kill;
|
||||
facial_pic = old.monst_start.facial_pic;
|
||||
health = old.m_d.health;
|
||||
mp = old.m_d.mp;
|
||||
max_mp = old.m_d.max_mp;
|
||||
ap = old.m_d.ap;
|
||||
morale = old.m_d.morale;
|
||||
m_morale = old.m_d.m_morale;
|
||||
for(int i = 0; i < 15; i++) status[i] = old.m_d.status[i];
|
||||
direction = old.m_d.direction;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -502,7 +500,7 @@ void cCreature::writeTo(std::ostream& file) {
|
||||
file << "STARTATT " << unsigned(start_attitude) << '\n';
|
||||
file << "STARTLOC " << start_loc.x << ' ' << start_loc.y << '\n';
|
||||
file << "LOCATION " << cur_loc.x << ' ' << cur_loc.y << '\n';
|
||||
file << "MOBILIY " << unsigned(mobility) << '\n';
|
||||
file << "MOBILITY " << unsigned(mobility) << '\n';
|
||||
file << "TIMEFLAG " << unsigned(time_flag) << '\n';
|
||||
file << "SUMMONED " << summoned << '\n';
|
||||
// TODO: Don't remember what these do
|
||||
@@ -522,18 +520,20 @@ void cCreature::writeTo(std::ostream& file) {
|
||||
file << "CURHP " << health << '\n';
|
||||
file << "CURSP " << mp << '\n';
|
||||
file << "MORALE " << morale << '\n';
|
||||
file << "DIRECTION " << direction << '\n';
|
||||
file << "DIRECTION " << unsigned(direction) << '\n';
|
||||
}
|
||||
|
||||
void cCreature::readFrom(std::istream& file) {
|
||||
while(file) {
|
||||
std::string cur;
|
||||
getline(file, cur);
|
||||
printf("Parsing line in town.txt: %s\n", cur.c_str());
|
||||
std::istringstream line(cur);
|
||||
line >> cur;
|
||||
if(cur == "MONSTER")
|
||||
if(cur == "MONSTER") {
|
||||
line >> number;
|
||||
else if(cur == "ATTITUDE")
|
||||
*this = cCreature(number);
|
||||
} else if(cur == "ATTITUDE")
|
||||
line >> attitude;
|
||||
else if(cur == "STARTATT") {
|
||||
unsigned int i;
|
||||
|
@@ -106,16 +106,12 @@ public:
|
||||
};
|
||||
unsigned char level;
|
||||
std::string m_name;
|
||||
short health; // TODO: Move health, mp and max_mp to cCreature
|
||||
short m_health;
|
||||
short mp;
|
||||
short max_mp;
|
||||
unsigned char armor;
|
||||
unsigned char skill;
|
||||
cAttack a[3];
|
||||
eMonsterType m_type;
|
||||
unsigned char speed;
|
||||
unsigned char ap; // TODO: Move ap to cCreature
|
||||
unsigned char mu;
|
||||
unsigned char cl;
|
||||
unsigned char breath;
|
||||
@@ -123,11 +119,8 @@ public:
|
||||
unsigned char treasure;
|
||||
unsigned char spec_skill; // TODO: Delete in favour of cAbility
|
||||
unsigned char poison;
|
||||
short morale,m_morale; // TODO: Move to cCreature (since these are calculated in-game based on the level)
|
||||
item_num_t corpse_item;
|
||||
short corpse_item_chance;
|
||||
short status[15]; // TODO: Move to cCreature
|
||||
unsigned char direction; // TODO: Move direction to cCreature
|
||||
unsigned char immunities;
|
||||
unsigned char x_width,y_width;
|
||||
unsigned char radiate_1; // TODO: Delete in favour of cAbility
|
||||
@@ -156,7 +149,7 @@ class cCreature : public cMonster {
|
||||
public:
|
||||
using cMonster::operator=;
|
||||
unsigned long id;
|
||||
m_num_t number; // TODO: This appears to be a duplicate of cMonster::m_num (ie it's used for the same thing)
|
||||
m_num_t number;
|
||||
short active, attitude;
|
||||
unsigned char start_attitude;
|
||||
location start_loc, cur_loc;
|
||||
@@ -170,6 +163,13 @@ public:
|
||||
short special_on_kill, facial_pic;
|
||||
short target;
|
||||
location targ_loc;
|
||||
short health;
|
||||
short mp;
|
||||
short max_mp;
|
||||
unsigned char ap;
|
||||
short morale,m_morale; // these are calculated in-game based on the level
|
||||
short status[15];
|
||||
unsigned char direction;
|
||||
|
||||
cCreature();
|
||||
cCreature(int num);
|
||||
|
@@ -270,11 +270,17 @@ void cParty::writeTo(std::ostream& file){
|
||||
for(unsigned int i = 0; i < 250; i++)
|
||||
if(graphicUsed[i])
|
||||
file << "GRAPHIC " << i << '\n';
|
||||
for(campIter iter = campaign_flags.begin(); iter != campaign_flags.end(); iter++){
|
||||
for(unsigned int i = 0; i < iter->second.size(); i++)
|
||||
if(iter->second[i] > 0)
|
||||
file << "CAMPAIGN \"" << iter->first << "\" " << i << ' ' << iter->second[i] << '\n';
|
||||
}
|
||||
file << '\f';
|
||||
for(int i = 0; i < 30; i++){
|
||||
if(boats[i].exists) {
|
||||
file << "BOAT " << i << '\n';
|
||||
boats[i].writeTo(file);
|
||||
file << '\f';
|
||||
}
|
||||
}
|
||||
file << '\f';
|
||||
@@ -282,6 +288,7 @@ void cParty::writeTo(std::ostream& file){
|
||||
if(horses[i].exists) {
|
||||
file << "HORSE " << i << '\n';
|
||||
horses[i].writeTo(file);
|
||||
file << '\f';
|
||||
}
|
||||
}
|
||||
file << '\f';
|
||||
@@ -290,6 +297,7 @@ void cParty::writeTo(std::ostream& file){
|
||||
if(magic_store_items[i][j].variety > ITEM_TYPE_NO_ITEM){
|
||||
file << "MAGICSTORE " << i << ' ' << j << '\n';
|
||||
magic_store_items[i][j].writeTo(file);
|
||||
file << '\f';
|
||||
}
|
||||
file << '\f';
|
||||
for(int i = 0; i < 10; i++)
|
||||
@@ -301,13 +309,9 @@ void cParty::writeTo(std::ostream& file){
|
||||
file << "HOME " << out_c[i].home_sector.x << ' ' << out_c[i].home_sector.y << '\n';
|
||||
file << "-\n";
|
||||
out_c[i].what_monst.writeTo(file);
|
||||
file << '\f';
|
||||
}
|
||||
file << '\f';
|
||||
for(campIter iter = campaign_flags.begin(); iter != campaign_flags.end(); iter++){
|
||||
for(unsigned int i = 0; i < iter->second.size(); i++)
|
||||
if(iter->second[i] > 0)
|
||||
file << "CAMPAIGN \"" << iter->first << "\" " << i << ' ' << iter->second[i] << '\n';
|
||||
}
|
||||
file << '\f';
|
||||
for(unsigned int i = 0; i < party_event_timers.size(); i++)
|
||||
file << "TIMER " << ' ' << party_event_timers[i].time << ' ' << party_event_timers[i].global_or_town
|
||||
@@ -318,6 +322,7 @@ void cParty::writeTo(std::ostream& file){
|
||||
if(creature_save[i][j].active > 0) {
|
||||
file << "CREATURE " << i << ' ' << j << '\n';
|
||||
creature_save[i][j].writeTo(file);
|
||||
file << '\f';
|
||||
}
|
||||
}
|
||||
file << '\f';
|
||||
@@ -326,18 +331,22 @@ void cParty::writeTo(std::ostream& file){
|
||||
if(stored_items[i][j].variety > ITEM_TYPE_NO_ITEM){
|
||||
file << "STORED " << i << ' ' << j << '\n';
|
||||
stored_items[i][j].writeTo(file);
|
||||
file << '\f';
|
||||
}
|
||||
if(summons.size() > 0) {
|
||||
file << '\f';
|
||||
file << "SUMMON" << '\n';
|
||||
for(cMonster& monst : summons)
|
||||
for(cMonster& monst : summons) {
|
||||
monst.writeTo(file);
|
||||
file << '\f';
|
||||
}
|
||||
}
|
||||
if(journal.size() > 0) {
|
||||
file << '\f';
|
||||
for(cJournal& entry : journal) {
|
||||
file << "JOURNAL " << entry.str_num << ' ' << entry.day << ' ' << maybe_quote_string(entry.in_scen) << '\n';
|
||||
// TODO: Save the actual string, if the player has asked us to
|
||||
file << '\f';
|
||||
}
|
||||
}
|
||||
if(special_notes.size() > 0) {
|
||||
@@ -345,6 +354,7 @@ void cParty::writeTo(std::ostream& file){
|
||||
for(cEncNote& note : special_notes) {
|
||||
file << "ENCNOTE " << note.type << ' ' << note.str_num << ' ' << note.where << '\n';
|
||||
// TODO: Save the actual strings, if the player has asked us to
|
||||
file << '\f';
|
||||
}
|
||||
}
|
||||
if(talk_save.size() > 0) {
|
||||
@@ -355,6 +365,7 @@ void cParty::writeTo(std::ostream& file){
|
||||
file << "WHERE " << note.town_num << ' ' << note.in_scen << '\n';
|
||||
file << "-\n";
|
||||
// TODO: Save the actual strings and names, if the player has asked us to
|
||||
file << '\f';
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -406,11 +417,7 @@ void cParty::readFrom(std::istream& file){
|
||||
sin >> loc_in_sec.x >> loc_in_sec.y;
|
||||
else if(cur == "IN")
|
||||
sin >> in_boat >> in_horse;
|
||||
else if(cur == "MAGICSTORE"){
|
||||
int i,j;
|
||||
sin >> i >> j >> cur;
|
||||
magic_store_items[i][j].readFrom(sin);
|
||||
}else if(cur == "ROSTER"){
|
||||
else if(cur == "ROSTER"){
|
||||
int i;
|
||||
sin >> i;
|
||||
m_noted[i] = true;
|
||||
@@ -492,7 +499,7 @@ void cParty::readFrom(std::istream& file){
|
||||
magic_store_items[i][j].readFrom(bin);
|
||||
} else if(cur == "ENCOUNTER") {
|
||||
int i;
|
||||
bin >> i >> cur;
|
||||
bin >> i;
|
||||
while(bin) {
|
||||
getline(bin, cur);
|
||||
std::istringstream sin(cur);
|
||||
@@ -508,6 +515,7 @@ void cParty::readFrom(std::istream& file){
|
||||
else if(cur == "-") break;
|
||||
}
|
||||
out_c[i].what_monst.readFrom(bin);
|
||||
out_c[i].exists = true;
|
||||
}else if(cur == "CAMPAIGN") {
|
||||
unsigned int i;
|
||||
int j;
|
||||
|
@@ -359,16 +359,11 @@ void cPlayer::readFrom(std::istream& file){
|
||||
while(file) {
|
||||
getline(file, cur, '\f');
|
||||
bin.str(cur);
|
||||
while(bin) {
|
||||
getline(bin, cur);
|
||||
sin.str(cur);
|
||||
sin >> cur;
|
||||
if(cur == "ITEM") {
|
||||
int i;
|
||||
sin >> i >> cur;
|
||||
items[i].readFrom(sin);
|
||||
}
|
||||
sin.clear();
|
||||
bin >> cur;
|
||||
if(cur == "ITEM") {
|
||||
int i;
|
||||
bin >> i;
|
||||
items[i].readFrom(bin);
|
||||
}
|
||||
bin.clear();
|
||||
}
|
||||
|
@@ -136,6 +136,11 @@ bool cCurTown::prep_talk(short which) {
|
||||
}
|
||||
}
|
||||
|
||||
void cCurTown::prep_arena() {
|
||||
if(loaded()) delete record;
|
||||
record = new cMedTown();
|
||||
}
|
||||
|
||||
cCurTown::~cCurTown() {
|
||||
if(talkNeedsDeleting && curTalk != NULL) delete curTalk;
|
||||
}
|
||||
|
@@ -67,6 +67,7 @@ public:
|
||||
short countMonsters();
|
||||
cSpeech& cur_talk(); // Get the currently loaded speech
|
||||
bool prep_talk(short which); // Prepare for loading specified speech, returning true if already loaded
|
||||
void prep_arena(); // Set up for a combat arena
|
||||
|
||||
bool is_explored(char x, char y) const;
|
||||
bool is_force_wall(char x, char y) const;
|
||||
|
Reference in New Issue
Block a user