mirror of
https://github.com/evennia/evennia.git
synced 2026-03-27 10:16:32 +01:00
Start adding chargen
This commit is contained in:
parent
4ba752ebd6
commit
1ab007a976
1 changed files with 193 additions and 0 deletions
193
evennia/contrib/rules/openadventure/chargen.py
Normal file
193
evennia/contrib/rules/openadventure/chargen.py
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
"""
|
||||
This is a convenient module for use by chargen implementations. It gives access
|
||||
to ready-made calculations (using the various rule systems) to get options and
|
||||
evaluate results during the character generation process.
|
||||
|
||||
"""
|
||||
from dataclasses import dataclass
|
||||
from evennia.utils.utils import callables_from_module, inherits_from
|
||||
|
||||
|
||||
@dataclass
|
||||
class ChargenChoice:
|
||||
"""
|
||||
This temporarily stores the choices done during chargen. It could be
|
||||
saved to an Attribute if persistence is required.
|
||||
|
||||
"""
|
||||
rulename = ""
|
||||
data = {}
|
||||
|
||||
|
||||
class ChargenStep:
|
||||
"""
|
||||
This represents the steps of a character generation. It assumes this is a
|
||||
sequential process (if chargen allows jumping that's fine too, one could
|
||||
just have a menu that points to each step).
|
||||
|
||||
"""
|
||||
step_name = ""
|
||||
prev_step = None
|
||||
next_step = None
|
||||
|
||||
def get_help(self, *args, **kwargs):
|
||||
"""
|
||||
This returns help text for this choice.
|
||||
|
||||
"""
|
||||
return self.__doc__.strip()
|
||||
|
||||
def options(self, *args, **kwargs):
|
||||
"""
|
||||
This presents the choices allowed by this step.
|
||||
|
||||
Returns:
|
||||
list: A list of all applicable choices, usually as rule-classes.
|
||||
|
||||
"""
|
||||
|
||||
def validate_input(self, inp, *args, **kwargs):
|
||||
"""
|
||||
This can be used to validate free-form inputs from the user.
|
||||
|
||||
Args:
|
||||
inp (str): Input from the user.
|
||||
Returns:
|
||||
bool: If input was valid or not.
|
||||
|
||||
"""
|
||||
|
||||
def user_choice(self, *args, **kwargs):
|
||||
"""
|
||||
This should be called with the user's choice. This must already be
|
||||
determined to be a valid choice at this point.
|
||||
|
||||
Args:
|
||||
*args, **kwargs: Input on any form.
|
||||
|
||||
Returns:
|
||||
CharacterStore: Storing the current, valid choice.
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class ArchetypeChoice(ChargenStep):
|
||||
"""
|
||||
Choose one archetype and record all of its characteristics–or–choose two
|
||||
archetypes, halve all the characteristic's numbers, then combine their
|
||||
values.
|
||||
|
||||
"""
|
||||
step_name = "Choose an Archetype"
|
||||
prev_step = None
|
||||
next_step = "Choose a Race"
|
||||
|
||||
def get_help(self, *args, **kwargs):
|
||||
return self.__doc__.strip()
|
||||
|
||||
def options(self, *args, **kwargs):
|
||||
"""
|
||||
Returns a list of Archetypes. Each Archetype class has a `.modifiers`
|
||||
dict on it with values keyed to enums for the bonuses/drawbacks of that
|
||||
archetype. The archetype's name is the class name, retrieved with `.__name__`.
|
||||
|
||||
"""
|
||||
from . import archetypes
|
||||
return callables_from_module(archetypes)
|
||||
|
||||
def user_choice(self, choice1, choice2=None, **kwargs):
|
||||
"""
|
||||
We allow one or two choices - they must be passed into this method
|
||||
together.
|
||||
|
||||
Args:
|
||||
choice1 (Archetype): The first archetype choice.
|
||||
choice2 (Archetype, optional): Second choice (for dual archetype choice)
|
||||
|
||||
Returns:
|
||||
ChargenStore: Holds rule_name and data; data has an additional 'name' field
|
||||
to identify the archetype (which may be a merger of two names).
|
||||
|
||||
"""
|
||||
data1 = choice1.modifiers
|
||||
if choice2:
|
||||
# dual-archetype - add with choice1 values and half, rounding down
|
||||
data2 = choice2.modifiers
|
||||
data = {}
|
||||
for key, value1 in data1.items():
|
||||
value2 = data2.get(key, 0)
|
||||
data[key] = int((value1 + value2) / 2)
|
||||
# add values from choice2 that was not yet covered
|
||||
data.update({key: int(value2 / 2) for key, value in data2.items() if key not in data})
|
||||
# create a new name for the dual-archetype by combining the names alphabetically
|
||||
data['name'] = "-".join(sorted((choice1.__name__, choice2.__name__)))
|
||||
else:
|
||||
data = data1
|
||||
data['name'] = choice1.__name__
|
||||
|
||||
return ChargenChoice(rulename="archetype", data=data)
|
||||
|
||||
|
||||
class RaceChoice(ChargenStep):
|
||||
"""
|
||||
Choose a race/creature type that best suits this character.
|
||||
|
||||
"""
|
||||
step_name = "Choose a Race"
|
||||
prev_step = "Choose an Archetype"
|
||||
next_step = "Choose a race Focus"
|
||||
|
||||
|
||||
def options(self, *args, **kwargs):
|
||||
"""
|
||||
Returns a list of races. Each Race class has the following properties:
|
||||
::
|
||||
size = enum for small, average, large
|
||||
bodytype = enum for slim, average, stocky
|
||||
modifiers = dict of enums and bonuses/drawbacks
|
||||
foci = list of which Focus may be chosen for this race
|
||||
feats = list of which Feats may be chosen for this race
|
||||
|
||||
"""
|
||||
from . import races
|
||||
all_ = callables_from_module(races)
|
||||
return [race for race in all_ if inherits_from(race, race.Race)]
|
||||
|
||||
def user_choice(self, choice, *args, **kwargs):
|
||||
"""
|
||||
The choice should be a distinct race.
|
||||
|
||||
Args:
|
||||
choice (Race): The chosen race.
|
||||
|
||||
Returns:
|
||||
ChargenChoice: This will have the Race class as .data.
|
||||
|
||||
"""
|
||||
return ChargenChoice(rulename="race", data=choice)
|
||||
|
||||
|
||||
class FocusChoice(ChargenStep):
|
||||
"""
|
||||
Each race has three 'subtypes' or Foci available to them. This represents
|
||||
natural strengths of that race that come across more or less in different
|
||||
individuals. Each Character may pick one race-Focus to emphasize.
|
||||
|
||||
"""
|
||||
def options(self, race, *args, **kwargs):
|
||||
"""
|
||||
To know which focus to offer, the chosen Race must be passed.
|
||||
|
||||
Args:
|
||||
race (Race): The race chosen on the previous step.
|
||||
|
||||
"""
|
||||
return list(race.foci)
|
||||
|
||||
def user_choice(self, choice, *args, **kwargs):
|
||||
"""
|
||||
|
||||
"""
|
||||
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue