Example #1
0
 def use(self, user):
     (x, y) = ui.target_tile()
     if (x, y) == (None, None):
         return False
     explode(x, y, self.radius, self.damage)
     user.mana -= self.mana_use
     return True
Example #2
0
def cast_fireball():
	#ask the player for a target tile to throw a fireball at
	ui.message('Left-click a target tile for the fireball, or right-click to cancel.', libtcod.light_cyan)
	(x, y) = ui.target_tile()
	if x is None: return 'cancelled'
	ui.message('The fireball explodes, burning everything within ' + str(FIREBALL_RADIUS) + ' tiles!', libtcod.orange)
 
	for obj in g.objects:  #damage every fighter in range, including the player
		if obj.distance(x, y) <= FIREBALL_RADIUS and obj.fighter:
			ui.message('The ' + obj.name + ' gets burned for ' + str(FIREBALL_DAMAGE) + ' hit points.', libtcod.orange)
			obj.fighter.take_damage(FIREBALL_DAMAGE)
Example #3
0
def bash_attack(actor):
    x, y = ui.target_tile(max_range=1)
    target = None
    for object in main.current_map.fighters:
        if object.x == x and object.y == y:
            target = object
            break
    if target is not None and target is not player.instance:
        result = player.bash_attack(target.x - actor.x, target.y - actor.y)
        if result != 'failed':
            return result
    return 'didnt-take-turn'
Example #4
0
 def use(self, user):
     pos = ui.target_tile()
     if pos == (None, None):
         return False
     for object in terrain.map.objects:
         if (object.x, object.y) == pos and isinstance(object, mob.Mob):
             if object.ai:
                 object.ai = ai.ConfusedMob(object.ai)
                 ui.message(
                     'The ' + object.name + ' is confused!', tcod.blue)
                 user.mana -= self.mana_use
                 return True
     # if code hasn't returned yet, no mob is at the position
     ui.message('There is no being there!')
Example #5
0
def cast_flashbang():
	#ask the player for a target tile to throw a fireball at
	ui.message('Left-click a target tile for the flashbang, or right-click to cancel.', libtcod.light_cyan)
	(x, y) = ui.target_tile()
	if x is None: return 'cancelled'
	ui.message('The flashbang explodes, blinding and deafening everything within ' + str(FLASHBANG_RADIUS) + ' tiles!', libtcod.orange)
 
	for obj in g.objects:  #damage every fighter in range, including the player
		if obj.distance(x, y) <= FLASHBANG_RADIUS and obj.fighter and obj.ai:
			old_ai = obj.ai
			obj.ai = monsters.ConfusedMonster(old_ai, FLASHBANG_LENGTH)
			obj.ai.owner = obj

			ui.message("The " + obj.name + " is dazed and confused!", libtcod.light_green)
Example #6
0
def throw_water_balloon():
	#ask the player for a target tile to throw a fireball at
	ui.message('Left-click a target tile for the water balloon, or right-click to cancel.', libtcod.light_cyan)
	(x, y) = ui.target_tile()
	if x is None: return 'cancelled'
	ui.message('The water balloon bursts, dampening everything around it!', libtcod.light_blue)
 
	for obj in g.objects:  #damage every fighter in range, including the player
		if obj.distance(x, y) <= WATERBALLOON_RADIUS and obj.light:
			if obj.ai:
				ui.message('The ' + obj.name + '\'s torch goes out!', libtcod.light_blue)
			else:
				ui.message('The ' + obj.name + ' goes out!', libtcod.light_blue)

			v.remove_light(obj)

			obj.light = None
			g.fov_recompute = True
Example #7
0
def attack_reach(actor, target, context):
    if actor is None:
        actor = player.instance
        x, y = ui.target_tile(max_range=1)
        target = None
        for object in main.current_map.fighters:
            if object.x == x and object.y == y:
                target = object
                break
        if target is not None and target is not player.instance:
            result = player.reach_attack(target.x - actor.x,
                                         target.y - actor.y)
            if result != 'failed':
                return result
        return 'didnt-take-turn'
    else:
        if abs(actor.x - target.x) <= 2 and abs(actor.y - target.y) <= 2:
            return actor.fighter.attack(target)
        else:
            return 'didnt-take-turn'
