예제 #1
0
def check_level_up():
    #see if the player's experience is enough to level-up
    level_up_xp = defn.LEVEL_UP_BASE + defn.player.properties[
        'level'] * defn.LEVEL_UP_FACTOR
    if defn.player.creature.xp >= level_up_xp:
        #it is! level up
        defn.player.properties['level'] += 1
        defn.player.creature.xp -= level_up_xp
        gui.message(
            'You reached level ' + str(defn.player.properties['level']) + '!',
            libtcod.yellow)
        choice = None
        while choice == None:  #keep asking until a choice is made
            choice = gui.menu('Level up! Choose a stat to raise:\n', [
                '+4 Life, from ' + str(defn.player.creature.base_max_hp),
                '+5 Mana Capacity, from ' +
                str(defn.player.creature.base_max_mana),
                '+1 Channeling, from ' + str(defn.player.creature.channeling)
            ], defn.LEVEL_SCREEN_WIDTH)

        if choice == 0:
            defn.player.creature.base_max_hp += 4
            defn.player.creature.hp += 4

        elif choice == 1:
            defn.player.creature.base_max_mana += 5
            defn.player.creature.mana += 5

        elif choice == 2:
            defn.player.creature.channeling += 1
예제 #2
0
def target_monster(max_range=None):
    gui.message('Left-click on target, or right-click to cancel.', libtcod.light_cyan)
    #primitive function highlighting range. Ideally would be implemented in read-only attribute of tile

        
    rangemap = defn.fov_map
    libtcod.map_compute_fov(rangemap, defn.player.x, defn.player.y, max_range, defn.FOV_LIGHT_WALLS, defn.FOV_ALGO)
    
    #returns a clicked monster inside FOV up to a range, or None if right-clicked
    while True:

    
        (x, y) = target_tile(max_range)
            
        if x is None:  #player cancelled
            #remove highlight
            for y in range(defn.MAP_HEIGHT):
                for x in range(defn.MAP_WIDTH):
                    if libtcod.map_is_in_fov(rangemap, x, y):
                        libtcod.console_set_char_background(defn.con, x, y, defn.dungeon[x][y].color, libtcod.BKGND_SET)
            return None
 
        #return the first clicked creature, otherwise continue looping
        for obj in defn.dungeon[x][y].objects:
            if obj.creature:
                return obj
예제 #3
0
def cast_heal(parameters):
    #heal the player
    if defn.player.creature.hp == defn.player.creature.max_hp:
        gui.message('You are already at full health.', libtcod.red)
        return 'cancelled'
    gui.message('Your wounds start to feel better!', libtcod.light_violet)
    defn.player.creature.heal(parameters['amount healed'])
예제 #4
0
def new_game():
    #create object representing the player
    object.make_monster(0, 0, 'player', monst.properties['player'])

    cfg.player.level = 1

    #generate map (at this point it's not drawn to the screen)
    cfg.dungeon_level = 1
    mapgen.make_bsp()
    mapgen.initialize_fov()

    cfg.game_state = 'playing'
    cfg.run_realtime = cfg.REAL_TIME
    cfg.inventory = []

    #create the list of game messages and their colors, starts empty
    cfg.game_msgs = []

    #create dictionaries of populations for monsters
    cfg.population = {}
    cfg.max_population = {}
    object.initialize_population()

    #a warm welcoming message!
    gui.message('Beginning genetic simulation.', libtcod.light_red * 0.7)
 def onOk(self, evt):
     name = self.nameEdit.GetValue()
     if not name:
         gui.messageBox(
             # Translators: A message box telling the user that he must enter a theme name in order to continue
             _("Please enter a name for your theme package."),
             # Translators: The title of a message box indicating an error.
             _("Error"))
         return
     try:
         name.encode("mbcs")
     except UnicodeEncodeError:
         gui.message(
             # Translators: A message telling the user to change the name of the new theme because the entered name is not valid.
             _("The theme name you have entered is not valid. Please try another name."
               ),
             # Translators: The title of a message box indicating an error.
             _("Error"))
         self.nameEdit.Clear()
         return self.nameEdit.SetFocus()
     infoDict = {
         "name": name,
         # Translators: The default message in the audio themes manager dialog which will be shown when no author was set for the audio theme.
         "author": self.authorEdit.GetValue() or _("Not Set"),
         # Translators: The default message in the audio themes manager dialog which will be shown when no description was set for the audio theme
         "summary": self.descEdit.GetValue() or _("No Description")
     }
     super(CreaterDialog, self).onOk(evt)
     dg = CreateNewDialog(parent=gui.mainFrame, infoDict=infoDict)
     dg.CenterOnScreen()
     dg.Show()
