Stage 9.1: story links (Serpico, Eleanor, Officer Lun) and newspaper importance fix
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
96e91a4884
commit
62bd641283
15 files changed
+240
-17
No files matched your search
@@ -2,6 +2,16 @@
|
||||
|
||||
## 未发布
|
||||
|
||||
### 第九阶段:剧情与收尾
|
||||
|
||||
- 9.1 剧情联动:每晚读游戏剧情线的选择,每个只生效一次,改动本 mod 世界的倍率(存档里的 `StoryMods`),第二天报纸头版登一条新闻。选择是玩家自己做的,市场要过几天才反应完(SPARK 分 5 晚走完),可以抢在前面用永续和预测盘下注。
|
||||
- 塞尔皮科的证据交给革命军:CRA 补贴池 +10,000,30 天内螺旋概率减半,SPARK 五晚内涨 20%;交给黑市:CRT 脱锚、镇压时被黑市出卖的概率永久减半;交给治安部:30 天内出金审查命中率 ×1.5、混币器制裁概率 ×1.5、操纵检出和内幕查处 ×1.3;举报他或他死了:没有影响。
|
||||
- 埃莉诺泄露数据盘:CRC 托管银行减记的概率翻倍,SPARK 五晚内涨 15%;交回数据盘:CRC 脱锚概率减半。
|
||||
- 伦警官被捕:14 天内出金审查、操纵检出、内幕查处 ×1.3(和治安部整顿叠加)。
|
||||
- 无尽模式关闭角色剧情线,这些选择不会出现。放贷人 Lou 被捕没有接(借贷暂缓)。
|
||||
- 游戏内验证:调试入口设置"证据给革命军、泄露数据盘、伦警官被捕"后过一夜("Run night (test)"),日志三条"剧情联动生效",第二天报纸头版登出三条新闻。没有在游戏里验证:真实剧情对话里做出选择后的联动、各倍率在游戏里的实际效果(单元测试覆盖:出金命中率上升、CRT 脱锚减半、SPARK 推涨合计 ×1.2、叠加)。
|
||||
- 报纸修复:报纸按重要度排序、最多登 4 条;mod 新闻原来的重要度是 2,游戏事件一多就被挤掉(此前各阶段"报纸新闻没有验证"的原因)。改为默认 5(游戏事件多在 4–7),剧情联动 9。
|
||||
|
||||
### 行情图
|
||||
|
||||
- K 线图标数字:图里用一套 3×5 像素数字字体(放大 2 倍后约 6×10),和像素风格一致。右侧刻度栏(宽 22 像素)标三条网格线的价格;最新收盘价是黄底价签,网格刻度离它太近时让开;预测阈值线的价格用蓝色标在刻度栏;成交量区右上标这一屏最大的成交额(≥ 1 万写成 "36k");底部每逢天数是 5 的倍数的蜡烛下面标天数并画一个刻度点。价格位数随大小变:≥ 100 不带小数,≥ 10 一位,≥ 1 两位,小于 1 三位(".995")。图宽 206 像素(显示 412)。游戏内验证:PSC 刻度 113 / 81.3、价签 91.8、量柱 36k、日期 −10 … 15(测试存档在第 16 天,调试入口往前补了 30 天,所以出现负数;真实历史从第 1 天开始)。
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace Decentralized.Domain
|
||||
History.RemoveAll(h => h.Key <= day - Tuning.AmlWindowDays);
|
||||
double recent = History.Sum(h => h.Value);
|
||||
double value = amount * price(Assets.CRC);
|
||||
r.HitChance = HitChance(value, taint, recent, rent, fromMixer || wallet.Flagged);
|
||||
r.HitChance = Math.Min(1, HitChance(value, taint, recent, rent, fromMixer || wallet.Flagged) * StoryMods.Current.Aml(day));
|
||||
wallet.Add(Assets.CRC, -amount);
|
||||
wallet.Taint -= taint;
|
||||
wallet.Basis -= basis;
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace Decentralized.Domain
|
||||
/// <summary>镇压事件开始:有一定概率被制裁,持续若干天。</summary>
|
||||
public void OnEvent(MarketEvent ev, int day, Rng rng)
|
||||
{
|
||||
if (ev == MarketEvent.Crackdown && rng.Chance(Tuning.MixerSanctionChance)) SanctionedUntil = day + Tuning.MixerSanctionDays;
|
||||
if (ev == MarketEvent.Crackdown && rng.Chance(Math.Min(1, Tuning.MixerSanctionChance * StoryMods.Current.Sanction(day)))) SanctionedUntil = day + Tuning.MixerSanctionDays;
|
||||
}
|
||||
|
||||
/// <summary>每晚:到期的存入提回钱包(污点按轮数降低),在途的各有小概率跑路。</summary>
|
||||
|
||||
@@ -195,7 +195,7 @@ namespace Decentralized.Domain
|
||||
bool insider = PosAll(m.Id).Sum(x => x.Insider) >= Tuning.PredictInsiderShare * m.ShareCap;
|
||||
if (pos.Yes) m.QYes -= pos.Shares; else m.QNo -= pos.Shares;
|
||||
Positions.Remove(pos);
|
||||
if (rng != null && insider && pos.Insider > 0 && got > pos.Cost && rng.Chance(Tuning.PredictInsiderCatch))
|
||||
if (rng != null && insider && pos.Insider > 0 && got > pos.Cost && rng.Chance(Math.Min(1, Tuning.PredictInsiderCatch * StoryMods.Current.Enforce(day))))
|
||||
{
|
||||
fraud = Math.Min(Tuning.PredictFraudCap, (got - pos.Cost) * Tuning.PredictFraudShare);
|
||||
got = 0;
|
||||
@@ -241,7 +241,7 @@ namespace Decentralized.Domain
|
||||
st.Count++; st.SumP0 += m.P0; if (res.Value) st.Hits++;
|
||||
var winners = all.Where(x => x.Yes == res.Value).ToList();
|
||||
// 操纵:行情盘上,赢家的方向和玩家推价的方向一致时按推价幅度被查——本金和收益都没收,收益的一半记罪证
|
||||
if (m.Kind == PredictKind.Price && winners.Count > 0 && winners.Any(x => x.Yes ? push > 0 : push < 0) && rng.Chance(Market.ManipChance(push)))
|
||||
if (m.Kind == PredictKind.Price && winners.Count > 0 && winners.Any(x => x.Yes ? push > 0 : push < 0) && rng.Chance(Math.Min(1, Market.ManipChance(push) * StoryMods.Current.Enforce(day))))
|
||||
{
|
||||
double profitM = winners.Sum(x => x.Shares) - cost;
|
||||
evs.Add(new PredictEvent { Kind = "manip", Title = m.Title, Market = m, Amount = cost, Fraud = Math.Min(Tuning.PredictFraudCap, Math.Max(0, profitM) * Tuning.PredictFraudShare) });
|
||||
@@ -257,7 +257,7 @@ namespace Decentralized.Domain
|
||||
{
|
||||
double payout = winners.Sum(x => x.Shares), profit = payout - cost;
|
||||
// 内幕持仓按盘口合计(拆到几个钱包里也一样)
|
||||
if (all.Sum(x => x.Insider) >= Tuning.PredictInsiderShare * m.ShareCap && rng.Chance(Tuning.PredictInsiderCatch))
|
||||
if (all.Sum(x => x.Insider) >= Tuning.PredictInsiderShare * m.ShareCap && rng.Chance(Math.Min(1, Tuning.PredictInsiderCatch * StoryMods.Current.Enforce(day))))
|
||||
{
|
||||
// 查实:本金和收益全部没收
|
||||
evs.Add(new PredictEvent { Kind = "caught", Title = m.Title, Market = m, Amount = payout, Fraud = Math.Min(Tuning.PredictFraudCap, Math.Max(0, profit) * Tuning.PredictFraudShare) });
|
||||
|
||||
@@ -34,13 +34,13 @@ namespace Decentralized.Domain
|
||||
/// <summary>减记发生时返回 CRC 持有量要乘的系数(其余情况为 1)。</summary>
|
||||
public double OnEventStart(MarketEvent ev, int day, Rng rng)
|
||||
{
|
||||
if (ev == MarketEvent.RevRaidUpper && CrcDepegEnd < 0 && rng.Chance(Tuning.CrcDepegChance))
|
||||
if (ev == MarketEvent.RevRaidUpper && CrcDepegEnd < 0 && rng.Chance(Tuning.CrcDepegChance * StoryMods.Current.CrcDepeg))
|
||||
{
|
||||
Crc = rng.Range(Tuning.CrcDepegMin, Tuning.CrcDepegMax);
|
||||
CrcDepegEnd = day + rng.Range(Tuning.CrcDepegDaysMin, Tuning.CrcDepegDaysMax);
|
||||
CrcHaircutPending = rng.Chance(Tuning.CrcHaircutChance);
|
||||
CrcHaircutPending = rng.Chance(Math.Min(1, Tuning.CrcHaircutChance * StoryMods.Current.CrcHaircut));
|
||||
}
|
||||
if ((ev == MarketEvent.GangWar || ev == MarketEvent.Crackdown) && CrtDepegEnd < 0 && rng.Chance(Tuning.CrtDepegChance))
|
||||
if ((ev == MarketEvent.GangWar || ev == MarketEvent.Crackdown) && CrtDepegEnd < 0 && rng.Chance(Tuning.CrtDepegChance * StoryMods.Current.CrtDepeg))
|
||||
{
|
||||
Crt = rng.Range(Tuning.CrtDepegMin, Tuning.CrtDepegMax);
|
||||
CrtDepegEnd = day + rng.Range(Tuning.CrtDepegDaysMin, Tuning.CrtDepegDaysMax);
|
||||
@@ -52,7 +52,7 @@ namespace Decentralized.Domain
|
||||
|
||||
/// <summary>镇压开始时,玩家持有的 CRT 被冻结一半的概率:黑市声望 0 时 40%,50 以上为 0。</summary>
|
||||
public static double CrtFreezeChance(double blackMarketRep) =>
|
||||
Math.Max(0, Tuning.CrtFreezeBase - blackMarketRep * Tuning.CrtFreezePerRep);
|
||||
Math.Max(0, Tuning.CrtFreezeBase - blackMarketRep * Tuning.CrtFreezePerRep) * StoryMods.Current.CrtFreeze;
|
||||
|
||||
/// <summary>镇压开始时是否冻结玩家的 CRT:按黑市声望,声望越低越容易被黑市"出卖"。</summary>
|
||||
public static bool CrtFrozenByCrackdown(double blackMarketRep, Rng rng) => rng.Chance(CrtFreezeChance(blackMarketRep));
|
||||
@@ -111,7 +111,7 @@ namespace Decentralized.Domain
|
||||
{
|
||||
CraSubsidy -= (Tuning.CraNpcStake + playerStaked) * CraRate;
|
||||
bool revFalling = RevHistory.Count == 7 && RevPower < RevHistory[0] - 5;
|
||||
double weekly = Tuning.CraSpiralWeekly * (revFalling ? 3 : 1);
|
||||
double weekly = Tuning.CraSpiralWeekly * (revFalling ? 3 : 1) * StoryMods.Current.CraSpiral(day);
|
||||
double daily = 1 - Math.Pow(1 - weekly, 1.0 / 7);
|
||||
if (CraWarnDay < 0 && (rng.Chance(daily) || CraSubsidy <= 0))
|
||||
{
|
||||
@@ -128,7 +128,7 @@ namespace Decentralized.Domain
|
||||
}
|
||||
else
|
||||
{
|
||||
Spark *= Math.Exp(rng.Gauss() * Tuning.SparkVol);
|
||||
Spark *= Math.Exp(rng.Gauss() * Tuning.SparkVol) * StoryMods.Current.TakeSparkPush();
|
||||
Spark += (Tuning.SparkStart - Spark) * Tuning.SparkRevert;
|
||||
Spark = Math.Max(Tuning.SparkStart * Tuning.SparkMinMult, Math.Min(Tuning.SparkStart * Tuning.SparkMaxMult, Spark));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Decentralized.Domain
|
||||
{
|
||||
/// <summary>
|
||||
/// 游戏剧情选择对本 mod 世界的影响:一组倍率和期限,随存档保存。各处的概率读 <see cref="Current"/>(接入层读档时指向存档里的这一份)。
|
||||
/// 每个选择只生效一次(Applied 记下键)。
|
||||
/// </summary>
|
||||
public sealed class StoryMods
|
||||
{
|
||||
/// <summary>当前生效的那一份。接入层读档时设成存档里的;测试里可以换。</summary>
|
||||
public static StoryMods Current = new StoryMods();
|
||||
|
||||
public List<string> Applied = new List<string>();
|
||||
/// <summary>CRC 脱锚、CRC 托管银行减记、CRT 脱锚、镇压时 CRT 被出卖的概率倍率(永久)。</summary>
|
||||
public double CrcDepeg = 1, CrcHaircut = 1, CrtDepeg = 1, CrtFreeze = 1;
|
||||
/// <summary>到这一天之前 CRA 螺旋概率减半。</summary>
|
||||
public int CraSafeUntil = -1;
|
||||
/// <summary>治安部整顿到这一天:出金审查命中率、混币器制裁概率、操纵与内幕查处概率上调。</summary>
|
||||
public int SecUntil = -1;
|
||||
/// <summary>伦警官被捕后的立威期到这一天:出金审查、操纵、内幕查处概率上调。</summary>
|
||||
public int LunUntil = -1;
|
||||
/// <summary>SPARK 每晚额外乘的倍数,还剩几晚。</summary>
|
||||
public double SparkPush = 1;
|
||||
public int SparkPushNights;
|
||||
|
||||
public bool Has(string key) => Applied.Contains(key);
|
||||
|
||||
public double CraSpiral(int day) => day < CraSafeUntil ? Tuning.StoryCraSpiralMult : 1;
|
||||
public double Aml(int day) => (day < SecUntil ? Tuning.StorySecAmlMult : 1) * (day < LunUntil ? Tuning.StoryLunMult : 1);
|
||||
public double Sanction(int day) => day < SecUntil ? Tuning.StorySecSanctionMult : 1;
|
||||
/// <summary>操纵检出、内幕查处的概率倍率。</summary>
|
||||
public double Enforce(int day) => (day < SecUntil ? Tuning.StorySecEnforceMult : 1) * (day < LunUntil ? Tuning.StoryLunMult : 1);
|
||||
|
||||
/// <summary>每晚取 SPARK 的额外倍数(推完就是 1)。</summary>
|
||||
public double TakeSparkPush()
|
||||
{
|
||||
if (SparkPushNights <= 0) return 1;
|
||||
SparkPushNights--;
|
||||
return SparkPush;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 记下一个剧情选择并设置倍率。返回 false 表示已经生效过。CRA 补贴池的注资由接入层做(这里只管倍率)。
|
||||
/// key:serpico_rev / serpico_bm / serpico_sec / eleanor_leak / eleanor_return / lun_arrested。
|
||||
/// </summary>
|
||||
public bool Apply(string key, int day)
|
||||
{
|
||||
if (Has(key)) return false;
|
||||
Applied.Add(key);
|
||||
switch (key)
|
||||
{
|
||||
case "serpico_rev":
|
||||
CraSafeUntil = day + Tuning.StorySecDays;
|
||||
PushSpark(Tuning.StorySerpicoSpark);
|
||||
break;
|
||||
case "serpico_bm":
|
||||
CrtDepeg *= Tuning.StoryBmCrtMult; CrtFreeze *= Tuning.StoryBmCrtMult;
|
||||
break;
|
||||
case "serpico_sec":
|
||||
SecUntil = day + Tuning.StorySecDays;
|
||||
break;
|
||||
case "eleanor_leak":
|
||||
CrcHaircut *= Tuning.StoryLeakHaircutMult;
|
||||
PushSpark(Tuning.StoryLeakSpark);
|
||||
break;
|
||||
case "eleanor_return":
|
||||
CrcDepeg *= Tuning.StoryReturnCrcMult;
|
||||
break;
|
||||
case "lun_arrested":
|
||||
LunUntil = day + Tuning.StoryLunDays;
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>SPARK 在接下来几晚里一共涨到 total 倍(每晚乘相同的倍数)。</summary>
|
||||
private void PushSpark(double total)
|
||||
{
|
||||
int n = Tuning.StorySparkNights;
|
||||
// 已经在推:把剩下的叠上去
|
||||
double left = SparkPushNights > 0 ? Math.Pow(SparkPush, SparkPushNights) : 1;
|
||||
SparkPush = Math.Pow(left * total, 1.0 / n);
|
||||
SparkPushNights = n;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,6 +235,17 @@ namespace Decentralized.Domain
|
||||
public const double FakeSupportChance = 0.04, FakeTransferShare = 0.08;
|
||||
public const int ScamMinDay = 10;
|
||||
|
||||
/// <summary>剧情联动:塞尔皮科证据交给革命军(CRA 补贴池注资、螺旋概率倍率与期限、SPARK 几晚内涨到的倍数)、交给黑市(CRT 脱锚与被出卖的倍率)、
|
||||
/// 交给治安部(期限内出金审查命中、混币器制裁、操纵与内幕查处的倍率);埃莉诺泄露数据盘(CRC 托管减记倍率、SPARK 涨幅)、交回(CRC 脱锚倍率);
|
||||
/// 伦警官被捕(期限与查处倍率);SPARK 推涨分几晚走完。</summary>
|
||||
public const double StoryRevSubsidy = 10000, StoryCraSpiralMult = 0.5, StorySerpicoSpark = 1.2;
|
||||
public const double StoryBmCrtMult = 0.5;
|
||||
public const int StorySecDays = 30;
|
||||
public const double StorySecAmlMult = 1.5, StorySecSanctionMult = 1.5, StorySecEnforceMult = 1.3;
|
||||
public const double StoryLeakHaircutMult = 2, StoryLeakSpark = 1.15, StoryReturnCrcMult = 0.5;
|
||||
public const int StoryLunDays = 14, StorySparkNights = 5;
|
||||
public const double StoryLunMult = 1.3;
|
||||
|
||||
/// <summary>行情图的 NPC 成交量:每天的基础量占主池深度的比例(按币种),价格波动越大成交越多(|涨跌幅| × 倍数),再乘 0.6–1.4 的随机。</summary>
|
||||
public const double ChartVolPsc = 0.12, ChartVolCrc = 0.10, ChartVolCrt = 0.06, ChartVolCra = 0.04, ChartVolSpark = 0.03, ChartVolPonero = 0.01, ChartVolMove = 8;
|
||||
|
||||
|
||||
@@ -132,6 +132,12 @@ namespace Decentralized
|
||||
CandleChart.Morning(d, day0 + 30);
|
||||
Log.Info($"测试:K 线 {d.Candles.Of(Assets.PSC).Count} 根,PSC {d.Market.Price:0.00}");
|
||||
}));
|
||||
ModHelper.AddDebugFunction(ModInfo.Id, ModInfo.Name, "Story: Serpico to Revolution, Eleanor leaks, Lun arrested (test)", () =>
|
||||
{
|
||||
var cd = PlayerStore.GetStoreClientData();
|
||||
cd.serpicoDocumentChoice = SerpicoStoryline.CHOICE_REVOLUTION; cd.eleanorDriveChoice = 2; cd.officerLunArrested = true;
|
||||
Log.Info("测试:剧情选择已设置(革命军 / 泄露 / 伦警官被捕),今晚生效");
|
||||
});
|
||||
ModHelper.AddDebugFunction(ModInfo.Id, ModInfo.Name, "Predict: window = tomorrow (test)", () => { foreach (var m in Session.Data.Predict.Markets) { m.FromDay = m.ToDay = StoreStation.GetDayCounter() + 1; } Log.Info("测试:所有盘口窗口改成明天"); });
|
||||
ModHelper.AddDebugFunction(ModInfo.Id, ModInfo.Name, "Perp fund 0 (test)", () => { Session.Data.Perps.InsuranceFund = 0; Log.Info("测试:保险基金清零"); });
|
||||
ModHelper.AddDebugFunction(ModInfo.Id, ModInfo.Name, "SPARK x0.3 (test)", () => { var st = Session.Data.Stable; st.Spark *= 0.3; Log.Info($"测试:SPARK 价格 {st.Spark:0.00}"); });
|
||||
|
||||
@@ -268,7 +268,7 @@ black.kind.Contraband.3,Contraband (high)
|
||||
black.kind.Tech,High-tech (markup)
|
||||
nightlog.bm.ready,"Black market: {0} arrived; a courier will come by once you open."
|
||||
item.web3guide.name,Web3 Handbook
|
||||
item.web3guide.desc,"Bank: depositing turns credits into CRC in your Poinbase account; withdrawing turns CRC back into credits and goes through compliance screening, which looks at the Poinbase account's taint. Trading: buys are paid in the quote coin, sells in the traded coin. Mixer: pick a coin, amount and rounds; each round takes a fee and lowers taint, rounds equal days of waiting, and the coins come back to the same address; the more you deposit, the worse the cleaning. Hardware wallets: on-chain coins sit in PLEDGER hardware wallets, each with its own balances and taint; open and connect them on the terminal's Wallets page. The Web3 page's trading, black market and mixer use the connected wallet, and coin-paying customers and mining rewards go into it too. Payments (black market, mixer, Ponero desk, listing fees) start as an invoice on the terminal; type the payee address on the wallet and hold ✓ to sign. The last two characters of an address are a checksum, so a one-character typo is usually caught; once in a while it happens to be valid and the coins go to an address nobody uses. DEX swaps also need a signature on the wallet. RatDigg miners (M1 / M2 / M3) are standalone machines with far more hash than a card and a lower power draw per hash; they need a battery, take modules and use no rig slots. Only the black market's miner dealers sell them, gated by black-market standing (M1 40, M2 60, M3 80), sometimes second-hand. When one burns out, repair it by putting electronic components in its repair slot in order; it comes back 20 health lower. Somewhere between day 50 and day 90 a "miner era" arrives, announced in the paper a few days earlier: the big farms halve their power costs, network hash climbs, GPU miners are diluted and low-end cards barely earn, while miners still do fine. Perps: the Perps tab on Poinbase uses your account CRC as margin, up to 5× on PSC and 3× on SPARK, one position per product, never long and short at once. Fills are worse than the quote (more so for bigger orders, like the spot pool) and opening and closing both cost a fee. Liquidation is checked only overnight against the day's average price: equity under 10% of notional wipes the margin. There is also a nightly funding payment; when the price is above its 7-day average, longs pay shorts. If a liquidation loses more than the margin, the insurance fund covers the gap; when it runs dry (a SPARK collapse can do that) winning positions are auto-deleveraged and give up half their profit; anything beyond that becomes your debt. Debt grows 2% a day, is repaid first from CRC in the account every night, blocks new positions and cash-outs, and after seven days items in your shop are seized to cover it; whatever is still short is written off and the perp account is banned for 30 days. Poinbase is a custodial account and can withdraw straight to the connected wallet; depositing from a wallet means sending to Poinbase's deposit address, which takes only CRC and PSC. More hardware wallets are sold by Dr. Jackson; drag one onto the trading terminal to add it, up to 5. The black market has cheaper ones. A wallet you no longer want can be destroyed on the Wallets page once its coins are moved out. Transfers pay a fee: slow, normal or fast, and gas prices rise and fall over roughly a week; when the network is congested fees rise and slow transactions may be dropped from the mempool. Check the full address before sending. Staking: CRA staked in the Revolution pool earns a daily rate that compounds into the stake; withdrawing means requesting first and waiting four days, with no interest while waiting and no way to take it early. The pool pays from a subsidy fund; when it runs low the rate is cut and word of big holders pulling out may spread. Treat that as a warning: once it collapses CRA is worthless within three days and four days of unlocking is too slow. The balance token SPARK can be minted and burned against CRA at the going price (with a fee); its price swings hard and crashes with the collapse. Staking, minting and burning are contract calls and need a signature on the wallet. Black market: coin only, no CRC, 30% above normal channels, with extra markup on high-tech goods and GPUs; the coin you pay leaves its share of taint with the seller and the goods carry no stolen tag; GPUs may be fake, inspect them yourself. Orders are cheaper than spot but take days and may be intercepted; merchants sell by type at their own price factor, 5+ items get 5% off and 10+ get 10% off, and a bulk merchant appears at random with the lowest prices but six days of waiting; escrow costs 5%, is released on delivery and refunded if the seller runs; advance release takes another 10% off, but a scammer keeps the money and only sellers with 30+ trades accept; the platform itself can rug, be taken over by enforcement, or a seller can be arrested, after which your orders get traced and crime logged; forum rumors can be warnings. An intercepted parcel sometLine truncated
|
||||
item.web3guide.desc,"Bank: depositing turns credits into CRC in your Poinbase account; withdrawing turns CRC back into credits and goes through compliance screening, which looks at the Poinbase account's taint. Trading: buys are paid in the quote coin, sells in the traded coin. Mixer: pick a coin, amount and rounds; each round takes a fee and lowers taint, rounds equal days of waiting, and the coins come back to the same address; the more you deposit, the worse the cleaning. Hardware wallets: on-chain coins sit in PLEDGER hardware wallets, each with its own balances and taint; open and connect them on the terminal's Wallets page. The Web3 page's trading, black market and mixer use the connected wallet, and coin-paying customers and mining rewards go into it too. Payments (black market, mixer, Ponero desk, listing fees) start as an invoice on the terminal; type the payee address on the wallet and hold ✓ to sign. The last two characters of an address are a checksum, so a one-character typo is usually caught; once in a while it happens to be valid and the coins go to an address nobody uses. DEX swaps also need a signature on the wallet. RatDigg miners (M1 / M2 / M3) are standalone machines with far more hash than a card and a lower power draw per hash; they need a battery, take modules and use no rig slots. Only the black market's miner dealers sell them, gated by black-market standing (M1 40, M2 60, M3 80), sometimes second-hand. When one burns out, repair it by putting electronic components in its repair slot in order; it comes back 20 health lower. Somewhere between day 50 and day 90 a "miner era" arrives, announced in the paper a few days earlier: the big farms halve their power costs, network hash climbs, GPU miners are diluted and low-end cards barely earn, while miners still do fine. Perps: the Perps tab on Poinbase uses your account CRC as margin, up to 5× on PSC and 3× on SPARK, one position per product, never long and short at once. Fills are worse than the quote (more so for bigger orders, like the spot pool) and opening and closing both cost a fee. Liquidation is checked only overnight against the day's average price: equity under 10% of notional wipes the margin. There is also a nightly funding payment; when the price is above its 7-day average, longs pay shorts. If a liquidation loses more than the margin, the insurance fund covers the gap; when it runs dry (a SPARK collapse can do that) winning positions are auto-deleveraged and give up half their profit; anything beyond that becomes your debt. Debt grows 2% a day, is repaid first from CRC in the account every night, blocks new positions and cash-outs, and after seven days items in your shop are seized to cover it; whatever is still short is written off and the perp account is banned for 30 days. Poinbase is a custodial account and can withdraw straight to the connected wallet; depositing from a wallet means sending to Poinbase's deposit address, which takes only CRC and PSC. More hardware wallets are sold by Dr. Jackson; drag one onto the trading terminal to add it, up to 5. The black market has cheaper ones. A wallet you no longer want can be destroyed on the Wallets page once its coins are moved out. Transfers pay a fee: slow, normal or fast, and gas prices rise and fall over roughly a week; when the network is congested fees rise and slow transactions may be dropped from the mempool. Check the full address before sending. Staking: CRA staked in the Revolution pool earns a daily rate that compounds into the stake; withdrawing means requesting first and waiting four days, with no interest while waiting and no way to take it early. The pool pays from a subsidy fund; when it runs low the rate is cut and word of big holders pulling out may spread. Treat that as a warning: once it collapses CRA is worthless within three days and four days of unlocking is too slow. The balance token SPARK can be minted and burned against CRA at the going price (with a fee); its price swings hard and crashes with the collapse. Staking, minting and burning are contract calls and need a signature on the wallet. Black market: coin only, no CRC, 30% above normal channels, with extra markup on high-tech goods and GPUs; the coin you pay leaves its share of taint with the seller and the goods carry no stolen tag; GPUs may be fake, inspect them yourself. Orders are cheaper than spot but take days and may be intercepted; merchants sell by type at their own price factor, 5+ items get 5% off and 10+ get 10% off, and a bulk merchant appears at random with the lowest prices but six days of waiting; escrow costs 5%, is released on delivery and refunded if the seller runs; advance release takes another 10% off, but a scammer keeps the money and only sellers with 30+ trades accept; the platform itself can rug, be taken over by enforcement, or a seller can be arrested, after which your orders get traced and crime logged; forum rumors can be warnings. An intercepted parcel sometLine truncated
|
||||
courier.odd1,...Package is here.
|
||||
courier.odd2,"(His hand stays in his pocket.) Sign here."
|
||||
courier.sign,Sign
|
||||
@@ -731,3 +731,15 @@ chart.empty,{0} daily chart: no history yet; recording from today.
|
||||
chart.caption,{0} daily H {2} L {3} C {4} ({5}%)
|
||||
chart.legend,"<size=80%>green up, red down; yellow 7-day MA; bars: grey market / cyan you</size>"
|
||||
chart.legend.thr,"<size=80%>green up, red down; yellow 7-day MA; blue dashes threshold</size>"
|
||||
news.story.serpico_rev.title,Revolution holds dirt on Security
|
||||
news.story.serpico_rev.desc,"The Revolution reportedly obtained evidence of corruption inside Security. Word from the staking pool: a large sum has been injected into the CRA subsidy, and SPARK has been firming up."
|
||||
news.story.serpico_bm.title,Black market strikes a quiet deal
|
||||
news.story.serpico_bm.desc,"An internal Security document changed hands on the black market. Darknet settlement has been noticeably steadier since, and CRT redemptions have not slipped once."
|
||||
news.story.serpico_sec.title,Security launches internal purge
|
||||
news.story.serpico_sec.desc,Security announced a full investigation into internal corruption and tighter monitoring of money flows. Poinbase is tightening cash-out screening and mixing services have been named.
|
||||
news.story.eleanor_leak.title,Nutrifruit breeding data leaked
|
||||
news.story.eleanor_leak.desc,"The lower-level paper published research that lets nutrifruit set seed again; Pastelle shares plunged. The bank custodying upper-level funds reports bad debts, and the Revolution is gaining ground."
|
||||
news.story.eleanor_return.title,Pastelle recovers stolen data
|
||||
news.story.eleanor_return.desc,"Pastelle confirmed it recovered stolen research data. Upper-level capital breathed a sigh of relief, and the CRC custodian bank was upgraded."
|
||||
news.story.lun_arrested.title,Officer Lun arrested for abuse of power
|
||||
news.story.lun_arrested.desc,Security arrested Officer Lun on the spot for abuse of power and promised a strict crackdown on illegal trading for the next two weeks.
|
||||
@@ -267,7 +267,7 @@ black.kind.Contraband.3,违禁品(高)
|
||||
black.kind.Tech,高科技物品(加价)
|
||||
nightlog.bm.ready,"黑市:{0} 到货,开店后会有快递员上门。"
|
||||
item.web3guide.name,Web3 手册
|
||||
item.web3guide.desc,"银行:存入把信用点换成 Poinbase 账户里的 CRC;提取把 CRC 换回信用点,要过合规审查,审查看 Poinbase 账户的污点。交易:买入按计价币的数量支付,卖出按所交易币的数量卖出。混币器:选币种、填数量和轮数,每轮扣手续费并降低污点,轮数即等待天数,到期提回同一个地址;存入越多,清洗越差。硬件钱包:链上的币放在 PLEDGER 硬件钱包里,每个钱包的余额和污点各算各的;在终端的钱包页打开、连接。Web3 页的交易、黑市、混币器用已连接的钱包,用币付款的顾客和挖矿收益也进它。付款(黑市、混币器、Ponero 兑换处、上架费)先在终端开账单,再在钱包里手输收款地址、按住 ✓ 签名;地址末尾两位是校验位,输错一位多半会被拦下,偶尔碰巧合法,币就转进了没人用的地址。DEX 兑换也要在钱包上签名。Poinbase 是托管账户,可以直接提到已连接的钱包;从钱包充值要转到 Poinbase 的充值地址,只收 CRC 和 PSC。更多硬件钱包向杰克逊博士购买,拖到交易终端上添加,最多 5 个;黑市上也有更便宜的。不要的钱包可以在钱包页销毁,要先把币转走。转账要付手续费,分慢、普通、快三档,gas 价格大约一周一个起落;网络拥堵时手续费变贵,慢档可能被挤出内存池。转账前核对完整地址。质押:把 CRA 质押进革命军质押池每天有日息,利息并入本金;取出要先申请,等四天才到账,等待期间没有利息,也不能提前拿。质押池靠补贴池付息,补贴池见底会降息,有时还会传出大户撤出的消息,那是预兆:一旦崩盘,三天内 CRA 就一文不值,四天的解锁期来不及。平衡代币 SPARK 可以和 CRA 按价格互相铸销(收手续费),价格波动很大,崩盘时会跟着暴跌。质押、铸销都是合约调用,要在钱包上签名。RatDigg 矿机(M1 / M2 / M3)是独立的机器,算力比显卡大得多、耗电更省,要放电池才挖,可以放模块,不占矿架槽位;只在黑市的矿机商那里有,要黑市声望(M1 40、M2 60、M3 80),偶尔有二手的。暴毙后要往修理槽里放电子元件按顺序修好,修好健康少 20。第 50 到 90 天之间会有一次"矿机时代",提前几天上报纸预告,之后大矿场的耗电成本砍半,全网算力涨上去,显卡矿工的收益被摊薄,低档显卡几乎不赚钱,矿机还行。永续合约:Poinbase 的"永续"页,用账户里的 CRC 当保证金,PSC 最高 5 倍、SPARK 最高 3 倍,一个品种只有一个仓位,不能同时多空。成交价比现价差一截(单越大差得越多,和现货池一样),开平仓还收手续费。强平只在夜里按当天均价检查,权益不到名义价值的 10% 就被强平,保证金没了;每晚还有资金费,价格比近 7 天均价高时多头付给空头。强平后亏光保证金还不够的缺口,先由保险基金垫,基金见底(SPARK 崩盘这类大行情会抽干它)后盈利的仓位会被自动减仓、少拿一半盈利,再不够就记成你的欠款:欠款每天涨 2%,账户里的 CRC 每晚先拿去还,没还清不能开仓、不能出金,七天不还就没收店里的物品抵债,抵不够的核销并拉黑永续账户 30 天。黑市:只收币,不收 CRC,价格比正常渠道贵 30%,高科技物品和显卡另有加价;付出去的币带着按比例的污点留在卖家那边,货不带赃物标签;显卡不保证真假,自己鉴定。订单比现货便宜,要等几天,路上可能被截获;商家按类型卖货,价格系数各不相同,一次订 5 件以上 95 折、10 件以上 9 折,大宗商家随机出现,价格最低但要等六天;托管多付 5% 托管费,收货后放款,卖家跑路时退款;提前放款再打九折,卖家若是骗子钱就没了,只有成交 30 单以上的卖家接受;平台自己也可能跑路,也可能被执法接管,或者卖家落网,之后你的订单会被追查、记罪证;论坛上的传闻可以当预兆。被截获的包裹有时会变成执法人员上门:签收当场记罪证并查封,拒签只损失货款。出售:在黑市的卖货页把储藏区里的违禁品、高科技物品和显卡上架,标价是参考价的 0.6 到 1.8 倍。倍率越高成交越慢(0.9 以下约一天,1.0 约两天,1.8 约十四天),货款带污点的可能性和比例也越高,近 7 天出售的量越大,污点越重;同时最多上架 10 件,上架收 5% 上架费,上架后可以改价(收 2% 改价费,标价按参考价重算,成交的快慢跟着新倍率走),成交扣 8% 抽成,货款托管 3 天后进钱包;卖假卡可能被买家看穿而退货,拉低好评;平台跑路时上架的货和未放款的货款都没了Line truncated
|
||||
item.web3guide.desc,"银行:存入把信用点换成 Poinbase 账户里的 CRC;提取把 CRC 换回信用点,要过合规审查,审查看 Poinbase 账户的污点。交易:买入按计价币的数量支付,卖出按所交易币的数量卖出。混币器:选币种、填数量和轮数,每轮扣手续费并降低污点,轮数即等待天数,到期提回同一个地址;存入越多,清洗越差。硬件钱包:链上的币放在 PLEDGER 硬件钱包里,每个钱包的余额和污点各算各的;在终端的钱包页打开、连接。Web3 页的交易、黑市、混币器用已连接的钱包,用币付款的顾客和挖矿收益也进它。付款(黑市、混币器、Ponero 兑换处、上架费)先在终端开账单,再在钱包里手输收款地址、按住 ✓ 签名;地址末尾两位是校验位,输错一位多半会被拦下,偶尔碰巧合法,币就转进了没人用的地址。DEX 兑换也要在钱包上签名。Poinbase 是托管账户,可以直接提到已连接的钱包;从钱包充值要转到 Poinbase 的充值地址,只收 CRC 和 PSC。更多硬件钱包向杰克逊博士购买,拖到交易终端上添加,最多 5 个;黑市上也有更便宜的。不要的钱包可以在钱包页销毁,要先把币转走。转账要付手续费,分慢、普通、快三档,gas 价格大约一周一个起落;网络拥堵时手续费变贵,慢档可能被挤出内存池。转账前核对完整地址。质押:把 CRA 质押进革命军质押池每天有日息,利息并入本金;取出要先申请,等四天才到账,等待期间没有利息,也不能提前拿。质押池靠补贴池付息,补贴池见底会降息,有时还会传出大户撤出的消息,那是预兆:一旦崩盘,三天内 CRA 就一文不值,四天的解锁期来不及。平衡代币 SPARK 可以和 CRA 按价格互相铸销(收手续费),价格波动很大,崩盘时会跟着暴跌。质押、铸销都是合约调用,要在钱包上签名。RatDigg 矿机(M1 / M2 / M3)是独立的机器,算力比显卡大得多、耗电更省,要放电池才挖,可以放模块,不占矿架槽位;只在黑市的矿机商那里有,要黑市声望(M1 40、M2 60、M3 80),偶尔有二手的。暴毙后要往修理槽里放电子元件按顺序修好,修好健康少 20。第 50 到 90 天之间会有一次"矿机时代",提前几天上报纸预告,之后大矿场的耗电成本砍半,全网算力涨上去,显卡矿工的收益被摊薄,低档显卡几乎不赚钱,矿机还行。永续合约:Poinbase 的"永续"页,用账户里的 CRC 当保证金,PSC 最高 5 倍、SPARK 最高 3 倍,一个品种只有一个仓位,不能同时多空。成交价比现价差一截(单越大差得越多,和现货池一样),开平仓还收手续费。强平只在夜里按当天均价检查,权益不到名义价值的 10% 就被强平,保证金没了;每晚还有资金费,价格比近 7 天均价高时多头付给空头。强平后亏光保证金还不够的缺口,先由保险基金垫,基金见底(SPARK 崩盘这类大行情会抽干它)后盈利的仓位会被自动减仓、少拿一半盈利,再不够就记成你的欠款:欠款每天涨 2%,账户里的 CRC 每晚先拿去还,没还清不能开仓、不能出金,七天不还就没收店里的物品抵债,抵不够的核销并拉黑永续账户 30 天。黑市:只收币,不收 CRC,价格比正常渠道贵 30%,高科技物品和显卡另有加价;付出去的币带着按比例的污点留在卖家那边,货不带赃物标签;显卡不保证真假,自己鉴定。订单比现货便宜,要等几天,路上可能被截获;商家按类型卖货,价格系数各不相同,一次订 5 件以上 95 折、10 件以上 9 折,大宗商家随机出现,价格最低但要等六天;托管多付 5% 托管费,收货后放款,卖家跑路时退款;提前放款再打九折,卖家若是骗子钱就没了,只有成交 30 单以上的卖家接受;平台自己也可能跑路,也可能被执法接管,或者卖家落网,之后你的订单会被追查、记罪证;论坛上的传闻可以当预兆。被截获的包裹有时会变成执法人员上门:签收当场记罪证并查封,拒签只损失货款。出售:在黑市的卖货页把储藏区里的违禁品、高科技物品和显卡上架,标价是参考价的 0.6 到 1.8 倍。倍率越高成交越慢(0.9 以下约一天,1.0 约两天,1.8 约十四天),货款带污点的可能性和比例也越高,近 7 天出售的量越大,污点越重;同时最多上架 10 件,上架收 5% 上架费,上架后可以改价(收 2% 改价费,标价按参考价重算,成交的快慢跟着新倍率走),成交扣 8% 抽成,货款托管 3 天后进钱包;卖假卡可能被买家看穿而退货,拉低好评;平台跑路时上架的货和未放款的货款都没了Line truncated
|
||||
courier.odd1,……东西到了。
|
||||
courier.odd2,"(他的手一直放在口袋里)在这儿签个字。"
|
||||
courier.sign,签收
|
||||
@@ -730,3 +730,15 @@ chart.empty,{0} 日 K:还没有历史,从今天开始记录。
|
||||
chart.caption,{0} 日K 高 {2} 低 {3} 收 {4}({5}%)
|
||||
chart.legend,<size=80%>绿涨红跌 黄线 7 日均线 柱:灰 市场 / 青 你的成交</size>
|
||||
chart.legend.thr,<size=80%>绿涨红跌 黄线 7 日均线 蓝虚线 阈值</size>
|
||||
news.story.serpico_rev.title,革命军握有治安部把柄
|
||||
news.story.serpico_rev.desc,据传革命军拿到了治安部内部腐败的证据。质押池传出消息:一笔大额资金注入 CRA 补贴池,SPARK 近日走强。
|
||||
news.story.serpico_bm.title,黑市与治安部达成默契
|
||||
news.story.serpico_bm.desc,一份治安部内部文件在黑市易手。此后暗网结算通道明显稳定,CRT 的兑付没再出过岔子。
|
||||
news.story.serpico_sec.title,治安部启动内部整顿
|
||||
news.story.serpico_sec.desc,治安部宣布彻查内部腐败,同时加强对资金流向的监控。Poinbase 收紧出金审查,混币服务被点名。
|
||||
news.story.eleanor_leak.title,营养果育种数据曝光
|
||||
news.story.eleanor_leak.desc,下层报社公开了一份营养果重新结籽的研究数据,帕斯泰尔公司股价重挫。托管上层资金的银行传出坏账,革命军声势上涨。
|
||||
news.story.eleanor_return.title,帕斯泰尔追回失窃数据
|
||||
news.story.eleanor_return.desc,帕斯泰尔公司证实追回一份失窃的研究数据。上层资本松了口气,CRC 的托管银行评级上调。
|
||||
news.story.lun_arrested.title,伦警官因滥用职权被捕
|
||||
news.story.lun_arrested.desc,治安部当场逮捕了滥用职权的伦警官,并表示接下来两周将从严查处各类违法交易。
|
||||
@@ -142,6 +142,7 @@ namespace Decentralized
|
||||
{
|
||||
var d = Session.Data;
|
||||
int day = StoreStation.GetDayCounter();
|
||||
StoryLinks.Night(d, day);
|
||||
var events = ActiveEvents();
|
||||
Log.Info($"夜间事件:{string.Join(",", events)}(新增 {string.Join(",", events.Where(e => !d.ActiveEvents.Contains(e)))}),黑市声望 {StoreReputation.GetBMReputation()}");
|
||||
bool wasSanctioned = d.Mixer.Sanctioned(day);
|
||||
@@ -307,10 +308,13 @@ namespace Decentralized
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>mod 新闻:不带价格修正的新闻事件,和原版新闻一样出现在报纸上。</summary>
|
||||
/// <summary>
|
||||
/// mod 新闻:不带价格修正的新闻事件,和原版新闻一样出现在报纸上。报纸按重要度排序、最多登 4 条,
|
||||
/// 游戏自己的事件重要度多在 4–7,mod 新闻默认 5 才不会总被挤掉;剧情联动用 9 登头版。
|
||||
/// </summary>
|
||||
public static class News
|
||||
{
|
||||
public static void Show(string id, string title, string text, int days)
|
||||
public static void Show(string id, string title, string text, int days, int importance = 5)
|
||||
{
|
||||
var mgr = StoreStation.Instance?.storeEventManager;
|
||||
if (mgr == null || mgr.IsEventActive(id)) return;
|
||||
@@ -318,7 +322,7 @@ namespace Decentralized
|
||||
{
|
||||
identifier = id, newsName = title, displayName = title, newsDescription = text,
|
||||
duration = days, eventType = StoreEvent.EventType.COSMETIC, eventArea = StoreEvent.EventArea.ALL,
|
||||
importance = 2, cooldown = 0, negociationDatas = new List<NegociationData>(),
|
||||
importance = importance, cooldown = 0, negociationDatas = new List<NegociationData>(),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,8 @@ namespace Decentralized
|
||||
public Scams Scams = new Scams();
|
||||
/// <summary>日 K 历史(PSC,Poinbase 主池价格)。</summary>
|
||||
public CandleBook Candles = new CandleBook();
|
||||
/// <summary>游戏剧情选择对本 mod 世界的影响。</summary>
|
||||
public StoryMods Story = new StoryMods();
|
||||
/// <summary>今天被伪造转账骗走的(晨间日志用):顾客名 + 信用点。</summary>
|
||||
public List<string> FakePaidToday = new List<string>();
|
||||
/// <summary>近几天的 gas 指数(每晚记明天的),情报线索里显示;最近一份局势简报。</summary>
|
||||
@@ -129,6 +131,8 @@ namespace Decentralized
|
||||
// 旧存档里的商家地址没有校验位:换成合法地址
|
||||
foreach (var s in Data.Black.Sellers) if (!ChainAddress.Valid(s.Name)) s.Name = ChainAddress.Make(Data.Rng.NextUInt());
|
||||
if (Data.Wallets.Count == 0) Data.AddWallet(false);
|
||||
if (Data.Story == null) Data.Story = new StoryMods();
|
||||
StoryMods.Current = Data.Story;
|
||||
Log.Info($"状态已载入(第 {Data.Day} 天,PSC {Data.Market.Price:0.00})");
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
using Decentralized.Domain;
|
||||
|
||||
namespace Decentralized
|
||||
{
|
||||
/// <summary>
|
||||
/// 剧情联动:每晚读游戏剧情线的选择(塞尔皮科的证据、埃莉诺的数据盘、伦警官被捕),每个选择只生效一次,
|
||||
/// 改动本 mod 世界的倍率(见 <see cref="StoryMods"/>),第二天报纸登一条新闻。选择是玩家自己做的,市场要过几天才反应完。
|
||||
/// 无尽模式关闭角色剧情线,这些选择不会出现。
|
||||
/// </summary>
|
||||
public static class StoryLinks
|
||||
{
|
||||
public static void Night(SaveData d, int day)
|
||||
{
|
||||
var data = PlayerStore.GetStoreClientData();
|
||||
if (data == null) return;
|
||||
switch (data.serpicoDocumentChoice)
|
||||
{
|
||||
case SerpicoStoryline.CHOICE_REVOLUTION: Apply(d, day, "serpico_rev"); break;
|
||||
case SerpicoStoryline.CHOICE_BLACK_MARKET: Apply(d, day, "serpico_bm"); break;
|
||||
case SerpicoStoryline.CHOICE_SECURITY: Apply(d, day, "serpico_sec"); break;
|
||||
}
|
||||
if (data.eleanorDriveChoice == 2) Apply(d, day, "eleanor_leak");
|
||||
else if (data.eleanorDriveChoice == 1) Apply(d, day, "eleanor_return");
|
||||
if (data.officerLunArrested) Apply(d, day, "lun_arrested");
|
||||
}
|
||||
|
||||
private static void Apply(SaveData d, int day, string key)
|
||||
{
|
||||
if (!d.Story.Apply(key, day)) return;
|
||||
if (key == "serpico_rev") d.Stable.CraSubsidy += Tuning.StoryRevSubsidy;
|
||||
News.Show("pd_news_story_" + key, L.T("news.story." + key + ".title"), L.T("news.story." + key + ".desc"), 4, 9);
|
||||
Log.Info($"剧情联动生效:{key}(第 {day} 天)");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -854,7 +854,7 @@ namespace Decentralized
|
||||
// 操纵:平仓盈利,而且盈利方向和玩家自己推价的方向一致,按推价幅度被查:盈利没收,记诈骗罪证,永续账户冻结几天
|
||||
double push = d.Market.PlayerPush, profit = paid - margin;
|
||||
bool aligned = _perpProduct == "PSC" && profit > 0 && (pos.Long ? push > 0 : push < 0);
|
||||
if (aligned && d.Rng.Chance(Market.ManipChance(push)))
|
||||
if (aligned && d.Rng.Chance(Math.Min(1, Market.ManipChance(push) * StoryMods.Current.Enforce(StoreStation.GetDayCounter()))))
|
||||
{
|
||||
int day = StoreStation.GetDayCounter();
|
||||
d.Poinbase.Add(Assets.CRC, -Math.Min(profit, d.Poinbase.Avail(Assets.CRC)));
|
||||
|
||||
@@ -1434,6 +1434,47 @@ internal static class Program
|
||||
Check(cb.Of("SPARK").Count == 0, "没有的币种是空的");
|
||||
});
|
||||
|
||||
Test("剧情联动:各选择的倍率与期限、只生效一次、SPARK 推涨", () =>
|
||||
{
|
||||
var saved = StoryMods.Current;
|
||||
try
|
||||
{
|
||||
var sm = new StoryMods(); StoryMods.Current = sm;
|
||||
Check(sm.Apply("serpico_sec", 50) && !sm.Apply("serpico_sec", 51), "只生效一次");
|
||||
Check(sm.Aml(60) == Tuning.StorySecAmlMult && sm.Aml(50 + Tuning.StorySecDays) == 1, "治安部整顿期内出金审查加重,到期恢复");
|
||||
Check(sm.Sanction(60) == Tuning.StorySecSanctionMult && sm.Enforce(60) == Tuning.StorySecEnforceMult, "制裁与查处倍率");
|
||||
sm.Apply("lun_arrested", 55);
|
||||
Check(Math.Abs(sm.Enforce(60) - Tuning.StorySecEnforceMult * Tuning.StoryLunMult) < 1e-12 && sm.Enforce(55 + Tuning.StoryLunDays) == Tuning.StorySecEnforceMult, "伦警官立威期叠加,先到期");
|
||||
// 出金审查真的变严
|
||||
var ex = new Exchange(); var ex2 = new Exchange();
|
||||
var w = new Wallet { Address = "p" }; w.Add(Assets.CRC, 10000); w.Taint = 3000;
|
||||
var w2 = new Wallet { Address = "p" }; w2.Add(Assets.CRC, 10000); w2.Taint = 3000;
|
||||
double hit = ex.Cashout(w, 2000, a => 1, 60, 300, false, new Rng(1)).HitChance;
|
||||
StoryMods.Current = new StoryMods();
|
||||
double hit0 = ex2.Cashout(w2, 2000, a => 1, 60, 300, false, new Rng(1)).HitChance;
|
||||
Check(hit > hit0 && hit <= 1, $"命中率 {hit0:0.000} → {hit:0.000}");
|
||||
// CRT 脱锚减半:镇压开始时脱锚的频率
|
||||
int dep0 = 0, dep1 = 0;
|
||||
for (ulong sd = 1; sd <= 2000; sd++)
|
||||
{
|
||||
StoryMods.Current = new StoryMods(); var s0 = new Stablecoins(); s0.OnEventStart(MarketEvent.Crackdown, 10, new Rng(sd)); if (s0.Crt < 1) dep0++;
|
||||
var bm = new StoryMods(); bm.Apply("serpico_bm", 1); StoryMods.Current = bm;
|
||||
var s1 = new Stablecoins(); s1.OnEventStart(MarketEvent.Crackdown, 10, new Rng(sd)); if (s1.Crt < 1) dep1++;
|
||||
}
|
||||
Check(dep1 < dep0 * 0.65 && dep1 > dep0 * 0.35, $"CRT 脱锚约减半:{dep0} → {dep1}");
|
||||
// SPARK 推涨:几晚内一共涨到设定倍数
|
||||
var rv = new StoryMods(); StoryMods.Current = rv; rv.Apply("serpico_rev", 10);
|
||||
Check(rv.CraSpiral(20) == Tuning.StoryCraSpiralMult, "螺旋概率减半");
|
||||
double prod = 1; for (int i = 0; i < 10; i++) prod *= rv.TakeSparkPush();
|
||||
Check(Math.Abs(prod - Tuning.StorySerpicoSpark) < 1e-9 && rv.SparkPushNights == 0, $"SPARK 推涨合计 {prod:0.000}");
|
||||
var lk = new StoryMods(); lk.Apply("serpico_rev", 1); lk.TakeSparkPush(); lk.Apply("eleanor_leak", 2);
|
||||
double p2 = 1; for (int i = 0; i < 10; i++) p2 *= lk.TakeSparkPush();
|
||||
Check(Math.Abs(p2 - Math.Pow(Tuning.StorySerpicoSpark, 1 - 1.0 / Tuning.StorySparkNights) * Tuning.StoryLeakSpark) < 1e-9, "两次推涨叠加");
|
||||
Check(lk.CrcHaircut == Tuning.StoryLeakHaircutMult, "泄露数据盘:CRC 减记概率翻倍");
|
||||
}
|
||||
finally { StoryMods.Current = saved; }
|
||||
});
|
||||
|
||||
Test("预测市场:先验概率", () =>
|
||||
{
|
||||
Check(Math.Abs(PredictMath.PurityAtLeast(8500, 8000, 8999) - 0.5) < 1e-9, "纯度 8500 以上一半");
|
||||
|
||||
Reference in new issue
Block a user