2019-12-22 20:04:07 +00:00
|
|
|
#include "Runtime/World/CDamageVulnerability.hpp"
|
2017-02-10 05:43:07 +00:00
|
|
|
|
2021-04-10 08:42:06 +00:00
|
|
|
namespace metaforce {
|
2017-02-10 05:43:07 +00:00
|
|
|
|
2020-05-27 17:02:20 +00:00
|
|
|
const CDamageVulnerability CDamageVulnerability::sNormalVulnerability(
|
2017-03-01 03:42:06 +00:00
|
|
|
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,
|
2019-07-16 15:54:07 +00:00
|
|
|
EVulnerability::Normal, EVulnerability::Normal, EVulnerability::Normal, EDeflectType::None);
|
2017-03-01 03:42:06 +00:00
|
|
|
|
2020-05-27 17:02:20 +00:00
|
|
|
const CDamageVulnerability CDamageVulnerability::sImmuneVulnerability(
|
2018-02-12 05:30:21 +00:00
|
|
|
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,
|
2019-07-16 15:54:07 +00:00
|
|
|
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EDeflectType::None);
|
2020-03-26 07:30:54 +00:00
|
|
|
|
2020-05-27 17:02:20 +00:00
|
|
|
const CDamageVulnerability CDamageVulnerability::sReflectVulnerability(
|
2018-02-12 05:30:21 +00:00
|
|
|
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,
|
2020-03-26 07:30:54 +00:00
|
|
|
EVulnerability::Deflect, EVulnerability::Deflect, EVulnerability::Deflect, EDeflectType::One);
|
2017-03-01 03:42:06 +00:00
|
|
|
|
2020-05-27 17:02:20 +00:00
|
|
|
const CDamageVulnerability CDamageVulnerability::sPassThroughVulnerability(
|
2017-03-01 03:42:06 +00:00
|
|
|
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,
|
2019-07-16 15:54:07 +00:00
|
|
|
EVulnerability::PassThrough, EVulnerability::PassThrough, EVulnerability::PassThrough, EDeflectType::None);
|
2017-02-10 05:43:07 +00:00
|
|
|
|
2021-05-09 03:14:38 +00:00
|
|
|
static constexpr bool is_deflect_direct(EVulnerability vuln) {
|
2022-03-31 06:40:11 +00:00
|
|
|
return vuln == EVulnerability::Deflect ||
|
|
|
|
(EVulnerability(u32(vuln) - u32(EVulnerability::DirectWeak)) < EVulnerability::Deflect) ||
|
|
|
|
vuln == EVulnerability::DirectImmune;
|
2017-02-10 05:43:07 +00:00
|
|
|
}
|
|
|
|
|
2020-04-26 04:53:50 +00:00
|
|
|
static constexpr bool is_normal_or_weak(EVulnerability vuln) {
|
2021-05-09 03:14:38 +00:00
|
|
|
return vuln == EVulnerability::Weak || vuln == EVulnerability::Normal;
|
|
|
|
}
|
2021-06-07 19:29:18 +00:00
|
|
|
static constexpr bool is_not_deflect(EVulnerability vuln) { return vuln != EVulnerability::Deflect; }
|
2018-11-19 01:19:44 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
void CDamageVulnerability::ConstructNew(CInputStream& in, int propCount) {
|
|
|
|
propCount -= 3;
|
2021-05-09 03:14:38 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < std::min(propCount, 15); ++i) {
|
2022-02-18 07:37:54 +00:00
|
|
|
x0_normal[i] = EVulnerability(in.ReadLong());
|
2021-05-09 03:14:38 +00:00
|
|
|
}
|
2017-02-10 05:43:07 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
if (propCount < 15) {
|
2021-05-09 03:14:38 +00:00
|
|
|
for (int i = propCount; i < 15; ++i) {
|
|
|
|
x0_normal[i] = EVulnerability::Deflect;
|
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
}
|
2017-02-10 05:43:07 +00:00
|
|
|
|
2021-05-09 03:14:38 +00:00
|
|
|
for (int i = 15; i < propCount; ++i) {
|
2022-02-18 07:37:54 +00:00
|
|
|
in.ReadLong();
|
2021-05-09 03:14:38 +00:00
|
|
|
}
|
2017-02-10 05:43:07 +00:00
|
|
|
|
2022-02-18 07:37:54 +00:00
|
|
|
x5c_deflected = EDeflectType(in.ReadLong());
|
|
|
|
in.ReadLong();
|
2021-05-09 03:14:38 +00:00
|
|
|
for (int i = 0; i < 4; ++i) {
|
2022-02-18 07:37:54 +00:00
|
|
|
x3c_charged[i] = EVulnerability(in.ReadLong());
|
2021-05-09 03:14:38 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
|
2022-02-18 07:37:54 +00:00
|
|
|
x60_chargedDeflected = EDeflectType(in.ReadLong());
|
|
|
|
in.ReadLong();
|
2021-05-09 03:14:38 +00:00
|
|
|
for (int i = 0; i < 4; ++i) {
|
2022-02-18 07:37:54 +00:00
|
|
|
x4c_combo[i] = EVulnerability(in.ReadLong());
|
2021-05-09 03:14:38 +00:00
|
|
|
}
|
2017-02-10 05:43:07 +00:00
|
|
|
|
2022-02-18 07:37:54 +00:00
|
|
|
x64_comboDeflected = EDeflectType(in.ReadLong());
|
2017-02-10 05:43:07 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
CDamageVulnerability::CDamageVulnerability(CInputStream& in) {
|
2022-02-18 07:37:54 +00:00
|
|
|
u32 propCount = in.ReadLong();
|
2018-12-08 05:30:43 +00:00
|
|
|
if (propCount == 11) {
|
2021-05-09 03:14:38 +00:00
|
|
|
for (int i = 0; i < 15; ++i) {
|
2022-02-18 07:37:54 +00:00
|
|
|
x0_normal[i] = EVulnerability(in.ReadLong());
|
2021-05-09 03:14:38 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
|
2022-02-18 07:37:54 +00:00
|
|
|
x5c_deflected = EDeflectType(in.ReadLong());
|
2021-05-09 03:14:38 +00:00
|
|
|
x3c_charged[0] = x0_normal[0];
|
|
|
|
x4c_combo[0] = x0_normal[0];
|
|
|
|
x3c_charged[1] = x0_normal[1];
|
|
|
|
x4c_combo[1] = x0_normal[1];
|
|
|
|
x3c_charged[2] = x0_normal[2];
|
|
|
|
x4c_combo[2] = x0_normal[2];
|
|
|
|
x3c_charged[3] = x0_normal[3];
|
|
|
|
x4c_combo[3] = x0_normal[3];
|
|
|
|
} else {
|
2018-12-08 05:30:43 +00:00
|
|
|
ConstructNew(in, propCount);
|
2021-05-09 03:14:38 +00:00
|
|
|
}
|
2017-02-10 05:43:07 +00:00
|
|
|
}
|
|
|
|
|
2019-07-16 15:54:07 +00:00
|
|
|
EDeflectType CDamageVulnerability::GetDeflectionType(const CWeaponMode& mode) const {
|
2021-05-09 03:14:38 +00:00
|
|
|
if (mode.IsCharged()) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return x60_chargedDeflected;
|
2021-05-09 03:14:38 +00:00
|
|
|
}
|
|
|
|
if (mode.IsComboed()) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return x64_comboDeflected;
|
2021-05-09 03:14:38 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
return x5c_deflected;
|
2017-03-01 03:42:06 +00:00
|
|
|
}
|
|
|
|
|
2022-04-03 19:18:36 +00:00
|
|
|
static inline bool check_hurts(EVulnerability vuln, bool direct) {
|
|
|
|
return direct == 0
|
|
|
|
? (is_normal_or_weak(vuln) || vuln == EVulnerability::DirectWeak || vuln == EVulnerability::DirectNormal)
|
|
|
|
: is_normal_or_weak(vuln);
|
|
|
|
}
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
bool CDamageVulnerability::WeaponHurts(const CWeaponMode& mode, bool ignoreDirect) const {
|
2022-04-03 19:18:36 +00:00
|
|
|
if (mode.GetType() < EWeaponType::Power || mode.GetType() > EWeaponType::OrangePhazon) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return false;
|
2021-05-09 03:14:38 +00:00
|
|
|
}
|
2022-04-01 05:28:13 +00:00
|
|
|
|
2021-05-09 03:14:38 +00:00
|
|
|
if (mode.IsInstantKill()) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return true;
|
2021-05-09 03:14:38 +00:00
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
|
2022-04-03 19:18:36 +00:00
|
|
|
bool normalHurts = check_hurts(x0_normal[u32(mode.GetType())], ignoreDirect);
|
|
|
|
bool chargedHurts =
|
|
|
|
(mode.GetType() < EWeaponType::Bomb) ? check_hurts(x3c_charged[u32(mode.GetType())], ignoreDirect) : true;
|
|
|
|
bool comboedHurts =
|
|
|
|
(mode.GetType() < EWeaponType::Bomb) ? check_hurts(x4c_combo[u32(mode.GetType())], ignoreDirect) : true;
|
2022-04-01 05:28:13 +00:00
|
|
|
|
2022-04-03 19:18:36 +00:00
|
|
|
return (normalHurts && !mode.IsCharged() && !mode.IsComboed()) || (chargedHurts && mode.IsCharged()) ||
|
|
|
|
(comboedHurts && mode.IsComboed());
|
|
|
|
}
|
2018-12-08 05:30:43 +00:00
|
|
|
|
2022-04-03 19:18:36 +00:00
|
|
|
static inline bool check_hits(EVulnerability vuln, bool direct) {
|
|
|
|
if (!direct) {
|
|
|
|
return is_not_deflect(vuln);
|
2021-05-09 03:14:38 +00:00
|
|
|
}
|
2022-04-03 19:18:36 +00:00
|
|
|
if (vuln == EVulnerability::Deflect ||
|
|
|
|
(static_cast<EVulnerability>(static_cast<u32>(vuln) - static_cast<u32>(EVulnerability::DirectWeak)) <=
|
|
|
|
EVulnerability::Normal) ||
|
|
|
|
vuln == EVulnerability::DirectImmune) {
|
|
|
|
return false;
|
2018-12-08 05:30:43 +00:00
|
|
|
}
|
2022-04-03 19:18:36 +00:00
|
|
|
return true;
|
2017-02-10 05:43:07 +00:00
|
|
|
}
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
bool CDamageVulnerability::WeaponHits(const CWeaponMode& mode, bool checkDirect) const {
|
2022-04-03 19:18:36 +00:00
|
|
|
if (mode.GetType() < EWeaponType::Power || mode.GetType() > EWeaponType::OrangePhazon) {
|
2017-02-10 05:43:07 +00:00
|
|
|
return false;
|
2020-05-17 16:25:04 +00:00
|
|
|
}
|
|
|
|
if (mode.IsInstantKill()) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return true;
|
2020-05-17 16:25:04 +00:00
|
|
|
}
|
2022-04-01 05:28:13 +00:00
|
|
|
|
2022-04-03 19:18:36 +00:00
|
|
|
bool normalHits = check_hits(x0_normal[u32(mode.GetType())], checkDirect);
|
|
|
|
bool chargedHits =
|
|
|
|
mode.GetType() < EWeaponType::Bomb ? check_hits(x3c_charged[u32(mode.GetType())], checkDirect) : true;
|
|
|
|
bool comboedHits =
|
|
|
|
mode.GetType() < EWeaponType::Bomb ? check_hits(x4c_combo[u32(mode.GetType())], checkDirect) : true;
|
2022-04-01 05:28:13 +00:00
|
|
|
bool result = false;
|
|
|
|
if ((normalHits && !mode.IsCharged() && !mode.IsComboed()) || (chargedHits && mode.IsCharged()) ||
|
|
|
|
(comboedHits && mode.IsComboed())) {
|
|
|
|
result = true;
|
2020-05-17 16:25:04 +00:00
|
|
|
}
|
2021-05-09 03:14:38 +00:00
|
|
|
|
2022-04-03 19:18:36 +00:00
|
|
|
return (normalHits && !mode.IsCharged() && !mode.IsComboed()) || (chargedHits && mode.IsCharged()) ||
|
|
|
|
(comboedHits && mode.IsComboed());
|
2017-02-10 05:43:07 +00:00
|
|
|
}
|
|
|
|
|
2022-04-01 05:37:23 +00:00
|
|
|
inline EVulnerability direct_to_normal(EVulnerability vuln) {
|
|
|
|
if (vuln == EVulnerability::DirectWeak) {
|
|
|
|
return EVulnerability::Weak;
|
|
|
|
}
|
|
|
|
if (vuln == EVulnerability::DirectNormal) {
|
|
|
|
return EVulnerability::Normal;
|
|
|
|
}
|
|
|
|
if (vuln == EVulnerability::DirectImmune) {
|
|
|
|
return EVulnerability::Immune;
|
|
|
|
}
|
|
|
|
return vuln;
|
|
|
|
}
|
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
EVulnerability CDamageVulnerability::GetVulnerability(const CWeaponMode& mode, bool ignoreDirect) const {
|
2022-04-01 05:37:23 +00:00
|
|
|
if (mode.GetType() < EWeaponType::Power || mode.GetType() > EWeaponType::OrangePhazon) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return EVulnerability::Deflect;
|
2020-04-16 05:26:14 +00:00
|
|
|
}
|
2022-04-03 19:18:36 +00:00
|
|
|
|
2020-04-16 05:26:14 +00:00
|
|
|
if (mode.IsInstantKill()) {
|
2018-12-08 05:30:43 +00:00
|
|
|
return EVulnerability::Normal;
|
2020-04-16 05:26:14 +00:00
|
|
|
}
|
2017-02-10 05:43:07 +00:00
|
|
|
|
2022-04-01 05:37:23 +00:00
|
|
|
EVulnerability vuln = x0_normal[u32(mode.GetType())];
|
|
|
|
EWeaponType type = mode.GetType();
|
2018-12-08 05:30:43 +00:00
|
|
|
if (mode.IsCharged()) {
|
2022-04-01 05:37:23 +00:00
|
|
|
vuln = type < EWeaponType::Bomb ? x3c_charged[u32(type)] : EVulnerability::Normal;
|
2018-12-08 05:30:43 +00:00
|
|
|
}
|
2017-02-10 05:43:07 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
if (mode.IsComboed()) {
|
2022-04-01 05:37:23 +00:00
|
|
|
vuln = type < EWeaponType::Bomb ? x4c_combo[u32(type)] : EVulnerability::Normal;
|
2018-12-08 05:30:43 +00:00
|
|
|
}
|
2022-04-01 05:37:23 +00:00
|
|
|
if (ignoreDirect == 1) {
|
2017-02-10 05:43:07 +00:00
|
|
|
return vuln;
|
2020-04-16 05:26:14 +00:00
|
|
|
}
|
2022-04-01 05:37:23 +00:00
|
|
|
return direct_to_normal(vuln);
|
2017-02-10 05:43:07 +00:00
|
|
|
}
|
2021-04-10 08:42:06 +00:00
|
|
|
} // namespace metaforce
|