Exemplo n.º 1
0
    def roll_check(self, check_name, advantage=False, disadvantage=False):
        is_stat = check_name in STAT_NAMES
        is_skill = check_name in [skill.name for skill in self.skills]
        modifier = 0
        stat = None
        if not is_stat and not is_skill:
            return LookupError("%s is not a valid skill or stat")
        elif is_stat:
            modifier += self.stat.modifier(check_name)
            stat = check_name
        elif is_skill:
            skill = list(
                filter(lambda skill: skill['name'] == check_name,
                       self.skills))[0]
            modifier += self.stat.modifier(skill.stat)
            stat = skill.stat
            if skill.trained and self.proficiency:
                modifier += self.proficiency

        modifier += get_bonuses(stat)

        if advantage or disadvantage:
            rolls = [roll("1d20") + modifier, roll("1d20") + modifier]
            if advantage:
                return max(rolls)
            else:
                return min(rolls)
        return roll("1d20") + modifier
Exemplo n.º 2
0
def validate(val_loader, model, cri, epoch, output_writers, device):
    val_loss = AverageMeter()

    # switch to evaluate mode
    model.eval()

    allrmse = []
    allpsnr = []
    allssim = []
    i = 0
    with torch.no_grad():
        for kdata, mask, image, fully in val_loader:
            kdata = kdata.float().to(device)
            mask = mask.float().to(device)
            image = image.float().to(device)

            _, _, w, h = kdata.size()

            # ifftshift
            kdata = roll(kdata, int(w / 2), 2)
            kdata = roll(kdata, int(h / 2), 3)
            mask = roll(mask, int(w / 2), 2)
            mask = roll(mask, int(h / 2), 3)

            # model forward
            reconsimage = model(kdata, mask)

            # calculate loss
            loss = cri(reconsimage[-1], image)

            # calculate score
            rmse = get_rmse(reconsimage[-1], image)
            psnr = get_psnr(reconsimage[-1], image)
            ssim = get_ssim(reconsimage[-1], image)
            allrmse.append(rmse.item())
            allpsnr.append(psnr)
            allssim.append(ssim.item())

            # record validation loss
            val_loss.update(loss.item(), kdata.size(0))

            # display results in tensorboard
            if 1 < i < 4:
                image = vutils.make_grid(image,
                                         normalize=True,
                                         scale_each=True)
                output_writers[i].add_image('gt image', image, 0)
                rec1 = vutils.make_grid(reconsimage[-1],
                                        normalize=True,
                                        scale_each=True)
                output_writers[i].add_image('reconstruction image 1 ', rec1,
                                            epoch)
            i = i + 1

        # print out average scores
        print(' * Average Validation Loss {:.3f}'.format(val_loss.avg))
        print(' * Average RMSE {:.4f}'.format(np.mean(np.asarray(allrmse))))
        print(' * Average PSNR {:.4f}'.format(np.mean(np.asarray(allpsnr))))
        print(' * Average SSIM {:.4f}'.format(np.mean(np.asarray(allssim))))
        return val_loss.avg
Exemplo n.º 3
0
def potion_drop(hero, room):
    level = LEVEL
    if room == ("battleroom"):
        potion_types = ['small', 'medium']
        chance = (level - 1) * 10
        if roll() <= chance:
            potion = random.choice(potion_types)
            if potion == 'small':
                hero.pots['small'] +=1
                print('You pick up a small health potion')
                return 1
            elif potion == 'medium':
                hero.pots['medium'] += 1
                print('You pick up a medium health potion')
                return 1
        else:
            return 0
    if room == ("traproom"):
        potion_types = ['medium', 'large']
        chance = (level - 1) * 10
        if roll() <= chance:
            potion = random.choice(potion_types)
            if potion == 'medium':
                hero.pots['medium'] +=1
                print('You pick up a medium health potion')
                return 1
            elif potion == 'large':
                hero.pots['large'] += 1
                print('You pick up a large health potion')
                return 1
        else:
            return 0
Exemplo n.º 4
0
def goldLoot(level):
    '''A simple loot generator: creates random gold loot for a level.
    '''
    _trace = TRACE + 'goldLoot('+str(level)+') '
    logging.info(_trace)
    treasure = TREASURE[level-1]
    logging.info(_trace+'treasure = '+str(treasure))
    # Coins
    coins_roll = roll(100, 1)
    logging.info('VALUE:: coins_roll = '+str(coins_roll))
    coins = treasure['coins']
    gp = 0
    for x in coins:
        range_ = x['range']
        if coins_roll <= range_ and not coins_roll > range_:
            dice = x['dice']
            die = x['die']
            if dice > 0:
                coin = x['coin']
                base = x['base']
                multiplier = roll(die, dice) 
                amount = multiplier*base
                # Convert to gold
                if coin == 'cp':
                    gp += amount/100
                elif coin == 'sp':
                    gp += amount/10
                elif coin == 'gp':
                    gp += amount
                elif coin == 'pp':
                    gp += amount*10
                logging.info('gp = '+str(gp))    
                return gp                   
Exemplo n.º 5
0
def train(train_loader, model, cri, optimizer, epoch, train_writer, device):
    global n_iter
    batch_time = AverageMeter()
    losses = AverageMeter()

    epoch_size = len(train_loader)

    # switch to train mode
    model.train()

    i = 0
    for kdata, mask, image, fully in train_loader:
        kdata = kdata.float().to(device)
        image = image.float().to(device)
        fully = fully.float().to(device)

        _, _, w, h = kdata.size()

        # generate undersampling mask on the fly
        idx = gaussiansample(h, int(h / 4), np.int(np.floor(h * 0.125)))
        randmask = torch.zeros((kdata.size(0), 1, w, h)).float().to(device)
        randmask[:, :, :, idx] = 1

        # ifftshift
        randmask = roll(randmask, int(w / 2), 2)
        randmask = roll(randmask, int(h / 2), 3)

        # generate undersampled k-space data
        randkdata = fully * randmask

        # model forward
        reconsimage = model(randkdata, randmask)

        # calculate loss
        loss = cri(reconsimage[-1], image)

        # record loss
        losses.update(loss.item(), kdata.size(0))
        train_writer.add_scalar('train_loss', loss.item(), n_iter)

        # compute gradient and do optimization step
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        n_iter += 1

        if i % 3 == 0:
            print('Epoch: [{:02d}][{:04d}]\t Loss {:.5f}'.format(
                epoch, i, losses.avg))

        if i >= epoch_size:
            break

        i = i + 1

    return losses.avg
