diff --git a/rsrc/dialogs/get-num.xml b/rsrc/dialogs/get-num.xml
index e88abc10..af5a88a1 100644
--- a/rsrc/dialogs/get-num.xml
+++ b/rsrc/dialogs/get-num.xml
@@ -3,6 +3,6 @@
diff --git a/src/dialogxml/keycodes.cpp b/src/dialogxml/keycodes.cpp
index be7c238e..ef43ef91 100644
--- a/src/dialogxml/keycodes.cpp
+++ b/src/dialogxml/keycodes.cpp
@@ -52,6 +52,16 @@ cKey charToKey(char ch) {
return {false, w('.'), mod_shift};
case '!':
return {false, w('1'), mod_shift};
+ case '@':
+ return {false, w('2'), mod_shift};
+ case '#':
+ return {false, w('3'), mod_shift};
+ case '$':
+ return {false, w('4'), mod_shift};
+ case '%':
+ return {false, w('5'), mod_shift};
+ case '^':
+ return {false, w('6'), mod_shift};
case '?':
return {false, w('/'), mod_shift};
}
diff --git a/src/game/boe.actions.cpp b/src/game/boe.actions.cpp
index 8886b621..0d352a92 100644
--- a/src/game/boe.actions.cpp
+++ b/src/game/boe.actions.cpp
@@ -1892,9 +1892,24 @@ void handle_menu_spell(eSpell spell_picked) {
advance_time(did_something, need_redraw, need_reprint);
}
-void initiate_outdoor_combat(short i) {
+static void set_up_combat() {
location to_place;
-
+ for(cPlayer& pc : univ.party)
+ if(pc.main_status == eMainStatus::ALIVE)
+ to_place = pc.combat_pos;
+ else for(cItem& item : pc.items)
+ if(item.variety != eItemType::NO_ITEM) {
+ place_item(item,to_place);
+ item.variety = eItemType::NO_ITEM;
+ }
+
+ overall_mode = MODE_COMBAT;
+ center = univ.current_pc().combat_pos;
+ draw_terrain();
+}
+
+void initiate_outdoor_combat(short i) {
+ // Make sure the player can see the monster they stepped next to
draw_terrain();
// Is combat too easy?
@@ -1905,24 +1920,11 @@ void initiate_outdoor_combat(short i) {
return;
}
-// Delay((long) 100,&dummy);
-
start_outdoor_combat(univ.party.out_c[i], univ.party.out_loc,count_walls(univ.party.out_loc));
univ.party.out_c[i].exists = false;
- for(cPlayer& pc : univ.party)
- if(pc.main_status == eMainStatus::ALIVE)
- to_place = pc.combat_pos;
- else for(cItem& item : pc.items)
- if(item.variety != eItemType::NO_ITEM) {
- place_item(item,to_place);
- item.variety = eItemType::NO_ITEM;
- }
-
- overall_mode = MODE_COMBAT;
- center = univ.current_pc().combat_pos;
- draw_terrain();
+ set_up_combat();
}
void show_inventory() {
@@ -1960,6 +1962,37 @@ void toggle_debug_mode() {
print_buf();
}
+void debug_fight_encounter(bool wandering) {
+ if(recording){
+ record_action("debug_fight_encounter", bool_to_str(wandering));
+ }
+ if(!is_out()){
+ ASB("Debug outdoor encounter: You have to be");
+ ASB("outdoors!");
+ print_buf();
+ return;
+ }
+
+ std::string prompt = "Which ";
+ if(wandering){
+ prompt += "wandering encounter?";
+ }else{
+ prompt += "special encounter?";
+ }
+
+ int i = get_num_response(0, 3, prompt);
+
+ cOutdoors::cWandering encounter;
+ if(wandering){
+ encounter = univ.out->wandering[i];
+ }else{
+ encounter = univ.out->special_enc[i];
+ }
+ start_outdoor_combat(encounter, univ.party.out_loc, count_walls(univ.party.out_loc));
+
+ set_up_combat();
+}
+
void debug_give_item() {
if(recording){
record_action("debug_give_item", "");
@@ -2331,7 +2364,7 @@ void show_debug_help() {
}
// Non-comprehensive list of unused keys:
-// JUXYZ chijklnoqvy @#$%^-_+[]{},.'"`~/\|;:
+// JUXYZ chijklnoqvy @#$-_+[]{},.'"`~/\|;:
void init_debug_actions() {
add_debug_action({'B'}, "Leave town", debug_leave_town);
add_debug_action({'C'}, "Get cleaned up (lose negative status effects)", debug_clean_up);
@@ -2362,6 +2395,9 @@ void init_debug_actions() {
add_debug_action({'<'}, "Make one day pass", debug_increase_age);
add_debug_action({'>'}, "Reset towns (excludes the one you're in, if any)", debug_towns_forget);
add_debug_action({'!'}, "Toggle Special Node Step-through Mode", debug_step_through);
+ // std::bind won't work here for reasons
+ add_debug_action({'%'}, "Fight wandering encounter from this section", []() -> void {debug_fight_encounter(true);});
+ add_debug_action({'^'}, "Fight special encounter from this section", []() -> void {debug_fight_encounter(false);});
add_debug_action({'/', '?'}, "Bring up this window", show_debug_help);
}
diff --git a/src/game/boe.actions.hpp b/src/game/boe.actions.hpp
index 732bf38e..cd288935 100644
--- a/src/game/boe.actions.hpp
+++ b/src/game/boe.actions.hpp
@@ -84,6 +84,7 @@ void show_inventory();
void toggle_debug_mode();
void init_debug_actions();
void show_debug_help();
+void debug_fight_encounter(bool wandering);
void debug_give_item();
void debug_print_location();
void debug_step_through();
diff --git a/src/game/boe.combat.cpp b/src/game/boe.combat.cpp
index 8c166421..447ee9ca 100644
--- a/src/game/boe.combat.cpp
+++ b/src/game/boe.combat.cpp
@@ -251,11 +251,7 @@ effect_pat_type field[8] = {
bool center_on_monst;
-
-
-
-
-void start_outdoor_combat(cOutdoors::cCreature encounter,location where,short num_walls) {
+void start_outdoor_combat(cOutdoors::cWandering encounter,location where,short num_walls) {
short how_many,num_tries = 0;
short low[10] = {15,7,4,3,2,1,1,7,2,1};
short high[10] = {30,10,6,5,3,2,1,10,4,1};
@@ -266,7 +262,7 @@ void start_outdoor_combat(cOutdoors::cCreature encounter,location where,short nu
nums[i] = get_ran(1,low[i],high[i]);
for(short i = 0; i < 3; i++)
nums[i + 7] = get_ran(1,low[i + 7],high[i + 7]);
- notify_out_combat_began(encounter.what_monst,nums);
+ notify_out_combat_began(encounter,nums);
print_buf();
play_sound(23);
@@ -286,15 +282,15 @@ void start_outdoor_combat(cOutdoors::cCreature encounter,location where,short nu
for(short i = 0; i < 7; i++) {
how_many = nums[i];
- if(encounter.what_monst.monst[i] != 0)
+ if(encounter.monst[i] != 0)
for(short j = 0; j < how_many; j++)
- set_up_monst(eAttitude::HOSTILE_A,encounter.what_monst.monst[i]);
+ set_up_monst(eAttitude::HOSTILE_A,encounter.monst[i]);
}
for(short i = 0; i < 3; i++) {
how_many = nums[i + 7];
- if(encounter.what_monst.friendly[i] != 0)
+ if(encounter.friendly[i] != 0)
for(short j = 0; j < how_many; j++)
- set_up_monst(eAttitude::FRIENDLY,encounter.what_monst.friendly[i]);
+ set_up_monst(eAttitude::FRIENDLY,encounter.friendly[i]);
}
// place PCs
@@ -371,6 +367,10 @@ void start_outdoor_combat(cOutdoors::cCreature encounter,location where,short nu
}
+void start_outdoor_combat(cOutdoors::cCreature encounter,location where,short num_walls) {
+ start_outdoor_combat(encounter.what_monst, where, num_walls);
+}
+
bool pc_combat_move(location destination) {
std::string create_line;
short s1;
diff --git a/src/game/boe.combat.hpp b/src/game/boe.combat.hpp
index 56eb2330..fa656658 100644
--- a/src/game/boe.combat.hpp
+++ b/src/game/boe.combat.hpp
@@ -9,6 +9,9 @@
#include "boe.global.hpp"
#include "spell.hpp"
+// For debug purposes, allow directly starting an outdoor encounter without
+// a wandering monster
+void start_outdoor_combat(cOutdoors::cWandering encounter,location where,short num_walls);
void start_outdoor_combat(cOutdoors::cCreature encounter,location where,short num_walls);
bool pc_combat_move(location destination);
void char_parry();
diff --git a/src/game/boe.main.cpp b/src/game/boe.main.cpp
index ec0efa3c..bbe35a36 100644
--- a/src/game/boe.main.cpp
+++ b/src/game/boe.main.cpp
@@ -875,6 +875,8 @@ static void replay_action(Element& action) {
easter_egg(boost::lexical_cast(action.GetText()));
}else if(t == "show_debug_panel"){
show_debug_help();
+ }else if(t == "debug_fight_encounter"){
+ debug_fight_encounter(str_to_bool(action.GetText()));
}else if(t == "advance_time"){
// This is bad regardless of strictness, because visual changes may have occurred which won't get redrawn/reprinted
throw std::string { "Replay system internal error! advance_time() was supposed to be called by the last action, but wasn't: " } + _last_action_type;