Various damage-related changes

- Rename unblockable damage to "weird" and special damage to "unblockable"
- Monsters now support immunity to any damage type
- Fix using wrong damage type for bonus damage in PC-on-PC attacks
- Forbid use of unblockable (formerly special) damage by the scenario designer, except in special nodes; if hacked in, it's replaced with weird (formerly unblockable) damage.
- Fix damage amount text in animations (both single-frame booms and fully animated booms)

Changed the following things from weird (formerly unblockable) damage to unblockable (formerly special) damage:
- Starvation
- Debug 'K' command
- Damage from items forcibly ending flight
- Damage from bashing doors
This commit is contained in:
2015-07-19 10:23:00 -04:00
parent c7e9e3ca6c
commit 9972c3d27d
21 changed files with 135 additions and 137 deletions

View File

@@ -131,8 +131,8 @@ void cCreature::drain_sp(int drain) {
}
void cCreature::poison(int how_much) {
if(how_much > 0) {
how_much *= poison_res;
if(how_much != 0) {
how_much *= resist[eDamageType::POISON];
how_much /= 100;
}
apply_status(eStatus::POISON, how_much);
@@ -226,9 +226,9 @@ void cCreature::sleep(eStatus which_status,int amount,int penalty) {
m_type == eRace::STONE || m_type == eRace::PLANT))
return;
short r1 = get_ran(1,1,100);
if(magic_res > 0) {
if(resist[eDamageType::MAGIC] > 0) {
r1 *= 100;
r1 /= magic_res;
r1 /= resist[eDamageType::MAGIC];
} else r1 = 200;
r1 += penalty;
if(which_status == eStatus::FORCECAGE && (mu > 0 || cl > 0))
@@ -314,7 +314,7 @@ int cCreature::magic_adjust(int how_much) {
return 0;
}
// TODO: Magic resistance status effect?
how_much *= magic_res;
how_much *= resist[eDamageType::MAGIC];
how_much /= 100;
return how_much;
}

View File

@@ -329,7 +329,7 @@ std::istream& operator >> (std::istream& in, eFieldType& e) {
// MARK: eDamageType
cEnumLookup dmg_names = {
"weap", "fire", "poison", "magic", "unblockable", "cold", "undead", "demon", "spec",
"weap", "fire", "poison", "magic", "weird", "cold", "undead", "demon", "spec",
};
std::ostream& operator << (std::ostream& out, eDamageType e) {

View File

@@ -1016,8 +1016,8 @@ std::string cItem::getAbilName() const {
case eDamageType::WEAPON: sout << "Enhanced"; break;
case eDamageType::UNDEAD: sout << "Necrotic"; break;
case eDamageType::DEMON: sout << "Unholy"; break;
case eDamageType::SPECIAL:
case eDamageType::UNBLOCKABLE: sout << "Dark"; break;
case eDamageType::SPECIAL: sout << "Assassin's"; break;
case eDamageType::MARKED: break; // Invalid
}
sout << " Weapon";
@@ -1058,10 +1058,10 @@ std::string cItem::getAbilName() const {
case eDamageType::MAGIC: sout << "in sparks"; break;
case eDamageType::POISON: sout << "into slime"; break;
case eDamageType::WEAPON: sout << "in shrapnel"; break;
case eDamageType::SPECIAL:
case eDamageType::UNBLOCKABLE: sout << "in darkness"; break;
case eDamageType::UNDEAD: sout.str("Implodes"); break;
case eDamageType::DEMON: sout << "into corruption"; break;
case eDamageType::SPECIAL: sout << "into energy"; break;
case eDamageType::MARKED: break; // Invalid
}
break;
@@ -1096,8 +1096,8 @@ std::string cItem::getAbilName() const {
case eDamageType::DEMON: sout << "Demon"; break;
case eDamageType::UNDEAD: sout << "Undead"; break;
case eDamageType::POISON: sout << "Poison"; break;
case eDamageType::SPECIAL:
case eDamageType::UNBLOCKABLE: sout << "Darkness"; break;
case eDamageType::SPECIAL: sout << "Assassin's"; break;
case eDamageType::MARKED: break; // Invalid
}
sout << " Protection";

View File

@@ -105,25 +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 = 0;
resist[eDamageType::MAGIC] = 0;
else if(old.immunities & 1)
magic_res = 50;
else magic_res = 100;
resist[eDamageType::MAGIC] = 50;
else resist[eDamageType::MAGIC] = 100;
if(old.immunities & 8)
fire_res = 0;
resist[eDamageType::FIRE] = 0;
else if(old.immunities & 4)
fire_res = 50;
else fire_res = 100;
resist[eDamageType::FIRE] = 50;
else resist[eDamageType::FIRE] = 100;
if(old.immunities & 32)
cold_res = 0;
resist[eDamageType::COLD] = 0;
else if(old.immunities & 16)
cold_res = 50;
else cold_res = 100;
resist[eDamageType::COLD] = 50;
else resist[eDamageType::COLD] = 100;
if(old.immunities & 128)
poison_res = 0;
resist[eDamageType::POISON] = 0;
else if(old.immunities & 64)
poison_res = 50;
else poison_res = 100;
resist[eDamageType::POISON] = 50;
else resist[eDamageType::POISON] = 100;
x_width = old.x_width;
y_width = old.y_width;
default_attitude = eAttitude(old.default_attitude);
@@ -379,7 +379,12 @@ std::map<eMonstAbil,uAbility>::iterator cMonster::addAbil(eMonstAbilTemplate wha
}
cMonster::cMonster(){
magic_res = poison_res = fire_res = cold_res = 100;
for(int i = 0; i <= 8; i++) {
eDamageType dmg = eDamageType(i);
resist[dmg] = 100;
}
// And just in case something weird happens:
resist[eDamageType::MARKED] = 100;
mindless = invuln = guard = invisible = false;
level = m_health = armor = skill = 0;
speed = 4;
@@ -536,12 +541,12 @@ std::string uAbility::to_string(eMonstAbil key) const {
case eDamageType::FIRE: sout << "Fiery"; break;
case eDamageType::COLD: sout << "Icy"; break;
case eDamageType::MAGIC: sout << "Shock"; break;
case eDamageType::SPECIAL:
case eDamageType::UNBLOCKABLE: sout << "Wounding"; break;
case eDamageType::POISON: sout << "Pain"; break;
case eDamageType::WEAPON: sout << "Stamina drain"; break;
case eDamageType::DEMON: sout << "Unholy"; break;
case eDamageType::UNDEAD: sout << "Necrotic"; break;
case eDamageType::SPECIAL: sout << "Assassinating"; break;
case eDamageType::MARKED: break; // Invalid
}
break;
@@ -766,7 +771,11 @@ void cMonster::writeTo(std::ostream& file) const {
file << "RACE " << m_type << '\n';
file << "TREASURE" << int(treasure) << '\n';
file << "CORPSEITEM " << corpse_item << ' ' << corpse_item_chance << '\n';
file << "IMMUNE " << magic_res << '\t' << fire_res << '\t' << cold_res << '\t' << poison_res << '\n';
for(int i = 0; i < 8; i++) {
eDamageType dmg = eDamageType(i);
if(resist.at(dmg) != 100)
file << "IMMUNE " << dmg << '\t' << resist.at(dmg) << '\n';
}
file << "SIZE " << int(x_width) << ' ' << int(y_width) << '\n';
file << "ATTITUDE " << int(default_attitude) << '\n';
file << "SUMMON " << int(summon_type) << '\n';
@@ -839,9 +848,10 @@ void cMonster::readFrom(std::istream& file) {
line >> temp1 >> temp2;
x_width = temp1;
y_width = temp2;
} else if(cur == "IMMUNE")
line >> magic_res >> fire_res >> cold_res >> poison_res;
else if(cur == "RACE")
} else if(cur == "IMMUNE") {
eDamageType dmg;
line >> dmg >> resist[dmg];
} else if(cur == "RACE")
line >> m_type;
else if(cur == "CORPSEITEM")
line >> corpse_item >> corpse_item_chance;

View File

@@ -109,10 +109,7 @@ public:
mutable std::map<eMonstAbil, uAbility> abil;
item_num_t corpse_item;
short corpse_item_chance;
unsigned int magic_res;
unsigned int fire_res;
unsigned int cold_res;
unsigned int poison_res;
std::map<eDamageType, int> resist;
bool mindless, invuln, invisible, guard;
unsigned int x_width,y_width;
eAttitude default_attitude;

View File

@@ -540,6 +540,7 @@ enum class eDamageType {
COLD = 5,
UNDEAD = 6,
DEMON = 7,
// Keep these two last
SPECIAL = 8, // Completely unblockable damage from assassination skill
MARKED = 10,
};