forge/blade/systems/skill.py (73 lines of code) (raw):

import abc import numpy as np from forge.blade.systems import experience class Skills: def __init__(self): self.melee = Melee() self.ranged = Ranged() self.defense = Defense() self.constitution = Constitution() self.fishing = Fishing() self.mining = Mining() self.cooking = Cooking() self.smithing = Smithing() def addCombatExp(self, skill, dmg): skill.exp += int(3*dmg) self.constitution.exp += int(dmg) class Skill: skillItems = abc.ABCMeta expCalculator = experience.ExperienceCalculator() def __init__(self): self.exp = 0 @property def level(self): return self.expCalculator.levelAtExp(self.exp) class CombatSkill(Skill): @property def isMelee(self): return False @property def isRanged(self): return False class NonCombatSkill(Skill): def success(self, levelReq): level = self.level if level < levelReq: return False chance = 0.5 + 0.05*(level - levelReq) if chance >= 1.0: return True return np.random.rand() < chance def attempt(self, inv, item): if (item.createSkill != self.__class__ or self.level < item.createLevel): return if item.recipe is not None: #Check that everything is available if not inv.satisfies(item.recipe): return inv.removeRecipe(item.recipe) if item.alwaysSucceeds or self.success(item.createLevel): inv.add(item, item.amtMade) self.exp += item.exp return True class HarvestingSkill(NonCombatSkill): #Attempt each item from highest to lowest tier until success def harvest(self, inv): for e in self.skillItems: if self.attempt(inv, e): return class ProcessingSkill(NonCombatSkill): def process(self, inv, item): self.attempt(inv, item) class Fishing(HarvestingSkill): pass class Mining(HarvestingSkill): pass class Cooking(ProcessingSkill): pass class Smithing(ProcessingSkill): pass class Melee(CombatSkill): @property def isMelee(self): return True class Ranged(CombatSkill): @property def isRanged(self): return True class Defense(CombatSkill): pass class Constitution(CombatSkill): pass