rom24-quickmud-python 2.5.0__py3-none-any.whl → 2.5.2__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.
- mud/commands/combat.py +26 -88
- mud/commands/healer.py +10 -10
- mud/commands/magic_items.py +1 -2
- mud/game_loop.py +19 -13
- mud/models/character.py +27 -26
- mud/skills/handlers.py +24 -22
- mud/skills/say_spell.py +153 -0
- mud/spawning/reset_handler.py +16 -6
- mud/world/world_state.py +3 -9
- {rom24_quickmud_python-2.5.0.dist-info → rom24_quickmud_python-2.5.2.dist-info}/METADATA +1 -1
- {rom24_quickmud_python-2.5.0.dist-info → rom24_quickmud_python-2.5.2.dist-info}/RECORD +15 -14
- {rom24_quickmud_python-2.5.0.dist-info → rom24_quickmud_python-2.5.2.dist-info}/WHEEL +0 -0
- {rom24_quickmud_python-2.5.0.dist-info → rom24_quickmud_python-2.5.2.dist-info}/entry_points.txt +0 -0
- {rom24_quickmud_python-2.5.0.dist-info → rom24_quickmud_python-2.5.2.dist-info}/licenses/LICENSE +0 -0
- {rom24_quickmud_python-2.5.0.dist-info → rom24_quickmud_python-2.5.2.dist-info}/top_level.txt +0 -0
mud/commands/combat.py
CHANGED
|
@@ -246,14 +246,17 @@ def do_rescue(char: Character, args: str) -> str:
|
|
|
246
246
|
|
|
247
247
|
|
|
248
248
|
def _find_room_target(char: Character, name: str) -> Character | None:
|
|
249
|
+
"""Find a character in the same room by name.
|
|
250
|
+
|
|
251
|
+
ROM Reference: src/act_info.c get_char_room()
|
|
252
|
+
Note: ROM allows finding self - individual commands check victim == ch.
|
|
253
|
+
"""
|
|
249
254
|
room = getattr(char, "room", None)
|
|
250
255
|
if room is None or not name:
|
|
251
256
|
return None
|
|
252
257
|
|
|
253
258
|
lowered = name.lower()
|
|
254
259
|
for candidate in getattr(room, "people", []) or []:
|
|
255
|
-
if candidate is char:
|
|
256
|
-
continue
|
|
257
260
|
candidate_name = getattr(candidate, "name", "") or ""
|
|
258
261
|
if lowered in candidate_name.lower():
|
|
259
262
|
return candidate
|
|
@@ -797,51 +800,22 @@ def do_dirt(char: Character, args: str) -> str:
|
|
|
797
800
|
if victim is None:
|
|
798
801
|
return "They aren't here."
|
|
799
802
|
|
|
800
|
-
#
|
|
803
|
+
# Match ROM safety/validation gates in the command layer.
|
|
804
|
+
if victim is char:
|
|
805
|
+
return "Very funny."
|
|
806
|
+
|
|
801
807
|
victim_affected = getattr(victim, "affected_by", 0)
|
|
802
808
|
if victim_affected & AffectFlag.BLIND:
|
|
803
809
|
return "They're already blinded."
|
|
804
810
|
|
|
805
|
-
if victim is char:
|
|
806
|
-
return "Very funny."
|
|
807
|
-
|
|
808
|
-
# Safety checks
|
|
809
811
|
safety_msg = _kill_safety_message(char, victim)
|
|
810
812
|
if safety_msg:
|
|
811
813
|
return safety_msg
|
|
812
814
|
|
|
813
|
-
#
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
)
|
|
818
|
-
victim_dex = skill_handlers._coerce_int(
|
|
819
|
-
getattr(victim, "perm_stat", [13] * 5)[1] if isinstance(getattr(victim, "perm_stat", []), list) else 13
|
|
820
|
-
)
|
|
821
|
-
chance += char_dex - 2 * victim_dex
|
|
822
|
-
|
|
823
|
-
# Level modifier
|
|
824
|
-
char_level = skill_handlers._coerce_int(getattr(char, "level", 1))
|
|
825
|
-
victim_level = skill_handlers._coerce_int(getattr(victim, "level", 1))
|
|
826
|
-
chance += (char_level - victim_level) * 2
|
|
827
|
-
|
|
828
|
-
# Roll
|
|
829
|
-
if rng_mm.number_percent() < chance:
|
|
830
|
-
# Success - blind the victim
|
|
831
|
-
victim.affected_by = victim_affected | AffectFlag.BLIND
|
|
832
|
-
skill_registry._apply_wait_state(char, get_pulse_violence())
|
|
833
|
-
|
|
834
|
-
# Start combat if not already fighting
|
|
835
|
-
if not getattr(char, "fighting", None):
|
|
836
|
-
char.fighting = victim
|
|
837
|
-
if not getattr(victim, "fighting", None):
|
|
838
|
-
victim.fighting = char
|
|
839
|
-
|
|
840
|
-
check_killer(char, victim)
|
|
841
|
-
return f"You kick dirt into {getattr(victim, 'name', 'their')} eyes!"
|
|
842
|
-
else:
|
|
843
|
-
skill_registry._apply_wait_state(char, get_pulse_violence())
|
|
844
|
-
return "You kick dirt but miss their eyes."
|
|
815
|
+
# Delegate parity math/effects to the skill handler.
|
|
816
|
+
result = skill_handlers.dirt_kicking(char, target=victim)
|
|
817
|
+
check_killer(char, victim)
|
|
818
|
+
return result
|
|
845
819
|
|
|
846
820
|
|
|
847
821
|
def do_trip(char: Character, args: str) -> str:
|
|
@@ -943,57 +917,21 @@ def do_disarm(char: Character, args: str) -> str:
|
|
|
943
917
|
if victim is None:
|
|
944
918
|
return "You aren't fighting anyone."
|
|
945
919
|
|
|
946
|
-
#
|
|
947
|
-
|
|
948
|
-
victim_weapon = victim_equipped.get("wield") or victim_equipped.get("main_hand")
|
|
949
|
-
if victim_weapon is None:
|
|
950
|
-
return "Your opponent is not wielding a weapon."
|
|
951
|
-
|
|
952
|
-
# Attacker should have weapon (or hand-to-hand skill)
|
|
953
|
-
char_equipped = getattr(char, "equipped", {})
|
|
954
|
-
char_weapon = char_equipped.get("wield") or char_equipped.get("main_hand")
|
|
920
|
+
# Attacker must have a weapon, or meet ROM hand-to-hand / NPC OFF_DISARM exception.
|
|
921
|
+
caster_weapon = get_wielded_weapon(char)
|
|
955
922
|
hth_skill = char.skills.get("hand to hand", 0)
|
|
956
|
-
|
|
957
|
-
if char_weapon is None and hth_skill == 0:
|
|
923
|
+
if caster_weapon is None and hth_skill == 0:
|
|
958
924
|
return "You must wield a weapon to disarm."
|
|
959
925
|
|
|
960
|
-
#
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
chance = skill_level
|
|
965
|
-
|
|
966
|
-
# Dex vs Str
|
|
967
|
-
char_dex = skill_handlers._coerce_int(
|
|
968
|
-
getattr(char, "perm_stat", [13] * 5)[1] if isinstance(getattr(char, "perm_stat", []), list) else 13
|
|
969
|
-
)
|
|
970
|
-
victim_str = skill_handlers._coerce_int(
|
|
971
|
-
getattr(victim, "perm_stat", [13] * 5)[0] if isinstance(getattr(victim, "perm_stat", []), list) else 13
|
|
972
|
-
)
|
|
973
|
-
chance += char_dex - 2 * victim_str
|
|
974
|
-
|
|
975
|
-
# Level modifier
|
|
976
|
-
char_level = skill_handlers._coerce_int(getattr(char, "level", 1))
|
|
977
|
-
victim_level = skill_handlers._coerce_int(getattr(victim, "level", 1))
|
|
978
|
-
chance += (char_level - victim_level) * 2
|
|
979
|
-
|
|
980
|
-
skill_registry._apply_wait_state(char, get_pulse_violence())
|
|
926
|
+
# Victim must be wielding a weapon
|
|
927
|
+
victim_weapon = get_wielded_weapon(victim)
|
|
928
|
+
if victim_weapon is None:
|
|
929
|
+
return "Your opponent is not wielding a weapon."
|
|
981
930
|
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
# Success - remove weapon from victim
|
|
985
|
-
if "wield" in victim_equipped:
|
|
986
|
-
del victim_equipped["wield"]
|
|
987
|
-
elif "main_hand" in victim_equipped:
|
|
988
|
-
del victim_equipped["main_hand"]
|
|
989
|
-
|
|
990
|
-
# Drop to room
|
|
991
|
-
victim_room = getattr(victim, "room", None)
|
|
992
|
-
if victim_room and hasattr(victim_room, "contents"):
|
|
993
|
-
victim_room.contents.append(victim_weapon)
|
|
994
|
-
victim_weapon.in_room = victim_room
|
|
931
|
+
success = skill_handlers.disarm(char, target=victim)
|
|
932
|
+
check_killer(char, victim)
|
|
995
933
|
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
934
|
+
victim_name = getattr(victim, "name", "them")
|
|
935
|
+
if success:
|
|
936
|
+
return f"You disarm {victim_name}!"
|
|
937
|
+
return f"You fail to disarm {victim_name}."
|
mud/commands/healer.py
CHANGED
|
@@ -21,16 +21,16 @@ def _find_healer(char: Character) -> object | None:
|
|
|
21
21
|
|
|
22
22
|
|
|
23
23
|
PRICE_GOLD = {
|
|
24
|
-
"light": 10,
|
|
25
|
-
"serious":
|
|
26
|
-
"critical": 25,
|
|
27
|
-
"heal": 50,
|
|
28
|
-
"blindness": 20,
|
|
29
|
-
"disease": 15,
|
|
30
|
-
"poison": 25,
|
|
31
|
-
"uncurse": 50,
|
|
32
|
-
"refresh": 5,
|
|
33
|
-
"mana": 10,
|
|
24
|
+
"light": 10, # ROM healer.c:88: cost = 1000 (10 gold)
|
|
25
|
+
"serious": 16, # ROM healer.c:96: cost = 1600 (16 gold) - NOTE: Display says 15g but actual cost is 16g!
|
|
26
|
+
"critical": 25, # ROM healer.c:104: cost = 2500 (25 gold)
|
|
27
|
+
"heal": 50, # ROM healer.c:112: cost = 5000 (50 gold)
|
|
28
|
+
"blindness": 20, # ROM healer.c:120: cost = 2000 (20 gold)
|
|
29
|
+
"disease": 15, # ROM healer.c:128: cost = 1500 (15 gold)
|
|
30
|
+
"poison": 25, # ROM healer.c:136: cost = 2500 (25 gold)
|
|
31
|
+
"uncurse": 50, # ROM healer.c:144: cost = 5000 (50 gold)
|
|
32
|
+
"refresh": 5, # ROM healer.c:161: cost = 500 (5 gold)
|
|
33
|
+
"mana": 10, # ROM healer.c:152: cost = 1000 (10 gold)
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
|
mud/commands/magic_items.py
CHANGED
|
@@ -152,8 +152,7 @@ def do_recite(ch: Character, args: str) -> str:
|
|
|
152
152
|
if not scroll:
|
|
153
153
|
return "You do not have that scroll."
|
|
154
154
|
|
|
155
|
-
|
|
156
|
-
if scroll.item_type != ItemType.ITEM_SCROLL:
|
|
155
|
+
if scroll.item_type != ItemType.SCROLL:
|
|
157
156
|
return "You can recite only scrolls."
|
|
158
157
|
|
|
159
158
|
# Check level requirement
|
mud/game_loop.py
CHANGED
|
@@ -198,10 +198,12 @@ def hit_gain(character: Character) -> int:
|
|
|
198
198
|
gain = gain * getattr(room, "heal_rate", 100) // 100
|
|
199
199
|
|
|
200
200
|
furniture = getattr(character, "on", None)
|
|
201
|
-
if furniture is not None
|
|
202
|
-
|
|
203
|
-
if
|
|
204
|
-
|
|
201
|
+
if furniture is not None:
|
|
202
|
+
item_type = getattr(furniture.prototype, "item_type", None)
|
|
203
|
+
if item_type == ItemType.FURNITURE or item_type == int(ItemType.FURNITURE):
|
|
204
|
+
values = getattr(furniture, "value", [100, 100, 100, 100, 100])
|
|
205
|
+
if len(values) > 3:
|
|
206
|
+
gain = gain * int(values[3]) // 100
|
|
205
207
|
|
|
206
208
|
if _has_affect(character, AffectFlag.POISON):
|
|
207
209
|
gain //= 4
|
|
@@ -262,13 +264,15 @@ def mana_gain(character: Character) -> int:
|
|
|
262
264
|
if character.pcdata.condition[Condition.THIRST] == 0:
|
|
263
265
|
gain //= 2
|
|
264
266
|
|
|
265
|
-
gain = gain * getattr(room, "
|
|
267
|
+
gain = gain * getattr(room, "heal_rate", 100) // 100
|
|
266
268
|
|
|
267
269
|
furniture = getattr(character, "on", None)
|
|
268
|
-
if furniture is not None
|
|
269
|
-
|
|
270
|
-
if
|
|
271
|
-
|
|
270
|
+
if furniture is not None:
|
|
271
|
+
item_type = getattr(furniture.prototype, "item_type", None)
|
|
272
|
+
if item_type == ItemType.FURNITURE or item_type == int(ItemType.FURNITURE):
|
|
273
|
+
values = getattr(furniture, "value", [100, 100, 100, 100, 100])
|
|
274
|
+
if len(values) > 3:
|
|
275
|
+
gain = gain * int(values[3]) // 100
|
|
272
276
|
|
|
273
277
|
if _has_affect(character, AffectFlag.POISON):
|
|
274
278
|
gain //= 4
|
|
@@ -307,10 +311,12 @@ def move_gain(character: Character) -> int:
|
|
|
307
311
|
gain = gain * getattr(room, "heal_rate", 100) // 100
|
|
308
312
|
|
|
309
313
|
furniture = getattr(character, "on", None)
|
|
310
|
-
if furniture is not None
|
|
311
|
-
|
|
312
|
-
if
|
|
313
|
-
|
|
314
|
+
if furniture is not None:
|
|
315
|
+
item_type = getattr(furniture.prototype, "item_type", None)
|
|
316
|
+
if item_type == ItemType.FURNITURE or item_type == int(ItemType.FURNITURE):
|
|
317
|
+
values = getattr(furniture, "value", [100, 100, 100, 100, 100])
|
|
318
|
+
if len(values) > 3:
|
|
319
|
+
gain = gain * int(values[3]) // 100
|
|
314
320
|
|
|
315
321
|
if _has_affect(character, AffectFlag.POISON):
|
|
316
322
|
gain //= 4
|
mud/models/character.py
CHANGED
|
@@ -260,20 +260,20 @@ class Character:
|
|
|
260
260
|
description: str | None = None
|
|
261
261
|
prompt: str | None = None
|
|
262
262
|
prefix: str | None = None
|
|
263
|
-
|
|
263
|
+
|
|
264
264
|
# Class/Race/Clan
|
|
265
265
|
sex: int = 0
|
|
266
266
|
ch_class: int = 0
|
|
267
267
|
race: int = 0
|
|
268
268
|
clan: int = 0
|
|
269
269
|
group: int = 0 # Group number for area repop (ROM: sh_int group)
|
|
270
|
-
|
|
270
|
+
|
|
271
271
|
# Levels and trust
|
|
272
272
|
level: int = 0
|
|
273
273
|
trust: int = 0
|
|
274
274
|
invis_level: int = 0
|
|
275
275
|
incog_level: int = 0
|
|
276
|
-
|
|
276
|
+
|
|
277
277
|
# Stats
|
|
278
278
|
hit: int = 0
|
|
279
279
|
max_hit: int = 0
|
|
@@ -284,76 +284,77 @@ class Character:
|
|
|
284
284
|
gold: int = 0
|
|
285
285
|
silver: int = 0
|
|
286
286
|
exp: int = 0
|
|
287
|
-
|
|
287
|
+
|
|
288
288
|
# Flags
|
|
289
289
|
act: int = 0
|
|
290
290
|
affected_by: int = 0
|
|
291
|
-
|
|
291
|
+
|
|
292
292
|
# Location
|
|
293
293
|
position: int = Position.STANDING
|
|
294
294
|
room: Room | None = None # ROM: in_room
|
|
295
295
|
was_in_room: Room | None = None # ROM: was_in_room
|
|
296
296
|
zone: object | None = None # ROM: AREA_DATA *zone
|
|
297
|
-
|
|
297
|
+
|
|
298
298
|
# Relationships
|
|
299
299
|
master: Character | None = None
|
|
300
300
|
leader: Character | None = None
|
|
301
301
|
pet: "Character | None" = None
|
|
302
302
|
reply: Character | None = None # ROM: reply target for tells
|
|
303
303
|
mprog_target: "Character | None" = None # ROM: mob program target
|
|
304
|
-
|
|
304
|
+
on: "Object | None" = None # ROM: furniture character is sitting/resting on (affects heal rate)
|
|
305
|
+
|
|
305
306
|
# Skills and training
|
|
306
307
|
practice: int = 0
|
|
307
308
|
train: int = 0
|
|
308
309
|
skills: dict[str, int] = field(default_factory=dict)
|
|
309
|
-
|
|
310
|
+
|
|
310
311
|
# Encumbrance
|
|
311
312
|
carry_weight: int = 0
|
|
312
313
|
carry_number: int = 0
|
|
313
|
-
|
|
314
|
+
|
|
314
315
|
# Combat stats
|
|
315
316
|
saving_throw: int = 0
|
|
316
317
|
alignment: int = 0
|
|
317
318
|
hitroll: int = 0
|
|
318
319
|
damroll: int = 0
|
|
319
320
|
wimpy: int = 0
|
|
320
|
-
|
|
321
|
+
|
|
321
322
|
# Display/UI
|
|
322
323
|
lines: int = DEFAULT_PAGE_LINES
|
|
323
324
|
newbie_help_seen: bool = False
|
|
324
|
-
|
|
325
|
+
|
|
325
326
|
# Time tracking
|
|
326
327
|
played: int = 0
|
|
327
328
|
logon: int = 0
|
|
328
329
|
timer: int = 0 # ROM: idle timer
|
|
329
|
-
|
|
330
|
+
|
|
330
331
|
# Stats (permanent and temporary modifiers)
|
|
331
332
|
perm_stat: list[int] = field(default_factory=list)
|
|
332
333
|
mod_stat: list[int] = field(default_factory=list)
|
|
333
|
-
|
|
334
|
+
|
|
334
335
|
# Body form and parts
|
|
335
336
|
form: int = 0
|
|
336
337
|
parts: int = 0
|
|
337
338
|
size: int = 0
|
|
338
339
|
material: str | None = None
|
|
339
340
|
off_flags: int = 0
|
|
340
|
-
|
|
341
|
+
|
|
341
342
|
# ROM parity: immunity/resistance/vulnerability bitvectors (merc.h)
|
|
342
343
|
imm_flags: int = 0
|
|
343
344
|
res_flags: int = 0
|
|
344
345
|
vuln_flags: int = 0
|
|
345
|
-
|
|
346
|
+
|
|
346
347
|
# Damage and attack type
|
|
347
348
|
damage: list[int] = field(default_factory=lambda: [0, 0, 0])
|
|
348
349
|
dam_type: int = 0
|
|
349
350
|
start_pos: int = 0
|
|
350
351
|
default_pos: int = 0
|
|
351
|
-
|
|
352
|
+
|
|
352
353
|
# Mob programs
|
|
353
354
|
mprog_delay: int = 0
|
|
354
355
|
mob_programs: list[MobProgram] = field(default_factory=list)
|
|
355
356
|
spec_fun: str | None = None # ROM: special function name
|
|
356
|
-
|
|
357
|
+
|
|
357
358
|
# Custom fields (Python-specific)
|
|
358
359
|
hometown_vnum: int = 0
|
|
359
360
|
pcdata: PCData | None = None
|
|
@@ -365,7 +366,7 @@ class Character:
|
|
|
365
366
|
connection: object | None = None
|
|
366
367
|
desc: object | None = None # ROM: DESCRIPTOR_DATA
|
|
367
368
|
is_admin: bool = False
|
|
368
|
-
|
|
369
|
+
|
|
369
370
|
# Communication and channels
|
|
370
371
|
imc_permission: str = "Mort" # IMC permission level (Notset/None/Mort/Imm/Admin/Imp)
|
|
371
372
|
muted_channels: set[str] = field(default_factory=set)
|
|
@@ -374,33 +375,33 @@ class Character:
|
|
|
374
375
|
wiznet: int = 0 # ROM: wiznet flags
|
|
375
376
|
comm: int = 0 # ROM: comm flags
|
|
376
377
|
log_commands: bool = False # Per-character admin logging flag mirroring ROM PLR_LOG
|
|
377
|
-
|
|
378
|
+
|
|
378
379
|
# Wait state and delays
|
|
379
380
|
wait: int = 0 # Wait-state (pulses) applied by actions like movement (ROM WAIT_STATE)
|
|
380
381
|
daze: int = 0 # Daze (pulses) — separate action delay used by ROM combat
|
|
381
|
-
|
|
382
|
+
|
|
382
383
|
# Armor class per index [AC_PIERCE, AC_BASH, AC_SLASH, AC_EXOTIC]
|
|
383
384
|
armor: list[int] = field(default_factory=lambda: [100, 100, 100, 100])
|
|
384
|
-
|
|
385
|
+
|
|
385
386
|
# Per-character command aliases: name -> expansion (pre-dispatch)
|
|
386
387
|
aliases: dict[str, str] = field(default_factory=dict)
|
|
387
|
-
|
|
388
|
+
|
|
388
389
|
# Optional defense chances (percent) for parity-friendly tests
|
|
389
390
|
shield_block_chance: int = 0
|
|
390
391
|
parry_chance: int = 0
|
|
391
392
|
dodge_chance: int = 0
|
|
392
|
-
|
|
393
|
+
|
|
393
394
|
# Combat skill levels (0-100) for multi-attack mechanics
|
|
394
395
|
second_attack_skill: int = 0
|
|
395
396
|
third_attack_skill: int = 0
|
|
396
397
|
enhanced_damage_skill: int = 0 # Enhanced damage skill level (0-100)
|
|
397
|
-
|
|
398
|
+
|
|
398
399
|
# Combat state - currently fighting target
|
|
399
400
|
fighting: Character | None = None
|
|
400
|
-
|
|
401
|
+
|
|
401
402
|
# Character type flag
|
|
402
403
|
is_npc: bool = True # Default to NPC, set to False for PCs
|
|
403
|
-
|
|
404
|
+
|
|
404
405
|
# Spell effects and character generation
|
|
405
406
|
spell_effects: dict[str, SpellEffect] = field(default_factory=dict) # Active spell effects keyed by skill name
|
|
406
407
|
default_weapon_vnum: int = 0
|
mud/skills/handlers.py
CHANGED
|
@@ -1354,7 +1354,7 @@ def bless(caster: Character, target: Character | None = None) -> bool:
|
|
|
1354
1354
|
if target is None:
|
|
1355
1355
|
raise ValueError("bless requires a target")
|
|
1356
1356
|
|
|
1357
|
-
if target.position == Position.FIGHTING:
|
|
1357
|
+
if target.position == Position.FIGHTING or target.has_spell_effect("bless"):
|
|
1358
1358
|
return False
|
|
1359
1359
|
|
|
1360
1360
|
level = max(getattr(caster, "level", 0), 0)
|
|
@@ -1890,31 +1890,29 @@ def chain_lightning(caster: Character, target: Character | None = None) -> bool:
|
|
|
1890
1890
|
if level <= 0:
|
|
1891
1891
|
break
|
|
1892
1892
|
|
|
1893
|
-
if found
|
|
1894
|
-
|
|
1893
|
+
if not found:
|
|
1894
|
+
if last_victim is caster:
|
|
1895
|
+
broadcast_room(
|
|
1896
|
+
room,
|
|
1897
|
+
"The bolt seems to have fizzled out.",
|
|
1898
|
+
exclude=caster,
|
|
1899
|
+
)
|
|
1900
|
+
_send_to_char(caster, "The bolt grounds out through your body.")
|
|
1901
|
+
break
|
|
1895
1902
|
|
|
1896
|
-
|
|
1903
|
+
last_victim = caster
|
|
1897
1904
|
broadcast_room(
|
|
1898
1905
|
room,
|
|
1899
|
-
"The bolt
|
|
1906
|
+
f"The bolt arcs to {caster_name}...whoops!",
|
|
1900
1907
|
exclude=caster,
|
|
1901
1908
|
)
|
|
1902
|
-
_send_to_char(caster, "
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
exclude=caster,
|
|
1910
|
-
)
|
|
1911
|
-
_send_to_char(caster, "You are struck by your own lightning!")
|
|
1912
|
-
damage = rng_mm.dice(level, 6)
|
|
1913
|
-
if saves_spell(level, caster, DamageType.LIGHTNING):
|
|
1914
|
-
damage = c_div(damage, 3)
|
|
1915
|
-
apply_damage(caster, caster, damage, DamageType.LIGHTNING, dt="chain lightning")
|
|
1916
|
-
any_hit = any_hit or damage > 0
|
|
1917
|
-
level -= 4
|
|
1909
|
+
_send_to_char(caster, "You are struck by your own lightning!")
|
|
1910
|
+
damage = rng_mm.dice(level, 6)
|
|
1911
|
+
if saves_spell(level, caster, DamageType.LIGHTNING):
|
|
1912
|
+
damage = c_div(damage, 3)
|
|
1913
|
+
apply_damage(caster, caster, damage, DamageType.LIGHTNING, dt="chain lightning")
|
|
1914
|
+
any_hit = any_hit or damage > 0
|
|
1915
|
+
level -= 4
|
|
1918
1916
|
|
|
1919
1917
|
return any_hit
|
|
1920
1918
|
|
|
@@ -3100,7 +3098,11 @@ def disarm(caster: Character, target: Character | None = None) -> bool:
|
|
|
3100
3098
|
victim_weapon.wear_loc = int(WearLocation.NONE)
|
|
3101
3099
|
|
|
3102
3100
|
drop_room = getattr(victim, "room", None)
|
|
3103
|
-
|
|
3101
|
+
|
|
3102
|
+
# ROM src/fight.c:2258-2265 - ITEM_NODROP/ITEM_INVENTORY keep weapon on victim.
|
|
3103
|
+
if extra_flags & (int(ExtraFlag.NODROP) | int(ExtraFlag.INVENTORY)):
|
|
3104
|
+
victim.add_object(victim_weapon)
|
|
3105
|
+
elif drop_room is not None and hasattr(drop_room, "add_object"):
|
|
3104
3106
|
drop_room.add_object(victim_weapon)
|
|
3105
3107
|
else:
|
|
3106
3108
|
victim.add_object(victim_weapon)
|
mud/skills/say_spell.py
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
"""ROM say_spell utility - syllable substitution for spell casting messages.
|
|
2
|
+
|
|
3
|
+
Mirroring ROM src/magic.c:132-207
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
from typing import TYPE_CHECKING, Any
|
|
9
|
+
|
|
10
|
+
if TYPE_CHECKING:
|
|
11
|
+
pass # Avoid import errors during type checking
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# ROM src/magic.c:146-178 - Syllable substitution table
|
|
15
|
+
_SYL_TABLE = [
|
|
16
|
+
(" ", " "),
|
|
17
|
+
("ar", "abra"),
|
|
18
|
+
("au", "kada"),
|
|
19
|
+
("bless", "fido"),
|
|
20
|
+
("blind", "nose"),
|
|
21
|
+
("bur", "mosa"),
|
|
22
|
+
("cu", "judi"),
|
|
23
|
+
("de", "oculo"),
|
|
24
|
+
("en", "unso"),
|
|
25
|
+
("light", "dies"),
|
|
26
|
+
("lo", "hi"),
|
|
27
|
+
("mor", "zak"),
|
|
28
|
+
("move", "sido"),
|
|
29
|
+
("ness", "lacri"),
|
|
30
|
+
("ning", "illa"),
|
|
31
|
+
("per", "duda"),
|
|
32
|
+
("ra", "gru"),
|
|
33
|
+
("fresh", "ima"),
|
|
34
|
+
("re", "candus"),
|
|
35
|
+
("son", "sabru"),
|
|
36
|
+
("tect", "infra"),
|
|
37
|
+
("tri", "cula"),
|
|
38
|
+
("ven", "nofo"),
|
|
39
|
+
# Single character substitutions
|
|
40
|
+
("a", "a"),
|
|
41
|
+
("b", "b"),
|
|
42
|
+
("c", "q"),
|
|
43
|
+
("d", "e"),
|
|
44
|
+
("e", "z"),
|
|
45
|
+
("f", "y"),
|
|
46
|
+
("g", "o"),
|
|
47
|
+
("h", "p"),
|
|
48
|
+
("i", "u"),
|
|
49
|
+
("j", "y"),
|
|
50
|
+
("k", "t"),
|
|
51
|
+
("l", "r"),
|
|
52
|
+
("m", "w"),
|
|
53
|
+
("n", "i"),
|
|
54
|
+
("o", "a"),
|
|
55
|
+
("p", "s"),
|
|
56
|
+
("q", "d"),
|
|
57
|
+
("r", "f"),
|
|
58
|
+
("s", "g"),
|
|
59
|
+
("t", "h"),
|
|
60
|
+
("u", "j"),
|
|
61
|
+
("v", "z"),
|
|
62
|
+
("w", "x"),
|
|
63
|
+
("x", "n"),
|
|
64
|
+
("y", "l"),
|
|
65
|
+
("z", "k"),
|
|
66
|
+
("", ""), # Terminator
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def say_spell(caster: Any, spell_name: str) -> tuple[str, str]:
|
|
71
|
+
"""ROM say_spell: convert spell name to gibberish for non-class observers.
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
caster: Character casting the spell
|
|
75
|
+
spell_name: Name of the spell being cast
|
|
76
|
+
|
|
77
|
+
Returns:
|
|
78
|
+
Tuple of (actual_words, garbled_words)
|
|
79
|
+
- actual_words: Message shown to same-class observers
|
|
80
|
+
- garbled_words: Message shown to different-class observers
|
|
81
|
+
|
|
82
|
+
ROM C Reference: src/magic.c:132-207
|
|
83
|
+
"""
|
|
84
|
+
if not spell_name:
|
|
85
|
+
return ("", "")
|
|
86
|
+
|
|
87
|
+
# Build garbled version using syllable substitution
|
|
88
|
+
garbled = []
|
|
89
|
+
name_lower = spell_name.lower()
|
|
90
|
+
pos = 0
|
|
91
|
+
|
|
92
|
+
while pos < len(name_lower):
|
|
93
|
+
matched = False
|
|
94
|
+
|
|
95
|
+
# Try each syllable in the table
|
|
96
|
+
for old, new in _SYL_TABLE:
|
|
97
|
+
if not old: # Terminator
|
|
98
|
+
break
|
|
99
|
+
|
|
100
|
+
if name_lower[pos:].startswith(old):
|
|
101
|
+
garbled.append(new)
|
|
102
|
+
pos += len(old)
|
|
103
|
+
matched = True
|
|
104
|
+
break
|
|
105
|
+
|
|
106
|
+
# If no match, advance by 1 character
|
|
107
|
+
if not matched:
|
|
108
|
+
pos += 1
|
|
109
|
+
|
|
110
|
+
garbled_words = "".join(garbled)
|
|
111
|
+
|
|
112
|
+
# Format messages
|
|
113
|
+
actual_msg = f"$n utters the words, '{spell_name}'."
|
|
114
|
+
garbled_msg = f"$n utters the words, '{garbled_words}'."
|
|
115
|
+
|
|
116
|
+
return (actual_msg, garbled_msg)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def broadcast_spell_words(caster: Any, spell_name: str) -> None:
|
|
120
|
+
"""Broadcast spell words to room with class-based filtering.
|
|
121
|
+
|
|
122
|
+
ROM C Reference: src/magic.c:199-204
|
|
123
|
+
"""
|
|
124
|
+
# Import here to avoid circular dependencies
|
|
125
|
+
try:
|
|
126
|
+
from mud.net.protocol import broadcast_room
|
|
127
|
+
except ImportError:
|
|
128
|
+
# Gracefully handle if module not available
|
|
129
|
+
return
|
|
130
|
+
|
|
131
|
+
room = getattr(caster, "room", None)
|
|
132
|
+
if room is None:
|
|
133
|
+
return
|
|
134
|
+
|
|
135
|
+
actual_msg, garbled_msg = say_spell(caster, spell_name)
|
|
136
|
+
caster_class = getattr(caster, "ch_class", None)
|
|
137
|
+
|
|
138
|
+
# ROM L199-203: Show actual words to same class, garbled to others
|
|
139
|
+
for occupant in list(getattr(room, "people", []) or []):
|
|
140
|
+
if occupant is caster:
|
|
141
|
+
continue
|
|
142
|
+
|
|
143
|
+
is_npc = getattr(occupant, "is_npc", True)
|
|
144
|
+
occupant_class = getattr(occupant, "ch_class", None)
|
|
145
|
+
|
|
146
|
+
# Non-NPCs of same class see actual words, others see garbled
|
|
147
|
+
if not is_npc and caster_class == occupant_class:
|
|
148
|
+
message = actual_msg.replace("$n", getattr(caster, "name", "Someone"))
|
|
149
|
+
else:
|
|
150
|
+
message = garbled_msg.replace("$n", getattr(caster, "name", "Someone"))
|
|
151
|
+
|
|
152
|
+
if hasattr(occupant, "messages"):
|
|
153
|
+
occupant.messages.append(message)
|
mud/spawning/reset_handler.py
CHANGED
|
@@ -410,7 +410,14 @@ def apply_resets(area: Area) -> None:
|
|
|
410
410
|
last_reset_succeeded = False
|
|
411
411
|
continue
|
|
412
412
|
|
|
413
|
-
|
|
413
|
+
# ROM parity: Check global limit using pMobIndex->count (ROM db.c:1704)
|
|
414
|
+
proto = mob_registry.get(mob_vnum)
|
|
415
|
+
proto_count = getattr(proto, "count", 0) if proto else 0
|
|
416
|
+
logging.debug(
|
|
417
|
+
f"M reset global limit check: mob_vnum={mob_vnum}, proto_count={proto_count}, global_limit={global_limit}"
|
|
418
|
+
)
|
|
419
|
+
if global_limit > 0 and proto_count >= global_limit:
|
|
420
|
+
logging.debug(f"M reset SKIPPED due to global limit: {proto_count} >= {global_limit}")
|
|
414
421
|
last_mob = None
|
|
415
422
|
last_obj = None
|
|
416
423
|
last_reset_succeeded = False
|
|
@@ -470,15 +477,17 @@ def apply_resets(area: Area) -> None:
|
|
|
470
477
|
proto = getattr(mob, "prototype", None)
|
|
471
478
|
if proto is not None and hasattr(proto, "count"):
|
|
472
479
|
proto.count = mob_counts[mob_vnum]
|
|
480
|
+
|
|
481
|
+
# ROM parity: Apply level fuzzing to mob (ROM db.c:1735)
|
|
482
|
+
# ROM C: pMob->level = URANGE(0, pMob->level - 2, LEVEL_HERO);
|
|
473
483
|
try:
|
|
474
484
|
mob_level = int(getattr(mob, "level", 0) or 0)
|
|
475
485
|
except Exception:
|
|
476
486
|
mob_level = 0
|
|
477
487
|
hero_cap = max(0, LEVEL_HERO - 1)
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
last_mob_level = base_level
|
|
488
|
+
fuzzed_level = max(0, min(mob_level - 2, hero_cap))
|
|
489
|
+
mob.level = fuzzed_level
|
|
490
|
+
last_mob_level = fuzzed_level
|
|
482
491
|
last_mob = mob
|
|
483
492
|
last_obj = None
|
|
484
493
|
last_reset_succeeded = True
|
|
@@ -579,7 +588,8 @@ def apply_resets(area: Area) -> None:
|
|
|
579
588
|
if rev_exits and rev_idx < len(rev_exits):
|
|
580
589
|
rev_exit = rev_exits[rev_idx]
|
|
581
590
|
if rev_exit is not None:
|
|
582
|
-
rev_exit.
|
|
591
|
+
rev_exit.rs_flags = base_flags
|
|
592
|
+
rev_exit.exit_info = base_flags
|
|
583
593
|
elif cmd == "G":
|
|
584
594
|
if not last_reset_succeeded:
|
|
585
595
|
continue
|
mud/world/world_state.py
CHANGED
|
@@ -15,9 +15,6 @@ from mud.spawning.reset_handler import apply_resets
|
|
|
15
15
|
|
|
16
16
|
from .linking import link_exits
|
|
17
17
|
|
|
18
|
-
# Global skill registry for world initialization
|
|
19
|
-
skill_registry = None
|
|
20
|
-
|
|
21
18
|
_wizlock_enabled = False
|
|
22
19
|
_newlock_enabled = False
|
|
23
20
|
|
|
@@ -159,18 +156,15 @@ def initialize_world(area_list_path: str | None = "area/area.lst", use_json: boo
|
|
|
159
156
|
# Load skills registry from JSON
|
|
160
157
|
from pathlib import Path
|
|
161
158
|
|
|
162
|
-
from mud.skills.registry import
|
|
159
|
+
from mud.skills.registry import skill_registry as global_skill_registry
|
|
163
160
|
|
|
164
161
|
skills_path = Path("data/skills.json")
|
|
165
162
|
if skills_path.exists():
|
|
166
163
|
try:
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
skill_registry.load(skills_path)
|
|
170
|
-
print(f"✅ Loaded {len(skill_registry.skills)} skills from {skills_path}")
|
|
164
|
+
global_skill_registry.load(skills_path)
|
|
165
|
+
print(f"✅ Loaded {len(global_skill_registry.skills)} skills from {skills_path}")
|
|
171
166
|
except Exception as e:
|
|
172
167
|
print(f"Warning: Failed to load skills from {skills_path}: {e}")
|
|
173
|
-
skill_registry = None
|
|
174
168
|
|
|
175
169
|
# Load shops from JSON (needed for shopkeeper detection in resets)
|
|
176
170
|
import json
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rom24-quickmud-python
|
|
3
|
-
Version: 2.5.
|
|
3
|
+
Version: 2.5.2
|
|
4
4
|
Summary: A modern Python port of the ROM 2.4b6 MUD engine with full telnet server and JSON world loading
|
|
5
5
|
Author-email: Mark Jedrzejczyk <mark.jedrzejczyk@gmail.com>
|
|
6
6
|
Maintainer-email: Mark Jedrzejczyk <mark.jedrzejczyk@gmail.com>
|
|
@@ -3,7 +3,7 @@ mud/__main__.py,sha256=WtSvCWscFHIlT7F_YWzIhN5xkTz0Ng8k83WbD-tuGxU,1330
|
|
|
3
3
|
mud/advancement.py,sha256=QWGYRv337unJIzQOupLiIEfKFBge9xvRCc4PQNc0Aq8,6218
|
|
4
4
|
mud/config.py,sha256=ijXo52Q2yL_dbowxMa5mKiXnNCFihWAhHYnnbih4OaY,6497
|
|
5
5
|
mud/entrypoint.py,sha256=WxBW3GfbKCOtSD5rx2ccSAC7lA3YRFi7DJ_EZvi1rmo,854
|
|
6
|
-
mud/game_loop.py,sha256=
|
|
6
|
+
mud/game_loop.py,sha256=C7EQ1zNZDWgNZc2I_QgdxEMCdxOnc30ejy89-n_nEqU,34389
|
|
7
7
|
mud/game_tick_scheduler.py,sha256=7ybo2ekDQQPGN82u6fhcrrg7tZ-JMtGy4UUrZv9_Umo,1539
|
|
8
8
|
mud/logging.py,sha256=DoKcplYwEePAmXKE2CI_wNk4pF-pc_aouoxa5C6tXlc,582
|
|
9
9
|
mud/mob_cmds.py,sha256=drtURAaaQtsivy8zOfJu6cOyP30L3W89qBxHRDQyLjk,34027
|
|
@@ -48,7 +48,7 @@ mud/commands/auto_settings.py,sha256=iO2GCVympiOhySHezcMXleegmswV8VrpEKUBOyXx0r0
|
|
|
48
48
|
mud/commands/build.py,sha256=uJaJYtmFHrwAoUl0RDWPAWVHduVNZrxtPsAnH-M5j_w,85938
|
|
49
49
|
mud/commands/channels.py,sha256=1PewUVrMk1Uh7dUj7ZZgUyL9xkQbSN7BY9KtBkL4GAc,1584
|
|
50
50
|
mud/commands/character.py,sha256=vLkfLJlxjDIfKXGG_8q5BexbdmhoKh1tAG0Lc56qWXc,4295
|
|
51
|
-
mud/commands/combat.py,sha256=
|
|
51
|
+
mud/commands/combat.py,sha256=uob0_6dR7IdHcHcFA7mBM9UI6X8J96WlJSt5YqEOMzs,31469
|
|
52
52
|
mud/commands/communication.py,sha256=H3OjaI41Y6dbwje7RDSn2SHoqXtqlv2pjZhxSR52HnQ,19359
|
|
53
53
|
mud/commands/compare.py,sha256=AmGl2OJy5KS_0U2zqv0EwSwpgfFee70oaDZC6xZ7Tzw,5176
|
|
54
54
|
mud/commands/consider.py,sha256=rQwLTZq28nfdpnBmEgpV72FSvJJE5JPuPMhtMouN-hE,2230
|
|
@@ -60,7 +60,7 @@ mud/commands/equipment.py,sha256=yWfaZmDYVgRuDIFlcUWEZMzMMYQlGrXfw4hgzgMZoJk,114
|
|
|
60
60
|
mud/commands/feedback.py,sha256=qEmUlVy1KC6ludpAREdqvf8gpa8jmgN4AMLor0EoO7E,2472
|
|
61
61
|
mud/commands/give.py,sha256=njzoCLD6m2ZKzvi8yjBwzJbR-hrN7JtBCKDxXsvn1zc,6760
|
|
62
62
|
mud/commands/group_commands.py,sha256=wmJj07pSImQLzGQ7QrGZPpmRGlhMQoEK4tj_cWMTLlg,12413
|
|
63
|
-
mud/commands/healer.py,sha256=
|
|
63
|
+
mud/commands/healer.py,sha256=VeRfW6ZuDFSrs6u_lae7mBCm6pGyOTWbNMhcYrFBQkQ,2771
|
|
64
64
|
mud/commands/help.py,sha256=GfQWy6MyFtDc-mW1dM7pPN1SFVsWtIGno8uR4dRQYjg,11124
|
|
65
65
|
mud/commands/imc.py,sha256=v1lPP2xDjQjkk7negwjCXJtcRPQkBEIGWmpPKf1XPzU,12204
|
|
66
66
|
mud/commands/imm_admin.py,sha256=xshWlMpV3RCLuxkdwVxwsiQCM6ku0Nh-rqHYejyCpc8,7455
|
|
@@ -78,7 +78,7 @@ mud/commands/info_extended.py,sha256=B1XYgmtHP74DOb6ysPRFZbg7h3NOUBcudrtAePC9ufo
|
|
|
78
78
|
mud/commands/inspection.py,sha256=IAwfVdiu3fcJvJ88Eny2bndBFdtqB4PfP01E82NDAyo,4343
|
|
79
79
|
mud/commands/inventory.py,sha256=Pgq7-3crr3H4llaYxSpxVJT_sq3wU6AvR2Sb8SwXbHg,6727
|
|
80
80
|
mud/commands/liquids.py,sha256=I8lPH9j446_SaP23NKNa1IOtp8L3sropDeiGRKwh798,8274
|
|
81
|
-
mud/commands/magic_items.py,sha256=
|
|
81
|
+
mud/commands/magic_items.py,sha256=EECy8Nh7kjMefPE_vJvUzR_6If9_cl8z_eNS7C6QC0Q,15195
|
|
82
82
|
mud/commands/misc_info.py,sha256=KXrL6V-QyCgv2Y0crnweF__gff22PE2cpPMujypHLKM,7728
|
|
83
83
|
mud/commands/misc_player.py,sha256=bY-_iaOg3XrNQVhxRth-HHCvKEGII54gOrZR1cXgprs,7869
|
|
84
84
|
mud/commands/mobprog_tools.py,sha256=1OXRolsjmVuBn_FtKc_I1M_sTYLYgSspqc8U9f5xFLA,5364
|
|
@@ -132,7 +132,7 @@ mud/models/area.py,sha256=RDn6e2N9AhoMW4d68-o8i1p1tNhuszaWjbOIkGTlW9I,835
|
|
|
132
132
|
mud/models/area_json.py,sha256=GUCWUgFf2s6DUWzcLLYhoxTP38P5cu1vrSD1W3i7D2c,731
|
|
133
133
|
mud/models/board.py,sha256=iO25xwmUjUCJLYY5nAJdrIweW0oryuSGffm58zy9wJ8,5169
|
|
134
134
|
mud/models/board_json.py,sha256=XG8t7lLW7b_V3IjzbGF-o6Ym36CTgKiOiBVZb-M0BpA,472
|
|
135
|
-
mud/models/character.py,sha256=
|
|
135
|
+
mud/models/character.py,sha256=lbOcidIIq2okdI2c9DldsTVCLlJSdtnXpRhMpXs4L8I,36796
|
|
136
136
|
mud/models/character_json.py,sha256=7rdI92S-JT38xb2iUyXTAJpLmFOIRy2pb6v1Yen8VQY,1046
|
|
137
137
|
mud/models/clans.py,sha256=0rAzhRdB_1k-GJpQXhANE-Vn1fEnY6oIuqDkq8kvD4c,2066
|
|
138
138
|
mud/models/classes.py,sha256=Fv0KjS339EBWqz5OBZu5TYSIDSRYpoalLTBJOf-6ThI,2602
|
|
@@ -182,13 +182,14 @@ mud/security/bans.py,sha256=m78mPOsG10fmsCzD1STjIltxOJIS4Va-0E7_cL04Zr8,9036
|
|
|
182
182
|
mud/security/hash_utils.py,sha256=GNd2W-TFLSIOk1WMQRuvJo8l4CueBYzPI0EhQuydxUg,656
|
|
183
183
|
mud/skills/__init__.py,sha256=zzIr-ejbrlrQF1CSepODWhpxQZv8rO2pgaqIi3vpMg0,241
|
|
184
184
|
mud/skills/groups.py,sha256=_80fJkXfrPUmTcZ9JsCJHIAhRdmmGhayMJgn1pSFcQY,8127
|
|
185
|
-
mud/skills/handlers.py,sha256=
|
|
185
|
+
mud/skills/handlers.py,sha256=JPn-qRrpMzdu87sVOgbxZU0IK-LeWmzwRWRLYXuh3gk,265536
|
|
186
186
|
mud/skills/metadata.py,sha256=xNpiH3EmCMWY_DtO_Pjrhs2U7bYOBxyrsTL0wC_RJes,15413
|
|
187
187
|
mud/skills/registry.py,sha256=B9qmxCQZde7dZaxqdnIRTPHAMYbrnfkDT2qUlCkgvrY,13332
|
|
188
|
+
mud/skills/say_spell.py,sha256=4voaTUbpYKsF0Plv9m-Eh0FK6lp1-Cz15rQBRq_XLNo,3909
|
|
188
189
|
mud/spawning/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
189
190
|
mud/spawning/mob_spawner.py,sha256=CZSvWn1aV3AQbxcS2QFqG0OzL2qXrLUNUKvoQnDQR9o,292
|
|
190
191
|
mud/spawning/obj_spawner.py,sha256=etEqWOvZsteajNO3HCzmJO7GulhxO4k_4ID9PUhZTsM,2708
|
|
191
|
-
mud/spawning/reset_handler.py,sha256=
|
|
192
|
+
mud/spawning/reset_handler.py,sha256=wtp-S0GP4XzhC7a6ekPrhnoxGXsixMT5sRvAXb2Vo84,33092
|
|
192
193
|
mud/spawning/templates.py,sha256=oyFsjjGW-cuEhMs9H1amoSqsWjlsnT7QpbOvlx1PDWs,15110
|
|
193
194
|
mud/utils/act.py,sha256=3GJVlnztkt4d2sMkxgL9uKGLerok8chTf_hM_N8mcaI,4224
|
|
194
195
|
mud/utils/rng_mm.py,sha256=7kCeV9Q6mqvTDaiIwrcEaSarlmFtNjJTYuLYUWYBs5U,3591
|
|
@@ -200,10 +201,10 @@ mud/world/look.py,sha256=n9ecKP3y9lEZuzKn2GHsXyd-azfD_vbfeHHCGdEKZls,9631
|
|
|
200
201
|
mud/world/movement.py,sha256=Y7it7pXrPORgKyy2tRB8br_kb4-s9UK-gj0N-E2U9oM,18695
|
|
201
202
|
mud/world/obj_find.py,sha256=4VAUSwWxhyYIMZIfxdDhKMAP5FZ0NpRikgX02vy0elo,4201
|
|
202
203
|
mud/world/vision.py,sha256=q8VjzSzm0cbNrHX6-o0j1UG-jlcM3Z9bzUxK6T-Bsi8,9862
|
|
203
|
-
mud/world/world_state.py,sha256=
|
|
204
|
-
rom24_quickmud_python-2.5.
|
|
205
|
-
rom24_quickmud_python-2.5.
|
|
206
|
-
rom24_quickmud_python-2.5.
|
|
207
|
-
rom24_quickmud_python-2.5.
|
|
208
|
-
rom24_quickmud_python-2.5.
|
|
209
|
-
rom24_quickmud_python-2.5.
|
|
204
|
+
mud/world/world_state.py,sha256=tmbLaYKkHTa69Mk3Ul4seMvxSNe_MAVJeibWVvwDTGQ,7772
|
|
205
|
+
rom24_quickmud_python-2.5.2.dist-info/licenses/LICENSE,sha256=anQ2j9As6sIC8tZgQCXbo0-09JDH9vPiqhA9djnOvkY,1078
|
|
206
|
+
rom24_quickmud_python-2.5.2.dist-info/METADATA,sha256=LZD6OYtT_iwkAO9uUavP0A1avrbhqUva5j4ChdpzhlE,12368
|
|
207
|
+
rom24_quickmud_python-2.5.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
208
|
+
rom24_quickmud_python-2.5.2.dist-info/entry_points.txt,sha256=VFru08UQTXZA_CkK-NBjJmWHyEX5a3864fQHjhaojbw,41
|
|
209
|
+
rom24_quickmud_python-2.5.2.dist-info/top_level.txt,sha256=Fk1WPmabIIjp7_iZXLYpbAVqiq7lG7TeAHt30AsOKtQ,4
|
|
210
|
+
rom24_quickmud_python-2.5.2.dist-info/RECORD,,
|
|
File without changes
|
{rom24_quickmud_python-2.5.0.dist-info → rom24_quickmud_python-2.5.2.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{rom24_quickmud_python-2.5.0.dist-info → rom24_quickmud_python-2.5.2.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
{rom24_quickmud_python-2.5.0.dist-info → rom24_quickmud_python-2.5.2.dist-info}/top_level.txt
RENAMED
|
File without changes
|