-
-
Notifications
You must be signed in to change notification settings - Fork 103
[MultiWeapon] Use WeaponX #1630
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from all commits
b39fac3
08718f8
685a81d
ee96284
6aaceab
1644f42
b0d1c9d
e8bee47
a6b1c21
0ec4836
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
#include "Body.h" | ||
|
||
#include <InfantryClass.h> | ||
#include <HouseClass.h> | ||
#include <OverlayTypeClass.h> | ||
#include <TerrainClass.h> | ||
|
||
#include <Ext/BulletType/Body.h> | ||
#include <Ext/WeaponType/Body.h> | ||
#include <Utilities/GeneralUtils.h> | ||
#include <Utilities/EnumFunctions.h> | ||
|
||
bool TechnoExt::IsSecondary(TechnoClass* const pThis, const int& nWeaponIndex) | ||
{ | ||
if (!pThis) | ||
return false; | ||
|
||
if (pThis->GetTechnoType()->IsGattling) | ||
return nWeaponIndex != 0 && nWeaponIndex % 2 != 0; | ||
|
||
const auto pTypeExt = TechnoTypeExt::ExtMap.Find(pThis->GetTechnoType()); | ||
|
||
if (pTypeExt && pTypeExt->MultiWeapon.Get() && | ||
!pTypeExt->MultiWeapon_IsSecondary.empty()) | ||
{ | ||
int index = nWeaponIndex + 1; | ||
return pTypeExt->MultiWeapon_IsSecondary.Contains(index); | ||
} | ||
|
||
return nWeaponIndex != 0; | ||
} | ||
|
||
// maybe it could be used as a new SelectWeapon, but not for now. | ||
bool TechnoExt::CheckMultiWeapon(TechnoClass* const pThis, AbstractClass* const pTarget, WeaponTypeClass* const pWeaponType) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It seems that this function is not being used yet? |
||
{ | ||
if (!pThis || !pWeaponType || pWeaponType->NeverUse || | ||
!pWeaponType->Projectile || !pWeaponType->Warhead || | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no need to check if Projectile or Warhead exist since they'll still crash elsewhere |
||
(pThis->InOpenToppedTransport && !pWeaponType->FireInTransport)) | ||
return false; | ||
|
||
const auto pWH = pWeaponType->Warhead; | ||
|
||
if (TechnoClass* pTargetTechno = abstract_cast<TechnoClass*>(pTarget)) | ||
{ | ||
if (pTargetTechno->Health <= 0 || !pTargetTechno->IsAlive) | ||
return false; | ||
|
||
if (const auto pTargetExt = TechnoExt::ExtMap.Find(pTargetTechno)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same, no need to do sanity check for pTargetExt |
||
{ | ||
const auto pShield = pTargetExt->Shield.get(); | ||
|
||
if (pShield && pShield->IsActive() && | ||
!pShield->CanBeTargeted(pWeaponType)) | ||
return false; | ||
} | ||
|
||
if (GeneralUtils::GetWarheadVersusArmor(pWH, pTargetTechno->GetTechnoType()->Armor) == 0.0) | ||
return false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is wrong when having a shield with a different armor that could be targeted. Should check it separately if (pShield || pShield->IsActive())
{ // shield checking }
else if (GeneralUtils::GetWarheadVersusArmor(pWH, pTargetTechno->GetTechnoType()->Armor) == 0.0)
{ return false; } |
||
|
||
if (pTargetTechno->IsInAir()) | ||
{ | ||
if (!pWeaponType->Projectile->AA) | ||
return false; | ||
} | ||
else | ||
{ | ||
const auto pBulletTypeExt = BulletTypeExt::ExtMap.Find(pWeaponType->Projectile); | ||
|
||
if (!pBulletTypeExt->AAOnly.Get()) | ||
return false; | ||
} | ||
|
||
if (pWH->IsLocomotor && pTarget->WhatAmI() == AbstractType::Building) | ||
return false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. put AA check and Locomotor check prior to armor check so there'll be more cases to bail out earlier with less calculation. Also Locomotor check can be put within ground target check since building can never fly |
||
|
||
if (pWH->ElectricAssault) | ||
{ | ||
if (!pThis->Owner->IsAlliedWith(pTargetTechno->Owner)) | ||
return false; | ||
|
||
if (pTargetTechno->WhatAmI() != AbstractType::Building) | ||
return false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no need to check here since there's already a pBld check below |
||
|
||
const auto pBld = abstract_cast<BuildingClass*>(pTargetTechno); | ||
|
||
if (!pBld || !pBld->Type || !pBld->Type->Overpowerable) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no need to check if pBld->Type exists |
||
return false; | ||
} | ||
|
||
if (pWeaponType->DrainWeapon && (pTargetTechno->DrainingMe || | ||
!pTargetTechno->GetTechnoType()->Drainable)) | ||
return false; | ||
|
||
if (pTargetTechno->AttachedBomb) | ||
{ | ||
if (pWH->IvanBomb) | ||
return false; | ||
|
||
if (pWH->BombDisarm && | ||
!pThis->Owner->IsControlledByHuman() && | ||
!pThis->Owner->IsAlliedWith(pTargetTechno->Owner)) | ||
return false; | ||
} | ||
else | ||
{ | ||
if (pWH->BombDisarm) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. else if (pWH->BombDisarm) |
||
return false; | ||
} | ||
|
||
if (pWH->Airstrike && pTargetTechno->IsInAir()) | ||
return false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same, could be put to above ground unit code block |
||
|
||
if (pWH->MindControl && (pTargetTechno->Owner == pThis->Owner || | ||
pTargetTechno->IsMindControlled() || pTargetTechno->GetTechnoType()->ImmuneToPsionics)) | ||
return false; | ||
|
||
if (pWH->Parasite && (pTargetTechno->WhatAmI() == AbstractType::Building || | ||
abstract_cast<FootClass*>(pTargetTechno)->ParasiteEatingMe)) | ||
return false; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. actually, maybe armor versus check can be put to here to save as many as calculations |
||
const auto pWeaponExt = WeaponTypeExt::ExtMap.Find(pWeaponType); | ||
|
||
if (pWeaponExt && !pWeaponExt->HasRequiredAttachedEffects(pTargetTechno, pThis)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no need to do sanity check for pWeaponExt, but CanTarget/CanTargetHouse should be checked |
||
return false; | ||
} | ||
else | ||
{ | ||
if (pWH->ElectricAssault || pWH->BombDisarm || pWH->Airstrike || pWeaponType->DrainWeapon) | ||
return false; | ||
|
||
if (pTarget->WhatAmI() == AbstractType::Terrain) | ||
{ | ||
if (!pWH->Wood) | ||
return false; | ||
} | ||
else if (pTarget->WhatAmI() == AbstractType::Cell) | ||
{ | ||
const auto pCell = abstract_cast<CellClass*>(pTarget); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. else if (const auto pCell = abstract_cast<CellClass*>(pTarget)) |
||
|
||
if (pCell && pCell->OverlayTypeIndex >= 0) | ||
{ | ||
auto overlayType = OverlayTypeClass::Array.GetItem(pCell->OverlayTypeIndex); | ||
|
||
if (overlayType->Wall && !pWH->Wall) | ||
return false; | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should check CanTarget |
||
} | ||
} | ||
|
||
return true; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
#include "Body.h" | ||
|
||
// There was no way to do it, so I decided to leave it at that. | ||
/* | ||
bool _fastcall CanElectricAssault(FootClass* pThis) | ||
{ | ||
const auto pType = pThis->GetTechnoType(); | ||
const auto pTypeExt = TechnoTypeExt::ExtMap.Find(pThis->GetTechnoType()); | ||
bool allowAssault = !pThis->GetTechnoType()->IsGattling && | ||
(pThis->WhatAmI() != AbstractType::Unit || !pThis->GetTechnoType()->Gunner); | ||
|
||
if (pTypeExt->MultiWeapon.Get() && allowAssault) | ||
{ | ||
for (int index = 0; index < pThis->GetTechnoType()->WeaponCount; index++) | ||
{ | ||
const auto pWeaponType = pThis->Veterancy.IsElite() ? | ||
pType->GetEliteWeapon(index)->WeaponType : pType->GetWeapon(index)->WeaponType; | ||
|
||
if (!pWeaponType || !pWeaponType->Warhead || | ||
!pWeaponType->Warhead->ElectricAssault) | ||
continue; | ||
|
||
return true; | ||
} | ||
} | ||
else if (allowAssault) | ||
{ | ||
const auto secondary = pThis->GetWeapon(1)->WeaponType; | ||
|
||
if (secondary && secondary->Warhead && | ||
secondary->Warhead->ElectricAssault) | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
DEFINE_HOOK(0x4D50E1, FootClass_Mission_Guard_ElectricAssult, 0xA) | ||
{ | ||
GET(FootClass*, pThis, ESI); | ||
enum { ElectricAssult = 0x4D5116, Skip = 0x4D51D4, SkipAll = 0x4D52F5 }; | ||
|
||
if (!pThis) | ||
return SkipAll; | ||
|
||
return CanElectricAssault(pThis) ? ElectricAssult : Skip; | ||
} | ||
|
||
DEFINE_HOOK(0x4D6F44, FootClass_Mission_AreaGuard_ElectricAssult, 0x6) | ||
{ | ||
GET(FootClass*, pThis, ESI); | ||
enum { ElectricAssult = 0x4D6F78, Skip = 0x4D7025, SkipAll = 0x4D715A }; | ||
|
||
if (!pThis) | ||
return SkipAll; | ||
|
||
return CanElectricAssault(pThis) ? ElectricAssult : Skip; | ||
} | ||
*/ | ||
|
||
// Do you think the infantry's way of determining that weapons are secondary is stupid ? | ||
// I think it's kind of stupid. | ||
DEFINE_HOOK(0x520888, InfantryClass_UpdateFiring_IsSecondary, 0x8) | ||
{ | ||
GET(InfantryClass*, pThis, EBP); | ||
GET(int, weaponIdx, EDI); | ||
enum { Primary = 0x5208D6, Secondary = 0x520890 }; | ||
|
||
R->AL(pThis->Crawling); | ||
return TechnoExt::IsSecondary(pThis, weaponIdx) ? Secondary : Primary; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,7 +59,7 @@ void TechnoTypeExt::ExtData::ParseBurstFLHs(INI_EX& exArtINI, const char* pArtSe | |
char tempBuffer[32]; | ||
char tempBufferFLH[48]; | ||
auto pThis = this->OwnerObject(); | ||
bool parseMultiWeapons = pThis->TurretCount > 0 && pThis->WeaponCount > 0; | ||
bool parseMultiWeapons = this->MultiWeapon.Get() || (pThis->TurretCount > 0 && pThis->WeaponCount > 0); | ||
auto weaponCount = parseMultiWeapons ? pThis->WeaponCount : 2; | ||
nFLH.resize(weaponCount); | ||
nEFlh.resize(weaponCount); | ||
|
@@ -1016,6 +1016,11 @@ void TechnoTypeExt::ExtData::Serialize(T& Stm) | |
.Process(this->Overload_DeathSound) | ||
.Process(this->Overload_ParticleSys) | ||
.Process(this->Overload_ParticleSysCount) | ||
|
||
.Process(this->MultiWeapon) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. wrong spacing |
||
.Process(this->MultiWeapon_IsSecondary) | ||
//.Process(this->MultiWeapon_SelectWeapon) | ||
.Process(this->LastMultiWeapon) | ||
; | ||
} | ||
void TechnoTypeExt::ExtData::LoadFromStream(PhobosStreamReader& Stm) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no need to do sanity check for pTypeExt