Exemplo n.º 6
0
 def apply(self, state):
     if self.character(state).is_small:
         damage = utils.roll(1, 6, advantage=2)
     elif self.character(state).is_large:
         damage = utils.explode_roll(1, 20, disadvantage=1)
     elif self.character(state).is_medium:
         damage = utils.roll(1, 6)
     else:
         damage = 0
     return self.damage(state, damage)
Exemplo n.º 7
0
    def rollAttack(self,
                   method: Union[Weapon, Spell],
                   target: 'Character',
                   advantage=0,
                   misc_mod: str = None) -> None:
        types = {
            'melee': self.abilities['str'].mod + self.pro_bonus,
            'ranged': self.abilities['dex'] + self.pro_bonus
        }
        if isinstance(method, Spell):
            try:
                assert method.attack
            except AssertionError:
                print("Spell doesn't have attack attribute.")
            rolled = roll('1d20') + self.abilities[
                self.spellcasting_ability].mod + self.pro_bonus
            if advantage != 0:

                def _roll():
                    return roll('1d20') + self.abilities[
                        self.spellcasting_ability].mod + self.pro_bonus

                rolls = [_roll(), _roll()]
                rolled = (max(rolls) if advantage > 0 else min(rolls))
            if rolled >= target.ac:
                print("Attack succeeded!")
                target.takeDamage(method.damage, method.damage_type)
                if self.misc_damages:
                    for damage in self.misc_damages:
                        target.takeDamage(damage['roll'], damage['type'],
                                          damage['multiplier'])
            else:
                print("Attack failed.")
        elif isinstance(method, Weapon):
            if not misc_mod:
                misc_mod = types[method.reach]
            rolled = roll('1d20') + misc_mod
            if advantage != 0:

                def _roll():
                    return roll('1d20') + misc_mod

                rolls = [_roll(), _roll()]
                rolled = (max(rolls) if advantage > 0 else min(rolls))
            if rolled >= target.ac:
                if self.misc_damages:
                    for damage in self.misc_damages:
                        target.takeDamage(damage['roll'], damage['type'],
                                          damage['multiplier'])
                for damage in method.damages:
                    target.takeDamage(damage['roll'], damage['type'],
                                      damage['multiplier'])
                print("Attack succeeded!")
            else:
                print("Attack failed.")
Exemplo n.º 8
0
def coin_drop(enemy, hero): 
    level = LEVEL
    if roll() <= int(enemy.lootchance_coins):
        coin_drops_level = COIN_LIST.loc[COIN_LIST['Level'] == level] #gets all dropabble coins for the current level
        coin_roll = roll() - hero.greed #rolls to see which drops you can get, factors greed
        coin_drops = coin_drops_level.loc[coin_drops_level['Rarity'] >= coin_roll] #makes a df of all dropabble items
        if coin_drops.empty:
            return 0
        coin_drops = coin_drops.sample() #takes a random drop from above dataframe
        return int(coin_drops['Amount']) #adds coins to hero's inventory
    return 0
    def divergence1d(self, p0, ppred):

        hder = 2*conf.hder

        dp = ppred-p0

        div = (utils.roll(dp, axis=0, shift=-1)-utils.roll(dp, axis=0, shift=1))/hder

        # reset dictionaries
        self.reset_dict()

        return p0, ppred, dp, div
Exemplo n.º 10
0
def wealth_drop(enemy, hero):
    level = LEVEL
    if roll() <= int(enemy.lootchance_wealth):
        wealth_level = WEALTH_LIST.loc[WEALTH_LIST['Level'] == level] #gets all dropabble wealth for the current level
        wealth_roll = roll() - hero.greed #rolls to see which drops you can get, factors greed
        wealth_drops = wealth_level.loc[wealth_level['Rarity'] >= wealth_roll] #makes a df of all dropabble wealth
        if wealth_drops.empty:
            return 0
        wealth_drop = wealth_drops.sample()
        print(wealth_drop.iloc[0]["Name"])
        return (wealth_drop.iloc[0]["Name"])
    return 0
Exemplo n.º 11
0
def weapon_drop(enemy, hero):
    level = LEVEL
    if roll() <= int(enemy.lootchance_gear):
        weapon_drops_level = WEAPON_LIST.loc[WEAPON_LIST['Level'] == level]
        weapon_roll = roll() - hero.greed #rolls to see which drops you can get, factors greed
        weapon_drops = weapon_drops_level.loc[weapon_drops_level['Rarity'] >= weapon_roll] #makes a df of all dropabble items
        if weapon_drops.empty:
            return 0
        weapon_drops = weapon_drops.sample() #takes a random drop from above dataframe
        print(weapon_drops.iloc[0]["Name"], weapon_drops.iloc[0]["Category"])
        hero.pick_up(weapon_drops.iloc[0]["Name"], weapon_drops.iloc[0]["Category"])
        return (weapon_drops.iloc[0]["Name"])

    return 0
Exemplo n.º 12
0
def spawnLocation(location, meters=60):
    """Creates a new location within random meters of provided location.
    Returns: a new location.
    """   
    _trace=TRACE+"spawnLocation() "
    logging.info(_trace)
    lat, lon = utils.parseGeoPt(location)
    logging.info(_trace+'lat = '+lat)
    logging.info(_trace+'lon = '+lon)
    
    # Randomly determine distance of new lat/lon
    ran_lat_meters = utils.roll(meters, 1)
    ran_lon_meters = utils.roll(meters, 1)
    logging.info(_trace+'ran_lat_meters = '+str(ran_lat_meters))
    logging.info(_trace+'ran_lon_meters = '+str(ran_lon_meters))
        
    lat_meters = ran_lat_meters*.00001
    lon_meters = ran_lon_meters*.00001
    logging.info(_trace+'lat_meters = '+str(lat_meters))
    logging.info(_trace+'lon_meters = '+str(lon_meters))

    # Randomly determine direction of new lat/lon
    pos_lat_vector = random.choice([True, False])
    pos_lon_vector = random.choice([True, False])
    logging.info(_trace+'pos_lat_vector = '+str(pos_lat_vector))
    logging.info(_trace+'pos_lon_vector = '+str(pos_lon_vector))
        
    lat = utils.strToIntOrFloat(lat)
    lon = utils.strToIntOrFloat(lon)
    new_lat = lat
    new_lon = lon
    if pos_lat_vector == False:
        new_lat = lat - lat_meters  
        logging.info(_trace+'False new_lat = '+str(new_lat))
    
    else:
        new_lat = lat + lat_meters              
        logging.info(_trace+'True new_lat = '+str(new_lat))
        
    if pos_lon_vector == False:
        new_lon = lon - lon_meters
        logging.info(_trace+'False new_lon = '+str(new_lon))    
    
    else:
        new_lon = lon + lon_meters
        logging.info(_trace+'True new_lon = '+str(new_lon))
                        
    new_location = db.GeoPt(str(new_lat), str(new_lon))
    return new_location
    def divergence2d(self, p0, ppred):

        hder = 2*conf.hder

        p0 = p0.view(conf.num_U, conf.num_nf, 2)
        ppred = ppred.view(conf.num_U, conf.num_nf, 2)

        dp = ppred-p0
        div = (utils.roll(dp[:, :, 0], axis=0, shift=-1)-utils.roll(dp[:, :, 0], axis=0, shift=1))/hder[0] + (
            utils.roll(dp[:, :, 1], axis=1,  shift=-1)-utils.roll(dp[:, :, 1], axis=1, shift=1))/hder[1]

        # reset dictionaries
        self.reset_dict()

        return p0, ppred, dp, div
