-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNNNN_ClassChangeSystem.js
More file actions
2662 lines (2414 loc) · 104 KB
/
NNNN_ClassChangeSystem.js
File metadata and controls
2662 lines (2414 loc) · 104 KB
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
//=============================================================================
// NNNN_ClassChangeSystem.js
//=============================================================================
/*:
* @target MZ
* @plugindesc v1.3.0 Enhanced Class Change System
* @author NeNeNeNeTai
* @url https://github.com/tomwu2021/NeNeNeNeTaiPlugin
* @help NNNN_ClassChangeSystem.js
*
* ◆主要功能 (Main Features)
* - 統一轉職系統,結合資源消耗和豐富UI體驗
* - 支援金錢和道具消耗
* - 詳細的職業轉換條件檢查
* - 多語言支持(繁體中文、英文、日文)
* - 現代化的用戶界面設計
* - 能力值變化預覽
* - 技能變化預覽
* - 職業圖像系統
*
* @param ShowMenuCommand
* @text Show Menu Command / メニューに表示 / 在菜單中顯示
* @desc Whether to show class change command in main menu
* @type boolean
* @default true
*
* @param MenuCommandPosition
* @text Menu Command Position / メニューコマンド位置 / 菜單命令位置
* @desc Position to insert command in menu (0 = top)
* @type number
* @default 3
*
* @param ClassListWidth
* @text Class List Width / 職業リスト幅 / 職業列表寬度
* @desc Width of the class selection window
* @type number
* @default 300
*
* @param AllowDuplicate
* @text Allow Duplicate / 允許重複轉職 / 允許重複職業
* @desc Whether to allow multiple actors to change to the same class
* @type boolean
* @default true
*
* @param HideUnchangeableClassName
* @text Hide Unchangeable Class Name / 隱藏不可轉職職業名稱 / 隱藏不可轉職職業名稱
* @desc Whether to hide the name of classes that cannot be changed
* @type boolean
* @default false
*
* @param HideUnchangeableClassDescription
* @text Hide Unchangeable Class Description / 隱藏不可轉職職業描述 / 隱藏不可轉職職業描述
* @desc Whether to hide the description of classes that cannot be changed
* @type boolean
* @default false
*
* @param KeepSkills
* @text Keep Skills / スキル保持 / 保留技能
* @desc Whether to keep learned skills when changing class
* @type boolean
* @default false
*
* @param KeepExp
* @text Keep Experience / 経験値保持 / 保留經驗值
* @desc Whether to keep current level and experience when changing class
* @type boolean
* @default true
*
* @param ClassList
* @text Available Classes / 利用可能職業 / 可用職業列表
* @type struct<ClassData>[]
* @desc List of classes available for change
*
*
* @param <DisplayText>
* @desc The display texts for changing classes.
*
* @param menuCommand
* @text Menu Command Text / メニューコマンドテキスト / 菜單命令文字
* @parent <DisplayText>
* @desc Text for the class change command in menu
* @type string
*
* @param confirmMessage
* @text Confirm Message / 確認メッセージ / 確認訊息
* @parent <DisplayText>
* @desc Confirmation message for class change
* @type string
*
* @param classText
* @text Class Text / 職業文字 / 職業文字
* @parent <DisplayText>
* @desc Text for the class name
* @type string
*
* @param successMessage
* @text Success Message / 成功メッセージ / 成功訊息
* @parent <DisplayText>
* @desc Message shown when class change succeeds
* @type string
*
* @param insufficientResources
* @text Insufficient Resources / 不足リソース / 資源不足
* @parent <DisplayText>
* @desc Message for insufficient resources
* @type string
*
* @param selectCharacterFirst
* @text Select Character First / キャラクター選択 / 請先選擇角色
* @parent <DisplayText>
* @desc Message to select character first
* @type string
*
* @param selectClassForConditions
* @text Select Class for Conditions / 条件用職業選択 / 選擇職業查看條件
* @parent <DisplayText>
* @desc Message to select class for viewing conditions
* @type string
*
* @param selectClassForStats
* @text Select Class for Stats / ステータス用職業選択 / 選擇職業查看數值
* @parent <DisplayText>
* @desc Message to select class for viewing stats
* @type string
*
* @param selectClassForSkills
* @text Select Class for Skills / スキル用職業選択 / 選擇職業查看技能
* @parent <DisplayText>
* @desc Message to select class for viewing skills
* @type string
*
* @param selectClassForIntro
* @text Select Class for Intro / 紹介用職業選択 / 選擇職業查看介紹
* @parent <DisplayText>
* @desc Message to select class for viewing introduction
* @type string
*
* @param classDescription
* @text Class Description / 職業説明 / 職業描述
* @parent <DisplayText>
* @desc Label for class description section
* @type string
*
* @param noClassDescription
* @text No Class Description / 職業説明なし / 無職業描述
* @parent <DisplayText>
* @desc Message when no class description available
* @type string
*
* @param classBasicInfo
* @text Class Basic Info / 職業基本情報 / 職業基本資訊
* @parent <DisplayText>
* @desc Label for class basic information
* @type string
*
* @param baseParams
* @text Base Parameters / 基本パラメータ / 基本參數
* @parent <DisplayText>
* @desc Label for base parameters
* @type string
*
* @param targetClass
* @text Target Class / 対象職業 / 目標職業
* @parent <DisplayText>
* @desc Label for target class
* @type string
*
* @param changeConditions
* @text Change Conditions / 転職条件 / 轉職條件
* @parent <DisplayText>
* @desc Label for class change conditions
* @type string
*
* @param allConditionsMet
* @text All Conditions Met / 全条件満足 / 符合所有條件
* @parent <DisplayText>
* @desc Message when all conditions are met
* @type string
*
* @param changeCost
* @text Change Cost / 転職コスト / 轉職費用
* @parent <DisplayText>
* @desc Label for class change cost
* @type string
*
* @param goldCost
* @text Gold Cost / ゴールドコスト / 金錢費用
* @parent <DisplayText>
* @type string
*
* @param forceMode
* @text Force Mode / 強制模式 / 強制模式
* @parent <DisplayText>
* @desc Label for force mode
* @type string
*
* @param paramRequirements
* @text Parameter Requirements / パラメータ要件 / 參數需求
* @parent <DisplayText>
* @desc Label for parameter requirements
* @type string
*
* @param baseStatsChange
* @text Base Stats Change / 基本ステータス変化 / 基本數值變化
* @parent <DisplayText>
* @desc Label for base stats change
* @type string
*
* @param skillChangePreview
* @text Skill Change Preview / スキル変化プレビュー / 技能變化預覽
* @parent <DisplayText>
* @desc Label for skill change preview
* @type string
*
* @param skillsLost
* @text Skills Lost / 失うスキル / 失去技能
* @parent <DisplayText>
* @desc Label for skills that will be lost
* @type string
*
* @param skillsGained
* @text Skills Gained / 得るスキル / 獲得技能
* @parent <DisplayText>
* @desc Label for skills that will be gained
* @type string
*
* @param noSkillChanges
* @text No Skill Changes / スキル変化なし / 無技能變化
* @parent <DisplayText>
* @desc Message when no skill changes
* @type string
*
* @param noNewSkills
* @text No New Skills / 新スキルなし / 無新技能
* @parent <DisplayText>
* @desc Message when no new skills
* @type string
*
* @param confirmChange
* @text Confirm Change / 変更確認 / 確認變更
* @parent <DisplayText>
* @desc Text for confirm button
* @type string
*
* @param cancel
* @text Cancel / キャンセル / 取消
* @parent <DisplayText>
* @desc Text for cancel button
* @type string
*
* @param classIntro
* @text Class Introduction Tab / 職業紹介タブ / 職業介紹頁籤
* @parent <DisplayText>
* @desc Text for class introduction tab
* @type string
*
* @param conditions
* @text Conditions Tab / 条件タブ / 條件頁籤
* @parent <DisplayText>
* @desc Text for conditions tab
* @type string
*
* @param statsComparison
* @text Stats Comparison Tab / ステータス比較タブ / 數值比較頁籤
* @parent <DisplayText>
* @desc Text for stats comparison tab
* @type string
*
* @param skillChanges
* @text Skill Changes Tab / スキル変化タブ / 技能變化頁籤
* @parent <DisplayText>
* @desc Text for skill changes tab
* @type string
*
* @param item
* @text Item Header / アイテムヘッダー / 項目標題
* @parent <DisplayText>
* @desc Header text for item column
* @type string
*
* @param before
* @text Before Header / 変更前ヘッダー / 變更前標題
* @parent <DisplayText>
* @desc Header text for before column
* @type string
*
* @param after
* @text After Header / 変更後ヘッダー / 變更後標題
* @parent <DisplayText>
* @desc Header text for after column
* @type string
*
* @param change
* @text Change Header / 変化ヘッダー / 變化標題
* @parent <DisplayText>
* @desc Header text for change column
* @type string
*
* @param operationHint
* @text Operation Hint / 操作ヒント / 操作提示
* @parent <DisplayText>
* @desc Text for operation hints
* @type string
*
* @param cannotPreviewStats
* @text Cannot Preview Stats / ステータスプレビュー不可 / 無法預覽數值
* @parent <DisplayText>
* @desc Error message for stats preview failure
* @type string
*
* @param invalidClass
* @text Invalid Class / 無效職業 / 無效職業
* @parent <DisplayText>
* @desc Error message for invalid class
* @type string
*
* @param cannotChangeFromCurrentClass
* @text Cannot Change From Current Class / 現職業から転職不可 / 無法從當前職業轉職
* @parent <DisplayText>
* @desc Error message for class change restriction
* @type string
*
* @param actorCannotChange
* @text Actor Cannot Change / アクター転職不可 / 角色無法轉職
* @parent <DisplayText>
* @desc Error message when actor cannot change to class
* @type string
*
* @param insufficientParam
* @text Insufficient Parameter / 不足パラメータ / 參數不足
* @parent <DisplayText>
* @desc Error message for insufficient parameters
* @type string
*
* @param insufficientGold
* @text Insufficient Gold / 不足ゴールド / 金錢不足
* @parent <DisplayText>
* @desc Error message for insufficient gold
* @type string
*
* @param insufficientItem
* @text Insufficient Item / 不足アイテム / 道具不足
* @parent <DisplayText>
* @desc Error message for insufficient items
* @type string
*
* @param unknownItem
* @text Unknown Item / 未知アイテム / 未知道具
* @parent <DisplayText>
* @desc Error message for unknown items
* @type string
*
* @param current
* @text Current / 現在 / 目前
* @parent <DisplayText>
* @desc Text for current value display
* @type string
*
* @param switchOff
* @text Switch Off / 過關 / 關閉
* @parent <DisplayText>
* @desc Switch off the class change system
* @type switch
*
* @param customScript
* @text Custom Script / カスタムスクリプト / 自訂腳本
* @parent <DisplayText>
* @desc Custom script for class change system
* @type string
*
* @param unchangeableClassNameReplacement
* @text Unchangeable Class Name Replacement / 不可轉職職業名稱替代 / 不可轉職職業名稱替代
* @parent <DisplayText>
* @desc Text to replace unchangeable class names
* @type string
* @default ????
*
*
* @command OpenClassChange
* @text 開啟轉職畫面
* @desc 開啟職業轉換畫面
*
* @arg actorId
* @text 指定角色ID
* @desc 直接指定要轉職的角色ID
* @type actor
*
* @arg variableActorId
* @text 角色ID變數
* @desc 用變數指定角色ID
* @type variable
*
* @arg isForce
* @text 強制轉職
* @desc 是否忽略條件強制轉職
* @type boolean
* @default false
*
* @command ForceClassChange
* @text 強制轉職
* @desc 強制角色轉職到指定職業
*
* @arg actorId
* @text 角色ID
* @desc 要轉職的角色ID
* @type actor
* @required
*
* @arg classId
* @text 職業ID
* @desc 目標職業ID
* @type class
* @required
*
* @arg isForce
* @text 忽略條件
* @desc 是否忽略轉職條件
* @type boolean
* @default true
*
* @command BatchUpdateClassList
* @text 批量更新職業列表
* @desc 批量啟用或停用指定職業
*
* @arg xClassList
* @text 職業 ID 列表
* @desc 要更新的職業 ID,用逗號分隔(例:1,2,3)
* @type string
* @required
*
* @arg enabled
* @text 啟用狀態
* @desc 設定為 true 啟用,設定為 false 停用
* @type boolean
* @default true
*/
/*~struct~ClassData:
* @param Class
* @text Class / 職業 / 職業
* @type class
* @desc Class ID
*
* @param Description
* @text Description / 描述 / 説明
* @desc Class description text
* @type string
*
* @param Enabled
* @text Enabled / 啟用 / 有効
* @desc Whether this class appears in the change list
* @type boolean
* @default true
*
* @param <Condition>
* @desc The conditions for changing classes.
*
* @param AllowedActors
* @parent <Condition>
* @text Allowed Actors / 允許角色 / 許可アクター
* @desc Actor IDs that can change to this class (comma separated)
* @type string
*
* @param FromClasses
* @parent <Condition>
* @text From Classes / 來源職業 / 元職業
* @desc Classes that can change to this class (comma separated)
* @type string
*
* @param RequiredLevel
* @parent <Condition>
* @text Required Level / 需要等級 / 必要レベル
* @desc Minimum level required
* @type number
* @default 1
*
* @param RequiredHp
* @parent <Condition>
* @text Required HP / 需要HP / 必要HP
* @desc Minimum HP parameter required
* @type number
* @default 0
*
* @param RequiredMp
* @parent <Condition>
* @text Required MP / 需要MP / 必要MP
* @desc Minimum MP parameter required
* @type number
* @default 0
*
* @param RequiredAtk
* @parent <Condition>
* @text Required ATK / 需要攻擊力 / 必要攻撃力
* @desc Minimum ATK parameter required
* @type number
* @default 0
*
* @param RequiredDef
* @parent <Condition>
* @text Required DEF / 需要防禦力 / 必要防御力
* @desc Minimum DEF parameter required
* @type number
* @default 0
*
* @param RequiredMat
* @parent <Condition>
* @text Required MAT / 需要魔攻 / 必要魔法攻撃
* @desc Minimum MAT parameter required
* @type number
* @default 0
*
* @param RequiredMdf
* @parent <Condition>
* @text Required MDF / 需要魔防 / 必要魔法防御
* @desc Minimum MDF parameter required
* @type number
* @default 0
*
* @param RequiredAgi
* @parent <Condition>
* @text Required AGI / 需要敏捷 / 必要敏捷性
* @desc Minimum AGI parameter required
* @type number
* @default 0
*
* @param RequiredLuk
* @parent <Condition>
* @text Required LUK / 需要運氣 / 必要運
* @desc Minimum LUK parameter required
* @type number
* @default 0
*
* @param RequiredSwitches
* @parent <Condition>
* @text Required Switches / 需要開關 / 必要スイッチ
* @desc Required switches (comma separated)
* @type string
*
* @param GoldCost
* @parent <Condition>
* @text Gold Cost / 金錢消耗 / ゴールド消費
* @desc Gold required for class change
* @type number
* @default 0
*
* @param ItemCosts
* @parent <Condition>
* @text Item Costs / 道具消耗 / アイテム消費
* @desc Items required (format: itemId/quantity,itemId/quantity)
* @type string
*
* @param CustomScript
* @parent <Condition>
* @text Custom Script / 自定義腳本 / カスタムスクリプト
* @desc Custom condition script
* @type string
*
* @param CustomScriptErrorMessage
* @parent <Condition>
* @text Custom Script Error Message / 不符合自定義腳本條件時要出現的錯誤訊息 / カスタムスクリプトエラーメッセージ
* @desc Custom condition script error message
* @type string
*
* @Param<Display>
* @desc The display settings for the class.
*
* @param EnabledPicture
* @parent <Display>
* @text Enable Picture / 啟用圖片 / 画像有効
* @desc Whether to display picture in list
* @type boolean
* @default true
*
* @param Picture
* @parent <Display>
* @text Class Picture / 職業示意圖片 / 職業画像
* @desc Picture file for this class
* @type file
* @dir img/pictures
*
*/
(() => {
'use strict';
//=============================================================================
// Constants and Initialization / 常數和初始化 / 定数と初期化
//=============================================================================
const pluginName = "NNNN_ClassChangeSystem";
const parameters = PluginManager.parameters(pluginName);
// Language detection / 語言檢測 / 言語検出
const isJapanese = () => Game_System.prototype.isJapanese.call(this);
const isChinese = () => Game_System.prototype.isChinese.call(this);
const getCurrentLanguage = () => {
if (isChinese()) return 'zh';
if (isJapanese()) return 'ja';
return 'en';
};
// Multi-language text configuration / 多語言文字配置 / 多言語テキスト設定
const TEXTS = {
input: {
menuCommand:parameters['menuCommand'],
classText:parameters['classText'],
confirmMessage:parameters['confirmMessage'],
successMessage:parameters['successMessage'],
insufficientResources:parameters['insufficientResources'],
selectCharacterFirst:parameters['selectCharacterFirst'],
selectClassForConditions:parameters['selectClassForConditions'],
selectClassForStats:parameters['selectClassForStats'],
selectClassForSkills:parameters['selectClassForSkills'],
selectClassForIntro:parameters['selectClassForIntro'],
classDescription:parameters['classDescription'],
noClassDescription:parameters['noClassDescription'],
classBasicInfo:parameters['classBasicInfo'],
baseParams:parameters['baseParams'],
targetClass:parameters['targetClass'],
changeConditions:parameters['changeConditions'],
allConditionsMet:parameters['allConditionsMet'],
changeCost:parameters['changeCost'],
goldCost:parameters['goldCost'],
forceMode:parameters['forceMode'],
paramRequirements:parameters['paramRequirements'],
baseStatsChange:parameters['baseStatsChange'],
skillChangePreview:parameters['skillChangePreview'],
skillsLost:parameters['skillsLost'],
skillsGained:parameters['skillsGained'],
noSkillChanges:parameters['noSkillChanges'],
noNewSkills:parameters['noNewSkills'],
confirmChange:parameters['confirmChange'],
cancel:parameters['cancel'],
tabs:{
classIntro:parameters['classIntro'],
conditions:parameters['conditions'],
statsComparison:parameters['statsComparison'],
skillChanges:parameters['skillChanges']
},
statHeaders:{
item:parameters['item'],
before:parameters['before'],
after:parameters['after'],
change:parameters['change']
},
operationHint:parameters['operationHint'],
errors:{
cannotPreviewStats:parameters['cannotPreviewStats'],
invalidClass:parameters['invalidClass'],
cannotChangeFromCurrentClass:parameters['cannotChangeFromCurrentClass'],
actorCannotChange:parameters['actorCannotChange'],
insufficientParam:parameters['insufficientParam'],
insufficientGold:parameters['insufficientGold'],
insufficientItem:parameters['insufficientItem'],
unknownItem:parameters['unknownItem'],
current:parameters['current'],
switchOff:parameters['switchOff'],
customScript:parameters['customScript']
}
}, // External input texts / 外部輸入文字 / 外部入力テキスト
zh: {
menuCommand: '轉職',
confirmMessage: '確認要進行轉職嗎?',
classText:'職業',
successMessage: '%1 成功轉職為 %2!',
insufficientResources: '資源不足或條件未滿足,無法進行轉職!',
selectCharacterFirst: '請先選擇角色',
selectClassForConditions: '選擇職業查看轉職條件',
selectClassForStats: '選擇職業查看能力比較',
selectClassForSkills: '選擇職業查看技能變化',
selectClassForIntro: '選擇職業查看介紹',
classDescription: '職業描述',
noClassDescription: '此職業暫無描述',
classBasicInfo: '基本資訊',
baseParams: '基礎參數',
targetClass: '目標職業:',
changeConditions: '轉職條件:',
allConditionsMet: '✓ 符合所有條件',
changeCost: '轉職消耗:',
goldCost: '金錢:',
forceMode: '✓ 強制轉職模式,忽略條件與消耗需求',
paramRequirements: '參數需求:',
baseStatsChange: '基礎能力值變化:',
skillChangePreview: '技能變化預覽',
skillsLost: '■ 失去技能:',
skillsGained: '■ 獲得技能:',
noSkillChanges: '沒有技能變化',
noNewSkills: '沒有新技能可學習',
confirmChange: '確認轉職',
cancel: '取消',
tabs: {
classIntro: '職業介紹',
conditions: '轉職條件',
statsComparison: '能力比較',
skillChanges: '技能變化'
},
statHeaders: {
item: '項目',
before: '轉職前',
after: '轉職後',
change: '變化'
},
operationHint: '← → 切換頁籤 R/F 滾動 T/E 切換角色',
errors: {
cannotPreviewStats: '無法預覽數值變化',
invalidClass: '無效職業',
cannotChangeFromCurrentClass: '無法從當前職業轉職到此職業',
actorCannotChange: '此角色無法轉職為此職業',
insufficientParam: '不足的參數',
insufficientGold: '不足的金錢',
insufficientItem: '不足的道具',
unknownItem: '未知的道具',
current: '目前',
switchOff: '未觸發事件-'
}
},
ja: {
menuCommand: '転職',
confirmMessage: '転職を実行しますか?',
classText:'職業',
successMessage: '%1 は %2 に転職しました!',
insufficientResources: 'リソース不足又は条件を満たしていないため、転職できません!',
selectCharacterFirst: 'まずキャラクターを選択してください',
selectClassForConditions: '職業を選択して転職条件を確認',
selectClassForStats: '職業を選択して能力変化を確認',
selectClassForSkills: '職業を選択してスキル変化を確認',
selectClassForIntro: '職業を選択して基本情報を確認',
classDescription: '職業説明',
noClassDescription: 'この職業には説明がありません',
classBasicInfo: '基本情報',
baseParams: '基礎パラメータ',
targetClass: '対象職業:',
changeConditions: '転職条件:',
allConditionsMet: '〇 すべての条件を満たしています',
changeCost: '転職コスト:',
goldCost: 'お金:',
forceMode: '〇 強制転職モード、条件とコストを無視',
paramRequirements: 'パラメータ要件:',
baseStatsChange: '基本ステータス変化:',
skillChangePreview: 'スキル変化プレビュー',
skillsLost: '■ 失うスキル:',
skillsGained: '■ 獲得スキル:',
noSkillChanges: 'スキル変化なし',
noNewSkills: '新しいスキルなし',
confirmChange: '転職確認',
cancel: 'キャンセル',
tabs: {
classIntro: '職業紹介',
conditions: '転職条件',
statsComparison: 'ステータス比較',
skillChanges: 'スキル変化'
},
statHeaders: {
item: '項目',
before: '変更前',
after: '変更後',
change: '変化'
},
operationHint: '← → タブ切替 R/F スクロール T/E アクター切替',
errors: {
cannotPreviewStats: 'ステータス変化をプレビューできません',
invalidClass: '無効な職業',
cannotChangeFromCurrentClass: '現在の職業からこの職業に転職できません',
actorCannotChange: 'アクターがこの職業に転職できません',
insufficientParam: '不足のパラメータ',
insufficientGold: '不足のお金',
insufficientItem: '不足のアイテム',
unknownItem: '未知のアイテム',
current: '現在',
switchOff: '特定のイベントで解放-'
}
},
en: {
menuCommand: 'Class Change',
confirmMessage: 'Confirm class change?',
classText:'Class',
successMessage: '%1 changed class to %2!',
insufficientResources: 'Insufficient resources or conditions not met for class change!',
selectCharacterFirst: 'Please select a character first',
selectClassForConditions: 'Select a class to view change conditions',
selectClassForStats: 'Select a class to view stat changes',
selectClassForSkills: 'Select a class to view skill changes',
selectClassForIntro: 'Select a class to view class introduction',
classDescription: 'Class Description',
noClassDescription: 'No description available for this class',
classBasicInfo: 'Basic Information',
baseParams: 'Base Parameters',
targetClass: 'Target Class:',
changeConditions: 'Change Conditions:',
allConditionsMet: '✓ All conditions met',
changeCost: 'Change Cost:',
goldCost: 'Gold:',
forceMode: '✓ Force Mode, ignore conditions and cost',
paramRequirements: 'Parameter Requirements:',
baseStatsChange: 'Base Stat Changes:',
skillChangePreview: 'Skill Change Preview',
skillsLost: '■ Skills Lost:',
skillsGained: '■ Skills Gained:',
noSkillChanges: 'No skill changes',
noNewSkills: 'No new skills to learn',
confirmChange: 'Confirm Change',
cancel: 'Cancel',
tabs: {
classIntro: 'Class Info',
conditions: 'Conditions',
statsComparison: 'Stats Comparison',
skillChanges: 'Skill Changes'
},
statHeaders: {
item: 'Item',
before: 'Before',
after: 'After',
change: 'Change'
},
operationHint: '← → Switch Tabs R/F Scroll T/E Switch Actor',
errors: {
cannotPreviewStats: 'Cannot preview stat changes',
invalidClass: 'Invalid class',
cannotChangeFromCurrentClass: 'Cannot change from current class to this class',
actorCannotChange: 'Actor cannot change to this class',
insufficientParam: 'Insufficient parameter',
insufficientGold: 'Insufficient gold',
insufficientItem: 'Insufficient item',
unknownItem: 'Unknown item',
current: 'Current',
switchOff: "Unlocked after specific event",
}
}
};
// Custom key mappings for class change system / 轉職系統自定義按鍵映射 / クラスチェンジシステムのカスタムキーマッピング
Input.keyMapper[69] = 'actorLeft'; // E key - 切換角色 (左)
Input.keyMapper[84] = 'actorRight'; // T key - 切換角色 (右)
Input.keyMapper[82] = 'infoUp'; // R key - 資訊頁面向上捲動
Input.keyMapper[70] = 'infoDown'; // F key - 資訊頁面向下捲動
// Get current language texts with external input support / 獲取當前語言文字並支援外部輸入 / 外部入力サポート付きの現在の言語テキストを取得
const getText = (key) => {
// Check external input first / 首先檢查外部輸入 / まず外部入力をチェック
if (TEXTS.input[key]) {
return TEXTS.input[key];
}
const lang = getCurrentLanguage();
const keys = key.split('.');
let text = TEXTS[lang];
for (const k of keys) {
text = text[k];
if (!text) break;
}
return text || key;
};
// Function to set external text / 設定外部文字的函數 / 外部テキスト設定関数
window.setClassChangeText = (key, value) => {
TEXTS.input[key] = value;
};
// Plugin parameters / 插件參數 / プラグインパラメータ
const showMenuCommand = parameters['ShowMenuCommand'] === 'true';
const menuCommandPosition = parseInt(parameters['MenuCommandPosition']) || 3;
const classListWidth = parseInt(parameters['ClassListWidth']) || 300;
const keepSkills = parameters['KeepSkills'] === 'true';
const keepExp = parameters['KeepExp'] === 'true';
const allowDuplicate = parameters["AllowDuplicate"] === 'true';
const hideUnchangeableClassDescription = parameters["HideUnchangeableClassDescription"] === 'true';
const hideUnchangeableClassName = parameters["HideUnchangeableClassName"] === 'true';
const unchangeableClassNameReplacement = parameters["UnchangeableClassNameReplacement"] || '????';
// Parse structured parameters / 解析結構化參數 / 構造化パラメータの解析
const parseStruct = (param) => {
if (!param) return [];
try {
return JSON.parse(param).map(item => JSON.parse(item));
} catch (e) {
return [];
}
};
const classList = parseStruct(parameters['ClassList']);
// Global variables / 全局變數 / グローバル変数
let selectedActor = null;
let selectedClass = null;
let isForceMode = false;
const classBitmaps = [];
for(const c of classList){
const classBitmap = {
pictureName: c.Picture,
bitmap: ImageManager.loadPicture(c.Picture)
};
classBitmaps.push(classBitmap);
}
//-----------------------------------------------------------------------------
// Plugin Commands / 插件命令 / プラグインコマンド
//-----------------------------------------------------------------------------
PluginManager.registerCommand(pluginName, 'OpenClassChange', args => {
let actorId = null;
if (args.variableActorId) {
actorId = $gameVariables.value(parseInt(args.variableActorId));
} else if (args.actorId) {
actorId = parseInt(args.actorId);
}
isForceMode = args.isForce === 'true';
selectedActor = null;
SceneManager.push(Scene_ActorSelection);
});
PluginManager.registerCommand(pluginName, 'ForceClassChange', args => {
const actorId = parseInt(args.actorId);
const classId = parseInt(args.classId);
const isForce = args.isForce === 'true';
const actor = $gameActors.actor(actorId);
const targetClass = $dataClasses[classId];
const currentClassId = actor.currentClass().id;
const sameClass = currentClassId === classId;
if(sameClass){
$gameMessage.add(getText('errors.cannotChangeFromCurrentClass'));
return;
}
if (actor && targetClass) {
if (isForce || checkClassChangeConditions(actor, classId).canChange) {
executeClassChange(actor, classId, isForce,true);
} else {
$gameMessage.add(getText('insufficientResources'));
}
}
});
PluginManager.registerCommand(pluginName, 'BatchUpdateClassList', args => {
const xClassList = args.xClassList || '';
const enabled = args.enabled === 'true';
const classIds = xClassList.split(',').map(id => parseInt(id.trim())).filter(id => !isNaN(id));
if (classIds.length === 0) {
return;
}
classList.forEach(classData => {
if (classData && classIds.includes(parseInt(classData.Class))) {
classData.Enabled = enabled;
}
});
});
//-----------------------------------------------------------------------------
// Utility Functions / 工具函數 / ユーティリティ関数
//-----------------------------------------------------------------------------
function getClassName(actor,classData,checkResult){
if(!classData){
return '';
}
if(checkResult === undefined || checkResult === null){
const check = checkClassChangeConditions(actor, classData.id);
checkResult = check.some(check => !check.canChange);
}
if(hideUnchangeableClassName && !checkResult){
return unchangeableClassNameReplacement??'';
}
return classData.name;
}
function getClassConditions(classId) {
// Find class data from plugin parameters / 從插件參數中查找職業數據 / プラグインパラメータから職業データを検索
const classData = classList.find(data => parseInt(data.Class) === classId);
const conditions = {};
if (classData) {
// Parse from ClassData parameters / 從ClassData參數解析 / ClassDataパラメータから解析
const classDataCopy = JsonEx.makeDeepCopy(classData);
Object.keys(classDataCopy).forEach(key => {
if(!paramFields.includes(key)){
delete classDataCopy[key];
return;
}
if(!classDataCopy[key] || classDataCopy[key] === 0 ||
classDataCopy[key] === '0' || classDataCopy[key] === ''){
delete classDataCopy[key];
return;
}
conditions[key] = classDataCopy[key];
});
if (classData.Description) {
conditions.Description = classData.Description;
}
if (classData.CustomScript && classData.CustomScriptErrorMessage) {
conditions.CustomScriptErrorMessage = classData.CustomScriptErrorMessage;
}
}
return conditions;
}
const paramFields = [
'AllowedActors',
'FromClasses',
'RequiredLevel',