Fix a plethora of bugs and crashes when loading new savegames; loading now works, though with a few glitches still

This commit is contained in:
2014-04-20 17:43:16 -04:00
parent 3a0f1ad7f5
commit 4cf1c5a8f6
16 changed files with 75 additions and 62 deletions

View File

@@ -1390,7 +1390,7 @@ bool handle_action(sf::Event event)
overall_mode = MODE_STARTUP;
draw_startup(0);
menu_activate();
univ.party.scen_name = ".exs"; // should be harmless...
univ.party.scen_name = ""; // should be harmless...
if(cChoiceDlog("congrats-save.xml",{"cancel","save"}).show() == "save"){
fs::path file = nav_put_party();
if(!file.empty()) save_party(file);
@@ -2101,7 +2101,10 @@ bool handle_keystroke(sf::Event& event){
void do_load()
{
fs::path file_to_load = nav_get_party();
if(!file_to_load.empty()) load_party(file_to_load);
if(!file_to_load.empty())
if(!load_party(file_to_load))
return;
finish_load_party();
if(overall_mode != MODE_STARTUP)
post_load();
menu_activate();
@@ -2214,15 +2217,15 @@ void increase_age()////
PSD[SDF_PARTY_FLIGHT] = move_to_zero(PSD[SDF_PARTY_FLIGHT]);
if ((overall_mode > MODE_OUTDOORS) && (univ.town->lighting_type == 2))
if ((overall_mode > MODE_OUTDOORS) && (univ.town->lighting_type == 2)) {
univ.party.light_level = max (0,univ.party.light_level - 9);
if (univ.town->lighting_type == 3) {
if (univ.party.light_level > 0)
ASB("Your light is drained.");
univ.party.light_level = 0;
if (univ.town->lighting_type == 3) {
if (univ.party.light_level > 0)
ASB("Your light is drained.");
univ.party.light_level = 0;
}
}
// Specials countdowns
if ((univ.party.age % 500 == 0
) && (get_ran(1,0,5) == 3) && (party_has_abil(52) == true)) {

View File

@@ -98,11 +98,14 @@ extern fs::path progDir;
//template_town_type town_template;
cCustomGraphics spec_scen_g;
extern bool pc_gworld_loaded;
extern sf::Texture pc_gworld;
std::ofstream flog("bladeslog.txt");
void finish_load_party(){
bool town_restore = (univ.town.num < 200) ? true : false;
bool in_scen = (univ.party.scen_name[0] = '.') ? false : true;
bool town_restore = univ.town.num < 200;
bool in_scen = univ.party.scen_name.length() > 0;
party_in_memory = true;
@@ -110,12 +113,23 @@ void finish_load_party(){
if (!in_scen) {
if(overall_mode != MODE_STARTUP) {
reload_startup();
overall_mode = MODE_STARTUP;
draw_startup(0);
}
if(!pc_gworld_loaded) {
pc_gworld.loadFromImage(*ResMgr::get<ImageRsrc>("pcs"));
pc_gworld_loaded = true;
}
overall_mode = MODE_STARTUP;
return;
}
fs::path path;
path = progDir/"Blades of Exile Scenarios";
path /= univ.party.scen_name;
std::cout<<"Searching for scenario at:\n"<<path<<'\n';
if (!load_scenario(path))
return;
// if at this point, startup must be over, so make this call to make sure we're ready,
// graphics wise
end_startup();
@@ -136,8 +150,8 @@ void finish_load_party(){
center = univ.party.p_loc;
}
else {
load_town_str(univ.town.num,univ.town.record);
load_town(univ.town.num,univ.town.record);
load_town_str(univ.town.num,univ.town.record);
for (int i = 0; i < univ.town->max_monst(); i++){
univ.town.monst[i].targ_loc.x = 0;

View File

@@ -5,6 +5,7 @@ namespace fs = boost::filesystem; // TODO: Centralize this alias!
//void load_file();
//void save_file(short mode);
void finish_load_party();
void change_rect_terrain(RECT r,ter_num_t terrain_type,short probability,bool hollow);
void swap_val(unsigned char *val,short a,short b);
void change_val_4 (unsigned char *val,short a,short b,short c,short d);

View File

@@ -570,7 +570,7 @@ void draw_party_symbol(short mode,location center)
source_rect = calc_rect(2 * (univ.party[current_pc].which_graphic / 8), univ.party[i].which_graphic % 8);
if(pc_dir[current_pc] >= 4)
source_rect.offset(28,0);
ter_num_t ter = univ.town->terrain(univ.town.p_loc.x,univ.town.p_loc.y);
ter_num_t ter = is_out() ? univ.out[univ.party.p_loc.x][univ.party.p_loc.y] : univ.town->terrain(univ.town.p_loc.x,univ.town.p_loc.y);
// now wedge in bed graphic
if ((is_town()) && (scenario.ter_types[ter].special == TER_SPEC_BED))
draw_one_terrain_spot((short) target.x,(short) target.y,10000 + scenario.ter_types[ter].flag1.u);

View File

@@ -165,7 +165,7 @@ short can_see(location p1,location p2,short mode)
return 6;
}
}
else {
else if(is_town()) {
if ((mode != 2) && (pt_in_light(p1,p2) == false)) {
return 6;
}

View File

@@ -483,9 +483,7 @@ void handle_file_menu(int item_hit)
switch (item_hit) {
case 1:
if(overall_mode == MODE_STARTUP)
startup_load();
else do_load();
do_load();
break;
case 2:
do_save(0);

View File

@@ -473,7 +473,6 @@ void put_party_in_scen(std::string scen_name)
univ.party.party_event_timers.clear();
fs::path path;
//std::cout << progDir;
path = progDir/"Blades of Exile Scenarios";
path /= scen_name;
std::cout<<"Searching for scenario at:\n"<<path<<'\n';
@@ -481,7 +480,7 @@ void put_party_in_scen(std::string scen_name)
return;
init_party_scen_data();
univ.party.scen_name = scen_name;
// if at this point, startup must be over, so make this call to make sure we're ready,
// graphics wise

View File

@@ -1829,14 +1829,16 @@ void special_increase_age()
bool redraw = false,stat_area = false;
location null_loc;
for (i = 0; i < 8; i++)
if ((univ.town->timer_spec_times[i] > 0) && (univ.party.age % univ.town->timer_spec_times[i] == 0)
&& ((is_town() == true) || ((is_combat() == true) && (which_combat_type == 1)))) {
run_special(9,2,univ.town->timer_specs[i],null_loc,&s1,&s2,&s3);
stat_area = true;
if (s3 > 0)
redraw = true;
}
if(is_town()) {
for(i = 0; i < 8; i++)
if((univ.town->timer_spec_times[i] > 0) && (univ.party.age % univ.town->timer_spec_times[i] == 0)
&& ((is_town() == true) || ((is_combat() == true) && (which_combat_type == 1)))) {
run_special(9,2,univ.town->timer_specs[i],null_loc,&s1,&s2,&s3);
stat_area = true;
if(s3 > 0)
redraw = true;
}
}
for (i = 0; i < 20; i++)
if ((scenario.scenario_timer_times[i] > 0) && (univ.party.age % scenario.scenario_timer_times[i] == 0)) {
run_special(10,0,scenario.scenario_timer_specs[i],null_loc,&s1,&s2,&s3);

View File

@@ -60,7 +60,7 @@ bool handle_startup_press(location the_point)
draw_start_button(i,0);
switch (i) {
case STARTBTN_LOAD:
startup_load();
do_load();
break;
case STARTBTN_NEW:
@@ -116,28 +116,6 @@ bool handle_startup_press(location the_point)
return false;
}
void startup_load()////
{
bool in_startup_mode = true;
fs::path file_to_load = nav_get_party();
if(!file_to_load.empty() && load_party(file_to_load)){
party_in_memory = true;
if(univ.party.scen_name.length() > 0)
in_startup_mode = false;
else in_startup_mode = true;
}
if (!in_startup_mode) {
//end_anim();
end_startup();
post_load();
}
else {
menu_activate();
draw_startup(0);
overall_mode = MODE_STARTUP;
}
}
/*
void start_game ()
{

View File

@@ -1,3 +1,2 @@
bool handle_startup_press(location the_point);
void startup_load();

View File

@@ -797,7 +797,7 @@ short do_look(location space)
std::string msg;
from_where = get_cur_loc();
is_lit = pt_in_light(from_where,space);
is_lit = is_out() || pt_in_light(from_where,space);
if (((overall_mode == MODE_LOOK_OUTDOORS) && (space == univ.party.p_loc)) ||
((overall_mode == MODE_LOOK_TOWN) && (space == univ.town.p_loc)))

View File

@@ -368,6 +368,7 @@ void cParty::readFrom(std::istream& file){
bin.str(cur);
while(bin) { // continue as long as no error, such as eof, occurs
getline(bin, cur);
printf("Parsing line in party.txt: %s\n", cur.c_str());
std::istringstream sin(cur);
sin >> cur;
if(cur == "AGE")
@@ -468,7 +469,9 @@ void cParty::readFrom(std::istream& file){
sin >> i;
graphicUsed[i] = true;
}
sin.clear();
}
bin.clear();
while(file) {
getline(file, cur, '\f');
bin.str(cur);
@@ -483,7 +486,6 @@ void cParty::readFrom(std::istream& file){
bin >> i;
horses[i].exists = true;
horses[i].readFrom(bin);
} else if(cur == "MAGICSTORE") {
int i,j;
bin >> i >> j;
@@ -563,6 +565,7 @@ void cParty::readFrom(std::istream& file){
getline(bin, note.the_str1);
getline(bin, note.the_str2);
}
bin.clear();
}
}

View File

@@ -245,10 +245,10 @@ void operator -= (eMainStatus& stat, eMainStatus othr){
}
void cPlayer::writeTo(std::ostream& file){
file << "STATUS main " << main_status << '\n';
file << "STATUS -1 " << main_status << '\n';
file << "NAME " << name << '\n';
file << "SKILL hp " << max_health << '\n';
file << "SKILL sp " << max_sp << '\n';
file << "SKILL -2 " << max_health << '\n';
file << "SKILL -1 " << max_sp << '\n';
for(int i = 0; i < 30; i++)
if(skills[i] > 0)
file << "SKILL " << i << ' ' << skills[i] << '\n';
@@ -292,6 +292,7 @@ void cPlayer::readFrom(std::istream& file){
bin.str(cur);
while(bin) { // continue as long as no error, such as eof, occurs
getline(bin, cur);
printf("Parsing line in pcN.txt: %s\n", cur.c_str());
sin.str(cur);
sin >> cur;
if(cur == "STATUS"){
@@ -352,7 +353,9 @@ void cPlayer::readFrom(std::istream& file){
sin >> race;
else if(cur == "POISON")
sin >> weap_poisoned;
sin.clear();
}
bin.clear();
while(file) {
getline(file, cur, '\f');
bin.str(cur);
@@ -365,7 +368,9 @@ void cPlayer::readFrom(std::istream& file){
sin >> i >> cur;
items[i].readFrom(sin);
}
sin.clear();
}
bin.clear();
}
}

View File

@@ -774,7 +774,9 @@ void cCurTown::readFrom(std::istream& file){
sin >> in_boat;
else if(cur == "AT")
sin >> p_loc.x >> p_loc.y;
sin.clear();
}
bin.clear();
while(file) {
getline(file, cur, '\f');
bin.str(cur);
@@ -807,6 +809,7 @@ void cCurTown::readFrom(std::istream& file){
}
record->readTerrainFrom(bin);
}
bin.clear();
}
}

View File

@@ -1179,7 +1179,7 @@ bool load_party_v2(fs::path file_to_load, bool town_restore, bool in_scen, bool
return false;
}
uint16_t magic;
fin.read((char*)magic, 2);
fin.read((char*)&magic, 2);
fin.read((char*)&univ.party.setup, sizeof(cParty::setup));
if(magic == 0x0E0B) // should be 0x0B0E!
for(auto& i : univ.party.setup)

View File

@@ -7,7 +7,7 @@
//
#include "tarball.hpp"
#include <boost/lexical_cast.hpp>
#include <algorithm>
tarball::header_posix_ustar tarball::generateTarHeader(const std::string& fileName, unsigned long long fileSize, bool directory){
static_assert(sizeof(header_posix_ustar) == 512, "Uh-oh! Padding in the tarball header!");
@@ -69,11 +69,19 @@ void tarball::readFrom(std::istream& in) {
header_posix_ustar& header = files.back().header;
in.read((char*)&header, sizeof(header_posix_ustar));
files.back().filename = header.name;
unsigned long long size = boost::lexical_cast<unsigned long long>(header.size);
unsigned long long size;
sscanf(header.size, "%llo", &size);
unsigned long long padLength = 512 - size % 512;
in.read(buf, size);
files.back().contents.write(buf, size);
in.seekg(padLength, std::ios_base::cur);
while(size > 0) {
unsigned long long chunkSz = std::min(size, 512ull);
in.read(buf, chunkSz);
files.back().contents.write(buf, chunkSz);
size -= chunkSz;
}
// Skip past the padding without using seekg.
// This is because the gzstreams don't support seekg.
// We're done with the data in this buffer, anyway, so just dump the padding here.
in.read(buf, padLength);
}
}