Skip to content

Commit

Permalink
Mickey's refactor.
Browse files Browse the repository at this point in the history
  • Loading branch information
mickeylyle committed Jan 4, 2023
1 parent bd5b807 commit 63bb0f1
Show file tree
Hide file tree
Showing 8 changed files with 305 additions and 329 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# Python-Character-Creator
Python for a DnD character creator.
Code is supposed to receive inputs from a user so they may be walked through the creation of a DnD character.

TODO:
- critical hits
- critical damage
- more content
155 changes: 155 additions & 0 deletions character.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
import math
from random import randint
from dataclasses import dataclass

from entity import Entity
from equipment import armors, weapons
from dice import roll


CHARACTER_ATTRIBUTES = ("Strength", "Dexterity", "Constitution", "Intelligence", "Wisdom", "Charisma")


@dataclass
class PlayerClass:
name: str
starting_hp: int
hit_die: int


classes = list()
classes.append(PlayerClass("Fighter", 6, 10))


class Character(Entity):
def __init__(self):
Entity.__init__(self, input("Name your character: "))
self.level = 1
self.picker("class", classes)
self.reset_attributes()
self.pick_attributes(26)
self.max_hp = self.player_class.starting_hp + \
self.get_attribute_mod(CHARACTER_ATTRIBUTES[2]) * self.level
self.current_hp = self.max_hp
print(self.get_attrs_str())
self.picker("armor", armors)
self.picker("weapon", weapons)


def get_attribute_mod(self, attribute):
return math.floor((self.attributes[attribute] - 10) / 2)


def get_attribute_mod_cost(self, attribute):
a = self.attributes[attribute]
if a < 14:
return 1
elif a == 14:
return 2
elif a > 14:
return "MAX"


def reset_attributes(self):
self.attributes = dict()
for a in CHARACTER_ATTRIBUTES:
self.attributes[a] = 8


def pick_attributes(self, points):
numbers = range(1, len(CHARACTER_ATTRIBUTES) + 1)
error = ""

while points > 0:
print(" Attribute\tValue\tModifier\tCost")
for n, a in zip(numbers, CHARACTER_ATTRIBUTES):
print(f"{n}: {a}\t{self.attributes[a]}\t{self.get_attribute_mod(a)}\t{self.get_attribute_mod_cost(a)}")
print()
print(f"Attribute Points: {points}")
print(error)
choice = int(input("Choose an attribute to increase: "))
print()
if choice in numbers:
choice -= 1
a = CHARACTER_ATTRIBUTES[choice]
cost = self.get_attribute_mod_cost(a)
if cost == "MAX":
error = f"{CHARACTER_ATTRIBUTES[choice]} is at maximum"
elif cost <= points:
self.attributes[a] += 1
points -= cost
error = ""
else:
error = f"Not enough points to increase {a}"
else:
error = f"Please pick a number between {min(numbers)} and {max(numbers)}"


def get_attack_bonus(self):
return self.get_attack_attr_bonus() + self.get_proficiency_bonus()


def get_attack_attr_bonus(self):
return max(self.get_attribute_mod["Strength"],
self.get_attribute_mod["Dexterity"]) \
if self.weapon.finesse else self.get_attribute_mod("Strength")


def get_proficiency_bonus(self):
return math.floor(2 + ((self.level - 1) * 0.25))


def roll_weapon_damage(self):
return roll(*self.weapon.damage) + self.get_attack_attr_bonus()


def __str__(self):
return f"{self.name} is a level {self.level} {self.player_class.name}\n" \
f"{self.get_health_str()}\n" \
f"Armor: {self.armor.name} AC: {self.armor.armor_class} Weapon: {self.weapon.name}" \
f"{self.get_attrs_str()}"


def get_attrs_str(self):
return ''.join([f"{a}: {self.attributes[a]}\n" for a in CHARACTER_ATTRIBUTES])


def picker(self, pick_type, pick_list):
choices = [g.name for g in pick_list]
numbers = range(1, len(pick_list) + 1)

for i, name in zip(numbers, choices):
print(f"{i}: {name}")

prompt = f"Which {pick_type} would you like? "

while True:
choice = int(input(prompt))
if choice in numbers:
break
else:
prompt = f"Please pick a number between {min(numbers)} and {max(numbers)}: "

if pick_type == "armor":
self.armor = armors[choice - 1]
print(f"You chose {self.armor.name}.\n")
elif pick_type == "weapon":
self.weapon = weapons[choice - 1]
print(f"You chose {self.weapon.name}.\n")
elif pick_type == "class":
self.player_class= classes[choice - 1]
print(f"You chose {self.player_class.name}.\n")


def attack(self, enemy):
attack_roll = roll(1, 20) + self.get_attack_bonus()
print(f"{self.name} swings their {self.weapon.name} at the {enemy.name}!")
if enemy.armor_class < attack_roll:
print(f"{self.name} smacks the {enemy.name} a good one! {attack_roll} vs {enemy.get_ac()} AC")
enemy.take_damage(self.roll_weapon_damage())
else:
print(f"{self.name} wiffs!")


def get_ac(self):
return self.armor.ac + min(self.armor.max_dex_bonus, self.attributes["Dexterity"])
Loading

0 comments on commit 63bb0f1

Please sign in to comment.