diff options
author | Steve Melenchuk <smelenchuk@gmail.com> | 2012-08-11 13:40:26 -0600 |
---|---|---|
committer | Steve Melenchuk <smelenchuk@gmail.com> | 2012-08-11 13:40:26 -0600 |
commit | 559a7a88b1209962f633385b0d0540f43753d321 (patch) | |
tree | fbf5cb09663b4dfea1f4dbb2b25b456d99c7cbcd /crawl-ref/source/tilereg-abl.cc | |
parent | 28a9c8c8c012c990261389df52073de3aed22e6d (diff) | |
download | crawl-ref-559a7a88b1209962f633385b0d0540f43753d321.tar.gz crawl-ref-559a7a88b1209962f633385b0d0540f43753d321.zip |
Abilities tab for local tiles, using the fancy new abilities tiles.
This works like the spell tab, but with intrinsic/evocable abilities,
invocations, and ZotDef abilities.
Diffstat (limited to 'crawl-ref/source/tilereg-abl.cc')
-rw-r--r-- | crawl-ref/source/tilereg-abl.cc | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/crawl-ref/source/tilereg-abl.cc b/crawl-ref/source/tilereg-abl.cc new file mode 100644 index 0000000000..b2110c66a7 --- /dev/null +++ b/crawl-ref/source/tilereg-abl.cc @@ -0,0 +1,265 @@ +#include "AppHdr.h" + +#ifdef USE_TILE_LOCAL + +#include "tilereg-abl.h" +#include "process_desc.h" + +#include "abl-show.h" +#include "cio.h" +#include "libutil.h" +#include "macro.h" +#include "message.h" +#include "stuff.h" +#include "tiledef-dngn.h" +#include "tiledef-icons.h" +#include "tilepick.h" +#include "viewgeom.h" + +AbilityRegion::AbilityRegion(const TileRegionInit &init) : GridRegion(init) +{ +} + +void AbilityRegion::activate() +{ + if (your_talents(false).size() == 0) + { + no_ability_msg(); + flush_prev_message(); + } +} + +void AbilityRegion::draw_tag() +{ + if (m_cursor == NO_CURSOR) + return; + + int curs_index = cursor_index(); + if (curs_index >= (int)m_items.size()) + return; + int idx = m_items[curs_index].idx; + if (idx == -1) + return; + + const ability_type ability = (ability_type) idx; + char* failure = failure_rate_to_string(get_talent(ability, false).fail); + std::string desc = make_stringf("%s (%s)", + ability_name(ability), + failure); + free(failure); + draw_desc(desc.c_str()); +} + +int AbilityRegion::handle_mouse(MouseEvent &event) +{ + unsigned int item_idx; + if (!place_cursor(event, item_idx)) + return 0; + + const ability_type ability = (ability_type) m_items[item_idx].idx; + if (event.button == MouseEvent::LEFT) + { + m_last_clicked_item = item_idx; + tiles.set_need_redraw(); + talent tal = get_talent(ability, true); + if (tal.which == ABIL_NON_ABILITY || !activate_talent(tal)) + flush_input_buffer(FLUSH_ON_FAILURE); + return CK_MOUSE_CMD; + } + else if (ability != NUM_ABILITIES && event.button == MouseEvent::RIGHT) + { + describe_talent(get_talent(ability, false)); + redraw_screen(); + return CK_MOUSE_CMD; + } + return 0; +} + +bool AbilityRegion::update_tab_tip_text(std::string &tip, bool active) +{ + const char *prefix1 = active ? "" : "[L-Click] "; + const char *prefix2 = active ? "" : " "; + + tip = make_stringf("%s%s\n%s%s", + prefix1, "Display abilities", + prefix2, "Use abilities"); + + return true; +} + +bool AbilityRegion::update_tip_text(std::string& tip) +{ + if (m_cursor == NO_CURSOR) + return false; + + unsigned int item_idx = cursor_index(); + if (item_idx >= m_items.size() || m_items[item_idx].empty()) + return false; + + int flag = m_items[item_idx].flag; + std::vector<command_type> cmd; + if (flag & TILEI_FLAG_INVALID) + tip = "You cannot use this ability right now."; + else + { + tip = "[L-Click] Use (%)"; + cmd.push_back(CMD_USE_ABILITY); + } + + // TODO: command to display abilities outside of use +#if 0 + tip += "\n[R-Click] Describe (%)"; + cmd.push_back(CMD_DISPLAY_SPELLS); + insert_commands(tip, cmd); +#endif + + return true; +} + +bool AbilityRegion::update_alt_text(std::string &alt) +{ + if (m_cursor == NO_CURSOR) + return false; + + unsigned int item_idx = cursor_index(); + if (item_idx >= m_items.size() || m_items[item_idx].empty()) + return false; + + if (m_last_clicked_item >= 0 + && item_idx == (unsigned int) m_last_clicked_item) + { + return false; + } + + int idx = m_items[item_idx].idx; + + const ability_type ability = (ability_type) idx; + + describe_info inf; + inf.body << get_ability_desc(ability); + + alt_desc_proc proc(crawl_view.msgsz.x, crawl_view.msgsz.y); + process_description<alt_desc_proc>(proc, inf); + + proc.get_string(alt); + + return true; +} + +int AbilityRegion::get_max_slots() +{ + return ABIL_MAX_INTRINSIC + (ABIL_MAX_EVOKE - ABIL_MIN_EVOKE) + 1 + + MAX_GOD_ABILITIES + 1 + + (ABIL_MAX_ZOTDEF - ABIL_MIN_ZOTDEF) + 1; +} + +void AbilityRegion::pack_buffers() +{ + const int max_spells = get_max_slots(); + + // Pack base separately, as it comes from a different texture... + int i = 0; + for (int y = 0; y < my; y++) + { + if (i >= max_spells) + break; + + for (int x = 0; x < mx; x++) + { + if (i++ >= max_spells) + break; + + m_buf.add_dngn_tile(TILE_ITEM_SLOT, x, y); + } + } + + i = 0; + for (int y = 0; y < my; y++) + { + if (i >= (int)m_items.size()) + break; + + for (int x = 0; x < mx; x++) + { + if (i >= (int)m_items.size()) + break; + + InventoryTile &item = m_items[i++]; + if (item.flag & TILEI_FLAG_INVALID) + m_buf.add_icons_tile(TILEI_MESH, x, y); + + if (item.flag & TILEI_FLAG_CURSOR) + m_buf.add_icons_tile(TILEI_CURSOR, x, y); + + if (item.quantity != -1) + draw_number(x, y, item.quantity); + + if (item.tile) + m_buf.add_spell_tile(item.tile, x, y); + } + } +} + +static InventoryTile _tile_for_ability(ability_type ability) +{ + InventoryTile desc; + desc.tile = tileidx_ability(ability); + desc.idx = (int) ability; + desc.quantity = get_talent(ability, true).fail; + + if (!check_ability_possible(ability, true, true)) + { + desc.flag |= TILEI_FLAG_INVALID; + } + + return desc; +} + +void AbilityRegion::update() +{ + m_items.clear(); + m_dirty = true; + + if (mx * my == 0) + return; + + const unsigned int max_abilities = std::min(get_max_slots(), mx*my); + + std::vector<talent> talents = your_talents(false); + if (talents.empty()) + return; + + std::vector<InventoryTile> m_zotdef; + std::vector<InventoryTile> m_invoc; + + for (unsigned int i = 0; i < talents.size(); ++i) + { + if (talents[i].is_invocation) + m_invoc.push_back(_tile_for_ability(talents[i].which)); + else if (talents[i].is_zotdef) + m_zotdef.push_back(_tile_for_ability(talents[i].which)); + else + m_items.push_back(_tile_for_ability(talents[i].which)); + + if (m_items.size() >= max_abilities) + return; + } + + for (std::vector<InventoryTile>::iterator it = m_zotdef.begin(); + it != m_zotdef.end(); it++) + { + m_items.push_back(*it); + if (m_items.size() >= max_abilities) + return; + } + + for (std::vector<InventoryTile>::iterator it = m_invoc.begin(); + it != m_invoc.end(); it++) + { + m_items.push_back(*it); + if (m_items.size() >= max_abilities) + return; + } +} + +#endif |