Exemplo n.º 14
0
def odds(args):
    # The input
    welcome = '- You attempt to make a check of {}'.format(args.check)
    welcome += ' by rolling a d{}'.format(', d'.join([str(die) for
                                                       die in args.dice[:-1]]))
    if len(args.dice) > 1: welcome += ' and a d'
    welcome += '{}.'.format(args.dice[-1])
    if args.bonus:
        welcome += '\n- Your bonus on the check is {}.'.format(args.bonus)
    print(welcome)
    hits, total, percent = make_check(args.check, args.dice,
                                      args.bonus, args.strictly_greater)

    # The odds
    if not args.roll:
        if percent % 1 == 0:
            print("- The odds of winning are {} in {}, i.e. {} %.".
                  format(*map(int, (hits, total, percent))))
        else:
            print("- The odds of winning are {} in {}, i.e. roughly {:.0f} %.".
                  format(*map(int, (hits, total, percent))))
    else: # Roll the dice
        result = roll(args.dice) + args.bonus
        if result >= args.check + args.strictly_greater:
            print("- Rolling dice ... the result is {} ({} was required), "
                  "you win!" .format(result,
                                     args.check + args.strictly_greater))
        else:
            print("- Rolling dice ... the result is {} ({} was required), "
                  "you lose!" .format(result,
                                      args.check + args.strictly_greater))
Exemplo n.º 15
0
 def save(self, ability_check, dc):
     rolled = roll('1d20') + self.abilities[ability_check].save
     saved = (rolled >= dc)
     if saved:
         print("Save succeeded!")
     else:
         print("Save failed.")
     return saved
Exemplo n.º 16
0
def get_correlation(s1, s2):
    start_date = '2016-03-01'
    end_date = min(s1.index[-1], s2.index[-1])
    s1 = s1[(s1.index >= start_date) & (s1.index <= end_date)]
    s2 = s2[(s2.index >= start_date) & (s2.index <= end_date)]
    df = pd.DataFrame({'s1': s1, 's2': s2}, index=s1.index)
    rolled_df = utils.roll(df, 60)
    corr = rolled_df.apply(lambda df: df['s1'].corr(df['s2']))
    return corr
Exemplo n.º 17
0
 def __computeHP(self) -> int:
     hp = 0
     higher_class_dc = '1d0'
     for key in self.classes.keys():
         if int(self.classes[key].hit_dice.split('d')[1]) > int(
                 higher_class_dc.split('d')[1]):
             higher_class_dc = self.classes[key].hit_dice
     for _ in range(self.level):
         hp += roll(higher_class_dc)
     return hp
Exemplo n.º 18
0
 def create_generic(self, weather_filepath, interval=10):
     self.interval = interval
     if self.raw_data is None:
         print("Error: no raw data. Use set_raw_data to set raw data.")
     else:
         formatted_data = util.merge_day_month(self.raw_data)
         rolling_data = util.roll(formatted_data, self.interval)
         merged_rolling = util.merge_rolling(formatted_data, rolling_data)
         merged_weather = util.merge_weather(merged_rolling, weather_filepath)
         self.weather_generic = merged_weather
Exemplo n.º 19
0
def get_dataframe():
    pnl = get_panel()
    pnl.ix[:, :, 'return'] = pnl.minor_xs('close').pct_change()
    df = pnl.minor_xs('return')

    rolled_df = utils.roll(df, 60)
    ratio = rolled_df.apply(lambda x: principal_ratio(x, 3))

    res = pd.DataFrame({'con60': ratio})
    res.index.name = 'date'

    return res
Exemplo n.º 20
0
 def takeDamage(self, droll: str, dtype: str, multiplier: int = 1) -> None:
     if (dtype in self.race.resistances or dtype in self.misc_resistances):
         multiplier *= 0.5
     if (dtype in self.vulnerabilities):
         multiplier *= 2
     ### future condition-based code ###
     damage = round(roll(droll) * multiplier)
     self.current_hp -= damage
     print(f"Took {damage} {dtype} damage!")
     if self.current_hp < 0:
         self.current_hp = 0
         print("HP is now 0, death rolls are now active.")
Exemplo n.º 21
0
def flee(hero, enemy):
    t6 = "Trying to escape the room..."
    print_slow(t6, 0.02)
    flee_roll = 50 + hero.agility
    if roll() < flee_roll:
        print("You successfully escape from the " + enemy.name)
        junction()
    else:
        print("You can't find a way out!")
        enemy_hit = roll()
        if enemy_hit < (
            enemy.hit_chance - hero.defense
        ):  # factors if the hit is successful based on hit chance and hero defense
            crit_enemy = enemy.crit_check(
                enemy
            )  # should have been a common function in parent class
            enemy_damage = int(
                random.randint(
                    int(0.8 * enemy.damage),
                    int((enemy.damage) * crit_enemy),
                )
            )
            print(
                "The "
                + enemy.name
                + " attack you for "
                + str(enemy_damage)
                + " damage"
            )
            hero.hp -= enemy_damage
            hero.print_status()
            battle_choices(hero, enemy)
            if hero.hp <= 0:
                hero.death()
        else:
            print("You dodge an incoming attack" + "\n")
            battle_choices(hero, enemy)
Exemplo n.º 22
0
def potion_drop(room):
    level = LEVEL
    if room == ("battleroom"):
        potion_types = ["small", "medium"]
        chance = (level - 1) * 10
        if roll() <= chance:
            potion = random.choice(potion_types)
            if potion == "small":
                hero.pots["small"] += 1
                return 1
            elif potion == "medium":
                hero.pots["medium"] += 1
                return 1
        else:
            return 0
