179 lines
11 KiB
C#
179 lines
11 KiB
C#
// ─────────────────────────────────────────────────────────────────────────────
|
|
// WLStarterKit.cs — 🔴 임시 테스트 장비 지급 (PD 2026-10-10 · PD 지시 시 삭제)
|
|
//
|
|
// PD 원문: 「기본 시작 무기는 검으로 하고, 인벤토리에 테스트 편의를 위해 임시로 각 무기 타입 별로 1개씩
|
|
// 가지고 있도록 해줘(추후 내가 지시하면 삭제할 임시 작업)」
|
|
//
|
|
// ■ 동작 — WLWeaponClassApplier.TryApply 가 인벤토리를 읽을 수 있을 때, 세이브 객체가 바뀔 때마다(로드·초기화) 1회:
|
|
// ① Resources/WL/WLStarterKit.json 의 grantGroups(계열별 기본 무기 그룹 6종)마다 같은 그룹 아이템이 없으면 1개 지급
|
|
// (등급 0부터 올라가며 표에 있는 첫 등급 · 있는 계열은 건너뜀 = 중복 0)
|
|
// 🔴 2026-10-11: WLEquipSettings.resetSaveEveryStart=1 이라 Play 마다 세이브가 비워진다 → 매 Play 다시 보장(전역 1회 표식 폐기)
|
|
// ② 무기를 아무것도 안 끼고 있으면 equipGroup(검 1435 묵광)을 장착 → 직업 전환기가 검 직업(10101)으로 바꾼다
|
|
// ③ #894(2026-10-17) PD 「무기 시너지를 시험할 수 있게 장갑·신발(펜릴 기사단 포함)을 시작 지급」 — synergyPartners 1 이면
|
|
// 무기 시너지 조건 장비(파츠 스킬 표 syn_key · req_key)를 1개씩 지급(없는 것만) · 장갑 · 신발 칸이 비어 있으면 표 순서의 첫 것을 장착
|
|
// #895 무기 시너지는 무기와 무관(장착 장비 조건만) → 무기 목록이 아니라 무기 시너지 정의 전부에서 조건 장비를 뽑는다
|
|
// #920(2026-10-18) PD 「장갑과 부츠 스킬을 변경할 예정이므로 게임 시작 시 장착하지 않은 상태로 시작」 — equipPartners 0 = 지급(인벤토리)만 · 장착 안 함
|
|
// ■ 끄기 = WLWeaponSettings.starterKit 0 · 완전 삭제 = 이 파일 + json + 설정 필드 + TryApply 한 줄.
|
|
// 🔴 Debug.LogError 금지(원본 ErrorLogHook 이 팝업을 띄운다).
|
|
// ─────────────────────────────────────────────────────────────────────────────
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using WL.Equip;
|
|
|
|
namespace WL.Combat.Weapon
|
|
{
|
|
[System.Serializable]
|
|
public class WLStarterKitJson
|
|
{
|
|
public int version = 1;
|
|
public int equipGroup = 1435;
|
|
public int[] grantGroups = new int[0];
|
|
public int synergyPartners = 0; // #894 1 = grantGroups 무기의 시너지 짝 장비(장갑 · 신발) 지급 + 시작 무기의 짝 장착
|
|
public int equipPartners = 1; // #920 PD 「장갑과 부츠 스킬을 변경할 예정이므로 게임 시작 시 장착하지 않은 상태로 시작」 — 0 = 짝 장비는 지급만(인벤토리) · 장착 안 함
|
|
public string note = "";
|
|
}
|
|
|
|
public static class WLStarterKit
|
|
{
|
|
public const string ResourcesPath = "WL/WLStarterKit";
|
|
public const string PrefsKeyPrefix = "WL_StarterKit_v";
|
|
|
|
public static int Granted, Equipped, Runs;
|
|
public static string LastLog = "";
|
|
static object s_lastData; // 마지막으로 처리한 세이브 객체 — 세이브가 다시 로드/초기화되면(새 객체) 다시 보장한다
|
|
|
|
/// <summary>검증용 — 다음 Ensure 가 세이브를 다시 훑게 한다(호환용 · 표식은 더 이상 쓰지 않는다).</summary>
|
|
public static void ResetPrefs()
|
|
{
|
|
PlayerPrefs.DeleteKey(PrefsKeyPrefix + "1");
|
|
s_lastData = null;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 🔴 2026-10-11 PD 「테스트 가능하게 종류별로 하나씩 추가해달라고 했잖아」 — 전역 PlayerPrefs 「1회 지급」 표식은 버린다.
|
|
/// WLEquipSettings.resetSaveEveryStart=1 이라 **Play 마다 인벤토리 세이브가 비워지는데** 표식은 남아 두 번째 Play 부터 지급이 건너뛰어졌다(PD 인벤토리 비어 있음).
|
|
/// 이제는 세이브가 로드/초기화될 때마다 「계열별 1개가 있는지」를 보장한다(없는 것만 지급 · 중복 0).
|
|
/// </summary>
|
|
public static void Ensure(WLWeaponSettings cfg)
|
|
{
|
|
if (cfg == null || cfg.starterKit == 0) return;
|
|
if (!WLInventory.EnsureLoaded()) return;
|
|
if (ReferenceEquals(s_lastData, WLInventory.Data)) return; // 이 세이브 객체는 이미 보장했다
|
|
var ta = Resources.Load<TextAsset>(ResourcesPath);
|
|
if (ta == null) { s_lastData = WLInventory.Data; LastLog = "표 없음 " + ResourcesPath; return; }
|
|
WLStarterKitJson j = null;
|
|
try { j = JsonUtility.FromJson<WLStarterKitJson>(ta.text); } catch (System.Exception ex) { LastLog = "표 파싱 실패 — " + ex.Message; }
|
|
if (j == null) { s_lastData = WLInventory.Data; return; }
|
|
s_lastData = WLInventory.Data;
|
|
Runs++;
|
|
|
|
int granted = 0;
|
|
var sb = new System.Text.StringBuilder();
|
|
if (j.grantGroups != null)
|
|
{
|
|
for (int i = 0; i < j.grantGroups.Length; i++)
|
|
{
|
|
int g = j.grantGroups[i];
|
|
if (FindGroup(g) != null) { sb.Append(g).Append("(있음) "); continue; }
|
|
var json = FirstTableItem(g);
|
|
if (json == null) { sb.Append(g).Append("(표 없음) "); continue; }
|
|
WLInventory.AddItem(json.Index, 1, 1);
|
|
granted++;
|
|
sb.Append(g).Append('→').Append(json.Item_name).Append(' ');
|
|
}
|
|
}
|
|
|
|
// ③ #894 무기 시너지 조건 장비(장갑 · 신발) — #895 무기 시너지는 무기와 무관(장착 장비 조건만) → 모든 무기 시너지의 조건 장비를 1개씩
|
|
int partners = 0;
|
|
var partnerGroups = j.synergyPartners != 0 ? PartnerGroups() : new List<int>();
|
|
if (j.synergyPartners != 0)
|
|
foreach (int pg in partnerGroups)
|
|
{
|
|
if (FindGroup(pg) != null) { sb.Append("짝 ").Append(pg).Append("(있음) "); continue; }
|
|
var json = FirstTableItem(pg);
|
|
if (json == null) { sb.Append("짝 ").Append(pg).Append("(표 없음) "); continue; }
|
|
WLInventory.AddItem(json.Index, 1, 1);
|
|
partners++;
|
|
sb.Append("짝 ").Append(pg).Append('→').Append(json.Item_name).Append(' ');
|
|
}
|
|
|
|
int equipped = 0;
|
|
if (WLInventory.EquippedInSlot(eFREquipmentType.Weapon) == null)
|
|
{
|
|
var it = FindGroup(j.equipGroup);
|
|
if (it != null && WLInventory.Equip(it.rawItem._id)) { equipped = 1; sb.Append("· 검 장착 ").Append(it.itemJson.Item_name); }
|
|
else sb.Append("· 검 그룹 ").Append(j.equipGroup).Append(" 없음 ");
|
|
}
|
|
|
|
// 조건 장비는 그 칸(장갑 · 신발)이 비어 있으면 표 순서의 첫 것을 낀다(#895 = 펜릴 기사단 신발 · 장갑 → 숫자 5 한 번으로 검기 발사체 · 원한의 맹독)
|
|
int partnerEquipped = 0;
|
|
if (j.synergyPartners != 0 && j.equipPartners != 0)
|
|
foreach (int pg in partnerGroups)
|
|
{
|
|
var p = FindGroup(pg);
|
|
if (p == null || p.itemJson == null || WLInventory.EquippedInSlot(p.itemJson.EquipmentType) != null) continue;
|
|
if (WLInventory.Equip(p.rawItem._id)) { partnerEquipped++; sb.Append("· 짝 장착 ").Append(p.itemJson.Item_name).Append(' '); }
|
|
}
|
|
|
|
if (granted > 0 || partners > 0 || equipped > 0 || partnerEquipped > 0)
|
|
WLInventory.Commit("WL 임시 시작 장비 — " + granted + "종 지급" + (partners > 0 ? " · 시너지 짝 " + partners + "종" : "") + (equipped > 0 ? " · 검 장착" : "") + (partnerEquipped > 0 ? " · 짝 장착" : ""));
|
|
Granted = granted; Equipped = equipped; PartnersGranted = partners; PartnersEquipped = partnerEquipped;
|
|
LastLog = "지급 " + granted + "종 · 짝 " + partners + "종" + (equipped > 0 ? " · 검 장착" : "") + (partnerEquipped > 0 ? " · 짝 장착 " + partnerEquipped : "") + " · " + sb;
|
|
if (cfg.verboseLog != 0 && (granted > 0 || partners > 0 || equipped > 0 || partnerEquipped > 0)) Debug.Log("[WL-833] 임시 시작 장비: " + LastLog);
|
|
}
|
|
|
|
public static int PartnersGranted, PartnersEquipped;
|
|
|
|
/// <summary>그 그룹의 표 아이템 중 가장 낮은 등급 하나(등급 0부터 · 기본 단계).</summary>
|
|
static ItemJson FirstTableItem(int group)
|
|
{
|
|
ItemJson json = null;
|
|
for (int gr = 0; gr < 7 && json == null; gr++)
|
|
{
|
|
try { json = WLEquipTables.FindGroupItem(group, (eFRItemGrade)gr, 0); } catch (System.Exception) { json = null; }
|
|
}
|
|
return json;
|
|
}
|
|
|
|
/// <summary>
|
|
/// #894 · #895 — 모든 무기 시너지의 조건 장비 그룹(중복 없음 · 파츠 스킬 표 순서). 무기 시너지 정의 → syn_key [+ req_key] → 그 스킬을 주는 장비 그룹 중 표에 있는 첫 그룹.
|
|
/// 값은 전부 파츠 스킬 표(WLPartSkillDefs.csv · 그룹 연결) — 이 파일에 아이템 번호 0개(C45).
|
|
/// </summary>
|
|
public static List<int> PartnerGroups()
|
|
{
|
|
var result = new List<int>();
|
|
if (!WL.PartSkill.WLPartSkillData.Enabled) return result;
|
|
foreach (var d in WL.PartSkill.WLPartSkillData.Defs)
|
|
{
|
|
if (d == null || d.kind != WL.PartSkill.WLPartKind.WeaponSyn) continue;
|
|
AddFirstGroup(result, d.synKey);
|
|
AddFirstGroup(result, d.reqKey);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
static void AddFirstGroup(List<int> result, string key)
|
|
{
|
|
if (string.IsNullOrEmpty(key)) return;
|
|
foreach (int pg in WL.PartSkill.WLPartSkillData.GroupsOf(key))
|
|
{
|
|
if (FirstTableItem(pg) == null) continue;
|
|
if (!result.Contains(pg)) result.Add(pg);
|
|
return;
|
|
}
|
|
}
|
|
|
|
static Item FindGroup(int group)
|
|
{
|
|
var items = WLInventory.SortedItems();
|
|
if (items == null) return null;
|
|
for (int i = 0; i < items.Count; i++)
|
|
{
|
|
var it = items[i];
|
|
if (it != null && it.itemJson != null && it.itemJson.GroupNo == group) return it;
|
|
}
|
|
return null;
|
|
}
|
|
}
|
|
}
|