From 750f876ed1aab3f6343981438b2e4ab1a280b48b Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Sun, 20 Apr 2014 00:20:36 -0400 Subject: [PATCH] Get most of the output for save files implemented, some existing stuff was tweaked --- osx/classes/monster.cpp | 33 +++++++ osx/classes/monster.h | 3 +- osx/classes/party.cpp | 208 +++++++++++++++++++++++---------------- osx/classes/party.h | 2 +- osx/classes/pc.cpp | 50 +++++----- osx/classes/universe.cpp | 65 ++++++------ osx/classes/vehicle.cpp | 8 ++ 7 files changed, 230 insertions(+), 139 deletions(-) diff --git a/osx/classes/monster.cpp b/osx/classes/monster.cpp index b1508b66..5221ad1d 100644 --- a/osx/classes/monster.cpp +++ b/osx/classes/monster.cpp @@ -488,3 +488,36 @@ bool cMonster::hasAbil(eMonstAbil what, unsigned char* x1, unsigned char* x2){ } return false; } + +void cMonster::writeTo(std::ostream& file) { + // TODO: Implement this (low priority since only used for exported summons) +} + +void cCreature::writeTo(std::ostream& file) { + file << "MONSTER " << number << '\n'; + file << "ATTITUDE " << attitude << '\n'; + 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 << "TIMEFLAG " << unsigned(time_flag) << '\n'; + file << "SUMMONED " << summoned << '\n'; + // TODO: Don't remember what these do + file << "EXTRA " << unsigned(extra1) << ' ' << unsigned(extra2) << '\n'; + file << "SPEC " << spec1 << ' ' << spec2 << '\n'; + file << "SPECCODE " << int(spec_enc_code) << '\n'; + file << "TIMECODE " << int(time_code) << '\n'; + file << "TIME " << monster_time << '\n'; + file << "TALK " << personality << '\n'; + file << "DEATH " << special_on_kill << '\n'; + file << "FACE " << facial_pic << '\n'; + file << "TARGET " << target << '\n'; + file << "TARGLOC " << targ_loc.x << ' ' << targ_loc.y << '\n'; + for(int i = 0; i < 15; i++) + if(status[i] != 0) + file << "STATUS " << i << ' ' << status[i] << '\n'; + file << "CURHP " << health << '\n'; + file << "CURSP " << mp << '\n'; + file << "MORALE " << morale << '\n'; + file << "DIRECTION " << direction << '\n'; +} diff --git a/osx/classes/monster.h b/osx/classes/monster.h index b14393bf..ff22f803 100644 --- a/osx/classes/monster.h +++ b/osx/classes/monster.h @@ -147,7 +147,7 @@ public: bool hasAbil(eMonstAbil what, unsigned char* x1 = NULL, unsigned char* x2 = NULL); cMonster& operator = (legacy::monster_record_type& old); cMonster(); - void writeTo(std::ostream& file, std::string prefix); + void writeTo(std::ostream& file); }; class cCreature : public cMonster { @@ -176,6 +176,7 @@ public: cCreature& operator = (legacy::creature_start_type old); cCreature& operator = (const cCreature& other); //cCreature& operator = (const cMonster& other); + void writeTo(std::ostream& file); }; std::ostream& operator << (std::ostream& out, eStatus& e); diff --git a/osx/classes/party.cpp b/osx/classes/party.cpp index 1dcf33c8..9e20591b 100644 --- a/osx/classes/party.cpp +++ b/osx/classes/party.cpp @@ -207,106 +207,109 @@ bool cParty::start_timer(short time, short node, short type){ } void cParty::writeTo(std::ostream& file){ - file << "AGE " << age << std::endl; - file << "GOLD " << gold << std::endl; - file << "FOOD " << food << std::endl; + file << "AGE " << age << '\n'; + file << "GOLD " << gold << '\n'; + file << "FOOD " << food << '\n'; for(int i = 0; i < 310; i++) for(int j = 0; j < 50; j++) if(stuff_done[i][j] > 0) - file << "SDF " << i << ' ' << j << ' ' << stuff_done[i][j] << std::endl; + file << "SDF " << i << ' ' << j << ' ' << unsigned(stuff_done[i][j]) << '\n'; + for(ptrIter iter = pointers.begin(); iter != pointers.end(); iter++) + file << "POINTER " << iter->first << ' ' << iter->second.first << ' ' << iter->second.second << '\n'; for(int i = 0; i < 200; i++) if(item_taken[i][0] > 0 || item_taken[i][1] > 0 || item_taken[i][2] > 0 || item_taken[i][3] > 0 || - item_taken[i][4] > 0 || item_taken[i][5] > 0 || item_taken[i][6] > 0 || item_taken[i][7] > 0) - file << "ITEMTAKEN " << i << ' ' << item_taken[i][0] << ' ' << item_taken[i][1] << ' ' - << item_taken[i][2] << ' ' << item_taken[i][3] << ' ' << item_taken[i][4] << ' ' << item_taken[i][5] - << ' ' << item_taken[i][6] << ' ' << item_taken[i][7] << std::endl; - file << "LIGHT " << light_level << std::endl; - file << "OUTCORNER " << outdoor_corner.x << ' ' << outdoor_corner.y << std::endl; - file << "INWHICHCORNER " << i_w_c.x << ' ' << i_w_c.y << std::endl; - file << "SECTOR " << p_loc.x << ' ' << p_loc.y << std::endl; - file << "LOCINSECTOR " << loc_in_sec.x << ' ' << loc_in_sec.y << std::endl; - // TODO: Delegate this to the cVehicle class + item_taken[i][4] > 0 || item_taken[i][5] > 0 || item_taken[i][6] > 0 || item_taken[i][7] > 0) { + file << "ITEMTAKEN " << i; + for(int j = 0; j < 8; j++) + file << ' ' << unsigned(item_taken[i][j]); + file << '\n'; + } + file << "LIGHT " << light_level << '\n'; + file << "OUTCORNER " << outdoor_corner.x << ' ' << outdoor_corner.y << '\n'; + file << "INWHICHCORNER " << i_w_c.x << ' ' << i_w_c.y << '\n'; + file << "SECTOR " << p_loc.x << ' ' << p_loc.y << '\n'; + file << "LOCINSECTOR " << loc_in_sec.x << ' ' << loc_in_sec.y << '\n'; + file << "IN " << in_boat << ' ' << in_horse << '\n'; + for(int i = 0; i < 256; i++) + if(m_noted[i]) + file << "ROSTER " << i << '\n'; + for(int i = 0; i < 256; i++) + if(m_seen[i]) + file << "SEEN " << i << '\n'; + for(int i = 0; i < 4; i++) + if(imprisoned_monst[i] > 0) + file << "SOULCRYSTAL " << i << ' ' << imprisoned_monst[i] << '\n'; + file << "DIRECTION " << direction << '\n'; + file << "WHICHSLOT " << at_which_save_slot << '\n'; + for(int i = 0; i < 20; i++) + if(alchemy[i]) + file << "ALCHEMY " << i << '\n'; + for(int i = 0; i < 200; i++) + if(can_find_town[i]) + file << "TOWNVISIBLE " << i << '\n'; + for(int i = 0; i < 100; i++) + if(key_times[i]) + file << "EVENT " << i << ' ' << key_times[i] << '\n'; + for(int i = 0; i < 50; i++) + if(spec_items[i]) + file << "ITEM " << i << '\n'; + for(int i = 0; i < 120; i++) + if(help_received[i]) + file << "HELP " << i << '\n'; + for(int i = 0; i < 200; i++) + if(m_killed[i] > 0) + file << "TOWNSLAUGHTER " << i << ' ' << m_killed[i] << '\n'; + file << "KILLS " << total_m_killed << '\n'; + file << "DAMAGE " << total_dam_done << '\n'; + file << "WOUNDS " << total_dam_taken << '\n'; + file << "EXPERIENCE " << total_xp_gained << '\n'; + file << "SCENARIO " << scen_name << '\n'; + file << "WON " << scen_won << '\n'; + file << "PLAYED " << scen_played << '\n'; + for(unsigned int i = 0; i < 250; i++) + if(graphicUsed[i]) + file << "GRAPHIC " << i << '\n'; + file << '\f'; for(int i = 0; i < 30; i++){ - if(!boats[i].exists) continue; - file << "BOAT " << i << ' '; - file << boats[i].loc.x << ' ' << boats[i].loc.y << ' '; - file << boats[i].loc_in_sec.x << ' ' << boats[i].loc_in_sec.y << ' '; - file << boats[i].sector.x << ' ' << boats[i].sector.y << ' '; - file << boats[i].which_town << ' ' << (short)boats[i].property << std::endl; + if(boats[i].exists) { + file << "BOAT " << i << '\n'; + boats[i].writeTo(file); + } } + file << '\f'; for(int i = 0; i < 30; i++){ - if(!horses[i].exists) continue; - file << "HORSE " << i << ' '; - file << horses[i].loc.x << ' ' << horses[i].loc.y << ' '; - file << horses[i].loc_in_sec.x << ' ' << horses[i].loc_in_sec.y << ' '; - file << horses[i].sector.x << ' ' << horses[i].sector.y << ' '; - file << horses[i].which_town << ' ' << (short)horses[i].property << std::endl; + if(horses[i].exists) { + file << "HORSE " << i << '\n'; + horses[i].writeTo(file); + } } - file << "IN " << in_boat << ' ' << in_horse << std::endl; + file << '\f'; for(int i = 0; i < 5; i++) for(int j = 0; j < 50; j++) if(magic_store_items[i][j].variety > ITEM_TYPE_NO_ITEM){ - std::ostringstream sout; - sout << "MAGICSTORE " << i << ' ' << j << ' '; - magic_store_items[i][j].writeTo(file, sout.str()); + file << "MAGICSTORE " << i << ' ' << j << '\n'; + magic_store_items[i][j].writeTo(file); } - for(int i = 0; i < 256; i++) - if(m_noted[i]) - file << "ROSTER " << i << std::endl; - for(int i = 0; i < 256; i++) - if(m_seen[i]) - file << "SEEN " << i << std::endl; + file << '\f'; for(int i = 0; i < 10; i++) if(out_c[i].exists){ - file << "ENCOUNTER " << i << " DIRECTION " << out_c[i].direction << std::endl; - file << "ENCOUNTER " << i << " SECTOR " << out_c[i].which_sector.x << ' ' << out_c[i].which_sector.y << std::endl; - file << "ENCOUNTER " << i << " LOCINSECTOR " << out_c[i].m_loc.x << ' ' << out_c[i].m_loc.y << std::endl; - file << "ENCOUNTER " << i << " HOME " << out_c[i].home_sector.x << ' ' << out_c[i].home_sector.y << std::endl; - std::ostringstream sout; - sout << "ENCOUNTER " << i << ' '; - out_c[i].what_monst.writeTo(file,sout.str()); + file << "ENCOUNTER " << i << "\n"; + file << "DIRECTION " << out_c[i].direction << '\n'; + file << "SECTOR " << out_c[i].which_sector.x << ' ' << out_c[i].which_sector.y << '\n'; + file << "LOCINSECTOR " << out_c[i].m_loc.x << ' ' << out_c[i].m_loc.y << '\n'; + file << "HOME " << out_c[i].home_sector.x << ' ' << out_c[i].home_sector.y << '\n'; + out_c[i].what_monst.writeTo(file); } - for(int i = 0; i < 4; i++) - if(imprisoned_monst[i] > 0) - file << "SOULCRYSTAL " << i << ' ' << imprisoned_monst[i] << std::endl; - file << "DIRECTION " << direction << std::endl; - file << "WHICHSLOT " << at_which_save_slot << std::endl; - for(int i = 0; i < 20; i++) - if(alchemy[i]) - file << "ALCHEMY " << i << std::endl; - for(int i = 0; i < 200; i++) - if(can_find_town[i]) - file << "TOWN " << i << std::endl; - for(int i = 0; i < 100; i++) - if(key_times[i]) - file << "EVENT " << i << ' ' << key_times[i] << std::endl; - for(int i = 0; i < 50; i++) - if(spec_items[i]) - file << "ITEM " << i << std::endl; - for(int i = 0; i < 120; i++) - if(help_received[i]) - file << "HELP " << i << std::endl; - for(int i = 0; i < 200; i++) - if(m_killed[i] > 0) - file << "TOWNSLAUGHTER " << i << ' ' << m_killed[i] << std::endl; - file << "KILLS " << total_m_killed << std::endl; - file << "DAMAGE " << total_dam_done << std::endl; - file << "WOUNDS " << total_dam_taken << std::endl; - file << "EXPERIENCE " << total_xp_gained << std::endl; - file << "SCENARIO " << scen_name << std::endl; - file << "WON " << scen_won << std::endl; - file << "PLAYED " << scen_played << std::endl; + 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] << std::endl; + file << "CAMPAIGN \"" << iter->first << "\" " << i << ' ' << iter->second[i] << '\n'; } - for(unsigned int i = 0; i < 250; i++) - if(graphicUsed[i]) - file << "GRAPHIC " << i << std::endl; + file << '\f'; for(unsigned int i = 0; i < party_event_timers.size(); i++) - file << "TIMER " << i << ' ' << party_event_timers[i].time << ' ' << party_event_timers[i].global_or_town - << ' ' << party_event_timers[i].node_to_call << std::endl; + file << "TIMER " << ' ' << party_event_timers[i].time << ' ' << party_event_timers[i].global_or_town + << ' ' << party_event_timers[i].node_to_call << '\n'; file << '\f'; for(int i = 0; i < 4; i++){ for(int j = 0; j < 64; j++){ @@ -317,10 +320,49 @@ void cParty::writeTo(std::ostream& file){ } file << '\f'; } - // TODO: The three journal note variables - // TODO: creature_save - // TODO: stored_items - // TODO: summons + file << '\f'; + for(int i = 0; i < 4; i++) + for(int j = 0; j < 60; j++) { + if(creature_save[i][j].active > 0) { + file << "CREATURE " << i << ' ' << j << '\n'; + creature_save[i][j].writeTo(file); + } + } + file << '\f'; + for(int i = 0; i < 3; i++) + for(int j = 0; j < 115; j++) + if(stored_items[i][j].variety > ITEM_TYPE_NO_ITEM){ + file << "STORED " << i << ' ' << j << '\n'; + stored_items[i][j].writeTo(file); + } + if(summons.size() > 0) { + file << '\f'; + for(cMonster& monst : summons) + monst.writeTo(file); + } + if(journal.size() > 0) { + file << '\f'; + for(cJournal& entry : journal) { + file << "JOURNAL " << entry.str_num << ' ' << entry.day << ' ' << entry.in_scen << '\n'; + // TODO: Save the actual string, if the player has asked us to + } + } + if(special_notes.size() > 0) { + file << '\f'; + 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 + } + } + if(talk_save.size() > 0) { + file << '\f'; + for(cConvers& note : talk_save) { + file << "TALKNOTE " << note.str_num1 << ' ' << note.str_num2 << '\n'; + file << "WHO " << note.personality << '\n'; + file << "WHERE " << note.town_num << ' ' << note.in_scen << '\n'; + // TODO: Save the actual strings and names, if the player has asked us to + } + } } void cParty::readFrom(std::istream& file){ diff --git a/osx/classes/party.h b/osx/classes/party.h index 19478423..529f20d0 100644 --- a/osx/classes/party.h +++ b/osx/classes/party.h @@ -103,7 +103,7 @@ public: cItemRec stored_items[3][115]; // formerly stored_items_list_type //string graphicsFile; // the name of the png file holding this party's custom item, pc, and summonable monster graphics - cMonster summons; // an array of monsters which can be summoned by the parties items yet don't originate from this scenario + std::vector summons; // an array of monsters which can be summoned by the party's items yet don't originate from this scenario bool graphicUsed[250]; // whether each custom graphics slot on the party's sheet is actually used; needed to place new custom graphics on the sheet. unsigned short scen_won, scen_played; // numbers of scenarios won and played respectively by this party std::map > campaign_flags; diff --git a/osx/classes/pc.cpp b/osx/classes/pc.cpp index 93940be5..1cb8c25e 100644 --- a/osx/classes/pc.cpp +++ b/osx/classes/pc.cpp @@ -246,43 +246,43 @@ void operator -= (eMainStatus& stat, eMainStatus othr){ } void cPlayer::writeTo(std::ostream& file){ - file << "STATUS -1 " << main_status << std::endl; - file << "NAME " << name << std::endl; - file << "SKILL -2 " << max_health << std::endl; - file << "SKILL -1 " << max_sp << std::endl; + file << "STATUS main " << main_status << '\n'; + file << "NAME " << name << '\n'; + file << "SKILL hp " << max_health << '\n'; + file << "SKILL sp " << max_sp << '\n'; for(int i = 0; i < 30; i++) if(skills[i] > 0) - file << "SKILL " << i << ' ' << skills[i] << std::endl; - file << "HEALTH " << cur_health << std::endl; - file << "MANA " << cur_sp << std::endl; - file << "EXPERIENCE " << experience << std::endl; - file << "SKILLPTS " << skill_pts << std::endl; - file << "LEVEL " << level << std::endl; + file << "SKILL " << i << ' ' << skills[i] << '\n'; + file << "HEALTH " << cur_health << '\n'; + file << "MANA " << cur_sp << '\n'; + file << "EXPERIENCE " << experience << '\n'; + file << "SKILLPTS " << skill_pts << '\n'; + file << "LEVEL " << level << '\n'; for(int i = 0; i < 15; i++) if(status[i] != 0) - file << "STATUS " << i << ' ' << status[i] << std::endl; - for(int i; i < 24; i++) - if(items[i].variety > ITEM_TYPE_NO_ITEM){ - std::ostringstream sout; - sout << "ITEM " << i << ' '; - items[i].writeTo(file, sout.str()); - } + file << "STATUS " << i << ' ' << status[i] << '\n'; for(int i = 0; i < 24; i++) if(equip[i]) - file << "EQUIP " << i << std::endl; + file << "EQUIP " << i << '\n'; for(int i = 0; i < 62; i++) if(mage_spells[i]) - file << "MAGE " << i << std::endl; + file << "MAGE " << i << '\n'; for(int i = 0; i < 62; i++) if(priest_spells[i]) - file << "PRIEST " << i << std::endl; + file << "PRIEST " << i << '\n'; for(int i = 0; i < 62; i++) if(traits[i]) - file << "TRAIT " << i << std::endl; - file << "ICON " << which_graphic << std::endl; - file << "RACE " << race << std::endl; - file << "DIRECTION " << direction << std::endl; - file << "POISON " << weap_poisoned << std::endl; + file << "TRAIT " << i << '\n'; + file << "ICON " << which_graphic << '\n'; + file << "RACE " << race << '\n'; + file << "DIRECTION " << direction << '\n'; + file << "POISON " << weap_poisoned << '\n'; + file << '\f'; + for(int i; i < 24; i++) + if(items[i].variety > ITEM_TYPE_NO_ITEM){ + file << "ITEM " << i << '\n'; + items[i].writeTo(file); + } } void cPlayer::readFrom(std::istream& file){ diff --git a/osx/classes/universe.cpp b/osx/classes/universe.cpp index e297bc5c..3973fb04 100644 --- a/osx/classes/universe.cpp +++ b/osx/classes/universe.cpp @@ -706,26 +706,26 @@ ter_num_t& cCurOut::operator [] (location loc) { } void cCurOut::writeTo(std::ostream& file){ -// for(int i = 0; i < 96; i++){ -// file << expl[i][0]; -// for(int j = 1; j < 96; j++){ -// file << '\t' << expl[i][j]; -// } -// file << std::endl; -// } -// file << '\f'; -// for(int i = 9; i < 96; i++){ -// file << out[i][0]; -// for(int j = 1; j < 96; j++){ -// file << '\t' << out[i][j]; -// } -// file << std::endl; -// } -// file << '\f'; + for(int i = 0; i < 96; i++){ + file << expl[i][0]; + for(int j = 1; j < 96; j++){ + file << '\t' << int(expl[i][j]); + } + file << std::endl; + } + file << '\f'; + for(int i = 9; i < 96; i++){ + file << out[i][0]; + for(int j = 1; j < 96; j++){ + file << '\t' << out[i][j]; + } + file << std::endl; + } + file << '\f'; for(int i = 0; i < 96; i++){ file << out_e[i][0]; for(int j = 1; j < 96; j++){ - file << '\t' << out_e[i][j]; + file << '\t' << unsigned(out_e[i][j]); } file << std::endl; } @@ -741,33 +741,40 @@ void cCurOut::writeTo(std::ostream& file){ } void cCurTown::writeTo(std::ostream& file){ - file << "TOWN " << num << std::endl; - file << "DIFFICULTY " << difficulty << std::endl; - if(hostile) file << "HOSTILE" << std::endl; - file << "INBOAT " << in_boat << std::endl; - file << "AT " << p_loc.x << ' ' << p_loc.y << std::endl; + file << "TOWN " << num << '\n'; + file << "DIFFICULTY " << difficulty << '\n'; + if(hostile) file << "HOSTILE" << '\n'; + file << "INBOAT " << in_boat << '\n'; + file << "AT " << p_loc.x << ' ' << p_loc.y << '\n'; + file << '\f'; for(int i; i < 115; i++) if(items[i].variety > ITEM_TYPE_NO_ITEM){ - std::ostringstream sout; - sout << "ITEM " << i << ' '; - items[i].writeTo(file, sout.str()); + file << "ITEM " << i << '\n'; + items[i].writeTo(file); } file << '\f'; + for(int i = 0; i < 60; i++) { + if(monst[i].active > 0) { + file << "CREATURE " << i << '\n'; + monst[i].writeTo(file); + } + } + file << '\f'; for(int i = 0; i < 64; i++){ file << fields[i][0]; for(int j = 1; j < 64; j++) file << '\t' << fields[i][j]; file << std::endl; } - file << '\f' << record->max_dim() << std::endl; + file << '\f'; + file << "SIZE " << record->max_dim() << "\n"; for(int i = 0; i < record->max_dim(); i++){ file << record->terrain(i,0); for(int j = 1; j < record->max_dim(); j++) file << '\t' << record->terrain(i,j); - file << std::endl; + file << '\n'; } - file << '\f'; - // TODO: Write population + // TODO: Do we need to save special_spot? } void cCurTown::readFrom(std::istream& file){ diff --git a/osx/classes/vehicle.cpp b/osx/classes/vehicle.cpp index b5273a55..481dc9b8 100644 --- a/osx/classes/vehicle.cpp +++ b/osx/classes/vehicle.cpp @@ -53,3 +53,11 @@ cVehicle& cVehicle::operator = (legacy::boat_record_type& old){ sector.y = old.boat_sector.y; return *this; } + +void cVehicle::writeTo(std::ostream& file) { + file << "LOCATION " << loc.x << ' ' << loc.y << '\n'; + file << "LOCINSECTOR " << loc_in_sec.x << ' ' << loc_in_sec.y << '\n'; + file << "SECTOR " << sector.x << ' ' << sector.y << '\n'; + file << "IN " << which_town << '\n'; + if(property) file << "OWNED\n"; +}