Add preview button to item/monster edit dialogs

This shows the monster or item info dialog as it would appear in-game
This commit is contained in:
2017-01-22 11:02:26 -05:00
parent 40110dc367
commit 8e43ce4347
8 changed files with 256 additions and 181 deletions

View File

@@ -90,4 +90,5 @@
</text> </text>
<button name="abils" type='large' top='357' left='155'>Abilities</button> <button name="abils" type='large' top='357' left='155'>Abilities</button>
<button name="desc" type='large' top='357' left='263'>Description</button> <button name="desc" type='large' top='357' left='263'>Description</button>
<button name="preview" type='regular' top='8' left='509'>Preview</button>
</dialog> </dialog>

View File

@@ -79,4 +79,5 @@
<text top='150' left='283' width='50' height='14'>Attack 1:</text> <text top='150' left='283' width='50' height='14'>Attack 1:</text>
<text top='174' left='283' width='50' height='14'>Attack 2:</text> <text top='174' left='283' width='50' height='14'>Attack 2:</text>
<text top='198' left='283' width='50' height='14'>Attack 3:</text> <text top='198' left='283' width='50' height='14'>Attack 3:</text>
<button name='preview' type='regular' top='8' left='600'>Preview</button>
</dialog> </dialog>

View File

@@ -213,6 +213,8 @@
91ACCE941900346C00FAEF8B /* sfml-graphics.framework in Copy Libraries and Frameworks */ = {isa = PBXBuildFile; fileRef = 91F6F8DE18F87F3700E3EA15 /* sfml-graphics.framework */; }; 91ACCE941900346C00FAEF8B /* sfml-graphics.framework in Copy Libraries and Frameworks */ = {isa = PBXBuildFile; fileRef = 91F6F8DE18F87F3700E3EA15 /* sfml-graphics.framework */; };
91ACCE961900346C00FAEF8B /* sfml-system.framework in Copy Libraries and Frameworks */ = {isa = PBXBuildFile; fileRef = 91F6F8E018F87F3700E3EA15 /* sfml-system.framework */; }; 91ACCE961900346C00FAEF8B /* sfml-system.framework in Copy Libraries and Frameworks */ = {isa = PBXBuildFile; fileRef = 91F6F8E018F87F3700E3EA15 /* sfml-system.framework */; };
91ACCE971900346C00FAEF8B /* sfml-window.framework in Copy Libraries and Frameworks */ = {isa = PBXBuildFile; fileRef = 91F6F8E118F87F3700E3EA15 /* sfml-window.framework */; }; 91ACCE971900346C00FAEF8B /* sfml-window.framework in Copy Libraries and Frameworks */ = {isa = PBXBuildFile; fileRef = 91F6F8E118F87F3700E3EA15 /* sfml-window.framework */; };
91B0D5D11E3442FE002BE4DA /* view_dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91B0D5D01E34428E002BE4DA /* view_dialogs.cpp */; };
91B0D5D21E344300002BE4DA /* view_dialogs.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91B0D5D01E34428E002BE4DA /* view_dialogs.cpp */; };
91B3EF1F0F969C9C00BF5B67 /* BoECharEd.icns in Resources */ = {isa = PBXBuildFile; fileRef = 91B3EF110F969BD300BF5B67 /* BoECharEd.icns */; }; 91B3EF1F0F969C9C00BF5B67 /* BoECharEd.icns in Resources */ = {isa = PBXBuildFile; fileRef = 91B3EF110F969BD300BF5B67 /* BoECharEd.icns */; };
91B3EF470F969F1700BF5B67 /* BoEScenEd.icns in Resources */ = {isa = PBXBuildFile; fileRef = 91B3EEDB0F969BA700BF5B67 /* BoEScenEd.icns */; }; 91B3EF470F969F1700BF5B67 /* BoEScenEd.icns in Resources */ = {isa = PBXBuildFile; fileRef = 91B3EEDB0F969BA700BF5B67 /* BoEScenEd.icns */; };
91B3EF480F969F2300BF5B67 /* pc.main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91B3EF050F969BD300BF5B67 /* pc.main.cpp */; }; 91B3EF480F969F2300BF5B67 /* pc.main.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 91B3EF050F969BD300BF5B67 /* pc.main.cpp */; };
@@ -669,6 +671,8 @@
91B0D5CD1E3408AB002BE4DA /* stealth */ = {isa = PBXFileReference; lastKnownFileType = folder; path = stealth; sourceTree = "<group>"; }; 91B0D5CD1E3408AB002BE4DA /* stealth */ = {isa = PBXFileReference; lastKnownFileType = folder; path = stealth; sourceTree = "<group>"; };
91B0D5CE1E3408AB002BE4DA /* valleydy */ = {isa = PBXFileReference; lastKnownFileType = folder; path = valleydy; sourceTree = "<group>"; }; 91B0D5CE1E3408AB002BE4DA /* valleydy */ = {isa = PBXFileReference; lastKnownFileType = folder; path = valleydy; sourceTree = "<group>"; };
91B0D5CF1E3408AB002BE4DA /* zakhazi */ = {isa = PBXFileReference; lastKnownFileType = folder; path = zakhazi; sourceTree = "<group>"; }; 91B0D5CF1E3408AB002BE4DA /* zakhazi */ = {isa = PBXFileReference; lastKnownFileType = folder; path = zakhazi; sourceTree = "<group>"; };
91B0D5D01E34428E002BE4DA /* view_dialogs.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = view_dialogs.cpp; sourceTree = "<group>"; };
91B0D5D31E3446CF002BE4DA /* view_dialogs.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = view_dialogs.hpp; sourceTree = "<group>"; };
91B3E8A50F938FFE00BF5B67 /* boe.consts.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = boe.consts.hpp; sourceTree = "<group>"; }; 91B3E8A50F938FFE00BF5B67 /* boe.consts.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = boe.consts.hpp; sourceTree = "<group>"; };
91B3EED90F969BA700BF5B67 /* BoEScenEd-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "BoEScenEd-Info.plist"; path = "scenedit/BoEScenEd-Info.plist"; sourceTree = SOURCE_ROOT; }; 91B3EED90F969BA700BF5B67 /* BoEScenEd-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "BoEScenEd-Info.plist"; path = "scenedit/BoEScenEd-Info.plist"; sourceTree = SOURCE_ROOT; };
91B3EEDB0F969BA700BF5B67 /* BoEScenEd.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = BoEScenEd.icns; path = icons/mac/BoEScenEd.icns; sourceTree = "<group>"; }; 91B3EEDB0F969BA700BF5B67 /* BoEScenEd.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = BoEScenEd.icns; path = icons/mac/BoEScenEd.icns; sourceTree = "<group>"; };
@@ -1092,6 +1096,7 @@
915325181A2E37EE000A9A1C /* specials_parse.cpp */, 915325181A2E37EE000A9A1C /* specials_parse.cpp */,
91BFA3D81902AD78001686E4 /* tarball.cpp */, 91BFA3D81902AD78001686E4 /* tarball.cpp */,
912283C80FD0E16C00B21642 /* undo.cpp */, 912283C80FD0E16C00B21642 /* undo.cpp */,
91B0D5D01E34428E002BE4DA /* view_dialogs.cpp */,
919145FF18E63B70005CF3A4 /* winutil.mac.mm */, 919145FF18E63B70005CF3A4 /* winutil.mac.mm */,
); );
name = src; name = src;
@@ -1113,6 +1118,7 @@
91BFA3D91902ADD5001686E4 /* tarball.hpp */, 91BFA3D91902ADD5001686E4 /* tarball.hpp */,
917B573F100B956C0096C978 /* undo.hpp */, 917B573F100B956C0096C978 /* undo.hpp */,
9179A4621A47D4E200FEF872 /* vector2d.hpp */, 9179A4621A47D4E200FEF872 /* vector2d.hpp */,
91B0D5D31E3446CF002BE4DA /* view_dialogs.hpp */,
919145FE18E63B41005CF3A4 /* winutil.hpp */, 919145FE18E63B41005CF3A4 /* winutil.hpp */,
); );
name = headers; name = headers;
@@ -1764,6 +1770,7 @@
912DFE8F18E2872400B00D75 /* boe.menus.mac.mm in Sources */, 912DFE8F18E2872400B00D75 /* boe.menus.mac.mm in Sources */,
919145FC18E3AB1B005CF3A4 /* boe.appleevents.mm in Sources */, 919145FC18E3AB1B005CF3A4 /* boe.appleevents.mm in Sources */,
915325171A2E1DF0000A9A1C /* oldstructs.cpp in Sources */, 915325171A2E1DF0000A9A1C /* oldstructs.cpp in Sources */,
91B0D5D11E3442FE002BE4DA /* view_dialogs.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -1866,6 +1873,7 @@
91B3F1850F97894A00BF5B67 /* scen.graphics.cpp in Sources */, 91B3F1850F97894A00BF5B67 /* scen.graphics.cpp in Sources */,
914CA45819074E0100B6ADD1 /* scen.menus.mac.mm in Sources */, 914CA45819074E0100B6ADD1 /* scen.menus.mac.mm in Sources */,
91034D211B225E4A008F01C1 /* scen.appleevents.mm in Sources */, 91034D211B225E4A008F01C1 /* scen.appleevents.mm in Sources */,
91B0D5D21E344300002BE4DA /* view_dialogs.cpp in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };

View File

@@ -26,6 +26,7 @@
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include "prefs.hpp" #include "prefs.hpp"
#include "spell.hpp" #include "spell.hpp"
#include "view_dialogs.hpp"
short mage_spell_pos = 0,priest_spell_pos = 0,skill_pos = 0; short mage_spell_pos = 0,priest_spell_pos = 0,skill_pos = 0;
@@ -181,104 +182,6 @@ void display_skills(eSkill force_skill,cDialog* parent) {
skillDlog.run(); skillDlog.run();
} }
static void put_item_info(cDialog& me,const cItem& s_i) {
std::string desc_str;
cPict& pic = dynamic_cast<cPict&>(me["pic"]);
pic.setPict(s_i.graphic_num, PIC_ITEM);
// id? magic?
cLed& id = dynamic_cast<cLed&>(me["id"]);
if(s_i.ident)
id.setState(led_red);
else id.setState(led_off);
cLed& magic = dynamic_cast<cLed&>(me["magic"]);
if(s_i.magic && s_i.ident)
magic.setState(led_red);
else magic.setState(led_off);
me["type"].setText(get_str("item-types-display", int(s_i.variety) + 1));
// Clear fields
me["val"].setText("");
me["dmg"].setText("");
me["bonus"].setText("");
me["def"].setText("");
me["enc"].setText("");
me["use"].setText("");
me["lvl"].setText("");
me["abil"].setText("");
if(!s_i.ident) {
me["name"].setText(s_i.name);
return;
}
me["name"].setText(s_i.full_name);
me["weight"].setTextToNum(s_i.item_weight());
me["desc"].setText(s_i.desc.substr(0,s_i.desc.find("|||")));
// TODO: This calculation (value for an item with charges) should be in a member function of cItem
me["val"].setTextToNum((s_i.charges > 0) ? s_i.value * s_i.charges : s_i.value);
if(s_i.ability != eItemAbil::NONE) {
if(s_i.concealed) {
me["abil"].setText("???");
} else {
std::string abil = s_i.getAbilName();
if(s_i.ability == eItemAbil::SUMMONING || s_i.ability == eItemAbil::MASS_SUMMONING)
abil.replace(abil.find("%s"), 2, univ.scenario.scen_monsters[s_i.abil_data[1]].m_name);
me["abil"].setText(abil);
}
}
if(s_i.charges > 0)
me["use"].setTextToNum(s_i.charges);
if(s_i.protection > 0)
me["def"].setTextToNum(s_i.protection);
std::string store_text;
switch(s_i.variety) {
case eItemType::ONE_HANDED:
case eItemType::TWO_HANDED:
case eItemType::BOW:
case eItemType::CROSSBOW:
case eItemType::THROWN_MISSILE:
case eItemType::MISSILE_NO_AMMO:
if(s_i.ability == eItemAbil::NONE)
me["abil"].setText("Key skill: " + get_str("skills", int(s_i.weap_type) * 2 + 1));
case eItemType::ARROW:
case eItemType::BOLTS:
me["dmg"].setTextToNum(s_i.item_level);
me["bonus"].setTextToNum(s_i.bonus);
break;
case eItemType::POTION:
case eItemType::RING:
case eItemType::SCROLL: // TODO: Does this make sense for a scroll, though?
case eItemType::TOOL: // and what about for a tool?
case eItemType::WAND: // and a wand? Maybe showing ability strength would be better...
case eItemType::NECKLACE: // TODO: This doesn't seem right for a necklace...
me["lvl"].setTextToNum(s_i.item_level);
break;
case eItemType::SHIELD:
case eItemType::ARMOR:
case eItemType::HELM:
case eItemType::GLOVES:
case eItemType::SHIELD_2:
case eItemType::BOOTS: // TODO: Should this also check eItemType::PANTS?
// TODO: Why is bonus and protection combined into "bonus"? Why not use the "defense" field?
me["bonus"].setTextToNum(s_i.bonus + s_i.protection);
me["def"].setTextToNum(s_i.item_level);
me["enc"].setTextToNum(s_i.awkward);
break;
case eItemType::WEAPON_POISON:
me["lvl"].setTextToNum(s_i.item_level);
break;
default:
// no item, gold, food, non-use, unused 1 and 2: do nothing
break;
}
}
static bool display_pc_item_event_filter(cDialog& me, std::string item_hit, cItem& store_i, short& item, const short pc_num) { static bool display_pc_item_event_filter(cDialog& me, std::string item_hit, cItem& store_i, short& item, const short pc_num) {
if(item_hit == "done") { if(item_hit == "done") {
@@ -288,13 +191,13 @@ static bool display_pc_item_event_filter(cDialog& me, std::string item_hit, cIte
item = (item == 0) ? 23 : item - 1; item = (item == 0) ? 23 : item - 1;
} while(univ.party[pc_num].items[item].variety == eItemType::NO_ITEM); } while(univ.party[pc_num].items[item].variety == eItemType::NO_ITEM);
store_i = univ.party[pc_num].items[item]; store_i = univ.party[pc_num].items[item];
put_item_info(me,store_i); put_item_info(me,store_i,univ.scenario);
} else if(item_hit == "right") { } else if(item_hit == "right") {
do { do {
item = (item == 23) ? 0 : item + 1; item = (item == 23) ? 0 : item + 1;
} while(univ.party[pc_num].items[item].variety == eItemType::NO_ITEM); } while(univ.party[pc_num].items[item].variety == eItemType::NO_ITEM);
store_i = univ.party[pc_num].items[item]; store_i = univ.party[pc_num].items[item];
put_item_info(me,store_i); put_item_info(me,store_i,univ.scenario);
} }
return true; return true;
} }
@@ -316,86 +219,11 @@ void display_pc_item(short pc_num,short item,cItem si,cDialog* parent) {
itemInfo["right"].hide(); itemInfo["right"].hide();
} }
put_item_info(itemInfo,si); put_item_info(itemInfo,si,univ.scenario);
itemInfo.run(); itemInfo.run();
} }
static void put_monst_info(cDialog& me, const cCreature& store_m) {
std::string store_text;
std::string str;
short i;
cPict& pic = dynamic_cast<cPict&>(me["pic"]);
if(store_m.invisible)
pic.setPict(400,PIC_MONST);// TODO: should probably be PICT_BLANK?
else if(store_m.picture_num < 1000)
pic.setPict(store_m.picture_num,PIC_MONST);
else {
ePicType type_g = PIC_CUSTOM_MONST;
short size_g = store_m.picture_num / 1000;
switch(size_g){
case 2:
type_g += PIC_WIDE;
break;
case 3:
type_g += PIC_TALL;
break;
case 4:
type_g += PIC_WIDE;
type_g += PIC_TALL;
break;
}
pic.setPict(store_m.picture_num % 1000, type_g);
}
store_text = get_m_name(store_m.number);
me["name"].setText(store_text);
i = 1;
for(auto& abil : store_m.abil) {
if(i > 4) break; // TODO: Support showing more than just the first four abilities
if(!abil.second.active) continue;
std::string id = "abil" + std::to_string(i);
std::string name = abil.second.to_string(abil.first);
if(abil.first == eMonstAbil::SUMMON && abil.second.summon.type == eMonstSummon::TYPE)
name.replace(name.find("%s"), 2, univ.scenario.scen_monsters[abil.second.summon.what].m_name);
me[id].setText(name);
i++;
}
for(short i = 0; i < store_m.a.size(); i++) {
if(store_m.a[i].dice > 0) {
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;
me[sout.str()].setText(store_text);
}
}
me["lvl"].setTextToNum(store_m.level);
me["hp"].setTextToNum(store_m.health);
me["sp"].setTextToNum(store_m.mp);
me["def"].setTextToNum(store_m.armor);
me["skill"].setTextToNum(store_m.skill);
me["morale"].setTextToNum(store_m.morale);
me["ap"].setTextToNum(store_m.speed);
me["mage"].setTextToNum(store_m.mu);
me["priest"].setTextToNum(store_m.cl);
// Immunities
me["magic-res"].setText(std::to_string(100 - store_m.resist.at(eDamageType::MAGIC)) + '%');
me["fire-res"].setText(std::to_string(100 - store_m.resist.at(eDamageType::FIRE)) + '%');
me["cold-res"].setText(std::to_string(100 - store_m.resist.at(eDamageType::COLD)) + '%');
me["poison-res"].setText(std::to_string(100 - store_m.resist.at(eDamageType::POISON)) + '%');
dynamic_cast<cLed&>(me["mindless"]).setState(store_m.mindless ? led_red : led_off);
dynamic_cast<cLed&>(me["invuln"]).setState(store_m.invuln ? led_red : led_off);
dynamic_cast<cLed&>(me["guard"]).setState(store_m.guard ? led_red : led_off);
}
static bool display_monst_event_filter(cDialog& me, std::string item_hit, cCreature& store_m) { static bool display_monst_event_filter(cDialog& me, std::string item_hit, cCreature& store_m) {
// This is a bit hacky; keep a cPopulation here to handle the full roster; it's treated like a rotating buffer. // This is a bit hacky; keep a cPopulation here to handle the full roster; it's treated like a rotating buffer.
static cPopulation roster; static cPopulation roster;
@@ -422,7 +250,7 @@ static bool display_monst_event_filter(cDialog& me, std::string item_hit, cCreat
roster.assign(position % 60, cCreature(on_monst_menu[position]), monst, univ.party.easy_mode, univ.difficulty_adjust()); roster.assign(position % 60, cCreature(on_monst_menu[position]), monst, univ.party.easy_mode, univ.difficulty_adjust());
store_m = roster[position % 60]; store_m = roster[position % 60];
} }
put_monst_info(me, store_m); put_monst_info(me, store_m, univ.scenario);
return true; return true;
} }
@@ -452,7 +280,7 @@ void display_monst(short array_pos,cCreature *which_m,short mode) {
monstInfo["left"].hide(); monstInfo["left"].hide();
monstInfo["right"].hide(); monstInfo["right"].hide();
} }
put_monst_info(monstInfo, store_m); put_monst_info(monstInfo, store_m, univ.scenario);
monstInfo.run(); monstInfo.run();
} }

View File

@@ -56,7 +56,7 @@ void cPopulation::assign(size_t n, const cTownperson& other, const cMonster& bas
dudes[n].max_mp = dudes[n].mp = 12 * dudes[n].level; dudes[n].max_mp = dudes[n].mp = 12 * dudes[n].level;
else dudes[n].max_mp = dudes[n].mp = 0; else dudes[n].max_mp = dudes[n].mp = 0;
dudes[n].m_morale = 10 * dudes[n].level; dudes[n].m_morale = 10 * dudes[n].level;
if(dudes[n].level >= 20) if(dudes[n].level > 20)
dudes[n].m_morale += 10 * (dudes[n].level - 20); dudes[n].m_morale += 10 * (dudes[n].level - 20);
dudes[n].morale = dudes[n].m_morale; dudes[n].morale = dudes[n].m_morale;
dudes[n].direction = DIR_HERE; dudes[n].direction = DIR_HERE;

View File

@@ -30,6 +30,7 @@
#include "spell.hpp" #include "spell.hpp"
#include "mathutil.hpp" #include "mathutil.hpp"
#include "winutil.hpp" #include "winutil.hpp"
#include "view_dialogs.hpp"
extern short cen_x, cen_y,cur_town; extern short cen_x, cen_y,cur_town;
extern bool mouse_button_held; extern bool mouse_button_held;
@@ -817,6 +818,14 @@ static bool edit_monst_type_event_filter(cDialog& me,std::string hit,cMonster& m
monst.a[2].type = eMonstMelee(i); monst.a[2].type = eMonstMelee(i);
put_monst_info_in_dlog(me,monst,which); put_monst_info_in_dlog(me,monst,which);
} }
} else if(hit == "preview") {
cDialog monstInfo("monster-info", &me);
monstInfo["left"].hide();
monstInfo["right"].hide();
monstInfo.attachClickHandlers([](cDialog&,std::string,eKeyMod){return false;}, {"guard","mindless","invuln"});
monstInfo["done"].attachClickHandler(std::bind(&cDialog::toast, &monstInfo, true));
put_monst_info(monstInfo, monst, scenario);
monstInfo.run();
} }
return true; return true;
} }
@@ -853,7 +862,7 @@ bool edit_monst_type(short which) {
monst_dlg["priest"].attachFocusHandler(std::bind(check_range, _1, _2, _3, 0, 7, "priest spells")); monst_dlg["priest"].attachFocusHandler(std::bind(check_range, _1, _2, _3, 0, 7, "priest spells"));
monst_dlg["treas"].attachFocusHandler(std::bind(check_range, _1, _2, _3, 0, 4, "treasure")); monst_dlg["treas"].attachFocusHandler(std::bind(check_range, _1, _2, _3, 0, 4, "treasure"));
monst_dlg.attachFocusHandlers(check_monst_dice,{"dice1","dice2","dice3","sides1","sides2","sides3"}); monst_dlg.attachFocusHandlers(check_monst_dice,{"dice1","dice2","dice3","sides1","sides2","sides3"});
monst_dlg.attachClickHandlers(std::bind(edit_monst_type_event_filter,_1,_2,std::ref(monst),std::ref(which)),{"okay","abils","picktype","picktype1","picktype2","picktype3"}); monst_dlg.attachClickHandlers(std::bind(edit_monst_type_event_filter,_1,_2,std::ref(monst),std::ref(which)),{"okay","abils","picktype","picktype1","picktype2","picktype3","preview"});
if(scenario.scen_monsters.size() == 1){ if(scenario.scen_monsters.size() == 1){
monst_dlg["left"].hide(); monst_dlg["left"].hide();
@@ -1665,6 +1674,21 @@ static bool edit_item_type_event_filter(cDialog& me, std::string hit, cItem& ite
if(temp_item.variety != eItemType::NO_ITEM) if(temp_item.variety != eItemType::NO_ITEM)
item = temp_item; item = temp_item;
put_item_info_in_dlog(me, item, which); put_item_info_in_dlog(me, item, which);
} else if(hit == "preview") {
cItem temp_item = item;
temp_item.ident = true;
cDialog itemInfo("item-info", &me);
itemInfo["left"].hide();
itemInfo["right"].hide();
itemInfo["done"].attachClickHandler(std::bind(&cDialog::toast, &itemInfo, false));
itemInfo["magic"].attachClickHandler([](cDialog&, std::string, eKeyMod){return false;});
itemInfo["id"].attachClickHandler([&temp_item](cDialog& me, std::string, eKeyMod){
temp_item.ident = !temp_item.ident;
put_item_info(me, temp_item, scenario);
return true;
});
put_item_info(itemInfo, temp_item, scenario);
itemInfo.run();
} }
return true; return true;
} }
@@ -1718,7 +1742,7 @@ bool edit_item_type(short which) {
item_dlg["weight"].attachFocusHandler(std::bind(check_range, _1, _2, _3, 0, 250, "Weight")); item_dlg["weight"].attachFocusHandler(std::bind(check_range, _1, _2, _3, 0, 250, "Weight"));
item_dlg["class"].attachFocusHandler(std::bind(check_range, _1, _2, _3, 0, 100, "Special Class")); item_dlg["class"].attachFocusHandler(std::bind(check_range, _1, _2, _3, 0, 100, "Special Class"));
item_dlg["variety"].attachFocusHandler(std::bind(change_item_variety, _1, _2, std::ref(item))); item_dlg["variety"].attachFocusHandler(std::bind(change_item_variety, _1, _2, std::ref(item)));
item_dlg.attachClickHandlers(std::bind(edit_item_type_event_filter, _1, _2, std::ref(item), std::ref(which)), {"okay", "cancel", "abils", "choosepic", "choosetp", "choosemiss", "desc"}); item_dlg.attachClickHandlers(std::bind(edit_item_type_event_filter, _1, _2, std::ref(item), std::ref(which)), {"okay", "cancel", "abils", "choosepic", "choosetp", "choosemiss", "desc", "preview"});
if(scenario.scen_items.size() == 1) { if(scenario.scen_items.size() == 1) {
item_dlg["prev"].hide(); item_dlg["prev"].hide();

197
src/tools/view_dialogs.cpp Normal file
View File

@@ -0,0 +1,197 @@
//
// view_dialogs.cpp
// BoE
//
// Created by Celtic Minstrel on 17-01-21.
//
//
#include "view_dialogs.hpp"
#include "dialog.hpp"
#include "pict.hpp"
#include "button.hpp"
#include "item.hpp"
#include "creature.hpp"
#include "scenario.hpp"
void put_item_info(cDialog& me, const cItem& s_i, const cScenario& scen) {
std::string desc_str;
cPict& pic = dynamic_cast<cPict&>(me["pic"]);
pic.setPict(s_i.graphic_num, PIC_ITEM);
// id? magic?
cLed& id = dynamic_cast<cLed&>(me["id"]);
if(s_i.ident)
id.setState(led_red);
else id.setState(led_off);
cLed& magic = dynamic_cast<cLed&>(me["magic"]);
if(s_i.magic && s_i.ident)
magic.setState(led_red);
else magic.setState(led_off);
me["type"].setText(get_str("item-types-display", int(s_i.variety) + 1));
// Clear fields
me["val"].setText("");
me["dmg"].setText("");
me["bonus"].setText("");
me["def"].setText("");
me["enc"].setText("");
me["use"].setText("");
me["lvl"].setText("");
me["abil"].setText("");
if(!s_i.ident) {
me["name"].setText(s_i.name);
return;
}
me["name"].setText(s_i.full_name);
me["weight"].setTextToNum(s_i.item_weight());
me["desc"].setText(s_i.desc.substr(0,s_i.desc.find("|||")));
// TODO: This calculation (value for an item with charges) should be in a member function of cItem
me["val"].setTextToNum((s_i.charges > 0) ? s_i.value * s_i.charges : s_i.value);
if(s_i.ability != eItemAbil::NONE) {
if(s_i.concealed) {
me["abil"].setText("???");
} else {
std::string abil = s_i.getAbilName();
if(s_i.ability == eItemAbil::SUMMONING || s_i.ability == eItemAbil::MASS_SUMMONING)
abil.replace(abil.find("%s"), 2, scen.scen_monsters[s_i.abil_data[1]].m_name);
me["abil"].setText(abil);
}
}
if(s_i.charges > 0)
me["use"].setTextToNum(s_i.charges);
if(s_i.protection > 0)
me["def"].setTextToNum(s_i.protection);
std::string store_text;
switch(s_i.variety) {
case eItemType::ONE_HANDED:
case eItemType::TWO_HANDED:
case eItemType::BOW:
case eItemType::CROSSBOW:
case eItemType::THROWN_MISSILE:
case eItemType::MISSILE_NO_AMMO:
if(s_i.ability == eItemAbil::NONE)
me["abil"].setText("Key skill: " + get_str("skills", int(s_i.weap_type) * 2 + 1));
case eItemType::ARROW:
case eItemType::BOLTS:
me["dmg"].setTextToNum(s_i.item_level);
me["bonus"].setTextToNum(s_i.bonus);
break;
case eItemType::POTION:
case eItemType::RING:
case eItemType::SCROLL: // TODO: Does this make sense for a scroll, though?
case eItemType::TOOL: // and what about for a tool?
case eItemType::WAND: // and a wand? Maybe showing ability strength would be better...
case eItemType::NECKLACE: // TODO: This doesn't seem right for a necklace...
me["lvl"].setTextToNum(s_i.item_level);
break;
case eItemType::SHIELD:
case eItemType::ARMOR:
case eItemType::HELM:
case eItemType::GLOVES:
case eItemType::SHIELD_2:
case eItemType::BOOTS: // TODO: Should this also check eItemType::PANTS?
// TODO: Why is bonus and protection combined into "bonus"? Why not use the "defense" field?
me["bonus"].setTextToNum(s_i.bonus + s_i.protection);
me["def"].setTextToNum(s_i.item_level);
me["enc"].setTextToNum(s_i.awkward);
break;
case eItemType::WEAPON_POISON:
me["lvl"].setTextToNum(s_i.item_level);
break;
default:
// no item, gold, food, non-use, unused 1 and 2: do nothing
break;
}
}
void put_monst_info(cDialog& me, const cMonster& store_m, const cScenario& scen) {
std::string store_text;
std::string str;
short i;
cPict& pic = dynamic_cast<cPict&>(me["pic"]);
if(store_m.invisible)
pic.setPict(400,PIC_MONST);// TODO: should probably be PICT_BLANK?
else if(store_m.picture_num < 1000)
pic.setPict(store_m.picture_num,PIC_MONST);
else {
ePicType type_g = PIC_CUSTOM_MONST;
short size_g = store_m.picture_num / 1000;
switch(size_g){
case 2:
type_g += PIC_WIDE;
break;
case 3:
type_g += PIC_TALL;
break;
case 4:
type_g += PIC_WIDE;
type_g += PIC_TALL;
break;
}
pic.setPict(store_m.picture_num % 1000, type_g);
}
me["name"].setText(store_m.m_name);
i = 1;
for(auto& abil : store_m.abil) {
if(i > 4) break; // TODO: Support showing more than just the first four abilities
if(!abil.second.active) continue;
std::string id = "abil" + std::to_string(i);
std::string name = abil.second.to_string(abil.first);
if(abil.first == eMonstAbil::SUMMON && abil.second.summon.type == eMonstSummon::TYPE)
name.replace(name.find("%s"), 2, scen.scen_monsters[abil.second.summon.what].m_name);
me[id].setText(name);
i++;
}
for(short i = 0; i < store_m.a.size(); i++) {
if(store_m.a[i].dice > 0) {
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;
me[sout.str()].setText(store_text);
}
}
me["lvl"].setTextToNum(store_m.level);
me["hp"].setTextToNum(store_m.m_health);
me["sp"].setTextToNum((store_m.mu + store_m.cl) ? store_m.level * 12 : 0);
me["def"].setTextToNum(store_m.armor);
me["skill"].setTextToNum(store_m.skill);
int morale = 10 * store_m.level;
if(store_m.level > 20)
morale += 10 * (store_m.level - 20);
me["morale"].setTextToNum(morale);
me["ap"].setTextToNum(store_m.speed);
me["mage"].setTextToNum(store_m.mu);
me["priest"].setTextToNum(store_m.cl);
// Immunities
me["magic-res"].setText(std::to_string(100 - store_m.resist.at(eDamageType::MAGIC)) + '%');
me["fire-res"].setText(std::to_string(100 - store_m.resist.at(eDamageType::FIRE)) + '%');
me["cold-res"].setText(std::to_string(100 - store_m.resist.at(eDamageType::COLD)) + '%');
me["poison-res"].setText(std::to_string(100 - store_m.resist.at(eDamageType::POISON)) + '%');
dynamic_cast<cLed&>(me["mindless"]).setState(store_m.mindless ? led_red : led_off);
dynamic_cast<cLed&>(me["invuln"]).setState(store_m.invuln ? led_red : led_off);
dynamic_cast<cLed&>(me["guard"]).setState(store_m.guard ? led_red : led_off);
}
void put_monst_info(cDialog& me, const cCreature& store_m, const cScenario& scen) {
put_monst_info(me, static_cast<const cMonster&>(store_m), scen);
me["hp"].setTextToNum(store_m.health);
me["sp"].setTextToNum(store_m.mp);
me["morale"].setTextToNum(store_m.morale);
}

View File

@@ -0,0 +1,16 @@
//
// view_dialogs.hpp
// BoE
//
// Created by Celtic Minstrel on 17-01-21.
//
//
#ifndef BOE_VIEW_DIALOGS_HPP
#define BOE_VIEW_DIALOGS_HPP
void put_item_info(class cDialog& me, const class cItem& s_i, const class cScenario& scen);
void put_monst_info(class cDialog& me, const class cMonster& store_m, const class cScenario& scen);
void put_monst_info(class cDialog& me, const class cCreature& store_m, const class cScenario& scen);
#endif