Example #8
0
def throw_light_orb():
	#Create a puddle of light around it
	ui.message('Left-click a target tile for the light orb, or right-click to cancel.', libtcod.light_cyan)
	(x, y) = ui.target_tile()
	if x is None: return 'cancelled'
 
	#TODO: make this land a bit randomly
	orb_ai = LightDarkOrb(LIGHT_ORB_TICK_TIME)
	l = object.Light(LIGHT_ORB_LSL)
	lit_orb = object.Object(g.player.x, g.player.y, '*', 'light orb', LIGHT_ORB_THROWN_COLOR, 
			light = l, ai = orb_ai)
	v.add_light(lit_orb)

	u.throw_object(lit_orb, g.player.x, g.player.y, x, y)

	g.objects.append(lit_orb)
	lit_orb.send_to_back()

	u.qinsert(lit_orb, g.time + LIGHT_ORB_TICK_TIME)

	ui.message('The light orb bursts into magical fire as it lands on the ground!', libtcod.orange)
	g.fov_recompute = True
Example #9
0
def throw_dark_orb():
	#Create a puddle of light around it
	ui.message('Left-click a target tile for the dark orb, or right-click to cancel.', libtcod.light_cyan)
	(x, y) = ui.target_tile()
	if x is None: return 'cancelled'
 
	#TODO: make this land a bit randomly
	#TODO: make this stop being lit eventually
	orb_ai = LightDarkOrb(DARK_ORB_TICK_TIME)
	l = object.Light(DARK_ORB_LSL)
	lit_orb = object.Object(g.player.x, g.player.y, '*', 'dark orb', DARK_ORB_THROWN_COLOR, 
				light = l, ai = orb_ai)
	v.add_light(lit_orb)
	
	u.throw_object(lit_orb, g.player.x, g.player.y, x, y)

	g.objects.append(lit_orb)
	lit_orb.send_to_back()

	u.qinsert(lit_orb, g.time + DARK_ORB_TICK_TIME)

	ui.message('The temperature drops as the orb begins to absorb light!', libtcod.light_violet)
	g.fov_recompute = True
Example #10
0
def _get_ability_target(actor, info, target_override):
    targeting = info.get('targeting', 'pick')
    range = info.get('range', 1000)
    ground_targeting = info.get('target_ground', False)
    target = None
    burst = info.get('burst')
    if isinstance(target_override, main.GameObject):
        x = target_override.x
        y = target_override.y
        target_override = x, y

    if targeting == 'override':
        return (0, 0)

    if targeting == 'self' and burst is None:
        if ground_targeting:
            target = actor.x, actor.y
        else:
            target = actor

    if target is None and targeting is not None:
        if actor is player.instance:
            if targeting == 'self':  # for self burst
                target = actor.x, actor.y
            else:
                ui.message_flush(
                    'Left-click a target tile, or right-click to cancel.',
                    libtcod.white)
                default_target = None
                if info.get(
                        'intent', 'aggressive'
                ) == 'aggressive' and ui.selected_monster is not None:
                    default_target = ui.selected_monster.x, ui.selected_monster.y
                target = ui.target_tile(range,
                                        targeting,
                                        default_target=default_target)

        else:
            if target_override is not None and targeting != 'self' and \
                            main.distance(actor.x, actor.y, target_override[0], target_override[1]) > range:
                target = None
                return target  # out of range
            if targeting == 'pick':
                target = (target_override[0], target_override[1])
            elif targeting == 'cone':
                target = main.cone(actor.x,
                                   actor.y,
                                   target_override[0],
                                   target_override[1],
                                   max_range=info['range'])
            elif targeting == 'beam':
                target = main.beam(actor.x, actor.y, target_override[0],
                                   target_override[1])
            elif targeting == 'beam wide':
                # TODO: Support wide beam outside of player targeting
                raise Exception("Not supported")
            elif targeting == 'beam_interrupt':
                target = main.beam_interrupt(actor.x, actor.y,
                                             target_override[0],
                                             target_override[1])
            elif targeting == 'summon':
                target = main.find_closest_open_tile(target_override[0],
                                                     target_override[1])
            elif targeting == 'self':
                target = actor.x, actor.y

        #Targeting failed
        if isinstance(target, tuple) and target[0] is None:
            target = None
        if target is None:
            return target

        if burst is not None and isinstance(target, tuple):
            if info.get('hits_friendlies', False):
                teams = None
            elif info.get('team') is not None:
                if info.get('allies_only') is not None:
                    teams = lambda o: o.fighter.team == info.get('team')
                else:
                    teams = lambda o: o.fighter.team != info.get('team')
            else:
                if info.get('allies_only') is not None:
                    teams = lambda o: o.fighter.team == actor.fighter.team
                else:
                    teams = lambda o: o.fighter.team != actor.fighter.team
            info['origin'] = target[0], target[1]
            if not ground_targeting:
                target = main.get_fighters_in_burst(target[0], target[1],
                                                    burst, actor, teams)
            else:
                target = main.get_tiles_in_burst(target[0], target[1], burst)
        elif not ground_targeting and targeting != 'summon':
            if target is not None:
                if isinstance(target, list):
                    target = [main.get_monster_at_tile(*t) for t in target]
                else:
                    pos = target
                    target = None
                    for fighter in main.current_map.fighters:
                        if fighter.x == pos[0] and fighter.y == pos[1]:
                            target = fighter
                            break

        #randomly select only some of the targets
        if info.get('random_select') is not None and not isinstance(
                target, tuple):
            mode = info.get('random_select')
            target = [
                target[i] for i in random.sample(xrange(len(target)), mode)
            ]

    return target
