from ..dice import MULT, ADD from .. import dice from .constants import * import collections def health_mod(func): def _inner(self): mod = 0 if self.attr.state >= WOUNDED: mod = -3 result = func(self) result += mod return result return _inner class Skills(object): def __init__(self, attr): self.skills = { 'agility','craft','fighting','knowledge', 'perception','persuasion','shooting','speed', 'stealth','toughness' } self.attr = attr self.training = Trainer(self) self.train = self.training.select def check(self, skill, dieroll=None): die = dice.DieJar().d20 if dieroll is None: dieroll = die else: dieroll.dice = dice.DieJar().d20 roll = dieroll.roll() if roll == 1: result = False if roll == 20: result = True else: result = roll < getattr(self, skill) return result, roll-result # (passes, difference) @property @health_mod def agility(self): return (self.attr.dex * 2) + self.training.agility @property @health_mod def craft(self): return self.attr.dex + self.attr.int + self.training.craft @property @health_mod def fighting(self): return self.attr.str + self.attr.int + self.training.fighting @property @health_mod def knowledge(self): return self.attr.int * 2 + self.training.knowledge @property @health_mod def perception(self): return self.attr.int + attr.spt + self.training.perception @property @health_mod def persuasion(self): return self.attr.spt * 2 + self.training.persuasion @property @health_mod def shooting(self): return self.attr.dex + self.attr.int + self.training.shooting @property @health_mod def speed(self): return self.attr.str + self.attr.dex + self.training.speed @property @health_mod def stealth(self): return self.attr.dex + self.attr.spt + self.training.stealth @property @health_mod def toughness(self): return self.attr.str + self.attr.spt + self.training.toughness class Trainer(object): mods = dict( untrained=-1, familiar=0, trained=1, experienced=2, mastered=3 ) def __init__(self, skills): self.skills = skills self.training = collections.defaultdict(lambda: -1) self.points = 500 self.training_cost = 100 def select(self, skill, degree): if hasattr(degree, 'upper'): degree = self.mods.get(degree, 0) if self.points >= self.training_cost and degree in self.mods.values(): self.training[skill] = degree self.points -= self.training_cost def __getattr__(self, key): skills = object.__getattribute__(self, 'skills') if key in self.skills.skills: return self.training[key] else: raise def __setattr__(self, key, value): if hasattr(self, 'skills') and key in self.skills.skills: if -1 <= value <= 3: self.training[key] = int(round(value)) else: raise AttributeError( 'cannot set training of %s to %d, (out of range [-1,3])' % (key, value) ) else: object.__setattr__(self, key, value)