Some item ability stuff

- Two new item abilities that increase damage as sp/hp is lost
- Two new item abilities that reduce damage as sp/hp is lost
- Support for using sp/hp as a weapon's key skill to determine hit chance
This commit is contained in:
2015-10-12 14:11:27 -04:00
parent b61200f627
commit ba984279b0
8 changed files with 50 additions and 13 deletions

View File

@@ -702,11 +702,16 @@ static void apply_weapon_status(eStatus status, int how_much, int dmg, iLiving&
void pc_attack_weapon(short who_att,iLiving& target,short hit_adj,short dam_adj,cItem& weap,short primary,bool do_poison) {
short r1, r2;
cPlayer& attacker = univ.party[who_att];
eSkill what_skill = weap.weap_type;
// safety valve
if(what_skill == eSkill::INVALID)
what_skill = eSkill::EDGED_WEAPONS;
int skill;
if(weap.weap_type == eSkill::INVALID)
skill = univ.party[who_att].skill(eSkill::EDGED_WEAPONS);
else if(weap.weap_type == eSkill::MAX_HP)
skill = 20 * univ.party[who_att].cur_health / univ.party[who_att].m_health;
else if(weap.weap_type == eSkill::MAX_SP)
skill = 20 * univ.party[who_att].cur_sp / univ.party[who_att].max_sp;
else skill = univ.party[who_att].skill(weap.weap_type);
std::string create_line = attacker.name + " swings.";
add_string_to_buf(create_line);
@@ -734,6 +739,14 @@ void pc_attack_weapon(short who_att,iLiving& target,short hit_adj,short dam_adj,
if(primary) r2 += 2; else r2 -= 1;
if(weap.ability == eItemAbil::WEAK_WEAPON)
r2 = (r2 * (10 - weap.abil_data[0])) / 10;
if(weap.ability == eItemAbil::HP_DAMAGE)
r2 = std::max<short>(1, double(r2) * double(attacker.cur_health) / double(attacker.max_health));
if(weap.ability == eItemAbil::SP_DAMAGE)
r2 = std::max<short>(1, double(r2) * double(attacker.cur_sp) / double(attacker.max_sp));
if(weap.ability == eItemAbil::HP_DAMAGE_REVERSE)
r2 += double(weap.abil_data[0]) * (1.0 - double(attacker.cur_health) / double(attacker.max_health));
if(weap.ability == eItemAbil::SP_DAMAGE_REVERSE)
r2 += double(weap.abil_data[0]) * (1.0 - double(attacker.cur_sp) / double(attacker.max_sp));
if(cPlayer* pc_target = dynamic_cast<cPlayer*>(&target)) {
// PCs get some additional defensive perks
@@ -755,7 +768,7 @@ void pc_attack_weapon(short who_att,iLiving& target,short hit_adj,short dam_adj,
do_explosion_anim(5,0);
end_missile_anim();
handle_marked_damage();
} else if(r1 <= hit_chance[univ.party[who_att].skill(what_skill)]) {
} else if(r1 <= hit_chance[skill]) {
eDamageType dmg_tp = eDamageType::SPECIAL;
short spec_dam = calc_spec_dam(weap.ability,weap.abil_data[0],weap.abil_data[1],target,dmg_tp);
short bonus_dam = 0;
@@ -1714,7 +1727,13 @@ void fire_missile(location target) {
cItem& missile = missile_firer.items[missile_inv_slot];
cItem& ammo = missile_firer.items[ammo_inv_slot];
skill = missile_firer.skill(missile.weap_type);
if(missile.weap_type == eSkill::INVALID)
skill = missile_firer.skill(eSkill::ARCHERY);
else if(missile.weap_type == eSkill::MAX_HP)
skill = 20 * missile_firer.cur_health / missile_firer.m_health;
else if(missile.weap_type == eSkill::MAX_SP)
skill = 20 * missile_firer.cur_sp / missile_firer.max_sp;
else skill = missile_firer.skill(missile.weap_type);
range = (overall_mode == MODE_FIRING) ? 12 : 8;
dam = ammo.item_level;
dam_bonus = ammo.bonus + minmax(-8,8,missile_firer.status[eStatus::BLESS_CURSE]);
@@ -1795,6 +1814,14 @@ void fire_missile(location target) {
r2 = get_ran(1,1,dam) + dam_bonus;
if(ammo.ability == eItemAbil::WEAK_WEAPON)
r2 = (r2 * (10 - ammo.abil_data[0])) / 10;
if(ammo.ability == eItemAbil::HP_DAMAGE)
r2 = std::max<short>(1, double(r2) * double(missile_firer.cur_health) / double(missile_firer.max_health));
if(ammo.ability == eItemAbil::SP_DAMAGE)
r2 = std::max<short>(1, double(r2) * double(missile_firer.cur_sp) / double(missile_firer.max_sp));
if(ammo.ability == eItemAbil::HP_DAMAGE_REVERSE)
r2 += double(ammo.abil_data[0]) * (1.0 - double(missile_firer.cur_health) / double(missile_firer.max_health));
if(ammo.ability == eItemAbil::SP_DAMAGE_REVERSE)
r2 += double(ammo.abil_data[0]) * (1.0 - double(missile_firer.cur_sp) / double(missile_firer.max_sp));
std::string create_line = missile_firer.name + " fires.";
add_string_to_buf(create_line);

View File

@@ -1180,6 +1180,7 @@ void use_item(short pc,short item) {
case eItemAbil::SMOKY_CRYSTAL: case eItemAbil::SOULSUCKER: case eItemAbil::SPEED: case eItemAbil::STATUS_PROTECTION:
case eItemAbil::STATUS_WEAPON: case eItemAbil::THIEVING: case eItemAbil::WEAK_WEAPON: case eItemAbil::WEAPON_CALL_SPECIAL:
case eItemAbil::WORMGRASS: case eItemAbil::UNUSED: case eItemAbil::DROP_CALL_SPECIAL:
case eItemAbil::HP_DAMAGE: case eItemAbil::HP_DAMAGE_REVERSE: case eItemAbil::SP_DAMAGE: case eItemAbil::SP_DAMAGE_REVERSE:
break;
}
}

View File

@@ -152,6 +152,7 @@ template<typename E> bool readEnum(std::istream& in, E& to, cEnumLookup& tbl, E
cEnumLookup skill_names = {
"str", "dex", "int", "edged", "bashing", "pole", "thrown", "archery", "defense",
"mage", "priest", "mage-lore", "alchemy", "item-lore", "traps", "lockpick", "assassin", "poison", "luck",
"hp", "sp",
};
std::ostream& operator << (std::ostream& out, eSkill e) {
@@ -203,9 +204,9 @@ std::istream& operator >> (std::istream& in, eItemUse& e){
cEnumLookup item_abils = {
"none", "weap-dmg", "weap-slay", "weap-heal", "weap-explode", "weap-return", "weap-dist", "weap-seek", "weap-antimagic", "weap-status",
"weap-soulsuck", "", "weap-weak", "weap-fear", "spec-weap", "", "", "", "", "",
"weap-soulsuck", "", "weap-weak", "weap-fear", "spec-weap", "hp-dmg", "hp-dmg-rev", "sp-dmg", "sp-dmg-rev", "",
"", "", "", "", "", "", "", "", "", "",
"prot-dmg", "prot-full", "prot-melee", "evade", "martyr", "encumber", "prot-status", "skill", "boost-stat", "boost-war",
"prot-dmg", "prot-full", "magery", "evade", "martyr", "encumber", "prot-status", "skill", "boost-stat", "boost-war",
"boost-magic", "accuracy", "thief", "giant", "light", "heavy", "status", "spec-hit", "save-life", "prot-petrify",
"regen", "poison-aug", "radiant", "will", "freedom", "speed", "slow", "prot-race", "lockpick", "missile-drain",
"spec-drop", "", "", "", "", "", "", "", "", "",

View File

@@ -975,6 +975,10 @@ std::string cItem::getAbilName() const {
case eItemAbil::SOULSUCKER: sout << "Soulsucker"; break;
case eItemAbil::DRAIN_MISSILES: sout << "Drain Missiles"; break;
case eItemAbil::WEAK_WEAPON: sout << "Weak Weapon"; break;
case eItemAbil::HP_DAMAGE: sout << "Damage Linked to Health"; break;
case eItemAbil::HP_DAMAGE_REVERSE: sout << "Berserker's Weapon"; break;
case eItemAbil::SP_DAMAGE: sout << "Damage Linked to Spell Points"; break;
case eItemAbil::SP_DAMAGE_REVERSE: sout << "Wildmage's Weapon"; break;
case eItemAbil::CAUSES_FEAR: sout << "Causes Fear"; break;
case eItemAbil::WEAPON_CALL_SPECIAL: sout << "Unusual Attack Effect"; break;
case eItemAbil::FULL_PROTECTION: sout << "Full Protection"; break;

View File

@@ -394,6 +394,10 @@ enum class eItemAbil {
WEAK_WEAPON = 12,
CAUSES_FEAR = 13,
WEAPON_CALL_SPECIAL = 14,
HP_DAMAGE = 15,
HP_DAMAGE_REVERSE = 16,
SP_DAMAGE = 17,
SP_DAMAGE_REVERSE = 18,
// General abilities
DAMAGE_PROTECTION = 30,
FULL_PROTECTION = 31,

View File

@@ -1894,7 +1894,7 @@ static bool edit_item_abil_event_filter(cDialog& me, std::string hit, cItem& ite
showError("You can only give an ability of this sort to a weapon.","",&me);
return true;
}
i = choose_text_res("item-abilities", 1, 14, int(item.ability), &me, "Choose Weapon Ability (inherent)");
i = choose_text_res("item-abilities", 1, 18, int(item.ability), &me, "Choose Weapon Ability (inherent)");
if(i < 0) return true;
eItemAbil abil = eItemAbil(i + 1);
if(abil >= eItemAbil::RETURNING_MISSILE && abil <= eItemAbil::SEEKING_MISSILE) {