Skip to content

Commit

Permalink
Merge pull request #45 from mmacy/docstring-work-02
Browse files Browse the repository at this point in the history
docstring pass on dungeon, inventory, party modules
  • Loading branch information
mmacy committed Jan 29, 2024
2 parents d1206e7 + 3fe5c4d commit ab25d2f
Show file tree
Hide file tree
Showing 6 changed files with 301 additions and 171 deletions.
2 changes: 2 additions & 0 deletions docs/reference/constants.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@
::: osrlib.constants.HALFLING_NAMES
::: osrlib.constants.MAGIC_USER_NAMES
::: osrlib.constants.THIEF_NAMES
::: osrlib.constants.ADVENTURE_NAMES
::: osrlib.constants.DUNGEON_NAMES
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ extra_css:
- "main.css"

plugins:
- search
- mkdocstrings:
handlers:
python:
Expand Down
208 changes: 153 additions & 55 deletions osrlib/osrlib/dungeon.py

Large diffs are not rendered by default.

53 changes: 30 additions & 23 deletions osrlib/osrlib/inventory.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
"""The `inventory` module includes the [Inventory][osrlib.inventory.Inventory] class which backs the `inventory` attribute of a [PlayerCharacter][osrlib.player_character.PlayerCharacter]."""

from collections import defaultdict
from typing import List

Expand Down Expand Up @@ -28,15 +30,18 @@ class Inventory:
owner (PlayerCharacter): Owner of the inventory.
Example:
>>> pc = PlayerCharacter()
>>> inv = Inventory(pc)
```python
>>> pc = PlayerCharacter()
>>> inv = Inventory(pc)
```
"""

def __init__(self, player_character_owner: "PlayerCharacter"):
"""Initialize a PlayerCharacter's inventory.
"""Creates a `PlayerCharacter` instance.
Args:
owner (PlayerCharacter): The player character that owns the inventory.
player_character_owner (PlayerCharacter): The player character that owns the inventory.
"""
self.items: defaultdict[ItemType, List[Item]] = defaultdict(list)
self.owner = player_character_owner
Expand Down Expand Up @@ -146,13 +151,13 @@ def unequip_item(self, item: Item):
else:
raise ItemNotEquippedError(f"Can't unequip item '{item.name}' because it is not currently equipped.")

def drop_all_items(self):
def drop_all_items(self) -> List[Item]:
"""Remove all items from the inventory and return a collection of the items that were removed.
Equipped items are unequipped prior to being removed.
Returns:
list[Item]: List of all items that were removed.
List of all items that were removed.
"""
removed_items = []
for item in self.all_items:
Expand All @@ -165,38 +170,38 @@ def drop_all_items(self):
return removed_items

@property
def all_items(self):
def all_items(self) -> List[Item]:
"""Gets all items stored in the items defaultdict inventory property.
Returns:
list[Item]: List of all items.
List of all items in the inventory.
"""
return [item for sublist in self.items.values() for item in sublist]

@property
def equipped_items(self):
def equipped_items(self) -> List[Item]:
"""Get all equipped items in the inventory.
Returns:
list[Item]: List of equipped items. Returns an empty list if no equipped items are present.
List of equipped items. Returns an empty list if no equipped items are present.
"""
return [item for item in self.all_items if item.is_equipped]

@property
def armor(self):
def armor(self) -> List[Armor]:
"""Gets all armor items stored in the items defaultdict inventory property.
Returns:
list[Item]: List of armor items. Returns an empty list if no armor items are present.
List of armor items. Returns an empty list if no armor items are present.
"""
return self.items[ItemType.ARMOR]

@property
def weapons(self):
def weapons(self) -> List[Weapon]:
"""Gets all weapon items stored in the items defaultdict inventory property.
Returns:
list[Item]: List of weapon items. Returns an empty list if no weapon items are present.
List of weapon items. Returns an empty list if no weapon items are present.
"""
return self.items[ItemType.WEAPON]

Expand All @@ -209,55 +214,57 @@ def get_equipped_weapon(self) -> Weapon:
return next((weapon for weapon in self.weapons if weapon.is_equipped), Weapon("Fists", "1d1"))

@property
def spells(self):
def spells(self) -> List[Spell]:
"""Gets all spell items stored in the items defaultdict inventory property.
Returns:
list[Item]: List of spell items. Returns an empty list if no spell items are present.
List of spell items. Returns an empty list if no spell items are present.
"""
return self.items[ItemType.SPELL]

@property
def equipment(self):
def equipment(self) -> List[Item]:
"""Gets all equipment items stored in the items defaultdict inventory property.
Returns:
list[Item]: List of equipment items. Returns an empty list if no equipment items are present.
List of equipment items. Returns an empty list if no equipment items are present.
"""
return self.items[ItemType.EQUIPMENT]

