Skip to content

Commit dead071

Browse files
committed
feat: add flora stripping functionality and controls
1 parent c39472c commit dead071

9 files changed

Lines changed: 677 additions & 21 deletions

src/dll/SC4PlopAndPaintDirector.cpp

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,13 @@ bool SC4PlopAndPaintDirector::PostAppShutdown() {
330330
propStripperControl_.Reset();
331331
}
332332

333+
if (floraStripperControl_) {
334+
StopFloraStripping();
335+
floraStripperControl_->SetCity(nullptr);
336+
floraStripperControl_->Shutdown();
337+
floraStripperControl_.Reset();
338+
}
339+
333340
if (propPainterControl_) {
334341
StopPropPainting();
335342
propPainterControl_->SetCity(nullptr);
@@ -583,7 +590,7 @@ bool SC4PlopAndPaintDirector::StartFloraPainting(const uint32_t floraTypeId,
583590
return false;
584591
}
585592

586-
if (!PrepareForExclusiveActivation_(false, true, false)) {
593+
if (!PrepareForExclusiveActivation_(false, true, false, false)) {
587594
LOG_INFO("Blocked flora paint switch while another tool still has a sketch in progress");
588595
return false;
589596
}
@@ -671,13 +678,74 @@ bool SC4PlopAndPaintDirector::IsFloraPainting() const {
671678
return floraPainting_;
672679
}
673680

681+
bool SC4PlopAndPaintDirector::StartFloraStripping() {
682+
if (!pCity_ || !pView3D_) {
683+
LOG_WARN("Cannot start flora stripping: city or view not available");
684+
return false;
685+
}
686+
687+
if (!PrepareForExclusiveActivation_(false, false, false, true)) {
688+
LOG_INFO("Blocked flora stripping while another tool still has a sketch in progress");
689+
return false;
690+
}
691+
692+
if (!floraStripperControl_) {
693+
auto* control = new FloraStripperInputControl();
694+
floraStripperControl_ = control;
695+
if (!floraStripperControl_->Init()) {
696+
LOG_ERROR("Failed to initialize FloraStripperInputControl");
697+
floraStripperControl_.Reset();
698+
return false;
699+
}
700+
}
701+
702+
floraStripperControl_->SetCity(pCity_);
703+
floraStripperControl_->SetWindow(pView3D_->AsIGZWin());
704+
floraStripperControl_->SetOnCancel([this]() {
705+
if (pView3D_ && floraStripperControl_ &&
706+
pView3D_->GetCurrentViewInputControl() == floraStripperControl_) {
707+
pView3D_->RemoveCurrentViewInputControl(false);
708+
}
709+
floraStripping_ = false;
710+
UpdatePaintPanels_();
711+
LOG_INFO("Stopped flora stripping");
712+
});
713+
714+
if (!pView3D_->SetCurrentViewInputControl(
715+
floraStripperControl_,
716+
cISC4View3DWin::ViewInputControlStackOperation_RemoveCurrentControl)) {
717+
LOG_WARN("Failed to set flora stripper as current view input control");
718+
UpdatePaintPanels_();
719+
return false;
720+
}
721+
722+
floraStripping_ = true;
723+
LOG_INFO("Started flora stripping");
724+
return true;
725+
}
726+
727+
void SC4PlopAndPaintDirector::StopFloraStripping() {
728+
if (pView3D_ && floraStripperControl_) {
729+
if (pView3D_->GetCurrentViewInputControl() == floraStripperControl_) {
730+
pView3D_->RemoveCurrentViewInputControl(false);
731+
}
732+
}
733+
floraStripping_ = false;
734+
UpdatePaintPanels_();
735+
LOG_INFO("Stopped flora stripping");
736+
}
737+
738+
bool SC4PlopAndPaintDirector::IsFloraStripping() const {
739+
return floraStripping_;
740+
}
741+
674742
bool SC4PlopAndPaintDirector::StartPropStripping() {
675743
if (!pCity_ || !pView3D_) {
676744
LOG_WARN("Cannot start prop stripping: city or view not available");
677745
return false;
678746
}
679747

680-
if (!PrepareForExclusiveActivation_(false, false, true)) {
748+
if (!PrepareForExclusiveActivation_(false, false, true, false)) {
681749
LOG_INFO("Blocked prop stripping while another tool still has a sketch in progress");
682750
return false;
683751
}
@@ -820,6 +888,9 @@ void SC4PlopAndPaintDirector::ProcessPendingToolActions_() {
820888
if (propStripperControl_) {
821889
propStripperControl_->ProcessPendingActions();
822890
}
891+
if (floraStripperControl_) {
892+
floraStripperControl_->ProcessPendingActions();
893+
}
823894
if (propPainterControl_) {
824895
propPainterControl_->ProcessPendingActions();
825896
}
@@ -844,8 +915,9 @@ void SC4PlopAndPaintDirector::DrawOverlayCallback_(const DrawServicePass pass, c
844915
PropPainterInputControl* painterControl = director->propPainterControl_;
845916
PropStripperInputControl* stripperControl = director->propStripperControl_;
846917
FloraPainterInputControl* floraControl = director->floraPlacerControl_;
918+
FloraStripperInputControl* floraStripperControl = director->floraStripperControl_;
847919

848-
const bool needsOverlay = painterControl || stripperControl || floraControl;
920+
const bool needsOverlay = painterControl || stripperControl || floraControl || floraStripperControl;
849921

850922
if (!director->drawOverlayEnabled_ || !director->imguiService_ || !needsOverlay) {
851923
return;
@@ -866,6 +938,9 @@ void SC4PlopAndPaintDirector::DrawOverlayCallback_(const DrawServicePass pass, c
866938
if (floraControl) {
867939
floraControl->DrawOverlay(device);
868940
}
941+
if (floraStripperControl) {
942+
floraStripperControl->DrawOverlay(device);
943+
}
869944
device->Release();
870945
dd->Release();
871946
}
@@ -946,7 +1021,8 @@ bool SC4PlopAndPaintDirector::PrepareForPaintSwitch_(BasePainterInputControl* co
9461021

9471022
bool SC4PlopAndPaintDirector::PrepareForExclusiveActivation_(const bool keepPropPainting,
9481023
const bool keepFloraPainting,
949-
const bool keepPropStripping) {
1024+
const bool keepPropStripping,
1025+
const bool keepFloraStripping) {
9501026
if (!keepPropPainting && !CanPrepareForPaintSwitch_(propPainterControl_, propPainting_)) {
9511027
return false;
9521028
}
@@ -967,6 +1043,10 @@ bool SC4PlopAndPaintDirector::PrepareForExclusiveActivation_(const bool keepProp
9671043
StopPropStripping();
9681044
}
9691045

1046+
if (!keepFloraStripping && floraStripping_) {
1047+
StopFloraStripping();
1048+
}
1049+
9701050
return true;
9711051
}
9721052

src/dll/SC4PlopAndPaintDirector.hpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "cRZAutoRefCount.h"
2121
#include "cRZMessage2COMDirector.h"
2222
#include "flora/FloraPainterInputControl.hpp"
23+
#include "flora/FloraStripperInputControl.hpp"
2324
#include "imgui.h"
2425
#include "paint/PaintStatusPanel.hpp"
2526
#include "props/PropPainterInputControl.hpp"
@@ -72,6 +73,9 @@ class SC4PlopAndPaintDirector final : public cRZMessage2COMDirector
7273
const std::optional<RecentPaintSource>& source = std::nullopt);
7374
void StopFloraPainting();
7475
[[nodiscard]] bool IsFloraPainting() const;
76+
bool StartFloraStripping();
77+
void StopFloraStripping();
78+
[[nodiscard]] bool IsFloraStripping() const;
7579
bool StartPropStripping();
7680
void StopPropStripping();
7781
[[nodiscard]] bool IsPropStripping() const;
@@ -101,7 +105,8 @@ class SC4PlopAndPaintDirector final : public cRZMessage2COMDirector
101105
void PersistRecentPaints_();
102106
bool CanPrepareForPaintSwitch_(BasePainterInputControl* control, bool isPaintingFlag) const;
103107
bool PrepareForPaintSwitch_(BasePainterInputControl* control, bool& isPaintingFlag);
104-
bool PrepareForExclusiveActivation_(bool keepPropPainting, bool keepFloraPainting, bool keepPropStripping);
108+
bool PrepareForExclusiveActivation_(bool keepPropPainting, bool keepFloraPainting, bool keepPropStripping,
109+
bool keepFloraStripping = false);
105110
void ApplySwitchPolicy_(BasePainterInputControl* control);
106111
[[nodiscard]] RecentPaintEntry BuildRecentPaintEntry_(RecentPaintEntry::Kind kind,
107112
uint32_t typeId,
@@ -130,6 +135,8 @@ class SC4PlopAndPaintDirector final : public cRZMessage2COMDirector
130135
bool propPainting_{false};
131136
cRZAutoRefCount<FloraPainterInputControl> floraPlacerControl_;
132137
bool floraPainting_{false};
138+
cRZAutoRefCount<FloraStripperInputControl> floraStripperControl_;
139+
bool floraStripping_{false};
133140
cRZAutoRefCount<PropStripperInputControl> propStripperControl_;
134141
bool propStripping_{false};
135142
std::unique_ptr<PaintStatusPanel> statusPanel_;

src/dll/common/PanelTab.hpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,52 @@ class PanelTab {
5151
}
5252
}
5353

54+
void RenderPropStripperControls_() const {
55+
if (!director_) {
56+
return;
57+
}
58+
59+
if (director_->IsPropStripping()) {
60+
ImGui::SameLine();
61+
if (ImGui::SmallButton("Stop stripping")) {
62+
director_->StopPropStripping();
63+
}
64+
}
65+
else {
66+
ImGui::SameLine();
67+
if (ImGui::SmallButton("Strip props")) {
68+
ReleaseImGuiInputCapture_();
69+
director_->StartPropStripping();
70+
}
71+
if (ImGui::IsItemHovered()) {
72+
ImGui::SetTooltip("Click props in the city to remove them one by one.\nPress B to toggle brush mode.\nHold left mouse in brush mode to strip within the preview radius.\nCtrl+Z to undo, ESC to stop.");
73+
}
74+
}
75+
}
76+
77+
void RenderFloraStripperControls_() const {
78+
if (!director_) {
79+
return;
80+
}
81+
82+
if (director_->IsFloraStripping()) {
83+
ImGui::SameLine();
84+
if (ImGui::SmallButton("Stop stripping")) {
85+
director_->StopFloraStripping();
86+
}
87+
}
88+
else {
89+
ImGui::SameLine();
90+
if (ImGui::SmallButton("Strip flora")) {
91+
ReleaseImGuiInputCapture_();
92+
director_->StartFloraStripping();
93+
}
94+
if (ImGui::IsItemHovered()) {
95+
ImGui::SetTooltip("Click flora in the city to remove it one by one.\nPress B to toggle brush mode.\nHold left mouse in brush mode to strip within the preview radius.\nCtrl+Z to undo, ESC to stop.");
96+
}
97+
}
98+
}
99+
54100
void RenderThumbnail_(const std::optional<void*> textureId,
55101
const ImVec2 size = ImVec2(UI::kIconSize, UI::kIconSize)) const {
56102
ThumbnailUi::Render(

src/dll/flora/FloraCollectionsPanelTab.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ void FloraCollectionsPanelTab::OnRender() {
105105
director_->StopFloraPainting();
106106
}
107107
}
108+
RenderFloraStripperControls_();
108109

109110
ImGui::Separator();
110111
if (ImGui::BeginChild("FloraCollectionsTableRegion", ImVec2(0, UI::familyTableHeight()), false)) {

src/dll/flora/FloraPanelTab.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ void FloraPanelTab::OnRender() {
7272
director_->StopFloraPainting();
7373
}
7474
}
75+
RenderFloraStripperControls_();
7576

7677
if (ImGui::BeginChild("FloraTableRegion", ImVec2(0, 0), false)) {
7778
RenderIndividualFloraTable_(filteredFloraIndices);

0 commit comments

Comments
 (0)