From 823fa4734ef83e9f2ec395d390d48ee31448d289 Mon Sep 17 00:00:00 2001 From: FS-21 Date: Thu, 31 Mar 2022 19:29:04 +0200 Subject: [PATCH 01/19] New actions 127 to 133 Ai trigger manipulation. More information in the documentation --- README.md | 2 +- docs/New-or-Enhanced-Logics.md | 81 +++++++++++++ docs/Whats-New.md | 1 + src/Commands/ObjectInfo.h | 17 +++ src/Ext/House/Body.cpp | 149 ++++++++++++++++++++++++ src/Ext/House/Body.h | 2 + src/Ext/Script/Body.cpp | 202 +++++++++++++++++++++++++++++++++ src/Ext/Script/Body.h | 15 ++- src/Ext/Team/Body.cpp | 2 + src/Ext/Team/Body.h | 4 + 10 files changed, 473 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b7b417a8a4..4618c864ed 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ Credits - **secsome (SEC-SOME)** - debug info dump hotkey, refactoring & porting of Ares helper code, introducing more Ares-derived stuff, disguise removal warhead, Mind Control removal warhead, Mind Control enhancement, shields, AnimList.PickRandom, MoveToCell fix, unlimited waypoints, Build At trigger action buildup anim fix, Undeploy building into a unit plays `EVA_NewRallyPointEstablished` fix, custom ore gathering anim, TemporaryClass related crash, Retry dialog on mission failure, Default disguise for individual InfantryTypes, PowerPlant Enhancer, SaveGame Trigger Action, QuickSave command, Numeric variables, Custom gravity for projectiles, Retint map actions bugfix, Sharpnel enhancement, Vanilla map preview reading bugfix - **Otamaa (Fahroni, BoredEXE)** - help with CellSpread, ported and fixed custom RadType code, togglable ElectricBolt bolts, customizable Chrono Locomotor properties per TechnoClass, DebrisMaximums fixes, Anim-to-Unit, NotHuman anim sequences improvements, Customizable OpenTopped Properties, hooks for ScriptType Actions 92 & 93, ore stage threshold for `HideIfNoOre`, occupied building `MuzzleFlashX` bugfix,`EnemyUIName=` for other TechnoTypes, TerrainType `DestroyAnim` & `DestroySound`, Laser trails for VoxelAnims - **E1 Elite** - TileSet 255 and above bridge repair fix -- **FS-21** - Dump Object Info enhancements, Powered.KillSpawns, Spawner.LimitRange, ScriptType Actions 71 to 113, MC deployer fixes, help with docs, Automatic Passenger Deletion, Fire SW At Location Trigger Action, Fire SW At Waypoint Trigger Action, Kill Object Automatically, Customize resource storage, Override Uncloaked Underwater attack behavior, AI Aircraft docks fix, Shared Ammo +- **FS-21** - Dump Object Info enhancements, Powered.KillSpawns, Spawner.LimitRange, ScriptType Actions 71 to 113 & 127 to 133, MC deployer fixes, help with docs, Automatic Passenger Deletion, Fire SW At Location Trigger Action, Fire SW At Waypoint Trigger Action, Kill Object Automatically, Customize resource storage, Override Uncloaked Underwater attack behavior, AI Aircraft docks fix, Shared Ammo - **AutoGavy** - interceptor logic, Warhead critical hit logic, Customize resource storage - **ChrisLv_CN** - interceptor logic, LaserTrails, laser fixes, general assistance (work relicensed under [following permission](images/ChrisLv-relicense.png)) - **Xkein** - general assistance, YRpp edits diff --git a/docs/New-or-Enhanced-Logics.md b/docs/New-or-Enhanced-Logics.md index ebb0d63870..de1b052c88 100644 --- a/docs/New-or-Enhanced-Logics.md +++ b/docs/New-or-Enhanced-Logics.md @@ -1170,6 +1170,87 @@ In `aimd.ini`: x=113,n ; where 0 > n <= 100 ``` +### `127` Set Side Index For Managing AI Triggers + +- Set the side index for enabling and disabling triggers. +0 means any side. + +In `aimd.ini`: +```ini +[SOMESCRIPTTYPE] ; ScriptType +x=127,n ; integer, where 0 > n, default -1 +``` + +### `128` Set House Index For Managing AI Triggers + +- Set the House index for enabling and disabling triggers. The indexes aren't the ones used in [Countries], these are internal in-game House indexes. + +In `aimd.ini`: +```ini +[SOMESCRIPTTYPE] ; ScriptType +x=128,n ; integer +``` + +- The possible argument values are: + +| *Argument* | *Description* | +| :--------: | :-------------------------------------------: | +| 4475-4482 | Multiplayer start location indexes | +| 8997 | Special case that returns the house index of the Team object | +| >= 0 | House index. Neutral houses can be used | +| -1 | Random non-neutral House | +| -2 | Find the first Neutral house available | +| -3 | Random Human Player alive | + +### `129` Enable Or Disable All AI Triggers + +- All AI Triggers will be enabled or disabled. +You must set the affected side with Action 127 and House with Action 128. + +In `aimd.ini`: +```ini +[SOMESCRIPTTYPE] ; ScriptType +x=129,n ; integer, 1 == enable, 0 == disable +``` + +### `130` Enable AI Triggers From List + +- When executed this action enable all AI Trigger Types from the selected list in `AITriggersList`. The second parameter is a 0-based index from the new section `AITriggersList` explained below. + +In `aimd.ini`: +```ini +[SOMESCRIPTTYPE] ; ScriptType +x=130,n +``` + +The second parameter is a 0-based index for the `AITriggersList` section that specifies the list of possible `AITriggerTypes` that can be evaluated. The new `AITriggersList` section must be declared in `rulesmd.ini` for making this script work: + +In `rulesmd.ini`: +```ini +[AITriggersList] ; List of AITriggerTypes lists +0=SOMEAITRIGGERTYPE,SOMEOTHERAITRIGGERTYPE,SAMPLETRIGGERTYPE +1=ANOTHERTRIGGERTYPE,YETANOTHERTRIGGERTYPE +; ... +``` + +### `131` Disable AI Triggers From List + +- Works silimar to the Action 130. When executed this action disable all AI Trigger Types from the selected list in `AITriggersList`. The second parameter is a 0-based index from the new section `AITriggersList`. + +### `132` Enable AI Triggers If Contains Any Objects From the List + +- When executed this action all AI Trigger Types that contains any unit of the selected list in `AITargetTypes` will be enabled. The second parameter is a 0-based index from the new section `AITargetTypes`. + +In `aimd.ini`: +```ini +[SOMESCRIPTTYPE] ; ScriptType +x=132,n +``` + +### `133` Disable AI Triggers If Contains Any Objects From the List + +- Works silimar to the Action 132. When executed this action all AI Trigger Types that contains any unit of the selected list in `AITargetTypes` will be disabled. The second parameter is a 0-based index from the new section `AITargetTypes`. + ### `500 - 523` Edit Variable - Operate a variable's value - The variable's value type is int16 instead of int32 in trigger actions for some reason, which means it ranges from -2^15 to 2^15-1. diff --git a/docs/Whats-New.md b/docs/Whats-New.md index 9235b48eee..923c83ce0a 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -250,6 +250,7 @@ New: - Script Action 111 that un-register Team success, is just the opposite effect of Action 49 (by FS-21) - Script Action 112 to regroup temporarily around the Team Leader (by FS-21) - Script Action 113 to Randomly Skip Next Action (by FS-21) +- Script Action 127 to 133 for new AI ways for enabling & disabling AI Triggers (by FS-21) - ObjectInfo now shows current Target and AI Trigger data (by FS-21) - Shield absorption and passthrough customization (by Morton) - Limbo Delivery of buildings (by Morton) diff --git a/src/Commands/ObjectInfo.h b/src/Commands/ObjectInfo.h index d21bbb17fb..7a01bb2434 100644 --- a/src/Commands/ObjectInfo.h +++ b/src/Commands/ObjectInfo.h @@ -162,6 +162,14 @@ class ObjectInfoCommandClass : public PhobosCommandClass if (pFoot->BelongsToATeam()) { auto pTeam = pFoot->Team; + //DEBUG: DELETE THESE LINES BEFORE A FUTURE MERGE INTO DEVELOP !!! + //ScriptExt::ManageTriggersFromList(nullptr, 0, false); + Debug::Log("List of available Triggers:\n"); + for (int i = 0; i < AITriggerTypeClass::Array->Count; i++) + { + auto pTrigger = AITriggerTypeClass::Array->GetItem(i); + Debug::Log("[%d] = %s [IsEnabled: %d] [SideIdx: %d] [HouseIdx: %d] [Curr: %f Min: %f, Max %f]\n", i, pTrigger->ID, pTrigger->IsEnabled, pTrigger->SideIndex, pTrigger->HouseIndex, pTrigger->Weight_Current, pTrigger->Weight_Minimum, pTrigger->Weight_Maximum); + } auto pTeamType = pFoot->Team->Type; bool found = false; @@ -271,6 +279,15 @@ class ObjectInfoCommandClass : public PhobosCommandClass append("Current Shield HP = (%d / %d)\n", pShieldData->GetHP(), pTypeShieldData->ShieldType->Strength); } + //DEBUG: DELETE THESE LINES BEFORE A FUTURE MERGE INTO DEVELOP !!! + //ScriptExt::ManageTriggersFromList(nullptr, 0, true); + Debug::Log("List of available Triggers:\n"); + for (int i = 0; i < AITriggerTypeClass::Array->Count; i++) + { + auto pTrigger = AITriggerTypeClass::Array->GetItem(i); + Debug::Log("[%d] = %s [IsEnabled: %d] [SideIdx: %d] [HouseIdx: %d] [Curr: %f Min: %f, Max %f]\n", i, pTrigger->ID, pTrigger->IsEnabled, pTrigger->SideIndex, pTrigger->HouseIndex, pTrigger->Weight_Current, pTrigger->Weight_Minimum, pTrigger->Weight_Maximum); + } + display(); }; diff --git a/src/Ext/House/Body.cpp b/src/Ext/House/Body.cpp index e22e584eed..4715653e42 100644 --- a/src/Ext/House/Body.cpp +++ b/src/Ext/House/Body.cpp @@ -82,6 +82,155 @@ HouseClass* HouseExt::GetHouseKind(OwnerHouseKind const kind, bool const allowRa return pDefault; } } + +int HouseExt::GetHouseIndex(int param, TeamClass* pTeam = nullptr, TActionClass* pTAction = nullptr) +{ + if ((pTeam && pTAction) || (param == 8997 && !pTeam && !pTAction)) + return -1; + + int houseIdx = -1; + std::vector housesListIdx; + + // Transtale the Multiplayer index into a valid index for the HouseClass array + if (param >= HouseClass::PlayerAtA && param <= HouseClass::PlayerAtH) + { + switch (param) + { + case HouseClass::PlayerAtA: + houseIdx = 0; + break; + + case HouseClass::PlayerAtB: + houseIdx = 1; + break; + + case HouseClass::PlayerAtC: + houseIdx = 2; + break; + + case HouseClass::PlayerAtD: + houseIdx = 3; + break; + + case HouseClass::PlayerAtE: + houseIdx = 4; + break; + + case HouseClass::PlayerAtF: + houseIdx = 5; + break; + + case HouseClass::PlayerAtG: + houseIdx = 6; + break; + + case HouseClass::PlayerAtH: + houseIdx = 7; + break; + + default: + break; + } + + if (houseIdx >= 0) + { + HouseClass* pHouse = HouseClass::Array->GetItem(houseIdx); + + if (!pHouse->Defeated + && !pHouse->IsObserver() + && !pHouse->Type->MultiplayPassive) + { + return houseIdx; + } + } + + return -1; + } + + // Special case that returns the house index of the TeamClass object or the Trigger Action + if (param == 8997) + { + return (pTeam ? pTeam->Owner->ArrayIndex : pTAction->TeamType->Owner->ArrayIndex); + } + + // Positive index values check. Includes any kind of House + if (param >= 0) + { + if (param < HouseClass::Array->Count) + { + HouseClass* pHouse = HouseClass::Array->GetItem(param); + + if (!pHouse->Defeated + && !pHouse->IsObserver()) + { + return houseIdx; + } + } + + return -1; + } + + // Special cases + switch (param) + { + case -1: + // Random non-neutral + for (auto pHouse : *HouseClass::Array) + { + if (!pHouse->Defeated + && !pHouse->IsObserver() + && !pHouse->Type->MultiplayPassive) + { + housesListIdx.push_back(pHouse->ArrayIndex); + } + } + + if (housesListIdx.size() > 0) + houseIdx = housesListIdx.at(ScenarioClass::Instance->Random.RandomRanged(0, housesListIdx.size() - 1)); + else + return -1; + + break; + + case -2: + // Find first Neutral house + for (auto pHouseNeutral : *HouseClass::Array) + { + if (pHouseNeutral->IsNeutral()) + { + houseIdx = pHouseNeutral->ArrayIndex; + break; + } + } + + break; + + case -3: + // Random Human Player + for (auto pHouse : *HouseClass::Array) + { + if (pHouse->ControlledByHuman() + && !pHouse->Defeated + && !pHouse->IsObserver()) + { + housesListIdx.push_back(pHouse->ArrayIndex); + } + } + + if (housesListIdx.size() > 0) + houseIdx = housesListIdx.at(ScenarioClass::Instance->Random.RandomRanged(0, housesListIdx.size() - 1)); + else + return -1; + + break; + + default: + break; + } + + return houseIdx; +} + // ============================= // load / save diff --git a/src/Ext/House/Body.h b/src/Ext/House/Body.h index fa9d00f530..acd05d4746 100644 --- a/src/Ext/House/Body.h +++ b/src/Ext/House/Body.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include #include @@ -51,4 +52,5 @@ class HouseExt static int ActiveHarvesterCount(HouseClass* pThis); static int TotalHarvesterCount(HouseClass* pThis); static HouseClass* GetHouseKind(OwnerHouseKind kind, bool allowRandom, HouseClass* pDefault, HouseClass* pInvoker = nullptr, HouseClass* pVictim = nullptr); + static int GetHouseIndex(int param, TeamClass* pTeam, TActionClass* pTAction); }; \ No newline at end of file diff --git a/src/Ext/Script/Body.cpp b/src/Ext/Script/Body.cpp index 9d52c081dc..fd28d8ab3f 100644 --- a/src/Ext/Script/Body.cpp +++ b/src/Ext/Script/Body.cpp @@ -196,6 +196,27 @@ void ScriptExt::ProcessAction(TeamClass* pTeam) case PhobosScripts::RandomSkipNextAction: ScriptExt::SkipNextAction(pTeam, -1); break; + case PhobosScripts::SetSideIdxForManagingTriggers: + ScriptExt::SetSideIdxForManagingTriggers(pTeam, -1); + break; + case PhobosScripts::SetHouseIdxForManagingTriggers: + ScriptExt::SetHouseIdxForManagingTriggers(pTeam, 1000000); + break; + case PhobosScripts::ManageAllAITriggers: + ScriptExt::ManageAITriggers(pTeam, -1); + break; + case PhobosScripts::EnableTriggersFromList: + ScriptExt::ManageTriggersFromList(pTeam, -1, true); + break; + case PhobosScripts::DisableTriggersFromList: + ScriptExt::ManageTriggersFromList(pTeam, -1, false); + break; + case PhobosScripts::EnableTriggersWithObjects: + ScriptExt::ManageTriggersWithObjects(pTeam, -1, true); + break; + case PhobosScripts::DisableTriggersWithObjects: + ScriptExt::ManageTriggersWithObjects(pTeam, -1, false); + break; default: // Do nothing because or it is a wrong Action number or it is an Ares/YR action... if (action > 70 && !IsExtVariableAction(action)) @@ -3003,3 +3024,184 @@ bool ScriptExt::IsExtVariableAction(int action) auto eAction = static_cast(action); return eAction >= PhobosScripts::LocalVariableAdd && eAction <= PhobosScripts::GlobalVariableAndByGlobal; } + +void ScriptExt::ManageTriggersFromList(TeamClass* pTeam, int idxAITriggerType = -1, bool isEnabled = false) +{ + auto pScript = pTeam->CurrentScript; + + if (idxAITriggerType < 0) + idxAITriggerType = pScript->Type->ScriptActions[pScript->CurrentMission].Argument; + + if (idxAITriggerType < 0) + return; + + if (RulesExt::Global()->AITriggersLists.Count <= 0) + return; + + DynamicVectorClass objectsList = RulesExt::Global()->AITriggersLists.GetItem(idxAITriggerType); + + for (auto pTrigger : *AITriggerTypeClass::Array) + { + if (objectsList.FindItemIndex(pTrigger) >= 0) + { + pTrigger->IsEnabled = isEnabled; + } + } + + // This action finished + pTeam->StepCompleted = true; +} + +void ScriptExt::ManageAllTriggersFromHouse(TeamClass* pTeam, HouseClass* pHouse = nullptr, int sideIdx = -1, int houseIdx = -1, bool isEnabled = true) +{ + // if pHouse is set then it overwrites any argument + if (pHouse) + { + houseIdx = pHouse->ArrayIndex; + sideIdx = pHouse->SideIndex; + } + + if (sideIdx < 0) + return; + + for (auto pTrigger : *AITriggerTypeClass::Array) + { + if ((houseIdx == -1 || houseIdx == pTrigger->HouseIndex) && (sideIdx == 0 || sideIdx == pTrigger->SideIndex)) + { + pTrigger->IsEnabled = isEnabled; + } + } + + // This action finished + pTeam->StepCompleted = true; +} + +void ScriptExt::SetSideIdxForManagingTriggers(TeamClass* pTeam, int sideIdx = -1) +{ + if (!pTeam) + return; + + auto pScript = pTeam->CurrentScript; + + if (sideIdx < 0) + sideIdx = pScript->Type->ScriptActions[pScript->CurrentMission].Argument; + + if (sideIdx < -1) + sideIdx = -1; + + if (auto pTeamData = TeamExt::ExtMap.Find(pTeam)) + pTeamData->TriggersSideIdx = sideIdx; + + // This action finished + pTeam->StepCompleted = true; +} + +void ScriptExt::SetHouseIdxForManagingTriggers(TeamClass* pTeam, int houseIdx = 1000000) +{ + if (!pTeam) + return; + + auto pScript = pTeam->CurrentScript; + + if (houseIdx == 1000000) + houseIdx = pScript->Type->ScriptActions[pScript->CurrentMission].Argument; + + houseIdx = HouseExt::GetHouseIndex(houseIdx, pTeam, nullptr); + + if (houseIdx < -1) + houseIdx = -1; + + if (auto pTeamData = TeamExt::ExtMap.Find(pTeam)) + pTeamData->TriggersHouseIdx = houseIdx; + + // This action finished + pTeam->StepCompleted = true; +} + +void ScriptExt::ManageAITriggers(TeamClass* pTeam, int enabled = -1) +{ + if (!pTeam) + return; + + if (auto pTeamData = TeamExt::ExtMap.Find(pTeam)) + { + int sideIdx = pTeamData->TriggersSideIdx; + int houseIdx = pTeamData->TriggersHouseIdx; + pTeamData->TriggersSideIdx = -1; + pTeamData->TriggersHouseIdx = -1; + auto pScript = pTeam->CurrentScript; + bool isEnabled = false; + + if (enabled < 0) + enabled = pScript->Type->ScriptActions[pScript->CurrentMission].Argument; + + if (enabled >= 1) + isEnabled = true; + + ScriptExt::ManageAllTriggersFromHouse(pTeam, nullptr, sideIdx, houseIdx, isEnabled); + } + + // This action finished + pTeam->StepCompleted = true; +} + +void ScriptExt::ManageTriggersWithObjects(TeamClass* pTeam, int idxAITargetType = -1, bool isEnabled = false) +{ + auto pScript = pTeam->CurrentScript; + + if (idxAITargetType < 0) + idxAITargetType = pScript->Type->ScriptActions[pScript->CurrentMission].Argument; + + if (idxAITargetType < 0) + return; + + if (RulesExt::Global()->AITargetTypesLists.Count <= 0) + return; + + DynamicVectorClass objectsList = RulesExt::Global()->AITargetTypesLists.GetItem(idxAITargetType); + + if (objectsList.Count == 0) + return; + + for (auto pTrigger : *AITriggerTypeClass::Array) + { + DynamicVectorClass entriesList; + + if (pTrigger->Team1) + { + for (auto entry : pTrigger->Team1->TaskForce->Entries) + { + if (entry.Amount > 0) + { + entriesList.AddItem(entry.Type); + } + } + } + + if (pTrigger->Team2) + { + for (auto entry : pTrigger->Team2->TaskForce->Entries) + { + if (entry.Amount > 0) + { + entriesList.AddItem(entry.Type); + } + } + } + + if (entriesList.Count > 0) + { + for (auto entry : entriesList) + { + if (objectsList.FindItemIndex(entry) >= 0) + { + pTrigger->IsEnabled = isEnabled; + break; + } + } + } + } + + // This action finished + pTeam->StepCompleted = true; +} diff --git a/src/Ext/Script/Body.h b/src/Ext/Script/Body.h index 023a5bc097..ee1d75c3f6 100644 --- a/src/Ext/Script/Body.h +++ b/src/Ext/Script/Body.h @@ -13,6 +13,7 @@ #include #include +#include #include #include #include @@ -62,6 +63,13 @@ enum class PhobosScripts : unsigned int UnregisterGreatSuccess = 111, GatherAroundLeader = 112, RandomSkipNextAction = 113, + SetSideIdxForManagingTriggers = 127, + SetHouseIdxForManagingTriggers = 128, + ManageAllAITriggers = 129, + EnableTriggersFromList = 130, + DisableTriggersFromList = 131, + EnableTriggersWithObjects = 132, + DisableTriggersWithObjects = 133, // Variables LocalVariableSet = 500, @@ -193,6 +201,8 @@ class ScriptExt static void SetMoveMissionEndMode(TeamClass* pTeam, int mode); static void SkipNextAction(TeamClass* pTeam, int successPercentage); static FootClass* FindTheTeamLeader(TeamClass* pTeam); + static void ManageTriggersFromList(TeamClass* pTeam, int idxAITriggerType, bool isEnabled); + static void ManageAllTriggersFromHouse(TeamClass* pTeam, HouseClass* pHouse, int sideIdx, int houseIdx, bool isEnabled); static bool IsExtVariableAction(int action); static void VariablesHandler(TeamClass* pTeam, PhobosScripts eAction, int nArg); @@ -200,7 +210,10 @@ class ScriptExt static void VariableOperationHandler(TeamClass* pTeam, int nVariable, int Number); template static void VariableBinaryOperationHandler(TeamClass* pTeam, int nVariable, int nVarToOperate); - + static void SetSideIdxForManagingTriggers(TeamClass* pTeam, int sideIdx); + static void SetHouseIdxForManagingTriggers(TeamClass* pTeam, int houseIdx); + static void ManageAITriggers(TeamClass* pTeam, int enabled); + static void ManageTriggersWithObjects(TeamClass* pTeam, int idxAITargetType, bool isEnabled); static ExtContainer ExtMap; diff --git a/src/Ext/Team/Body.cpp b/src/Ext/Team/Body.cpp index 54f359782c..1b7f0fc7b5 100644 --- a/src/Ext/Team/Body.cpp +++ b/src/Ext/Team/Body.cpp @@ -19,6 +19,8 @@ void TeamExt::ExtData::Serialize(T& Stm) .Process(this->WaitNoTargetCounter) .Process(this->WaitNoTargetTimer) .Process(this->TeamLeader) + .Process(this->TriggersSideIdx) + .Process(this->TriggersHouseIdx) ; } diff --git a/src/Ext/Team/Body.h b/src/Ext/Team/Body.h index a3ad86116f..e04275961c 100644 --- a/src/Ext/Team/Body.h +++ b/src/Ext/Team/Body.h @@ -24,6 +24,8 @@ class TeamExt int WaitNoTargetCounter; TimerStruct WaitNoTargetTimer; FootClass* TeamLeader; + int TriggersSideIdx; + int TriggersHouseIdx; ExtData(TeamClass* OwnerObject) : Extension(OwnerObject) , WaitNoTargetAttempts { 0 } @@ -35,6 +37,8 @@ class TeamExt , WaitNoTargetCounter { 0 } , WaitNoTargetTimer { 0 } , TeamLeader { nullptr } + , TriggersSideIdx { -1 } + , TriggersHouseIdx { -1 } { } virtual ~ExtData() = default; From ce08daebb2136611a8083c028002486dbe1d5321 Mon Sep 17 00:00:00 2001 From: FS-21 Date: Thu, 31 Mar 2022 19:40:40 +0200 Subject: [PATCH 02/19] I forgot including in this branch some code --- src/Ext/Rules/Body.cpp | 21 +++++++++++++++++++++ src/Ext/Rules/Body.h | 2 ++ 2 files changed, 23 insertions(+) diff --git a/src/Ext/Rules/Body.cpp b/src/Ext/Rules/Body.cpp index c6a0afca64..f3f5a6716c 100644 --- a/src/Ext/Rules/Body.cpp +++ b/src/Ext/Rules/Body.cpp @@ -63,6 +63,7 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI) const char* sectionAITargetTypes = "AITargetTypes"; const char* sectionAIScriptsList = "AIScriptsList"; + const char* sectionAITriggersList = "AITriggersList"; INI_EX exINI(pINI); @@ -112,6 +113,25 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI) AIScriptsLists.AddItem(objectsList); objectsList.Clear(); } + + // Section AITriggersList + int triggerItemsCount = pINI->GetKeyCount(sectionAITriggersList); + for (int i = 0; i < triggerItemsCount; ++i) + { + DynamicVectorClass objectsList; + + char* context = nullptr; + pINI->ReadString(sectionAITriggersList, pINI->GetKeyName(sectionAITriggersList, i), "", Phobos::readBuffer); + + for (char *cur = strtok_s(Phobos::readBuffer, Phobos::readDelims, &context); cur; cur = strtok_s(nullptr, Phobos::readDelims, &context)) + { + AITriggerTypeClass* pNewTrigger = GameCreate(cur); + objectsList.AddItem(pNewTrigger); + } + + AITriggersLists.AddItem(objectsList); + objectsList.Clear(); + } } // this runs between the before and after type data loading methods for rules ini @@ -166,6 +186,7 @@ void RulesExt::ExtData::Serialize(T& Stm) .Process(this->JumpjetAllowLayerDeviation) .Process(this->AITargetTypesLists) .Process(this->AIScriptsLists) + .Process(this->AITriggersLists) .Process(this->Storage_TiberiumIndex) ; } diff --git a/src/Ext/Rules/Body.h b/src/Ext/Rules/Body.h index 0219a2cf7f..416fb518ab 100644 --- a/src/Ext/Rules/Body.h +++ b/src/Ext/Rules/Body.h @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -30,6 +31,7 @@ class RulesExt PhobosFixedString<32u> MissingCameo; DynamicVectorClass> AITargetTypesLists; DynamicVectorClass> AIScriptsLists; + DynamicVectorClass> AITriggersLists; Valueable JumpjetCrash; Valueable JumpjetNoWobbles; From f178aab4398acee71eeaf0642b0818a206bf6dd2 Mon Sep 17 00:00:00 2001 From: FS-21 Date: Sun, 17 Apr 2022 17:56:49 +0200 Subject: [PATCH 03/19] Point to latest YRpp --- YRpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/YRpp b/YRpp index 9ecaa0167b..93d3d54fc3 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit 9ecaa0167b73af9b2b01d3170422542d76f64609 +Subproject commit 93d3d54fc352378fcc8d1da4e1d2c41074d8f63f From 0fa5476fde46dfd292df270c6208e38f4d7d5290 Mon Sep 17 00:00:00 2001 From: Metadorius Date: Wed, 11 May 2022 19:38:10 +0300 Subject: [PATCH 04/19] Update GH Actions workflows - Split non-PR and main branch nightly build PRs - Use PR HEAD instead of merge commit --- .github/actions/build-phobos/action.yml | 26 +++++++++++++++ .github/workflows/nightly.yml | 34 +++++++++----------- .github/workflows/pr-nightly-comment.yml | 4 +-- .github/workflows/pr-nightly.yml | 40 ++++++++++++++++++++++++ 4 files changed, 83 insertions(+), 21 deletions(-) create mode 100644 .github/actions/build-phobos/action.yml create mode 100644 .github/workflows/pr-nightly.yml diff --git a/.github/actions/build-phobos/action.yml b/.github/actions/build-phobos/action.yml new file mode 100644 index 0000000000..2fe749b7cd --- /dev/null +++ b/.github/actions/build-phobos/action.yml @@ -0,0 +1,26 @@ +name: 'Build Phobos' +inputs: + sln-path: + description: 'Path to the solution file relative to the root of the project' + required: false + default: '.' + build-config: + description: 'Configuration to build' + required: true +runs: + using: "composite" + steps: + - name: Add MSBuild to PATH + uses: microsoft/setup-msbuild@v1 + + - name: Restore NuGet packages + working-directory: ${{env.GITHUB_WORKSPACE}} + run: nuget restore ${{inputs.sln-path}} + + - uses: ammaraskar/msvc-problem-matcher@master + - name: Build + working-directory: ${{env.GITHUB_WORKSPACE}} + # Add additional options to the MSBuild command line here (like platform or verbosity level). + # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference + run: msbuild /m /p:Configuration=${{inputs.build-config}} /p:GitCommit=${{github.sha}} /p:GitBranch=${{github.ref}} ${{inputs.sln-path}} + diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index bea505fedd..bd193b5fbf 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -1,6 +1,11 @@ name: Nightly Build -on: [push, pull_request] +on: + push: + branches: + - master + - main + - develop env: # Path to the solution file relative to the root of the project. @@ -18,24 +23,15 @@ jobs: runs-on: windows-2019 steps: - - uses: actions/checkout@v2 - - - name: Checkout submodules - run: git submodule update --init --recursive - - - name: Add MSBuild to PATH - uses: microsoft/setup-msbuild@v1 - - - name: Restore NuGet packages - working-directory: ${{env.GITHUB_WORKSPACE}} - run: nuget restore ${{env.SOLUTION_FILE_PATH}} + - uses: actions/checkout@v3 + with: + submodules: recursive - - uses: ammaraskar/msvc-problem-matcher@master - - name: Build - working-directory: ${{env.GITHUB_WORKSPACE}} - # Add additional options to the MSBuild command line here (like platform or verbosity level). - # See https://docs.microsoft.com/visualstudio/msbuild/msbuild-command-line-reference - run: msbuild /m /p:Configuration=${{env.BUILD_CONFIGURATION}} /p:GitCommit=${{github.sha}} /p:GitBranch=${{github.ref}} ${{env.SOLUTION_FILE_PATH}} + - name: Build Phobos + uses: ./.github/actions/build-phobos # Build steps are reused + with: + sln-path: ${{env.SOLUTION_FILE_PATH}} + build-config: ${{env.BUILD_CONFIGURATION}} - name: Upload Artifact if: ${{success()}} @@ -44,4 +40,4 @@ jobs: name: compiled-dll-${{github.sha}} path: | ${{env.SOLUTION_FILE_PATH}}/${{env.BUILD_CONFIGURATION}}/Phobos.dll - ${{env.SOLUTION_FILE_PATH}}/${{env.BUILD_CONFIGURATION}}/IntDir/Phobos.pdb + ${{env.SOLUTION_FILE_PATH}}/${{env.BUILD_CONFIGURATION}}/IntDir/Phobos.pdb \ No newline at end of file diff --git a/.github/workflows/pr-nightly-comment.yml b/.github/workflows/pr-nightly-comment.yml index 6354ebc7f2..fb527c1507 100644 --- a/.github/workflows/pr-nightly-comment.yml +++ b/.github/workflows/pr-nightly-comment.yml @@ -1,7 +1,7 @@ -name: Nightly Build comment on pull request +name: Nightly Build Comment on Pull Request on: workflow_run: - workflows: ['Nightly Build'] + workflows: ['Pull Request Nightly Build'] types: [completed] jobs: pr_comment: diff --git a/.github/workflows/pr-nightly.yml b/.github/workflows/pr-nightly.yml new file mode 100644 index 0000000000..66dbb9b8d2 --- /dev/null +++ b/.github/workflows/pr-nightly.yml @@ -0,0 +1,40 @@ +name: Pull Request Nightly Build + +on: + pull_request: + +env: + # Path to the solution file relative to the root of the project. + SOLUTION_FILE_PATH: . + + # Configuration type to build. + # You can convert this to a build matrix if you need coverage of multiple configuration types. + # https://docs.github.com/actions/learn-github-actions/managing-complex-workflows#using-a-build-matrix + BUILD_CONFIGURATION: DevBuild + # GIT_COMMIT: $(git rev-parse --short "$GITHUB_SHA") + # GIT_BRANCH: ${GITHUB_REF#refs/heads/} + +jobs: + build: + runs-on: windows-2019 + + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + ref: ${{ github.event.pull_request.head.sha }} + + - name: Build Phobos + uses: ./.github/actions/build-phobos # Setup steps are reused + with: + sln-path: ${{env.SOLUTION_FILE_PATH}} + build-config: ${{env.BUILD_CONFIGURATION}} + + - name: Upload Artifact + if: ${{success()}} + uses: actions/upload-artifact@v2 + with: + name: compiled-dll-${{github.sha}} + path: | + ${{input.sln-path}}/${{input.build-config}}/Phobos.dll + ${{input.sln-path}}/${{input.build-config}}/IntDir/Phobos.pdb \ No newline at end of file From 5299dff5ba40f56aab18689576b39d5a816ad986 Mon Sep 17 00:00:00 2001 From: FS-21 Date: Wed, 11 May 2022 19:00:42 +0200 Subject: [PATCH 05/19] Fix name due to YRpp change --- src/Ext/Script/Body.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Ext/Script/Body.cpp b/src/Ext/Script/Body.cpp index 6a17fafe1d..104a3f9281 100644 --- a/src/Ext/Script/Body.cpp +++ b/src/Ext/Script/Body.cpp @@ -853,7 +853,7 @@ void ScriptExt::Mission_Attack(TeamClass *pTeam, bool repeatAction = true, int c if (pUnitType->WhatAmI() != AbstractType::AircraftType) { pUnit->QueueMission(Mission::Attack, true); - pUnit->ClickedAction(Action::Attack, selectedTarget, false); + pUnit->ObjectClickedAction(Action::Attack, selectedTarget, false); if (pUnit->GetCurrentMission() != Mission::Attack) pUnit->Mission_Attack(); @@ -886,7 +886,7 @@ void ScriptExt::Mission_Attack(TeamClass *pTeam, bool repeatAction = true, int c else { pUnit->QueueMission(Mission::Attack, true); - pUnit->ClickedAction(Action::Attack, selectedTarget, false); + pUnit->ObjectClickedAction(Action::Attack, selectedTarget, false); pUnit->Mission_Attack(); } } @@ -988,7 +988,7 @@ void ScriptExt::Mission_Attack(TeamClass *pTeam, bool repeatAction = true, int c pUnit->QueueMission(Mission::Attack, true); if (pFocus) - pUnit->ClickedAction(Action::Attack, pFocus, false); + pUnit->ObjectClickedAction(Action::Attack, pFocus, false); pUnit->Mission_Attack(); } @@ -1008,7 +1008,7 @@ void ScriptExt::Mission_Attack(TeamClass *pTeam, bool repeatAction = true, int c pUnit->QueueMission(Mission::Attack, true); if (pFocus) - pUnit->ClickedAction(Action::Attack, pFocus, false); + pUnit->ObjectClickedAction(Action::Attack, pFocus, false); pUnit->Mission_Attack(); } @@ -2208,7 +2208,7 @@ void ScriptExt::Mission_Move(TeamClass *pTeam, int calcThreatMode = 0, bool pick if (pUnitType->WhatAmI() != AbstractType::AircraftType) { pUnit->QueueMission(Mission::Move, false); - pUnit->ClickedAction(Action::Move, selectedTarget, false); + pUnit->ObjectClickedAction(Action::Move, selectedTarget, false); if (pUnit->GetCurrentMission() != Mission::Move) pUnit->Mission_Move(); From 2500eb984b95046eac6e153fefa4a8b4f52df280 Mon Sep 17 00:00:00 2001 From: FS-21 Date: Mon, 17 Oct 2022 19:45:10 +0200 Subject: [PATCH 06/19] Point to latest YRpp --- YRpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/YRpp b/YRpp index 5676ca549e..a41eb1a449 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit 5676ca549e93e3276d1a4721a0f0f3b78e515f28 +Subproject commit a41eb1a4491f8256459a1c3e4a25af5ebded45db From e9c7793651f84c17243497cd4201082b1b91c414 Mon Sep 17 00:00:00 2001 From: FS-21 Date: Mon, 17 Oct 2022 19:59:36 +0200 Subject: [PATCH 07/19] Point changelog to v0.3.1 and not v0.3 --- docs/Whats-New.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/Whats-New.md b/docs/Whats-New.md index 0ac0d15e65..7b0d6324c4 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -252,6 +252,7 @@ New: - Building airstrike target eligibility customization (by Starkku) - IvanBomb detonation & image display centered on buildings (by Starkku) - Forcing specific weapon against cloaked or disguised targets (by Starkku) +- Script action for enabling & disabling AI Triggers (by FS-21) Vanilla fixes: - Allow AI to repair structures built from base nodes/trigger action 125/SW delivery in single player missions (by Trsdy) @@ -303,7 +304,6 @@ New: - Script action to regroup temporarily around the Team Leader (by FS-21) - Script action to randomly skip next action (by FS-21) - Script action for timed script action jumps (by FS-21) -- Script Action 127 to 133 for new AI ways for enabling & disabling AI Triggers (by FS-21) - ObjectInfo now shows current Target and AI Trigger data (by FS-21) - Shield absorption and passthrough customization (by Morton) - Limbo Delivery of buildings (by Morton) From 41825d991f48ea303abd524c646adcfea6f9a2a5 Mon Sep 17 00:00:00 2001 From: FS-21 Date: Mon, 17 Oct 2022 20:06:35 +0200 Subject: [PATCH 08/19] Actions renumeration Changed action numbers: SetSideIdxForManagingTriggers = 127 -> 16005, SetHouseIdxForManagingTriggers = 128 -> 16006, ManageAllAITriggers = 129 -> 16007, EnableTriggersFromList = 130 -> 16008, DisableTriggersFromList = 131 -> 16009, DisableTriggersWithObjects = 133 -> 16010, EnableTriggersWithObjects = 132 -> 16011, --- src/Ext/Script/Body.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Ext/Script/Body.h b/src/Ext/Script/Body.h index 587f9af4b7..1b73b52b7f 100644 --- a/src/Ext/Script/Body.h +++ b/src/Ext/Script/Body.h @@ -58,13 +58,6 @@ enum class PhobosScripts : unsigned int WaitUntilFullAmmo = 10101, GatherAroundLeader = 10102, LoadIntoTransports = 10103, - SetSideIdxForManagingTriggers = 127, - SetHouseIdxForManagingTriggers = 128, - ManageAllAITriggers = 129, - EnableTriggersFromList = 130, - DisableTriggersFromList = 131, - EnableTriggersWithObjects = 132, - DisableTriggersWithObjects = 133, // Range 12000-12999 are suplementary/setup pre-actions WaitIfNoTarget = 12000, @@ -83,6 +76,13 @@ enum class PhobosScripts : unsigned int StopForceJumpCountdown = 16002, RandomSkipNextAction = 16003, PickRandomScript = 16004, + SetSideIdxForManagingTriggers = 16005, + SetHouseIdxForManagingTriggers = 16006, + ManageAllAITriggers = 16007, + EnableTriggersFromList = 16008, + DisableTriggersFromList = 16009, + DisableTriggersWithObjects = 16010, + EnableTriggersWithObjects = 16011, // Range 18000-18999 are variable actions LocalVariableSet = 18000, From 531e7715d4fc17e78ef84e53aba97f6a6fad9573 Mon Sep 17 00:00:00 2001 From: FS-21 Date: Mon, 17 Oct 2022 20:22:49 +0200 Subject: [PATCH 09/19] Added lost documentation from older merges And updated the action ranges of these new actions --- docs/AI-Scripting-and-Mapping.md | 81 ++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/docs/AI-Scripting-and-Mapping.md b/docs/AI-Scripting-and-Mapping.md index 50ab2899d8..83d0be08c7 100644 --- a/docs/AI-Scripting-and-Mapping.md +++ b/docs/AI-Scripting-and-Mapping.md @@ -314,6 +314,87 @@ In `rulesmd.ini`: ; ... ``` +### `16005` Set Side Index For Managing AI Triggers + +- Set the side index for enabling and disabling triggers. +0 means any side. + +In `aimd.ini`: +```ini +[SOMESCRIPTTYPE] ; ScriptType +x=16005,n ; integer, where 0 > n, default -1 +``` + +### `16006` Set House Index For Managing AI Triggers + +- Set the house index for enabling and disabling triggers. The indexes aren't the ones used in [Countries], these are internal in-game House indexes. + +In `aimd.ini`: +```ini +[SOMESCRIPTTYPE] ; ScriptType +x=16006,n ; integer +``` + +- The possible argument values are: + +| *Argument* | *Description* | +| :--------: | :-------------------------------------------: | +| 4475-4482 | Multiplayer start location indexes | +| 8997 | Special case that returns the house index of the Team object | +| >= 0 | House index. Neutral houses can be used | +| -1 | Random non-neutral House | +| -2 | Find the first Neutral house available | +| -3 | Random Human Player alive | + +### `16007` Enable Or Disable All AI Triggers + +- All AI triggers will be enabled or disabled. +You must set the affected side with action `16005` and house with action `16006`. + +In `aimd.ini`: +```ini +[SOMESCRIPTTYPE] ; ScriptType +x=16007,n ; integer, 1 == enable, 0 == disable +``` + +### `16008` Enable AI Triggers From List + +- When executed this action enable all AI trigger types from the selected list in `AITriggersList`. The second parameter is a 0-based index from the new section `AITriggersList` explained below. + +In `aimd.ini`: +```ini +[SOMESCRIPTTYPE] ; ScriptType +x=16008,n +``` + +The second parameter is a 0-based index for the `AITriggersList` section that specifies the list of possible `AITriggerTypes` that can be evaluated. The new `AITriggersList` section must be declared in `rulesmd.ini` for making this script work: + +In `rulesmd.ini`: +```ini +[AITriggersList] ; List of AITriggerTypes lists +0=SOMEAITRIGGERTYPE,SOMEOTHERAITRIGGERTYPE,SAMPLETRIGGERTYPE +1=ANOTHERTRIGGERTYPE,YETANOTHERTRIGGERTYPE +; ... +``` + +### `16009` Disable AI Triggers From List + +- Works silimar to the Action `16008`. When executed this action disable all AI trigger types from the selected list in `AITriggersList`. The second parameter is a 0-based index from the new section `AITriggersList`. + +### `16010` Disable AI Triggers If Contains Any Objects From the List + +- Works silimar to the Action `16011`. When executed this action all AI Trigger Types that contains any unit of the selected list in `AITargetTypes` will be disabled. The second parameter is a 0-based index from the new section `AITargetTypes`. + +### `16011` Enable AI Triggers If Contains Any Objects From the List + +- When executed this action all AI trigger types that contains any unit of the selected list in `AITargetTypes` will be enabled. The second parameter is a 0-based index from the new section `AITargetTypes`. + +In `aimd.ini`: +```ini +[SOMESCRIPTTYPE] ; ScriptType +x=132,n +``` + ### `18000-18999` Variable Manipulation #### `18000-18023` Edit Variable From aaa7f0b110f5b9fd26db0a9ce7e8b877fd59c489 Mon Sep 17 00:00:00 2001 From: FS-21 Date: Mon, 17 Oct 2022 20:25:20 +0200 Subject: [PATCH 10/19] small change in docs --- CREDITS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CREDITS.md b/CREDITS.md index 89e50dfecc..0fb80fde55 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -104,9 +104,9 @@ This page lists all the individual contributions to the project by their author. - MakeInfantry logic on BombClass bugfix - **FS-21**: - Dump Object Info enhancements + - Majority of ScriptType actions - `Powered.KillSpawns` - `Spawner.LimitRange` - - Majority of ScriptType actions - MC deployer fixes - Help with docs - Automatic Passenger Deletion logic From 61c50d97d0c84f5cad9765acb8c89bf5c88a0e25 Mon Sep 17 00:00:00 2001 From: FS-21 Date: Mon, 13 Feb 2023 07:01:52 +0100 Subject: [PATCH 11/19] Compilation fixes --- src/Ext/House/Body.cpp | 2 +- src/Ext/Rules/Body.cpp | 11 +++++------ src/Ext/Rules/Body.h | 2 +- src/Ext/Script/Body.cpp | 16 ++++++++++++---- 4 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/Ext/House/Body.cpp b/src/Ext/House/Body.cpp index c76c77621f..e94b10d66b 100644 --- a/src/Ext/House/Body.cpp +++ b/src/Ext/House/Body.cpp @@ -216,7 +216,7 @@ int HouseExt::GetHouseIndex(int param, TeamClass* pTeam = nullptr, TActionClass* // Random Human Player for (auto pHouse : *HouseClass::Array) { - if (pHouse->ControlledByHuman() + if (pHouse->IsControlledByHuman() && !pHouse->Defeated && !pHouse->IsObserver()) { diff --git a/src/Ext/Rules/Body.cpp b/src/Ext/Rules/Body.cpp index 2584660126..a6a93e7285 100644 --- a/src/Ext/Rules/Body.cpp +++ b/src/Ext/Rules/Body.cpp @@ -152,19 +152,18 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI) int triggerItemsCount = pINI->GetKeyCount(sectionAITriggersList); for (int i = 0; i < triggerItemsCount; ++i) { - DynamicVectorClass objectsList; + std::vector objectsList; char* context = nullptr; pINI->ReadString(sectionAITriggersList, pINI->GetKeyName(sectionAITriggersList, i), "", Phobos::readBuffer); for (char *cur = strtok_s(Phobos::readBuffer, Phobos::readDelims, &context); cur; cur = strtok_s(nullptr, Phobos::readDelims, &context)) { - AITriggerTypeClass* pNewTrigger = GameCreate(cur); - objectsList.AddItem(pNewTrigger); + AITriggerTypeClass* pNewTrigger = GameCreate(cur); // Note: Don't use ::FindOrAllocate(cur) here... + objectsList.emplace_back(pNewTrigger); } - AITriggersLists.AddItem(objectsList); - objectsList.Clear(); + AITriggersLists.emplace_back(objectsList); } } @@ -196,6 +195,7 @@ void RulesExt::ExtData::Serialize(T& Stm) Stm .Process(this->AITargetTypesLists) .Process(this->AIScriptsLists) + .Process(this->AITriggersLists) .Process(this->HarvesterTypes) .Process(this->Storage_TiberiumIndex) .Process(this->InfantryGainSelfHealCap) @@ -221,7 +221,6 @@ void RulesExt::ExtData::Serialize(T& Stm) .Process(this->Pips_SelfHeal_Infantry_Offset) .Process(this->Pips_SelfHeal_Units_Offset) .Process(this->Pips_SelfHeal_Buildings_Offset) - .Process(this->AITriggersLists) .Process(this->AllowParallelAIQueues) .Process(this->ForbidParallelAIQueues_Aircraft) .Process(this->ForbidParallelAIQueues_Building) diff --git a/src/Ext/Rules/Body.h b/src/Ext/Rules/Body.h index 3cab0865f7..e6730da352 100644 --- a/src/Ext/Rules/Body.h +++ b/src/Ext/Rules/Body.h @@ -28,7 +28,7 @@ class RulesExt public: std::vector> AITargetTypesLists; std::vector> AIScriptsLists; - DynamicVectorClass> AITriggersLists; + std::vector> AITriggersLists; ValueableVector HarvesterTypes; Valueable Storage_TiberiumIndex; diff --git a/src/Ext/Script/Body.cpp b/src/Ext/Script/Body.cpp index 2fee0e39c8..0b4662af1a 100644 --- a/src/Ext/Script/Body.cpp +++ b/src/Ext/Script/Body.cpp @@ -3123,10 +3123,14 @@ void ScriptExt::ManageTriggersFromList(TeamClass* pTeam, int idxAITriggerType = if (idxAITriggerType < 0) return; - if (RulesExt::Global()->AITriggersLists.Count <= 0) + if (RulesExt::Global()->AITriggersLists.size() <= 0) return; - DynamicVectorClass objectsList = RulesExt::Global()->AITriggersLists.GetItem(idxAITriggerType); + DynamicVectorClass objectsList; + for (auto obj : RulesExt::Global()->AITriggersLists[idxAITriggerType]) + { + objectsList.AddUnique(obj); + } for (auto pTrigger : *AITriggerTypeClass::Array) { @@ -3243,10 +3247,14 @@ void ScriptExt::ManageTriggersWithObjects(TeamClass* pTeam, int idxAITargetType if (idxAITargetType < 0) return; - if (RulesExt::Global()->AITargetTypesLists.Count <= 0) + if (RulesExt::Global()->AITargetTypesLists.size() <= 0) return; - DynamicVectorClass objectsList = RulesExt::Global()->AITargetTypesLists.GetItem(idxAITargetType); + DynamicVectorClass objectsList; + for (auto obj : RulesExt::Global()->AITargetTypesLists[idxAITargetType]) + { + objectsList.AddUnique(obj); + } if (objectsList.Count == 0) return; From ec077b7eb6054da4957d8dad511edc98e4a2de3b Mon Sep 17 00:00:00 2001 From: FS-21 Date: Sat, 27 May 2023 07:10:10 +0200 Subject: [PATCH 12/19] . --- src/Ext/House/Body.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ext/House/Body.cpp b/src/Ext/House/Body.cpp index da7396eb73..12a7aa5cf2 100644 --- a/src/Ext/House/Body.cpp +++ b/src/Ext/House/Body.cpp @@ -357,7 +357,7 @@ int HouseExt::GetHouseIndex(int param, TeamClass* pTeam = nullptr, TActionClass* { if ((pTeam && pTAction) || (param == 8997 && !pTeam && !pTAction)) return -1; - + int houseIdx = -1; std::vector housesListIdx; From aea534c766654c2c252d1c659c6f782459630d0f Mon Sep 17 00:00:00 2001 From: FS-21 Date: Tue, 30 Apr 2024 13:21:42 +0200 Subject: [PATCH 13/19] Moved code into the new file and more tweaks --- Phobos.vcxproj | 1 + src/Ext/House/Body.h | 2 +- src/Ext/Rules/Body.cpp | 2 +- src/Ext/Script/Body.ManageAITriggers.cpp | 195 +++++++++++++++++++++++ src/Ext/Script/Body.cpp | 189 ---------------------- 5 files changed, 198 insertions(+), 191 deletions(-) create mode 100644 src/Ext/Script/Body.ManageAITriggers.cpp diff --git a/Phobos.vcxproj b/Phobos.vcxproj index 7cd780d98d..c5a2d6239b 100644 --- a/Phobos.vcxproj +++ b/Phobos.vcxproj @@ -41,6 +41,7 @@ + diff --git a/src/Ext/House/Body.h b/src/Ext/House/Body.h index cf96d9eda6..abe9f0084f 100644 --- a/src/Ext/House/Body.h +++ b/src/Ext/House/Body.h @@ -1,6 +1,6 @@ #pragma once #include -#include +#include #include #include diff --git a/src/Ext/Rules/Body.cpp b/src/Ext/Rules/Body.cpp index 9dde4f86fb..1c0f856556 100644 --- a/src/Ext/Rules/Body.cpp +++ b/src/Ext/Rules/Body.cpp @@ -201,7 +201,7 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI) objectsList.emplace_back(pNewTrigger); } - AITriggersLists.emplace_back(objectsList); + this->AITriggersLists.emplace_back(std::move(objectsList)); } } diff --git a/src/Ext/Script/Body.ManageAITriggers.cpp b/src/Ext/Script/Body.ManageAITriggers.cpp new file mode 100644 index 0000000000..19fbe9aa3e --- /dev/null +++ b/src/Ext/Script/Body.ManageAITriggers.cpp @@ -0,0 +1,195 @@ +#include "Body.h" + +void ScriptExt::ManageTriggersFromList(TeamClass* pTeam, int idxAITriggerType = -1, bool isEnabled = false) +{ + if (!pTeam) + return; + + auto pScript = pTeam->CurrentScript; + + if (idxAITriggerType < 0) + idxAITriggerType = pScript->Type->ScriptActions[pScript->CurrentMission].Argument; + + if (idxAITriggerType < 0) + return; + + if (RulesExt::Global()->AITriggersLists.size() <= 0) + return; + + DynamicVectorClass objectsList; + for (auto obj : RulesExt::Global()->AITriggersLists[idxAITriggerType]) + { + objectsList.AddUnique(obj); + } + + for (auto pTrigger : *AITriggerTypeClass::Array) + { + if (objectsList.FindItemIndex(pTrigger) >= 0) + pTrigger->IsEnabled = isEnabled; + } + + // This action finished + pTeam->StepCompleted = true; +} + +void ScriptExt::ManageAllTriggersFromHouse(TeamClass* pTeam, HouseClass* pHouse = nullptr, int sideIdx = -1, int houseIdx = -1, bool isEnabled = true) +{ + if (!pTeam) + return; + + // if pHouse is set then it overwrites any argument + if (pHouse) + { + houseIdx = pHouse->ArrayIndex; + sideIdx = pHouse->SideIndex; + } + + if (sideIdx < 0) + return; + + for (auto pTrigger : *AITriggerTypeClass::Array) + { + if ((houseIdx == -1 || houseIdx == pTrigger->HouseIndex) && (sideIdx == 0 || sideIdx == pTrigger->SideIndex)) + pTrigger->IsEnabled = isEnabled; + } + + // This action finished + pTeam->StepCompleted = true; +} + +void ScriptExt::SetSideIdxForManagingTriggers(TeamClass* pTeam, int sideIdx = -1) +{ + if (!pTeam) + return; + + auto pScript = pTeam->CurrentScript; + + if (sideIdx < 0) + sideIdx = pScript->Type->ScriptActions[pScript->CurrentMission].Argument; + + if (sideIdx < -1) + sideIdx = -1; + + if (auto pTeamData = TeamExt::ExtMap.Find(pTeam)) + pTeamData->TriggersSideIdx = sideIdx; + + // This action finished + pTeam->StepCompleted = true; +} + +void ScriptExt::SetHouseIdxForManagingTriggers(TeamClass* pTeam, int houseIdx = 1000000) +{ + if (!pTeam) + return; + + auto pScript = pTeam->CurrentScript; + + if (houseIdx == 1000000) + houseIdx = pScript->Type->ScriptActions[pScript->CurrentMission].Argument; + + houseIdx = HouseExt::GetHouseIndex(houseIdx, pTeam, nullptr); + + if (houseIdx < -1) + houseIdx = -1; + + if (auto pTeamData = TeamExt::ExtMap.Find(pTeam)) + pTeamData->TriggersHouseIdx = houseIdx; + + // This action finished + pTeam->StepCompleted = true; +} + +void ScriptExt::ManageAITriggers(TeamClass* pTeam, int enabled = -1) +{ + if (!pTeam) + return; + + auto pTeamData = TeamExt::ExtMap.Find(pTeam); + if (!pTeamData) + { + // This action finished + pTeam->StepCompleted = true; + } + + int sideIdx = pTeamData->TriggersSideIdx; + int houseIdx = pTeamData->TriggersHouseIdx; + pTeamData->TriggersSideIdx = -1; + pTeamData->TriggersHouseIdx = -1; + auto pScript = pTeam->CurrentScript; + bool isEnabled = false; + + if (enabled < 0) + enabled = pScript->Type->ScriptActions[pScript->CurrentMission].Argument; + + if (enabled >= 1) + isEnabled = true; + + ScriptExt::ManageAllTriggersFromHouse(pTeam, nullptr, sideIdx, houseIdx, isEnabled); + + // This action finished + pTeam->StepCompleted = true; +} + +void ScriptExt::ManageTriggersWithObjects(TeamClass* pTeam, int idxAITargetType = -1, bool isEnabled = false) +{ + if (!pTeam) + return; + + auto pScript = pTeam->CurrentScript; + + if (idxAITargetType < 0) + idxAITargetType = pScript->Type->ScriptActions[pScript->CurrentMission].Argument; + + if (idxAITargetType < 0) + return; + + if (RulesExt::Global()->AITargetTypesLists.size() <= 0) + return; + + DynamicVectorClass objectsList; + for (auto obj : RulesExt::Global()->AITargetTypesLists[idxAITargetType]) + { + objectsList.AddUnique(obj); + } + + if (objectsList.Count == 0) + return; + + for (auto pTrigger : *AITriggerTypeClass::Array) + { + DynamicVectorClass entriesList; + + if (pTrigger->Team1) + { + for (auto entry : pTrigger->Team1->TaskForce->Entries) + { + if (entry.Amount > 0) + entriesList.AddItem(entry.Type); + } + } + + if (pTrigger->Team2) + { + for (auto entry : pTrigger->Team2->TaskForce->Entries) + { + if (entry.Amount > 0) + entriesList.AddItem(entry.Type); + } + } + + if (entriesList.Count > 0) + { + for (auto entry : entriesList) + { + if (objectsList.FindItemIndex(entry) >= 0) + { + pTrigger->IsEnabled = isEnabled; + break; + } + } + } + } + + // This action finished + pTeam->StepCompleted = true; +} diff --git a/src/Ext/Script/Body.cpp b/src/Ext/Script/Body.cpp index df9aa6498b..a6ad19037b 100644 --- a/src/Ext/Script/Body.cpp +++ b/src/Ext/Script/Body.cpp @@ -1315,192 +1315,3 @@ void ScriptExt::Log(const char* pFormat, ...) Debug::LogWithVArgs(pFormat, args); va_end(args); } - -void ScriptExt::ManageTriggersFromList(TeamClass* pTeam, int idxAITriggerType = -1, bool isEnabled = false) -{ - auto pScript = pTeam->CurrentScript; - - if (idxAITriggerType < 0) - idxAITriggerType = pScript->Type->ScriptActions[pScript->CurrentMission].Argument; - - if (idxAITriggerType < 0) - return; - - if (RulesExt::Global()->AITriggersLists.size() <= 0) - return; - - DynamicVectorClass objectsList; - for (auto obj : RulesExt::Global()->AITriggersLists[idxAITriggerType]) - { - objectsList.AddUnique(obj); - } - - for (auto pTrigger : *AITriggerTypeClass::Array) - { - if (objectsList.FindItemIndex(pTrigger) >= 0) - { - pTrigger->IsEnabled = isEnabled; - } - } - - // This action finished - pTeam->StepCompleted = true; -} - -void ScriptExt::ManageAllTriggersFromHouse(TeamClass* pTeam, HouseClass* pHouse = nullptr, int sideIdx = -1, int houseIdx = -1, bool isEnabled = true) -{ - // if pHouse is set then it overwrites any argument - if (pHouse) - { - houseIdx = pHouse->ArrayIndex; - sideIdx = pHouse->SideIndex; - } - - if (sideIdx < 0) - return; - - for (auto pTrigger : *AITriggerTypeClass::Array) - { - if ((houseIdx == -1 || houseIdx == pTrigger->HouseIndex) && (sideIdx == 0 || sideIdx == pTrigger->SideIndex)) - { - pTrigger->IsEnabled = isEnabled; - } - } - - // This action finished - pTeam->StepCompleted = true; -} - -void ScriptExt::SetSideIdxForManagingTriggers(TeamClass* pTeam, int sideIdx = -1) -{ - if (!pTeam) - return; - - auto pScript = pTeam->CurrentScript; - - if (sideIdx < 0) - sideIdx = pScript->Type->ScriptActions[pScript->CurrentMission].Argument; - - if (sideIdx < -1) - sideIdx = -1; - - if (auto pTeamData = TeamExt::ExtMap.Find(pTeam)) - pTeamData->TriggersSideIdx = sideIdx; - - // This action finished - pTeam->StepCompleted = true; -} - -void ScriptExt::SetHouseIdxForManagingTriggers(TeamClass* pTeam, int houseIdx = 1000000) -{ - if (!pTeam) - return; - - auto pScript = pTeam->CurrentScript; - - if (houseIdx == 1000000) - houseIdx = pScript->Type->ScriptActions[pScript->CurrentMission].Argument; - - houseIdx = HouseExt::GetHouseIndex(houseIdx, pTeam, nullptr); - - if (houseIdx < -1) - houseIdx = -1; - - if (auto pTeamData = TeamExt::ExtMap.Find(pTeam)) - pTeamData->TriggersHouseIdx = houseIdx; - - // This action finished - pTeam->StepCompleted = true; -} - -void ScriptExt::ManageAITriggers(TeamClass* pTeam, int enabled = -1) -{ - if (!pTeam) - return; - - if (auto pTeamData = TeamExt::ExtMap.Find(pTeam)) - { - int sideIdx = pTeamData->TriggersSideIdx; - int houseIdx = pTeamData->TriggersHouseIdx; - pTeamData->TriggersSideIdx = -1; - pTeamData->TriggersHouseIdx = -1; - auto pScript = pTeam->CurrentScript; - bool isEnabled = false; - - if (enabled < 0) - enabled = pScript->Type->ScriptActions[pScript->CurrentMission].Argument; - - if (enabled >= 1) - isEnabled = true; - - ScriptExt::ManageAllTriggersFromHouse(pTeam, nullptr, sideIdx, houseIdx, isEnabled); - } - - // This action finished - pTeam->StepCompleted = true; -} - -void ScriptExt::ManageTriggersWithObjects(TeamClass* pTeam, int idxAITargetType = -1, bool isEnabled = false) -{ - auto pScript = pTeam->CurrentScript; - - if (idxAITargetType < 0) - idxAITargetType = pScript->Type->ScriptActions[pScript->CurrentMission].Argument; - - if (idxAITargetType < 0) - return; - - if (RulesExt::Global()->AITargetTypesLists.size() <= 0) - return; - - DynamicVectorClass objectsList; - for (auto obj : RulesExt::Global()->AITargetTypesLists[idxAITargetType]) - { - objectsList.AddUnique(obj); - } - - if (objectsList.Count == 0) - return; - - for (auto pTrigger : *AITriggerTypeClass::Array) - { - DynamicVectorClass entriesList; - - if (pTrigger->Team1) - { - for (auto entry : pTrigger->Team1->TaskForce->Entries) - { - if (entry.Amount > 0) - { - entriesList.AddItem(entry.Type); - } - } - } - - if (pTrigger->Team2) - { - for (auto entry : pTrigger->Team2->TaskForce->Entries) - { - if (entry.Amount > 0) - { - entriesList.AddItem(entry.Type); - } - } - } - - if (entriesList.Count > 0) - { - for (auto entry : entriesList) - { - if (objectsList.FindItemIndex(entry) >= 0) - { - pTrigger->IsEnabled = isEnabled; - break; - } - } - } - } - - // This action finished - pTeam->StepCompleted = true; -} From 474a070cd4f816774e8817de2dba544877b9ecf7 Mon Sep 17 00:00:00 2001 From: FS-21 Date: Mon, 15 Jul 2024 09:40:35 +0200 Subject: [PATCH 14/19] Rewrote HouseExt::GetHouseIndex(...) with the requested changes. Applied all the feedback to these AITrigger manipulation functions. I also tweaked some "return" that didn't explain "why" and avoided an infinite loop. Tweaked ScriptExt::SetCloseEnoughDistance() with a small change not related to this PR (is too small for a PR and isn't a bug). --- src/Ext/House/Body.cpp | 159 ++++++----------------- src/Ext/Script/Body.ManageAITriggers.cpp | 91 ++++++------- src/Ext/Script/Body.cpp | 14 +- 3 files changed, 87 insertions(+), 177 deletions(-) diff --git a/src/Ext/House/Body.cpp b/src/Ext/House/Body.cpp index 056cc23d82..c444bdf054 100644 --- a/src/Ext/House/Body.cpp +++ b/src/Ext/House/Body.cpp @@ -488,144 +488,61 @@ int HouseExt::GetHouseIndex(int param, TeamClass* pTeam = nullptr, TActionClass* int houseIdx = -1; std::vector housesListIdx; - // Transtale the Multiplayer index into a valid index for the HouseClass array - if (param >= HouseClass::PlayerAtA && param <= HouseClass::PlayerAtH) + // Check special cases + if (param < 0) { - switch (param) - { - case HouseClass::PlayerAtA: - houseIdx = 0; - break; - - case HouseClass::PlayerAtB: - houseIdx = 1; - break; - - case HouseClass::PlayerAtC: - houseIdx = 2; - break; - - case HouseClass::PlayerAtD: - houseIdx = 3; - break; - - case HouseClass::PlayerAtE: - houseIdx = 4; - break; - - case HouseClass::PlayerAtF: - houseIdx = 5; - break; - - case HouseClass::PlayerAtG: - houseIdx = 6; - break; - - case HouseClass::PlayerAtH: - houseIdx = 7; - break; - - default: - break; - } + if (param < -3) + return -1; - if (houseIdx >= 0) + for (auto pHouse : *HouseClass::Array) { - HouseClass* pHouse = HouseClass::Array->GetItem(houseIdx); - - if (!pHouse->Defeated - && !pHouse->IsObserver() - && !pHouse->Type->MultiplayPassive) + if (param == -2 && pHouse->IsNeutral()) { - return houseIdx; + houseIdx = pHouse->ArrayIndex; + break; + } + else if (!pHouse->Defeated && !pHouse->IsObserver()) + { + if ((param == -1 && !pHouse->Type->MultiplayPassive) // Random non-neutral player + || (param == -3 && !pHouse->IsObserver())) // Random human player + { + housesListIdx.push_back(pHouse->ArrayIndex); + } + + if (housesListIdx.size() > 0) + houseIdx = housesListIdx.at(ScenarioClass::Instance->Random.RandomRanged(0, housesListIdx.size() - 1)); + else + return -1; } } - return -1; + return houseIdx; } - // Special case that returns the house index of the TeamClass object or the Trigger Action - if (param == 8997) + // Check a specific house of the map + if (param >= HouseClass::PlayerAtA && param <= HouseClass::PlayerAtH) { - return (pTeam ? pTeam->Owner->ArrayIndex : pTAction->TeamType->Owner->ArrayIndex); + // Is a multiplayer house index (Player@A - Player@H) ? + houseIdx = param - HouseClass::PlayerAtA; } - - // Positive index values check. Includes any kind of House - if (param >= 0) + else if (param == 8997) { - if (param < HouseClass::Array->Count) - { - HouseClass* pHouse = HouseClass::Array->GetItem(param); - - if (!pHouse->Defeated - && !pHouse->IsObserver()) - { - return houseIdx; - } - } - - return -1; + // Is the owner of the trigger ? + houseIdx = pTeam ? pTeam->Owner->ArrayIndex : pTAction->TeamType->Owner->ArrayIndex; } - - // Special cases - switch (param) + else if (param > 8997 || HouseClass::Array()->Count <= param) { - case -1: - // Random non-neutral - for (auto pHouse : *HouseClass::Array) - { - if (!pHouse->Defeated - && !pHouse->IsObserver() - && !pHouse->Type->MultiplayPassive) - { - housesListIdx.push_back(pHouse->ArrayIndex); - } - } + // Is a invalid index value + if (pTAction) + Debug::Log(__FUNCTION__": Invalid house index '%d'. This action could be skipped.\n", (int)pTAction->ActionKind, param); - if (housesListIdx.size() > 0) - houseIdx = housesListIdx.at(ScenarioClass::Instance->Random.RandomRanged(0, housesListIdx.size() - 1)); - else - return -1; - - break; - - case -2: - // Find first Neutral house - for (auto pHouseNeutral : *HouseClass::Array) - { - if (pHouseNeutral->IsNeutral()) - { - houseIdx = pHouseNeutral->ArrayIndex; - break; - } - } - - break; - - case -3: - // Random Human Player - for (auto pHouse : *HouseClass::Array) - { - if (pHouse->IsControlledByHuman() - && !pHouse->Defeated - && !pHouse->IsObserver()) - { - housesListIdx.push_back(pHouse->ArrayIndex); - } - } - - if (housesListIdx.size() > 0) - houseIdx = housesListIdx.at(ScenarioClass::Instance->Random.RandomRanged(0, housesListIdx.size() - 1)); - else - return -1; - - break; - - default: - break; + return -1; } - return houseIdx; + HouseClass* pHouse = HouseClass::Array->GetItem(houseIdx); + + if (!pHouse->Defeated && !pHouse->IsObserver()) + return houseIdx; } void HouseExt::ExtData::LoadFromINIFile(CCINIClass* const pINI) diff --git a/src/Ext/Script/Body.ManageAITriggers.cpp b/src/Ext/Script/Body.ManageAITriggers.cpp index 19fbe9aa3e..3be501d099 100644 --- a/src/Ext/Script/Body.ManageAITriggers.cpp +++ b/src/Ext/Script/Body.ManageAITriggers.cpp @@ -2,25 +2,28 @@ void ScriptExt::ManageTriggersFromList(TeamClass* pTeam, int idxAITriggerType = -1, bool isEnabled = false) { - if (!pTeam) - return; - auto pScript = pTeam->CurrentScript; if (idxAITriggerType < 0) idxAITriggerType = pScript->Type->ScriptActions[pScript->CurrentMission].Argument; - if (idxAITriggerType < 0) - return; + if (idxAITriggerType < 0 || RulesExt::Global()->AITriggersLists.size() <= 0) + { + pTeam->StepCompleted = true; + ScriptExt::Log("AI Scripts - ManageTriggersFromList: [%s] [%s] (line: %d = %d,%d) Aborting script action because the [AITriggersLists] index %d is invalid.\n", + pTeam->Type->ID, + pScript->Type->ID, + pScript->CurrentMission, + pScript->Type->ScriptActions[pScript->CurrentMission].Action, + pScript->Type->ScriptActions[pScript->CurrentMission].Argument, + idxAITriggerType); - if (RulesExt::Global()->AITriggersLists.size() <= 0) return; + } DynamicVectorClass objectsList; for (auto obj : RulesExt::Global()->AITriggersLists[idxAITriggerType]) - { objectsList.AddUnique(obj); - } for (auto pTrigger : *AITriggerTypeClass::Array) { @@ -34,9 +37,6 @@ void ScriptExt::ManageTriggersFromList(TeamClass* pTeam, int idxAITriggerType = void ScriptExt::ManageAllTriggersFromHouse(TeamClass* pTeam, HouseClass* pHouse = nullptr, int sideIdx = -1, int houseIdx = -1, bool isEnabled = true) { - if (!pTeam) - return; - // if pHouse is set then it overwrites any argument if (pHouse) { @@ -59,9 +59,6 @@ void ScriptExt::ManageAllTriggersFromHouse(TeamClass* pTeam, HouseClass* pHouse void ScriptExt::SetSideIdxForManagingTriggers(TeamClass* pTeam, int sideIdx = -1) { - if (!pTeam) - return; - auto pScript = pTeam->CurrentScript; if (sideIdx < 0) @@ -79,9 +76,6 @@ void ScriptExt::SetSideIdxForManagingTriggers(TeamClass* pTeam, int sideIdx = -1 void ScriptExt::SetHouseIdxForManagingTriggers(TeamClass* pTeam, int houseIdx = 1000000) { - if (!pTeam) - return; - auto pScript = pTeam->CurrentScript; if (houseIdx == 1000000) @@ -101,14 +95,12 @@ void ScriptExt::SetHouseIdxForManagingTriggers(TeamClass* pTeam, int houseIdx = void ScriptExt::ManageAITriggers(TeamClass* pTeam, int enabled = -1) { - if (!pTeam) - return; - auto pTeamData = TeamExt::ExtMap.Find(pTeam); if (!pTeamData) { // This action finished pTeam->StepCompleted = true; + return; } int sideIdx = pTeamData->TriggersSideIdx; @@ -120,8 +112,7 @@ void ScriptExt::ManageAITriggers(TeamClass* pTeam, int enabled = -1) if (enabled < 0) enabled = pScript->Type->ScriptActions[pScript->CurrentMission].Argument; - - if (enabled >= 1) + else isEnabled = true; ScriptExt::ManageAllTriggersFromHouse(pTeam, nullptr, sideIdx, houseIdx, isEnabled); @@ -132,60 +123,60 @@ void ScriptExt::ManageAITriggers(TeamClass* pTeam, int enabled = -1) void ScriptExt::ManageTriggersWithObjects(TeamClass* pTeam, int idxAITargetType = -1, bool isEnabled = false) { - if (!pTeam) - return; - auto pScript = pTeam->CurrentScript; if (idxAITargetType < 0) idxAITargetType = pScript->Type->ScriptActions[pScript->CurrentMission].Argument; - if (idxAITargetType < 0) - return; + if (idxAITargetType < 0 || RulesExt::Global()->AITargetTypesLists.size() <= 0) + { + pTeam->StepCompleted = true; + ScriptExt::Log("AI Scripts - ManageTriggersWithObjects: [%s] [%s] (line: %d = %d,%d) Aborting script action because the [AITargetTypes] index %d is invalid.\n", + pTeam->Type->ID, + pScript->Type->ID, + pScript->CurrentMission, + pScript->Type->ScriptActions[pScript->CurrentMission].Action, + pScript->Type->ScriptActions[pScript->CurrentMission].Argument, + idxAITargetType); - if (RulesExt::Global()->AITargetTypesLists.size() <= 0) return; + } DynamicVectorClass objectsList; for (auto obj : RulesExt::Global()->AITargetTypesLists[idxAITargetType]) - { objectsList.AddUnique(obj); - } if (objectsList.Count == 0) + { + pTeam->StepCompleted = true; return; + } - for (auto pTrigger : *AITriggerTypeClass::Array) + auto AddTechnosFromTeam = [&](DynamicVectorClass& entriesList, TeamTypeClass* pTeam) { - DynamicVectorClass entriesList; - - if (pTrigger->Team1) + if (pTeam) { - for (auto entry : pTrigger->Team1->TaskForce->Entries) + for (auto entry : pTeam->TaskForce->Entries) { if (entry.Amount > 0) entriesList.AddItem(entry.Type); } } + }; - if (pTrigger->Team2) - { - for (auto entry : pTrigger->Team2->TaskForce->Entries) - { - if (entry.Amount > 0) - entriesList.AddItem(entry.Type); - } - } + for (auto pTrigger : *AITriggerTypeClass::Array) + { + DynamicVectorClass entriesList; + + AddTechnosFromTeam(entriesList, pTrigger->Team1); + AddTechnosFromTeam(entriesList, pTrigger->Team2); - if (entriesList.Count > 0) + for (auto entry : entriesList) { - for (auto entry : entriesList) + if (objectsList.FindItemIndex(entry) >= 0) { - if (objectsList.FindItemIndex(entry) >= 0) - { - pTrigger->IsEnabled = isEnabled; - break; - } + pTrigger->IsEnabled = isEnabled; + break; } } } diff --git a/src/Ext/Script/Body.cpp b/src/Ext/Script/Body.cpp index a6ad19037b..1b488dd1b6 100644 --- a/src/Ext/Script/Body.cpp +++ b/src/Ext/Script/Body.cpp @@ -705,15 +705,17 @@ void ScriptExt::SetCloseEnoughDistance(TeamClass* pTeam, double distance = -1) if (distance <= 0) distance = pTeam->CurrentScript->Type->ScriptActions[pTeam->CurrentScript->CurrentMission].Argument; - auto const pTeamData = TeamExt::ExtMap.Find(pTeam); - - if (pTeamData) + auto pTeamData = TeamExt::ExtMap.Find(pTeam); + if (!pTeamData) { - if (distance > 0) - pTeamData->CloseEnough = distance; + // This action finished + pTeam->StepCompleted = true; + return; } - if (distance <= 0) + if (distance > 0) + pTeamData->CloseEnough = distance; + else pTeamData->CloseEnough = RulesClass::Instance->CloseEnough / 256.0; // This action finished From 7718627db517a92dd110f95145ad9083bab59add Mon Sep 17 00:00:00 2001 From: FS-21 Date: Mon, 15 Jul 2024 11:31:43 +0200 Subject: [PATCH 15/19] Fix small mistake --- src/Ext/Script/Body.ManageAITriggers.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Ext/Script/Body.ManageAITriggers.cpp b/src/Ext/Script/Body.ManageAITriggers.cpp index 3be501d099..4685e80c82 100644 --- a/src/Ext/Script/Body.ManageAITriggers.cpp +++ b/src/Ext/Script/Body.ManageAITriggers.cpp @@ -83,9 +83,6 @@ void ScriptExt::SetHouseIdxForManagingTriggers(TeamClass* pTeam, int houseIdx = houseIdx = HouseExt::GetHouseIndex(houseIdx, pTeam, nullptr); - if (houseIdx < -1) - houseIdx = -1; - if (auto pTeamData = TeamExt::ExtMap.Find(pTeam)) pTeamData->TriggersHouseIdx = houseIdx; From 5c8a756868db063c6d9c168192d5272c2846ea5e Mon Sep 17 00:00:00 2001 From: FS-21 Date: Mon, 15 Jul 2024 11:42:51 +0200 Subject: [PATCH 16/19] Moved scriptType Action Before: 16005 After: 16012 Reason: Another one was merged and took the 16005 --- docs/AI-Scripting-and-Mapping.md | 26 +++++++++++++------------- src/Ext/Script/Body.h | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/AI-Scripting-and-Mapping.md b/docs/AI-Scripting-and-Mapping.md index eb40ef9874..bd52b28603 100644 --- a/docs/AI-Scripting-and-Mapping.md +++ b/docs/AI-Scripting-and-Mapping.md @@ -416,17 +416,6 @@ In `rulesmd.ini`: ; ... ``` -### `16005` Set Side Index For Managing AI Triggers - -- Set the side index for enabling and disabling triggers. -0 means any side. - -In `aimd.ini`: -```ini -[SOMESCRIPTTYPE] ; ScriptType -x=16005,n ; integer, where 0 > n, default -1 -``` - ### `16006` Set House Index For Managing AI Triggers - Set the house index for enabling and disabling triggers. The indexes aren't the ones used in [Countries], these are internal in-game House indexes. @@ -451,7 +440,7 @@ x=16006,n ; integer ### `16007` Enable Or Disable All AI Triggers - All AI triggers will be enabled or disabled. -You must set the affected side with action `16005` and house with action `16006`. +You must set the affected side with action `16012` and house with action `16006`. In `aimd.ini`: ```ini @@ -494,7 +483,18 @@ In `rulesmd.ini`: In `aimd.ini`: ```ini [SOMESCRIPTTYPE] ; ScriptType -x=132,n +x=16011,n +``` + +### `16012` Set Side Index For Managing AI Triggers + +- Set the side index for enabling and disabling triggers. +0 means any side. + +In `aimd.ini`: +```ini +[SOMESCRIPTTYPE] ; ScriptType +x=16012,n ; integer, where 0 > n, default -1 ``` ### `18000-18999` Variable Manipulation diff --git a/src/Ext/Script/Body.h b/src/Ext/Script/Body.h index 15a7cb4e3f..9062dacbf3 100644 --- a/src/Ext/Script/Body.h +++ b/src/Ext/Script/Body.h @@ -77,13 +77,13 @@ enum class PhobosScripts : unsigned int StopForceJumpCountdown = 16002, RandomSkipNextAction = 16003, PickRandomScript = 16004, - SetSideIdxForManagingTriggers = 16005, SetHouseIdxForManagingTriggers = 16006, ManageAllAITriggers = 16007, EnableTriggersFromList = 16008, DisableTriggersFromList = 16009, DisableTriggersWithObjects = 16010, EnableTriggersWithObjects = 16011, + SetSideIdxForManagingTriggers = 16012, // Range 18000-18999 are variable actions LocalVariableSet = 18000, From 4e92269eef47265e9d4099b23b9f586f50bd1b26 Mon Sep 17 00:00:00 2001 From: FS-21 Date: Thu, 29 Aug 2024 12:37:39 +0200 Subject: [PATCH 17/19] Small changes Due to review feedback --- src/Ext/Script/Body.ManageAITriggers.cpp | 8 +++++--- src/Ext/Script/Body.cpp | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Ext/Script/Body.ManageAITriggers.cpp b/src/Ext/Script/Body.ManageAITriggers.cpp index 4685e80c82..2db3ec2490 100644 --- a/src/Ext/Script/Body.ManageAITriggers.cpp +++ b/src/Ext/Script/Body.ManageAITriggers.cpp @@ -64,7 +64,8 @@ void ScriptExt::SetSideIdxForManagingTriggers(TeamClass* pTeam, int sideIdx = -1 if (sideIdx < 0) sideIdx = pScript->Type->ScriptActions[pScript->CurrentMission].Argument; - if (sideIdx < -1) + // Any negative value will mark it as "Any side" + if (sideIdx < 0) sideIdx = -1; if (auto pTeamData = TeamExt::ExtMap.Find(pTeam)) @@ -74,11 +75,12 @@ void ScriptExt::SetSideIdxForManagingTriggers(TeamClass* pTeam, int sideIdx = -1 pTeam->StepCompleted = true; } -void ScriptExt::SetHouseIdxForManagingTriggers(TeamClass* pTeam, int houseIdx = 1000000) +void ScriptExt::SetHouseIdxForManagingTriggers(TeamClass* pTeam, int houseIdx = 2147483647) { auto pScript = pTeam->CurrentScript; - if (houseIdx == 1000000) + // Note: this magic number is a default index value the game will never be able to use due to technical limitations + if (houseIdx == 2147483647) houseIdx = pScript->Type->ScriptActions[pScript->CurrentMission].Argument; houseIdx = HouseExt::GetHouseIndex(houseIdx, pTeam, nullptr); diff --git a/src/Ext/Script/Body.cpp b/src/Ext/Script/Body.cpp index 92df80f273..745051d6dd 100644 --- a/src/Ext/Script/Body.cpp +++ b/src/Ext/Script/Body.cpp @@ -220,7 +220,7 @@ void ScriptExt::ProcessAction(TeamClass* pTeam) ScriptExt::SetSideIdxForManagingTriggers(pTeam, -1); break; case PhobosScripts::SetHouseIdxForManagingTriggers: - ScriptExt::SetHouseIdxForManagingTriggers(pTeam, 1000000); + ScriptExt::SetHouseIdxForManagingTriggers(pTeam, 2147483647); break; case PhobosScripts::ManageAllAITriggers: ScriptExt::ManageAITriggers(pTeam, -1); From 34a5a0caadffd644ff164e8fbab4d984bbb6a928 Mon Sep 17 00:00:00 2001 From: FS-21 Date: Thu, 29 Aug 2024 13:09:03 +0200 Subject: [PATCH 18/19] FA2 documentation --- docs/Whats-New.md | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/docs/Whats-New.md b/docs/Whats-New.md index 927e751736..1c82e57553 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -215,6 +215,16 @@ SaveGameOnScenarioStart=true ; boolean 10102=Regroup Temporarily Around the Team Leader,20,0,1,[LONG DESC] 10103=Load Onto Transports,0,0,1,[LONG DESC] 10104=Chronoshift to Enemy Base,20,0,1,[LONG DESC] + + + 16006=16006 - Set House Index For Managing AI Triggers,20,0,1,[LONG DESC] + 16007=16007 - Enable Or Disable All AI Triggers,21,0,1,[LONG DESC] + 16008=16008 - Enable AI Triggers From List,28,0,1,[LONG DESC] + 16009=16009 - Disable AI Triggers From List,28,0,1,[LONG DESC] + 16010=16010 - Disable AI Triggers If Contains Any Objects From the List,29,0,1,[LONG DESC] + 16011=16011 - Enable AI Triggers If Contains Any Objects From the List,29,0,1,[LONG DESC] + 16012=16012 - Set Side Index For Managing AI Triggers,20,0,1,[LONG DESC] + 18000=Local variable set,22,0,1,[LONG DESC] 18001=Local variable add,22,0,1,[LONG DESC] 18002=Local variable minus,22,0,1,[LONG DESC] @@ -295,6 +305,12 @@ SaveGameOnScenarioStart=true ; boolean 25=Local variables,-4 26=Global variables,-5 27=Global variables,-6 + 28=AI Scripts List, -7 + 29=AI Target Type,-8 + + [ScriptParamTypes] + 7=AIScriptsList,1,1,0 + 8=AITargetTypes,1,1,0 ``` From c66f451d84087e6bb3a4847db50ac03e9d7e779c Mon Sep 17 00:00:00 2001 From: FS-21 Date: Thu, 29 Aug 2024 13:09:59 +0200 Subject: [PATCH 19/19] fix mistake --- docs/Whats-New.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/Whats-New.md b/docs/Whats-New.md index 1c82e57553..188b2e20fe 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -217,13 +217,13 @@ SaveGameOnScenarioStart=true ; boolean 10104=Chronoshift to Enemy Base,20,0,1,[LONG DESC] - 16006=16006 - Set House Index For Managing AI Triggers,20,0,1,[LONG DESC] - 16007=16007 - Enable Or Disable All AI Triggers,21,0,1,[LONG DESC] - 16008=16008 - Enable AI Triggers From List,28,0,1,[LONG DESC] - 16009=16009 - Disable AI Triggers From List,28,0,1,[LONG DESC] - 16010=16010 - Disable AI Triggers If Contains Any Objects From the List,29,0,1,[LONG DESC] - 16011=16011 - Enable AI Triggers If Contains Any Objects From the List,29,0,1,[LONG DESC] - 16012=16012 - Set Side Index For Managing AI Triggers,20,0,1,[LONG DESC] + 16006=Set House Index For Managing AI Triggers,20,0,1,[LONG DESC] + 16007=Enable Or Disable All AI Triggers,21,0,1,[LONG DESC] + 16008=Enable AI Triggers From List,28,0,1,[LONG DESC] + 16009=Disable AI Triggers From List,28,0,1,[LONG DESC] + 16010=Disable AI Triggers If Contains Any Objects From the List,29,0,1,[LONG DESC] + 16011=Enable AI Triggers If Contains Any Objects From the List,29,0,1,[LONG DESC] + 16012=Set Side Index For Managing AI Triggers,20,0,1,[LONG DESC] 18000=Local variable set,22,0,1,[LONG DESC] 18001=Local variable add,22,0,1,[LONG DESC]