diff --git a/CREDITS.md b/CREDITS.md index 31dd562065..3ecead2d75 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -571,6 +571,7 @@ This page lists all the individual contributions to the project by their author. - Customize ivan bomb visibility - Fix the issue where vehicles always finish turret resetting first before turn to a new attack target, now it should turn to new target immediately - Fixed a bug that computer player record cannot be log normally in non English mode + - Cloak Enhancement - **Apollo** - Translucent SHP drawing patches - **ststl**: - Customizable `ShowTimer` priority of superweapons diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index c56310bfc9..343dae63eb 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -2579,6 +2579,26 @@ Ammo.DeployUnlockMinimumAmount=-1 ; integer Ammo.DeployUnlockMaximumAmount=-1 ; integer ``` +### Cloak Enhancement + +- When unit start cloak or stop cloaking, an animation can play on his location + - You can also set whether cloak units kick out parasites + +In `rulesmd.ini`: +```ini +[General] +Cloak.KickOutParasite=false ; boolean + +[AudioVisual] +CloakAnims= ; List of Animation +DecloakAnims= ; List of Animation + +[SOMETECHNO] +CloakAnims= ; List of Animation, default to [AudioVisual] -> CloakAnims +DecloakAnims= ; List of Animation, default to [AudioVisual] -> DecloakAnims +Cloak.KickOutParasite= ; boolean, default to [General] -> Cloak.KickOutParasite +``` + ### Custom hover vehicles shutdown drowning death - `HoverDrownable` allows customization of whether hover vehicles will drown and die when deactivated on water zone. diff --git a/docs/Whats-New.md b/docs/Whats-New.md index a3ebd531e7..68b6030d64 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -426,6 +426,7 @@ HideShakeEffects=false ; boolean - [Roof production anim](New-or-Enhanced-Logics.md#roof-production-anim) (by Noble_Fish) - [Customize whether the unit exits from the roof](Fixed-or-Improved-Logics.md#customize-whether-the-unit-exits-from-the-roof) (by Noble_Fish) - [Customize whether the unit can be detected by psychic detector](Fixed-or-Improved-Logics.md#customize-whether-the-unit-can-be-detected-by-psychic-detector) (by Noble_Fish) +- Cloak Enhancement (by NetsuNegi) #### Vanilla fixes: - Fixed the bug where a building with `Factory=BuildingType` owned by the AI did not play `ProductionAnim` when placing a produced building (by Noble_Fish) diff --git a/docs/locale/zh_CN/LC_MESSAGES/CREDITS.po b/docs/locale/zh_CN/LC_MESSAGES/CREDITS.po index 21043cea94..af6dc40f4f 100644 --- a/docs/locale/zh_CN/LC_MESSAGES/CREDITS.po +++ b/docs/locale/zh_CN/LC_MESSAGES/CREDITS.po @@ -1903,6 +1903,10 @@ msgid "" "in non English mode" msgstr "修复了非英文模式下,电脑玩家的战绩数据无法正常录入日志文件的bug" +msgid "" +msgid "Cloak Enhancement" +msgstr "隐形增强" + msgid "**Apollo** - Translucent SHP drawing patches" msgstr "**Apollo** - 半透明 SHP 绘制补丁" diff --git a/docs/locale/zh_CN/LC_MESSAGES/New-or-Enhanced-Logics.po b/docs/locale/zh_CN/LC_MESSAGES/New-or-Enhanced-Logics.po index 86be490772..75693ac6dc 100644 --- a/docs/locale/zh_CN/LC_MESSAGES/New-or-Enhanced-Logics.po +++ b/docs/locale/zh_CN/LC_MESSAGES/New-or-Enhanced-Logics.po @@ -5400,6 +5400,16 @@ msgstr "" "`Ammo.DeployUnlockMinimumAmount` & `Ammo.DeployUnlockMaximumAmount` " "分别设定载具启用部署功能所需的最低与最高弹药量阈值,负值表示禁用检查。" +msgid "Cloak Enhancement" +msgstr "隐形增强" + +msgid "When unit start cloak or stop cloaking, " +"an animation can play on his location" +msgstr "当单位开始或停止隐形时,可以在其位置播放动画" + +msgid "You can also set whether cloak units kick out parasites" +msgstr "您也可以设置隐形单位是否踢出寄生者" + msgid "Custom hover vehicles shutdown drowning death" msgstr "自定义悬浮载具溺死" diff --git a/docs/locale/zh_CN/LC_MESSAGES/Whats-New.po b/docs/locale/zh_CN/LC_MESSAGES/Whats-New.po index dc43acb2cf..508ac00dc4 100644 --- a/docs/locale/zh_CN/LC_MESSAGES/Whats-New.po +++ b/docs/locale/zh_CN/LC_MESSAGES/Whats-New.po @@ -864,6 +864,9 @@ msgid "" msgstr "" "[修改弹药弹头](New-or-Enhanced-Logics.md#modify-ammo-on-impact)(by FS-21)" +msgid "Cloak Enhancement (by NetsuNegi)" +msgstr "隐形增强(by NetsuNegi)" + msgid "Vanilla fixes:" msgstr "原版问题修复:" diff --git a/src/Ext/Rules/Body.cpp b/src/Ext/Rules/Body.cpp index 856b0991a0..bc86659c57 100644 --- a/src/Ext/Rules/Body.cpp +++ b/src/Ext/Rules/Body.cpp @@ -260,6 +260,10 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI) this->ROF_RandomDelay.Read(exINI, GameStrings::CombatDamage, "ROF.RandomDelay"); + this->CloakAnims.Read(exINI, GameStrings::AudioVisual, "CloakAnims"); + this->DecloakAnims.Read(exINI, GameStrings::AudioVisual, "DecloakAnims"); + this->Cloak_KickOutParasite.Read(exINI, GameStrings::General, "Cloak.KickOutParasite"); + this->DisplayIncome.Read(exINI, GameStrings::AudioVisual, "DisplayIncome"); this->DisplayIncome_Delay.Read(exINI, GameStrings::AudioVisual, "DisplayIncome.Delay"); if (!this->DisplayIncome_Delay) @@ -1109,6 +1113,9 @@ void RulesExt::ExtData::Serialize(T& Stm) .Process(this->KeepAlive_Buildings) .Process(this->KeepAlive_Defenses) .Process(this->AutoTarget_InsignificantWhenMindControlled) + .Process(this->CloakAnims) + .Process(this->DecloakAnims) + .Process(this->Cloak_KickOutParasite) ; } diff --git a/src/Ext/Rules/Body.h b/src/Ext/Rules/Body.h index 707de53c9b..993f1ca9a7 100644 --- a/src/Ext/Rules/Body.h +++ b/src/Ext/Rules/Body.h @@ -546,6 +546,10 @@ class RulesExt Valueable KeepAlive_Defenses; Valueable AutoTarget_InsignificantWhenMindControlled; + ValueableVector CloakAnims; + ValueableVector DecloakAnims; + Valueable Cloak_KickOutParasite; + ExtData(RulesClass* OwnerObject) : Extension(OwnerObject) , Storage_TiberiumIndex { -1 } , HarvesterDumpAmount { 0.0f } @@ -1028,6 +1032,10 @@ class RulesExt , KeepAlive_Defenses { true } , AutoTarget_InsignificantWhenMindControlled { true } + + , CloakAnims {} + , DecloakAnims {} + , Cloak_KickOutParasite { false } { } virtual ~ExtData() = default; diff --git a/src/Ext/Techno/Hooks.cpp b/src/Ext/Techno/Hooks.cpp index 6d0a24caab..0dcfa8e9da 100644 --- a/src/Ext/Techno/Hooks.cpp +++ b/src/Ext/Techno/Hooks.cpp @@ -1369,6 +1369,56 @@ DEFINE_HOOK(0x708FC0, TechnoClass_ResponseMove_Pickup, 0x5) return 0; } +DEFINE_HOOK(0x7037F7, TechnoClass_Cloak_CloakAnim, 0x5) +{ + GET(TechnoClass* const, pThis, ESI); + + const auto pTypeExt = TechnoExt::Fetch(pThis)->TypeExtData; + const auto& cloakAnims = !pTypeExt->CloakAnims.empty() ? pTypeExt->CloakAnims : RulesExt::Global()->CloakAnims; + AnimExt::CreateRandomAnim(cloakAnims, pThis->GetCenterCoords(), pThis, pThis->Owner, true); + return 0; +} + +DEFINE_HOOK(0x703736, TechnoClass_Uncloak_DecloakAnim, 0x6) +{ + GET(TechnoClass* const, pThis, ESI); + + const auto pTypeExt = TechnoExt::Fetch(pThis)->TypeExtData; + const auto& decloakAnims = !pTypeExt->DecloakAnims.empty() ? pTypeExt->DecloakAnims : RulesExt::Global()->DecloakAnims; + AnimExt::CreateRandomAnim(decloakAnims, pThis->GetCenterCoords(), pThis, pThis->Owner, true); + return 0; +} + +DEFINE_HOOK(0x4D9992, FootClass_PointerGotInvalid_Parasite, 0x7) +{ + enum { SkipGameCode = 0x4D99D3 }; + + GET(FootClass*, pThis, ESI); + GET(AbstractClass*, pAbstract, EDI); + GET(FootClass*, pParasiteOwner, EAX); + GET(bool, removed, EBX); + + if (pParasiteOwner == pAbstract && (!pParasiteOwner->Health || !Make_Global(0xA8ED5C))) + { + pThis->ParasiteEatingMe = nullptr; + return SkipGameCode; + } + + if (!removed) + { + const auto pTypeExt = TechnoExt::Fetch(pThis)->TypeExtData; + removed = pTypeExt->Cloak_KickOutParasite.Get(RulesExt::Global()->Cloak_KickOutParasite); + } + + if (pParasiteOwner && pParasiteOwner->Health > 0) + pParasiteOwner->ParasiteImUsing->PointerExpired(pAbstract, removed); + + if (pThis == pAbstract && removed) + pThis->ParasiteEatingMe = nullptr; + + return SkipGameCode; +} + // Handle disabling deploy action & cursor for vehicles and aircraft. // Possible hook locations for other types in same function: Building: 0x700E3F, Infantry: 0x700E2C DEFINE_HOOK(0x7010C1, TechnoClass_CanShowDeployCursor_UnitsAndAircraft, 0x5) diff --git a/src/Ext/TechnoType/Body.cpp b/src/Ext/TechnoType/Body.cpp index d020ca21a1..ae05a36241 100644 --- a/src/Ext/TechnoType/Body.cpp +++ b/src/Ext/TechnoType/Body.cpp @@ -1195,6 +1195,10 @@ void TechnoTypeExt::LoadFromINIFile(CCINIClass* const pINI) this->ExitThroughRoof.Read(exINI, pSection, "ExitThroughRoof"); this->PsychicDetectable.Read(exINI, pSection, "PsychicDetectable"); + this->CloakAnims.Read(exINI, pSection, "CloakAnims"); + this->DecloakAnims.Read(exINI, pSection, "DecloakAnims"); + this->Cloak_KickOutParasite.Read(exINI, pSection, "Cloak.KickOutParasite"); + // Ares 0.2 this->RadarJamRadius.Read(exINI, pSection, "RadarJamRadius"); @@ -1823,6 +1827,10 @@ void TechnoTypeExt::Serialize(T& Stm) .Process(this->ExitThroughRoof) .Process(this->PsychicDetectable) + .Process(this->CloakAnims) + .Process(this->DecloakAnims) + .Process(this->Cloak_KickOutParasite) + // Ares 0.2 .Process(this->RadarJamRadius) diff --git a/src/Ext/TechnoType/Body.h b/src/Ext/TechnoType/Body.h index a62e54a9b2..c7c2ba9ed6 100644 --- a/src/Ext/TechnoType/Body.h +++ b/src/Ext/TechnoType/Body.h @@ -435,6 +435,10 @@ class TechnoTypeExt : public ObjectTypeExt Nullable ExitThroughRoof; Valueable PsychicDetectable; + ValueableVector CloakAnims; + ValueableVector DecloakAnims; + Nullable Cloak_KickOutParasite; + // Ares 0.2 Valueable RadarJamRadius; @@ -843,6 +847,10 @@ class TechnoTypeExt : public ObjectTypeExt , ExitThroughRoof {} + , CloakAnims {} + , DecloakAnims {} + , Cloak_KickOutParasite {} + // Ares 0.2 , RadarJamRadius { 0 }