@property
def magic_items(self):
def magic_items(self) -> List[Item]:
"""Gets all magic items stored in the items defaultdict inventory property.
Returns:
list[Item]: List of magic items. Returns an empty list if no magic items are present.
List of magic items. Returns an empty list if no magic items are present.
"""
return self.items[ItemType.MAGIC_ITEM]

@property
def misc_items(self):
def misc_items(self) -> List[Item]:
"""Gets all miscellaneous items stored in the items defaultdict inventory property.
Miscellaneous items include items that are not armor, weapons, spells, equipment, or magic items.
Returns:
list[Item]: List of miscellaneous items. Returns an empty list if no miscellaneous items are present.
List of miscellaneous items. Returns an empty list if no miscellaneous items are present.
"""
return self.items[ItemType.ITEM]

def to_dict(self) -> dict:
"""Serializes the `Inventory` to a dictionary, typically in preparation for writing it to persistent storage in a downstream operation."""
return {
"items": [item.to_dict() for item in self.all_items],
"owner": self.owner.name,
}

@classmethod
def from_dict(cls, inventory_dict: dict, player_character_owner: "PlayerCharacter") -> "Inventory":
"""Converts a dictionary to an inventory.
"""Deserializes a dictionary representation of an `Inventory` object. Typically done after getting the dictionary from persistent storage.
Args:
inventory_dict (dict): Dictionary representation of the inventory.
player_character_owner (PlayerCharacter): The player character that owns the inventory.
"""
player_character_owner.inventory = Inventory(player_character_owner)

Expand Down
40 changes: 27 additions & 13 deletions osrlib/osrlib/item.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Classes that represent items in the game and player character (PC) inventory."""
"""The `item` module includes classes that represent items in the game like weapons, armor, spells, and regular adventuring gear."""
from enum import Enum
from typing import Optional, Set

Expand Down Expand Up @@ -69,8 +69,12 @@ class Item:
quest (Optional[Quest]): The quest that the item is a part of.
Example:
>>> usable_by = {CharacterClassType.FIGHTER, CharacterClassType.THIEF}
>>> item = Item("Sword", ItemType.WEAPON, usable_by, max_equipped=1, gp_value=10)
```python
# Create an item that is a sword usable by fighters and thieves
usable_by = {CharacterClassType.FIGHTER, CharacterClassType.THIEF}
item = Item("Sword", ItemType.WEAPON, usable_by, max_equipped=1, gp_value=10)
```
"""

def __init__(
Expand Down Expand Up @@ -223,7 +227,11 @@ class Armor(Item):
and a negative number increases AC (bad). Defaults to 1.
Example:
>>> armor = Armor("Plate Mail", ac_modifier=7)
```python
# Create a suit of plate mail
armor = Armor("Plate Mail", ac_modifier=7)
```
"""

def __init__(self, name: str, ac_modifier: int = -1, **kwargs):
Expand Down Expand Up @@ -267,6 +275,9 @@ def from_dict(cls, armor_dict: dict) -> "Armor":
class Weapon(Item):
"""Represents a weapon item in the game.
The Weapon class extends the Item class to represent weapons in the game. It specifies damage die and may have a
range indicating how far it can attack. Melee weapons typically have `None` as their range value.
Args:
name (str): The name of the weapon.
to_hit_damage_die (str, optional): The to-hit and damage roll for the weapon. Defaults to '1d4'.
Expand All @@ -277,14 +288,13 @@ class Weapon(Item):
damage_die (str): The damage die for the weapon, formatted like '1d8', '2d4', '1d6+1', etc.
range (Optional[int]): The range of the weapon in feet.
Note:
The Weapon class extends the Item class to represent weapons in the game.
It specifies damage die and may have a range indicating how far it can attack.
Melee weapons typically have `None` as their range value.
Example:
>>> sword = Weapon(name="Longsword", to_hit_damage_die="1d8")
>>> enchanted_bow = Weapon(name="Longbow of Accuracy", to_hit_damage_die="1d8+1", range=150)
```python
# Create a sword and a longbow +1
sword = Weapon(name="Longsword", to_hit_damage_die="1d8")
enchanted_bow = Weapon(name="Longbow of Accuracy", to_hit_damage_die="1d8+1", range=150)
```
"""

def __init__(
Expand Down Expand Up @@ -351,8 +361,12 @@ class Spell(Item):
instantaneous spell.
Example:
>>> fireball = Spell(name="Fireball", spell_level=3, damage_die="8d6", range=150, duration_minutes=None)
>>> heal = Spell(name="Heal", spell_level=6, damage_die=None, range=None, duration_minutes=10)
```python
# Create two spells, one of 3rd-level (fireball) and another of 6th-level (heal)
fireball = Spell(name="Fireball", spell_level=3, damage_die="8d6", range=150, duration_minutes=None)
heal = Spell(name="Heal", spell_level=6, damage_die=None, range=None, duration_minutes=10)
```
"""

def __init__(
Expand Down
Loading

0 comments on commit ab25d2f

Please sign in to comment.