第十阶段 stage 1(一):解锁物品放前台、首页帮助入口、鉴定手册用原版文档模型、涡轮不能作用于矿机

This commit is contained in:
ZHU MINCHAO committed 2026-11-05 01:21:35 +08:00
1 parent 00a000e3f9
commit ad60b07ca9
19 files changed
+118 -53

No files matched your search

+68 -25
View File
@@ -16,7 +16,6 @@ namespace Decentralized
public const string Terminal = "pd_terminal";
public const string Rig = "pd_rig";
public const string Guide = "pd_gpu_guide";
public const string Web3Guide = "pd_web3_guide";
public const string GpuPrefix = "pd_gpu_";
public const string HwWallet = "pd_hw_wallet";
public const string KeyDrive = "pd_key_drive";
@@ -30,13 +29,24 @@ namespace Decentralized
public const string LookTag = "PD_LOOK", BackTag = "PD_BACK", SeedTag = "PD_SEED", ClaimTag = "PD_CLAIM", ExposedTag = "PD_EXPOSED", MarkupTag = "PD_MARKUP", EditedTag = "PD_EDITED";
public static Action OpenTerminal;
public static Action OpenHandbook, OpenGpuHandbook;
public static Action OpenGpuHandbook;
/// <summary>硬件钱包拖到交易终端上:添加一个钱包(参数:是否被投毒)。</summary>
public static Action<bool> AddWallet;
public static Func<bool> CanAddWallet;
public static void Subscribe() => ModHook.OnModItemDirectoryInit += Register;
public static void Unsubscribe() => ModHook.OnModItemDirectoryInit -= Register;
public static void Subscribe()
{
ModHook.OnModItemDirectoryInit += Register;
ModHook.OnLeavingStoreEarly += SweepFront;
ModHook.OnGoingSleepEarly += SweepFront;
}
public static void Unsubscribe()
{
ModHook.OnModItemDirectoryInit -= Register;
ModHook.OnLeavingStoreEarly -= SweepFront;
ModHook.OnGoingSleepEarly -= SweepFront;
}
public static string GpuId(string model) => GpuPrefix + model.ToLowerInvariant();
@@ -47,8 +57,8 @@ namespace Decentralized
dir.Add(Terminal, CreateTerminal);
dir.Add(Rig, CreateRig);
WrapElectronics(dir);
WrapTurbos(dir);
dir.Add(Guide, CreateGuide);
dir.Add(Web3Guide, CreateWeb3Guide);
dir.Add(HwWallet, CreateHwWallet);
dir.Add(KeyDrive, CreateKeyDrive);
AsicItems.Register(dir);
@@ -77,34 +87,21 @@ namespace Decentralized
return item;
}
/// <summary>显卡鉴定手册:档次对照、序列号规则、外观折扣。和游戏里的鉴定手册一样,是一件物品,说明里就是内容。</summary>
/// <summary>显卡鉴定手册:型号对照、序列号规则、外观折扣。做法同游戏里的鉴定手册(海明威鉴定指南):纸张图、文档类型、拖放音效。</summary>
private static GameItem CreateGuide()
{
var item = ItemDirectory.CreateEmptyItem(Guide);
item.SetSpriteAndShapeFromMod(ModInfo.Id, "gpu_guide");
item.SetSpriteAndShape("Items/items_misc", "guide1");
item.EnableTag("DOCUMENT");
item.SetGameItemType("DOCUMENT");
item.EnableTag("GUIDE_PAPER_TAG");
BookHelper.InitPaperGuide(item);
item.name = L.T("item.guide.name");
item.shortDescription = L.T("item.guide.desc");
item.mayActivateSlotItemFunc = (_, _, _) => true;
item.canActivateSlotItemFunc = (_, _, _) => true;
item.onActivateSlotItemFunc = (_, _, _) => Log.Guard("打开鉴定手册", () => OpenGpuHandbook?.Invoke());
item.unitValue = 0;
item.EnableTag(GeneralHelper.IMPORTANT_TAG);
item.EnableTag(TypeHelper.NOT_FOR_RESALE);
ModHelper.SetSource(item, ModInfo.Id, ModInfo.Name);
return item;
}
/// <summary>Web3 手册:银行、交易、混币器、黑市与 Ponero 的规则。界面上不放说明,规则都在这里。</summary>
private static GameItem CreateWeb3Guide()
{
var item = ItemDirectory.CreateEmptyItem(Web3Guide);
item.SetSpriteAndShapeFromMod(ModInfo.Id, "gpu_guide");
item.name = L.T("item.web3guide.name");
item.shortDescription = L.T("item.web3guide.desc");
item.mayActivateSlotItemFunc = (_, _, _) => true;
item.canActivateSlotItemFunc = (_, _, _) => true;
item.onActivateSlotItemFunc = (_, _, _) => Log.Guard("打开手册", () => OpenHandbook?.Invoke());
item.unitValue = 0;
item.unitValue = 50;
item.EnableTag(GeneralHelper.IMPORTANT_TAG);
item.EnableTag(TypeHelper.NOT_FOR_RESALE);
ModHelper.SetSource(item, ModInfo.Id, ModInfo.Name);
@@ -538,6 +535,30 @@ namespace Decentralized
catch (Exception ex) { Log.Error("[Rig] 包装电子元件失败:" + ex); }
}
/// <summary>
/// 涡轮增压器不能作用于矿架和 ASIC 矿机:它们带"标准机器"标签,原版涡轮只看这个标签,还会手动触发目标的夜间结算(等于白天多扣一次电)。
/// 在原版涡轮工厂外包一层,对这两类目标返回否;是替换判断函数而不是追加(追加是"或",原来的"是"还会生效)。
/// </summary>
private static void WrapTurbos(ModItemDirectory dir)
{
foreach (var id in new[] { "turbo_booster", "turbo_booster_adv", "turbo_booster_hypertech" })
{
var make = DirectoryMaster.GetFactory<GameItem>(id);
if (make == null) { Log.Warn($"[Rig] 找不到原版 {id}"); continue; }
dir.Set(id, () =>
{
var it = make();
var may = it.mayThisTargetItemFunc;
var can = it.canThisTargetItemFunc;
it.mayThisTargetItemFunc = (s, t) => !IsMiner(t) && (may?.Invoke(s, t) ?? false);
it.canThisTargetItemFunc = (s, t) => !IsMiner(t) && (can?.Invoke(s, t) ?? false);
return it;
});
}
}
private static bool IsMiner(GameItem t) => t != null && (t.identifier == Rig || AsicItems.Is(t));
private static readonly System.Runtime.CompilerServices.ConditionalWeakTable<GameItem, Tuple<GameGridInventory, GameInventory>> RigInv = new System.Runtime.CompilerServices.ConditionalWeakTable<GameItem, Tuple<GameGridInventory, GameInventory>>();
private static bool CanUpgradeWith(GameItem rig, GameItem src)
@@ -614,6 +635,7 @@ namespace Decentralized
/// <summary>夜间早段:按矿架上的显卡总耗电(含模块效果)从电池扣电;扣电成功,登记今晚参与挖矿的显卡和模块效果。</summary>
private static void NightDraw(GameItem rig, GameSlotInventory battery, GameInventory modules, GameInventory cards)
{
if (!Session.TonightDrawn.Add(rig.uniqueId)) return;
var list = Cards(cards).Where(c => !c.IsTag(DeadTag)).ToList();
Session.TonightRigs++;
if (list.Count == 0) return;
@@ -641,6 +663,27 @@ namespace Decentralized
Give(item);
}
/// <summary>放到前台(解锁送的东西第一眼能看到);前台放不下时退回储藏区。游戏离店和过夜会清空前台,<see cref="SweepFront"/> 在那之前把 mod 的物品收进储藏区。</summary>
public static void GiveToFront(GameItem item)
{
GeneralHelper.SetItemOwned(item, true);
var front = EmporiumEntry.Instance?.frontInvinvElement;
if (front != null && GraphUtils.CanAccept(front, item) && GraphUtils.TryAcceptAll(front, item) == 0) return;
Give(item);
}
/// <summary>离店、睡觉前:前台上属于 mod 的物品收进储藏区(游戏随后会清空前台,没拿走的终端、钱包会丢)。</summary>
private static void SweepFront()
{
Log.Guard("收起前台的 mod 物品", () =>
{
var e = EmporiumEntry.Instance;
if (e?.frontInvinvElement == null || e.invElement == null) return;
foreach (var it in e.frontInvinvElement.childItems.ToList())
if (it.identifier != null && it.identifier.StartsWith("pd_") && GeneralHelper.IsItemOwned(it)) GraphUtils.TryAcceptAll(e.invElement, it);
});
}
public static void Give(GameItem item)
{
GeneralHelper.SetItemOwned(item, true);