Merge more item abilities

- The strength, dexterity, and intelligence abilities have been merged; it's now possible to make items that boost some other skill, though the handling for this is not yet implemented.
- The occasional haste/bless/disease abilities have been merged.
- Move affect_pc and affect_party functions into cPlayer and cParty respectively
This commit is contained in:
2015-01-13 11:45:45 -05:00
parent d6aeba8e0f
commit 12c87a85af
11 changed files with 193 additions and 128 deletions

View File

@@ -2191,13 +2191,20 @@ void do_rest(long length, int hp_restore, int mp_restore) {
for(int i = 0; i < 6; i++)
univ.party[i].status.clear();
// Specials countdowns
if((length > 500 || age_before / 500 < univ.party.age / 500) && party_has_abil(eItemAbil::DISEASE_PARTY) && get_ran(1,0,5) == 3) {
// TODO: This seems to be the "radioactivity" handler, and the string appears to not exist.
cStrDlog display_enc_string("Missing String: Radioactivity", "", "", 8, PIC_DLOG);
display_enc_string.setSound(3);
display_enc_string.show();
if((length > 500 || age_before / 500 < univ.party.age / 500) && 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++)
disease_pc(i,5);
for(int j = 0; j < 24; j++) {
cItem& item = univ.party[i].items[j];
if(item.ability != eItemAbil::OCCASIONAL_STATUS) continue;
if(item.magic_use_type < 2) continue;
if(get_ran(1,0,5) != 3) continue;
int how_much = item.abil_data[0];
if(item.magic_use_type % 2 == 1) how_much *= -1;
if(isStatusNegative(eStatus(item.abil_data[1])))
how_much *= -1;
univ.party.apply_status(eStatus(item.abil_data[1]), how_much);
}
}
// Plants and magic shops
if(length > 4000 || age_before / 4000 < univ.party.age / 4000)
@@ -2293,14 +2300,21 @@ void increase_age() {
}
// Specials countdowns
if((univ.party.age % 500 == 0 && get_ran(1,0,5) == 3 && party_has_abil(eItemAbil::DISEASE_PARTY))) {
update_stat = true;
// TODO: This seems to be the "radioactivity" handler, and the string appears to not exist.
cStrDlog display_enc_string("Missing String: Radioactivity", "", "", 8, PIC_DLOG);
display_enc_string.setSound(3);
display_enc_string.show();
for(i = 0; i < 6; i++)
disease_pc(i,2);
if(univ.party.age % 500 == 0 && 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];
if(item.ability != eItemAbil::OCCASIONAL_STATUS) continue;
if(item.magic_use_type < 2) continue;
if(get_ran(1,0,5) != 3) continue;
int how_much = item.abil_data[0];
if(item.magic_use_type % 2 == 1) how_much *= -1;
eStatus status = eStatus(item.abil_data[1]);
if(isStatusNegative(status))
how_much *= -1;
univ.party.apply_status(status, how_much);
}
}

View File

