Created
January 9, 2025 22:46
-
-
Save Pinacolada64/0c33d4352bb2e187404940988f35a838 to your computer and use it in GitHub Desktop.
Trying out some Item classes and functions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from dataclasses import dataclass | |
from enum import StrEnum | |
from typing import Optional | |
# from flags import Size | |
@dataclass | |
class Item(object): | |
name: str = None | |
# percent_left: int: depletes with each use, 0 indicating the item is destroyed; or | |
# percent_left: None indicates a one-time use (e.g., bullets can't be reused) | |
percent_left: Optional[int] = None | |
quantity: int = 1 | |
class Armor(Item): | |
armor_class: int | |
class Shield(Item): | |
# TODO: weight (iron shield vs. wooden shield will be different), | |
# could also define effectiveness, heavier shields absorb more damage | |
# FIXME: int will eventually be Size, but circular reference currently prevents using it | |
size: int | |
skill: int | |
@dataclass | |
class WeaponClass(StrEnum): | |
# in original code, 1 gets changed to 10: | |
ENERGY = 1 | |
HACK_SLASH_BASH = 2 | |
POKE_JAB = 3 | |
# I don't know why class 4 was skipped, but keep it that way | |
POLE_RANGED = 5 | |
# likewise, classes 6 & 7 were skipped | |
# +10% surprise against enemy | |
PROJECTILE = 8 | |
PROXIMITY = 9 | |
@dataclass | |
class Weapon(Item): | |
super().__init__(**kwargs) | |
weapon_class: WeaponClass | |
@dataclass | |
class Spell: | |
charges: int | |
chance_to_cast: int | |
@dataclass | |
class StormWeapon(Weapon): | |
# enchanted weapon with a personality, may be able to cast spells | |
can_cast_spells: bool = True | |
spell_list: Optional[Spell | list[Spell]] = None | |
@dataclass | |
class Ammunition(Item): | |
quantity: int = 1 | |
enchanted: bool = False # I think there are some magical ammunition items | |
@dataclass | |
class AmmunitionWeapon(Weapon): | |
super().__init__(percent_left) | |
# a weapon that needs ammunition (e.g., SLING needs ROCKS or STEELIES, BOW needs ARROW, etc.) | |
takes_ammunition_type: Optional[list[Ammunition] | Ammunition] = None | |
loaded_ammunition_type: Optional[Ammunition] = None # None specifies the weapon being unloaded | |
# some might go with multiple Weapons: e.g., bullets; | |
# None is an option to avoid partially instantiated objects: | |
goes_with: Optional[Weapon | list[Weapon]] = None | |
def load_weapon(self, ammo: Ammunition): | |
# this can be called for SABRE POWER and the POWER PAK on the Spaceship level: | |
if self.takes_ammunition_type == ammo: | |
print(f"You load {ammo.quantity} {ammo.name} into the {self.name}.") | |
else: | |
# TODO: different messages for different weapon classes | |
if self.weapon_class == WeaponClass.PROJECTILE: | |
print(f"The {self.name} jams and cannot be fired. " | |
f"It is loaded with the wrong kind of ammunition.") | |
def has_correct_ammo(self): | |
# return whether the loaded ammunition type is correct for the weapon | |
if isinstance(self.takes_ammunition_type, list): | |
return self.loaded_ammunition_type in self.takes_ammunition_type | |
else: | |
return self.takes_ammunition_type == self.loaded_ammunition_type | |
if __name__ == '__main__': | |
# trying to avoid a circular reference here by stating 'bullet.goes_with=colt_45'; | |
# colt_45 isn't instantiated yet | |
bullets = Ammunition(name=".45 bullets", quantity=6, percent_left=None) | |
colt_45 = AmmunitionWeapon(name="Colt .45", | |
percent_left=100, | |
takes_ammunition_type=bullets, | |
loaded_ammunition_type=None, | |
# likewise, avoiding circular reference here, set 'goes_with' later: | |
goes_with=None, | |
weapon_class=WeaponClass.PROJECTILE) | |
# now that the gun is instantiated, we can say the bullet goes with the gun: | |
bullets.goes_with = colt_45 | |
colt_45.loaded_ammunition_type = bullets | |
colt_45.load_weapon(bullets) | |
if colt_45.has_correct_ammo(): | |
print(f"The {colt_45.name} can be fired using {colt_45.takes_ammunition_type}, of which you have " | |
f"{colt_45.loaded_ammunition_type.quantity}.") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment