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:
2014-04-21 21:35:26 -04:00
parent e8022df514
commit 434d4c522f
10 changed files with 85 additions and 57 deletions

View File

@@ -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);////

View File

@@ -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();

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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;
}

View File

@@ -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;