diff --git a/src/boe.actions.cpp b/src/boe.actions.cpp index 051f988b..437e4692 100644 --- a/src/boe.actions.cpp +++ b/src/boe.actions.cpp @@ -1900,7 +1900,7 @@ bool handle_keystroke(sf::Event& event){ 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) ) - 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); draw_terrain(); @@ -2549,7 +2549,7 @@ void drop_pc(short which) { return; } 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++) univ.party.swap_pcs(i, i + 1); univ.party[5].main_status = eMainStatus::ABSENT; diff --git a/src/boe.combat.cpp b/src/boe.combat.cpp index 0c61b868..418e9000 100644 --- a/src/boe.combat.cpp +++ b/src/boe.combat.cpp @@ -577,11 +577,11 @@ void pc_attack(short who_att,iLiving* target) { } if(r1 <= hit_chance[attacker.skill(eSkill::DEXTERITY)]) { - size_t i_monst = univ.get_target_i(*target); // TODO: Change to damage_target() - if(i_monst >= 100) - damage_monst(i_monst - 100, who_att, r2, eDamageType::WEAPON,4); - else damage_pc(i_monst, r2, eDamageType::WEAPON, univ.party[who_att].race, 4); + if(cCreature* m_target = dynamic_cast(target)) + damage_monst(*m_target, who_att, r2, eDamageType::WEAPON,4); + else if(cPlayer* pc_target = dynamic_cast(target)) + damage_pc(*pc_target, r2, eDamageType::WEAPON, univ.party[who_att].race, 4); } else { draw_terrain(2); @@ -604,7 +604,7 @@ void pc_attack(short who_att,iLiving* target) { if(target->is_shielded()) { int how_much = target->get_shared_dmg(store_hp - target->get_health()); 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; @@ -783,21 +783,21 @@ void pc_attack_weapon(short who_att,iLiving& target,short hit_adj,short dam_adj, bool damaged = false; if(cCreature* monst = dynamic_cast(&target)) { 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) - 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) - 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) monst->damaged_msg(r2, spec_dam + bonus_dam); } else if(cPlayer* who = dynamic_cast(&target)) { eRace race = univ.party[who_att].race; 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) - 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) - 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) { std::string msg = " " + who->name + " takes " + std::to_string(r2); if(spec_dam + bonus_dam) @@ -978,7 +978,7 @@ void place_target(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; bool freebie = false,ap_taken = false,cost_taken = false; short num_targets = 1; @@ -1322,7 +1322,7 @@ void do_combat_cast(location target) { store_sound = 53; r1 = get_ran(4,1,8); 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->poison(5 + r2); break; @@ -1472,10 +1472,10 @@ void do_combat_cast(location target) { add_string_to_buf(" Monster resisted."); else { r1 = get_ran((spell_being_cast == eSpell::TURN_UNDEAD) ? 2 : 6, 1, 14); - size_t i_targ = univ.get_target_i(*victim); - if(i_targ < 100) - damage_pc(i_targ, r1, eDamageType::UNBLOCKABLE, eRace::UNKNOWN, 0); - else damage_monst(i_targ, current_pc, r1, eDamageType::UNBLOCKABLE, 0); + if(cur_monst != nullptr) + damage_monst(*cur_monst, current_pc, r1, eDamageType::UNBLOCKABLE, 0); + else if(cPlayer* who = dynamic_cast(victim)) + damage_pc(*who, r1, eDamageType::UNBLOCKABLE, eRace::UNKNOWN, 0); } store_sound = 24; break; @@ -1499,10 +1499,10 @@ void do_combat_cast(location target) { r1 = get_ran(8 + bonus * 2, 1, 11); if(univ.party[spell_caster].status[eStatus::DUMB] < 0) r1 += -25 * univ.party[spell_caster].status[eStatus::DUMB] / 3; - size_t i_targ = univ.get_target_i(*victim); - if(i_targ < 100) - damage_pc(i_targ, r1, eDamageType::UNBLOCKABLE, eRace::UNKNOWN, 0); - else damage_monst(i_targ, current_pc, r1, eDamageType::UNBLOCKABLE, 0); + if(cur_monst != nullptr) + damage_monst(*cur_monst, current_pc, r1, eDamageType::UNBLOCKABLE, 0); + else if(cPlayer* who = dynamic_cast(victim)) + damage_pc(*who, r1, eDamageType::UNBLOCKABLE, eRace::UNKNOWN, 0); } store_sound = 24; break; @@ -1551,12 +1551,12 @@ void handle_marked_damage() { for(i = 0; i < 6; i++) 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; } for(i = 0; i < univ.town.monst.size(); i++) 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; } @@ -1758,15 +1758,16 @@ void fire_missile(location target) { ASB(" There is a flash of light."); victim->heal(r2); } else if(cCreature* monst = dynamic_cast(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) - 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); } else if(cPlayer* who = dynamic_cast(victim)) { + // TODO: Should the race really be included here? Maybe it's meant for melee attacks only. 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) - 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) { std::string msg = " " + who->name + " takes " + std::to_string(r2); if(spec_dam) msg += '+' + std::to_string(spec_dam); @@ -2595,7 +2596,7 @@ void do_monster_turn() { printed_acid = true; } 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]--; } @@ -2619,7 +2620,7 @@ void do_monster_turn() { printed_poison = true; } 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]--; } if(cur_monst->status[eStatus::DISEASE] > 0) { // Disease @@ -2750,9 +2751,9 @@ void monster_attack(short who_att,iLiving* target) { bool damaged = false; if(m_target != nullptr) { // 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) { - 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) 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()); add_string_to_buf(" Shares damage!"); 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) { @@ -2983,10 +2984,10 @@ void monst_fire_missile(short m_num,short bless,std::pair a if(pc_target != nullptr) { add_string_to_buf(" Hits " + pc_target->name + '.'); // 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) { 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 { if(pc_target != nullptr) @@ -3169,7 +3170,10 @@ void monst_basic_abil(short m_num, std::pair abil, iLiving* break; case eMonstAbil::PETRIFY: 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; case eMonstAbil::DRAIN_SP: if(pc_target != nullptr) { @@ -3916,11 +3920,11 @@ bool monst_cast_priest(cCreature *caster,short targ) { 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) - damage_pc(target,dam,type,eRace::UNKNOWN,0); - else damage_monst(target - 100, 7, dam, type,0); + damage_pc(univ.party[target],dam,type,eRace::UNKNOWN,sound_type); + 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) { case WALL_FORCE: 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; case WALL_FIRE: 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; case WALL_ICE: 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; case WALL_BLADES: 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; case OBJECT_BLOCK: 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; case BARRIER_CAGE: 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; 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; } } @@ -4225,29 +4229,29 @@ static void place_spell_pattern(effect_pat_type pat,location center,unsigned sho break; case WALL_FORCE: 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; case WALL_FIRE: 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; case CLOUD_STINK: which_m->curse(get_ran(1,1,2)); break; case WALL_ICE: 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; case WALL_BLADES: 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; case CLOUD_SLEEP: which_m->sleep(eStatus::ASLEEP,3,0); break; case OBJECT_BLOCK: 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; case BARRIER_CAGE: 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; 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; } } @@ -4341,12 +4345,12 @@ void do_shockwave(location target) { for(i = 0; i < 6; i++) if((dist(target,univ.party[i].combat_pos) > 0) && (dist(target,univ.party[i].combat_pos) < 11) && 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++) 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) && (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); end_missile_anim(); handle_marked_damage(); @@ -4355,16 +4359,17 @@ void do_shockwave(location target) { void radius_damage(location target,short radius, short dam, eDamageType type) { short i; + // TODO: Why no booms in town mode? if(is_town()) { for(i = 0; i < 6; i++) if((dist(target,univ.town.p_loc) > 0) && (dist(target,univ.town.p_loc) <= radius) && 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++) 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) && (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; } @@ -4372,12 +4377,12 @@ void radius_damage(location target,short radius, short dam, eDamageType type) { for(i = 0; i < 6; i++) if((dist(target,univ.party[i].combat_pos) > 0) && (dist(target,univ.party[i].combat_pos) <= radius) && 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++) 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) && (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); end_missile_anim(); 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(univ.town.monst[i].on_space(target)) { if(processing_fields) - damage_monst(i, 6, dam, type,0); - else damage_monst(i, (monsters_going) ? 7 : current_pc, dam, type,0); + damage_monst(univ.town.monst[i], 6, 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; } @@ -4425,7 +4430,7 @@ void hit_space(location target,short dam,eDamageType type,short report,short hit for(i = 0; i < 6; i++) if(univ.party[i].main_status == eMainStatus::ALIVE && !stop_hitting) 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; } if(overall_mode < MODE_COMBAT) @@ -4457,7 +4462,7 @@ void do_poison() { if(univ.party[i].main_status == eMainStatus::ALIVE) if(univ.party[i].status[eStatus::POISON] > 0) { 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) move_to_zero(univ.party[i].status[eStatus::POISON]); 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].status[eStatus::ACID] > 0) { 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]); } if(overall_mode < MODE_COMBAT) diff --git a/src/boe.combat.h b/src/boe.combat.h index c12030b9..8dc256f0 100644 --- a/src/boe.combat.h +++ b/src/boe.combat.h @@ -30,7 +30,7 @@ void monst_basic_abil(short m_num, std::pair abil, iLiving* bool monst_breathe(cCreature *caster,location targ_space,uAbility dam_type); bool monst_cast_mage(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 closest_pc_loc(location where); short count_levels(location where,short radius); diff --git a/src/boe.main.cpp b/src/boe.main.cpp index 30ce6704..8c80518c 100644 --- a/src/boe.main.cpp +++ b/src/boe.main.cpp @@ -441,7 +441,7 @@ void handle_menu_choice(eMenu item_hit) { if(choice < 6) { std::string confirm = cChoiceDlog("delete-pc-confirm",{"yes","no"}).show(); if(confirm == "yes") - kill_pc(choice,eMainStatus::ABSENT); + kill_pc(univ.party[choice],eMainStatus::ABSENT); } draw_terrain(); } diff --git a/src/boe.monster.cpp b/src/boe.monster.cpp index 9196cd1f..8e134bdc 100644 --- a/src/boe.monster.cpp +++ b/src/boe.monster.cpp @@ -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? if(univ.town.is_quickfire(where_check.x,where_check.y)) { 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; } if(univ.town.is_blade_wall(where_check.x,where_check.y)) { r1 = get_ran(6,1,8); 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; } if(univ.town.is_force_wall(where_check.x,where_check.y)) { r1 = get_ran(3,1,6); 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; } 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)) { r1 = get_ran(3,1,6); 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; } 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)) { r1 = get_ran(2,1,6); 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; } 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); if(univ.town.is_fire_barr(where_check.x,where_check.y)) { r1 = get_ran(2,1,10); - damage_monst(which_monst,7,r1,eDamageType::FIRE,0); + damage_monst(*which_m,7,r1,eDamageType::FIRE,0); } } diff --git a/src/boe.party.cpp b/src/boe.party.cpp index bbe7da81..d1728b63 100644 --- a/src/boe.party.cpp +++ b/src/boe.party.cpp @@ -1476,7 +1476,7 @@ void do_mindduel(short pc_num,cCreature *monst) { sout.str(""); sout << " " << univ.party[pc_num].name << " is killed!"; 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->spell_note(22); 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++) 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(); } @@ -2335,10 +2335,10 @@ void slay_party(eMainStatus mode) { 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; - if(univ.party[which_pc].main_status != eMainStatus::ALIVE) + if(which_pc.main_status != eMainStatus::ALIVE) return false; // 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 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++) { - if((univ.party[which_pc].items[i].variety != eItemType::NO_ITEM) && (univ.party[which_pc].equip[i])) { - if(isArmourType(univ.party[which_pc].items[i].variety)) { - r1 = get_ran(1,1,univ.party[which_pc].items[i].item_level); + if((which_pc.items[i].variety != eItemType::NO_ITEM) && (which_pc.equip[i])) { + if(isArmourType(which_pc.items[i].variety)) { + r1 = get_ran(1,1,which_pc.items[i].item_level); how_much -= r1; // bonus for magical items - if(univ.party[which_pc].items[i].bonus > 0) { - r1 = get_ran(1,1,univ.party[which_pc].items[i].bonus); + if(which_pc.items[i].bonus > 0) { + r1 = get_ran(1,1,which_pc.items[i].bonus); 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) { - how_much = how_much - univ.party[which_pc].items[i].bonus; + if(which_pc.items[i].bonus < 0) { + how_much = how_much - which_pc.items[i].bonus; } 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; } - if(univ.party[which_pc].items[i].protection > 0) { - r1 = get_ran(1,1,univ.party[which_pc].items[i].protection); + if(which_pc.items[i].protection > 0) { + r1 = get_ran(1,1,which_pc.items[i].protection); how_much -= r1; } - if(univ.party[which_pc].items[i].protection < 0) { - r1 = get_ran(1,1,-1 * univ.party[which_pc].items[i].protection); + if(which_pc.items[i].protection < 0) { + r1 = get_ran(1,1,-1 * which_pc.items[i].protection); how_much += r1; } } - if(univ.party[which_pc].items[i].ability == eItemAbil::MELEE_PROTECTION) { - r1 = get_ran(1,1,univ.party[which_pc].items[i].abil_data[0]); + if(which_pc.items[i].ability == eItemAbil::MELEE_PROTECTION) { + r1 = get_ran(1,1,which_pc.items[i].abil_data[0]); if(damage_type == eDamageType::DEMON) how_much -= max(1,r1 / 5); 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 // TODO: Used to also apply this to fire damage; is that correct? - if(damage_type == eDamageType::WEAPON && univ.party[which_pc].parry < 100) - how_much -= univ.party[which_pc].parry / 4; + if(damage_type == eDamageType::WEAPON && which_pc.parry < 100) + how_much -= which_pc.parry / 4; if(damage_type != eDamageType::MARKED) { if(PSD[SDF_EASY_MODE] > 0) how_much -= 3; // toughness - if(univ.party[which_pc].traits[eTrait::TOUGHNESS]) + if(which_pc.traits[eTrait::TOUGHNESS]) how_much--; // 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; } - 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; else how_much = how_much / 2; } // 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; 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 // 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; } if(type_of_attacker == eRace::SKELETAL) { // 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; } // 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; // Mag. res helps w. fire and cold // TODO: Why doesn't this help with magic damage!? if(damage_type == eDamageType::FIRE || damage_type == eDamageType::COLD) { - int magic_res = univ.party[which_pc].status[eStatus::MAGIC_RESISTANCE]; + int magic_res = which_pc.status[eStatus::MAGIC_RESISTANCE]; if(magic_res > 0) how_much /= 2; 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 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); if(boom_anim_active) { if(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. short boom_type = 2; 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; if(is_town()) 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) return false; else return true; @@ -2476,14 +2476,14 @@ bool damage_pc(short which_pc,short how_much,eDamageType damage_type,eRace type_ } else { // if asleep, get bonus - if(univ.party[which_pc].status[eStatus::ASLEEP] > 0) - univ.party[which_pc].status[eStatus::ASLEEP]--; + if(which_pc.status[eStatus::ASLEEP] > 0) + which_pc.status[eStatus::ASLEEP]--; 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(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()) 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); @@ -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; - if(univ.party[which_pc].cur_health >= how_much) - univ.party[which_pc].cur_health = univ.party[which_pc].cur_health - how_much; - else if(univ.party[which_pc].cur_health > 0) - univ.party[which_pc].cur_health = 0; + if(which_pc.cur_health >= how_much) + which_pc.cur_health = which_pc.cur_health - how_much; + else if(which_pc.cur_health > 0) + which_pc.cur_health = 0; else // Check if PC can die 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); } 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); } - 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); put_pc_screen(); return true; } -void cPlayer::petrify(int strength) { +void petrify_pc(cPlayer& which_pc,int strength) { std::ostringstream create_line; short r1 = get_ran(1,0,20); - r1 += level / 4; - r1 += status[eStatus::BLESS_CURSE]; + r1 += which_pc.level / 4; + r1 += which_pc.status[eStatus::BLESS_CURSE]; r1 -= strength; - if(has_abil_equip(eItemAbil::PROTECT_FROM_PETRIFY) < 24) + if(which_pc.has_abil_equip(eItemAbil::PROTECT_FROM_PETRIFY) < 24) r1 = 20; if(r1 > 14) { - create_line << " " << name << "resists."; + create_line << " " << which_pc.name << "resists."; } else { - size_t i = 0; - for(int j = 0; j < 6; j++) { - if(this == &party[j]) - i = j; - } - create_line << " " << name << "is turned to stone."; - kill_pc(i,eMainStatus::STONE); + create_line << " " << which_pc.name << "is turned to stone."; + kill_pc(which_pc,eMainStatus::STONE); } 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; bool dummy,no_save = false; location item_loc; @@ -2548,22 +2543,22 @@ void kill_pc(short which_pc,eMainStatus type) { } 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 && get_ran(1,1,100) < hit_chance[luck]) { 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) { - if(combat_active_pc == which_pc) + if(combat_active_pc < 6 && &which_pc == &univ.party[combat_active_pc]) combat_active_pc = 6; 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) 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) for(i = 0; i < 24; i++) - if(univ.party[which_pc].items[i].variety != eItemType::NO_ITEM) { - dummy = place_item(univ.party[which_pc].items[i],item_loc,true); - univ.party[which_pc].items[i].variety = eItemType::NO_ITEM; + if(which_pc.items[i].variety != eItemType::NO_ITEM) { + dummy = place_item(which_pc.items[i],item_loc,true); + which_pc.items[i].variety = eItemType::NO_ITEM; } if(type == eMainStatus::DEAD || type == eMainStatus::DUST) play_sound(21); - univ.party[which_pc].main_status = type; - univ.party[which_pc].ap = 0; + which_pc.main_status = type; + which_pc.ap = 0; } else { add_string_to_buf(" Life saved!"); - univ.party[which_pc].take_item(i); - univ.party[which_pc].heal(200); + which_pc.take_item(i); + which_pc.heal(200); } if(univ.party[current_pc].main_status != eMainStatus::ALIVE) current_pc = first_active_pc(); diff --git a/src/boe.party.h b/src/boe.party.h index e43ebdd6..cd1c1a66 100644 --- a/src/boe.party.h +++ b/src/boe.party.h @@ -37,8 +37,9 @@ mon_num_t pick_trapped_monst(); bool flying() ; void hit_party(short how_much,eDamageType damage_type,short snd_type = 0); 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); -void kill_pc(short which_pc,eMainStatus type); +bool damage_pc(cPlayer& which_pc,short how_much,eDamageType damage_type,eRace type_of_attacker, short sound_type,bool do_print = true); +void petrify_pc(cPlayer& which_pc,int strength); +void kill_pc(cPlayer& which_pc,eMainStatus type); void set_pc_moves(); void take_ap(short num); short trait_present(eTrait which_trait); diff --git a/src/boe.specials.cpp b/src/boe.specials.cpp index 16e775c7..d8a6ed91 100644 --- a/src/boe.specials.cpp +++ b/src/boe.specials.cpp @@ -351,7 +351,7 @@ bool check_special_terrain(location where_check,eSpecCtx mode,cPlayer& which_pc, hit_party(r1,dam_type); fast_bang = 1; 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 boom_space(univ.party.p_loc,overall_mode,pic_type,r1,12); 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 void check_fields(location where_check,eSpecCtx mode,cPlayer& which_pc) { 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) { 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!"); r1 = get_ran(1,1,6) + 1; 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)) { add_string_to_buf(" Force wall!"); r1 = get_ran(2,1,6); 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)) { add_string_to_buf(" Ice wall!"); r1 = get_ran(2,1,6); 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) 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!"); r1 = get_ran(4,1,8); 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)) { add_string_to_buf(" Quickfire!"); r1 = get_ran(2,1,8); 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)) { 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)) { 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)) { add_string_to_buf(" Magic barrier!"); r1 = get_ran(2,1,10); if(is_town()) fast_bang = 1; 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); fast_bang = 0; } @@ -903,7 +902,7 @@ void use_item(short pc,short item) { case eItemUse::HARM_ONE: ASB(" You feel terrible."); 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].dumbfound(2 * str); break; @@ -916,7 +915,7 @@ void use_item(short pc,short item) { 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); + damage_pc(univ.party[i],20 * str,eDamageType::UNBLOCKABLE,eRace::HUMAN,0); univ.party[i].disease(2 * str); univ.party[i].dumbfound(2 * str); } @@ -978,7 +977,7 @@ void use_item(short pc,short item) { break; case eItemUse::HARM_ONE: 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; case eItemUse::HELP_ALL: ASB(" You all feel better."); @@ -1072,7 +1071,7 @@ void use_item(short pc,short item) { break; case eItemUse::HARM_ONE: 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); break; 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. -bool damage_monst(short which_m, short who_hit, short how_much, eDamageType dam_type, short sound_type, bool do_print) { - cCreature *victim; +bool damage_monst(cCreature& victim, short who_hit, short how_much, eDamageType dam_type, short sound_type, bool do_print) { short r1,which_spot; 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); - if(univ.town.monst[which_m].active == 0) return false; + if(victim.active == 0) return false; if(sound_type == 0) { 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; } - victim = &univ.town.monst[which_m]; - if(dam_type == eDamageType::MAGIC) { - how_much *= victim->magic_res; + how_much *= victim.magic_res; how_much /= 100; } if(dam_type == eDamageType::FIRE) { - how_much *= victim->fire_res; + how_much *= victim.fire_res; how_much /= 100; } if(dam_type == eDamageType::COLD) { - how_much *= victim->cold_res; + how_much *= victim.cold_res; how_much /= 100; } if(dam_type == eDamageType::POISON) { - how_much *= victim->poison_res; + how_much *= victim.poison_res; how_much /= 100; } // Absorb damage? 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) { - if(32767 - victim->health > how_much) - victim->health = 32767; - else victim->health += how_much; + && victim.abil[eMonstAbil::ABSORB_SPELLS].active && get_ran(1,1,1000) <= victim.abil[eMonstAbil::ABSORB_SPELLS].special.extra1) { + if(32767 - victim.health > how_much) + victim.health = 32767; + else victim.health += how_much; ASB(" Magic absorbed."); return false; } // 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; - 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; // Invulnerable? - if(dam_type != eDamageType::SPECIAL && victim->invuln) + if(dam_type != eDamageType::SPECIAL && victim.invuln) 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; // Mag. res helps w. fire and cold // TODO: Why doesn't this help with magic damage!? 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) how_much /= 2; else if(magic_res < 0) how_much *= 2; } - r1 = get_ran(1,0,(victim->armor * 5) / 4); - r1 += victim->level / 4; + r1 = get_ran(1,0,(victim.armor * 5) / 4); + r1 += victim.level / 4; if(dam_type == eDamageType::WEAPON) how_much -= r1; @@ -1489,8 +1485,8 @@ bool damage_monst(short which_m, short who_hit, short how_much, eDamageType dam_ boom_type = 0; else if(dam_type == eDamageType::MAGIC) boom_type = 3; - univ.town.monst[which_m].marked_damage += how_much; - add_explosion(victim->cur_loc,how_much,0,boom_type,14 * (victim->x_width - 1),18 * (victim->y_width - 1)); + 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)); // Note: Windows version printed an "undamaged" message here if applicable, but I don't think that's right. if(how_much == 0) 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(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)) { draw_terrain(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) - victim->damaged_msg(how_much,0); - victim->health = victim->health - how_much; + victim.damaged_msg(how_much,0); + victim.health = victim.health - how_much; if(in_scen_debug) - victim->health = -1; + victim.health = -1; // splitting monsters - 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); + 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); if(where_put.x > 0) - if((which_spot = place_monster(victim->number,where_put)) < 90) { - static_cast(univ.town.monst[which_spot]) = *victim; - univ.town.monst[which_spot].health = victim->health; - victim->spell_note(27); + if((which_spot = place_monster(victim.number,where_put)) < 90) { + static_cast(univ.town.monst[which_spot]) = victim; + univ.town.monst[which_spot].health = victim.health; + victim.spell_note(27); } } if(who_hit < 7) univ.party.total_dam_done += how_much; // Monster damages. Make it hostile. - victim->active = 2; + victim.active = 2; if(dam_type != eDamageType::MARKED) { - if(party_can_see_monst(which_m)) { - boom_space(victim->cur_loc,100,boom_gr[dam_type],how_much,sound_type); + 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); } 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) { - victim->killed_msg(); + if(victim.health < 0) { + victim.killed_msg(); kill_monst(victim,who_hit); } else { if(how_much > 0) - victim->morale = victim->morale - 1; + victim.morale = victim.morale - 1; if(how_much > 5) - victim->morale = victim->morale - 1; + victim.morale = victim.morale - 1; if(how_much > 10) - victim->morale = victim->morale - 1; + victim.morale = victim.morale - 1; 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]))) { add_string_to_buf("Damaged an innocent."); - victim->attitude = 1; + victim.attitude = 1; make_town_hostile(); } return true; } -void cCreature::petrify(int strength) { - spell_note(9); +void petrify_monst(cCreature& which_m,int strength) { + which_m.spell_note(9); short r1 = get_ran(1,0,20); - r1 += level / 4; - r1 += status[eStatus::BLESS_CURSE]; + r1 += which_m.level / 4; + r1 += which_m.status[eStatus::BLESS_CURSE]; r1 -= strength; // TODO: This should probably do something similar to charm_monst with the magic resistance - if(r1 > 14 || magic_res == 0) - spell_note(10); + if(r1 > 14 || which_m.magic_res == 0) + which_m.spell_note(10); else { - spell_note(8); - kill_monst(this,7); + which_m.spell_note(8); + 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; location l; - if(isHumanoid(which_m->m_type)) { - if(which_m->m_type == eRace::GOBLIN) + if(isHumanoid(which_m.m_type)) { + if(which_m.m_type == eRace::GOBLIN) i = 4; else i = get_ran(1,0,1); play_sound(29 + i); - } else switch(which_m->m_type) { + } else switch(which_m.m_type) { 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 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 - if(univ.party.sd_legit(which_m->spec1,which_m->spec2)) - PSD[which_m->spec1][which_m->spec2] = 1; + if(univ.party.sd_legit(which_m.spec1,which_m.spec2)) + PSD[which_m.spec1][which_m.spec2] = 1; - 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); - 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); + 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); + 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); - if(!in_scen_debug && (which_m->summon_time == 0 || !which_m->party_summoned)) { // no xp for party-summoned monsters - xp = which_m->level * 2; + if(!in_scen_debug && (which_m.summon_time == 0 || !which_m.party_summoned)) { // no xp for party-summoned monsters + xp = which_m.level * 2; if(who_killed < 6) award_xp(who_killed,xp); 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); award_party_xp(i); } - l = which_m->cur_loc; - place_glands(l,which_m->number); + l = which_m.cur_loc; + place_glands(l,which_m.number); } - if(!in_scen_debug && which_m->summon_time == 0) - place_treasure(which_m->cur_loc, which_m->level / 2, which_m->treasure, 0); + if(!in_scen_debug && which_m.summon_time == 0) + place_treasure(which_m.cur_loc, which_m.level / 2, which_m.treasure, 0); - i = which_m->cur_loc.x; - j = which_m->cur_loc.y; + i = which_m.cur_loc.x; + j = which_m.cur_loc.y; if(type == eMainStatus::DUST) univ.town.set_ash(i,j,true); else if(type == eMainStatus::ABSENT || type == eMainStatus::STONE); - else switch(which_m->m_type) { + else switch(which_m.m_type) { case eRace::DEMON: univ.town.set_ash(i,j,true); break; @@ -1652,13 +1648,13 @@ void kill_monst(cCreature *which_m,short who_killed,eMainStatus type) { 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]++; } - 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. @@ -1775,7 +1771,7 @@ void push_things() { } if(univ.town.is_block(univ.town.p_loc.x,univ.town.p_loc.y)) { 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++) 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; int snd_type = spec.ex2c < 0 ? 0 : -spec.ex2c; 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_pc(pc_num,r1,dam_type,eRace::UNKNOWN, snd_type); + else damage_target(pc_num, r1, dam_type, snd_type); break; } 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){ // When passed to kill_pc, the SPLIT party status actually means "no saving throw". 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; 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; case 2: if(spec.ex1c > 0) - univ.party[i].petrify(spec.ex1c); - else kill_pc(i,eMainStatus::SPLIT_STONE); + petrify_pc(univ.party[i],spec.ex1c); + else kill_pc(univ.party[i],eMainStatus::SPLIT_STONE); break; case 3: 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; break; 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; } } @@ -2850,18 +2845,18 @@ void affect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type, switch(spec.ex1a) { case 0: who.spell_note(46); - kill_monst(&who,7,eMainStatus::DEAD); + kill_monst(who,7,eMainStatus::DEAD); break; case 1: who.spell_note(51); - kill_monst(&who,7,eMainStatus::DUST); + kill_monst(who,7,eMainStatus::DUST); break; case 2: if(spec.ex1c > 0) - who.petrify(spec.ex1c); + petrify_monst(who,spec.ex1c); else { who.spell_note(8); - kill_monst(&who,7,eMainStatus::STONE); + kill_monst(who,7,eMainStatus::STONE); } break; case 5: diff --git a/src/boe.specials.h b/src/boe.specials.h index bb69fff8..53f5803b 100644 --- a/src/boe.specials.h +++ b/src/boe.specials.h @@ -9,8 +9,9 @@ void use_spec_item(short item); void use_item(short pc,short item); bool use_space(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); -void kill_monst(cCreature *which_m,short who_killed,eMainStatus type = eMainStatus::DEAD); +bool damage_monst(cCreature& which_m, short who_hit, short how_much, eDamageType dam_type, short sound_type, bool do_print = true); +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 do_rest(long length, int hp_restore, int mp_restore); void out_move_party(short x,short y) ; diff --git a/src/boe.town.cpp b/src/boe.town.cpp index 78a9c676..b6de83b3 100644 --- a/src/boe.town.cpp +++ b/src/boe.town.cpp @@ -1208,7 +1208,7 @@ void bash_door(location where,short pc_num) { unlock_adjust = univ.scenario.ter_types[terrain].flag2; if(unlock_adjust >= 5 || r1 > (unlock_adjust * 15 + 40) || univ.scenario.ter_types[terrain].flag3 != 1) { 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 { add_string_to_buf(" Lock breaks."); diff --git a/src/boe.townspec.cpp b/src/boe.townspec.cpp index 5928ef4d..50a7f696 100644 --- a/src/boe.townspec.cpp +++ b/src/boe.townspec.cpp @@ -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++) { add_string_to_buf(" A knife flies out!"); 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; diff --git a/src/classes/creature.hpp b/src/classes/creature.hpp index 39e6a5cd..af075ae4 100644 --- a/src/classes/creature.hpp +++ b/src/classes/creature.hpp @@ -46,8 +46,6 @@ public: void avatar(); void drain_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_magic() const; diff --git a/src/classes/living.hpp b/src/classes/living.hpp index 45961d67..3378562b 100644 --- a/src/classes/living.hpp +++ b/src/classes/living.hpp @@ -46,7 +46,6 @@ public: virtual void avatar() = 0; virtual void drain_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_magic() const = 0; diff --git a/src/classes/party.cpp b/src/classes/party.cpp index 5c90c48a..d7e01d89 100644 --- a/src/classes/party.cpp +++ b/src/classes/party.cpp @@ -382,11 +382,6 @@ void cParty::restore_sp(int 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 { if(univ.town.num == 200) return p_loc; diff --git a/src/classes/party.h b/src/classes/party.h index 45088ad2..70f886ff 100644 --- a/src/classes/party.h +++ b/src/classes/party.h @@ -167,8 +167,6 @@ public: void avatar(); void drain_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_magic() const; diff --git a/src/classes/pc.h b/src/classes/pc.h index d10d9fc7..4c63a9d6 100644 --- a/src/classes/pc.h +++ b/src/classes/pc.h @@ -81,8 +81,6 @@ public: void avatar(); void drain_sp(int how_much); void restore_sp(int how_much); - void petrify(int adj); - void kill(eMainStatus type = eMainStatus::DEAD); void combine_things(); void sort_items();