Revert petrify to being handled by freestanding functions

- Also change kill/damage to take a player/monster reference instead of an index
This commit is contained in:
2015-02-02 12:41:17 -05:00
parent 1d733d081c
commit ea49a13ff8
16 changed files with 245 additions and 260 deletions

View File

@@ -1900,7 +1900,7 @@ bool handle_keystroke(sf::Event& event){
if((univ.town.monst[i].active > 0) && (univ.town.monst[i].attitude % 2 == 1) if((univ.town.monst[i].active > 0) && (univ.town.monst[i].attitude % 2 == 1)
&& (dist(univ.town.monst[i].cur_loc,univ.town.p_loc) <= 10) ) && (dist(univ.town.monst[i].cur_loc,univ.town.p_loc) <= 10) )
damage_monst(i, 7,1000,eDamageType::UNBLOCKABLE,0); damage_monst(univ.town.monst[i], 7,1000,eDamageType::UNBLOCKABLE,0);
} }
// kill_monst(&univ.town.monst[i],6); // kill_monst(&univ.town.monst[i],6);
draw_terrain(); draw_terrain();
@@ -2549,7 +2549,7 @@ void drop_pc(short which) {
return; return;
} }
add_string_to_buf("Delete PC: OK."); add_string_to_buf("Delete PC: OK.");
kill_pc(which,eMainStatus::ABSENT); kill_pc(univ.party[which],eMainStatus::ABSENT);
for(short i = which; i < 5; i++) for(short i = which; i < 5; i++)
univ.party.swap_pcs(i, i + 1); univ.party.swap_pcs(i, i + 1);
univ.party[5].main_status = eMainStatus::ABSENT; univ.party[5].main_status = eMainStatus::ABSENT;

View File

