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 from dataclasses import dataclass
def level_up_time(level) -> int:
# seconds
return 20 * level * 60
class Traits(enum.Enum): class Traits(enum.Enum):
name = "Name" name = "Name"
race = "Race" race = "Race"
@@ -26,6 +21,20 @@ class Stat(enum.Enum):
mp_max = "MP Max" 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 = [ PRIME_STATS = [
Stat.strength, Stat.strength,
Stat.condition, Stat.condition,
@@ -38,20 +47,6 @@ PRIME_STATS = [
ALL_STATS = PRIME_STATS + [Stat.hp_max, Stat.mp_max] ALL_STATS = PRIME_STATS + [Stat.hp_max, Stat.mp_max]
EQUIPS = [
"Weapon",
"Shield",
"Helm",
"Hauberk",
"Brassairts",
"Vambraces",
"Gauntlets",
"Gambeson",
"Cuisses",
"Greaves",
"Sollerets",
]
SPELLS = [ SPELLS = [
"Slime Finger", "Slime Finger",
"Rabbit Punch", "Rabbit Punch",
+142 -17
View File
@@ -1,9 +1,15 @@
import datetime import datetime
import enum
import random import random
import typing as T 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: def generate_name() -> str:
@@ -20,7 +26,7 @@ def generate_name() -> str:
@dataclass @dataclass
class Stats: class Stats:
def __init__(self): def __init__(self) -> None:
self.values = {stat: 0 for stat in Stat} self.values = {stat: 0 for stat in Stat}
def __iter__(self) -> T.Iterable[T.Tuple[Stat, int]]: def __iter__(self) -> T.Iterable[T.Tuple[Stat, int]]:
@@ -34,24 +40,145 @@ class Stats:
@dataclass @dataclass
class Player: class Item:
name: str name: str
stats: Stats quantity: int
race: Race
class_: Class
birthday: datetime.datetime @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: class Roster:
def __init__(self) -> None: def __init__(self) -> None:
self.players: T.List[Player] = [] self.players: T.List[Player] = []
def add_player(self, player: Player) -> None:
self.players.append(player)
class StatsBuilder: class StatsBuilder:
def __init__(self): def __init__(self) -> None:
self.history: T.List[Stats] = [] self.history: T.List[Stats] = []
def roll(self): def roll(self) -> Stats:
stats = Stats() stats = Stats()
for stat in PRIME_STATS: for stat in PRIME_STATS:
stats[stat] = ( stats[stat] = (
@@ -67,18 +194,16 @@ class StatsBuilder:
self.history.append(stats) self.history.append(stats)
return stats return stats
def unroll(self): def unroll(self) -> Stats:
self.history.pop() self.history.pop()
return self.history[-1] 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() now = datetime.datetime.now()
random.seed(now) random.seed(now)
return Player( return Player(
birthday=now, birthday=now, name=name, race=race, class_=class_, stats=stats
name=generate_name(),
stats=stats_builder.roll(),
race=random.choice(RACES),
class_=random.choice(CLASSES),
) )
+18 -30
View File
@@ -5,15 +5,15 @@ import urwid
import urwid_readline import urwid_readline
from pqcli.config import CLASSES, PRIME_STATS, RACES 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.button import MenuButton
from pqcli.ui.line_box import LineBox from pqcli.ui.line_box import LineBox
class StatsBox(urwid.Filler): class StatsBox(urwid.Filler):
def __init__(self, player: Player, stats_builder: StatsBuilder) -> None: def __init__(self) -> None:
self.player = player self.stats_builder = StatsBuilder()
self.stats_builder = stats_builder self.stats = self.stats_builder.roll()
self.stat_labels = {stat: urwid.Text("0") for stat in PRIME_STATS} self.stat_labels = {stat: urwid.Text("0") for stat in PRIME_STATS}
self.total_label = urwid.Text("0") self.total_label = urwid.Text("0")
self.update_values() self.update_values()
@@ -59,48 +59,46 @@ class StatsBox(urwid.Filler):
) )
def on_roll_press(self, _user_data: T.Any) -> None: 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() self.update_values()
def on_unroll_press(self, _user_data: T.Any) -> None: def on_unroll_press(self, _user_data: T.Any) -> None:
try: try:
self.player.stats = self.stats_builder.unroll() self.stats = self.stats_builder.unroll()
except IndexError: except IndexError:
return return
self.update_values() self.update_values()
def update_values(self) -> None: def update_values(self) -> None:
for stat, edit in self.stat_labels.items(): 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( self.total_label.set_text(
str( str(sum(self.stats[stat] for stat in self.stat_labels.keys()))
sum(
self.player.stats[stat] for stat in self.stat_labels.keys()
)
)
) )
class RaceBox(LineBox): class RaceBox(LineBox):
def __init__(self, player: Player) -> None: def __init__(self) -> None:
race_checkboxes = [] race_checkboxes = []
self.race = random.choice(RACES)
for race in RACES: for race in RACES:
urwid.RadioButton( urwid.RadioButton(
group=race_checkboxes, group=race_checkboxes,
label=race.name, label=race.name,
state=race.name == player.race.name, state=race.name == self.race.name,
) )
super().__init__(urwid.ListBox(race_checkboxes), title="Race") super().__init__(urwid.ListBox(race_checkboxes), title="Race")
class ClassBox(LineBox): class ClassBox(LineBox):
def __init__(self, player: Player) -> None: def __init__(self) -> None:
class_checkboxes = [] class_checkboxes = []
self.class_ = random.choice(CLASSES)
for class_ in CLASSES: for class_ in CLASSES:
urwid.RadioButton( urwid.RadioButton(
group=class_checkboxes, group=class_checkboxes,
label=class_.name, label=class_.name,
state=class_.name == player.class_.name, state=class_.name == self.class_.name,
) )
super().__init__(urwid.ListBox(class_checkboxes), title="Class") super().__init__(urwid.ListBox(class_checkboxes), title="Class")
@@ -110,24 +108,17 @@ class NewGameView(urwid.Pile):
self.on_confirm = on_confirm self.on_confirm = on_confirm
self.on_cancel = on_cancel self.on_cancel = on_cancel
stats_builder = StatsBuilder() race_box = RaceBox()
self.player = create_player(stats_builder) class_box = ClassBox()
stats_box = StatsBox()
race_box = RaceBox(self.player)
class_box = ClassBox(self.player)
stats_box = StatsBox(self.player, stats_builder)
self.char_name_edit = urwid_readline.ReadlineEdit( self.char_name_edit = urwid_readline.ReadlineEdit(
"Name: ", self.player.name "Name: ", generate_name()
) )
generate_char_name_btn = MenuButton( generate_char_name_btn = MenuButton(
"Generate random name", on_press=self.on_generate_char_name_press "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__( super().__init__(
[ [
(1, urwid.Filler(self.char_name_edit)), (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_text = generate_name()
self.char_name_edit.edit_pos = len(self.char_name_edit.edit_text) 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: def on_generate_char_name_press(self, _user_data: T.Any) -> None:
self.generate_random_char_name() self.generate_random_char_name()