Exemplo n.º 23
0
 def energy(self, x):
     S = 0
     for i in range(self.dims):
         S += x * roll(x, [1], [i + 1])
         #S += x*roll(x,[-1],[i+1])
     term1 = x**2
     term2 = (term1 - 1)**2
     for _ in range(self.dims):
         S = S.sum(-1)
         term1 = term1.sum(-1)
         term2 = term2.sum(-1)
     S *= -2 * self.kappa
     term2 *= self.lamb
     S += term1 + term2
     return S
Exemplo n.º 24
0
 def apply(self, state):
     enemies = []
     total_damage = 0
     for enemy in state.scene.enemies:
         raw_damage = utils.roll(1, 10, disadvantage=1) - 10
         if raw_damage < 0:
             damage = 0
         elif raw_damage < 3:
             damage = 3
         else:
             damage = raw_damage
         enemy = enemy.set(health=enemy.health - damage)
         total_damage += damage
         if enemy.health < 0:
             enemy = enemy.set(health=0)
         enemies.append(enemy)
     return state.set(
         scene=state.scene.set(action=state.scene.action.set(
             effect_description=f'Did {total_damage} Damage'),
                               enemies=pyrsistent.pvector(enemies)))
Exemplo n.º 25
0
 def cast(self, slot_level: int, target: 'Character' = None) -> None:
     try:
         assert self.caster
     except:
         raise Warning("No caster specified for the spell!")
     if not self.dc:
         self.dc = self.caster.dc
     try:
         assert slot_level >= self.level
         assert self.caster.slots[slot_level].uses > 0
         self.caster.slots[slot_level].consume()
         if target:
             saved = target.save(self.check, self.dc)
             if self.damage_type:
                 multiplier = 1
                 if saved:
                     multiplier = 0.5
                 target.takeDamage(self.damage[str(slot_level)],
                                   self.damage_type,
                                   multiplier=multiplier)
                 if self.caster.misc_damages:
                     for damage in self.caster.misc_damages:
                         target.takeDamage(damage['roll'], damage['type'],
                                           damage['multiplier'])
             if self.condition:
                 if not saved:
                     target.setCondition(self.condition)
             if self.heal_roll:
                 target.heal(roll(self.heal_roll))
         if self.concentration:
             self.caster.setCondition('concentrating')
         if self.condition and not target:
             self.caster.setCondition(self.condition)
     except AssertionError:
         print(
             "No enough uses available for that slot or slot level is too low."
         )
         return None
Exemplo n.º 26
0
 def __init__(self,
              name,
              stats: Stats,
              hp: Union[int, str],
              speed: Union[int, List[int]],
              alignment=None,
              skills: List[Skill] = None,
              bonuses: List[Bonus] = None):
     self.name = name
     self.stats = stats
     if type(hp) is str:
         self.hp = roll(hp)
     else:
         self.hp = hp
     self.speed = {"land": 0, "flying": 0}
     if type(speed) is int:
         self.speed["land"] = speed
     else:
         self.speed["land"] = speed[0]
         self.speed["flying"] = speed[1]
     self.alignment = alignment
     self.skills = skills
     self.bonuses = bonuses
Exemplo n.º 27
0
def loot(level):
    """Creates random loot for a level.
    {
     'coins': {'coin': 'gp', 'amount': 100}, 
     'gems': [{'gp': 100, 'type': 'Ruby'}, {'gp': 1000, 'type': 'Diamond'}],
     'item': item.json
    }
    """
    logging.info('METHOD:: loot()')
    treasure = TREASURE[level]
    loot = {'coins': None, 'gems': None, 'item': None}
    
    # Coins
    coins_roll = roll(100, 1)
    logging.info('VALUE:: coins_roll = '+str(coins_roll))
    coins = treasure['coins']
    for x in coins:
        range_ = x['range']
        logging.info('VALUE:: coin range_ = '+str(range_))
        if coins_roll <= range_:
            dice = x['dice']
            die = x['die']
            if dice > 0:
                coin = x['coin']
                base = x['base']
                multiplier = roll(die, dice) 
                amount = multiplier*base
                loot['coins'] = {'coin': coin, 'amount': amount}
    
    # Gems
    gems_roll = roll(100, 1)
    logging.info('VALUE:: gems_roll = '+str(gems_roll))
    gems = treasure['gems']
    for x in gems:   
        range_ = x['range']
        logging.info('VALUE:: gem range_ = '+str(range_))   
        if gems_roll <= range_:
            dice = x['dice']
            die = x['die']
            if dice > 0:
                number_of_gems = roll(die, dice)
                gems = []
                for i in number_of_gems:
                    gem_type_roll = roll(100, 1)
                    for g in GEMS:
                        range_ = g['range']
                        if gem_type_roll <= range_:
                            gem_value = roll(g['dice'], g['die'])
                            gem_value = gem_value*g['base']
                            gem_type = choice(g['gem'])
                            gem = {'gp': gem_value, 'type': gem_type}
                            gems.append(gem)
                
                loot['gems'] = gems
                           
    # Item
    items_roll = roll(100, 1)
    logging.info('VALUE:: items_roll = '+str(items_roll))
    items = treasure['items']
    for x in items:       
        range_ = x['range']
        logging.info('VALUE:: items range_ = '+str(range_))   
        if items_roll <= range_:    
            dice = x['dice']
            die = x['die']
            if dice > 0:
                item_level_mod = roll(die, dice)
                item_level = item_level_mod + level - 1
                item_class_roll = roll(100, 1)
                item_class = None
                if item_class_roll <= 30:
                    item_class = models.Weapon
                elif item_class_roll <= 50:
                    item_class = models.Armor                                        
                elif item_class_roll <= 80:
                    item_class = models.Potion
                elif item_class_roll <= 90:
                    item_class = models.Implement                 
                elif item_class_roll <= 95:
                    item_class = models.Gear
                elif item_class_roll <= 99:
                    item_class = models.Artifact                                                            
                elif item_class_roll <= 100:
                    item_class = models.Ring
                
                query = item_class.all()
                query.filter('level =', item_level)
                item_choices = query.fetch(1000)
                random_item = choice(item_choices)
                loot['item'] = random_item.json
                                    
    return loot            
Exemplo n.º 28
0
 def crit_check(self):
     if roll() < self.crit_chance:
         print("You unleash a critical strike")
         return self.crit_multi
     return 1
Exemplo n.º 29
0
#code used for the variant: summon X monsters.

"""
This code takes in 3 command line arguments: the amount of monsters using this feature, the chance that it will summon a monster, and the die used to summon it
Monster amount: int
Summon chance: int, 1-100, it represents a percentage chance
Summon Die: string, described in a (x)d(y) where x is the number of dice used, and y is the type of die (1d4, 2d6, 3d20, etc.)
"""
import random
import sys
from utils import roll

monster_amount = int(sys.argv[1])
summon_chance = int(sys.argv[2])

