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:
@@ -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)) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 ()
|
||||
{
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
|
||||
bool handle_startup_press(location the_point);
|
||||
void startup_load();
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user