def damage_bonus_table(strength, size): key = strength + size damage_bonus = 0 damage_bonus_string = None build = 0 if key >= 165: number_d6 = math.ceil(((key - 204) / 80) + 1) damage_bonus_string = f"+{number_d6}d6" damage_bonus = dice_roll(d6_pool(number_d6)) build = number_d6 + 1 elif key >= 125: damage_bonus_string = f"+1d4" damage_bonus = dice_roll(dice_pool(1, 4)) build = 1 elif key >= 85: pass else: damage_bonus = -1 if key >= 65 else -2 damage_bonus_string = str(damage_bonus) build = damage_bonus return { 'damage-bonus': damage_bonus, 'build': build, 'dice': damage_bonus_string }
def __call__(self, kwargs): if not self._noCache and not self._dirty: return self._result result = None self._dirty = False if self._sourceAsEnabler: for enabler in self._enablers: #print('enabler "{}" priority({}), value({})'.format(*enabler)) if enabler[2]: break # do upstreams merging return self._defaultResult else: for name, estimator in self._sources.items(): if isinstance(estimator, int): # support constant int or expression resultNew = estimator #elif isinstance(estimator, dict): # # support multi int/tuple # resultNew = Calculator._IntDict(estimator) elif isinstance(estimator, tuple): if len(estimator) == 2: resultNew = Calculator._IntDict() if isinstance(estimator[1], int): # support ('physical', 3) resultNew[estimator[0]] = estimator[1] elif isinstance(estimator[1], tuple): if not self._noCache: raise RuntimeError( 'dice tuple need noCache property on "%s"' % self._name) if len(estimator[1]) != 3: raise RuntimeError( 'dice tuple format error returned by "%s"' % name) # support ('physical', (1,6,2)) resultNew[estimator[0]] = dice_roll(*estimator[1]) elif len(estimator) == 3: # support lambda kwargs: ('physical', (1,6,2)) resultNew = dice_roll(*estimator) else: raise RuntimeError('invalid source tuple "%s"' % name) elif callable(estimator): resultNew = estimator(kwargs) else: continue result = _postproc_result(result, resultNew, self._methodMerge, self._methodSource) for upstream in self._upstreams: resultNew = upstream(kwargs) result = _postproc_result(result, resultNew, self._methodMerge, self._methodSource) #print(' {}: {} result: {}->{}'.format(self._name, upstream._name, resultNew, result)) self._result = self._defaultResult if result is None else result #print(' {} result: {}'.format(self._name, self._result)) return self._result
def generate_random(cls, name, skill_dict): # RULES: STR, CON, POW, DEX, APP are all 3d6 # RULES: INT and SIZ are 2d6 + 6 # RULES: EDU is 2d6+6 # RULES: under 7th edition rules I multiply them by 5 # RULES: under the laundry files age is 17 + 2d6, but we are hard coding 7e for now age = sample(range(15, 90), 1) character = cls( name=name, strength=Characteristic("Strength", "STR", dice_roll(d6_pool(3)) * 5), constitution=Characteristic("Constitution", "CON", dice_roll(d6_pool(3)) * 5), size=Characteristic("Size", "SIZ", dice_roll(d6_pool(2), 6) * 5), dexterity=Characteristic("Dexterity", "DEX", dice_roll(d6_pool(3)) * 5), appearance=Characteristic("Appearance", "APP", dice_roll(d6_pool(3)) * 5), intelligence=Characteristic("Intelligence", "INT", dice_roll(d6_pool(2), 6) * 5), power=Characteristic("Power", "POW", dice_roll(d6_pool(3)) * 5), education=Characteristic("Education", "EDU", dice_roll(d6_pool(2), 6) * 5), luck=Characteristic("Luck", "LUK", dice_roll(d6_pool(3)) * 5), age=age, skill_dict=skill_dict, ) # character.apply_age_penalty(age) return character
def apply(self, unit, hand): print('apply', hand, 'weapon:', self.name) apply_weapon_attacks(self, unit, hand) # weapon base damage weaponParams = self.proto.damageRoll unit.calc.addSource('Damage.' + hand, name=self.name, calcInt=lambda caster, target: ('Physical', self.name, dice_roll(1, weaponParams[1], weaponParams[0])), noCache=True) # weapon enhancement if hasattr(self, 'enhancement'): unit.calc.addSource('Weapon.%s.Additional' % hand, name='WeaponEnhancement', calcInt=('Magical', 'WeaponEnhancement', self.model.enhancement)) unit.calc.addSource('AttackBonus.' + hand, name='WeaponEnhancement', calcInt=self.enhancement) # weapon critical parameter criticalParams = self.proto.criticalThreat unit.calc.addSource('Weapon.%s.CriticalRange' % hand, name='WeaponBase', calcInt=criticalParams[0]) unit.calc.addSource('Weapon.%s.CriticalMultiplier' % hand, name='WeaponBase', calcInt=criticalParams[1]) # weapon related feats unit.feats.apply(weapon=self, hand=hand)
def meleeAttack(self, caster, target, attack): info = '{} attack:turnOffset({}) bab({}) {} weapon({}) {}'\ .format(caster.getName(), round(attack[0], 3), attack[1], attack[2], attack[3].name, target.getName()) roll = dice_roll(1, 20, 1) info += ', roll: ' + str(roll) if roll == 1: print(info, ', missing') return False abFinal = attack[1] # bab from attack abFinal += caster.getAttackBonus( target, attack[2]) # ab from caster's Buff, Feats, Str dcCaster = roll + abFinal dcTarget = int(target.getArmorClass(caster)) info += ', dc:{} against {}'.format(dcCaster, dcTarget) if roll < 20: if dcCaster < dcTarget: print(info, ', missing') return False print(info, ', hit', end=' ') damages = self.weapon_calc_damage(caster, target, roll, attack) target.applyDamages(damages) if target.isDead() and 'proto' in dir(target): xp = int(target.proto['xp']) # todo: XP penalty caster.addXP(xp) return True
def criticalCheck(self, caster, target, attack): roll = dice_roll(1, 20, 1) if roll == 1: return False dcCaster = roll + attack[1] + caster.getAttackBonus(target, attack[2]) dcTarget = target.getArmorClass(caster) if roll < 20: if dcCaster < dcTarget: return False return True
def get_melee_attack(accuracy, damage_info, defense, armor): roll = randint(1, 100) + accuracy - defense if roll > 25: return (True, max(dice_roll(*damage_info) - armor, 0)) else: return (False, 0)
def test_if_dice_roll_return_integer(): assert isinstance(dice_roll()[0], int)
'paralysis or turn to stone': 13, 'dragon breath': 16, 'rods, staves, or spells': 15 } if __name__ == "__main__": print(f'Generating skill rolls...') # Step 1 ability_names = [ 'strength', 'intelligence', 'wisdom', 'dexterity', 'constitution', 'charisma' ] # Step 2 abilities = dict( zip(ability_names, [dice_roll(dice_pool(3, 6)) for x in range(6)])) #TODO #21 Step 3: Select Character Class #TODO #22 Step 4: Select Special Abilities, like Magic-User and Elf spells #TODO #23 Step 5: Ability Score Adjustments #TODO #24 Step 6: Bonuses and Penalties # Step 7: XP #TODO #25 Step 8: HP # Step 9: Alignment # Step 10: GP gp = dice_roll(dice_pool(3, 6)) * 10 #TODO #26 Step 11: Inventory #TODO #27 Step 12: Armor Class #TODO #28 Step 13: THAC0, Saving throws print( f'Available classes: Cleric, Dwarf, Halfling, Elf, Fighter, Magic-User, Thief.' )
input() allowedactions = ['attack'] while player.attribute['hp'] > 0 and enemy.attribute['hp'] > 0: print( 'what shall you do? (Sorry, all you can do is attack right now. Spell casting and special abilities are coming)' ) for allowedaction in allowedactions: print(allowedaction, end=" | ") print() command = input('>>') if command.lower().strip() in allowedactions: attackroll = dice_roll( 1, 20) + player.modifier['strength'] + player.profbonus if attackroll >= enemy.attribute['ac']: print( f'Your long sword strikes the {enemy.creature} and cuts deep') damage = dice_roll(1, 8) + player.modifier['strength'] print(f'You do {damage} points of damage to the {enemy.creature}') enemy.attribute['hp'] = enemy.attribute['hp'] - damage else: print(f'Your attack has failed to hit the {enemy.creature}.') print(f'The {enemy.creature} comes with a visious attack') attackroll = dice_roll( 1, 20) + enemy.profbonus + enemy.modifier['strength'] if attackroll >= player.attribute['ac']: print(f'The {enemy.creature} has struck you') damage = dice_roll(1, 6) + enemy.modifier['strength'] player.attribute['hp'] = player.attribute['hp'] - damage
def run_games(number_of_throws=100, games=10000): number_of_games = games # number of simulated games to play game_results = {} print(f'Begin {number_of_games} games') for game in range(number_of_games): throws_counter = 0 number_of_throws = number_of_throws # maximum number of throws in game simulation # list of chance cards and actions chance_cards = [ 'Drunk', 0, 39, 24, 13, 'bank_pays', 'gooj', 'back_3', 10, 'house_repairs', 'fees', 'fine', 5, 'street_repairs', 'crossword', 'loan' ] chance_card_positions = [7, 22, 36] # list of community chest cards and actions community_cards = [ 0, 19, 10, 'hospital', 'doctors', 'insurance', 'ban_error', 'annuity', 'inherit', 'stock', 'interest', 'refund', 'prize', 'birthday', 'gooj', 'pay' ] community_chest_locations = [2, 33] # track number of consecutive doubles thrown and 'get out of jail free' cards acquired doubles = [False, False, False] non_doubles_in_jail = 0 gooj_cards = 0 player_position = 0 # start at Go (denoted by 0) in_jail = False # tracks if player is in jail or visiting jail, defaults visiting # track every space landed on during a game position_landings = [] while throws_counter <= number_of_throws: roll = dice_roll() # if roll is a third consecutive double, move to jail if roll[1]: if doubles == [False, False, False]: doubles[0] = True elif doubles == [True, False, False]: doubles[1] = True elif doubles == [True, True, False]: doubles[2] = True player_position = 10 in_jail = True doubles = [False, False, False] position_landings.append(player_position) throws_counter += 1 continue else: doubles = [False, False, False] # if find on jail square have a seperate set of rules if in_jail: if gooj_cards > 0: gooj_cards -= 1 in_jail = False throws_counter += 1 continue if roll[1]: #player_position = move_player(roll, player_position) non_doubles_in_jail = 0 in_jail = False throws_counter += 1 continue else: non_doubles_in_jail += 1 throws_counter += 1 if non_doubles_in_jail >= 3: in_jail = False continue else: continue # currently if roll double and get out of jail, the counter still removes a card # also only want to roll three times before getting out of jail automatically else: player_position = move_player(roll, player_position) if player_position in chance_card_positions: #print('TAKE A CHANCE CARD') if len(chance_cards) == 0: chance_cards = [ 'Drunk', 0, 39, 24, 13, 'bank_pays', 'gooj', 'back_3', 'jail', 'house_repairs', 'fees', 'fine', 5, 'street_repairs', 'crossword', 'loan' ] chance_card = select_chance_card(chance_cards) if isinstance(chance_card, int): player_position = chance_card elif chance_card == 'back_3': player_position = player_position - 3 elif chance_card == 'gooj': gooj_cards += 1 elif chance_card == 'jail': player_position = 10 in_jail = True elif player_position in community_chest_locations: #print('TAKE A COMMUNITY CHEST CARD') if len(community_cards) == 0: community_cards = [ 0, 1, 'jail', 'hospital', 'doctors', 'insurance', 'ban_error', 'annuity', 'inherit', 'stock', 'interest', 'refund', 'prize', 'birthday', 'gooj', 'pay' ] community_card = select_community_chest_card(community_cards) if isinstance(community_card, int): player_position = community_card elif community_card == 'gooj': gooj_cards += 1 elif community_card == 'jail': player_position = 10 in_jail = True #print(f'Total number of goes: {throws_counter}') #print(player_position) position_landings.append(player_position) throws_counter += 1 res = collections.Counter(position_landings) #print(res) game_results[game] = res results_df = pd.DataFrame() for game_number, game_results in game_results.items(): results_df = results_df.append(game_results, ignore_index=True) return results_df
def apply_age_penalty(self, strength=None, constitution=None, size=None, dexterity=None, appearance=None, intelligence=None, power=None, education=None): if strength == None: strength = self.strength if constitution == None: constitution = self.constitution if size == None: size = self.size if dexterity == None: dexterity = self.dexterity if appearance == None: appearance = self.appearance if intelligence == None: intelligence = self.intelligence if power == None: power = self.power if education == None: education = self.education if self.age >= 80: for _ in range(4): education.skill_improvement(check=True) self.strength = strength self.constitution = constitution self.dexterity = dexterity self.appearance.score -= 25 self.movement_rate.score -= 5 elif self.age >= 70: for _ in range(4): education.skill_improvement(check=True) self.strength = strength self.constitution = constitution self.dexterity = dexterity self.appearance.score -= 20 self.movement_rate.score -= 4 elif self.age >= 60: for _ in range(4): education.skill_improvement(check=True) self.strength = strength self.constitution = constitution self.dexterity = dexterity self.appearance.score -= 15 self.movement_rate.score -= 3 elif self.age >= 50: for _ in range(3): education.skill_improvement(check=True) self.strength = strength self.constitution = constitution self.dexterity = dexterity self.appearance.score -= 10 self.movement_rate.score -= 2 elif self.age >= 40: for _ in range(2): education.skill_improvement(check=True) self.strength = strength self.constitution = constitution self.dexterity = dexterity self.appearance.score -= 5 self.movement_rate.score -= 1 elif self.age >= 20: education.skill_improvement(check=True) elif self.age >= 15: self.size = size self.strength = strength self.education.score -= 5 luck_roll = [d6_pool(3), d6_pool(3)] self.luck = max(dice_roll(x) for x in luck_roll) * 5 self.damage_bonus_table = damage_bonus_table(strength, size)
if skill_dict[key].important is True ] def skill_roll(self, skill_name): skill = self.skill_dict[skill_name] return skill.roll() if __name__ == "__main__": print("Welcome to the Call of Cthulhu character generator.") name = input("Please provide a name for your character: ") skill_dict = Investigator.read_skill_dict() # Now we will start creating a character. stat_block = { "STR": Characteristic("Strength", "STR", dice_roll(d6_pool(3)) * 5), "CON": Characteristic("Constitution", "CON", dice_roll(d6_pool(3)) * 5), "SIZ": Characteristic("Size", "SIZ", dice_roll(d6_pool(2), 6) * 5), "DEX": Characteristic("Dexterity", "DEX", dice_roll(d6_pool(3)) * 5), "APP": Characteristic("Appearance", "APP", dice_roll(d6_pool(3)) * 5), "INT": Characteristic("Intelligence", "INT", dice_roll(d6_pool(2), 6) * 5), "POW": Characteristic("Power", "POW", dice_roll(d6_pool(3)) * 5), "EDU": Characteristic("Education", "EDU", dice_roll(d6_pool(2), 6) * 5), "LUK": Characteristic("Luck", "LUK",