mirror of
				https://github.com/AxioDL/metaforce.git
				synced 2025-10-27 15:30:23 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			277 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			277 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #include "Runtime/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, EDeflectType::None);
 | |
| 
 | |
| 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, EDeflectType::None);
 | |
| 
 | |
| 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, EDeflectType::One);
 | |
| 
 | |
| 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, EDeflectType::None);
 | |
| 
 | |
| static inline bool is_not_immune(EVulnerability vuln) {
 | |
|   return vuln != EVulnerability::Immune && vuln != EVulnerability::DirectImmune;
 | |
| }
 | |
| 
 | |
| static inline bool is_normal_or_weak(EVulnerability vuln) {
 | |
|   return vuln == EVulnerability::Normal || vuln == EVulnerability::Weak;
 | |
| }
 | |
| 
 | |
| 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 = EDeflectType(in.readUint32Big());
 | |
|   EVulnerability* vulns2 = &x3c_chargedPower;
 | |
|   in.readUint32Big();
 | |
|   for (int i = 0; i < 4; ++i)
 | |
|     vulns2[i] = EVulnerability(in.readUint32Big());
 | |
| 
 | |
|   x60_chargedDeflected = EDeflectType(in.readUint32Big());
 | |
|   EVulnerability* vulns3 = &x4c_superMissile;
 | |
|   in.readUint32Big();
 | |
|   for (int i = 0; i < 4; ++i)
 | |
|     vulns3[i] = EVulnerability(in.readUint32Big());
 | |
| 
 | |
|   x64_comboDeflected = EDeflectType(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 = EDeflectType::None;
 | |
|     else
 | |
|       x5c_deflected = EDeflectType(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,
 | |
|                                            EDeflectType deflectType)
 | |
| : 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(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) {}
 | |
| 
 | |
| 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, EDeflectType 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) {}
 | |
| 
 | |
| EDeflectType 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_normal_or_weak(normalVuln);
 | |
|   } else {
 | |
|     if (!is_normal_or_weak(normalVuln) &&
 | |
|         (normalVuln != EVulnerability::DirectWeak && 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_normal_or_weak(chargedVuln);
 | |
|       comboedHurts = is_normal_or_weak(comboedVuln);
 | |
|     } else {
 | |
|       if (!is_normal_or_weak(chargedVuln) &&
 | |
|           (chargedVuln != EVulnerability::DirectWeak && chargedVuln != EVulnerability::DirectNormal))
 | |
|         chargedHurts = false;
 | |
|       if (!is_normal_or_weak(comboedVuln) &&
 | |
|           (comboedVuln != EVulnerability::DirectWeak && comboedVuln != EVulnerability::DirectNormal))
 | |
|         comboedHurts = false;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (normalHurts && !mode.IsCharged() && !mode.IsComboed())
 | |
|     return true;
 | |
|   if (chargedHurts && mode.IsCharged())
 | |
|     return true;
 | |
|   return comboedHurts && mode.IsComboed();
 | |
| }
 | |
| 
 | |
| 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;
 | |
|   return comboedVuln && mode.IsComboed();
 | |
| }
 | |
| 
 | |
| 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::DirectWeak)
 | |
|     return EVulnerability::Weak;
 | |
|   else if (vuln == EVulnerability::DirectNormal)
 | |
|     return EVulnerability::Normal;
 | |
|   else if (vuln == EVulnerability::DirectImmune)
 | |
|     return EVulnerability::Immune;
 | |
| 
 | |
|   return vuln;
 | |
| }
 | |
| } // namespace urde
 |