@@ -577,11 +577,11 @@ void pc_attack(short who_att,iLiving* target) {
} }
if(r1 <= hit_chance[attacker.skill(eSkill::DEXTERITY)]) { if(r1 <= hit_chance[attacker.skill(eSkill::DEXTERITY)]) {
size_t i_monst = univ.get_target_i(*target);
// TODO: Change to damage_target() // TODO: Change to damage_target()
if(i_monst >= 100) if(cCreature* m_target = dynamic_cast<cCreature*>(target))
damage_monst(i_monst - 100, who_att, r2, eDamageType::WEAPON,4); damage_monst(*m_target, who_att, r2, eDamageType::WEAPON,4);
else damage_pc(i_monst, r2, eDamageType::WEAPON, univ.party[who_att].race, 4); else if(cPlayer* pc_target = dynamic_cast<cPlayer*>(target))
damage_pc(*pc_target, r2, eDamageType::WEAPON, univ.party[who_att].race, 4);
} }
else { else {
draw_terrain(2); draw_terrain(2);
@@ -604,7 +604,7 @@ void pc_attack(short who_att,iLiving* target) {
if(target->is_shielded()) { if(target->is_shielded()) {
int how_much = target->get_shared_dmg(store_hp - target->get_health()); int how_much = target->get_shared_dmg(store_hp - target->get_health());
add_string_to_buf(" Shares damage!"); add_string_to_buf(" Shares damage!");
damage_pc(who_att, how_much, eDamageType::MAGIC,eRace::UNKNOWN,0); damage_pc(attacker, how_much, eDamageType::MAGIC,eRace::UNKNOWN,0);
} }
} }
combat_posing_monster = current_working_monster = -1; combat_posing_monster = current_working_monster = -1;
@@ -783,21 +783,21 @@ void pc_attack_weapon(short who_att,iLiving& target,short hit_adj,short dam_adj,
bool damaged = false; bool damaged = false;
if(cCreature* monst = dynamic_cast<cCreature*>(&target)) { if(cCreature* monst = dynamic_cast<cCreature*>(&target)) {
if(dmg_snd != no_dmg) if(dmg_snd != no_dmg)
damaged = damaged || damage_monst(i_monst - 100, who_att, r2, eDamageType::WEAPON, dmg_snd, false); damaged = damaged || damage_monst(*monst, who_att, r2, eDamageType::WEAPON, dmg_snd, false);
if(spec_dam) if(spec_dam)
damaged = damaged || damage_monst(i_monst - 100, who_att, spec_dam, eDamageType::SPECIAL, 5, false); damaged = damaged || damage_monst(*monst, who_att, spec_dam, eDamageType::SPECIAL, 5, false);
if(bonus_dam) if(bonus_dam)
damaged = damaged || damage_monst(i_monst - 100, who_att, bonus_dam, dmg_tp, 0, false); damaged = damaged || damage_monst(*monst, who_att, bonus_dam, dmg_tp, 0, false);
if(damaged) if(damaged)
monst->damaged_msg(r2, spec_dam + bonus_dam); monst->damaged_msg(r2, spec_dam + bonus_dam);
} else if(cPlayer* who = dynamic_cast<cPlayer*>(&target)) { } else if(cPlayer* who = dynamic_cast<cPlayer*>(&target)) {
eRace race = univ.party[who_att].race; eRace race = univ.party[who_att].race;
if(dmg_snd != no_dmg) if(dmg_snd != no_dmg)
damaged = damaged || damage_pc(i_monst, r2, eDamageType::WEAPON, race, dmg_snd, false); damaged = damaged || damage_pc(*who, r2, eDamageType::WEAPON, race, dmg_snd, false);
if(spec_dam) if(spec_dam)
damaged = damaged || damage_pc(i_monst, spec_dam, eDamageType::SPECIAL, race, dmg_snd, false); damaged = damaged || damage_pc(*who, spec_dam, eDamageType::SPECIAL, race, dmg_snd, false);
if(bonus_dam) if(bonus_dam)
damaged = damaged || damage_pc(i_monst, bonus_dam, eDamageType::SPECIAL, race, dmg_snd, false); damaged = damaged || damage_pc(*who, bonus_dam, eDamageType::SPECIAL, race, dmg_snd, false);
if(damaged) { if(damaged) {
std::string msg = " " + who->name + " takes " + std::to_string(r2); std::string msg = " " + who->name + " takes " + std::to_string(r2);
if(spec_dam + bonus_dam) if(spec_dam + bonus_dam)
@@ -978,7 +978,7 @@ void place_target(location target) {
} }
void do_combat_cast(location target) { void do_combat_cast(location target) {
short adjust,r1,r2,targ_num,level,bonus = 1,i,item; short adjust,r1,r2,level,bonus = 1,i,item;
snd_num_t store_sound = 0; snd_num_t store_sound = 0;
bool freebie = false,ap_taken = false,cost_taken = false; bool freebie = false,ap_taken = false,cost_taken = false;
short num_targets = 1; short num_targets = 1;
@@ -1322,7 +1322,7 @@ void do_combat_cast(location target) {
store_sound = 53; store_sound = 53;
r1 = get_ran(4,1,8); r1 = get_ran(4,1,8);
r2 = get_ran(1,0,2); r2 = get_ran(1,0,2);
damage_monst(targ_num, 7, r1, eDamageType::MAGIC,0); damage_monst(*cur_monst, 7, r1, eDamageType::MAGIC,0);
victim->slow(4 + r2); victim->slow(4 + r2);
victim->poison(5 + r2); victim->poison(5 + r2);
break; break;
@@ -1472,10 +1472,10 @@ void do_combat_cast(location target) {
add_string_to_buf(" Monster resisted."); add_string_to_buf(" Monster resisted.");
else { else {
r1 = get_ran((spell_being_cast == eSpell::TURN_UNDEAD) ? 2 : 6, 1, 14); r1 = get_ran((spell_being_cast == eSpell::TURN_UNDEAD) ? 2 : 6, 1, 14);
size_t i_targ = univ.get_target_i(*victim); if(cur_monst != nullptr)
if(i_targ < 100) damage_monst(*cur_monst, current_pc, r1, eDamageType::UNBLOCKABLE, 0);
damage_pc(i_targ, r1, eDamageType::UNBLOCKABLE, eRace::UNKNOWN, 0); else if(cPlayer* who = dynamic_cast<cPlayer*>(victim))
else damage_monst(i_targ, current_pc, r1, eDamageType::UNBLOCKABLE, 0); damage_pc(*who, r1, eDamageType::UNBLOCKABLE, eRace::UNKNOWN, 0);
} }
store_sound = 24; store_sound = 24;
break; break;
@@ -1499,10 +1499,10 @@ void do_combat_cast(location target) {
r1 = get_ran(8 + bonus * 2, 1, 11); r1 = get_ran(8 + bonus * 2, 1, 11);
if(univ.party[spell_caster].status[eStatus::DUMB] < 0) if(univ.party[spell_caster].status[eStatus::DUMB] < 0)
r1 += -25 * univ.party[spell_caster].status[eStatus::DUMB] / 3; r1 += -25 * univ.party[spell_caster].status[eStatus::DUMB] / 3;
size_t i_targ = univ.get_target_i(*victim); if(cur_monst != nullptr)
if(i_targ < 100) damage_monst(*cur_monst, current_pc, r1, eDamageType::UNBLOCKABLE, 0);
damage_pc(i_targ, r1, eDamageType::UNBLOCKABLE, eRace::UNKNOWN, 0); else if(cPlayer* who = dynamic_cast<cPlayer*>(victim))
else damage_monst(i_targ, current_pc, r1, eDamageType::UNBLOCKABLE, 0); damage_pc(*who, r1, eDamageType::UNBLOCKABLE, eRace::UNKNOWN, 0);
} }
store_sound = 24; store_sound = 24;
break; break;
@@ -1551,12 +1551,12 @@ void handle_marked_damage() {
for(i = 0; i < 6; i++) for(i = 0; i < 6; i++)
if(univ.party[i].marked_damage > 0) { if(univ.party[i].marked_damage > 0) {
damage_pc(i,univ.party[i].marked_damage,eDamageType::MARKED,eRace::UNKNOWN,0); damage_pc(univ.party[i],univ.party[i].marked_damage,eDamageType::MARKED,eRace::UNKNOWN,0);
univ.party[i].marked_damage = 0; univ.party[i].marked_damage = 0;
} }
for(i = 0; i < univ.town.monst.size(); i++) for(i = 0; i < univ.town.monst.size(); i++)
if(univ.town.monst[i].marked_damage > 0) { if(univ.town.monst[i].marked_damage > 0) {
damage_monst(i, current_pc, univ.town.monst[i].marked_damage, eDamageType::MARKED,0); damage_monst(univ.town.monst[i], current_pc, univ.town.monst[i].marked_damage, eDamageType::MARKED,0);
univ.town.monst[i].marked_damage = 0; univ.town.monst[i].marked_damage = 0;
} }
@@ -1758,15 +1758,16 @@ void fire_missile(location target) {
ASB(" There is a flash of light."); ASB(" There is a flash of light.");
victim->heal(r2); victim->heal(r2);
} else if(cCreature* monst = dynamic_cast<cCreature*>(victim)) { } else if(cCreature* monst = dynamic_cast<cCreature*>(victim)) {
bool damaged = damage_monst(i_monst - 100, current_pc, r2, eDamageType::WEAPON,13,false); bool damaged = damage_monst(*monst, current_pc, r2, eDamageType::WEAPON,13,false);
if(spec_dam > 0) if(spec_dam > 0)
damaged = damaged || damage_monst(i_monst - 100, current_pc, spec_dam, dmg_tp, 0,false); damaged = damaged || damage_monst(*monst, current_pc, spec_dam, dmg_tp, 0,false);
if(damaged) monst->damaged_msg(r2, spec_dam); if(damaged) monst->damaged_msg(r2, spec_dam);
} else if(cPlayer* who = dynamic_cast<cPlayer*>(victim)) { } else if(cPlayer* who = dynamic_cast<cPlayer*>(victim)) {
// TODO: Should the race really be included here? Maybe it's meant for melee attacks only.
eRace race = missile_firer.race; eRace race = missile_firer.race;
bool damaged = damage_pc(i_monst, r2, eDamageType::WEAPON, race, 0, false); bool damaged = damage_pc(*who, r2, eDamageType::WEAPON, race, 0, false);
if(spec_dam > 0) if(spec_dam > 0)
damaged = damaged || damage_pc(i_monst, spec_dam, dmg_tp, race, 0, false); damaged = damaged || damage_pc(*who, spec_dam, dmg_tp, race, 0, false);
if(damaged) { if(damaged) {
std::string msg = " " + who->name + " takes " + std::to_string(r2); std::string msg = " " + who->name + " takes " + std::to_string(r2);
if(spec_dam) msg += '+' + std::to_string(spec_dam); if(spec_dam) msg += '+' + std::to_string(spec_dam);
@@ -2595,7 +2596,7 @@ void do_monster_turn() {
printed_acid = true; printed_acid = true;
} }
r1 = get_ran(cur_monst->status[eStatus::ACID],1,6); r1 = get_ran(cur_monst->status[eStatus::ACID],1,6);
damage_monst(i, 6,r1, eDamageType::MAGIC,0); damage_monst(*cur_monst, 6,r1, eDamageType::MAGIC,0);
cur_monst->status[eStatus::ACID]--; cur_monst->status[eStatus::ACID]--;
} }
@@ -2619,7 +2620,7 @@ void do_monster_turn() {
printed_poison = true; printed_poison = true;
} }
r1 = get_ran(cur_monst->status[eStatus::POISON],1,6); r1 = get_ran(cur_monst->status[eStatus::POISON],1,6);
damage_monst(i, 6, r1, eDamageType::POISON,0); damage_monst(*cur_monst, 6, r1, eDamageType::POISON,0);
cur_monst->status[eStatus::POISON]--; cur_monst->status[eStatus::POISON]--;
} }
if(cur_monst->status[eStatus::DISEASE] > 0) { // Disease if(cur_monst->status[eStatus::DISEASE] > 0) { // Disease
@@ -2750,9 +2751,9 @@ void monster_attack(short who_att,iLiving* target) {
bool damaged = false; bool damaged = false;
if(m_target != nullptr) { if(m_target != nullptr) {
// TODO: Maybe this damage should be printed? // TODO: Maybe this damage should be printed?
damaged = damage_monst(i_monst - 100,7,r2,dam_type,sound_type,false); damaged = damage_monst(*m_target,7,r2,dam_type,sound_type,false);
} else if(pc_target != nullptr) { } else if(pc_target != nullptr) {
damaged = damage_pc(i_monst,r2,dam_type,attacker->m_type,sound_type); damaged = damage_pc(*pc_target,r2,dam_type,attacker->m_type,sound_type);
if(store_hp - target->get_health() <= 0) if(store_hp - target->get_health() <= 0)
damaged = false; damaged = false;
} }
@@ -2763,7 +2764,7 @@ void monster_attack(short who_att,iLiving* target) {
int dmg = attacker->get_shared_dmg(store_hp - target->get_health()); int dmg = attacker->get_shared_dmg(store_hp - target->get_health());
add_string_to_buf(" Shares damage!"); add_string_to_buf(" Shares damage!");
int who_hit = pc_target != nullptr ? 6 : 7; int who_hit = pc_target != nullptr ? 6 : 7;
damage_monst(who_att, who_hit, dmg, eDamageType::MAGIC,0); damage_monst(*attacker, who_hit, dmg, eDamageType::MAGIC,0);
} }
if(i == 0 && attacker->status[eStatus::POISONED_WEAPON] > 0) { if(i == 0 && attacker->status[eStatus::POISONED_WEAPON] > 0) {
@@ -2983,10 +2984,10 @@ void monst_fire_missile(short m_num,short bless,std::pair<eMonstAbil,uAbility> a
if(pc_target != nullptr) { if(pc_target != nullptr) {
add_string_to_buf(" Hits " + pc_target->name + '.'); add_string_to_buf(" Hits " + pc_target->name + '.');
// TODO: Should we pass in the monster's actual race here? // TODO: Should we pass in the monster's actual race here?
damage_pc(i_monst,r2,eDamageType::WEAPON,eRace::UNKNOWN,13); damage_pc(*pc_target,r2,eDamageType::WEAPON,eRace::UNKNOWN,13);
} else if(m_target != nullptr) { } else if(m_target != nullptr) {
m_target->spell_note(16); m_target->spell_note(16);
damage_monst(i_monst - 100,7,r2,eDamageType::WEAPON,13); damage_monst(*m_target,7,r2,eDamageType::WEAPON,13);
} }
} else { } else {
if(pc_target != nullptr) if(pc_target != nullptr)
@@ -3169,7 +3170,10 @@ void monst_basic_abil(short m_num, std::pair<eMonstAbil,uAbility> abil, iLiving*
break; break;
case eMonstAbil::PETRIFY: case eMonstAbil::PETRIFY:
i = univ.town.monst[m_num].level * abil.second.gen.strength / 100; i = univ.town.monst[m_num].level * abil.second.gen.strength / 100;
target->petrify(i); if(pc_target != nullptr)
petrify_pc(*pc_target, i);
else if(m_target != nullptr)
petrify_monst(*m_target, i);
break; break;
case eMonstAbil::DRAIN_SP: case eMonstAbil::DRAIN_SP:
if(pc_target != nullptr) { if(pc_target != nullptr) {
@@ -3916,11 +3920,11 @@ bool monst_cast_priest(cCreature *caster,short targ) {
return acted; return acted;
} }
void damage_target(short target,short dam,eDamageType type) { void damage_target(short target,short dam,eDamageType type,short sound_type) {
if(target == 6) return; if(target == 6) return;
if(target < 6) if(target < 6)
damage_pc(target,dam,type,eRace::UNKNOWN,0); damage_pc(univ.party[target],dam,type,eRace::UNKNOWN,sound_type);
else damage_monst(target - 100, 7, dam, type,0); else damage_monst(univ.town.monst[target - 100], 7, dam, type,sound_type);
} }
@@ -4137,23 +4141,23 @@ static void place_spell_pattern(effect_pat_type pat,location center,unsigned sho
switch(effect) { switch(effect) {
case WALL_FORCE: case WALL_FORCE:
r1 = get_ran(2,1,6); r1 = get_ran(2,1,6);
damage_pc(k,r1,eDamageType::MAGIC,eRace::UNKNOWN,0); damage_pc(univ.party[k],r1,eDamageType::MAGIC,eRace::UNKNOWN,0);
break; break;
case WALL_FIRE: case WALL_FIRE:
r1 = get_ran(1,1,6) + 1; r1 = get_ran(1,1,6) + 1;
damage_pc(k,r1,eDamageType::FIRE,eRace::UNKNOWN,0); damage_pc(univ.party[k],r1,eDamageType::FIRE,eRace::UNKNOWN,0);
break; break;
case WALL_ICE: case WALL_ICE:
r1 = get_ran(2,1,6); r1 = get_ran(2,1,6);
damage_pc(k,r1,eDamageType::COLD,eRace::UNKNOWN,0); damage_pc(univ.party[k],r1,eDamageType::COLD,eRace::UNKNOWN,0);
break; break;
case WALL_BLADES: case WALL_BLADES:
r1 = get_ran(4,1,8); r1 = get_ran(4,1,8);
damage_pc(k,r1,eDamageType::WEAPON,eRace::UNKNOWN,0); damage_pc(univ.party[k],r1,eDamageType::WEAPON,eRace::UNKNOWN,0);
break; break;
case OBJECT_BLOCK: case OBJECT_BLOCK:
r1 = get_ran(6,1,8); r1 = get_ran(6,1,8);
damage_pc(k,r1,eDamageType::WEAPON,eRace::UNKNOWN,0); damage_pc(univ.party[k],r1,eDamageType::WEAPON,eRace::UNKNOWN,0);
break; break;
case BARRIER_CAGE: case BARRIER_CAGE:
univ.party[k].status[eStatus::FORCECAGE] = 8; univ.party[k].status[eStatus::FORCECAGE] = 8;
@@ -4192,7 +4196,7 @@ static void place_spell_pattern(effect_pat_type pat,location center,unsigned sho
} }
if(type == eDamageType::MARKED) break; if(type == eDamageType::MARKED) break;
r1 = get_ran(dice,1,6); r1 = get_ran(dice,1,6);
damage_pc(k,r1,type,eRace::UNKNOWN,0); damage_pc(univ.party[k],r1,type,eRace::UNKNOWN,0);
break; break;
} }
} }
@@ -4225,29 +4229,29 @@ static void place_spell_pattern(effect_pat_type pat,location center,unsigned sho
break; break;
case WALL_FORCE: case WALL_FORCE:
r1 = get_ran(3,1,6); r1 = get_ran(3,1,6);
damage_monst(k, who_hit, r1, eDamageType::MAGIC,0); damage_monst(univ.town.monst[k], who_hit, r1, eDamageType::MAGIC,0);
break; break;
case WALL_FIRE: case WALL_FIRE:
r1 = get_ran(2,1,6); r1 = get_ran(2,1,6);
damage_monst(k, who_hit, r1, eDamageType::FIRE,0); damage_monst(univ.town.monst[k], who_hit, r1, eDamageType::FIRE,0);
break; break;
case CLOUD_STINK: case CLOUD_STINK:
which_m->curse(get_ran(1,1,2)); which_m->curse(get_ran(1,1,2));
break; break;
case WALL_ICE: case WALL_ICE:
r1 = get_ran(3,1,6); r1 = get_ran(3,1,6);
damage_monst(k, who_hit, r1, eDamageType::COLD,0); damage_monst(univ.town.monst[k], who_hit, r1, eDamageType::COLD,0);
break; break;
case WALL_BLADES: case WALL_BLADES:
r1 = get_ran(6,1,8); r1 = get_ran(6,1,8);
damage_monst(k, who_hit, r1, eDamageType::WEAPON,0); damage_monst(univ.town.monst[k], who_hit, r1, eDamageType::WEAPON,0);
break; break;
case CLOUD_SLEEP: case CLOUD_SLEEP:
which_m->sleep(eStatus::ASLEEP,3,0); which_m->sleep(eStatus::ASLEEP,3,0);
break; break;
case OBJECT_BLOCK: case OBJECT_BLOCK:
r1 = get_ran(6,1,8); r1 = get_ran(6,1,8);
damage_monst(k,who_hit,r1,eDamageType::WEAPON,0); damage_monst(univ.town.monst[k],who_hit,r1,eDamageType::WEAPON,0);
break; break;
case BARRIER_CAGE: case BARRIER_CAGE:
univ.town.monst[k].status[eStatus::FORCECAGE] = 8; univ.town.monst[k].status[eStatus::FORCECAGE] = 8;
@@ -4286,7 +4290,7 @@ static void place_spell_pattern(effect_pat_type pat,location center,unsigned sho
} }
if(type == eDamageType::MARKED) break; if(type == eDamageType::MARKED) break;
r1 = get_ran(dice,1,6); r1 = get_ran(dice,1,6);
damage_monst(k,who_hit,r1,type,0); damage_monst(univ.town.monst[k],who_hit,r1,type,0);
break; break;
} }
} }
@@ -4341,12 +4345,12 @@ void do_shockwave(location target) {
for(i = 0; i < 6; i++) for(i = 0; i < 6; i++)
if((dist(target,univ.party[i].combat_pos) > 0) && (dist(target,univ.party[i].combat_pos) < 11) if((dist(target,univ.party[i].combat_pos) > 0) && (dist(target,univ.party[i].combat_pos) < 11)
&& univ.party[i].main_status == eMainStatus::ALIVE) && univ.party[i].main_status == eMainStatus::ALIVE)
damage_pc(i, get_ran(2 + dist(target,univ.party[i].combat_pos) / 2, 1, 6), eDamageType::UNBLOCKABLE,eRace::UNKNOWN,0); damage_pc(univ.party[i], get_ran(2 + dist(target,univ.party[i].combat_pos) / 2, 1, 6), eDamageType::UNBLOCKABLE,eRace::UNKNOWN,0);
for(i = 0; i < univ.town.monst.size(); i++) for(i = 0; i < univ.town.monst.size(); i++)
if((univ.town.monst[i].active != 0) && (dist(target,univ.town.monst[i].cur_loc) > 0) if((univ.town.monst[i].active != 0) && (dist(target,univ.town.monst[i].cur_loc) > 0)
&& (dist(target,univ.town.monst[i].cur_loc) < 11) && (dist(target,univ.town.monst[i].cur_loc) < 11)
&& (can_see_light(target,univ.town.monst[i].cur_loc,sight_obscurity) < 5)) && (can_see_light(target,univ.town.monst[i].cur_loc,sight_obscurity) < 5))
damage_monst(i, current_pc, get_ran(2 + dist(target,univ.town.monst[i].cur_loc) / 2 , 1, 6), eDamageType::UNBLOCKABLE,0); damage_monst(univ.town.monst[i],current_pc,get_ran(2 + dist(target,univ.town.monst[i].cur_loc) / 2,1,6),eDamageType::UNBLOCKABLE,0);
do_explosion_anim(5,0); do_explosion_anim(5,0);
end_missile_anim(); end_missile_anim();
handle_marked_damage(); handle_marked_damage();
@@ -4355,16 +4359,17 @@ void do_shockwave(location target) {
void radius_damage(location target,short radius, short dam, eDamageType type) { void radius_damage(location target,short radius, short dam, eDamageType type) {
short i; short i;
// TODO: Why no booms in town mode?
if(is_town()) { if(is_town()) {
for(i = 0; i < 6; i++) for(i = 0; i < 6; i++)
if((dist(target,univ.town.p_loc) > 0) && (dist(target,univ.town.p_loc) <= radius) if((dist(target,univ.town.p_loc) > 0) && (dist(target,univ.town.p_loc) <= radius)
&& univ.party[i].main_status == eMainStatus::ALIVE) && univ.party[i].main_status == eMainStatus::ALIVE)
damage_pc(i, dam, type,eRace::UNKNOWN,0); damage_pc(univ.party[i], dam, type,eRace::UNKNOWN,0);
for(i = 0; i < univ.town.monst.size(); i++) for(i = 0; i < univ.town.monst.size(); i++)
if((univ.town.monst[i].active != 0) && (dist(target,univ.town.monst[i].cur_loc) > 0) if((univ.town.monst[i].active != 0) && (dist(target,univ.town.monst[i].cur_loc) > 0)
&& (dist(target,univ.town.monst[i].cur_loc) <= radius) && (dist(target,univ.town.monst[i].cur_loc) <= radius)
&& (can_see_light(target,univ.town.monst[i].cur_loc,sight_obscurity) < 5)) && (can_see_light(target,univ.town.monst[i].cur_loc,sight_obscurity) < 5))
damage_monst(i, current_pc, dam, type,0); damage_monst(univ.town.monst[i], current_pc, dam, type,0);
return; return;
} }
@@ -4372,12 +4377,12 @@ void radius_damage(location target,short radius, short dam, eDamageType type) {
for(i = 0; i < 6; i++) for(i = 0; i < 6; i++)
if((dist(target,univ.party[i].combat_pos) > 0) && (dist(target,univ.party[i].combat_pos) <= radius) if((dist(target,univ.party[i].combat_pos) > 0) && (dist(target,univ.party[i].combat_pos) <= radius)
&& univ.party[i].main_status == eMainStatus::ALIVE) && univ.party[i].main_status == eMainStatus::ALIVE)
damage_pc(i, dam, type,eRace::UNKNOWN,0); damage_pc(univ.party[i], dam, type,eRace::UNKNOWN,0);
for(i = 0; i < univ.town.monst.size(); i++) for(i = 0; i < univ.town.monst.size(); i++)
if((univ.town.monst[i].active != 0) && (dist(target,univ.town.monst[i].cur_loc) > 0) if((univ.town.monst[i].active != 0) && (dist(target,univ.town.monst[i].cur_loc) > 0)
&& (dist(target,univ.town.monst[i].cur_loc) <= radius) && (dist(target,univ.town.monst[i].cur_loc) <= radius)
&& (can_see_light(target,univ.town.monst[i].cur_loc,sight_obscurity) < 5)) && (can_see_light(target,univ.town.monst[i].cur_loc,sight_obscurity) < 5))
damage_monst(i, current_pc, dam, type,0); damage_monst(univ.town.monst[i], current_pc, dam, type,0);
do_explosion_anim(5,0); do_explosion_anim(5,0);
end_missile_anim(); end_missile_anim();
handle_marked_damage(); handle_marked_damage();
@@ -4416,8 +4421,8 @@ void hit_space(location target,short dam,eDamageType type,short report,short hit
if((hit_monsters) && (univ.town.monst[i].active != 0) && !stop_hitting) if((hit_monsters) && (univ.town.monst[i].active != 0) && !stop_hitting)
if(univ.town.monst[i].on_space(target)) { if(univ.town.monst[i].on_space(target)) {
if(processing_fields) if(processing_fields)
damage_monst(i, 6, dam, type,0); damage_monst(univ.town.monst[i], 6, dam, type,0);
else damage_monst(i, (monsters_going) ? 7 : current_pc, dam, type,0); else damage_monst(univ.town.monst[i], (monsters_going) ? 7 : current_pc, dam, type,0);
stop_hitting = (hit_all == 1) ? false : true; stop_hitting = (hit_all == 1) ? false : true;
} }
@@ -4425,7 +4430,7 @@ void hit_space(location target,short dam,eDamageType type,short report,short hit
for(i = 0; i < 6; i++) for(i = 0; i < 6; i++)
if(univ.party[i].main_status == eMainStatus::ALIVE && !stop_hitting) if(univ.party[i].main_status == eMainStatus::ALIVE && !stop_hitting)
if(univ.party[i].combat_pos == target) { if(univ.party[i].combat_pos == target) {
damage_pc(i,dam,type,eRace::UNKNOWN,0); damage_pc(univ.party[i],dam,type,eRace::UNKNOWN,0);
stop_hitting = (hit_all == 1) ? false : true; stop_hitting = (hit_all == 1) ? false : true;
} }
if(overall_mode < MODE_COMBAT) if(overall_mode < MODE_COMBAT)
@@ -4457,7 +4462,7 @@ void do_poison() {
if(univ.party[i].main_status == eMainStatus::ALIVE) if(univ.party[i].main_status == eMainStatus::ALIVE)
if(univ.party[i].status[eStatus::POISON] > 0) { if(univ.party[i].status[eStatus::POISON] > 0) {
r1 = get_ran(univ.party[i].status[eStatus::POISON],1,6); r1 = get_ran(univ.party[i].status[eStatus::POISON],1,6);
damage_pc(i,r1,eDamageType::POISON,eRace::UNKNOWN,0); damage_pc(univ.party[i],r1,eDamageType::POISON,eRace::UNKNOWN,0);
if(get_ran(1,0,8) < 6) if(get_ran(1,0,8) < 6)
move_to_zero(univ.party[i].status[eStatus::POISON]); move_to_zero(univ.party[i].status[eStatus::POISON]);
if(get_ran(1,0,8) < 6) if(get_ran(1,0,8) < 6)
@@ -4533,7 +4538,7 @@ void handle_acid() {
if(univ.party[i].main_status == eMainStatus::ALIVE) if(univ.party[i].main_status == eMainStatus::ALIVE)
if(univ.party[i].status[eStatus::ACID] > 0) { if(univ.party[i].status[eStatus::ACID] > 0) {
r1 = get_ran(univ.party[i].status[eStatus::ACID],1,6); r1 = get_ran(univ.party[i].status[eStatus::ACID],1,6);
damage_pc(i,r1,eDamageType::MAGIC,eRace::UNKNOWN,0); damage_pc(univ.party[i],r1,eDamageType::MAGIC,eRace::UNKNOWN,0);
move_to_zero(univ.party[i].status[eStatus::ACID]); move_to_zero(univ.party[i].status[eStatus::ACID]);
} }
if(overall_mode < MODE_COMBAT) if(overall_mode < MODE_COMBAT)

View File

@@ -30,7 +30,7 @@ void monst_basic_abil(short m_num, std::pair<eMonstAbil,uAbility> abil, iLiving*
bool monst_breathe(cCreature *caster,location targ_space,uAbility dam_type); bool monst_breathe(cCreature *caster,location targ_space,uAbility dam_type);
bool monst_cast_mage(cCreature *caster,short targ); bool monst_cast_mage(cCreature *caster,short targ);
bool monst_cast_priest(cCreature *caster,short targ); bool monst_cast_priest(cCreature *caster,short targ);
void damage_target(short target,short dam,eDamageType type); void damage_target(short target,short dam,eDamageType type,short sound_type = 0);
location find_fireball_loc(location where,short radius,short mode,short *m); location find_fireball_loc(location where,short radius,short mode,short *m);
location closest_pc_loc(location where); location closest_pc_loc(location where);
short count_levels(location where,short radius); short count_levels(location where,short radius);

View File

@@ -441,7 +441,7 @@ void handle_menu_choice(eMenu item_hit) {
if(choice < 6) { if(choice < 6) {
std::string confirm = cChoiceDlog("delete-pc-confirm",{"yes","no"}).show(); std::string confirm = cChoiceDlog("delete-pc-confirm",{"yes","no"}).show();
if(confirm == "yes") if(confirm == "yes")
kill_pc(choice,eMainStatus::ABSENT); kill_pc(univ.party[choice],eMainStatus::ABSENT);
} }
draw_terrain(); draw_terrain();
} }

View File

@@ -810,19 +810,19 @@ void monst_inflict_fields(short which_monst) {
// TODO: If the goal is to damage the monster by any fields it's on, why all the break statements? // TODO: If the goal is to damage the monster by any fields it's on, why all the break statements?
if(univ.town.is_quickfire(where_check.x,where_check.y)) { if(univ.town.is_quickfire(where_check.x,where_check.y)) {
r1 = get_ran(2,1,8); r1 = get_ran(2,1,8);
damage_monst(which_monst,7,r1,eDamageType::FIRE,0); damage_monst(*which_m,7,r1,eDamageType::FIRE,0);
break; break;
} }
if(univ.town.is_blade_wall(where_check.x,where_check.y)) { if(univ.town.is_blade_wall(where_check.x,where_check.y)) {
r1 = get_ran(6,1,8); r1 = get_ran(6,1,8);
if(have_radiate && which_radiate != eFieldType::WALL_BLADES) if(have_radiate && which_radiate != eFieldType::WALL_BLADES)
damage_monst(which_monst,7,r1,eDamageType::WEAPON,0); damage_monst(*which_m,7,r1,eDamageType::WEAPON,0);
break; break;
} }
if(univ.town.is_force_wall(where_check.x,where_check.y)) { if(univ.town.is_force_wall(where_check.x,where_check.y)) {
r1 = get_ran(3,1,6); r1 = get_ran(3,1,6);
if(have_radiate && which_radiate != eFieldType::WALL_FORCE) if(have_radiate && which_radiate != eFieldType::WALL_FORCE)
damage_monst(which_monst,7,r1,eDamageType::MAGIC,0); damage_monst(*which_m,7,r1,eDamageType::MAGIC,0);
break; break;
} }
if(univ.town.is_sleep_cloud(where_check.x,where_check.y)) { if(univ.town.is_sleep_cloud(where_check.x,where_check.y)) {
@@ -833,7 +833,7 @@ void monst_inflict_fields(short which_monst) {
if(univ.town.is_ice_wall(where_check.x,where_check.y)) { if(univ.town.is_ice_wall(where_check.x,where_check.y)) {
r1 = get_ran(3,1,6); r1 = get_ran(3,1,6);
if(have_radiate && which_radiate != eFieldType::WALL_ICE) if(have_radiate && which_radiate != eFieldType::WALL_ICE)
damage_monst(which_monst,7,r1,eDamageType::COLD,0); damage_monst(*which_m,7,r1,eDamageType::COLD,0);
break; break;
} }
if(univ.town.is_scloud(where_check.x,where_check.y)) { if(univ.town.is_scloud(where_check.x,where_check.y)) {
@@ -852,7 +852,7 @@ void monst_inflict_fields(short which_monst) {
if(univ.town.is_fire_wall(where_check.x,where_check.y)) { if(univ.town.is_fire_wall(where_check.x,where_check.y)) {
r1 = get_ran(2,1,6); r1 = get_ran(2,1,6);
if(have_radiate && which_radiate != eFieldType::WALL_FIRE) if(have_radiate && which_radiate != eFieldType::WALL_FIRE)
damage_monst(which_monst,7,r1,eDamageType::FIRE,0); damage_monst(*which_m,7,r1,eDamageType::FIRE,0);
break; break;
} }
if(univ.town.is_force_cage(where_check.x,where_check.y)) if(univ.town.is_force_cage(where_check.x,where_check.y))
@@ -874,7 +874,7 @@ void monst_inflict_fields(short which_monst) {
univ.town.set_barrel(where_check.x,where_check.y,false); univ.town.set_barrel(where_check.x,where_check.y,false);
if(univ.town.is_fire_barr(where_check.x,where_check.y)) { if(univ.town.is_fire_barr(where_check.x,where_check.y)) {
r1 = get_ran(2,1,10); r1 = get_ran(2,1,10);
damage_monst(which_monst,7,r1,eDamageType::FIRE,0); damage_monst(*which_m,7,r1,eDamageType::FIRE,0);
} }
} }

View File

@@ -1476,7 +1476,7 @@ void do_mindduel(short pc_num,cCreature *monst) {
sout.str(""); sout.str("");
sout << " " << univ.party[pc_num].name << " is killed!"; sout << " " << univ.party[pc_num].name << " is killed!";
add_string_to_buf(sout.str()); add_string_to_buf(sout.str());
kill_pc(pc_num,eMainStatus::DEAD); kill_pc(univ.party[pc_num],eMainStatus::DEAD);
} }
} }
@@ -1493,7 +1493,7 @@ void do_mindduel(short pc_num,cCreature *monst) {
monst->status[eStatus::DUMB] += 2; monst->status[eStatus::DUMB] += 2;
monst->spell_note(22); monst->spell_note(22);
if(monst->status[eStatus::DUMB] > 7) { if(monst->status[eStatus::DUMB] > 7) {
kill_monst(monst,pc_num); kill_monst(*monst,pc_num);
} }
} }
@@ -2321,7 +2321,7 @@ void hit_party(short how_much,eDamageType damage_type,short snd_type) {
for(i = 0; i < 6; i++) for(i = 0; i < 6; i++)
if(univ.party[i].main_status == eMainStatus::ALIVE) if(univ.party[i].main_status == eMainStatus::ALIVE)
dummy = damage_pc(i,how_much,damage_type,eRace::UNKNOWN,snd_type); dummy = damage_pc(univ.party[i],how_much,damage_type,eRace::UNKNOWN,snd_type);
put_pc_screen(); put_pc_screen();
} }
@@ -2335,10 +2335,10 @@ void slay_party(eMainStatus mode) {
put_pc_screen(); put_pc_screen();
} }
bool damage_pc(short which_pc,short how_much,eDamageType damage_type,eRace type_of_attacker, short sound_type,bool do_print) { bool damage_pc(cPlayer& which_pc,short how_much,eDamageType damage_type,eRace type_of_attacker, short sound_type,bool do_print) {
short i, r1,level; short i, r1,level;
if(univ.party[which_pc].main_status != eMainStatus::ALIVE) if(which_pc.main_status != eMainStatus::ALIVE)
return false; return false;
// TODO: I think there should be a way to force sound_type = 0 for UNBLOCKABLE // TODO: I think there should be a way to force sound_type = 0 for UNBLOCKABLE
@@ -2355,37 +2355,37 @@ bool damage_pc(short which_pc,short how_much,eDamageType damage_type,eRace type_
// armor // armor
if(damage_type == eDamageType::WEAPON || damage_type == eDamageType::UNDEAD || damage_type == eDamageType::DEMON) { if(damage_type == eDamageType::WEAPON || damage_type == eDamageType::UNDEAD || damage_type == eDamageType::DEMON) {
how_much -= minmax(-5,5,univ.party[which_pc].status[eStatus::BLESS_CURSE]); how_much -= minmax(-5,5,which_pc.status[eStatus::BLESS_CURSE]);
for(i = 0; i < 24; i++) { for(i = 0; i < 24; i++) {
if((univ.party[which_pc].items[i].variety != eItemType::NO_ITEM) && (univ.party[which_pc].equip[i])) { if((which_pc.items[i].variety != eItemType::NO_ITEM) && (which_pc.equip[i])) {
if(isArmourType(univ.party[which_pc].items[i].variety)) { if(isArmourType(which_pc.items[i].variety)) {
r1 = get_ran(1,1,univ.party[which_pc].items[i].item_level); r1 = get_ran(1,1,which_pc.items[i].item_level);
how_much -= r1; how_much -= r1;
// bonus for magical items // bonus for magical items
if(univ.party[which_pc].items[i].bonus > 0) { if(which_pc.items[i].bonus > 0) {
r1 = get_ran(1,1,univ.party[which_pc].items[i].bonus); r1 = get_ran(1,1,which_pc.items[i].bonus);
how_much -= r1; how_much -= r1;
how_much -= univ.party[which_pc].items[i].bonus / 2; how_much -= which_pc.items[i].bonus / 2;
} }
if(univ.party[which_pc].items[i].bonus < 0) { if(which_pc.items[i].bonus < 0) {
how_much = how_much - univ.party[which_pc].items[i].bonus; how_much = how_much - which_pc.items[i].bonus;
} }
r1 = get_ran(1,1,100); r1 = get_ran(1,1,100);
if(r1 < hit_chance[univ.party[which_pc].skill(eSkill::DEFENSE)] - 20) if(r1 < hit_chance[which_pc.skill(eSkill::DEFENSE)] - 20)
how_much -= 1; how_much -= 1;
} }
if(univ.party[which_pc].items[i].protection > 0) { if(which_pc.items[i].protection > 0) {
r1 = get_ran(1,1,univ.party[which_pc].items[i].protection); r1 = get_ran(1,1,which_pc.items[i].protection);
how_much -= r1; how_much -= r1;
} }
if(univ.party[which_pc].items[i].protection < 0) { if(which_pc.items[i].protection < 0) {
r1 = get_ran(1,1,-1 * univ.party[which_pc].items[i].protection); r1 = get_ran(1,1,-1 * which_pc.items[i].protection);
how_much += r1; how_much += r1;
} }
} }
if(univ.party[which_pc].items[i].ability == eItemAbil::MELEE_PROTECTION) { if(which_pc.items[i].ability == eItemAbil::MELEE_PROTECTION) {
r1 = get_ran(1,1,univ.party[which_pc].items[i].abil_data[0]); r1 = get_ran(1,1,which_pc.items[i].abil_data[0]);
if(damage_type == eDamageType::DEMON) if(damage_type == eDamageType::DEMON)
how_much -= max(1,r1 / 5); how_much -= max(1,r1 / 5);
else if(damage_type == eDamageType::UNDEAD) else if(damage_type == eDamageType::UNDEAD)
@@ -2397,48 +2397,48 @@ bool damage_pc(short which_pc,short how_much,eDamageType damage_type,eRace type_
// parry // parry
// TODO: Used to also apply this to fire damage; is that correct? // TODO: Used to also apply this to fire damage; is that correct?
if(damage_type == eDamageType::WEAPON && univ.party[which_pc].parry < 100) if(damage_type == eDamageType::WEAPON && which_pc.parry < 100)
how_much -= univ.party[which_pc].parry / 4; how_much -= which_pc.parry / 4;
if(damage_type != eDamageType::MARKED) { if(damage_type != eDamageType::MARKED) {
if(PSD[SDF_EASY_MODE] > 0) if(PSD[SDF_EASY_MODE] > 0)
how_much -= 3; how_much -= 3;
// toughness // toughness
if(univ.party[which_pc].traits[eTrait::TOUGHNESS]) if(which_pc.traits[eTrait::TOUGHNESS])
how_much--; how_much--;
// luck // luck
if(get_ran(1,1,100) < 2 * (hit_chance[univ.party[which_pc].skill(eSkill::LUCK)] - 20)) if(get_ran(1,1,100) < 2 * (hit_chance[which_pc.skill(eSkill::LUCK)] - 20))
how_much -= 1; how_much -= 1;
} }
if((level = univ.party[which_pc].get_prot_level(eItemAbil::DAMAGE_PROTECTION,int(damage_type))) > 0) { if((level = which_pc.get_prot_level(eItemAbil::DAMAGE_PROTECTION,int(damage_type))) > 0) {
if(damage_type == eDamageType::WEAPON) how_much -= level; if(damage_type == eDamageType::WEAPON) how_much -= level;
else how_much = how_much / 2; else how_much = how_much / 2;
} }
// TODO: Do these perhaps depend on the ability strength less than they should? // TODO: Do these perhaps depend on the ability strength less than they should?
if((level = univ.party[which_pc].get_prot_level(eItemAbil::PROTECT_FROM_SPECIES,int(type_of_attacker))) > 0) if((level = which_pc.get_prot_level(eItemAbil::PROTECT_FROM_SPECIES,int(type_of_attacker))) > 0)
how_much = how_much / 2; how_much = how_much / 2;
if(isHumanoid(type_of_attacker) && !isHuman(type_of_attacker) && type_of_attacker != eRace::HUMANOID) { if(isHumanoid(type_of_attacker) && !isHuman(type_of_attacker) && type_of_attacker != eRace::HUMANOID) {
// If it's a slith, nephil, vahnatai, or goblin, Protection from Humanoids also helps // If it's a slith, nephil, vahnatai, or goblin, Protection from Humanoids also helps
// Humanoid is explicitly excluded here because otherwise it would help twice. // Humanoid is explicitly excluded here because otherwise it would help twice.
if((level = univ.party[which_pc].get_prot_level(eItemAbil::PROTECT_FROM_SPECIES,int(eRace::HUMANOID))) > 0) if((level = which_pc.get_prot_level(eItemAbil::PROTECT_FROM_SPECIES,int(eRace::HUMANOID))) > 0)
how_much = how_much / 2; how_much = how_much / 2;
} }
if(type_of_attacker == eRace::SKELETAL) { if(type_of_attacker == eRace::SKELETAL) {
// Protection from Undead helps with both types of undead // Protection from Undead helps with both types of undead
if((level = univ.party[which_pc].get_prot_level(eItemAbil::PROTECT_FROM_SPECIES,int(eRace::UNDEAD))) > 0) if((level = which_pc.get_prot_level(eItemAbil::PROTECT_FROM_SPECIES,int(eRace::UNDEAD))) > 0)
how_much = how_much / 2; how_much = how_much / 2;
} }
// invuln // invuln
if(damage_type != eDamageType::SPECIAL && univ.party[which_pc].status[eStatus::INVULNERABLE] > 0) if(damage_type != eDamageType::SPECIAL && which_pc.status[eStatus::INVULNERABLE] > 0)
how_much = 0; how_much = 0;
// Mag. res helps w. fire and cold // Mag. res helps w. fire and cold
// TODO: Why doesn't this help with magic damage!? // TODO: Why doesn't this help with magic damage!?
if(damage_type == eDamageType::FIRE || damage_type == eDamageType::COLD) { if(damage_type == eDamageType::FIRE || damage_type == eDamageType::COLD) {
int magic_res = univ.party[which_pc].status[eStatus::MAGIC_RESISTANCE]; int magic_res = which_pc.status[eStatus::MAGIC_RESISTANCE];
if(magic_res > 0) if(magic_res > 0)
how_much /= 2; how_much /= 2;
else if(magic_res < 0) else if(magic_res < 0)
@@ -2447,13 +2447,13 @@ bool damage_pc(short which_pc,short how_much,eDamageType damage_type,eRace type_
// major resistance // major resistance
if((damage_type == eDamageType::FIRE || damage_type == eDamageType::POISON || damage_type == eDamageType::MAGIC || damage_type == eDamageType::COLD) if((damage_type == eDamageType::FIRE || damage_type == eDamageType::POISON || damage_type == eDamageType::MAGIC || damage_type == eDamageType::COLD)
&& ((level = univ.party[which_pc].get_prot_level(eItemAbil::FULL_PROTECTION)) > 0)) && ((level = which_pc.get_prot_level(eItemAbil::FULL_PROTECTION)) > 0))
how_much = how_much / ((level >= 7) ? 4 : 2); how_much = how_much / ((level >= 7) ? 4 : 2);
if(boom_anim_active) { if(boom_anim_active) {
if(how_much < 0) if(how_much < 0)
how_much = 0; how_much = 0;
univ.party[which_pc].marked_damage += how_much; which_pc.marked_damage += how_much;
// It would also be nice to have a special boom type for cold. // It would also be nice to have a special boom type for cold.
short boom_type = 2; short boom_type = 2;
if(damage_type == eDamageType::FIRE) if(damage_type == eDamageType::FIRE)
@@ -2462,7 +2462,7 @@ bool damage_pc(short which_pc,short how_much,eDamageType damage_type,eRace type_
boom_type = 3; boom_type = 3;
if(is_town()) if(is_town())
add_explosion(univ.town.p_loc,how_much,0,boom_type,0,0); add_explosion(univ.town.p_loc,how_much,0,boom_type,0,0);
else add_explosion(univ.party[which_pc].combat_pos,how_much,0,boom_type,0,0); else add_explosion(which_pc.combat_pos,how_much,0,boom_type,0,0);
if(how_much == 0) if(how_much == 0)
return false; return false;
else return true; else return true;
@@ -2476,14 +2476,14 @@ bool damage_pc(short which_pc,short how_much,eDamageType damage_type,eRace type_
} }
else { else {
// if asleep, get bonus // if asleep, get bonus
if(univ.party[which_pc].status[eStatus::ASLEEP] > 0) if(which_pc.status[eStatus::ASLEEP] > 0)
univ.party[which_pc].status[eStatus::ASLEEP]--; which_pc.status[eStatus::ASLEEP]--;
if(do_print) if(do_print)
add_string_to_buf(" " + univ.party[which_pc].name + " takes " + std::to_string(how_much) + '.'); add_string_to_buf(" " + which_pc.name + " takes " + std::to_string(how_much) + '.');
if(damage_type != eDamageType::MARKED) { if(damage_type != eDamageType::MARKED) {
if(is_combat()) if(is_combat())
boom_space(univ.party[which_pc].combat_pos,overall_mode,boom_gr[damage_type],how_much,sound_type); boom_space(which_pc.combat_pos,overall_mode,boom_gr[damage_type],how_much,sound_type);
else if(is_town()) else if(is_town())
boom_space(univ.town.p_loc,overall_mode,boom_gr[damage_type],how_much,sound_type); boom_space(univ.town.p_loc,overall_mode,boom_gr[damage_type],how_much,sound_type);
else boom_space(univ.town.p_loc,100,boom_gr[damage_type],how_much,sound_type); else boom_space(univ.town.p_loc,100,boom_gr[damage_type],how_much,sound_type);
@@ -2494,50 +2494,45 @@ bool damage_pc(short which_pc,short how_much,eDamageType damage_type,eRace type_
univ.party.total_dam_taken += how_much; univ.party.total_dam_taken += how_much;
if(univ.party[which_pc].cur_health >= how_much) if(which_pc.cur_health >= how_much)
univ.party[which_pc].cur_health = univ.party[which_pc].cur_health - how_much; which_pc.cur_health = which_pc.cur_health - how_much;
else if(univ.party[which_pc].cur_health > 0) else if(which_pc.cur_health > 0)
univ.party[which_pc].cur_health = 0; which_pc.cur_health = 0;
else // Check if PC can die else // Check if PC can die
if(how_much > 25) { if(how_much > 25) {
add_string_to_buf(" " + univ.party[which_pc].name + " is obliterated."); add_string_to_buf(" " + which_pc.name + " is obliterated.");
kill_pc(which_pc, eMainStatus::DUST); kill_pc(which_pc, eMainStatus::DUST);
} }
else { else {
add_string_to_buf(" " + univ.party[which_pc].name + " is killed."); add_string_to_buf(" " + which_pc.name + " is killed.");
kill_pc(which_pc,eMainStatus::DEAD); kill_pc(which_pc,eMainStatus::DEAD);
} }
if(univ.party[which_pc].cur_health == 0 && univ.party[which_pc].main_status == eMainStatus::ALIVE) if(which_pc.cur_health == 0 && which_pc.main_status == eMainStatus::ALIVE)
play_sound(3); play_sound(3);
put_pc_screen(); put_pc_screen();
return true; return true;
} }
void cPlayer::petrify(int strength) { void petrify_pc(cPlayer& which_pc,int strength) {
std::ostringstream create_line; std::ostringstream create_line;
short r1 = get_ran(1,0,20); short r1 = get_ran(1,0,20);
r1 += level / 4; r1 += which_pc.level / 4;
r1 += status[eStatus::BLESS_CURSE]; r1 += which_pc.status[eStatus::BLESS_CURSE];
r1 -= strength; r1 -= strength;
if(has_abil_equip(eItemAbil::PROTECT_FROM_PETRIFY) < 24) if(which_pc.has_abil_equip(eItemAbil::PROTECT_FROM_PETRIFY) < 24)
r1 = 20; r1 = 20;
if(r1 > 14) { if(r1 > 14) {
create_line << " " << name << "resists."; create_line << " " << which_pc.name << "resists.";
} else { } else {
size_t i = 0; create_line << " " << which_pc.name << "is turned to stone.";
for(int j = 0; j < 6; j++) { kill_pc(which_pc,eMainStatus::STONE);
if(this == &party[j])
i = j;
}
create_line << " " << name << "is turned to stone.";
kill_pc(i,eMainStatus::STONE);
} }
add_string_to_buf(create_line.str()); add_string_to_buf(create_line.str());
} }
void kill_pc(short which_pc,eMainStatus type) { void kill_pc(cPlayer& which_pc,eMainStatus type) {
short i = 24; short i = 24;
bool dummy,no_save = false; bool dummy,no_save = false;
location item_loc; location item_loc;
@@ -2548,22 +2543,22 @@ void kill_pc(short which_pc,eMainStatus type) {
} }
if(type != eMainStatus::STONE) if(type != eMainStatus::STONE)
i = univ.party[which_pc].has_abil_equip(eItemAbil::LIFE_SAVING); i = which_pc.has_abil_equip(eItemAbil::LIFE_SAVING);
int luck = univ.party[which_pc].skill(eSkill::LUCK); int luck = which_pc.skill(eSkill::LUCK);
if(!no_save && type != eMainStatus::ABSENT && luck > 0 && if(!no_save && type != eMainStatus::ABSENT && luck > 0 &&
get_ran(1,1,100) < hit_chance[luck]) { get_ran(1,1,100) < hit_chance[luck]) {
add_string_to_buf(" But you luck out!"); add_string_to_buf(" But you luck out!");
univ.party[which_pc].cur_health = 0; which_pc.cur_health = 0;
} }
else if(i == 24 || type == eMainStatus::ABSENT) { else if(i == 24 || type == eMainStatus::ABSENT) {
if(combat_active_pc == which_pc) if(combat_active_pc < 6 && &which_pc == &univ.party[combat_active_pc])
combat_active_pc = 6; combat_active_pc = 6;
for(i = 0; i < 24; i++) for(i = 0; i < 24; i++)
univ.party[which_pc].equip[i] = false; which_pc.equip[i] = false;
item_loc = (overall_mode >= MODE_COMBAT) ? univ.party[which_pc].combat_pos : univ.town.p_loc; item_loc = (overall_mode >= MODE_COMBAT) ? which_pc.combat_pos : univ.town.p_loc;
if(type == eMainStatus::DEAD) if(type == eMainStatus::DEAD)
univ.town.set_lg_blood(item_loc.x,item_loc.y,true); univ.town.set_lg_blood(item_loc.x,item_loc.y,true);
@@ -2572,19 +2567,19 @@ void kill_pc(short which_pc,eMainStatus type) {
if(overall_mode != MODE_OUTDOORS) if(overall_mode != MODE_OUTDOORS)
for(i = 0; i < 24; i++) for(i = 0; i < 24; i++)
if(univ.party[which_pc].items[i].variety != eItemType::NO_ITEM) { if(which_pc.items[i].variety != eItemType::NO_ITEM) {
dummy = place_item(univ.party[which_pc].items[i],item_loc,true); dummy = place_item(which_pc.items[i],item_loc,true);
univ.party[which_pc].items[i].variety = eItemType::NO_ITEM; which_pc.items[i].variety = eItemType::NO_ITEM;
} }
if(type == eMainStatus::DEAD || type == eMainStatus::DUST) if(type == eMainStatus::DEAD || type == eMainStatus::DUST)
play_sound(21); play_sound(21);
univ.party[which_pc].main_status = type; which_pc.main_status = type;
univ.party[which_pc].ap = 0; which_pc.ap = 0;
} }
else { else {
add_string_to_buf(" Life saved!"); add_string_to_buf(" Life saved!");
univ.party[which_pc].take_item(i); which_pc.take_item(i);
univ.party[which_pc].heal(200); which_pc.heal(200);
} }
if(univ.party[current_pc].main_status != eMainStatus::ALIVE) if(univ.party[current_pc].main_status != eMainStatus::ALIVE)
current_pc = first_active_pc(); current_pc = first_active_pc();

View File

@@ -37,8 +37,9 @@ mon_num_t pick_trapped_monst();
bool flying() ; bool flying() ;
void hit_party(short how_much,eDamageType damage_type,short snd_type = 0); void hit_party(short how_much,eDamageType damage_type,short snd_type = 0);
void slay_party(eMainStatus mode); void slay_party(eMainStatus mode);
bool damage_pc(short which_pc,short how_much,eDamageType damage_type,eRace type_of_attacker, short sound_type,bool do_print = true); bool damage_pc(cPlayer& which_pc,short how_much,eDamageType damage_type,eRace type_of_attacker, short sound_type,bool do_print = true);
void kill_pc(short which_pc,eMainStatus type); void petrify_pc(cPlayer& which_pc,int strength);
void kill_pc(cPlayer& which_pc,eMainStatus type);
void set_pc_moves(); void set_pc_moves();
void take_ap(short num); void take_ap(short num);
short trait_present(eTrait which_trait); short trait_present(eTrait which_trait);

View File

@@ -351,7 +351,7 @@ bool check_special_terrain(location where_check,eSpecCtx mode,cPlayer& which_pc,
hit_party(r1,dam_type); hit_party(r1,dam_type);
fast_bang = 1; fast_bang = 1;
if(mode == eSpecCtx::COMBAT_MOVE) if(mode == eSpecCtx::COMBAT_MOVE)
damage_pc(univ.get_target_i(which_pc),r1,dam_type,eRace::UNKNOWN,0); damage_pc(which_pc,r1,dam_type,eRace::UNKNOWN,0);
else else
boom_space(univ.party.p_loc,overall_mode,pic_type,r1,12); boom_space(univ.party.p_loc,overall_mode,pic_type,r1,12);
fast_bang = 0; fast_bang = 0;
@@ -484,7 +484,6 @@ bool check_special_terrain(location where_check,eSpecCtx mode,cPlayer& which_pc,
// All this does is print a message // All this does is print a message
void check_fields(location where_check,eSpecCtx mode,cPlayer& which_pc) { void check_fields(location where_check,eSpecCtx mode,cPlayer& which_pc) {
short r1,i; short r1,i;
size_t i_pc = univ.get_target_i(which_pc);
if(mode != eSpecCtx::COMBAT_MOVE && mode != eSpecCtx::TOWN_MOVE && mode != eSpecCtx::OUT_MOVE) { if(mode != eSpecCtx::COMBAT_MOVE && mode != eSpecCtx::TOWN_MOVE && mode != eSpecCtx::OUT_MOVE) {
std::cout << "Note: Improper mode passed to check_special_terrain: " << int(mode) << std::endl; std::cout << "Note: Improper mode passed to check_special_terrain: " << int(mode) << std::endl;
@@ -496,19 +495,19 @@ void check_fields(location where_check,eSpecCtx mode,cPlayer& which_pc) {
add_string_to_buf(" Fire wall!"); add_string_to_buf(" Fire wall!");
r1 = get_ran(1,1,6) + 1; r1 = get_ran(1,1,6) + 1;
if(mode == eSpecCtx::COMBAT_MOVE) if(mode == eSpecCtx::COMBAT_MOVE)
damage_pc(i_pc,r1,eDamageType::FIRE,eRace::UNKNOWN,0); damage_pc(which_pc,r1,eDamageType::FIRE,eRace::UNKNOWN,0);
} }
if(univ.town.is_force_wall(where_check.x,where_check.y)) { if(univ.town.is_force_wall(where_check.x,where_check.y)) {
add_string_to_buf(" Force wall!"); add_string_to_buf(" Force wall!");
r1 = get_ran(2,1,6); r1 = get_ran(2,1,6);
if(mode == eSpecCtx::COMBAT_MOVE) if(mode == eSpecCtx::COMBAT_MOVE)
damage_pc(i_pc,r1,eDamageType::MAGIC,eRace::UNKNOWN,0); damage_pc(which_pc,r1,eDamageType::MAGIC,eRace::UNKNOWN,0);
} }
if(univ.town.is_ice_wall(where_check.x,where_check.y)) { if(univ.town.is_ice_wall(where_check.x,where_check.y)) {
add_string_to_buf(" Ice wall!"); add_string_to_buf(" Ice wall!");
r1 = get_ran(2,1,6); r1 = get_ran(2,1,6);
if(mode == eSpecCtx::COMBAT_MOVE) if(mode == eSpecCtx::COMBAT_MOVE)
damage_pc(i_pc,r1,eDamageType::COLD,eRace::UNKNOWN,0); damage_pc(which_pc,r1,eDamageType::COLD,eRace::UNKNOWN,0);
if(overall_mode < MODE_COMBAT) if(overall_mode < MODE_COMBAT)
boom_space(univ.party.p_loc,overall_mode,4,r1,7); boom_space(univ.party.p_loc,overall_mode,4,r1,7);
} }
@@ -516,28 +515,28 @@ void check_fields(location where_check,eSpecCtx mode,cPlayer& which_pc) {
add_string_to_buf(" Blade wall!"); add_string_to_buf(" Blade wall!");
r1 = get_ran(4,1,8); r1 = get_ran(4,1,8);
if(mode == eSpecCtx::COMBAT_MOVE) if(mode == eSpecCtx::COMBAT_MOVE)
damage_pc(i_pc,r1,eDamageType::WEAPON,eRace::UNKNOWN,0); damage_pc(which_pc,r1,eDamageType::WEAPON,eRace::UNKNOWN,0);
} }
if(univ.town.is_quickfire(where_check.x,where_check.y)) { if(univ.town.is_quickfire(where_check.x,where_check.y)) {
add_string_to_buf(" Quickfire!"); add_string_to_buf(" Quickfire!");
r1 = get_ran(2,1,8); r1 = get_ran(2,1,8);
if(mode == eSpecCtx::COMBAT_MOVE) if(mode == eSpecCtx::COMBAT_MOVE)
damage_pc(i_pc,r1,eDamageType::FIRE,eRace::UNKNOWN,0); damage_pc(which_pc,r1,eDamageType::FIRE,eRace::UNKNOWN,0);
} }
if(univ.town.is_scloud(where_check.x,where_check.y)) { if(univ.town.is_scloud(where_check.x,where_check.y)) {
add_string_to_buf(" Stinking cloud!"); add_string_to_buf(" Stinking cloud!");
univ.party[current_pc].curse(get_ran(1,2,3)); which_pc.curse(get_ran(1,2,3));
} }
if(univ.town.is_sleep_cloud(where_check.x,where_check.y)) { if(univ.town.is_sleep_cloud(where_check.x,where_check.y)) {
add_string_to_buf(" Sleep cloud!"); add_string_to_buf(" Sleep cloud!");
univ.party[current_pc].sleep(eStatus::ASLEEP,3,0); which_pc.sleep(eStatus::ASLEEP,3,0);
} }
if(univ.town.is_fire_barr(where_check.x,where_check.y)) { if(univ.town.is_fire_barr(where_check.x,where_check.y)) {
add_string_to_buf(" Magic barrier!"); add_string_to_buf(" Magic barrier!");
r1 = get_ran(2,1,10); r1 = get_ran(2,1,10);
if(is_town()) fast_bang = 1; if(is_town()) fast_bang = 1;
if(mode == eSpecCtx::COMBAT_MOVE) if(mode == eSpecCtx::COMBAT_MOVE)
damage_pc(i_pc,r1,eDamageType::MAGIC,eRace::UNKNOWN,0); damage_pc(which_pc,r1,eDamageType::MAGIC,eRace::UNKNOWN,0);
else hit_party(r1,eDamageType::MAGIC,0); else hit_party(r1,eDamageType::MAGIC,0);
fast_bang = 0; fast_bang = 0;
} }
@@ -903,7 +902,7 @@ void use_item(short pc,short item) {
case eItemUse::HARM_ONE: case eItemUse::HARM_ONE:
ASB(" You feel terrible."); ASB(" You feel terrible.");
drain_pc(pc,str * 5); drain_pc(pc,str * 5);
damage_pc(pc,20 * str,eDamageType::UNBLOCKABLE,eRace::HUMAN,0); damage_pc(univ.party[pc],20 * str,eDamageType::UNBLOCKABLE,eRace::HUMAN,0);
univ.party[pc].disease(2 * str); univ.party[pc].disease(2 * str);
univ.party[pc].dumbfound(2 * str); univ.party[pc].dumbfound(2 * str);
break; break;
@@ -916,7 +915,7 @@ void use_item(short pc,short item) {
ASB(" You all feel terrible."); ASB(" You all feel terrible.");
for(i = 0; i < 6; i++) { for(i = 0; i < 6; i++) {
drain_pc(i,str * 5); drain_pc(i,str * 5);
damage_pc(i,20 * str,eDamageType::UNBLOCKABLE,eRace::HUMAN,0); damage_pc(univ.party[i],20 * str,eDamageType::UNBLOCKABLE,eRace::HUMAN,0);
univ.party[i].disease(2 * str); univ.party[i].disease(2 * str);
univ.party[i].dumbfound(2 * str); univ.party[i].dumbfound(2 * str);
} }
@@ -978,7 +977,7 @@ void use_item(short pc,short item) {
break; break;
case eItemUse::HARM_ONE: case eItemUse::HARM_ONE:
ASB(" You feel sick."); ASB(" You feel sick.");
damage_pc(pc,20 * str,eDamageType::UNBLOCKABLE,eRace::HUMAN,0); damage_pc(univ.party[pc],20 * str,eDamageType::UNBLOCKABLE,eRace::HUMAN,0);
break; break;
case eItemUse::HELP_ALL: case eItemUse::HELP_ALL:
ASB(" You all feel better."); ASB(" You all feel better.");
@@ -1072,7 +1071,7 @@ void use_item(short pc,short item) {
break; break;
case eItemUse::HARM_ONE: case eItemUse::HARM_ONE:
ASB(" You feel terrible."); ASB(" You feel terrible.");
damage_pc(pc, str*25, eDamageType::UNBLOCKABLE, eRace::UNKNOWN, 0); damage_pc(univ.party[pc], str*25, eDamageType::UNBLOCKABLE, eRace::UNKNOWN, 0);
univ.party[pc].poison(str); univ.party[pc].poison(str);
break; break;
case eItemUse::HELP_ALL: case eItemUse::HELP_ALL:
@@ -1404,14 +1403,13 @@ void change_level(short town_num,short x,short y) {
// Damaging and killing monsters needs to be here because several have specials attached to them. // Damaging and killing monsters needs to be here because several have specials attached to them.
bool damage_monst(short which_m, short who_hit, short how_much, eDamageType dam_type, short sound_type, bool do_print) { bool damage_monst(cCreature& victim, short who_hit, short how_much, eDamageType dam_type, short sound_type, bool do_print) {
cCreature *victim;
short r1,which_spot; short r1,which_spot;
location where_put; location where_put;
//print_num(which_m,(short)univ.town.monst[which_m].m_loc.x,(short)univ.town.monst[which_m].m_loc.y); //print_num(which_m,(short)univ.town.monst[which_m].m_loc.x,(short)univ.town.monst[which_m].m_loc.y);
if(univ.town.monst[which_m].active == 0) return false; if(victim.active == 0) return false;
if(sound_type == 0) { if(sound_type == 0) {
if(dam_type == eDamageType::FIRE || dam_type == eDamageType::UNBLOCKABLE) if(dam_type == eDamageType::FIRE || dam_type == eDamageType::UNBLOCKABLE)
@@ -1424,59 +1422,57 @@ bool damage_monst(short which_m, short who_hit, short how_much, eDamageType dam_
sound_type = 11; sound_type = 11;
} }
victim = &univ.town.monst[which_m];
if(dam_type == eDamageType::MAGIC) { if(dam_type == eDamageType::MAGIC) {
how_much *= victim->magic_res; how_much *= victim.magic_res;
how_much /= 100; how_much /= 100;
} }
if(dam_type == eDamageType::FIRE) { if(dam_type == eDamageType::FIRE) {
how_much *= victim->fire_res; how_much *= victim.fire_res;
how_much /= 100; how_much /= 100;
} }
if(dam_type == eDamageType::COLD) { if(dam_type == eDamageType::COLD) {
how_much *= victim->cold_res; how_much *= victim.cold_res;
how_much /= 100; how_much /= 100;
} }
if(dam_type == eDamageType::POISON) { if(dam_type == eDamageType::POISON) {
how_much *= victim->poison_res; how_much *= victim.poison_res;
how_much /= 100; how_much /= 100;
} }
// Absorb damage? // Absorb damage?
if((dam_type == eDamageType::FIRE || dam_type == eDamageType::MAGIC || dam_type == eDamageType::COLD) if((dam_type == eDamageType::FIRE || dam_type == eDamageType::MAGIC || dam_type == eDamageType::COLD)
&& victim->abil[eMonstAbil::ABSORB_SPELLS].active && get_ran(1,1,1000) <= victim->abil[eMonstAbil::ABSORB_SPELLS].special.extra1) { && victim.abil[eMonstAbil::ABSORB_SPELLS].active && get_ran(1,1,1000) <= victim.abil[eMonstAbil::ABSORB_SPELLS].special.extra1) {
if(32767 - victim->health > how_much) if(32767 - victim.health > how_much)
victim->health = 32767; victim.health = 32767;
else victim->health += how_much; else victim.health += how_much;
ASB(" Magic absorbed."); ASB(" Magic absorbed.");
return false; return false;
} }
// Saving throw // Saving throw
if((dam_type == eDamageType::FIRE || dam_type == eDamageType::COLD) && get_ran(1,0,20) <= victim->level) if((dam_type == eDamageType::FIRE || dam_type == eDamageType::COLD) && get_ran(1,0,20) <= victim.level)
how_much /= 2; how_much /= 2;
if(dam_type == eDamageType::MAGIC && (get_ran(1,0,24) <= victim->level)) if(dam_type == eDamageType::MAGIC && (get_ran(1,0,24) <= victim.level))
how_much /= 2; how_much /= 2;
// Invulnerable? // Invulnerable?
if(dam_type != eDamageType::SPECIAL && victim->invuln) if(dam_type != eDamageType::SPECIAL && victim.invuln)
how_much = how_much / 10; how_much = how_much / 10;
if(dam_type != eDamageType::SPECIAL && victim->status[eStatus::INVULNERABLE] > 0) if(dam_type != eDamageType::SPECIAL && victim.status[eStatus::INVULNERABLE] > 0)
how_much /= 10; how_much /= 10;
// Mag. res helps w. fire and cold // Mag. res helps w. fire and cold
// TODO: Why doesn't this help with magic damage!? // TODO: Why doesn't this help with magic damage!?
if(dam_type == eDamageType::FIRE || dam_type == eDamageType::COLD) { if(dam_type == eDamageType::FIRE || dam_type == eDamageType::COLD) {
int magic_res = victim->status[eStatus::MAGIC_RESISTANCE]; int magic_res = victim.status[eStatus::MAGIC_RESISTANCE];
if(magic_res > 0) if(magic_res > 0)
how_much /= 2; how_much /= 2;
else if(magic_res < 0) else if(magic_res < 0)
how_much *= 2; how_much *= 2;
} }
r1 = get_ran(1,0,(victim->armor * 5) / 4); r1 = get_ran(1,0,(victim.armor * 5) / 4);
r1 += victim->level / 4; r1 += victim.level / 4;
if(dam_type == eDamageType::WEAPON) if(dam_type == eDamageType::WEAPON)
how_much -= r1; how_much -= r1;
@@ -1489,8 +1485,8 @@ bool damage_monst(short which_m, short who_hit, short how_much, eDamageType dam_
boom_type = 0; boom_type = 0;
else if(dam_type == eDamageType::MAGIC) else if(dam_type == eDamageType::MAGIC)
boom_type = 3; boom_type = 3;
univ.town.monst[which_m].marked_damage += how_much; victim.marked_damage += how_much;
add_explosion(victim->cur_loc,how_much,0,boom_type,14 * (victim->x_width - 1),18 * (victim->y_width - 1)); add_explosion(victim.cur_loc,how_much,0,boom_type,14 * (victim.x_width - 1),18 * (victim.y_width - 1));
// Note: Windows version printed an "undamaged" message here if applicable, but I don't think that's right. // Note: Windows version printed an "undamaged" message here if applicable, but I don't think that's right.
if(how_much == 0) if(how_much == 0)
return false; return false;
@@ -1499,7 +1495,7 @@ bool damage_monst(short which_m, short who_hit, short how_much, eDamageType dam_
if(how_much <= 0) { if(how_much <= 0) {
if(is_combat()) if(is_combat())
victim->spell_note(7); victim.spell_note(7);
if(how_much <= 0 && (dam_type == eDamageType::WEAPON || dam_type == eDamageType::UNDEAD || dam_type == eDamageType::DEMON)) { if(how_much <= 0 && (dam_type == eDamageType::WEAPON || dam_type == eDamageType::UNDEAD || dam_type == eDamageType::DEMON)) {
draw_terrain(2); draw_terrain(2);
play_sound(2); play_sound(2);
@@ -1510,88 +1506,88 @@ bool damage_monst(short which_m, short who_hit, short how_much, eDamageType dam_
} }
if(do_print) if(do_print)
victim->damaged_msg(how_much,0); victim.damaged_msg(how_much,0);
victim->health = victim->health - how_much; victim.health = victim.health - how_much;
if(in_scen_debug) if(in_scen_debug)
victim->health = -1; victim.health = -1;
// splitting monsters // splitting monsters
if(victim->abil[eMonstAbil::SPLITS].active && victim->health > 0 && get_ran(1,1,1000) < victim->abil[eMonstAbil::SPLITS].special.extra1){ if(victim.abil[eMonstAbil::SPLITS].active && victim.health > 0 && get_ran(1,1,1000) < victim.abil[eMonstAbil::SPLITS].special.extra1){
where_put = find_clear_spot(victim->cur_loc,1); where_put = find_clear_spot(victim.cur_loc,1);
if(where_put.x > 0) if(where_put.x > 0)
if((which_spot = place_monster(victim->number,where_put)) < 90) { if((which_spot = place_monster(victim.number,where_put)) < 90) {
static_cast<cTownperson&>(univ.town.monst[which_spot]) = *victim; static_cast<cTownperson&>(univ.town.monst[which_spot]) = victim;
univ.town.monst[which_spot].health = victim->health; univ.town.monst[which_spot].health = victim.health;
victim->spell_note(27); victim.spell_note(27);
} }
} }
if(who_hit < 7) if(who_hit < 7)
univ.party.total_dam_done += how_much; univ.party.total_dam_done += how_much;
// Monster damages. Make it hostile. // Monster damages. Make it hostile.
victim->active = 2; victim.active = 2;
if(dam_type != eDamageType::MARKED) { if(dam_type != eDamageType::MARKED) {
if(party_can_see_monst(which_m)) { if(party_can_see_monst(univ.get_target_i(victim) - 100)) {
boom_space(victim->cur_loc,100,boom_gr[dam_type],how_much,sound_type); boom_space(victim.cur_loc,100,boom_gr[dam_type],how_much,sound_type);
} }
else { else {
boom_space(victim->cur_loc,overall_mode, boom_gr[dam_type],how_much,sound_type); boom_space(victim.cur_loc,overall_mode, boom_gr[dam_type],how_much,sound_type);
} }
} }
if(victim->health < 0) { if(victim.health < 0) {
victim->killed_msg(); victim.killed_msg();
kill_monst(victim,who_hit); kill_monst(victim,who_hit);
} }
else { else {
if(how_much > 0) if(how_much > 0)
victim->morale = victim->morale - 1; victim.morale = victim.morale - 1;
if(how_much > 5) if(how_much > 5)
victim->morale = victim->morale - 1; victim.morale = victim.morale - 1;
if(how_much > 10) if(how_much > 10)
victim->morale = victim->morale - 1; victim.morale = victim.morale - 1;
if(how_much > 20) if(how_much > 20)
victim->morale = victim->morale - 2; victim.morale = victim.morale - 2;
} }
if((victim->attitude % 2 != 1) && (who_hit < 7) && if((victim.attitude % 2 != 1) && (who_hit < 7) &&
((processing_fields && !monsters_going) || (processing_fields && !PSD[SDF_HOSTILES_PRESENT]))) { ((processing_fields && !monsters_going) || (processing_fields && !PSD[SDF_HOSTILES_PRESENT]))) {
add_string_to_buf("Damaged an innocent."); add_string_to_buf("Damaged an innocent.");
victim->attitude = 1; victim.attitude = 1;
make_town_hostile(); make_town_hostile();
} }
return true; return true;
} }
void cCreature::petrify(int strength) { void petrify_monst(cCreature& which_m,int strength) {
spell_note(9); which_m.spell_note(9);
short r1 = get_ran(1,0,20); short r1 = get_ran(1,0,20);
r1 += level / 4; r1 += which_m.level / 4;
r1 += status[eStatus::BLESS_CURSE]; r1 += which_m.status[eStatus::BLESS_CURSE];
r1 -= strength; r1 -= strength;
// TODO: This should probably do something similar to charm_monst with the magic resistance // TODO: This should probably do something similar to charm_monst with the magic resistance
if(r1 > 14 || magic_res == 0) if(r1 > 14 || which_m.magic_res == 0)
spell_note(10); which_m.spell_note(10);
else { else {
spell_note(8); which_m.spell_note(8);
kill_monst(this,7); kill_monst(which_m,7,eMainStatus::STONE);
} }
} }
void kill_monst(cCreature *which_m,short who_killed,eMainStatus type) { void kill_monst(cCreature& which_m,short who_killed,eMainStatus type) {
short xp,i,j,s1,s2,s3; short xp,i,j,s1,s2,s3;
location l; location l;
if(isHumanoid(which_m->m_type)) { if(isHumanoid(which_m.m_type)) {
if(which_m->m_type == eRace::GOBLIN) if(which_m.m_type == eRace::GOBLIN)
i = 4; i = 4;
else i = get_ran(1,0,1); else i = get_ran(1,0,1);
play_sound(29 + i); play_sound(29 + i);
} else switch(which_m->m_type) { } else switch(which_m.m_type) {
case eRace::GIANT: play_sound(29); break; case eRace::GIANT: play_sound(29); break;
// TODO: Should birds be considered beasts? If there are any birds in the bladbase, probably; otherwise, better to have new sound // TODO: Should birds be considered beasts? If there are any birds in the bladbase, probably; otherwise, better to have new sound
case eRace::REPTILE: case eRace::BEAST: case eRace::DEMON: case eRace::UNDEAD: case eRace::SKELETAL: case eRace::STONE: case eRace::REPTILE: case eRace::BEAST: case eRace::DEMON: case eRace::UNDEAD: case eRace::SKELETAL: case eRace::STONE:
@@ -1601,16 +1597,16 @@ void kill_monst(cCreature *which_m,short who_killed,eMainStatus type) {
} }
// Special killing effects // Special killing effects
if(univ.party.sd_legit(which_m->spec1,which_m->spec2)) if(univ.party.sd_legit(which_m.spec1,which_m.spec2))
PSD[which_m->spec1][which_m->spec2] = 1; PSD[which_m.spec1][which_m.spec2] = 1;
if(which_m->special_on_kill >= 0) if(which_m.special_on_kill >= 0)
run_special(eSpecCtx::KILL_MONST,2,which_m->special_on_kill,which_m->cur_loc,&s1,&s2,&s3); run_special(eSpecCtx::KILL_MONST,2,which_m.special_on_kill,which_m.cur_loc,&s1,&s2,&s3);
if(which_m->abil[eMonstAbil::DEATH_TRIGGER].active) if(which_m.abil[eMonstAbil::DEATH_TRIGGER].active)
run_special(eSpecCtx::KILL_MONST,0,which_m->abil[eMonstAbil::DEATH_TRIGGER].special.extra1,which_m->cur_loc,&s1,&s2,&s3); run_special(eSpecCtx::KILL_MONST,0,which_m.abil[eMonstAbil::DEATH_TRIGGER].special.extra1,which_m.cur_loc,&s1,&s2,&s3);
if(!in_scen_debug && (which_m->summon_time == 0 || !which_m->party_summoned)) { // no xp for party-summoned monsters if(!in_scen_debug && (which_m.summon_time == 0 || !which_m.party_summoned)) { // no xp for party-summoned monsters
xp = which_m->level * 2; xp = which_m.level * 2;
if(who_killed < 6) if(who_killed < 6)
award_xp(who_killed,xp); award_xp(who_killed,xp);
else if(who_killed == 6) else if(who_killed == 6)
@@ -1620,19 +1616,19 @@ void kill_monst(cCreature *which_m,short who_killed,eMainStatus type) {
i = max((xp / 6),1); i = max((xp / 6),1);
award_party_xp(i); award_party_xp(i);
} }
l = which_m->cur_loc; l = which_m.cur_loc;
place_glands(l,which_m->number); place_glands(l,which_m.number);
} }
if(!in_scen_debug && which_m->summon_time == 0) if(!in_scen_debug && which_m.summon_time == 0)
place_treasure(which_m->cur_loc, which_m->level / 2, which_m->treasure, 0); place_treasure(which_m.cur_loc, which_m.level / 2, which_m.treasure, 0);
i = which_m->cur_loc.x; i = which_m.cur_loc.x;
j = which_m->cur_loc.y; j = which_m.cur_loc.y;
if(type == eMainStatus::DUST) if(type == eMainStatus::DUST)
univ.town.set_ash(i,j,true); univ.town.set_ash(i,j,true);
else if(type == eMainStatus::ABSENT || type == eMainStatus::STONE); else if(type == eMainStatus::ABSENT || type == eMainStatus::STONE);
else switch(which_m->m_type) { else switch(which_m.m_type) {
case eRace::DEMON: case eRace::DEMON:
univ.town.set_ash(i,j,true); univ.town.set_ash(i,j,true);
break; break;
@@ -1652,13 +1648,13 @@ void kill_monst(cCreature *which_m,short who_killed,eMainStatus type) {
break; break;
} }
if((is_town() || which_combat_type == 1) && which_m->summon_time == 0) { if((is_town() || which_combat_type == 1) && which_m.summon_time == 0) {
univ.party.m_killed[univ.town.num]++; univ.party.m_killed[univ.town.num]++;
} }
which_m->spec1 = 0; // make sure, if this is a spec. activated monster, it won't come back which_m.spec1 = 0; // make sure, if this is a spec. activated monster, it won't come back
which_m->active = 0; which_m.active = 0;
} }
// Pushes party and monsters around by moving walls and conveyor belts. // Pushes party and monsters around by moving walls and conveyor belts.
@@ -1775,7 +1771,7 @@ void push_things() {
} }
if(univ.town.is_block(univ.town.p_loc.x,univ.town.p_loc.y)) { if(univ.town.is_block(univ.town.p_loc.x,univ.town.p_loc.y)) {
ASB("You crash into the block."); ASB("You crash into the block.");
damage_pc(i,get_ran(1, 1, 6), eDamageType::WEAPON,eRace::UNKNOWN,0); damage_pc(univ.party[i],get_ran(1, 1, 6), eDamageType::WEAPON,eRace::UNKNOWN,0);
} }
for(k = 0; k < univ.town.items.size(); k++) for(k = 0; k < univ.town.items.size(); k++)
if(univ.town.items[k].variety != eItemType::NO_ITEM && univ.town.items[k].contained if(univ.town.items[k].variety != eItemType::NO_ITEM && univ.town.items[k].contained
@@ -2761,8 +2757,7 @@ void affect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
eDamageType dam_type = (eDamageType) spec.ex2b; eDamageType dam_type = (eDamageType) spec.ex2b;
int snd_type = spec.ex2c < 0 ? 0 : -spec.ex2c; int snd_type = spec.ex2c < 0 ? 0 : -spec.ex2c;
if(pc_num == 6) hit_party(r1, dam_type, snd_type); if(pc_num == 6) hit_party(r1, dam_type, snd_type);
else if(pc_num >= 100) damage_monst(pc_num - 100, 7, r1, dam_type, snd_type); else damage_target(pc_num, r1, dam_type, snd_type);
else damage_pc(pc_num,r1,dam_type,eRace::UNKNOWN, snd_type);
break; break;
} }
case eSpecType::AFFECT_HP: case eSpecType::AFFECT_HP:
@@ -2817,15 +2812,15 @@ void affect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
else switch(spec.ex1a){ else switch(spec.ex1a){
// When passed to kill_pc, the SPLIT party status actually means "no saving throw". // When passed to kill_pc, the SPLIT party status actually means "no saving throw".
case 0: case 0:
kill_pc(i,spec.ex1c > 0 ? eMainStatus::DEAD : eMainStatus::SPLIT_DEAD); kill_pc(univ.party[i],spec.ex1c > 0 ? eMainStatus::DEAD : eMainStatus::SPLIT_DEAD);
break; break;
case 1: case 1:
kill_pc(i,spec.ex1c > 0 ? eMainStatus::DUST : eMainStatus::SPLIT_DUST); kill_pc(univ.party[i],spec.ex1c > 0 ? eMainStatus::DUST : eMainStatus::SPLIT_DUST);
break; break;
case 2: case 2:
if(spec.ex1c > 0) if(spec.ex1c > 0)
univ.party[i].petrify(spec.ex1c); petrify_pc(univ.party[i],spec.ex1c);
else kill_pc(i,eMainStatus::SPLIT_STONE); else kill_pc(univ.party[i],eMainStatus::SPLIT_STONE);
break; break;
case 3: case 3:
if(!is_combat() || which_combat_type != 0) if(!is_combat() || which_combat_type != 0)
@@ -2838,7 +2833,7 @@ void affect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
univ.party[i].main_status += eMainStatus::SPLIT; univ.party[i].main_status += eMainStatus::SPLIT;
break; break;
case 5: case 5:
kill_pc(i,spec.ex1c > 0 ? eMainStatus::ABSENT : eMainStatus::SPLIT_ABSENT); kill_pc(univ.party[i],spec.ex1c > 0 ? eMainStatus::ABSENT : eMainStatus::SPLIT_ABSENT);
break; break;
} }
} }
@@ -2850,18 +2845,18 @@ void affect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
switch(spec.ex1a) { switch(spec.ex1a) {
case 0: case 0:
who.spell_note(46); who.spell_note(46);
kill_monst(&who,7,eMainStatus::DEAD); kill_monst(who,7,eMainStatus::DEAD);
break; break;
case 1: case 1:
who.spell_note(51); who.spell_note(51);
kill_monst(&who,7,eMainStatus::DUST); kill_monst(who,7,eMainStatus::DUST);
break; break;
case 2: case 2:
if(spec.ex1c > 0) if(spec.ex1c > 0)
who.petrify(spec.ex1c); petrify_monst(who,spec.ex1c);
else { else {
who.spell_note(8); who.spell_note(8);
kill_monst(&who,7,eMainStatus::STONE); kill_monst(who,7,eMainStatus::STONE);
} }
break; break;
case 5: case 5:

View File

@@ -9,8 +9,9 @@ void use_spec_item(short item);
void use_item(short pc,short item); void use_item(short pc,short item);
bool use_space(location where); bool use_space(location where);
bool adj_town_look(location where); bool adj_town_look(location where);
bool damage_monst(short which_m, short who_hit, short how_much, eDamageType dam_type, short sound_type, bool do_print = true); bool damage_monst(cCreature& which_m, short who_hit, short how_much, eDamageType dam_type, short sound_type, bool do_print = true);
void kill_monst(cCreature *which_m,short who_killed,eMainStatus type = eMainStatus::DEAD); void petrify_monst(cCreature& which_m,int strength);
void kill_monst(cCreature& which_m,short who_killed,eMainStatus type = eMainStatus::DEAD);
void special_increase_age(long length = 1, bool queue = false); void special_increase_age(long length = 1, bool queue = false);
void do_rest(long length, int hp_restore, int mp_restore); void do_rest(long length, int hp_restore, int mp_restore);
void out_move_party(short x,short y) ; void out_move_party(short x,short y) ;

View File

@@ -1208,7 +1208,7 @@ void bash_door(location where,short pc_num) {
unlock_adjust = univ.scenario.ter_types[terrain].flag2; unlock_adjust = univ.scenario.ter_types[terrain].flag2;
if(unlock_adjust >= 5 || r1 > (unlock_adjust * 15 + 40) || univ.scenario.ter_types[terrain].flag3 != 1) { if(unlock_adjust >= 5 || r1 > (unlock_adjust * 15 + 40) || univ.scenario.ter_types[terrain].flag3 != 1) {
add_string_to_buf(" Didn't work."); add_string_to_buf(" Didn't work.");
damage_pc(pc_num,get_ran(1,1,4),eDamageType::UNBLOCKABLE,eRace::UNKNOWN,0); damage_pc(univ.party[pc_num],get_ran(1,1,4),eDamageType::UNBLOCKABLE,eRace::UNKNOWN,0);
} }
else { else {
add_string_to_buf(" Lock breaks."); add_string_to_buf(" Lock breaks.");

View File

@@ -76,7 +76,7 @@ bool run_trap(short pc_num,eTrapType trap_type,short trap_level,short diff) {
for(i = 0; i < num_hits; i++) { for(i = 0; i < num_hits; i++) {
add_string_to_buf(" A knife flies out!"); add_string_to_buf(" A knife flies out!");
r1 = get_ran(2 + univ.town.difficulty / 14,1,10); r1 = get_ran(2 + univ.town.difficulty / 14,1,10);
damage_pc(pc_num,r1,eDamageType::WEAPON,eRace::UNKNOWN,0); damage_pc(disarmer,r1,eDamageType::WEAPON,eRace::UNKNOWN,0);
} }
break; break;

View File

@@ -46,8 +46,6 @@ public:
void avatar(); void avatar();
void drain_sp(int how_much); void drain_sp(int how_much);
void restore_sp(int how_much); void restore_sp(int how_much);
void petrify(int adj);
void kill(eMainStatus type = eMainStatus::DEAD);
int get_health() const; int get_health() const;
int get_magic() const; int get_magic() const;

View File

@@ -46,7 +46,6 @@ public:
virtual void avatar() = 0; virtual void avatar() = 0;
virtual void drain_sp(int how_much) = 0; virtual void drain_sp(int how_much) = 0;
virtual void restore_sp(int how_much) = 0; virtual void restore_sp(int how_much) = 0;
virtual void petrify(int adj) = 0;
virtual int get_health() const = 0; virtual int get_health() const = 0;
virtual int get_magic() const = 0; virtual int get_magic() const = 0;

View File

@@ -382,11 +382,6 @@ void cParty::restore_sp(int how_much) {
adven[i]->restore_sp(how_much); adven[i]->restore_sp(how_much);
} }
void cParty::petrify(int adj) {
for(int i = 0; i < 6; i++)
adven[i]->petrify(adj);
}
location cParty::get_loc() const { location cParty::get_loc() const {
if(univ.town.num == 200) if(univ.town.num == 200)
return p_loc; return p_loc;

View File

@@ -167,8 +167,6 @@ public:
void avatar(); void avatar();
void drain_sp(int how_much); void drain_sp(int how_much);
void restore_sp(int how_much); void restore_sp(int how_much);
void petrify(int adj);
void kill(eMainStatus type = eMainStatus::DEAD);
int get_health() const; int get_health() const;
int get_magic() const; int get_magic() const;

View File

@@ -81,8 +81,6 @@ public:
void avatar(); void avatar();
void drain_sp(int how_much); void drain_sp(int how_much);
void restore_sp(int how_much); void restore_sp(int how_much);
void petrify(int adj);
void kill(eMainStatus type = eMainStatus::DEAD);
void combine_things(); void combine_things();
void sort_items(); void sort_items();