Skip to content
4 changes: 3 additions & 1 deletion CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,8 @@ This page lists all the individual contributions to the project by their author.
- Fix a bug where game will crash after loading if a techno with `AlphaImage` converts to a type without it, or an anim with `AlphaImage` changes to a type without it through `Next`
- Fix a bug where updating the `OpenTopped` attribute during convert did not update the coordinates of passengers
- Fix the bug that low-air taking off / landing objects will receive twice damage
- Aux technos and TechLevel requirement of superweapon
- Allow `AuxBuilding` and Ares' `SW.Aux/NegBuildings` to count building upgrades
- **Apollo** - Translucent SHP drawing patches
- **ststl**:
- Customizable `ShowTimer` priority of superweapons
Expand Down Expand Up @@ -640,7 +642,6 @@ This page lists all the individual contributions to the project by their author.
- **Ollerus**:
- Build limit group enhancement
- Customizable rocker amplitude
<!-- - Allow `AuxBuilding` and Ares' `SW.Aux/NegBuildings` to count building upgrades -->
- Type select for buildings (doc)
- Enhanced Bombard trajectory
- Shield armor inheritance customization
Expand All @@ -665,6 +666,7 @@ This page lists all the individual contributions to the project by their author.
- Maximum amount for power plant enhancer
- Return warhead
- `ElectricAssault` weapons can now auto acquire allies' overpowerable defenses
- Allow `AuxBuilding` and Ares' `SW.Aux/NegBuildings` to count building upgrades
- **NaotoYuuki** - Vertical & meteor trajectory projectile prototypes
- **handama**:
- AI script action to `16005 Jump Back To Previous Script`
Expand Down
4 changes: 2 additions & 2 deletions docs/Fixed-or-Improved-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,6 @@ This page describes all ingame logics that are fixed or improved in Phobos witho
- `AirburstWeapon` now supports `IsLaser`, `IsElectricBolt`, `IsRadBeam`, and `AttachedParticleSystem`.
- Subterranean movement now benefits from speed multipliers from all sources such as veterancy, AttachEffect etc.
- Aircraft will now behave as expected according to it's `MovementZone` and `SpeedType` when moving onto different surfaces. In particular, this fixes erratic behavior when vanilla aircraft is ordered to move onto water surface and instead the movement order changes to a shore nearby.
<!-- - Allowed `AuxBuilding` to count building upgrades. -->
- Fixed the bug that parasite will vanish if it missed its target when its previous cell is occupied.
- Prevent the units with locomotors that cause problems from entering the tank bunker.
- Fixed an issue where a unit will leave an impassable invisible barrier in its original position when it is teleported by ChronoSphere onto an uncrushable unit and self destruct.
Expand Down Expand Up @@ -326,6 +325,7 @@ This page describes all ingame logics that are fixed or improved in Phobos witho
- Fixed the issue that the time for units in the area guard mission to reacquire targets after eliminating the target is significantly longer than that in other missions.
- Purely visual animations and particles are no longer included in frame CRC generation and are thus exempt from any sync checks between players in multiplayer games.
- Fixed the bug that low-air taking off / landing objects will receive twice damage.
- Allowed `AuxBuilding` to count building upgrades.

## Fixes / interactions with other extensions

Expand All @@ -342,7 +342,6 @@ This page describes all ingame logics that are fixed or improved in Phobos witho
- Suppressed Ares' swizzle warning when parsing `Tags` and `TaskForces` (typically begin with `[Developer fatal]Pointer 00000000 declared change to both`).
- Fixed Academy *(Ares feature)* not working on the initial payloads *(Ares feature)* of vehicles built from a war factory.
- Fixed Ares' InitialPayload not being created for vehicles spawned by trigger actions.
<!-- - Allowed Ares' `SW.AuxBuildings` and `SW.NegBuildings` to count building upgrades. -->
- Taking over Ares' AlphaImage respawn logic to make it not recreate in every frame for buildings, static techno and techno without turret, in order to reduce lags from it.
- Fixed an issue where a portion of Ares's trigger event 75/77 was determined unsuccessfully.
- Fixed an issue where some units crashed after the deployment transformation.
Expand Down Expand Up @@ -376,6 +375,7 @@ This page describes all ingame logics that are fixed or improved in Phobos witho
- Fixed the issue that `BombSight` not being updated correctly in techno conversion.
- `EVA.Tag` already supports being set for specific countries, and `EVAIndex` is no longer reset after load game.
- `DisableWeapons.Duration` now makes `Gattling=yes` rate tick down and stops the sounds from playing, no longer interferes with target acquisition and works together with Phobos' `OpenTopped.CheckTransportDisableWeapons`.
- Allowed Ares' `SW.AuxBuildings` and `SW.NegBuildings` to count building upgrades.

## Newly added global settings

Expand Down
18 changes: 18 additions & 0 deletions docs/New-or-Enhanced-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -1086,6 +1086,24 @@ In `rulesmd.ini`:
AISuperWeaponDelay= ; integer, game frames
```

### Aux technos and TechLevel requirement of superweapon

- `SW.AuxTechnos` specifies the auxiliary technos without which this super weapon cannot become available. The player has to own at least one techno of any of these types to get access to this super weapon.
- `SW.NegTechnos` specifies the negative auxiliary technos whose presence will cause the super weapon to become unavailable. This super weapon can become available only if the player does not own any techno of any of these types.
- `SW.TechLevel` specifies the TechLevel that the owner must not fall below in order to use this super weapon. The super weapon becomes available only if the player's TechLevel reaches that level.

In `rulesmd.ini`:
```ini
[SOMESW] ; SuperWeaponType
SW.AuxTechnos= ; List of TechnoTypes
SW.NegTechnos= ; List of TechnoTypes
SW.TechLevel=0 ; integer
```

```{note}
`SW.TechLevel` does not treat `-1` as a special value. If you want to restrict a super weapon to be available only to AI players, please use `SW.AllowPlayer` and `SW.AllowAI`.
```

### Convert TechnoType

- Warheads can now change TechnoTypes of affected units to other Types in the same category (infantry to infantry, vehicles to vehicles, aircraft to aircraft).
Expand Down
3 changes: 2 additions & 1 deletion docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -709,7 +709,6 @@ Phobos fixes:
- Fixed cells with `CanBeBuiltOn=true` TerrainTypes on them not being considered valid build locations by AI (by Starkku)

Fixes / interactions with other extensions:
<!-- - Allowed `AuxBuilding` and Ares' `SW.Aux/NegBuildings` to count building upgrades (by Ollerus) -->
- Taking over Ares' AlphaImage respawn logic to reduce lags from it (by NetsuNegi)
- Fixed an issue that Ares' Type Conversion not resetting barrel's direction by `FireAngle` (by TaranDahl)
- Fixed the issue where Ares' `Flash.Duration` cannot override the weapon's repair flash effect (by Sovietianqi, based on knowledge of DeathFish)
Expand All @@ -728,6 +727,8 @@ Fixes / interactions with other extensions:
- Fixed the issue that `BombSight` not being updated correctly in techno conversion (by TaranDahl)
- `EVA.Tag` already supports being set for specific countries, and `EVAIndex` is no longer reset after load game (by FlyStar)
- `DisableWeapons.Duration` now makes `Gattling=yes` rate tick down and stops the sounds from playing, no longer interferes with target acquisition and works together with Phobos' `OpenTopped.CheckTransportDisableWeapons` (by Starkku)
- Allowed `AuxBuilding` and Ares' `SW.Aux/NegBuildings` to count building upgrades (by Ollerus & NetsuNegi)
- [Aux technos and TechLevel requirement of superweapon](New-or-Enhanced-Logics.md#aux-technos-and-techlevel-requirement-of-superweapon) (by NetsuNegi & Ollerus)
```

### 0.4.0.3
Expand Down
10 changes: 10 additions & 0 deletions docs/locale/zh_CN/LC_MESSAGES/CREDITS.po
Original file line number Diff line number Diff line change
Expand Up @@ -1763,6 +1763,16 @@ msgid ""
"twice damage"
msgstr "修复了低空起飞/降落的物体会受到两次伤害的 Bug"

