osrlib 2.0.1__tar.gz → 2.2.0__tar.gz
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.
- {osrlib-2.0.1 → osrlib-2.2.0}/PKG-INFO +1 -1
- {osrlib-2.0.1 → osrlib-2.2.0}/pyproject.toml +1 -1
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/core/character.py +13 -3
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/core/classes.py +12 -6
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/core/combat.py +215 -133
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/core/effects.py +11 -5
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/core/events.py +95 -8
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/core/items.py +113 -49
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/core/monsters.py +87 -13
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/core/ruleset.py +6 -5
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/core/spells.py +21 -2
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/crawl/adventure.py +73 -41
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/crawl/battle.py +1307 -287
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/crawl/commands.py +1000 -300
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/crawl/dungeon.py +119 -32
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/crawl/encounter.py +200 -65
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/crawl/events.py +258 -37
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/crawl/exploration.py +158 -60
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/crawl/interpreter.py +72 -43
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/crawl/narrative.py +4 -4
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/crawl/party.py +63 -15
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/crawl/quests.py +10 -7
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/crawl/session.py +445 -70
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/crawl/triggers.py +45 -19
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/crawl/views.py +20 -4
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/data/monsters.json +572 -287
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/data/spells.json +2 -1
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/messages.py +35 -2
- {osrlib-2.0.1 → osrlib-2.2.0}/LICENSE +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/LICENSE-OGL.md +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/README.md +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/__init__.py +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/core/__init__.py +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/core/abilities.py +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/core/alignment.py +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/core/clock.py +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/core/creature.py +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/core/dice.py +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/core/npc.py +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/core/rng.py +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/core/tables.py +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/core/treasure.py +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/core/validation.py +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/crawl/__init__.py +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/crawl/content_pack.py +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/crawl/gates.py +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/crawl/stocking.py +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/data/LICENSE-OGL.md +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/data/__init__.py +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/data/abilities.json +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/data/classes.json +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/data/combat_tables.json +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/data/encounter_tables.json +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/data/equipment.json +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/data/languages.json +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/data/magic_items.json +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/data/treasure.json +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/errors.py +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/persistence.py +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/py.typed +0 -0
- {osrlib-2.0.1 → osrlib-2.2.0}/src/osrlib/versioning.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "osrlib"
|
|
3
|
-
version = "2.0
|
|
3
|
+
version = "2.2.0"
|
|
4
4
|
description = "B/X (1981 Basic/Expert) tabletop RPG rules engine for turn-based dungeon crawlers"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
# The wheel ships Open Game Content (osrlib/data/*.json and its LICENSE-OGL.md
|
|
@@ -228,9 +228,10 @@ class Character(BaseModel):
|
|
|
228
228
|
id: str | None = None
|
|
229
229
|
"""The character's id within a game, like `"character-0001"`, or `None` before a session assigns one.
|
|
230
230
|
|
|
231
|
-
[`GameSession.new`][osrlib.crawl.session.GameSession.new] assigns an id
|
|
232
|
-
|
|
233
|
-
|
|
231
|
+
[`GameSession.new`][osrlib.crawl.session.GameSession.new] assigns an id from the session's
|
|
232
|
+
[`IdAllocator`][osrlib.core.monsters.IdAllocator] to each party member whose id is `None`.
|
|
233
|
+
[`AddMember`][osrlib.crawl.commands.AddMember] does the same for a character who joins during play. Commands refer
|
|
234
|
+
to a character by this id. An event about a character with no id uses the character's `name` instead.
|
|
234
235
|
"""
|
|
235
236
|
|
|
236
237
|
name: str = Field(min_length=1)
|
|
@@ -287,6 +288,15 @@ class Character(BaseModel):
|
|
|
287
288
|
[`kill`][osrlib.core.effects.kill] applies, not a hit point value.
|
|
288
289
|
"""
|
|
289
290
|
|
|
291
|
+
nonregen_damage: int = Field(default=0, ge=0)
|
|
292
|
+
"""The fire and acid damage that a worn ring of regeneration can't heal, up to `max_hp`.
|
|
293
|
+
|
|
294
|
+
While the character wears the ring, [`deal_damage`][osrlib.core.combat.deal_damage] adds fire and acid damage
|
|
295
|
+
here. The ring heals the character only up to `max_hp` less this amount. Other healing, like a potion, heals this
|
|
296
|
+
damage too. So each time the character takes damage while wearing the ring, `deal_damage` first lowers this value
|
|
297
|
+
to the damage the character had before that hit. It's 0 for a character who has never worn the ring.
|
|
298
|
+
"""
|
|
299
|
+
|
|
290
300
|
inventory: Inventory = Field(default_factory=Inventory)
|
|
291
301
|
"""Everything the character carries, wears, and wields, and their coins. See
|
|
292
302
|
[`Inventory`][osrlib.core.items.Inventory] and the buying and equipping functions in
|
|
@@ -1180,9 +1180,10 @@ class DrainResult(BaseModel):
|
|
|
1180
1180
|
"""
|
|
1181
1181
|
|
|
1182
1182
|
hp_lost: int
|
|
1183
|
-
"""The hit points the drain
|
|
1183
|
+
"""The hit points the drain rolls to take, from both maximum and current hit points.
|
|
1184
1184
|
|
|
1185
1185
|
Neither total drops below 1 while the character has a level left, so the totals can fall by less than this.
|
|
1186
|
+
The drain event in `events` has its own `hp_lost`, which is how far the maximum actually fell.
|
|
1186
1187
|
"""
|
|
1187
1188
|
|
|
1188
1189
|
xp_after: int | None = None
|
|
@@ -1249,8 +1250,10 @@ def drain_levels(
|
|
|
1249
1250
|
`streams.get(`[`ADVANCEMENT_STREAM`][osrlib.core.character.ADVANCEMENT_STREAM]`)`,
|
|
1250
1251
|
the stream that level gains draw from.
|
|
1251
1252
|
spawn_consequence: A description of what a victim drained of all levels becomes, like the
|
|
1252
|
-
description of the monster's `energy_drain` ability.
|
|
1253
|
-
drain event for you to show
|
|
1253
|
+
description of the monster's `energy_drain` ability. When the drain kills the character,
|
|
1254
|
+
this function copies it onto the `combat.drain.slain` event for you to show. osrlib
|
|
1255
|
+
doesn't act on it. When the character survives, the function doesn't copy it, because
|
|
1256
|
+
the character hasn't become anything. `None` leaves it off.
|
|
1254
1257
|
|
|
1255
1258
|
Returns:
|
|
1256
1259
|
What the character lost, and the events that describe it.
|
|
@@ -1290,6 +1293,9 @@ def drain_levels(
|
|
|
1290
1293
|
result = drain_levels(character, fighter, levels=1, xp_policy="halfway", stream=advancement)
|
|
1291
1294
|
print(result.levels_lost, result.new_level, result.hp_lost, result.slain)
|
|
1292
1295
|
# 1 1 9 False
|
|
1296
|
+
|
|
1297
|
+
# The lost level's d8 came up 8, and Rurik's CON modifier adds 1, so the drain takes 9
|
|
1298
|
+
# hit points: maximum hit points fall from 10 to 1.
|
|
1293
1299
|
print(character.level, character.xp, character.max_hp)
|
|
1294
1300
|
# 1 1000 1
|
|
1295
1301
|
```
|
|
@@ -1301,6 +1307,7 @@ def drain_levels(
|
|
|
1301
1307
|
if xp_policy not in ("halfway", "level_minimum"):
|
|
1302
1308
|
raise ValueError(f"unknown xp policy {xp_policy!r}")
|
|
1303
1309
|
former_level = character.level
|
|
1310
|
+
former_max_hp = character.max_hp
|
|
1304
1311
|
hp_rolls: list[int] = []
|
|
1305
1312
|
hp_lost = 0
|
|
1306
1313
|
slain = False
|
|
@@ -1334,7 +1341,7 @@ def drain_levels(
|
|
|
1334
1341
|
target_id=character.id or character.name,
|
|
1335
1342
|
levels_lost=levels_lost,
|
|
1336
1343
|
new_level=0,
|
|
1337
|
-
hp_lost=
|
|
1344
|
+
hp_lost=former_max_hp - character.max_hp,
|
|
1338
1345
|
spawn_consequence=spawn_consequence,
|
|
1339
1346
|
)
|
|
1340
1347
|
)
|
|
@@ -1360,9 +1367,8 @@ def drain_levels(
|
|
|
1360
1367
|
target_id=character.id or character.name,
|
|
1361
1368
|
levels_lost=former_level - character.level,
|
|
1362
1369
|
new_level=character.level,
|
|
1363
|
-
hp_lost=
|
|
1370
|
+
hp_lost=former_max_hp - character.max_hp,
|
|
1364
1371
|
xp_after=xp_after,
|
|
1365
|
-
spawn_consequence=spawn_consequence,
|
|
1366
1372
|
)
|
|
1367
1373
|
)
|
|
1368
1374
|
events.append(
|