예제 #6
0
 def declare_attack(self, source, target, dice_bonus, d12_bonus):
     #to avoid the corpse-counterattack problem, check if target is attackable.
     if target.creature:
         if source.creature and 'daze' in source.creature.conditions and libtcod.random_get_int(
                 0, 1, 12) < 7:
             gui.message(
                 source.title.capitalize() + ' is too dazed to attack!',
                 libtcod.orange)
             source.creature.adjust_turn_counter(3)
         else:
             self.resolve_attack_roll(self.dice + dice_bonus, d12_bonus,
                                      source, target)
             #additional strikes do not gain any bonuses.
             if source.creature and (['doublestrike'] in self.traits
                                     or ['triplestrike']) in self.traits:
                 self.resolve_attack_roll(self.dice, d12_bonus, source,
                                          target)
             if source.creature and ['triplestrike'] in self.traits:
                 self.resolve_attack_roll(self.dice, d12_bonus, source,
                                          target)
         #remove daze (and potentially other conditions) at conclusion of attacks
         if source.creature:
             daze_removal = False
             for condition in source.creature.conditions:
                 if condition == 'daze':
                     source.creature.conditions.remove(condition)
                     daze_removal = True
             if daze_removal:
                 gui.message(
                     source.title.capitalize() + ' is dazed no longer!',
                     libtcod.orange)
예제 #7
0
def next_level():
    #advance to the next level
    gui.message('You take a moment to rest, and recover your strength.', libtcod.light_violet)
    cfg.player.fighter.heal(cfg.player.fighter.max_hp / 2)  #heal the player by 50%
 
    cfg.dungeon_level += 1
    gui.message('After a rare moment of peace, you descend deeper into the heart of the dungeon...', libtcod.red)
    make_bsp()  #create a fresh new level!
    initialize_fov()
예제 #8
0
 def take_damage(self, amount):
     stats = self.owner.get_component("stats")
     if amount > 0:
         msg = "{} takes {} damage".format(self.owner.name,
                                       amount)
         stats.cur_hp -= amount
         if stats.cur_hp <= 0:
             self.die()
     else:
         msg = "{} shrugs the attack off".format(self.owner.name)
     gui.message(msg)
예제 #9
0
def organizeFiles(addrGUI):
    dest = addrGUI.get()
    addrGUI.delete(0, tk.END)
    if os.path.isdir(dest) == False:
        gui.message(False)
        return None
    allFiles = getOnlyFiles(dest)  # Get list of files
    populate_filesAndExt(allFiles)  # Populate Dictionary
    ext = identifyExt(dest, allFiles)
    populate_foldersToMake(ext)  # Populate list with unique ext
    generateFolderDirectories(dest, foldersToMake)  # Make new directories
    changePaths(dest, allFiles)
    gui.message(True)
예제 #10
0
def reset_global_variables():

    #Reset all global variables to starting values
    defn.game_msgs = []
    defn.inventory = []
    defn.objects = []
    defn.dungeon = []
    defn.game = Game()
    defn.dungeon_level = 1
    defn.game_state = 'playing'
    defn.player_location_changed = True
    defn.autoplaying = None
    gui.message ('Press *?* for a list of commands', libtcod.white)
예제 #11
0
 def attack(self, target):
     destructible = target.get_component("destructible")
     if not destructible:
         return
     else:
         msg = "{} attacks {}".format(self.owner.name,
                                      target.name)
         gui.message(msg)
         #print "attack", "defense"
         #print self.attack_value, destructible.defense
         damage = max(self.attack_value - destructible.defense,
                      0)
         destructible.take_damage(damage)
