From 54a8ae82133db93e133760da252b2acc0348946c Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Tue, 20 Jan 2015 12:16:34 -0500 Subject: [PATCH] Merge more item abilities - Bliss and doom merged into single ability (distinguished by item use type) - The three party status abilities merged into one - Major healing now has a negative version - Summoning and mass summoning now use first ability data to determine duration; second ability data determines monster - Added generic use message for spell abilities that didn't already have a specialized message - Mass summoning no longer redundantly recalculates random number of summons after each summon --- src/boe.party.cpp | 1 + src/boe.specials.cpp | 134 ++++++++++++++++++++------------------ src/classes/item.cpp | 33 ++++++++-- src/classes/simpletypes.h | 9 +-- src/classes/universe.cpp | 8 +-- 5 files changed, 103 insertions(+), 82 deletions(-) diff --git a/src/boe.party.cpp b/src/boe.party.cpp index c9b27915..c20c2ec4 100644 --- a/src/boe.party.cpp +++ b/src/boe.party.cpp @@ -2593,6 +2593,7 @@ bool damage_pc(short which_pc,short how_much,eDamageType damage_type,eRace type_ if(univ.party[which_pc].main_status != eMainStatus::ALIVE) return false; + // TODO: I think there should be a way to force sound_type = 0 for UNBLOCKABLE if(sound_type == 0) { if(damage_type == eDamageType::FIRE || damage_type == eDamageType::UNBLOCKABLE) sound_type = 5; diff --git a/src/boe.specials.cpp b/src/boe.specials.cpp index 172d0a8e..91f40ced 100644 --- a/src/boe.specials.cpp +++ b/src/boe.specials.cpp @@ -72,9 +72,9 @@ bool special_in_progress = false; // 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 abil_chart = { - {eItemAbil::POISON_WEAPON,13}, {eItemAbil::AFFECT_STATUS,3}, {eItemAbil::BLISS,3}, {eItemAbil::AFFECT_EXPERIENCE,4}, - {eItemAbil::AFFECT_SKILL_POINTS,4}, {eItemAbil::AFFECT_HEALTH,4}, {eItemAbil::AFFECT_SPELL_POINTS,4}, {eItemAbil::DOOM,3}, - {eItemAbil::LIGHT,13}, {eItemAbil::STEALTH,3}, {eItemAbil::FIREWALK,3}, {eItemAbil::FLYING,5}, {eItemAbil::MAJOR_HEALING,4}, + {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}, }; @@ -632,7 +632,8 @@ void use_item(short pc,short item) { 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.p_loc; @@ -892,18 +893,34 @@ void use_item(short pc,short item) { } break; } - case eItemAbil::BLISS: + case eItemAbil::BLISS_DOOM: switch(type) { - case 0: case 1: + case 0: ASB(" You feel wonderful!"); heal_pc(pc,str * 20); univ.party[pc].apply_status(eStatus::BLESS_CURSE,str); break; - case 2: case 3: + case 1: + ASB(" You feel terrible."); + drain_pc(pc,str * 5); + damage_pc(pc,20 * str,eDamageType::UNBLOCKABLE,eRace::HUMAN,0); + disease_pc(pc,2 * str); + dumbfound_pc(pc,2 * str); + break; + case 2: ASB(" Everyone feels wonderful!"); heal_party(str*20); univ.party.apply_status(eStatus::BLESS_CURSE,str); break; + case 3: + ASB(" You all feel terrible."); + for(i = 0; i < 6; i++) { + drain_pc(i,str * 5); + damage_pc(i,20 * str,eDamageType::UNBLOCKABLE,eRace::HUMAN,0); + disease_pc(i,2 * str); + dumbfound_pc(i,2 * str); + } + break; } break; case eItemAbil::AFFECT_EXPERIENCE: @@ -992,66 +1009,51 @@ void use_item(short pc,short item) { break; } break; - case eItemAbil::DOOM: - switch(type) { - case 0: case 1: - ASB(" You feel terrible."); - drain_pc(pc,str * 5); - damage_pc(pc,20 * str,eDamageType::UNBLOCKABLE,eRace::HUMAN,0); - disease_pc(pc,2 * str); - dumbfound_pc(pc,2 * str); - break; - case 2: case 3: - ASB(" You all feel terrible."); - for(i = 0; i < 6; i++) { - drain_pc(i,str * 5); - damage_pc(i,20 * str,eDamageType::UNBLOCKABLE,eRace::HUMAN,0); - disease_pc(i,2 * str); - dumbfound_pc(i,2 * str); - } - break; - } - break; case eItemAbil::LIGHT: ASB(" You have more light."); increase_light(50 * str); break; - case eItemAbil::STEALTH: - ASB(" Your footsteps become quieter."); - univ.party.status[ePartyStatus::STEALTH] += 5 * str; - break; - case eItemAbil::FIREWALK: - ASB(" You feel chilly."); - univ.party.status[ePartyStatus::FIREWALK] += 2 * str; - break; - case eItemAbil::FLYING: - if(univ.party.status[ePartyStatus::FLIGHT] > 0) { - add_string_to_buf(" Not while already flying. "); - take_charge = false; - break; - } - if(univ.party.in_boat >= 0) { - add_string_to_buf(" Leave boat first. "); - take_charge = false; - } else if(univ.party.in_horse >= 0) { - add_string_to_buf(" Leave horse first. "); - take_charge = false; - } else { - ASB(" You rise into the air!"); - univ.party.status[ePartyStatus::FLIGHT] += str; - } - break; - case eItemAbil::MAJOR_HEALING: - switch(type) { - case 0: case 1: - ASB(" You feel wonderful."); - heal_pc(pc,200); - cure_pc(pc,8); + case eItemAbil::AFFECT_PARTY_STATUS: + switch(ePartyStatus(univ.party[pc].items[item].abil_data[1])) { + case ePartyStatus::STEALTH: ASB(" Your footsteps become quieter."); str *= 5; break; + case ePartyStatus::FIREWALK: ASB(" You feel chilly."); str *= 2; break; + case ePartyStatus::DETECT_LIFE: ASB(" You detect life."); break; + case ePartyStatus::FLIGHT: + if(univ.party.status[ePartyStatus::FLIGHT] > 0) { + add_string_to_buf(" Not while already flying. "); + take_charge = false; + } else if(univ.party.in_boat >= 0) { + add_string_to_buf(" Leave boat first. "); + take_charge = false; + } else if(univ.party.in_horse >= 0) { + add_string_to_buf(" Leave horse first. "); + take_charge = false; + } else ASB(" You rise into the air!"); break; - case 2: case 3: + } + if(take_charge) univ.party.status[ePartyStatus(univ.party[pc].items[item].abil_data[1])] += str; + break; + case eItemAbil::HEALTH_POISON: + switch(type) { + case 0: + ASB(" You feel wonderful."); + heal_pc(pc,str*25); + cure_pc(pc,str); + break; + case 1: + ASB(" You feel terrible."); + damage_pc(pc, str*25, eDamageType::UNBLOCKABLE, eRace::UNKNOWN, 0); + poison_pc(pc,str); + break; + case 2: ASB(" You all feel wonderful."); - heal_party(200); - cure_party(8); + heal_party(str*25); + cure_party(str); + break; + case 3: + ASB(" You all feel terrible."); + hit_party(str*25, eDamageType::UNBLOCKABLE); + poison_party(str); break; } break; @@ -1088,6 +1090,7 @@ void use_item(short pc,short item) { case eSpell::WALL_ICE_BALL: add_string_to_buf(" It shoots a blue sphere."); break; case eSpell::CHARM_FOE: add_string_to_buf(" It fires a lovely, sparkling beam."); break; case eSpell::ANTIMAGIC: add_string_to_buf(" Your hair stands on end."); break; + default: add_string_to_buf(" It casts a spell: " + (*spell).name()); break; } if(overall_mode == MODE_COMBAT) { bool priest = (*spell).is_priest(); @@ -1112,13 +1115,14 @@ void use_item(short pc,short item) { else do_mage_spell(current_pc, spell, true); break; case eItemAbil::SUMMONING: - if(!summon_monster(str,user_loc,50,2)) + if(!summon_monster(univ.party[pc].items[item].abil_data[1],user_loc,str,2)) add_string_to_buf(" Summon failed."); break; case eItemAbil::MASS_SUMMONING: - r1 = get_ran(6,1,4); - for(i = 0; i < get_ran(1,3,5); i++) // TODO: Why recalculate the random number for each loop iteration? - if(!summon_monster(str,user_loc,r1,2)) + r1 = get_ran(str,1,4); + j = get_ran(1,3,5); + for(i = 0; i < j; i++) + if(!summon_monster(univ.party[pc].items[item].abil_data[1],user_loc,r1,2)) add_string_to_buf(" Summon failed."); break; case eItemAbil::QUICKFIRE: diff --git a/src/classes/item.cpp b/src/classes/item.cpp index b1874b16..67afb42f 100644 --- a/src/classes/item.cpp +++ b/src/classes/item.cpp @@ -343,7 +343,7 @@ cItem::cItem(eAlchemy recipe) : cItem('alch') { break; case eAlchemy::BLISS: value = 250; - ability = eItemAbil::BLISS; + ability = eItemAbil::BLISS_DOOM; abil_data[0] = 5; break; case eAlchemy::POWER_STRONG: @@ -615,7 +615,11 @@ void cItem::append(legacy::item_record_type& old){ abil_data[1] = int(eStatus::ACID); break; case 84: - ability = eItemAbil::BLISS; + ability = eItemAbil::BLISS_DOOM; + if(magic_use_type == 1) + magic_use_type = 0; + else if(magic_use_type == 3) + magic_use_type = 2; break; case 85: ability = eItemAbil::AFFECT_EXPERIENCE; @@ -630,22 +634,33 @@ void cItem::append(legacy::item_record_type& old){ ability = eItemAbil::AFFECT_SPELL_POINTS; break; case 89: - ability = eItemAbil::DOOM; + ability = eItemAbil::BLISS_DOOM; + if(magic_use_type == 0) + magic_use_type = 1; + else if(magic_use_type == 2) + magic_use_type = 3; break; case 90: ability = eItemAbil::LIGHT; break; case 91: - ability = eItemAbil::STEALTH; + ability = eItemAbil::AFFECT_PARTY_STATUS; + abil_data[1] = int(ePartyStatus::STEALTH); break; case 92: - ability = eItemAbil::FIREWALK; + ability = eItemAbil::AFFECT_PARTY_STATUS; + abil_data[1] = int(ePartyStatus::FIREWALK); break; case 93: - ability = eItemAbil::FLYING; + ability = eItemAbil::AFFECT_PARTY_STATUS; + abil_data[1] = int(ePartyStatus::FLIGHT); break; case 94: - ability = eItemAbil::MAJOR_HEALING; + ability = eItemAbil::HEALTH_POISON; + if(magic_use_type == 1) + magic_use_type = 0; + else if(magic_use_type == 3) + magic_use_type = 2; break; case 95: ability = eItemAbil::CALL_SPECIAL; @@ -698,9 +713,13 @@ void cItem::append(legacy::item_record_type& old){ break; case 119: ability = eItemAbil::SUMMONING; + abil_data[1] = abil_data[0]; + abil_data[0] = 50; break; case 120: ability = eItemAbil::MASS_SUMMONING; + abil_data[1] = abil_data[0]; + abil_data[0] = 6; break; case 121: ability = eItemAbil::CAST_SPELL; diff --git a/src/classes/simpletypes.h b/src/classes/simpletypes.h index 8483ff94..d6b8f74c 100644 --- a/src/classes/simpletypes.h +++ b/src/classes/simpletypes.h @@ -350,17 +350,14 @@ enum class eItemAbil { POISON_WEAPON = 70, //put poison on weapon AFFECT_STATUS = 71, CAST_SPELL = 72, - BLISS = 84, + BLISS_DOOM = 84, AFFECT_EXPERIENCE = 85, AFFECT_SKILL_POINTS = 86, AFFECT_HEALTH = 87, AFFECT_SPELL_POINTS = 88, - DOOM = 89, LIGHT = 90, - STEALTH = 91, - FIREWALK = 92, - FLYING = 93, - MAJOR_HEALING = 94, + AFFECT_PARTY_STATUS = 91, + HEALTH_POISON = 94, CALL_SPECIAL = 95, SUMMONING = 119, MASS_SUMMONING = 120, diff --git a/src/classes/universe.cpp b/src/classes/universe.cpp index 739ae7f7..c441db85 100644 --- a/src/classes/universe.cpp +++ b/src/classes/universe.cpp @@ -907,7 +907,7 @@ void cUniverse::check_item(cItem& item) { else if(item.graphic_num >= 1000) update_items[item.graphic_num - 1000].insert(&item); if(item.ability == eItemAbil::SUMMONING || item.ability == eItemAbil::MASS_SUMMONING) { - mon_num_t monst = item.abil_data[0]; + mon_num_t monst = item.abil_data[1]; if(monst >= 10000) check_monst(party.summons[monst - 10000]); else check_monst(scenario.scen_monsters[monst]); @@ -1031,7 +1031,7 @@ void cUniverse::exportSummons() { for(size_t j = 0; j < party[i].items.size(); j++) { if(party[i].items[j].variety == eItemType::NO_ITEM) continue; if(party[i].items[j].ability == eItemAbil::SUMMONING || party[i].items[j].ability == eItemAbil::MASS_SUMMONING) { - mon_num_t monst = party[i].items[j].abil_data[0]; + mon_num_t monst = party[i].items[j].abil_data[1]; if(monst >= 10000) used_monsters.insert(monst - 10000); else { @@ -1045,7 +1045,7 @@ void cUniverse::exportSummons() { for(size_t j = 0; j < party.stored_items[i].size(); j++) { if(party.stored_items[i][j].variety == eItemType::NO_ITEM) continue; if(party.stored_items[i][j].ability == eItemAbil::SUMMONING||party.stored_items[i][j].ability == eItemAbil::MASS_SUMMONING) { - mon_num_t monst = party.stored_items[i][j].abil_data[0]; + mon_num_t monst = party.stored_items[i][j].abil_data[1]; if(monst >= 10000) used_monsters.insert(monst - 10000); else { @@ -1092,7 +1092,7 @@ void cUniverse::exportSummons() { party.summons[dest] = scenario.scen_monsters[monst]; else party.summons.push_back(scenario.scen_monsters[monst]); for(auto& item : update_items[monst]) - item->abil_data[0] = 10000 + dest; + item->abil_data[1] = 10000 + dest; for(int i = 0; i < 4; i++) if(party.imprisoned_monst[i] == monst) party.imprisoned_monst[i] = dest + 10000;