Skip to content
Closed

- #1

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
2 changes: 2 additions & 0 deletions CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@ This page lists all the individual contributions to the project by their author.
- Several new Infotypes, no display in specific status and a new single frame display method
- Customizable spawn delay of `VoxelAnim`'s `TrailerAnim` and fix its incorrect position
- Add `DebrisMinimums` to keep the count of debris within a certain range
- Task subtitles display in the middle of the screen
- **Ollerus**:
- Build limit group enhancement
- Customizable rocker amplitude
Expand Down Expand Up @@ -552,6 +553,7 @@ This page lists all the individual contributions to the project by their author.
- Targeting limitation for berzerk technos
- Allows refineries to use multiple ActiveAnim simultaneously
- Several attackmove related enhancement
- Fix the bug that `OpenToppedWarpDistance` is calculated incorrectly for building target
- **tyuah8**:
- Drive/Jumpjet/Ship/Teleport locomotor did not power on when it is un-piggybacked bugfix
- Destroyed unit leaves sensors bugfix
Expand Down
1 change: 1 addition & 0 deletions Phobos.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@
<ClCompile Include="src\Misc\Hooks.INIInheritance.cpp" />
<ClCompile Include="src\Misc\Hooks.SkirmishColors.cpp" />
<ClCompile Include="src\Misc\Hooks.Overlay.cpp" />
<ClCompile Include="src\Misc\Hooks.Message.cpp" />
<ClCompile Include="src\New\Type\Affiliated\TypeConvertGroup.cpp" />
<ClCompile Include="src\Ext\BuildingType\Hooks.Upgrade.cpp" />
<ClCompile Include="src\Phobos.COM.cpp" />
Expand Down
1 change: 1 addition & 0 deletions docs/Fixed-or-Improved-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ This page describes all ingame logics that are fixed or improved in Phobos witho
- Fixed the bug that `DamageSelf` and `AllowDamageOnSelf` are ineffective on airforce.
- Fixed the bug that damaged particle dont disappear after building has repaired by engineer.
- Fixed the issue of incorrect position of `TrailerAnim` in `VoxelAnim`.
- Fixed the bug that `OpenToppedWarpDistance` is calculated incorrectly for building target.

## Fixes / interactions with other extensions