예제 #12
0
def tame_animal(parameters, source=None, target=None):
    source=defn.player
    if parameters['target type']=='none':
        pass
            #eventually, maybe we can upgrade so that everything in sight is converted.
    elif parameters['target type']=='creature':
            #find target. currently geared to ranged attacks, though can easily be extended to melee
        target = spfn.target_monster(parameters['range'])
        if target:
            if target.creature.alignment == 'dungeon' and 'animal' in target.properties['subtypes']:
                if defn.player.properties['level'] > target.properties['level']:
                    health_percentage = float(target.creature.hp) / float(target.creature.max_hp)
                    if health_percentage <= parameters['threshold'] or target.creature.hp == 1:
                        target.creature.alignment = 'player'
                        target.color = libtcod.white
                        gui.message('The ' + target.name + ' submits to your will!', libtcod.green)
                        choice = gui.menu('Name your new friend?', ['Yes', 'No'], 24)
                        if choice == 0: #give it a name
                            name = itxt.input_text(50, 5, 'What would you like to name it?\n\n', '\n\n(Press *ENTER* when done)')
                            target.personal_name = name
                        return 'succeeded'
                    else:
                        gui.message('The ' + target.name + ' resists your attempts to tame it.', libtcod.red)
                        return 'failed'
                gui.message('You are not experienced enough to tame that.', libtcod.white)
                return 'cancelled' 
            gui.message('You cannot tame that!', libtcod.white)
            return 'cancelled' 
        else:
            return 'cancelled'
예제 #13
0
    def take_damage(self, damage):
        #apply damage if possible

        if damage > 0:
            self.hp -= damage
 
            #dig through wall
            if self.hp <= 0:
                self.blocked = False
                self.block_sight = False
                self.hp = self.max_hp
                gui.message('The wall crumbles!',libtcod.light_orange)

                #update map
                cfg.fov_recompute = True
예제 #14
0
def check_data_retrieval_error(price_data, dependent_var_list, independent_var_list, data_source):
    """Check whether there was an error retrieving data"""
    # Check whether data was retrieved successfully:
    tickers_list = dependent_var_list + independent_var_list
    if data_source == 'Bloomberg':
        if len(tickers_list) > 1:
            if len(price_data.columns) < len(tickers_list):
                und_errors = np.setdiff1d(tickers_list, price_data.columns)
                gu.message('There was a problem loading data for the following underlyings:\n' + '\n'.join(und_errors))
                for und_error in und_errors:
                    if und_error in dependent_var_list:
                        dependent_var_list.remove(und_error)
                    if und_error in independent_var_list:
                        independent_var_list.remove(und_error)

    return dependent_var_list, independent_var_list
예제 #15
0
def next_level():
    gui.message(
        'You pass through the magical gate with some apprehension. The gate\'s magic heals and restores you.',
        libtcod.light_violet)
    #heal the player by 50%
    defn.player.creature.conditions = []
    defn.player.creature.heal(defn.player.creature.max_hp)
    #store all friendly creatures
    for obj in defn.objects:
        if obj.creature and obj != defn.player and not obj in defn.player.creatures:
            if obj.creature.alignment == 'player':
                defn.player.creatures.append(obj)
    #increment the dungeon level
    defn.dungeon_level += 1
    #generate a new map
    make_map()
    mpfn.initialize_fov()
예제 #16
0
def book(parameters):

    spellbook = defn.player.spellbook

    #lets you learn 1-6 copies of spell, depending on training and level.
    level_copies = [4,2,1,1,0,0]

    #this is not actually the spell instance that will go in your book - it is just a placeholder to find the properties
    spell = parameters['spell']

    if spell.properties['school'] in defn.antitraining:
        level_copies = [2,1,0,0,0,0]
    if spell.properties['school'] in defn.training:
        level_copies = [6,4,2,2,1,1]

    if level_copies[spell.properties['level']-1] == 0:
        gui.message('Unfortunately, you are not skilled enough in the ' + spell.properties['school'] + ' school of magic to learn anything from this book.', libtcod.yellow)
        return 'cancelled'

    copies = level_copies[spell.properties['level']-1]
    
    if len(spellbook.contents)<26:
        spellbook.insert(spell, copies)
        gui.message('As you memorize the spells contained in the tome, it crumbles to dust.', libtcod.green)
        return 'succeeded'
    else:
        gui.message('Your spellbook is full.', libtcod.white)
        return 'cancelled'
