-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathpandas.hpp
2337 lines (1907 loc) · 119 KB
/
pandas.hpp
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
// Copyright (c) Pandas Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder
#pragma once
#include "../custom/defines_pre.hpp"
#include "./packets.hpp"
#include "./renewal.hpp"
#include "./secure.hpp"
#include "./classes/general.hpp"
#include "../custom/defines_post.hpp"
#define Pandas
#ifdef Pandas
#define Pandas_Basic
#define Pandas_DatabaseIncrease
#define Pandas_StructIncrease
#define Pandas_BattleConfigure
#define Pandas_InternalConfigure
#define Pandas_FuncIncrease
#define Pandas_PacketFunction
#define Pandas_CreativeWork
#define Pandas_Speedup
#define Pandas_Bugfix
#define Pandas_Crashfix
#define Pandas_ScriptEngine
#define Pandas_Redeclaration
#define Pandas_UserExperience
#define Pandas_Cleanup
#define Pandas_NpcEvent
#define Pandas_Mapflags
#define Pandas_AtCommands
#define Pandas_Bonuses
#define Pandas_ScriptCommands
#define Pandas_ScriptConstants
#define Pandas_ScriptResults
#define Pandas_ScriptParams
#define Pandas_WebServer
#endif // Pandas
#ifndef GIT_BRANCH
#define GIT_BRANCH ""
#endif // GIT_BRANCH
#ifndef GIT_HASH
#define GIT_HASH ""
#endif // GIT_HASH
// ============================================================================
// 基础组 - Pandas_Basic
// ============================================================================
#ifdef Pandas_Basic
// 熊猫模拟器社区版版本号
// 在 Windows 环境下版本号优先以资源文件中的文件版本号为准 (失败才会使用此处的版本号)
// 在 Linux 环境下版本号将直接使用此处定义的版本号
//
// 约定:
// - 版本号的末尾若带有 -dev 后缀则表示这是一个还未 Release 的开发中版本
// - 在 Windows 环境下资源文件中定义的版本号最后一段如果为 1, 也表示这是一个开发中的版本
//
// 例如:
// 1.0.1.0
// ^ 此处第四段为 0 表示这是一个 1.0.1 的正式版本 (Release)
// 1.0.2.1
// ^ 此处第四段为 1 表示这是一个 1.0.2 的开发版本 (develop)
//
// 在 Windows 环境下, 程序启动时会根据第四段的值自动携带对应的版本后缀, 以便进行版本区分
#define Pandas_Version "1.2.4.0"
// 在启动时显示 Pandas 的 LOGO
#define Pandas_Show_Logo
// 在启动时显示 Pandas 的版本号
#define Pandas_Show_Version
// 是否启用 Google Breakpad 用于处理程序崩溃
#define Pandas_Google_Breakpad
// 是否启用一些杂乱的自定义辅助函数
#define Pandas_Helper_Common_Function
// 是否启用代码分析工具所建议的处理措施以避免潜在风险
// 包含的工具有: LGTM, CodeQL, Microsoft Code Analysis 等
#define Pandas_CodeAnalysis_Suggestion
#endif // Pandas_Basic
// ============================================================================
// 数据结构增强组 - Pandas_StructIncrease
// ============================================================================
#ifdef Pandas_StructIncrease
// 使 map_session_data, npc_data, mob_data, homun_data,
// mercenary_data, elemental_data, pet_data 能够有一个独立的结构体用来
// 存放 Pandas 针对多单位通用的拓展 [Sola丶小克]
#define Pandas_Struct_Unit_CommonData
// 以下选项开关需要依赖 Pandas_Struct_Unit_CommonData 的拓展
#ifdef Pandas_Struct_Unit_CommonData
// 使 s_unit_common_data 可记录单位的光环信息 [Sola丶小克]
#define Pandas_Struct_Unit_CommonData_Aura
// 使 s_unit_common_data 可记录战斗记录信息 [Sola丶小克]
#define Pandas_Struct_Unit_CommonData_BattleRecord
#endif // Pandas_Struct_Unit_CommonData
// 使 map_session_data 有一个独立的结构体用来存放 Pandas 的拓展 [Sola丶小克]
// 结构体修改定位 pc.hpp -> map_session_data.pandas
#define Pandas_Struct_Map_Session_Data_Pandas
// 以下选项开关需要依赖 Pandas_Struct_Map_Session_Data_Pandas 的拓展
#ifdef Pandas_Struct_Map_Session_Data_Pandas
// 使 map_session_data 可记录当前玩家正在处理哪一个脚本事件 [Sola丶小克]
// 结构体修改定位 pc.hpp -> map_session_data.pandas.workinevent
#define Pandas_Struct_Map_Session_Data_WorkInEvent
// 使 map_session_data 可记录事件中断请求 [Sola丶小克]
// 结构体修改定位 pc.hpp -> map_session_data.pandas.eventhalt
#define Pandas_Struct_Map_Session_Data_EventHalt
// 使 map_session_data 可记录事件触发请求 [Sola丶小克]
// 结构体修改定位 pc.hpp -> map_session_data.pandas.eventtrigger
#define Pandas_Struct_Map_Session_Data_EventTrigger
// 使 map_session_data 可记录当前是否正在进行护身符能力计算 [Sola丶小克]
// 结构体修改定位 pc.hpp -> map_session_data.pandas.amulet_calculating
#define Pandas_Struct_Map_Session_Data_AmuletCalculating
// 使 map_session_data 可记录即将支持捕捉的多个魔物编号 [Sola丶小克]
#define Pandas_Struct_Map_Session_Data_MultiCatchTargetClass
// 使 map_session_data 可记录接下来的 pc_setpos 调用是不是一次多人传送 [Sola丶小克]
// 结构体修改定位 pc.hpp -> map_session_data.pandas.multitransfer
#define Pandas_Struct_Map_Session_Data_MultiTransfer
// 使 map_session_data 可记录是否在 LoadEndAck 调用中不弹出队列中的事件 [Sola丶小克]
// 结构体修改定位 pc.hpp -> map_session_data.pandas.skip_loadendack_npc_event_dequeue
#define Pandas_Struct_Map_Session_Data_Skip_LoadEndAck_NPC_Event_Dequeue
// 使 map_session_data 可记录离线挂店 / 挂机角色的朝向等状态数据 [Sola丶小克]
// rAthena 使用完成 autotrade 的朝向数据后就销毁掉了
// 为了能够支持离线挂店 / 挂机可以被 recall 召唤, 我们需要保留一部分数据
#define Pandas_Struct_Map_Session_Data_Autotrade_Configure
// 使 map_session_data 可记录玩家已经生成的 bonus_script 记录数 [Sola丶小克]
// 结构体修改定位 pc.hpp -> map_session_data.pandas.bonus_script_counter
#define Pandas_Struct_Map_Session_Data_BonusScript_Counter
#endif // Pandas_Struct_Map_Session_Data_Pandas
// 使 item_data 有一个独立的结构体用来存放 Pandas 的拓展 [Sola丶小克]
// 结构体修改定位 itemdb.hpp -> item_data.pandas
#define Pandas_Struct_Item_Data_Pandas
// 以下选项开关需要依赖 Pandas_Struct_Item_Data_Pandas 的拓展
#ifdef Pandas_Struct_Item_Data_Pandas
// 使 item_data 可记录当前物品的使用、穿戴、卸装脚本的原文 [Sola丶小克]
// 结构体修改定位 itemdb.hpp -> item_data.pandas.script_plaintext
#define Pandas_Struct_Item_Data_Script_Plaintext
// 使 item_data 可记录当前物品可捕捉的魔物编号 [Sola丶小克]
// 结构体修改定位 itemdb.hpp -> item_data.pandas.taming_mobid
#define Pandas_Struct_Item_Data_Taming_Mobid
// 使 item_data 可记录此物品的使用脚本是否执行了 callfunc 指令 [Sola丶小克]
// 结构体修改定位 itemdb.hpp -> item_data.pandas.has_callfunc
#define Pandas_Struct_Item_Data_Has_CallFunc
// 使 item_data 可记录此物品的特殊属性 [Sola丶小克]
// 效果与 item_data.flag 类似, 只是数据源为 item_properties.yml
// 结构体修改定位 itemdb.hpp -> item_data.pandas.properties
#define Pandas_Struct_Item_Data_Properties
#endif // Pandas_Struct_Item_Data_Pandas
// 使 npc_data 有一个独立的结构体用来存放 Pandas 的拓展 [Sola丶小克]
// 结构体修改定位 npc.hpp -> npc_data.pandas
#define Pandas_Struct_Npc_Data_Pandas
// 以下选项开关需要依赖 Pandas_Struct_Npc_Data_Pandas 的拓展
#ifdef Pandas_Struct_Npc_Data_Pandas
// 使 npc_data 结构体可记录此 NPC 的自毁策略 [Sola丶小克]
// 结构体修改定位 npc.hpp -> npc_data.pandas.destruction_strategy
#define Pandas_Struct_Npc_Data_DestructionStrategy
#endif // Pandas_Struct_Npc_Data_Pandas
// 使 mob_data 有一个独立的结构体用来存放 Pandas 的拓展 [Sola丶小克]
// 结构体修改定位 mob.hpp -> mob_data.pandas
#define Pandas_Struct_Mob_Data_Pandas
// 以下选项开关需要依赖 Pandas_Struct_Mob_Data_Pandas 的拓展
#ifdef Pandas_Struct_Mob_Data_Pandas
// 使 mob_data 结构体可记录此魔物被 setunitdata 修改过哪些项目 [Sola丶小克]
// 结构体修改定位 mob.hpp -> mob_data.pandas.special_setunitdata
#define Pandas_Struct_Mob_Data_Special_SetUnitData
// 使 mob_data 结构体可记录此魔物特殊的基础经验或职业经验 [Sola丶小克]
// 结构体修改定位 mob.hpp -> mob_data.pandas.base_exp 和 job_exp
#define Pandas_Struct_Mob_Data_SpecialExperience
#endif // Pandas_Struct_Mob_Data_Pandas
// 对离线挂店 autotrade 的定义进行拓展处理 [Sola丶小克]
// 进行拓展处理之后能够在代码改动较少的情况下, 更好的支持多种不同类型的 "离线挂店" 行为
//
// 在默认情况下 sd->state.autotrade 的值若为 0 则表示没有离线挂店
// 若非零的话则表示启用了离线挂店, 且 &2 表示开启的是离线摆摊挂店 &3 表示开启的是离线收购挂店
#define Pandas_Struct_Autotrade_Extend
// 对 bonus_script_data 的定义进行拓展处理 [Sola丶小克]
// 默认的 rAthena 中 bonus_script 机制并没有唯一编号的概念, 为了提高对 bonus_script 的控制粒度
// 我们需要将唯一编号引入到我们需要拓展的相关数据结构体中
#define Pandas_Struct_BonusScriptData_Extend
// 使 s_mail.item 能有一个 details 字段用来记录附件道具更详细的信息 [Sola丶小克]
#define Pandas_Struct_S_Mail_With_Details
// 使 s_random_opt_data 能保存脚本的明文 [Sola丶小克]
#define Pandas_Struct_S_Random_Opt_Data_With_Plaintext
// 使 s_item_combo 能保存脚本的明文 [Sola丶小克]
#define Pandas_Struct_S_Item_Combo_With_Plaintext
// 使 status_change 能保存 cloak 是否正在进行中的状态 [Sola丶小克]
#define Pandas_Struct_Status_Change_Cloak_Reverting
// 使 map_data 能保存全部魔物的刷新点信息 [Sola丶小克]
#define Pandas_Struct_Map_Data_Mob_Spawns
#endif // Pandas_StructIncrease
// ============================================================================
// 数据库增强组 - Pandas_DatabaseIncrease
// ============================================================================
#ifdef Pandas_DatabaseIncrease
// 是否启用道具特殊属性数据库 [Sola丶小克]
// 为了避免未来可能存在的冲突, 直接创建一个新的数据库来存放对物品属性的自定义扩充
// 此选项依赖 Pandas_Struct_Item_Data_Properties 的拓展
#ifdef Pandas_Struct_Item_Data_Properties
#define Pandas_Database_ItemProperties
#endif // Pandas_Struct_Item_Data_Properties
// 是否启用魔物道具固定掉率数据库及其功能 [Sola丶小克]
// 通过这个数据库可以指定某个道具的全局固定掉落概率, 且能绕过等级惩罚和VIP掉率加成等机制
#define Pandas_Database_MobItem_FixedRatio
// 是否拓展 Yaml 的 Database 操作类使之能抑制错误信息 [Sola丶小克]
#define Pandas_Database_Yaml_BeQuiet
// 是否支持用于读取 SQL 连接编码的 Sql_GetEncoding 函数 [Sola丶小克]
#define Pandas_Database_SQL_GetEncoding
#endif // Pandas_DatabaseIncrease
// ============================================================================
// 战斗配置组 - Pandas_BattleConfigure
// ============================================================================
#ifdef Pandas_BattleConfigure
// 是否支持对战斗配置选项进行完整性检查 [╰づ记忆•斑驳〤 实现] [Sola丶小克 改进]
#define Pandas_BattleConfig_Verification
// 是否启用 force_loadevent 配置选项及其功能 [Sola丶小克]
// 此选项可以强制没有 loadevent 标记的地图也能触发 OnPCLoadMapEvent 事件
#define Pandas_BattleConfig_Force_LoadEvent
// 是否启用 force_identified 配置选项及其功能 [Sola丶小克]
// 此选项可以强制特定渠道获得的装备自动变成已鉴定
#define Pandas_BattleConfig_Force_Identified
// 是否启用 cashmount_useitem_limit 配置选项及其功能 [Sola丶小克]
// 此选项可以使乘坐“商城坐骑”时禁止使用特定类型的物品
#define Pandas_BattleConfig_CashMounting_UseitemLimit
// 是否启用 max_aspd_for_pvp 配置选项及其功能 [Sola丶小克]
// 此选项用于限制玩家在 PVP 地图上的最大攻击速度 (以 MF_PVP 地图标记为准)
#define Pandas_BattleConfig_MaxAspdForPVP
// 是否启用 max_aspd_for_gvg 配置选项及其功能 [Sola丶小克]
// 此选项用于限制玩家在 GVG 地图上的最大攻击速度 (以 MF_GVG/MF_GVG_TE 地图标记为准)
#define Pandas_BattleConfig_MaxAspdForGVG
// 是否启用 atcmd_no_permission 配置选项及其功能 [Sola丶小克]
// 此选项用于指定没有指令权限的玩家, 在执行了管理员指令时的处理策略
#define Pandas_BattleConfig_AtCmd_No_Permission
// 是否启用 suspend_monsterignore 配置选项及其功能 [Sola丶小克]
// 此选项用于指定当玩家使用挂机系列指令时, 哪些模式不会被魔物攻击 (掩码选项)
#define Pandas_BattleConfig_Suspend_MonsterIgnore
// 是否启用 suspend_whisper_response 配置选项及其功能 [Sola丶小克]
// 此选项用于指定当玩家使用挂机系列指令时, 处于哪些模式会自动回复私聊讯息 (掩码选项)
#define Pandas_BattleConfig_Suspend_Whisper_Response
// 是否启用 suspend_offline_bodydirection 配置选项及其功能 [Sola丶小克]
// 此选项用于指定当玩家进入离线挂机模式时, 地图服务器重启后的身体朝向哪里
#define Pandas_BattleConfig_Suspend_Offline_BodyDirection
// 是否启用 suspend_offline_headdirection 配置选项及其功能 [Sola丶小克]
// 此选项用于指定当玩家进入离线挂机模式时, 地图服务器重启后的头部朝向哪里
#define Pandas_BattleConfig_Suspend_Offline_HeadDirection
// 是否启用 suspend_offline_sitdown 配置选项及其功能 [Sola丶小克]
// 此选项用于指定当玩家进入离线挂机模式时, 地图服务器重启后处于站立还是坐下状态
#define Pandas_BattleConfig_Suspend_Offline_Sitdown
// 是否启用 suspend_afk_bodydirection 配置选项及其功能 [Sola丶小克]
// 此选项用于指定当玩家进入离开模式时, 地图服务器重启后的身体朝向哪里
#define Pandas_BattleConfig_Suspend_AFK_BodyDirection
// 是否启用 suspend_afk_headdirection 配置选项及其功能 [Sola丶小克]
// 此选项用于指定当玩家进入离开模式时, 地图服务器重启后的头部朝向哪里
#define Pandas_BattleConfig_Suspend_AFK_Headdirection
// 是否启用 suspend_afk_sitdown 配置选项及其功能 [Sola丶小克]
// 此选项用于指定当玩家进入离开模式时, 地图服务器重启后处于站立还是坐下状态
#define Pandas_BattleConfig_Suspend_AFK_Sitdown
// 是否启用 suspend_afk_headtop_viewid 配置选项及其功能 [Sola丶小克]
// 此选项用于当玩家进入离开模式时, 将头饰上的更换为哪一个指定的头饰外观编号
#define Pandas_BattleConfig_Suspend_AFK_HeadTop_ViewID
// 是否启用 suspend_normal_bodydirection 配置选项及其功能 [Sola丶小克]
// 此选项用于指定当玩家进入普通模式时, 被拉上线的角色身体朝向哪里
#define Pandas_BattleConfig_Suspend_Normal_BodyDirection
// 是否启用 suspend_normal_headdirection 配置选项及其功能 [Sola丶小克]
// 此选项用于指定当玩家进入普通模式时, 被拉上线的角色头部朝向哪里
#define Pandas_BattleConfig_Suspend_Normal_HeadDirection
// 是否启用 suspend_normal_sitdown 配置选项及其功能 [Sola丶小克]
// 此选项用于指定当玩家进入普通模式时, 被拉上线的角色处于站立还是坐下状态
#define Pandas_BattleConfig_Suspend_Normal_Sitdown
// 是否启用 multiplayer_recall_behavior 配置选项及其功能 [Sola丶小克]
// 此选项用于控制多人召唤时是否避开在线摆摊玩家
#define Pandas_BattleConfig_Multiplayer_Recall_Behavior
// 是否启用 always_trigger_npc_killevent 配置选项及其功能 [Sola丶小克]
// 此选项用于控制当魔物拥有且触发了自己的死亡事件标签后, 是否还会继续触发 OnNPCKillEvent 事件
#define Pandas_BattleConfig_AlwaysTriggerNPCKillEvent
// 是否启用 always_trigger_mvp_killevent 配置选项及其功能 [Sola丶小克]
// 此选项用于控制当 MVP 魔物拥有且触发了自己的死亡事件标签后, 是否还会继续触发 OnPCKillMvpEvent 事件
#define Pandas_BattleConfig_AlwaysTriggerMVPKillEvent
// 是否启用 batrec_autoenabled_unit 配置选项及其功能 [Sola丶小克]
// 此选项用于设置默认情况下有哪些类型的单位会启用战斗记录
#define Pandas_BattleConfig_BattleRecord_AutoEnabled_Unit
// 是否启用 repeat_clearunit_interval 配置选项及其功能 [Sola丶小克]
// 此选项用于设置重发魔物死亡封包的间隔时间 (单位为: 毫秒)
#define Pandas_BattleConfig_Repeat_ClearUnit_Interval
// 是否启用 dead_area_size 配置选项及其功能 [Sola丶小克]
// 此选项用于设置魔物死亡封包将会发送给周围多少个格的玩家
#define Pandas_BattleConfig_Dead_Area_Size
// 是否启用 remove_manhole_with_status 配置选项及其功能 [Sola丶小克]
// 此选项用于设置当"人孔/黑洞陷阱"地面陷阱被移除的时候是否同时使被捕获的玩家脱困
#define Pandas_BattleConfig_Remove_Manhole_With_Status
// 是否启用 restore_mes_logic 配置选项及其功能 [Sola丶小克]
// 此选项用于设置是否使 2021-11-03 及更新版本的客户端在执行 mes 指令时使用经典换行策略
#define Pandas_BattleConfig_Restore_Mes_Logic
// 是否启用 itemdb_warning_policy 配置选项及其功能 [Sola丶小克]
// 此选项用于控制是否关闭加载物品数据库时的一些警告信息
#define Pandas_BattleConfig_ItemDB_Warning_Policy
// 是否启用 mob_default_damagemotion 配置选项及其功能 [Renee]
// 此选项用于控制当魔物被攻击时受伤动画的默认播放时长, 值越小看起来越快 (单位为: 毫秒)
#define Pandas_BattleConfig_MobDB_DamageMotion_Min
// 是否启用 mob_setunitdata_persistence 配置选项及其功能 [Sola丶小克]
// 此选项用于控制是否高优先级持久化保存 setunitdata 对魔物的设置
#define Pandas_BattleConfig_Mob_SetUnitData_Persistence
// 是否启用 strict_parameters_of_rand 配置选项及其功能 [Sola丶小克]
// 此选项用于控制是否对 rand 脚本指令进行严格的参数检查, 以便兼容以前早期的脚本
#define Pandas_BattleConfig_Strict_Parameters_Of_Rand
// PYHELP - BATTLECONFIG - INSERT POINT - <Section 1>
#endif // Pandas_BattleConfigure
// ============================================================================
// 服务器通用配置组 - Pandas_InternalConfigure
// ============================================================================
#ifdef Pandas_InternalConfigure
// 是否启用 hide_server_ipaddress 配置选项及其功能 [Sola丶小克]
// 此选项用于确保服务端不主动返回服务器的 IP 地址给到客户端, 通常用于支持代理方式登录
#define Pandas_InterConfig_HideServerIpAddress
#endif // Pandas_InternalConfigure
// ============================================================================
// 函数修改组 - Pandas_FuncIncrease
// ============================================================================
#ifdef Pandas_FuncIncrease
// 在 pc.cpp 中的 pc_equipitem 增加 swapping 参数 [Sola丶小克]
// 新增的 swapping 用于判断当前的装备穿戴调用是否由装备切换机制引发, 默认为 false
#define Pandas_FuncParams_PC_EQUIPITEM
// 调整 pc.cpp 中 pc_equipitem 执行道具绑定的时机 [Sola丶小克]
#define Pandas_FuncLogic_PC_EQUIPITEM_BOUND_OPPORTUNITY
// 调整 storage.cpp 中 storage_additem 的函数定义, 移除 static 关键字 [Sola丶小克]
#define Pandas_FuncDefine_STORAGE_ADDITEM
// 调整 instance.cpp 中 instance_destroy 的定义
// 增加 skip_erase 参数用于控制成功销毁副本后不 erase 掉 instance 对象
// 以便交由外部来进行 erase, 这样才能获取下一个指针的正确位置 (C++11) [Sola丶小克]
#define Pandas_FuncDefine_Instance_Destory
// 调整各单位的死亡处理函数, 以便支持更多参数信息 [Sola丶小克]
// 玩家单位 : pc.cpp -> pc_dead
// 魔物单位 : mob.cpp -> mob_dead
// 生命体单位 : homunculus.cpp -> hom_dead
// 佣兵单位 : mercenary.cpp -> mercenary_dead
// 元素精灵 : elemental.cpp -> elemental_dead
#define Pandas_FuncDefine_UnitDead_With_ExtendInfo
// 调整用于计算 MAX_INVENTORY 相关的变量
// 以便能够支持将背包的最大上限设置成超过 128 的值 [Sola丶小克]
//
// 提示: 根据目前的 struct item 和 struct s_storage 的体积情况,
// 应该可支持将 MAX_INVENTORY 调整到 800 左右, 但设置越大对性能影响会越大
#define Pandas_FuncExtend_Increase_Inventory
// 调整 atcommand.cpp 中 atcommand_reload 配置重载指令的逻辑 [Sola丶小克]
// 我们希望在执行某些 reload 指令 (@reloadbattleconf) 时能重新计算全服玩家的属性和能力值
#define Pandas_FuncLogic_ATCOMMAND_RELOAD
// 重写 instance.cpp -> instance_destroy_command 函数
// 因为 rAthena 官方实现的该函数在切换队长后的处理并不友好 [Sola丶小克]
#define Pandas_FuncLogic_Instance_Destroy_Command
// 当某个 IP 地址被判定为可以连接的时候, 不再将其列入 DDoS 攻击的判定范围 [Sola丶小克]
// 在默认 rAthena 的逻辑下, 就算某个 IP 地址就算被判定成允许连接,
// 只要他连接频度过高也依然会在终端呈现出: 发现来自 %d.%d.%d.%d 的 DDoS 攻击!
// 虽然有提示, 但是根据白名单规则却又进行了放行操作.. 因此这个提示是很没意义的.
//
// 启用此选项将改变判断逻辑, 变成如下:
// 只要 IP 地址被判定为无条件放行, 那么他将不会因为高频连接而被判定为发起了 DDoS 攻击.
#define Pandas_FuncLogic_Whitelist_Privileges
// 调整 clif.cpp 中给 clif_item_equip 函数增加 caller 参数 [Sola丶小克]
// 新增的 caller 参数用来标记调用这个函数的调用者是谁, 以便在必要情况下能够调整返回给客户端的字段值
#define Pandas_FuncParams_Clif_Item_Equip
// 在 mob.cpp 中的 mob_once_spawn_sub 增加 spawn_flag 参数 [Sola丶小克]
// 新增的 spawn_flag 参数可以用来控制召唤出来的魔物是不是 BOSS (可以被 BOSS 雷达探测)
#define Pandas_FuncDefine_Mob_Once_Spawn_Sub
// 在 mob.cpp 中的 mob_once_spawn 增加 spawn_flag 参数 [Sola丶小克]
// 新增的 spawn_flag 参数可以用来控制召唤出来的魔物是不是 BOSS (可以被 BOSS 雷达探测)
// 此选项依赖 Pandas_FuncDefine_Mob_Once_Spawn_Sub 的拓展
#ifdef Pandas_FuncDefine_Mob_Once_Spawn_Sub
#define Pandas_FuncDefine_Mob_Once_Spawn
#endif // Pandas_FuncDefine_Mob_Once_Spawn_Sub
// 在 map.cpp 中的 map_getmob_boss 增加 alive_first 参数 [Sola丶小克]
// 新增的 alive_first 参数可以指定优先返回存活着的 BOSS 魔物
#define Pandas_FuncDefine_Mob_Getmob_Boss
// 在 mob.cpp 中的 mvptomb_create 增加 killer_gid 参数 [Sola丶小克]
// 新增的 killer_gid 参数用于传递杀死 MVP 玩家的游戏单位编号
#define Pandas_FuncParams_Mob_MvpTomb_Create
#endif // Pandas_FuncIncrease
// ============================================================================
// 封包修改组 - Pandas_PacketFunction
// ============================================================================
#ifdef Pandas_PacketFunction
// 没有什么需要修改
#endif // Pandas_PacketFunction
// ============================================================================
// 原创功能组 - Pandas_CreativeWork
// ============================================================================
#ifdef Pandas_CreativeWork
// 以下选项开关需要依赖 Pandas_Database_Yaml_BeQuiet 的拓展
#ifdef Pandas_Database_Yaml_BeQuiet
// 是否启用终端控制台的信息翻译机制 [Sola丶小克]
#define Pandas_Console_Translate
#endif // Pandas_Database_Yaml_BeQuiet
// 扩展信息配置文件 (Msg_conf) 的 ID 最大上限,
// 同时提供 msg_txt_cn 宏定义函数, 方便在工程中使用自定义信息 [Sola丶小克]
#define Pandas_Message_Conf
// 对消息文件进行清理, 移除几乎用不到的其他国家语言
// 同时也暂时移除掉 langtype 管理员指令, 这个指令目前不太合适熊猫模拟器
// 主要留下: 英文, 简体中文, 繁体中文 这三种. [Sola丶小克]
#define Pandas_Message_Reorganize
// 将部分硬编码的字符串提取到消息文件中 [Sola丶小克]
// 这么做的主要目的是在有需要的时候, 可以将内容进行汉化或者其他处理
#define Pandas_Message_Hardcode_Extract
// 是否支持在 map_athena.conf 中设定封包混淆密钥 [Sola丶小克]
#ifdef PACKET_OBFUSCATION
#define Pandas_Support_Specify_PacketKeys
#endif // PACKET_OBFUSCATION
// 是否支持读取 UTF8-BOM 编码的配置或者数据文件 [Sola丶小克]
#define Pandas_Support_UTF8BOM_Files
// 在使用 _M/_F 注册的时候, 能够限制使用中文等字符作为游戏账号 [Sola丶小克]
// 这里的 PCRE_SUPPORT 在"项目属性 -> C/C++ -> 预处理器"中定义
#ifdef PCRE_SUPPORT
#define Pandas_Strict_Userid_Verification
#endif // PCRE_SUPPORT
// 是否支持隐藏角色服务器的在线人数 [Sola丶小克]
#define Pandas_Support_Hide_Online_Players_Count
// 是否扩展魔物名称能展现的信息, 比如体型、种族、属性 [Sola丶小克 改进]
#define Pandas_MobInfomation_Extend
// 是否加强 2013-12-23 以及 2013-08-07 客户端的混淆密钥 [Sola丶小克]
#define Pandas_Packet_Obfuscation_Keys
// 使影子装备可以支持插卡, 而不会被强制转换成普通道具 [Sola丶小克]
// 也使得卡片可以设置为可插入到影子装备, 而不会被系统判定为无效道具, 被变成杂货物品(IT_ETC)
#define Pandas_Shadowgear_Support_Card
// 以下选项依赖 Pandas_Struct_Item_Data_Properties 的拓展
#ifdef Pandas_Struct_Item_Data_Properties
// 启用道具特殊属性的部分生效代码 [Sola丶小克]
// 此选项开启后 (item_properties.yml) 数据库中以下选项才能发挥作用:
//
// Property 节点的 &1 = 避免物品被玩家主动使用而消耗
// Property 节点的 &2 = 避免物品被作为发动技能的必要道具而消耗
#define Pandas_Item_Properties
// 是否启用护身符系统 [Sola丶小克]
// 此选项开启后 (item_properties.yml) 数据库中以下选项才能发挥作用:
//
// Property 节点的 &4 = 该道具为护身符道具
#define Pandas_Item_Amulet_System
// 是否启用道具外观控制机制 [Sola丶小克]
// 此选项开启后 (item_properties.yml) 数据库中以下选项才能发挥作用:
//
// ControlViewID 节点中的 InvisibleWhenISee 子节点
// ControlViewID 节点中的 InvisibleWhenTheySee 子节点
// 此选项依赖 Pandas_FuncParams_Clif_Item_Equip 的拓展
#ifdef Pandas_FuncParams_Clif_Item_Equip
#define Pandas_Item_ControlViewID
#endif // Pandas_FuncParams_Clif_Item_Equip
// 是否启用特殊的道具掉落公告规则 [Sola丶小克]
// 此选项开启后 (item_properties.yml) 数据库中以下选项才能发挥作用:
//
// AnnouceRules 节点的 &1 - 打死魔物, 魔物将道具掉落到地上时公告
// AnnouceRules 节点的 &2 - 打死魔物, 掉落 MVP 奖励到玩家的背包时公告
// AnnouceRules 节点的 &4 - 使用"偷窃"技能, 从魔物身上偷到物品时公告
#define Pandas_Item_Special_Annouce
#endif // Pandas_Struct_Item_Data_Properties
// 使 pointshop 类型的商店能支持指定变量别名, 用于展现给玩家 [Sola丶小克]
#define Pandas_Support_Pointshop_Variable_DisplayName
// 使墓碑中的魔物名称能尊重 override_mob_names 战斗配置选项的设置 [Sola丶小克]
#define Pandas_Make_Tomb_Mobname_Follow_Override_Mob_Names
// 检测 import 目录是否存在, 若不存在能够从 import-tmpl 复制一份 [Sola丶小克]
#define Pandas_Deploy_Import_Directories
// 是否对数据库配置相关的一系列逻辑进行优化 [Sola丶小克]
//
// 目前主要包括以下几个改动:
//
// --------------------------------------
// 改动一:重新整理 inter_athena.conf 中对各个 codepage 选项的定义
// --------------------------------------
//
// 在 rAthena 原始的代码中:
//
// char_server_db 和 map_server_db 通过 default_codepage 选项控制编码
// 而其他的 login_server_db, ipban_db_db, log_db_db 则各自有自己的 codepage 设置项
// 且后面这几个数据库连接时, 并不尊重 default_codepage 选项.
//
// 这样其实对于无法查看代码的用户而言非常容易混淆, 因为 default_codepage 选项并不总是 default
// 为此我们进行了一些调整, 让它看起来更加合理.
//
// 调整之后各个选项的逻辑如下:
//
// 我们为 char_server_db 和 map_server_db 也分配自己的 codepage 设置项.
// 当各个连接的 codepage 设置项为空的时候, 则默认使用 default_codepage 选项的值作为默认编码.
//
// --------------------------------------
// 改动二:使用数据库编码自动判定机制
// --------------------------------------
//
// 与数据库建立连接时, 如果配置的 codepage 等于 auto, 那么会根据特定规则自动选择编码
//
// 调整的细节需求点如下所示:
//
// - 能够输出目标数据库当前所使用的编码
// - 当在 inter_athena.conf 中指定了 codepage 时, 能提示最终使用的编码
// - 若目标数据库使用 utf8 或者 utf8mb4 编码, 为了兼容性考虑会根据操作
// 系统语言来选择使用 gbk 或 big5 编码, 若不是简体中文也不是繁体中文则直接
// 使用当前数据库的 `character_set_database` 编码.
//
// --------------------------------------
// 改动三:用 mysql_set_character_set 来设置 MySQL 的编码字符集
// --------------------------------------
#define Pandas_SQL_Configure_Optimization
// 是否启用一列用于控制角色称号的指令、事件等等 [Sola丶小克]
#define Pandas_Character_Title_Controller
#ifndef _WIN32
// 在 Linux 环境下输出信息时, 能转换成终端自适应编码 [Sola丶小克]
// 由于 rAthena 全部终端的输出默认只能使用 ANSI 编码, 完全没考虑会输出中文的情况
// 这会导致在终端输出中文的时候只能是 GBK 或 BIG5 中的其中一种,
// 为了让终端显示中文的角色名, 通常只能将系统的语言设置为 GBK 或 BIG5 其中一种编码
//
// 但现在 UTF8 的支持已经是 Liunx 终端的标配,
// 我们完全可以在 GBK 或 BIG5 字符输出的时候将其转变成 UTF8 编码输出.
// 启用此选项后, 程序会根据系统语言, 将对应编码的文本在输出到终端之前转换成 UTF8 编码再输出
// 以此解决乱码问题, 使之可以完美呈现中文控制台信息...
//
// 注意: 当前仅支持终端编码为 utf8 时的转化, 请确保 locale 指令返回的语言选项中符合以下任何一种:
// - POSIX
// - C.utf8
// - en_US.utf8
// - zh_CN.utf8
// - zh_TW.utf8
// 可以通过 export LANG="zh_TW.utf8" 这样的方式来临时切换编码进行测试
//
// 使用 locale -a 可以观察本机可以启用的编码, 如若类似 zh_CN.utf8 等选项不在返回值中,
// 那么说明你的系统没有安装中文语言包, 不同的 Linux 发行版安装中文语言包的方法各有不同, 请上网查阅
#define Pandas_Console_Charset_SmartConvert
#endif // _WIN32
// 建立 MySQL 连接的时候主动禁止 SSL 模式 [Sola丶小克]
// 在 MySQL 8.0 (或更早之前的某个版本) 开始, 由于 MySQL 默认启用了 SSL 连接模式.
// 这会导致在没有安全证书的情况下, 无法建立正常的数据库连接.
// 因此我们在与 MySQL 服务器建立连接的时候主动设置一下, 禁用掉 SSL 连接模式.
//
// 备注: 目前仅在 Windows 环境下需要此操作, 在 Linux 环境下测试可直连 MySQL 8.0 暂时没问题
#ifdef _WIN32
#define Pandas_MySQL_SSL_Mode_Disabled
#endif // _WIN32
// 以下选项开关需要依赖 Pandas_Struct_Autotrade_Extend 的拓展
#ifdef Pandas_Struct_Autotrade_Extend
// 是否启用玩家挂起子系统 (在原来离线挂店的基础上, 额外新增两种不同类型的挂起方式)
// 方式一: @suspend - 离线挂机, 角色在游戏内将永久在线
// 方式二: @afk - 离开模式, 角色头上会顶一个 AFK 帽子并坐到地上
// 上述这两种方式都是 autotrade 的拓展, 因此需要依赖 Pandas_Struct_Autotrade_Extend 的调整
#define Pandas_Player_Suspend_System
#endif // Pandas_Struct_Autotrade_Extend
// 使公会的初始化人数以及“扩充组合体制”(GD_EXTENSION)每级增加人数可被宏定义 [Sola丶小克]
// 拓展出来两个宏: GUILD_INITIAL_MEMBER(初始化人数) 和 GUILD_EXTENSION_PERLEVEL (扩充组合体制每级增加人数)
#define Pandas_Guild_Extension_Configure
// 是否支持使用 @recall 等指令单独召唤离线挂店 / 离线挂机的角色
// 主要用于管理员调整挂机单位的站位, 避免阻挡到其他的 NPC 或者传送点等 [Sola丶小克]
// 此选项依赖以下拓展, 任意一个不成立则将会 undef 此选项的定义
// - Pandas_Struct_Map_Session_Data_MultiTransfer
// - Pandas_Struct_Map_Session_Data_Autotrade_Configure
// - Pandas_Struct_Map_Session_Data_Skip_LoadEndAck_NPC_Event_Dequeue
#define Pandas_Support_Transfer_Autotrade_Player
#ifndef Pandas_Struct_Map_Session_Data_MultiTransfer
#undef Pandas_Support_Transfer_Autotrade_Player
#endif // Pandas_Struct_Map_Session_Data_MultiTransfer
#ifndef Pandas_Struct_Map_Session_Data_Autotrade_Configure
#undef Pandas_Support_Transfer_Autotrade_Player
#endif // Pandas_Struct_Map_Session_Data_Autotrade_Configure
#ifndef Pandas_Struct_Map_Session_Data_Skip_LoadEndAck_NPC_Event_Dequeue
#undef Pandas_Support_Transfer_Autotrade_Player
#endif // Pandas_Struct_Map_Session_Data_Skip_LoadEndAck_NPC_Event_Dequeue
// 是否支持根据系统语言读取对应的消息数据库文件 [Sola丶小克]
// 此选项依赖 Pandas_Support_UTF8BOM_Files 的拓展
#ifdef Pandas_Support_UTF8BOM_Files
#define Pandas_Adaptive_Importing_Message_Database
#endif // Pandas_Support_UTF8BOM_Files
// 是否支持处理 Windows 10 编码选项带来的中文乱码问题 [Sola丶小克]
// Beta: Use Unicode UTF-8 for worldwide language support
// 开启后将会根据当前操作系统的语言, 重新设定终端的输出编码为我们预期的编码
// 备注: 目前仅在 Windows 环境下需要此操作
#ifdef _WIN32
#define Pandas_Setup_Console_Output_Codepage
#endif // _WIN32
// 实验性读取 SSO 登录封包传递的 MAC 地址和客户端内网 IP 地址信息 [Sola丶小克]
// 参考: https://github.com/brAthena/brAthena20180924/commit/51dd5f2cc2fa9967cc65e681d71038ef34e6cd6c
//
// 已知在 20180620 客户端中, 当本机有多个网络连接的时候, 只会读取第一个网络连接的 IP 地址
// 而第一个网络连接的 IP 不一定是真正联网通讯用的 IP 地址, 因此只能作为一个不完全可靠的特征来参考
// 经过简单测试, MAC 地址是可靠的, 但据 Jian916 提醒可能部分用户会无法读取到 MAC 地址
// 读取不到的情况暂时无法模拟出来, 等待进一步的情报
#define Pandas_Extract_SSOPacket_MacAddress
// 使程序能够持久化保存每个道具的脚本字符串 [Sola丶小克]
// 此选项依赖 Pandas_Struct_Item_Data_Script_Plaintext 的拓展
#ifdef Pandas_Struct_Item_Data_Script_Plaintext
#define Pandas_Persistence_Itemdb_Script
#endif // Pandas_Struct_Item_Data_Script_Plaintext
// 是否启用角色光环机制 [Sola丶小克]
// 此选项依赖以下拓展, 任意一个不成立则将会 undef 此选项的定义
// - Pandas_Struct_Unit_CommonData_Aura
#define Pandas_Aura_Mechanism
#ifndef Pandas_Struct_Unit_CommonData_Aura
#undef Pandas_Aura_Mechanism
#endif // Pandas_Struct_Unit_CommonData_Aura
// 优化对极端计算的支持 (AKA: 变态服拓展包) [Sola丶小克]
// 主要用来解决因为 rAthena 主要定位于仿官服带来的各种数值计算的限制
//
// - 避免 MATK 和其他属性计算时带来的溢出异常
// 例如: MATK 若超过 65535 之后会直接归零, 导致魔法伤害为 0 的问题
// - 将可能会导致计算时溢出的变量类型进行提升
// 例如: 在进行 cardfix 等 bonus 计算时由于变量类型限制带来的溢出或瓶颈
// - 解除角色或其他拥有六维属性的单位的加点上限
// 默认的六维属性最大上限是 32767, 解除之后理论可达到 0x7FFFFFFF
#define Pandas_Extreme_Computing
// 是否启用战斗记录机制 (输出, 承伤等等) [Sola丶小克]
// 此选项依赖 Pandas_Struct_Unit_CommonData_BattleRecord 的拓展
#ifdef Pandas_Struct_Unit_CommonData_BattleRecord
#define Pandas_BattleRecord
#endif // Pandas_Struct_Unit_CommonData_BattleRecord
// 是否启用 bonus_script 的唯一编号机制 [Sola丶小克]
// 此选项依赖以下拓展, 任意一个不成立则将会 undef 此选项的定义
// - Pandas_Struct_BonusScriptData_Extend
// - Pandas_Struct_Map_Session_Data_BonusScript_Counter
#define Pandas_BonusScript_Unique_ID
#ifndef Pandas_Struct_BonusScriptData_Extend
#undef Pandas_BonusScript_Unique_ID
#endif // Pandas_Struct_BonusScriptData_Extend
#ifndef Pandas_Struct_Map_Session_Data_BonusScript_Counter
#undef Pandas_BonusScript_Unique_ID
#endif // Pandas_Struct_Map_Session_Data_BonusScript_Counter
// 是否启用对负载均衡的友好处理支持 [Sola丶小克]
// 启用阿里云和 Google Cloud 等云计算平台的负载均衡业务后, 通常会对存活的后端服务器进行健康监测
// 此举会导致终端出现大量的无价值信息. 比如:
// 大量健康检查探测服务器的 IP 地址不断的与我们的游戏服务端建立连接, 确认我们端口正常工作后就立刻关闭连接
// 以及他们频繁访问我们的游戏服务器, 导致我们将他们判定为发起了 DDoS 攻击的提示信息.
//
// 启用此选项后, 我们将支持在 packet_athena.conf 中设置这些健康检查的服务器 IP 区段
// 在不影响他们对我们正常服务器进行探测的情况下, 不再显示出大量无价值信息到终端干扰游戏管理员观察服务器状态.
#define Pandas_Health_Monitors_Silent
// 解锁仓库以及背包的最大容量限制 [Sola丶小克]
// 目前经过本地测试可以到 2000 个道具不会出现其他问题, 但建议大家不要设置太大
//
// 注意事项:
// 如果对仓库容量有扩充需求, 应该优先考虑开设多个仓库, 而不是提高单个仓库的容量,
// 因为过大的容量在每次打开仓库或者背包的时候会带来客户端有些卡顿的感觉 (服务端送来超多内容然后客户端填充他们)
#define Pandas_Unlock_Storage_Capacity_Limit
// 使 setunitdata 针对魔物单位的基础状态设置不会被能力过程直接洗刷掉 [Sola丶小克]
// 此选项依赖 Pandas_Struct_Mob_Data_Special_SetUnitData 的拓展
#ifdef Pandas_Struct_Mob_Data_Special_SetUnitData
#define Pandas_Persistent_SetUnitData_For_Monster_StatusData
#endif // Pandas_Struct_Mob_Data_Special_SetUnitData
// 是否扩展 e_job_types 枚举类型的可选值 [Sola丶小克]
// 此项目会影响默认可用的 NPC 外观数量, 提取自客户端 npcidentity.lub 文件
#define Pandas_Update_NPC_Identity_Information
// 是否支持 future 封装以便执行异步任务 [Sola丶小克]
//
// 此功能由 inhyositsu <inhyositsu@gmail.com> 实现,
// 后续由 Sola丶小克 进行微调并汇入熊猫模拟器
#define Pandas_Support_Future_Execution
#endif // Pandas_CreativeWork
// ============================================================================
// 官方缺陷修正组 - Pandas_Bugfix
// ============================================================================
#ifdef Pandas_Bugfix
// 修正逐影的“抄袭/复制”技能,在偷到技能后角色服务器存档时可能会出现 -8 报错的问题 [Sola丶小克]
// 被抄袭的技能的 flag 是 SKILL_FLAG_PLAGIARIZED 值为 2
// 但好不歹的写入到数据库之前 rAthena 计算技能等级的时候是拿着 flag - SKILL_FLAG_REPLACED_LV_0 (值为 10)
// 使抄袭的技能等级变成了 -8 级, 而数据库中的字段无法保存负数, 认为超过了保存范围而报错
// 若触发报错的话, 那么逐影的技能将全部丢失. 下次上线之后会发现技能是空的.
//
// 备注: 2021年7月12日 测试的时候, 发现有的数据库在经过配置后不会报错, -8 会被保存成 0
// 这种情况下技能不会全丢, 但也不是一种正确的预期情况
//
// 实际上抄袭和复制到的技能并不需要被写入到 skill 表, 而是记录在变量中
// 抄袭对应的技能编号保存在变量: SKILL_VAR_PLAGIARISM 等级是 SKILL_VAR_PLAGIARISM_LV
// 复制对应的技能编号保存在变量: SKILL_VAR_REPRODUCE 等级是 SKILL_VAR_REPRODUCE_LV
#define Pandas_Fix_ShadowChaser_Lose_Skill
// 解决魔物死亡但客户端没移除魔物单位的问题 [Sola丶小克]
//
// 造成问题存在几个可能的原因, 且这些原因在逻辑上都是合理存在的, 因此每种情况都要进行规避:
//
// 第一种情况:
// 魔物死亡后会发送 clif_clearunit_area 的 CLR_DEAD 封包给客户端
// 但是由于复杂网络结构 (比如: 使用了转发\盾机\负载均衡), 可能会导致这个小封包粘在上一个封包中发出
// 导致客户端无法正常收到和解析这个小封包.
//
// 缓解措施是: 在一个指定的时间间隔内, 由服务端补发一个封包给客户端
// 但付出的代价是每个魔物死亡都需要额外发送一个封包, 请根据网络环境酌情选择开启或者关闭
// 可通过 repeat_clearunit_interval 战斗配置选项控制发送间隔
// 但是要注意, 取值不能太大 (间隔不能太久), 否则一方面没意义,
// 另外一方面如果魔物由于其他机制用相同的 GameID 复活则会导致它被错误的移除
//
// 第二种情况:
// 部分技能会击退魔物, 当你召唤 100 个波利,然后用暴风雪打距离屏幕边缘的怪物
// 技能读条完毕后立刻往反方向移动 (提前 @speed 1), 等暴风雪结束后回来观看, 较大概率会有魔物死亡但没被移除
//
// 造成这一现象的原因是, 当魔物死亡的时候 clif_clearunit_area 的 CLR_DEAD 封包会发送给
// 死亡的魔物周围 AREA_SIZE 格子的其他单位, 但如果你跑得太快, 那么封包发送的时候你已经不在接收范围内了
// 最后导致看起来和没收到 clif_clearunit_area 的 CLR_DEAD 封包一样, 客户端就无法移除它
//
// 缓解措施是: 在发送 clif_clearunit_area 的 CLR_DEAD 封包时, 给与一个更大的 AREA_SIZE
//
// 第三钟情况:
// 这是剩下的实际上能在特定机器上重现, 并最终验证解决了的情况.
//
// 魔物死亡时候的 CLR_DEAD 封包发送是使用 clif_clearunit_delayed 延迟发送的
// 如果在 clif_clearunit_delayed 发送之后服务端又给客户端发送了移动封包,
// 那么客户端将再次生成一个空血魔物, 有时甚至能看到魔物空血了还在移动
//
// 确定且经过验证的解决方案: 魔物只要死亡就立刻停止移动 (感谢 "Mr.Siu" 提供环境配合验证)
//
// 可能还会有其他情况导致类似的事情发生, 碰见再具体分析
#define Pandas_Ease_Mob_Stuck_After_Dead
// 修正潜在可能存在算术溢出的情况 [Sola丶小克]
#define Pandas_Fix_Potential_Arithmetic_Overflow
// 修正未判断 sscanf 返回值可能导致程序工作不符合预期的问题 [Sola丶小克]
#define Pandas_Fix_Ignore_sscanf_Return_Value
// 修正在部分情况下角色公会图标刷新不及时的问题 [Sola丶小克]
#define Pandas_Fix_GuildEmblem_Update
// 修正部分简体、繁体中文字符作为角色名时, 会被变成问号的问题 [Sola丶小克]
// 例如: "凯撒"中的"凯"字, "聽風"中的"聽"字等
#define Pandas_Fix_Chinese_Character_Trimmed
// 修正使用 duplicate 或 copynpc 复制商店类型的 NPC 时, 由于没有完整的复制出售的商品列表,
// 导致使用 npcshop* 系列指令调整复制后的商店内容时, 原商店的内容也会同步受到影响的问题.
// 目前根据各位脚本大神的反馈, 更希望各个商店 NPC 的商品列表内容是各自独立的 [Sola丶小克]
#define Pandas_Fix_Duplicate_Shop_With_FullyShopItemList
// 修正 npc_unloadfile 和 npc_parsesrcfile 的行为会被空格影响的问题 [Sola丶小克]
// 如果 @reloadnpc 时给定的路径带空格, 系统将无法正确的 unloadnpc, 导致 npc 重复出现
#define Pandas_Fix_NPC_Filepath_WhiteSpace_Effects
// 修正 skill_db.yml 的 ItemCost 字段指定的 Item 道具不存在时
// 会导致地图服务器直接崩溃的问题. 看代码应该是 rAthena 的工程师手误了 [Sola丶小克]
#define Pandas_Fix_SkillDB_ItemCost_NoexistsItem_Crash
// 修正离线挂店的角色在服务器重启自动上线后, 头饰外观会暂时丢失的问题 [Sola丶小克]
#define Pandas_Fix_Autotrade_HeadView_Missing
// 修正角色服务器加载不存在的角色信息时, 由于返回值判断错误而导致流程继续执行的问题 [Sola丶小克]
// 例如: 当离线挂店/挂机角色由于各种意外不存在于 char 表里面时, 就会触发误判
#define Pandas_Fix_Char_FromSql_NextRow_Result_Logic
// 修正在 20180620 客户端中, 如果在玩家过图时将宠物变回宠物蛋,
// 背包中对应的宠物蛋没有出现的问题 (pet_disable_in_gvg 战斗配置选项) [Sola丶小克]
#define Pandas_Fix_LoadEndAck_Pet_Return_To_Egg_Missing
// 修正当前坐标就是移动的目的地时, 可能会导致单位无法移动或被传送的问题 [Sola丶小克]
//
// 重现方法:
// 1. 使物品的掉率尽可能的高
// 2. 召唤 10 到 20 只波利, 并杀死其中一两个
// 3. 其他波利会为了拾取死亡波利掉落的东西, 往一个方向移动
//
// 出现结果:
// - 在 Debug 环境下, 较高概率出现有些波利会被卡住再也无法移动的现象
// - 在 Release 环境下, 较高概率出现有些波利往掉落道具的地方跳动时跳着跳着就消失了,
// 被随机传送到本地图的其他位置去了
//
// 原因分析:
// 出现此问题是因为在某种情况下, 魔物的当前所在坐标和即将移动到的目的地坐标完全一致
// 这会导致单位无法进行实质性的移动操作, 造成被卡住的现象.
//
// 临时方案:
// 在 unit_walktoxy_sub 函数中, 如果发现当前坐标和目的地坐标一致, 那么放弃移动.
// 但问题更本质的原因是: 为什么会出现这样的情况...
#define Pandas_Fix_Same_Coordinate_Move_Logic
// 修正更换队长后, 新队长无法看到销毁副本按钮的问题
// 此选项开关需要依赖 Pandas_FuncLogic_Instance_Destroy_Command 的拓展 [Sola丶小克]
#ifdef Pandas_FuncLogic_Instance_Destroy_Command
#define Pandas_Fix_Dungeon_Command_Status_Refresh
#endif // Pandas_FuncLogic_Instance_Destroy_Command
// 修正当 block_free 数组中存在重复指针时, 会导致的无效指针错误的问题 [Sola丶小克]
#define Pandas_Fix_DuplicateBlock_When_Freeblock_Unlock
// 修正复兴后 "魔术子弹"(GS_MAGICALBULLET) 的伤害溢出问题 [Sola丶小克]
// 处于该状态下若攻击者的 matk_min 小于被攻击者的 mdef 则会导致
// 这一次普攻出现计算溢出的情况, 可以秒杀一切 BOSS
#define Pandas_Fix_MagicalBullet_Damage_Overflow
// 修正 csv2yaml 辅助工具可能存在的多余反斜杠问题 [Sola丶小克]
#define Pandas_Fix_Csv2Yaml_Extra_Slashes_In_The_Path
// 修正 yaml2sql 辅助工具无法生成不含 Body 节点的空 sql 问题 [Sola丶小克]
// 当来源文件不存在 Body 节点时, 应认为数据为空而生成空 sql 文件, 而不是直接放弃生成
#define Pandas_Fix_Yaml2Sql_NoBodyNode_Break
// 修正频道系统出现频道重名时, 没有进行严格校验,
// 导致地图服务器结束时会提示存在内存泄露的问题 [Sola丶小克]
#define Pandas_Fix_Duplicate_Channel_Name_Make_MemoryLeak
// 修正 FAW 魔法傀儡 (技能编号: 2282) 重复扣减原石碎片的问题 [Sola丶小克]
#define Pandas_Fix_MagicDecoy_Twice_Deduction_Of_Ore
// 修正 progressbar 某些情况下会导致角色无法移动的问题 [Sola丶小克]
//
// 可能的现象:
// - 在 progressbar 期间使用 @load 或 @jump 会导致角色传送后无法移动
// - 在 progressbar 之前使用了 menu / select 会导致打断进度条后角色无法移动
#define Pandas_Fix_Progressbar_Abort_Stuck
// 修正 progressbar 期间使用 @refresh 或 @refreshall 会导致角色无法移动的问题 [Sola丶小克]
#define Pandas_Fix_Progressbar_Refresh_Stuck
// 修正挂店中的角色被临时踢下线后, 如果趁着地图服务器还未重启而直接进入游戏
// 并对手推车中原先离线摆摊的商品进行增删操作, 可能会导致下次地图服务器启动时出现 vending_reopen 错误 3 的情况,
// 更严重的甚至在下次重启地图服务器后出现离线挂店的商品与价格的错位 [Sola丶小克]
#define Pandas_Fix_When_Relogin_Then_Clear_Autotrade_Store
// 发送邮件之前, 对附件中的道具进行更加严格的检查
// 当检测到附件内容非法的时候也能正确的重置客户端物品栏中的状态, 避免错乱
// 此选项开关需要依赖 Pandas_Struct_S_Mail_With_Details 的拓展 [Sola丶小克]
#ifdef Pandas_Struct_S_Mail_With_Details
#define Pandas_Fix_Mail_ItemAttachment_Check
#endif // Pandas_Struct_S_Mail_With_Details
// 修正 cloak 的状态处理过于令人费解的问题
// 此选项开关需要依赖 Pandas_Struct_Status_Change_Cloak_Reverting 的拓展 [Sola丶小克]
#ifdef Pandas_Struct_Status_Change_Cloak_Reverting
#define Pandas_Fix_Cloak_Status_Baffling
#endif // Pandas_Struct_Status_Change_Cloak_Reverting
// 修正获取道具分组的随机算法权重不符合预期的问题 [Sola丶小克]
// 所有最终使用 item_group_db.yml 数据的指令函数 (比如 getrandgroupitem 等)
// 最后都会经过 itemdb.cpp 中的 get_random_itemsubgroup 来获取随机物品
// 该函数的实现并不严谨, 随机出来的物品概率与 doc/item_group.txt 的描述不符合
// 这可能导致很多卡片或者道具过多流入到市场, 打破游戏平衡
//
// 感谢 "红狐狸" 提醒此问题
#define Pandas_Fix_GetRandom_ItemSubGroup_Algorithm
// 修正在保存 s_storage 数据期间如果发生了存储内容的增删改时,
// 特定操作流程下可能诱发数据丢失的问题 [Sola丶小克]
//
// 可能的重现步骤:
// - 编写一个脚本, 调用 atcommand("@clearstorage"); 之后立刻调用 storagegetitem 501,1;
// - 执行上述脚本后立刻小退, 重复多次
// - 观察每次角色进入地图服务器时, 角色服务器提示加载到的仓库物品数量
// - 如果角色服务器在保存仓库数据时比较慢, 那么你会看到反复小退仓库的数量是: 1、0、1、0...
#define Pandas_Fix_Storage_DirtyFlag_Override
// 修正写入公会仓库日志时没有对角色名进行转义处理的问题 [Sola丶小克]
//
// 可能的重现步骤:
// - 创建角色名带单引号的角色
// - 加入公会, 开启公会仓库, 存入物品
// - 此时地图服务器在写入 guild_storage_log 的时候将抛出错误
//
// 感谢 "小林" 反馈此问题
#define Pandas_Fix_Guild_Storage_Log_Escape_For_CharName
// 修正使用 @showexp 指令后呈现的经验值数值会错误的问题 [Sola丶小克]
// 备注: 单次获得的经验超过 long 的有效阈值范围后就会溢出成负数, 但最新的有效经验值区间是 int64
#define Pandas_Fix_GainExp_Display_Overflow
// 修正 inter_server.yml 中的 Max 超大时没有妥善处理的问题 [Sola丶小克]
// 启用后 Max 字段的值最多不能超过 MAX_STORAGE 的值
#define Pandas_Fix_INTER_SERVER_DB_Field_Verify
// 修正特殊情况下 bonus_script 拥有 BSF_REM_ON_LOGOUT 标记位,
// 也会在重新进入游戏时生效的问题 [Sola丶小克]
//
// 正常情况下角色若正常退出游戏, 标记位包含 BSF_REM_ON_LOGOUT 的 bonus_script 不会被记录,
// 那怕由于操作仓库而导致角色数据被提前保存, 也会在角色退出的时候被清除.
//
// 但如果在包含 BSF_REM_ON_LOGOUT 的 bonus_script 记录在数据库时强制关闭地图服务器,
// 那么这条 bonus_script 将会保存到下次服务器启动, 并且玩家进入游戏时还有效.
//
// 解决方案: 进入游戏加载 bonus_script 的时候抛弃拥有 BSF_REM_ON_LOGOUT 标记位的数据
#define Pandas_Fix_Bonus_Script_Effective_Timing_Exception