Project_WL/Assets/WL/Combat/Weapon/WLWeaponGradeCheat.cs

159 lines
8.4 KiB
C#

// ─────────────────────────────────────────────────────────────────────────────
// WLWeaponGradeCheat.cs — 🔴 임시 테스트 치트: 숫자 키로 낀 무기 등급 바꾸기 (PD #886 · 2026-10-17 · PD 지시 시 삭제)
//
// PD 원문: 「이후 스킬은 내가 하나씩 보면서 테스트 할 수 있도록 각 무기 타입별로 배치하고,
// 숫자 버튼 입력에 따라 무기 등급을 바꿀 수 있게 치트 기능을 제공해줘.」
//
// ■ 동작 — 숫자 키 1~7(키패드 포함 · 등급 표 단계 수까지) = 지금 낀 장비(#894 PD 「숫자 키가 낀 장비 전체 등급을 바꾸게」 = 무기 · 장갑 · 신발 등 모든 칸)를
// 칸마다 같은 그룹의 그 등급(기본 단계) 아이템으로 바꿔 낀다.
// 인벤토리에 그 아이템이 있으면 그것을, 없으면 같은 레벨로 1개 지급 → WLInventory.Equip(저장 · 통지)
// → 무기 기술 슬롯(WLWeaponSkillSlots) · 파츠 스킬(WLPartSkillState)이 장착 변경으로 다시 붙는다. 화면 위쪽에 결과 한 줄.
// ■ 무기 타입별 시험 무기 = WLStarterKit.json grantGroups(무기 기술이 있는 무기 전부 + 창) — 이 파일은 등급만 바꾼다.
// ■ 값 = Resources/WL/WLWeaponGradeCheat.json · 끄기 = enabled 0(오브젝트 0) · 완전 삭제 = 이 파일 + json
// 🔴 Debug.LogError 금지(원본 ErrorLogHook 이 팝업을 띄운다).
// ─────────────────────────────────────────────────────────────────────────────
using System.Collections.Generic;
using UnityEngine;
using WL.Equip;
namespace WL.Combat.Weapon
{
[System.Serializable]
public class WLWeaponGradeCheatJson
{
public int enabled = 0;
public float messageSeconds = 2.5f;
public float messageFontScale = 0.028f;
public float messageTopRatio = 0.12f;
public string note = "";
}
public static class WLWeaponGradeCheat
{
public const string ResourcesPath = "WL/WLWeaponGradeCheat";
public static int Applied, Failed;
public static string LastLog = "";
internal static string Message = "";
internal static float MessageUntil;
static WLWeaponGradeCheatJson s_cfg;
static WLWeaponGradeCheatRunner s_runner;
internal static WLWeaponGradeCheatJson Cfg
{
get
{
if (s_cfg != null) return s_cfg;
s_cfg = new WLWeaponGradeCheatJson();
var ta = Resources.Load<TextAsset>(ResourcesPath);
if (ta == null) { LastLog = "설정 없음 " + ResourcesPath; return s_cfg; }
try { JsonUtility.FromJsonOverwrite(ta.text, s_cfg); } catch (System.Exception ex) { LastLog = "설정 파싱 실패 — " + ex.Message; }
return s_cfg;
}
}
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.AfterSceneLoad)]
static void Boot()
{
s_cfg = null;
if (Cfg.enabled == 0 || !DSUtil.CheckNull(s_runner)) return; // 꺼져 있으면 오브젝트 0
var go = new GameObject("[WL886] WeaponGradeCheat");
go.hideFlags = HideFlags.HideAndDontSave;
s_runner = go.AddComponent<WLWeaponGradeCheatRunner>();
}
/// <summary>낀 장비 전체를 칸마다 같은 그룹의 tier 등급(기본 단계) 아이템으로 바꿔 낀다 · 결과 문장을 화면에 띄운다.</summary>
public static string Apply(int tier)
{
var r = ApplyInner(tier);
LastLog = r; Message = r; MessageUntil = Time.unscaledTime + Cfg.messageSeconds;
return r;
}
public static int LastChanged, LastSame, LastMissing;
static string ApplyInner(int tier)
{
if (!WLInventory.EnsureLoaded()) { Failed++; return "인벤토리 없음"; }
var step = WLEquipGrades.BaseStepOfTier(tier);
if (step == null) { Failed++; return "등급 " + tier + " 없음(표 " + WLEquipGrades.MaxTier + "단계)"; }
// #894 — 먼저 낀 장비를 모아 두고 바꾼다(바꾸는 동안 칸 내용이 바뀐다)
var cur = new List<Item>();
for (int t = (int)eFREquipmentType.Weapon; t < (int)eFREquipmentType.Max; t++)
{
var e = WLInventory.EquippedInSlot((eFREquipmentType)t);
if (e != null && e.itemJson != null) cur.Add(e);
}
if (cur.Count == 0) { Failed++; return "낀 장비 없음"; }
int changed = 0, same = 0, missing = 0;
var fail = new System.Text.StringBuilder();
foreach (var c in cur)
{
int r = SwapToStep(c, step);
if (r == 1) changed++;
else if (r == 0) same++;
else { missing++; fail.Append(' ').Append(c.itemJson.Item_name).Append(r == -1 ? "(그 등급 없음)" : "(장착 실패)"); }
}
LastChanged = changed; LastSame = same; LastMissing = missing;
if (changed > 0) Applied++;
if (missing > 0) Failed++;
return "낀 장비 " + cur.Count + "개 → " + WLEquipGrades.TierLabel(tier, false) + " (숫자 " + tier + ") · 바꿈 " + changed
+ (same > 0 ? " · 이미 " + same : "") + (missing > 0 ? " · 못 바꿈" + fail : "");
}
/// <summary>그 장비를 같은 그룹의 step 아이템으로 바꿔 낀다. 1 바꿈 · 0 이미 그 등급 · -1 표에 없음 · -2 장착 실패.</summary>
static int SwapToStep(Item cur, WLGradeFrMap step)
{
int g = cur.itemJson.GroupNo;
ItemJson found = null;
foreach (var j in WLEquipTables.Items)
if (j != null && j.IsEquipment && j.GroupNo == g && (int)j.ItemGrade == step.frGrade && j.GradeLv == step.gradeLv) { found = j; break; }
if (found == null) return -1;
if (found.Index == cur.itemJson.Index) return 0;
Item it = null;
foreach (var x in WLInventory.SortedItems()) if (x.itemJson.Index == found.Index) { it = x; break; }
if (it == null)
{
var gained = new List<Item>();
WLInventory.AddItem(found.Index, Mathf.Max(1, cur.rawItem.level), 1, gained);
it = gained.Count > 0 ? gained[gained.Count - 1] : null;
}
return it != null && WLInventory.Equip(it.rawItem._id) ? 1 : -2;
}
}
/// <summary>숫자 키 읽기 · 결과 한 줄 표시. 숨김 GameObject 1개.</summary>
internal sealed class WLWeaponGradeCheatRunner : MonoBehaviour
{
static readonly KeyCode[] s_alpha = { KeyCode.Alpha1, KeyCode.Alpha2, KeyCode.Alpha3, KeyCode.Alpha4, KeyCode.Alpha5, KeyCode.Alpha6, KeyCode.Alpha7, KeyCode.Alpha8, KeyCode.Alpha9 };
static readonly KeyCode[] s_pad = { KeyCode.Keypad1, KeyCode.Keypad2, KeyCode.Keypad3, KeyCode.Keypad4, KeyCode.Keypad5, KeyCode.Keypad6, KeyCode.Keypad7, KeyCode.Keypad8, KeyCode.Keypad9 };
GUIStyle _style;
void Update()
{
if (!Input.anyKeyDown) return;
int max = Mathf.Min(s_alpha.Length, WLEquipGrades.MaxTier);
for (int i = 0; i < max; i++)
if (Input.GetKeyDown(s_alpha[i]) || Input.GetKeyDown(s_pad[i])) { WLWeaponGradeCheat.Apply(i + 1); break; }
}
void OnGUI()
{
var msg = WLWeaponGradeCheat.Message;
if (string.IsNullOrEmpty(msg) || Time.unscaledTime > WLWeaponGradeCheat.MessageUntil) return;
var c = WLWeaponGradeCheat.Cfg;
if (_style == null) _style = new GUIStyle(GUI.skin.label) { alignment = TextAnchor.MiddleCenter, fontStyle = FontStyle.Bold };
_style.fontSize = Mathf.Max(14, Mathf.RoundToInt(Screen.height * c.messageFontScale));
var r = new Rect(0f, Screen.height * c.messageTopRatio, Screen.width, _style.fontSize * 2f);
var keep = GUI.color;
GUI.color = new Color(0f, 0f, 0f, 0.75f); GUI.Label(new Rect(r.x + 2f, r.y + 2f, r.width, r.height), msg, _style);
GUI.color = Color.yellow; GUI.Label(r, msg, _style);
GUI.color = keep;
}
}
}