예제 #17
0
def handle_keys():
    #global keys

    if defn.key.vk == libtcod.KEY_ENTER and defn.key.lalt:
        #Alt+Enter: toggle fullscreen
        libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())

    elif defn.key.vk == libtcod.KEY_ESCAPE:
        return 'exit'  #exit game

    if defn.game_state == 'playing':

        #autoplay module
        if defn.autoplaying != None:
            #if any hostile monsters are in view, stop autoplaying:
            for obj in defn.objects:
                if obj.creature and obj.creature.alignment != 'player' and libtcod.map_is_in_fov(
                        defn.fov_map, obj.x, obj.y):
                    gui.message(
                        'Seeing enemies, you decide to pay a bit more attention to what you are doing.',
                        libtcod.white)
                    defn.autoplaying = None
                    break

            #Move.

            if defn.autoplaying == 'autoexplore':

                #first check if standing on an item. If so, pick it up.
                for obj in defn.dungeon[defn.player.x][
                        defn.player.
                        y].objects:  #look for an item in the player's tile
                    if obj.item and len(defn.inventory) < 26:
                        #we have an error where a full inventory will cause the player to remain on the same spot, continually trying to pick up the item.
                        if obj.item.pick_up() == 'cancelled':
                            defn.autoplaying == None
                        return
                    #compute fog of war (FOW) dijkstra map
                unexplored_tiles = []
                for y in range(defn.MAP_HEIGHT):
                    for x in range(defn.MAP_WIDTH):
                        if not defn.dungeon[x][y].explored:
                            unexplored_tiles.append(defn.dungeon[x][y])
                    #if inventory is not full, compute item map
                item_tiles = []
                if len(defn.inventory) < 26:
                    for obj in defn.objects:
                        if obj.item and defn.dungeon[obj.x][obj.y].explored:
                            item_tiles.append(defn.dungeon[obj.x][obj.y])

                    #check whether any target squares were found
                dijkstra_autoexplore_map = djks.Map(unexplored_tiles +
                                                    item_tiles)
                dijkstra_autoexplore_map.compute_map()
                #if there is a next point, move there, otherwise cancel autoplay:
                if dijkstra_autoexplore_map.array[defn.player.x][
                        defn.player.y] < 999:
                    destination = dijkstra_autoexplore_map.get_next_step(
                        defn.player.x, defn.player.y)
                    defn.player.creature.try_to_move(destination.x,
                                                     destination.y)
                    return
                else:
                    #cancel autoplay; we're done
                    defn.autoplaying = None
            elif defn.autoplaying == 'autoascend':

                #go up if standing on the portal
                if defn.stairs.x == defn.player.x and defn.stairs.y == defn.player.y:
                    dgen.next_level()
                    defn.autoplaying = None
                    return
                    #see if the portal is visible:
                portals = []
                for y in range(defn.MAP_HEIGHT):
                    for x in range(defn.MAP_WIDTH):
                        if defn.stairs in defn.dungeon[x][
                                y].objects and defn.dungeon[x][y].explored:
                            portals.append(defn.dungeon[x][y])
                if portals:
                    dijkstra_autoascend_map = djks.Map(portals)
                    dijkstra_autoascend_map.compute_map()
                    destination = dijkstra_autoascend_map.get_next_step(
                        defn.player.x, defn.player.y)
                    defn.player.creature.try_to_move(destination.x,
                                                     destination.y)
                    return
                    #cancel autoplay; we're done
                    defn.autoplaying = None
                else:
                    #no portals found; cancel autoplay
                    gui.message(
                        'You have no idea where the nearest portal is.',
                        libtcod.white)
                    defn.autoplaying = None

            else:
                #stop autoexploring when a key is pressed.
                defn.autoplaying = None

        #autofight with tab
        if defn.key.vk == libtcod.KEY_TAB:
            enemy_tiles = []
            for obj in defn.objects:
                if obj.creature and obj.creature.alignment != 'player' and libtcod.map_is_in_fov(
                        defn.fov_map, obj.x, obj.y):
                    enemy_tiles.append(defn.dungeon[obj.x][obj.y])
            if enemy_tiles:
                #create dijkstra map and roll towards nearest enemy.
                dijkstra_autofight_map = djks.Map(enemy_tiles)
                dijkstra_autofight_map.compute_map()
                destination = dijkstra_autofight_map.get_next_step(
                    defn.player.x, defn.player.y)
                defn.player.creature.try_to_move(destination.x, destination.y)
                return
            else:
                gui.message('No enemies in sight!', libtcod.white)

        #cancel autoplay if any key is pressed

        if defn.key.vk != libtcod.KEY_NONE:
            defn.autoplaying = None

        #movement keys

        try:
            (dx0, dx1) = {
                libtcod.KEY_KP1: (-1, 1),
                libtcod.KEY_KP2: (0, 1),
                libtcod.KEY_KP3: (1, 1),
                libtcod.KEY_KP4: (-1, 0),
                libtcod.KEY_KP6: (1, 0),
                libtcod.KEY_KP7: (-1, -1),
                libtcod.KEY_KP8: (0, -1),
                libtcod.KEY_KP9: (1, -1)
            }[defn.key.vk]
            player_move_or_attack(dx0, dx1)
        except:

            if defn.key.vk == libtcod.KEY_KP5:
                return

            key_char = chr(defn.key.c)

            if key_char == ',':
                #pick up an item
                for obj in defn.dungeon[defn.player.x][
                        defn.player.
                        y].objects:  #look for an item in the player's tile
                    if obj.item:
                        obj.item.pick_up()
                        return

            if key_char == '?':
                gui.msgbox(
                    'Use the numpad keys to move around. You can mouse-over any object to identify it. The following keys can be used to get more information:'
                    + '\n\nI = examine an item in your inventory' +
                    '\nZ = examine a spell in your spellbook' +
                    '\nc = access information about your character' +
                    '\nx = get information on a nearby object' +
                    '\n\nThe following keys may be used to interact with your environment:'
                    + '\n\nCOMMA = pick up item from current position' +
                    '\ni = use an item from your inventory' +
                    '\nd = drop an item from your inventory' +
                    '\nz = choose a spell from your spellbook to cast' +
                    '\ns = summon an ally from a previous level' +
                    '\n\nTo avoid tedious repetition, you can automate certain tasks:'
                    + '\n\n< = travel to the nearest portal and pass through' +
                    '\no = autoexplore (press any key to stop exploring)' +
                    '\nTAB = move towards/attack nearest enemy' +
                    '\n\nYour objective on each level is to find the exit and ascend to the next level. Enemies will get more dangerous the further you go, so it will be to your advantage to pick up equipment that you find lying around.',
                    50)

            if key_char == 'i':
                #show the inventory; if an item is selected, use it
                chosen_item = inventory_menu(
                    'Press the key next to an item to use it, or any other to cancel.\n'
                )
                if chosen_item is not None:
                    if chosen_item.use() != 'cancelled':
                        return

            if key_char == 'I':
                #show the inventory; if an item is selected, describe it
                chosen_item = inventory_menu(
                    'Press the key next to an item to examine it, or any other to cancel.\n'
                )
                if chosen_item is not None:
                    info = chosen_item.owner
                    info.describe()

            if key_char == 'z':
                spellbook = defn.player.spellbook
                #show the spellbook; if a spell is selected, use it
                chosen_spell = spellbook_menu(
                    'Press the key next to a spell to cast it, or any other to cancel.\n'
                )
                if chosen_spell is not None:
                    if defn.player.creature.cast_spell(
                            chosen_spell) != 'cancelled':
                        spellbook.remove(chosen_spell, 1)
                    return

            if key_char == 'Z':
                #show the inventory; if an item is selected, describe it
                chosen_spell = spellbook_menu(
                    'Press the key next to a spell for more information, or any other to cancel.\n'
                )
                if chosen_spell is not None:
                    chosen_spell.describe()

            if key_char == 'd':
                #show the inventory; if an item is selected, drop it
                chosen_item = inventory_menu(
                    'Press the key next to an item to drop it, or any other to cancel.\n'
                )
                if chosen_item is not None:
                    chosen_item.drop()
                    chosen_item.owner.send_to_back()
                    return

                chosen_item = inventory_menu(
                    'Press the key next to an item to drop it, or any other to cancel.\n'
                )
                if chosen_item is not None:
                    chosen_item.drop()
                    return

            if key_char == '<':
                #go up if standing on the portal
                if defn.stairs.x == defn.player.x and defn.stairs.y == defn.player.y:
                    dgen.next_level()
                    defn.autoplaying = None
                #head toward portal and then blank input key in preparation for override.
                defn.autoplaying = 'autoascend'
                defn.key.vk = libtcod.KEY_NONE

            if key_char == 'o':
                #initialize autoexplore and then blank input key in preparation for override.
                defn.autoplaying = 'autoexplore'
                defn.key.vk = libtcod.KEY_NONE

            if key_char == 'c':
                #show character information
                #first, compute traits
                traits_inc = []
                appended_traits = []
                for trait in defn.player.traits:
                    if trait[0] not in appended_traits:
                        if len(trait) == 2:
                            if trait[0][-1:] == '+':  #sum them
                                trait_inc = [
                                    trait[0],
                                    data.sum_values_from_list(
                                        defn.player.traits, trait[0])
                                ]
                            else:  #find max
                                trait_inc = [
                                    trait[0],
                                    data.max_value_from_list(
                                        defn.player.traits, trait[0])
                                ]
                            traits_inc.append(trait_inc)
                            appended_traits.append(trait_inc[0])
                        else:
                            traits_inc.append(trait)
                            appended_traits.append(trait)
                traits = ''

                for trait in traits_inc:
                    if len(trait) == 1:
                        traits += '\n   ' + trait[0].capitalize()
                    else:
                        traits += '\n   ' + trait[0].capitalize() + str(
                            trait[1])

                #next, compute conditions

                conditions_inc = []
                appended_conditions = []
                for condition in defn.player.creature.conditions:
                    if condition not in appended_conditions:
                        conditions_inc.append([
                            condition,
                            data.count_instances_in_list(
                                defn.player.creature.conditions, condition)
                        ])
                        appended_conditions.append(condition)

                conditions = ''

                for condition in conditions_inc:
                    conditions += '\n   ' + condition[0].capitalize(
                    ) + ' (' + str(condition[1]) + ')'

                level_up_xp = defn.LEVEL_UP_BASE + defn.player.properties[
                    'level'] * defn.LEVEL_UP_FACTOR
                gui.msgbox(
                    'Character Information\n\nLevel: ' +
                    str(defn.player.properties['level']) + '\nExperience: ' +
                    str(defn.player.creature.xp) +
                    '\nExperience to level up: ' + str(level_up_xp) +
                    '\n\nLife: ' + str(defn.player.creature.max_hp) +
                    '\nMana Capacity: ' + str(defn.player.creature.max_mana) +
                    '\n\nAttack: ' +
                    str(defn.player.creature.active_attack.name.capitalize()) +
                    '\n\nTraits:' + traits + '\n\nConditions' + conditions,
                    defn.CHARACTER_SCREEN_WIDTH)

            if key_char == 'x':
                #first, select a target object
                target = None
                gui.message(
                    'Click on the object you would like to know more about, or right click to cancel.',
                    libtcod.white)
                rangemap = defn.fov_map
                while True:
                    #render the screen. this erases the inventory and shows the names of objects under the mouse.
                    libtcod.console_flush()
                    libtcod.sys_check_for_event(
                        libtcod.EVENT_KEY_PRESS | libtcod.EVENT_MOUSE,
                        defn.key, defn.mouse)
                    game.render_all()

                    (x, y) = (defn.mouse.cx, defn.mouse.cy)

                    if defn.mouse.lbutton_pressed and libtcod.map_is_in_fov(
                            defn.fov_map, x, y):
                        for j in range(defn.MAP_HEIGHT):
                            for i in range(defn.MAP_WIDTH):
                                if libtcod.map_is_in_fov(rangemap, i, j):
                                    libtcod.console_set_char_background(
                                        defn.con, i, j,
                                        defn.dungeon[i][j].color,
                                        libtcod.BKGND_SET)
                        break

                    if defn.mouse.rbutton_pressed or defn.key.vk == libtcod.KEY_ESCAPE:
                        for j in range(defn.MAP_HEIGHT):
                            for i in range(defn.MAP_WIDTH):
                                if libtcod.map_is_in_fov(rangemap, i, j):
                                    libtcod.console_set_char_background(
                                        defn.con, i, j,
                                        defn.dungeon[i][j].color,
                                        libtcod.BKGND_SET)
                        break
                if x != None:
                    for obj in defn.dungeon[x][y].objects:
                        target = obj
                        #describe the target more fully if it is a creature
                        if target.creature:
                            traits_inc = []
                            appended_traits = []
                            for trait in target.traits:
                                if trait[0] not in appended_traits:
                                    if len(trait) == 2:
                                        if trait[0][-1:] == '+':  #sum them
                                            trait_inc = [
                                                trait[0],
                                                data.sum_values_from_list(
                                                    target.traits, trait[0])
                                            ]
                                        else:  #find max
                                            trait_inc = [
                                                trait[0],
                                                data.max_value_from_list(
                                                    target.traits, trait[0])
                                            ]
                                        traits_inc.append(trait_inc)
                                        appended_traits.append(trait_inc[0])
                                    else:
                                        traits_inc.append(trait)
                                        appended_traits.append(trait)
                            traits = ''

                            for trait in traits_inc:
                                if len(trait) == 1:
                                    traits += '\n   ' + trait[0].capitalize()
                                else:
                                    traits += '\n   ' + trait[0].capitalize(
                                    ) + str(trait[1])

                            #next, compute conditions

                            conditions_inc = []
                            appended_conditions = []
                            for condition in target.creature.conditions:
                                if condition not in appended_conditions:
                                    conditions_inc.append([
                                        condition,
                                        data.count_instances_in_list(
                                            target.creature.conditions,
                                            condition)
                                    ])
                                    appended_conditions.append(condition)

                            conditions = ''

                            for condition in conditions_inc:
                                conditions += '\n   ' + condition[
                                    0].capitalize() + ' (' + str(
                                        condition[1]) + ')'

                            title = target.title.capitalize()
                            if target.title == target.name:
                                title = title + ', ' + target.properties['name']
                            #now describe the creature
                            gui.msgbox(
                                title + '\n\nLevel: ' +
                                str(target.properties['level']) +
                                '\n\nAttack: ' +
                                str(target.creature.active_attack.name.
                                    capitalize()) + '\n\nTraits:' + traits +
                                '\n\nConditions:' + conditions + '\n\n' +
                                target.properties['description'],
                                defn.CHARACTER_SCREEN_WIDTH)

                        else:
                            target.describe()
                        break

                        #later, can add menu in case of multiple objects
            if key_char == 's':
                #summon an ally
                creature = summoning_menu(
                    'Press the key next to a creature to select it, or any other to cancel.\n'
                )
                if creature != None:
                    gui.message(
                        'Left-click on an open tile to summon creature there, or right-click to cancel.',
                        libtcod.light_cyan)
                    x0, x1 = spfn.target_tile(3)
                    if mpop.place_object(creature, [x0, x1]) != 'failed':
                        defn.player.creatures.remove(creature)
                    else:
                        gui.message('There\'s something in the way...',
                                    libtcod.light_cyan)

            #if key_char == 'w':
            #defn.player.creature.heal(30)
            #dgen.next_level()
            #defn.inventory.append(idic.get_item('scroll of animate dead',0,0))
            #defn.inventory.append(idic.get_item('scroll of heal',0,0))
            #defn.inventory.append(idic.get_item('scroll of minor heal',0,0))

            return 'didnt-take-turn'
