-
-
Notifications
You must be signed in to change notification settings - Fork 132
DeployFire supports buildings #2104
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 14 commits
d8f03c0
370c73f
2d59ca8
869ff47
296d0b5
1d5dc66
b3d4bee
39dedf3
6b3f1a8
935d435
7c15f55
4592cc3
15f44fe
9d9add0
08f0fd8
f41fe8d
8c8e55f
badaf46
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,121 @@ | ||
| #include "Body.h" | ||
|
|
||
| DEFINE_HOOK(0x447358, BuildingClass_MouseOverObject_DeployFire, 0x6) | ||
| { | ||
| GET(BuildingTypeClass* const, pType, EAX); | ||
|
|
||
| return pType->DeployFire ? 0x4472EC : 0; | ||
| } | ||
|
|
||
| DEFINE_HOOK(0x443459, BuildingClass_ObjectClickedAction_DeployFire, 0x6) | ||
| { | ||
| GET(BuildingClass*, pThis, EBX); | ||
| enum { SkipGameCode = 0x443568, SkipFactory = 0x4434F2 }; | ||
|
|
||
| auto const pType = pThis->Type; | ||
|
|
||
| // Perhaps Factory should not allow the use of DeployFire. | ||
| if (pType->Factory != AbstractType::None) | ||
| { | ||
| if (!pThis->IsPrimaryFactory) | ||
| { | ||
| // Do not enter unloading tasks simultaneously, as this may prevent buildings from producing units in a timely manner. | ||
| pThis->ClickedEvent(EventType::Primary); | ||
| return SkipGameCode; | ||
| } | ||
| } | ||
| else if (pType->DeployFire) | ||
| { | ||
| pThis->ClickedMission(Mission::Unload, pThis, nullptr, nullptr); | ||
| return SkipGameCode; | ||
| } | ||
|
|
||
| return SkipFactory; | ||
| } | ||
|
|
||
| DEFINE_HOOK(0x44E29D, BuildingClass_Mission_Unload_DeployFire, 0x6) | ||
| { | ||
| GET(BuildingClass* const, pThis, EBP); | ||
| GET(BuildingTypeClass* const, pType, EAX); | ||
| enum { SkipGameCode = 0x44E37F, ReturnGuard = 0x44E371, Continue = 0x44E2BE }; | ||
|
|
||
| const int cells = static_cast<int>(pType->SuperGapRadiusInCells); | ||
|
|
||
| if (!pType->GapGenerator || !cells) | ||
| { | ||
| if (pType->DeployFire) | ||
| { | ||
| auto const pCell = pThis->GetCell(); | ||
|
|
||
| if (pThis->Target != pCell) | ||
| pThis->SetTarget(pCell); | ||
|
|
||
| const int deployFireWeapon = pType->DeployFireWeapon; | ||
| const int weaponIndex = deployFireWeapon >= 0 ? deployFireWeapon : pThis->SelectWeapon(pCell); | ||
| const FireError fireError = pThis->GetFireError(pCell, weaponIndex, true); | ||
|
|
||
| if (fireError == FireError::ILLEGAL) | ||
| { | ||
| // Do not allow the building to remain in the Unload task indefinitely. | ||
| pThis->QueueMission(Mission::Guard, false); | ||
| pThis->NextMission(); | ||
|
Comment on lines
+69
to
+70
Contributor
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 use |
||
|
|
||
| return SkipGameCode; | ||
| } | ||
| else if (fireError == FireError::OK && pThis->Fire(pCell, weaponIndex)) | ||
| { | ||
| auto const pWeapon = pThis->GetWeapon(weaponIndex)->WeaponType; | ||
|
|
||
| if (pWeapon->FireOnce) | ||
| { | ||
| // When Turret=yes, the Unload task may not be canceled, so this handling is performed. | ||
| pThis->QueueMission(Mission::Guard, false); | ||
| pThis->NextMission(); | ||
|
Contributor
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 |
||
|
|
||
| return SkipGameCode; | ||
| } | ||
| } | ||
|
|
||
| auto const pTypeExt = BuildingTypeExt::ExtMap.Find(pType); | ||
| const int result = pTypeExt->DeployFireDelay.isset() | ||
| ? pTypeExt->DeployFireDelay : (ScenarioClass::Instance->Random.RandomRanged(0, 2) + 14); | ||
|
|
||
| R->EBX(result); | ||
| return SkipGameCode; | ||
| } | ||
|
|
||
| return ReturnGuard; | ||
| } | ||
|
|
||
| return Continue; | ||
| } | ||
|
|
||
| DEFINE_HOOK(0x730B09, DeployCommandClass_Execute_BuildingDeploy, 0x5) | ||
| { | ||
| for (const auto pObject : ObjectClass::CurrentObjects) | ||
| { | ||
| const AbstractFlags flags = pObject->AbstractFlags; | ||
|
|
||
| if (!(flags & AbstractFlags::Techno) || (flags & AbstractFlags::Foot)) | ||
| continue; | ||
|
|
||
| const auto pBuilding = static_cast<BuildingClass*>(pObject); | ||
| auto const pType = pBuilding->Type; | ||
| const auto pHouse = pBuilding->Owner; | ||
|
|
||
| if (!pHouse->IsControlledByCurrentPlayer() || !pType->DeployFire || pType->Factory != AbstractType::None) | ||
| continue; | ||
|
|
||
| const Mission currentMission = pBuilding->CurrentMission; | ||
|
|
||
| if (currentMission == Mission::Construction || currentMission == Mission::Selling) | ||
| continue; | ||
|
|
||
| if (pBuilding->EMPLockRemaining > 0 || !pBuilding->WasOnline || pBuilding->BunkerLinkedItem) | ||
| continue; | ||
|
|
||
|
Comment on lines
+96
to
+113
Contributor
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 be wrapped into a function. |
||
| pBuilding->ClickedMission(Mission::Unload, nullptr, nullptr, nullptr); | ||
| } | ||
|
|
||
| return 0; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -874,19 +874,33 @@ DEFINE_HOOK(0x4C7512, EventClass_Execute_StopCommand, 0x6) | |
|
|
||
| if (auto const pUnit = abstract_cast<UnitClass*>(pThis)) | ||
| { | ||
| auto const pType = pUnit->Type; | ||
|
|
||
| // issue #112 Make FireOnce=yes work on other TechnoType | ||
| // Author: Starkku | ||
| if (pUnit->CurrentMission == Mission::Unload && pUnit->Type->DeployFire && !pUnit->Type->IsSimpleDeployer) | ||
| if (pUnit->CurrentMission == Mission::Unload && pType->DeployFire && !pType->IsSimpleDeployer) | ||
| { | ||
| pUnit->SetTarget(nullptr); | ||
| pThis->QueueMission(Mission::Guard, true); | ||
| } | ||
|
|
||
| // Explicit stop command should reset subterranean harvester state machine. | ||
| auto const pExt = TechnoExt::ExtMap.Find(pUnit); | ||
| pExt->SubterraneanHarvStatus = 0; | ||
| pExt->SubterraneanHarvRallyPoint = nullptr; | ||
| } | ||
| else if (auto const pBuilding = abstract_cast<BuildingClass*, true>(pThis)) | ||
| { | ||
| auto const pType = pBuilding->Type; | ||
|
|
||
| if (pBuilding->CurrentMission == Mission::Unload | ||
| && pType->DeployFire && pType->Factory == AbstractType::None) | ||
| { | ||
| pBuilding->SetTarget(nullptr); | ||
| pBuilding->QueueMission(Mission::Guard, false); | ||
| pBuilding->NextMission(); | ||
|
Comment on lines
+915
to
+916
Contributor
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 |
||
| } | ||
| } | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
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.
OmniFireis actually a tag limited to UnitClass. AircraftClass usesFighter, BuildingClass must face the target to fire, while InfantryClass ignores the facing.