Exemple #1
0
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
    }
Exemple #2
0
    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
Exemple #3
0
    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
Exemple #4
0
    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)
Exemple #5
0
    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
Exemple #6
0
    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
Exemple #7
0
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)
Exemple #8
0
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)
Exemple #9
0
def test_if_dice_roll_return_integer():
    assert isinstance(dice_roll()[0], int)
Exemple #10
0
                '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.'
    )
Exemple #11
0
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
Exemple #12
0
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
Exemple #13
0
 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)
Exemple #14
0
                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",