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)
&& (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;

View File

@@ -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<cCreature*>(target))
damage_monst(*m_target, who_att, r2, eDamageType::WEAPON,4);
else if(cPlayer* pc_target = dynamic_cast<cPlayer*>(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<cCreature*>(&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<cPlayer*>(&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<cPlayer*>(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<cPlayer*>(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<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)
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<cPlayer*>(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<eMonstAbil,uAbility> 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<eMonstAbil,uAbility> 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)

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_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);

View File

@@ -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();
}

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?
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);
}
}

View File

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

View File

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

View File

@@ -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<cTownperson&>(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<cTownperson&>(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:

View File

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

View File

@@ -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.");

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++) {
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;

View File

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

View File

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

View File

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

View File

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

View File

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