-
-
Notifications
You must be signed in to change notification settings - Fork 128
Add Rebuild X Keyboard Commands #2129
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 4 commits
52ec449
4c8c18a
659478b
ce2ddf9
b80444a
73edb17
cb9ffcd
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 |
|---|---|---|
|
|
@@ -521,6 +521,18 @@ For this command to work in multiplayer - you need to use a version of [YRpp spa | |
| - Switches on/off [Task subtitles' label in the middle of the screen](#task-subtitles-display-in-the-middle-of-the-screen). | ||
| - For localization add `TXT_TOGGLE_MESSAGE` and `TXT_TOGGLE_MESSAGE_DESC` into your `.csf` file. | ||
|
|
||
| ### `[ ]` Rebuild Structure | ||
| - Re-queue the last produced Power/Resource/Tech Building you placed. | ||
|
|
||
| ### `[ ]` Rebuild Defense | ||
| - Re-queue the last produced Defensive Building you placed. | ||
|
|
||
| ### `[ ]` Rebuild Infantry | ||
| - Re-queue the last produced Infantry you built. | ||
|
|
||
| ### `[ ]` Rebuild Vehicle | ||
| - Re-queue the last produced Vehicle you built. | ||
|
||
|
|
||
| ## Loading screen | ||
|
|
||
| - PCX files can now be used as loadscreen images. | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| #include "BuildLastOfTab.h" | ||
|
|
||
| #include <Utilities/GeneralUtils.h> | ||
| #include <Ext/House/Body.h> | ||
| #include <HouseClass.h> | ||
| #include <EventClass.h> | ||
| #include <SidebarClass.h> | ||
|
|
||
| static constexpr const char* BuildLastTabNames[4] = | ||
| { | ||
| "RebuildStructure", | ||
| "RebuildDefense", | ||
| "RebuildInfantry", | ||
| "RebuildVehicle", | ||
| }; | ||
|
|
||
| static constexpr const char* BuildLastTabDescKeys[4] = | ||
| { | ||
| "RebuildStructure_Desc", | ||
| "RebuildDefense_Desc", | ||
| "RebuildInfantry_Desc", | ||
| "RebuildVehicle_Desc", | ||
| }; | ||
|
|
||
| static constexpr const wchar_t* BuildLastTabUINames[4] = | ||
| { | ||
| L"Rebuild Structure", | ||
| L"Rebuild Defense", | ||
| L"Rebuild Infantry", | ||
| L"Rebuild Vehicle", | ||
| }; | ||
|
|
||
| static constexpr const wchar_t* BuildLastTabUIDescs[4] = | ||
| { | ||
| L"Re-queue the last produced Power/Resources building.", | ||
| L"Re-queue the last produced Defense/Combat building.", | ||
| L"Re-queue the last produced Infantry unit.", | ||
| L"Re-queue the last produced Vehicle or Aircraft.", | ||
| }; | ||
|
|
||
| template<int TabIndex> | ||
| const char* BuildLastOfTabCommandClass<TabIndex>::GetName() const | ||
| { | ||
| return BuildLastTabNames[TabIndex]; | ||
| } | ||
|
|
||
| template<int TabIndex> | ||
| const wchar_t* BuildLastOfTabCommandClass<TabIndex>::GetUIName() const | ||
| { | ||
| return GeneralUtils::LoadStringUnlessMissing(BuildLastTabNames[TabIndex], BuildLastTabUINames[TabIndex]); | ||
| } | ||
|
|
||
| template<int TabIndex> | ||
| const wchar_t* BuildLastOfTabCommandClass<TabIndex>::GetUICategory() const | ||
| { | ||
| return CATEGORY_INTERFACE; | ||
| } | ||
|
|
||
| template<int TabIndex> | ||
| const wchar_t* BuildLastOfTabCommandClass<TabIndex>::GetUIDescription() const | ||
| { | ||
| static_assert(TabIndex >= 0 && TabIndex < 4, "TabIndex out of range"); | ||
| return GeneralUtils::LoadStringUnlessMissing(BuildLastTabDescKeys[TabIndex], BuildLastTabUIDescs[TabIndex]); | ||
| } | ||
|
|
||
| template<int TabIndex> | ||
| void BuildLastOfTabCommandClass<TabIndex>::Execute(WWKey eInput) const | ||
| { | ||
| auto const pPlayer = HouseClass::CurrentPlayer; | ||
| if (!pPlayer) | ||
| return; | ||
|
|
||
| auto const pExt = HouseExt::ExtMap.Find(pPlayer); | ||
| if (!pExt) | ||
| return; | ||
|
|
||
| auto const typeIndex = pExt->LastBuiltPerTab[TabIndex]; | ||
| if (typeIndex < 0) | ||
| return; | ||
|
|
||
| // Focus the sidebar to the corresponding tab. | ||
| if (SidebarClass::Instance.IsSidebarActive) | ||
| { | ||
| SidebarClass::Instance.ActiveTabIndex = TabIndex; | ||
| SidebarClass::Instance.SidebarNeedsRepaint(); | ||
| } | ||
|
|
||
| auto const rtti = pExt->LastBuiltRTTIPerTab[TabIndex]; | ||
| auto const isNaval = pExt->LastBuiltIsNavalPerTab[TabIndex]; | ||
|
|
||
| EventClass::OutList.Add(EventClass( | ||
|
Member
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. I am pretty sure this bypasses all the legality checks?
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. It will get rejected by the house if the house can't build it. That said, what we did in Vinifera is check if it's present on th sidebar as an icon as a shortcut. |
||
| pPlayer->ArrayIndex, | ||
| EventType::Produce, | ||
| static_cast<int>(rtti), | ||
| typeIndex, | ||
| isNaval ? TRUE : FALSE | ||
| )); | ||
| } | ||
|
|
||
| // Explicit instantiations | ||
| template class BuildLastOfTabCommandClass<0>; | ||
| template class BuildLastOfTabCommandClass<1>; | ||
| template class BuildLastOfTabCommandClass<2>; | ||
| template class BuildLastOfTabCommandClass<3>; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| #pragma once | ||
|
|
||
| #include "Commands.h" | ||
|
|
||
| // Re-queue the last produced item from a specific production tab. | ||
| // TabIndex: 0 = Power/Infrastructure, 1 = Defense/Combat, 2 = Infantry, 3 = Vehicles/Aircraft | ||
| template<int TabIndex> | ||
| class BuildLastOfTabCommandClass : public CommandClass | ||
| { | ||
| public: | ||
| virtual const char* GetName() const override; | ||
| virtual const wchar_t* GetUIName() const override; | ||
| virtual const wchar_t* GetUICategory() const override; | ||
| virtual const wchar_t* GetUIDescription() const override; | ||
| virtual void Execute(WWKey eInput) const override; | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| #include "Body.h" | ||
|
|
||
| #include <SidebarClass.h> | ||
| #include <BuildingTypeClass.h> | ||
| #include <TechnoClass.h> | ||
|
|
||
| // Hook into HouseClass::RegisterObjectGain_FromFactory (0x4FB6B0). | ||
| // Fires when a unit or building is delivered from a factory. | ||
| // At this point: EDI = HouseClass*, EBP = TechnoClass* (the object being delivered). | ||
| // We track the delivered type per sidebar tab so the "Build Last" commands can re-queue it. | ||
|
|
||
| DEFINE_HOOK(0x4FB6C2, HouseClass_RegisterObjectGain_TrackLastBuiltTab, 0x7) | ||
| { | ||
| GET(HouseClass* const, pThis, EDI); | ||
| GET(TechnoClass* const, pTechno, EBP); | ||
|
|
||
| if (pThis != HouseClass::CurrentPlayer) | ||
| return 0; | ||
|
|
||
| auto const pType = pTechno->GetTechnoType(); | ||
| if (!pType) | ||
| return 0; | ||
|
|
||
| auto const absType = pType->WhatAmI(); | ||
| auto const isNaval = pType->Naval; | ||
|
|
||
| auto buildCat = BuildCat::DontCare; | ||
| if (absType == AbstractType::BuildingType) | ||
| buildCat = static_cast<BuildingTypeClass const*>(pType)->BuildCat; | ||
|
|
||
| int const tabIdx = SidebarClass::GetObjectTabIdx(absType, buildCat, isNaval); | ||
|
|
||
| if (tabIdx >= 0 && tabIdx < 4) | ||
| { | ||
| auto const pExt = HouseExt::ExtMap.Find(pThis); | ||
| pExt->LastBuiltPerTab[tabIdx] = pType->GetArrayIndex(); | ||
| pExt->LastBuiltRTTIPerTab[tabIdx] = absType; | ||
| pExt->LastBuiltIsNavalPerTab[tabIdx] = isNaval; | ||
| } | ||
|
|
||
| return 0; | ||
| } |
Uh oh!
There was an error while loading. Please reload this page.