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
This commit is contained in:
2014-04-22 02:06:31 -04:00
parent d90a006e43
commit a4430cdf5a
15 changed files with 71 additions and 100 deletions

View File

@@ -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;

View File

@@ -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);
}
}
}

View File

@@ -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;

View File

@@ -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)
{

View File

@@ -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 {

View File

@@ -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<short>(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);

View File

@@ -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;
}

View File

@@ -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

View File

@@ -386,13 +386,13 @@ std::shared_ptr<sf::Texture> 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";

View File

@@ -413,7 +413,6 @@
<array class="NSMutableArray" key="NSMenuItems">
<object class="NSMenuItem" id="313433515">
<reference key="NSMenu" ref="633756543"/>
<bool key="NSIsDisabled">YES</bool>
<string key="NSTitle">About this menu</string>
<string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>
@@ -447,7 +446,6 @@
<array class="NSMutableArray" key="NSMenuItems">
<object class="NSMenuItem" id="364052514">
<reference key="NSMenu" ref="248471372"/>
<bool key="NSIsDisabled">YES</bool>
<string key="NSTitle">About this menu</string>
<string key="NSKeyEquiv"/>
<int key="NSMnemonicLoc">2147483647</int>

View File

@@ -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);
}

View File

@@ -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 {

View File

@@ -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);
}

View File

@@ -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);

View File

@@ -59,7 +59,7 @@
<led name='spell16' state='off' top='317' left='247'/>
<led name='spell17' state='off' top='331' left='247'/>
<led name='spell18' state='off' top='345' left='247'/>
<led name='spell19' state='off' top='259' left='247'/>
<led name='spell19' state='off' top='359' left='247'/>
<led name='spell20' state='off' top='373' left='247'/>
<led name='spell21' state='off' top='247' left='379'/>
<led name='spell22' state='off' top='261' left='379'/>