@@ -1735,21 +1735,53 @@ void combat_run_monst() {
move_to_zero(univ.party[i].status[eStatus::PARALYZED]);
// Do special items
if(((item_level = get_prot_level(i,eItemAbil::OCCASIONAL_HASTE)) > 0)
&& (get_ran(1,0,10) == 5)) {
update_stat = true;
univ.party[i].status[eStatus::HASTE_SLOW] += item_level / 2;
add_string_to_buf("An item hastes you!");
}
if((item_level = get_prot_level(i,eItemAbil::OCCASIONAL_BLESS)) > 0) {
if(get_ran(1,0,10) == 5) {
update_stat = true;
univ.party[i].status[eStatus::BLESS_CURSE] += item_level / 2;
add_string_to_buf("An item blesses you!");
for(int j = 0; j < 24; j++) {
cItem& item = univ.party[i].items[j];
if(item.ability != eItemAbil::OCCASIONAL_STATUS) continue;
if(item.magic_use_type > 1) continue; // Affects whole party, which is handled elsewhere
if(get_ran(1,0,10) != 5) continue;
int how_much = item.abil_data[0];
if(item.magic_use_type % 2 == 1) how_much *= -1;
eStatus status = eStatus(item.abil_data[1]);
if(isStatusNegative(status))
how_much *= -1;
switch(status) {
case eStatus::MAIN: break;
case eStatus::HASTE_SLOW:
if(how_much > 0) add_string_to_buf("An item hastes you!");
else add_string_to_buf("An item slows you!");
break;
case eStatus::BLESS_CURSE:
if(how_much > 0) add_string_to_buf("An item blesses you!");
else add_string_to_buf("An item curses you!");
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)
add_string_to_buf("An item cures you!");
break;
case eStatus::INVULNERABLE:
case eStatus::MAGIC_RESISTANCE:
case eStatus::INVISIBLE:
case eStatus::MARTYRS_SHIELD:
if(how_much > 0) add_string_to_buf("An item protects you!");
// TODO: Message for negative amounts:
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)
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)
add_string_to_buf("An item clears your mind!");
break;
// TODO: Messages for other statuses?
}
univ.party[i].apply_status(status, how_much);
update_stat = true;
}
}
special_increase_age();

View File

