Impl ShopEditor UI (WIP)

This commit is contained in:
2022-10-31 22:47:12 +08:00
parent 757bb2dd95
commit 52317d8d5a
11 changed files with 983 additions and 570 deletions

View File

@ -49,6 +49,9 @@
<setting name="DefaultMailSender" serializeAs="String">
<value>GrasscutterTools</value>
</setting>
<setting name="ShopJsonPath" serializeAs="String">
<value />
</setting>
</GrasscutterTools.Properties.Settings>
</userSettings>
</configuration>

View File

@ -266,6 +266,7 @@ namespace GrasscutterTools.Forms
this.LblMailTitleLabel = new System.Windows.Forms.Label();
this.TxtMailSender = new System.Windows.Forms.TextBox();
this.LblMailSenderLabel = new System.Windows.Forms.Label();
this.BtnOpenShopEditor = new System.Windows.Forms.Button();
this.GrpCommand.SuspendLayout();
this.TPRemoteCall.SuspendLayout();
this.GrpServerStatus.SuspendLayout();
@ -2004,6 +2005,7 @@ namespace GrasscutterTools.Forms
//
// TPHome
//
this.TPHome.Controls.Add(this.BtnOpenShopEditor);
this.TPHome.Controls.Add(this.BtnOpenDropEditor);
this.TPHome.Controls.Add(this.LnkNewVersion);
this.TPHome.Controls.Add(this.LblAbout);
@ -2394,6 +2396,13 @@ namespace GrasscutterTools.Forms
resources.ApplyResources(this.LblMailSenderLabel, "LblMailSenderLabel");
this.LblMailSenderLabel.Name = "LblMailSenderLabel";
//
// BtnOpenShopEditor
//
resources.ApplyResources(this.BtnOpenShopEditor, "BtnOpenShopEditor");
this.BtnOpenShopEditor.Name = "BtnOpenShopEditor";
this.BtnOpenShopEditor.UseVisualStyleBackColor = true;
this.BtnOpenShopEditor.Click += new System.EventHandler(this.BtnOpenShopEditor_Click);
//
// FormMain
//
resources.ApplyResources(this, "$this");
@ -2743,5 +2752,6 @@ namespace GrasscutterTools.Forms
private System.Windows.Forms.LinkLabel LnkSetConst;
private System.Windows.Forms.NumericUpDown NUDSetConstellation;
private System.Windows.Forms.FlowLayoutPanel FLPEntityType;
private System.Windows.Forms.Button BtnOpenShopEditor;
}
}

View File

