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
This commit is contained in:
2015-01-20 12:16:34 -05:00
parent 09b1dc35ab
commit 54a8ae8213
5 changed files with 103 additions and 82 deletions

View File

@@ -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;

View File

@@ -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<eItemAbil, short> 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:

View File

@@ -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;

View File

@@ -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,

View File

@@ -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;