Make monster resistances a percentage and update monster info dialog
- Fix monster roster menu not working
This commit is contained in:
@@ -384,7 +384,8 @@ static void put_monst_info(cDialog& me, const cCreature& store_m) {
|
||||
|
||||
i = 1;
|
||||
for(auto& abil : store_m.abil) {
|
||||
if(i > 2) break; // TODO: Support showing more than just the first two abilities
|
||||
if(i > 4) break; // TODO: Support showing more than just the first four abilities
|
||||
if(!abil.second.active) continue;
|
||||
std::string id = "abil" + std::to_string(i);
|
||||
me[id].setText(abil.second.to_string(abil.first));
|
||||
i++;
|
||||
@@ -411,14 +412,13 @@ static void put_monst_info(cDialog& me, const cCreature& store_m) {
|
||||
me["mage"].setTextToNum(store_m.mu);
|
||||
me["priest"].setTextToNum(store_m.cl);
|
||||
// Immunities
|
||||
dynamic_cast<cLed&>(me["magic-res"]).setState(store_m.magic_res == RESIST_HALF ? led_red : led_off);
|
||||
dynamic_cast<cLed&>(me["magic-imm"]).setState(store_m.magic_res == RESIST_ALL ? led_red : led_off);
|
||||
dynamic_cast<cLed&>(me["fire-res"]).setState(store_m.fire_res == RESIST_HALF ? led_red : led_off);
|
||||
dynamic_cast<cLed&>(me["fire-imm"]).setState(store_m.fire_res == RESIST_ALL ? led_red : led_off);
|
||||
dynamic_cast<cLed&>(me["cold-res"]).setState(store_m.cold_res == RESIST_HALF ? led_red : led_off);
|
||||
dynamic_cast<cLed&>(me["cold-imm"]).setState(store_m.cold_res == RESIST_ALL ? led_red : led_off);
|
||||
dynamic_cast<cLed&>(me["poison-res"]).setState(store_m.poison_res == RESIST_HALF ? led_red : led_off);
|
||||
dynamic_cast<cLed&>(me["poison-imm"]).setState(store_m.poison_res == RESIST_ALL ? led_red : led_off);
|
||||
me["magic-res"].setText(std::to_string(100 - store_m.magic_res) + '%');
|
||||
me["fire-res"].setText(std::to_string(100 - store_m.fire_res) + '%');
|
||||
me["cold-res"].setText(std::to_string(100 - store_m.cold_res) + '%');
|
||||
me["poison-res"].setText(std::to_string(100 - store_m.poison_res) + '%');
|
||||
dynamic_cast<cLed&>(me["mindless"]).setState(store_m.mindless ? led_red : led_off);
|
||||
dynamic_cast<cLed&>(me["invuln"]).setState(store_m.invuln ? led_red : led_off);
|
||||
dynamic_cast<cLed&>(me["guard"]).setState(store_m.guard ? led_red : led_off);
|
||||
}
|
||||
|
||||
|
||||
@@ -446,6 +446,7 @@ static bool display_monst_event_filter(cDialog& me, std::string item_hit, cCreat
|
||||
if(roster[position % 60].number != on_monst_menu[position]) {
|
||||
cMonster& monst = univ.scenario.scen_monsters[on_monst_menu[position]];
|
||||
roster.assign(position % 60, cCreature(on_monst_menu[position]), monst, PSD[SDF_EASY_MODE], univ.difficulty_adjust());
|
||||
store_m = roster[position % 60];
|
||||
}
|
||||
put_monst_info(me, store_m);
|
||||
return true;
|
||||
@@ -468,8 +469,7 @@ void display_monst(short array_pos,cCreature *which_m,short mode) {
|
||||
monstInfo["done"].attachClickHandler(std::bind(&cDialog::toast, &monstInfo, true));
|
||||
monstInfo.attachClickHandlers(event_filter, {"left", "right"});
|
||||
// Also add the click handler to the LEDs to suppress normal LED behaviour
|
||||
monstInfo.attachClickHandlers(event_filter, {"immune1", "immune2", "immune3", "immune4"});
|
||||
monstInfo.attachClickHandlers(event_filter, {"immune5", "immune6", "immune7", "immune8"});
|
||||
monstInfo.attachClickHandlers(event_filter, {"guard", "mindless", "invuln"});
|
||||
|
||||
if(full_roster) {
|
||||
// This is a bit hacky - call event handler with dummy ID to ensure the monster details are correctly populated.
|
||||
@@ -478,32 +478,6 @@ void display_monst(short array_pos,cCreature *which_m,short mode) {
|
||||
monstInfo["left"].hide();
|
||||
monstInfo["right"].hide();
|
||||
}
|
||||
// TODO: Put these labels in the XML definition
|
||||
monstInfo.addLabelFor("name", "Name", LABEL_LEFT, 26, true);
|
||||
monstInfo.addLabelFor("lvl", "Level", LABEL_LEFT, 21, true);
|
||||
monstInfo.addLabelFor("hp", "Health", LABEL_LEFT, 24, true);
|
||||
monstInfo.addLabelFor("sp", "Magic Pts.", LABEL_LEFT, 32, true);
|
||||
monstInfo.addLabelFor("def", "Armor", LABEL_LEFT, 23, true);
|
||||
monstInfo.addLabelFor("skill", "Skill", LABEL_LEFT, 18, true);
|
||||
monstInfo.addLabelFor("morale", "Morale", LABEL_LEFT, 23, true);
|
||||
monstInfo.addLabelFor("ap", "Speed", LABEL_LEFT, 19, true);
|
||||
monstInfo.addLabelFor("attack1", "Att #1", LABEL_LEFT, 26, true);
|
||||
monstInfo.addLabelFor("attack2", "Att #2", LABEL_LEFT, 23, true);
|
||||
monstInfo.addLabelFor("attack3", "Att #3", LABEL_LEFT, 22, true);
|
||||
monstInfo.addLabelFor("mage", "Mage L.", LABEL_LEFT, 34, true);
|
||||
monstInfo.addLabelFor("priest", "Priest L.", LABEL_LEFT, 30, true);
|
||||
monstInfo.addLabelFor("poison", "Poison", LABEL_LEFT, 23, true);
|
||||
monstInfo.addLabelFor("abil1", "Ability 1", LABEL_LEFT, 29, true);
|
||||
monstInfo.addLabelFor("abil2", "Ability 2", LABEL_LEFT, 29, true);
|
||||
// TODO: These could be the actual content text instead of a label, maybe?
|
||||
monstInfo.addLabelFor("immune1", "Magic Resistant", LABEL_LEFT, 45, false);
|
||||
monstInfo.addLabelFor("immune2", "Immune To Magic", LABEL_LEFT, 45, false);
|
||||
monstInfo.addLabelFor("immune3", "Fire Resistant", LABEL_LEFT, 45, false);
|
||||
monstInfo.addLabelFor("immune4", "Immune To Fire", LABEL_LEFT, 45, false);
|
||||
monstInfo.addLabelFor("immune5", "Cold Resistant", LABEL_LEFT, 45, false);
|
||||
monstInfo.addLabelFor("immune6", "Immune To Cold", LABEL_LEFT, 45, false);
|
||||
monstInfo.addLabelFor("immune7", "Poison Resistant", LABEL_LEFT, 45, false);
|
||||
monstInfo.addLabelFor("immune8", "Immune To Poison", LABEL_LEFT, 45, false);
|
||||
put_monst_info(monstInfo, store_m);
|
||||
|
||||
monstInfo.run();
|
||||
|
@@ -297,34 +297,32 @@ bool monst_hate_spot(short which_m,location *good_loc) {
|
||||
else if(univ.town.is_ice_wall(loc.x,loc.y)) {
|
||||
hate_spot = true;
|
||||
if(have_radiate && which_radiate == eFieldType::WALL_ICE) hate_spot = false;
|
||||
else if(univ.town.monst[which_m].cold_res == RESIST_ALL) hate_spot = false;
|
||||
else if(univ.town.monst[which_m].cold_res == 0) hate_spot = false;
|
||||
}
|
||||
// Hate fire wall?
|
||||
else if(univ.town.is_fire_wall(loc.x,loc.y)) {
|
||||
hate_spot = true;
|
||||
if(have_radiate && which_radiate == eFieldType::WALL_FIRE) hate_spot = false;
|
||||
else if(univ.town.monst[which_m].fire_res == RESIST_ALL) hate_spot = false;
|
||||
else if(univ.town.monst[which_m].fire_res == 0) hate_spot = false;
|
||||
}
|
||||
// Note: Monsters used to enter shock walls even if they were merely resistant to magic
|
||||
// Hate shock wall?
|
||||
else if(univ.town.is_force_wall(loc.x,loc.y)) {
|
||||
hate_spot = true;
|
||||
if(have_radiate && which_radiate == eFieldType::WALL_FORCE) hate_spot = false;
|
||||
else if(univ.town.monst[which_m].magic_res == RESIST_ALL) hate_spot = false;
|
||||
else if(univ.town.monst[which_m].magic_res == 0) hate_spot = false;
|
||||
}
|
||||
// Hate stink cloud?
|
||||
else if(univ.town.is_scloud(loc.x,loc.y)) {
|
||||
hate_spot = true;
|
||||
if(have_radiate && which_radiate == eFieldType::CLOUD_STINK) hate_spot = false;
|
||||
else if(univ.town.monst[which_m].magic_res == RESIST_ALL) hate_spot = false;
|
||||
else if(univ.town.monst[which_m].magic_res == RESIST_HALF) hate_spot = false;
|
||||
else if(univ.town.monst[which_m].magic_res <= 50) hate_spot = false;
|
||||
}
|
||||
// Hate sleep cloud?
|
||||
else if(univ.town.is_sleep_cloud(loc.x,loc.y)) {
|
||||
hate_spot = true;
|
||||
if(have_radiate && which_radiate == eFieldType::CLOUD_SLEEP) hate_spot = false;
|
||||
else if(univ.town.monst[which_m].magic_res == RESIST_ALL) hate_spot = false;
|
||||
else if(univ.town.monst[which_m].magic_res == RESIST_HALF) hate_spot = false;
|
||||
else if(univ.town.monst[which_m].magic_res <= 50) hate_spot = false;
|
||||
}
|
||||
// Hate antimagic?
|
||||
else if(univ.town.is_antimagic(loc.x,loc.y)) {
|
||||
@@ -1056,13 +1054,13 @@ bool monst_check_special_terrain(location where_check,short mode,short which_mon
|
||||
case eTerSpec::DAMAGING: // TODO: Update this to check other cases
|
||||
switch(eDamageType(ter_flag)) {
|
||||
case eDamageType::FIRE:
|
||||
return univ.town.monst[which_monst].fire_res == RESIST_ALL;
|
||||
return univ.town.monst[which_monst].fire_res == 0;
|
||||
case eDamageType::COLD:
|
||||
return univ.town.monst[which_monst].cold_res == RESIST_ALL;
|
||||
return univ.town.monst[which_monst].cold_res == 0;
|
||||
case eDamageType::MAGIC:
|
||||
return univ.town.monst[which_monst].magic_res == RESIST_ALL;
|
||||
return univ.town.monst[which_monst].magic_res == 0;
|
||||
case eDamageType::POISON:
|
||||
return univ.town.monst[which_monst].poison_res == RESIST_ALL;
|
||||
return univ.town.monst[which_monst].poison_res == 0;
|
||||
default:
|
||||
return univ.town.monst[which_monst].invuln;
|
||||
}
|
||||
@@ -1108,32 +1106,14 @@ void magic_adjust(cCreature *which_m,short *how_much) {
|
||||
which_m->health = 32767;
|
||||
else which_m->health += 3;
|
||||
}
|
||||
switch(which_m->magic_res) {
|
||||
case RESIST_HALF:
|
||||
*how_much /= 2;
|
||||
break;
|
||||
case RESIST_ALL:
|
||||
*how_much = 0;
|
||||
break;
|
||||
case RESIST_DOUBLE:
|
||||
*how_much *= 2;
|
||||
break;
|
||||
}
|
||||
*how_much *= which_m->magic_res;
|
||||
*how_much /= 100;
|
||||
}
|
||||
|
||||
void poison_monst(cCreature *which_m,short how_much) {
|
||||
if(how_much > 0) {
|
||||
switch(which_m->poison_res) {
|
||||
case RESIST_HALF:
|
||||
how_much /= 2;
|
||||
break;
|
||||
case RESIST_ALL:
|
||||
monst_spell_note(which_m->number,10);
|
||||
return;
|
||||
case RESIST_DOUBLE:
|
||||
how_much *= 2;
|
||||
break;
|
||||
}
|
||||
how_much *= which_m->poison_res;
|
||||
how_much /= 100;
|
||||
}
|
||||
which_m->status[eStatus::POISON] = min(8, which_m->status[eStatus::POISON] + how_much);
|
||||
if(how_much >= 0)
|
||||
@@ -1225,17 +1205,10 @@ void charm_monst(cCreature *which_m,short penalty,eStatus which_status,short amo
|
||||
which_m->m_type == eRace::STONE || which_m->m_type == eRace::PLANT))
|
||||
return;
|
||||
r1 = get_ran(1,1,100);
|
||||
switch(which_m->magic_res) {
|
||||
case RESIST_HALF:
|
||||
r1 *= 2;
|
||||
break;
|
||||
case RESIST_ALL:
|
||||
r1 = 200;
|
||||
break;
|
||||
case RESIST_DOUBLE:
|
||||
r1 /= 2;
|
||||
break;
|
||||
}
|
||||
if(which_m->magic_res > 0) {
|
||||
r1 *= 100;
|
||||
r1 /= which_m->magic_res;
|
||||
} else r1 = 200;
|
||||
r1 += penalty;
|
||||
if(which_status == eStatus::ASLEEP)
|
||||
r1 -= 25;
|
||||
|
@@ -1413,56 +1413,20 @@ bool damage_monst(short which_m, short who_hit, short how_much, short how_much_s
|
||||
victim = &univ.town.monst[which_m];
|
||||
|
||||
if(dam_type == eDamageType::MAGIC) {
|
||||
switch(victim->magic_res) {
|
||||
case RESIST_HALF:
|
||||
how_much /= 2;
|
||||
break;
|
||||
case RESIST_ALL:
|
||||
how_much = 0;
|
||||
break;
|
||||
case RESIST_DOUBLE:
|
||||
how_much *= 2;
|
||||
break;
|
||||
}
|
||||
how_much *= victim->magic_res;
|
||||
how_much /= 100;
|
||||
}
|
||||
if(dam_type == eDamageType::FIRE) {
|
||||
switch(victim->fire_res) {
|
||||
case RESIST_HALF:
|
||||
how_much /= 2;
|
||||
break;
|
||||
case RESIST_ALL:
|
||||
how_much = 0;
|
||||
break;
|
||||
case RESIST_DOUBLE:
|
||||
how_much *= 2;
|
||||
break;
|
||||
}
|
||||
how_much *= victim->fire_res;
|
||||
how_much /= 100;
|
||||
}
|
||||
if(dam_type == eDamageType::COLD) {
|
||||
switch(victim->cold_res) {
|
||||
case RESIST_HALF:
|
||||
how_much /= 2;
|
||||
break;
|
||||
case RESIST_ALL:
|
||||
how_much = 0;
|
||||
break;
|
||||
case RESIST_DOUBLE:
|
||||
how_much *= 2;
|
||||
break;
|
||||
}
|
||||
how_much *= victim->cold_res;
|
||||
how_much /= 100;
|
||||
}
|
||||
if(dam_type == eDamageType::POISON) {
|
||||
switch(victim->poison_res) {
|
||||
case RESIST_HALF:
|
||||
how_much /= 2;
|
||||
break;
|
||||
case RESIST_ALL:
|
||||
how_much = 0;
|
||||
break;
|
||||
case RESIST_DOUBLE:
|
||||
how_much *= 2;
|
||||
break;
|
||||
}
|
||||
how_much *= victim->poison_res;
|
||||
how_much /= 100;
|
||||
}
|
||||
|
||||
// Absorb damage?
|
||||
@@ -1602,7 +1566,8 @@ void petrify_monst(cCreature* m_target, short strength) {
|
||||
r1 += m_target->status[eStatus::BLESS_CURSE];
|
||||
r1 -= strength;
|
||||
|
||||
if(r1 > 14 || m_target->magic_res == RESIST_ALL)
|
||||
// TODO: This should probably do something similar to charm_monst with the magic resistance
|
||||
if(r1 > 14 || m_target->magic_res == 0)
|
||||
monst_spell_note(m_target->number,10);
|
||||
else {
|
||||
monst_spell_note(m_target->number,8);
|
||||
|
@@ -105,21 +105,25 @@ void cMonster::append(legacy::monster_record_type& old){
|
||||
corpse_item = old.corpse_item;
|
||||
corpse_item_chance = old.corpse_item_chance;
|
||||
if(old.immunities & 2)
|
||||
magic_res = RESIST_ALL;
|
||||
magic_res = 0;
|
||||
else if(old.immunities & 1)
|
||||
magic_res = RESIST_HALF;
|
||||
magic_res = 50;
|
||||
else magic_res = 100;
|
||||
if(old.immunities & 8)
|
||||
fire_res = RESIST_ALL;
|
||||
fire_res = 0;
|
||||
else if(old.immunities & 4)
|
||||
fire_res = RESIST_HALF;
|
||||
fire_res = 50;
|
||||
else fire_res = 100;
|
||||
if(old.immunities & 32)
|
||||
cold_res = RESIST_ALL;
|
||||
cold_res = 0;
|
||||
else if(old.immunities & 16)
|
||||
cold_res = RESIST_HALF;
|
||||
cold_res = 50;
|
||||
else cold_res = 100;
|
||||
if(old.immunities & 128)
|
||||
poison_res = RESIST_ALL;
|
||||
poison_res = 0;
|
||||
else if(old.immunities & 64)
|
||||
poison_res = RESIST_HALF;
|
||||
poison_res = 50;
|
||||
else poison_res = 100;
|
||||
x_width = old.x_width;
|
||||
y_width = old.y_width;
|
||||
default_attitude = old.default_attitude;
|
||||
@@ -143,7 +147,7 @@ void cMonster::addAbil(eMonstAbilTemplate what, int param) {
|
||||
abil[eMonstAbil::MISSILE].missile = {true, eMonstMissile::ARROW, 3, 2, 7, 4, 8, 750};
|
||||
break;
|
||||
case eMonstAbilTemplate::THROWS_SPEARS:
|
||||
abil[eMonstAbil::MISSILE].missile = {true, eMonstMissile::ARROW, 5, 3, 7, 6, 8, 625};
|
||||
abil[eMonstAbil::MISSILE].missile = {true, eMonstMissile::SPEAR, 5, 3, 7, 6, 8, 625};
|
||||
break;
|
||||
case eMonstAbilTemplate::THROWS_ROCKS1:
|
||||
abil[eMonstAbil::MISSILE].missile = {true, eMonstMissile::ROCK, 12, 4, 7, 8, 10, 625};
|
||||
@@ -365,6 +369,7 @@ void cMonster::addAbil(eMonstAbilTemplate what, int param) {
|
||||
}
|
||||
|
||||
cMonster::cMonster(){
|
||||
magic_res = poison_res = fire_res = cold_res = 100;
|
||||
// TODO: Fill in
|
||||
see_str1 = -1;
|
||||
see_str2 = -1;
|
||||
@@ -812,14 +817,9 @@ void cMonster::readFrom(std::istream& file) {
|
||||
line >> temp1 >> temp2;
|
||||
x_width = temp1;
|
||||
y_width = temp2;
|
||||
} else if(cur == "IMMUNE") {
|
||||
line >> temp1 >> temp2;
|
||||
magic_res = temp1;
|
||||
fire_res = temp2;
|
||||
line >> temp1 >> temp2;
|
||||
cold_res = temp1;
|
||||
poison_res = temp2;
|
||||
} else if(cur == "RACE")
|
||||
} else if(cur == "IMMUNE")
|
||||
line >> magic_res >> fire_res >> cold_res >> poison_res;
|
||||
else if(cur == "RACE")
|
||||
line >> m_type;
|
||||
else if(cur == "CORPSEITEM")
|
||||
line >> corpse_item >> corpse_item_chance;
|
||||
|
@@ -70,8 +70,6 @@ inline eDirection& operator++ (eDirection& me, int) {
|
||||
else return me = (eDirection)(1 + (int)me);
|
||||
}
|
||||
|
||||
enum eResistType {RESIST_NONE, RESIST_HALF, RESIST_ALL, RESIST_DOUBLE};
|
||||
|
||||
union uAbility {
|
||||
bool active;
|
||||
struct {
|
||||
@@ -128,10 +126,10 @@ public:
|
||||
std::map<eMonstAbil, uAbility> abil;
|
||||
item_num_t corpse_item;
|
||||
short corpse_item_chance;
|
||||
unsigned int magic_res : 2;
|
||||
unsigned int fire_res : 2;
|
||||
unsigned int cold_res : 2;
|
||||
unsigned int poison_res : 2;
|
||||
unsigned int magic_res;
|
||||
unsigned int fire_res;
|
||||
unsigned int cold_res;
|
||||
unsigned int poison_res;
|
||||
bool mindless : 1;
|
||||
bool invuln : 1;
|
||||
bool invisible : 1;
|
||||
|
@@ -578,15 +578,6 @@ static void put_monst_abils_in_dlog(cDialog& me, cMonster& store_monst, short wh
|
||||
me["loot-chance"].setTextToNum(store_monst.corpse_item_chance);
|
||||
|
||||
dynamic_cast<cLedGroup&>(me["summon"]).setSelected("s" + boost::lexical_cast<std::string,short>(store_monst.summon_type));
|
||||
|
||||
dynamic_cast<cLed&>(me["magic-res"]).setState(store_monst.magic_res == RESIST_HALF ? led_red : led_off);
|
||||
dynamic_cast<cLed&>(me["magic-imm"]).setState(store_monst.magic_res == RESIST_ALL ? led_red : led_off);
|
||||
dynamic_cast<cLed&>(me["fire-res"]).setState(store_monst.fire_res == RESIST_HALF ? led_red : led_off);
|
||||
dynamic_cast<cLed&>(me["fire-imm"]).setState(store_monst.fire_res == RESIST_ALL ? led_red : led_off);
|
||||
dynamic_cast<cLed&>(me["cold-res"]).setState(store_monst.cold_res == RESIST_HALF ? led_red : led_off);
|
||||
dynamic_cast<cLed&>(me["cold-imm"]).setState(store_monst.cold_res == RESIST_ALL ? led_red : led_off);
|
||||
dynamic_cast<cLed&>(me["poison-res"]).setState(store_monst.poison_res == RESIST_HALF ? led_red : led_off);
|
||||
dynamic_cast<cLed&>(me["poison-imm"]).setState(store_monst.poison_res == RESIST_ALL ? led_red : led_off);
|
||||
}
|
||||
|
||||
static bool save_monst_abils(cDialog& me, cMonster& store_monst) {
|
||||
@@ -594,14 +585,6 @@ static bool save_monst_abils(cDialog& me, cMonster& store_monst) {
|
||||
|
||||
store_monst.corpse_item = me["loot-item"].getTextAsNum();
|
||||
store_monst.corpse_item_chance = me["loot-chance"].getTextAsNum();
|
||||
if(dynamic_cast<cLed&>(me["magic-res"]).getState() != led_off) store_monst.magic_res = RESIST_HALF;
|
||||
if(dynamic_cast<cLed&>(me["magic-imm"]).getState() != led_off) store_monst.magic_res = RESIST_ALL;
|
||||
if(dynamic_cast<cLed&>(me["fire-res"]).getState() != led_off) store_monst.fire_res = RESIST_HALF;
|
||||
if(dynamic_cast<cLed&>(me["fire-imm"]).getState() != led_off) store_monst.fire_res = RESIST_ALL;
|
||||
if(dynamic_cast<cLed&>(me["cold-res"]).getState() != led_off) store_monst.cold_res = RESIST_HALF;
|
||||
if(dynamic_cast<cLed&>(me["cold-imm"]).getState() != led_off) store_monst.cold_res = RESIST_ALL;
|
||||
if(dynamic_cast<cLed&>(me["poison-res"]).getState() != led_off) store_monst.poison_res = RESIST_HALF;
|
||||
if(dynamic_cast<cLed&>(me["poison-imm"]).getState() != led_off) store_monst.poison_res = RESIST_ALL;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user