mechanic: refactor creating new player

This commit is contained in:
rr-
2018-11-05 21:04:39 +01:00
parent a1d90547fb
commit 5c80a224ce
3 changed files with 174 additions and 66 deletions
+14 -19
View File
@@ -3,11 +3,6 @@ import typing as T
from dataclasses import dataclass
def level_up_time(level) -> int:
# seconds
return 20 * level * 60
class Traits(enum.Enum):
name = "Name"
race = "Race"
@@ -26,6 +21,20 @@ class Stat(enum.Enum):
mp_max = "MP Max"
class Equipment(enum.Enum):
weapon = "Weapon"
shield = "Shield"
helm = "Helm"
hauberk = "Hauberk"
brassairts = "Brassairts"
vambraces = "Vambraces"
gauntlets = "Gauntlets"
gambeson = "Gambeson"
cuisses = "Cuisses"
greaves = "Greaves"
sollerets = "Sollerets"
PRIME_STATS = [
Stat.strength,
Stat.condition,
@@ -38,20 +47,6 @@ PRIME_STATS = [
ALL_STATS = PRIME_STATS + [Stat.hp_max, Stat.mp_max]
EQUIPS = [
"Weapon",
"Shield",
"Helm",
"Hauberk",
"Brassairts",
"Vambraces",
"Gauntlets",
"Gambeson",
"Cuisses",
"Greaves",
"Sollerets",
]
SPELLS = [
"Slime Finger",
"Rabbit Punch",
+142 -17
View File
@@ -1,9 +1,15 @@
import datetime
import enum
import random
import typing as T
from dataclasses import dataclass
from dataclasses import dataclass, field
from pqcli.config import CLASSES, PRIME_STATS, RACES, Class, Race, Stat
from pqcli.config import *
def level_up_time(level: int) -> int:
# seconds
return 20 * level * 60
def generate_name() -> str:
@@ -20,7 +26,7 @@ def generate_name() -> str:
@dataclass
class Stats:
def __init__(self):
def __init__(self) -> None:
self.values = {stat: 0 for stat in Stat}
def __iter__(self) -> T.Iterable[T.Tuple[Stat, int]]:
@@ -34,24 +40,145 @@ class Stats:
@dataclass
class Player:
class Item:
name: str
stats: Stats
race: Race
class_: Class
birthday: datetime.datetime
quantity: int
@dataclass
class Spell:
name: str
level: int
class Inventory:
def __init__(self, items: T.Optional[T.List[Item]] = []) -> None:
self.items = [] if items is None else items
def add(self, item_name: str, quantity: int) -> None:
for item in self.items:
if item.name == item_name:
item.quantity += quantity
break
else:
self.items.append(Item(name=item_name, quantity=quantity))
class SpellBook:
def __init__(self, spells: T.Optional[T.List[Item]] = None) -> None:
self.spells = [] if spells is None else spells
def add(self, spell_name: str, level: int) -> None:
for item in self.spells:
if item.name == spell_name:
item.level += level
break
else:
self.spells.append(Spell(name=spell_name, level=level))
class Bar:
def __init__(self, max_: int, position: int = 0) -> None:
self.position = position
self.max_ = max_
class TaskType(enum.Enum):
task = "task"
plot = "plot"
@dataclass
class Task:
task_type: TaskType
length: int
description: str
class Player:
def __init__(
self,
name: str,
birthday: datetime.datetime,
race: Race,
class_: Class,
stats: Stats,
) -> None:
self.name: str = name
self.birthday: datetime.datetime = birthday
self.race: Race = race
self.class_: Class = class_
self.stats: Stats = stats
self.level = 1
self.act = 0
self.queue: T.List[Task] = [
Task(
TaskType.task,
10,
"Experiencing an enigmatic and foreboding night vision",
),
Task(
TaskType.task,
6,
"Much is revealed about that wise old bastard you'd underestimated",
),
Task(
TaskType.task,
6,
"A shocking series of events leaves you alone and bewildered, but resolute",
),
Task(
TaskType.task,
4,
"Drawing upon an unrealized reserve of determination, you set out on a long and dangerous journey",
),
Task(TaskType.plot, 2, "Loading"),
]
self.exp_bar = Bar(max_=level_up_time(1))
self.encum_bar = Bar(max_=stats[Stat.strength] + 10)
self.quest_bar = Bar(max_=1)
self.task_bar = Bar(max_=2000)
self.plot_bar = Bar(max_=sum(task.length for task in self.queue))
self.inventory = Inventory([Item(name="Gold", quantity=0)])
self.spell_book = SpellBook()
self.equipment: T.Dict[Equipment, str] = {
Equipment.weapon: "Sharp Rock",
Equipment.hauberk: "-3 Burlap",
}
def special_item() -> str:
return interesting_item() + " of " + random.choice(ITEM_OFS)
def interesting_item() -> str:
return random.choice(ITEM_ATTRIB) + " " + random.choice(SPECIALS)
def boring_item() -> str:
return random.choice(BORING_ITEMS)
def win_item(player: Player) -> None:
player.inventory.add(special_item(), 1)
class Roster:
def __init__(self) -> None:
self.players: T.List[Player] = []
def add_player(self, player: Player) -> None:
self.players.append(player)
class StatsBuilder:
def __init__(self):
def __init__(self) -> None:
self.history: T.List[Stats] = []
def roll(self):
def roll(self) -> Stats:
stats = Stats()
for stat in PRIME_STATS:
stats[stat] = (
@@ -67,18 +194,16 @@ class StatsBuilder:
self.history.append(stats)
return stats
def unroll(self):
def unroll(self) -> Stats:
self.history.pop()
return self.history[-1]
def create_player(stats_builder: StatsBuilder) -> Player:
def create_player(
name: str, race: Race, class_: Class, stats: Stats
) -> Player:
now = datetime.datetime.now()
random.seed(now)
return Player(
birthday=now,
name=generate_name(),
stats=stats_builder.roll(),
race=random.choice(RACES),
class_=random.choice(CLASSES),
birthday=now, name=name, race=race, class_=class_, stats=stats
)
+18 -30
View File
@@ -5,15 +5,15 @@ import urwid
import urwid_readline
from pqcli.config import CLASSES, PRIME_STATS, RACES
from pqcli.mechanic import Player, StatsBuilder, create_player, generate_name
from pqcli.mechanic import Stats, StatsBuilder, generate_name
from pqcli.ui.button import MenuButton
from pqcli.ui.line_box import LineBox
class StatsBox(urwid.Filler):
def __init__(self, player: Player, stats_builder: StatsBuilder) -> None:
self.player = player
self.stats_builder = stats_builder
def __init__(self) -> None:
self.stats_builder = StatsBuilder()
self.stats = self.stats_builder.roll()
self.stat_labels = {stat: urwid.Text("0") for stat in PRIME_STATS}
self.total_label = urwid.Text("0")
self.update_values()
@@ -59,48 +59,46 @@ class StatsBox(urwid.Filler):
)
def on_roll_press(self, _user_data: T.Any) -> None:
self.player.stats = self.stats_builder.roll()
self.stats = self.stats_builder.roll()
self.update_values()
def on_unroll_press(self, _user_data: T.Any) -> None:
try:
self.player.stats = self.stats_builder.unroll()
self.stats = self.stats_builder.unroll()
except IndexError:
return
self.update_values()
def update_values(self) -> None:
for stat, edit in self.stat_labels.items():
edit.set_text(str(self.player.stats[stat]))
edit.set_text(str(self.stats[stat]))
self.total_label.set_text(
str(
sum(
self.player.stats[stat] for stat in self.stat_labels.keys()
)
)
str(sum(self.stats[stat] for stat in self.stat_labels.keys()))
)
class RaceBox(LineBox):
def __init__(self, player: Player) -> None:
def __init__(self) -> None:
race_checkboxes = []
self.race = random.choice(RACES)
for race in RACES:
urwid.RadioButton(
group=race_checkboxes,
label=race.name,
state=race.name == player.race.name,
state=race.name == self.race.name,
)
super().__init__(urwid.ListBox(race_checkboxes), title="Race")
class ClassBox(LineBox):
def __init__(self, player: Player) -> None:
def __init__(self) -> None:
class_checkboxes = []
self.class_ = random.choice(CLASSES)
for class_ in CLASSES:
urwid.RadioButton(
group=class_checkboxes,
label=class_.name,
state=class_.name == player.class_.name,
state=class_.name == self.class_.name,
)
super().__init__(urwid.ListBox(class_checkboxes), title="Class")
@@ -110,24 +108,17 @@ class NewGameView(urwid.Pile):
self.on_confirm = on_confirm
self.on_cancel = on_cancel
stats_builder = StatsBuilder()
self.player = create_player(stats_builder)
race_box = RaceBox(self.player)
class_box = ClassBox(self.player)
stats_box = StatsBox(self.player, stats_builder)
race_box = RaceBox()
class_box = ClassBox()
stats_box = StatsBox()
self.char_name_edit = urwid_readline.ReadlineEdit(
"Name: ", self.player.name
"Name: ", generate_name()
)
generate_char_name_btn = MenuButton(
"Generate random name", on_press=self.on_generate_char_name_press
)
urwid.connect_signal(
self.char_name_edit, "postchange", self.on_char_name_change
)
super().__init__(
[
(1, urwid.Filler(self.char_name_edit)),
@@ -154,9 +145,6 @@ class NewGameView(urwid.Pile):
self.char_name_edit.edit_text = generate_name()
self.char_name_edit.edit_pos = len(self.char_name_edit.edit_text)
def on_char_name_change(self, widget: urwid.Text, old_text: str) -> None:
self.player.name = widget.edit_text
def on_generate_char_name_press(self, _user_data: T.Any) -> None:
self.generate_random_char_name()