Add an info structure for eItemType enum
This commit is contained in:
@@ -2278,7 +2278,7 @@ bool damage_pc(cPlayer& which_pc,short how_much,eDamageType damage_type,eRace ty
|
||||
how_much -= minmax(-5,5,which_pc.status[eStatus::BLESS_CURSE]);
|
||||
for(short i = 0; i < which_pc.items.size(); i++) {
|
||||
if((which_pc.items[i].variety != eItemType::NO_ITEM) && (which_pc.equip[i])) {
|
||||
if(isArmourType(which_pc.items[i].variety)) {
|
||||
if((*which_pc.items[i].variety).is_armour) {
|
||||
r1 = get_ran(1,1,which_pc.items[i].item_level);
|
||||
how_much -= r1;
|
||||
|
||||
|
@@ -314,7 +314,7 @@ void put_item_screen(short screen_num) {
|
||||
style.italic = true;
|
||||
if(univ.party[pc].items[i_num].variety == eItemType::ONE_HANDED || univ.party[pc].items[i_num].variety == eItemType::TWO_HANDED)
|
||||
style.colour = sf::Color::Magenta;
|
||||
else if(isArmourType(univ.party[pc].items[i_num].variety))
|
||||
else if((*univ.party[pc].items[i_num].variety).is_armour)
|
||||
style.colour = sf::Color::Green;
|
||||
else style.colour = sf::Color::Blue;
|
||||
} else style.colour = sf::Color::Black;
|
||||
@@ -394,7 +394,7 @@ void place_buy_button(short position,short pc_num,short item_num) {
|
||||
}
|
||||
break;
|
||||
case MODE_SELL_WEAP:
|
||||
if(isWeaponType(univ.party[pc_num].items[item_num].variety) &&
|
||||
if((*univ.party[pc_num].items[item_num].variety).is_weapon &&
|
||||
(!univ.party[pc_num].equip[item_num]) &&
|
||||
(univ.party[pc_num].items[item_num].ident) && (val_to_place > 0) &&
|
||||
(!univ.party[pc_num].items[item_num].unsellable)) {
|
||||
@@ -403,7 +403,7 @@ void place_buy_button(short position,short pc_num,short item_num) {
|
||||
}
|
||||
break;
|
||||
case MODE_SELL_ARMOR:
|
||||
if(isArmourType(univ.party[pc_num].items[item_num].variety) &&
|
||||
if((*univ.party[pc_num].items[item_num].variety).is_armour &&
|
||||
(!univ.party[pc_num].equip[item_num]) &&
|
||||
(univ.party[pc_num].items[item_num].ident) && (val_to_place > 0) &&
|
||||
(!univ.party[pc_num].items[item_num].unsellable)) {
|
||||
|
@@ -24,25 +24,50 @@
|
||||
#include "spell.hpp"
|
||||
#include "race.hpp"
|
||||
|
||||
extern const std::multiset<eItemType> equippable = {
|
||||
eItemType::ONE_HANDED, eItemType::TWO_HANDED, eItemType::BOW, eItemType::ARROW, eItemType::THROWN_MISSILE,
|
||||
eItemType::TOOL, eItemType::SHIELD, eItemType::ARMOR, eItemType::HELM, eItemType::GLOVES,
|
||||
eItemType::SHIELD_2, eItemType::BOOTS, eItemType::RING, eItemType::NECKLACE, eItemType::PANTS,
|
||||
eItemType::CROSSBOW, eItemType::BOLTS, eItemType::MISSILE_NO_AMMO,
|
||||
// And these are the ones that you can equip two of
|
||||
eItemType::ONE_HANDED, eItemType::RING,
|
||||
};
|
||||
static std::array<item_variety_t, 28> load_item_type_info() {
|
||||
std::multiset<eItemType> equippable = {
|
||||
eItemType::ONE_HANDED, eItemType::TWO_HANDED, eItemType::BOW, eItemType::ARROW, eItemType::THROWN_MISSILE,
|
||||
eItemType::TOOL, eItemType::SHIELD, eItemType::ARMOR, eItemType::HELM, eItemType::GLOVES,
|
||||
eItemType::SHIELD_2, eItemType::BOOTS, eItemType::RING, eItemType::NECKLACE, eItemType::PANTS,
|
||||
eItemType::CROSSBOW, eItemType::BOLTS, eItemType::MISSILE_NO_AMMO,
|
||||
// And these are the ones that you can equip two of
|
||||
eItemType::ONE_HANDED, eItemType::RING,
|
||||
};
|
||||
|
||||
std::multiset<eItemType> num_hands_to_use = {
|
||||
eItemType::ONE_HANDED, eItemType::TWO_HANDED, eItemType::TWO_HANDED, eItemType::SHIELD, eItemType::SHIELD_2,
|
||||
};
|
||||
|
||||
// For following, if an item of type n is equipped, no other items of type n can be equipped,
|
||||
std::map<const eItemType, const eItemCat> excluding_types = {
|
||||
{eItemType::BOW, eItemCat::MISSILE_WEAPON},
|
||||
{eItemType::CROSSBOW, eItemCat::MISSILE_WEAPON},
|
||||
{eItemType::MISSILE_NO_AMMO, eItemCat::MISSILE_WEAPON},
|
||||
{eItemType::ARROW, eItemCat::MISSILE_AMMO},
|
||||
{eItemType::THROWN_MISSILE, eItemCat::MISSILE_AMMO},
|
||||
{eItemType::BOLTS, eItemCat::MISSILE_AMMO},
|
||||
};
|
||||
|
||||
std::array<item_variety_t, 28> all_info;
|
||||
int i = -1;
|
||||
for(auto& info : all_info) {
|
||||
eItemType type = eItemType(++i);
|
||||
info.self = type;
|
||||
// TODO: Maybe don't base these on i?
|
||||
info.is_armour = i >= 12 && i <= 17;
|
||||
info.is_weapon = (i >= 1 && i <= 6 && i != 3) || (i >= 23 && i <= 25);
|
||||
info.is_missile = i == 5 || i == 6 || i == 24 || i == 25;
|
||||
info.equip_count = equippable.count(type);
|
||||
info.num_hands = num_hands_to_use.count(type);
|
||||
info.exclusion = info.num_hands ? eItemCat::HANDS : excluding_types[type];
|
||||
}
|
||||
return all_info;
|
||||
}
|
||||
|
||||
extern const std::multiset<eItemType> num_hands_to_use = {
|
||||
eItemType::ONE_HANDED, eItemType::TWO_HANDED, eItemType::TWO_HANDED, eItemType::SHIELD, eItemType::SHIELD_2,
|
||||
};
|
||||
|
||||
// For following, if an item of type n is equipped, no other items of type n can be equipped,
|
||||
// TODO: Should SHIELD and SHIELD_2 have an entry here?
|
||||
std::map<const eItemType, const short> excluding_types = {
|
||||
{eItemType::BOW, 2}, {eItemType::ARROW, 1}, {eItemType::THROWN_MISSILE, 1},
|
||||
{eItemType::CROSSBOW, 2}, {eItemType::BOLTS, 1}, {eItemType::MISSILE_NO_AMMO, 2}
|
||||
};
|
||||
const item_variety_t& operator*(eItemType type) {
|
||||
static std::array<item_variety_t, 28> item_type_info = load_item_type_info();
|
||||
return item_type_info[int(type)];
|
||||
}
|
||||
|
||||
unsigned char cItem::rec_treas_class() const {
|
||||
short tmp = value;
|
||||
|
@@ -44,19 +44,18 @@ enum class eItemType {
|
||||
QUEST = 27,
|
||||
};
|
||||
|
||||
inline bool isArmourType(eItemType type) {
|
||||
int code = (int) type;
|
||||
return code >= 12 && code <= 17;
|
||||
}
|
||||
enum class eItemCat {
|
||||
MISC, MISSILE_WEAPON, MISSILE_AMMO, HANDS,
|
||||
};
|
||||
|
||||
inline bool isWeaponType(eItemType type) {
|
||||
int code = (int) type;
|
||||
return (code >= 1 && code <= 6 && code != 3) || (code >= 23 && code <= 25);
|
||||
}
|
||||
struct item_variety_t {
|
||||
eItemType self;
|
||||
bool is_armour, is_weapon, is_missile;
|
||||
int equip_count, num_hands;
|
||||
eItemCat exclusion;
|
||||
};
|
||||
|
||||
inline bool isMissileType(eItemType type) {
|
||||
return type == eItemType::ARROW || type == eItemType::BOLTS || type == eItemType::THROWN_MISSILE || type == eItemType::MISSILE_NO_AMMO;
|
||||
}
|
||||
const item_variety_t& operator*(eItemType type);
|
||||
|
||||
enum class eItemUse {HELP_ONE, HARM_ONE, HELP_ALL, HARM_ALL};
|
||||
|
||||
|
@@ -47,7 +47,6 @@ extern ter_num_t template_terrain[64][64];
|
||||
extern cScenario scenario;
|
||||
extern cCustomGraphics spec_scen_g;
|
||||
extern location cur_out;
|
||||
extern const std::multiset<eItemType> equippable;
|
||||
|
||||
const std::set<eItemAbil> items_no_strength = {
|
||||
eItemAbil::NONE, eItemAbil::HEALING_WEAPON, eItemAbil::RETURNING_MISSILE, eItemAbil::SEEKING_MISSILE, eItemAbil::DRAIN_MISSILES,
|
||||
@@ -1918,7 +1917,7 @@ static bool edit_item_abil_event_filter(cDialog& me, std::string hit, cItem& ite
|
||||
put_item_abils_in_dlog(me, item, which);
|
||||
} else if(hit == "weapon") {
|
||||
save_item_abils(me, item);
|
||||
if(!isWeaponType(item.variety)) {
|
||||
if(!(*item.variety).is_weapon) {
|
||||
showError("You can only give an ability of this sort to a weapon.","",&me);
|
||||
return true;
|
||||
}
|
||||
@@ -1936,7 +1935,7 @@ static bool edit_item_abil_event_filter(cDialog& me, std::string hit, cItem& ite
|
||||
put_item_abils_in_dlog(me, item, which);
|
||||
} else if(hit == "general") {
|
||||
save_item_abils(me, item);
|
||||
if(equippable.count(item.variety) == 0 || item.variety == eItemType::ARROW || item.variety == eItemType::THROWN_MISSILE || item.variety == eItemType::BOLTS){
|
||||
if((*item.variety).equip_count == 0 || item.variety == eItemType::ARROW || item.variety == eItemType::THROWN_MISSILE || item.variety == eItemType::BOLTS){
|
||||
showError("You can only give an ability of this sort to an non-missile item which can be equipped (like armor, or a ring).",&me);
|
||||
return true;
|
||||
}
|
||||
|
@@ -439,9 +439,9 @@ void writeItemsToXml(ticpp::Printer&& data, cScenario& scenario) {
|
||||
data.PushElement("protection", item.protection);
|
||||
if(item.charges > 0)
|
||||
data.PushElement("charges", item.charges);
|
||||
if(isWeaponType(item.variety) && item.variety != eItemType::ARROW && item.variety != eItemType::BOLTS)
|
||||
if((*item.variety).is_weapon && item.variety != eItemType::ARROW && item.variety != eItemType::BOLTS)
|
||||
data.PushElement("weapon-type", item.weap_type);
|
||||
if(item.missile > 0 || isMissileType(item.variety))
|
||||
if(item.missile > 0 || (*item.variety).is_missile)
|
||||
data.PushElement("missile-type", item.missile);
|
||||
data.PushElement("pic", item.graphic_num);
|
||||
if(item.type_flag > 0)
|
||||
|
@@ -18,10 +18,6 @@
|
||||
#include "mathutil.hpp"
|
||||
#include "fileio.hpp"
|
||||
|
||||
extern const std::multiset<eItemType> equippable;
|
||||
extern const std::multiset<eItemType> num_hands_to_use;
|
||||
extern std::map<const eItemType, const short> excluding_types;
|
||||
|
||||
extern short skill_bonus[21];
|
||||
// A nice convenient bitset with just the low 30 bits set, for initializing spells
|
||||
const uint32_t cPlayer::basic_spells = std::numeric_limits<uint32_t>::max() >> 2;
|
||||
@@ -496,24 +492,18 @@ bool cPlayer::give_item(cItem item, int flags) {
|
||||
print_result(announce.str());
|
||||
}
|
||||
|
||||
if(equip_type != 0 && equippable.count(item.variety)) {
|
||||
if(equip_type != 0 && (*item.variety).equip_count) {
|
||||
if(!equip_item(free_space.slot, false) && equip_type != GIVE_EQUIP_SOFT) {
|
||||
int exclude = 0;
|
||||
if(num_hands_to_use.count(item.variety))
|
||||
exclude = 100;
|
||||
else exclude = excluding_types[item.variety];
|
||||
eItemCat exclude = (*item.variety).exclusion;
|
||||
int rem1 = items.size(), rem2 = items.size();
|
||||
for(int i = 0; i < items.size(); i++) {
|
||||
if(i == free_space.slot) continue;
|
||||
if(!equip[i]) continue;
|
||||
int check_exclude = 0;
|
||||
if(num_hands_to_use.count(items[i].variety))
|
||||
check_exclude = 100;
|
||||
else check_exclude = excluding_types[items[i].variety];
|
||||
eItemCat check_exclude = (*items[i].variety).exclusion;
|
||||
if(exclude != check_exclude) continue;
|
||||
if(exclude == 0 && item.variety != items[i].variety)
|
||||
if(exclude == eItemCat::MISC && item.variety != items[i].variety)
|
||||
continue;
|
||||
if(exclude == 100) {
|
||||
if(exclude == eItemCat::HANDS) {
|
||||
if(rem1 == items.size()) {
|
||||
if(item.variety == eItemType::ONE_HANDED || item.variety == eItemType::TWO_HANDED || rem2 < items.size())
|
||||
rem1 = i;
|
||||
@@ -528,18 +518,13 @@ bool cPlayer::give_item(cItem item, int flags) {
|
||||
}
|
||||
bool can_rem1 = rem1 < items.size() && (!items[rem1].cursed || equip_type == GIVE_EQUIP_FORCE);
|
||||
bool can_rem2 = rem2 < items.size() && (!items[rem2].cursed || equip_type == GIVE_EQUIP_FORCE);
|
||||
if(exclude == 100) {
|
||||
if(item.variety == eItemType::TWO_HANDED) {
|
||||
if(can_rem1) equip[rem1] = false;
|
||||
if(can_rem2) equip[rem2] = false;
|
||||
} else if(item.variety == eItemType::ONE_HANDED) {
|
||||
if(exclude == eItemCat::HANDS) {
|
||||
if((*item.variety).num_hands == 2 && can_rem1 && can_rem2) {
|
||||
equip[rem1] = false;
|
||||
equip[rem2] = false;
|
||||
} else if((*item.variety).num_hands == 1) {
|
||||
if(can_rem1) equip[rem1] = false;
|
||||
else if(can_rem2) equip[rem2] = false;
|
||||
} else { // It's a shield
|
||||
if(can_rem2 && items[rem2].variety != item.variety)
|
||||
equip[rem2] = false;
|
||||
else if(can_rem1 && items[rem1].variety != item.variety)
|
||||
equip[rem1] = false;
|
||||
}
|
||||
if((rem1 == weap_poisoned.slot && !equip[rem1]) || (rem2 == weap_poisoned.slot && !equip[rem2])) {
|
||||
status[eStatus::POISONED_WEAPON] = 0;
|
||||
@@ -559,7 +544,7 @@ bool cPlayer::give_item(cItem item, int flags) {
|
||||
}
|
||||
|
||||
bool cPlayer::equip_item(int which_item, bool do_print) {
|
||||
if(!equippable.count(items[which_item].variety)) {
|
||||
if((*items[which_item].variety).equip_count == 0) {
|
||||
if(do_print && print_result)
|
||||
print_result("Equip: Can't equip this item.");
|
||||
return false;
|
||||
@@ -569,15 +554,15 @@ bool cPlayer::equip_item(int which_item, bool do_print) {
|
||||
if(equip[i]) {
|
||||
if(items[i].variety == items[which_item].variety)
|
||||
num_this_type++;
|
||||
hands_occupied += num_hands_to_use.count(items[i].variety);
|
||||
hands_occupied += (*items[i].variety).num_hands;
|
||||
}
|
||||
|
||||
|
||||
short equip_item_type = excluding_types[items[which_item].variety];
|
||||
eItemCat equip_item_type = (*items[which_item].variety).exclusion;
|
||||
// Now if missile is already equipped, no more missiles
|
||||
if(equip_item_type > 0) {
|
||||
if(equip_item_type != eItemCat::MISC) {
|
||||
for(int i = 0; i < items.size(); i++)
|
||||
if(equip[i] && excluding_types[items[i].variety] == equip_item_type) {
|
||||
if(equip[i] && (*items[i].variety).exclusion == equip_item_type) {
|
||||
if(do_print && print_result) {
|
||||
print_result("Equip: You have something of this type");
|
||||
print_result(" equipped.");
|
||||
@@ -587,11 +572,11 @@ bool cPlayer::equip_item(int which_item, bool do_print) {
|
||||
}
|
||||
|
||||
size_t hands_free = 2 - hands_occupied;
|
||||
if(hands_free < num_hands_to_use.count(items[which_item].variety)) {
|
||||
if(hands_free < (*items[which_item].variety).num_hands) {
|
||||
if(do_print && print_result)
|
||||
print_result("Equip: Not enough free hands");
|
||||
return false;
|
||||
} else if(equippable.count(items[which_item].variety) <= num_this_type) {
|
||||
} else if((*items[which_item].variety).equip_count <= num_this_type) {
|
||||
if(do_print && print_result)
|
||||
print_result("Equip: Can't equip another");
|
||||
return false;
|
||||
|
Reference in New Issue
Block a user