msgid ""
"Aux technos and TechLevel requirement of superweapon"
msgstr "超级武器的辅助单位和科技等级限制"

msgid ""
"Allow `AuxBuilding` and Ares' `SW.Aux/NegBuildings` to count building "
"upgrades"
msgstr ""
"允许了 Ares 的 `SW.AuxBuildings` 和 `SW.NegBuildings` 计入建筑加载物"

msgid "**Apollo** - Translucent SHP drawing patches"
msgstr "**Apollo** - 半透明 SHP 绘制补丁"

Expand Down
8 changes: 8 additions & 0 deletions docs/locale/zh_CN/LC_MESSAGES/Fixed-or-Improved-Logics.po
Original file line number Diff line number Diff line change
Expand Up @@ -1683,6 +1683,9 @@ msgid ""
"twice damage."
msgstr "修复了低空起飞/降落的物体会受到两次伤害的 Bug。"

msgid "Allowed `AuxBuilding` to count building upgrades."
msgstr "允许了 `AuxBuilding` 计入建筑加载物。"

msgid "Fixes / interactions with other extensions"
msgstr "修复或与其他扩展的交互"

Expand Down Expand Up @@ -1912,6 +1915,11 @@ msgid ""
msgstr ""
"现在 `DisableWeapons.Duration` 会使 `Gattling=yes` 的速率降低并停止播放音效,不再干扰目标获取并且可以和 Phobos 的 `OpenTopped.CheckTransportDisableWeapons` 共用。"

msgid ""
"Allowed Ares' `SW.AuxBuildings` and `SW.NegBuildings` to count building upgrades."
msgstr ""
"允许了 Ares 的 `SW.AuxBuildings` 和 `SW.NegBuildings` 计入建筑加载物。"

msgid "Newly added global settings"
msgstr "新增的全局设定"

Expand Down
32 changes: 32 additions & 0 deletions docs/locale/zh_CN/LC_MESSAGES/New-or-Enhanced-Logics.po
Original file line number Diff line number Diff line change
Expand Up @@ -2799,6 +2799,38 @@ msgstr ""
"默认情况下 AI 所属方只检查它是否拥有能够发射的超级武器并在 106 到 112 "
"个游戏帧的随机间隔内发射它们。这一行为现在可以自定义设置为明确的间隔时间或予以禁用。0 及更小的值会禁用间隔并导致 AI 所属方每帧检查超级武器。"

msgid "Aux technos and TechLevel requirement of superweapon"
msgstr "超级武器的辅助单位和科技等级限制"

msgid ""
"`SW.AuxTechnos` specifies the auxiliary technos without which this super "
"weapon cannot become available. The player has to own at least one techno"
" of any of these types to get access to this super weapon."
msgstr ""
"`SW.AuxTechnos` 指定了在没有它们时超武无法变得可用的辅助单位。玩家至少拥有这些单位中的一种才能获得该超武的使用权。"

msgid ""
"`SW.NegTechnos` specifies the negative auxiliary technos whose presence "
"will cause the super weapon to become unavailable. This super weapon can "
"become available only if the player does not own any techno of any of "
"these types."
msgstr ""
"`SW.NegTechnos` 指定了在存在它们时超武会变得不可用的否决单位,超武仅在玩家没有这些单位中的任意一种时才能变得可用。"

msgid ""
"`SW.TechLevel` specifies the TechLevel that the owner must not fall below"
" in order to use this super weapon. The super weapon becomes available "
"only if the player's TechLevel reaches that level."
msgstr ""
"`SW.TechLevel` 指定了所属方为了能用该超武所不能低于的科技等级。超武仅在玩家所属方的科技达到这一等级时才能变得可用。"

msgid ""
"`SW.TechLevel` does not treat `-1` as a special value. If you want to "
"restrict a super weapon to be available only to AI players, please use "
"`SW.AllowPlayer` and `SW.AllowAI`."
msgstr ""
"`SW.TechLevel` 并不以 `-1` 为特殊值。如果你想要限制一个超级武器仅 AI 玩家可用,请使用 `SW.AllowPlayer` 和 `SW.AllowAI`。"

