Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When the player can't end outdoor combat, list living enemies #538

Merged
merged 2 commits into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 23 additions & 6 deletions src/game/boe.combat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ extern short fast_bang;
extern short store_current_pc;
extern short combat_posing_monster , current_working_monster ; // 0-5 PC 100 + x - monster x
extern short missile_firer,current_monst_tactic;
extern cOutdoors::cWandering store_wandering_special;
eSpell spell_being_cast;
bool spell_freebie;
short missile_inv_slot, ammo_inv_slot;
Expand Down Expand Up @@ -4660,7 +4661,14 @@ bool hit_end_c_button() {
bool end_ok = true;

if(which_combat_type == 0) {
end_ok = out_monst_all_dead();
auto out_monst_remaining = out_monst_alive();
if(!out_monst_remaining.empty()){
// Print remaining monsters.
add_string_to_buf("Enemies are still alive!");
print_encounter_monsters(store_wandering_special, nullptr, out_monst_remaining);

end_ok = false;
}
}
for(cPlayer& pc : univ.party) {
if(pc.status[eStatus::FORCECAGE] > 0) {
Expand All @@ -4674,14 +4682,23 @@ bool hit_end_c_button() {
return end_ok;
}

bool out_monst_all_dead() {
for(short i = 0; i < univ.town.monst.size(); i++)
if(univ.town.monst[i].is_alive() && !univ.town.monst[i].is_friendly()) {
std::map<std::string,short> out_monst_alive() {
std::map<std::string,short> monst_alive;
for(short i = 0; i < univ.town.monst.size(); i++){
cCreature& m = univ.town.monst[i];
if(m.is_alive() && !m.is_friendly()) {
if(monst_alive.find(m.m_name) != monst_alive.end()){
// Would += work in this context?
monst_alive[m.m_name] = monst_alive[m.m_name] + 1;
}else{
monst_alive[m.m_name] = 1;
}

//print_nums(5555,i,univ.town.monst[i].number);
//print_nums(5555,univ.town.monst[i].m_loc.x,univ.town.monst[i].m_loc.y);
return false;
}
return true;
}
return monst_alive;
}

void end_combat() {
Expand Down
3 changes: 2 additions & 1 deletion src/game/boe.combat.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#ifndef BOE_GAME_COMBAT_H
#define BOE_GAME_COMBAT_H

#include <map>
#include "location.hpp"
#include "scenario/monster.hpp"
#include "scenario/outdoors.hpp"
Expand Down Expand Up @@ -49,7 +50,7 @@ void do_poison();
void handle_disease();
void handle_acid();
bool hit_end_c_button();
bool out_monst_all_dead();
std::map<std::string,short> out_monst_alive();
void end_combat();
bool combat_cast_mage_spell();
bool combat_cast_priest_spell();
Expand Down
57 changes: 43 additions & 14 deletions src/game/boe.text.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -838,25 +838,54 @@ cVehicle* out_horse_there(location where) {
return &univ.party.horses[i];
return nullptr;
}
void notify_out_combat_began(cOutdoors::cWandering encounter,short *nums) {
std::string msg;

add_string_to_buf("COMBAT!");

for(short i = 0; i < 6; i++)

void print_monster_count(std::string m_name, short num){
if(num > 0){
std::ostringstream sout;
sout << " ";
if(num > 1){
sout << num << " x ";
}
sout << m_name;
add_string_to_buf(sout.str());
}
}

void print_encounter_monsters(cOutdoors::cWandering encounter, short* nums, std::map<std::string,short> alive) {
std::string m_name;
bool remaining_specified = !alive.empty();
// Still follow the predefined ordering when giving an updated total, and leave summons to the end.
for(short i = 0; i < 7; i++)
if(encounter.monst[i] != 0) {
msg = get_m_name(encounter.monst[i]);
std::ostringstream sout;
sout << " " << nums[i] << " x " << msg;
msg = sout.str();
add_string_to_buf(msg);
m_name = get_m_name(encounter.monst[i]);
short num = 0;
// Combat is just starting, so print the predefined amount
if(!remaining_specified){
num = nums[i];
}
// Combat has started, so need to check how many are still alive
else{
auto iter = alive.find(m_name);
if(iter != alive.end()){
num = iter->second;
alive.erase(iter);
}
}
print_monster_count(m_name, num);
}
// Monsters still in the alive map must have been summoned
if(!alive.empty()){
for (auto iter = alive.begin(); iter != alive.end(); ++iter){
print_monster_count(iter->first, iter->second);
}
if(encounter.monst[6] != 0) {
msg = " " + get_m_name(encounter.monst[6]);
add_string_to_buf(msg);
}
}

void notify_out_combat_began(cOutdoors::cWandering encounter,short *nums) {
add_string_to_buf("COMBAT!");
print_encounter_monsters(encounter, nums);
}

std::string get_m_name(mon_num_t num) {
if(num >= 10000) return univ.party.summons[num - 10000].m_name;
return univ.scenario.scen_monsters[num].m_name;
Expand Down
2 changes: 2 additions & 0 deletions src/game/boe.text.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ cVehicle* town_boat_there(location where);
cVehicle* out_boat_there(location where);
cVehicle* town_horse_there(location where);
cVehicle* out_horse_there(location where);
// Specify the alive map when combat is in progress so casualties and summons are reflected
void print_encounter_monsters(cOutdoors::cWandering encounter, short* nums, std::map<std::string,short> alive = {});
void notify_out_combat_began(cOutdoors::cWandering encounter,short *nums) ;
std::string get_m_name(mon_num_t num);
std::string get_ter_name(ter_num_t num);
Expand Down
Loading