feat: 젬 장착 제약 시스템 추가

- 기반 스킬 분류를 도입하고 젬별 장착 가능 스킬 타입 조건을 추가함
- 동일 젬 중복 장착, 카테고리 상호 배타, 특정 젬 상호 배타를 로드아웃 검증에 반영함
- 테스트용 젬/스킬 자산과 디버그 생성 메뉴를 새 제약 구조에 맞게 갱신함
- Unity 재컴파일과 콘솔 확인으로 신규 컴파일 에러가 없음을 검증함
This commit is contained in:
2026-03-26 14:49:59 +09:00
parent e4710f9a29
commit 1261d4dc3c
27 changed files with 399 additions and 34 deletions

View File

@@ -65,6 +65,14 @@ namespace Colosseum.Skills
[Tooltip("젬의 주 역할 분류")]
[SerializeField] private SkillGemCategory category = SkillGemCategory.Common;
[Header("장착 제약")]
[Tooltip("장착 가능한 기반 스킬 분류입니다. None 또는 All이면 제한하지 않습니다.")]
[SerializeField] private SkillBaseType allowedSkillTypes = SkillBaseType.All;
[Tooltip("함께 장착할 수 없는 젬 분류")]
[SerializeField] private SkillGemCategory[] incompatibleCategories = Array.Empty<SkillGemCategory>();
[Tooltip("함께 장착할 수 없는 특정 젬")]
[SerializeField] private List<SkillGemData> incompatibleGems = new();
[Header("기본 수치 보정")]
[Tooltip("장착 시 마나 비용 배율")]
[Min(0f)] [SerializeField] private float manaCostMultiplier = 1f;
@@ -99,6 +107,7 @@ namespace Colosseum.Skills
public string Description => description;
public Sprite Icon => icon;
public SkillGemCategory Category => category;
public SkillBaseType AllowedSkillTypes => allowedSkillTypes;
public float ManaCostMultiplier => manaCostMultiplier;
public float CooldownMultiplier => cooldownMultiplier;
public float CastSpeedMultiplier => castSpeedMultiplier;
@@ -107,9 +116,59 @@ namespace Colosseum.Skills
public float ShieldMultiplier => shieldMultiplier;
public float ThreatMultiplier => threatMultiplier;
public int AdditionalRepeatCount => additionalRepeatCount;
public IReadOnlyList<SkillGemCategory> IncompatibleCategories => incompatibleCategories;
public IReadOnlyList<SkillGemData> IncompatibleGems => incompatibleGems;
public IReadOnlyList<SkillEffect> CastStartEffects => castStartEffects;
public IReadOnlyList<SkillGemTriggeredEffectEntry> TriggeredEffects => triggeredEffects;
public IReadOnlyList<AbnormalityData> SelfAbnormalities => selfAbnormalities;
public IReadOnlyList<SkillGemTriggeredAbnormalityEntry> OnHitAbnormalities => onHitAbnormalities;
/// <summary>
/// 지정한 기반 스킬에 이 젬을 장착할 수 있는지 확인합니다.
/// </summary>
public bool CanAttachToSkill(SkillData skill)
{
if (skill == null)
return false;
if (allowedSkillTypes == SkillBaseType.None || allowedSkillTypes == SkillBaseType.All)
return true;
return (allowedSkillTypes & skill.BaseTypes) != 0;
}
/// <summary>
/// 지정한 젬 분류와 상호 배타적인지 확인합니다.
/// </summary>
public bool IsCategoryIncompatible(SkillGemCategory otherCategory)
{
if (incompatibleCategories == null || incompatibleCategories.Length == 0)
return false;
for (int i = 0; i < incompatibleCategories.Length; i++)
{
if (incompatibleCategories[i] == otherCategory)
return true;
}
return false;
}
/// <summary>
/// 지정한 젬과 상호 배타적인지 확인합니다.
/// </summary>
public bool IsGemIncompatible(SkillGemData other)
{
if (other == null || incompatibleGems == null || incompatibleGems.Count == 0)
return false;
for (int i = 0; i < incompatibleGems.Count; i++)
{
if (incompatibleGems[i] == other)
return true;
}
return false;
}
}
}