msgid "Convert TechnoType"
msgstr "单位转换超武"

Expand Down
8 changes: 8 additions & 0 deletions docs/locale/zh_CN/LC_MESSAGES/Whats-New.po
Original file line number Diff line number Diff line change
Expand Up @@ -2688,6 +2688,14 @@ msgstr ""
"现在 `DisableWeapons.Duration` 会使 `Gattling=yes` 的速率降低并停止播放音效,不再干扰目标获取并且可以和"
" Phobos 的 `OpenTopped.CheckTransportDisableWeapons` 共用(by Starkku)"

msgid ""
"Allowed `AuxBuilding` and Ares' `SW.Aux/NegBuildings` to count building upgrades (by Ollerus & NetsuNegi)"
msgstr ""
"允许了 Ares 的 `SW.AuxBuildings` 和 `SW.NegBuildings` 计入建筑加载物(by Ollerus 与 NetsuNegi)"

msgid "[Aux technos and TechLevel requirement of superweapon](New-or-Enhanced-Logics.md#aux-technos-and-techlevel-requirement-of-superweapon) (by NetsuNegi & Ollerus)"
msgstr "[超级武器的辅助单位和科技等级限制](New-or-Enhanced-Logics.md#aux-technos-and-techlevel-requirement-of-superweapon)(by NetsuNegi 与 Ollerus)"

msgid "0.4.0.3"
msgstr "0.4.0.3"

Expand Down
3 changes: 3 additions & 0 deletions src/Ext/House/Hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,9 @@ DEFINE_HOOK(0x7015C9, TechnoClass_Captured_UpdateTracking, 0x6)
if (!I_am_human)
TechnoExt::ChangeOwnerMissionFix(pMe);
}

pThis->Owner->RecheckTechTree = true;
pNewOwner->RecheckTechTree = true;
}

for (const auto& pTrail : pExt->LaserTrails)
Expand Down
10 changes: 10 additions & 0 deletions src/Ext/SWType/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ void SWTypeExt::ExtData::Serialize(T& Stm)
.Process(this->SW_ManualFire)
.Process(this->SW_ShowCameo)
.Process(this->SW_Unstoppable)
.Process(this->SW_AllowPlayer)
.Process(this->SW_AllowAI)
.Process(this->SW_Inhibitors)
.Process(this->SW_AnyInhibitor)
.Process(this->SW_Designators)
Expand All @@ -39,6 +41,9 @@ void SWTypeExt::ExtData::Serialize(T& Stm)
.Process(this->SW_ForbiddenHouses)
.Process(this->SW_AuxBuildings)
.Process(this->SW_NegBuildings)
.Process(this->SW_AuxTechnos)
.Process(this->SW_NegTechnos)
.Process(this->SW_TechLevel)
.Process(this->SW_InitialReady)
.Process(this->SW_PostDependent)
.Process(this->SW_MaxCount)
Expand Down Expand Up @@ -116,6 +121,8 @@ void SWTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
this->SW_ManualFire.Read(exINI, pSection, "SW.ManualFire");
this->SW_ShowCameo.Read(exINI, pSection, "SW.ShowCameo");
this->SW_Unstoppable.Read(exINI, pSection, "SW.Unstoppable");
this->SW_AllowPlayer.Read(exINI, pSection, "SW.AllowPlayer");
this->SW_AllowAI.Read(exINI, pSection, "SW.AllowAI");
this->SW_Inhibitors.Read(exINI, pSection, "SW.Inhibitors");
this->SW_AnyInhibitor.Read(exINI, pSection, "SW.AnyInhibitor");
this->SW_Designators.Read(exINI, pSection, "SW.Designators");
Expand All @@ -126,6 +133,9 @@ void SWTypeExt::ExtData::LoadFromINIFile(CCINIClass* const pINI)
this->SW_ForbiddenHouses = pINI->ReadHouseTypesList(pSection, "SW.ForbiddenHouses", this->SW_ForbiddenHouses);
this->SW_AuxBuildings.Read(exINI, pSection, "SW.AuxBuildings");
this->SW_NegBuildings.Read(exINI, pSection, "SW.NegBuildings");
this->SW_AuxTechnos.Read(exINI, pSection, "SW.AuxTechnos");
this->SW_NegTechnos.Read(exINI, pSection, "SW.NegTechnos");
this->SW_TechLevel.Read(exINI, pSection, "SW.TechLevel");
this->SW_InitialReady.Read(exINI, pSection, "SW.InitialReady");
this->SW_PostDependent.Read(exINI, pSection, "SW.PostDependent");
this->SW_MaxCount.Read(exINI, pSection, "SW.MaxCount");
Expand Down
11 changes: 11 additions & 0 deletions src/Ext/SWType/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ class SWTypeExt
Valueable<bool> SW_ManualFire;
Valueable<bool> SW_ShowCameo;
Valueable<bool> SW_Unstoppable;
Valueable<bool> SW_AllowPlayer;
Valueable<bool> SW_AllowAI;
ValueableVector<TechnoTypeClass*> SW_Inhibitors;
Valueable<bool> SW_AnyInhibitor;
ValueableVector<TechnoTypeClass*> SW_Designators;
Expand All @@ -40,6 +42,9 @@ class SWTypeExt
DWORD SW_ForbiddenHouses;
ValueableVector<BuildingTypeClass*> SW_AuxBuildings;
ValueableVector<BuildingTypeClass*> SW_NegBuildings;
ValueableVector<TechnoTypeClass*> SW_AuxTechnos;
ValueableVector<TechnoTypeClass*> SW_NegTechnos;
Valueable<int> SW_TechLevel;
Valueable<bool> SW_InitialReady;
ValueableIdx<SuperWeaponTypeClass> SW_PostDependent;
Valueable<int> SW_MaxCount;
Expand Down Expand Up @@ -119,6 +124,8 @@ class SWTypeExt
, SW_ManualFire { true }
, SW_ShowCameo { true }
, SW_Unstoppable { false }
, SW_AllowPlayer { true }
, SW_AllowAI { true }
, SW_Inhibitors {}
, SW_AnyInhibitor { false }
, SW_Designators { }
Expand All @@ -129,6 +136,9 @@ class SWTypeExt
, SW_ForbiddenHouses { 0u }
, SW_AuxBuildings {}
, SW_NegBuildings {}
, SW_AuxTechnos {}
, SW_NegTechnos {}
, SW_TechLevel { 0 }
, SW_InitialReady { false }
, SW_PostDependent {}
, SW_MaxCount { -1 }
Expand Down Expand Up @@ -242,5 +252,6 @@ class SWTypeExt
static bool SaveGlobals(PhobosStreamWriter& Stm);

static bool Activate(SuperClass* pSuper, CellStruct cell, bool isPlayer);
static SuperClass* __stdcall IsSuperAvailable(int swIdx, HouseClass* pHouse);

};
77 changes: 52 additions & 25 deletions src/Ext/SWType/SWHelpers.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#include "Body.h"
#include <MessageListClass.h>

#include <Ext/House/Body.h>

