@@ -734,6 +734,23 @@ def _summon_goods(s, params):
734734 + (" 这种旧物已经揭秘,到货即修满。" if item .get ("pre_repaired" ) else "" ), before )
735735
736736
737+ def _exchange_resources (s , params ):
738+ if not any (e ["id" ] == "true_ending" for e in s .get ("endings" , [])):
739+ raise IllegalAction ("夜铺之外解锁后才能兑换星沙和声望" )
740+ resource , amount = params .get ("resource" ), params .get ("amount" )
741+ rates = {"stardust" : ("星沙" , 2 ), "reputation" : ("声望" , 1 )}
742+ if not isinstance (resource , str ) or resource not in rates or type (amount ) is not int or amount < 1 :
743+ raise IllegalAction ("resource 填 stardust 或 reputation,amount 填正整数" )
744+ label , rate = rates [resource ]
745+ if amount > s .get (resource , 0 ):
746+ raise IllegalAction (f"{ label } 不足,未兑换" )
747+ before = (s ["coins" ], s ["reputation" ])
748+ s [resource ] -= amount
749+ s ["coins" ] += amount * rate
750+ _log (s , s ["day" ], SHIFTS [s ["shift_index" ]], "exchange_resources" ,
751+ f"把{ amount } { '粒' if resource == 'stardust' else '点' } { label } 换成{ amount * rate } 枚古币,不占班次。" , before )
752+
753+
737754def _buy_sand (s , params ):
738755 if not _buy_sand_open (s ):
739756 raise IllegalAction ("收齐全部旧物图鉴(第七面墙)以后,才能用古币换星沙" )
@@ -979,7 +996,7 @@ def _collect(s, item):
979996]
980997TRUE_ENDING_SCENE = [
981998 "门铃响了。魔女莉莉丝站在门口,手里没有货。" ,
982- "她走过你的柜台,指尖轻轻拂过异物志。那些曾经修好的东西,有些早已被客人带走;可这一晚,你听见它们的声音从很远的地方回来。每一位来客,都在顾客簿上留下了自己的名字 。" ,
999+ "她走过你的柜台,指尖轻轻拂过异物志。那些曾经修好的东西,有些早已被客人带走;可这一晚,你听见它们的声音从很远的地方回来。顾客簿上的名字,在灯下泛起温暖的光 。" ,
9831000 "『我第一次来时,这里还是一间小铺子。』她看着你,笑了一下。『现在,迷路的东西知道该往哪里去了。』" ,
9841001 "她推开货架尽头那扇门。门后没有墙。一条幽蓝的隧道伸向深处,远处亮着许多窗。有一扇窗后,似乎也有人正在整理柜台。" ,
9851002 "莉莉丝把钥匙留在你手里。『恭喜,店主。你可以过去看看。』她替你扶住门,又回头看了一眼还亮着灯的铺子。『也可以先把今晚的生意做完。』" ,
@@ -1063,11 +1080,10 @@ def _check_endings(s):
10631080 codes = [row [0 ] for row in ITEMS ] # ITEMS 是元组列表,按编号比
10641081 discovered = all (code in s ["collection" ] for code in codes )
10651082 revealed = discovered and all (s ["collection" ][code ]["revealed" ] for code in codes )
1066- guests = all (customer [0 ] in s ["customer_book" ] for customer in CUSTOMERS )
10671083 unlocked = False
10681084 for key , ready , title , reward , pages in (
10691085 ("collection" , discovered , "第七面墙" , "没有背面的店主铭牌" , COLLECTION_SCENE ),
1070- ("true_ending" , revealed and guests , "夜铺之外" , "通往亚空间的钥匙" , TRUE_ENDING_SCENE ),
1086+ ("true_ending" , revealed , "夜铺之外" , "通往亚空间的钥匙" , TRUE_ENDING_SCENE ),
10711087 ("grand_slam" , None , "万灯送行" , GRAND_SLAM_REWARD , GRAND_SLAM_SCENE ),
10721088 ):
10731089 if key == "grand_slam" : # 前两座奖杯都到手(可能就在这一步),七十二句话都说出口
@@ -1127,6 +1143,10 @@ def new_game(seats, seed):
11271143
11281144
11291145def _spawn_customer (s ):
1146+ if s ["shift_index" ] == LAST_SHIFT :
1147+ # 深夜行动之后已经没有可接待的班次,下一位等跨日后再入店、计到访。
1148+ s ["customer" ] = None
1149+ return
11301150 pool = [c for c in CUSTOMERS
11311151 if s ["customer_book" ].get (c [0 ], {}).get ("visits" , 0 ) < MAX_CUSTOMER_VISITS
11321152 and not s ["customer_book" ].get (c [0 ], {}).get ("farewell" )
@@ -1145,7 +1165,7 @@ def _spawn_customer(s):
11451165 "visits" : 0 , "deals" : 0 , "trust" : 0 ,
11461166 "neighbor" : set (s ["unlocked_locations" ]) <= NEIGHBOR_LOCATIONS })
11471167 row ["visits" ] += 1
1148- if (row .get ("neighbor" , True ) or cid in SPECIAL_CUSTOMERS
1168+ if (clue is None or row .get ("neighbor" , True ) or cid in SPECIAL_CUSTOMERS
11491169 or row ["visits" ] >= REGULAR_VISITS ):
11501170 row ["request" ] = request
11511171 request = row ["request" ]
@@ -1166,9 +1186,9 @@ def _public_item(item):
11661186 return view
11671187
11681188
1169- CUSTOMER_HINT = ("新手提示:客人只认旧物的「类别」(每件旧物都标着,比如陪伴、照明),不看名字和故事像不像 。"
1170- "从客人说的要求猜他要哪一两类;远方来的生客不直说要什么,只能从线索猜,来过四次成了熟客才会直说; "
1171- "本局开头就来过的老街坊一直直说。类别对上才会买;手上没有对的类别,就送客(dismiss,不另收费),等下一位客人 。" )
1189+ CUSTOMER_HINT = ("经营提示:普通客人按旧物类别购买;线索暗示的是能触发个人故事的那一件,修满后交付有额外回馈 。"
1190+ "无对应旧物的客人直接说明收货类别;有线索的远方生客第五次起直说类别,老街坊一直直说。 "
1191+ "特殊客人只收点名的那一件。库存缺合适的货可主动淘货;送客会消耗一次有限到访机会 。" )
11721192
11731193
11741194def _is_open (s ):
@@ -1185,11 +1205,13 @@ def _waiting_item(s, cid):
11851205
11861206def _customer_view (row , cid ):
11871207 view = {key : deepcopy (value ) for key , value in row .items () if not key .startswith ("_" )}
1188- clue = next (c [3 ] for c in CUSTOMERS if c [0 ] == cid )
1208+ template = next (c for c in CUSTOMERS if c [0 ] == cid )
1209+ clue = template [3 ]
11891210 if clue :
11901211 view ["clue" ] = clue
11911212 else :
11921213 view .pop ("clue" , None )
1214+ view ["request" ] = template [2 ]
11931215 return view
11941216
11951217
@@ -1278,6 +1300,9 @@ def _legal_actions(s):
12781300 if _buy_sand_open (s ):
12791301 actions .append ({"action_id" : "summon_goods" , "params" : {
12801302 "code" : "图鉴collection.entries中的code;99枚古币指定召来一件旧物,不占班次,需要货架空位" }})
1303+ if any (e ["id" ] == "true_ending" for e in s .get ("endings" , [])):
1304+ actions .append ({"action_id" : "exchange_resources" , "params" : {
1305+ "resource" : ["stardust" , "reputation" ], "amount" : "正整数;每粒星沙换2古币,每点声望换1古币,不占班次" }})
12811306 if s .get ("apple_pending" ):
12821307 actions .append ({"action_id" : "golden_apple" , "params" : {"choice" : _apple_text (s )}})
12831308 if s .get ("scroll" ):
@@ -1324,6 +1349,8 @@ def observe(full_state, seat_id):
13241349 for cid , row in s ["customer_book" ].items ()],
13251350 ** ({"summon_goods" : "货物飞来已解锁:summon_goods {\" code\" :\" 图鉴编号\" },99古币指定召货,不占班次;需要货架空位" }
13261351 if _buy_sand_open (s ) else {}),
1352+ ** ({"exchange_resources" : "通关兑换:exchange_resources {\" resource\" :\" stardust或reputation\" ,\" amount\" :数量};1星沙换2古币,1声望换1古币,不占班次" }
1353+ if any (e ["id" ] == "true_ending" for e in s .get ("endings" , [])) else {}),
13271354 "customer_collection" : {"found" : len (s ["customer_book" ]), "total" : len (CUSTOMERS ),
13281355 "visit_limit" : MAX_CUSTOMER_VISITS ,
13291356 "retired" : sum (row ["visits" ] >= MAX_CUSTOMER_VISITS
@@ -1551,6 +1578,8 @@ def apply(full_state, seat_id, action_id, params):
15511578 _buy_sand (s , params )
15521579 elif action_id == "summon_goods" :
15531580 _summon_goods (s , params )
1581+ elif action_id == "exchange_resources" :
1582+ _exchange_resources (s , params )
15541583 elif action_id == "golden_apple" :
15551584 _golden_apple (s , params )
15561585 elif action_id == "sand_repair" :
@@ -1712,6 +1741,8 @@ def _work_shift(s, params):
17121741 elif c and c .setdefault ("_arrived_day" , s ["day" ] - 1 ) + CUSTOMER_WAIT_DAYS <= s ["day" ]:
17131742 report += f" { c ['name' ]} 等了三天,没等到合适的东西,走了。"
17141743 _spawn_customer (s )
1744+ elif c is None :
1745+ _spawn_customer (s )
17151746 report += " " + _day_summary (s , day )
17161747 if dream : # 梦单独起一行放在最后,别埋在打烊流水里
17171748 report += "\n 【夜里的梦】" + dream + (" (用 map 看看新出现的地方。)" if s ["dreams" ] >= 3 else "" )
@@ -1921,7 +1952,9 @@ def _do_focus(s, params, flags):
19211952 if focus == "dismiss" :
19221953 name = s ["customer" ]["name" ]
19231954 _spawn_customer (s )
1924- return f"向{ name } 说明暂时无货,记下需求送客。" + ("另一位客人进门。" if s ["customer" ] else "眼下没有新的来客,店铺仍可经营。" )
1955+ return f"向{ name } 说明暂时无货,记下需求送客。" + (
1956+ "深夜将尽,下一位客人待打烊后再安排。" if s ["shift_index" ] == LAST_SHIFT else
1957+ "另一位客人进门。" if s ["customer" ] else "眼下没有新的来客,店铺仍可经营。" )
19251958 if focus == "curate" :
19261959 item ["displayed" ] = True
19271960 s ["reputation" ] += 1
0 commit comments