-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path蟹脚小游戏.js
2642 lines (2334 loc) · 87.1 KB
/
蟹脚小游戏.js
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// ==UserScript==
// @name 蟹脚小游戏
// @author 错误
// @version 2.2.1
// @description 使用指令.cult查看游戏指引,使用指令.cult master查看骰主指令\n经验值获得:翻垃圾;遭遇警察,神话生物;强行越狱成功;献祭成功;还有抢劫,战胜等级高的对手可获得更多;\n贡献值:贡献值越高发展信众获得的货币就越高;达到一定上限,献祭成功后可晋升职位;\n职位:职位越高发展信众获得的贡献度越高\n抢劫:成败和等级,武器数值挂钩,同时具有随机性;\n市场目前在买卖多几次后,各地物价会逐渐持平
// @timestamp 1717065841
// 2024-05-30 18:44:01
// @license MIT
// @homepageURL https://github.com/error2913/sealdice-js/
// @updateUrl https://raw.githubusercontent.com/error2913/sealdice-js/main/%E8%9F%B9%E8%84%9A%E5%B0%8F%E6%B8%B8%E6%88%8F.js
// ==/UserScript==
// 首先检查是否已经存在
//部分指令参考了星界佬佬的诡秘游戏,虽然已经看不清形状了
let ext = seal.ext.find('蟹脚小游戏');
if (!ext) {
// 不存在,那么建立扩展
ext = seal.ext.new('蟹脚小游戏', '错误', '2.2.1');
// 注册扩展
seal.ext.register(ext);
seal.ext.registerIntConfig(ext, "指令间隔/s(抢劫)", 30)
seal.ext.registerIntConfig(ext, "指令间隔/s(前往)", 30)
seal.ext.registerIntConfig(ext, "指令间隔/s(逛逛)", 30)
seal.ext.registerIntConfig(ext, "指令间隔/s(强行越狱)", 60)
seal.ext.registerIntConfig(ext, "指令间隔/s(交易)", 20)
seal.ext.registerIntConfig(ext, "逮捕时间/s", 180)
seal.ext.registerIntConfig(ext, "精神病院时间/s", 600)
seal.ext.registerIntConfig(ext, "迷路概率%", 20)
seal.ext.registerIntConfig(ext, "越狱概率%", 50)
seal.ext.registerIntConfig(ext, "献祭概率%", 40)
seal.ext.registerIntConfig(ext, "最大抢夺率%", 50)
seal.ext.registerIntConfig(ext, "罚款率%", 20)
seal.ext.registerIntConfig(ext, "价格调整幅度因子", 100)
seal.ext.registerTemplateConfig(ext, "地点列表", ["阿卡姆", "金斯波特", "印斯茅斯", "南极营地", "拉莱耶", "乌撒", "无名之城"], '修改后请重载')
const lead = `游戏指引:
今日商店、查看背包、个人信息、
武器商店、发展信众、教团信息、
买武器、翻垃圾、排行榜、前往、
注销、购入、售出、逛逛、抢劫、
情报、行情、散播、丢弃、改名、
献祭、使用、转账、送`
const players = {}
const places = {}
const cults = {}
const playerlist = JSON.parse(ext.storageGet("playerlist") || '{}')
const use = JSON.parse(ext.storageGet("use") || '{}')
const priceUpdCache = {}
//所有地点和教团的一个数组
const placelist = seal.ext.getTemplateConfig(ext, "地点列表")
const cultlist = ["大衮密令教", "黄印兄弟会", "银色暮光密教", "血腥之舌", "不灭之炎的奴仆"]
//教团对应的邪神
const cultgods = {
"大衮密令教": ["父神大衮", "母神海德拉", "天父克苏鲁"],
"黄印兄弟会": ["黄衣之王哈斯塔"],
"银色暮光密教": ["克苏鲁", "犹格索托斯", "奈亚拉托提普"],
"血腥之舌": ["奈亚拉托提普"],
"不灭之炎的奴仆": ["活火焰克图格亚"]
}
//衣服颜色
const level = {
"灰": 250,
"蓝": 1000,
"红": 2500,
"黑": 5000,
"紫": 10000,
"白": 15000,
"金": 20000
}
//一些文本
let cultText = ""
for (let cult of cultlist) { cultText += cult + "、" }
cultText = cultText.slice(0, -1)
let placeText = ""
for (let place of placelist) { placeText += place + "、" }
placeText = placeText.slice(0, -1)
//货物列表
const goodlst = [
{ p: 1, max: 22, min: 20, weight: 40, lst: ["手电筒", "提灯", "土豆", "皮下注射器", "阿司匹林", "女士内衣", "男士内裤", "婴儿奶嘴", "防水火柴", "致死镜", "米纳尔的星石", "羊皮纸"] },
{ p: 1, max: 115, min: 100, weight: 35, lst: ["铅蓄电池", "留声机唱片", "胶卷", "警用手铐", "潜水服", "医用威士忌", "黄铜头像", "瑟德夫卡之像", "梦境结晶器", "书写专用血液"] },
{ p: 0.9, max: 900, min: 750, weight: 15, lst: ["灵魂精盐", "医用血包", "雷明顿牌打字机", "11.43mm自动手枪子弹", "雪茄", "翡翠小像", "盖尔之镜", "月之透镜"] },
{ p: 0.5, max: 6500, min: 5000, weight: 2, lst: ["夏塔克鸟蛋", "缸中之脑", "黄金蜂蜜酒", "伊波恩戒指", "格拉基启示录残卷", "银之匙", "透特的匕首"] },
{ p: 0.2, max: 46875, min: 31250, weight: 1, lst: ["不明的乳汁", "奇怪多面体", "阿尔哈兹莱德之灯", "拉莱耶圆盘"] },
{ p: 0.06, max: 4687500, min: 2343750, weight: 0, lst: ["光辉的偏方三八面体"] }
]
//武器列表
const weaponlst = {
"弓箭": 20, "黄铜指虎": 20, "长鞭": 15, "燃烧的火把": 20, "电锯": 40, "甩棍": 30, "大头棍": 30, "护身棒": 30,
"棒球棍": 30, "板球棒": 30, "拨火棍": 30, "警棍": 20, "弩": 30, "绞具": 40, "手斧": 30, "镰刀": 30, "甘蔗刀": 30, "切肉菜刀": 30, "弹簧折叠刀": 20, "220v通电导线": 45,
"催泪瓦斯": 5, "双节棍": 30, "投石": 15, "手里剑": 15, "矛": 25, "骑士长枪": 25, "投矛": 25, "马刀": 35, "佩剑": 30, "重剑": 30, "花剑": 20, "剑杖": 20, "电棍": 15, "电击枪": 15,
"战斗回力镖": 25, "伐木斧": 35, "燧发枪": 20, "5.6mm小型自动手枪": 15, "6.35mm短口手枪": 15, "7.65mm左轮手枪": 20, "7.65mm自动手枪": 20,
"马格南左轮": 30, "9mm左轮手枪": 25, "9mm自动手枪": 25, "贝瑞塔M9": 25, "9mm格洛克17": 25, "9mm鲁格P08": 25, "10.4mm左轮手枪": 25,
"11.2mm马格南左轮手枪": 45, "11.43mm左轮手枪": 35, "11.43mm自动手枪": 35, "IMI沙漠之鹰": 55, "14.7mm春田步枪": 45,
"5.6mm栓式枪机步枪": 20, "7.62mm杠杆式枪机步枪": 30, "马提尼·亨利步枪": 50, "莫兰上校的气动步枪": 35, "加兰德M1步枪": 50, "加兰德M2步枪": 50,
"SKS半自动步枪": 35, "7.7mm李·恩菲尔德": 50, "7.62mm栓式枪机步枪": 50, "7.62mm半自动步枪": 50, "11.28mm马林步枪": 60,
"猎象枪": 65, "20号霰弹枪": 30, "16号霰弹枪": 40, "12号霰弹枪": 60, "12号霰弹枪": 60, "10号霰弹枪": 70,
"12号贝里尼M3": 60, "12号SPAS": 60, "AKM": 35, "AK-74": 35, "巴雷特M82": 100,
"FN-FAL": 80, "加利尔突击步枪": 60, "M16A2": 60, "M4": 60, "斯泰尔AUG": 60, "贝雷塔M70": 60, "MP18I": 25, "MP28II": 25, "MP5": 25, "MAC-11": 25,
"蝎式冲锋枪": 20, "汤普森冲锋枪": 35, "乌兹微型冲锋枪": 25, "1882年式加特林": 80, "M1918式勃朗宁自动步枪": 80, "勃朗宁M1917A1": 80,
"布伦轻机枪": 80, "路易斯Ⅰ型机枪": 80, "GE-M134式7.62mm速射机枪": 80, "FN米尼米": 60, "维克斯.303机枪": 80,
"莫洛托夫燃烧瓶": 65, "信号弹枪": 40, "M79-40mm榴弹发射器": 75,
"81mm迫击炮": 150, "75mm野战火炮": 250, "120mm坦克炮": 250, "5英寸舰载炮": 375, "火焰喷射器": 65, "M72式单发轻型反坦克炮": 200
}
//载具列表
const carlst = {
"二手别克": 75, "诺顿摩托车": 95, "二手雪佛兰 F.B. 轿车": 300, "福特 T 型车": 360, "福特 A 型车": 450, "福特 TT 卡车": 490,
"法国雷诺 AX": 500, "雪佛兰皮卡": 545, "雪佛兰敞篷车": 570, "雪佛兰 Capitol": 695, "庞帝克 6-28": 745,
"法国雪铁龙 C3": 800, "道奇 S/1": 985, "斯图贝克独裁者": 995, "斯图贝克房车": 995,
"别克 D-45": 1020, "克莱斯勒 F-58": 1045, "道奇半吨小卡车": 1085, "德国宝马迪克西": 1225, "奥兹摩比 43-AT": 1345, "哈德森面包车": 1450, "哈德孙 Super Six": 1750,
"凯迪拉克 55": 2240, "帕卡德双六缸房车": 2950, "西班牙希斯帕诺- 苏扎 阿方索": 4000, "意大利蓝旗亚 兰姆达214": 4050, "皮尔斯箭": 6000, "英国劳斯莱斯:银魅": 6750,
"德国梅塞迪斯- 奔驰 SS": 7750, "英国宾利 3 升型": 9000, "英国劳斯莱斯:幻影Ⅰ型": 10800, "杜森堡 J 型车": 20000
}
//神话生物列表
const myths = [
"食尸鬼", "古老者", "恐怖猎手", "空鬼",
"蛇人", "深潜者", "修格斯", "星之彩",
"炎之精", "钻地魔虫", "拜亚基", "蠕行者",
"黑山羊幼崽", "飞天水螅", "廷达罗斯猎犬", "米戈",
"夏盖虫族", "星之眷属", "无形之子"
]
//神话生物前缀
const mythwords = [
"正在觅食的", "不可名状的", "完全无害的", "忸怩作态的",
"悄无声息的", "狂暴无比的", "优雅飘逸的", "笨拙可爱的",
"神秘莫测的", "慢吞吞的", "迅速闪电的", "悲伤落泪的",
"愤怒咆哮的", "喜悦洋溢的", "好奇探索的", "疯狂狂乱的",
"慎重考虑的", "大胆无畏的", "恐惧颤抖的", "勇敢无畏的",
"狡猾多诈的", "忠诚不渝的", "胆小怕事的", "坚定不移的",
"犹豫不决的", "冷静自若的", "热情奔放的", "冷漠无情的",
"激动万分的", "平静如水的", "悠闲自得的", "紧张兮兮的",
"专注致志的", "分心忘我的", "愚蠢无知的", "聪明伶俐的",
"懒散无力的", "勤奋努力的", "贪婪无厌的", "慷慨大方的",
"自私自利的", "无私奉献的", "虚荣心强的", "谦逊低调的",
"傲慢自大的", "谨慎小心的", "鲁莽冲动的", "快乐欢喜的",
"悲观失望的", "乐观向上的", "顽固不化的", "灵活多变的",
"随意随性的"
]
const views = [
"图书馆", "森林", "祭坛", "教堂",
"沙漠", "遗迹", "废弃小屋", "洞穴",
"剧院", "墓地", "医院", "工厂",
"学校", "码头", "矿井", "城堡",
"实验室",
]
const viewwords = ["废弃的", "黑暗的", "古老的", "荒凉的", "暴风雨中的", "幽暗的"]
const viewfounds = [
"一本{{word}}书籍,书中记载着关于人类智慧的深刻见解",
"一位{{word}}吟游诗人,他为你演奏了一首治愈心灵的乐曲",
"一幅{{word}}壁画,壁画中的光芒照亮了你的内心",
"一只{{word}}海龟,它缓慢而沉稳的游动让你感到时间的流逝变得缓慢",
"一片{{word}}绿洲,清澈的泉水和茂密的植被让你感到生命的奇迹",
"一面{{word}}镜子,镜中的自己显得格外平静和自信",
"一颗{{word}}宝石,宝石的光芒照亮了你的内心",
"一台{{word}}留声机,播放的音乐让你感到时光倒流",
"一瓶{{word}}镇静剂,服用后感到内心的焦虑逐渐平息",
"一台{{word}}收音机,播放的广播让你感到与外界的联系",
"一棵{{word}}古树,树下的宁静让你感到内心的平静",
"一艘{{word}}船只,船上的航海日志让你感到冒险的激情",
"一颗{{word}}水晶,水晶的光芒照亮了你的内心",
]
const viewfoundwords = ["古老的", "神秘的", "刻有祝福符文的", "巨大的", "温暖的", "发光的", "老旧的"]
class Player {
constructor(id, name) {
this.id = id;
this.name = name;
this.cult = cultlist[Math.floor(Math.random() * cultlist.length)];
this.place = placelist[Math.floor(Math.random() * placelist.length)];
this.car = '二手别克';
this.weapon = '催泪瓦斯';
this.goods = { "土豆": 20 };
this.san = Math.floor(Math.random() * (80 - 40 + 1)) + 40;
this.down = 0;
this.money = 100;
this.contr = 0;
this.color = '无'
this.exp = 0;
this.missionDate = '';
this.time = {
movTime: 0,
strollTime: 0,
healTime: 0,
robTime: 0,
arrestTime: 0,
escTime: 0,
tradeTime: 0
};
}
// 从存储中获取数据并初始化玩家对象
static getData(id) {
try {
let idData = JSON.parse(ext.storageGet(id) || '{}');
let player = new Player(id, idData.name)
player.cult = idData.cult
player.place = idData.place
player.car = idData.car
player.weapon = idData.weapon
player.goods = idData.goods
player.san = idData.san
player.down = idData.down
player.money = idData.money
player.contr = idData.contr
player.color = idData.color
player.exp = idData.exp
player.missionDate = idData.missionDate
players[id] = player
} catch (error) {
console.error(`Failed to initialize ${id}:`, error);
}
}
// 保存玩家数据到存储
saveData() {
ext.storageSet(this.id, JSON.stringify(this));
}
movPlace(dest) {
let place = this.place
if (places.hasOwnProperty(place)) {
places[place].members = places[place].members.filter(item => item !== this.id)
places[place].saveData()
}
if (places.hasOwnProperty(dest)) {
places[dest].members.push(this.id)
places[dest].saveData()
}
this.place = dest
this.saveData()
}
movCult(dest) {
let cult = this.cult
if (cults.hasOwnProperty(cult)) {
cults[cult].members = cults[cult].members.filter(item => item !== this.id)
cults[cult].saveData()
}
if (cults.hasOwnProperty(dest)) {
cults[dest].members.push(this.id)
cults[dest].saveData()
}
this.cult = dest
this.color = '灰'
this.contr = 0
this.saveData()
}
//把钱从第一个人抢给第二个人,返回抢到的数字
robMoneyTo(altid) {
let maxrob = seal.ext.getIntConfig(ext, "最大抢夺率%") / 100
let lostmoney = Math.ceil(Math.random() * this.money * maxrob)
this.money -= lostmoney
players[altid].money += lostmoney
return lostmoney;
}
/** 将num数量的货物添加到背包,返回溢出数量*/
addGood(good, num) {
let space = carlst[this.car]
let goodsnum = 0
for (let good in this.goods) goodsnum += this.goods[good]
let outnum = goodsnum + num - space
//货物是否溢出
if (outnum > 0) {
num -= outnum
//增加落魄值作为补偿
this.down += outnum / 10
this.down = parseFloat(this.down.toFixed(1));
} else outnum = 0
if (num > 0) {
if (!this.goods.hasOwnProperty(good)) this.goods[good] = num
else this.goods[good] += num
}
this.saveData()
return outnum;
}
/** 把num数量的货物从背包去除,返回bool*/
takeGood(good, num) {
if (!this.goods.hasOwnProperty(good) || this.goods[good] < num) return false;
this.goods[good] -= num;
if (this.goods[good] <= 0) delete this.goods[good];
this.saveData()
return true;
}
//把货物抢给另一个人,这里老是出bug,抢的都是写什么undefined*NaN啦、啥都没有*null啦 #死掉
robGoodsTo(altid) {
let maxrob = seal.ext.getIntConfig(ext, "最大抢夺率%") / 100
//计算货物数量
let goodsnum = 0
for (let good in this.goods) goodsnum += this.goods[good]
let lostlst = {}
let drawtime = Math.ceil(Math.random() * goodsnum * maxrob)
//按权重抽取至少一个货物
for (let i = 0; i < drawtime; i++) {
let ran = Math.ceil(Math.random() * goodsnum)
let tmpsum = 0
//抽取种类
for (let good in this.goods) {
tmpsum += this.goods[good]
if (ran <= tmpsum) {
this.takeGood(good, 1)
lostlst[good] = (lostlst[good] || 0) + 1
goodsnum -= 1
break;
}
}
}
//把货物加给第二个人并输出文本
let text = ``
for (let good in lostlst) {
let outnum = players[altid].addGood(good, lostlst[good])
if (outnum > 0) this.addGood(good, outnum)
let num = lostlst[good] - outnum
text += num > 0 ? `${good}×${num}、` : ``
}
if (!text) return `车装不下了`
return text.slice(0, -1);
}
//抢劫:发起对另一个人的抢劫
rob(altid) {
let place = this.place
let altplace = players[altid].place
let weapon1 = this.weapon
let weapon2 = players[altid].weapon
let val1 = weaponlst[weapon1] / 5
let val2 = weaponlst[weapon2] / 5
let lv1 = this.getLv()[0]
let lv2 = players[altid].getLv()[0]
let ran1 = Math.floor(Math.random() * 100)
let ran2 = Math.floor(Math.random() * 100)
let text = `在${players[altid].place}
${this.name}(Lv${lv1})=>${players[altid].name}(Lv${lv2})
${weapon1}(${val1 * 5}) vs ${weapon2}(${val2 * 5})\n`
//位置不对
if (place !== altplace) {
let missText = this.ckMiss(altplace)
if (missText) return missText
else this.movPlace(altplace)
}
//赢
if (ran1 + lv1 + val1 >= ran2 + lv2 + val2) {
this.exp += lv1 < lv2 ? lv2 - lv1 + 1 : 1
players[altid].exp += 1
let goodsnum = 0
for (let good in players[altid].goods) goodsnum += players[altid].goods[good]
text += `抢劫成功!\n`
//抢钱
if (players[altid].money <= 0) text += `对方钱包空空\n`
else text += `抢走了$ ${players[altid].robMoneyTo(this.id)}\n`
//抢货
if (goodsnum > 20) text += players[altid].robGoodsTo(this.id)
}
//输
else {
players[altid].exp += lv1 > lv2 ? lv1 - lv2 + 1 : 1
this.exp += 1
let goodsnum = 0
for (let good in this.goods) goodsnum += this.goods[good]
text += `抢劫失败!\n`
//抢钱
if (this.money <= 0) text += `你钱包空空\n`
else text += `被抢走了$ ${this.robMoneyTo(altid)}\n`
//抢货
if (goodsnum > 20) text += this.robGoodsTo(altid)
}
this.saveData()
return text;
}
//修改san值并判断,返回文本
stSan(now, num) {
//修改san值
this.san += num
let maxheal = 0.8
let text = ``
if (num >= 0) text = `san+${num}=>${this.san}`
else text = `san${num}=>${this.san}`
if (this.san <= 0) {
let lostmoney = Math.ceil(Math.random() * this.money * maxheal)
lostmoney = lostmoney < 500 ? 500 : lostmoney
let healInterval = seal.ext.getIntConfig(ext, "精神病院时间/s")
this.time.healTime = now
this.san += Math.floor(Math.random() * (80 - 40 + 1)) + 40;
this.money -= lostmoney
text += `\nsan值小于零!精神崩溃!被抓进${this.place}精神病院${healInterval}秒,扣除医疗费用$ ${lostmoney}。\nsan值=>${this.san}\n货币=>$ ${this.money}`
}
else if (this.san <= 20) {
text += `\n警告!精神不稳定!`
}
else if (this.san > 100) {
text += "\n哟哈!精神满溢!"
this.san = 100
}
this.saveData()
return text;
}
//检查指令,返回Bool
ckCmd(ctx, msg, ckHeal = true, ckArrest = true) {
const now = parseInt(seal.format(ctx, "{$tTimestamp}"))
let healInterval = seal.ext.getIntConfig(ext, "精神病院时间/s")
let arrestInterval = seal.ext.getIntConfig(ext, "逮捕时间/s")
let text = ``
if (ckHeal) {
let t = now - this.time.healTime
if (t < healInterval) {
text = `<${this.name}>在精神病院无力地嘶吼着,治疗结束还有${healInterval - t}!`
}
}
if (ckArrest) {
let t = now - this.time.arrestTime
if (t < arrestInterval) {
text = `<${this.name}>在越狱中,还有${arrestInterval - t}秒就可以逃出来了!`
}
}
if (text) {
seal.replyToSender(ctx, msg, text)
return true
} else return false
}
//翻垃圾时间~翻一次、返回一段文本
rubbish() {
this.down -= 6
this.down = parseFloat(this.down.toFixed(1));
this.exp += 1
let ran = Math.random()
let text = ``
//翻到货物
if (ran <= 0.85) {
let ran = Math.random()
let good
let num = 0
//按权重概率抽取
let sumW = 0
for (let i = 0; i < goodlst.length; i++) sumW += goodlst[i].weight
let tmpW = 0
for (let i = 0; i < goodlst.length; i++) {
tmpW += goodlst[i].weight
if (ran <= tmpW / sumW) {
let goods = goodlst[i].lst
good = goods[Math.floor(Math.random() * goods.length)]
num = Math.ceil(Math.random() * goodlst[i].weight)
break;
}
}
let outnum = this.addGood(good, num)
text = `${good}×${num}${outnum > 0 ? `,溢出${outnum}件` : ``}`
}
//翻到回san道具
else if (ran <= 0.95) {
let good = '圣水'
let num = 1
let outnum = this.addGood(good, num)
text = `${good}×${num}${outnum > 0 ? `,溢出${outnum}件` : ``}`
}
//翻到车
else {
let formercar = this.car
let cars = Object.keys(carlst)
let car = cars[Math.floor(Math.random() * cars.length)]
if (carlst[this.car] > carlst[car]) {
this.money += carlst[car]
text = `一台${car}!卖掉赚了$ ${carlst[car]}!`
}
else {
this.car = car
text = `一台${car}!原来的${formercar}就丢到垃圾堆里吧。`
}
}
this.saveData()
return text;
}
ckMiss(altplace) {
let text = ``
if (Math.random() * 100 <= seal.ext.getIntConfig(ext, "迷路概率%")) {
let newplace
let place = this.place
do newplace = placelist[Math.floor(Math.random() * placelist.length)]
while (newplace == place || newplace == altplace)
this.movPlace(newplace)
text = `<${this.name}>迷路了!走着走着竟然到了${newplace}!\n`
}
return text
}
meetMyth(now) {
let lostsan = Math.ceil(Math.random() * 6)
let view = views[Math.floor(Math.random() * views.length)]
let viewword = viewwords[Math.floor(Math.random() * viewwords.length)]
let myth = myths[Math.floor(Math.random() * myths.length)]
let mythword = mythwords[Math.floor(Math.random() * mythwords.length)]
this.exp += 1
return `在${this.place},${viewword + view}\n<${this.name}>遇到了${mythword}${myth}!\n${this.stSan(now, -lostsan)}`
}
meetOther(ctx, msg) {
let members = places[this.place].members
let altid
do altid = members[Math.floor(Math.random() * members.length)]
while (altid == this.id && members.length > 1)
if (players[altid].ckCmd(ctx, msg)) return;
return `遭遇了抢劫!\n${this.rob(altid)}`
}
meetPolice(now) {
let arrestInterval = seal.ext.getIntConfig(ext, "逮捕时间/s")
let fine_p = seal.ext.getIntConfig(ext, "罚款率%") / 100
let fine = Math.floor(this.money * fine_p)
let goods = Object.keys(this.goods)
let good = goods[Math.floor(Math.random() * goods.length)]
let num = Math.ceil(this.goods[good] * fine_p)
this.exp += 1
this.money -= Math.max(fine, 0)
this.down += 10
this.time.arrestTime = now
this.takeGood(good, num)
let reason = goods.length > 0 ? `检查出车上有${good},没收${good}×${num}!` : ``
let fineText = fine > 0 ? `货币-$ ${fine}` : ``
return `在${this.place}
<${this.name}>遇到了警察,被抓起来了!但作为一名教徒,越狱只需${arrestInterval}秒!
${reason}
落魄值+10=>${this.down}
${fineText}`
}
meetView(now) {
let addsan = Math.ceil(Math.random() * 6)
let view = views[Math.floor(Math.random() * views.length)]
let viewword = viewwords[Math.floor(Math.random() * viewwords.length)]
let viewfound = viewfounds[Math.floor(Math.random() * viewfounds.length)]
let viewfoundword = viewfoundwords[Math.floor(Math.random() * viewfoundwords.length)]
return `在${this.place},${viewword + view}\n<${this.name}>遇到了${viewfound.replace('{{word}}', viewfoundword)}\n${this.stSan(now, addsan)}`
}
meet(now, ctx, msg) {
if (!placelist.includes(this.place)) this.movPlace(placelist[Math.floor(Math.random() * placelist.length)])
let members = places[this.place].members
let ran = Math.random()
if (members.length > 1 && ran <= 0.3) return this.meetOther(ctx, msg)
else if (ran <= 0.6) return this.meetMyth(now)
else if (ran <= 0.9) return this.meetPolice(now)
else return this.meetView(now)
}
getLv() {
let expLimit = 10
let lv = 1
while (this.exp >= expLimit) {
lv += 1
expLimit += lv * 10
}
return [lv, expLimit]
}
colorUp() {
let color = this.color
let text = ``
if (this.contr >= level[color]) {
let colors = Object.keys(level)
let index = colors.indexOf(color)
if (index == colors.length - 1) text = `已达到最高位阶\n`
else {
this.color = colors[index + 1]
text = `晋升至${this.color}衣\n`
}
}
return text;
}
/**使用货物,返回文本*/
useGood(good, num, now) {
if (good == "圣水") {
if (!this.takeGood('圣水', num)) return `没有此物品或物品数量不足`
return `<${this.name}>使用了${good}×${num}\n${this.stSan(now, 10 * num)}`
}
if (Object.keys(weaponlst).includes(good)) {
let formerweapon = this.weapon
this.weapon = good
if (!this.takeGood(good, 1)) return `没有此物品或物品数量不足`
this.addGood(formerweapon, 1)
return `<${this.name}>更换了武器\n${formerweapon}=>${good}`
}
if (Object.keys(use).includes(good)) {
if (!this.takeGood(good, num)) return `没有此物品或物品数量不足`
return use[good]
}
return `无法使用${good}`
}
/**发展信众 */
mission(date) {
if (this.missionDate == date) return `<${this.name}>今天的传单已经派完了`
let increase = Math.floor(Math.random() * (150 - 100 + 1)) + 100
increase *= Object.keys(level).indexOf(this.color) / 10 + 1
increase = Math.floor(increase)
let moneyincrease = this.contr * (Math.floor(Math.random() * (15 - 5 + 1)) + 5)
this.missionDate = date
this.contr += increase
this.money += moneyincrease
this.saveData()
return `在${this.place}\n<${this.name}>发展了${increase}个信众。\n贡献度=>${this.contr}\n货币+$ ${moneyincrease}=>$ ${this.money}`
}
/**获取货物推荐 */
getRecommend(prices) {
let profits = []
for (let goodinfo of prices) {
profits.push({
good: goodinfo.good,
profit: goodinfo.dif * Math.floor(this.money / goodinfo.mingood.price),
maxplace: goodinfo.maxgood.place,
minplace: goodinfo.mingood.place
})
}
profits.sort((a, b) => b.profit - a.profit)
return profits[0]
}
giveMoneyTo(altid, num) {
this.money -= num
this.saveData()
players[altid].money += num
players[altid].saveData()
return `<${this.name}>=><${players[altid].name}>\n$ ${num}`
}
transGoodto(altid, good, num) {
if (!this.takeGood(good, num)) return `没有此物品或物品数量不足`
let outnum = players[altid].addGood(good, num)
if (outnum > 0) {
this.addGood(good, outnum)
return `${good}×${num},溢出${outnum}件`
}
return `${good}×${num}`
}
sacrfice(good, num, now) {
//扣除物品
if (!this.takeGood(good, num)) return `没有此物品或物品数量不足`
let cult = this.cult
if (!cultlist.includes(cult)) return `你还没有加入教团,无法献祭`
let gods = Object.keys(cults[cult].ones)
let god = gods[Math.floor(Math.random() * gods.length)]
let text = `在${this.place}\n<${this.name}>向伟大的${god}献上了祭品:${good}×${num}\n`
if (Math.random() * 100 <= seal.ext.getIntConfig(ext, "献祭概率%")) {
text += `献祭成功!\n`
let increase = Math.ceil(Math.random() * 10) + 10
cults[cult].ones[god] += increase
this.exp += 5
text += `${god}的注视值+${increase}=>${cults[cult].ones[god]}\n`
if (cults[cult].ones[god] >= 100) {
cults[cult].ones[god] = 0
let gift = `${god}的雕像`
let outnum = this.addGood(gift, 1)
text += `${god}的注视值达到100!获得了${gift}×1${outnum > 0 ? `,溢出${outnum}件` : ``}\n`
}
//晋升
text += this.colorUp()
cults[cult].saveData()
}
else text += `献祭失败!\n`
return `${text}${this.stSan(now, -10)}`
}
}
class Place {
constructor(name) {
this.name = name
this.members = []
this.says = []
this.shop = {}
this.date = ''
}
// 从存储中获取数据并初始化地点对象
static getData(name) {
try {
let placeData = JSON.parse(ext.storageGet(name) || '{}');
let place = new Place(name)
place.members = placeData.members || []
place.says = placeData.says || []
place.shop = placeData.shop || {}
place.date = placeData.date || ''
places[name] = place
} catch (error) {
console.error(`Failed to initialize ${name}:`, error);
}
}
// 保存地点数据到存储
saveData() {
ext.storageSet(this.name, JSON.stringify(this));
}
//更新当地商店
updateshop(date) {
this.date = date
this.shop = {}
let ran = Math.random()
for (let i = 0; i < goodlst.length; i++) {
if (ran < goodlst[i].p) {
let max = goodlst[i].max
let min = goodlst[i].min
let goods = goodlst[i].lst
let good;
//生成商品列表
for (let k = 0; k < Math.ceil(goods.length / 2); k++) {
do good = goods[Math.floor(Math.random() * goods.length)]
while (this.shop.hasOwnProperty(good))
this.shop[good] = Math.floor(Math.random() * (max - min + 1)) + min
}
}
}
this.saveData()
}
//获取当地商店货物列表,返回文本
getShop(date) {
let place = this.name
if (this.date != date) this.updateshop(date)
let shoplst = Object.keys(this.shop)
let text = `${place}商店`
let good = ''
for (let i = 0; i < shoplst.length; i++) {
good = shoplst[i]
text += i % 2 == 0 ? `\n` : `|`
text += `${good}:$${this.shop[good]}`
}
return text
}
/**动态调整售价,num为正,指售出的数量,num为负,指购入的数量 */
adjustPrice(good, num) {
//先调整缓存的价格
if (priceUpdCache.hasOwnProperty(good)) {
let place = priceUpdCache[good].place
if (!placelist.includes(place)) {
delete priceUpdCache[good]
return;
}
let price = priceUpdCache[good].price
if (places[place].shop.hasOwnProperty(good)) {
places[place].shop[good] = price
places[place].saveData()
}
}
let factor = seal.ext.getIntConfig(ext, "价格调整幅度因子")
let price = this.shop[good]
let maxprice, minprice
for (let i = 0; i < goodlst.length; i++) {
if (goodlst[i].lst.includes(good)) {
let prices = []
for (let place of placelist) if (places[place].shop.hasOwnProperty(good)) prices.push(places[place].shop[good])
prices.sort((a, b) => b - a)
maxprice = prices[0]
minprice = prices[prices.length - 1]
break;
}
}
let midprice = Math.floor((maxprice + minprice) / 2)
let profit = (maxprice - minprice) / minprice
if (num > 0) {
let adjustFactor = (maxprice - midprice) * (profit + 1) / factor
price -= Math.floor(adjustFactor * num)
price = Math.max(price, midprice)
}
else {
let adjustFactor = (midprice - minprice) * (profit + 1) / factor
price += Math.floor(adjustFactor * (-num))
price = Math.min(price, midprice)
}
priceUpdCache[good] = {
place: this.name,
price: price
}
}
}
class Cult {
constructor(name) {
this.name = name
this.members = []
this.ones = {}
this.weapons = {}
this.date = ''
}
// 从存储中获取数据并初始化教团对象
static getData(name) {
try {
let cultData = JSON.parse(ext.storageGet(name) || '{}');
let cult = new Cult(name)
cult.members = cultData.members || []
cult.ones = cultData.ones || {}
cult.weapons = cultData.weapons || {}
cult.date = cultData.date || ''
cults[name] = cult
} catch (error) {
console.error(`Failed to initialize ${cult}:`, error);
}
}
// 保存教团数据到存储
saveData() {
ext.storageSet(this.name, JSON.stringify(this));
}
//更新武器商店
updateWeapon(date) {
this.date = date
this.weapons = {}
let weapon
let weapons = Object.keys(weaponlst)
for (let i = 0; i < 5; i++) {
do weapon = weapons[Math.floor(Math.random() * weapons.length)]
while (this.weapons.hasOwnProperty(weapon))
let num = weaponlst[weapon] / 5
this.weapons[weapon] = {
price: Math.ceil(Math.pow(1.2, num) * 100 * num),
rest: Math.ceil(Math.random() * 2)
}
}
this.saveData()
}
//生成武器商店
weaponShop(date) {
let cult = this.name
if (this.date != date) this.updateWeapon(date)
let shoplst = Object.keys(this.weapons)
let text = `${cult}武器商店`
for (let i = 0; i < shoplst.length; i++) {
let weapon = shoplst[i]
text += `\n${weapon}(${weaponlst[weapon]}):$ ${this.weapons[weapon].price} 剩余:${this.weapons[weapon].rest}`
}
return text
}
}
//初始化————
for (let id in playerlist) if (!players.hasOwnProperty(id)) Player.getData(id)
for (let place of placelist) if (!places.hasOwnProperty(place)) Place.getData(place)
for (let cult of cultlist) if (!cults.hasOwnProperty(cult)) {
Cult.getData(cult)
if (cultgods.hasOwnProperty(cult)) cultgods[cult].forEach(god => { if (!cults[cult].ones.hasOwnProperty(god)) cults[cult].ones[god] = 0; })
else cults[cult].ones['未知'] = 0;
}
function getTime() {
const now = new Date();
const dateString = now.toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' }).replace(/,/g, '');;
const [date, time] = dateString.split(' ');
const [month, day, year] = date.split('/');
const [hours, minutes, seconds] = time.split(':');
return `${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')} ${hours}:${minutes}:${seconds}`;
}
//打乱数组
function shuffle(array) {
let arr = array
for (let i = arr.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]]; // 交换元素
}
return arr
}
//检查是否存在该玩家并加入游戏
function ckId(id, name) {
if (!playerlist.hasOwnProperty(id)) {
const player = new Player(id, name)
players[id] = player
players[id].movPlace(players[id].place)
players[id].movCult(players[id].cult)
players[id].saveData()
playerlist[id] = getTime()
ext.storageSet('playerlist', JSON.stringify(playerlist));
}
}
/**检查参数是否为数字并返回,若为all则返回ifAll,无效则返回0*/
function ckNum(val, ifAll) {
switch (val) {
case '': return 1
case 'all': return ifAll
default: {
val = parseInt(val)
return isNaN(val) ? 0 : val
}
}
}
function findPlayer(text) {
text = text.toLowerCase()
let lst = []
for (let id in players) if (players[id].name.includes(text)) lst.push(id)
return lst
}
function getPrices(date) {
let allgoods = {}
//获取当日所有商品和价格
for (let place of placelist) {
places[place].getShop(date)
for (let good in places[place].shop) {
if (!allgoods.hasOwnProperty(good)) allgoods[good] = []
allgoods[good].push({
place: place,
price: places[place].shop[good]
})
}
}
//计算所有商品的最大差价
let prices = []
for (let good in allgoods) {
if (allgoods[good].length > 1) {
allgoods[good].sort((a, b) => a.price - b.price)
let maxgood = allgoods[good][allgoods[good].length - 1]
let mingood = allgoods[good][0]
prices.push({
good: good,