Files
bansonic_beta_main/Assets/scripts/gamePlay_gameplay/LevelRules/LevelRuleConfig_SO.cs
T
2026-07-24 04:43:13 +08:00

143 lines
4.5 KiB
C#

using System;
using UnityEngine;
[CreateAssetMenu(fileName = "NewLevelRuleConfig", menuName = "Bansonic/Gameplay/Level Rule Config")]
public class LevelRuleConfig_SO : ScriptableObject
{
[Header("Match")]
public int songID = 0;
public string songName = string.Empty;
[Tooltip("-1 means any difficulty.")]
public int difficulty = -1;
[Header("Support Track")]
public bool useLeastNoteTrackAsSupportTrack = false;
[Tooltip("Used when useLeastNoteTrackAsSupportTrack is false. 0-4. -1 disables support-track logic.")]
public int supportTrackIndex = -1;
public int maxSupportCharges = 3;
public int adjacentSkillCastsPerSupportCharge = 3;
public float adjacentSkillCastWindow = 5f;
[Header("Echo")]
public bool enableAdjacentSkillEcho = false;
public float echoWindow = 1.5f;
public int echoThreshold = 3;
public int maxEchoStacks = 4;
public float echoResistancePerStack = 0.06f;
public float echoResistanceDuration = 4f;
public int echoManaPenalty = 0;
[Header("Conditional Rewards")]
public int allAlliesAliveScoreOnEnemyDeath = 0;
public bool awardAllAlliesAliveScorePerEnemy = false;
[Tooltip("At settlement: average living HP percent * this value is added as team score.")]
public int finalAverageHpPercentScore = 0;
[Header("Stages")]
public LevelRuleStage[] stages = Array.Empty<LevelRuleStage>();
public bool Matches(SongData song, int currentDifficulty)
{
if (song == null)
return false;
bool idMatches = songID != 0 && song.songID == songID;
bool nameMatches = !string.IsNullOrWhiteSpace(songName) && string.Equals(song.songName, songName, StringComparison.OrdinalIgnoreCase);
if (!idMatches && !nameMatches)
return false;
return difficulty < 0 || difficulty == currentDifficulty;
}
}
[Serializable]
public class LevelRuleStage
{
[Tooltip("-1 means match by current stage index. If enemyID > 0, enemy ID also has to match.")]
public int stageIndex = -1;
public int enemyID = 0;
[Tooltip("If > 0, this enemy is held at 1 HP before this song time.")]
public float minimumDeathSongTime = -1f;
public bool clearEchoOnSpawn = true;
public bool clearSupportChargesOnSpawn = false;
public LevelRuleAction[] onSpawn = Array.Empty<LevelRuleAction>();
public LevelRuleAction[] onManaFull = Array.Empty<LevelRuleAction>();
public LevelRuleAction[] onDeath = Array.Empty<LevelRuleAction>();
public LevelRuleAction[] onDamaged = Array.Empty<LevelRuleAction>();
public LevelRuleHoldAction[] onHoldStart = Array.Empty<LevelRuleHoldAction>();
public LevelRuleHoldAction[] onHoldComplete = Array.Empty<LevelRuleHoldAction>();
public LevelRuleHoldAction[] onHoldBreak = Array.Empty<LevelRuleHoldAction>();
public LevelRuleHpPhase[] hpPhases = Array.Empty<LevelRuleHpPhase>();
public bool Matches(int currentStageIndex, EnemyData_SO data)
{
if (stageIndex >= 0 && stageIndex != currentStageIndex)
return false;
if (enemyID > 0 && (data == null || data.enemyID != enemyID))
return false;
return stageIndex >= 0 || enemyID > 0;
}
}
[Serializable]
public class LevelRuleHpPhase
{
[Range(0f, 1f)]
public float hpPercentThreshold = 0.5f;
public bool triggerOnce = true;
public LevelRuleAction[] actions = Array.Empty<LevelRuleAction>();
}
[Serializable]
public class LevelRuleHoldAction
{
public LevelRuleAction[] actions = Array.Empty<LevelRuleAction>();
}
[Serializable]
public class LevelRuleAction
{
public string actionId = string.Empty;
public LevelRuleActionType actionType = LevelRuleActionType.None;
public LevelRuleTarget target = LevelRuleTarget.CurrentEnemy;
public float amount = 0f;
public bool amountScalesByDifficultyLevel = false;
public bool amountIsPercentOfMaxHp = false;
public float duration = 0f;
public int maxTriggersPerEnemy = 0;
public bool onlyIfAllAlliesAlive = false;
public bool requireSupportCharge = false;
public int scoreReward = 0;
}
public enum LevelRuleActionType
{
None,
Damage,
Heal,
ManaDelta,
AttackDelta,
ResistanceDeltaTimed,
HealReceivedMultiplierTimed,
AddTeamScore,
DamageCurrentEnemyByOwnAttack,
SpendSupportChargeForEnemyVulnerability,
ClearEnemyMana
}
public enum LevelRuleTarget
{
CurrentEnemy,
AllLivingAllies,
TriggerTrackAlly,
HighestCurrentManaAlly,
HighestAttackAlly,
HighestRecentHitTrackAlly,
HighestRecentSkillCastAlly
}