Terminal and graphics cards redrawn; rig slots 2 to 5 with electronics
Terminal: monitor with a top face and a trapezoid keyboard. Graphics card: a metal bracket with ports, two fans, brand stripe, gold fingers with a PCIe notch and power connectors on top, now 2x2 cells. Rig: two slots by default, an upgrade slot that takes the next level's electronics (4 common, 1 rare, 2 rare) and consumes them at once; the card grid reshapes with the slot count, which is kept on the rig's tags. Verified in game, including the slot limit, the upgrade items, five cards, and save and reload. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
No files matched your search
@@ -0,0 +1,58 @@
|
||||
using System;
|
||||
|
||||
namespace Decentralized.Domain
|
||||
{
|
||||
/// <summary>
|
||||
/// 矿架的显卡槽:默认 2 个,投入电子元件逐个升级,最多 5 个。每张显卡占 2×2 格,槽在矿架窗口里是一列 2 格宽的格子,
|
||||
/// 每个槽两行;未解锁的行是不可放的格子。游戏里电子元件的价值是 33 / 350 / 2,500(普通 / 稀有 / 超科技)。
|
||||
/// </summary>
|
||||
public static class RigSlots
|
||||
{
|
||||
public const int Base = 2, Max = 5;
|
||||
public const int CellWidth = 2, CellsPerSlot = 2;
|
||||
|
||||
/// <summary>升级到第 n 个槽需要的电子元件(物品 id,件数)。n 从 3 开始。</summary>
|
||||
public static (string Item, int Count) Cost(int slot)
|
||||
{
|
||||
switch (slot)
|
||||
{
|
||||
case 3: return ("common_electronic", 4);
|
||||
case 4: return ("rare_electronic", 1);
|
||||
case 5: return ("rare_electronic", 2);
|
||||
default: throw new ArgumentOutOfRangeException(nameof(slot));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>当前槽数下,下一次升级需要什么;已满时返回 null。</summary>
|
||||
public static (string Item, int Count)? Next(int slots) => slots >= Max ? ((string, int)?)null : Cost(slots + 1);
|
||||
|
||||
/// <summary>
|
||||
/// 投入 count 件 item:只收下一级需要的那种;累计到够用就解锁一个槽,多出的留作下一级进度(若下一级是同一种元件)。
|
||||
/// 返回实际收下的件数;其余退回(不收)。
|
||||
/// </summary>
|
||||
public static int Insert(ref int slots, ref int progress, string item, int count)
|
||||
{
|
||||
if (slots >= Max || count <= 0) return 0;
|
||||
var need = Cost(slots + 1);
|
||||
if (item != need.Item) return 0;
|
||||
int take = Math.Min(count, need.Count - progress);
|
||||
progress += take;
|
||||
if (progress >= need.Count)
|
||||
{
|
||||
slots++;
|
||||
progress = 0;
|
||||
}
|
||||
return take;
|
||||
}
|
||||
|
||||
/// <summary>显卡格子的形状字符串:宽 2,高 2 × 最大槽数;前 slots × 2 行可放(0),其余不可放(1)。</summary>
|
||||
public static string Shape(int slots)
|
||||
{
|
||||
var sb = new System.Text.StringBuilder();
|
||||
for (int row = 0; row < Max * CellsPerSlot; row++)
|
||||
for (int col = 0; col < CellWidth; col++)
|
||||
sb.Append(row < slots * CellsPerSlot ? '0' : '1');
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ namespace Decentralized.Domain
|
||||
public const double NpcTargetRatio = 3.5;
|
||||
public const double NpcAdj = 0.05;
|
||||
public const double PoolFee = 0.03;
|
||||
public const int RigPrice = 400, RigKj = 2, RigSlots = 4;
|
||||
public const int RigPrice = 400, RigKj = 2;
|
||||
/// <summary>矿架上模块百分比的折算系数(原版机器用 2–4),以及各项上限。</summary>
|
||||
public const double ModuleRatio = 4, ModuleHashCap = 0.20, ModuleKjCap = 0.25, ModuleWearCap = 0.30;
|
||||
public const double DeathBase = 0.001, DeathWorn = 0.03, FakeDeathFactor = 2;
|
||||
|
||||
@@ -117,15 +117,22 @@ namespace Decentralized
|
||||
|
||||
// ---------- 矿架 ----------
|
||||
|
||||
public const string SlotsTag = "PD_SLOTS", ProgressTag = "PD_SLOT_PROGRESS";
|
||||
|
||||
private static int SlotsOf(GameItem rig) => rig.IsTag(SlotsTag) ? rig.GetTagReadonly(SlotsTag).GetInt() : RigSlots.Base;
|
||||
|
||||
private static GameItem CreateRig()
|
||||
{
|
||||
var battery = new GameSlotInventory();
|
||||
var upgrade = new GameSlotInventory();
|
||||
var modules = new GameGridInventory(MachineHelper.DEFAULT_MODULE_BAY_CONFIG, 7);
|
||||
var cards = new GameGridInventory(2, 4);
|
||||
// 显卡每张 2×2 格:一列 2 格宽的格子,每个槽两行;未解锁的行不可放
|
||||
var cards = new GameGridInventory(RigSlots.Shape(RigSlots.Base), RigSlots.CellWidth);
|
||||
var window = MachineHelper.CreateMachineryWindow(true,
|
||||
MachineHelper.PowerPanel(battery),
|
||||
MachineHelper.Panel(L.T("rig.label.modules"), modules, "module"),
|
||||
MachineHelper.Panel(L.T("rig.label.cards"), cards, "cards"));
|
||||
MachineHelper.Panel(L.T("rig.label.cards"), cards, "cards"),
|
||||
MachineHelper.Panel(L.T("rig.label.upgrade"), upgrade, "upgrade"));
|
||||
var rig = ItemDirectory.CreateEmptyItem(Rig).SetContentWindow(window);
|
||||
rig.SetSpriteAndShapeFromMod(ModInfo.Id, "rig");
|
||||
rig.name = L.T("item.rig.name");
|
||||
@@ -139,13 +146,48 @@ namespace Decentralized
|
||||
cards.mayInventoryAddItemFunc = (item, _) => GeneralHelper.IsItemOwned(item) && IsGpu(item) && !item.IsTag(DeadTag);
|
||||
cards.onSlotAddItemEndFunc = (_, _, _) => UpdateRig(rig, modules, cards);
|
||||
cards.onSlotRemoveItemEndFunc = (_, _, _) => UpdateRig(rig, modules, cards);
|
||||
rig.onLoaded = _ => UpdateRig(rig, modules, cards);
|
||||
// 升级槽:只收下一级需要的电子元件,放进去立刻投入(计入进度),攒够解锁一个显卡槽
|
||||
upgrade.mayInventoryAddItemFunc = (item, _) =>
|
||||
{
|
||||
var need = RigSlots.Next(SlotsOf(rig));
|
||||
return GeneralHelper.IsItemOwned(item) && need != null && item.identifier == need.Value.Item;
|
||||
};
|
||||
upgrade.onSlotAddItemEndFunc = (item, _, _) => Log.Guard("矿架升级槽位", () => TakeUpgrade(rig, upgrade, cards, modules, item));
|
||||
rig.onLoaded = _ => { ApplySlots(rig, cards); UpdateRig(rig, modules, cards); };
|
||||
rig.onCycleEndEarlySlotItemFunc = (_, _, _) => Log.Guard("矿架扣电", () => NightDraw(rig, battery, modules, cards));
|
||||
ModHelper.SetSource(rig, ModInfo.Id, ModInfo.Name);
|
||||
ApplySlots(rig, cards);
|
||||
UpdateRig(rig, modules, cards);
|
||||
return rig;
|
||||
}
|
||||
|
||||
/// <summary>按标签里的槽数设置显卡格子的形状(游戏自己扩展模块槽也是 SetShape 加 Validate)。</summary>
|
||||
private static void ApplySlots(GameItem rig, GameGridInventory cards)
|
||||
{
|
||||
cards.SetShape(RigSlots.Shape(SlotsOf(rig)), RigSlots.CellWidth);
|
||||
rig.contentWindow?.Validate();
|
||||
}
|
||||
|
||||
private static void TakeUpgrade(GameItem rig, GameSlotInventory upgradeSlot, GameGridInventory cards, GameInventory modules, GameItem item)
|
||||
{
|
||||
int slots = SlotsOf(rig);
|
||||
int progress = rig.IsTag(ProgressTag) ? rig.GetTagReadonly(ProgressTag).GetInt() : 0;
|
||||
int before = slots;
|
||||
int took = RigSlots.Insert(ref slots, ref progress, item.identifier, item.unitCount);
|
||||
if (took <= 0) return;
|
||||
rig.ModifyTag(SlotsTag, s => s.Enable().SetInt(slots));
|
||||
rig.ModifyTag(ProgressTag, s => s.Enable().SetInt(progress));
|
||||
// 消耗收下的件数;放不下的部分留在升级槽里(玩家取回)
|
||||
if (took >= item.unitCount) { upgradeSlot.Expel(item); item.Destroy(); }
|
||||
else item.GetSplitItem(took).Destroy();
|
||||
if (slots != before)
|
||||
{
|
||||
ApplySlots(rig, cards);
|
||||
EmporiumAudioPlayer.Instance?.ratchet?.Play();
|
||||
}
|
||||
UpdateRig(rig, (GameGridInventory)modules, cards);
|
||||
}
|
||||
|
||||
public static List<GameItem> Cards(GameInventory cards) => cards.childItems.Where(IsGpu).ToList();
|
||||
|
||||
/// <summary>按模块槽里的模块重新汇总三项百分比(游戏自己的公式,含相邻效果),换算成本 mod 的模块效果。</summary>
|
||||
@@ -167,7 +209,14 @@ namespace Decentralized
|
||||
int kj = RigKj(cards, b);
|
||||
rig.ModifyTag(MachineryHelper.MACHINERY_DRAWN_POWER, s => s.Enable().SetInt(kj));
|
||||
double hash = Cards(cards).Select(ToUnit).Sum(u => u.Hash(b));
|
||||
rig.shortDescription = L.T("item.rig.desc", Fmt.Num(hash * 10), kj);
|
||||
int slots = SlotsOf(rig);
|
||||
rig.shortDescription = L.T("item.rig.desc", slots, Fmt.Num(hash * 10), kj);
|
||||
var next = RigSlots.Next(slots);
|
||||
if (next != null)
|
||||
{
|
||||
int progress = rig.IsTag(ProgressTag) ? rig.GetTagReadonly(ProgressTag).GetInt() : 0;
|
||||
rig.shortDescription += " " + L.T("item.rig.next", slots + 1, L.T("mat." + next.Value.Item), progress, next.Value.Count);
|
||||
}
|
||||
if (b.Hash != 1 || b.Kj != 1 || b.Wear != 1)
|
||||
rig.shortDescription += " " + L.T("item.rig.modules", Pct(b.Hash), Pct(b.Kj), Pct(b.Wear));
|
||||
}
|
||||
|
||||
@@ -5,9 +5,13 @@ upgrade.desc,Members receive a trading terminal and an RZX 50 graphics card. The
|
||||
item.terminal.name,Trading Terminal
|
||||
item.terminal.desc,Wallet, the Poinbase exchange and the nightly mining report.
|
||||
item.rig.name,Mining Rig
|
||||
item.rig.desc,"Holds up to four graphics cards. Hashrate {0} MH/s. Draws {1} kJ per day."
|
||||
item.rig.desc,"Holds up to {0} graphics cards. Hashrate {1} MH/s. Draws {2} kJ per day."
|
||||
rig.label.modules,Modules
|
||||
item.rig.modules,"Modules: hashrate {0}, power draw {1}, wear {2}."
|
||||
rig.label.upgrade,Upgrade slot
|
||||
item.rig.next,"Slot {0}: put in {1} ({2}/{3})."
|
||||
mat.common_electronic,Common electronics
|
||||
mat.rare_electronic,Rare electronics
|
||||
rig.label.cards,Graphics cards
|
||||
item.gpu.name,{0} {1}
|
||||
item.gpu.desc,"Hashrate {0} MH/s. Draws {1} kJ per day. Condition {2}%."
|
||||
|
||||
|
@@ -4,9 +4,13 @@ upgrade.desc,成员可获得一台交易终端和一张 RZX 50 显卡。终端
|
||||
item.terminal.name,交易终端
|
||||
item.terminal.desc,钱包、Poinbase 交易所与夜间挖矿报告。
|
||||
item.rig.name,矿架
|
||||
item.rig.desc,可装 4 张显卡。算力 {0} MH/s。耗电 {1} kJ/天。
|
||||
item.rig.desc,最多装 {0} 张显卡。算力 {1} MH/s。耗电 {2} kJ/天。
|
||||
rig.label.modules,模块
|
||||
item.rig.modules,模块:算力 {0},耗电 {1},损耗 {2}。
|
||||
rig.label.upgrade,升级槽位
|
||||
item.rig.next,第 {0} 槽:投入{1}({2}/{3})。
|
||||
mat.common_electronic,普通电子元件
|
||||
mat.rare_electronic,稀有电子元件
|
||||
rig.label.cards,显卡
|
||||
item.gpu.name,{0} {1}
|
||||
item.gpu.desc,算力 {0} MH/s。耗电 {1} kJ/天。健康度 {2}%。
|
||||
|
||||
|
|
Before Width: | Height: | Size: 229 B After Width: | Height: | Size: 375 B |
|
Before Width: | Height: | Size: 185 B After Width: | Height: | Size: 329 B |
|
Before Width: | Height: | Size: 185 B After Width: | Height: | Size: 328 B |
|
Before Width: | Height: | Size: 229 B After Width: | Height: | Size: 259 B |