Skip to content

Commit

Permalink
Fix combat related bugs
Browse files Browse the repository at this point in the history
- Fix half growth dark fog base keep regenerating
- Fix combat drones doesn't increase ground base threat
- Fix NebulaModTeam#707: IndexOutOfRangeException in SpaceSector.RemoveEnemyWithComponents (IL_026A)
  • Loading branch information
starfi5h committed Sep 13, 2024
1 parent ac8d198 commit 265223c
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 26 deletions.
48 changes: 23 additions & 25 deletions NebulaPatcher/Patches/Dynamic/EnemyDFGroundSystem_Patch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,31 +78,6 @@ public static bool ExecuteDeferredUnitFormation_Prefix(EnemyDFGroundSystem __ins
return true;
}

[HarmonyPrefix]
[HarmonyPatch(nameof(EnemyDFGroundSystem.CanEraseBase))]
public static bool CanEraseBase_Prefix(DFGBaseComponent _base, ref bool __result)
{
if (!Multiplayer.IsActive) return true;

if (_base == null || _base.id == 0)
{
__result = true;
return false;
}
// Skip __instance.builders.buffer[_base.builderId].sp check as it may have different value
var pbuilders = _base.pbuilders;
for (var i = 2; i < pbuilders.Length; i++)
{
if (pbuilders[i].instId > 0)
{
__result = false;
return false;
}
}
__result = true;
return false;
}

[HarmonyPrefix]
[HarmonyPatch(nameof(EnemyDFGroundSystem.NotifyEnemyKilled))]
public static bool NotifyEnemyKilled_Prefix()
Expand Down Expand Up @@ -231,4 +206,27 @@ public static void KeyTickLogic_Prefix(EnemyDFGroundSystem __instance)
}
}

[HarmonyPostfix]
[HarmonyPatch(nameof(EnemyDFGroundSystem.KeyTickLogic))]
public static void KeyTickLogic_Postfix(EnemyDFGroundSystem __instance)
{
if (!Multiplayer.IsActive || Multiplayer.Session.IsServer) return;

var cursor = __instance.bases.cursor;
var baseBuffer = __instance.bases.buffer;
var enemyPool = __instance.factory.enemyPool;
for (var baseId = 1; baseId < cursor; baseId++)
{
var dfgbaseComponent = baseBuffer[baseId];
if (dfgbaseComponent == null || dfgbaseComponent.id != baseId) continue;
if (dfgbaseComponent.enemyId != 0 && enemyPool[dfgbaseComponent.enemyId].id == 0)
{
// Note: isInvincible in enemy is used by Nebula client to note if the enemy is pending to get killed
// isInvincible will get set back to true in EnemyDFGroundSystem.KeyTickLogic when base sp > 0
// So we'll need to set isInvincible = true to let host's incoming KillEnemyFinally packet get executed
//if (!enemyPool[dfgbaseComponent.enemyId].isInvincible) Log.Debug($"Base[{baseId}] isInvincible = true");
enemyPool[dfgbaseComponent.enemyId].isInvincible = true;
}
}
}
}
21 changes: 21 additions & 0 deletions NebulaPatcher/Patches/Dynamic/SkillSystem_Patch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,25 @@ public static void DamageObject_Prefix(int damage, int slice, ref SkillTarget ta
Multiplayer.Session.Network.SendPacketToLocalPlanet(packet);
}
}

[HarmonyPrefix]
[HarmonyPatch(nameof(SkillSystem.DamageGroundObjectByLocalCaster))]
public static void DamageGroundObjectByLocalCaster_Prefix(PlanetFactory factory, int damage, int slice, ref SkillTarget target, ref SkillTarget caster)
{
if (caster.type != ETargetType.Craft
|| target.type != ETargetType.Enemy
|| !Multiplayer.IsActive || Multiplayer.Session.Combat.IsIncomingRequest.Value) return;

if (factory == GameMain.localPlanet?.factory) // Sync for local planet combat drones
{
target.astroId = caster.astroId = GameMain.localPlanet.astroId;
var packet = new CombatStatDamagePacket(damage, slice, in target, in caster)
{
// Change the caster to player as craft (space fleet) is not sync yet
CasterType = (short)ETargetType.Player,
CasterId = Multiplayer.Session.LocalPlayer.Id
};
Multiplayer.Session.Network.SendPacketToLocalPlanet(packet);
}
}
}
16 changes: 16 additions & 0 deletions NebulaPatcher/Patches/Dynamic/SpaceSector_Patch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,22 @@ public static bool KillEnemyFinal_Prefix(SpaceSector __instance, int enemyId)
return false;
}

[HarmonyPrefix]
[HarmonyPatch(nameof(SpaceSector.RemoveEnemyWithComponents))]
public static void RemoveEnemyWithComponents_Prefix(SpaceSector __instance, int id)
{
// Fix IndexOutOfRangeException in SpaceSector.RemoveEnemyWithComponents IL_026A
// This is due to combatStats is not sync in client
if (id != 0 && __instance.enemyPool[id].id != 0)
{
if (__instance.enemyPool[id].combatStatId != 0)
{
if (__instance.enemyPool[id].combatStatId >= __instance.skillSystem.combatStats.cursor)
__instance.enemyPool[id].combatStatId = 0;
}
}
}

[HarmonyPrefix]
[HarmonyPatch(nameof(SpaceSector.TryCreateNewHive))]
public static bool TryCreateNewHive_Prefix(StarData star)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,9 @@ public static IEnumerable<CodeInstruction> UpdateFactoryThreat_Transpiler(IEnume

static bool LaunchCondition(DFGBaseComponent @this)
{
if (!Multiplayer.IsActive || @this.groundSystem.local_player_alive == true) return @this.groundSystem.local_player_alive;
if (!Multiplayer.IsActive) return @this.groundSystem.local_player_grounded_alive;

// In MP, replace local_player_grounded_alive flag with the following condition
var planetId = @this.groundSystem.planet.id;
var players = Multiplayer.Session.Combat.Players;
for (var i = 0; i < players.Length; i++)
Expand Down

0 comments on commit 265223c

Please sign in to comment.