// Universal handler of the rolls-weights system
std::vector<int> SWTypeExt::ExtData::WeightedRollsHandler(ValueableVector<float>* rolls, std::vector<ValueableVector<int>>* weights, size_t size)
{
Expand Down Expand Up @@ -169,46 +171,58 @@ std::pair<double, double> SWTypeExt::ExtData::GetLaunchSiteRange(BuildingClass*

bool SWTypeExt::ExtData::IsAvailable(HouseClass* pHouse) const
{
if (pHouse->TechLevel < this->SW_TechLevel)
return false;

const auto pThis = this->OwnerObject();
const int shots = this->SW_Shots;

if (shots >= 0 && HouseExt::ExtMap.Find(pHouse)->SuperExts[pThis->ArrayIndex].ShotCount >= shots)
return false;

if (pHouse->IsControlledByHuman() ? (!this->SW_AllowPlayer) : (!this->SW_AllowAI))
return false;

auto IsTechnoPresent = [pHouse](TechnoTypeClass* pType)
{
const auto pBuildingType = abstract_cast<BuildingTypeClass*, true>(pType);

if (pBuildingType && (!BuildingTypeExt::ExtMap.Find(pBuildingType)->PowersUp_Buildings.empty() || BuildingTypeClass::Find(pBuildingType->PowersUpBuilding)))
return BuildingTypeExt::GetUpgradesAmount(pBuildingType, pHouse) > 0;

return HouseExt::ExtMap.Find(pHouse)->CountOwnedPresentAndLimboed(pType) > 0;
};

// check whether the optional aux building exists
if (pThis->AuxBuilding)
{
if ((BuildingTypeExt::ExtMap.Find(pThis->AuxBuilding)->PowersUp_Buildings.size() > 0 || BuildingTypeClass::Find(pThis->AuxBuilding->PowersUpBuilding))
&& BuildingTypeExt::GetUpgradesAmount(pThis->AuxBuilding, pHouse) <= 0)
Comment thread
Coronia marked this conversation as resolved.
return false;
else if (pHouse->CountOwnedAndPresent(pThis->AuxBuilding) <= 0)
return false;
}
if (pThis->AuxBuilding && !IsTechnoPresent(pThis->AuxBuilding))
return false;

// allow only certain houses, disallow forbidden houses
const auto OwnerBits = 1u << pHouse->Type->ArrayIndex;
const auto ownerBits = 1u << pHouse->Type->ArrayIndex;

if (!(this->SW_RequiredHouses & OwnerBits) || (this->SW_ForbiddenHouses & OwnerBits))
if (!(this->SW_RequiredHouses & ownerBits) || (this->SW_ForbiddenHouses & ownerBits))
return false;

// check that any aux building exist and no neg building
auto IsBuildingPresent = [pHouse](BuildingTypeClass* pType)
{
if (pType)
{
if (BuildingTypeExt::ExtMap.Find(pType)->PowersUp_Buildings.size() > 0 || BuildingTypeClass::Find(pType->PowersUpBuilding))
return BuildingTypeExt::GetUpgradesAmount(pType, pHouse) > 0;
Comment thread
Coronia marked this conversation as resolved.
else
return pHouse->CountOwnedAndPresent(pType) > 0;
}

return false;
};
const auto& auxBuildings = this->SW_AuxBuildings;

if (!auxBuildings.empty() && std::ranges::none_of(auxBuildings, IsTechnoPresent))
return false;

const auto& negBuildings = this->SW_NegBuildings;

if (std::ranges::any_of(negBuildings, IsTechnoPresent))
return false;

const auto& Aux = this->SW_AuxBuildings;
const auto& auxTechnos = this->SW_AuxTechnos;

if (!Aux.empty() && std::none_of(Aux.begin(), Aux.end(), IsBuildingPresent))
if (!auxTechnos.empty() && std::ranges::none_of(auxTechnos, IsTechnoPresent))
return false;

const auto& Neg = this->SW_NegBuildings;
const auto& negTechnos = this->SW_NegTechnos;

if (std::any_of(Neg.begin(), Neg.end(), IsBuildingPresent))
if (std::ranges::any_of(negTechnos, IsTechnoPresent))
return false;

return true;
Expand Down Expand Up @@ -309,3 +323,16 @@ void SWTypeExt::ExtData::PrintMessage(const CSFText& message, HouseClass* pFirer
// print the message
MessageListClass::Instance.PrintMessage(message, RulesClass::Instance->MessageDelay, color);
}

SuperClass* __stdcall SWTypeExt::IsSuperAvailable(int swIdx, HouseClass* pHouse)
{
if (const auto pSuper = pHouse->Supers.GetItemOrDefault(swIdx))
{
const auto pExt = SWTypeExt::ExtMap.Find(pSuper->Type);

if (pExt->IsAvailable(pHouse))
return pSuper;
}

return nullptr;
}
Loading
Loading