Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -861,3 +861,8 @@ This page lists all the individual contributions to the project by their author.
- Revert Ares patch to allow OpenTopped transport customization
- Fix for units with Fly, Jumpjet or Rocket locomotors crashing off-map not being cleaned up
- Fix for mirage tanks (and other vehicles disguised as terrain) incorrectly displaying veterancy insignia to enemy players when not clearly visible
- **Chang_zhi**:
- Add `ClampToScreen` tag for `BannerType` to control whether banner position is clamped to the visible area



2 changes: 2 additions & 0 deletions docs/AI-Scripting-and-Mapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -820,6 +820,7 @@ Team delay change will take effect for a house after its next AI team is created
- `Duration` determines how long the banner will be displayed. Negative values mean the banner can always be displayed until being deleted. The banner itself won't be deleted when it's not displaying.
- `Delay` determines when the banner will be displayed again after it stops displaying by a positive `Duration`. Neagtive values mean it can't be displayed again.
- If an `SHP` banner displays again after the delay, it'll start from the frame when it's stopped last time. This can also be changed to its first frame if `SHP.RefreshAfterDelay` set to true.
- `ClampToScreen` controls whether the banner is clamped to stay within the visible area. When disabled, a PCX banner exceeding the top screen edge may crash the game.

In `rulesmd.ini`:
```ini
Expand All @@ -837,6 +838,7 @@ CSF.Background=false ; boolean
CSF.VariableFormat=none ; List of Variable Format Enumeration (none|variable|prefix/prefixed|surfix/surfixed)
Duration=-1 ; integer
Delay=-1 ; integer
ClampToScreen=true ; boolean
```

