From a4430cdf5a2d665d04def2282db6ea12a347eb64 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Tue, 22 Apr 2014 02:06:31 -0400 Subject: [PATCH] Fix spellcasting and dynamic menus - Spell targeting line and array draws nicely, though not the same as the original - Fix targeting falsely complaining about being off the edge of town - Monster info dialog works properly; attacks now display correctly - Fix dialogs always showing the wrong terrain or monster graphic - Spell menus, monster menus, and PC editor item menus all work - Spellcasting dialog now chooses the correct spell - Fix out-of-place LED in spellcasting dialog --- osx/boe.actions.cpp | 7 +++++- osx/boe.graphics.cpp | 30 +++-------------------- osx/boe.infodlg.cpp | 7 +++--- osx/boe.main.cpp | 49 ++++++------------------------------- osx/boe.menus.mac.mm | 28 ++++++++++----------- osx/boe.party.cpp | 6 ++--- osx/classes/monster.cpp | 7 +++++- osx/classes/monster.h | 1 + osx/dialogxml/pict.cpp | 4 +-- osx/menu.xib | 2 -- osx/pcedit/pc.main.cpp | 5 ++-- osx/pcedit/pc.menus.mac.mm | 7 +++++- osx/tools/graphtool.cpp | 15 ++++++++++++ osx/tools/graphtool.h | 1 + rsrc/dialogs/cast-spell.xml | 2 +- 15 files changed, 71 insertions(+), 100 deletions(-) diff --git a/osx/boe.actions.cpp b/osx/boe.actions.cpp index 1cf92d95..5d50a688 100644 --- a/osx/boe.actions.cpp +++ b/osx/boe.actions.cpp @@ -374,7 +374,7 @@ bool handle_action(sf::Event event) case MODE_TOWN_TARGET: case MODE_COMBAT: case MODE_SPELL_TARGET: case MODE_FIRING: case MODE_THROWING: case MODE_FANCY_TARGET: case MODE_DROP_COMBAT: case MODE_LOOK_COMBAT: - cur_loc = (overall_mode > MODE_COMBAT) ? center : pc_pos[current_pc]; + cur_loc = (overall_mode < MODE_COMBAT) ? center : pc_pos[current_pc]; for (i = 0; i < 9; i++) if(the_point.in(combat_buttons[i])) { button_hit = i; @@ -1450,6 +1450,11 @@ bool someone_awake() void handle_menu_spell(short spell_picked,short spell_type) { + if(!prime_time()) { + ASB("Finish what you're doing first."); + print_buf(); + return; + } location pass_point; sf::Event event; diff --git a/osx/boe.graphics.cpp b/osx/boe.graphics.cpp index 8517c76c..2a93b3b4 100644 --- a/osx/boe.graphics.cpp +++ b/osx/boe.graphics.cpp @@ -610,6 +610,8 @@ void redraw_screen(int refresh) { if(overall_mode == MODE_FANCY_TARGET) draw_targets(center); if(overall_mode != MODE_STARTUP) { + if(!is_out()) + draw_targeting_line(sf::Mouse::getPosition(mainPtr)); refresh_stat_areas(0); text_sbar->draw(); item_sbar->draw(); @@ -1692,21 +1694,7 @@ void draw_targeting_line(location where_curs) terrain_rect.offset(5 + ul.x,5 + ul.y); mainPtr.setActive(); clip_rect(mainPtr, terrain_rect); - // TODO: Not sure if this will even work - sf::ConvexShape line(3); - line.setPoint(0, where_curs); - line.setPoint(1, location(k, l)); - line.setPoint(2, location(k - 1, l + 1)); - line.setOutlineThickness(2); - line.setOutlineColor(sf::Color::Black); - mainPtr.draw(line, sf::RenderStates(sf::BlendAdd)); -#if 0 - PenMode (patXor); - PenSize(2,2); - MoveTo(where_curs.h,where_curs.v); - LineTo(k,l); -#endif - + draw_line(mainPtr, where_curs, location(k, l), 2, {128,128,128}, sf::BlendAdd); redraw_rect.left = min(where_curs.x,k) - 4; redraw_rect.right = max(where_curs.x,k) + 4; redraw_rect.top = min(where_curs.y,l) - 4; @@ -1725,8 +1713,7 @@ void draw_targeting_line(location where_curs) target_rect.right = target_rect.left + BITMAP_WIDTH; target_rect.top = 13 + BITMAP_HEIGHT * j + 5 + ul.y; target_rect.bottom = target_rect.top + BITMAP_HEIGHT; - // TODO: Not sure if black is the right colour here - frame_rect(mainPtr, target_rect, sf::Color::Black); + frame_rect(mainPtr, target_rect, sf::Color::White); target_rect.inset(-5,-5); redraw_rect2 = rectunion(target_rect,redraw_rect2); @@ -1745,17 +1732,8 @@ void draw_targeting_line(location where_curs) } } - mainPtr.display(); - sf::sleep(time_in_ticks(4)); - redraw_rect2.inset(-5,-5); - redraw_partial_terrain(redraw_rect2); undo_clip(mainPtr); - if (is_combat()) - draw_pcs(center,1); - else draw_party_symbol(0,center); - if (overall_mode == MODE_FANCY_TARGET) - draw_targets(center); } } } diff --git a/osx/boe.infodlg.cpp b/osx/boe.infodlg.cpp index c266487a..a90356b7 100644 --- a/osx/boe.infodlg.cpp +++ b/osx/boe.infodlg.cpp @@ -429,8 +429,9 @@ static void put_monst_info(cDialog& me) for(i = 0; i < 3; i++) { if (store_m->a[i] > 0) { - std::ostringstream sout(store_text); - sout << store_m->a[i] / 100 + 1 << 'd' << store_m->a[i] % 100; + if(store_m->a[i].sides == 0) continue; + std::ostringstream sout(std::ios_base::ate); + sout << store_m->a[i]; store_text = sout.str(); sout.str("attack"); sout << i + 1; @@ -494,7 +495,7 @@ static bool display_monst_event_filter(cDialog& me, std::string item_hit, eKeyMo void display_monst(short array_pos,cCreature *which_m,short mode) //creature_data_type *which_m; // if NULL, show full roster -//short mode; // if 1, full roster, else use monster from storwhich_me_m +//short mode; // if 1, full roster, else use monster from store_m { position = array_pos; full_roster = false; diff --git a/osx/boe.main.cpp b/osx/boe.main.cpp index 72fef969..2e9b9ffb 100644 --- a/osx/boe.main.cpp +++ b/osx/boe.main.cpp @@ -305,13 +305,13 @@ void Handle_One_Event() clear_sound_memory(); - if(map_visible && mini_map.pollEvent(event)){ - if(event.type == sf::Event::Closed) { - mini_map.setVisible(false); - map_visible = false; - } else if(event.type == sf::Event::GainedFocus) - makeFrontWindow(mainPtr); - } + if(map_visible && mini_map.pollEvent(event)){ + if(event.type == sf::Event::Closed) { + mini_map.setVisible(false); + map_visible = false; + } else if(event.type == sf::Event::GainedFocus) + makeFrontWindow(mainPtr); + } if(!mainPtr.pollEvent(event)) { if(changed_display_mode) { changed_display_mode = false; @@ -344,9 +344,6 @@ void Handle_One_Event() if(!gInBackground) { location where(event.mouseMove.x, event.mouseMove.y); change_cursor(where); - // TODO: Probably don't actually need the conditional here? - if(animTimer.getElapsedTime().asMilliseconds() % fiveTicks <= 60) - draw_targeting_line(where); } break; @@ -689,38 +686,6 @@ void handle_actions_menu(int item_hit) } } -// TODO: Maybe just use handle_menu_spell instead -void handle_mage_spells_menu(int item_hit) -{ - switch (item_hit) { - case 1: - give_help(209,0); - break; - default: - if (prime_time() == false) { - ASB("Finish what you're doing first."); - print_buf(); - } - else handle_menu_spell(on_spell_menu[0][item_hit - 3],0); - break; - } -} -void handle_priest_spells_menu(int item_hit) -{ - switch (item_hit) { - case 1: - give_help(209,0); - break; - default: - if (prime_time() == false) { - ASB("Finish what you're doing first."); - print_buf(); - } - else handle_menu_spell(on_spell_menu[1][item_hit - 3],1); - break; - } -} - // TODO: Let this function take a cMonster* instead of the item_hit void handle_monster_info_menu(int item_hit) { diff --git a/osx/boe.menus.mac.mm b/osx/boe.menus.mac.mm index e971e4ff..054fd1e5 100644 --- a/osx/boe.menus.mac.mm +++ b/osx/boe.menus.mac.mm @@ -117,6 +117,9 @@ void init_menubar() { help_menu = [[menu_bar_handle itemWithTitle: @"Help"] submenu]; library_menu = [[menu_bar_handle itemWithTitle: @"Library"] submenu]; actions_menu = [[menu_bar_handle itemWithTitle: @"Actions"] submenu]; + mage_spells_menu = [[menu_bar_handle itemWithTitle: @"Cast Mage"] submenu]; + priest_spells_menu = [[menu_bar_handle itemWithTitle: @"Cast Priest"] submenu]; + monster_info_menu = [[menu_bar_handle itemWithTitle: @"Monsters"] submenu]; MenuHandler* handler = [[[MenuHandler alloc] init] retain]; setMenuCallback([help_menu itemAtIndex: 0], handler, @selector(onlineHelp:), 0); @@ -141,13 +144,10 @@ void init_menubar() { setMenuCallback([library_menu itemAtIndex: i], handler, @selector(libMenu:), i + 1); for(int i = 0; i < [actions_menu numberOfItems]; i++) setMenuCallback([actions_menu itemAtIndex: i], handler, @selector(actMenu:), i + 1); - // TODO: Spell menus and monster menu - NSMenu* mage_menu = [[menu_bar_handle itemWithTitle: @"Mage Spells"] submenu]; - setMenuCallback([mage_menu itemAtIndex: 0], handler, @selector(menuHelp:), 0); - NSMenu* priest_menu = [[menu_bar_handle itemWithTitle: @"Priest Spells"] submenu]; - setMenuCallback([priest_menu itemAtIndex: 0], handler, @selector(menuHelp:), 1); - NSMenu* monst_menu = [[menu_bar_handle itemWithTitle: @"Monsters"] submenu]; - setMenuCallback([monst_menu itemAtIndex: 0], handler, @selector(menuHelp:), 2); + + setMenuCallback([mage_spells_menu itemAtIndex: 0], handler, @selector(menuHelp:), 0); + setMenuCallback([priest_spells_menu itemAtIndex: 0], handler, @selector(menuHelp:), 1); + setMenuCallback([monster_info_menu itemAtIndex: 0], handler, @selector(menuHelp:), 2); menu_activate(); } @@ -209,7 +209,7 @@ void adjust_spell_menus() NSString* str = [NSString stringWithUTF8String: spell_name]; NSMenuItem* newItem = [spell_menu addItemWithTitle: str action: @selector(spellMenu:) keyEquivalent: @""]; [newItem setTarget: targ]; - [newItem setRepresentedObject: [SpellWrapper withSpell: i ofType: 0]]; + [newItem setRepresentedObject: [SpellWrapper withSpell: on_spell_menu[0][i] ofType: 0]]; } } @@ -243,11 +243,10 @@ void adjust_spell_menus() else sprintf(spell_name," L%d - %s, C ?",spell_level[i], priest_s_name[on_spell_menu[1][i]]); spell_name[0] = strlen((char *) spell_name); - // TODO: Figure out what to put for the action (which should be an Objective-C selector) NSString* str = [NSString stringWithUTF8String: spell_name]; NSMenuItem* newItem = [spell_menu addItemWithTitle: str action: @selector(spellMenu:) keyEquivalent: @""]; [newItem setTarget: targ]; - [newItem setRepresentedObject: [SpellWrapper withSpell: i ofType: 1]]; + [newItem setRepresentedObject: [SpellWrapper withSpell: on_spell_menu[1][i] ofType: 1]]; } } @@ -289,8 +288,7 @@ void handle_help_menu(int item_hit); void handle_library_menu(int item_hit); void handle_actions_menu(int item_hit); void handle_monster_info_menu(int item_hit); -void handle_mage_spells_menu(int item_hit); -void handle_priest_spells_menu(int item_hit); +void handle_menu_spell(short spell_picked,short spell_type); @implementation MenuHandler -(void) appMenu:(id) sender { @@ -310,13 +308,13 @@ void handle_priest_spells_menu(int item_hit); } -(void) monstMenu:(id) sender { - handle_monster_info_menu(1); + cMonster* monst = [[sender representedObject] monst]; + handle_monster_info_menu([monster_info_menu indexOfItem: sender] - 1); } -(void) spellMenu:(id) sender { SpellWrapper* spell = [sender representedObject]; - if([spell type] == 0) handle_mage_spells_menu([spell num]); - else if([spell type] == 1) handle_priest_spells_menu([spell num]); + handle_menu_spell([spell num], [spell type]); } -(void) libMenu:(id) sender { diff --git a/osx/boe.party.cpp b/osx/boe.party.cpp index bbdd6364..8132e5f7 100644 --- a/osx/boe.party.cpp +++ b/osx/boe.party.cpp @@ -2255,7 +2255,7 @@ static bool pick_spell_event_filter(cDialog& me, std::string item_hit, eKeyMod m static bool pick_spell_select_led(cDialog& me, std::string id, eKeyMod mods) { static const char*const choose_target = " Now pick a target."; static const char*const bad_spell = " Spell not available."; - short item_hit = id[id.length() - 1] - '1'; + short item_hit = boost::lexical_cast(id.substr(5)) - 1; if(mod_contains(mods, mod_alt)) { int i = (on_which_spell_page == 0) ? item_hit : spell_index[item_hit]; display_spells(store_situation,i,&me); @@ -2265,8 +2265,8 @@ static bool pick_spell_select_led(cDialog& me, std::string id, eKeyMod mods) { } else { if (store_situation == 0) - store_mage = (on_which_spell_page == 0) ? item_hit - 37 : spell_index[item_hit - 37]; - else store_priest = (on_which_spell_page == 0) ? item_hit - 37 : spell_index[item_hit - 37]; + store_mage = (on_which_spell_page == 0) ? item_hit : spell_index[item_hit]; + else store_priest = (on_which_spell_page == 0) ? item_hit : spell_index[item_hit]; draw_spell_info(me); put_spell_led_buttons(me); diff --git a/osx/classes/monster.cpp b/osx/classes/monster.cpp index 6b5aa3d2..fd5ef83a 100644 --- a/osx/classes/monster.cpp +++ b/osx/classes/monster.cpp @@ -131,11 +131,16 @@ cMonster::cAttack::operator int(){ } cMonster::cAttack& cMonster::cAttack::operator=(int n){ - dice = n / 100; + dice = n / 100 + 1; sides = n % 100; return *this; } +std::ostream& operator<<(std::ostream& out, cMonster::cAttack& att) { + out << int(att.dice) << 'd' << int(att.sides); + return out; +} + std::ostream& operator << (std::ostream& out, eStatus& e){ return out << (int) e; } diff --git a/osx/classes/monster.h b/osx/classes/monster.h index 46322c3b..2d15e388 100644 --- a/osx/classes/monster.h +++ b/osx/classes/monster.h @@ -188,4 +188,5 @@ std::ostream& operator << (std::ostream& out, eRace& e); std::istream& operator >> (std::istream& in, eRace& e); std::ostream& operator << (std::ostream& out, eMonstAbil& e); std::istream& operator >> (std::istream& in, eMonstAbil& e); +std::ostream& operator<<(std::ostream& out, cMonster::cAttack& att); #endif \ No newline at end of file diff --git a/osx/dialogxml/pict.cpp b/osx/dialogxml/pict.cpp index bf4d3697..4c4b030c 100644 --- a/osx/dialogxml/pict.cpp +++ b/osx/dialogxml/pict.cpp @@ -386,13 +386,13 @@ std::shared_ptr cPict::getSheet(eSheetType type, size_t n) { std::ostringstream sout; switch(type) { case SHEET_TER: - sout << "ter" << n; + sout << "ter" << n + 1; break; case SHEET_TER_ANIM: sout << "teranim"; break; case SHEET_MONST: - sout << "monst" << n; + sout << "monst" << n + 1; break; case SHEET_DLOG: sout << "dlogpics"; diff --git a/osx/menu.xib b/osx/menu.xib index 7e05018b..fd8c3b75 100644 --- a/osx/menu.xib +++ b/osx/menu.xib @@ -413,7 +413,6 @@ - YES About this menu 2147483647 @@ -447,7 +446,6 @@ - YES About this menu 2147483647 diff --git a/osx/pcedit/pc.main.cpp b/osx/pcedit/pc.main.cpp index 7154b0e2..b4b9e52f 100644 --- a/osx/pcedit/pc.main.cpp +++ b/osx/pcedit/pc.main.cpp @@ -98,8 +98,6 @@ extern fs::path progDir; short specials_res_id; char start_name[256]; -//#include "pc.itemdata.h" -cItemRec item_list[400]; cScenario scenario; // @@ -462,6 +460,7 @@ void handle_edit_menu(int item_hit) // return i; //} +// TODO: Let this take the item directly instead of the index void handle_item_menu(int item_hit) { short choice; @@ -471,7 +470,7 @@ void handle_item_menu(int item_hit) display_strings(5,7); return; } - store_i = item_list[item_hit]; + store_i = scenario.scen_items[item_hit]; store_i.ident = true; give_to_pc(current_active_pc,store_i,false); } diff --git a/osx/pcedit/pc.menus.mac.mm b/osx/pcedit/pc.menus.mac.mm index 0191607f..bd445c13 100644 --- a/osx/pcedit/pc.menus.mac.mm +++ b/osx/pcedit/pc.menus.mac.mm @@ -89,7 +89,7 @@ void menu_activate() { } void update_item_menu() { - id targ = [[apple_menu itemAtIndex: 1] target]; + id targ = [[file_menu itemAtIndex: 0] target]; cItemRec(& item_list)[400] = scenario.scen_items; for(int j = 0; j < 4; j++){ [items_menu[j] removeAllItems]; @@ -123,6 +123,11 @@ void update_item_menu() { -(void) itemMenu:(id) sender { ItemWrapper* item = [sender representedObject]; cItemRec& theItem = [item item]; + for(int i = 0; i < 4; i++) { + int whichItem = [items_menu[i] indexOfItem: sender]; + if(whichItem >= 0) + handle_item_menu(whichItem + 100 * i); + } } -(void) helpMenu:(id) sender { diff --git a/osx/tools/graphtool.cpp b/osx/tools/graphtool.cpp index e20678af..727d0bf9 100644 --- a/osx/tools/graphtool.cpp +++ b/osx/tools/graphtool.cpp @@ -882,9 +882,24 @@ public: // TODO: Additional functions? }; +void draw_line(sf::RenderTarget& target, location from, location to, int thickness, sf::Color colour, sf::BlendMode mode) { + sf::VertexArray line(sf::LinesStrip, 2); + line[0].position = from; + line[0].color = colour; + line[1].position = to; + line[1].color = colour; + setActiveRenderTarget(target); + float saveThickness; + glGetFloatv(GL_LINE_WIDTH, &saveThickness); + glLineWidth(thickness); + target.draw(line, mode); + glLineWidth(saveThickness); +} + static void fill_shape(sf::RenderTarget& target, sf::Shape& shape, int x, int y, sf::Color colour) { shape.setPosition(x, y); shape.setFillColor(colour); + setActiveRenderTarget(target); target.draw(shape); } diff --git a/osx/tools/graphtool.h b/osx/tools/graphtool.h index 7b16ac69..31ec8043 100644 --- a/osx/tools/graphtool.h +++ b/osx/tools/graphtool.h @@ -95,6 +95,7 @@ void fill_roundrect(sf::RenderTarget& target, RECT rect, int rad, sf::Color colo void frame_roundrect(sf::RenderTarget& target, RECT rect, int rad, sf::Color colour); void fill_region(sf::RenderWindow& target, Region& region, sf::Color colour); void frame_region(sf::RenderWindow& target, Region& region, sf::Color colour); +void draw_line(sf::RenderTarget& target, location from, location to, int thickness, sf::Color colour, sf::BlendMode mode = sf::BlendNone); void clip_rect(sf::RenderTarget& where, RECT rect); void clip_region(sf::RenderWindow& where, Region& region); diff --git a/rsrc/dialogs/cast-spell.xml b/rsrc/dialogs/cast-spell.xml index 116e2d29..4e3f4914 100644 --- a/rsrc/dialogs/cast-spell.xml +++ b/rsrc/dialogs/cast-spell.xml @@ -59,7 +59,7 @@ - +