Skip to content

Instantly share code, notes, and snippets.

@Pinacolada64
Created November 9, 2022 07:17
Show Gist options
  • Save Pinacolada64/207013168194d3a77cfb5e044a286403 to your computer and use it in GitHub Desktop.
Save Pinacolada64/207013168194d3a77cfb5e044a286403 to your computer and use it in GitHub Desktop.
Trying a different way of instantiating a character
"""
A note about positional parameters:
https://www.reddit.com/r/learnpython/comments/yptsyp/comment/ivkydz0/?utm_source=share&utm_medium=web2x&context=3
"""
from dataclasses import dataclass
from typing import Tuple
@dataclass
class Character:
def __init__(self):
"""
Attributes, flags and other stuff about characters.
"""
name: str
id: int # for Player.connect
connection_id: int # TODO: eventually, CommodoreServer Internet Protocol connection ID
gender: str # [ male | female ]
# creates a new kwargs dict for each Character:
# set with Character.set_stat('xyz', val)
stats: dict['chr': int, 'con': int, 'dex': int, 'int': int, 'str': int, 'wis': int, 'egy': int]
# status flags:
flag: dict[
'room_descriptions': bool,
# status flags:
'autoduel': bool,
'hourglass': bool,
'expert': bool,
'more_prompt': bool,
'architect': bool,
# orator_mode: bool # TODO: define orator_mode more succinctly
# health flags:
'hungry': bool,
'thirsty': bool,
'diseased': bool,
'poisoned': bool,
'tired': bool,
'on_horse': bool,
'unconscious': bool,
# other flags:
'debug': bool,
'dungeon_master': bool,
'compass_used': bool,
'thug_attack': bool,
# game objectives:
'spur_alive': bool,
'dwarf_alive': bool,
'wraith_king_alive': bool,
'wraith_master': bool,
'tut_treasure': dict['examined': bool, 'taken': bool],
# magic items:
'gauntlets_worn': bool,
'ring_worn': bool,
'amulet_of_life': bool,
# wizard_glow stuff:
# 0 if inactive
# != 0 is number of rounds left, decrement every turn
'wizard_glow': int
]
"""
# things you can only do once per day (file_formats.txt)
'pr' has PRAYed once
'pr2' can PRAY twice per day (only if char_class is Druid)
"""
once_per_day: list
# TODO: money types may be expanded to platinum, electrum in future
# creates a new silver dict for each Character:
# in_bank: may be cleared on character death (TODO: look in TLOS source)
# in_bar: should be preserved after character's death (TODO: same)
# use Character.set_silver("kind", value)
silver: dict['in_hand': int, 'in_bank': int, 'in_bar': int]
age: int
birthday: Tuple[('0', '0', '0')] # (month, day, year)
guild: str # [civilian | fist | sword | claw | outlaw]
# 1 2 3 4 5 6 7 8 9
char_class: str # Wizard Druid Fighter Paladin Ranger Thief Archer Assassin Knight
race: str # ......Human Ogre Pixie Elf Hobbit Gnome Dwarf Orc Half-Elf
natural_alignment: str # good | neutral | evil (depends on race)
# client info:
client: dict[
# host (i.e., Python, C64, C128...?)
'name': None,
# screen dimensions:
'rows': int,
'cols': int,
# {'translation': None | ASCII | ANSI | Commodore }
'translation': str,
# colors for [bracket reader] text highlighting on C64/128:
'text': None,
'highlight': None,
'background': None,
'border': None]
hit_points: int
experience: int
# map stats:
map_level: int # cl
map_room: int # cr
moves_made: int
# combat stats:
armor: list # e.g., should it be its own class with attributes?
# Armor(object):
# def __init__(name, percent_left, armor_class, ...)
# TODO: weight (iron armor vs. padded leather armor will be different),
# could also define effectiveness, heavier armor absorbs more damage
shield: dict
shield_used: int # shield item being USEd
shield_skill: dict['item': int, 'skill': int]
# same:
# Shield(object):
# def __init__(name, percent_left, shield_size, ...)
# TODO: weight (iron shield vs. wooden shield will be different),
# could also define effectiveness, heavier shields absorb more damage
weapon: dict
weapon_used: int # if != 0, this weapon READYed
weapon_skill: dict # {weapon_item: int, weapon_skill: int}
weapon_left: int # map this to a rating
# bad_hombre_rating is calculated from stats, not stored in player log
honor_rating: int # helps determine current_alignment
formal_training: int
monsters_killed: int
"""
monsters_killed is not always the same as dead_monsters[];
still increment it if you re-kill a re-animated monster
"""
dead_monsters: list # keeps track of monsters for Zelda in the bar to resurrect
monster_at_quit: str
# ally stuff:
allies: list # (list of tuples?)
ally_inv: list
ally_abilities: list
# horse stuff:
has_horse: bool
horse_name: str
horse_armor: dict
has_saddlebags: bool
saddlebags: list # these can carry items for GIVE and TAKE commands
vinny_loan: dict # {amount_payable: int, days_til_due: int}
# inventory
"""
# TODO: There should be methods here for Inventory:
Inventory.item_held(item): check player/ally inventory, return True or False
(is it important to know whether the player or ally is carrying an item?)
maybe return Character or Ally object if they hold it, or None if no-one holds it
Or could be written:
if 'armor' in Character.inventory and 'armor' in Character.used:
# meaning 'armor' is in 'inventory' and 'used' lists?
# could this be shortened? perhaps:
# if Character.ItemHeldUsed('armor')
"""
max_inv: int
# also see weapons[], armor[], shields[]
food: list
drink: list
spells: list # list of dicts('spell_name': str, 'charges', 'chance_to_cast': int)
booby_traps: dict['room': int, 'combination': str] # combo: '[a-i]'
times_played: int # TODO: increment at Character.save()
last_play_date: Tuple[(0, 0, 0)] # (month, day, year) like birthday
special_items: dict
# SCRAP OF PAPER is randomly placed on level 1 with a random elevator combination
# TODO: avoid placing objects in map "holes" where no room exists
# DINGHY # does not actually need to be carried around in inventory, I don't suppose, just a flag?
combinations: dict['elevator': (0, 0, 0),
'locker': (0, 0, 0),
'castle': (0, 0, 0)] # tuple: combo is 3 digits: (nn, nn, nn)
def create_character(self):
pass
def display_stats(self):
print(f"Name: {self.name:20} Gender: {self.gender.title()}")
for stat_name, stat in self.stat.items():
# print(f" Int: {self.stat['int']:20}", end='')
print(f" {stat_name.title()}: {stat: 2d}") # end=''
print(f"HP: {self.hp:,}")
def display_inv(self):
print("\nInventory:")
if self.inv:
count = 0
for i in self.inv:
count += 1
print(f'{count: 2}. - {i.name}')
print(f'\t{i.description}')
else:
print("\tNothing")
print("\nAllies:")
if self.allies:
count = 0
for i in self.allies:
count += 1
print(f" {count: 2}. - {i.name}")
else:
print("\tNone... sniff...")
class Item:
def __init__(self, name, description):
self.name = name
self.description = description
class Wand(Item):
def __init__(self, name, description, charges, attribute, adjustment, effectiveness):
# name is already given in Item superclass, but can't be left out here?
super().__init__(name, description)
self.name = name
self.description = description # listed in inv line
self.charges = charges # how many shots this thing fires
self.attribute = attribute # which attribute it affects
self.adjustment = adjustment # how many points +/- it affects
self.effectiveness = effectiveness # random percentage it succeeds or fails
class Book(Item):
def __init__(self, name, description, text, attribute, adjustment, effectiveness):
super().__init__(name, description)
self.name = name
self.description = description # shown in inv listing
self.text = text # text displayed when read
self.attribute = attribute # which attribute it affects
self.adjustment = adjustment # how many points +/- it affects
self.effectiveness = effectiveness # % chance to adjust stats
# class Dog(pet):
# def __init__(self, name, chases_cats):
# pet.__init__(self, name, "Dog")
# self.chases_cats = chases_cats
#
# def ChasesCats(self):
# return self.chases_cats
guide = Book(name="Adventurer's Guide",
description="A guide to adventuring.",
text="text",
attribute="wis",
adjustment=5,
effectiveness=50)
wand = Wand(name="Wand of Understanding",
description="Intelligence booster.",
charges=20, attribute="int",
adjustment=5,
effectiveness=80)
snrak = Item(name="Snrakity Thing",
description="A thing of snraking.")
Amber = Character()
print(Amber)
Amber.name = "Amber"
Amber.hp = 100
Amber.silver = {'in_hand': 2000, 'in_bank': 2000, 'in_bar': 1000}
Amber.inv = [guide]
Amber.allies = ['Rulan', 'Jee', 'Shaia']
Amber.stat = {'int': 20, 'wis': 20}
Amber.age = 25
Amber.gender = 'female'
print(Amber)
Rulan = Character()
Rulan.name = "Rulan"
Rulan.hp = 100
Rulan.silver = {'in_hand': 2000, 'in_bank': 2000, 'in_bar': 1000}
Rulan.inv = []
Rulan.allies = ['Jee']
Rulan.stat = {'int': 5}
Rulan.age = 46
Rulan.gender = 'male'
Rulan.char_class = 'polarfuchs'
Tricuspa = Character()
Tricuspa.name = "Tria"
Tricuspa.hp = 100
Tricuspa.silver = {'in_hand': 2000, 'in_bank': 2000, 'in_bar': 1000}
Tricuspa.inv = [guide, wand]
Tricuspa.allies = list
Tricuspa.stat = {'int': 5}
Tricuspa.age = 40
Tricuspa.gender = 'female'
Jee = Character()
Jee.name = "J'ee"
Jee.char_class = 'drgn'
Jee.char_race = 'galaxy'
Jee.hp = 100
Jee.silver = {'in_hand': 2000, 'in_bank': 2000, 'in_bar': 1000}
Jee.inv = [guide, wand, snrak]
Jee.allies = [Rulan]
Jee.stat = {'int': 18}
Shaia = Character()
Shaia.name = "Shaia"
Shaia.char_class = "faerie"
Shaia.hp = 2000
Shaia.silver = {'in_hand': 2000, 'in_bank': 2000, 'in_bar': 1000}
Shaia.inv = [wand]
Shaia.allies = ["Jee", "Rulan"]
Shaia.stat = {'int': 24}
Shaia.flag = dict['dungeon_master': True]
# Rulan.allies = [Amber, Jee]
# Amber.allies = [Rulan, Jee]
print(f"Shaia.flag['dungeon_master'=]")
party = [Amber, Jee, Rulan, Tricuspa]
while True:
cmd = input("Command: ").lower()
if cmd == "stat":
for member in party:
member.display_stats()
member.display_inv()
print()
if cmd == "quit":
exit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment