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
2 changes: 2 additions & 0 deletions CREDITS.md
Original file line number Diff line number Diff line change
Expand Up @@ -685,6 +685,8 @@ This page lists all the individual contributions to the project by their author.
- Fix an issue that the AI would set anger towards friendly houses, causing it to act stupidly
- Fix an issue that the AI would look for the first house in the array as an enemy instead of the nearest one when there were no enemies
- `AllowBerzerkOnAllies`
- Allow techno conversion working on buildings
- Fixed the issue that multiple attributes such as cloaking and sensor would not be updated correctly in techno conversion
- **solar-III (凤九歌)**
- Target scanning delay customization (documentation)
- Skip target scanning function calling for unarmed technos (documentation)
Expand Down
2 changes: 2 additions & 0 deletions docs/Fixed-or-Improved-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,8 @@ This page describes all ingame logics that are fixed or improved in Phobos witho
- Fixed the issue that technos cannot spawn survivors due to non-probabilistic reasons when the tech type was destroyed.
- Fixed the bug that vehicle survivor can spawn on wrong position when transport has been destroyed.
- Fixed the bug that building with `Explodes=yes` use Ares's rubble logic will cause it's owner cannot defeat normally.
- Allow techno conversion working on buildings (Convert building to a bigger one is not recommended, as this may lead to problems).
- Fixed the issue that multiple attributes such as cloaking and sensor would not be updated correctly in techno conversion.

## Newly added global settings

Expand Down
2 changes: 2 additions & 0 deletions docs/Whats-New.md
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,8 @@ New:
- [Return warhead](New-or-Enhanced-Logics.md#return-warhead) (by Ollerus)
- [`AllowBerzerkOnAllies`](Fixed-or-Improved-Logics.md#berzerk-on-allies) (by TaranDahl)
- Customize whether warhead can be used to targeting ironcurtained technos or not (by NetsuNegi)
- Allow techno conversion working on buildings (by TaranDahl)
- Fixed the issue that multiple attributes such as cloaking and sensor would not be updated correctly in techno conversion (by TaranDahl)

Vanilla fixes:
- Fixed sidebar not updating queued unit numbers when adding or removing units when the production is on hold (by CrimRecya)
Expand Down
4 changes: 2 additions & 2 deletions src/Ext/SWType/FireSuperWeapon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,8 +318,8 @@ void SWTypeExt::ExtData::ApplySWNext(SuperClass* pSW, const CellStruct& cell)

void SWTypeExt::ExtData::ApplyTypeConversion(SuperClass* pSW)
{
for (const auto pTargetFoot : FootClass::Array)
TypeConvertGroup::Convert(pTargetFoot, this->Convert_Pairs, pSW->Owner);
for (const auto pTarget : TechnoClass::Array)
TypeConvertGroup::Convert(pTarget, this->Convert_Pairs, pSW->Owner);
}

void SWTypeExt::ExtData::HandleEMPulseLaunch(SuperClass* pSW, const CellStruct& cell) const
Expand Down
163 changes: 135 additions & 28 deletions src/Ext/Techno/Body.Update.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -947,10 +947,9 @@ void TechnoExt::ExtData::UpdateTypeData(TechnoTypeClass* pCurrentType)
bool hasTemporal = false;
bool hasAirstrike = false;
bool hasLocomotor = false;
bool hasParasite = false;

auto checkWeapon = [&maxCapture, &infiniteCapture, &hasTemporal,
&hasAirstrike, &hasLocomotor, &hasParasite](WeaponTypeClass* pWeaponType)
&hasAirstrike, &hasLocomotor](WeaponTypeClass* pWeaponType)
{
if (!pWeaponType)
return;
Expand All @@ -974,9 +973,6 @@ void TechnoExt::ExtData::UpdateTypeData(TechnoTypeClass* pCurrentType)

if (pWH->IsLocomotor)
hasLocomotor = true;

if (pWH->Parasite)
hasParasite = true;
};

for (int i = 0; i < TechnoTypeClass::MaxWeapons; i++)
Expand Down Expand Up @@ -1087,31 +1083,28 @@ void TechnoExt::ExtData::UpdateTypeData(TechnoTypeClass* pCurrentType)
barrelRecoil.HoldFrames = barrelAnimData.HoldFrames;
}