summon_die_arg = sys.argv[3].split("d")
summon_die_amount = int(summon_die_arg[0])
summon_die = int(summon_die_arg[1])

sucesses = filter(lambda x: x<summon_chance, roll(1, 100, monster_amount))

summons = roll(summon_die_amount, summon_die, len(sucesses))

print("Total sucesses: {}".format(len(sucesses)))
print("Summon amounts: {}".format(summons))
print("Total summons: {}".format(sum(summons)))

	
Exemplo n.º 30
0
def attackMonster(attacker, attack, monster):
    '''Resolves an attack against a Monster. Returns the damage result as 
    a dictionary: {'damage': 10, 'keywords': ['Fire'], 'status': 'Hit'}, and
    Returns a List of entities to be updated.    
    '''
    _trace = TRACE+'rollAttack():: '
    logging.info(_trace)
    damage_keywords = attack.damage_keywords
    json = {'key': str(monster.key()), 'name': monster.name,
            'damage': 0, 'keywords': damage_keywords, 
            'status': 'Hit', 'hp': 0, 'xp': monster.experience}
    
    entities = [] 
    
    # Roll Attack, natural 20 is a Hit
    #attack_roll = utils.roll(20, 1)  
    attack_roll = 19  # FOR TESTING
    logging.info(_trace+'attack_roll = '+str(attack_roll))    
    
    if attack.class_name() == models.WPN:
        # get attack mod using proficiency and ability
        # if magic, add bonus
        # get defense value
        # compare values
        # hit?
        # assign damage
        # TODO:: if magic, check for keywords
        
        json_weapon = item.getJSONItem(models.WPN, attack)
        logging.info(_trace+'Attack = Item.Weapon')
        logging.info(_trace+'Weapon = '+str(json_weapon))
        if attack.magic == True: pass
        else: pass
        
        # Get Proficiency and Ability Mod, add to attack roll
        logging.info(_trace+'proficiency = '+str(attack.proficiency))
        logging.info(_trace+'attack_mod = '+str(attack.attack_mod))
        mod_attack_roll = attack_roll + attack.attack_mod + attack.proficiency
        logging.info(_trace+'mod_attack_roll = '+str(mod_attack_roll))    
            
        # Get Defense Score
        defense = 'AC'
        defense_score = monster.scores['defenses'][defense]['score']
        logging.info(_trace+'defense_score = '+str(defense_score))     
    
        # Evaluate Hit
        if mod_attack_roll < defense_score:
            logging.info(_trace+'Attack is a Miss!')
            json['status'] = 'Miss'

        # Roll Damage
        else:    
            logging.info(_trace+'Attack is a Hit!')
            damage_dice = attack.damage_dice 
            damage_die = attack.damage_die
            damage = 0
            if damage_die != 0:
                damage = utils.roll(damage_die, damage_dice)
            if attack.damage_mod:
                damage += damage_mod
            logging.info(_trace+'damage before defenses = '+str(damage))
    
            # Calculate Defenses
            immunities = monster.immunities
            resist =  monster.resist
            vulnerable = monster.vulnerable
            for d in damage_keywords:
                # No Damage if Monster has immunity
                if d in immunities:
                    json['status'] = 'Immune to '+d
                    return json        
        
                # Reduced Damage for resistence
                if resist is not None:
                    resist_keys = resist.keys()
                    if d in resist_keys:
                        mod = resist[d]
                        damage -= mod
                        json['status'] = 'Resists '+d
        
                # Increased Damage for vulnerability
                if vulnerable is not None:
                    vulnerable_keys = vulnerable.keys()
                    if d in vulnerable_keys:
                        mod = vulnerable[d]
                        damage += mod
                        json['status'] = 'Vulnerable to '+d                    
    
                # Damage cannot be less than 0
                if damage < 0:
                    damage = 0    
            
            # Update damage to monster, determine kill, assign experience
            hp = monster.hit_points['hp']
            hp -= damage
            if hp < 0:
                hp = 0
                monster.status = 'KIA'
                attacker.experience += monster.experience
                entities = [monster, attacker]
            
            monster.hit_points['hp'] = 0
                    
            json['hp'] = hp
            json['damage'] = damage     
                
    elif attack.class_name() == models.ATT:    
        # assign damage
        # Weapon damage?
        # -- get weapon
        # dice damage?
        # -- roll damage
        # Ability bonus to damage?
        # -- add to damage
        # damange keywords?
        # -- add/subtract
        json_attack = power.getJSONPower(models.ATT, attack)
        logging.info(_trace+'Attack = '+models.ATT)
        logging.info(_trace+'Attack = '+str(json_attack))
        
        # Get Attack Score
        logging.info(_trace+'attack_mod = '+str(attack.attack_mod))
        abil = attack.attack_ability
        logging.info(_trace+'attack ability = '+abil)
        ability_mod = attacker.scores['abilities'][abil]['mod']
        mod_attack_roll = attack_roll + attack.attack_mod + ability_mod
        logging.info(_trace+'mod_attack_roll = '+str(mod_attack_roll))    
         
        # Get Defense Score
        def_abil = attack.defense_ability
        defense_score = monster.scores['defenses'][def_abil]['score']
        logging.info(_trace+'defense ability = '+def_abil)        
        logging.info(_trace+'defense score = '+str(defense_score))         
    
        # Evaluate Hit
        if mod_attack_roll < defense_score:
            logging.info(_trace+'Attack is a Miss!')
            json['status'] = 'Miss'

        # Roll Damage
        else:    
            logging.info(_trace+'Attack is a Hit!')
            damage_dice = attack.damage_dice 
            damage_die = attack.damage_die
            ability = attack.damage_ability_type
            damage = 0
            # Check for mods and add Damage
            if damage_die != 0:
                damage_roll= utils.roll(damage_die, damage_dice)
                logging.info(_trace+'damage_roll = '+str(damage_roll))                  
                damage += damage_roll
            if ability:
                damage_mod = attacker.scores['abilities'][ability]['mod']
                damage += damage_mod
            if attack.damage_weapon_multiplier > 0:
                # TODO: currenty the associated weapon/implement is not passed
                # so a default is used ...
                damage += utils.roll(10, 1)
            logging.info(_trace+'damage before defenses = '+str(damage))  
    
            # Calculate Defenses
            immunities = monster.immunities
            resist =  monster.resist
            vulnerable = monster.vulnerable
            for d in damage_keywords:
                # No Damage if Monster has immunity
                if d in immunities:
                    json['status'] = 'Immune to '+d
                    return json        
        
                # Reduced Damage for resistence
                if resist is not None:
                    resist_keys = resist.keys()
                    if d in resist_keys:
                        mod = resist[d]
                        damage -= mod
                        json['status'] = 'Resists '+d
        
                # Increased Damage for vulnerability
                if vulnerable is not None:
                    vulnerable_keys = vulnerable.keys()
                    if d in vulnerable_keys:
                        mod = vulnerable[d]
                        damage += mod
                        json['status'] = 'Vulnerable to '+d                    
    
                # Damage cannot be less than 0
                if damage < 0:
                    damage = 0    
    
                json['damage'] = damage
    
    return json, entities