예제 #18
0
	vbox.pack_start(label1)
	vbox.pack_start(hbox)
	vbox.pack_start(hbox2)

	dialog.add_button("Cancel", 0)
	dialog.add_button("OK", 1)

	dialog.show_all()
	return dialog

verts = objects.selected_vertices()
dialog = build_gui()

if verts == None:
	gui.message(gui.MESSAGE_ERROR, "Hey you bummer! Please select some vertices!")
elif dialog.run() == 1:
	max = 0
	min = 100

	for vert in verts:
		vert.temp = True
		pos = vert.position()
		if pos[1] < min:
			min = pos[1]
		if pos[1] > max:
			max = pos[1]
		vert.set_frame(start_frame)

	avg = max + min
	avg = avg / 2
예제 #19
0
    def resolve_attack_roll(self, dice, d12_bonus, source, target):

        #manage defenses
        avoided = False
        def_effect = None
        #still need to implement unavoidable attacks

        if target.creature.defenses:
            defense_choices = []
            for defense in target.creature.defenses:
                if defense and defense.uses > 0 and (
                        defense.range == self.range['type']
                        or defense.range == 'any'):
                    defense_choices.append(defense)
            if defense_choices:
                defense = random.choice(defense_choices)
                #for now, no bonuses. Adding defense bonuses later should be easy.
                def_bonus = data.sum_values_from_list(source.traits,
                                                      'defense +')
                #daze reduction in defense roll
                for condition in target.creature.conditions:
                    if condition == 'daze':
                        def_bonus -= 2
                if defense.use(def_bonus):
                    gui.message(
                        target.title.capitalize() + ' avoids ' + source.title +
                        '\'s attack!', libtcod.red)
                    avoided = True
                    if defense.effect:
                        def_effect = defense.effect

        #mage wars attack formula
        if not avoided:
            normal_damage = 0
            critical_damage = 0

            dice_to_roll = dice

            #subtract dice if weak. Later can also add aegis here.
            if source.creature:
                for condition in source.creature.conditions:
                    if condition == 'weak' and 'magical' not in self.traits:
                        dice_to_roll -= 1

            if not ['no damage'] in self.traits:
                for i in range(max(dice_to_roll, 1)):
                    roll = libtcod.random_get_int(0, 0, 2)
                    crit = roll * libtcod.random_get_int(0, 0, 1)
                    if ['incorporeal'
                        ] in target.traits and not ['ethereal'] in self.traits:
                        #unlike the game, this formula is the simplest way to implement this:
                        normal_damage += max(roll - crit - 1, 0)
                        critical_damage += max(crit - 1, 0)
                    else:
                        normal_damage += roll - crit
                        critical_damage += crit

            armor = max(
                target.creature.armor -
                data.sum_values_from_list(self.traits, 'piercing +'), 0)

            #sturdy (vet's belt effect)
            for trait in target.traits:
                if trait[0] == 'sturdy +':
                    if critical_damage >= trait[1]:
                        normal_damage += trait[1]
                        critical_damage -= trait[1]
                    else:
                        normal_damage += critical_damage
                        critical_damage = 0

            if ['resilient'] in target.traits:
                damage = critical_damage
            else:
                damage = max(normal_damage - armor, 0) + critical_damage

            if damage > 0:
                if not self.is_counterstrike:
                    gui.message(
                        source.title.capitalize() + ' attacks ' +
                        target.title + ' with ' + self.name + '! ' +
                        str(damage) + ' damage!', libtcod.red)
                else:
                    gui.message(
                        source.title.capitalize() + ' retaliates with ' +
                        self.name + '! ' + str(damage) + ' damage!',
                        libtcod.orange)
                target.creature.take_damage(damage)
            else:
                if not self.is_counterstrike:
                    gui.message(
                        source.title.capitalize() + ' attacks ' +
                        target.title + ' with ' + self.name + '. No damage!',
                        libtcod.red)
                else:
                    gui.message(
                        source.title.capitalize() +
                        ' retaliates but fails to inflict any damage.',
                        libtcod.orange)

            roll = libtcod.random_get_int(0, 1, 12)

            #rolling for effects
            effects = None
            if self.effects:
                for effect in self.effects:
                    if roll >= effect[1]:
                        effects = effect[0]

            #implement effects
            if effects and target.creature:
                #for now, don't worry about poison immunity.
                for effect in effects:
                    #poison immunity
                    if effect in ['rot', 'weak', 'cripple', 'tainted'
                                  ] and ['poison immunity'] in target.traits:
                        gui.message(target.title + ' resists the poison!',
                                    libtcod.purple)
                        break
                    #long term should probably define a class of conditions or something so I don't have to maintain a list of what constitutes a condition.
                    if effect in ['rot', 'weak', 'burn', 'cripple']:
                        gui.message(
                            source.title.capitalize() + ' inflicts ' + effect +
                            ' on ' + target.title + '!', libtcod.purple)
                        target.creature.conditions.append(effect)
                    if effect == 'tainted':
                        gui.message(
                            source.title.capitalize() + 's\' attack taints ' +
                            target.title + '!', libtcod.purple)
                        target.creature.conditions.append('tainted')
                        target.creature.take_damage(3)
                    if effect == 'daze':
                        gui.message(target.title + ' is dazed!',
                                    libtcod.purple)
                        target.creature.conditions.append('daze')
                    if effect == 'stun':
                        gui.message(target.title + ' is stunned!',
                                    libtcod.purple)
                        target.creature.conditions.append('stun')

            #resolve counterstrikes. currently just takes the first counterstriking attack it finds.
            #note that counterstrikes currently use up time
            #something odd going on here; sometimes target.creature has no attack attribute.
            #problem occurs when creature is transformed into remains.
            #check if target still exists as a creature, e.g. has not been killed or so forth with 'if target.creature'
            #long run find a better way to fix this problem

        if target.creature:
            if target.creature.attacks and self.range[
                    'type'] == 'melee' and not self.is_counterstrike:
                for attack in target.creature.attacks:
                    #currently returns the first counterattack it finds. special case for shield bash, rather than giving defenses effects
                    if ([
                            'counterstrike'
                    ] in attack.traits) or (attack.name == 'shield bash'
                                            and def_effect == 'shield bash'):
                        attack.is_counterstrike = True
                        target.creature.attack(source, attack)
                        attack.is_counterstrike = False
                        break