// Only FootClass* can use this.
if (const auto pFoot = abstract_cast<FootClass*, true>(pThis))
{
auto& pParasiteImUsing = pFoot->ParasiteImUsing;
if (pThis->Cloakable && !pCurrentType->Cloakable)
pThis->Uncloak(true);
pThis->Cloakable = pCurrentType->Cloakable;

if (hasParasite)
{
if (!pParasiteImUsing)
{
// Rebuild a ParasiteClass
pParasiteImUsing = GameCreate<ParasiteClass>(pFoot);
}
}
else if (pParasiteImUsing)
{
if (pParasiteImUsing->Victim)
{
// Release of victims.
pParasiteImUsing->ExitUnit();
}
if (pOldType->BombSight)
BombListClass::Instance.RemoveDetector(pThis);
if (pCurrentType->BombSight)
BombListClass::Instance.AddDetector(pThis);

// Delete it
GameDelete(pParasiteImUsing);
pParasiteImUsing = nullptr;
}
// TODO : Fix this
//pThis->UpdateSight(0, 0, 0, 0, 0);
//MapClass::Instance.RevealArea3(&pThis->Location, 0, pThis->LastSightRange + 3, 0);

if (pOldType->GapGenerator)
pThis->DestroyGap();
if (pCurrentType->GapGenerator)
{
auto temp = pOldType->GapRadiusInCells;
pThis->GapRadius = pCurrentType->GapRadiusInCells;
pOldType->GapRadiusInCells = pCurrentType->GapRadiusInCells;
pThis->CreateGap();
pOldType->GapRadiusInCells = temp;
}

// handle AutoTargetOwnPosition
Expand Down Expand Up @@ -1226,6 +1219,57 @@ void TechnoExt::ExtData::UpdateTypeData_Foot()
pThis->ClearDisguise();
}

bool hasParasite = false;

auto checkWeapon = [&hasParasite](WeaponTypeClass* pWeaponType)
{
if (!pWeaponType)
return;

const auto pWH = pWeaponType->Warhead;

if (pWH->Parasite)
hasParasite = true;
};

for (int i = 0; i < TechnoTypeClass::MaxWeapons; i++)
{
checkWeapon(pThis->GetWeapon(i)->WeaponType);
}

auto& pParasiteImUsing = pThis->ParasiteImUsing;

if (hasParasite)
{
if (!pParasiteImUsing)
{
// Rebuild a ParasiteClass
pParasiteImUsing = GameCreate<ParasiteClass>(pThis);
}
}
else if (pParasiteImUsing)
{
if (pParasiteImUsing->Victim)
{
// Release of victims.
pParasiteImUsing->ExitUnit();
}

// Delete it
GameDelete(pParasiteImUsing);
pParasiteImUsing = nullptr;
}

if (pOldType->SensorsSight)
pThis->RemoveSensorsAt(CellStruct::Empty);
if (pCurrentType->SensorsSight)
{
auto temp = pOldType->SensorsSight;
pOldType->SensorsSight = pCurrentType->SensorsSight;
pThis->AddSensorsAt(CellStruct::Empty);
pOldType->SensorsSight = temp;
}

if (abs != AbstractType::Aircraft)
{
auto const pLocomotorType = pCurrentType->Locomotor;
Expand Down Expand Up @@ -1313,6 +1357,69 @@ void TechnoExt::ExtData::UpdateTypeData_Foot()
this->PreviousType = nullptr;
}

void TechnoExt::ExtData::UpdateTypeData_Building()
{
auto const pThis = static_cast<BuildingClass*>(this->OwnerObject());
auto const pOldType = static_cast<BuildingTypeClass*>(this->PreviousType);
auto const pNewType = static_cast<BuildingTypeClass*>(this->TypeExtData->OwnerObject());

pThis->Type = pOldType;

pThis->DestroyNthAnim(BuildingAnimSlot::All);

// Skip audio related

// Maybe buggy
auto dockNumber = std::max(pNewType->NumberOfDocks, 1);
pThis->SetLinkCount(dockNumber);

if (pNewType->LoadBuildup())
pThis->HasBuildUp = true;
else
pThis->AI_Sellable = false;

// Skip SecretLab related

HouseClass* const pOwner = pThis->Owner;

// TODO : Handle addon logics ()

if (!pThis->InLimbo)
pOwner->RegisterLoss(pThis, false);
pOwner->RemoveTracking(pThis);

if (pThis->Factory)
pThis->Factory->AbandonProduction();

// Maybe buggy
if (!pThis->InLimbo)
{
auto pCrd = pThis->Location;
pThis->Limbo();
pThis->Type = pNewType;
pThis->ActuallyPlacedOnMap = false;
++Unsorted::ScenarioInit;
pThis->Unlimbo(pCrd, DirType::North);
--Unsorted::ScenarioInit;
pThis->Place(false);
pThis->Mark(MarkType::Change);
}

pThis->Type = pNewType;

pOwner->AddTracking(pThis);
if (!pThis->InLimbo)
pOwner->RegisterGain(pThis, false);
pOwner->RecheckTechTree = true;

pThis->Ammo = Math::min(pThis->Ammo, pNewType->Ammo);

pThis->SecondaryFacing.SetROT(pNewType->ROT);
pThis->PrimaryFacing.SetROT(pNewType->ROT);

this->PreviousType = nullptr;
}

void TechnoExt::ExtData::UpdateLaserTrails()
{
if (this->LaserTrails.size() <= 0)
Expand Down
Loading