Merge pull request #551 from NQNStudios:keys
Refactor Debug Keys * Collect debug keys into a central location so that the debug help dialog can automatically list every defined debug key. * Add buttons so that debug actions can be taken directly from the debug help dialog. * Add new debug keys to immediately fight an encounter from the current outdoor section.
This commit is contained in:
@@ -3,6 +3,6 @@
|
|||||||
<dialog defbtn='okay'>
|
<dialog defbtn='okay'>
|
||||||
<field name="number" type='int' top='33' left='90' width='75' height='16'/>
|
<field name="number" type='int' top='33' left='90' width='75' height='16'/>
|
||||||
<pict type='dlog' num='2' top='8' left='8'/>
|
<pict type='dlog' num='2' top='8' left='8'/>
|
||||||
<text name='prompt' size='large' top='8' left='49' width='163' height='16'>How many?</text>
|
<text name='prompt' size='large' top='8' left='49' width='193' height='16'>How many?</text>
|
||||||
<button name='okay' type='regular' top='63' left='141'>OK</button>
|
<button name='okay' type='regular' top='63' left='141'>OK</button>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
@@ -3,31 +3,41 @@
|
|||||||
<dialog defbtn='okay'>
|
<dialog defbtn='okay'>
|
||||||
<pict type='dlog' num='16' top='8' left='8'/>
|
<pict type='dlog' num='16' top='8' left='8'/>
|
||||||
<text top='8' left='50' width='400' height='16'>DEBUG MODE HELP</text>
|
<text top='8' left='50' width='400' height='16'>DEBUG MODE HELP</text>
|
||||||
<text top='22' left='50' width='400' height='250'>
|
<text top='22' left='50' width='400' height='50'>
|
||||||
Debug mode is intended to aid you in testing your scenario.
|
Debug mode is intended to aid you in testing your scenario.
|
||||||
While in debug mode, monsters don't move in combat and are killed in one hit.
|
While in debug mode, monsters don't move in combat and are killed in one hit.
|
||||||
In addition, you have access to a lot of additional hotkeys.<br/><br/>
|
In addition, you have access to a lot of additional hotkeys.<br/><br/>
|
||||||
Debug hot keys<br/>
|
Debug hot keys:<br/>
|
||||||
B - Leave town<br/>
|
|
||||||
C - Get cleaned up (lose negative status effects)<br/>
|
|
||||||
D - Toggle Debug mode<br/>
|
|
||||||
E - Stealth, Detect Life, Firewalk<br/>
|
|
||||||
F - Flight<br/>
|
|
||||||
G - Toggle Ghost mode (letting you pass through walls)<br/>
|
|
||||||
H - Heal<br/>
|
|
||||||
K - Kill everything<br/>
|
|
||||||
N - End Scenario<br/>
|
|
||||||
O - Location<br/>
|
|
||||||
Q - Magic map<br/>
|
|
||||||
R - Return to Start<br/>
|
|
||||||
S - Set stuff done flags<br/>
|
|
||||||
T - Enter Town<br/>
|
|
||||||
W - Refresh jobs/shops<br/>
|
|
||||||
= - Heal, increase magic skills<br/>
|
|
||||||
< - Make one day pass<br/>
|
|
||||||
> - Reset towns (excludes the one you're in, if any)<br/>
|
|
||||||
! - Toggle Special Node Step-through Mode<br/>
|
|
||||||
/ - Bring up this list<br/>
|
|
||||||
</text>
|
</text>
|
||||||
<button name='okay' type='regular' top='280' left='387'>OK</button>
|
<button name='btn1' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='3'></button>
|
||||||
|
<button name='btn2' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn3' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn4' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn5' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn6' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn7' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn8' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn9' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn10' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn11' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn12' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn13' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn14' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn15' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn16' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn17' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn18' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn19' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn20' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn21' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn22' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn23' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn24' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn25' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn26' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn27' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn28' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn29' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='btn30' type='tiny' relative='pos-in pos' rel-anchor='prev' left='0' top='1'></button>
|
||||||
|
<button name='okay' type='regular' top='400' left='387'>OK</button>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
@@ -12,10 +12,10 @@
|
|||||||
<text top='41' left='68' width='111' height='14'>World height:</text>
|
<text top='41' left='68' width='111' height='14'>World height:</text>
|
||||||
<text name='height' top='41' left='186' width='37'/>
|
<text name='height' top='41' left='186' width='37'/>
|
||||||
<text name='y' framed='true' top='88' left='142' width='75' height='16'/>
|
<text name='y' framed='true' top='88' left='142' width='75' height='16'/>
|
||||||
<button name='xminus' type='small' top='59' left='77'>-</button>
|
<button name='xminus' type='small' top='59' left='77' def-key='left'>-</button>
|
||||||
<button name='xplus' type='small' top='59' left='106'>+</button>
|
<button name='xplus' type='small' top='59' left='106' def-key='right'>+</button>
|
||||||
<button name='yminus' type='small' top='84' left='77'>-</button>
|
<button name='yminus' type='small' top='84' left='77' def-key='up'>-</button>
|
||||||
<button name='yplus' type='small' top='84' left='106'>+</button>
|
<button name='yplus' type='small' top='84' left='106' def-key='down'>+</button>
|
||||||
<text name='title' framed='true' top='111' left='142' width='150' height='16'/>
|
<text name='title' framed='true' top='111' left='142' width='150' height='16'/>
|
||||||
<button name='choose' type='regular' top='111' left='66'>Choose</button>
|
<button name='choose' type='regular' top='111' left='66'>Choose</button>
|
||||||
</dialog>
|
</dialog>
|
||||||
|
@@ -5,7 +5,9 @@
|
|||||||
* Created by Celtic Minstrel on 11/05/09.
|
* Created by Celtic Minstrel on 11/05/09.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
#include <sstream>
|
||||||
|
#include <codecvt>
|
||||||
|
#include <locale>
|
||||||
#include "keycodes.hpp"
|
#include "keycodes.hpp"
|
||||||
//#include <sstream>
|
//#include <sstream>
|
||||||
//#include "dialog.hpp"
|
//#include "dialog.hpp"
|
||||||
@@ -18,6 +20,54 @@
|
|||||||
//#include "cursors.hpp"
|
//#include "cursors.hpp"
|
||||||
#include "keymods.hpp"
|
#include "keymods.hpp"
|
||||||
|
|
||||||
|
// Windows won't compile if this conversion is not explicit.
|
||||||
|
// (Wildly enough, it claims that char->wchar_t is a NARROWING conversion).
|
||||||
|
static wchar_t w(char ch) {
|
||||||
|
#ifdef SFML_SYSTEM_WINDOWS
|
||||||
|
std::ostringstream sstr;
|
||||||
|
sstr << ch;
|
||||||
|
std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
|
||||||
|
std::wstring wide_str = converter.from_bytes(sstr.str());
|
||||||
|
return wide_str[0];
|
||||||
|
#else
|
||||||
|
return ch;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: This only supports a few characters including the ones
|
||||||
|
// that are currently used for debug key shortcuts!
|
||||||
|
// It is also very hard-coded to the key layout on my laptop (which may only be standard in the US!)
|
||||||
|
cKey charToKey(char ch) {
|
||||||
|
if(ch >= 'a' && ch <= 'z'){
|
||||||
|
return {false, w(ch)};
|
||||||
|
}else if(ch >= 'A' && ch <= 'Z'){
|
||||||
|
return {false, w(tolower(ch)), mod_shift};
|
||||||
|
}
|
||||||
|
switch(ch){
|
||||||
|
case '=': case '/':
|
||||||
|
return {false, w(ch)};
|
||||||
|
case '<':
|
||||||
|
return {false, w(','), mod_shift};
|
||||||
|
case '>':
|
||||||
|
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};
|
||||||
|
}
|
||||||
|
throw "Tried to convert unsupported char to cKey!";
|
||||||
|
}
|
||||||
|
|
||||||
eKeyMod operator + (eKeyMod lhs, eKeyMod rhs){
|
eKeyMod operator + (eKeyMod lhs, eKeyMod rhs){
|
||||||
if(lhs == rhs) return lhs;
|
if(lhs == rhs) return lhs;
|
||||||
else if(lhs == mod_none) return rhs;
|
else if(lhs == mod_none) return rhs;
|
||||||
|
@@ -57,6 +57,8 @@ struct cKey {
|
|||||||
eKeyMod mod;
|
eKeyMod mod;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
cKey charToKey(char ch);
|
||||||
|
|
||||||
/// Combine two key modifiers.
|
/// Combine two key modifiers.
|
||||||
/// @param lhs @param rhs
|
/// @param lhs @param rhs
|
||||||
/// @return lhs + rhs
|
/// @return lhs + rhs
|
||||||
|
@@ -27,6 +27,7 @@
|
|||||||
#include "boe.ui.hpp"
|
#include "boe.ui.hpp"
|
||||||
#include "mathutil.hpp"
|
#include "mathutil.hpp"
|
||||||
#include "fileio/fileio.hpp"
|
#include "fileio/fileio.hpp"
|
||||||
|
#include "fileio/resmgr/res_dialog.hpp"
|
||||||
#include "dialogxml/dialogs/choicedlog.hpp"
|
#include "dialogxml/dialogs/choicedlog.hpp"
|
||||||
#include "dialogxml/dialogs/dialog.hpp"
|
#include "dialogxml/dialogs/dialog.hpp"
|
||||||
#include "dialogxml/widgets/scrollbar.hpp"
|
#include "dialogxml/widgets/scrollbar.hpp"
|
||||||
@@ -1887,9 +1888,24 @@ void handle_menu_spell(eSpell spell_picked) {
|
|||||||
advance_time(did_something, need_redraw, need_reprint);
|
advance_time(did_something, need_redraw, need_reprint);
|
||||||
}
|
}
|
||||||
|
|
||||||
void initiate_outdoor_combat(short i) {
|
static void set_up_combat() {
|
||||||
location to_place;
|
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();
|
draw_terrain();
|
||||||
|
|
||||||
// Is combat too easy?
|
// Is combat too easy?
|
||||||
@@ -1900,24 +1916,11 @@ void initiate_outdoor_combat(short i) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delay((long) 100,&dummy);
|
|
||||||
|
|
||||||
start_outdoor_combat(univ.party.out_c[i], univ.party.out_loc,count_walls(univ.party.out_loc));
|
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;
|
univ.party.out_c[i].exists = false;
|
||||||
|
|
||||||
for(cPlayer& pc : univ.party)
|
set_up_combat();
|
||||||
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 show_inventory() {
|
void show_inventory() {
|
||||||
@@ -1955,6 +1958,37 @@ void toggle_debug_mode() {
|
|||||||
print_buf();
|
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() {
|
void debug_give_item() {
|
||||||
if(recording){
|
if(recording){
|
||||||
record_action("debug_give_item", "");
|
record_action("debug_give_item", "");
|
||||||
@@ -2265,6 +2299,111 @@ void easter_egg(int idx) {
|
|||||||
print_buf();
|
print_buf();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::map<char,key_action_t> debug_actions;
|
||||||
|
std::vector<std::vector<char>> debug_actions_help_order;
|
||||||
|
|
||||||
|
void add_debug_action(std::vector<char> keys, std::string name, void (*action)()) {
|
||||||
|
key_action_t shortcut = {keys, name, action};
|
||||||
|
for(char ch: keys){
|
||||||
|
debug_actions[ch] = shortcut;
|
||||||
|
}
|
||||||
|
debug_actions_help_order.push_back(keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
void show_debug_help() {
|
||||||
|
if(recording){
|
||||||
|
record_action("show_debug_help", "");
|
||||||
|
}
|
||||||
|
cDialog debug_panel(*ResMgr::dialogs.get("help-debug"));
|
||||||
|
int idx;
|
||||||
|
for(idx = 0; idx < debug_actions_help_order.size(); ++idx){
|
||||||
|
std::ostringstream btn_name;
|
||||||
|
btn_name << "btn" << (idx+1);
|
||||||
|
cControl& button = debug_panel[btn_name.str()];
|
||||||
|
key_action_t action = debug_actions[debug_actions_help_order[idx][0]];
|
||||||
|
std::ostringstream btn_text;
|
||||||
|
btn_text << action.keys[0];
|
||||||
|
for(int key_idx = 1; key_idx < action.keys.size(); ++key_idx){
|
||||||
|
btn_text << ", " << action.keys[key_idx];
|
||||||
|
}
|
||||||
|
btn_text << " - " << action.name;
|
||||||
|
button.setText(btn_text.str());
|
||||||
|
// TODO it's unfortunate that the button can only have one key if actions might have
|
||||||
|
// more than one
|
||||||
|
button.attachKey(charToKey(action.keys[0]));
|
||||||
|
// Don't recursively open the panel
|
||||||
|
if(action.action != &show_debug_help){
|
||||||
|
button.attachClickHandler([action](cDialog& me, std::string, eKeyMod) -> bool {
|
||||||
|
me.toast(false);
|
||||||
|
action.action();
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(; idx < 30; ++idx){
|
||||||
|
std::ostringstream btn_name;
|
||||||
|
btn_name << "btn" << (idx+1);
|
||||||
|
cControl& button = debug_panel[btn_name.str()];
|
||||||
|
button.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
debug_panel.attachClickHandlers([](cDialog& me, std::string, eKeyMod) -> bool {
|
||||||
|
me.toast(false);
|
||||||
|
return true;
|
||||||
|
}, {"okay"});
|
||||||
|
|
||||||
|
debug_panel.run();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Non-comprehensive list of unused keys:
|
||||||
|
// 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);
|
||||||
|
add_debug_action({'D'}, "Toggle Debug mode", toggle_debug_mode);
|
||||||
|
add_debug_action({'E'}, "Stealth, Detect Life, Firewalk", debug_stealth_detect_life_firewalk);
|
||||||
|
add_debug_action({'F'}, "Flight", debug_fly);
|
||||||
|
add_debug_action({'G'}, "Toggle Ghost mode (letting you pass through walls)", debug_ghost_mode);
|
||||||
|
add_debug_action({'H'}, "Heal", debug_heal);
|
||||||
|
// This one was missing from the old help dialog:
|
||||||
|
add_debug_action({'I'}, "Give item", debug_give_item);
|
||||||
|
add_debug_action({'K'}, "Kill everything", debug_kill);
|
||||||
|
add_debug_action({'N'}, "End scenario", []() -> void {handle_victory(true);});
|
||||||
|
add_debug_action({'O'}, "Print your location", debug_print_location);
|
||||||
|
add_debug_action({'Q'}, "Magic map", debug_magic_map);
|
||||||
|
add_debug_action({'R'}, "Return to start", debug_return_to_start);
|
||||||
|
add_debug_action({'S'}, "Set stuff done flags", []() -> void {
|
||||||
|
// edit_stuff_done() is used in the character editor which
|
||||||
|
// doesn't have replays, so its replay action is recorded
|
||||||
|
// external to the function definition unlike most actions.
|
||||||
|
if(recording){
|
||||||
|
record_action("edit_stuff_done", "");
|
||||||
|
}
|
||||||
|
edit_stuff_done();
|
||||||
|
});
|
||||||
|
add_debug_action({'T'}, "Enter town", debug_enter_town);
|
||||||
|
add_debug_action({'W'}, "Refresh jobs/shops", debug_refresh_stores);
|
||||||
|
add_debug_action({'='}, "Heal, increase magic skills", debug_heal_plus_extra);
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Later we might want to know whether the key is used or not
|
||||||
|
bool handle_debug_key(char key) {
|
||||||
|
if(!univ.debug_mode)
|
||||||
|
return false;
|
||||||
|
if(debug_actions.find(key) != debug_actions.end()){
|
||||||
|
debug_actions[key].action();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool handle_keystroke(const sf::Event& event, cFramerateLimiter& fps_limiter){
|
bool handle_keystroke(const sf::Event& event, cFramerateLimiter& fps_limiter){
|
||||||
bool are_done = false;
|
bool are_done = false;
|
||||||
location pass_point; // TODO: This isn't needed
|
location pass_point; // TODO: This isn't needed
|
||||||
@@ -2443,6 +2582,11 @@ bool handle_keystroke(const sf::Event& event, cFramerateLimiter& fps_limiter){
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
|
// In debug mode, override basic help menus with a debug mode cheat-sheet
|
||||||
|
if(univ.debug_mode){
|
||||||
|
show_debug_help();
|
||||||
|
break;
|
||||||
|
}
|
||||||
if(overall_mode == MODE_SHOPPING) {
|
if(overall_mode == MODE_SHOPPING) {
|
||||||
give_help_and_record(226,27);
|
give_help_and_record(226,27);
|
||||||
break;
|
break;
|
||||||
@@ -2488,116 +2632,15 @@ bool handle_keystroke(const sf::Event& event, cFramerateLimiter& fps_limiter){
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
case 'D':
|
case 'D':
|
||||||
toggle_debug_mode();
|
toggle_debug_mode();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// 'z', Really? 'i' is not used
|
||||||
case 'z':
|
case 'z':
|
||||||
show_inventory();
|
show_inventory();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '=':
|
|
||||||
if(!univ.debug_mode) break;
|
|
||||||
debug_heal_plus_extra();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'B':
|
|
||||||
if(!univ.debug_mode) break;
|
|
||||||
debug_leave_town();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'C':
|
|
||||||
if(!univ.debug_mode) break;
|
|
||||||
debug_clean_up();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'E':
|
|
||||||
if(!univ.debug_mode) break;
|
|
||||||
debug_stealth_detect_life_firewalk();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'F':
|
|
||||||
if(!univ.debug_mode) break;
|
|
||||||
debug_fly();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'G':
|
|
||||||
if(!univ.debug_mode) break;
|
|
||||||
debug_ghost_mode();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'H':
|
|
||||||
if(!univ.debug_mode) break;
|
|
||||||
debug_heal();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'K':
|
|
||||||
if(!univ.debug_mode) break;
|
|
||||||
debug_kill();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'N':
|
|
||||||
if(!univ.debug_mode) break;
|
|
||||||
handle_victory(true);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'O':
|
|
||||||
if(!univ.debug_mode) break;
|
|
||||||
debug_print_location();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'I':
|
|
||||||
if(!univ.debug_mode) break;
|
|
||||||
debug_give_item();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'Q':
|
|
||||||
if(!univ.debug_mode) break;
|
|
||||||
debug_magic_map();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'R':
|
|
||||||
if(!univ.debug_mode) break;
|
|
||||||
debug_return_to_start();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'S':
|
|
||||||
if(!univ.debug_mode) break;
|
|
||||||
// edit_stuff_done() is used in the character editor which
|
|
||||||
// doesn't have replays, so its replay action is recorded
|
|
||||||
// external to the function definition unlike most actions.
|
|
||||||
if(recording){
|
|
||||||
record_action("edit_stuff_done", "");
|
|
||||||
}
|
|
||||||
edit_stuff_done();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'T':
|
|
||||||
if(!univ.debug_mode) break;
|
|
||||||
debug_enter_town();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'W':
|
|
||||||
if(!univ.debug_mode) break;
|
|
||||||
debug_refresh_stores();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case '<':
|
|
||||||
if(!univ.debug_mode) break;
|
|
||||||
debug_increase_age();
|
|
||||||
break;
|
|
||||||
case '>':
|
|
||||||
if(!univ.debug_mode) break;
|
|
||||||
debug_towns_forget();
|
|
||||||
break;
|
|
||||||
case '!':
|
|
||||||
if(!univ.debug_mode) break;
|
|
||||||
debug_step_through();
|
|
||||||
break;
|
|
||||||
case '/':
|
|
||||||
if(!univ.debug_mode) break;
|
|
||||||
show_dialog_action("help-debug");
|
|
||||||
break;
|
|
||||||
case 'a': // Show automap
|
case 'a': // Show automap
|
||||||
display_map();
|
display_map();
|
||||||
break;
|
break;
|
||||||
@@ -2704,6 +2747,11 @@ bool handle_keystroke(const sf::Event& event, cFramerateLimiter& fps_limiter){
|
|||||||
advance_time(did_something, need_redraw, need_reprint);
|
advance_time(did_something, need_redraw, need_reprint);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// Debug action keyboard shortcuts:
|
||||||
|
default:
|
||||||
|
handle_debug_key(chr);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
spell_forced = false;
|
spell_forced = false;
|
||||||
return are_done;
|
return are_done;
|
||||||
|
@@ -2,11 +2,18 @@
|
|||||||
#ifndef BOE_GAME_ACTIONS_H
|
#ifndef BOE_GAME_ACTIONS_H
|
||||||
#define BOE_GAME_ACTIONS_H
|
#define BOE_GAME_ACTIONS_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
#include <SFML/Window/Event.hpp>
|
#include <SFML/Window/Event.hpp>
|
||||||
#include "location.hpp"
|
#include "location.hpp"
|
||||||
#include "dialogxml/keycodes.hpp"
|
#include "dialogxml/keycodes.hpp"
|
||||||
#include "tools/framerate_limiter.hpp"
|
#include "tools/framerate_limiter.hpp"
|
||||||
|
|
||||||
|
struct key_action_t {
|
||||||
|
std::vector<char> keys;
|
||||||
|
std::string name;
|
||||||
|
void (*action)();
|
||||||
|
};
|
||||||
|
|
||||||
void init_screen_locs();
|
void init_screen_locs();
|
||||||
bool prime_time();
|
bool prime_time();
|
||||||
bool handle_action(const sf::Event& event, cFramerateLimiter& fps_limiter);
|
bool handle_action(const sf::Event& event, cFramerateLimiter& fps_limiter);
|
||||||
@@ -75,6 +82,9 @@ void handle_use_space_select(bool& need_reprint);
|
|||||||
void handle_use_space(location destination, bool& did_something, bool& need_redraw);
|
void handle_use_space(location destination, bool& did_something, bool& need_redraw);
|
||||||
void show_inventory();
|
void show_inventory();
|
||||||
void toggle_debug_mode();
|
void toggle_debug_mode();
|
||||||
|
void init_debug_actions();
|
||||||
|
void show_debug_help();
|
||||||
|
void debug_fight_encounter(bool wandering);
|
||||||
void debug_give_item();
|
void debug_give_item();
|
||||||
void debug_print_location();
|
void debug_print_location();
|
||||||
void debug_step_through();
|
void debug_step_through();
|
||||||
|
@@ -251,11 +251,7 @@ effect_pat_type field[8] = {
|
|||||||
|
|
||||||
bool center_on_monst;
|
bool center_on_monst;
|
||||||
|
|
||||||
|
void start_outdoor_combat(cOutdoors::cWandering encounter,location where,short num_walls) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void start_outdoor_combat(cOutdoors::cCreature encounter,location where,short num_walls) {
|
|
||||||
short how_many,num_tries = 0;
|
short how_many,num_tries = 0;
|
||||||
short low[10] = {15,7,4,3,2,1,1,7,2,1};
|
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};
|
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]);
|
nums[i] = get_ran(1,low[i],high[i]);
|
||||||
for(short i = 0; i < 3; i++)
|
for(short i = 0; i < 3; i++)
|
||||||
nums[i + 7] = get_ran(1,low[i + 7],high[i + 7]);
|
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();
|
print_buf();
|
||||||
play_sound(23);
|
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++) {
|
for(short i = 0; i < 7; i++) {
|
||||||
how_many = nums[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++)
|
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++) {
|
for(short i = 0; i < 3; i++) {
|
||||||
how_many = nums[i + 7];
|
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++)
|
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
|
// 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) {
|
bool pc_combat_move(location destination) {
|
||||||
std::string create_line;
|
std::string create_line;
|
||||||
short s1;
|
short s1;
|
||||||
|
@@ -9,6 +9,9 @@
|
|||||||
#include "boe.global.hpp"
|
#include "boe.global.hpp"
|
||||||
#include "spell.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);
|
void start_outdoor_combat(cOutdoors::cCreature encounter,location where,short num_walls);
|
||||||
bool pc_combat_move(location destination);
|
bool pc_combat_move(location destination);
|
||||||
void char_parry();
|
void char_parry();
|
||||||
|
@@ -873,6 +873,10 @@ static void replay_action(Element& action) {
|
|||||||
cancel_item_target(did_something, need_redraw, need_reprint);
|
cancel_item_target(did_something, need_redraw, need_reprint);
|
||||||
}else if(t == "easter_egg"){
|
}else if(t == "easter_egg"){
|
||||||
easter_egg(boost::lexical_cast<int>(action.GetText()));
|
easter_egg(boost::lexical_cast<int>(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"){
|
}else if(t == "advance_time"){
|
||||||
// This is bad regardless of strictness, because visual changes may have occurred which won't get redrawn/reprinted
|
// 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;
|
throw std::string { "Replay system internal error! advance_time() was supposed to be called by the last action, but wasn't: " } + _last_action_type;
|
||||||
@@ -942,6 +946,7 @@ void init_boe(int argc, char* argv[]) {
|
|||||||
cUniverse::print_result = iLiving::print_result = add_string_to_buf;
|
cUniverse::print_result = iLiving::print_result = add_string_to_buf;
|
||||||
cPlayer::give_help = give_help;
|
cPlayer::give_help = give_help;
|
||||||
init_fileio();
|
init_fileio();
|
||||||
|
init_debug_actions();
|
||||||
init_spell_menus();
|
init_spell_menus();
|
||||||
init_mini_map();
|
init_mini_map();
|
||||||
redraw_screen(REFRESH_NONE);
|
redraw_screen(REFRESH_NONE);
|
||||||
|
@@ -41,9 +41,12 @@ using bitmap = std::array<std::bitset<y>, x>;
|
|||||||
class cOutdoors : public cArea {
|
class cOutdoors : public cArea {
|
||||||
cScenario* scenario;
|
cScenario* scenario;
|
||||||
public:
|
public:
|
||||||
|
// Definition of an outdoor combat encounter
|
||||||
class cWandering { // formerly out_wandering_type
|
class cWandering { // formerly out_wandering_type
|
||||||
public:
|
public:
|
||||||
|
// max 7 types of monster per encounter
|
||||||
std::array<mon_num_t,7> monst;
|
std::array<mon_num_t,7> monst;
|
||||||
|
// max 3 types of friendly npc per encounter
|
||||||
std::array<mon_num_t,3> friendly;
|
std::array<mon_num_t,3> friendly;
|
||||||
short spec_on_meet,spec_on_win,spec_on_flee;
|
short spec_on_meet,spec_on_win,spec_on_flee;
|
||||||
short end_spec1,end_spec2;
|
short end_spec1,end_spec2;
|
||||||
@@ -55,6 +58,7 @@ public:
|
|||||||
void readFrom(const cTagFile_Page& page);
|
void readFrom(const cTagFile_Page& page);
|
||||||
cWandering();
|
cWandering();
|
||||||
};
|
};
|
||||||
|
// Instantiation of an outdoor wandering monster on the map
|
||||||
class cCreature { // formerly outdoor_creature_type
|
class cCreature { // formerly outdoor_creature_type
|
||||||
public:
|
public:
|
||||||
bool exists = false;
|
bool exists = false;
|
||||||
|
Reference in New Issue
Block a user