-
Notifications
You must be signed in to change notification settings - Fork 48
/
WorldBossRankingRewardSheet.cs
112 lines (103 loc) · 4.09 KB
/
WorldBossRankingRewardSheet.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
using System;
using System.Collections.Generic;
using System.Linq;
using Lib9c;
using Libplanet.Types.Assets;
using Nekoyume.Helper;
using Nekoyume.Model.Item;
using static Nekoyume.TableData.TableExtensions;
namespace Nekoyume.TableData
{
// This sheet not on-chain data. don't call this sheet in `IAction.Execute()`
public class WorldBossRankingRewardSheet : Sheet<int, WorldBossRankingRewardSheet.Row>
{
public class Row : SheetRow<int>
{
public struct RuneInfo
{
public int RuneId;
public int RuneQty;
public RuneInfo(int id, int qty)
{
RuneId = id;
RuneQty = qty;
}
}
public int Id;
public int BossId;
public int RankingMin;
public int RankingMax;
public int RateMin;
public int RateMax;
public List<RuneInfo> Runes;
public int Crystal;
public List<(int itemId, int quantity)> Materials;
public override int Key => Id;
public override void Set(IReadOnlyList<string> fields)
{
Id = ParseInt(fields[0]);
BossId = ParseInt(fields[1]);
RankingMin = ParseInt(fields[2]);
RankingMax = ParseInt(fields[3]);
RateMin = ParseInt(fields[4]);
RateMax = ParseInt(fields[5]);
Runes = new List<RuneInfo>();
for (int i = 0; i < 3; i++)
{
var offset = i * 2;
var id = TryParseInt(fields[6 + offset], out var value) ? value : 0;
var quantity = TryParseInt(fields[7 + offset], out value) ? value : 0;
if (id != 0 && quantity > 0)
{
Runes.Add(new RuneInfo(id, quantity));
}
}
Crystal = ParseInt(fields[12]);
if (fields.Count > 13)
{
Materials = new List<(int, int)>();
for (int i = 0; i < 2; i++)
{
var offset = i * 2;
var id = TryParseInt(fields[13 + offset], out var value) ? value : 0;
var quantity = TryParseInt(fields[14 + offset], out value) ? value : 0;
if (id != 0 && quantity > 0)
{
Materials.Add((id, quantity));
}
}
}
}
public List<FungibleAssetValue> GetRewards(
RuneSheet runeSheet,
MaterialItemSheet materialSheet)
{
var result = new List<FungibleAssetValue>
{
Crystal * CrystalCalculator.CRYSTAL
};
result.AddRange(Runes.Select(runeInfo =>
RuneHelper.ToFungibleAssetValue(runeSheet[runeInfo.RuneId], runeInfo.RuneQty)));
foreach (var (itemId, quantity) in Materials)
{
var isTradable = materialSheet[itemId].ItemSubType
is ItemSubType.Circle or ItemSubType.Scroll;
var currency = Currencies.GetItemCurrency(itemId, isTradable);
result.Add(currency * quantity);
}
return result;
}
}
public WorldBossRankingRewardSheet() : base(nameof(WorldBossRankingRewardSheet))
{
}
public Row FindRow(int bossId, int ranking, int rate)
{
if (ranking <= 0 && rate <= 0)
{
throw new ArgumentException($"ranking or rate must be greater than 0. ranking: {ranking}, rate: {rate}");
}
return OrderedList.LastOrDefault(r => r.BossId == bossId && r.RankingMin <= ranking && ranking <= r.RankingMax) ?? OrderedList.LastOrDefault(r => r.BossId == bossId && r.RateMin <= rate && rate <= r.RateMax);
}
}
}