Introduce two dialogs for debugging - a Set SDF dialog and a Debug Help dialog
- sd_legit() moved into cParty class
This commit is contained in:
32
rsrc/dialogs/help-debug.xml
Normal file
32
rsrc/dialogs/help-debug.xml
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||||
<?xml-stylesheet href="dialog.xsl" type="text/xsl"?>
|
||||
<dialog defbtn='okay'>
|
||||
<pict type='dlog' num='16' top='8' left='8'/>
|
||||
<text top='8' left='50' width='400' height='16'>DEBUG MODE HELP</text>
|
||||
<text top='22' left='50' width='400' height='250'>
|
||||
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.
|
||||
In addition, you have access to a lot of additional hotkeys.<br/><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/>
|
||||
/ - Bring up this list<br/>
|
||||
</text>
|
||||
<button name='okay' type='regular' top='280' left='387'>OK</button>
|
||||
</dialog>
|
19
rsrc/dialogs/set-sdf.xml
Normal file
19
rsrc/dialogs/set-sdf.xml
Normal file
@@ -0,0 +1,19 @@
|
||||
<?xml version='1.0' encoding='UTF-8' standalone='no'?>
|
||||
<?xml-stylesheet href="dialog.xsl" type="text/xsl"?>
|
||||
<dialog defbtn='okay'>
|
||||
<pict type='dlog' num='7' top='8' left='8'/>
|
||||
<text size='large' top='8' left='50' width='200' height='17'>Edit Stuff Done</text>
|
||||
<text top='30' left='50' width='200' height='50'>
|
||||
Here you can edit all the game data that lets the scenario know what you've done.
|
||||
You can very easily mess up your game by doing this, so be sure you know what you're doing first.
|
||||
</text>
|
||||
<text top='105' left='8' width='100' height='16'>SDF Part A:</text>
|
||||
<field name='x' top='103' left='110' width='80' height='16'/>
|
||||
<text top='125' left='8' width='100' height='16'>SDF Part B:</text>
|
||||
<field name='y' top='123' left='110' width='80' height='16'/>
|
||||
<text top='145' left='8' width='100' height='16'>Value:</text>
|
||||
<field name='val' top='143' left='110' width='80' height='16'/>
|
||||
<text name='feedback' top='165' left='8' width='230' height='16'/>
|
||||
<button name='exit' type='regular' top='185' left='187'>Exit</button>
|
||||
<button name='set' type='regular' top='185' left='122'>Set</button>
|
||||
</dialog>
|
@@ -124,6 +124,9 @@ std::queue<pending_special_type> special_queue;
|
||||
bool end_scenario = false;
|
||||
bool current_bash_is_bash = false;
|
||||
|
||||
// This is defined in pc.editors.cpp since the PC editor also uses it
|
||||
extern void edit_stuff_done();
|
||||
|
||||
void init_screen_locs() {
|
||||
short i,j,k,l;
|
||||
rectangle startup_base = {279,5,327,306};
|
||||
@@ -1944,27 +1947,14 @@ bool handle_keystroke(sf::Event& event){
|
||||
print_buf();
|
||||
break;
|
||||
|
||||
case 'S': // TODO: Create a dedicated dialog for this.
|
||||
case 'S':
|
||||
if(!in_scen_debug) break;
|
||||
i = get_num_response(0,299,"Enter SDF Part A");
|
||||
if(i >= 0 && i < 300){
|
||||
j = get_num_response(0,49,"Enter SDF Part B");
|
||||
if(j >= 0 && j < 50){
|
||||
int x = get_num_response(-1,255,"Enter SDF Value or -1 to print");
|
||||
if(x < 256 && x >= 0)
|
||||
PSD[i][j] = x;
|
||||
else if(x == -1){
|
||||
sout << "SDF(" << i << ',' << j << ") = " << PSD[i][j];
|
||||
add_string_to_buf(sout.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
edit_stuff_done();
|
||||
break;
|
||||
|
||||
case 'T':
|
||||
if(!in_scen_debug) break;
|
||||
short find_direction_from;
|
||||
sout << "Enter Town Number (between 0 and " << univ.scenario.towns.size() - 1 << ')';
|
||||
i = get_num_response(0, univ.scenario.towns.size() - 1, "Enter Town Number");
|
||||
if(i >= 0 && i < univ.scenario.towns.size()) {
|
||||
if(univ.party.direction == 0) find_direction_from = 2;
|
||||
@@ -2000,28 +1990,7 @@ bool handle_keystroke(sf::Event& event){
|
||||
break;
|
||||
case '/':
|
||||
if(!in_scen_debug) break;
|
||||
// TODO: Make a dialog for this instead of flooding the transcript
|
||||
ASB("Debug hot keys");
|
||||
ASB(" B Leave town");
|
||||
ASB(" C Get cleaned up");
|
||||
ASB(" D Toggle Debug mode");
|
||||
ASB(" E Stealth, Detect Life, Firewalk");
|
||||
ASB(" F Flight");
|
||||
ASB(" G Ghost");
|
||||
ASB(" H Heal");
|
||||
ASB(" K Kill things");
|
||||
ASB(" N End Scenario");
|
||||
ASB(" O Location");
|
||||
ASB(" Q Magic map");
|
||||
ASB(" R Return to Start");
|
||||
ASB(" S Set a SDF");
|
||||
ASB(" T Enter Town");
|
||||
ASB(" W Refresh jobs/shops");
|
||||
ASB(" = Heal, increase magic skills");
|
||||
ASB(" < Make one day pass");
|
||||
ASB(" > Towns forgive you");
|
||||
ASB(" / Bring up this list");
|
||||
print_buf();
|
||||
cChoiceDlog("help-debug").show();
|
||||
break;
|
||||
case 'a':
|
||||
if(overall_mode < MODE_TALK_TOWN) {
|
||||
|
@@ -751,7 +751,7 @@ void handle_talk_event(location p) {
|
||||
strnum2 = 0;
|
||||
break;
|
||||
case eTalkNode::BUY_SDF:
|
||||
if((sd_legit(b,c)) && (PSD[b][c] == d)) {
|
||||
if((univ.party.sd_legit(b,c)) && (PSD[b][c] == d)) {
|
||||
save_talk_str1 = "You've already learned that.";
|
||||
strnum1 = -1;
|
||||
}
|
||||
@@ -762,7 +762,7 @@ void handle_talk_event(location p) {
|
||||
else {
|
||||
univ.party.gold -= a;
|
||||
put_pc_screen();
|
||||
if(sd_legit(b,c))
|
||||
if(univ.party.sd_legit(b,c))
|
||||
PSD[b][c] = d;
|
||||
else giveError("Invalid Stuff Done flag called in conversation.");
|
||||
}
|
||||
@@ -878,7 +878,7 @@ void handle_talk_event(location p) {
|
||||
// TODO: Any reason not to call something like kill_monst?
|
||||
univ.town.monst[store_m_num].active = 0;
|
||||
// Special killing effects
|
||||
if(sd_legit(univ.town.monst[store_m_num].spec1,univ.town.monst[store_m_num].spec2))
|
||||
if(univ.party.sd_legit(univ.town.monst[store_m_num].spec1,univ.town.monst[store_m_num].spec2))
|
||||
PSD[univ.town.monst[store_m_num].spec1][univ.town.monst[store_m_num].spec2] = 1;
|
||||
}
|
||||
talk_end_forced = true;
|
||||
|
@@ -713,11 +713,3 @@ void pause(short length) {
|
||||
if(give_delays)
|
||||
sf::sleep(time_in_ticks(len));
|
||||
}
|
||||
|
||||
// TODO: I think this should be in a better place, maybe in cParty?
|
||||
// stuff done legit, i.e. flags are within proper ranges for stuff done flag
|
||||
bool sd_legit(short a, short b) {
|
||||
if((minmax(0,299,a) == a) && (minmax(0,9,b) == b))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
@@ -12,4 +12,3 @@ void set_up_apple_events();
|
||||
void move_sound(ter_num_t ter,short step);
|
||||
void incidental_noises(bool on_surface);
|
||||
void pause(short length);
|
||||
bool sd_legit(short a, short b);
|
||||
|
@@ -85,7 +85,7 @@ void place_outd_wand_monst(location where,cOutdoors::cWandering group,short forc
|
||||
|
||||
while(i < 10) {
|
||||
if(!univ.party.out_c[i].exists || ((i == 9) && (forced > 0))) {
|
||||
if((sd_legit(group.end_spec1,group.end_spec2)) && (PSD[group.end_spec1][group.end_spec2] > 0))
|
||||
if((univ.party.sd_legit(group.end_spec1,group.end_spec2)) && (PSD[group.end_spec1][group.end_spec2] > 0))
|
||||
return;
|
||||
univ.party.out_c[i].exists = true;
|
||||
univ.party.out_c[i].direction = 0;
|
||||
|
@@ -1524,7 +1524,7 @@ void kill_monst(cCreature *which_m,short who_killed,eMainStatus type) {
|
||||
}
|
||||
|
||||
// Special killing effects
|
||||
if(sd_legit(which_m->spec1,which_m->spec2))
|
||||
if(univ.party.sd_legit(which_m->spec1,which_m->spec2))
|
||||
PSD[which_m->spec1][which_m->spec2] = 1;
|
||||
|
||||
if(which_m->special_on_kill >= 0)
|
||||
@@ -2111,7 +2111,7 @@ void general_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
else for(i = 0; i < 10; i++) PSD[spec.sd1][i] = spec.ex1a;
|
||||
break;
|
||||
case eSpecType::COPY_SDF:
|
||||
if(!sd_legit(spec.sd1,spec.sd2) || !sd_legit(spec.ex1a,spec.ex1b))
|
||||
if(!univ.party.sd_legit(spec.sd1,spec.sd2) || !univ.party.sd_legit(spec.ex1a,spec.ex1b))
|
||||
giveError("Stuff Done flag out of range.");
|
||||
else PSD[spec.sd1][spec.sd2] = PSD[spec.ex1a][spec.ex1b];
|
||||
break;
|
||||
@@ -2146,7 +2146,7 @@ void general_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
}
|
||||
break;
|
||||
case eSpecType::SET_CAMP_FLAG:
|
||||
if(!sd_legit(spec.sd1,spec.sd2))
|
||||
if(!univ.party.sd_legit(spec.sd1,spec.sd2))
|
||||
giveError("Stuff Done flag out of range (x - 0..299, y - 0..49).");
|
||||
else {
|
||||
set_campaign_flag(spec.sd1,spec.sd2,spec.ex1a,spec.ex1b,spec.m1,spec.ex2a);
|
||||
@@ -2345,7 +2345,7 @@ void oneshot_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
|
||||
spec = cur_node;
|
||||
*next_spec = cur_node.jumpto;
|
||||
if((sd_legit(spec.sd1,spec.sd2)) && (PSD[spec.sd1][spec.sd2] == 250)) {
|
||||
if((univ.party.sd_legit(spec.sd1,spec.sd2)) && (PSD[spec.sd1][spec.sd2] == 250)) {
|
||||
*next_spec = -1;
|
||||
return;
|
||||
}
|
||||
@@ -2492,7 +2492,7 @@ void oneshot_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
if(check_mess) {
|
||||
handle_message(which_mode,cur_spec_type,cur_node.m1,cur_node.m2,a,b);
|
||||
}
|
||||
if((set_sd) && (sd_legit(spec.sd1,spec.sd2)))
|
||||
if((set_sd) && (univ.party.sd_legit(spec.sd1,spec.sd2)))
|
||||
PSD[spec.sd1][spec.sd2] = 250;
|
||||
|
||||
}
|
||||
@@ -2963,7 +2963,7 @@ void ifthen_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
|
||||
switch(cur_node.type) {
|
||||
case eSpecType::IF_SDF:
|
||||
if(sd_legit(spec.sd1,spec.sd2)) {
|
||||
if(univ.party.sd_legit(spec.sd1,spec.sd2)) {
|
||||
if((spec.ex1a >= 0) && (PSD[spec.sd1][spec.sd2] >= spec.ex1a))
|
||||
*next_spec = spec.ex1b;
|
||||
else if((spec.ex2a >= 0) && (PSD[spec.sd1][spec.sd2] < spec.ex2a))
|
||||
@@ -2986,7 +2986,7 @@ void ifthen_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
*next_spec = spec.ex1b;
|
||||
break;
|
||||
case eSpecType::IF_SDF_COMPARE:
|
||||
if((sd_legit(spec.sd1,spec.sd2)) && (sd_legit(spec.ex1a,spec.ex1b))) {
|
||||
if((univ.party.sd_legit(spec.sd1,spec.sd2)) && (univ.party.sd_legit(spec.ex1a,spec.ex1b))) {
|
||||
if(PSD[spec.ex1a][spec.ex1b] < PSD[spec.sd1][spec.sd2])
|
||||
*next_spec = spec.ex2b;
|
||||
}
|
||||
@@ -3237,7 +3237,7 @@ void ifthen_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
if(j == 3) *next_spec = spec.pictype;
|
||||
break;
|
||||
case eSpecType::IF_SDF_EQ:
|
||||
if(sd_legit(spec.sd1,spec.sd2)) {
|
||||
if(univ.party.sd_legit(spec.sd1,spec.sd2)) {
|
||||
if(PSD[spec.sd1][spec.sd2] == spec.ex1a)
|
||||
*next_spec = spec.ex1b;
|
||||
}
|
||||
@@ -4175,7 +4175,7 @@ void outdoor_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
}
|
||||
|
||||
void setsd(short a,short b,short val) {
|
||||
if(!sd_legit(a,b)) {
|
||||
if(!univ.party.sd_legit(a,b)) {
|
||||
giveError("The scenario attempted to change an out of range Stuff Done flag.");
|
||||
return;
|
||||
}
|
||||
|
@@ -126,7 +126,7 @@ void start_town_mode(short which_town, short entry_dir) {
|
||||
for(i = 0; i < 10; i++)
|
||||
if(univ.scenario.town_to_add_to[i] >= 0 && univ.scenario.town_to_add_to[i] < 200 &&
|
||||
town_number == univ.scenario.town_to_add_to[i] &&
|
||||
sd_legit(univ.scenario.flag_to_add_to_town[i][0],univ.scenario.flag_to_add_to_town[i][1])) {
|
||||
univ.party.sd_legit(univ.scenario.flag_to_add_to_town[i][0],univ.scenario.flag_to_add_to_town[i][1])) {
|
||||
former_town = town_number;
|
||||
town_number += PSD[univ.scenario.flag_to_add_to_town[i][0]][univ.scenario.flag_to_add_to_town[i][1]];
|
||||
// Now update horses & boats
|
||||
@@ -431,7 +431,7 @@ void start_town_mode(short which_town, short entry_dir) {
|
||||
|
||||
// Clean out unwanted monsters
|
||||
for(i = 0; i < univ.town.monst.size(); i++)
|
||||
if(sd_legit(univ.town.monst[i].spec1,univ.town.monst[i].spec2)) {
|
||||
if(univ.party.sd_legit(univ.town.monst[i].spec1,univ.town.monst[i].spec2)) {
|
||||
if(PSD[univ.town.monst[i].spec1][univ.town.monst[i].spec2] > 0)
|
||||
univ.town.monst[i].active = 0;
|
||||
}
|
||||
@@ -1006,7 +1006,7 @@ void create_out_combat_terrain(short type,short num_walls,short /*spec_code*/) {
|
||||
void elim_monst(unsigned short which,short spec_a,short spec_b) {
|
||||
short i;
|
||||
|
||||
if(!sd_legit(spec_a,spec_b))
|
||||
if(!univ.party.sd_legit(spec_a,spec_b))
|
||||
return;
|
||||
if(PSD[spec_a][spec_b] > 0) {
|
||||
for(i = 0; i < univ.town.monst.size(); i++)
|
||||
@@ -1130,7 +1130,7 @@ void erase_specials() {
|
||||
//if(univ.town->spec_id[k] >= 0) {
|
||||
sn = univ.town->specials[univ.town->spec_id[k]];
|
||||
sd1 = sn.sd1; sd2 = sn.sd2;
|
||||
if((sd_legit(sd1,sd2)) && (PSD[sd1][sd2] == 250)) {
|
||||
if((univ.party.sd_legit(sd1,sd2)) && (PSD[sd1][sd2] == 250)) {
|
||||
where = univ.town->special_locs[k];
|
||||
if((where.x != 100) && ((where.x > univ.town->max_dim()) || (where.y > univ.town->max_dim())
|
||||
|| (where.x < 0) || (where.y < 0))) {
|
||||
@@ -1189,7 +1189,7 @@ void erase_out_specials() {
|
||||
|
||||
sn = sector.specials[sector.special_id[k]];
|
||||
sd1 = sn.sd1; sd2 = sn.sd2;
|
||||
if((sd_legit(sd1,sd2)) && (PSD[sd1][sd2] == 250)) {
|
||||
if((univ.party.sd_legit(sd1,sd2)) && (PSD[sd1][sd2] == 250)) {
|
||||
where = sector.special_locs[k];
|
||||
if((where.x > 48) || (where.y > 48)
|
||||
|| (where.x < 0) || (where.y < 0)) {
|
||||
|
@@ -19,6 +19,7 @@
|
||||
#include "dlogutil.hpp"
|
||||
#include "oldstructs.h"
|
||||
#include "fileio.hpp"
|
||||
#include "mathutil.hpp"
|
||||
|
||||
cParty::cParty(cUniverse& univ, long party_preset) : univ(univ) {
|
||||
gold = 200;
|
||||
@@ -982,6 +983,13 @@ iLiving& cParty::pc_present() const {
|
||||
return *adven[ret];
|
||||
}
|
||||
|
||||
// stuff done legit, i.e. flags are within proper ranges for stuff done flag
|
||||
bool cParty::sd_legit(short a, short b) {
|
||||
if((minmax(0,299,a) == a) && (minmax(0,49,b) == b))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const cParty::cConvers& one, const cParty::cConvers& two) {
|
||||
if(one.who_said != two.who_said) return false;
|
||||
if(one.in_town != two.in_town) return false;
|
||||
|
@@ -186,6 +186,8 @@ public:
|
||||
iLiving& pc_present() const; // If only one pc is present, returns that pc. Otherwise returns party.
|
||||
void swap_pcs(size_t a, size_t b);
|
||||
|
||||
bool sd_legit(short a, short b);
|
||||
|
||||
typedef std::vector<cEncNote>::iterator encIter;
|
||||
typedef std::vector<cJournal>::iterator journalIter;
|
||||
typedef std::vector<cConvers>::iterator talkIter;
|
||||
|
@@ -539,3 +539,39 @@ bool spend_xp(short pc_num, short mode, cDialog* parent) {
|
||||
|
||||
return xpDlog.getResult<bool>();
|
||||
}
|
||||
|
||||
void edit_stuff_done() {
|
||||
cDialog sdf_dlg("set-sdf");
|
||||
sdf_dlg.attachFocusHandlers([](cDialog& me, std::string, bool losing) -> bool {
|
||||
if(!losing) return true;
|
||||
int x = me["x"].getTextAsNum(), y = me["y"].getTextAsNum();
|
||||
if(!univ.party.sd_legit(x,y)) {
|
||||
std::ostringstream strb;
|
||||
strb << "SDF (" << x << ',' << y << ") does not exist!";
|
||||
me["feedback"].setText(strb.str());
|
||||
} else {
|
||||
me["feedback"].setText("");
|
||||
me["val"].setTextToNum(univ.party.stuff_done[x][y]);
|
||||
}
|
||||
return true;
|
||||
}, {"x","y"});
|
||||
sdf_dlg["set"].attachClickHandler([](cDialog& me, std::string, eKeyMod) -> bool {
|
||||
int x = me["x"].getTextAsNum(), y = me["y"].getTextAsNum(), val = me["val"].getTextAsNum();
|
||||
std::ostringstream strb;
|
||||
if(!univ.party.sd_legit(x,y)) {
|
||||
strb << "SDF (" << x << ',' << y << ") does not exist!";
|
||||
me["feedback"].setText(strb.str());
|
||||
} else {
|
||||
strb << "You have set SDF (" << x << ',' << y << ") = " << val;
|
||||
me["feedback"].setText(strb.str());
|
||||
univ.party.stuff_done[x][y] = val;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
sdf_dlg["exit"].attachClickHandler(std::bind(&cDialog::toast, &sdf_dlg, false));
|
||||
// Initialize fields with some default values
|
||||
sdf_dlg["x"].setText("0");
|
||||
sdf_dlg["y"].setText("0");
|
||||
sdf_dlg["val"].setTextToNum(univ.party.stuff_done[0][0]);
|
||||
sdf_dlg.run();
|
||||
}
|
||||
|
@@ -5,3 +5,4 @@ bool take_gold(short amount,bool print_result);
|
||||
void give_spec_items();
|
||||
void pick_race_abil(cPlayer *pc,short mode);
|
||||
void reset_boats();
|
||||
void edit_stuff_done();
|
||||
|
@@ -307,6 +307,9 @@ void handle_menu_choice(eMenu item_hit) {
|
||||
case eMenu::EDIT_XP:
|
||||
edit_xp(&univ.party[current_active_pc]);
|
||||
break;
|
||||
case eMenu::SET_SDF:
|
||||
edit_stuff_done();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user