Merge and generalize more item abilities

- It's now possible to create an item that protects from any type of damage, status effect, or species (though some status effects may not be implemented)
- It's now possible to create slayer weapons for any species
This commit is contained in:
2015-01-13 10:35:12 -05:00
parent 84689cacaf
commit d6aeba8e0f
7 changed files with 188 additions and 169 deletions

View File

@@ -632,7 +632,11 @@ void pc_attack_weapon(short who_att,short target,short hit_adj,short dam_adj,cIt
r2 = (r2 * (10 - weap.abil_data[0])) / 10;
if(r1 <= hit_chance[univ.party[who_att].skills[what_skill]]) {
short spec_dam = calc_spec_dam(weap.ability,weap.abil_data[0],which_m);
eDamageType dmg_tp = eDamageType::UNBLOCKABLE;
short spec_dam = calc_spec_dam(weap.ability,weap.abil_data[0],weap.abil_data[1],which_m,dmg_tp);
short bonus_dam = 0;
if(dmg_tp != eDamageType::UNBLOCKABLE)
std::swap(spec_dam, bonus_dam);
if(primary) {
// assassinate
r1 = get_ran(1,1,100);
@@ -660,6 +664,8 @@ void pc_attack_weapon(short who_att,short target,short hit_adj,short dam_adj,cIt
damage_monst(target, who_att, r2, spec_dam, eDamageType::WEAPON, 0);
break;
}
if(bonus_dam)
damage_monst(target, who_att, bonus_dam, 0, dmg_tp, 0);
if(do_poison) {
// poison
if(univ.party[who_att].status[eStatus::POISONED_WEAPON] > 0) {
@@ -749,49 +755,49 @@ void pc_attack_weapon(short who_att,short target,short hit_adj,short dam_adj,cIt
}
short calc_spec_dam(eItemAbil abil,short abil_str,cCreature *monst) {
short calc_spec_dam(eItemAbil abil,short abil_str,short abil_dat,cCreature* monst,eDamageType& dmg_type) {
short store = 0;
switch(abil) {
case eItemAbil::FLAMING_WEAPON:
case eItemAbil::DAMAGING_WEAPON:
case eItemAbil::MISSILE_LIGHTNING:
store += get_ran(abil_str,1,6);
if(abil == eItemAbil::DAMAGING_WEAPON)
dmg_type = eDamageType(abil_dat);
else dmg_type = eDamageType::FIRE;
break;
case eItemAbil::DEMON_SLAYER:
if(monst->m_type == eRace::DEMON)
store += 8 * abil_str;
case eItemAbil::SLAYER_WEAPON:
case eItemAbil::MISSILE_SLAYER:
if(monst->m_type != eRace(abil_dat))
break;
case eItemAbil::MISSILE_SLAY_DEMON:
if(monst->m_type == eRace::DEMON)
store += 25 + 8 * abil_str;
store += abil_str;
switch(eRace(abil_dat)) {
case eRace::DEMON:
case eRace::GIANT:
store *= 8;
break;
case eItemAbil::MISSILE_SLAY_UNDEAD:
if(monst->m_type == eRace::UNDEAD)
store += 20 + 6 * abil_str;
case eRace::UNDEAD:
store *= 6;
break;
case eItemAbil::UNDEAD_SLAYER:
if(monst->m_type == eRace::UNDEAD)
store += 6 * abil_str;
case eRace::REPTILE:
store *= 5;
break;
case eItemAbil::LIZARD_SLAYER:
if(monst->m_type == eRace::REPTILE)
store += 5 * abil_str;
case eRace::MAGE:
case eRace::PRIEST:
store *= 4;
break;
case eItemAbil::GIANT_SLAYER:
if(monst->m_type == eRace::GIANT)
store += 8 * abil_str;
case eRace::BUG:
case eRace::PLANT:
store *= 7;
break;
case eItemAbil::MAGE_SLAYER:
if(monst->m_type == eRace::MAGE)
store += 4 * abil_str;
break;
case eItemAbil::PRIEST_SLAYER:
if(monst->m_type == eRace::PRIEST)
store += 4 * abil_str;
break;
case eItemAbil::BUG_SLAYER:
if(monst->m_type == eRace::BUG)
store += 7 * abil_str;
}
if(abil == eItemAbil::MISSILE_SLAYER) {
if(eRace(abil_dat) == eRace::DEMON)
store += 25;
else if(eRace(abil_dat) == eRace::UNDEAD)
store += 20;
else store += 10;
}
break;
case eItemAbil::CAUSES_FEAR:
scare_monst(monst,abil_str * 10);
@@ -1513,6 +1519,7 @@ void fire_missile(location target) {
add_string_to_buf(create_line);
if(overall_mode == MODE_THROWING) {
// TODO: Store the missile in cItem directly
switch(univ.party[missile_firer].items[ammo_inv_slot].item_level) {
case 7:
m_type = 10;
@@ -1539,13 +1546,17 @@ void fire_missile(location target) {
add_string_to_buf(" Missed.");
else if((targ_monst = monst_there(target)) < univ.town->max_monst()) {
cur_monst = &univ.town.monst[targ_monst];
spec_dam = calc_spec_dam(univ.party[missile_firer].items[ammo_inv_slot].ability,
univ.party[missile_firer].items[ammo_inv_slot].abil_data[0],cur_monst);
eDamageType dmg_tp = eDamageType::UNBLOCKABLE;
short bonus_dam = 0;
cItem& missile = univ.party[missile_firer].items[ammo_inv_slot];
spec_dam = calc_spec_dam(missile.ability,missile.abil_data[0],missile.abil_data[1],cur_monst,dmg_tp);
if(dmg_tp != eDamageType::UNBLOCKABLE) std::swap(bonus_dam, spec_dam);
if(univ.party[missile_firer].items[ammo_inv_slot].ability == eItemAbil::MISSILE_HEAL_TARGET) {
ASB(" There is a flash of light.");
cur_monst->health += r2;
}
else damage_monst(targ_monst, missile_firer, r2, spec_dam, eDamageType::WEAPON,13);
if(bonus_dam) damage_monst(targ_monst, missile_firer, bonus_dam, 0, dmg_tp, 0);
//if(univ.party[missile_firer].items[ammo_inv_slot].ability == 33)
// hit_space(cur_monst->m_loc,get_ran(3,1,6),1,1,1);
@@ -4129,7 +4140,7 @@ void handle_disease() {
r1 = get_ran(1,0,7);
if(univ.party[i].traits[eTrait::GOOD_CONST])
r1 -= 2;
if((get_ran(1,0,7) <= 0) || (pc_has_abil_equip(i,eItemAbil::PROTECT_FROM_DISEASE) < 24))
if((get_ran(1,0,7) <= 0) || (pc_has_abil_equip(i,eItemAbil::STATUS_PROTECTION,int(eStatus::DISEASE)) < 24))
move_to_zero(univ.party[i].status[eStatus::DISEASE]);
}
put_pc_screen();

View File

@@ -13,7 +13,7 @@ void char_parry();
void char_stand_ready();
void pc_attack(short who_att,short target);
void pc_attack_weapon(short who_att,short target,short hit_adj,short dam_adj,cItem& weap,short primary,bool do_poison);
short calc_spec_dam(eItemAbil abil,short abil_str,cCreature *monst);
short calc_spec_dam(eItemAbil abil,short abil_str,short abil_dat,cCreature* monst,eDamageType& dmg_type);
void place_target(location target);
void do_combat_cast(location target);
void handle_marked_damage();

View File

@@ -159,15 +159,18 @@ bool give_to_pc(short pc_num,cItem item,short print_result,bool allow_overload)
// TODO: Utilize the second parameter in special node processing
// if abil > 0, force abil, else ignore
bool forced_give(short item_num,eItemAbil abil) {
bool forced_give(short item_num,eItemAbil abil,short dat) {
short i,j;
cItem item;
if((item_num < 0) || (item_num > 399))
return true;
item = get_stored_item(item_num);
if(abil > eItemAbil::NONE)
if(abil > eItemAbil::NONE) {
item.ability = abil;
item.abil_data[0] = dat / 1000;
item.abil_data[1] = dat % 1000;
}
for(i = 0; i < 6; i++)
for(j = 0; j < 24; j++)
if(univ.party[i].main_status == eMainStatus::ALIVE && univ.party[i].items[j].variety == eItemType::NO_ITEM) {
@@ -216,52 +219,54 @@ bool take_gold(short amount,bool print_result) {
}
// returnes equipped protection level of specified abil, or -1 if no such abil is equipped
short get_prot_level(short pc_num,eItemAbil abil) {
short get_prot_level(short pc_num,eItemAbil abil, short dat) {
short i = 0;
for(i = 0; i < 24; i++)
if(univ.party[pc_num].items[i].variety != eItemType::NO_ITEM && (univ.party[pc_num].items[i].ability == abil)
&& (univ.party[pc_num].equip[i]))
&& univ.party[pc_num].equip[i] && (dat < 0 || dat == univ.party[pc_num].items[i].abil_data[1]))
return univ.party[pc_num].items[i].abil_data[0];
return -1;
}
short pc_has_abil_equip(short pc_num,eItemAbil abil) {
short i = 0;
while((univ.party[pc_num].items[i].variety == eItemType::NO_ITEM || univ.party[pc_num].items[i].ability != abil
|| !univ.party[pc_num].equip[i]) && (i < 24))
i++;
return i;
}
short pc_has_abil(short pc_num,eItemAbil abil) {
short i = 0;
while((univ.party[pc_num].items[i].variety == eItemType::NO_ITEM || univ.party[pc_num].items[i].ability != abil
) && (i < 24))
i++;
short pc_has_abil_equip(short pc_num,eItemAbil abil,short dat) {
for(short i = 0; i < 24; i++) {
if(univ.party[pc_num].items[i].variety == eItemType::NO_ITEM) continue;
if(univ.party[pc_num].items[i].ability != abil) continue;
if(!univ.party[pc_num].equip[i]) continue;
if(dat >= 0 && dat != univ.party[pc_num].items[i].abil_data[1]) continue;
return i;
}
return 0;
}
bool party_has_abil(eItemAbil abil) {
short pc_has_abil(short pc_num,eItemAbil abil,short dat) {
for(short i = 0; i < 24; i++) {
if(univ.party[pc_num].items[i].variety == eItemType::NO_ITEM) continue;
if(univ.party[pc_num].items[i].ability != abil) continue;
if(dat >= 0 && dat != univ.party[pc_num].items[i].abil_data[1]) continue;
return i;
}
return 0;
}
bool party_has_abil(eItemAbil abil,short dat) {
short i;
for(i = 0; i < 6; i++)
if(univ.party[i].main_status == eMainStatus::ALIVE)
if(pc_has_abil(i,abil) < 24)
if(pc_has_abil(i,abil,dat) < 24)
return true;
return false;
}
bool party_take_abil(eItemAbil abil) {
bool party_take_abil(eItemAbil abil,short dat) {
short i,item;
for(i = 0; i < 6; i++)
if(univ.party[i].main_status == eMainStatus::ALIVE)
if((item = pc_has_abil(i,abil)) < 24) {
if((item = pc_has_abil(i,abil,dat)) < 24) {
if(univ.party[i].items[item].charges > 1)
univ.party[i].items[item].charges--;
else take_item(i,item);
@@ -449,8 +454,9 @@ void enchant_weapon(short pc_num,short item_hit,short enchant_type,short new_val
case 4:
store_name += " (F!)";
univ.party[pc_num].items[item_hit].value = new_val;
univ.party[pc_num].items[item_hit].ability = eItemAbil::FLAMING_WEAPON;
univ.party[pc_num].items[item_hit].ability = eItemAbil::DAMAGING_WEAPON;
univ.party[pc_num].items[item_hit].abil_data[0] = 5;
univ.party[pc_num].items[item_hit].abil_data[1] = int(eDamageType::FIRE);
break;
case 5:
store_name += " (+5)";

View File

@@ -4,15 +4,15 @@
void sort_pc_items(short pc_num);
bool give_to_pc(short pc_num,cItem item,short print_result,bool allow_overload = false);
bool forced_give(short item_num,eItemAbil abil);
bool forced_give(short item_num,eItemAbil abil,short dat = -1);
bool GTP(short item_num);
bool silent_GTP(short item_num);
void give_gold(short amount,bool print_result);
bool take_gold(short amount,bool print_result);
short pc_has_abil_equip(short pc_num,eItemAbil abil);
short pc_has_abil(short pc_num,eItemAbil abil);
bool party_has_abil(eItemAbil abil);
bool party_take_abil(eItemAbil abil);
short pc_has_abil_equip(short pc_num,eItemAbil abil,short dat = -1);
short pc_has_abil(short pc_num,eItemAbil abil,short dat = -1);
bool party_has_abil(eItemAbil abil,short dat = -1);
bool party_take_abil(eItemAbil abil,short dat = -1);
bool party_check_class(unsigned int item_class,short mode);
short pc_carry_weight(short pc_num);
short amount_pc_can_carry(short pc_num);
@@ -32,7 +32,7 @@ void combine_things(short pc_num);
short dist_from_party(location where);
void set_item_flag(cItem *item);
short get_item(location place,short pc_num,bool check_container);
short get_prot_level(short pc_num,eItemAbil abil);
short get_prot_level(short pc_num,eItemAbil abil,short dat = -1);
void make_town_hostile();
void set_town_attitude(short lo,short hi,short att);

View File

@@ -379,9 +379,12 @@ void cure_party(short amt) {
// if how_much < 0, bless
void curse_pc(short which_pc,short how_much) {
int level;
if(univ.party[which_pc].main_status != eMainStatus::ALIVE)
return;
if(univ.party[which_pc].main_status == eMainStatus::ALIVE) {
if(how_much > 0 && (level = get_prot_level(which_pc,eItemAbil::STATUS_PROTECTION,int(eStatus::BLESS_CURSE))) > 0)
how_much -= level / 2;
univ.party[which_pc].status[eStatus::BLESS_CURSE] = minmax(-8,8,univ.party[which_pc].status[eStatus::BLESS_CURSE] - how_much);
if(how_much < 0)
add_string_to_buf(" " + univ.party[which_pc].name + " blessed.");
@@ -396,7 +399,7 @@ void curse_pc(short which_pc,short how_much) {
}
void dumbfound_pc(short which_pc,short how_much) {
short r1;
short r1,level;
if(univ.party[which_pc].main_status != eMainStatus::ALIVE)
return;
@@ -405,6 +408,8 @@ void dumbfound_pc(short which_pc,short how_much) {
add_string_to_buf(" Ring of Will glows.");
r1 -= 10;
}
if((level = get_prot_level(which_pc,eItemAbil::STATUS_PROTECTION,int(eStatus::DUMB))) > 0)
how_much -= level / 4;
if(r1 < univ.party[which_pc].level)
how_much -= 2;
if(how_much <= 0) {
@@ -433,7 +438,7 @@ void disease_pc(short which_pc,short how_much) {
add_string_to_buf(" " + univ.party[which_pc].name + " saved.");
return;
}
if((level = get_prot_level(which_pc,eItemAbil::PROTECT_FROM_DISEASE)) > 0)
if((level = get_prot_level(which_pc,eItemAbil::STATUS_PROTECTION,int(eStatus::DISEASE))) > 0)
how_much -= level / 2;
if(univ.party[which_pc].traits[eTrait::FRAIL] && how_much > 1)
how_much++;
@@ -462,7 +467,8 @@ void sleep_pc(short which_pc,short how_much,eStatus what_type,short adjust) {
how_much -= level / 2;
if((level = get_prot_level(which_pc,eItemAbil::FREE_ACTION)) > 0)
how_much -= (what_type == eStatus::ASLEEP) ? level : level * 300;
if((level = get_prot_level(which_pc,eItemAbil::STATUS_PROTECTION,int(what_type))) > 0)
how_much -= level / 4;
}
r1 = get_ran(1,1,100) + adjust;
@@ -493,10 +499,12 @@ void sleep_pc(short which_pc,short how_much,eStatus what_type,short adjust) {
// if how_much < 0, haste
void slow_pc(short which_pc,short how_much) {
int level;
if(univ.party[which_pc].main_status != eMainStatus::ALIVE)
return;
if(univ.party[which_pc].main_status == eMainStatus::ALIVE) {
if(how_much > 0 && (level = get_prot_level(which_pc,eItemAbil::STATUS_PROTECTION,int(eStatus::HASTE_SLOW))) > 0)
how_much -= level / 2;
univ.party[which_pc].status[eStatus::HASTE_SLOW] = minmax(-8,8,univ.party[which_pc].status[eStatus::HASTE_SLOW] - how_much);
if(how_much < 0)
add_string_to_buf(" " + univ.party[which_pc].name + " hasted.");
@@ -508,9 +516,12 @@ void slow_pc(short which_pc,short how_much) {
}
void web_pc(short which_pc,short how_much) {
int level;
if(univ.party[which_pc].main_status != eMainStatus::ALIVE)
return;
if(univ.party[which_pc].main_status == eMainStatus::ALIVE) {
if((level = get_prot_level(which_pc,eItemAbil::STATUS_PROTECTION,int(eStatus::WEBS))) > 0)
how_much -= level / 2;
univ.party[which_pc].status[eStatus::WEBS] = min(univ.party[which_pc].status[eStatus::WEBS] + how_much,8);
add_string_to_buf(" " + univ.party[which_pc].name + " webbed.");
one_sound(17);
@@ -522,7 +533,7 @@ void web_pc(short which_pc,short how_much) {
void acid_pc(short which_pc,short how_much) {
if(univ.party[which_pc].main_status != eMainStatus::ALIVE)
return;
if(pc_has_abil_equip(which_pc,eItemAbil::ACID_PROTECTION) < 24) {
if(pc_has_abil_equip(which_pc,eItemAbil::STATUS_PROTECTION,int(eStatus::ACID)) < 24) {
add_string_to_buf(" " + univ.party[which_pc].name + " resists acid.");
return;
}
@@ -2536,7 +2547,7 @@ void poison_pc(short which_pc,short how_much) {
short level;
if(univ.party[which_pc].main_status == eMainStatus::ALIVE) {
if((level = get_prot_level(which_pc,eItemAbil::POISON_PROTECTION)) > 0)
if((level = get_prot_level(which_pc,eItemAbil::STATUS_PROTECTION,int(eStatus::POISON))) > 0)
how_much -= level / 2;
if((level = get_prot_level(which_pc,eItemAbil::FULL_PROTECTION)) > 0)
how_much -= level / 3;
@@ -2574,6 +2585,9 @@ void affect_pc(short which_pc,eStatus type,short how_much) {
eStatus::MAGIC_RESISTANCE, eStatus::DUMB,
};
// TODO: Apply STATUS_PROTECTION item abilities; the challenge is to determine whether to apply to positive or negative how_much
// TODO: I'd like to merge poison_pc, web_pc, acid_pc etc into this function.
if(univ.party[which_pc].main_status != eMainStatus::ALIVE)
return;
univ.party[which_pc].status[type] = minmax (-8,8,univ.party[which_pc].status[type] + how_much);
@@ -2685,42 +2699,24 @@ bool damage_pc(short which_pc,short how_much,eDamageType damage_type,eRace type_
how_much -= 1;
}
if(damage_type == eDamageType::WEAPON && ((level = get_prot_level(which_pc,eItemAbil::PROTECTION)) > 0))
how_much = how_much - level;
if(damage_type == eDamageType::UNDEAD && ((level = get_prot_level(which_pc,eItemAbil::PROTECT_FROM_UNDEAD)) > 0))
if((level = get_prot_level(which_pc,eItemAbil::DAMAGE_PROTECTION,int(damage_type))) > 0) {
if(damage_type == eDamageType::WEAPON) how_much -= level;
else how_much = how_much / ((level >= 7) ? 4 : 2);
}
// TODO: Do these perhaps depend on the ability strength less than they should?
if((level = get_prot_level(which_pc,eItemAbil::PROTECT_FROM_SPECIES,int(type_of_attacker))) > 0)
how_much = how_much / ((level >= 7) ? 4 : 2);
if(damage_type == eDamageType::DEMON && ((level = get_prot_level(which_pc,eItemAbil::PROTECT_FROM_DEMONS)) > 0))
how_much = how_much / ((level >= 7) ? 4 : 2);
if((type_of_attacker == eRace::HUMANOID) && ((level = get_prot_level(which_pc,eItemAbil::PROTECT_FROM_HUMANOIDS)) > 0))
how_much = how_much / ((level >= 7) ? 4 : 2);
// TODO: Should sliths be counted as reptiles?
if((type_of_attacker == eRace::REPTILE) && ((level = get_prot_level(which_pc,eItemAbil::PROTECT_FROM_REPTILES)) > 0))
how_much = how_much / ((level >= 7) ? 4 : 2);
if((type_of_attacker == eRace::GIANT) && ((level = get_prot_level(which_pc,eItemAbil::PROTECT_FROM_GIANTS)) > 0))
how_much = how_much / ((level >= 7) ? 4 : 2);
// invuln
if(univ.party[which_pc].status[eStatus::INVULNERABLE] > 0)
how_much = 0;
// magic resistance
if(damage_type == eDamageType::MAGIC && ((level = get_prot_level(which_pc,eItemAbil::MAGIC_PROTECTION)) > 0))
how_much = how_much / ((level >= 7) ? 4 : 2);
// Mag. res helps w. fire and cold
// TODO: Why doesn't this help with magic damage?
if((damage_type == eDamageType::FIRE || damage_type == eDamageType::COLD) &&
univ.party[which_pc].status[eStatus::MAGIC_RESISTANCE] > 0)
how_much = how_much / 2;
// fire res.
if(damage_type == eDamageType::FIRE && ((level = get_prot_level(which_pc,eItemAbil::FIRE_PROTECTION)) > 0))
how_much = how_much / ((level >= 7) ? 4 : 2);
// cold res.
if(damage_type == eDamageType::COLD && ((level = get_prot_level(which_pc,eItemAbil::COLD_PROTECTION)) > 0))
how_much = how_much / ((level >= 7) ? 4 : 2);
// major resistance
if((damage_type == eDamageType::FIRE || damage_type == eDamageType::POISON || damage_type == eDamageType::MAGIC || damage_type == eDamageType::COLD)
&& ((level = get_prot_level(which_pc,eItemAbil::FULL_PROTECTION)) > 0))

View File

@@ -266,31 +266,39 @@ void cItem::append(legacy::item_record_type& old){
case 0:
ability = eItemAbil::NONE;
break;
case 1:
ability = eItemAbil::FLAMING_WEAPON;
case 1: // Flaming weapon
ability = eItemAbil::DAMAGING_WEAPON;
abil_data[1] = int(eDamageType::UNBLOCKABLE);
break;
case 2:
ability = eItemAbil::DEMON_SLAYER;
case 2: // Demon slayer
ability = eItemAbil::SLAYER_WEAPON;
abil_data[1] = int(eRace::DEMON);
break;
case 3:
ability = eItemAbil::UNDEAD_SLAYER;
case 3: // Undead slayer
ability = eItemAbil::SLAYER_WEAPON;
abil_data[1] = int(eRace::UNDEAD);
break;
case 4:
ability = eItemAbil::LIZARD_SLAYER;
case 4: // Lizard slayer
ability = eItemAbil::SLAYER_WEAPON;
abil_data[1] = int(eRace::REPTILE);
break;
case 5:
ability = eItemAbil::GIANT_SLAYER;
case 5: // Giant slayer
ability = eItemAbil::SLAYER_WEAPON;
abil_data[1] = int(eRace::GIANT);
break;
case 6:
ability = eItemAbil::MAGE_SLAYER;
case 6: // Mage slayer
ability = eItemAbil::SLAYER_WEAPON;
abil_data[1] = int(eRace::MAGE);
break;
case 7:
ability = eItemAbil::PRIEST_SLAYER;
case 7: // Priest slayer
ability = eItemAbil::SLAYER_WEAPON;
abil_data[1] = int(eRace::PRIEST);
break;
case 8:
ability = eItemAbil::BUG_SLAYER;
case 8: // Bug slayer
ability = eItemAbil::SLAYER_WEAPON;
abil_data[1] = int(eRace::BUG);
break;
case 9:
case 9: // Acidic weapon
ability = eItemAbil::STATUS_WEAPON;
abil_data[1] = int(eStatus::ACID);
break;
@@ -306,31 +314,37 @@ void cItem::append(legacy::item_record_type& old){
case 13:
ability = eItemAbil::CAUSES_FEAR;
break;
case 14:
case 14: // Poisoned weapon
ability = eItemAbil::STATUS_WEAPON;
abil_data[1] = int(eStatus::POISON);
break;
// General abilities
case 30:
ability = eItemAbil::PROTECTION;
case 30: // Protection
ability = eItemAbil::DAMAGE_PROTECTION;
abil_data[1] = int(eDamageType::WEAPON);
break;
case 31:
ability = eItemAbil::FULL_PROTECTION;
break;
case 32:
ability = eItemAbil::FIRE_PROTECTION;
case 32: // Fire protection
ability = eItemAbil::DAMAGE_PROTECTION;
abil_data[1] = int(eDamageType::FIRE);
break;
case 33:
ability = eItemAbil::COLD_PROTECTION;
case 33: // Cold protection
ability = eItemAbil::DAMAGE_PROTECTION;
abil_data[1] = int(eDamageType::COLD);
break;
case 34:
ability = eItemAbil::POISON_PROTECTION;
case 34: // Poison protection
ability = eItemAbil::STATUS_PROTECTION;
abil_data[1] = int(eStatus::POISON);
break;
case 35:
ability = eItemAbil::MAGIC_PROTECTION;
case 35: // Magic protection
ability = eItemAbil::DAMAGE_PROTECTION;
abil_data[1] = int(eDamageType::MAGIC);
break;
case 36:
ability = eItemAbil::ACID_PROTECTION;
case 36: // Acid protection
ability = eItemAbil::STATUS_PROTECTION;
abil_data[1] = int(eStatus::ACID);
break;
case 37:
ability = eItemAbil::SKILL;
@@ -392,23 +406,29 @@ void cItem::append(legacy::item_record_type& old){
case 56:
ability = eItemAbil::SLOW_WEARER;
break;
case 57:
ability = eItemAbil::PROTECT_FROM_UNDEAD;
case 57: // Protect from undead
ability = eItemAbil::DAMAGE_PROTECTION;
abil_data[1] = int(eDamageType::UNDEAD);
break;
case 58:
ability = eItemAbil::PROTECT_FROM_DEMONS;
case 58: // Protect from demons
ability = eItemAbil::DAMAGE_PROTECTION;
abil_data[1] = int(eDamageType::DEMON);
break;
case 59:
ability = eItemAbil::PROTECT_FROM_HUMANOIDS;
case 59: // Protect from humanoids
ability = eItemAbil::PROTECT_FROM_SPECIES;
abil_data[1] = int(eRace::HUMANOID);
break;
case 60:
ability = eItemAbil::PROTECT_FROM_REPTILES;
case 60: // Protect from reptiles
ability = eItemAbil::PROTECT_FROM_SPECIES;
abil_data[1] = int(eRace::REPTILE);
break;
case 61:
ability = eItemAbil::PROTECT_FROM_GIANTS;
case 61: // Protect from giants
ability = eItemAbil::PROTECT_FROM_SPECIES;
abil_data[1] = int(eRace::GIANT);
break;
case 62:
ability = eItemAbil::PROTECT_FROM_DISEASE;
case 62: // Protect from disease
ability = eItemAbil::STATUS_PROTECTION;
abil_data[1] = int(eStatus::DISEASE);
break;
// Usable abilities
case 70:
@@ -677,10 +697,12 @@ void cItem::append(legacy::item_record_type& old){
ability = eItemAbil::MISSILE_ACID;
break;
case 174:
ability = eItemAbil::MISSILE_SLAY_UNDEAD;
ability = eItemAbil::MISSILE_SLAYER;
abil_data[1] = int(eRace::UNDEAD);
break;
case 175:
ability = eItemAbil::MISSILE_SLAY_DEMON;
ability = eItemAbil::MISSILE_SLAYER;
abil_data[1] = int(eRace::DEMON);
break;
case 176:
ability = eItemAbil::MISSILE_HEAL_TARGET;

View File

@@ -292,27 +292,17 @@ inline bool isWeaponType(eItemType type) {
enum class eItemAbil {
// Weapon abilities
NONE = 0,
FLAMING_WEAPON = 1,
DEMON_SLAYER = 2,
UNDEAD_SLAYER = 3,
LIZARD_SLAYER = 4,
GIANT_SLAYER = 5,
MAGE_SLAYER = 6,
PRIEST_SLAYER = 7,
BUG_SLAYER = 8,
DAMAGING_WEAPON = 1,
SLAYER_WEAPON = 2,
STATUS_WEAPON = 9,
SOULSUCKER = 10,
DRAIN_MISSILES = 11,
WEAK_WEAPON = 12,
CAUSES_FEAR = 13,
// General abilities
PROTECTION = 30,
DAMAGE_PROTECTION = 30,
FULL_PROTECTION = 31,
FIRE_PROTECTION = 32,
COLD_PROTECTION = 33,
POISON_PROTECTION = 34,
MAGIC_PROTECTION = 35,
ACID_PROTECTION = 36,
STATUS_PROTECTION = 36,
SKILL = 37,
STRENGTH = 38,
DEXTERITY = 39,
@@ -333,12 +323,7 @@ enum class eItemAbil {
FREE_ACTION = 54,
SPEED = 55,
SLOW_WEARER = 56,
PROTECT_FROM_UNDEAD = 57,
PROTECT_FROM_DEMONS = 58,
PROTECT_FROM_HUMANOIDS = 59,
PROTECT_FROM_REPTILES = 60,
PROTECT_FROM_GIANTS = 61,
PROTECT_FROM_DISEASE = 62,
PROTECT_FROM_SPECIES = 57,
// Nonspell Usable
POISON_WEAPON = 70, //put poison on weapon
AFFECT_STATUS = 71,
@@ -376,8 +361,7 @@ enum class eItemAbil {
MISSILE_LIGHTNING = 171,
MISSILE_EXPLODING = 172,
MISSILE_ACID = 173,
MISSILE_SLAY_UNDEAD = 174,
MISSILE_SLAY_DEMON = 175,
MISSILE_SLAYER = 174,
MISSILE_HEAL_TARGET = 176,
};