CDamageVulnerability fixes

This commit is contained in:
Phillip Stephens 2021-05-08 20:14:38 -07:00
parent 6a125d805e
commit 61464651cd
Signed by: Antidote
GPG Key ID: F8BEE4C83DACA60D
3 changed files with 150 additions and 154 deletions

View File

@ -32,7 +32,8 @@ enum class EWeaponType {
Lava = 11, Lava = 11,
Heat = 12, Heat = 12,
Unused1 = 13, Unused1 = 13,
OrangePhazon = 14 OrangePhazon = 14,
Max = 15
}; };
enum class EProjectileAttrib { enum class EProjectileAttrib {

View File

@ -34,40 +34,46 @@ const CDamageVulnerability CDamageVulnerability::sPassThroughVulnerability(
EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough,
EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EDeflectType::None); EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EDeflectType::None);
static constexpr bool is_not_deflect_direct(EVulnerability vuln) { static constexpr bool is_deflect_direct(EVulnerability vuln) {
return vuln != EVulnerability::Deflect && vuln != EVulnerability::DirectWeak && return vuln == EVulnerability::Deflect || vuln == EVulnerability::DirectWeak ||
vuln != EVulnerability::DirectNormal && vuln != EVulnerability::DirectImmune; vuln == EVulnerability::DirectNormal || vuln == EVulnerability::DirectImmune;
} }
static constexpr bool is_normal_or_weak(EVulnerability vuln) { static constexpr bool is_normal_or_weak(EVulnerability vuln) {
return vuln == EVulnerability::Normal || vuln == EVulnerability::Weak; return vuln == EVulnerability::Weak || vuln == EVulnerability::Normal;
}
static constexpr bool is_not_deflect(EVulnerability vuln) {
return vuln != EVulnerability::Deflect;
} }
void CDamageVulnerability::ConstructNew(CInputStream& in, int propCount) { void CDamageVulnerability::ConstructNew(CInputStream& in, int propCount) {
propCount -= 3; propCount -= 3;
EVulnerability* vulns = &x0_power;
for (int i = 0; i < std::min(propCount, 15); ++i)
vulns[i] = EVulnerability(in.readUint32Big());
if (propCount < 15) { for (int i = 0; i < std::min(propCount, 15); ++i) {
for (int i = propCount; i < 15; ++i) x0_normal[i] = EVulnerability(in.readUint32Big());
vulns[i] = EVulnerability::Deflect;
} }
for (int i = 15; i < propCount; ++i) if (propCount < 15) {
for (int i = propCount; i < 15; ++i) {
x0_normal[i] = EVulnerability::Deflect;
}
}
for (int i = 15; i < propCount; ++i) {
in.readUint32Big(); in.readUint32Big();
}
x5c_deflected = EDeflectType(in.readUint32Big()); x5c_deflected = EDeflectType(in.readUint32Big());
EVulnerability* vulns2 = &x3c_chargedPower;
in.readUint32Big(); in.readUint32Big();
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i) {
vulns2[i] = EVulnerability(in.readUint32Big()); x3c_charged[i] = EVulnerability(in.readUint32Big());
}
x60_chargedDeflected = EDeflectType(in.readUint32Big()); x60_chargedDeflected = EDeflectType(in.readUint32Big());
EVulnerability* vulns3 = &x4c_superMissile;
in.readUint32Big(); in.readUint32Big();
for (int i = 0; i < 4; ++i) for (int i = 0; i < 4; ++i) {
vulns3[i] = EVulnerability(in.readUint32Big()); x4c_combo[i] = EVulnerability(in.readUint32Big());
}
x64_comboDeflected = EDeflectType(in.readUint32Big()); x64_comboDeflected = EDeflectType(in.readUint32Big());
} }
@ -75,74 +81,105 @@ void CDamageVulnerability::ConstructNew(CInputStream& in, int propCount) {
CDamageVulnerability::CDamageVulnerability(CInputStream& in) { CDamageVulnerability::CDamageVulnerability(CInputStream& in) {
u32 propCount = in.readUint32Big(); u32 propCount = in.readUint32Big();
if (propCount == 11) { if (propCount == 11) {
EVulnerability* vulns = &x0_power; for (int i = 0; i < 15; ++i) {
for (int i = 0; i < 15; ++i) x0_normal[i] = EVulnerability(in.readUint32Big());
vulns[i] = EVulnerability(in.readUint32Big()); }
if (propCount == 15) if (propCount == 15) {
x5c_deflected = EDeflectType::None; x5c_deflected = EDeflectType::None;
else } else {
x5c_deflected = EDeflectType(in.readUint32Big()); x5c_deflected = EDeflectType(in.readUint32Big());
}
x3c_chargedPower = x0_power; x3c_charged[0] = x0_normal[0];
x4c_superMissile = x0_power; x4c_combo[0] = x0_normal[0];
x40_chargedIce = x4_ice; x3c_charged[1] = x0_normal[1];
x50_iceSpreader = x4_ice; x4c_combo[1] = x0_normal[1];
x44_chargedWave = x8_wave; x3c_charged[2] = x0_normal[2];
x54_wavebuster = x8_wave; x4c_combo[2] = x0_normal[2];
x48_chargedPlasma = xc_plasma; x3c_charged[3] = x0_normal[3];
x58_flamethrower = xc_plasma; x4c_combo[3] = x0_normal[3];
} else } else {
ConstructNew(in, propCount); ConstructNew(in, propCount);
}
} }
EDeflectType CDamageVulnerability::GetDeflectionType(const CWeaponMode& mode) const { EDeflectType CDamageVulnerability::GetDeflectionType(const CWeaponMode& mode) const {
if (mode.IsCharged()) if (mode.IsCharged()) {
return x60_chargedDeflected; return x60_chargedDeflected;
if (mode.IsComboed()) }
if (mode.IsComboed()) {
return x64_comboDeflected; return x64_comboDeflected;
}
return x5c_deflected; return x5c_deflected;
} }
bool CDamageVulnerability::WeaponHurts(const CWeaponMode& mode, bool ignoreDirect) const { bool CDamageVulnerability::WeaponHurts(const CWeaponMode& mode, bool ignoreDirect) const {
if (mode.GetType() == EWeaponType::None || mode.GetType() > EWeaponType::OrangePhazon) if (mode.GetType() == EWeaponType::None || mode.GetType() > EWeaponType::OrangePhazon) {
return false; return false;
if (mode.IsInstantKill()) }
if (mode.IsInstantKill()) {
return true; return true;
}
EVulnerability normalVuln = (&x0_power)[u32(mode.GetType())];
bool normalHurts = true; bool normalHurts = true;
if (ignoreDirect) { const auto vuln = x0_normal[u32(mode.GetType())];
normalHurts = is_normal_or_weak(normalVuln); if (!ignoreDirect) {
} else { bool directHurts = true;
if (!is_normal_or_weak(normalVuln) && if (!is_normal_or_weak(vuln) && vuln != EVulnerability::DirectWeak) {
(normalVuln != EVulnerability::DirectWeak && normalVuln != EVulnerability::DirectNormal)) directHurts = false;
}
if (!directHurts && vuln != EVulnerability::DirectNormal) {
normalHurts = false; normalHurts = false;
}
} else if (!is_normal_or_weak(vuln)) {
normalHurts = false;
} }
bool chargedHurts = true; bool chargedHurts = true;
bool comboedHurts = true;
if (mode.GetType() < EWeaponType::Bomb) { if (mode.GetType() < EWeaponType::Bomb) {
EVulnerability chargedVuln = (&x3c_chargedPower)[u32(mode.GetType())]; const auto chargedVuln = x3c_charged[u32(mode.GetType())];
EVulnerability comboedVuln = (&x4c_superMissile)[u32(mode.GetType())]; if (!ignoreDirect) {
if (ignoreDirect) { bool directHurts = true;
chargedHurts = is_normal_or_weak(chargedVuln); if (!is_normal_or_weak(chargedVuln) && chargedVuln != EVulnerability::DirectWeak) {
comboedHurts = is_normal_or_weak(comboedVuln); directHurts = false;
} else { }
if (!is_normal_or_weak(chargedVuln) &&
(chargedVuln != EVulnerability::DirectWeak && chargedVuln != EVulnerability::DirectNormal)) if (!directHurts && chargedVuln != EVulnerability::DirectNormal) {
chargedHurts = false; chargedHurts = false;
if (!is_normal_or_weak(comboedVuln) && }
(comboedVuln != EVulnerability::DirectWeak && comboedVuln != EVulnerability::DirectNormal)) } else if (!is_normal_or_weak(chargedVuln)) {
comboedHurts = false; chargedHurts = false;
} }
} }
if (normalHurts && !mode.IsCharged() && !mode.IsComboed()) bool comboedHurts = true;
return true; if (mode.GetType() < EWeaponType::Bomb) {
if (chargedHurts && mode.IsCharged()) const auto comboedVuln = x4c_combo[u32(mode.GetType())];
return true; if (!ignoreDirect) {
return comboedHurts && mode.IsComboed(); bool directHurts = true;
if (!is_normal_or_weak(comboedVuln) && comboedVuln != EVulnerability::DirectWeak) {
directHurts = false;
}
if (!directHurts && comboedVuln != EVulnerability::DirectNormal) {
comboedHurts = false;
}
} else if (!is_normal_or_weak(comboedVuln)) {
comboedHurts = false;
}
}
if (((!normalHurts || mode.IsCharged()) || mode.IsComboed()) && (!chargedHurts || !mode.IsCharged())) {
if (!comboedHurts) {
return false;
}
if (!mode.IsComboed()) {
return false;
}
}
return true;
} }
bool CDamageVulnerability::WeaponHits(const CWeaponMode& mode, bool checkDirect) const { bool CDamageVulnerability::WeaponHits(const CWeaponMode& mode, bool checkDirect) const {
@ -152,39 +189,56 @@ bool CDamageVulnerability::WeaponHits(const CWeaponMode& mode, bool checkDirect)
if (mode.IsInstantKill()) { if (mode.IsInstantKill()) {
return true; return true;
} }
const auto normalVuln = x0_normal[u32(mode.GetType())];
bool normalVuln; bool normalHits = true;
if (!checkDirect) { if (!checkDirect) {
normalVuln = (&x0_power)[u32(mode.GetType())] != EVulnerability::Deflect; normalHits = is_not_deflect(normalVuln);
} else { } else if (is_deflect_direct(normalVuln)) {
normalVuln = is_not_deflect_direct((&x0_power)[u32(mode.GetType())]); normalHits = false;
} }
bool chargedVuln = true; bool chargedHits = true;
bool comboedVuln = true;
if (mode.GetType() < EWeaponType::Bomb) { if (mode.GetType() < EWeaponType::Bomb) {
const EVulnerability chargedPowerVuln = (&x3c_chargedPower)[u32(mode.GetType())]; const auto chargedVuln = x3c_charged[u32(mode.GetType())];
const EVulnerability superMissileVuln = (&x4c_superMissile)[u32(mode.GetType())];
if (!checkDirect) { if (!checkDirect) {
chargedVuln = chargedPowerVuln != EVulnerability::Deflect; chargedHits = is_not_deflect(chargedVuln);
comboedVuln = superMissileVuln != EVulnerability::Deflect; } else if (is_deflect_direct(normalVuln)) {
chargedHits = false;
} else { } else {
chargedVuln = is_not_deflect_direct(chargedPowerVuln); chargedHits = true;
comboedVuln = is_not_deflect_direct(superMissileVuln);
} }
} }
if (normalVuln && !mode.IsCharged() && !mode.IsComboed()) { bool comboedHits = true;
if (mode.GetType() < EWeaponType::Bomb) {
const auto chargedVuln = x3c_charged[u32(mode.GetType())];
if (!checkDirect) {
comboedHits = is_not_deflect(chargedVuln);
} else if (is_deflect_direct(normalVuln)) {
comboedHits = false;
} else {
comboedHits = true;
}
}
if (normalHits && !mode.IsCharged() && !mode.IsComboed()) {
return true; return true;
} }
if (chargedVuln && mode.IsCharged()) {
return true; if (!chargedHits || !mode.IsCharged()) {
if (comboedHits) {
return false;
}
if (!mode.IsComboed()) {
return false;
}
} }
return comboedVuln && mode.IsComboed(); return true;
} }
EVulnerability CDamageVulnerability::GetVulnerability(const CWeaponMode& mode, bool ignoreDirect) const { EVulnerability CDamageVulnerability::GetVulnerability(const CWeaponMode& mode, bool ignoreDirect) const {
if (mode.GetType() == EWeaponType::None || mode.GetType() > EWeaponType::OrangePhazon) { const auto type = mode.GetType();
if (type <= EWeaponType::None || type >= EWeaponType::Max) {
return EVulnerability::Deflect; return EVulnerability::Deflect;
} }
@ -192,18 +246,18 @@ EVulnerability CDamageVulnerability::GetVulnerability(const CWeaponMode& mode, b
return EVulnerability::Normal; return EVulnerability::Normal;
} }
EVulnerability vuln = (&x0_power)[u32(mode.GetType())]; auto vuln = x0_normal[u32(type)];
if (mode.IsCharged()) { if (mode.IsCharged()) {
if (mode.GetType() < EWeaponType::Bomb) { if (type < EWeaponType::Bomb) {
vuln = (&x3c_chargedPower)[u32(mode.GetType())]; vuln = x3c_charged[u32(type)];
} else { } else {
vuln = EVulnerability::Normal; vuln = EVulnerability::Normal;
} }
} }
if (mode.IsComboed()) { if (mode.IsComboed()) {
if (mode.GetType() < EWeaponType::Bomb) { if (type < EWeaponType::Bomb) {
vuln = (&x3c_chargedPower)[u32(mode.GetType())]; vuln = x4c_combo[u32(type)];
} else { } else {
vuln = EVulnerability::Normal; vuln = EVulnerability::Normal;
} }
@ -216,9 +270,11 @@ EVulnerability CDamageVulnerability::GetVulnerability(const CWeaponMode& mode, b
if (vuln == EVulnerability::DirectWeak) { if (vuln == EVulnerability::DirectWeak) {
return EVulnerability::Weak; return EVulnerability::Weak;
} }
if (vuln == EVulnerability::DirectNormal) { if (vuln == EVulnerability::DirectNormal) {
return EVulnerability::Normal; return EVulnerability::Normal;
} }
if (vuln == EVulnerability::DirectImmune) { if (vuln == EVulnerability::DirectImmune) {
return EVulnerability::Immune; return EVulnerability::Immune;
} }

View File

@ -9,32 +9,9 @@ enum class EVulnerability { Weak, Normal, Deflect, Immune, PassThrough, DirectWe
enum class EDeflectType { None, One, Two, Three, Four }; enum class EDeflectType { None, One, Two, Three, Four };
class CDamageVulnerability { class CDamageVulnerability {
EVulnerability x0_power; std::array<EVulnerability, 15> x0_normal;
EVulnerability x4_ice; std::array<EVulnerability, 4> x3c_charged;
EVulnerability x8_wave; std::array<EVulnerability, 4> x4c_combo;
EVulnerability xc_plasma;
EVulnerability x10_bomb;
EVulnerability x14_powerbomb;
EVulnerability x18_missile;
EVulnerability x1c_boostBall;
EVulnerability x20_phazon;
EVulnerability x24_enemyWp1;
EVulnerability x28_enemyWp2Poison;
EVulnerability x2c_enemyWp3Lava;
EVulnerability x30_enemyWp4;
EVulnerability x34_unk1;
EVulnerability x38_unk2;
EVulnerability x3c_chargedPower;
EVulnerability x40_chargedIce;
EVulnerability x44_chargedWave;
EVulnerability x48_chargedPlasma;
EVulnerability x4c_superMissile;
EVulnerability x50_iceSpreader;
EVulnerability x54_wavebuster;
EVulnerability x58_flamethrower;
EDeflectType x5c_deflected; EDeflectType x5c_deflected;
EDeflectType x60_chargedDeflected{}; EDeflectType x60_chargedDeflected{};
EDeflectType x64_comboDeflected{}; EDeflectType x64_comboDeflected{};
@ -54,29 +31,10 @@ public:
EVulnerability boostBall, EVulnerability phazon, EVulnerability enemyWp1, EVulnerability boostBall, EVulnerability phazon, EVulnerability enemyWp1,
EVulnerability enemyWp2, EVulnerability enemyWp3, EVulnerability enemyWp4, EVulnerability enemyWp2, EVulnerability enemyWp3, EVulnerability enemyWp4,
EVulnerability v1, EVulnerability v2, EDeflectType deflectType) EVulnerability v1, EVulnerability v2, EDeflectType deflectType)
: x0_power(power) : x0_normal({power, ice, wave, plasma, powerBomb, missile, boostBall, phazon, enemyWp1, enemyWp2, enemyWp3, enemyWp4,
, x4_ice(ice) v1, v2})
, x8_wave(wave) , x3c_charged({x0_normal[0], x0_normal[1], x0_normal[2], x0_normal[3]})
, xc_plasma(plasma) , x4c_combo({x0_normal[0], x0_normal[1], x0_normal[2], x0_normal[3]})
, x10_bomb(bomb)
, x14_powerbomb(powerBomb)
, x18_missile(missile)
, x1c_boostBall(boostBall)
, x20_phazon(phazon)
, x24_enemyWp1(enemyWp1)
, x28_enemyWp2Poison(enemyWp2)
, x2c_enemyWp3Lava(enemyWp3)
, x30_enemyWp4(enemyWp4)
, x34_unk1(v1)
, x38_unk2(v2)
, x3c_chargedPower(x0_power)
, x40_chargedIce(x4_ice)
, x44_chargedWave(x8_wave)
, x48_chargedPlasma(xc_plasma)
, x4c_superMissile(x0_power)
, x50_iceSpreader(x4_ice)
, x54_wavebuster(x8_wave)
, x58_flamethrower(xc_plasma)
, x5c_deflected(deflectType) {} , x5c_deflected(deflectType) {}
constexpr CDamageVulnerability(EVulnerability power, EVulnerability ice, EVulnerability wave, EVulnerability plasma, constexpr CDamageVulnerability(EVulnerability power, EVulnerability ice, EVulnerability wave, EVulnerability plasma,
@ -87,29 +45,10 @@ public:
EVulnerability chargedIce, EVulnerability chargedWave, EVulnerability chargedPlasma, EVulnerability chargedIce, EVulnerability chargedWave, EVulnerability chargedPlasma,
EVulnerability superMissile, EVulnerability iceSpreader, EVulnerability waveBuster, EVulnerability superMissile, EVulnerability iceSpreader, EVulnerability waveBuster,
EVulnerability flameThrower, EDeflectType deflected) EVulnerability flameThrower, EDeflectType deflected)
: x0_power(power) : x0_normal({power, ice, wave, plasma, powerBomb, missile, boostBall, phazon, enemyWp1, enemyWp2, enemyWp3, enemyWp4,
, x4_ice(ice) v1, v2})
, x8_wave(wave) , x3c_charged({chargedPower, chargedIce, chargedWave, chargedPlasma})
, xc_plasma(plasma) , x4c_combo({superMissile, iceSpreader, waveBuster, flameThrower})
, x10_bomb(bomb)
, x14_powerbomb(powerBomb)
, x18_missile(missile)
, x1c_boostBall(boostBall)
, x20_phazon(phazon)
, x24_enemyWp1(enemyWp1)
, x28_enemyWp2Poison(enemyWp2)
, x2c_enemyWp3Lava(enemyWp3)
, x30_enemyWp4(enemyWp4)
, x34_unk1(v1)
, x38_unk2(v2)
, x3c_chargedPower(chargedPower)
, x40_chargedIce(chargedIce)
, x44_chargedWave(chargedWave)
, x48_chargedPlasma(chargedPlasma)
, x4c_superMissile(superMissile)
, x50_iceSpreader(iceSpreader)
, x54_wavebuster(waveBuster)
, x58_flamethrower(flameThrower)
, x5c_deflected(deflected) {} , x5c_deflected(deflected) {}
EDeflectType GetDeflectionType(const CWeaponMode& mode) const; EDeflectType GetDeflectionType(const CWeaponMode& mode) const;