Implement basic structure for combat system and refactor code
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 59b9870361cbdec4b9419c57a3ff71df
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
using KernelPanic.Data;
|
||||
|
||||
namespace KernelPanic.Combat
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents one runtime card and its per-combat mutable state.
|
||||
/// </summary>
|
||||
public sealed class CardInstance
|
||||
{
|
||||
public CardInstance(CardDefinition definition)
|
||||
{
|
||||
Definition = definition;
|
||||
}
|
||||
|
||||
public CardDefinition Definition { get; }
|
||||
public int TemporaryCostDelta { get; set; }
|
||||
public bool IsBroken { get; set; }
|
||||
public bool IsLocked { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c05e61a09404ee046a6771f8ac75803c
|
||||
@@ -0,0 +1,21 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace KernelPanic.Combat
|
||||
{
|
||||
/// <summary>
|
||||
/// Carries runtime combat references needed by card effects during resolution.
|
||||
/// </summary>
|
||||
public sealed class CombatContext
|
||||
{
|
||||
public CombatContext(CombatantState source, IReadOnlyList<CombatantState> targets, CombatManager combatManager)
|
||||
{
|
||||
Source = source;
|
||||
Targets = targets;
|
||||
CombatManager = combatManager;
|
||||
}
|
||||
|
||||
public CombatantState Source { get; }
|
||||
public IReadOnlyList<CombatantState> Targets { get; }
|
||||
public CombatManager CombatManager { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2eed81ad20b42a447858691a49666804
|
||||
@@ -0,0 +1,56 @@
|
||||
using KernelPanic.Core;
|
||||
using UnityEngine;
|
||||
|
||||
namespace KernelPanic.Combat
|
||||
{
|
||||
/// <summary>
|
||||
/// Owns the combat turn phase state machine and coordinates combat lifecycle transitions.
|
||||
/// </summary>
|
||||
public sealed class CombatManager : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private TurnPhase currentPhase = TurnPhase.Boot;
|
||||
|
||||
public TurnPhase CurrentPhase => currentPhase;
|
||||
|
||||
public void StartCombat()
|
||||
{
|
||||
SetPhase(TurnPhase.Boot);
|
||||
}
|
||||
|
||||
public void AdvancePhase()
|
||||
{
|
||||
TurnPhase nextPhase = GetNextPhase(currentPhase);
|
||||
SetPhase(nextPhase);
|
||||
}
|
||||
|
||||
public void EndPlayerTurn()
|
||||
{
|
||||
SetPhase(TurnPhase.Interpret);
|
||||
}
|
||||
|
||||
private void SetPhase(TurnPhase nextPhase)
|
||||
{
|
||||
TurnPhase previousPhase = currentPhase;
|
||||
currentPhase = nextPhase;
|
||||
GameEvents.RaisePhaseChanged(new PhaseChangedEvent(previousPhase, nextPhase));
|
||||
EnterPhase(nextPhase);
|
||||
}
|
||||
|
||||
private static TurnPhase GetNextPhase(TurnPhase phase)
|
||||
{
|
||||
return phase switch
|
||||
{
|
||||
TurnPhase.Boot => TurnPhase.Allocate,
|
||||
TurnPhase.Allocate => TurnPhase.Execute,
|
||||
TurnPhase.Execute => TurnPhase.Interpret,
|
||||
TurnPhase.Interpret => TurnPhase.EnemyProcess,
|
||||
TurnPhase.EnemyProcess => TurnPhase.GarbageCollection,
|
||||
_ => TurnPhase.Allocate
|
||||
};
|
||||
}
|
||||
|
||||
private void EnterPhase(TurnPhase phase)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f87432412de1ee46bf7d4c9c530d4c6
|
||||
@@ -0,0 +1,28 @@
|
||||
using System.Collections.Generic;
|
||||
using KernelPanic.Core;
|
||||
|
||||
namespace KernelPanic.Combat
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores mutable combat stats and statuses for a player or enemy.
|
||||
/// </summary>
|
||||
public sealed class CombatantState
|
||||
{
|
||||
private readonly Dictionary<StatusType, int> activeStatuses = new();
|
||||
|
||||
public CombatantState(int maxUptime, int ram, int cycles)
|
||||
{
|
||||
MaxUptime = maxUptime;
|
||||
CurrentUptime = maxUptime;
|
||||
Ram = ram;
|
||||
Cycles = cycles;
|
||||
}
|
||||
|
||||
public int CurrentUptime { get; set; }
|
||||
public int MaxUptime { get; set; }
|
||||
public int Shield { get; set; }
|
||||
public int Ram { get; set; }
|
||||
public int Cycles { get; set; }
|
||||
public IReadOnlyDictionary<StatusType, int> ActiveStatuses => activeStatuses;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93b1080022652b542903e204d36a64f8
|
||||
@@ -0,0 +1,49 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace KernelPanic.Combat
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages draw, discard, and exhaust piles for a combat deck.
|
||||
/// </summary>
|
||||
public sealed class DeckController
|
||||
{
|
||||
private readonly List<CardInstance> drawPile = new();
|
||||
private readonly List<CardInstance> discardPile = new();
|
||||
private readonly List<CardInstance> exhaustPile = new();
|
||||
|
||||
public IReadOnlyList<CardInstance> DrawPile => drawPile;
|
||||
public IReadOnlyList<CardInstance> DiscardPile => discardPile;
|
||||
public IReadOnlyList<CardInstance> ExhaustPile => exhaustPile;
|
||||
|
||||
public void Initialize(IEnumerable<CardInstance> cards)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public IReadOnlyList<CardInstance> Draw(int count)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Discard(CardInstance card)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Exhaust(CardInstance card)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ShuffleDrawPile()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ReshuffleDiscardIntoDraw()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6683933e853af334ba19e658b13c878d
|
||||
@@ -0,0 +1,41 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace KernelPanic.Combat
|
||||
{
|
||||
/// <summary>
|
||||
/// Manages cards currently held in hand with a RAM-based capacity.
|
||||
/// </summary>
|
||||
public sealed class HandController
|
||||
{
|
||||
private readonly List<CardInstance> cards = new();
|
||||
|
||||
public HandController(int ramCapacity)
|
||||
{
|
||||
RamCapacity = ramCapacity;
|
||||
}
|
||||
|
||||
public int RamCapacity { get; private set; }
|
||||
public IReadOnlyList<CardInstance> Cards => cards;
|
||||
|
||||
public bool CanAdd(CardInstance card)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Add(CardInstance card)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool Remove(CardInstance card)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bece1c6fddc2c63489bf129bf6295a31
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace KernelPanic.Combat
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a runtime card effect that can apply itself to a combat context.
|
||||
/// </summary>
|
||||
public interface ICardEffect
|
||||
{
|
||||
void Execute(CombatContext context);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 886be8d59396e5e488eea3ea58445fb4
|
||||
@@ -0,0 +1,11 @@
|
||||
namespace KernelPanic.Combat
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides a common contract for card resolution tracks.
|
||||
/// </summary>
|
||||
public interface IResolutionTrack
|
||||
{
|
||||
void Enqueue(CardInstance card);
|
||||
void Resolve(CombatContext context);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5d296d1160df6d747adaeec9ef68c710
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace KernelPanic.Combat
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores played cards in FIFO order for resolution during the Interpret phase.
|
||||
/// </summary>
|
||||
public sealed class InterpreterQueue : IResolutionTrack
|
||||
{
|
||||
private readonly Queue<CardInstance> queuedCards = new();
|
||||
|
||||
public int Count => queuedCards.Count;
|
||||
|
||||
public void Enqueue(CardInstance card)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Resolve(CombatContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 13c99cf765e7e8b48a58afbacc8a5440
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace KernelPanic.Combat
|
||||
{
|
||||
/// <summary>
|
||||
/// Stores played cards in LIFO order until explicitly force-evaluated.
|
||||
/// </summary>
|
||||
public sealed class LazyStack : IResolutionTrack
|
||||
{
|
||||
private readonly Stack<CardInstance> stackedCards = new();
|
||||
|
||||
public int Count => stackedCards.Count;
|
||||
|
||||
public void Enqueue(CardInstance card)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Resolve(CombatContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void ForceEvaluate(CombatContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 556859e6fac10a24bb4a60165fd82157
|
||||
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
|
||||
namespace KernelPanic.Combat
|
||||
{
|
||||
/// <summary>
|
||||
/// Resolves cards immediately when they are added to the native track.
|
||||
/// </summary>
|
||||
public sealed class NativeTrack : IResolutionTrack
|
||||
{
|
||||
public void Enqueue(CardInstance card)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Resolve(CombatContext context)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b662e4e1a38b1554084a063fd3d415e2
|
||||
@@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using KernelPanic.Core;
|
||||
|
||||
namespace KernelPanic.Combat
|
||||
{
|
||||
/// <summary>
|
||||
/// Applies, ticks, and expires status effects on a combatant.
|
||||
/// </summary>
|
||||
public sealed class StatusEffectController
|
||||
{
|
||||
public void Apply(CombatantState target, StatusType statusType, int stacks)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Tick(CombatantState target)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Expire(CombatantState target, StatusType statusType)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5f91b8d9171889f4996bb3106d97f1f6
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d51c41fa71b1068438855f64f946cc57
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,140 @@
|
||||
using System;
|
||||
using KernelPanic.Combat;
|
||||
|
||||
namespace KernelPanic.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides runtime events for gameplay systems that need to observe combat and run milestones.
|
||||
/// </summary>
|
||||
public static class GameEvents
|
||||
{
|
||||
public static event Action<CardPlayedEvent> CardPlayed;
|
||||
public static event Action<CardResolvedEvent> CardResolved;
|
||||
public static event Action<PhaseChangedEvent> PhaseChanged;
|
||||
public static event Action<DamageDealtEvent> DamageDealt;
|
||||
public static event Action<WaveClearedEvent> WaveCleared;
|
||||
public static event Action<RunEndedEvent> RunEnded;
|
||||
|
||||
public static void RaiseCardPlayed(CardPlayedEvent payload)
|
||||
{
|
||||
CardPlayed?.Invoke(payload);
|
||||
}
|
||||
|
||||
public static void RaiseCardResolved(CardResolvedEvent payload)
|
||||
{
|
||||
CardResolved?.Invoke(payload);
|
||||
}
|
||||
|
||||
public static void RaisePhaseChanged(PhaseChangedEvent payload)
|
||||
{
|
||||
PhaseChanged?.Invoke(payload);
|
||||
}
|
||||
|
||||
public static void RaiseDamageDealt(DamageDealtEvent payload)
|
||||
{
|
||||
DamageDealt?.Invoke(payload);
|
||||
}
|
||||
|
||||
public static void RaiseWaveCleared(WaveClearedEvent payload)
|
||||
{
|
||||
WaveCleared?.Invoke(payload);
|
||||
}
|
||||
|
||||
public static void RaiseRunEnded(RunEndedEvent payload)
|
||||
{
|
||||
RunEnded?.Invoke(payload);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes a card that entered a resolution track.
|
||||
/// </summary>
|
||||
public readonly struct CardPlayedEvent
|
||||
{
|
||||
public CardPlayedEvent(CardInstance card, ResolutionTrack track)
|
||||
{
|
||||
Card = card;
|
||||
Track = track;
|
||||
}
|
||||
|
||||
public CardInstance Card { get; }
|
||||
public ResolutionTrack Track { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes a card whose effects finished resolving.
|
||||
/// </summary>
|
||||
public readonly struct CardResolvedEvent
|
||||
{
|
||||
public CardResolvedEvent(CardInstance card, ResolutionTrack track)
|
||||
{
|
||||
Card = card;
|
||||
Track = track;
|
||||
}
|
||||
|
||||
public CardInstance Card { get; }
|
||||
public ResolutionTrack Track { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes a transition between combat phases.
|
||||
/// </summary>
|
||||
public readonly struct PhaseChangedEvent
|
||||
{
|
||||
public PhaseChangedEvent(TurnPhase previousPhase, TurnPhase nextPhase)
|
||||
{
|
||||
PreviousPhase = previousPhase;
|
||||
NextPhase = nextPhase;
|
||||
}
|
||||
|
||||
public TurnPhase PreviousPhase { get; }
|
||||
public TurnPhase NextPhase { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes damage applied from one combatant to another.
|
||||
/// </summary>
|
||||
public readonly struct DamageDealtEvent
|
||||
{
|
||||
public DamageDealtEvent(CombatantState source, CombatantState target, int amount, Language language)
|
||||
{
|
||||
Source = source;
|
||||
Target = target;
|
||||
Amount = amount;
|
||||
Language = language;
|
||||
}
|
||||
|
||||
public CombatantState Source { get; }
|
||||
public CombatantState Target { get; }
|
||||
public int Amount { get; }
|
||||
public Language Language { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes a completed enemy wave.
|
||||
/// </summary>
|
||||
public readonly struct WaveClearedEvent
|
||||
{
|
||||
public WaveClearedEvent(int waveNumber)
|
||||
{
|
||||
WaveNumber = waveNumber;
|
||||
}
|
||||
|
||||
public int WaveNumber { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes the end of a run and its earned meta currency.
|
||||
/// </summary>
|
||||
public readonly struct RunEndedEvent
|
||||
{
|
||||
public RunEndedEvent(bool playerDied, int entropyEarned)
|
||||
{
|
||||
PlayerDied = playerDied;
|
||||
EntropyEarned = entropyEarned;
|
||||
}
|
||||
|
||||
public bool PlayerDied { get; }
|
||||
public int EntropyEarned { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cf446c6fd7627294c9e2aa23c9b576e7
|
||||
@@ -0,0 +1,21 @@
|
||||
namespace KernelPanic.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Identifies a programming language used as a card damage type.
|
||||
/// </summary>
|
||||
public enum Language
|
||||
{
|
||||
C,
|
||||
CPlusPlus,
|
||||
Rust,
|
||||
Python,
|
||||
JavaScript,
|
||||
TypeScript,
|
||||
Haskell,
|
||||
Assembly,
|
||||
Java,
|
||||
Go,
|
||||
Ruby,
|
||||
PHP
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c06078e18f184c84cab3579c0e562dbe
|
||||
@@ -0,0 +1,13 @@
|
||||
namespace KernelPanic.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the rarity tier of cards and rewards.
|
||||
/// </summary>
|
||||
public enum Rarity
|
||||
{
|
||||
Common,
|
||||
Rare,
|
||||
Epic,
|
||||
Legendary
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 542a3f97e8074ed428fd7019177f221b
|
||||
@@ -0,0 +1,12 @@
|
||||
namespace KernelPanic.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Identifies the combat resolution track a card uses when played.
|
||||
/// </summary>
|
||||
public enum ResolutionTrack
|
||||
{
|
||||
Native,
|
||||
InterpreterQueue,
|
||||
LazyStack
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3b76dcac6b8cae447bb9079460692238
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace KernelPanic.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Identifies a combat status effect category.
|
||||
/// </summary>
|
||||
public enum StatusType
|
||||
{
|
||||
Segfault,
|
||||
MemoryLeak,
|
||||
RaceCondition,
|
||||
Deprecated,
|
||||
DependencyError,
|
||||
Deadlock
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cbdd46dffec613346ae6191f18a94225
|
||||
@@ -0,0 +1,15 @@
|
||||
namespace KernelPanic.Core
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the high-level phases of one combat turn.
|
||||
/// </summary>
|
||||
public enum TurnPhase
|
||||
{
|
||||
Boot,
|
||||
Allocate,
|
||||
Execute,
|
||||
Interpret,
|
||||
EnemyProcess,
|
||||
GarbageCollection
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e1974726f936d0640943801549b4574e
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e0a39b97df9ee0641b2bbadf5bca417c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,34 @@
|
||||
using System.Collections.Generic;
|
||||
using KernelPanic.Core;
|
||||
using UnityEngine;
|
||||
|
||||
namespace KernelPanic.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines immutable card data used to create runtime card instances.
|
||||
/// </summary>
|
||||
public sealed class CardDefinition : ScriptableObject
|
||||
{
|
||||
[SerializeField] private string id;
|
||||
[SerializeField] private string displayName;
|
||||
[SerializeField] private string description;
|
||||
[SerializeField] private Language language;
|
||||
[SerializeField] private Rarity rarity;
|
||||
[SerializeField] private int cycleCost;
|
||||
[SerializeField] private ResolutionTrack resolutionTrack;
|
||||
[SerializeField] private bool distroExclusive;
|
||||
[SerializeField] private CardDefinition upgradeTarget;
|
||||
[SerializeField] private List<CardEffectDefinition> effects = new();
|
||||
|
||||
public string Id => id;
|
||||
public string DisplayName => displayName;
|
||||
public string Description => description;
|
||||
public Language Language => language;
|
||||
public Rarity Rarity => rarity;
|
||||
public int CycleCost => cycleCost;
|
||||
public ResolutionTrack ResolutionTrack => resolutionTrack;
|
||||
public bool DistroExclusive => distroExclusive;
|
||||
public CardDefinition UpgradeTarget => upgradeTarget;
|
||||
public IReadOnlyList<CardEffectDefinition> Effects => effects;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5178747fac4dbfc448ff15d8a687e03c
|
||||
@@ -0,0 +1,13 @@
|
||||
using KernelPanic.Combat;
|
||||
using UnityEngine;
|
||||
|
||||
namespace KernelPanic.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines serialized card effect data that can create a runtime effect.
|
||||
/// </summary>
|
||||
public abstract class CardEffectDefinition : ScriptableObject
|
||||
{
|
||||
public abstract ICardEffect CreateRuntimeEffect();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: fdb3d58d94b76834598e408448e19d2a
|
||||
@@ -0,0 +1,30 @@
|
||||
using System.Collections.Generic;
|
||||
using KernelPanic.Core;
|
||||
using UnityEngine;
|
||||
|
||||
namespace KernelPanic.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines a playable distro character and its starting combat constraints.
|
||||
/// </summary>
|
||||
public sealed class DistroDefinition : ScriptableObject
|
||||
{
|
||||
[SerializeField] private string id;
|
||||
[SerializeField] private string displayName;
|
||||
[SerializeField] private Language primaryLanguage;
|
||||
[SerializeField] private Language secondaryLanguage;
|
||||
[SerializeField] private int baseUptime;
|
||||
[SerializeField] private int baseRam;
|
||||
[SerializeField] private int baseCyclesPerTurn;
|
||||
[SerializeField] private List<CardDefinition> exclusiveCards = new();
|
||||
|
||||
public string Id => id;
|
||||
public string DisplayName => displayName;
|
||||
public Language PrimaryLanguage => primaryLanguage;
|
||||
public Language SecondaryLanguage => secondaryLanguage;
|
||||
public int BaseUptime => baseUptime;
|
||||
public int BaseRam => baseRam;
|
||||
public int BaseCyclesPerTurn => baseCyclesPerTurn;
|
||||
public IReadOnlyList<CardDefinition> ExclusiveCards => exclusiveCards;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bd550368fd0c75d43a53aa4fb3b6541e
|
||||
@@ -0,0 +1,26 @@
|
||||
using System.Collections.Generic;
|
||||
using KernelPanic.Core;
|
||||
using UnityEngine;
|
||||
|
||||
namespace KernelPanic.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines enemy stats and language affinities for runtime combat setup.
|
||||
/// </summary>
|
||||
public sealed class EnemyDefinition : ScriptableObject
|
||||
{
|
||||
[SerializeField] private string id;
|
||||
[SerializeField] private string displayName;
|
||||
[SerializeField] private int baseUptime;
|
||||
[SerializeField] private List<Language> resistedLanguages = new();
|
||||
[SerializeField] private List<Language> weakLanguages = new();
|
||||
|
||||
public string Id => id;
|
||||
public string DisplayName => displayName;
|
||||
public int BaseUptime => baseUptime;
|
||||
public IReadOnlyList<Language> ResistedLanguages => resistedLanguages;
|
||||
public IReadOnlyList<Language> WeakLanguages => weakLanguages;
|
||||
|
||||
// TODO: Model enemy intents once combat actions are defined.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8b5b43b43c697c142b33fbfc5160cf90
|
||||
@@ -0,0 +1,17 @@
|
||||
using KernelPanic.Core;
|
||||
using UnityEngine;
|
||||
|
||||
namespace KernelPanic.Data
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines serialized status effect metadata and future stacking behavior.
|
||||
/// </summary>
|
||||
public sealed class StatusEffectDefinition : ScriptableObject
|
||||
{
|
||||
[SerializeField] private StatusType statusType;
|
||||
[SerializeField] private string stackingBehavior;
|
||||
|
||||
public StatusType StatusType => statusType;
|
||||
public string StackingBehavior => stackingBehavior;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1470a223647d6514f9439de7ded702c9
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"name": "KernelPanic.Runtime",
|
||||
"rootNamespace": "KernelPanic",
|
||||
"references": [],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6aad857173769044f861a0c6b1318032
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae19044bbccbb074da1d5e38b61e5657
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,26 @@
|
||||
namespace KernelPanic.Meta
|
||||
{
|
||||
/// <summary>
|
||||
/// Tracks the player's persistent entropy currency balance.
|
||||
/// </summary>
|
||||
public sealed class EntropyWallet
|
||||
{
|
||||
public int Balance { get; private set; }
|
||||
|
||||
public void Add(int amount)
|
||||
{
|
||||
Balance += amount;
|
||||
}
|
||||
|
||||
public bool Spend(int amount)
|
||||
{
|
||||
if (Balance < amount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
Balance -= amount;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8b77d0de67282ca4181a7c53feec4343
|
||||
@@ -0,0 +1,30 @@
|
||||
using System;
|
||||
|
||||
namespace KernelPanic.Meta
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides the contract for spending entropy on persistent unlock pulls.
|
||||
/// </summary>
|
||||
public sealed class GachaService
|
||||
{
|
||||
public GachaPullResult PerformPull(EntropyWallet wallet, int cost)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents the result of a persistent unlock pull.
|
||||
/// </summary>
|
||||
public readonly struct GachaPullResult
|
||||
{
|
||||
public GachaPullResult(bool success, string unlockId)
|
||||
{
|
||||
Success = success;
|
||||
UnlockId = unlockId;
|
||||
}
|
||||
|
||||
public bool Success { get; }
|
||||
public string UnlockId { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f62e697e985a8a44ca26ccb8e853ee66
|
||||
@@ -0,0 +1,28 @@
|
||||
using System;
|
||||
|
||||
namespace KernelPanic.Meta
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides save and load contracts for persistent meta progression.
|
||||
/// </summary>
|
||||
public sealed class SaveService
|
||||
{
|
||||
public void Save(SaveData data)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public SaveData Load()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Stores persistent progression data for serialization.
|
||||
/// </summary>
|
||||
public sealed class SaveData
|
||||
{
|
||||
public int EntropyBalance { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 752a83f338afd024b8e728a1921e38ee
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9ae21840b594d4147a8f5497c992b4fa
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using KernelPanic.Data;
|
||||
|
||||
namespace KernelPanic.Run
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides post-wave reward choice generation contracts.
|
||||
/// </summary>
|
||||
public sealed class RewardService
|
||||
{
|
||||
public IReadOnlyList<RewardChoice> GeneratePostWaveChoices(RunConfig runConfig, int waveNumber)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents one selectable reward option after clearing a wave.
|
||||
/// </summary>
|
||||
public readonly struct RewardChoice
|
||||
{
|
||||
public RewardChoice(RewardChoiceType type, CardDefinition card)
|
||||
{
|
||||
Type = type;
|
||||
Card = card;
|
||||
}
|
||||
|
||||
public RewardChoiceType Type { get; }
|
||||
public CardDefinition Card { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Identifies the type of reward choice offered after a wave.
|
||||
/// </summary>
|
||||
public enum RewardChoiceType
|
||||
{
|
||||
AddCard,
|
||||
UpgradeCard,
|
||||
Skip
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a06eada6fbafd6e44ae1d21238a64750
|
||||
@@ -0,0 +1,25 @@
|
||||
using System.Collections.Generic;
|
||||
using KernelPanic.Core;
|
||||
using KernelPanic.Data;
|
||||
|
||||
namespace KernelPanic.Run
|
||||
{
|
||||
/// <summary>
|
||||
/// Describes the player choices and starting deck used to begin a run.
|
||||
/// </summary>
|
||||
public sealed class RunConfig
|
||||
{
|
||||
public RunConfig(DistroDefinition distro, Language primaryLanguage, Language secondaryLanguage, IReadOnlyList<CardDefinition> startingDeck)
|
||||
{
|
||||
Distro = distro;
|
||||
PrimaryLanguage = primaryLanguage;
|
||||
SecondaryLanguage = secondaryLanguage;
|
||||
StartingDeck = startingDeck;
|
||||
}
|
||||
|
||||
public DistroDefinition Distro { get; }
|
||||
public Language PrimaryLanguage { get; }
|
||||
public Language SecondaryLanguage { get; }
|
||||
public IReadOnlyList<CardDefinition> StartingDeck { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0c3d34a2ce0e53b4b8f9a77feb60fb95
|
||||
@@ -0,0 +1,56 @@
|
||||
using KernelPanic.Combat;
|
||||
using KernelPanic.Core;
|
||||
using UnityEngine;
|
||||
|
||||
namespace KernelPanic.Run
|
||||
{
|
||||
/// <summary>
|
||||
/// Coordinates run lifecycle, wave progression, and run-level event handling.
|
||||
/// </summary>
|
||||
public sealed class RunManager : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private CombatManager combatManager;
|
||||
[SerializeField] private int currentWaveNumber;
|
||||
[SerializeField] private bool isRunActive;
|
||||
[SerializeField] private bool isPlayerDead;
|
||||
|
||||
public int CurrentWaveNumber => currentWaveNumber;
|
||||
public bool IsRunActive => isRunActive;
|
||||
public bool IsPlayerDead => isPlayerDead;
|
||||
|
||||
private void OnEnable()
|
||||
{
|
||||
GameEvents.WaveCleared += HandleWaveCleared;
|
||||
GameEvents.RunEnded += HandleRunEnded;
|
||||
}
|
||||
|
||||
private void OnDisable()
|
||||
{
|
||||
GameEvents.WaveCleared -= HandleWaveCleared;
|
||||
GameEvents.RunEnded -= HandleRunEnded;
|
||||
}
|
||||
|
||||
public void StartRun(RunConfig config)
|
||||
{
|
||||
isRunActive = true;
|
||||
isPlayerDead = false;
|
||||
currentWaveNumber = 1;
|
||||
StartCombat();
|
||||
}
|
||||
|
||||
public void StartCombat()
|
||||
{
|
||||
combatManager?.StartCombat();
|
||||
}
|
||||
|
||||
private void HandleWaveCleared(WaveClearedEvent payload)
|
||||
{
|
||||
}
|
||||
|
||||
private void HandleRunEnded(RunEndedEvent payload)
|
||||
{
|
||||
isRunActive = false;
|
||||
isPlayerDead = payload.PlayerDied;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 234cc6c5ca577b64ea44020f5514cebe
|
||||
Reference in New Issue
Block a user