boe.actions.cpp: try to make key work even when the talk ends
boe.town.cpp: try to simplify the code when monsters are loaded in a town...
This commit is contained in:
@@ -1637,9 +1637,8 @@ bool handle_keystroke(const sf::Event& event){
|
|||||||
chr2 = kb::G;
|
chr2 = kb::G;
|
||||||
for(short i = 0; i < 9; i++)
|
for(short i = 0; i < 9; i++)
|
||||||
if(chr2 == talk_chars[i] && (!talk_end_forced || i == 6 || i == 5)) {
|
if(chr2 == talk_chars[i] && (!talk_end_forced || i == 6 || i == 5)) {
|
||||||
int j = talk_end_forced ? i - 5 : i;
|
|
||||||
// related to talk_area_rect, unsure why adding +9 is needed?
|
// related to talk_area_rect, unsure why adding +9 is needed?
|
||||||
pass_point = talk_words[j].rect.topLeft();
|
pass_point = talk_words[i].rect.topLeft();
|
||||||
pass_point.x += talk_area_rect.left+9;
|
pass_point.x += talk_area_rect.left+9;
|
||||||
pass_point.y += talk_area_rect.top+9;
|
pass_point.y += talk_area_rect.top+9;
|
||||||
pass_point = mainPtr.mapCoordsToPixel(pass_point, mainView);
|
pass_point = mainPtr.mapCoordsToPixel(pass_point, mainView);
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ void force_town_enter(short which_town,location where_start) {
|
|||||||
void start_town_mode(short which_town, short entry_dir) {
|
void start_town_mode(short which_town, short entry_dir) {
|
||||||
short town_number;
|
short town_number;
|
||||||
short former_town;
|
short former_town;
|
||||||
bool monsters_loaded = false,town_toast = false;
|
bool monsters_loaded = false;
|
||||||
location loc;
|
location loc;
|
||||||
unsigned short temp;
|
unsigned short temp;
|
||||||
bool play_town_sound = false;
|
bool play_town_sound = false;
|
||||||
@@ -143,8 +143,10 @@ void start_town_mode(short which_town, short entry_dir) {
|
|||||||
univ.town.monst.which_town = town_number;
|
univ.town.monst.which_town = town_number;
|
||||||
univ.town.monst.hostile = false;
|
univ.town.monst.hostile = false;
|
||||||
|
|
||||||
for(auto& pop : univ.party.creature_save)
|
for(size_t i=0 ; i<univ.party.creature_save.size(); ++i) {
|
||||||
if(town_number == pop.which_town) {
|
auto const &pop = univ.party.creature_save[i];
|
||||||
|
if(town_number != pop.which_town)
|
||||||
|
continue;
|
||||||
univ.town.monst = pop;
|
univ.town.monst = pop;
|
||||||
monsters_loaded = true;
|
monsters_loaded = true;
|
||||||
|
|
||||||
@@ -161,35 +163,46 @@ void start_town_mode(short which_town, short entry_dir) {
|
|||||||
if(monst.summon_time > 0)
|
if(monst.summon_time > 0)
|
||||||
monst.active = 0;
|
monst.active = 0;
|
||||||
monst.target = 6;
|
monst.target = 6;
|
||||||
// Bonus SP and HP wear off
|
|
||||||
if(monst.mp > monst.max_mp)
|
|
||||||
monst.mp = monst.max_mp;
|
|
||||||
if(monst.health > monst.m_health)
|
|
||||||
monst.health = monst.m_health;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for(short j = 0; j < univ.town->max_dim; j++)
|
||||||
|
for(short k = 0; k < univ.town->max_dim; k++) { // now load in saved setup,
|
||||||
|
temp = univ.party.setup[i][j][k] << 8;
|
||||||
|
temp &= ~(OBJECT_CRATE | OBJECT_BARREL | OBJECT_BLOCK);
|
||||||
|
univ.town.fields[j][k] |= temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(!monsters_loaded) {
|
||||||
|
univ.town.monst.clear();
|
||||||
|
for(short i = 0; i < univ.town->creatures.size(); i++){
|
||||||
|
if(univ.town->creatures[i].number > 0) {
|
||||||
|
// recreate the lists.
|
||||||
|
const cTownperson& preset = univ.town->creatures[i];
|
||||||
|
univ.town.monst.assign(i, preset, univ.scenario.scen_monsters[preset.number], univ.party.easy_mode, univ.difficulty_adjust());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool const town_toast=(univ.town->town_chop_time > 0 && day_reached(univ.town->town_chop_time,univ.town->town_chop_key)) ||
|
||||||
|
univ.town->is_cleaned_out();
|
||||||
|
if (town_toast)
|
||||||
|
add_string_to_buf(univ.town->is_cleaned_out() ? "Area has been cleaned out." : "Area has been abandoned.");
|
||||||
|
for(size_t i=0; i<univ.town.monst.size(); ++i) {
|
||||||
|
auto &monst=univ.town.monst[i];
|
||||||
|
if (!monsters_loaded && monst.spec_enc_code>0)
|
||||||
|
monst.active = 0;
|
||||||
// Now, travelling NPCs might have arrived. Go through and put them in.
|
// Now, travelling NPCs might have arrived. Go through and put them in.
|
||||||
// These should have protected status (i.e. spec1 >= 200, spec1 <= 204)
|
// These should have protected status (i.e. spec1 >= 200, spec1 <= 204)
|
||||||
for(auto& monst : univ.town.monst) {
|
|
||||||
switch(monst.time_flag){
|
switch(monst.time_flag){
|
||||||
case eMonstTime::ALWAYS: break; // Nothing to do.
|
case eMonstTime::ALWAYS: break; // Nothing to do.
|
||||||
case eMonstTime::SOMETIMES_A: case eMonstTime::SOMETIMES_B: case eMonstTime::SOMETIMES_C:
|
case eMonstTime::SOMETIMES_A: case eMonstTime::SOMETIMES_B: case eMonstTime::SOMETIMES_C:
|
||||||
if((univ.party.calc_day() % 3) + 3 != int(monst.time_flag))
|
monst.active = (univ.party.calc_day() % 3) + 3 == int(monst.time_flag) ? 1 : 0;
|
||||||
monst.active = 0;
|
if (monst.active) monst.spec_enc_code=0;
|
||||||
else {
|
|
||||||
monst.active = 1;
|
|
||||||
monst.spec_enc_code = 0;
|
|
||||||
monst.cur_loc = monst.start_loc;
|
|
||||||
monst.health = monst.m_health;
|
|
||||||
}
|
|
||||||
break ;
|
break ;
|
||||||
|
|
||||||
// Now, appearing/disappearing monsters might have arrived/disappeared.
|
// Now, appearing/disappearing monsters might have arrived/disappeared.
|
||||||
case eMonstTime::APPEAR_ON_DAY:
|
case eMonstTime::APPEAR_ON_DAY:
|
||||||
if(day_reached(monst.monster_time, monst.time_code)) {
|
monst.active = day_reached(monst.monster_time, monst.time_code) ? 1 : 0;
|
||||||
monst.active = 1;
|
|
||||||
monst.time_flag = eMonstTime::ALWAYS;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case eMonstTime::DISAPPEAR_ON_DAY:
|
case eMonstTime::DISAPPEAR_ON_DAY:
|
||||||
if(day_reached(monst.monster_time, monst.time_code)) {
|
if(day_reached(monst.monster_time, monst.time_code)) {
|
||||||
@@ -198,15 +211,15 @@ void start_town_mode(short which_town, short entry_dir) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case eMonstTime::APPEAR_WHEN_EVENT:
|
case eMonstTime::APPEAR_WHEN_EVENT:
|
||||||
|
monst.active = 0;
|
||||||
if(univ.party.key_times.find(monst.time_code) == univ.party.key_times.end())
|
if(univ.party.key_times.find(monst.time_code) == univ.party.key_times.end())
|
||||||
break; // Event hasn't happened yet
|
break; // Event hasn't happened yet
|
||||||
if(univ.party.calc_day() >= univ.party.key_times[monst.time_code]){ //calc_day is used because of the "definition" of univ.party.key_times
|
if(univ.party.calc_day() >= univ.party.key_times[monst.time_code]) //calc_day is used because of the "definition" of univ.party.key_times
|
||||||
monst.active = 1;
|
monst.active = 1;
|
||||||
monst.time_flag = eMonstTime::ALWAYS;
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case eMonstTime::DISAPPEAR_WHEN_EVENT:
|
case eMonstTime::DISAPPEAR_WHEN_EVENT:
|
||||||
|
if (!monst.active)
|
||||||
|
break;
|
||||||
if(univ.party.key_times.find(monst.time_code) == univ.party.key_times.end())
|
if(univ.party.key_times.find(monst.time_code) == univ.party.key_times.end())
|
||||||
break; // Event hasn't happened yet
|
break; // Event hasn't happened yet
|
||||||
if(univ.party.calc_day() >= univ.party.key_times[monst.time_code]) {
|
if(univ.party.calc_day() >= univ.party.key_times[monst.time_code]) {
|
||||||
@@ -214,133 +227,42 @@ void start_town_mode(short which_town, short entry_dir) {
|
|||||||
monst.time_flag = eMonstTime::ALWAYS;
|
monst.time_flag = eMonstTime::ALWAYS;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
// toasting
|
||||||
case eMonstTime::APPEAR_AFTER_CHOP:
|
case eMonstTime::APPEAR_AFTER_CHOP:
|
||||||
// TODO: Should these two cases be separated?
|
if(town_toast)
|
||||||
if(univ.town->town_chop_time > 0 && day_reached(univ.town->town_chop_time,univ.town->town_chop_key))
|
|
||||||
monst.active += 10;
|
monst.active += 10;
|
||||||
else if(univ.town->is_cleaned_out())
|
else
|
||||||
monst.active += 10;
|
monst.active = 0;
|
||||||
else monst.active = 0;
|
break;
|
||||||
if(monst.active >= 10)
|
}
|
||||||
|
if (town_toast) {
|
||||||
|
if (univ.town->is_cleaned_out() || monst.active>=10 || monst.is_friendly())
|
||||||
|
monst.active -= 10;
|
||||||
|
}
|
||||||
|
if(monst.active<=0) {
|
||||||
|
monst.active=0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
monst.time_flag = eMonstTime::ALWAYS;
|
monst.time_flag = eMonstTime::ALWAYS;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(short j = 0; j < univ.town->max_dim; j++)
|
// Flush excess doomguards and viscous goos
|
||||||
for(short k = 0; k < univ.town->max_dim; k++) { // now load in saved setup,
|
if(monst.abil[eMonstAbil::SPLITS].active &&
|
||||||
// except that pushable things restore to orig locs
|
(i >= univ.town->creatures.size() || monst.number != univ.town->creatures[i].number))
|
||||||
// TODO: THIS IS A TEMPORARY HACK TO GET i VALUE
|
|
||||||
int i = std::find_if(univ.party.creature_save.begin(), univ.party.creature_save.end(), [&pop](cPopulation& p) {return &p == &pop;}) - univ.party.creature_save.begin();
|
|
||||||
temp = univ.party.setup[i][j][k] << 8;
|
|
||||||
temp &= ~(OBJECT_CRATE | OBJECT_BARREL | OBJECT_BLOCK);
|
|
||||||
univ.town.fields[j][k] |= temp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!monsters_loaded) {
|
|
||||||
univ.town.monst.clear();
|
|
||||||
for(short i = 0; i < univ.town->creatures.size(); i++){
|
|
||||||
if(univ.town->creatures[i].number > 0) {
|
|
||||||
// First set up the values.
|
|
||||||
const cTownperson& preset = univ.town->creatures[i];
|
|
||||||
univ.town.monst.assign(i, preset, univ.scenario.scen_monsters[preset.number], univ.party.easy_mode, univ.difficulty_adjust());
|
|
||||||
cCreature& monst = univ.town.monst[i];
|
|
||||||
|
|
||||||
if(monst.spec_enc_code > 0)
|
|
||||||
monst.active = 0;
|
monst.active = 0;
|
||||||
|
|
||||||
// Now, if necessary, fry the monster.
|
// In forcecage? checkme all case ?
|
||||||
switch(monst.time_flag) {
|
if(!monsters_loaded && univ.town.is_force_cage(monst.cur_loc.x, monst.cur_loc.y))
|
||||||
case eMonstTime::APPEAR_ON_DAY:
|
|
||||||
if(!day_reached(monst.monster_time, monst.time_code))
|
|
||||||
monst.active = 0;
|
|
||||||
break;
|
|
||||||
case eMonstTime::DISAPPEAR_ON_DAY:
|
|
||||||
if(day_reached(monst.monster_time, monst.time_code))
|
|
||||||
monst.active = 0;
|
|
||||||
break;
|
|
||||||
case eMonstTime::SOMETIMES_A: case eMonstTime::SOMETIMES_B: case eMonstTime::SOMETIMES_C:
|
|
||||||
if((univ.party.calc_day() % 3) + 3 != int(monst.time_flag)) {
|
|
||||||
monst.active = 0;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
monst.active = 1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case eMonstTime::APPEAR_WHEN_EVENT:
|
|
||||||
if(univ.party.key_times.find(monst.time_code) == univ.party.key_times.end())
|
|
||||||
monst.active = 0; // Event hasn't happened yet
|
|
||||||
else if(univ.party.calc_day() < univ.party.key_times[univ.town.monst[i].time_code])
|
|
||||||
monst.active = 0; // This would only be reached if the time was set back (or in a legacy save)
|
|
||||||
break;
|
|
||||||
|
|
||||||
case eMonstTime::DISAPPEAR_WHEN_EVENT:
|
|
||||||
if(univ.party.key_times.find(monst.time_code) == univ.party.key_times.end())
|
|
||||||
break; // Event hasn't happened yet
|
|
||||||
if(univ.party.calc_day() >= univ.party.key_times[univ.town.monst[i].time_code])
|
|
||||||
monst.active = 0;
|
|
||||||
break;
|
|
||||||
case eMonstTime::APPEAR_AFTER_CHOP:
|
|
||||||
// TODO: Should these two cases be separated?
|
|
||||||
if(univ.town->town_chop_time > 0 && day_reached(univ.town->town_chop_time,univ.town->town_chop_key))
|
|
||||||
monst.active += 10;
|
|
||||||
else if(univ.town->is_cleaned_out())
|
|
||||||
monst.active += 10;
|
|
||||||
else monst.active = 0;
|
|
||||||
break;
|
|
||||||
case eMonstTime::ALWAYS:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(monst.active) {
|
|
||||||
// In forcecage?
|
|
||||||
if(univ.town.is_force_cage(monst.cur_loc.x, monst.cur_loc.y))
|
|
||||||
monst.status[eStatus::FORCECAGE] = 1000;
|
monst.status[eStatus::FORCECAGE] = 1000;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now munch all large monsters that are misplaced
|
// Now munch all large monsters that are misplaced
|
||||||
// only large monsters, as some smaller monsters are intentionally placed
|
// only large monsters, as some smaller monsters are intentionally placed
|
||||||
// where they cannot be
|
// where they cannot be
|
||||||
for(short i = 0; i < univ.town.monst.size(); i++) {
|
if((monst.x_width > 1 || monst.y_width > 1) && !monst_can_be_there(monst.cur_loc,i))
|
||||||
if(univ.town.monst[i].active > 0)
|
monst.active = 0;
|
||||||
if(((univ.town.monst[i].x_width > 1) || (univ.town.monst[i].y_width > 1)) &&
|
|
||||||
!monst_can_be_there(univ.town.monst[i].cur_loc,i))
|
|
||||||
univ.town.monst[i].active = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Thrash town?
|
|
||||||
if(univ.town->is_cleaned_out()) {
|
|
||||||
town_toast = true;
|
|
||||||
add_string_to_buf("Area has been cleaned out.");
|
|
||||||
}
|
|
||||||
if(univ.town->town_chop_time > 0) {
|
|
||||||
if(day_reached(univ.town->town_chop_time,univ.town->town_chop_key)) {
|
|
||||||
add_string_to_buf("Area has been abandoned.");
|
|
||||||
for(auto& monst : univ.town.monst)
|
|
||||||
if(monst.active > 0 && monst.active < 10 && !monst.is_friendly())
|
|
||||||
monst.active += 10;
|
|
||||||
town_toast = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(town_toast) {
|
|
||||||
for(auto& monst : univ.town.monst)
|
|
||||||
if(monst.active >= 10)
|
|
||||||
monst.active -= 10;
|
|
||||||
else monst.active = 0;
|
|
||||||
}
|
|
||||||
handle_town_specials(town_number, (short) town_toast,(entry_dir < 9) ? univ.town->start_locs[entry_dir] : town_force_loc);
|
handle_town_specials(town_number, (short) town_toast,(entry_dir < 9) ? univ.town->start_locs[entry_dir] : town_force_loc);
|
||||||
|
|
||||||
// Flush excess doomguards and viscous goos
|
|
||||||
for(short i = 0; i < univ.town.monst.size(); i++)
|
|
||||||
if((univ.town.monst[i].abil[eMonstAbil::SPLITS].active) &&
|
|
||||||
(i >= univ.town->creatures.size() || univ.town.monst[i].number != univ.town->creatures[i].number))
|
|
||||||
univ.town.monst[i].active = 0;
|
|
||||||
|
|
||||||
// Set up field booleans, correct for doors
|
// Set up field booleans, correct for doors
|
||||||
for(short j = 0; j < univ.town->max_dim; j++)
|
for(short j = 0; j < univ.town->max_dim; j++)
|
||||||
for(short k = 0; k < univ.town->max_dim; k++) {
|
for(short k = 0; k < univ.town->max_dim; k++) {
|
||||||
|
|||||||
Reference in New Issue
Block a user