In `mycampaign.map`:
Expand Down
1 change: 1 addition & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -592,6 +592,7 @@ HideShakeEffects=false ; boolean
- [Animation transparency customization settings](New-or-Enhanced-Logics.md#customizable-animation-transparency-settings) (by Starkku)
- [Customize `Tiled` drawing interval and centering](Fixed-or-Improved-Logics.md#customize-the-drawing-interval-for-tiled) (by Noble_Fish)
- [Customize whether technos with `Locomotor=Fly` wobble](Fixed-or-Improved-Logics.md#customize-whether-technos-with-locomotor-fly-wobble) (by Noble_Fish)
- Add `ClampToScreen` tag for `BannerType` (defaults to `true`) to control whether banner position is clamped to the visible area (by Chang_zhi)

#### Vanilla fixes:
- Fixed sidebar not updating queued unit numbers when adding or removing units when the production is on hold (by CrimRecya)
Expand Down
8 changes: 8 additions & 0 deletions docs/locale/zh_CN/LC_MESSAGES/AI-Scripting-and-Mapping.po
Original file line number Diff line number Diff line change
Expand Up @@ -1559,6 +1559,14 @@ msgid ""
"frame if `SHP.RefreshAfterDelay` set to true."
msgstr "一个 `SHP` 横幅会在再次显示时从上次结束时的帧开始。这可以通过 `SHP.RefreshAfterDelay=true` 更改为从头开始。"

msgid ""
"`ClampToScreen` controls whether the banner is clamped to stay within the"
" visible area. When disabled, a PCX banner exceeding the top screen edge "
"may crash the game."
msgstr ""
"`ClampToScreen` 控制横幅是否被限制在可视区域内。禁用后,PCX "
"横幅超出屏幕上边缘时可能导致游戏崩溃。"

msgid "Trigger events"
msgstr "触发条件"

Expand Down
8 changes: 8 additions & 0 deletions docs/locale/zh_CN/LC_MESSAGES/CREDITS.po
Original file line number Diff line number Diff line change
Expand Up @@ -2928,3 +2928,11 @@ msgid ""
" being cleaned up"
msgstr "修复了 `Locomotor` 为 `Fly`、`Jumpjet` 或 `Rocket` 的单位在地图外坠毁时未能清除的问题"

msgid "**Chang_zhi**:"
msgstr "**Chang_zhi**:"

msgid ""
"Add `ClampToScreen` tag for `BannerType` to control whether banner "
"position is clamped to the visible area"
msgstr ""
"为 `BannerType` 添加了 `ClampToScreen` 标签以控制横幅位置是否被限制在可视化区域内"
6 changes: 6 additions & 0 deletions docs/locale/zh_CN/LC_MESSAGES/Whats-New.po
Original file line number Diff line number Diff line change
Expand Up @@ -1981,6 +1981,12 @@ msgstr ""
"[寄生击杀水上目标后刷出的自定义](Fixed-or-Improved-Logics.md#dehardcode-of-parasites-"
"unlimboing-after-killing-naval-targets)(by Noble_Fish)"

msgid ""
"Add `ClampToScreen` tag for `BannerType` (defaults to `true`) to control "
"whether banner position is clamped to the visible area (by Chang_zhi)"
msgstr ""
"为 `BannerType` 添加了 `ClampToScreen` 标签(默认为 `true`),用于控制横幅位置是否被限制在可视区域内(by Chang_zhi)"

msgid "Vanilla fixes:"
msgstr "原版问题修复:"

Expand Down
46 changes: 44 additions & 2 deletions src/New/Entity/BannerClass.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
#include "BannerClass.h"

#include <Drawing.h>

#include <Ext/Scenario/Body.h>

#include <algorithm>

std::vector<std::unique_ptr<BannerClass>> BannerClass::Array;

BannerClass::BannerClass
Expand Down Expand Up @@ -61,9 +65,21 @@ void BannerClass::Render()

void BannerClass::RenderPCX(Point2D position)
{
auto const pType = this->Type;
BSurface* pcx = this->Type->PCX.GetSurface();
position.X -= pcx->Width / 2;
position.Y -= pcx->Height / 2;

// Clamp the position to keep the PCX within the visible area,
// preventing it from being drawn partially off-screen.
if(pType->ClampToScreen)
{
int maxX = std::max(0, DSurface::ViewBounds.Width - pcx->Width);
int maxY = std::max(0, DSurface::ViewBounds.Height - pcx->Height);
position.X = std::clamp(position.X, 0, maxX);
position.Y = std::clamp(position.Y, 0, maxY);
}

RectangleStruct bounds(position.X, position.Y, pcx->Width, pcx->Height);
PCX::Instance.BlitToSurface(&bounds, DSurface::Composite, pcx);
}
Expand All @@ -76,6 +92,16 @@ void BannerClass::RenderSHP(Point2D position)
position.X -= shape->Width / 2;
position.Y -= shape->Height / 2;

// Clamp the position to keep the SHP within the visible area,
// preventing it from being drawn partially off-screen.
if (pType->ClampToScreen)
{
int maxX = std::max(0, DSurface::ViewBounds.Width - shape->Width);
int maxY = std::max(0, DSurface::ViewBounds.Height - shape->Height);
position.X = std::clamp(position.X, 0, maxX);
position.Y = std::clamp(position.Y, 0, maxY);
}

DSurface::Composite->DrawSHP
(
palette,
Expand Down Expand Up @@ -134,11 +160,27 @@ void BannerClass::RenderCSF(Point2D position)
}

const TextPrintType textFlags = TextPrintType::UseGradPal
| TextPrintType::Center
| TextPrintType::Metal12
| (pType->CSF_Background
? TextPrintType::Background
: TextPrintType::LASTPOINT);
: TextPrintType::LASTPOINT)
| (pType->ClampToScreen
? TextPrintType::LASTPOINT
: TextPrintType::Center);


// Measure the text, manually center, then clamp to screen bounds.
if (pType->ClampToScreen)
{
RectangleStruct textRect = Drawing::GetTextDimensions(
text.c_str(), position, static_cast<WORD>(textFlags));
position.X -= textRect.Width / 2;
position.Y -= textRect.Height / 2;
int maxX = std::max(0, DSurface::ViewBounds.Width - textRect.Width);
int maxY = std::max(0, DSurface::ViewBounds.Height - textRect.Height);
position.X = std::clamp(position.X, 0, maxX);
position.Y = std::clamp(position.Y, 0, maxY);
}

DSurface::Composite->DrawText
(
Expand Down
2 changes: 2 additions & 0 deletions src/New/Type/BannerTypeClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ void BannerTypeClass::LoadFromINI(CCINIClass* pINI)
this->Duration.Read(exINI, section, "Duration");
this->Delay.Read(exINI, section, "Delay");
this->Shape_RefreshAfterDelay.Read(exINI, section, "SHP.RefreshAfterDelay");
this->ClampToScreen.Read(exINI, section, "ClampToScreen");
}

template <typename T>
Expand All @@ -41,6 +42,7 @@ void BannerTypeClass::Serialize(T& stm)
.Process(this->Duration)
.Process(this->Delay)
.Process(this->Shape_RefreshAfterDelay)
.Process(this->ClampToScreen)
;
}

Expand Down
4 changes: 4 additions & 0 deletions src/New/Type/BannerTypeClass.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ class BannerTypeClass final : public Enumerable<BannerTypeClass>
Valueable<int> Delay;
Valueable<bool> Shape_RefreshAfterDelay;

//Clamp to screen
Valueable<bool> ClampToScreen;

BannerTypeClass(const char* const pTitle) : Enumerable<BannerTypeClass>(pTitle)
, PCX { }
, Shape { }
Expand All @@ -36,6 +39,7 @@ class BannerTypeClass final : public Enumerable<BannerTypeClass>
, Duration { -1 }
, Delay { -1 }
, Shape_RefreshAfterDelay { false }
, ClampToScreen { true }
{ }

virtual void LoadFromINI(CCINIClass* pINI);
Expand Down
Loading