0

I'm surprised this isn't crashing, but I'm really not sure what's happened here. On mouse over + key press 'd' should bring up menu of objects under mouse (which it does). When selecting an object it should print a message to console from that objects description. It doesn't though, it prints something like <__main__.Object instance at 0x02AE1800>.

Here is the relevant code

def menu(header, options, width):
    if len(options) > 26: raise ValueError('Cannot have a menu with more than 26 options.'

    #calculate the total height for the header (afer auto wrap) and one line per option
    header_height = libtcod.console_get_height_rect(con, 0, 0, width, SCREEN_HEIGHT, header)
    height = len(options) + header_height

    #create an off-screen console that represents the menu's window
    window = libtcod.console_new(width, height)

    #print the header, with auto wrap, baby.
    libtcod.console_set_default_foreground(window, libtcod.white)
    libtcod.console_print_rect_ex(window, 0, 0, width, height, libtcod.BKGND_NONE, libtcod.LEFT, header)

    #print all the options
    y = header_height
    letter_index = ord('a')
    for option_text in options:
        text = '(' + chr(letter_index) + ') ' + option_text
        libtcod.console_print_ex(window, 0, y, libtcod.BKGND_NONE, libtcod.LEFT, text)
        y += 1
        letter_index += 1

    #blit the contents of "window" to the root console
    x = SCREEN_WIDTH/2 - width/2
    y = SCREEN_HEIGHT   /2 - height/2
    libtcod.console_blit(window, 0, 0, width, height, 0, x, y, 1.0, 0.7)

    #present the root console to the player and wait for keypress
    libtcod.console_flush()
    key = libtcod.console_wait_for_keypress(True)

    #convert the ASCII code to an index; if it corresponds to an option, return it
    index = key.c - ord('a')
    if index >= 0 and index < len(options): return index
    return None

def handle_keys():
    global keys;

            if key_char == 'd':
                #show the description menu, if an item is selected, describe it.
                chosen_object = description_menu('Press the key next to an object to see its description.\n')
                if chosen_object is not None:
                    chosen_object.describe()
                else:
                    return 'cancelled'

            return 'didnt-take-turn'

def description_menu(header): 

    global mouse

    #return a string with the names of all objects under the mouse
    (x, y) = (mouse.cx, mouse.cy)

    #create a list with the names of all objects at the mouse's coordinates and in FOV
    names = [obj for obj in objects if obj.x == x and obj.y == y and libtcod.map_is_in_fov(fov_map, obj.x, obj.y) and obj.description is not None]

    #show a menu with each object under the mouse as an option
    if len(names) == 0:
        options = ['There is nothing here.']
    else:
        options = [object.name for object in names]

    index = menu(header, options, INVENTORY_WIDTH)

    #if an item was chosen, return it
    if index is None or len(names) == 0: return None
    return names[index]

Class Object:
    #this is a generic object: the player, a monster, an item, the stairs...
    #it's always represented by a character on screen.
    def __init__(self, x, y, char, name, color, blocks=False, fighter=None, ai=None, item=None, description=None):
        self.x = x
        self.y = y
        self.char = char
        self.name = name
        self.color = color
        self.blocks = blocks
        self.fighter = fighter
        if self.fighter: #let the fighter component know who owns it
            self.fighter.owner = self
        self.ai = ai
        if self.ai: #let the ai component know who owns it
            self.ai.owner = self
        self.item = item
        if self.item: #let the item component know who owns it, like a bitch
            self.item.owner = self
        self.description = self
        if self.description: #let the description component know who owns it
            self.description.owner = self

    def describe(self):
        #describe this object
        if self.description is None:
            message('The ' + self.owner.name + ' cannot be described.')
        else:
            message(str(self.description), libtcod.white)`
B-mo
  • 49
  • 1
  • 9
  • what's the definition of `message`? You call it in `describe()`. If you cut this down even more so we could reproduce it, it'd help. – TankorSmash Sep 03 '14 at 21:06

1 Answers1

1

My guess would be that you are passing a string representation of the Object instance to message when you really want to be passing a string that carries some easy-to-understand information. The str method calls Object.__str__ (one of python's magic methods) Object.__str__ has not been defined in your code, so str defaults to calling Object.__repr__ which is where you are getting the <__main__.Object instance at 0x02AE1800>.

Try defining Object.__str__ so that it returns a string holding the information you would want it to display when print-ing it.

For example:

Class Object:
    def __init__(self, name, x, y):
        self.name = name
        self.x = x
        self.y = y

    def __str__(self):
        return("Object " + self.name + " is at position [" + self.x + "," + self.y + "]")

In the end, I can't say for sure what the problem is because we don't have the definition of the message method. you should include the code for that method so that we can better understand what is going on. Good luck!

Humdilla
  • 36
  • 2