Expand Down
16 changes: 16 additions & 0 deletions docs/User-Interface.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,23 @@ ShowTimer=yes
ShowTimer.Priority=0 ; integer
```

### Task subtitles display in the middle of the screen

![Message Display In Center](_static/images/messagedisplayincenter.png)

- Now you can set `MessageApplyHoverState` to true,to make the upper left messages not disappear while mouse hovering over the top of display area.
- You can also let task subtitles (created by trigger 11) to display directly in the middle area of the screen instead of the upper left corner, with a semi transparent background, by setting `MessageDisplayInCenter` to true.
- When the mouse hovers over the subtitle area (simply judged as a rectangle), its opacity will increase and it will not disappear during this period.

In `RA2MD.INI`:
```ini
[Phobos]
MessageApplyHoverState=false ; boolean
MessageDisplayInCenter=false ; boolean
```

### Type select for buildings

- In vanilla game, type select can almost only be used on 1x1 buildings with `UndeploysInto`. Now it's possible to use it on all buildings if `BuildingTypeSelectable` set to true.

In `rulesmd.ini`:
Expand Down
2 changes: 2 additions & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@ New:
- Several attackmove related enhancement (by TaranDahl)
- Ground line for select box (by NetsuNegi)
- Support for more optional weapons (by FlyStar)
- Task subtitles display in the middle of the screen (by CrimRecya)

Vanilla fixes:
- Fixed sidebar not updating queued unit numbers when adding or removing units when the production is on hold (by CrimRecya)
Expand Down Expand Up @@ -437,6 +438,7 @@ Vanilla fixes:
- Fixed the bug that `DamageSelf` and `AllowDamageOnSelf` are ineffective on airforce (by NetsuNegi)
- Fixed the bug that damaged particle dont disappear after building has repaired by engineer (by NetsuNegi)
- Fixed the issue of incorrect position of `TrailerAnim` in `VoxelAnim` (by CrimRecya)
- Fixed the bug that `OpenToppedWarpDistance` is calculated incorrectly for building target (by TaranDahl)

Phobos fixes:
- Fixed the bug that `AllowAirstrike=no` cannot completely prevent air strikes from being launched against it (by NetsuNegi)
Expand Down
Binary file added docs/_static/images/messagedisplayincenter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/Ext/Bullet/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ void BulletExt::ExtData::ApplyRadiationToCell(CellStruct cell, int spread, int r
{
const auto pRadExt = RadSiteExt::ExtMap.Find(pSite);

if (pRadExt->Type != pRadType || pWeapon != pRadExt->Weapon)
if (pRadExt->Type != pRadType || spread != pSite->Spread)
return false;

if (pRadExt->RadInvoker && pThis->Owner)
Expand Down
99 changes: 77 additions & 22 deletions src/Ext/RadSite/Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,12 @@ DEFINE_HOOK(0x43FB23, BuildingClass_AI_Radiation, 0x5)
if (pBuilding->Type->ImmuneToRadiation || pBuilding->InLimbo || pBuilding->BeingWarpedOut || pBuilding->TemporalTargetingMe)
return 0;

int radDelay = RulesExt::Global()->RadApplicationDelay_Building;

if (RulesExt::Global()->UseGlobalRadApplicationDelay &&
(radDelay == 0 || Unsorted::CurrentFrame % radDelay != 0))
if (RulesExt::Global()->UseGlobalRadApplicationDelay)
{
return 0;
const int delay = RulesExt::Global()->RadApplicationDelay_Building;

if (delay == 0 || Unsorted::CurrentFrame % delay)
return 0;
}

const auto buildingCoords = pBuilding->GetMapCoords();
Expand All @@ -141,39 +141,65 @@ DEFINE_HOOK(0x43FB23, BuildingClass_AI_Radiation, 0x5)
continue;

const auto pCellExt = CellExt::ExtMap.Find(pCell);
std::vector<std::pair<RadTypeClass*, std::vector<std::pair<RadSiteClass*, int>>>> typeMap;
typeMap.reserve(RadTypeClass::Array.size());

for (const auto& [pRadSite, radLevel] : pCellExt->RadLevels)
{
if (radLevel <= 0)
continue;

const auto pRadExt = RadSiteExt::ExtMap.Find(pRadSite);
RadTypeClass* pType = pRadExt->Type;
int maxDamageCount = pType->GetBuildingDamageMaxCount();
const auto pRadType = pRadExt->Type;
int maxDamageCount = pRadType->GetBuildingDamageMaxCount();

if (maxDamageCount > 0 && damageCounts[pRadSite] >= maxDamageCount)
continue;

if (!pType->GetWarhead())
if (!pRadType->GetWarhead())
continue;

if (!RulesExt::Global()->UseGlobalRadApplicationDelay)
{
int delay = pType->GetBuildingApplicationDelay();
const int delay = pRadType->GetBuildingApplicationDelay();

if ((delay == 0) || (Unsorted::CurrentFrame % delay != 0))
if (delay == 0 || Unsorted::CurrentFrame % delay)
continue;
}

if (pBuilding->IsAlive) // simple fix for previous issues
const auto it = std::ranges::find_if(typeMap, [pRadType](std::pair<RadTypeClass*, std::vector<std::pair<RadSiteClass*, int>>> const& item) { return item.first == pRadType; });

if (it != typeMap.cend())
{
it->second.emplace_back(pRadSite, radLevel);
}
else
{
std::vector<std::pair<RadSiteClass*, int>> sites { std::make_pair(pRadSite, radLevel) };
typeMap.emplace_back(pRadType, std::move(sites));
}
}

for (auto& [_, sites] : typeMap)
std::ranges::stable_sort(sites, [](std::pair<RadSiteClass*, int> const& left, std::pair<RadSiteClass*, int> const& right) { return left.second > right.second; });

for (const auto& [pRadType, sites] : typeMap)
{
const int radLevelMax = pRadType->GetLevelMax();
int radLevelSum = 0;

for (const auto& [pRadSite, radLevel] : sites)
{
int damage = Game::F2I(radLevel * pType->GetLevelFactor());
const int remain = radLevelMax - radLevelSum;
int damage = static_cast<int>(std::min(radLevel, remain) * pRadType->GetLevelFactor());

if (maxDamageCount > 0)
damageCounts[pRadSite]++;
if (pBuilding->IsAlive && !RadSiteExt::ExtMap.Find(pRadSite)->ApplyRadiationDamage(pBuilding, damage))
return 0;

if (!pRadExt->ApplyRadiationDamage(pBuilding, damage))
if (radLevel >= remain)
break;

radLevelSum += radLevel;
}
}
}
Expand All @@ -196,32 +222,61 @@ DEFINE_HOOK(0x4DA59F, FootClass_AI_Radiation, 0x5)
{
const auto pCell = pFoot->GetCell();
const auto pCellExt = CellExt::ExtMap.Find(pCell);
std::vector<std::pair<RadTypeClass*, std::vector<std::pair<RadSiteClass*, int>>>> typeMap;
typeMap.reserve(RadTypeClass::Array.size());

for (const auto& [pRadSite, radLevel] : pCellExt->RadLevels)
{
if (radLevel <= 0)
continue;

const auto pRadExt = RadSiteExt::ExtMap.Find(pRadSite);
RadTypeClass* pType = pRadExt->Type;
const auto pRadType = pRadExt->Type;

if (!pType->GetWarhead())
if (!pRadType->GetWarhead())
continue;

if (!RulesExt::Global()->UseGlobalRadApplicationDelay)
{
int delay = pType->GetApplicationDelay();
const int delay = pRadType->GetApplicationDelay();

if ((delay == 0) || (Unsorted::CurrentFrame % delay != 0))
if (delay == 0 || Unsorted::CurrentFrame % delay)
continue;
}

if (pFoot->IsAlive || !pFoot->IsSinking)
const auto it = std::ranges::find_if(typeMap, [pRadType](std::pair<RadTypeClass*, std::vector<std::pair<RadSiteClass*, int>>> const& item) { return item.first == pRadType; });

if (it != typeMap.cend())
{
it->second.emplace_back(pRadSite, radLevel);
}
else
{
std::vector<std::pair<RadSiteClass*, int>> sites { std::make_pair(pRadSite, radLevel) };
typeMap.emplace_back(pRadType, std::move(sites));
}
}

for (auto& [_, sites] : typeMap)
std::ranges::stable_sort(sites, [](std::pair<RadSiteClass*, int> const& left, std::pair<RadSiteClass*, int> const& right) { return left.second > right.second; });

for (const auto& [pRadType, sites] : typeMap)
{
const int radLevelMax = pRadType->GetLevelMax();
int radLevelSum = 0;

for (const auto& [pRadSite, radLevel] : sites)
{
int damage = Game::F2I(radLevel * pType->GetLevelFactor());
const int remain = radLevelMax - radLevelSum;
int damage = static_cast<int>(std::min(radLevel, remain) * pRadType->GetLevelFactor());

if ((pFoot->IsAlive || !pFoot->IsSinking) && !RadSiteExt::ExtMap.Find(pRadSite)->ApplyRadiationDamage(pFoot, damage))
return ReturnFromFunction;

if (!pRadExt->ApplyRadiationDamage(pFoot, damage))
if (radLevel >= remain)
break;

radLevelSum += radLevel;
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/Ext/Scenario/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ void ScenarioExt::ExtData::Serialize(T& Stm)
.Process(this->TransportReloaders)
.Process(this->SWSidebar_Enable)
.Process(this->SWSidebar_Indices)
// .Process(this->NewMessageList); // Should not S/L
;
}

Expand Down
4 changes: 4 additions & 0 deletions src/Ext/Scenario/Body.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <ScenarioClass.h>
#include <MessageListClass.h>

#include <Helpers/Macro.h>
#include <Utilities/Container.h>
Expand Down Expand Up @@ -39,6 +40,8 @@ class ScenarioExt
bool SWSidebar_Enable;
std::vector<int> SWSidebar_Indices;

std::unique_ptr<MessageListClass> NewMessageList;

ExtData(ScenarioClass* OwnerObject) : Extension<ScenarioClass>(OwnerObject)
, ShowBriefing { false }
, BriefingTheme { -1 }
Expand All @@ -48,6 +51,7 @@ class ScenarioExt
, TransportReloaders {}
, SWSidebar_Enable { true }
, SWSidebar_Indices {}
, NewMessageList {}
{ }

void SetVariableToByID(bool bIsGlobal, int nIndex, char bState);
Expand Down
12 changes: 12 additions & 0 deletions src/Misc/Hooks.BugFixes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2250,3 +2250,15 @@ DEFINE_HOOK(0x489E47, DamageArea_RockerItemsFix2, 0x6)
}

#pragma region

DEFINE_HOOK(0x71A7BC, TemporalClass_Update_DistCheck, 0x6)
{
enum { SkipGameCode = 0x71A82C };

GET(TemporalClass*, pThis, ESI);
GET(TechnoClass*, pTarget, ECX);

// Vanilla check is incorrect for buildingtargets
R->EAX(pThis->Owner->DistanceFrom(pTarget));
return SkipGameCode;
}
Loading