Example #11
0
def shatter_item(actor, target, context):
    x, y = 0, 0
    dc = context['save_dc']
    if actor is player.instance:  # player is casting
        ui.message_flush('Left-click a target tile, or right-click to cancel.',
                         libtcod.white)
        (x, y) = ui.target_tile()
        if x is None:
            return 'cancelled'
        choices = main.get_objects(
            x, y, lambda o: o.fighter and o.fighter.inventory and len(
                o.fighter.inventory) > 0)
        if len(choices) == 0:
            choices = main.get_objects(x, y, lambda o: o.item is not None)
        if len(choices) > 1:
            target = choices[ui.menu('Which target?',
                                     [i.name for i in choices], 24)]
        elif len(choices) > 0:
            target = choices[0]
        else:
            ui.message('No valid targets here', libtcod.gray)
            return 'cancelled'
        dc += 4
    else:
        x, y = target.x, target.y

    if target is None:
        return 'cancelled'
    item = None
    inventory = None
    if target.fighter is not None:
        inventory = target.fighter.inventory
        if inventory is None or len(inventory) == 0:
            if actor == player.instance:
                ui.message('Target has no items', libtcod.light_blue)
            return 'cancelled'
        item = inventory[libtcod.random_get_int(0, 0, len(inventory) - 1)]
        dc += 5
    elif target.item is not None:
        item = target

    if main.roll_dice('1d20') + main.roll_dice('1d{}'.format(
            actor.fighter.spell_power())) > dc:
        ui.render_explosion(x, y, 1, libtcod.yellow, libtcod.flame)
        ui.message("The {} shatters into pieces!".format(item.name),
                   libtcod.flame)
        if inventory is not None:
            inventory.remove(item)
        item.destroy()
        damage_factor = 4
        if item.equipment is not None:
            damage_factor = item.equipment.weight
        for obj in main.current_map.fighters:
            if obj.distance(x, y) <= context['burst']:
                combat.attack_magical_ex(
                    actor,
                    obj,
                    base_damage_dice='2d{}'.format(damage_factor),
                    spell_dice_number=context['dice'],
                    spell_elements=context['element'],
                    pierce=context['pierce'],
                    shred=context['shred'],
                    defense_types=context['defense_types'],
                    damage_types=context['damage_types'],
                    blockable=context['blockable'],
                    attack_name=context['name'])
        return 'success'
    else:
        ui.message("Shatter failed to break the {}!".format(item.name),
                   libtcod.yellow)
        return 'success'