Don't hard-code player max inventory size at all use points
This commit is contained in:
@@ -1571,14 +1571,13 @@ void initiate_outdoor_combat(short i) {
|
||||
|
||||
univ.party.out_c[i].exists = false;
|
||||
|
||||
for(short m = 0; m < 6; m++)
|
||||
if(univ.party[m].main_status == eMainStatus::ALIVE)
|
||||
to_place = univ.party[m].combat_pos;
|
||||
for(short m = 0; m < 6; m++)
|
||||
for(short n = 0; n < 24; n++)
|
||||
if(univ.party[m].main_status != eMainStatus::ALIVE && univ.party[m].items[n].variety != eItemType::NO_ITEM) {
|
||||
place_item(univ.party[m].items[n],to_place);
|
||||
univ.party[m].items[n].variety = eItemType::NO_ITEM;
|
||||
for(cPlayer& pc : univ.party)
|
||||
if(pc.main_status == eMainStatus::ALIVE)
|
||||
to_place = pc.combat_pos;
|
||||
else for(cItem& item : pc.items)
|
||||
if(item.variety != eItemType::NO_ITEM) {
|
||||
place_item(item,to_place);
|
||||
item.variety = eItemType::NO_ITEM;
|
||||
}
|
||||
|
||||
overall_mode = MODE_COMBAT;
|
||||
@@ -2258,9 +2257,8 @@ void do_rest(long length, int hp_restore, int mp_restore) {
|
||||
// Specials countdowns
|
||||
if((length > 500 || age_before / 500 < univ.party.age / 500) && univ.party.has_abil(eItemAbil::OCCASIONAL_STATUS)) {
|
||||
// TODO: There used to be a "display strings" here; should we hook in a special node call?
|
||||
for(int i = 0; i < 6; i++)
|
||||
for(int j = 0; j < 24; j++) {
|
||||
cItem& item = univ.party[i].items[j];
|
||||
for(cPlayer& pc : univ.party)
|
||||
for(const cItem& item : pc.items) {
|
||||
if(item.ability != eItemAbil::OCCASIONAL_STATUS) continue;
|
||||
if(item.abil_data[1] > 15) continue;
|
||||
if(!item.abil_group()) continue;
|
||||
@@ -2279,27 +2277,27 @@ void do_rest(long length, int hp_restore, int mp_restore) {
|
||||
univ.party.heal(hp_restore);
|
||||
univ.party.restore_sp(mp_restore);
|
||||
// Recuperation and chronic disease disads
|
||||
for(int i = 0; i < 6; i++)
|
||||
if(univ.party[i].main_status == eMainStatus::ALIVE) {
|
||||
if(univ.party[i].traits[eTrait::RECUPERATION] && univ.party[i].cur_health < univ.party[i].max_health) {
|
||||
univ.party[i].heal(hp_restore / 5);
|
||||
for(cPlayer& pc : univ.party)
|
||||
if(pc.main_status == eMainStatus::ALIVE) {
|
||||
if(pc.traits[eTrait::RECUPERATION] && pc.cur_health < pc.max_health) {
|
||||
pc.heal(hp_restore / 5);
|
||||
}
|
||||
if(univ.party[i].traits[eTrait::CHRONIC_DISEASE] && get_ran(1,0,110) == 1) {
|
||||
univ.party[i].disease(6);
|
||||
if(pc.traits[eTrait::CHRONIC_DISEASE] && get_ran(1,0,110) == 1) {
|
||||
pc.disease(6);
|
||||
}
|
||||
short item = univ.party[i].has_abil_equip(eItemAbil::REGENERATE);
|
||||
if(item < 24 && univ.party[i].cur_health < univ.party[i].max_health && (overall_mode > MODE_OUTDOORS || get_ran(1,0,10) == 5)){
|
||||
int j = get_ran(1,0,univ.party[i].items[item].abil_data[0] / 3);
|
||||
if(univ.party[i].items[item].abil_data[0] / 3 == 0)
|
||||
short item = pc.has_abil_equip(eItemAbil::REGENERATE);
|
||||
if(item < pc.items.size() && pc.cur_health < pc.max_health && (overall_mode > MODE_OUTDOORS || get_ran(1,0,10) == 5)){
|
||||
int j = get_ran(1,0,pc.items[item].abil_data[0] / 3);
|
||||
if(pc.items[item].abil_data[0] / 3 == 0)
|
||||
j = get_ran(1,0,1);
|
||||
if(is_out()) j = j * 4;
|
||||
univ.party[i].heal(j);
|
||||
pc.heal(j);
|
||||
}
|
||||
// Bonus SP and HP wear off
|
||||
if(univ.party[i].cur_sp > univ.party[i].max_sp)
|
||||
univ.party[i].cur_sp = univ.party[i].max_sp;
|
||||
if(univ.party[i].cur_health > univ.party[i].max_health)
|
||||
univ.party[i].cur_health = univ.party[i].max_health;
|
||||
if(pc.cur_sp > pc.max_sp)
|
||||
pc.cur_sp = pc.max_sp;
|
||||
if(pc.cur_health > pc.max_health)
|
||||
pc.cur_health = pc.max_health;
|
||||
}
|
||||
special_increase_age(length, true);
|
||||
put_pc_screen();
|
||||
@@ -2377,9 +2375,8 @@ void increase_age() {
|
||||
// Specials countdowns
|
||||
if(univ.party.age % 500 == 0 && univ.party.has_abil(eItemAbil::OCCASIONAL_STATUS)) {
|
||||
// TODO: There used to be a "display strings" here; should we hook in a special node call?
|
||||
for(int i = 0; i < 6; i++)
|
||||
for(int j = 0; j < 24; j++) {
|
||||
cItem& item = univ.party[i].items[j];
|
||||
for(cPlayer& pc : univ.party)
|
||||
for(const cItem& item : pc.items) {
|
||||
if(item.ability != eItemAbil::OCCASIONAL_STATUS) continue;
|
||||
if(item.abil_data[1] > 15) continue;
|
||||
if(!item.abil_group()) continue;
|
||||
@@ -2507,17 +2504,16 @@ void increase_age() {
|
||||
|
||||
// Blessing, slowed,etc.
|
||||
if(univ.party.age % 4 == 0)
|
||||
for(short i = 0; i < 6; i++) {
|
||||
move_to_zero(univ.party[i].status[eStatus::BLESS_CURSE]);
|
||||
move_to_zero(univ.party[i].status[eStatus::HASTE_SLOW]);
|
||||
if((item = univ.party[i].has_abil_equip(eItemAbil::REGENERATE)) < 24
|
||||
&& (univ.party[i].cur_health < univ.party[i].max_health)
|
||||
for(cPlayer& pc : univ.party) {
|
||||
move_to_zero(pc.status[eStatus::BLESS_CURSE]);
|
||||
move_to_zero(pc.status[eStatus::HASTE_SLOW]);
|
||||
if((item = pc.has_abil_equip(eItemAbil::REGENERATE)) < pc.items.size() && (pc.cur_health < pc.max_health)
|
||||
&& ((overall_mode > MODE_OUTDOORS) || (get_ran(1,0,10) == 5))){
|
||||
int j = get_ran(1,0,univ.party[i].items[item].abil_data[0] / 3);
|
||||
if(univ.party[i].items[item].abil_data[0] / 3 == 0)
|
||||
int j = get_ran(1,0,pc.items[item].abil_data[0] / 3);
|
||||
if(pc.items[item].abil_data[0] / 3 == 0)
|
||||
j = get_ran(1,0,1);
|
||||
if(is_out()) j = j * 4;
|
||||
univ.party[i].heal(j);
|
||||
pc.heal(j);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -512,7 +512,7 @@ void char_stand_ready() {
|
||||
}
|
||||
|
||||
void pc_attack(short who_att,iLiving* target) {
|
||||
short r1,r2,weap1 = 24, weap2 = 24,skill_item;
|
||||
short r1,r2,skill_item;
|
||||
short hit_adj, dam_adj;
|
||||
cPlayer& attacker = univ.party[who_att];
|
||||
|
||||
@@ -529,12 +529,8 @@ void pc_attack(short who_att,iLiving* target) {
|
||||
|
||||
attacker.last_attacked = target;
|
||||
|
||||
for(short i = 0; i < 24; i++)
|
||||
if((attacker.items[i].variety == eItemType::ONE_HANDED || attacker.items[i].variety == eItemType::TWO_HANDED) && attacker.equip[i]) {
|
||||
if(weap1 == 24)
|
||||
weap1 = i;
|
||||
else weap2 = i;
|
||||
}
|
||||
auto weapons = attacker.get_weapons();
|
||||
auto weap1 = weapons.first, weap2 = weapons.second, no_weap = attacker.items.cend();
|
||||
|
||||
hit_adj = (-5 * minmax(-8,8,attacker.status[eStatus::BLESS_CURSE])) + 5 * minmax(-8,8,target->status[eStatus::BLESS_CURSE])
|
||||
- attacker.stat_adj(eSkill::DEXTERITY) * 5 + (get_encumbrance(who_att)) * 5;
|
||||
@@ -548,11 +544,11 @@ void pc_attack(short who_att,iLiving* target) {
|
||||
}
|
||||
|
||||
// TODO: These don't stack?
|
||||
if((skill_item = attacker.has_abil_equip(eItemAbil::SKILL)) < 24) {
|
||||
if((skill_item = attacker.has_abil_equip(eItemAbil::SKILL)) < attacker.items.size()) {
|
||||
hit_adj += 5 * (attacker.items[skill_item].abil_data[0] / 2 + 1);
|
||||
dam_adj += attacker.items[skill_item].abil_data[0] / 2;
|
||||
}
|
||||
if((skill_item = attacker.has_abil_equip(eItemAbil::GIANT_STRENGTH)) < 24) {
|
||||
if((skill_item = attacker.has_abil_equip(eItemAbil::GIANT_STRENGTH)) < attacker.items.size()) {
|
||||
dam_adj += attacker.items[skill_item].abil_data[0];
|
||||
hit_adj += attacker.items[skill_item].abil_data[0] * 2;
|
||||
}
|
||||
@@ -563,7 +559,7 @@ void pc_attack(short who_att,iLiving* target) {
|
||||
|
||||
combat_posing_monster = current_working_monster = who_att;
|
||||
|
||||
if(weap1 == 24) {
|
||||
if(weap1 == no_weap) {
|
||||
std::string create_line = univ.party[who_att].name + " punches.";
|
||||
add_string_to_buf(create_line);
|
||||
|
||||
@@ -605,11 +601,11 @@ void pc_attack(short who_att,iLiving* target) {
|
||||
}
|
||||
}
|
||||
|
||||
short weap_poisoned = attacker.weap_poisoned;
|
||||
if(weap1 < 24)
|
||||
pc_attack_weapon(who_att, *target, hit_adj, dam_adj, attacker.items[weap1], weap2 < 24 ? 2 : 1, weap_poisoned == weap1);
|
||||
if(weap2 < 24 && target->is_alive())
|
||||
pc_attack_weapon(who_att, *target, hit_adj, dam_adj, attacker.items[weap2], 0, weap_poisoned == weap2);
|
||||
auto weap_poisoned = attacker.items.begin() + attacker.weap_poisoned;
|
||||
if(weap1 != no_weap)
|
||||
pc_attack_weapon(who_att, *target, hit_adj, dam_adj, *weap1, 1 + (weap2 != no_weap), weap_poisoned == weap1);
|
||||
if(weap2 != no_weap && target->is_alive())
|
||||
pc_attack_weapon(who_att, *target, hit_adj, dam_adj, *weap2, 0, weap_poisoned == weap2);
|
||||
move_to_zero(attacker.status[eStatus::POISONED_WEAPON]);
|
||||
take_ap(4);
|
||||
|
||||
@@ -699,19 +695,19 @@ static void apply_weapon_status(eStatus status, int how_much, int dmg, iLiving&
|
||||
}
|
||||
|
||||
// primary: 0 - secondary weapon, 1 - primary (and only) weapon, 2 - primary of two weapons
|
||||
void pc_attack_weapon(short who_att,iLiving& target,short hit_adj,short dam_adj,cItem& weap,short primary,bool do_poison) {
|
||||
void pc_attack_weapon(short who_att,iLiving& target,short hit_adj,short dam_adj,const cItem& weap,short primary,bool do_poison) {
|
||||
short r1, r2;
|
||||
cPlayer& attacker = univ.party[who_att];
|
||||
|
||||
// safety valve
|
||||
int skill;
|
||||
if(weap.weap_type == eSkill::INVALID)
|
||||
skill = univ.party[who_att].skill(eSkill::EDGED_WEAPONS);
|
||||
skill = attacker.skill(eSkill::EDGED_WEAPONS);
|
||||
else if(weap.weap_type == eSkill::MAX_HP)
|
||||
skill = 20 * univ.party[who_att].cur_health / univ.party[who_att].max_health;
|
||||
skill = 20 * attacker.cur_health / attacker.max_health;
|
||||
else if(weap.weap_type == eSkill::MAX_SP)
|
||||
skill = 20 * univ.party[who_att].cur_sp / univ.party[who_att].max_sp;
|
||||
else skill = univ.party[who_att].skill(weap.weap_type);
|
||||
skill = 20 * attacker.cur_sp / attacker.max_sp;
|
||||
else skill = attacker.skill(weap.weap_type);
|
||||
|
||||
std::string create_line = attacker.name + " swings.";
|
||||
add_string_to_buf(create_line);
|
||||
@@ -780,8 +776,8 @@ void pc_attack_weapon(short who_att,iLiving& target,short hit_adj,short dam_adj,
|
||||
splits = who->amorphous;
|
||||
// assassinate
|
||||
r1 = get_ran(1,1,100);
|
||||
int assassin = univ.party[who_att].skill(eSkill::ASSASSINATION);
|
||||
if((univ.party[who_att].level >= target.get_level() - 1) && assassin >= target.get_level() / 2
|
||||
int assassin = attacker.skill(eSkill::ASSASSINATION);
|
||||
if((attacker.level >= target.get_level() - 1) && assassin >= target.get_level() / 2
|
||||
&& !splits) // Can't assassinate splitters
|
||||
if(r1 < hit_chance[max(assassin - target.get_level(),0)]) {
|
||||
add_string_to_buf(" You assassinate.");
|
||||
@@ -821,7 +817,7 @@ void pc_attack_weapon(short who_att,iLiving& target,short hit_adj,short dam_adj,
|
||||
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;
|
||||
eRace race = attacker.race;
|
||||
if(dmg_snd != no_dmg)
|
||||
damaged = damaged || damage_pc(*who, r2, eDamageType::WEAPON, race, dmg_snd, false);
|
||||
if(spec_dam)
|
||||
@@ -837,21 +833,21 @@ void pc_attack_weapon(short who_att,iLiving& target,short hit_adj,short dam_adj,
|
||||
}
|
||||
if(do_poison) {
|
||||
// poison
|
||||
if(univ.party[who_att].status[eStatus::POISONED_WEAPON] > 0) {
|
||||
short poison_amt = univ.party[who_att].status[eStatus::POISONED_WEAPON];
|
||||
if(univ.party[who_att].has_abil_equip(eItemAbil::POISON_AUGMENT) < 24)
|
||||
if(attacker.status[eStatus::POISONED_WEAPON] > 0) {
|
||||
short poison_amt = attacker.status[eStatus::POISONED_WEAPON];
|
||||
if(attacker.has_abil_equip(eItemAbil::POISON_AUGMENT) < attacker.items.size())
|
||||
poison_amt += 2;
|
||||
target.poison(poison_amt);
|
||||
if(dynamic_cast<cPlayer*>(&target))
|
||||
put_pc_screen();
|
||||
move_to_zero(univ.party[who_att].status[eStatus::POISONED_WEAPON]);
|
||||
move_to_zero(attacker.status[eStatus::POISONED_WEAPON]);
|
||||
}
|
||||
}
|
||||
if((weap.ability == eItemAbil::STATUS_WEAPON) && (get_ran(1,0,1) == 1)) {
|
||||
apply_weapon_status(eStatus(weap.abil_data[1]), weap.abil_data[0], r2 + spec_dam, target, "Blade");
|
||||
} else if(weap.ability == eItemAbil::SOULSUCKER && get_ran(1,0,1) == 1) {
|
||||
add_string_to_buf(" Blade drains life.");
|
||||
univ.party[who_att].heal(weap.abil_data[0] / 2);
|
||||
attacker.heal(weap.abil_data[0] / 2);
|
||||
} else if(weap.ability == eItemAbil::ANTIMAGIC_WEAPON) {
|
||||
short before = target.get_magic();
|
||||
int mage = 0, cleric = 0;
|
||||
@@ -863,16 +859,16 @@ void pc_attack_weapon(short who_att,iLiving& target,short hit_adj,short dam_adj,
|
||||
target.drain_sp(weap.abil_data[0]);
|
||||
if(before > target.get_magic()) {
|
||||
add_string_to_buf(" Blade drains energy.");
|
||||
univ.party[who_att].restore_sp(before / 3);
|
||||
attacker.restore_sp(before / 3);
|
||||
}
|
||||
} else if(weap.ability == eItemAbil::WEAPON_CALL_SPECIAL) {
|
||||
short s1,s2,s3;
|
||||
univ.party.force_ptr(21, target.get_loc().x);
|
||||
univ.party.force_ptr(22, target.get_loc().y);
|
||||
univ.party.force_ptr(20, i_monst);
|
||||
run_special(eSpecCtx::ATTACKING_MELEE, 0, weap.abil_data[0],univ.party[who_att].combat_pos, &s1, &s2, &s3);
|
||||
run_special(eSpecCtx::ATTACKING_MELEE, 0, weap.abil_data[0],attacker.combat_pos, &s1, &s2, &s3);
|
||||
if(s1 > 0)
|
||||
univ.party[who_att].ap += 4;
|
||||
attacker.ap += 4;
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -1416,7 +1412,7 @@ void do_combat_cast(location target) {
|
||||
add_string_to_buf(" Can't duel: no magic.");
|
||||
else {
|
||||
item = caster.has_abil(eItemAbil::SMOKY_CRYSTAL);
|
||||
if(item >= 24)
|
||||
if(item >= caster.items.size())
|
||||
add_string_to_buf(" You need a smoky crystal. ");
|
||||
else {
|
||||
caster.remove_charge(item);
|
||||
@@ -1854,7 +1850,7 @@ void fire_missile(location target) {
|
||||
// poison
|
||||
if(missile_firer.status[eStatus::POISONED_WEAPON] > 0 && missile_firer.weap_poisoned == ammo_inv_slot) {
|
||||
poison_amt = missile_firer.status[eStatus::POISONED_WEAPON];
|
||||
if(missile_firer.has_abil_equip(eItemAbil::POISON_AUGMENT) < 24)
|
||||
if(missile_firer.has_abil_equip(eItemAbil::POISON_AUGMENT) < missile_firer.items.size())
|
||||
poison_amt++;
|
||||
victim->poison(poison_amt);
|
||||
if(dynamic_cast<cPlayer*>(victim))
|
||||
@@ -1897,7 +1893,7 @@ void fire_missile(location target) {
|
||||
run_special(eSpecCtx::ATTACKED_RANGE, 0, monst->abil[eMonstAbil::HIT_TRIGGER].special.extra1, missile_firer.combat_pos, &s1, &s2, &s3);
|
||||
if(s1 > 0)
|
||||
missile_firer.ap += (overall_mode == MODE_FIRING) ? 3 : 2;
|
||||
} else if((pc = dynamic_cast<cPlayer*>(victim)) && (spec_item = pc->has_abil_equip(eItemAbil::HIT_CALL_SPECIAL)) < 24) {
|
||||
} else if((pc = dynamic_cast<cPlayer*>(victim)) && (spec_item = pc->has_abil_equip(eItemAbil::HIT_CALL_SPECIAL)) < pc->items.size()) {
|
||||
short s1,s2,s3;
|
||||
univ.party.force_ptr(21, pc->combat_pos.x);
|
||||
univ.party.force_ptr(22, pc->combat_pos.y);
|
||||
@@ -1913,7 +1909,7 @@ void fire_missile(location target) {
|
||||
if(ammo.ability != eItemAbil::RETURNING_MISSILE)
|
||||
ammo.charges--;
|
||||
else ammo.charges = 1;
|
||||
if(missile_firer.has_abil_equip(eItemAbil::DRAIN_MISSILES) < 24
|
||||
if(missile_firer.has_abil_equip(eItemAbil::DRAIN_MISSILES) < missile_firer.items.size()
|
||||
&& ammo.ability != eItemAbil::RETURNING_MISSILE)
|
||||
ammo.charges--;
|
||||
if(ammo.charges <= 0)
|
||||
@@ -2083,34 +2079,33 @@ void combat_run_monst() {
|
||||
|
||||
univ.party.age++;
|
||||
if(univ.party.age % 4 == 0)
|
||||
for(short i = 0; i < 6; i++) {
|
||||
if(univ.party[i].status[eStatus::BLESS_CURSE] != 0 || univ.party[i].status[eStatus::HASTE_SLOW] != 0)
|
||||
for(cPlayer& pc : univ.party) {
|
||||
if(pc.status[eStatus::BLESS_CURSE] != 0 || pc.status[eStatus::HASTE_SLOW] != 0)
|
||||
update_stat = true;
|
||||
move_to_zero(univ.party[i].status[eStatus::BLESS_CURSE]);
|
||||
move_to_zero(univ.party[i].status[eStatus::HASTE_SLOW]);
|
||||
move_to_zero(pc.status[eStatus::BLESS_CURSE]);
|
||||
move_to_zero(pc.status[eStatus::HASTE_SLOW]);
|
||||
move_to_zero(univ.party.status[ePartyStatus::STEALTH]);
|
||||
if((item = univ.party[i].has_abil_equip(eItemAbil::REGENERATE)) < 24) {
|
||||
if((item = pc.has_abil_equip(eItemAbil::REGENERATE)) < pc.items.size()) {
|
||||
update_stat = true;
|
||||
univ.party[i].heal(get_ran(1,0,univ.party[i].items[item].item_level + 1));
|
||||
pc.heal(get_ran(1,0,pc.items[item].item_level + 1));
|
||||
}
|
||||
}
|
||||
for(short i = 0; i < 6; i++)
|
||||
if(univ.party[i].main_status == eMainStatus::ALIVE) {
|
||||
if(univ.party[i].status[eStatus::INVULNERABLE] != 0 || univ.party[i].status[eStatus::MAGIC_RESISTANCE] != 0
|
||||
|| univ.party[i].status[eStatus::INVISIBLE] != 0 || univ.party[i].status[eStatus::MARTYRS_SHIELD] != 0
|
||||
|| univ.party[i].status[eStatus::ASLEEP] != 0 || univ.party[i].status[eStatus::PARALYZED] != 0)
|
||||
for(cPlayer& pc : univ.party)
|
||||
if(pc.main_status == eMainStatus::ALIVE) {
|
||||
if(pc.status[eStatus::INVULNERABLE] != 0 || pc.status[eStatus::MAGIC_RESISTANCE] != 0
|
||||
|| pc.status[eStatus::INVISIBLE] != 0 || pc.status[eStatus::MARTYRS_SHIELD] != 0
|
||||
|| pc.status[eStatus::ASLEEP] != 0 || pc.status[eStatus::PARALYZED] != 0)
|
||||
update_stat = true;
|
||||
|
||||
move_to_zero(univ.party[i].status[eStatus::INVULNERABLE]);
|
||||
move_to_zero(univ.party[i].status[eStatus::MAGIC_RESISTANCE]);
|
||||
move_to_zero(univ.party[i].status[eStatus::INVISIBLE]);
|
||||
move_to_zero(univ.party[i].status[eStatus::MARTYRS_SHIELD]);
|
||||
move_to_zero(univ.party[i].status[eStatus::ASLEEP]);
|
||||
move_to_zero(univ.party[i].status[eStatus::PARALYZED]);
|
||||
move_to_zero(pc.status[eStatus::INVULNERABLE]);
|
||||
move_to_zero(pc.status[eStatus::MAGIC_RESISTANCE]);
|
||||
move_to_zero(pc.status[eStatus::INVISIBLE]);
|
||||
move_to_zero(pc.status[eStatus::MARTYRS_SHIELD]);
|
||||
move_to_zero(pc.status[eStatus::ASLEEP]);
|
||||
move_to_zero(pc.status[eStatus::PARALYZED]);
|
||||
|
||||
// Do special items
|
||||
for(int j = 0; j < 24; j++) {
|
||||
cItem& item = univ.party[i].items[j];
|
||||
for(const cItem& item : pc.items) {
|
||||
if(item.ability != eItemAbil::OCCASIONAL_STATUS) continue;
|
||||
if(item.abil_group()) continue; // Affects whole party, which is handled elsewhere
|
||||
if(get_ran(1,0,10) != 5) continue;
|
||||
@@ -2132,7 +2127,7 @@ void combat_run_monst() {
|
||||
break;
|
||||
case eStatus::POISON:
|
||||
if(how_much > 0) add_string_to_buf("An item poisons you!");
|
||||
else if(univ.party[i].status[eStatus::POISON] > 0)
|
||||
else if(pc.status[eStatus::POISON] > 0)
|
||||
add_string_to_buf("An item cures you!");
|
||||
break;
|
||||
case eStatus::INVULNERABLE:
|
||||
@@ -2144,55 +2139,49 @@ void combat_run_monst() {
|
||||
break;
|
||||
case eStatus::DISEASE:
|
||||
if(how_much > 0) add_string_to_buf("An item diseases you!");
|
||||
else if(univ.party[i].status[eStatus::DISEASE] > 0)
|
||||
else if(pc.status[eStatus::DISEASE] > 0)
|
||||
add_string_to_buf("An item cures you!");
|
||||
break;
|
||||
case eStatus::DUMB:
|
||||
if(how_much > 0) add_string_to_buf("An item clouds your mind!");
|
||||
else if(univ.party[i].status[eStatus::DUMB] > 0)
|
||||
else if(pc.status[eStatus::DUMB] > 0)
|
||||
add_string_to_buf("An item clears your mind!");
|
||||
else add_string_to_buf("An item enlightens you!");
|
||||
break;
|
||||
case eStatus::WEBS:
|
||||
if(how_much > 0) add_string_to_buf("An item constricts you!");
|
||||
else if(univ.party[i].status[eStatus::WEBS] > 0)
|
||||
else if(pc.status[eStatus::WEBS] > 0)
|
||||
add_string_to_buf("An item cleanses you!");
|
||||
break;
|
||||
case eStatus::ASLEEP:
|
||||
if(how_much > 0) add_string_to_buf("An item knocks you out!");
|
||||
else if(univ.party[i].status[eStatus::ASLEEP] > 0)
|
||||
else if(pc.status[eStatus::ASLEEP] > 0)
|
||||
add_string_to_buf("An item wakes you!");
|
||||
else add_string_to_buf("An item makes you restless!");
|
||||
break;
|
||||
case eStatus::PARALYZED:
|
||||
if(how_much > 0) add_string_to_buf("An item paralyzes you!");
|
||||
else if(univ.party[i].status[eStatus::PARALYZED] > 0)
|
||||
else if(pc.status[eStatus::PARALYZED] > 0)
|
||||
add_string_to_buf("An item restores your movement!");
|
||||
break;
|
||||
case eStatus::ACID:
|
||||
if(how_much > 0) add_string_to_buf("An item covers you in acid!");
|
||||
else if(univ.party[i].status[eStatus::ACID] > 0)
|
||||
else if(pc.status[eStatus::ACID] > 0)
|
||||
add_string_to_buf("An item neutralizes the acid!");
|
||||
break;
|
||||
case eStatus::FORCECAGE:
|
||||
if(how_much > 0) add_string_to_buf("An item entraps you!");
|
||||
else if(-how_much > univ.party[i].status[eStatus::FORCECAGE])
|
||||
else if(-how_much > pc.status[eStatus::FORCECAGE])
|
||||
add_string_to_buf("An item frees you!");
|
||||
else add_string_to_buf("An item weakens the barrier!");
|
||||
break;
|
||||
case eStatus::POISONED_WEAPON:
|
||||
if(how_much > 0) {
|
||||
if(univ.party[i].status[eStatus::POISONED_WEAPON] <= 0) {
|
||||
if(pc.status[eStatus::POISONED_WEAPON] <= 0) {
|
||||
// Need to figure out which weapon to apply to.
|
||||
int weap = 24;
|
||||
for(int k = 0; k < 24; k++) {
|
||||
if(is_poisonable_weap(i, k)) {
|
||||
weap = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(weap < 24)
|
||||
univ.party[i].weap_poisoned = weap;
|
||||
auto weap = std::find_if(pc.items.begin(), pc.items.end(), is_poisonable_weap);
|
||||
if(weap != pc.items.end())
|
||||
pc.weap_poisoned = weap - pc.items.begin();
|
||||
else continue;
|
||||
add_string_to_buf("An item poisons your weapon!");
|
||||
} else add_string_to_buf("An item augments your weapon poison!");
|
||||
@@ -2201,7 +2190,7 @@ void combat_run_monst() {
|
||||
}
|
||||
// Note: Since this is an item you're wearing, it bypasses any resistance you might have to the status effect.
|
||||
// Thus we just call apply_status instead of all the various status-specific calls.
|
||||
univ.party[i].apply_status(status, how_much);
|
||||
pc.apply_status(status, how_much);
|
||||
update_stat = true;
|
||||
}
|
||||
}
|
||||
@@ -2977,7 +2966,7 @@ void monster_attack(short who_att,iLiving* target) {
|
||||
}
|
||||
|
||||
int spec_item;
|
||||
if(pc_target != nullptr && (spec_item = pc_target->has_abil_equip(eItemAbil::HIT_CALL_SPECIAL)) < 24) {
|
||||
if(pc_target != nullptr && (spec_item = pc_target->has_abil_equip(eItemAbil::HIT_CALL_SPECIAL)) < pc_target->items.size()) {
|
||||
short s1,s2,s3;
|
||||
univ.party.force_ptr(21, target->get_loc().x);
|
||||
univ.party.force_ptr(22, target->get_loc().y);
|
||||
@@ -3118,7 +3107,7 @@ void monst_fire_missile(short m_num,short bless,std::pair<eMonstAbil,uAbility> a
|
||||
}
|
||||
if(pc_target != nullptr) {
|
||||
int spec_item = pc_target->has_abil_equip(eItemAbil::HIT_CALL_SPECIAL);
|
||||
if(spec_item < 24) {
|
||||
if(spec_item < pc_target->items.size()) {
|
||||
short s1,s2,s3;
|
||||
// TODO: This force_ptr...run_special code is almost duplicated in several places; maybe make a call_attack_spec subroutine!
|
||||
univ.party.force_ptr(21, target->get_loc().x);
|
||||
@@ -3238,7 +3227,7 @@ void monst_basic_abil(short m_num, std::pair<eMonstAbil,uAbility> abil, iLiving*
|
||||
handle_marked_damage();
|
||||
break;
|
||||
case eMonstAbil::STUN:
|
||||
if(pc_target != nullptr && pc_target->has_abil_equip(eItemAbil::LIFE_SAVING) < 24)
|
||||
if(pc_target != nullptr && pc_target->has_abil_equip(eItemAbil::LIFE_SAVING) < pc_target->items.size())
|
||||
break;
|
||||
case eMonstAbil::STATUS: case eMonstAbil::STATUS2:
|
||||
switch(abil.second.gen.stat) {
|
||||
@@ -3311,8 +3300,8 @@ void monst_basic_abil(short m_num, std::pair<eMonstAbil,uAbility> abil, iLiving*
|
||||
case eMonstAbil::DRAIN_XP:
|
||||
if(pc_target != nullptr) {
|
||||
i = univ.get_target_i(*target);
|
||||
if(pc_target->has_abil_equip(eItemAbil::LIFE_SAVING) < 24) break;
|
||||
drain_pc(i, univ.town.monst[m_num].level * abil.second.gen.strength / 100);
|
||||
if(pc_target->has_abil_equip(eItemAbil::LIFE_SAVING) < pc_target->items.size()) break;
|
||||
drain_pc(*pc_target, univ.town.monst[m_num].level * abil.second.gen.strength / 100);
|
||||
}
|
||||
break;
|
||||
case eMonstAbil::KILL:
|
||||
@@ -4582,45 +4571,42 @@ void do_poison() {
|
||||
|
||||
void handle_disease() {
|
||||
short r1 = 0;
|
||||
bool disease = false;
|
||||
|
||||
for(short i = 0; i < 6; i++)
|
||||
if(univ.party[i].main_status == eMainStatus::ALIVE)
|
||||
if(univ.party[i].status[eStatus::DISEASE] > 0)
|
||||
disease = true;
|
||||
bool disease = std::any_of(univ.party.begin(), univ.party.end(), [](const cPlayer& pc) {
|
||||
return pc.main_status == eMainStatus::ALIVE && pc.status[eStatus::DISEASE] > 0;
|
||||
});
|
||||
|
||||
if(disease) {
|
||||
add_string_to_buf("Disease:");
|
||||
for(short i = 0; i < 6; i++)
|
||||
if(univ.party[i].main_status == eMainStatus::ALIVE)
|
||||
if(univ.party[i].status[eStatus::DISEASE] > 0) {
|
||||
for(cPlayer& pc : univ.party)
|
||||
if(pc.main_status == eMainStatus::ALIVE)
|
||||
if(pc.status[eStatus::DISEASE] > 0) {
|
||||
r1 = get_ran(1,1,10);
|
||||
switch(r1) {
|
||||
case 1: case 2:
|
||||
univ.party[i].poison(2);
|
||||
pc.poison(2);
|
||||
break;
|
||||
case 3: case 4:
|
||||
univ.party[i].slow(2);
|
||||
pc.slow(2);
|
||||
break;
|
||||
case 5:
|
||||
drain_pc(i,5);
|
||||
drain_pc(pc,5);
|
||||
break;
|
||||
case 6: case 7:
|
||||
univ.party[i].curse(3);
|
||||
pc.curse(3);
|
||||
break;
|
||||
case 8:
|
||||
univ.party[i].dumbfound(3);
|
||||
pc.dumbfound(3);
|
||||
adjust_spell_menus();
|
||||
break;
|
||||
case 9: case 10:
|
||||
add_string_to_buf(" " + univ.party[i].name + " unaffected.");
|
||||
add_string_to_buf(" " + pc.name + " unaffected.");
|
||||
break;
|
||||
}
|
||||
r1 = get_ran(1,0,7);
|
||||
if(univ.party[i].traits[eTrait::GOOD_CONST])
|
||||
if(pc.traits[eTrait::GOOD_CONST])
|
||||
r1 -= 2;
|
||||
if(r1 <= 0 || univ.party[i].has_abil_equip(eItemAbil::STATUS_PROTECTION,int(eStatus::DISEASE)) < 24)
|
||||
move_to_zero(univ.party[i].status[eStatus::DISEASE]);
|
||||
if(r1 <= 0 || pc.has_abil_equip(eItemAbil::STATUS_PROTECTION,int(eStatus::DISEASE)) < pc.items.size())
|
||||
move_to_zero(pc.status[eStatus::DISEASE]);
|
||||
}
|
||||
put_pc_screen();
|
||||
}
|
||||
|
@@ -13,7 +13,7 @@ bool pc_combat_move(location destination);
|
||||
void char_parry();
|
||||
void char_stand_ready();
|
||||
void pc_attack(short who_att,iLiving* target);
|
||||
void pc_attack_weapon(short who_att,iLiving& target,short hit_adj,short dam_adj,cItem& weap,short primary,bool do_poison);
|
||||
void pc_attack_weapon(short who_att,iLiving& target,short hit_adj,short dam_adj,const cItem& weap,short primary,bool do_poison);
|
||||
short calc_spec_dam(eItemAbil abil,short abil_str,short abil_dat,iLiving& monst,eDamageType& dmg_type);
|
||||
void place_target(location target);
|
||||
void do_combat_cast(location target);
|
||||
|
@@ -312,7 +312,7 @@ void handle_sale(cShopItem item, int i) {
|
||||
univ.party[current_pc].status[eStatus::PARALYZED] = 0;
|
||||
break;
|
||||
case eShopItemType::REMOVE_CURSE:
|
||||
for(int i = 0; i < 24; i++)
|
||||
for(int i = 0; i < univ.party[current_pc].items.size(); i++)
|
||||
if((univ.party[current_pc].equip[i]) &&
|
||||
(univ.party[current_pc].items[i].cursed))
|
||||
univ.party[current_pc].items[i].cursed = univ.party[current_pc].items[i].unsellable = false;
|
||||
@@ -522,7 +522,7 @@ void set_up_shop_array() {
|
||||
shop_array[i++] = j;
|
||||
break;
|
||||
case eShopItemType::REMOVE_CURSE:
|
||||
for(int i = 0; i < 24; i++) {
|
||||
for(int i = 0; i < univ.party[current_pc].items.size(); i++) {
|
||||
if((univ.party[current_pc].equip[i]) && (univ.party[current_pc].items[i].cursed)) {
|
||||
shop_array[i++] = j;
|
||||
break;
|
||||
|
@@ -498,7 +498,7 @@ void display_alchemy() {
|
||||
static void display_pc_info(cDialog& me, const short pc) {
|
||||
std::ostringstream to_draw;
|
||||
|
||||
short weap1 = 24,weap2 = 24,hit_adj = 0, dam_adj = 0,skill_item;
|
||||
short hit_adj = 0, dam_adj = 0,skill_item;
|
||||
|
||||
to_draw << univ.party[pc].name << " is carrying " << univ.party[pc].cur_weight() << " stones out of " << univ.party[pc].max_weight() << '.';
|
||||
me["weight"].setText(to_draw.str());
|
||||
@@ -531,26 +531,21 @@ static void display_pc_info(cDialog& me, const short pc) {
|
||||
else dynamic_cast<cPict&>(me["pic"]).setPict(pic,PIC_PC);
|
||||
|
||||
// Fight bonuses
|
||||
for(short i = 0; i < 24; i++)
|
||||
if((univ.party[pc].items[i].variety == eItemType::ONE_HANDED || univ.party[pc].items[i].variety == eItemType::TWO_HANDED) &&
|
||||
(univ.party[pc].equip[i])) {
|
||||
if(weap1 == 24)
|
||||
weap1 = i;
|
||||
else weap2 = i;
|
||||
}
|
||||
decltype(univ.party[pc].items)::const_iterator weap1, weap2, no_weap = univ.party[pc].items.end();
|
||||
std::tie(weap1, weap2) = univ.party[pc].get_weapons();
|
||||
|
||||
hit_adj = univ.party[pc].stat_adj(eSkill::DEXTERITY) * 5 - (total_encumbrance(pc)) * 5
|
||||
+ 5 * minmax(-8,8,univ.party[pc].status[eStatus::BLESS_CURSE]);
|
||||
if(!univ.party[pc].traits[eTrait::AMBIDEXTROUS] && weap2 < 24)
|
||||
if(!univ.party[pc].traits[eTrait::AMBIDEXTROUS] && weap2 != no_weap)
|
||||
hit_adj -= 25;
|
||||
|
||||
// TODO: Perhaps dam_adj and hit_adj calculation should be moved into a function somewhere?
|
||||
dam_adj = univ.party[pc].stat_adj(eSkill::STRENGTH) + minmax(-8,8,univ.party[pc].status[eStatus::BLESS_CURSE]);
|
||||
if((skill_item = univ.party[pc].has_abil_equip(eItemAbil::SKILL)) < 24) {
|
||||
if((skill_item = univ.party[pc].has_abil_equip(eItemAbil::SKILL)) < univ.party[pc].items.size()) {
|
||||
hit_adj += 5 * (univ.party[pc].items[skill_item].abil_data[0] / 2 + 1);
|
||||
dam_adj += univ.party[pc].items[skill_item].abil_data[0] / 2;
|
||||
}
|
||||
if((skill_item = univ.party[pc].has_abil_equip(eItemAbil::GIANT_STRENGTH)) < 24) {
|
||||
if((skill_item = univ.party[pc].has_abil_equip(eItemAbil::GIANT_STRENGTH)) < univ.party[pc].items.size()) {
|
||||
dam_adj += univ.party[pc].items[skill_item].abil_data[0];
|
||||
hit_adj += univ.party[pc].items[skill_item].abil_data[0] * 2;
|
||||
}
|
||||
@@ -559,31 +554,31 @@ static void display_pc_info(cDialog& me, const short pc) {
|
||||
me["weap1b"].setText("");
|
||||
me["weap2a"].setText("No weapon.");
|
||||
me["weap2b"].setText("");
|
||||
if(weap1 < 24) {
|
||||
if(!univ.party[pc].items[weap1].ident)
|
||||
if(weap1 != no_weap) {
|
||||
if(!weap1->ident)
|
||||
me["weap1a"].setText("Not identified.");
|
||||
else {
|
||||
// TODO: What's with always putting the percent sign in front?
|
||||
if(hit_adj + 5 * univ.party[pc].items[weap1].bonus < 0)
|
||||
to_draw << "Penalty to hit: %" << hit_adj + 5 * univ.party[pc].items[weap1].bonus;
|
||||
else to_draw << "Bonus to hit: +%" << hit_adj + 5 * univ.party[pc].items[weap1].bonus;
|
||||
if(hit_adj + 5 * weap1->bonus < 0)
|
||||
to_draw << "Penalty to hit: %" << hit_adj + 5 * weap1->bonus;
|
||||
else to_draw << "Bonus to hit: +%" << hit_adj + 5 * weap1->bonus;
|
||||
me["weap1a"].setText(to_draw.str());
|
||||
to_draw.str("");
|
||||
to_draw << "Damage: (1-" << univ.party[pc].items[weap1].item_level << ") + " << dam_adj + univ.party[pc].items[weap1].bonus;
|
||||
to_draw << "Damage: (1-" << weap1->item_level << ") + " << dam_adj + weap1->bonus;
|
||||
me["weap1b"].setText(to_draw.str());
|
||||
to_draw.str("");
|
||||
}
|
||||
}
|
||||
if(weap2 < 24) {
|
||||
if(!univ.party[pc].items[weap2].ident)
|
||||
if(weap2 != no_weap) {
|
||||
if(!weap2->ident)
|
||||
me["weap2a"].setText("Not identified.");
|
||||
else {
|
||||
if(hit_adj + 5 * univ.party[pc].items[weap2].bonus < 0)
|
||||
to_draw << "Penalty to hit: %" << hit_adj + 5 * univ.party[pc].items[weap2].bonus;
|
||||
else to_draw << "Bonus to hit: +%" << hit_adj + 5 * univ.party[pc].items[weap2].bonus;
|
||||
if(hit_adj + 5 * weap2->bonus < 0)
|
||||
to_draw << "Penalty to hit: %" << hit_adj + 5 * weap2->bonus;
|
||||
else to_draw << "Bonus to hit: +%" << hit_adj + 5 * weap2->bonus;
|
||||
me["weap2a"].setText(to_draw.str());
|
||||
to_draw.str("");
|
||||
to_draw << "Damage: (1-" << univ.party[pc].items[weap2].item_level << ") + " << dam_adj + univ.party[pc].items[weap2].bonus;
|
||||
to_draw << "Damage: (1-" << weap2->item_level << ") + " << dam_adj + weap2->bonus;
|
||||
me["weap2b"].setText(to_draw.str());
|
||||
to_draw.str("");
|
||||
}
|
||||
|
@@ -221,7 +221,7 @@ void give_thing(short pc_num, short item_num) {
|
||||
univ.party[pc_num].take_item(item_num);
|
||||
}
|
||||
else {
|
||||
if(univ.party[who_to].has_space() == 24)
|
||||
if(univ.party[who_to].has_space() == univ.party[who_to].items.size())
|
||||
ASB("Can't give: PC has max. # of items.");
|
||||
else ASB("Can't give: PC carrying too much.");
|
||||
if(how_many > 0)
|
||||
@@ -364,7 +364,7 @@ static void put_item_graphics(cDialog& me, size_t& first_item_shown, short& curr
|
||||
|
||||
// First make sure all arrays for who can get stuff are in order.
|
||||
if(current_getting_pc < 6 && (univ.party[current_getting_pc].main_status != eMainStatus::ALIVE
|
||||
|| univ.party[current_getting_pc].has_space() == 24)) {
|
||||
|| univ.party[current_getting_pc].has_space() == univ.party[current_getting_pc].items.size())) {
|
||||
current_getting_pc = 6;
|
||||
|
||||
}
|
||||
@@ -373,7 +373,7 @@ static void put_item_graphics(cDialog& me, size_t& first_item_shown, short& curr
|
||||
std::ostringstream sout;
|
||||
sout << "pc" << i + 1;
|
||||
std::string id = sout.str();
|
||||
if(univ.party[i].main_status == eMainStatus::ALIVE && univ.party[i].has_space() < 24
|
||||
if(univ.party[i].main_status == eMainStatus::ALIVE && univ.party[i].has_space() < univ.party[i].items.size()
|
||||
&& ((!is_combat()) || (current_pc == i))) {
|
||||
if(current_getting_pc == 6)
|
||||
current_getting_pc = i;
|
||||
@@ -912,7 +912,7 @@ short char_select_pc(short mode,const char *title) {
|
||||
can_pick = false;
|
||||
else switch(mode) {
|
||||
case 3:
|
||||
if(univ.party[i].has_space() == 24)
|
||||
if(univ.party[i].has_space() == univ.party[i].items.size())
|
||||
can_pick = false;
|
||||
case 0:
|
||||
if(univ.party[i].main_status != eMainStatus::ALIVE)
|
||||
|
@@ -1192,7 +1192,7 @@ short get_encumbrance(short pc_num) {
|
||||
what_val = univ.party[pc_num].free_weight();
|
||||
if(what_val < 0) store += what_val / -10;
|
||||
|
||||
for(short i = 0; i < 24; i++)
|
||||
for(short i = 0; i < univ.party[pc_num].items.size(); i++)
|
||||
if(univ.party[pc_num].equip[i]) {
|
||||
what_val = univ.party[pc_num].items[i].awkward;
|
||||
if(univ.party[pc_num].items[i].ability == eItemAbil::ENCUMBERING)
|
||||
|
@@ -348,10 +348,10 @@ void award_xp(short pc_num,short amt,bool force) {
|
||||
}
|
||||
}
|
||||
|
||||
void drain_pc(short which_pc,short how_much) {
|
||||
if(univ.party[which_pc].main_status == eMainStatus::ALIVE) {
|
||||
univ.party[which_pc].experience = max(univ.party[which_pc].experience - how_much,0);
|
||||
add_string_to_buf(" " + univ.party[which_pc].name + " drained.");
|
||||
void drain_pc(cPlayer& which_pc,short how_much) {
|
||||
if(which_pc.main_status == eMainStatus::ALIVE) {
|
||||
which_pc.experience = max(which_pc.experience - how_much,0);
|
||||
add_string_to_buf(" " + which_pc.name + " drained.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -401,22 +401,21 @@ short check_party_stat(eSkill which_stat, short mode) {
|
||||
}
|
||||
|
||||
bool poison_weapon(short pc_num, short how_much,bool safe) {
|
||||
short weap = 24,p_level,r1;
|
||||
short p_level,r1;
|
||||
short p_chance[21] = {
|
||||
40,72,81,85,88,89,90,
|
||||
91,92,93,94,94,95,95,96,97,98,100,100,100,100};
|
||||
// TODO: This doesn't allow you to choose between poisoning a melee weapon and poisoning arrows, except by temporarily dequipping one
|
||||
|
||||
for(short i = 0; i < 24; i++)
|
||||
if((univ.party[pc_num].equip[i]) && (is_poisonable_weap(pc_num,i))) {
|
||||
weap = i;
|
||||
i = 30;
|
||||
auto weap = univ.party[pc_num].items.begin();
|
||||
do {
|
||||
weap = std::find_if(weap, univ.party[pc_num].items.end(), is_poisonable_weap);
|
||||
|
||||
if(!univ.party[pc_num].equip[weap - univ.party[pc_num].items.begin()]) {
|
||||
weap++;
|
||||
continue;
|
||||
}
|
||||
if(weap == 24) {
|
||||
add_string_to_buf(" No weapon equipped.");
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
|
||||
p_level = how_much;
|
||||
add_string_to_buf(" You poison your weapon.");
|
||||
r1 = get_ran(1,1,100);
|
||||
@@ -434,18 +433,19 @@ bool poison_weapon(short pc_num, short how_much,bool safe) {
|
||||
}
|
||||
if(!safe)
|
||||
play_sound(55);
|
||||
univ.party[pc_num].weap_poisoned = weap;
|
||||
univ.party[pc_num].weap_poisoned = weap - univ.party[pc_num].items.end();
|
||||
univ.party[pc_num].status[eStatus::POISONED_WEAPON] = max(univ.party[pc_num].status[eStatus::POISONED_WEAPON], p_level);
|
||||
|
||||
return true;
|
||||
}
|
||||
} while(weap != univ.party[pc_num].items.end());
|
||||
|
||||
add_string_to_buf(" No weapon equipped.");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_poisonable_weap(short pc_num,short item) {
|
||||
if((univ.party[pc_num].items[item].variety == eItemType::ONE_HANDED) ||
|
||||
(univ.party[pc_num].items[item].variety == eItemType::TWO_HANDED) ||
|
||||
(univ.party[pc_num].items[item].variety == eItemType::ARROW) ||
|
||||
(univ.party[pc_num].items[item].variety == eItemType::BOLTS))
|
||||
bool is_poisonable_weap(cItem& weap) {
|
||||
if(weap.variety == eItemType::ONE_HANDED || weap.variety == eItemType::TWO_HANDED ||
|
||||
weap.variety == eItemType::ARROW || weap.variety == eItemType::BOLTS)
|
||||
return true;
|
||||
else return false;
|
||||
|
||||
@@ -587,9 +587,9 @@ void do_mage_spell(short pc_num,eSpell spell_num,bool freebie) {
|
||||
if(!freebie)
|
||||
univ.party[pc_num].cur_sp -= (*spell_num).cost;
|
||||
ASB("All of your items are identified.");
|
||||
for(short i = 0; i < 6; i++)
|
||||
for(short j = 0; j < 24; j++)
|
||||
univ.party[i].items[j].ident = true;
|
||||
for(cPlayer& pc : univ.party)
|
||||
for(cItem& item : pc.items)
|
||||
item.ident = true;
|
||||
break;
|
||||
|
||||
case eSpell::TRUE_SIGHT:
|
||||
@@ -683,7 +683,7 @@ void do_mage_spell(short pc_num,eSpell spell_num,bool freebie) {
|
||||
|
||||
case eSpell::MAGIC_MAP:
|
||||
item = univ.party[pc_num].has_abil(eItemAbil::SAPPHIRE);
|
||||
if(item == 24 && !freebie)
|
||||
if(item == univ.party[pc_num].items.size() && !freebie)
|
||||
add_string_to_buf(" You need a sapphire.");
|
||||
else if(univ.town->defy_scrying || univ.town->defy_mapping)
|
||||
add_string_to_buf(" The spell fails.");
|
||||
@@ -1051,11 +1051,11 @@ void do_priest_spell(short pc_num,eSpell spell_num,bool freebie) {
|
||||
}
|
||||
else sout << " wasn't stoned.";
|
||||
} else if(spell_num == eSpell::CURSE_REMOVE) {
|
||||
for(int i = 0; i < 24; i++)
|
||||
if(univ.party[target].items[i].cursed){
|
||||
for(cItem& item : univ.party[target].items)
|
||||
if(item.cursed){
|
||||
r1 = get_ran(1,0,200) - 10 * adj;
|
||||
if(r1 < 60) {
|
||||
univ.party[target].items[i].cursed = univ.party[target].items[i].unsellable = false;
|
||||
item.cursed = item.unsellable = false;
|
||||
}
|
||||
}
|
||||
play_sound(52);
|
||||
@@ -1063,7 +1063,7 @@ void do_priest_spell(short pc_num,eSpell spell_num,bool freebie) {
|
||||
} else {
|
||||
|
||||
if(!univ.scenario.is_legacy) {
|
||||
if((item = univ.party[pc_num].has_abil(eItemAbil::RESURRECTION_BALM)) == 24) {
|
||||
if((item = univ.party[pc_num].has_abil(eItemAbil::RESURRECTION_BALM)) == univ.party[pc_num].items.size()) {
|
||||
add_string_to_buf(" Need resurrection balm.");
|
||||
break;
|
||||
}
|
||||
@@ -2054,18 +2054,18 @@ void do_alchemy() {
|
||||
// TODO: Remove need for this cast by changing the above data to either std::maps or an unary operator*
|
||||
int which_p = int(potion);
|
||||
if(potion != eAlchemy::NONE) {
|
||||
if(univ.party[pc_num].has_space() == 24) {
|
||||
if(univ.party[pc_num].has_space() == univ.party[pc_num].items.size()) {
|
||||
add_string_to_buf("Alchemy: Can't carry another item.");
|
||||
return;
|
||||
}
|
||||
|
||||
if((which_item = univ.party[pc_num].has_abil(alch_ingred1[which_p])) == 24) {
|
||||
if((which_item = univ.party[pc_num].has_abil(alch_ingred1[which_p])) == univ.party[pc_num].items.size()) {
|
||||
add_string_to_buf("Alchemy: Don't have ingredients.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(alch_ingred2[which_p] != eItemAbil::NONE) {
|
||||
if(univ.party[pc_num].has_abil(alch_ingred2[which_p]) == 24) {
|
||||
if(univ.party[pc_num].has_abil(alch_ingred2[which_p]) == univ.party[pc_num].items.size()) {
|
||||
add_string_to_buf("Alchemy: Don't have ingredients.");
|
||||
return;
|
||||
}
|
||||
@@ -2268,7 +2268,7 @@ bool damage_pc(cPlayer& which_pc,short how_much,eDamageType damage_type,eRace ty
|
||||
// armor
|
||||
if(damage_type == eDamageType::WEAPON || damage_type == eDamageType::UNDEAD || damage_type == eDamageType::DEMON) {
|
||||
how_much -= minmax(-5,5,which_pc.status[eStatus::BLESS_CURSE]);
|
||||
for(short i = 0; i < 24; i++) {
|
||||
for(short i = 0; i < which_pc.items.size(); i++) {
|
||||
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);
|
||||
@@ -2427,7 +2427,7 @@ void petrify_pc(cPlayer& which_pc,int strength) {
|
||||
r1 += which_pc.status[eStatus::BLESS_CURSE];
|
||||
r1 -= strength;
|
||||
|
||||
if(which_pc.has_abil_equip(eItemAbil::PROTECT_FROM_PETRIFY) < 24)
|
||||
if(which_pc.has_abil_equip(eItemAbil::PROTECT_FROM_PETRIFY) < which_pc.items.size())
|
||||
r1 = 20;
|
||||
|
||||
if(r1 > 14) {
|
||||
@@ -2440,7 +2440,7 @@ void petrify_pc(cPlayer& which_pc,int strength) {
|
||||
}
|
||||
|
||||
void kill_pc(cPlayer& which_pc,eMainStatus type) {
|
||||
short i_weap = 24;
|
||||
short i_weap = which_pc.items.size();
|
||||
bool dummy,no_save = false;
|
||||
location item_loc;
|
||||
|
||||
@@ -2457,12 +2457,11 @@ void kill_pc(cPlayer& which_pc,eMainStatus type) {
|
||||
get_ran(1,1,100) < hit_chance[luck]) {
|
||||
add_string_to_buf(" But you luck out!");
|
||||
which_pc.cur_health = 0;
|
||||
}
|
||||
else if(i_weap == 24 || type == eMainStatus::ABSENT) {
|
||||
} else if(i_weap == which_pc.items.size() || type == eMainStatus::ABSENT) {
|
||||
if(combat_active_pc < 6 && &which_pc == &univ.party[combat_active_pc])
|
||||
combat_active_pc = 6;
|
||||
|
||||
for(short i = 0; i < 24; i++)
|
||||
for(short i = 0; i < which_pc.items.size(); i++)
|
||||
which_pc.equip[i] = false;
|
||||
|
||||
item_loc = (overall_mode >= MODE_COMBAT) ? which_pc.combat_pos : univ.party.town_loc;
|
||||
@@ -2493,10 +2492,10 @@ void kill_pc(cPlayer& which_pc,eMainStatus type) {
|
||||
}
|
||||
|
||||
if(overall_mode != MODE_OUTDOORS)
|
||||
for(short i = 0; i < 24; i++)
|
||||
if(which_pc.items[i].variety != eItemType::NO_ITEM) {
|
||||
dummy = place_item(which_pc.items[i],item_loc);
|
||||
which_pc.items[i].variety = eItemType::NO_ITEM;
|
||||
for(cItem& item : which_pc.items)
|
||||
if(item.variety != eItemType::NO_ITEM) {
|
||||
dummy = place_item(item,item_loc);
|
||||
item.variety = eItemType::NO_ITEM;
|
||||
}
|
||||
if(type == eMainStatus::DEAD || type == eMainStatus::DUST)
|
||||
play_sound(21);
|
||||
|
@@ -11,10 +11,10 @@ bool take_sp(short pc_num,short amt);
|
||||
void increase_light(short amt);
|
||||
void award_party_xp(short amt);
|
||||
void award_xp(short pc_num,short amt,bool force = false);
|
||||
void drain_pc(short which_pc,short how_much);
|
||||
void drain_pc(cPlayer& who,short how_much); // TODO: Move to a member function
|
||||
short check_party_stat(eSkill which_stat, short mode);
|
||||
bool poison_weapon( short pc_num, short how_much,bool safe);
|
||||
bool is_poisonable_weap(short pc_num,short item);
|
||||
bool is_poisonable_weap(class cItem& weap);
|
||||
void cast_spell(eSkill type);
|
||||
bool repeat_cast_ok(eSkill type);
|
||||
void give_party_spell(short which);
|
||||
|
@@ -890,7 +890,7 @@ void use_item(short pc,short item) {
|
||||
break;
|
||||
case eItemUse::HARM_ONE:
|
||||
ASB(" You feel terrible.");
|
||||
drain_pc(pc,str * 5);
|
||||
drain_pc(univ.party[pc],str * 5);
|
||||
damage_pc(univ.party[pc],20 * str,eDamageType::UNBLOCKABLE,eRace::HUMAN,0);
|
||||
univ.party[pc].disease(2 * str);
|
||||
univ.party[pc].dumbfound(2 * str);
|
||||
@@ -903,7 +903,7 @@ void use_item(short pc,short item) {
|
||||
case eItemUse::HARM_ALL:
|
||||
ASB(" You all feel terrible.");
|
||||
for(short i = 0; i < 6; i++) {
|
||||
drain_pc(i,str * 5);
|
||||
drain_pc(univ.party[i],str * 5);
|
||||
damage_pc(univ.party[i],20 * str,eDamageType::UNBLOCKABLE,eRace::HUMAN,0);
|
||||
univ.party[i].disease(2 * str);
|
||||
univ.party[i].dumbfound(2 * str);
|
||||
@@ -921,7 +921,7 @@ void use_item(short pc,short item) {
|
||||
break;
|
||||
case eItemUse::HARM_ONE:
|
||||
ASB(" You feel forgetful.");
|
||||
drain_pc(pc,str * 5);
|
||||
drain_pc(univ.party[pc],str * 5);
|
||||
break;
|
||||
case eItemUse::HELP_ALL:
|
||||
ASB(" You all feel much smarter.");
|
||||
@@ -930,7 +930,7 @@ void use_item(short pc,short item) {
|
||||
case eItemUse::HARM_ALL:
|
||||
ASB(" You all feel forgetful.");
|
||||
for(short i = 0; i < 6; i++)
|
||||
drain_pc(i,str * 5);
|
||||
drain_pc(univ.party[i],str * 5);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -2754,7 +2754,7 @@ void affect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
can_pick = false;
|
||||
else if(spec.ex1a == 3 && univ.party[pc].main_status == eMainStatus::ALIVE)
|
||||
can_pick = false;
|
||||
else if(spec.ex1a == 4 && univ.party[pc].has_space() == 24)
|
||||
else if(spec.ex1a == 4 && univ.party[pc].has_space() == univ.party[pc].items.size())
|
||||
can_pick = false;
|
||||
} else if(pc >= 100 && pc < univ.town.monst.size() + 100) {
|
||||
short monst = pc - 100;
|
||||
@@ -2791,7 +2791,7 @@ void affect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
can_pick = false;
|
||||
else if(spec.ex1a == 3 && found->main_status == eMainStatus::ALIVE)
|
||||
can_pick = false;
|
||||
else if(spec.ex1a == 4 && found->has_space() == 24)
|
||||
else if(spec.ex1a == 4 && found->has_space() == found->items.size())
|
||||
can_pick = false;
|
||||
}
|
||||
if(can_pick)
|
||||
@@ -2817,7 +2817,7 @@ void affect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
can_pick = false;
|
||||
else if(spec.ex1a == 3 && univ.party[i].main_status == eMainStatus::ALIVE)
|
||||
can_pick = false;
|
||||
else if(spec.ex1a == 4 && univ.party[i].has_space() == 24)
|
||||
else if(spec.ex1a == 4 && univ.party[i].has_space() == univ.party[i].items.size())
|
||||
can_pick = false;
|
||||
tries++;
|
||||
}
|
||||
@@ -2866,7 +2866,7 @@ void affect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
if(spec.ex1a < 0)
|
||||
univ.party[i].experience = univ.party[i].level * univ.party[i].get_tnl();
|
||||
else if(spec.ex1b == 0) award_xp(i,spec.ex1a,true);
|
||||
else drain_pc(i,spec.ex1a);
|
||||
else drain_pc(univ.party[i],spec.ex1a);
|
||||
}
|
||||
break;
|
||||
case eSpecType::AFFECT_SKILL_PTS:
|
||||
@@ -3406,16 +3406,16 @@ void ifthen_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
|
||||
*next_spec = spec.ex1b;
|
||||
break;
|
||||
case eSpecType::IF_EQUIP_ITEM_CLASS:
|
||||
for(short i = 0; i < 6; i++)
|
||||
if(univ.party[i].main_status == eMainStatus::ALIVE)
|
||||
for(short j = 0; j < 24; j++)
|
||||
if(univ.party[i].items[j].variety != eItemType::NO_ITEM && univ.party[i].items[j].special_class == (unsigned)spec.ex1a
|
||||
&& univ.party[i].equip[j]) {
|
||||
for(cPlayer& pc : univ.party)
|
||||
if(pc.main_status == eMainStatus::ALIVE)
|
||||
for(short j = 0; j < pc.items.size(); j++)
|
||||
if(pc.items[j].variety != eItemType::NO_ITEM && pc.items[j].special_class == (unsigned)spec.ex1a
|
||||
&& pc.equip[j]) {
|
||||
*next_spec = spec.ex1b;
|
||||
if(spec.ex2a > 0) {
|
||||
*redraw = 1;
|
||||
univ.party[i].take_item(j);
|
||||
if(i == stat_window)
|
||||
pc.take_item(j);
|
||||
if(&pc == &univ.party[stat_window])
|
||||
put_item_screen(stat_window);
|
||||
}
|
||||
}
|
||||
|
@@ -628,7 +628,7 @@ void refresh_stat_areas(short mode) {
|
||||
short total_encumbrance(short pc_num) {
|
||||
short store = 0,what_val;
|
||||
|
||||
for(short i = 0; i < 24; i++)
|
||||
for(short i = 0; i < univ.party[pc_num].items.size(); i++)
|
||||
if(univ.party[pc_num].equip[i]) {
|
||||
what_val = univ.party[pc_num].items[i].awkward;
|
||||
store += what_val;
|
||||
|
@@ -476,13 +476,13 @@ void start_town_mode(short which_town, short entry_dir) {
|
||||
update_explored(univ.party.town_loc);
|
||||
|
||||
// If a PC dead, drop his items
|
||||
for(short m = 0; m < 6; m++) {
|
||||
if(univ.party[m].main_status == eMainStatus::ALIVE || isSplit(univ.party[m].main_status))
|
||||
for(cPlayer& pc : univ.party) {
|
||||
if(pc.main_status == eMainStatus::ALIVE || isSplit(pc.main_status))
|
||||
continue;
|
||||
for(short n = 0; n < 24; n++)
|
||||
if(univ.party[m].items[n].variety != eItemType::NO_ITEM) {
|
||||
place_item(univ.party[m].items[n],univ.party.town_loc);
|
||||
univ.party[m].items[n].variety = eItemType::NO_ITEM;
|
||||
for(cItem& item : pc.items)
|
||||
if(item.variety != eItemType::NO_ITEM) {
|
||||
place_item(item,univ.party.town_loc);
|
||||
item.variety = eItemType::NO_ITEM;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -659,9 +659,9 @@ void handle_leave_town_specials(short /*town_number*/, short which_spec,location
|
||||
}
|
||||
|
||||
bool abil_exists(eItemAbil abil) { // use when outdoors
|
||||
for(short i = 0; i < 6; i++)
|
||||
for(short j = 0; j < 24; j++)
|
||||
if(univ.party[i].items[j].variety != eItemType::NO_ITEM && univ.party[i].items[j].ability == abil)
|
||||
for(const cPlayer& pc : univ.party)
|
||||
for(const cItem& item : pc.items)
|
||||
if(item.variety != eItemType::NO_ITEM && item.ability == abil)
|
||||
return true;
|
||||
for(short i = 0; i < 3; i++)
|
||||
for(short j = 0; j < univ.town.items.size(); j++)
|
||||
@@ -1149,7 +1149,7 @@ void pick_lock(location where,short pc_num) {
|
||||
|
||||
terrain = univ.town->terrain(where.x,where.y);
|
||||
which_item = univ.party[pc_num].has_abil_equip(eItemAbil::LOCKPICKS);
|
||||
if(which_item == 24) {
|
||||
if(which_item == univ.party[pc_num].items.size()) {
|
||||
add_string_to_buf(" Need lockpick equipped.");
|
||||
return;
|
||||
}
|
||||
@@ -1166,7 +1166,7 @@ void pick_lock(location where,short pc_num) {
|
||||
if(univ.party[pc_num].traits[eTrait::NIMBLE])
|
||||
r1 -= 8;
|
||||
|
||||
if(univ.party[pc_num].has_abil_equip(eItemAbil::THIEVING) < 24)
|
||||
if(univ.party[pc_num].has_abil_equip(eItemAbil::THIEVING) < univ.party[pc_num].items.size())
|
||||
r1 = r1 - 12;
|
||||
|
||||
if(univ.scenario.ter_types[terrain].special != eTerSpec::UNLOCKABLE) {
|
||||
|
@@ -458,22 +458,23 @@ bool cParty::forced_give(cItem item,eItemAbil abil,short dat) {
|
||||
item.abil_data[0] = dat / 1000;
|
||||
item.abil_data[1] = dat % 1000;
|
||||
}
|
||||
for(int i = 0; i < 6; i++)
|
||||
for(int j = 0; j < 24; j++)
|
||||
if(adven[i]->main_status == eMainStatus::ALIVE && adven[i]->items[j].variety == eItemType::NO_ITEM) {
|
||||
adven[i]->items[j] = item;
|
||||
// TODO: It's strange to check main_status in the inner loop here rather than the outer loop
|
||||
for(cPlayer& pc : *this)
|
||||
for(cItem& slot : pc.items)
|
||||
if(pc.main_status == eMainStatus::ALIVE && slot.variety == eItemType::NO_ITEM) {
|
||||
slot = item;
|
||||
|
||||
if(print_result) {
|
||||
std::ostringstream announce;
|
||||
announce << " " << adven[i]->name << " gets ";
|
||||
announce << " " << pc.name << " gets ";
|
||||
if(!item.ident)
|
||||
announce << item.name;
|
||||
else announce << item.full_name;
|
||||
announce << '.';
|
||||
print_result(announce.str());
|
||||
}
|
||||
adven[i]->combine_things();
|
||||
adven[i]->sort_items();
|
||||
pc.combine_things();
|
||||
pc.sort_items();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -482,7 +483,7 @@ bool cParty::forced_give(cItem item,eItemAbil abil,short dat) {
|
||||
bool cParty::has_abil(eItemAbil abil, short dat) {
|
||||
for(int i = 0; i < 6; i++)
|
||||
if(adven[i]->main_status == eMainStatus::ALIVE)
|
||||
if(adven[i]->has_abil(abil,dat) < 24)
|
||||
if(adven[i]->has_abil(abil,dat) < adven[i]->items.size())
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
@@ -491,7 +492,7 @@ bool cParty::take_abil(eItemAbil abil, short dat) {
|
||||
short item;
|
||||
for(int i = 0; i < 6; i++)
|
||||
if(adven[i]->main_status == eMainStatus::ALIVE)
|
||||
if((item = adven[i]->has_abil(abil,dat)) < 24) {
|
||||
if((item = adven[i]->has_abil(abil,dat)) < adven[i]->items.size()) {
|
||||
if(adven[i]->items[item].charges > 1)
|
||||
adven[i]->items[item].charges--;
|
||||
else adven[i]->take_item(item);
|
||||
|
@@ -159,7 +159,7 @@ void cPlayer::curse(int how_much) {
|
||||
void cPlayer::dumbfound(int how_much) {
|
||||
if(!is_alive()) return;
|
||||
short r1 = get_ran(1,0,90);
|
||||
if(has_abil_equip(eItemAbil::WILL) < 24) {
|
||||
if(has_abil_equip(eItemAbil::WILL) < items.size()) {
|
||||
if(print_result)
|
||||
print_result(" Ring of Will glows.");
|
||||
r1 -= 10;
|
||||
@@ -285,7 +285,7 @@ void cPlayer::web(int how_much) {
|
||||
|
||||
void cPlayer::acid(int how_much) {
|
||||
if(!is_alive()) return;
|
||||
if(has_abil_equip(eItemAbil::STATUS_PROTECTION,int(eStatus::ACID)) < 24) {
|
||||
if(has_abil_equip(eItemAbil::STATUS_PROTECTION,int(eStatus::ACID)) < items.size()) {
|
||||
if(print_result)
|
||||
print_result(" " + name + " resists acid.");
|
||||
return;
|
||||
@@ -340,7 +340,7 @@ short cPlayer::stat_adj(eSkill which) const {
|
||||
tr -= 2;
|
||||
}
|
||||
// TODO: Use ability strength?
|
||||
if(has_abil_equip(eItemAbil::BOOST_STAT,int(which)) < 24)
|
||||
if(has_abil_equip(eItemAbil::BOOST_STAT,int(which)) < items.size())
|
||||
tr++;
|
||||
return tr;
|
||||
}
|
||||
@@ -479,7 +479,7 @@ bool cPlayer::give_item(cItem item, int flags) {
|
||||
return false;
|
||||
}
|
||||
free_space = has_space();
|
||||
if(free_space == 24 || main_status != eMainStatus::ALIVE)
|
||||
if(free_space == items.size() || main_status != eMainStatus::ALIVE)
|
||||
return false;
|
||||
else {
|
||||
item.property = false;
|
||||
@@ -503,8 +503,8 @@ bool cPlayer::give_item(cItem item, int flags) {
|
||||
if(num_hands_to_use.count(item.variety))
|
||||
exclude = 100;
|
||||
else exclude = excluding_types[item.variety];
|
||||
int rem1 = 24, rem2 = 24;
|
||||
for(int i = 0; i < 24; i++) {
|
||||
int rem1 = items.size(), rem2 = items.size();
|
||||
for(int i = 0; i < items.size(); i++) {
|
||||
if(i == free_space) continue;
|
||||
if(!equip[i]) continue;
|
||||
int check_exclude = 0;
|
||||
@@ -515,20 +515,20 @@ bool cPlayer::give_item(cItem item, int flags) {
|
||||
if(exclude == 0 && item.variety != items[i].variety)
|
||||
continue;
|
||||
if(exclude == 100) {
|
||||
if(rem1 == 24) {
|
||||
if(item.variety == eItemType::ONE_HANDED || item.variety == eItemType::TWO_HANDED || rem2 < 24)
|
||||
if(rem1 == items.size()) {
|
||||
if(item.variety == eItemType::ONE_HANDED || item.variety == eItemType::TWO_HANDED || rem2 < items.size())
|
||||
rem1 = i;
|
||||
if(rem1 < 24) continue;
|
||||
if(rem1 < items.size()) continue;
|
||||
}
|
||||
if(rem2 == 24) {
|
||||
if(item.variety == eItemType::SHIELD || item.variety == eItemType::SHIELD_2 || rem1 < 24)
|
||||
if(rem2 == items.size()) {
|
||||
if(item.variety == eItemType::SHIELD || item.variety == eItemType::SHIELD_2 || rem1 < items.size())
|
||||
rem2 = i;
|
||||
}
|
||||
} else if(rem1 < 24)
|
||||
} else if(rem1 < items.size())
|
||||
rem1 = i;
|
||||
}
|
||||
bool can_rem1 = rem1 < 24 && (!items[rem1].cursed || equip_type == GIVE_EQUIP_FORCE);
|
||||
bool can_rem2 = rem2 < 24 && (!items[rem2].cursed || equip_type == GIVE_EQUIP_FORCE);
|
||||
bool can_rem1 = rem1 < items.size() && (!items[rem1].cursed || equip_type == GIVE_EQUIP_FORCE);
|
||||
bool can_rem2 = rem2 < items.size() && (!items[rem2].cursed || equip_type == GIVE_EQUIP_FORCE);
|
||||
if(exclude == 100) {
|
||||
if(item.variety == eItemType::TWO_HANDED) {
|
||||
if(can_rem1) equip[rem1] = false;
|
||||
@@ -564,7 +564,7 @@ bool cPlayer::equip_item(int which_item, bool do_print) {
|
||||
return false;
|
||||
}
|
||||
unsigned short num_this_type = 0, hands_occupied = 0;
|
||||
for(int i = 0; i < 24; i++)
|
||||
for(int i = 0; i < items.size(); i++)
|
||||
if(equip[i]) {
|
||||
if(items[i].variety == items[which_item].variety)
|
||||
num_this_type++;
|
||||
@@ -575,7 +575,7 @@ bool cPlayer::equip_item(int which_item, bool do_print) {
|
||||
short equip_item_type = excluding_types[items[which_item].variety];
|
||||
// Now if missile is already equipped, no more missiles
|
||||
if(equip_item_type > 0) {
|
||||
for(int i = 0; i < 24; i++)
|
||||
for(int i = 0; i < items.size(); i++)
|
||||
if(equip[i] && excluding_types[items[i].variety] == equip_item_type) {
|
||||
if(do_print && print_result) {
|
||||
print_result("Equip: You have something of this type");
|
||||
@@ -623,6 +623,32 @@ bool cPlayer::unequip_item(int which_item, bool do_print) {
|
||||
return true;
|
||||
}
|
||||
|
||||
auto cPlayer::get_weapons() -> std::pair<decltype(items)::const_iterator, decltype(items)::const_iterator> {
|
||||
using iter_t = decltype(items)::const_iterator;
|
||||
iter_t beg = items.begin(), end = items.end();
|
||||
std::pair<iter_t, iter_t> result = {beg, beg};
|
||||
auto is_weapon = [](const cItem& item) {
|
||||
return item.variety == eItemType::ONE_HANDED || item.variety == eItemType::TWO_HANDED;
|
||||
};
|
||||
auto is_equipped = [this](iter_t item) {
|
||||
if(item == items.end()) return true; // Treat a non-existent item as equipped to avoid incrementing an end iterator
|
||||
return equip[item - items.begin()];
|
||||
};
|
||||
|
||||
do {
|
||||
result.first = std::find_if(result.first, end, is_weapon);
|
||||
if(!is_equipped(result.first)) result.first++;
|
||||
} while(result.first != end);
|
||||
if(result.first != end && result.first + 1 != end) {
|
||||
result.second = result.first + 1;
|
||||
do {
|
||||
result.second = std::find_if(result.second, end, is_weapon);
|
||||
if(!is_equipped(result.second)) result.second++;
|
||||
} while(result.second != end);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
short cPlayer::max_weight() const {
|
||||
return 100 + (15 * min(skill(eSkill::STRENGTH),20)) + (traits[eTrait::STRENGTH] * 30)
|
||||
+ (traits[eTrait::BAD_BACK] * -50) + (race == eRace::VAHNATAI) * -25;
|
||||
@@ -632,7 +658,7 @@ short cPlayer::cur_weight() const {
|
||||
short weight = 0;
|
||||
bool airy = false,heavy = false;
|
||||
|
||||
for(int i = 0; i < 24; i++)
|
||||
for(int i = 0; i < items.size(); i++)
|
||||
if(items[i].variety != eItemType::NO_ITEM) {
|
||||
weight += items[i].item_weight();
|
||||
if(items[i].ability == eItemAbil::LIGHTER_OBJECT)
|
||||
@@ -654,17 +680,17 @@ short cPlayer::free_weight() const {
|
||||
}
|
||||
|
||||
short cPlayer::has_space() const {
|
||||
for(int i = 0; i < 24; i++) {
|
||||
for(int i = 0; i < items.size(); i++) {
|
||||
if(items[i].variety == eItemType::NO_ITEM)
|
||||
return i;
|
||||
}
|
||||
return 24;
|
||||
return items.size();
|
||||
}
|
||||
|
||||
void cPlayer::combine_things() {
|
||||
for(int i = 0; i < 24; i++) {
|
||||
for(int i = 0; i < items.size(); i++) {
|
||||
if(items[i].variety != eItemType::NO_ITEM && items[i].type_flag > 0 && items[i].ident) {
|
||||
for(int j = i + 1; j < 24; j++)
|
||||
for(int j = i + 1; j < items.size(); j++)
|
||||
if(items[j].variety != eItemType::NO_ITEM && items[j].type_flag == items[i].type_flag && items[j].ident) {
|
||||
if(print_result) print_result("(items combined)");
|
||||
short test = items[i].charges + items[j].charges;
|
||||
@@ -687,7 +713,7 @@ void cPlayer::combine_things() {
|
||||
|
||||
short cPlayer::get_prot_level(eItemAbil abil, short dat) const {
|
||||
int sum = 0;
|
||||
for(int i = 0; i < 24; i++) {
|
||||
for(int i = 0; i < items.size(); i++) {
|
||||
if(items[i].variety == eItemType::NO_ITEM) continue;
|
||||
if(items[i].ability != abil) continue;
|
||||
if(!equip[i]) continue;
|
||||
@@ -699,24 +725,24 @@ short cPlayer::get_prot_level(eItemAbil abil, short dat) const {
|
||||
}
|
||||
|
||||
short cPlayer::has_abil_equip(eItemAbil abil,short dat) const {
|
||||
for(short i = 0; i < 24; i++) {
|
||||
for(short i = 0; i < items.size(); i++) {
|
||||
if(items[i].variety == eItemType::NO_ITEM) continue;
|
||||
if(items[i].ability != abil) continue;
|
||||
if(!equip[i]) continue;
|
||||
if(dat >= 0 && dat != items[i].abil_data[1]) continue;
|
||||
return i;
|
||||
}
|
||||
return 24;
|
||||
return items.size();
|
||||
}
|
||||
|
||||
short cPlayer::has_abil(eItemAbil abil,short dat) const {
|
||||
for(short i = 0; i < 24; i++) {
|
||||
for(short i = 0; i < items.size(); i++) {
|
||||
if(items[i].variety == eItemType::NO_ITEM) continue;
|
||||
if(items[i].ability != abil) continue;
|
||||
if(dat >= 0 && dat != items[i].abil_data[1]) continue;
|
||||
return i;
|
||||
}
|
||||
return 24;
|
||||
return items.size();
|
||||
}
|
||||
|
||||
short cPlayer::skill(eSkill skill) const {
|
||||
@@ -737,11 +763,11 @@ eBuyStatus cPlayer::ok_to_buy(short cost,cItem item) const {
|
||||
if(party->quest_status[item.item_level] != eQuestStatus::AVAILABLE)
|
||||
return eBuyStatus::HAVE_LOTS;
|
||||
} else if(item.variety != eItemType::GOLD && item.variety != eItemType::FOOD) {
|
||||
for(int i = 0; i < 24; i++)
|
||||
for(int i = 0; i < items.size(); i++)
|
||||
if(items[i].variety != eItemType::NO_ITEM && items[i].type_flag == item.type_flag && items[i].charges > 123)
|
||||
return eBuyStatus::HAVE_LOTS;
|
||||
|
||||
if(has_space() == 24)
|
||||
if(has_space() == items.size())
|
||||
return eBuyStatus::NO_SPACE;
|
||||
if(item.item_weight() > free_weight()) {
|
||||
return eBuyStatus::TOO_HEAVY;
|
||||
@@ -842,17 +868,15 @@ cPlayer::cPlayer(cParty& party) : party(&party) {
|
||||
experience = 0;
|
||||
skill_pts = 65;
|
||||
level = 1;
|
||||
for(short i = 0; i < 24; i++)
|
||||
items[i] = cItem();
|
||||
for(short i = 0; i < 24; i++)
|
||||
equip[i] = false;
|
||||
std::fill(items.begin(), items.end(), cItem());
|
||||
std::fill(equip.begin(), equip.end(), false);
|
||||
|
||||
for(short i = 0; i < 62; i++) {
|
||||
priest_spells[i] = i < 30;
|
||||
mage_spells[i] = i < 30;
|
||||
}
|
||||
which_graphic = 0;
|
||||
weap_poisoned = 24;
|
||||
weap_poisoned = items.size();
|
||||
|
||||
race = eRace::HUMAN;
|
||||
direction = DIR_N;
|
||||
@@ -900,16 +924,14 @@ cPlayer::cPlayer(cParty& party,long key,short slot) : cPlayer(party) {
|
||||
experience = 0;
|
||||
skill_pts = 60;
|
||||
level = 1;
|
||||
for(short i = 0; i < 24; i++)
|
||||
items[i] = cItem();
|
||||
for(short i = 0; i < 24; i++)
|
||||
equip[i] = false;
|
||||
std::fill(items.begin(), items.end(), cItem());
|
||||
std::fill(equip.begin(), equip.end(), false);
|
||||
|
||||
priest_spells.set();
|
||||
mage_spells.set();
|
||||
which_graphic = slot * 3 + 1; // 1, 4, 7, 10, 13, 16
|
||||
if(slot == 2) which_graphic++;
|
||||
weap_poisoned = 24; // was 16, as an E2 relic
|
||||
weap_poisoned = items.size();
|
||||
|
||||
for(short i = 0; i < 10; i++) {
|
||||
eTrait trait = eTrait(i);
|
||||
@@ -992,10 +1014,8 @@ cPlayer::cPlayer(cParty& party,long key,short slot) : cPlayer(party) {
|
||||
skill_pts = 0;
|
||||
level = 1;
|
||||
|
||||
for(short i = 0; i < 24; i++)
|
||||
items[i] = cItem();
|
||||
for(short i = 0; i < 24; i++)
|
||||
equip[i] = false;
|
||||
std::fill(items.begin(), items.end(), cItem());
|
||||
std::fill(equip.begin(), equip.end(), false);
|
||||
cur_sp = pc_sp[slot];
|
||||
max_sp = pc_sp[slot];
|
||||
for(short i = 0; i < 62; i++) {
|
||||
@@ -1049,7 +1069,7 @@ void cPlayer::writeTo(std::ostream& file) const {
|
||||
if(status[stat] != 0)
|
||||
file << "STATUS " << i << ' ' << status.at(stat) << '\n';
|
||||
}
|
||||
for(int i = 0; i < 24; i++)
|
||||
for(int i = 0; i < equip.size(); i++)
|
||||
if(equip[i])
|
||||
file << "EQUIP " << i << '\n';
|
||||
for(int i = 0; i < 62; i++)
|
||||
@@ -1069,7 +1089,7 @@ void cPlayer::writeTo(std::ostream& file) const {
|
||||
file << "DIRECTION " << direction << '\n';
|
||||
file << "POISON " << weap_poisoned << '\n';
|
||||
file << '\f';
|
||||
for(int i = 0; i < 24; i++)
|
||||
for(int i = 0; i < items.size(); i++)
|
||||
if(items[i].variety != eItemType::NO_ITEM){
|
||||
file << "ITEM " << i << '\n';
|
||||
items[i].writeTo(file);
|
||||
|
@@ -98,6 +98,7 @@ public:
|
||||
bool give_item(cItem item, int flags);
|
||||
bool equip_item(int which_item, bool do_print);
|
||||
bool unequip_item(int which_item, bool do_print);
|
||||
auto get_weapons() -> std::pair<decltype(items)::const_iterator, decltype(items)::const_iterator>;
|
||||
void take_item(int which_item);
|
||||
void remove_charge(int which_item);
|
||||
short has_space() const;
|
||||
|
@@ -69,18 +69,18 @@ bool handle_action(sf::Event event) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for(short i = 0; i < 24; i++)
|
||||
for(short i = 0; i < univ.party[current_active_pc].items.size(); i++) {
|
||||
if((the_point.in(item_string_rects[i][1])) && // drop item
|
||||
univ.party[current_active_pc].items[i].variety != eItemType::NO_ITEM) {
|
||||
flash_rect(item_string_rects[i][1]);
|
||||
univ.party[current_active_pc].take_item(i);
|
||||
}
|
||||
for(short i = 0; i < 24; i++)
|
||||
if((the_point.in(item_string_rects[i][2])) && // identify item
|
||||
univ.party[current_active_pc].items[i].variety != eItemType::NO_ITEM) {
|
||||
flash_rect(item_string_rects[i][2]);
|
||||
univ.party[current_active_pc].items[i].ident = true;
|
||||
}
|
||||
}
|
||||
|
||||
return to_return;
|
||||
}
|
||||
|
@@ -329,7 +329,7 @@ void draw_items() {
|
||||
return; // If PC is dead, it has no items
|
||||
}
|
||||
sf::Texture& invenbtn_gworld = *ResMgr::get<ImageRsrc>("invenbtns");
|
||||
for(short i = 0; i < 24; i++) // Loop through items and draw each
|
||||
for(short i = 0; i < univ.party[current_active_pc].items.size(); i++) // Loop through items and draw each
|
||||
if(univ.party[current_active_pc].items[i].variety != eItemType::NO_ITEM) { // i.e. does item exist
|
||||
std::string to_draw = std::to_string(i + 1) + ". ";
|
||||
if(!univ.party[current_active_pc].items[i].ident)
|
||||
|
Reference in New Issue
Block a user