Example #1
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
Example #2
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