mirror of https://github.com/AxioDL/metaforce.git
276 lines
10 KiB
C++
276 lines
10 KiB
C++
#include "World/CDamageVulnerability.hpp"
|
|
|
|
namespace urde
|
|
{
|
|
|
|
const CDamageVulnerability CDamageVulnerability::sNormalVulnerability(
|
|
EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal,
|
|
EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal,
|
|
EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal,
|
|
EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal,
|
|
EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal,
|
|
EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal, EVulnerability::DoubleDamage);
|
|
|
|
const CDamageVulnerability CDamageVulnerability::sImmuneVulnerability(
|
|
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect,
|
|
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect,
|
|
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect,
|
|
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect,
|
|
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect,
|
|
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::DoubleDamage);
|
|
/* LOL, thanks retro */
|
|
const CDamageVulnerability CDamageVulnerability::sReflectVulnerability(
|
|
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect,
|
|
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect,
|
|
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect,
|
|
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect,
|
|
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect,
|
|
EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::Reflect, EVulnerability::DoubleDamage);
|
|
|
|
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, EVulnerability::PassThrough,
|
|
EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough,
|
|
EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough,
|
|
EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::DoubleDamage);
|
|
static inline bool is_normal_or_weak(EVulnerability vuln)
|
|
{
|
|
return (vuln == EVulnerability::DoubleDamage || vuln == EVulnerability::Normal);
|
|
}
|
|
|
|
static inline bool is_not_immune(EVulnerability vuln)
|
|
{
|
|
return vuln != EVulnerability::Immune && vuln != EVulnerability::DirectImmune;
|
|
}
|
|
|
|
void CDamageVulnerability::ConstructNew(CInputStream& in, int propCount)
|
|
{
|
|
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 = propCount; i < 15; ++i)
|
|
vulns[i] = EVulnerability::Reflect;
|
|
}
|
|
|
|
for (int i = 15; i < propCount; ++i)
|
|
in.readUint32Big();
|
|
|
|
x5c_ = EVulnerability(in.readUint32Big());
|
|
EVulnerability* vulns2 = &x3c_chargedPower;
|
|
in.readUint32Big();
|
|
for (int i = 0; i < 4; ++i)
|
|
vulns2[i] = EVulnerability(in.readUint32Big());
|
|
|
|
x60_chargedPhazon = EVulnerability(in.readUint32Big());
|
|
EVulnerability* vulns3 = &x4c_superMissile;
|
|
in.readUint32Big();
|
|
for (int i = 0; i < 4; ++i)
|
|
vulns3[i] = EVulnerability(in.readUint32Big());
|
|
|
|
x64_phazonCombo = EVulnerability(in.readUint32Big());
|
|
}
|
|
|
|
CDamageVulnerability::CDamageVulnerability(CInputStream& in)
|
|
{
|
|
u32 propCount = in.readUint32Big();
|
|
if (propCount == 11)
|
|
{
|
|
EVulnerability* vulns = &x0_power;
|
|
for (int i = 0; i < 15; ++i)
|
|
vulns[i] = EVulnerability(in.readUint32Big());
|
|
|
|
if (propCount == 15)
|
|
x5c_ = EVulnerability::DoubleDamage;
|
|
else
|
|
x5c_ = EVulnerability(in.readUint32Big());
|
|
|
|
x3c_chargedPower = x0_power;
|
|
x4c_superMissile = x0_power;
|
|
x40_chargedIce = x4_ice;
|
|
x50_iceSpreader = x4_ice;
|
|
x44_chargedWave = x8_wave;
|
|
x54_wavebuster = x8_wave;
|
|
x48_chargedPlasma = xc_plasma;
|
|
x58_flamethrower = xc_plasma;
|
|
}
|
|
else
|
|
ConstructNew(in, propCount);
|
|
}
|
|
|
|
CDamageVulnerability::CDamageVulnerability(EVulnerability power, EVulnerability ice, EVulnerability wave,
|
|
EVulnerability plasma, EVulnerability bomb, EVulnerability powerBomb,
|
|
EVulnerability missile, EVulnerability boostBall, EVulnerability phazon,
|
|
EVulnerability enemyWp1, EVulnerability enemyWp2, EVulnerability enemyWp3,
|
|
EVulnerability enemyWp4, EVulnerability v1, EVulnerability v2,
|
|
EVulnerability chargedPower, EVulnerability chargedIce,
|
|
EVulnerability chargedWave, EVulnerability chargedPlasma,
|
|
EVulnerability superMissile, EVulnerability iceSpreader,
|
|
EVulnerability waveBuster, EVulnerability flameThrower, EVulnerability v3)
|
|
: x0_power(power)
|
|
, x4_ice(ice)
|
|
, x8_wave(wave)
|
|
, xc_plasma(plasma)
|
|
, 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_(v3)
|
|
{
|
|
}
|
|
|
|
EVulnerability CDamageVulnerability::GetPhazonVulnerability(const CWeaponMode& mode) const
|
|
{
|
|
if (mode.IsCharged())
|
|
return x60_chargedPhazon;
|
|
if (mode.IsComboed())
|
|
return x64_phazonCombo;
|
|
return x5c_;
|
|
}
|
|
|
|
bool CDamageVulnerability::WeaponHurts(const CWeaponMode& mode, bool ignoreDirect) const
|
|
{
|
|
if (mode.GetType() == EWeaponType::None || mode.GetType() > EWeaponType::Unused2)
|
|
return false;
|
|
if (mode.IsInstantKill())
|
|
return true;
|
|
|
|
EVulnerability normalVuln = (&x0_power)[u32(mode.GetType())];
|
|
bool normalHurts = true;
|
|
if (ignoreDirect)
|
|
normalHurts = is_not_immune(normalVuln);
|
|
else
|
|
{
|
|
if (!is_not_immune(normalVuln) &&
|
|
(normalVuln != EVulnerability::DirectDouble && normalVuln != EVulnerability::DirectNormal))
|
|
normalHurts = false;
|
|
}
|
|
|
|
bool chargedHurts = true;
|
|
bool comboedHurts = true;
|
|
if (mode.GetType() < EWeaponType::Bomb)
|
|
{
|
|
EVulnerability chargedVuln = (&x3c_chargedPower)[u32(mode.GetType())];
|
|
EVulnerability comboedVuln = (&x4c_superMissile)[u32(mode.GetType())];
|
|
if (ignoreDirect)
|
|
{
|
|
chargedHurts = is_not_immune(chargedVuln);
|
|
comboedHurts = is_not_immune(comboedVuln);
|
|
}
|
|
else
|
|
{
|
|
if (!is_not_immune(chargedVuln) &&
|
|
(chargedVuln != EVulnerability::DirectDouble && chargedVuln != EVulnerability::DirectNormal))
|
|
chargedHurts = false;
|
|
if (!is_not_immune(comboedVuln) &&
|
|
(comboedVuln != EVulnerability::DirectDouble && comboedVuln != EVulnerability::DirectNormal))
|
|
comboedHurts = false;
|
|
}
|
|
}
|
|
|
|
if (normalHurts && !mode.IsCharged() && !mode.IsComboed())
|
|
return true;
|
|
if (chargedHurts && mode.IsCharged())
|
|
return true;
|
|
if (comboedHurts && mode.IsComboed())
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
bool CDamageVulnerability::WeaponHits(const CWeaponMode& mode, bool checkDirect) const
|
|
{
|
|
if (mode.GetType() == EWeaponType::None || mode.GetType() > EWeaponType::Unused2)
|
|
return false;
|
|
if (mode.IsInstantKill())
|
|
return true;
|
|
|
|
bool normalVuln;
|
|
if (!checkDirect)
|
|
normalVuln = (&x0_power)[u32(mode.GetType())] != EVulnerability::Immune;
|
|
else
|
|
normalVuln = is_not_immune((&x0_power)[u32(mode.GetType())]);
|
|
|
|
bool chargedVuln = true;
|
|
bool comboedVuln = true;
|
|
|
|
if (mode.GetType() < EWeaponType::Bomb)
|
|
{
|
|
if (!checkDirect)
|
|
{
|
|
chargedVuln = (&x3c_chargedPower)[u32(mode.GetType())] != EVulnerability::Immune;
|
|
comboedVuln = (&x4c_superMissile)[u32(mode.GetType())] != EVulnerability::Immune;
|
|
}
|
|
else
|
|
{
|
|
chargedVuln = is_not_immune((&x3c_chargedPower)[u32(mode.GetType())]);
|
|
comboedVuln = is_not_immune((&x4c_superMissile)[u32(mode.GetType())]);
|
|
}
|
|
}
|
|
|
|
if (normalVuln && !mode.IsCharged() && !mode.IsComboed())
|
|
return true;
|
|
if (chargedVuln && mode.IsCharged())
|
|
return true;
|
|
if (comboedVuln && mode.IsComboed())
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
EVulnerability CDamageVulnerability::GetVulnerability(const CWeaponMode& mode, bool ignoreDirect) const
|
|
{
|
|
if (mode.GetType() == EWeaponType::None || mode.GetType() > EWeaponType::Unused2)
|
|
return EVulnerability::Reflect;
|
|
|
|
if (mode.IsInstantKill())
|
|
return EVulnerability::Normal;
|
|
|
|
EVulnerability vuln = (&x0_power)[u32(mode.GetType())];
|
|
if (mode.IsCharged())
|
|
{
|
|
if (mode.GetType() < EWeaponType::Bomb)
|
|
vuln = (&x3c_chargedPower)[u32(mode.GetType())];
|
|
else
|
|
vuln = EVulnerability::Normal;
|
|
}
|
|
|
|
if (mode.IsComboed())
|
|
{
|
|
if (mode.GetType() < EWeaponType::Bomb)
|
|
vuln = (&x3c_chargedPower)[u32(mode.GetType())];
|
|
else
|
|
vuln = EVulnerability::Normal;
|
|
}
|
|
|
|
if (ignoreDirect)
|
|
return vuln;
|
|
|
|
if (vuln == EVulnerability::DirectDouble)
|
|
return EVulnerability::DoubleDamage;
|
|
else if (vuln == EVulnerability::DirectNormal)
|
|
return EVulnerability::Normal;
|
|
else if (vuln == EVulnerability::DirectImmune)
|
|
return EVulnerability::Immune;
|
|
|
|
return vuln;
|
|
}
|
|
}
|