#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::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::DoubleDamage); /* LOL, thanks retro */ const CDamageVulnerability CDamageVulnerability::sReflectVulnerability( EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, 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::Deflect; } for (int i = 15; i < propCount; ++i) in.readUint32Big(); x5c_deflected = EVulnerability(in.readUint32Big()); EVulnerability* vulns2 = &x3c_chargedPower; in.readUint32Big(); for (int i = 0; i < 4; ++i) vulns2[i] = EVulnerability(in.readUint32Big()); x60_chargedDeflected = EVulnerability(in.readUint32Big()); EVulnerability* vulns3 = &x4c_superMissile; in.readUint32Big(); for (int i = 0; i < 4; ++i) vulns3[i] = EVulnerability(in.readUint32Big()); x64_comboDeflected = 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_deflected = EVulnerability::DoubleDamage; else x5c_deflected = 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 deflected) : 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_deflected(deflected) { } EVulnerability CDamageVulnerability::GetDeflectionType(const CWeaponMode& mode) const { if (mode.IsCharged()) return x60_chargedDeflected; if (mode.IsComboed()) return x64_comboDeflected; return x5c_deflected; } bool CDamageVulnerability::WeaponHurts(const CWeaponMode& mode, bool ignoreDirect) const { if (mode.GetType() == EWeaponType::None || mode.GetType() > EWeaponType::OrangePhazon) 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::OrangePhazon) 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::OrangePhazon) return EVulnerability::Deflect; 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; } }