Files
oboe/src/pcedit/pc.main.cpp

339 lines
8.6 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <iostream>
#include <cstring>
#include "pc.global.h"
#include "universe.h"
#include "pc.graphics.h"
#include "pc.editors.h"
#include "pc.action.h"
#include "pc.fileio.h"
#include "soundtool.hpp"
#include "graphtool.hpp"
#include "boe.consts.h"
#include "dlogutil.hpp"
#include "fileio.hpp"
#include "pc.menus.h"
#include "winutil.hpp"
#include "cursors.hpp"
cUniverse univ;
rectangle pc_area_buttons[6][4] ; // 0 - whole 1 - pic 2 - name 3 - stat strs 4,5 - later
rectangle item_string_rects[24][4]; // 0 - name 1 - drop 2 - id 3 -
rectangle pc_info_rect; // Frame that holds a pc's basic info and items
rectangle name_rect; //Holds pc name inside pc_info_rect
rectangle info_area_rect;
rectangle hp_sp_rect; // Holds hit points and spells points for pc
rectangle skill_rect; // Holds "Skills:" string
rectangle pc_skills_rect[19]; //Holds current pc's skill levels
rectangle status_rect; //Holds the string "Status:"
rectangle pc_status_rect[10]; //Holds first 8 effects on pc
rectangle traits_rect; //Holds the string "Traits:"
rectangle pc_traits_rect[16]; //Holds pc traits
rectangle pc_race_rect; //Holds current pc's race
rectangle edit_rect[5][2]; //Buttons that bring up pc edit dialog boxs
short current_active_pc = 0;
/* Mac stuff globals */
bool All_Done = false,diff_depth_ok = false;
sf::Event event;
sf::RenderWindow mainPtr;
bool gInBackground = false;
fs::path file_in_mem;
bool party_in_scen = false;
bool scen_items_loaded = false;
short store_flags[3];
/* Prototypes */
int main(int argc, char* argv[]);
void Initialize(void);
void Handle_One_Event();
void Handle_Activate();
void Handle_Update();
void Mouse_Pressed();
bool verify_restore_quit(bool mode);
void set_up_apple_events();
extern bool cur_scen_is_mac;
extern fs::path progDir;
short specials_res_id;
char start_name[256];
//MW specified return type was 'void', changed to ISO C style for Carbonisation -jmr
int main(int /*argc*/, char* argv[]) {
try {
init_directories(argv[0]);
init_menubar();
Initialize();
init_fileio();
init_main_buttons();
Set_up_win();
init_graph_tool();
init_snd_tool();
set_up_apple_events();
cDialog::init();
redraw_screen();
menu_activate();
update_item_menu();
while(!All_Done)
Handle_One_Event();
return 0;
} catch(std::exception& x) {
giveError(x.what());
throw;
} catch(std::string& x) {
giveError(x);
throw;
} catch(...) {
giveError("An unknown error occurred!");
throw;
}
}
void Initialize(void) {
check_for_intel();
//
// To make the Random sequences truly random, we need to make the seed start
// at a different number. An easy way to do this is to put the current time
// and date into the seed. Since it is always incrementing the starting seed
// will always be different. Dont for each call of Random, or the sequence
// will no longer be random. Only needed once, here in the init.
srand(time(NULL));
// Make a new window for drawing in, and it must be a color window.
// The window is full screen size, made smaller to make it more visible.
int height = 440 + getMenubarHeight();
mainPtr.create(sf::VideoMode(590, height), "Blades of Exile Character Editor", sf::Style::Titlebar | sf::Style::Close);
init_menubar();
}
void Handle_One_Event() {
if(!mainPtr.pollEvent(event)) return;
init_main_buttons();
redraw_screen();
switch(event.type){
case sf::Event::KeyPressed:
break;
case sf::Event::MouseButtonPressed:
Mouse_Pressed();
break;
case sf::Event::GainedFocus:
set_cursor(sword_curs);
break;
case sf::Event::Closed:
All_Done = verify_restore_quit(false);
break;
default:
break;
}
}
void Mouse_Pressed() {
bool try_to_end;
try_to_end = handle_action(event);
if(try_to_end)
All_Done = verify_restore_quit(false);
}
static void display_strings(short nstr, pic_num_t pic) {
cStrDlog display_strings(get_str("pcedit", nstr), "", "Editing party", pic, PIC_DLOG);
display_strings.setSound(57);
display_strings.show();
}
void handle_menu_choice(eMenu item_hit) {
int i,j,k;
fs::path file;
switch(item_hit) {
case eMenu::NONE: break;
case eMenu::ABOUT:
cChoiceDlog("about-pced").show();
break;
case eMenu::FILE_SAVE:
save_party(file_in_mem, univ);
break;
case eMenu::FILE_SAVE_AS:
file = nav_put_party();
if(!file.empty()) save_party(file, univ);
break;
case eMenu::FILE_OPEN:
if(verify_restore_quit(true)){
file = nav_get_party();
if(!file.empty()) {
if(load_party(file, univ)) {
file_in_mem = file;
party_in_scen = !univ.party.scen_name.empty();
if(!party_in_scen) load_base_item_defs();
scen_items_loaded = true;
update_item_menu();
}
}
menu_activate();
}
break;
case eMenu::QUIT:
All_Done = verify_restore_quit(false);
break;
case eMenu::EDIT_GOLD:
edit_gold_or_food(0);
break;
case eMenu::EDIT_FOOD:
edit_gold_or_food(1);
break;
case eMenu::LEAVE_TOWN:
if(univ.party.is_split()) {
cChoiceDlog("reunite-first").show();
break;
}
cChoiceDlog("leave-town").show();
leave_town();
break;
case eMenu::REUNITE_PARTY:
if(!univ.party.is_split()) {
cChoiceDlog("not-split").show();
break;
}
if(univ.party.left_in != size_t(-1) && univ.party.left_in != univ.town.num) {
std::string need_town = univ.scenario.towns[univ.party.left_in]->town_name;
giveError("You can't reunite your party when you're in a different town than you split up in.", "Return to the following town in-game and then try again: " + need_town);
break;
}
cChoiceDlog("reunited").show();
univ.town.p_loc = univ.party.left_at;
for(i = 0; i < 6; i++)
if(univ.party[i].main_status >= eMainStatus::SPLIT)
univ.party[i].main_status -= eMainStatus::SPLIT;
break;
case eMenu::RESET_TOWNS:
display_strings(20,7);
for(i = 0; i < 4; i++)
univ.party.creature_save[i].which_town = 200;
break;
case eMenu::HEAL_DAMAGE:
display_strings(1,15);
for(i = 0; i < 6; i++)
univ.party[i].cur_health = univ.party[i].max_health;
break;
case eMenu::RESTORE_MANA:
display_strings(2,15);
for(i = 0; i < 6; i++)
univ.party[i].cur_sp = univ.party[i].max_sp;
break;
case eMenu::RAISE_DEAD:
display_strings(3,15);
for(i = 0; i < 6; i++)
if(univ.party[i].main_status == eMainStatus::DEAD || univ.party[i].main_status == eMainStatus::DUST ||
univ.party[i].main_status == eMainStatus::STONE)
univ.party[i].main_status = eMainStatus::ALIVE;
break;
case eMenu::CURE_CONDITIONS:
display_strings(4,15);
univ.party.clear_bad_status();
break;
case eMenu::LEAVE_SCENARIO:
if(!party_in_scen) {
display_strings(25,15);
break;
}
if(cChoiceDlog("leave-scenario",{"okay","cancel"}).show() != "okay")
break;
remove_party_from_scen();
break;
case eMenu::EDIT_ALCHEMY:
display_alchemy(true);
break;
case eMenu::OWN_VEHICLES:
display_strings(6,7);
for(i = 0; i < univ.party.boats.size(); i++)
univ.party.boats[i].property = false;
for(i = 0; i < univ.party.horses.size(); i++)
univ.party.horses[i].property = false;
break;
case eMenu::EDIT_DAY:
edit_day();
break;
case eMenu::ADD_OUT_MAPS:
if(!party_in_scen) {
display_strings(25,15);
break;
}
display_strings(13,15);
for(i = 0; i < 100; i++)
for(j = 0; j < 6; j++)
for(k = 0; k < 48; k++)
univ.out_maps[i][j][k] = 255;
break;
case eMenu::ADD_TOWN_MAPS:
if(!party_in_scen) {
display_strings(25,15);
break;
}
display_strings(14,15);
for(i = 0; i < 200; i++)
for(j = 0; j < 8; j++)
for(k = 0; k < 64; k++)
univ.town_maps[i][j][k] = 255;
break;
case eMenu::EDIT_MAGE:
display_pc(current_active_pc,0,0);
break;
case eMenu::EDIT_PRIEST:
display_pc(current_active_pc,1,0);
break;
case eMenu::EDIT_TRAITS:
pick_race_abil(&univ.party[current_active_pc],0);
break;
case eMenu::EDIT_SKILLS:
spend_xp(current_active_pc,1,0);
break;
case eMenu::EDIT_XP:
edit_xp(&univ.party[current_active_pc]);
break;
case eMenu::SET_SDF:
edit_stuff_done();
break;
}
}
// TODO: Let this take the item directly instead of the index
void handle_item_menu(int item_hit) {
cItem store_i;
store_i = univ.scenario.scen_items[item_hit];
store_i.ident = true;
univ.party[current_active_pc].give_item(store_i,false);
}
//short mode; // 0 - quit 1- restore
bool verify_restore_quit(bool mode) {
std::string choice;
if(file_in_mem.empty())
return true;
cChoiceDlog verify(mode ? "save-open" : "save-quit", {"save", "quit", "cancel"});
choice = verify.show();
if(choice == "cancel")
return false;
if(choice == "quit")
return true;
save_party(file_in_mem, univ);
return true;
}