/** * Grasscutter Tools * Copyright (C) 2022 jie65535 * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . * **/ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows.Forms; using GrasscutterTools.Game; using GrasscutterTools.Game.Gacha; using GrasscutterTools.Properties; using Newtonsoft.Json; namespace GrasscutterTools.Forms { /// /// 卡池编辑器 /// public partial class FormGachaBannerEditor : Form { #region - 初始化 - public FormGachaBannerEditor() { InitializeComponent(); Icon = Resources.IconGrasscutter; CmbBannerType.SelectedIndex = 0; InitBannerPrefab(); InitCheckedListBoxs(); } private void InitBannerPrefab() { CmbPrefab.DisplayMember = "Value"; CmbPrefab.DataSource = GameData.GachaBannerPrefabs; //CmbPrefab.Items.Clear(); //CmbPrefab.Items.AddRange(GameData.GachaBannerPrefabs.Names); } private void InitCheckedListBoxs() { InitCheckedListBox(ListYellowPool, "yellow"); InitCheckedListBox(ListPurplePool, "purple"); } private void InitCheckedListBox(CheckedListBox list, string color) { var kvs = new List(); for (int i = 0; i < GameData.AvatarColors.Count; i++) { if (GameData.AvatarColors.Names[i] == color) { var id = GameData.AvatarColors.Ids[i]; var index = Array.IndexOf(GameData.Avatars.Ids, id); if (index >= 0) kvs.Add($"{id}:{GameData.Avatars.Names[index]}"); } } for (int i = 0; i < GameData.WeaponColors.Count; i++) { if (GameData.WeaponColors.Names[i] == color) { var id = GameData.WeaponColors.Ids[i]; var index = Array.IndexOf(GameData.Weapons.Ids, id); if (index >= 0) kvs.Add($"{id}:{GameData.Weapons.Names[index]}"); } } list.Items.AddRange(kvs.ToArray()); } private void InitRateUpItems(GachaBanner banner) { UpdateCheckedListBox(ListYellowPool, banner.RateUpItems1); UpdateCheckedListBox(ListPurplePool, banner.RateUpItems2); } #endregion - 初始化 - #region - UI - private static string TrimPrefixAndSuffix(string text, int prefixLength, int suffixLength) { return text.Substring(prefixLength, text.Length - prefixLength - suffixLength); } private void ShowBanner(GachaBanner banner) { try { NUDGachaType.Value = banner.GachaType; NUDScheduleId.Value = banner.ScheduleId; CmbBannerType.SelectedIndex = (int)banner.BannerType; const string titlePrefix = "UI_GACHA_SHOW_PANEL_"; const string suffix = "_TITLE"; if (string.IsNullOrEmpty(banner.TitlePath) || banner.TitlePath.Length <= titlePrefix.Length + suffix.Length) { CmbPrefab.SelectedIndex = -1; } else { var titleKey = TrimPrefixAndSuffix(banner.TitlePath, titlePrefix.Length, suffix.Length); CmbPrefab.SelectedIndex = GameData.GachaBannerTitles.FindIndex(it => it.Key == titleKey); } RbCostItem224.Checked = banner.CostItem == 224; RbCostItem223.Checked = banner.CostItem == 223; NUDBeginTime.Value = banner.BeginTime; NUDEndTime.Value = banner.EndTime; NUDSortId.Value = banner.SortId; TxtRateUpItems1.Text = string.Join(", ", banner.RateUpItems1); TxtRateUpItems2.Text = string.Join(", ", banner.RateUpItems2); NUDBaseYellowWeight.Value = banner.BaseYellowWeight * 0.01M; NUDBasePurpleWeight.Value = banner.BasePurpleWeight * 0.01M; NUDEventChance.Value = banner.EventChance; NUDSoftPity.Value = banner.SoftPity; NUDHardPity.Value = banner.HardPity; InitRateUpItems(banner); } catch (Exception ex) { MessageBox.Show("UI更新失败:" + ex.Message, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); } } private GachaBanner ParseBanner() { if (CmbBannerType.SelectedIndex < 0) { MessageBox.Show("请选择奖池类型", Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); return null; } if (CmbPrefab.SelectedIndex < 0) { MessageBox.Show("请选择奖池预制", Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); return null; } int[] yellowIds; if (string.IsNullOrEmpty(TxtRateUpItems1.Text)) yellowIds = new int[0]; else yellowIds = TxtRateUpItems1.Text.Split(',').Select(s => int.Parse(s.Trim())).ToArray(); int[] purpleIds; if (string.IsNullOrEmpty(TxtRateUpItems2.Text)) purpleIds = new int[0]; else purpleIds = TxtRateUpItems2.Text.Split(',').Select(s => int.Parse(s.Trim())).ToArray(); var prefabId = GameData.GachaBannerPrefabs[CmbPrefab.SelectedIndex].Key; GachaBanner banner = new GachaBanner { GachaType = (int)NUDGachaType.Value, ScheduleId = (int)NUDScheduleId.Value, BannerType = (BannerType)CmbBannerType.SelectedIndex, PrefabPath = $"GachaShowPanel_{prefabId}", PreviewPrefabPath = $"UI_Tab_GachaShowPanel_{prefabId}", TitlePath = $"UI_GACHA_SHOW_PANEL_{prefabId}_TITLE", CostItem = RbCostItem224.Checked ? 224 : 223, BeginTime = (int)NUDBeginTime.Value, EndTime = (int)NUDEndTime.Value, SortId = (int)NUDSortId.Value, RateUpItems1 = yellowIds, RateUpItems2 = purpleIds, BaseYellowWeight = (int)(NUDBaseYellowWeight.Value * 100), BasePurpleWeight = (int)(NUDBasePurpleWeight.Value * 100), EventChance = (int)NUDEventChance.Value, SoftPity = (int)NUDSoftPity.Value, HardPity = (int)NUDHardPity.Value }; return banner; } #endregion - UI - #region - 事件 - private void UpdateCheckedListBox(CheckedListBox list, int[] checkedIds) { for (int i = 0; i < list.Items.Count; i++) { if (checkedIds.Length == 0) list.SetItemChecked(i, false); else { var item = list.Items[i] as string; var id = ItemMap.ToId(item); list.SetItemChecked(i, Array.IndexOf(checkedIds, id) != -1); } } } private void ListYellowPool_ItemCheck(object sender, ItemCheckEventArgs e) { BeginInvoke(new Action(() => UpdateCheckedItems(ListYellowPool, TxtRateUpItems1) )); } private void ListPurplePool_ItemCheck(object sender, ItemCheckEventArgs e) { BeginInvoke(new Action(() => UpdateCheckedItems(ListPurplePool, TxtRateUpItems2) )); } private void UpdateCheckedItems(CheckedListBox list, TextBox txt) { if (list.CheckedItems.Count == 0) txt.Text = ""; else { StringBuilder builder = new StringBuilder(); foreach (string item in list.CheckedItems) builder.Append(ItemMap.ToId(item)) .Append(", "); txt.Text = builder.ToString(0, builder.Length - 2); } } private void BtnGen_Click(object sender, EventArgs e) { var banner = ParseBanner(); if (banner != null) { TxtJson.Text = JsonConvert.SerializeObject(banner, Formatting.Indented); } } private void BtnParse_Click(object sender, EventArgs e) { try { ShowBanner(JsonConvert.DeserializeObject(TxtJson.Text)); } catch (Exception ex) { MessageBox.Show("Json解析失败,错误消息:" + ex.Message, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error); } } #endregion - 事件 - } }