Status effects expire on their data duration; loot rolls never throw
A status effect added without an explicit duration started with no remaining turns and the countdown skipped it, so it never expired. OnTurnEnd counted down a second time, expired unlimited effects after one turn and removed expired stacks by id; it is now a pure hook. The victory screen rolls loot through LootEntry.Roll, so a loot table with MinCount > MaxCount no longer throws half-way through the battle end, and its success-path diagnostics are no longer logged as errors. Mod unit tests for the status effect lifetime.
This commit is contained in:
1 parent
72b54eb564
commit
68976523f0
5 files changed
+55
-27
No files matched your search
@@ -45,6 +45,7 @@ namespace Cthangover.Core.Cards.StatusEffect
|
||||
Name = info.Name;
|
||||
Description = info.Description;
|
||||
Duration = info.Duration;
|
||||
RemainingTurns = info.Duration;
|
||||
EffectType = info.Type;
|
||||
Icon = TextureUtils.LoadFromModGroup("characters", info.Icon);
|
||||
Actions = StatusEffectActionFactory.Instance.Get(info.Actions);
|
||||
|
||||
@@ -134,21 +134,13 @@ namespace Cthangover.Core.Cards.StatusEffect
|
||||
/// <summary>Fires end-of-turn hooks on all active effects. Operates
|
||||
/// on a defensive copy so that <c>OnTurnEnd</c> callbacks that
|
||||
/// add or remove effects do not invalidate the enumerator.
|
||||
/// Decrements remaining turns and removes expired effects via
|
||||
/// <see cref="Remove"/> (which also fires
|
||||
/// <c>OnRemove</c>).</summary>
|
||||
/// Durations count down in <see cref="OnTurnStart"/> only.</summary>
|
||||
public void OnTurnEnd()
|
||||
{
|
||||
// Only the hook: the countdown belongs to OnTurnStart, a second one
|
||||
// here halved every duration and expired effects without one.
|
||||
foreach (var statusEffect in ActiveStatusEffects)
|
||||
{
|
||||
statusEffect.Actions?.OnTurnEnd(owner);
|
||||
statusEffect.RemainingTurns--;
|
||||
if (statusEffect.RemainingTurns <= 0)
|
||||
{
|
||||
statusEffect.Actions?.OnFinalAction(owner);
|
||||
Remove(statusEffect.ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>Pipes outgoing damage through every active effect's
|
||||
|
||||
@@ -75,17 +75,17 @@ namespace Cthangover.TurnBattle
|
||||
audioService?.PlaySound("battle/winground", SoundType.UI);
|
||||
|
||||
var bg = GetNodeOrNull<TextureRect>("TransitionBg");
|
||||
GameLogger.Log("BATTLE", $"Winground.Show: TransitionBg={(bg != null ? "found" : "NULL")}, texture={(bg?.Texture != null ? "has" : "null")}", LogLevel.Error);
|
||||
GameLogger.Log("BATTLE", $"Winground.Show: TransitionBg={(bg != null ? "found" : "NULL")}, texture={(bg?.Texture != null ? "has" : "null")}", bg != null ? LogLevel.Debug : LogLevel.Error);
|
||||
|
||||
if (bg != null && bg.Texture == null)
|
||||
{
|
||||
var tex = Textures.Resolve("winground");
|
||||
GameLogger.Log("BATTLE", $"Winground.Show: ResolveTexture('winground') = {(tex != null ? "loaded" : "NULL")}", LogLevel.Error);
|
||||
GameLogger.Log("BATTLE", $"Winground.Show: ResolveTexture('winground') = {(tex != null ? "loaded" : "NULL")}", tex != null ? LogLevel.Debug : LogLevel.Error);
|
||||
bg.Texture = tex;
|
||||
}
|
||||
|
||||
data = BattleRequest.Current;
|
||||
GameLogger.Log("BATTLE_UI", $"Winground.Show: BattleData={(data != null ? "found" : "NULL")}", LogLevel.Error);
|
||||
GameLogger.Log("BATTLE_UI", $"Winground.Show: BattleData={(data != null ? "found" : "NULL")}", data != null ? LogLevel.Debug : LogLevel.Error);
|
||||
|
||||
var expTracking = BuildExpTracking();
|
||||
var defeatedEnemies = BuildDefeatedEnemies();
|
||||
@@ -167,7 +167,7 @@ namespace Cthangover.TurnBattle
|
||||
private void BuildCharExpDisplay(Dictionary<string, int> expTracking)
|
||||
{
|
||||
var container = charExpContainer ?? GetNodeOrNull<Container>("Content/CharExpContainer");
|
||||
GameLogger.Log("BATTLE_UI", $"BuildCharExpDisplay: charExpContainer export={(charExpContainer != null ? "found" : "NULL")}, GetNodeOrNull fallback={(container != null ? "found" : "NULL")}", LogLevel.Error);
|
||||
GameLogger.Log("BATTLE_UI", $"BuildCharExpDisplay: charExpContainer export={(charExpContainer != null ? "found" : "NULL")}, GetNodeOrNull fallback={(container != null ? "found" : "NULL")}", LogLevel.Debug);
|
||||
|
||||
if (container == null)
|
||||
{
|
||||
@@ -180,7 +180,7 @@ namespace Cthangover.TurnBattle
|
||||
|
||||
var charData = GameData.Instance.Runtime.CharacterData;
|
||||
|
||||
GameLogger.Log("BATTLE_UI", $"BuildCharExpDisplay: expTracking={(expTracking != null ? $"found ({expTracking.Count} entries)" : "NULL")}, BattleSet count={charData.BattleSet.Count}", LogLevel.Error);
|
||||
GameLogger.Log("BATTLE_UI", $"BuildCharExpDisplay: expTracking={(expTracking != null ? $"found ({expTracking.Count} entries)" : "NULL")}, BattleSet count={charData.BattleSet.Count}", LogLevel.Debug);
|
||||
|
||||
var battleSetList = charData.BattleSet.ToList();
|
||||
|
||||
@@ -208,7 +208,7 @@ namespace Cthangover.TurnBattle
|
||||
reportCard.Setup(cardTemplate?.Image, name, earnedExp);
|
||||
container.AddChild(reportCard);
|
||||
|
||||
GameLogger.Log("BATTLE_UI", $"BuildCharExpDisplay: added reportCard for '{characterType}', id='{info.ID}', name='{name}', earnedExp={earnedExp}, cardTemplate={(cardTemplate != null ? "found" : "NULL")}, icon={(cardTemplate?.Image != null ? "has" : "null")}", LogLevel.Error);
|
||||
GameLogger.Log("BATTLE_UI", $"BuildCharExpDisplay: added reportCard for '{characterType}', id='{info.ID}', name='{name}', earnedExp={earnedExp}, cardTemplate={(cardTemplate != null ? "found" : "NULL")}, icon={(cardTemplate?.Image != null ? "has" : "null")}", LogLevel.Debug);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -247,16 +247,7 @@ namespace Cthangover.TurnBattle
|
||||
if (string.IsNullOrWhiteSpace(entry.ItemId))
|
||||
continue;
|
||||
|
||||
var probability = Math.Clamp(entry.Probability, 0, 100);
|
||||
if (probability <= 0)
|
||||
continue;
|
||||
if (probability < 100 && random.Next(1, 101) > probability)
|
||||
continue;
|
||||
|
||||
var count = entry.MinCount == entry.MaxCount
|
||||
? entry.MinCount
|
||||
: random.Next(entry.MinCount, entry.MaxCount + 1);
|
||||
|
||||
var count = entry.Roll(random);
|
||||
if (count > 0)
|
||||
TryAddLootItem(loot, entry.ItemId, count);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user