@@ -2283,19 +2283,14 @@ short stat_adj(short pc_num,eSkill which) {
if(which == eSkill::INTELLIGENCE) {
if(univ.party[pc_num].traits[eTrait::MAGICALLY_APT])
tr++;
if(pc_has_abil_equip(pc_num,eItemAbil::INTELLIGENCE) < 24)
tr++;
}
if(which == eSkill::STRENGTH) {
if(univ.party[pc_num].traits[eTrait::STRENGTH])
tr++;
if(pc_has_abil_equip(pc_num,eItemAbil::STRENGTH) < 24)
tr++;
}
if(which == eSkill::DEXTERITY) {
if(pc_has_abil_equip(pc_num,eItemAbil::DEXTERITY) < 24)
tr++;
}
// TODO: Use ability strength?
if(pc_has_abil_equip(pc_num,eItemAbil::BOOST_STAT,int(which)) < 24)
tr++;
return tr;
}
@@ -2573,37 +2568,6 @@ void poison_party(short how_much) {
for(i = 0; i < 6; i++)
poison_pc(i,how_much);
}
//type; // which status to affect
void affect_pc(short which_pc,eStatus type,short how_much) {
static const std::set<eStatus> allow_negative = {
// The obvious ones:
eStatus::BLESS_CURSE, eStatus::HASTE_SLOW,
// The ones that BoE previously allowed:
eStatus::POISONED_WEAPON, eStatus::POISON, eStatus::ASLEEP,
// (Note: Negative levels of sleep can be obtained from the Hyperactivity spell. The other two never go negative.)
// The additional ones that make sense in the negative:
eStatus::MAGIC_RESISTANCE, eStatus::DUMB,
};
// TODO: Apply STATUS_PROTECTION item abilities; the challenge is to determine whether to apply to positive or negative how_much
// TODO: I'd like to merge poison_pc, web_pc, acid_pc etc into this function.
if(univ.party[which_pc].main_status != eMainStatus::ALIVE)
return;
univ.party[which_pc].status[type] = minmax (-8,8,univ.party[which_pc].status[type] + how_much);
if(!allow_negative.count(type))
univ.party[which_pc].status[type] = max(univ.party[which_pc].status[type],0);
put_pc_screen();
}
//type; // which status to affect
void affect_party(eStatus type,short how_much) {
short i;
for(i = 0; i < 6; i++)
if(univ.party[i].main_status == eMainStatus::ALIVE)
univ.party[i].status[type] = minmax (-8,8,univ.party[i].status[type] + how_much);
put_pc_screen();
}
void void_sanctuary(short pc_num) {
if(univ.party[pc_num].status[eStatus::INVISIBLE] > 0) {

View File

@@ -49,8 +49,6 @@ bool flying() ;
void acid_pc(short which_pc,short how_much);
void poison_pc(short which_pc,short how_much);
void poison_party(short how_much);
void affect_pc(short which_pc,eStatus type,short how_much);
void affect_party(eStatus type,short how_much);
void void_sanctuary(short pc_num);
void hit_party(short how_much,eDamageType damage_type);
void slay_party(eMainStatus mode);

View File

@@ -391,10 +391,10 @@ bool check_special_terrain(location where_check,eSpecCtx mode,short which_pc,sho
slow_pc(i,ter_flag1.s);
break;
case eStatus::INVULNERABLE: // Should say "You feel odd." / "You feel protected."?
affect_pc(i,eStatus::INVULNERABLE,ter_flag1.u);
univ.party[i].apply_status(eStatus::INVULNERABLE,ter_flag1.u);
break;
case eStatus::MAGIC_RESISTANCE: // Should say "You feel odd." / "You feel protected."?
affect_pc(i,eStatus::MAGIC_RESISTANCE,ter_flag1.u);
univ.party[i].apply_status(eStatus::MAGIC_RESISTANCE,ter_flag1.u);
break;
case eStatus::WEBS: // Should say "You feel sticky." / "Your skin tingles."?
web_pc(i,ter_flag1.u);
@@ -405,13 +405,13 @@ bool check_special_terrain(location where_check,eSpecCtx mode,short which_pc,sho
case eStatus::INVISIBLE:
if(ter_flag1.s < 0) add_string_to_buf("You feel obscure.");
else add_string_to_buf("You feel exposed.");
affect_pc(i,eStatus::INVISIBLE,ter_flag1.s);
univ.party[i].apply_status(eStatus::INVISIBLE,ter_flag1.s);
break;
case eStatus::DUMB: // Should say "You feel clearheaded." / "You feel confused."?
dumbfound_pc(i,ter_flag1.u);
break;
case eStatus::MARTYRS_SHIELD: // Should say "You feel dull." / "You start to glow slightly."?
affect_pc(i,eStatus::MARTYRS_SHIELD,ter_flag1.u);
univ.party[i].apply_status(eStatus::MARTYRS_SHIELD,ter_flag1.u);
break;
case eStatus::ASLEEP: // Should say "You feel alert." / "You feel very tired."?
sleep_pc(i,ter_flag1.u,eStatus::ASLEEP,ter_flag1.u / 2);
@@ -695,8 +695,8 @@ void use_item(short pc,short item) {
str = str * -1;
}else ASB(" You feel blessed.");
if(type > 1)
affect_party(status,str);
else affect_pc(pc,status,str);
univ.party.apply_status(status,str);
else univ.party[pc].apply_status(status,str);
break;
case eStatus::HASTE_SLOW:
// TODO: Is this the right sound?
@@ -706,8 +706,8 @@ void use_item(short pc,short item) {
str = str * -1;
}else ASB(" You feel speedy.");
if(type > 1)
affect_party(status,str);
else affect_pc(pc,status,str);
univ.party.apply_status(status,str);
else univ.party[pc].apply_status(status,str);
break;
case eStatus::INVULNERABLE:
// TODO: Is this the right sound?
@@ -717,8 +717,8 @@ void use_item(short pc,short item) {
str = str * -1;
}else ASB(" You feel protected.");
if(type > 1)
affect_party(status,str);
else affect_pc(pc,status,str);
univ.party.apply_status(status,str);
else univ.party[pc].apply_status(status,str);
break;
case eStatus::MAGIC_RESISTANCE:
// TODO: Is this the right sound?
@@ -728,8 +728,8 @@ void use_item(short pc,short item) {
str = str * -1;
}else ASB(" You feel protected.");
if(type > 1)
affect_party(status,str);
else affect_pc(pc,status,str);
univ.party.apply_status(status,str);
else univ.party[pc].apply_status(status,str);
break;
case eStatus::WEBS:
if(type % 2 == 1)
@@ -739,8 +739,8 @@ void use_item(short pc,short item) {
str = str * -1;
}
if(type > 1)
affect_party(status,str);
else affect_pc(pc,status,str);
univ.party.apply_status(status,str);
else univ.party[pc].apply_status(status,str);
break;
case eStatus::INVISIBLE:
// TODO: Is this the right sound?
@@ -750,8 +750,8 @@ void use_item(short pc,short item) {
str = str * -1;
}else ASB(" You feel obscure.");
if(type > 1)
affect_party(status,str);
else affect_pc(pc,status,str);
univ.party.apply_status(status,str);
else univ.party[pc].apply_status(status,str);
break;
case eStatus::MARTYRS_SHIELD:
// TODO: Is this the right sound?
@@ -761,8 +761,8 @@ void use_item(short pc,short item) {
str = str * -1;
}else ASB(" You start to glow slightly.");
if(type > 1)
affect_party(status,str);
else affect_pc(pc,status,str);
univ.party.apply_status(status,str);
else univ.party[pc].apply_status(status,str);
break;
case eStatus::POISON:
switch(type) {
@@ -788,7 +788,7 @@ void use_item(short pc,short item) {
switch(type) {
case 0:
ASB(" You feel healthy.");
affect_pc(pc,eStatus::DISEASE,-1 * str);
univ.party[pc].apply_status(eStatus::DISEASE,-1 * str);
break;
case 1:
ASB(" You feel sick.");
@@ -796,7 +796,7 @@ void use_item(short pc,short item) {
break;
case 2:
ASB(" You all feel healthy.");
affect_party(eStatus::DISEASE,-1 * str);
univ.party.apply_status(eStatus::DISEASE,-1 * str);
break;
case 3:
ASB(" You all feel sick.");
@@ -809,7 +809,7 @@ void use_item(short pc,short item) {
switch(type) {
case 0:
ASB(" You feel clear headed.");
affect_pc(pc,eStatus::DUMB,-1 * str);
univ.party[pc].apply_status(eStatus::DUMB,-1 * str);
break;
case 1:
ASB(" You feel confused.");
@@ -817,7 +817,7 @@ void use_item(short pc,short item) {
break;
case 2:
ASB(" You all feel clear headed.");
affect_party(eStatus::DUMB,-1 * str);
univ.party.apply_status(eStatus::DUMB,-1 * str);
break;
case 3:
ASB(" You all feel confused.");
@@ -830,7 +830,7 @@ void use_item(short pc,short item) {
switch(type) {
case 0:
ASB(" You feel alert.");
affect_pc(pc,eStatus::ASLEEP,-1 * str);
univ.party[pc].apply_status(eStatus::ASLEEP,-1 * str);
break;
case 1:
ASB(" You feel very tired.");
@@ -838,7 +838,7 @@ void use_item(short pc,short item) {
break;
case 2:
ASB(" You all feel alert.");
affect_party(eStatus::ASLEEP,-1 * str);
univ.party.apply_status(eStatus::ASLEEP,-1 * str);
break;
case 3:
ASB(" You all feel very tired.");
@@ -851,7 +851,7 @@ void use_item(short pc,short item) {
switch(type) {
case 0:
ASB(" You find it easier to move.");
affect_pc(pc,eStatus::PARALYZED,-1 * str * 100);
univ.party[pc].apply_status(eStatus::PARALYZED,-1 * str * 100);
break;
case 1:
ASB(" You feel very stiff.");
@@ -859,7 +859,7 @@ void use_item(short pc,short item) {
break;
case 2:
ASB(" You all find it easier to move.");
affect_party(eStatus::PARALYZED,-1 * str * 100);
univ.party.apply_status(eStatus::PARALYZED,-1 * str * 100);
break;
case 3:
ASB(" You all feel very stiff.");
@@ -872,7 +872,7 @@ void use_item(short pc,short item) {
switch(type) {
case 0:
ASB(" Your skin tingles pleasantly.");
affect_pc(pc,eStatus::ACID,-1 * str);
univ.party[pc].apply_status(eStatus::ACID,-1 * str);
break;
case 1:
ASB(" Your skin burns!");
@@ -880,7 +880,7 @@ void use_item(short pc,short item) {
break;
case 2:
ASB(" You all tingle pleasantly.");
affect_party(eStatus::ACID,-1 * str);
univ.party.apply_status(eStatus::ACID,-1 * str);
break;
case 3:
ASB(" Everyone's skin burns!");
@@ -895,14 +895,12 @@ void use_item(short pc,short item) {
case 0: case 1:
ASB(" You feel wonderful!");
heal_pc(pc,str * 20);
affect_pc(pc,eStatus::BLESS_CURSE,str);
univ.party[pc].apply_status(eStatus::BLESS_CURSE,str);
break;
case 2: case 3:
ASB(" Everyone feels wonderful!");
for(i = 0; i < 6; i++) {
heal_pc(i,str * 20);
affect_pc(i,eStatus::BLESS_CURSE,str);
}
heal_party(str*20);
univ.party.apply_status(eStatus::BLESS_CURSE,str);
break;
}
break;
@@ -2664,18 +2662,18 @@ void affect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
case eSpecType::AFFECT_INVULN:
for(i = 0; i < 6; i++)
if((pc < 0) || (pc == i))
affect_pc(i,eStatus::INVULNERABLE,spec.ex1a * ((spec.ex1b != 0) ? -1: 1));
univ.party[i].apply_status(eStatus::INVULNERABLE,spec.ex1a * ((spec.ex1b != 0) ? -1: 1));
break;
case eSpecType::AFFECT_MAGIC_RES:
for(i = 0; i < 6; i++)
if((pc < 0) || (pc == i))
affect_pc(i,eStatus::MAGIC_RESISTANCE,spec.ex1a * ((spec.ex1b != 0) ? -1: 1));
univ.party[i].apply_status(eStatus::MAGIC_RESISTANCE,spec.ex1a * ((spec.ex1b != 0) ? -1: 1));
break;
case eSpecType::AFFECT_WEBS:
if(spec.ex2a < 0) {
for(i = 0; i < 6; i++)
if((pc < 0) || (pc == i))
affect_pc(i,eStatus::WEBS,spec.ex1a * ((spec.ex1b != 0) ? -1: 1));
univ.party[i].apply_status(eStatus::WEBS,spec.ex1a * ((spec.ex1b != 0) ? -1: 1));
}
else {
if(univ.town.monst[spec.ex2a].active > 0) {
@@ -2690,7 +2688,7 @@ void affect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
if(spec.ex2a < 0) {
for(i = 0; i < 6; i++)
if((pc < 0) || (pc == i))
affect_pc(i,eStatus::DISEASE,spec.ex1a * ((spec.ex1b != 0) ? 1: -1));
univ.party[i].apply_status(eStatus::DISEASE,spec.ex1a * ((spec.ex1b != 0) ? 1: -1));
}
else {
if(univ.town.monst[spec.ex2a].active > 0) {
@@ -2704,13 +2702,13 @@ void affect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
case eSpecType::AFFECT_SANCTUARY:
for(i = 0; i < 6; i++)
if((pc < 0) || (pc == i))
affect_pc(i,eStatus::INVISIBLE,spec.ex1a * ((spec.ex1b != 0) ? -1: 1));
univ.party[i].apply_status(eStatus::INVISIBLE,spec.ex1a * ((spec.ex1b != 0) ? -1: 1));
break;
case eSpecType::AFFECT_CURSE_BLESS:
if(spec.ex2a < 0) {
for(i = 0; i < 6; i++)
if((pc < 0) || (pc == i))
affect_pc(i,eStatus::BLESS_CURSE,spec.ex1a * ((spec.ex1b != 0) ? -1: 1));
univ.party[i].apply_status(eStatus::BLESS_CURSE,spec.ex1a * ((spec.ex1b != 0) ? -1: 1));
}
else {
if(univ.town.monst[spec.ex2a].active > 0) {
@@ -2725,7 +2723,7 @@ void affect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
if(spec.ex2a < 0) {
for(i = 0; i < 6; i++)
if((pc < 0) || (pc == i))
affect_pc(i,eStatus::DUMB,spec.ex1a * ((spec.ex1b == 0) ? -1: 1));
univ.party[i].apply_status(eStatus::DUMB,spec.ex1a * ((spec.ex1b == 0) ? -1: 1));
}
else {
if(univ.town.monst[spec.ex2a].active > 0) {
@@ -2741,7 +2739,7 @@ void affect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
for(i = 0; i < 6; i++)
if((pc < 0) || (pc == i)) {
if(spec.ex1b == 0) {
affect_pc(i,eStatus::ASLEEP,-1 * spec.ex1a);
univ.party[i].apply_status(eStatus::ASLEEP,-1 * spec.ex1a);
}
else sleep_pc(i,spec.ex1a,eStatus::ASLEEP,10);
}
@@ -2760,7 +2758,7 @@ void affect_spec(eSpecCtx which_mode,cSpecial cur_node,short cur_spec_type,
for(i = 0; i < 6; i++)
if((pc < 0) || (pc == i)) {
if(spec.ex1b == 0) {
affect_pc(i,eStatus::PARALYZED,-1 * spec.ex1a);
univ.party[i].apply_status(eStatus::PARALYZED,-1 * spec.ex1a);
}
else sleep_pc(i,spec.ex1a,eStatus::PARALYZED,10);
}

View File

@@ -349,14 +349,20 @@ void cItem::append(legacy::item_record_type& old){
case 37:
ability = eItemAbil::SKILL;
break;
case 38:
ability = eItemAbil::STRENGTH;
case 38: // Strength
ability = eItemAbil::BOOST_STAT;
abil_data[0] = 1;
abil_data[1] = int(eSkill::STRENGTH);
break;
case 39:
ability = eItemAbil::DEXTERITY;
case 39: // Dexterity
ability = eItemAbil::BOOST_STAT;
abil_data[0] = 1;
abil_data[1] = int(eSkill::DEXTERITY);
break;
case 40:
ability = eItemAbil::INTELLIGENCE;
case 40: // Intelligence
ability = eItemAbil::BOOST_STAT;
abil_data[0] = 1;
abil_data[1] = int(eSkill::INTELLIGENCE);
break;
case 41:
ability = eItemAbil::ACCURACY;
@@ -374,10 +380,14 @@ void cItem::append(legacy::item_record_type& old){
ability = eItemAbil::HEAVIER_OBJECT;
break;
case 46:
ability = eItemAbil::OCCASIONAL_BLESS;
ability = eItemAbil::OCCASIONAL_STATUS;
abil_data[1] = int(eStatus::BLESS_CURSE);
magic_use_type = 0;
break;
case 47:
ability = eItemAbil::OCCASIONAL_HASTE;
ability = eItemAbil::OCCASIONAL_STATUS;
abil_data[1] = int(eStatus::HASTE_SLOW);
magic_use_type = 0;
break;
case 48:
ability = eItemAbil::LIFE_SAVING;
@@ -392,7 +402,9 @@ void cItem::append(legacy::item_record_type& old){
ability = eItemAbil::POISON_AUGMENT;
break;
case 52:
ability = eItemAbil::DISEASE_PARTY;
ability = eItemAbil::OCCASIONAL_STATUS;
abil_data[1] = int(eStatus::DISEASE);
magic_use_type = 3;
break;
case 53:
ability = eItemAbil::WILL;

View File

@@ -231,6 +231,11 @@ bool cParty::record(eEncNoteType type, const std::string& what, const std::strin
return false;
}
void cParty::apply_status(eStatus which, int how_much) {
for(int i = 0; i < 6; i++)
adven[i].apply_status(which, how_much);
}
bool cParty::start_timer(short time, short node, short type){
if(party_event_timers.size() == party_event_timers.max_size()) return false; // Shouldn't be reached
cTimer t;

View File

@@ -127,6 +127,8 @@ public:
void append(legacy::stored_items_list_type& old,short which_list);
void append(legacy::setup_save_type& old);
void apply_status(eStatus which, int how_much);
void add_pc(legacy::pc_record_type old);
void add_pc(cPlayer new_pc);
void void_pcs();

View File

@@ -15,6 +15,7 @@
#include "classes.h"
#include "oldstructs.h"
#include "mathutil.hpp"
void cPlayer::append(legacy::pc_record_type old){
int i;
@@ -75,6 +76,27 @@ short cPlayer::get_tnl(){
return tnl;
}
void cPlayer::apply_status(eStatus which, int how_much) {
static const std::set<eStatus> allow_negative = {
// The obvious ones:
eStatus::BLESS_CURSE, eStatus::HASTE_SLOW,
// The ones that BoE previously allowed:
eStatus::POISONED_WEAPON, eStatus::POISON, eStatus::ASLEEP,
// (Note: Negative levels of sleep can be obtained from the Hyperactivity spell. The other two never go negative.)
// The additional ones that make sense in the negative:
eStatus::MAGIC_RESISTANCE, eStatus::DUMB,
};
// TODO: Apply STATUS_PROTECTION item abilities; the challenge is to determine whether to apply to positive or negative how_much
// TODO: I'd like to merge poison_pc, web_pc, acid_pc etc into this function.
if(main_status != eMainStatus::ALIVE)
return;
status[which] = minmax(-8,8,status[which] + how_much);
if(!allow_negative.count(which))
status[which] = max(status[which],0);
}
void cPlayer::finish_create() {
// Start items
switch(race) {

View File

@@ -49,6 +49,7 @@ public:
short marked_damage, dir, parry, last_attacked;
void finish_create();
void apply_status(eStatus which, int how_much);
void append(legacy::pc_record_type old);
cPlayer();

View File

@@ -103,13 +103,34 @@ enum class eStatus {
ASLEEP = 11,
PARALYZED = 12,
ACID = 13,
FORCECAGE = 14, // This is new and currently unused, since forcecages aren't even really implemented yet.
FORCECAGE = 14,
// This one is new
// It's not quite a real status effect since it doesn't expire
// We use 15 because 14 was technically a "reserved/unused" status, though it was never used for anything
CHARM = 15,
};
inline bool isStatusNegative(eStatus stat) {
switch(stat) {
case eStatus::POISONED_WEAPON: return false;
case eStatus::BLESS_CURSE: return false;
case eStatus::POISON: return true;
case eStatus::HASTE_SLOW: return false;
case eStatus::INVULNERABLE: return false;
case eStatus::MAGIC_RESISTANCE: return false;
case eStatus::WEBS: return true;
case eStatus::DISEASE: return true;
case eStatus::INVISIBLE: return false;
case eStatus::DUMB: return true;
case eStatus::MARTYRS_SHIELD: return false;
case eStatus::ASLEEP: return true;
case eStatus::PARALYZED: return true;
case eStatus::ACID: return true;
case eStatus::FORCECAGE: return true;
case eStatus::CHARM: return true;
}
return false;
}
/* Special Ability a.k.a spec_skill */
enum eMonstAbil {
@@ -304,21 +325,17 @@ enum class eItemAbil {
FULL_PROTECTION = 31,
STATUS_PROTECTION = 36,
SKILL = 37,
STRENGTH = 38,
DEXTERITY = 39,
INTELLIGENCE = 40,
BOOST_STAT = 38,
ACCURACY = 41,
THIEVING = 42,
GIANT_STRENGTH = 43,
LIGHTER_OBJECT = 44,
HEAVIER_OBJECT = 45,
OCCASIONAL_BLESS = 46,
OCCASIONAL_HASTE = 47,
OCCASIONAL_STATUS = 46,
LIFE_SAVING = 48,
PROTECT_FROM_PETRIFY = 49,
REGENERATE = 50,
POISON_AUGMENT = 51,
DISEASE_PARTY = 52,
WILL = 53,
FREE_ACTION = 54,
SPEED = 55,
@@ -345,7 +362,7 @@ enum class eItemAbil {
QUICKFIRE = 129,
// Reagents
HOLLY = 150, // Holly/Toadstool
COMFREY = 151, // Comfreey Root
COMFREY = 151, // Comfrey Root
NETTLE = 152, // Glowing Nettle
WORMGRASS = 153, // Crypt Shroom/Wormgrass
ASPTONGUE = 154, // Asptongue Mold