CharacterManager 0.0.1a0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,570 @@
1
+ """Module-level constants for the Character package.
2
+
3
+ Centralising defaults here keeps the runtime files free of magic numbers
4
+ and lets you grep for a balance knob in one place. The package still
5
+ works without ever touching this file — every constant has a sane
6
+ default applied at the dataclass level.
7
+ """
8
+
9
+
10
+ from __future__ import annotations
11
+
12
+ import re
13
+ import sys
14
+ from typing import FrozenSet, Literal, Tuple, Dict
15
+ from dataclasses import dataclass
16
+ from decimal import Decimal
17
+
18
+ __version__ = "0.0.1-alpha"
19
+ __author__ = "PlayGames-2020"
20
+ __summary__ = ""
21
+
22
+ _match = re.match(r"(\d+)\.(\d+)\.(\d+)(?:-(.+))?", __version__)
23
+
24
+ if _match: major, minor, patch, tag = _match.groups()
25
+ else: major, minor, patch, tag = 0, 0, 0, "unknown"
26
+
27
+ VERSION_INFO = (int(major), int(minor), int(patch), tag or "release")
28
+
29
+ NAME = __name__
30
+
31
+ _REQUIRED_PY = (3, 9)
32
+ if sys.version_info < (3, 9):
33
+ runtime = ".".join(str(v) for v in (_REQUIRED_PY))
34
+ info = f"{__name__} requires Python {runtime} or higher" \
35
+ f"(current: {sys.version.split()[0]})"
36
+ print(info)
37
+ raise RuntimeError(info)
38
+
39
+
40
+ # ---------------------------------------------------------------------------
41
+ # Identity defaults
42
+ # ---------------------------------------------------------------------------
43
+
44
+
45
+ DEFAULT_SEX: Literal["\u2014", "man", "woman", "hermaphrodite"] = "\u2014"
46
+
47
+ DEFAULT_SEXUALITY: Literal[
48
+ "\u2014", "heterosexual"
49
+ ] = "\u2014"
50
+
51
+ DEFAULT_RACE: Literal[
52
+ "human", "elf", "dwarf", "orc", "halfling", "dragonborn",
53
+ "gnome", "troll", "half-elf", "half-orc", "half-human", "vampire",
54
+ ] = "human"
55
+
56
+ DEFAULT_JOB_RPG: Literal[
57
+ "unemployed", "barbarian", "warrior", "ranger",
58
+ "rogue", "mage", "cleric", "thief", "farmer",
59
+ ] = "unemployed"
60
+
61
+ DEFAULT_JOB: Literal[
62
+ "unemployed"
63
+ ] = "unemployed"
64
+
65
+ DEFAULT_SOCIAL_CLASS: Literal["outsider", "noble"] = "outsider"
66
+
67
+ DEFAULT_AGE = 18
68
+
69
+ DEFAULT_WEIGHT = round(60.0, 2) # kg (float to accept values like 60.5, 72.3 ...)
70
+
71
+ DEFAULT_HEIGHT = Decimal("1.60")
72
+
73
+ DEFAULT_IS_PREGNANT: Literal[False, True] = False
74
+
75
+ DEFAULT_PREGNACY_STATE: Literal[0, 1, 2, 3, 4, 5] = 0
76
+
77
+
78
+ # ---------------------------------------------------------------------------
79
+ # Identity option lists (read-only — never mutate these tuples)
80
+ # ---------------------------------------------------------------------------
81
+
82
+
83
+ SEX_OPTIONS = ("man", "woman", "hermaphrodite")
84
+
85
+ SEXUALITY_OPTIONS = (
86
+ "heterosexual", "gay", "lesbian",
87
+ "bisexual", "pansexual", "asexual",
88
+ )
89
+
90
+ RACE_OPTIONS = (
91
+ "human", "elf", "dwarf", "orc", "halfling", "dragonborn",
92
+ "gnome", "troll", "half-elf", "half-orc", "half-human", "vampire",
93
+ )
94
+
95
+ JOB_RPG_OPTIONS = (
96
+ "unemployed", "barbarian", "warrior", "ranger",
97
+ "rogue", "mage", "cleric", "thief", "farmer",
98
+ )
99
+
100
+ JOB_OPTIONS = (
101
+ "unemployed"
102
+ )
103
+
104
+ SOCIAL_CLASS_OPTIONS = ("outsider", "noble")
105
+
106
+ WOMEN_OPTIONS = ("woman", "hermaphrodite")
107
+
108
+ SEXUALITY_BY_SEX: Dict[str, Tuple[str, ...]] = {
109
+ "man": ("heterosexual", "gay", "bisexual", "pansexual", "asexual"),
110
+ "woman": ("heterosexual", "lesbian", "bisexual", "pansexual", "asexual"),
111
+ "hermaphrodite": ("heterosexual", "bisexual", "pansexual", "asexual"),
112
+ }
113
+
114
+
115
+ # ---------------------------------------------------------------------------
116
+ # RPG stats defaults
117
+ # ---------------------------------------------------------------------------
118
+
119
+
120
+ MIN_LEVEL = 1
121
+ MAX_LEVEL = 100
122
+
123
+ XP = 0
124
+ XP_TO_NEXT = 100
125
+
126
+ HP = 100
127
+ MAX_HP = 100
128
+
129
+ MP = 30
130
+ MAX_MP = 30
131
+
132
+ STAMINA = 100
133
+ MAX_STAMINA = 100
134
+
135
+ GOLD = 0
136
+
137
+ LEVEL_XP_GROWTH = 1.25
138
+ LEVEL_UP_HP_GAIN = 10
139
+ LEVEL_UP_MP_GAIN = 5
140
+
141
+
142
+ # ---------------------------------------------------------------------------
143
+ # Race constraints (per-race age/height/weight bounds + adult threshold)
144
+ # ---------------------------------------------------------------------------
145
+
146
+
147
+ # Used by :py:meth:`Character.validate` when ``character.race`` is the
148
+ # em-dash placeholder, so the global "human" defaults still apply.
149
+ DEFAULT_RACE_FOR_VALIDATION = "human"
150
+
151
+ @dataclass(frozen=True)
152
+ class RaceConstraint:
153
+ """Per-race physical / age envelope.
154
+
155
+ All tuples are inclusive ranges. ``adult_age`` is the age at which
156
+ the race is mature (used by :py:meth:`Character.is_adult`).
157
+ """
158
+
159
+ age: Tuple[int, int]
160
+ adult_age: int
161
+ height: Tuple[Decimal, Decimal]
162
+ weight: Tuple[float, float]
163
+
164
+
165
+ RACE_CONSTRAINTS: Dict[str, RaceConstraint] = {
166
+ "human": RaceConstraint(
167
+ age=(0, 100),
168
+ adult_age=18,
169
+ height=(Decimal("1.40"), Decimal("2.20")),
170
+ weight=(40.0, 200.0),
171
+ ),
172
+ "elf": RaceConstraint(
173
+ age=(0, 1000),
174
+ adult_age=50,
175
+ height=(Decimal("1.50"), Decimal("2.10")),
176
+ weight=(35.0, 150.0),
177
+ ),
178
+ "dwarf": RaceConstraint(
179
+ age=(0, 400),
180
+ adult_age=25,
181
+ height=(Decimal("1.00"), Decimal("1.60")),
182
+ weight=(50.0, 250.0),
183
+ ),
184
+ "orc": RaceConstraint(
185
+ age=(0, 80),
186
+ adult_age=14,
187
+ height=(Decimal("1.60"), Decimal("2.40")),
188
+ weight=(60.0, 300.0),
189
+ ),
190
+ "halfling": RaceConstraint(
191
+ age=(0, 200),
192
+ adult_age=18,
193
+ height=(Decimal("0.80"), Decimal("1.30")),
194
+ weight=(25.0, 80.0),
195
+ ),
196
+ "dragonborn": RaceConstraint(
197
+ age=(0, 200),
198
+ adult_age=21,
199
+ height=(Decimal("1.60"), Decimal("2.30")),
200
+ weight=(60.0, 250.0),
201
+ ),
202
+ "gnome": RaceConstraint(
203
+ age=(0, 300),
204
+ adult_age=25,
205
+ height=(Decimal("0.90"), Decimal("1.30")),
206
+ weight=(30.0, 80.0),
207
+ ),
208
+ "troll": RaceConstraint(
209
+ age=(0, 200),
210
+ adult_age=30,
211
+ height=(Decimal("1.80"), Decimal("3.00")),
212
+ weight=(80.0, 400.0),
213
+ ),
214
+ "half-elf": RaceConstraint(
215
+ age=(0, 500),
216
+ adult_age=25,
217
+ height=(Decimal("1.50"), Decimal("2.10")),
218
+ weight=(40.0, 180.0),
219
+ ),
220
+ "half-orc": RaceConstraint(
221
+ age=(0, 100),
222
+ adult_age=16,
223
+ height=(Decimal("1.60"), Decimal("2.30")),
224
+ weight=(60.0, 280.0),
225
+ ),
226
+ "half-human": RaceConstraint(
227
+ age=(0, 150),
228
+ adult_age=20,
229
+ height=(Decimal("1.50"), Decimal("2.20")),
230
+ weight=(45.0, 220.0),
231
+ ),
232
+ "vampire": RaceConstraint(
233
+ age=(0, 1000),
234
+ adult_age=100,
235
+ height=(Decimal("1.60"), Decimal("2.10")),
236
+ weight=(50.0, 180.0),
237
+ ),
238
+ }
239
+
240
+
241
+ # ---------------------------------------------------------------------------
242
+ # Validation bounds (Character/Combat/RPG)
243
+ # ---------------------------------------------------------------------------
244
+
245
+
246
+ MIN_AGE = 0
247
+ MAX_AGE = 1500
248
+
249
+ MIN_WEIGHT = 0.1 # kg
250
+ MAX_WEIGHT = 1000.0 # kg
251
+
252
+ MIN_HEIGHT = Decimal("0.3") # meters
253
+ MAX_HEIGHT = Decimal("3.5") # meters
254
+
255
+ MIN_STAT = -100
256
+ MAX_STAT = 1000
257
+
258
+ MIN_ACCURACY = 0
259
+ MAX_ACCURACY = 100
260
+
261
+
262
+ # ---------------------------------------------------------------------------
263
+ # Job RPG stat caps (per-job-rpg allowed range for combat stats)
264
+ # ---------------------------------------------------------------------------
265
+
266
+
267
+ JOB_RPG_STAT_RANGES: Dict[str, Dict[str, Tuple[int, int]]] = {
268
+ "barbarian": {
269
+ "strength": (5, MAX_STAT),
270
+ "attack": (5, MAX_STAT),
271
+ "magic_attack": (-100, 5), # dumb-as-rocks bonus flavour
272
+ "defense": (5, MAX_STAT),
273
+ "magic_defense": (-100, 10),
274
+ "luck": (-100, MAX_STAT),
275
+ },
276
+ "warrior": {
277
+ "strength": (5, MAX_STAT),
278
+ "attack": (5, MAX_STAT),
279
+ "magic_attack": (-100, 10),
280
+ "defense": (5, MAX_STAT),
281
+ "magic_defense": (-100, 15),
282
+ "luck": (-100, MAX_STAT),
283
+ },
284
+ "ranger": {
285
+ "strength": (0, MAX_STAT),
286
+ "attack": (0, MAX_STAT),
287
+ "magic_attack": (0, MAX_STAT),
288
+ "defense": (0, MAX_STAT),
289
+ "magic_defense": (0, MAX_STAT),
290
+ "luck": (5, MAX_STAT),
291
+ },
292
+ "rogue": {
293
+ "strength": (0, MAX_STAT),
294
+ "attack": (5, MAX_STAT),
295
+ "magic_attack": (-100, 15),
296
+ "defense": (0, MAX_STAT),
297
+ "magic_defense": (-100, 15),
298
+ "luck": (5, MAX_STAT),
299
+ },
300
+ "mage": {
301
+ "strength": (-100, 10),
302
+ "attack": (-100, 8),
303
+ "magic_attack": (10, MAX_STAT),
304
+ "defense": (-100, 8),
305
+ "magic_defense": (10, MAX_STAT),
306
+ "luck": (-100, MAX_STAT),
307
+ },
308
+ "cleric": {
309
+ "strength": (0, MAX_STAT),
310
+ "attack": (0, MAX_STAT),
311
+ "magic_attack": (5, MAX_STAT),
312
+ "defense": (0, MAX_STAT),
313
+ "magic_defense": (5, MAX_STAT),
314
+ "luck": (0, MAX_STAT),
315
+ },
316
+ "thief": {
317
+ "strength": (-100, 15),
318
+ "attack": (0, MAX_STAT),
319
+ "magic_attack": (-100, 10),
320
+ "defense": (-100, 10),
321
+ "magic_defense": (-100, 10),
322
+ "luck": (10, MAX_STAT),
323
+ },
324
+ "farmer": {
325
+ "strength": (0, 25),
326
+ "attack": (0, 20),
327
+ "magic_attack": (-100, 5),
328
+ "defense": (0, 20),
329
+ "magic_defense": (-100, 10),
330
+ "luck": (-100, 15),
331
+ },
332
+ }
333
+
334
+
335
+ # ---------------------------------------------------------------------------
336
+ # Items / Inventory / Equipment
337
+ # ---------------------------------------------------------------------------
338
+
339
+
340
+ EQUIPMENT_SLOTS: tuple[str, ...] = (
341
+ "head", "chest", "legs", "feet",
342
+ "mainhand", "offhand",
343
+ "ring_left", "ring_right",
344
+ "necklace", "back", "trinket",
345
+ )
346
+
347
+ ITEM_TYPE_SLOTS: dict[str, tuple[str, ...]] = {
348
+ "weapon": ("mainhand", "offhand"),
349
+ "armor": ("head", "chest", "legs", "feet", "back"),
350
+ "jewelry": ("ring_left", "ring_right", "necklace", "trinket"),
351
+ "consumable": (),
352
+ "quest": (),
353
+ "misc": (),
354
+ }
355
+
356
+ ITEM_TYPES: tuple[str, ...] = (
357
+ "weapon", "armor", "jewelry", "consumable", "quest", "misc",
358
+ )
359
+
360
+ DEFAULT_ITEM_TYPE = "misc"
361
+
362
+ ITEM_RARITIES: tuple[str, ...] = (
363
+ "common", "uncommon", "rare", "epic", "legendary",
364
+ )
365
+
366
+ DEFAULT_ITEM_RARITY = "common"
367
+
368
+ ITEM_RARITY_VALUE_MULTIPLIER: Dict[str, float] = {
369
+ "common": 1.0,
370
+ "uncommon": 1.5,
371
+ "rare": 2.0,
372
+ "epic": 3.0,
373
+ "legendary": 5.0,
374
+ }
375
+
376
+ DEFAULT_INVENTORY_MAX_WEIGHT = 50.0 # kg
377
+ DEFAULT_ITEM_WEIGHT = 1.0 # kg
378
+ DEFAULT_ITEM_VALUE = 0 # gold
379
+
380
+
381
+ # ---------------------------------------------------------------------------
382
+ # Status effects
383
+ # ---------------------------------------------------------------------------
384
+
385
+
386
+ STATUS_TAGS: tuple[str, ...] = (
387
+ "buff", "debuff", "damage_over_time", "heal_over_time",
388
+ "stun", "silence", "stealth", "invulnerable",
389
+ )
390
+
391
+ DEFAULT_STATUS_DURATION = 3 # turns
392
+
393
+
394
+ # ---------------------------------------------------------------------------
395
+ # Skills
396
+ # ---------------------------------------------------------------------------
397
+
398
+
399
+ DEFAULT_SKILL_MANA_COST = 0
400
+ DEFAULT_SKILL_STAMINA_COST = 0
401
+ DEFAULT_SKILL_COOLDOWN = 0
402
+ DEFAULT_SKILL_POWER = 0
403
+
404
+ NPC_BLOCK_OPTIONS: tuple[str, ...] = (
405
+ "free", "taken", "married", "widowed",
406
+ "religious", "enemy", "child",
407
+ )
408
+
409
+
410
+ # ===================================================================
411
+ # Categorical blocking set
412
+ # ===================================================================
413
+ # NPCs in any of these blocks CANNOT have a relationship,
414
+ # regardless of the player's sexuality. ``widowed`` is OUT by
415
+ # design: widowers are single, it is only narrative flavor.
416
+
417
+ BLOCKED_FOR_RELATIONSHIP: FrozenSet[str] = frozenset({
418
+ "taken",
419
+ "married",
420
+ "religious",
421
+ "enemy",
422
+ "child",
423
+ })
424
+
425
+
426
+
427
+ # ===================================================================
428
+ # Pure compatibility table — single source of truth
429
+ # ===================================================================
430
+ # Keys: (player's sex, player's sexuality).
431
+ # Values: ``frozenset`` of NPC sex values with which the player can
432
+ # have a relationship.
433
+ #
434
+ # Coverage:
435
+ # - heterosexual: classic binary pair (woman↔man).
436
+ # - gay/lesbian: monosexual (only the same biological sex).
437
+ # - bisexual/pansexual: both binary sexes + hermaphrodite
438
+ # (attraction beyond the binary).
439
+ # - asexual: always empty.
440
+ # - hermaphrodite player: each explicit orientation resolves an
441
+ # ambiguity — gay includes men AND hermaphrodites (allows
442
+ # the intersex he/she-he/she pair + both identifying as gay);
443
+ # same for lesbian.
444
+ #
445
+ # Cases covered by ``.get(..., frozenset())`` in ``is_compatible``
446
+ # (do not need to be here):
447
+ # - Player.sex == "\u2014" (not configured) → key missing.
448
+ # - Player.sexuality == "\u2014" (not configured) → key missing.
449
+ # - NPC.sex == "\u2014" (no sex) → never in any set.
450
+
451
+ COMPATIBILITY: Dict[tuple, FrozenSet[str]] = {
452
+ # --- heterosexual: strict binary pair ---
453
+ ("man", "heterosexual"): frozenset({"woman"}),
454
+ ("woman", "heterosexual"): frozenset({"man"}),
455
+ ("hermaphrodite", "heterosexual"): frozenset(), # ambiguous — forces explicit choice
456
+
457
+ # --- Monosexual: player gay/lesbian ---
458
+ ("man", "gay"): frozenset({"man"}),
459
+ ("woman", "lesbian"): frozenset({"woman"}),
460
+ ("hermaphrodite", "gay"): frozenset({"man", "hermaphrodite"}),
461
+ ("hermaphrodite", "lesbian"): frozenset({"woman", "hermaphrodite"}),
462
+
463
+ # --- Bi/Pan: both binary sexes + hermaphrodite ---
464
+ ("man", "bisexual"): frozenset({"man", "woman"}),
465
+ ("woman", "bisexual"): frozenset({"man", "woman"}),
466
+ ("hermaphrodite", "bisexual"): frozenset({"man", "woman", "hermaphrodite"}),
467
+ ("man", "pansexual"): frozenset({"man", "woman"}),
468
+ ("woman", "pansexual"): frozenset({"man", "woman"}),
469
+ ("hermaphrodite", "pansexual"): frozenset({"man", "woman", "hermaphrodite"}),
470
+
471
+ # --- Asexual: no romantic attraction ---
472
+ ("man", "asexual"): frozenset(),
473
+ ("woman", "asexual"): frozenset(),
474
+ ("hermaphrodite", "asexual"): frozenset(),
475
+ }
476
+
477
+
478
+ # ---------------------------------------------------------------------------
479
+ # Type aliases for constraint reuse
480
+ # ---------------------------------------------------------------------------
481
+
482
+ SexLiteral = Literal["\u2014", "man", "woman", "hermaphrodite"]
483
+ SexualityLiteral = Literal[
484
+ "\u2014", "heterosexual", "gay", "lesbian",
485
+ "bisexual", "pansexual", "asexual",
486
+ ]
487
+ RaceLiteral = Literal[
488
+ "human", "elf", "dwarf", "orc", "halfling", "dragonborn",
489
+ "gnome", "troll", "half-elf", "half-orc", "half-human", "vampire",
490
+ ]
491
+ JobRPGLiteral = Literal[
492
+ "unemployed", "barbarian", "warrior", "ranger",
493
+ "rogue", "mage", "cleric", "thief", "farmer",
494
+ ]
495
+ JobLiteral = Literal[
496
+ "unemployed"
497
+ ]
498
+ SocialClassLiteral = Literal["outsider", "noble"]
499
+ EquipmentSlotLiteral = Literal[
500
+ "head", "chest", "legs", "feet",
501
+ "mainhand", "offhand",
502
+ "ring_left", "ring_right",
503
+ "necklace", "back", "trinket",
504
+ ]
505
+ ItemTypeLiteral = Literal[
506
+ "weapon", "armor", "jewelry", "consumable", "quest", "misc",
507
+ ]
508
+ ItemRarityLiteral = Literal[
509
+ "common", "uncommon", "rare", "epic", "legendary",
510
+ ]
511
+
512
+
513
+ # ===================================================================
514
+ # Blocking categories
515
+ # ===================================================================
516
+ # Source of truth for the blocks the NPC can take. Use the strings
517
+ # directly in ``NPCStats.relationship_block = "..."``. Re-exported
518
+ # also for the type hint in ``NPCStats``.
519
+ #
520
+ # English stable identifiers (i18n labels live in the ``_UI_*-BLOCK``
521
+ # table of ``game/renpy/character_creation.rpy``).
522
+
523
+ RelationshipBlock = Literal[
524
+ "free", # default — no categorical restriction
525
+ "taken", # dating someone else
526
+ "married", # married
527
+ "widowed", # spouse deceased — mechanically free
528
+ "religious", # vow / celibacy / sacred order
529
+ "enemy", # categorical incompatible (even if ``friendly=True``)
530
+ "child", # minor (narrative safeguard)
531
+ ]
532
+
533
+ SEX_NPC = Literal["\u2014", "man", "woman", "hermaphrodite"]
534
+
535
+ RACE_NPC = Literal[
536
+ "human", "elf", "dwarf", "orc", "halfling", "dragonborn",
537
+ "gnome", "troll", "half-elf", "half-orc", "half-human", "vampire",
538
+ ]
539
+
540
+
541
+ __all__ = [
542
+ "__version__", "VERSION_INFO", "NAME",
543
+ "DEFAULT_SEX", "DEFAULT_SEXUALITY", "DEFAULT_RACE",
544
+ "DEFAULT_JOB_RPG", "DEFAULT_JOB", "DEFAULT_SOCIAL_CLASS",
545
+ "DEFAULT_AGE", "DEFAULT_WEIGHT", "DEFAULT_HEIGHT",
546
+ "DEFAULT_IS_PREGNANT", "DEFAULT_PREGNACY_STATE",
547
+ "SEX_OPTIONS", "SEXUALITY_OPTIONS", "RACE_OPTIONS", "JOB_RPG_OPTIONS",
548
+ "JOB_OPTIONS", "SOCIAL_CLASS_OPTIONS","WOMEN_OPTIONS", "SEXUALITY_BY_SEX",
549
+ "MIN_LEVEL", "MAX_LEVEL", "XP", "XP_TO_NEXT", "HP", "MAX_HP", "MP", "MAX_MP",
550
+ "STAMINA", "MAX_STAMINA", "GOLD", "LEVEL_XP_GROWTH", "LEVEL_UP_HP_GAIN",
551
+ "LEVEL_UP_MP_GAIN",
552
+ "DEFAULT_RACE_FOR_VALIDATION",
553
+ "RACE_CONSTRAINTS",
554
+ "MIN_AGE", "MAX_AGE", "MIN_WEIGHT", "MAX_WEIGHT", "MIN_HEIGHT",
555
+ "MAX_HEIGHT", "MIN_STAT", "MAX_STAT", "MIN_ACCURACY", "MAX_ACCURACY",
556
+ "JOB_RPG_STAT_RANGES",
557
+ "EQUIPMENT_SLOTS", "ITEM_TYPE_SLOTS", "ITEM_TYPES", "DEFAULT_ITEM_TYPE",
558
+ "ITEM_RARITIES", "DEFAULT_ITEM_RARITY", "ITEM_RARITY_VALUE_MULTIPLIER",
559
+ "DEFAULT_INVENTORY_MAX_WEIGHT", "DEFAULT_ITEM_WEIGHT", "DEFAULT_ITEM_VALUE",
560
+ "STATUS_TAGS", "DEFAULT_STATUS_DURATION",
561
+ "DEFAULT_SKILL_MANA_COST", "DEFAULT_SKILL_STAMINA_COST",
562
+ "DEFAULT_SKILL_COOLDOWN", "DEFAULT_SKILL_POWER",
563
+ "NPC_BLOCK_OPTIONS",
564
+ "BLOCKED_FOR_RELATIONSHIP",
565
+ "COMPATIBILITY",
566
+ "SexLiteral", "SexualityLiteral", "RaceLiteral", "JobRPGLiteral",
567
+ "JobLiteral", "SocialClassLiteral", "EquipmentSlotLiteral",
568
+ "ItemTypeLiteral", "ItemRarityLiteral", "RelationshipBlock", "SEX_NPC",
569
+ "RACE_NPC"
570
+ ]