Allow taking items from a scenario even if they summon monsters or have custom graphics. Breaks older saved games.
(Older saved games might still work if not in a scenario.) - Remove items that call a special node when entering a new scenario - Remove stone block if a monster is placed on it - Monsters captured by Capture Soul now persist across scenarios - Fix barrels/crates not being restored when re-entering the town - Fix issue when saving monster status effects - Fix version number stored in saved game file; also, it's now stored in hexadecimal - Fix issue with saving which would have caused all but the first timer to be ignored when loading the saved game - Fix timers being written to out-of-bounds memory when loading a saved game - Fix use of std::skipws where std::ws was intended - Fix issue with the fields array being shifted right by one tile on loading; also, fields array is now saved as hexadecimal - Fields and terrain array use the town's dimension instead of dimension hard-coded (in the case of fields) or stored in the file - Fix PC editor remove from scenario option not working properly - Reconstruct the universe when loading a saved game to ensure there isn't leakage from the previous universe - Fix excess padding in output tarballs when the filesize is a multiple of 512 - Add hasFile function to tarball class
This commit is contained in:
@@ -197,21 +197,19 @@ void draw_monsters() {
|
||||
// TODO: Windows special-cases the bear and drake, whose graphics are split between two columns/sheets. Is this necessary?
|
||||
// It really doesn't look necessary to me, since each quadrant of the graphic is fetched separately.
|
||||
// Technically what they do is always pass 0 as the final argument to get_monster_template_rect, instead of passing k; they also hardcode the sheet to look on (4 for drake, 5 for bear).
|
||||
m_num_t m_num = univ.party.out_c[i].what_monst.monst[j];
|
||||
pic_num_t this_monst = univ.scenario.scen_monsters[m_num].picture_num;
|
||||
source_rect = get_monster_template_rect(this_monst,(univ.party.out_c[i].direction < 4) ? 0 : 1,k);
|
||||
source_rect = get_monster_template_rect(picture_wanted,(univ.party.out_c[i].direction < 4) ? 0 : 1,k);
|
||||
to_rect = monst_rects[(width - 1) * 2 + height - 1][k];
|
||||
to_rect.offset(13 + 28 * where_draw.x,13 + 36 * where_draw.y);
|
||||
rect_draw_some_item(monst_gworld[m_pic_index[this_monst].i/20], source_rect, terrain_screen_gworld,to_rect, sf::BlendAlpha);
|
||||
rect_draw_some_item(monst_gworld[m_pic_index[picture_wanted].i/20], source_rect, terrain_screen_gworld,to_rect, sf::BlendAlpha);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(is_town())
|
||||
if(is_town() || is_combat()) {
|
||||
for(i = 0; i < univ.town->max_monst(); i++)
|
||||
if((univ.town.monst[i].active != 0) && (univ.town.monst[i].spec_skill != 11))
|
||||
if(party_can_see_monst(i)) {
|
||||
if(point_onscreen(center,univ.town.monst[i].cur_loc) && party_can_see_monst(i)) {
|
||||
check_if_monst_seen(univ.town.monst[i].number, univ.town.monst[i].cur_loc);
|
||||
where_draw.x = univ.town.monst[i].cur_loc.x - center.x + 4;
|
||||
where_draw.y = univ.town.monst[i].cur_loc.y - center.y + 4;
|
||||
@@ -221,80 +219,27 @@ void draw_monsters() {
|
||||
store_loc = where_draw;
|
||||
store_loc.x += k % width;
|
||||
store_loc.y += k / width;
|
||||
// customize?
|
||||
if(univ.town.monst[i].picture_num >= 1000) {
|
||||
sf::Texture* src_gw;
|
||||
graf_pos_ref(src_gw, source_rect) = spec_scen_g.find_graphic((univ.town.monst[i].picture_num % 1000) +
|
||||
k + ((univ.town.monst[i].direction < 4) ? 0 : width * height)
|
||||
+ ((combat_posing_monster == i + 100) ? (2 * width * height) : 0));
|
||||
ter = univ.town->terrain(univ.town.monst[i].cur_loc.x,univ.town.monst[i].cur_loc.y);
|
||||
// in bed?
|
||||
if((store_loc.x >= 0) && (store_loc.x < 9) && (store_loc.y >= 0) && (store_loc.y < 9) &&
|
||||
univ.scenario.ter_types[ter].special == eTerSpec::BED &&
|
||||
isHumanoid(univ.town.monst[i].m_type)
|
||||
&& ((univ.town.monst[i].active == 1) || (univ.town.monst[i].target == 6)) &&
|
||||
(width == 1) && (height == 1)) ////
|
||||
draw_one_terrain_spot((short) where_draw.x,(short) where_draw.y,10000 + univ.scenario.ter_types[ter].flag1.u);
|
||||
else Draw_Some_Item(*src_gw, source_rect, terrain_screen_gworld, store_loc, 1, 0);
|
||||
}
|
||||
if(univ.town.monst[i].picture_num < 1000) {
|
||||
pic_num_t this_monst = univ.town.monst[i].picture_num;
|
||||
source_rect = get_monster_template_rect(this_monst,
|
||||
((univ.town.monst[i].direction < 4) ? 0 : 1) + ((combat_posing_monster == i + 100) ? 10 : 0),k);
|
||||
ter = univ.town->terrain(univ.town.monst[i].cur_loc.x,univ.town.monst[i].cur_loc.y);
|
||||
// in bed?
|
||||
if((store_loc.x >= 0) && (store_loc.x < 9) && (store_loc.y >= 0) && (store_loc.y < 9) &&
|
||||
(univ.scenario.ter_types[ter].special == eTerSpec::BED) &&
|
||||
isHumanoid(univ.town.monst[i].m_type)
|
||||
&& ((univ.town.monst[i].active == 1) || (univ.town.monst[i].target == 6)) &&
|
||||
(width == 1) && (height == 1)) ////
|
||||
draw_one_terrain_spot((short) where_draw.x,(short) where_draw.y,10000 + univ.scenario.ter_types[ter].flag1.u);
|
||||
else Draw_Some_Item(monst_gworld[m_pic_index[this_monst].i/20], source_rect, terrain_screen_gworld, store_loc, 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(is_combat()) {
|
||||
for(i = 0; i < univ.town->max_monst(); i++)
|
||||
if((univ.town.monst[i].active != 0) && (univ.town.monst[i].spec_skill != 11))
|
||||
if(point_onscreen(center,univ.town.monst[i].cur_loc) && party_can_see_monst(i)) {
|
||||
check_if_monst_seen(univ.town.monst[i].number,univ.town.monst[i].cur_loc);
|
||||
where_draw.x = univ.town.monst[i].cur_loc.x - center.x + 4;
|
||||
where_draw.y = univ.town.monst[i].cur_loc.y - center.y + 4;
|
||||
get_monst_dims(univ.town.monst[i].number,&width,&height);
|
||||
|
||||
for(k = 0; k < width * height; k++) {
|
||||
store_loc = where_draw;
|
||||
store_loc.x += k % width;
|
||||
store_loc.y += k / width;
|
||||
// customize?
|
||||
if(univ.town.monst[i].picture_num >= 1000) {
|
||||
ter = univ.town->terrain(univ.town.monst[i].cur_loc.x,univ.town.monst[i].cur_loc.y);
|
||||
// in bed?
|
||||
if(store_loc.x >= 0 && store_loc.x < 9 && store_loc.y >= 0 && store_loc.y < 9 &&
|
||||
(univ.scenario.ter_types[ter].special == eTerSpec::BED) && isHumanoid(univ.town.monst[i].m_type)
|
||||
&& (univ.town.monst[i].active == 1 || univ.town.monst[i].target == 6) &&
|
||||
width == 1 && height == 1)
|
||||
draw_one_terrain_spot((short) where_draw.x,(short) where_draw.y,10000 + univ.scenario.ter_types[ter].flag1.u);
|
||||
else if(univ.town.monst[i].picture_num >= 1000) {
|
||||
bool isParty = univ.town.monst[i].picture_num >= 10000;
|
||||
sf::Texture* src_gw;
|
||||
pic_num_t need_pic = (univ.town.monst[i].picture_num % 1000) + k;
|
||||
if(univ.town.monst[i].direction >= 4) need_pic += width * height;
|
||||
if(combat_posing_monster == i + 100) need_pic += (2 * width * height);
|
||||
graf_pos_ref(src_gw, source_rect) = spec_scen_g.find_graphic(need_pic);
|
||||
ter = univ.town->terrain(univ.town.monst[i].cur_loc.x,univ.town.monst[i].cur_loc.y);
|
||||
if((store_loc.x >= 0) && (store_loc.x < 9) && (store_loc.y >= 0) && (store_loc.y < 9) &&
|
||||
univ.scenario.ter_types[ter].special == eTerSpec::BED &&
|
||||
isHumanoid(univ.town.monst[i].m_type)
|
||||
&& ((univ.town.monst[i].active == 1) || (univ.town.monst[i].target == 6)) &&
|
||||
(width == 1) && (height == 1))
|
||||
draw_one_terrain_spot((short) where_draw.x,(short) where_draw.y,10000 + univ.scenario.ter_types[ter].flag1.u);
|
||||
else Draw_Some_Item(*src_gw, source_rect, terrain_screen_gworld, store_loc, 1, 0);
|
||||
}
|
||||
if(univ.town.monst[i].picture_num < 1000) {
|
||||
Draw_Some_Item(*src_gw, source_rect, terrain_screen_gworld, store_loc, 1, 0);
|
||||
} else {
|
||||
pic_num_t this_monst = univ.town.monst[i].picture_num;
|
||||
int pic_mode = (univ.town.monst[i].direction) < 4 ? 0 : 1;
|
||||
pic_mode += (combat_posing_monster == i + 100) ? 10 : 0;
|
||||
source_rect = get_monster_template_rect(this_monst, pic_mode, k);
|
||||
ter = univ.town->terrain(univ.town.monst[i].cur_loc.x,univ.town.monst[i].cur_loc.y);
|
||||
if((store_loc.x >= 0) && (store_loc.x < 9) && (store_loc.y >= 0) && (store_loc.y < 9) &&
|
||||
univ.scenario.ter_types[ter].special == eTerSpec::BED &&
|
||||
isHumanoid(univ.town.monst[i].m_type)
|
||||
&& ((univ.town.monst[i].active == 1) || (univ.town.monst[i].target == 6)) &&
|
||||
(width == 1) && (height == 1))
|
||||
draw_one_terrain_spot((short) where_draw.x,(short) where_draw.y,10000 + univ.scenario.ter_types[ter].flag1.u);
|
||||
else Draw_Some_Item(monst_gworld[m_pic_index[this_monst].i/20], source_rect, terrain_screen_gworld, store_loc, 1, 0);
|
||||
Draw_Some_Item(monst_gworld[m_pic_index[this_monst].i/20], source_rect, terrain_screen_gworld, store_loc, 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -315,7 +260,7 @@ void play_see_monster_str(unsigned short m, location monst_loc) {
|
||||
short where1 = is_out() ? univ.party.outdoor_corner.x + univ.party.i_w_c.x : univ.town.num;
|
||||
short where2 = is_out() ? univ.party.outdoor_corner.y + univ.party.i_w_c.y : univ.town.num;
|
||||
std::string placename = is_out() ? univ.out->out_name : univ.town->town_name;
|
||||
cStrDlog display_strings(str1 ? univ.scenario.monst_strs[str1] : "", str2 ? univ.scenario.monst_strs[str2] : "", "", pic, type, NULL);
|
||||
cStrDlog display_strings(str1 < 100 ? univ.scenario.monst_strs[str1] : "", str2 < 100 ? univ.scenario.monst_strs[str2] : "", "", pic, type, NULL);
|
||||
display_strings.setSound(snd);
|
||||
display_strings.setRecordHandler(cStringRecorder(NOTE_MONST).string1(str1).string2(str2).from(where1,where2).at(placename));
|
||||
display_strings.show();
|
||||
@@ -389,10 +334,16 @@ void draw_items(location where){
|
||||
if(univ.town.items[i].variety != eItemType::NO_ITEM && univ.town.items[i].item_loc == where) {
|
||||
if(univ.town.items[i].contained) continue;
|
||||
if(party_can_see(where) >= 6) continue;
|
||||
if(univ.town.items[i].graphic_num >= 1000){
|
||||
if(univ.town.items[i].graphic_num >= 10000){
|
||||
sf::Texture* src_gw;
|
||||
graf_pos_ref(src_gw, from_rect) = spec_scen_g.find_graphic(univ.town.items[i].graphic_num - 10000, true);
|
||||
to_rect = coord_to_rect(where_draw.x,where_draw.y);
|
||||
terrain_there[where_draw.x][where_draw.y] = -1;
|
||||
rect_draw_some_item(*src_gw,from_rect,terrain_screen_gworld,to_rect,sf::BlendAlpha);
|
||||
}else if(univ.town.items[i].graphic_num >= 1000){
|
||||
sf::Texture* src_gw;
|
||||
graf_pos_ref(src_gw, from_rect) = spec_scen_g.find_graphic(univ.town.items[i].graphic_num - 1000);
|
||||
to_rect = coord_to_rect(where.x,where.y);
|
||||
to_rect = coord_to_rect(where_draw.x,where_draw.y);
|
||||
terrain_there[where_draw.x][where_draw.y] = -1;
|
||||
rect_draw_some_item(*src_gw,from_rect,terrain_screen_gworld,to_rect,sf::BlendAlpha);
|
||||
}else{
|
||||
@@ -753,14 +704,17 @@ char get_fluid_trim(location where,ter_num_t ter_type) {
|
||||
}
|
||||
|
||||
// Sees if party has seen a monster of this sort, gives special messages as necessary
|
||||
void check_if_monst_seen(unsigned short m_num, location at) {
|
||||
void check_if_monst_seen(unsigned short m_num, location at) {\
|
||||
// Give special messages if necessary
|
||||
if(!univ.party.m_seen[m_num]) {
|
||||
if(m_num < 10000 && !univ.party.m_seen[m_num]) {
|
||||
univ.party.m_seen[m_num] = true;
|
||||
play_see_monster_str(m_num, at);
|
||||
}
|
||||
// Make the monster vocalize if applicable
|
||||
snd_num_t sound = univ.scenario.scen_monsters[m_num].ambient_sound;
|
||||
snd_num_t sound;
|
||||
if(m_num >= 10000)
|
||||
sound = univ.party.summons[m_num - 10000].ambient_sound;
|
||||
else sound = univ.scenario.scen_monsters[m_num].ambient_sound;
|
||||
if(get_ran(1,1,100) < 10) play_sound(-sound);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user