Exemplo n.º 31
0
 def will_not_put(self):
     return not roll(int(Spider.CHANCE_TO_PUT * 100))
Exemplo n.º 32
0
def rollEncounter(player_party, geo_pt):
    '''Creates a random monster encounter.  Returns a NonPlayerParty of
    monsters or None.  The chance of encountering monsters is based on the
    player_party's encounter log.
    ''' 
    _trace = TRACE+'rollEncounter():: '
    logging.info(_trace)
    logging.info(_trace+' player_party = '+str(player_party))    

    # Determine likelyhood of encounter ...
    '''
    {'encounter_log': {'total': 23, 'uniques': 2, 'start_time': POSIX
                   'last_encounter': {'time_since': POSIX, 'checks': 9}}}
    '''
    log = player_party.log
    checks = log['encounter_log']['last_encounter']['checks']
    player_party.log['encounter_log']['last_encounter']['checks'] = checks + 1
    mod = checks*2
    r = utils.roll(100, 1)
    logging.info(_trace+'r = '+str(r))     
    
    if r > 97: unique = True
    else: unique = False
    r = r + mod 
    
    ### TEST ROLL - uncomment to test a specific roll
    r = 75
    ###
    
    # There is an Encounter :)
    if r >= 75:
        # Update the Encounter Log ...
        player_party.log['encounter_log']['total'] += 1
        last_encounter = {'time_since': time.time(), 'checks': 0}
        player_party.log['encounter_log']['last_encounter'] = last_encounter
        
        # Get number of PCs and the average level of the Party ...
        party_size = len(player_party.players)
        members = db.get(player_party.players)
        total = 0
        for m in members:
            total = total + m.level
        avg_level = total/party_size
        logging.info(_trace+'avg_level = '+str(avg_level))        
        monster_party = models.NonPlayerParty(location = geo_pt, 
                                              monsters = [],
                                              json = {'monsters': []},
                                              level = avg_level)
        
        # Get the appropriate Monster table for the Party level ...    
        monster_level = MONSTER_XP_LEVELS[avg_level]
        logging.info(_trace+'monster_level = '+str(monster_level))
        
        # Get XP target for the encounter based on party level and size ...
        party_xp = monster_level[models.STAN]*party_size   
        logging.info(_trace+'party_xp = '+str(party_xp))
        
        # Roll Monster Encounter template   
        if unique:
            r = 10
        else:    
            # Change die sides to exclude results from monster generator
            
            # Low level
            if avg_level < 3:
                r = utils.roll(8, 1) 
                
            # Higher level includes Solo encounters           
            else:
                r = utils.roll(9, 1) 
        
        logging.info(_trace+'r = '+str(r))
        
        ### TEST ROLL - uncomment to test a specific roll
        r = 1
        ###
        
        entities = []    
        label = None
        ######################################################################
        # Minions Minions Minions!
        if r == 1 or r == 2:
            logging.info(_trace+'Minions Minions Minions!')              

            #  Randomly adjust level to create more variety ...
            if avg_level > 3:
                r = utils.roll(5, 1)
                logging.info(_trace+'r = '+str(r)) 
                level_mod = 0
                if r == 1:
                    level_mod = +2
                if r == 2:
                    level_mod = +1
                if r == 3:
                    level_mod = 0
                if r == 4:
                    level_mod = -1
                if r == 5:
                    level_mod = -2
                
                avg_level += level_mod        
                logging.info(_trace+'new avg_level = '+avg_level) 
            
            # Get Minion XP and # of Minions for this level ...
            minion_xp = MONSTER_XP_LEVELS[avg_level][models.MIN]
            npc_party_size = party_xp/minion_xp
            logging.info(_trace+'npc_party_size = '+str(npc_party_size)) 
                        
            q = db.Query(models.NonPlayerCharacterTemplate, keys_only=True)                    
            q.filter('role = ', models.MIN)
            q.filter('challenge =', models.STAN)
            q.filter('level =', avg_level)
            q.filter('unique =', False)
            npc_keys = q.fetch(100)
            logging.info(_trace+'# npc_keys = '+str(len(npc_keys)))              
            r = utils.roll(len(npc_keys), 1)
            logging.info(_trace+'r = '+str(r))  
            npc_key = npc_keys[r-1] # indexes start at 0
            npc = db.get(npc_key)
            for i in range(npc_party_size):
                m = monster.createMonsterFromTemplate(npc)
                monster_party.monsters.append(m.key())
                entities.append(m)
                
            label = str(npc_party_size) + ' ' + entities[0].name
            if npc_party_size > 1:
                label += 's'

                
        ######################################################################
        # There's one for everyone.                
        elif r == 3 or r == 4:  
            logging.info(_trace+'There\'s one for everyone!')  
            logging.info(_trace+'monster_level = '+str(monster_level[models.STAN]))
            q = db.Query(models.NonPlayerCharacter, keys_only=True)
            q.filter('challenge =', models.STAN)
            q.filter('experience =', monster_level[models.STAN])
            q.filter('level =', avg_level)
            q.filter('unique =', False)    
            logging.info(_trace+'query = '+str(q))             
            npc_keys = q.fetch(100)         
            r = utils.roll(len(npc_keys), 1)
            logging.info(_trace+'r = '+str(r))
            npc_key = npc_keys[r-1]
            npc = db.get(npc_key)
            monster_party_size = party_size
            for i in str(monster_party_size):
                m = models.Monster(npc = npc_key,
                                   json = character.getJSONNonPlayer(npc))
                                    
                entities.append(m)            

        ######################################################################        
        # Minions plus Mini-boss - oh noze!   
        elif r == 5 or r == 6:
            logging.info(_trace+'Minions + Mini-boss!')                
            boss_level = avg_level + 2        
            logging.info(_trace+'boss_level = '+boss_level)

            # Get Mini-boss
            q = db.Query(models.NonPlayerCharacter, keys_only=True)
            q.filter('challenge =', models.LEAD)
            q.filter('level =', boss_level)
            q.filter('unique =', False)            
            npc_keys = q.fetch(100)
            logging.info(_trace+'# npc_keys = '+str(len(npc_keys)))                
            r = utils.roll(len(npc_keys), 1)
            logging.info(_trace+'r = '+str(r))              
            npc_key = npc_keys[r]
            npc = db.get(npc_key)
            elite = models.Monster(npc = npc_key,
                                   json = character.getJSONNonPlayer(npc))
                                    
            entities.append(elite)            
            
            # Get Minions
            race = elite.race
            q = db.Query(models.NonPlayerCharacter, keys_only=True)
            q.filter('role =', models.MIN)
            q.filter('challenge =', models.STAN)
            q.filter('level =', avg_level)
            q.filter('unique =', False)    
            q.filter('race =', race)                      
            npc_keys = q.fetch(100)
            logging.info(_trace+'# npc_keys = '+str(len(npc_keys)))              
            r = utils.roll(len(npc_keys), 1)
            logging.info(_trace+'r = '+str(r))
            npc_key = npc_keys[r]
            npc = db.get(npc_key)

            # Get Minion XP and # of Minions for this level ...
            minion_xp = MONSTER_XP_LEVELS[avg_level][models.MIN]
            npc_party_size = party_xp/minion_xp
            logging.info(_trace+'npc_party_size = '+str(npc_party_size))

            for i in str(npc_party_size):
                m = models.Monster(npc = npc_key,
                                   json = character.getJSONNonPlayer(npc))
                                    
                entities.append(m)
                        
        ######################################################################
        # Dungeon Master party.            
        elif r == 7 or r == 8:
            logging.info(_trace+'You made the DM angry!') 
            # Return a set monster party  ...

        ######################################################################        
        # Solo boss - uh-oh.                        
        elif r == 9:  
            logging.info(_trace+'Solo boss - uh-oh!')              
            #  Randomly adjust level to create more variety ...
            if avg_level > 1:
                r = utils.roll(3, 1)
                level_mod = 0  
                if r == 1:
                    level_mod = -1
                if r == 2:
                    level_mod = 0
                if r == 3:
                    level_mod = 1             
                avg_level += level_mod        
                logging.info(_trace+'new avg_level = '+avg_level)
                                
            q = db.Query(models.NonPlayerCharacter, keys_only=True)
            q.filter('challenge =', models.SOLO)
            q.filter('level =', avg_level)
            q.filter('unique =', False)            
            npc_keys = q.fetch(100)
            r = utils.roll(len(npc_keys), 1)
            npc_key = npc_keys[r]
            npc = db.get(npc_key)
            solo = models.Monster(npc = npc_key,
                                  json = character.getJSONNonPlayer(npc))
                                
            entities.append(solo)  
     


            
        ######################################################################        
        elif r == 10: # Unique NPC.
            logging.info(_trace+'Unique NPC')
            player_party.log['encounters']['uniques'] += 1            
            q = db.Query(models.NonPlayerCharacter, keys_only=True)
            q.filter('level =', avg_level)
            q.filter('unique =', True)            
            npc_keys = q.fetch(100)
            logging.info(_trace+'# npc_keys = '+str(len(npc_keys)))              
            r = utils.roll(len(npc_keys), 1)
            logging.info(_trace+'r = '+str(r))
            npc_key = npc_keys[r]
            npc = db.get(npc_key)
            solo = models.Monster(npc = npc_key,
                                  json = character.getJSONNonPlayer(npc))
                            
            entities.append(solo)
            
            # More than 1 Player? Throw in some Minions and make it a Party!
            if party_size > 1:
                q = db.Query(models.NonPlayerCharacter, keys_only=True)
                q.filter('role =', models.MIN)
                q.filter('challenge =', models.STAN)
                q.filter('level =', avg_level)
                q.filter('unique =', False)            
                npc_keys = q.fetch(100)
                r = utils.roll(len(npc_keys), 1)
                npc_key = npc_keys[r]
                npc = db.get(npc_key)
                minion_party_size = party_size*4
                for i in minion_party_size:
                    m = models.Monster(npc = npc_key,
                                       json = character.getJSONNonPlayer(npc))

                    entities.append(m)                    

    else:
        return None            
    
    db.put(entities) # IDs assigned

    # Need a new loop to get monster JSON after IDs are created ... 
    for e in entities:
        monster_json = monster.getJSONMonsterLite(e)
        monster_party.json['monsters'].append(monster_json)

    parties = [player_party, monster_party]        
    db.put(parties)
    
    # Create pin
    monster_loc = spawnLocation(player_party.location)    
    _pin = pin.createMonsterPartyPin(monster_loc, monster_party, entities)
    monster_party.json['pin_key'] = str(_pin.key())
    monster_party.json['location'] = str(monster_loc)
    monster_party.json['label'] = label

    return monster_party    