@ -65,6 +65,7 @@ namespace GrasscutterTools.Forms
Text += " - by jie65535 - v" + AppVersion.ToString(3);
#if DEBUG
Text += "-debug";
//Text += "-debug -攻击修改特供版";
#endif
GameData.LoadResources();
@ -295,6 +296,27 @@ namespace GrasscutterTools.Forms
}
}
/// <summary>
/// 商店编辑器窗口实例
/// </summary>
private FormShopEditor ShopEditor;
/// <summary>
/// 点击打开商店编辑器时触发
/// </summary>
private void BtnOpenShopEditor_Click(object sender, EventArgs e)
{
if (ShopEditor == null || ShopEditor.IsDisposed)
{
ShopEditor = new FormShopEditor();
ShopEditor.Show();
}
else
{
ToTop(ShopEditor);
}
}
/// <summary>
/// 语言选中项改变时触发
/// </summary>
@ -1184,6 +1206,11 @@ namespace GrasscutterTools.Forms
if (!string.IsNullOrEmpty(selectedItem))
{
var id = ItemMap.ToId(selectedItem);
//// 自定义攻击Gadget特供版
//SetCommand("/at", $"set n {id}");
//return true;
if (Check(CommandVersion.V1_3_1))
SetCommand("/spawn", $"{id} x{NUDEntityAmout.Value} lv{NUDEntityLevel.Value}" + (ChkInfiniteHP.Checked ? " hp0" : ""));
else

View File

@ -5468,6 +5468,30 @@
<data name="&gt;&gt;TPCustom.ZOrder" xml:space="preserve">
<value>1</value>
</data>
<data name="BtnOpenShopEditor.Location" type="System.Drawing.Point, System.Drawing">
<value>313, 187</value>
</data>
<data name="BtnOpenShopEditor.Size" type="System.Drawing.Size, System.Drawing">
<value>100, 23</value>
</data>
<data name="BtnOpenShopEditor.TabIndex" type="System.Int32, mscorlib">
<value>11</value>
</data>
<data name="BtnOpenShopEditor.Text" xml:space="preserve">
<value>商店编辑器</value>
</data>
<data name="&gt;&gt;BtnOpenShopEditor.Name" xml:space="preserve">
<value>BtnOpenShopEditor</value>
</data>
<data name="&gt;&gt;BtnOpenShopEditor.Type" xml:space="preserve">
<value>System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</data>
<data name="&gt;&gt;BtnOpenShopEditor.Parent" xml:space="preserve">
<value>TPHome</value>
</data>
<data name="&gt;&gt;BtnOpenShopEditor.ZOrder" xml:space="preserve">
<value>0</value>
</data>
<data name="BtnOpenDropEditor.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Bottom, Right</value>
</data>
@ -5496,7 +5520,7 @@
<value>TPHome</value>
</data>
<data name="&gt;&gt;BtnOpenDropEditor.ZOrder" xml:space="preserve">
<value>0</value>
<value>1</value>
</data>
<data name="LnkNewVersion.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Bottom, Left</value>
@ -5532,7 +5556,7 @@
<value>TPHome</value>
</data>
<data name="&gt;&gt;LnkNewVersion.ZOrder" xml:space="preserve">
<value>1</value>
<value>2</value>
</data>
<data name="LblAbout.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Left</value>
@ -5568,7 +5592,7 @@
<value>TPHome</value>
</data>
<data name="&gt;&gt;LblAbout.ZOrder" xml:space="preserve">
<value>2</value>
<value>3</value>
</data>
<data name="BtnOpenTextMap.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Bottom, Right</value>
@ -5598,7 +5622,7 @@
<value>TPHome</value>
</data>
<data name="&gt;&gt;BtnOpenTextMap.ZOrder" xml:space="preserve">
<value>3</value>
<value>4</value>
</data>
<data name="BtnOpenGachaBannerEditor.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Bottom, Right</value>
@ -5628,7 +5652,7 @@
<value>TPHome</value>
</data>
<data name="&gt;&gt;BtnOpenGachaBannerEditor.ZOrder" xml:space="preserve">
<value>4</value>
<value>5</value>
</data>
<data name="GrasscutterToolsIcon.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Top, Bottom, Left, Right</value>
@ -5658,7 +5682,7 @@
<value>TPHome</value>
</data>
<data name="&gt;&gt;GrasscutterToolsIcon.ZOrder" xml:space="preserve">
<value>5</value>
<value>6</value>
</data>
<data name="GrpSettings.Anchor" type="System.Windows.Forms.AnchorStyles, System.Windows.Forms">
<value>Bottom, Left</value>
@ -5898,7 +5922,7 @@
<value>TPHome</value>
</data>
<data name="&gt;&gt;GrpSettings.ZOrder" xml:space="preserve">
<value>6</value>
<value>7</value>
</data>
<data name="TPHome.Location" type="System.Drawing.Point, System.Drawing">
<value>4, 26</value>

File diff suppressed because it is too large Load Diff

View File

@ -1,24 +1,281 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using GrasscutterTools.Game;
using GrasscutterTools.Game.Shop;
using GrasscutterTools.Properties;
using GrasscutterTools.Utils;
using Newtonsoft.Json;
namespace GrasscutterTools.Forms
{
public partial class FormShopEditor : Form
{
#region - -
private Dictionary<int, List<ShopInfo>> Shops = new Dictionary<int, List<ShopInfo>>();
private List<ShopInfo> SelectedShop = new List<ShopInfo>();
#endregion
#region - -
public FormShopEditor()
{
InitializeComponent();
Icon = Resources.IconGrasscutter;
ListShop.Items.AddRange(GameData.ShopType.Lines);
ListItems.Items.AddRange(GameData.Items.Lines);
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
try
{
// 加载文件路径
var path = Settings.Default.ShopJsonPath;
TxtShopJsonPath.Text = path;
if (!string.IsNullOrEmpty(path) && File.Exists(path))
LoadShops(path);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
protected override void OnFormClosed(FormClosedEventArgs e)
{
Settings.Default.ShopJsonPath = TxtShopJsonPath.Text;
Settings.Default.Save();
base.OnFormClosed(e);
}
#endregion - -
#region - Shop.json -
/// <summary>
/// 点击加载Shop.json按钮时触发
/// </summary>
private void BtnLoad_Click(object sender, EventArgs e)
{
try
{
var path = TxtShopJsonPath.Text.Trim();
if (path == string.Empty)
{
var dialog = new OpenFileDialog
{
FileName = "Shop.json",
Filter = "Shop.Json (*.json)|*.json|All files (*.*)|*.*",
};
var result = dialog.ShowDialog();
if (result == DialogResult.OK)
path = TxtShopJsonPath.Text = dialog.FileName;
else
return;
}
// 反序列化
LoadShops(path);
MessageBox.Show("OK", Resources.Tips, MessageBoxButtons.OK);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
/// <summary>
/// 加载商店
/// </summary>
/// <param name="path"></param>
private void LoadShops(string path)
{
// 反序列化
var banners = JsonConvert.DeserializeObject<List<ShopTable>>(File.ReadAllText(path));
Shops = new Dictionary<int, List<ShopInfo>>(banners.Count);
foreach (var item in banners)
Shops.Add(item.ShopType, item.Items);
}
/// <summary>
/// 点击保存Shop.json按钮时触发
/// </summary>
private void BtnSave_Click(object sender, EventArgs e)
{
try
{
var path = TxtShopJsonPath.Text.Trim();
if (path == string.Empty)
{
var dialog = new SaveFileDialog
{
FileName = "Shop.json",
Filter = "Shop.json (*.json)|*.json|All files (*.*)|*.*",
};
var result = dialog.ShowDialog();
if (result == DialogResult.OK)
path = TxtShopJsonPath.Text = dialog.FileName;
else
return;
}
// 序列化
var banners = new List<ShopTable>(Shops.Count);
foreach (var shop in Shops)
{
banners.Add(new ShopTable
{
ShopType = shop.Key,
Items = shop.Value,
});
}
File.WriteAllText(path, JsonConvert.SerializeObject(banners));
MessageBox.Show("OK", Resources.Tips, MessageBoxButtons.OK);
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString(), Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
#endregion - Shop.json -
#region - -
/// <summary>
/// 商店列表选中项改变时触发
/// </summary>
private void ListShop_SelectedIndexChanged(object sender, EventArgs e)
{
if (ListShop.SelectedIndex == -1) return;
var shopType = ItemMap.ToId(ListShop.SelectedItem as string);
SelectedShop.Clear();
if (Shops.TryGetValue(shopType, out var items))
SelectedShop.AddRange(items);
ShowGoodsList(SelectedShop);
}
#endregion - -
#region - -
/// <summary>
/// 显示商品列表
/// </summary>
private void ShowGoodsList(List<ShopInfo> banner)
{
ListGoods.BeginUpdate();
ListGoods.Items.Clear();
if (banner.Count > 0)
{
ListGoods.Items.AddRange(banner.Select(it => it.ToString()).ToArray());
ListGoods.SelectedIndex = 0;
}
ListGoods.EndUpdate();
}
/// <summary>
/// 商品列表选中项改变时触发
/// </summary>
private void ListGoods_SelectedIndexChanged(object sender, EventArgs e)
{
if (ListGoods.SelectedIndex == -1) return;
ShowGoods(SelectedShop[ListGoods.SelectedIndex]);
}
#endregion - -
#region - -
/// <summary>
/// 显示商品
/// </summary>
/// <param name="goods"></param>
private void ShowGoods(ShopInfo goods)
{
NUDGoodsId.Value = goods.GoodsId;
TxtGoodsItem.Text = $"{goods.GoodsItem.Id}:{GameData.Items[goods.GoodsItem.Id]}";
NUDGoodsItemCount.Value = goods.GoodsItem.Count;
NUDBuyLimit.Value = goods.BuyLimit;
NUDMinLevel.Value = goods.MinLevel;
NUDMaxLevel.Value = goods.MaxLevel;
DTPBeginTime.Value = DateTimeOffset.FromUnixTimeSeconds(goods.BeginTime).DateTime;
DTPEndTime.Value = DateTimeOffset.FromUnixTimeSeconds(goods.EndTime).DateTime;
NUDRefreshParm.Value = goods.ShopRefreshParam;
CmbRefreshType.SelectedIndex = (int)goods.RefreshType;
NUDCostHcoin.Value = goods.HCoin;
NUDCostScoin.Value = goods.SCoin;
NUDCostMcoin.Value = goods.MCoin;
var items = new ItemParamData[4];
goods.CostItemList?.CopyTo(items, 0);
NUDCostItem1.Value = items[0].Id;
NUDCostItem1Count.Value = items[0].Count;
NUDCostItem2.Value = items[1].Id;
NUDCostItem2Count.Value = items[1].Count;
NUDCostItem3.Value = items[2].Id;
NUDCostItem3Count.Value = items[2].Count;
NUDCostItem4.Value = items[3].Id;
NUDCostItem4Count.Value = items[3].Count;
}
/// <summary>
/// 点击生成商品ID链接标签时触发
/// </summary>
private void LnkGenGoodsId_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
{
}
/// <summary>
/// 刷新类型选中项改变时触发
/// </summary>
private void CmbRefreshType_SelectedIndexChanged(object sender, EventArgs e)
{
NUDRefreshParm.Enabled = CmbRefreshType.SelectedIndex > 0;
}
/// <summary>
/// 点击保存商品按钮时触发
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void BtnSaveGoods_Click(object sender, EventArgs e)
{
}
#endregion - -
#region - -
/// <summary>
/// 物品列表过滤框输入改变事件
/// </summary>
private void TxtItemFilter_TextChanged(object sender, EventArgs e)
{
UIUtil.ListBoxFilter(ListItems, GameData.Items.Lines, TxtItemFilter.Text);
}
/// <summary>
/// 物品列表选中项改变时触发
/// </summary>
private void ListItems_SelectedIndexChanged(object sender, EventArgs e)
{
if (ListItems.SelectedIndex == -1) return;
TxtGoodsItem.Text = ListItems.SelectedItem as string;
}
#endregion - -
}
}

View File

@ -66,8 +66,19 @@ namespace GrasscutterTools.Game.Shop
[JsonProperty("disableType")]
public int DisableType { get; set; }
[JsonProperty("secondarySheetId")]
public int SecondarySheetId { get; set; }
[JsonProperty("refreshType")]
public ShopRefreshType RefreshType { get; set; }
[JsonProperty("shopRefreshParam")]
public int ShopRefreshParam { get; set; }
public override string ToString()
{
return $"{GoodsId}:{GameData.Items[GoodsItem.Id]} x{GoodsItem.Count}";
}
}
}

View File

@ -0,0 +1,34 @@
using Newtonsoft.Json;
namespace GrasscutterTools.Game.Shop
{
/// <summary>
/// 商品刷新类型
/// </summary>
public enum ShopRefreshType
{
/// <summary>
/// 不刷新
/// </summary>
[JsonProperty("NONE")]
None,
/// <summary>
/// 按天刷新
/// </summary>
[JsonProperty("SHOP_REFRESH_DAILY")]
Daily,
/// <summary>
/// 按周刷新
/// </summary>
[JsonProperty("SHOP_REFRESH_WEEKLY")]
Weekly,
/// <summary>
/// 按月刷新
/// </summary>
[JsonProperty("SHOP_REFRESH_MONTHLY")]
Monthly,
}
}

View File

@ -142,6 +142,7 @@
<Compile Include="Game\SetStatsCommand.cs" />
<Compile Include="Game\Shop\ItemParamData.cs" />
<Compile Include="Game\Shop\ShopInfo.cs" />
<Compile Include="Game\Shop\ShopRefreshType.cs" />
<Compile Include="Game\Shop\ShopTable.cs" />
<Compile Include="Game\TextMapData.cs" />
<Compile Include="GOOD\GOOD.cs" />

View File

@ -178,5 +178,17 @@ namespace GrasscutterTools.Properties {
this["DefaultMailSender"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string ShopJsonPath {
get {
return ((string)(this["ShopJsonPath"]));
}
set {
this["ShopJsonPath"] = value;
}
}
}
}

View File

@ -41,5 +41,8 @@
<Setting Name="DefaultMailSender" Type="System.String" Scope="User">
<Value Profile="(Default)">GrasscutterTools</Value>
</Setting>
<Setting Name="ShopJsonPath" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
</Settings>
</SettingsFile>