def _attack(self, attack, attacker, attackee): if attack.means.condition: success, msg = self.on_set_condition(attack, attacker, attackee) else: method = getattr(self, 'on_' + attack.means.name) success, msg = method(attack, attacker, attackee) if success: logger.msg_warn(msg.strip()) else: logger.msg_info(msg.strip())
def zap(self, being, wand, direction): if wand.charges < 1: logger.msg_info('{You} cannot zap a wand without charges.'.format(**being.words_dict)) return False wand.item.charges -= 1 tile = self.game.level.tile_for(being) spell = wand.spell first = True # if its ray we now know it. if not wand.item.known and wand.kind.bounce: wand.item.known = True # if we have a ray or a beam if wand.kind.ray_dice: length = wand.kind.ray_dice.roll() while length > 0: tiles = self.game.level.get_ray(tile, direction, length+1, all_types=wand.item.can_tunnel) if first: tiles = tiles[1:] length -= len(tiles) self.events['wand_zapped'].emit(spell.view(), [t.idx for t in tiles], direction) for t in tiles: logger.ddebug('A {} passes through {}.'.format(wand.item.zap, t)) other = tile.being if spell.damage and t.being: if self.player_can_see(t): logger.msg_warn("The {zap} hits {you}.".format(zap=wand.item.zap, **t.being.words_dict)) else: logger.ddebug("The (unseen) {zap} hits {you}.".format(zap=wand.item.zap, **t.being.words_dict)) if self.combat_arena.spell_attack(tile, t, spell): wand.item.known = True if spell.method and spell.handle(self.game, t): wand.item.known = True logger.msg_warn('The wand {} {}.'.format(spell.verb.she, t.being)) self.handle_spell(spell, t, other, tile.being) # if the wand does not bounce or the tiletype does not bouce then stop if not (tiles[-1].tiletype.bounce and wand.kind.bounce): break direction = direction.bounce(tiles[-1].tiletype.bounce) tile = self.game.level.adjacent_tile(tiles[-1], direction) first = False elif spell.method and spell.handle(self.game, tile): wand.item.known = True self.handle_spell(spell, tile, being) if not being.is_dead: self.turn_done(being) return True