Exemplo n.º 33
0
import sys
from utils import roll

monster_amount = int(sys.argv[1])
attack_bonus = int(sys.argv[2])
average_damage = int(sys.argv[3])
ac = int(sys.argv[4])

attack_rolls = roll(1, 20, monster_amount)
add_attack_bonus = map(lambda x: x + attack_bonus, attack_rolls)

hits = filter(lambda x: x >= ac, add_attack_bonus)

damage = average_damage * len(hits)

print(attack_rolls)
print(add_attack_bonus)
print(hits)
print("Total damage: {}".format(damage))
Exemplo n.º 34
0
def prov_roll_1(x):
    return utils.roll(x, 1, np.random.randint(conf.dim))
Exemplo n.º 35
0
def fight(hero, enemy):
    initiative = roll() + hero.agility
    hero.print_status()
    print("\n" + "\n" + "--------battle-------")
    print(
        enemy.name
        + " health: "
        + str(enemy.health)
        + "/"
        + str(enemy.hp)
        + "\n"
    )
    if initiative > 50:
        hero_hit = roll()
        if hero_hit < (
            hero.hit_chance - enemy.defense
        ):  # factors if the hit is successful based on hit chance and monster defense
            crit_proc = hero.crit_check()
            attack_damage = int(
                random.randint(
                    int(0.8 * hero.damage), int((hero.damage) * crit_proc)
                )
            )
            print("You hit for {} damage".format(attack_damage))
            enemy.health -= attack_damage
        else:
            print("You swing wildly and miss...")
        enemy_hit = roll()
        if enemy_hit < (
            enemy.hit_chance - hero.defense
        ):  # factors if the hit is successful based on hit chance and hero defense
        # should have been a common function in parent class
            crit_enemy = enemy.crit_check()
            enemy_damage = int(
                random.randint(
                    int(0.8 * enemy.damage),
                    int((enemy.damage) * crit_enemy),
                )
            )
            print("You take {} damage".format(enemy_damage) + "\n")
            hero.health -= enemy_damage
        else:
            print("You successfully dodge the attack" + "\n")
    else:
        enemy_hit = roll()
        if enemy_hit < (enemy.hit_chance - hero.defense): 
            crit_enemy = enemy.crit_check()
            enemy_damage = int(
                random.randint(
                    int(0.8 * enemy.damage),
                    int((enemy.damage) * crit_enemy),
                )
            )
            print("You take {} damage".format(enemy_damage) + "\n")
            hero.health -= enemy_damage
        else:
            print("You successfully dodge the attack" + "\n")
        hero_hit = roll()
        if hero_hit < (
            hero.hit_chance - enemy.defense
        ):  # factors if the hit is successful based on hit chance and monster defense
            crit_proc = hero.crit_check()
            attack_damage = int(
                random.randint(
                    int(0.8 * hero.damage), int((hero.damage) * crit_proc)
                )
            )
            print("You hit for {} damage".format(attack_damage) + "\n")
            enemy.health -= attack_damage
        else:
            print("You swing wildly and miss..." + "\n")
    if hero.health <= 0:
        hero.death()  # handles death
    elif enemy.health <= 0:
        battle_room_success(
            hero, enemy
        ) 
    else:
        battle_choices(hero, enemy)
