mirror of
https://github.com/jie65535/GrasscutterCommandGenerator.git
synced 2025-08-02 16:59:14 +08:00
Implement ShopEditor
This commit is contained in:
parent
52317d8d5a
commit
302e4e327d
@ -33,7 +33,10 @@
|
||||
this.ListItems = new System.Windows.Forms.ListBox();
|
||||
this.GrpShopList = new System.Windows.Forms.GroupBox();
|
||||
this.GrpGoodsList = new System.Windows.Forms.GroupBox();
|
||||
this.BtnClearGoods = new System.Windows.Forms.Button();
|
||||
this.BtnDeleteGoods = new System.Windows.Forms.Button();
|
||||
this.GrpItems = new System.Windows.Forms.GroupBox();
|
||||
this.TxtItemFilter = new System.Windows.Forms.TextBox();
|
||||
this.GrpGoodsInfo = new System.Windows.Forms.GroupBox();
|
||||
this.BtnSaveGoods = new System.Windows.Forms.Button();
|
||||
this.CmbRefreshType = new System.Windows.Forms.ComboBox();
|
||||
@ -82,7 +85,6 @@
|
||||
this.BtnLoad = new System.Windows.Forms.Button();
|
||||
this.TxtShopJsonPath = new System.Windows.Forms.TextBox();
|
||||
this.LblShopPathLabel = new System.Windows.Forms.Label();
|
||||
this.TxtItemFilter = new System.Windows.Forms.TextBox();
|
||||
this.GrpShopList.SuspendLayout();
|
||||
this.GrpGoodsList.SuspendLayout();
|
||||
this.GrpItems.SuspendLayout();
|
||||
@ -113,18 +115,20 @@
|
||||
this.ListShop.ItemHeight = 17;
|
||||
this.ListShop.Location = new System.Drawing.Point(3, 19);
|
||||
this.ListShop.Name = "ListShop";
|
||||
this.ListShop.Size = new System.Drawing.Size(244, 169);
|
||||
this.ListShop.Size = new System.Drawing.Size(244, 178);
|
||||
this.ListShop.TabIndex = 0;
|
||||
this.ListShop.SelectedIndexChanged += new System.EventHandler(this.ListShop_SelectedIndexChanged);
|
||||
//
|
||||
// ListGoods
|
||||
//
|
||||
this.ListGoods.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.ListGoods.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.ListGoods.FormattingEnabled = true;
|
||||
this.ListGoods.ItemHeight = 17;
|
||||
this.ListGoods.Location = new System.Drawing.Point(3, 19);
|
||||
this.ListGoods.Name = "ListGoods";
|
||||
this.ListGoods.Size = new System.Drawing.Size(244, 289);
|
||||
this.ListGoods.Size = new System.Drawing.Size(244, 242);
|
||||
this.ListGoods.TabIndex = 1;
|
||||
this.ListGoods.SelectedIndexChanged += new System.EventHandler(this.ListGoods_SelectedIndexChanged);
|
||||
//
|
||||
@ -146,7 +150,7 @@
|
||||
this.GrpShopList.Controls.Add(this.ListShop);
|
||||
this.GrpShopList.Location = new System.Drawing.Point(12, 41);
|
||||
this.GrpShopList.Name = "GrpShopList";
|
||||
this.GrpShopList.Size = new System.Drawing.Size(250, 191);
|
||||
this.GrpShopList.Size = new System.Drawing.Size(250, 200);
|
||||
this.GrpShopList.TabIndex = 3;
|
||||
this.GrpShopList.TabStop = false;
|
||||
this.GrpShopList.Text = "商店列表";
|
||||
@ -155,14 +159,38 @@
|
||||
//
|
||||
this.GrpGoodsList.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
| System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.GrpGoodsList.Controls.Add(this.BtnClearGoods);
|
||||
this.GrpGoodsList.Controls.Add(this.BtnDeleteGoods);
|
||||
this.GrpGoodsList.Controls.Add(this.ListGoods);
|
||||
this.GrpGoodsList.Location = new System.Drawing.Point(12, 238);
|
||||
this.GrpGoodsList.Location = new System.Drawing.Point(12, 247);
|
||||
this.GrpGoodsList.Name = "GrpGoodsList";
|
||||
this.GrpGoodsList.Size = new System.Drawing.Size(250, 311);
|
||||
this.GrpGoodsList.Size = new System.Drawing.Size(250, 302);
|
||||
this.GrpGoodsList.TabIndex = 4;
|
||||
this.GrpGoodsList.TabStop = false;
|
||||
this.GrpGoodsList.Text = "商品列表";
|
||||
//
|
||||
// BtnClearGoods
|
||||
//
|
||||
this.BtnClearGoods.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.BtnClearGoods.Location = new System.Drawing.Point(112, 273);
|
||||
this.BtnClearGoods.Name = "BtnClearGoods";
|
||||
this.BtnClearGoods.Size = new System.Drawing.Size(100, 23);
|
||||
this.BtnClearGoods.TabIndex = 3;
|
||||
this.BtnClearGoods.Text = "× 清空";
|
||||
this.BtnClearGoods.UseVisualStyleBackColor = true;
|
||||
this.BtnClearGoods.Click += new System.EventHandler(this.BtnClearGoods_Click);
|
||||
//
|
||||
// BtnDeleteGoods
|
||||
//
|
||||
this.BtnDeleteGoods.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
|
||||
this.BtnDeleteGoods.Location = new System.Drawing.Point(6, 273);
|
||||
this.BtnDeleteGoods.Name = "BtnDeleteGoods";
|
||||
this.BtnDeleteGoods.Size = new System.Drawing.Size(100, 23);
|
||||
this.BtnDeleteGoods.TabIndex = 2;
|
||||
this.BtnDeleteGoods.Text = "- 删除";
|
||||
this.BtnDeleteGoods.UseVisualStyleBackColor = true;
|
||||
this.BtnDeleteGoods.Click += new System.EventHandler(this.BtnDeleteGoods_Click);
|
||||
//
|
||||
// GrpItems
|
||||
//
|
||||
this.GrpItems.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
@ -176,6 +204,14 @@
|
||||
this.GrpItems.TabStop = false;
|
||||
this.GrpItems.Text = "物品列表";
|
||||
//
|
||||
// TxtItemFilter
|
||||
//
|
||||
this.TxtItemFilter.Location = new System.Drawing.Point(6, 22);
|
||||
this.TxtItemFilter.Name = "TxtItemFilter";
|
||||
this.TxtItemFilter.Size = new System.Drawing.Size(238, 23);
|
||||
this.TxtItemFilter.TabIndex = 3;
|
||||
this.TxtItemFilter.TextChanged += new System.EventHandler(this.TxtItemFilter_TextChanged);
|
||||
//
|
||||
// GrpGoodsInfo
|
||||
//
|
||||
this.GrpGoodsInfo.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
|
||||
@ -234,11 +270,11 @@
|
||||
// BtnSaveGoods
|
||||
//
|
||||
this.BtnSaveGoods.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.BtnSaveGoods.Location = new System.Drawing.Point(114, 472);
|
||||
this.BtnSaveGoods.Location = new System.Drawing.Point(99, 472);
|
||||
this.BtnSaveGoods.Name = "BtnSaveGoods";
|
||||
this.BtnSaveGoods.Size = new System.Drawing.Size(120, 30);
|
||||
this.BtnSaveGoods.Size = new System.Drawing.Size(150, 30);
|
||||
this.BtnSaveGoods.TabIndex = 30;
|
||||
this.BtnSaveGoods.Text = "√ 保存";
|
||||
this.BtnSaveGoods.Text = "√ 添加或更新";
|
||||
this.BtnSaveGoods.UseVisualStyleBackColor = true;
|
||||
this.BtnSaveGoods.Click += new System.EventHandler(this.BtnSaveGoods_Click);
|
||||
//
|
||||
@ -262,6 +298,11 @@
|
||||
//
|
||||
this.NUDRefreshParm.Anchor = System.Windows.Forms.AnchorStyles.Top;
|
||||
this.NUDRefreshParm.Location = new System.Drawing.Point(119, 209);
|
||||
this.NUDRefreshParm.Maximum = new decimal(new int[] {
|
||||
1000,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.NUDRefreshParm.Name = "NUDRefreshParm";
|
||||
this.NUDRefreshParm.Size = new System.Drawing.Size(50, 23);
|
||||
this.NUDRefreshParm.TabIndex = 9;
|
||||
@ -275,6 +316,7 @@
|
||||
this.DTPEndTime.Name = "DTPEndTime";
|
||||
this.DTPEndTime.Size = new System.Drawing.Size(160, 23);
|
||||
this.DTPEndTime.TabIndex = 8;
|
||||
this.DTPEndTime.Value = new System.DateTime(2035, 1, 1, 0, 0, 0, 0);
|
||||
//
|
||||
// DTPBeginTime
|
||||
//
|
||||
@ -285,6 +327,7 @@
|
||||
this.DTPBeginTime.Name = "DTPBeginTime";
|
||||
this.DTPBeginTime.Size = new System.Drawing.Size(160, 23);
|
||||
this.DTPBeginTime.TabIndex = 7;
|
||||
this.DTPBeginTime.Value = new System.DateTime(2022, 1, 1, 0, 0, 0, 0);
|
||||
//
|
||||
// NUDGoodsId
|
||||
//
|
||||
@ -752,7 +795,7 @@
|
||||
// BtnSave
|
||||
//
|
||||
this.BtnSave.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
||||
this.BtnSave.Location = new System.Drawing.Point(720, 12);
|
||||
this.BtnSave.Location = new System.Drawing.Point(772, 12);
|
||||
this.BtnSave.Name = "BtnSave";
|
||||
this.BtnSave.Size = new System.Drawing.Size(100, 23);
|
||||
this.BtnSave.TabIndex = 2;
|
||||
@ -763,7 +806,7 @@
|
||||
// BtnLoad
|
||||
//
|
||||
this.BtnLoad.ImeMode = System.Windows.Forms.ImeMode.NoControl;
|
||||
this.BtnLoad.Location = new System.Drawing.Point(615, 12);
|
||||
this.BtnLoad.Location = new System.Drawing.Point(666, 12);
|
||||
this.BtnLoad.Name = "BtnLoad";
|
||||
this.BtnLoad.Size = new System.Drawing.Size(100, 23);
|
||||
this.BtnLoad.TabIndex = 1;
|
||||
@ -775,7 +818,7 @@
|
||||
//
|
||||
this.TxtShopJsonPath.Location = new System.Drawing.Point(122, 12);
|
||||
this.TxtShopJsonPath.Name = "TxtShopJsonPath";
|
||||
this.TxtShopJsonPath.Size = new System.Drawing.Size(487, 23);
|
||||
this.TxtShopJsonPath.Size = new System.Drawing.Size(538, 23);
|
||||
this.TxtShopJsonPath.TabIndex = 0;
|
||||
//
|
||||
// LblShopPathLabel
|
||||
@ -788,14 +831,6 @@
|
||||
this.LblShopPathLabel.TabIndex = 7;
|
||||
this.LblShopPathLabel.Text = "Shop.json 路径:";
|
||||
//
|
||||
// TxtItemFilter
|
||||
//
|
||||
this.TxtItemFilter.Location = new System.Drawing.Point(6, 22);
|
||||
this.TxtItemFilter.Name = "TxtItemFilter";
|
||||
this.TxtItemFilter.Size = new System.Drawing.Size(238, 23);
|
||||
this.TxtItemFilter.TabIndex = 3;
|
||||
this.TxtItemFilter.TextChanged += new System.EventHandler(this.TxtItemFilter_TextChanged);
|
||||
//
|
||||
// FormShopEditor
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 17F);
|
||||
@ -900,5 +935,7 @@
|
||||
private System.Windows.Forms.Label LblRefreshModeLabel;
|
||||
private System.Windows.Forms.Button BtnSaveGoods;
|
||||
private System.Windows.Forms.TextBox TxtItemFilter;
|
||||
private System.Windows.Forms.Button BtnClearGoods;
|
||||
private System.Windows.Forms.Button BtnDeleteGoods;
|
||||
}
|
||||
}
|
@ -1,4 +1,23 @@
|
||||
using System;
|
||||
/**
|
||||
* 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 <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
**/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@ -6,6 +25,7 @@ using System.Windows.Forms;
|
||||
|
||||
using GrasscutterTools.Game;
|
||||
using GrasscutterTools.Game.Shop;
|
||||
using GrasscutterTools.GOOD;
|
||||
using GrasscutterTools.Properties;
|
||||
using GrasscutterTools.Utils;
|
||||
|
||||
@ -17,11 +37,17 @@ namespace GrasscutterTools.Forms
|
||||
{
|
||||
#region - 成员 -
|
||||
|
||||
/// <summary>
|
||||
/// 商店列表数据
|
||||
/// </summary>
|
||||
private Dictionary<int, List<ShopInfo>> Shops = new Dictionary<int, List<ShopInfo>>();
|
||||
|
||||
private List<ShopInfo> SelectedShop = new List<ShopInfo>();
|
||||
/// <summary>
|
||||
/// 选中的商店类型
|
||||
/// </summary>
|
||||
private int SelectedShopType;
|
||||
|
||||
#endregion
|
||||
#endregion - 成员 -
|
||||
|
||||
#region - 构造与窗体事件 -
|
||||
|
||||
@ -69,9 +95,9 @@ namespace GrasscutterTools.Forms
|
||||
/// </summary>
|
||||
private void BtnLoad_Click(object sender, EventArgs e)
|
||||
{
|
||||
var path = TxtShopJsonPath.Text.Trim();
|
||||
try
|
||||
{
|
||||
var path = TxtShopJsonPath.Text.Trim();
|
||||
if (path == string.Empty)
|
||||
{
|
||||
var dialog = new OpenFileDialog
|
||||
@ -92,14 +118,23 @@ namespace GrasscutterTools.Forms
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.ToString(), Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
try
|
||||
{
|
||||
// 当Json解析失败时尝试以tsv方式解析
|
||||
LoadShopsFromTsv(path);
|
||||
MessageBox.Show("OK", Resources.Tips, MessageBoxButtons.OK);
|
||||
}
|
||||
catch
|
||||
{
|
||||
MessageBox.Show(ex.ToString(), Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加载商店
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <param name="path">文件路径</param>
|
||||
private void LoadShops(string path)
|
||||
{
|
||||
// 反序列化
|
||||
@ -109,6 +144,50 @@ namespace GrasscutterTools.Forms
|
||||
Shops.Add(item.ShopType, item.Items);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从TSV加载商店
|
||||
/// </summary>
|
||||
/// <param name="path">文件路径</param>
|
||||
private void LoadShopsFromTsv(string path)
|
||||
{
|
||||
var lines = File.ReadAllLines(path);
|
||||
Shops = new Dictionary<int, List<ShopInfo>>();
|
||||
for (int i = 1; i < lines.Length; i++)
|
||||
{
|
||||
var cells = lines[i].Split('\t');
|
||||
|
||||
var goods = new ShopInfo
|
||||
{
|
||||
GoodsId = int.Parse(cells[0]),
|
||||
GoodsItem = new ItemParamData(int.Parse(cells[2]), int.Parse(cells[4])),
|
||||
BuyLimit = TryParse(cells[16]),
|
||||
MinLevel = TryParse(cells[29]),
|
||||
MaxLevel = TryParse(cells[30]),
|
||||
BeginTime = (int)new DateTimeOffset(DateTime.Parse(cells[20])).ToUnixTimeSeconds(),
|
||||
EndTime = (int)new DateTimeOffset(DateTime.Parse(cells[21])).ToUnixTimeSeconds(),
|
||||
RefreshType = (ShopRefreshType)TryParse(cells[17]),
|
||||
ShopRefreshParam = TryParse(cells[18]),
|
||||
HCoin = TryParse(cells[5]),
|
||||
SCoin = TryParse(cells[6]),
|
||||
MCoin = TryParse(cells[7]),
|
||||
CostItemList = new List<ItemParamData>
|
||||
{
|
||||
new ItemParamData(TryParse(cells[8]), TryParse(cells[9])),
|
||||
new ItemParamData(TryParse(cells[10]), TryParse(cells[11])),
|
||||
new ItemParamData(TryParse(cells[12]), TryParse(cells[13])),
|
||||
new ItemParamData(TryParse(cells[14]), TryParse(cells[15])),
|
||||
}
|
||||
};
|
||||
|
||||
var shopType = int.Parse(cells[1]);
|
||||
if (!Shops.TryGetValue(shopType, out List<ShopInfo> shops))
|
||||
Shops.Add(shopType, shops = new List<ShopInfo>());
|
||||
shops.Add(goods);
|
||||
}
|
||||
}
|
||||
|
||||
private static int TryParse(string value) => int.TryParse(value, out int n) ? n : 0;
|
||||
|
||||
/// <summary>
|
||||
/// 点击保存Shop.json按钮时触发
|
||||
/// </summary>
|
||||
@ -135,13 +214,20 @@ namespace GrasscutterTools.Forms
|
||||
var banners = new List<ShopTable>(Shops.Count);
|
||||
foreach (var shop in Shops)
|
||||
{
|
||||
banners.Add(new ShopTable
|
||||
if (shop.Value != null && shop.Value.Count > 0)
|
||||
{
|
||||
ShopType = shop.Key,
|
||||
Items = shop.Value,
|
||||
});
|
||||
banners.Add(new ShopTable
|
||||
{
|
||||
ShopType = shop.Key,
|
||||
Items = shop.Value,
|
||||
});
|
||||
}
|
||||
}
|
||||
File.WriteAllText(path, JsonConvert.SerializeObject(banners));
|
||||
File.WriteAllText(path, JsonConvert.SerializeObject(banners, new JsonSerializerSettings
|
||||
{
|
||||
Formatting = Formatting.Indented,
|
||||
DefaultValueHandling = DefaultValueHandling.Ignore,
|
||||
}));
|
||||
MessageBox.Show("OK", Resources.Tips, MessageBoxButtons.OK);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -159,12 +245,14 @@ namespace GrasscutterTools.Forms
|
||||
/// </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);
|
||||
if (ListShop.SelectedIndex == -1)
|
||||
{
|
||||
SelectedShopType = 0;
|
||||
return;
|
||||
}
|
||||
SelectedShopType = ItemMap.ToId(ListShop.SelectedItem as string);
|
||||
Shops.TryGetValue(SelectedShopType, out var shop);
|
||||
ShowGoodsList(shop);
|
||||
}
|
||||
|
||||
#endregion - 商店列表 -
|
||||
@ -178,10 +266,10 @@ namespace GrasscutterTools.Forms
|
||||
{
|
||||
ListGoods.BeginUpdate();
|
||||
ListGoods.Items.Clear();
|
||||
if (banner.Count > 0)
|
||||
if (banner != null && banner.Count > 0)
|
||||
{
|
||||
ListGoods.Items.AddRange(banner.Select(it => it.ToString()).ToArray());
|
||||
ListGoods.SelectedIndex = 0;
|
||||
//ListGoods.SelectedIndex = 0;
|
||||
}
|
||||
ListGoods.EndUpdate();
|
||||
}
|
||||
@ -192,7 +280,33 @@ namespace GrasscutterTools.Forms
|
||||
private void ListGoods_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (ListGoods.SelectedIndex == -1) return;
|
||||
ShowGoods(SelectedShop[ListGoods.SelectedIndex]);
|
||||
ShowGoods(Shops[SelectedShopType][ListGoods.SelectedIndex]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 点击删除商品按钮时触发
|
||||
/// </summary>
|
||||
private void BtnDeleteGoods_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (ListGoods.SelectedIndex == -1) return;
|
||||
if (MessageBox.Show(Resources.AskConfirmDeletion, Resources.Tips, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
|
||||
{
|
||||
Shops[SelectedShopType].RemoveAt(ListGoods.SelectedIndex);
|
||||
ListGoods.Items.RemoveAt(ListGoods.SelectedIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 点击清空商品按钮时触发
|
||||
/// </summary>
|
||||
private void BtnClearGoods_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (ListGoods.Items.Count == 0) return;
|
||||
if (MessageBox.Show(Resources.AskConfirmDeletion, Resources.Tips, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
|
||||
{
|
||||
Shops.Remove(SelectedShopType);
|
||||
ListGoods.Items.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
#endregion - 商品列表 -
|
||||
@ -211,8 +325,8 @@ namespace GrasscutterTools.Forms
|
||||
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;
|
||||
DTPBeginTime.Value = DateTimeOffset.FromUnixTimeSeconds(goods.BeginTime).LocalDateTime;
|
||||
DTPEndTime.Value = DateTimeOffset.FromUnixTimeSeconds(goods.EndTime).LocalDateTime;
|
||||
NUDRefreshParm.Value = goods.ShopRefreshParam;
|
||||
CmbRefreshType.SelectedIndex = (int)goods.RefreshType;
|
||||
NUDCostHcoin.Value = goods.HCoin;
|
||||
@ -235,6 +349,10 @@ namespace GrasscutterTools.Forms
|
||||
/// </summary>
|
||||
private void LnkGenGoodsId_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
{
|
||||
if (ListShop.SelectedIndex == -1) return;
|
||||
|
||||
if (ItemMap.TryToId(TxtGoodsItem.Text, out int itemId))
|
||||
NUDGoodsId.Value = SelectedShopType * 1000 + itemId % 1000;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -243,15 +361,91 @@ namespace GrasscutterTools.Forms
|
||||
private void CmbRefreshType_SelectedIndexChanged(object sender, EventArgs e)
|
||||
{
|
||||
NUDRefreshParm.Enabled = CmbRefreshType.SelectedIndex > 0;
|
||||
if (CmbRefreshType.SelectedIndex == 0)
|
||||
NUDRefreshParm.Value = 0;
|
||||
else if (NUDRefreshParm.Value == 0)
|
||||
NUDRefreshParm.Value = 1;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 点击保存商品按钮时触发
|
||||
/// </summary>
|
||||
/// <param name="sender"></param>
|
||||
/// <param name="e"></param>
|
||||
private void BtnSaveGoods_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (!ItemMap.TryToId(TxtGoodsItem.Text, out int itemId))
|
||||
{
|
||||
MessageBox.Show(Resources.EmptyInputTip, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查ID冲突
|
||||
var goodsId = (int)NUDGoodsId.Value;
|
||||
if (Shops.Any(kv => kv.Key != SelectedShopType && kv.Value.Any(it => it.GoodsId == goodsId)))
|
||||
{
|
||||
MessageBox.Show(Resources.GoodsIDConflictPrompt, Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
List<ItemParamData> costs = new List<ItemParamData>();
|
||||
if (NUDCostItem1Count.Value > 0 && NUDCostItem1.Value > 0)
|
||||
costs.Add(new ItemParamData((int)NUDCostItem1.Value, (int)NUDCostItem1Count.Value));
|
||||
if (NUDCostItem2Count.Value > 0 && NUDCostItem2.Value > 0)
|
||||
costs.Add(new ItemParamData((int)NUDCostItem2.Value, (int)NUDCostItem2Count.Value));
|
||||
if (NUDCostItem3Count.Value > 0 && NUDCostItem3.Value > 0)
|
||||
costs.Add(new ItemParamData((int)NUDCostItem3.Value, (int)NUDCostItem3Count.Value));
|
||||
if (NUDCostItem4Count.Value > 0 && NUDCostItem4.Value > 0)
|
||||
costs.Add(new ItemParamData((int)NUDCostItem4.Value, (int)NUDCostItem4Count.Value));
|
||||
ShopInfo goods = new ShopInfo
|
||||
{
|
||||
GoodsId = goodsId,
|
||||
GoodsItem = new ItemParamData(itemId, (int)NUDGoodsItemCount.Value),
|
||||
BuyLimit = (int)NUDBuyLimit.Value,
|
||||
MinLevel = (int)NUDMinLevel.Value,
|
||||
MaxLevel = (int)NUDMaxLevel.Value,
|
||||
BeginTime = (int)new DateTimeOffset(DTPBeginTime.Value).ToUnixTimeSeconds(),
|
||||
EndTime = (int)new DateTimeOffset(DTPEndTime.Value).ToUnixTimeSeconds(),
|
||||
RefreshType = CmbRefreshType.SelectedIndex == -1 ? ShopRefreshType.None : (ShopRefreshType)CmbRefreshType.SelectedIndex,
|
||||
ShopRefreshParam = (int)NUDRefreshParm.Value,
|
||||
HCoin = (int)NUDCostHcoin.Value,
|
||||
SCoin = (int)NUDCostScoin.Value,
|
||||
MCoin = (int)NUDCostMcoin.Value,
|
||||
CostItemList = costs,
|
||||
// 以下属性不认识,代码里看似也没用,不写了
|
||||
//BoughtNum
|
||||
//DisableType
|
||||
//PreGoodsIdList
|
||||
//SecondarySheetId
|
||||
};
|
||||
|
||||
if (Shops.TryGetValue(SelectedShopType, out var shop))
|
||||
{
|
||||
var i = shop.FindIndex(it => it.GoodsId == goodsId);
|
||||
if (i == -1)
|
||||
{
|
||||
// 增加到现有列表
|
||||
shop.Add(goods);
|
||||
ListGoods.Items.Add(goods.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
// 修改
|
||||
shop[i] = goods;
|
||||
ListGoods.Items[i] = goods.ToString();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 增加到新列表
|
||||
Shops[SelectedShopType] = new List<ShopInfo> { goods };
|
||||
ListGoods.Items.Add(goods.ToString());
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.ToString(), Resources.Error, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion - 商品信息 -
|
||||
@ -276,6 +470,5 @@ namespace GrasscutterTools.Forms
|
||||
}
|
||||
|
||||
#endregion - 物品列表 -
|
||||
|
||||
}
|
||||
}
|
@ -72,5 +72,13 @@ namespace GrasscutterTools.Game
|
||||
public string[] Lines { get; }
|
||||
|
||||
public static int ToId(string line) => int.Parse(line.Substring(0, line.IndexOf(':')).Trim());
|
||||
|
||||
public static bool TryToId(string line, out int id)
|
||||
{
|
||||
id = 0;
|
||||
var sp = line.IndexOf(':');
|
||||
if (sp == -1) return false;
|
||||
return int.TryParse(line.Substring(0, sp).Trim(), out id);
|
||||
}
|
||||
}
|
||||
}
|
@ -22,6 +22,12 @@ namespace GrasscutterTools.Game.Shop
|
||||
{
|
||||
public struct ItemParamData
|
||||
{
|
||||
public ItemParamData(int id, int count)
|
||||
{
|
||||
Id = id;
|
||||
Count = count;
|
||||
}
|
||||
|
||||
[JsonProperty("id")]
|
||||
public int Id { get; set; }
|
||||
|
||||
|
@ -30,6 +30,9 @@ namespace GrasscutterTools.Game.Shop
|
||||
[JsonProperty("goodsItem")]
|
||||
public ItemParamData GoodsItem { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消耗摩拉
|
||||
/// </summary>
|
||||
[JsonProperty("scoin")]
|
||||
public int SCoin { get; set; }
|
||||
|
||||
@ -55,11 +58,18 @@ namespace GrasscutterTools.Game.Shop
|
||||
public int MaxLevel { get; set; } = 61;
|
||||
|
||||
[JsonProperty("preGoodsIdList")]
|
||||
public List<int> PreGoodsIdList { get; set; } = new List<int>();
|
||||
public List<int> PreGoodsIdList { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消耗创世结晶
|
||||
/// </summary>
|
||||
[JsonProperty("mcoin")]
|
||||
public int MCoin { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消耗原石
|
||||
/// </summary>
|
||||
|
||||
[JsonProperty("hcoin")]
|
||||
public int HCoin { get; set; }
|
||||
|
||||
|
@ -591,12 +591,15 @@ namespace GrasscutterTools.Properties {
|
||||
///071:华紫樱绯
|
||||
///076:苍流踏花
|
||||
///081:素霓伣天
|
||||
///091:提纳里池
|
||||
///092:钟离池
|
||||
///093:猎人之径池
|
||||
///097:赛诺池
|
||||
///098:温迪池
|
||||
///099:终末嗟谈之诗/赤沙之杖池 的本地化字符串。
|
||||
///091:巡御蘙荟-提纳里
|
||||
///092:陵薮市朝-钟离
|
||||
///093:神铸赋形-猎人贯虹
|
||||
///097:雳裁冥昭-赛诺
|
||||
///098:杯装之诗-温迪
|
||||
///099:神铸赋形-赤沙终末
|
||||
///100:翩舞歈莲-妮露
|
||||
///101:深秘之息-阿贝多
|
||||
///101:神铸赋形-圣显绿箭 的本地化字符串。
|
||||
/// </summary>
|
||||
internal static string GachaBennerPrefab {
|
||||
get {
|
||||
@ -666,6 +669,15 @@ namespace GrasscutterTools.Properties {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 当前商品ID与其它商店中的ID存在冲突,请更换其它ID或自动生成ID 的本地化字符串。
|
||||
/// </summary>
|
||||
internal static string GoodsIDConflictPrompt {
|
||||
get {
|
||||
return ResourceManager.GetString("GoodsIDConflictPrompt", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 帮助 的本地化字符串。
|
||||
/// </summary>
|
||||
@ -902,20 +914,20 @@ namespace GrasscutterTools.Properties {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 30302:女神像解锁$HIDDEN - [N/A] 362713143
|
||||
///30303:女神像解锁$HIDDEN - [N/A] 715511863
|
||||
///30304:女神像解锁$HIDDEN - [N/A] 163018255
|
||||
///30305:女神像解锁$HIDDEN - [N/A] 3694648119
|
||||
///30306:女神像解锁$HIDDEN - [N/A] 3223799591
|
||||
///30307:女神像解锁$HIDDEN - [N/A] 1232757671
|
||||
///30308:女神像解锁$HIDDEN - [N/A] 3056513767
|
||||
///30309:女神像解锁$HIDDEN - [N/A] 2426653367
|
||||
///30310:女神像解锁$HIDDEN - [N/A] 2003131071
|
||||
///30311:女神像解锁$HIDDEN - [N/A] 105277231
|
||||
///30312:女神像解锁$HIDDEN - [N/A] 3391806215
|
||||
///30313:女神像解锁$HIDDEN - [N/A] 1357500887
|
||||
///30314:女神像解锁$HIDDEN - [N/A] 3054344935
|
||||
///30315:女神像 [字符串的其余部分被截断]"; 的本地化字符串。
|
||||
/// 查找类似 30302:七天神像解锁$HIDDEN - 苍风高地 362713143
|
||||
///30303:七天神像解锁$HIDDEN - 风啸山坡 715511863
|
||||
///30304:七天神像解锁$HIDDEN - 明冠山地 163018255
|
||||
///30305:七天神像解锁$HIDDEN - 碧水原 3694648119
|
||||
///30306:七天神像解锁$HIDDEN - 云来海 3223799591
|
||||
///30307:七天神像解锁$HIDDEN - 珉林 1232757671
|
||||
///30308:七天神像解锁$HIDDEN - 璃沙郊 3056513767
|
||||
///30309:七天神像解锁$HIDDEN - 琼玑原 2426653367
|
||||
///30310:七天神像解锁$HIDDEN - 龙脊雪山 2003131071
|
||||
///30311:七天神像解锁$HIDDEN - 鸣神岛 105277231
|
||||
///30312:七天神像解锁$HIDDEN - 神无冢 3391806215
|
||||
///30313:七天神像解锁$HIDDEN - 八酝岛 1357500887
|
||||
///30314:七天神像解锁$HIDDEN - 清籁岛 3054344935
|
||||
///30315:七天神像解锁$HIDDEN [字符串的其余部分被截断]"; 的本地化字符串。
|
||||
/// </summary>
|
||||
internal static string Quest {
|
||||
get {
|
||||
|
@ -279,4 +279,7 @@ Improvement suggestions have been submitted, please use caution to send emails t
|
||||
<data name="ShopType" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\en-us\ShopType.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||
</data>
|
||||
<data name="GoodsIDConflictPrompt" xml:space="preserve">
|
||||
<value>There is a conflict between the current goods ID and the ID in other stores, please replace with another ID or automatically generate an ID</value>
|
||||
</data>
|
||||
</root>
|
@ -288,4 +288,7 @@
|
||||
<data name="ShopType" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\zh-cn\ShopType.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||
</data>
|
||||
<data name="GoodsIDConflictPrompt" xml:space="preserve">
|
||||
<value>当前商品ID与其它商店中的ID存在冲突,请更换其它ID或自动生成ID</value>
|
||||
</data>
|
||||
</root>
|
@ -267,4 +267,7 @@
|
||||
<data name="ShopType" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\ru-ru\ShopType.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||
</data>
|
||||
<data name="GoodsIDConflictPrompt" xml:space="preserve">
|
||||
<value>Существует конфликт между текущим идентификатором товара и идентификатором в других магазинах, пожалуйста, замените другим идентификатором или автоматически сгенерируйте идентификатор</value>
|
||||
</data>
|
||||
</root>
|
@ -273,4 +273,7 @@
|
||||
<data name="ShopType" type="System.Resources.ResXFileRef, System.Windows.Forms">
|
||||
<value>..\Resources\zh-tw\ShopType.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;utf-8</value>
|
||||
</data>
|
||||
<data name="GoodsIDConflictPrompt" xml:space="preserve">
|
||||
<value>當前商品ID與其它商店中的ID存在衝突,請更換其它ID或自動生成ID</value>
|
||||
</data>
|
||||
</root>
|
Loading…
Reference in New Issue
Block a user