Move abil_chart to be private to cItem and fix missing entries for summoning and quickfire abilities
This commit is contained in:
@@ -80,15 +80,6 @@ static void start_cartoon() {
|
||||
cartoon_happening = true;
|
||||
}
|
||||
|
||||
// 0 - can't use 1 - combat only 2 - town only 3 - town & combat only 4 - everywhere 5 - outdoor
|
||||
// + 10 - mag. inept can use
|
||||
std::map<eItemAbil, short> abil_chart = {
|
||||
{eItemAbil::POISON_WEAPON,13}, {eItemAbil::AFFECT_STATUS,3}, {eItemAbil::BLISS_DOOM,3}, {eItemAbil::AFFECT_EXPERIENCE,4},
|
||||
{eItemAbil::AFFECT_SKILL_POINTS,4}, {eItemAbil::AFFECT_HEALTH,4}, {eItemAbil::AFFECT_SPELL_POINTS,4},
|
||||
{eItemAbil::LIGHT,13}, {eItemAbil::AFFECT_PARTY_STATUS,3}, {eItemAbil::HEALTH_POISON,4},
|
||||
{eItemAbil::CALL_SPECIAL,4}, {eItemAbil::CAST_SPELL,4}, {eItemAbil::MESSAGE,14},
|
||||
};
|
||||
|
||||
// which is unused
|
||||
//short mode; // 0 - pre 1 - end by victory 2 - end by flight
|
||||
// wanderin spec 99 -> generic spec
|
||||
@@ -553,47 +544,19 @@ void use_spec_item(short item) {
|
||||
|
||||
|
||||
void use_item(short pc,short item) {
|
||||
bool take_charge = true,inept_ok = false;
|
||||
short level,item_use_code,str,r1;
|
||||
bool take_charge = true;
|
||||
short level,str,r1;
|
||||
short sp[3] = {}; // Dummy values to pass to run_special; not actually used
|
||||
std::string str1, str2; // Used by books
|
||||
eStatus status;
|
||||
eItemUse type;
|
||||
eSpell spell;
|
||||
location user_loc;
|
||||
eItemAbil abil = univ.party[pc].items[item].ability;
|
||||
const cItem& item_rec = univ.party[pc].items[item];
|
||||
eItemAbil abil = item_rec.ability;
|
||||
bool inept_ok = !item_rec.use_magic();
|
||||
level = univ.party[pc].items[item].item_level;
|
||||
|
||||
// TODO: Replace abil_chart with a cItem member function
|
||||
item_use_code = abil_chart[abil];
|
||||
if(item_use_code >= 10) {
|
||||
item_use_code -= 10;
|
||||
inept_ok = true;
|
||||
}
|
||||
if(abil == eItemAbil::AFFECT_STATUS) {
|
||||
status = eStatus(univ.party[pc].items[item].abil_data[1]);
|
||||
if(status == eStatus::POISON || status == eStatus::DISEASE || status == eStatus::HASTE_SLOW || status == eStatus:: BLESS_CURSE)
|
||||
item_use_code = 4;
|
||||
} else if(abil == eItemAbil::CAST_SPELL) {
|
||||
spell = eSpell(univ.party[pc].items[item].abil_data[1]);
|
||||
int when = (*spell).when_cast;
|
||||
// Rather than trying to translate the spell's "when cast" value to the less expressive item_use_code,
|
||||
// simply check if it's useable in the current context.
|
||||
if(is_out() && when & WHEN_OUTDOORS)
|
||||
item_use_code = 5;
|
||||
else if(is_town() && when & WHEN_TOWN)
|
||||
item_use_code = 2;
|
||||
else if(is_combat() && when & WHEN_COMBAT)
|
||||
item_use_code = 1;
|
||||
else {
|
||||
// It's not useable in the current context, so translate to the item_use_code that gives the best error message
|
||||
if(is_town() || is_out())
|
||||
item_use_code = 1;
|
||||
else item_use_code = 2;
|
||||
}
|
||||
} else if(abil == eItemAbil::AFFECT_PARTY_STATUS && univ.party[pc].items[item].abil_data[1] == int(ePartyStatus::FLIGHT))
|
||||
item_use_code = 5;
|
||||
|
||||
if(is_out())
|
||||
user_loc = univ.party.out_loc;
|
||||
if(is_town())
|
||||
@@ -601,7 +564,7 @@ void use_item(short pc,short item) {
|
||||
if(is_combat())
|
||||
user_loc = univ.current_pc().combat_pos;
|
||||
|
||||
if(item_use_code == 0) {
|
||||
if(!item_rec.can_use()) {
|
||||
add_string_to_buf("Use: Can't use this item.");
|
||||
take_charge = false;
|
||||
}
|
||||
@@ -610,25 +573,23 @@ void use_item(short pc,short item) {
|
||||
take_charge = false;
|
||||
}
|
||||
|
||||
// 0 - can't use 1 - combat only 2 - town only 3 - town & combat only 4 - everywhere 5 - outdoor
|
||||
if(take_charge) {
|
||||
if(overall_mode == MODE_OUTDOORS && item_use_code < 4) {
|
||||
if(overall_mode == MODE_OUTDOORS && !item_rec.use_outdoors()) {
|
||||
add_string_to_buf("Use: Not while outdoors.");
|
||||
take_charge = false;
|
||||
}
|
||||
// TODO: Almost all of these look wrong!
|
||||
if((overall_mode == MODE_TOWN) && (item_use_code == 1)) {
|
||||
if((overall_mode != MODE_OUTDOORS) && !item_rec.use_in_town() && !item_rec.use_in_combat()){
|
||||
add_string_to_buf("Use: Only outdoors.");
|
||||
take_charge = false;
|
||||
}
|
||||
if((overall_mode == MODE_TOWN) && !item_rec.use_in_town()) {
|
||||
add_string_to_buf("Use: Not while in town.");
|
||||
take_charge = false;
|
||||
}
|
||||
if((overall_mode == MODE_COMBAT) && (item_use_code == 2)) {
|
||||
if((overall_mode == MODE_COMBAT) && !item_rec.use_in_combat()) {
|
||||
add_string_to_buf("Use: Not in combat.");
|
||||
take_charge = false;
|
||||
}
|
||||
if((overall_mode != MODE_OUTDOORS) && (item_use_code == 5)){
|
||||
add_string_to_buf("Use: Only outdoors.");
|
||||
take_charge = false;
|
||||
}
|
||||
}
|
||||
if(take_charge) {
|
||||
cItem& the_item = univ.party[pc].items[item];
|
||||
|
@@ -72,7 +72,6 @@ extern enum_map(eItemButton, bool) item_area_button_active[8];
|
||||
extern enum_map(ePlayerButton, bool) pc_area_button_active[6];
|
||||
extern rectangle item_screen_button_rects[9];
|
||||
extern std::vector<int> spec_item_array;
|
||||
extern std::map<eItemAbil, short> abil_chart;
|
||||
// combat globals
|
||||
extern short item_bottom_button_active[9];
|
||||
extern cUniverse univ;
|
||||
@@ -322,7 +321,7 @@ void put_item_screen(eItemWinMode screen_num) {
|
||||
if((stat_screen_mode == MODE_SHOP) &&
|
||||
((is_town()) || (is_out()) || ((is_combat()) && (pc == univ.cur_pc)))) { // place give and drop and use
|
||||
place_item_graphic(i,univ.party[pc].items[i_num].graphic_num);
|
||||
if(abil_chart[univ.party[pc].items[i_num].ability]) // place use if can
|
||||
if(item.can_use()) // place use if can
|
||||
place_item_button(ITEMBTN_NORM,i);
|
||||
else place_item_button(ITEMBTN_ALL,i);
|
||||
}
|
||||
@@ -333,7 +332,7 @@ void put_item_screen(eItemWinMode screen_num) {
|
||||
((is_town()) || (is_out()) || ((is_combat()) && (pc == univ.cur_pc)))) { // place give and drop and use
|
||||
place_item_button(1,i,ITEMBTN_GIVE);
|
||||
place_item_button(2,i,ITEMBTN_DROP);
|
||||
if(abil_chart[item.ability]) // place use if can
|
||||
if(item.can_use()) // place use if can
|
||||
place_item_button(0,i,ITEMBTN_USE);
|
||||
}
|
||||
}
|
||||
|
@@ -1358,3 +1358,65 @@ void cItem::readFrom(std::istream& sin){
|
||||
else if(cur == "UNSELLABLE") unsellable = true;
|
||||
}
|
||||
}
|
||||
|
||||
enum {USE_COMBAT = 1, USE_TOWN = 2, USE_OUTDOORS = 4, USE_MAGIC = 8};
|
||||
|
||||
std::map<eItemAbil, short> abil_chart = {
|
||||
{eItemAbil::POISON_WEAPON, USE_TOWN | USE_COMBAT},
|
||||
{eItemAbil::AFFECT_STATUS, USE_TOWN | USE_COMBAT | USE_MAGIC}, // This is the default, some statuses can also be used outdoors though
|
||||
// CAST_SPELL is omitted, taken from the spell's info
|
||||
{eItemAbil::BLISS_DOOM, USE_TOWN | USE_COMBAT | USE_MAGIC},
|
||||
{eItemAbil::AFFECT_EXPERIENCE, USE_TOWN | USE_COMBAT | USE_OUTDOORS | USE_MAGIC},
|
||||
{eItemAbil::AFFECT_SKILL_POINTS, USE_TOWN | USE_COMBAT | USE_OUTDOORS | USE_MAGIC},
|
||||
{eItemAbil::AFFECT_HEALTH, USE_TOWN | USE_COMBAT | USE_OUTDOORS | USE_MAGIC},
|
||||
{eItemAbil::AFFECT_SPELL_POINTS, USE_TOWN | USE_COMBAT | USE_OUTDOORS | USE_MAGIC},
|
||||
{eItemAbil::LIGHT, USE_TOWN | USE_COMBAT},
|
||||
{eItemAbil::AFFECT_PARTY_STATUS, USE_TOWN | USE_COMBAT | USE_MAGIC},
|
||||
{eItemAbil::HEALTH_POISON, USE_TOWN | USE_COMBAT | USE_OUTDOORS | USE_MAGIC},
|
||||
{eItemAbil::CALL_SPECIAL, USE_TOWN | USE_COMBAT | USE_OUTDOORS | USE_MAGIC},
|
||||
{eItemAbil::SUMMONING, USE_TOWN | USE_COMBAT | USE_MAGIC},
|
||||
{eItemAbil::MASS_SUMMONING, USE_TOWN | USE_COMBAT | USE_MAGIC},
|
||||
{eItemAbil::QUICKFIRE, USE_TOWN | USE_COMBAT | USE_MAGIC},
|
||||
{eItemAbil::MESSAGE, USE_TOWN | USE_COMBAT | USE_OUTDOORS},
|
||||
};
|
||||
|
||||
bool cItem::use_in_combat() const {
|
||||
if(ability == eItemAbil::CAST_SPELL) {
|
||||
auto spell = eSpell(abil_data[1]);
|
||||
int when = (*spell).when_cast;
|
||||
return when & WHEN_COMBAT;
|
||||
} else if(ability == eItemAbil::AFFECT_PARTY_STATUS && abil_data[1] == int(ePartyStatus::FLIGHT))
|
||||
return false;
|
||||
return abil_chart[ability] & USE_COMBAT;
|
||||
}
|
||||
|
||||
bool cItem::use_in_town() const {
|
||||
if(ability == eItemAbil::CAST_SPELL) {
|
||||
auto spell = eSpell(abil_data[1]);
|
||||
int when = (*spell).when_cast;
|
||||
return when & WHEN_TOWN;
|
||||
} else if(ability == eItemAbil::AFFECT_PARTY_STATUS && abil_data[1] == int(ePartyStatus::FLIGHT))
|
||||
return false;
|
||||
return abil_chart[ability] & USE_TOWN;
|
||||
}
|
||||
|
||||
bool cItem::use_outdoors() const {
|
||||
if(ability == eItemAbil::CAST_SPELL) {
|
||||
auto spell = eSpell(abil_data[1]);
|
||||
int when = (*spell).when_cast;
|
||||
return when & WHEN_OUTDOORS;
|
||||
} else if(ability == eItemAbil::AFFECT_STATUS) {
|
||||
auto status = eStatus(abil_data[1]);
|
||||
if(status == eStatus::POISON || status == eStatus::DISEASE || status == eStatus::HASTE_SLOW || status == eStatus:: BLESS_CURSE)
|
||||
return true;
|
||||
}
|
||||
return abil_chart[ability] & USE_OUTDOORS;
|
||||
}
|
||||
|
||||
bool cItem::use_magic() const {
|
||||
return abil_chart[ability] & USE_MAGIC;
|
||||
}
|
||||
|
||||
bool cItem::can_use() const {
|
||||
return use_in_town() || use_in_combat() || use_outdoors();
|
||||
}
|
||||
|
@@ -52,6 +52,11 @@ public:
|
||||
void enchant_weapon(eEnchant enchant_type, short new_val);
|
||||
bool abil_harms() const;
|
||||
bool abil_group() const;
|
||||
bool can_use() const;
|
||||
bool use_in_combat() const;
|
||||
bool use_in_town() const;
|
||||
bool use_outdoors() const;
|
||||
bool use_magic() const;
|
||||
|
||||
cItem();
|
||||
explicit cItem(long preset);
|
||||
|
Reference in New Issue
Block a user