Exemplo n.º 36
0
def attackMonster(attacker, attack, monster):
    '''Resolves an attack against a Monster and returns the damage result as 
    a dictionary: {'damage': 10, 'keywords': ['Fire'], 'status': 'Hit'}
    '''
    _trace = TRACE+'rollAttack():: '
    logging.info(_trace)
    damage_keywords = attack.damage_keywords
    json = {'monster': str(monster.key()),'damage': 0, 'keywords': damage_keywords, 'status': 'Hit'}
    
    # Roll Attack, natural 20 is a Hit
    attack_roll = utils.roll(20, 1)    
    
    if attack.class_name() == 'Weapon':
        # get attack mod using proficiency and ability
        # if magic, add bonus
        # get defense value
        # compare values
        # hit?
        # assign damage
        # if magic, check for keywords
        
        logging.info(_trace+'Attack = Item.Weapon')
        if attack.magic == True: pass
        else: pass
                
        mod_attack_roll = attack_roll + attack.attack_mod
        logging.info(_trace+'attack_roll = '+str(attack_roll))
        logging.info(_trace+'mod_attack_roll = '+str(mod_attack_roll))
    
        # Get Defense Score
        defense = attack.defense_ability
        defense_score = monster.scores['defenses'][defense]['score']
        logging.info(_trace+'defense_score = '+str(defense_score))     
    
        # Evaluate Hit
        if mod_attack_roll < defense_score:
            logging.info(_trace+'Attack is a Miss!')
            json['status'] = 'Miss'

        # Roll Damage
        else:    
            logging.info(_trace+'Attack is a Hit!')
            damage_dice = attack.damage_dice 
            damage_die = attack.damage_die
            ability = attack.damage_ability_mod
            damage = 0
            if damage_die != 0:
                damage = utils.roll(damage_die, damage_dice)
            ability_mod = attacker.scores['abilities'][ability]['mod']
            damage += ability_mod
            logging.info(_trace+'unmodified damage = '+str(damage))
    
            # Calculate Defenses
            immunities = monster.immunities
            resist =  monster.resist
            vulnerable = monster.vulnerable
            for d in damage_keywords:
                # No Damage if Monster has immunity
                if d in immunities:
                    json['status'] = 'Immune to '+d
                    return json        
        
                # Reduced Damage for resistence
                if resist is not None:
                    resist_keys = resist.keys()
                    if d in resist_keys:
                        mod = resist[d]
                        damage -= mod
                        json['status'] = 'Resists '+d
        
                # Increased Damage for vulnerability
                if vulnerable is not None:
                    vulnerable_keys = vulnerable.keys()
                    if d in vulnerable_keys:
                        mod = vulnerable[d]
                        damage += mod
                        json['status'] = 'Vulnerable to '+d                    
    
                # Damage cannot be less than 0
                if damage < 0:
                    damage = 0    
    
                json['damage'] = damage        
                
    elif attack.class_name() == 'Attack':    
        logging.info(_trace+'Attack = Power.Attack')
        # get attack ability mod
        # get attack mod
        # get defense value
        # compare values
        # hit?
        # assign damage
        # Weapon damage?
        # -- get weapon
        # dice damage?
        # -- roll damage
        # Ability bonus to damage?
        # -- add to damage
        # damange keywords?
        # -- add/subtract
        
        mod_attack_roll = attack_roll + attack.attack_mod
        logging.info(_trace+'attack_roll = '+str(attack_roll))
        logging.info(_trace+'mod_attack_roll = '+str(mod_attack_roll))
    
        # Get Defense Score
        defense = attack.defense_ability
        defense_score = monster.scores['defenses'][defense]['score']
        logging.info(_trace+'defense_score = '+str(defense_score))     
    
        # Evaluate Hit
        if mod_attack_roll < defense_score:
            logging.info(_trace+'Attack is a Miss!')
            json['status'] = 'Miss'

        # Roll Damage
        else:    
            logging.info(_trace+'Attack is a Hit!')
            damage_dice = attack.damage_dice 
            damage_die = attack.damage_die
            ability = attack.damage_ability_mod
            damage = 0
            if damage_die != 0:
                damage = utils.roll(damage_die, damage_dice)
            ability_mod = attacker.scores['abilities'][ability]['mod']
            damage += ability_mod
            logging.info(_trace+'unmodified damage = '+str(damage))
    
            # Calculate Defenses
            immunities = monster.immunities
            resist =  monster.resist
            vulnerable = monster.vulnerable
            for d in damage_keywords:
                # No Damage if Monster has immunity
                if d in immunities:
                    json['status'] = 'Immune to '+d
                    return json        
        
                # Reduced Damage for resistence
                if resist is not None:
                    resist_keys = resist.keys()
                    if d in resist_keys:
                        mod = resist[d]
                        damage -= mod
                        json['status'] = 'Resists '+d
        
                # Increased Damage for vulnerability
                if vulnerable is not None:
                    vulnerable_keys = vulnerable.keys()
                    if d in vulnerable_keys:
                        mod = vulnerable[d]
                        damage += mod
                        json['status'] = 'Vulnerable to '+d                    
    
                # Damage cannot be less than 0
                if damage < 0:
                    damage = 0    
    
                json['damage'] = damage
    
    return json
Exemplo n.º 37
0
 def crit_check(self):
     if roll() < self.crit_chance:
         print("The {} attack you with a critical strike".format(self.name))
         return self.crit_multi
     return 1