def update(this, delta_time): "Checks if player is pulling it and if they're at the correct side of it." if display.keyDown(ord('E')) and (this.attributes["can_pull"]): # If they pulled the lever... if (world.player.X == this.X - 1) and (world.player.Y == this.Y) and (this.attributes["mode"] != this.MODE_LEFT): # They're to the left, not already max left this.attributes["can_pull"] = False this.attributes["mode"] -= 1 if this.attributes["mode"] == 0: # It was pulled to the left this.attributes["on_left"](this) # Call on_left with this as a parameter. else: # It was pulled to the mid if this.attributes["on_mid"] is None: this.attributes["mode"] -= 1 this.attributes["on_left"](this) else: this.attributes["on_mid"](this) if (world.player.X == this.X + 1) and (world.player.Y == this.Y) and (this.attributes["mode"] != this.MODE_RIGHT): # They're to the right, not already max right. this.attributes["can_pull"] = False this.attributes["mode"] += 1 if this.attributes["mode"] == 2: this.attributes["on_right"](this) # It was pulled to the right else: if this.attributes["on_mid"] is None: this.attributes["mode"] += 1 this.attributes["on_right"](this) else: this.attributes["on_mid"](this) # It was pulled to the mid. if not display.keyDown(ord('E')): this.attributes["can_pull"] = True if (world.player.X == this.X - 1 or world.player.X == this.X + 1) and world.player.Y == this.Y and display.sidebar_line < 29: display.printc(50, display.sidebar_line, "Press E to pull lever") display.sidebar_line += 1
def tick(this, delta_time): this.time -= delta_time if this.owner.type == "player" and this.name is not None and display.sidebar_line < 15: # Only show the first few effects. time_left = "Inf" if this.time < float("inf"): time_left = str(int(this.time/1000)) display.printc(51, display.sidebar_line, this.name + '(' + time_left + ')') display.sidebar_line += 1
def tick(this, delta_time): this.time -= delta_time if this.owner.type == "player" and this.name is not None and display.sidebar_line < 15: # Only show the first few effects. time_left = "Inf" if this.time < float("inf"): time_left = str(int(this.time / 1000)) display.printc(51, display.sidebar_line, this.name + '(' + time_left + ')') display.sidebar_line += 1
def save(name): try: with open("res/maps/" + name + ".wrld", "wb") as handle: pickle.dump(map, handle) pickle.dump(objects, handle) except Exception as ex: display.printc(20, 10, "Could not save. Press ESC to continue.") display.refresh() while not display.keyDown(display.CONST.VK_ESCAPE): pass
def save_player(): try: with open("res/saves/" + save_name + ".plr", "wb") as handle: pickle.dump(player, handle) pickle.dump(world_name, handle) display.flash() except Exception as ex: display.printc(20, 10, "Could not save. Press ESC to continue.") display.refresh() while not display.keyDown(display.CONST.VK_ESCAPE): pass
def redraw(this): # Redraws menu # Clear right pane this.clear() printc(50, 5, this._text) # Redraw description # Redraw current options. linecount = 0 for elem in this._pages[this._page]: display.printc(51, linecount + this._opt_start, elem) linecount += elem.count('\n') + 1
def redraw(this): # Redraws menu # Clear right pane this.clear() printc(50, 5, this._text) # Redraw description # Redraw current options. linecount = 0 for elem in this._pages[this._page]: display.printc(51, linecount + this._opt_start, elem) linecount += elem.count('\n') + 1
def __init__(this, text, *opt_list): """Starts a menu. Arguments: text: A string containing the introduction text to the menu *opt_list: A list of strings as options to display. Begins by displaying the text and initializing for future updatethis.() calls. """ this._cursor = 0 # Where cursor is currently this._pages = [[]] # All pages of options. this._opt_start = 0 # Top place cursor/options can go. this._page = 0 # What page we're on this._opt = 0 # What option we're on. this._page_opt = 0 # Where we are on the page. this._can_up = True # They can go up this._can_down = True # They can go down this._end_val = -1 # Not finished yet this._text = text if text.count('\n') > 10: # Count lines of text raise BaseException( "Menu Error: Too long of basic description. Be more concise.") this.clear() # Clear so that menu is drawn nicely printc(50, 5, text) this._opt_start = 7 + text.count( '\n' ) # What line we're printing on for options. 5 (start) + 1 (description) + extra description lines # + 1 (blank space after description) # Turn strings in opt_list to options PAGE_SIZE = 26 - this._opt_start # Max lines in a page pages = [[]] # List of pages, contains list of options. linecount = 0 # How many lines all our options take up so far. for opt in opt_list: if linecount + opt.count( '\n') + 1 >= PAGE_SIZE: # If overflow of page pages.append([]) # New page linecount = 0 # Haven't used any of it. pages[-1].append(opt) # Add option if len(pages) == 1: # Only print first page display.printc(51, linecount + this._opt_start, opt) linecount += opt.count('\n') + 1 this._pages = pages this._cursor = this._opt_start
def __init__(this, text, *opt_list): """Starts a menu. Arguments: text: A string containing the introduction text to the menu *opt_list: A list of strings as options to display. Begins by displaying the text and initializing for future updatethis.() calls. """ this._cursor = 0 # Where cursor is currently this._pages = [[]] # All pages of options. this._opt_start = 0 # Top place cursor/options can go. this._page = 0 # What page we're on this._opt = 0 # What option we're on. this._page_opt = 0 # Where we are on the page. this._can_up = True # They can go up this._can_down = True # They can go down this._end_val = -1 # Not finished yet this._text = text if text.count('\n') > 10: # Count lines of text raise BaseException("Menu Error: Too long of basic description. Be more concise.") this.clear() # Clear so that menu is drawn nicely printc(50, 5, text) this._opt_start = 7 + text.count('\n') # What line we're printing on for options. 5 (start) + 1 (description) + extra description lines # + 1 (blank space after description) # Turn strings in opt_list to options PAGE_SIZE = 26 - this._opt_start # Max lines in a page pages = [[]] # List of pages, contains list of options. linecount = 0 # How many lines all our options take up so far. for opt in opt_list: if linecount + opt.count('\n') + 1 >= PAGE_SIZE: # If overflow of page pages.append([]) # New page linecount = 0 # Haven't used any of it. pages[-1].append(opt) # Add option if len(pages) == 1: # Only print first page display.printc(51, linecount + this._opt_start, opt) linecount += opt.count('\n') + 1 this._pages = pages this._cursor = this._opt_start
def update(this, delta_time): if world.player.X == this.X and world.player.Y == this.Y: # Colliding with player. # Update menu if this.attributes["open"]: if display.current_menu.update( ) is not None: # They chose something if this.attributes["contents"] == []: # Nothing in chest return # So add to their stock or create new one. if this.attributes["contents"][display.current_menu.update( )] in world.player.attributes["items"]: # Get their item location world.player.attributes["items"][world.player.attributes["items"].index(this.attributes["contents"][display.current_menu.update()])].amount \ += this.attributes["contents"][display.current_menu.update()].amount # And add how many were in the chest. else: # Give them the item world.player.attributes["items"].append( this.attributes["contents"][ display.current_menu.update()] ) # Giving the player the chest's items. # Remove from chest this.attributes["contents"].remove( this.attributes["contents"][ display.current_menu.update()]) this.attributes["open"] = False # Close chest display.current_menu = None else: if display.current_menu is None: # We can actually make it option_list = [] for item in this.attributes["contents"]: option_list.append(item.name) if option_list != []: display.current_menu = display.menu( "A Chest!", *option_list) this.attributes["open"] = True elif display.sidebar_line < 24: display.printc(50, display.sidebar_line, "An empty chest.") display.sidebar_line += 1 elif this.attributes["open"]: # Not colliding but opened. display.current_menu.clear() # Clear right pane display.current_menu = None # Remove menu this.attributes["open"] = False
def tick(self, delta_time): # First, find closest enemy closest_enemy = None closest_dist_sq = float("inf") for other in world.objects: if other.type == "enemy": # If they're an enemy... dist_sq = (obj.X - other.X)**2 + (obj.Y - other.Y)**2 # Find distance if dist_sq < closest_dist_sq: # If this one is closer closest_enemy = other # Now it's the one we check with closest_dist_sq = dist_sq # Now re-print enemy HP. So HP + spaces equal to extra space if (closest_enemy is not None) and ("EXP" in closest_enemy.attributes): exp_str = "EXP:" + str(int(closest_enemy.attributes["EXP"])) spaces_str = ' ' * (34 - len(exp_str)) str_to_print = exp_str + spaces_str else: str_to_print = "No enemies nearby " display.printc(display.HAT_X, display.HAT_Y, str_to_print)
def tick(self, delta_time): # First, find closest enemy closest_enemy = None closest_dist_sq = float("inf") for other in world.objects: if other.type == "enemy": # If they're an enemy... dist_sq = (obj.X - other.X)**2 + (obj.Y - other.Y)**2 # Find distance if dist_sq < closest_dist_sq: # If this one is closer closest_enemy = other # Now it's the one we check with closest_dist_sq = dist_sq # Now re-print enemy HP. So HP + spaces equal to extra space if (closest_enemy is not None) and ("EXP" in closest_enemy.attributes): exp_str = "EXP:" + str(int(closest_enemy.attributes["EXP"])) spaces_str = ' ' * (34 - len(exp_str)) str_to_print = exp_str + spaces_str else: str_to_print = "No enemies nearby " display.printc(display.HAT_X, display.HAT_Y, str_to_print)
def draw(this): display.printc(display.SPELL_BOX_START + 1, 1, this.image[0], this.sp_color) display.printc(display.SPELL_BOX_START + 1, 2, this.image[1], this.sp_color) display.printc(display.SPELL_BOX_START + 1, 3, this.image[2], this.sp_color)
def update(this, delta_time): if world.player.X == this.X and world.player.Y == this.Y: # Colliding with player. # Update menu if this.attributes["open"]: if display.current_menu.update() is not None: # They chose something if this.attributes["contents"] == []: # Nothing in chest return # So add to their stock or create new one. if this.attributes["contents"][display.current_menu.update()] in world.player.attributes["items"]: # Get their item location world.player.attributes["items"][world.player.attributes["items"].index(this.attributes["contents"][display.current_menu.update()])].amount \ += this.attributes["contents"][display.current_menu.update()].amount # And add how many were in the chest. else: # Give them the item world.player.attributes["items"].append(this.attributes["contents"][display.current_menu.update()]) # Giving the player the chest's items. # Remove from chest this.attributes["contents"].remove(this.attributes["contents"][display.current_menu.update()]) this.attributes["open"] = False # Close chest display.current_menu = None else: if display.current_menu is None: # We can actually make it option_list = [] for item in this.attributes["contents"]: option_list.append(item.name) if option_list != []: display.current_menu = display.menu("A Chest!", *option_list) this.attributes["open"] = True elif display.sidebar_line < 24: display.printc(50, display.sidebar_line, "An empty chest.") display.sidebar_line += 1 elif this.attributes["open"]: # Not colliding but opened. display.current_menu.clear() # Clear right pane display.current_menu = None # Remove menu this.attributes["open"] = False
def draw(this): display.printc(display.SPELL_BOX_START + 1, 1, this.image[0], this.sp_color) display.printc(display.SPELL_BOX_START + 1, 2, this.image[1], this.sp_color) display.printc(display.SPELL_BOX_START + 1, 3, this.image[2], this.sp_color)
def new_game(): # Get their save name display.clear() display.flushinp() inpt = display.getch() curs_loc = 0 file_name = "" display.printc(30, 9, "Enter your name:") while inpt != 10: # Until ENTER pressed if inpt == 8: # Backspace if curs_loc != 0: curs_loc -= 1 file_name = file_name[:-1] # Remove last character display.printc(curs_loc + 30, 10, ' ') elif (inpt != -1) and (curs_loc < 45) and (chr(inpt) in "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-1234567890 "): # Also don't let them get too long. 45 chosen arbitrarily because yeah. display.printc(curs_loc + 30, 10, chr(inpt)) file_name += chr(inpt) curs_loc += 1 display.refresh() inpt = display.getch() # Wait for release while display.keyDown(display.CONST.VK_RETURN): pass if file_name == len(file_name) * ' ': file_name = "default" world.save_name = file_name # Class select! # What color each class should be color_list = [display.RED, display.BLUE, display.YELLOW] # What the middle text is for each class text_list = ["+ Warrior +", "+ Mage +", "+ Thief +"] # The box of '+'s top and bottom box = '+' * 14 # Number of rows each box takes up. 3 for the box + 2 for the space below box_size = 5 # Where the boxes start display on y-axis box_start = 4 # Left side of boxes box_left = 32 # Clear screen and set up menu. display.clear() for i in range(len(text_list)): display.printc(box_left, box_start + i * box_size, box) display.printc(box_left, box_start + i * box_size + 1, text_list[i]) display.printc(box_left, box_start + i * box_size + 2, box) # Draw first box in color display.printc(box_left, box_start, box, color_list[0]) display.printc(box_left, box_start + 1, text_list[0], color_list[0]) display.printc(box_left, box_start + 2, box, color_list[0]) choice = 0; display.refresh() while True: # Check for choice down/up if display.keyDown(ord('Q')) or display.keyDown(display.CONST.VK_UP): # Redraw current box in white display.printc(box_left, box_start + choice * box_size, box) display.printc(box_left, box_start + choice * box_size + 1, text_list[choice]) display.printc(box_left, box_start + choice * box_size + 2, box) # If decrementing choice would bring it below zero, set it to one past last if choice == 0: choice = len(text_list) # And decrement it. choice -= 1 # Redraw new box in correct color. display.printc(box_left, box_start + choice * box_size, box, color_list[choice]) display.printc(box_left, box_start + choice * box_size + 1, text_list[choice], color_list[choice]) display.printc(box_left, box_start + choice * box_size + 2, box, color_list[choice]) # Refresh display display.refresh() # Wait for release while display.keyDown(ord('Q')) or display.keyDown(display.CONST.VK_UP): pass if display.keyDown(ord('E')) or display.keyDown(display.CONST.VK_DOWN): # Redraw current box in white display.printc(box_left, box_start + choice * box_size, box) display.printc(box_left, box_start + choice * box_size + 1, text_list[choice]) display.printc(box_left, box_start + choice * box_size + 2, box) # Go down choice += 1 # Wrap options if choice == len(text_list): choice = 0 # Redraw new box in correct color. display.printc(box_left, box_start + choice * box_size, box, color_list[choice]) display.printc(box_left, box_start + choice * box_size + 1, text_list[choice], color_list[choice]) display.printc(box_left, box_start + choice * box_size + 2, box, color_list[choice]) # Refresh display display.refresh() # Wait for release while display.keyDown(ord('E')) or display.keyDown(display.CONST.VK_DOWN): pass # Check if they chose an option if display.keyDown(display.CONST.VK_RETURN): # Basic player. Choice will modify it's attributes. world.player = player.player(world.WORLD_X // 2, world.WORLD_Y - 3) hat = start_eq.start_hat() shirt = start_eq.start_shirt() pants = start_eq.start_pants() weapon = start_eq.start_weapon() ring = start_eq.start_ring() sp = spell.spell(heal.manaCost, heal.heal, heal.name, heal.icon, heal.color) pclass = "" if not choice: # Choice was 0, so warrior pclass = "warrior" if choice == 1: # Choice was Mage pclass = "mage" if choice == 2: # Choice was Thief pclass = "thief" world.player.attributes["class"] = pclass world.player.attributes["items"] = [hat, shirt, pants, ring, weapon, sp] # Give them their equips world.player.attributes["hat"] = hat hat.equip(world.player) world.player.attributes["shirt"] = shirt shirt.equip( world.player) world.player.attributes["pants"] = pants pants.equip(world.player) world.player.attributes["ring"] = ring ring.equip(world.player) world.player.attributes["weapon"] = weapon weapon.equip(world.player) world.player.attributes["spell"] = sp # Load starting world world.load("tutorial.start") world.objects = [world.player] + world.objects return
def start(): """Gives the main menu option to load a file, create a new file, or exit""" display.printc(28, 10, "Welcome to pyRPG!") display.printc(30, 11, ">Load a file") display.printc(31, 12, "New game") display.printc(31, 13, "Multiplayer") display.printc(31, 14, "Exit game") display.printc(28, 15, "Press H for help") display.refresh() opt = 0 while True: # Move cursor up if w or up key pressed if display.keyDown(ord('Q')) or display.keyDown(display.CONST.VK_UP): # Clear old cursor display.printc(30, opt + 11, ' ') opt -= 1 if opt < 0: opt = 3 # Redraw for good menu display.printc(30, opt + 11, '>') display.refresh() # Wait for release while display.keyDown(ord('Q')) or display.keyDown(display.CONST.VK_UP): pass # Move cursor down if s or down key pressed if display.keyDown(ord('E')) or display.keyDown(display.CONST.VK_DOWN): # Clear old cursor display.printc(30, opt + 11, ' ') opt += 1 if opt > 3: opt = 0 # Redraw for good menu display.printc(30, opt + 11, '>') display.refresh() # Wait for release while display.keyDown(ord('E')) or display.keyDown(display.CONST.VK_DOWN): pass # If they have e or enter pressed, they chose an option. if display.keyDown(display.CONST.VK_RETURN): # Wait for key release while display.keyDown(display.CONST.VK_RETURN): pass if opt == 0: load_game() display.clear() return if opt == 1: new_game() world.player.attributes["HP"] = world.player.attributes["maxHP"] world.player.attributes["MP"] = world.player.attributes["maxMP"] world.save_player() display.clear() return if opt == 2: multiplayer.multiplayer() display.clear() display.printc(28, 10, "Welcome to pyRPG!") display.printc(31, 11, "Load a file") display.printc(31, 12, "New game") display.printc(30, 13, ">Multiplayer") display.printc(31, 14, "Exit game") display.printc(28, 15, "Press H for help") display.refresh() if opt == 3: display.end() # They chose exit # They need help! if display.keyDown(ord('H')): help_menu() display.clear() display.printc(28, 10, "Welcome to pyRPG!") display.printc(31, 11, "Load a file") display.printc(31, 12, "New game") display.printc(31, 13, "Multiplayer") display.printc(31, 14, "Exit game") display.printc(28, 15, "Press H for help") display.printc(30, opt + 11, '>') display.refresh()
def help_menu(): display.clear() display.printc(0, 0, "pyRPG is a real-time terminal based RPG") display.printc(0, 4, "In a menu, use either the UP ARROW key or the Q key to move your cursor up") display.printc(0, 5, "Use either the DOWN ARROW key or the E key to move your cursor down") display.printc(0, 6, "Use ENTER to select the current option") display.printc(0, 9, "Character controls:") display.printc(0, 10, "Use WASD to move and IJKL to attack directionally") display.printc(0, 11, "Press SPACE to cast your current spell, set in the Spell menu") display.printc(0, 12, "Press LEFT SHIFT to use your item, set in the Consumable menu of your inventory") display.printc(0, 13, "Press ESC to open the main menu to save, access inventory, set spell, or exit") display.printc(0, 15, "Press ENTER to go to page two or press ESC to exit to the main menu") display.refresh() while (not display.keyDown(display.CONST.VK_ESCAPE)) and (not display.keyDown(display.CONST.VK_RETURN)): pass # Wait for press of ESC or ENTER if display.keyDown(display.CONST.VK_ESCAPE): while display.keyDown(display.CONST.VK_ESCAPE): pass # Wait for release return while display.keyDown(display.CONST.VK_RETURN): pass # Wait for release # Now give page 2 of the menu. display.clear() display.printc(0, 0, "Colors and symbols guide:") display.printc(0, 2, "Colors:") display.printc(0, 3, "Red", display.RED) display.printc(4, 3, "is either a locked portal ( ) or an obstacle. Often, objects hurt.") display.printc(31, 3, "O", display.RED) display.printc(57, 3, "red", display.RED) display.printc(0, 4, "White objects tend to be neutral. Walls (#) and floors (.) tend to be white.") display.printc(0, 5, "Blue", display.BLUE) display.printc(5, 5, "objects are often portals ( ). Also, player attacks ( ) are blue.") display.printc(32, 5, "O", display.BLUE) display.printc(58, 5, "!", display.BLUE) display.printc(0, 6, "Cyan", display.CYAN) display.printc(5, 6, "objects are enemies. All enemies are and all things are enemies.") display.printc(42, 6, "cyan", display.CYAN) display.printc(55, 6, "cyan", display.CYAN) display.printc(0, 7, "Green", display.GREEN) display.printc(6, 7, "objects are grass( ) and NPCs. Talk to things that are .") display.printc(24, 7, ';', display.GREEN) display.printc(61, 7, "green", display.GREEN) display.printc(0, 8, "Magenta", display.MAGENTA) display.printc(8, 8, "tends not to be used. Enemy attacks ( ) are .") display.printc(45, 8, "!", display.MAGENTA) display.printc(52, 8, "magenta", display.MAGENTA) display.printc(0, 9, "Yellow", display.YELLOW) display.printc(7, 9, "is loot! Money ( ) and chests ( ) are . things are good.") display.printc(23, 9, "$", display.YELLOW) display.printc(38, 9, "@", display.YELLOW) display.printc(45, 9, "yellow", display.YELLOW) display.printc(53, 9, "Yellow", display.YELLOW) display.printc(0, 11, "Common Symbols:") display.printc(0, 12, "@", display.YELLOW) display.printc(2, 12, "is a chest. Stand next to to see what it holds!") display.printc(0, 13, "# is a wall. Walls block movement of the player, attacks, and enemies.") display.printc(0, 14, ". is a common ground tile. It does nothing special.") display.printc(0, 15, "#", display.RED) display.printc(2, 15, "is lava. Stepping on it hurts!") display.printc(0, 16, ';', display.GREEN) display.printc(2, 16, "is a common ground tile. It does nothing special.") display.printc(0, 17, "| \\\\ /", display.YELLOW) display.printc(6, 17, "are levers. Stand next to it and press ENTER to pull it. What does it do?") display.printc(0, 20, "These are common trends and there are objects that break these trends.") display.printc(0, 21, "However, they hold true for most objects that you will encounter.") display.printc(0, 22, "Also, the rule about cyan objects ALWAYS holds.") display.printc(21, 22, "cyan", display.CYAN) display.printc(0, 24, "Press ENTER to continue...") display.refresh() while not display.keyDown(display.CONST.VK_RETURN): pass while display.keyDown(display.CONST.VK_RETURN): pass return
def load_game(): display.clear() # Get all save files saves = glob.glob("res/saves/*.plr") # Parse res/saves/FILE.plr to just FILE. Much better for display, don't want the res/ for pickling. saves = [file[10:-4] for file in saves] if len(saves) == 0: display.printc(30, 8, "No saves were found...") display.flushinp() while display.getch() == -1: pass display.end() # Break saves into pages. PAGE_SIZE = 25 pages = [[]] for opt in saves: # Add every object to the list. if len(pages[-1]) == PAGE_SIZE: # If list overflow, add a new page pages.append([]) # Add option to last element in pages. Also should edits it to give amount held too. pages[-1].append(opt) curr_page = 0 choice = 0 # Display first page for index in range(len(pages[curr_page])): display.printc(10, index, pages[curr_page][index]) # Print out the option display.printc(9, 0, '>') # Cursor display.refresh() can_up = True can_down = True while True: # Now loop and wait for a choice if (display.keyDown(ord('Q')) or display.keyDown(display.CONST.VK_UP)) and can_up: # Go up 1. display.printc(9, choice, ' ') # Remove old arrow if choice == 0: # Already at top of page. if curr_page == 0: curr_page = len(pages) - 1 # Go to last page else: # Go up a page curr_page -= 1 choice = len(pages[-1]) # Go to bottom of page display.clear() # Clear all the old stuff. for index in range(len(pages[curr_page])): # Draw the new page display.printc(10, index, pages[curr_page][index]) # Print out the option choice -= 1 # Go up 1. display.printc(9, choice, '>') # Redraw arrow display.refresh() # Refresh screen can_up = False if not (display.keyDown(ord('Q')) or display.keyDown(display.CONST.VK_UP)): can_up = True if (display.keyDown(ord('E')) or display.keyDown(display.CONST.VK_DOWN)) and can_down: # Go down 1. display.printc(9, choice, ' ') # Remove old arrow if choice == len(pages[curr_page]) - 1: # Already at bottom of page. if curr_page == len(pages) - 1: curr_page = 0 # Go to first page else: # Go down a page curr_page += 1 choice = -1 # Go to top of page display.clear() # Clear all the old stuff. for index in range(len(pages[curr_page])): # Draw the new page display.printc(10, index, pages[curr_page][index]) # Print out the option choice += 1 # Go down 1. if choice == len(pages[curr_page]): choice -= 1 # At bottom, can't go down display.printc(9, choice, '>') # Redraw arrow display.refresh() # Refresh screen can_down = False if not (display.keyDown(ord('E')) or display.keyDown(display.CONST.VK_DOWN)): can_down = True # TODO: Possibly let them easily skip through pages with AD and left/right arrow keys if display.keyDown(display.CONST.VK_RETURN): file = pages[curr_page][choice] world.load_player(file) return
from objects import Player #makemaps.make_from_file('maps/Multiplayer/start.txt', 'maps/Multiplayer/start.py') display.start() main_menu.start() # Title menu! # Needs world selection menu. Probably try for a scrolling menu with basic graphics if possible. # Print world out world.dispworld() display.draw_topbar() display.printc(display.WEAPON_X, display.WEAPON_Y, world.player.attributes["weapon"].name) display.printc(display.HAT_X, display.HAT_Y, world.player.attributes["hat"].name) display.printc(display.SHIRT_X, display.SHIRT_Y, world.player.attributes["shirt"].name) display.printc(display.PANTS_X, display.PANTS_Y, world.player.attributes["pants"].name) display.printc(display.RING_X, display.RING_Y, world.player.attributes["ring"].name) world.player.attributes["spell"].draw() world.player.attributes["consumable"].draw() start_time = time.time() since_start = 0 while True: # Main game loop try: new_map_loaded = False # Refresh screen. Draw player first. display.printc(world.player.X, world.player.Y + 5, world.player.char(), world.player.color(), world.map[world.player.X][world.player.Y][1])
def inventory_menu(): while True: menu = display.menu( "Inventory\nMax HP: \\frRed\n\\fwMax MP: \\fbBlue\n\\fwMovement Speed: \\fgGreen\n\\fwAttack Speed: White\nMagic Power: \\fcCyan\n\\fwStrength: \\fmMagenta\n\\fwLuck: \\fyYellow", "Back", "Set Consumable", "Set Weapon", "Set Hat", "Set Shirt", "Set Pants", "Set Ring") while menu.update() is None: display.refresh() if menu.update() != 0: set_active( [0, "consumable", "weapon", "hat", "shirt", "pants", "ring"][menu.update()]) # Redraw equip names. display.printc(display.WEAPON_X, display.WEAPON_Y, ' ' * 33) display.printc(display.WEAPON_X, display.WEAPON_Y, world.player.attributes["weapon"].name[:33]) display.printc(display.HAT_X, display.HAT_Y, ' ' * 36) display.printc(display.HAT_X, display.HAT_Y, world.player.attributes["hat"].name[:36]) display.printc(display.SHIRT_X, display.SHIRT_Y, ' ' * 34) display.printc(display.SHIRT_X, display.SHIRT_Y, world.player.attributes["shirt"].name[:34]) display.printc(display.PANTS_X, display.PANTS_Y, ' ' * 34) display.printc(display.PANTS_X, display.PANTS_Y, world.player.attributes["pants"].name[:34]) display.printc(display.RING_X, display.RING_Y, ' ' * 35) display.printc(display.RING_X, display.RING_Y, world.player.attributes["ring"].name[:35]) if menu.update() == 0: return
def clear(this): for i in range(5, 25): display.printc(50, i, ' ' * 30)
def update(this): """Updates the menu, returns None if no option selected, otherwise returns option.""" if this._end_val != -1: return this._end_val display.printc(50, this._cursor, ' ') # Update # Move cursor up if this._can_up: if keyDown(CONST.VK_UP) or keyDown(ord('Q')): # Go up in the menu. if this._page_opt == 0: # Top of page if this._page != 0: # Go to prev page this._page -= 1 # Redraw page for i in range(this._opt_start, 50): display.printc(50, i, ' ' * 29) linecount = 0 for elem in this._pages[this._page]: display.printc(51, linecount + this._opt_start, elem) linecount += elem.count('\n') + 1 # Reset cursor, page loc stuff this._page_opt = len(this._pages[this._page]) - 1 this._cursor = linecount + this._opt_start - 1 - this._pages[this._page][this._page_opt].count('\n') this._opt -= 1 else: this._page_opt -= 1 # Track previous option # Move cursor up proper amount of lines this._cursor -= this._pages[this._page][this._page_opt].count('\n') + 1 this._opt -= 1 # Select previous option. this._can_up = False elif not (keyDown(CONST.VK_UP) or keyDown(ord('Q'))): this._can_up = True # Move cursor down if this._can_down: if keyDown(CONST.VK_DOWN) or keyDown(ord('E')): # Go down in the menu. if this._page_opt == len(this._pages[this._page]) - 1: # Top of page if this._page != len(this._pages) - 1: # Go to next page this._page += 1 # Redraw page for i in range(this._opt_start, 50): display.printc(50, i, ' ' * 29) linecount = 0 for elem in this._pages[this._page]: display.printc(51, linecount + this._opt_start, elem) linecount += elem.count('\n') + 1 # Reset cursor, page loc stuff this._cursor = this._opt_start this._page_opt = 0 this._opt += 1 else: # Move cursor up proper amount of lines this._cursor += this._pages[this._page][this._page_opt].count('\n') + 1 this._page_opt += 1 # Track next option this._opt += 1 # Select previous option. this._can_down = False elif not (keyDown(CONST.VK_DOWN) or keyDown(ord('E'))): this._can_down = True if keyDown(CONST.VK_RETURN): while keyDown(CONST.VK_RETURN): pass this._end_val = this._opt this.clear() return this._opt # Redraw cursor display.printc(50, this._cursor, '>')
def update(this, delta_time): # Reprint top bar status display.printc(8, 0, str(int(this.attributes["HP"])) + "/" + str(int(this.attributes["maxHP"])) + " ") display.printc(8, 1, str(int(this.attributes["MP"])) + "/" + str(int(this.attributes["maxMP"])) + " ") display.printc(10, 2, str(this.attributes["money"]) + " ") display.printc(12, 3, str(this.attributes["level"])) display.printc(5, 4, str(int(0.5*this.attributes["level"]**2 + 0.5*this.attributes["level"] + 4 - this.attributes["EXP"])) + " to level ") # Check HP diff for flash on hit stuff if this.attributes["HP"] < this.attributes["lastHP"]: this.attributes["sincehit"] = 0 else: this.attributes["sincehit"] += delta_time # Check for movement if display.keyDown(ord('W')) and (not "del_up" in this.attributes["effects"]): if (this.Y > 0) and world.map[this.X][this.Y - 1][3]: this.Y -= 1 this.attributes["effects"]["del_up"] = effect.effect(this, 500/(1+2.718**(.01*this.attributes["mov_spd"]))) if display.keyDown(ord('S')) and (not "del_down" in this.attributes["effects"]): if (this.Y < world.WORLD_Y - 1) and world.map[this.X][this.Y + 1][3]: this.Y += 1 this.attributes["effects"]["del_down"] = effect.effect(this, 500/(1+2.718**(.01*this.attributes["mov_spd"]))) if display.keyDown(ord('A')) and (not "del_left" in this.attributes["effects"]): if (this.X > 0) and world.map[this.X - 1][this.Y][3]: this.X -= 1 this.attributes["effects"]["del_left"] = effect.effect(this, 500/(1+2.718**(.01*this.attributes["mov_spd"]))) if display.keyDown(ord('D')) and (not "del_right" in this.attributes["effects"]): if (this.X < world.WORLD_X - 1) and world.map[this.X + 1][this.Y][3]: this.X += 1 this.attributes["effects"]["del_right"] = effect.effect(this, 500/(1+2.718**(.01*this.attributes["mov_spd"]))) # Check for spell cast if display.keyDown(ord(' ')) and this.attributes["can_cast"]: this.attributes["spell"].cast(this) this.attributes["can_cast"] = False if not display.keyDown(ord(' ')): this.attributes["can_cast"] = True # Attacks! if (display.keyDown(ord('I'))) and (this.Y != 0) and (world.map[this.X][this.Y - 1][3]) and (not "del_atk" in this.attributes["effects"]): world.objects.append(attack.attack(this.X, this.Y - 1, 0, -1, (this.attributes["strength"] * this.attributes["weapon"].attributes["damage"] // 2), this.attributes["weapon"].attributes["range"], 100, this)) this.attributes["effects"]["del_atk"] = effect.effect(this, 500/(1+2.718**(.01*this.attributes["atk_spd"]))) if (display.keyDown(ord('J'))) and (this.X != 0) and (world.map[this.X - 1][this.Y][3]) and (not "del_atk" in this.attributes["effects"]): world.objects.append(attack.attack(this.X - 1, this.Y, -1, 0, (this.attributes["strength"] * this.attributes["weapon"].attributes["damage"] // 2), this.attributes["weapon"].attributes["range"], 100, this)) this.attributes["effects"]["del_atk"] = effect.effect(this, 500/(1+2.718**(.01*this.attributes["atk_spd"]))) if (display.keyDown(ord('K'))) and (this.Y != 19) and (world.map[this.X][this.Y + 1][3]) and (not "del_atk" in this.attributes["effects"]): world.objects.append(attack.attack(this.X, this.Y + 1, 0, 1, (this.attributes["strength"] * this.attributes["weapon"].attributes["damage"] // 2), this.attributes["weapon"].attributes["range"], 100, this)) this.attributes["effects"]["del_atk"] = effect.effect(this, 500/(1+2.718**(.01*this.attributes["atk_spd"]))) if (display.keyDown(ord('L'))) and (this.X != 49) and (world.map[this.X + 1][this.Y][3]) and (not "del_atk" in this.attributes["effects"]): world.objects.append(attack.attack(this.X + 1, this.Y, 1, 0, (this.attributes["strength"] * this.attributes["weapon"].attributes["damage"] // 2), this.attributes["weapon"].attributes["range"], 100, this)) this.attributes["effects"]["del_atk"] = effect.effect(this, 500/(1+2.718**(.01*this.attributes["atk_spd"]))) # Or with our constants in python, time = 500/(1+2.718^(.01x)), which is a nice logistic formula. # Check for item use if display.keyDown(display.CONST.VK_LSHIFT) and this.attributes["can_item"] and (this.attributes["consumable"].name != "Nothing"): this.attributes["consumable"].use(this) this.attributes["can_item"] = False this.attributes["consumable"].amount -= 1 if this.attributes["consumable"].amount == 0: del this.attributes["items"][this.attributes["items"].index(this.attributes["consumable"])] this.attributes["consumable"] = item.item("Nothing", "consumable", 0, 1, {"icon" : [" ", " ", " "], "color" : 0}) this.attributes["consumable"].draw() if not display.keyDown(display.CONST.VK_SHIFT): this.attributes["can_item"] = True # Update all effects. eff_printed = 0 if display.sidebar_line < 10: # Must have room to show some effects display.printc(50, display.sidebar_line, "Effects:") eff_printed = display.sidebar_line display.sidebar_line += 1 eff_del_list = [] for eff_name in this.attributes["effects"]: eff = this.attributes["effects"][eff_name] eff.tick(delta_time) # Tick effect if eff.time <= 0: # Remove effect eff_del_list.append(eff_name) for eff_name in eff_del_list: this.attributes["effects"][eff_name].uneffect(this) del this.attributes["effects"][eff_name] del eff_del_list if eff_printed == display.sidebar_line - 1: display.printc(50, display.sidebar_line, " No effects") display.sidebar_line += 1 if this.attributes["HP"] <= 0: #TODO: Actually have things happen when you die. display.printc(33, 9, "+++++++++++++", display.RED) display.printc(33, 10, "+ You DIED! +", display.RED) display.printc(33, 11, "+++++++++++++", display.RED) display.refresh() time.sleep(1) display.flushinp() while display.getch() != -1: # Wait for key release pass while display.getch() == -1: # Wait for keypress pass display.end() # Finally, update lastHP. Done after effects because we don't want effects to make you constantly red this.attributes["lastHP"] = this.attributes["HP"]
def multiplayer(): # Get username and password. display.clear() display.flushinp() inpt = display.getch() curs_loc = 0 char_name = "" display.printc(30, 9, "Enter your name:") while inpt != 10: # Until ENTER pressed if inpt == 8: # Backspace if curs_loc != 0: curs_loc -= 1 char_name = char_name[:-1] # Remove last character display.printc(curs_loc + 30, 10, ' ') elif (inpt != -1) and (curs_loc < 45) and (chr(inpt) in "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-1234567890 "): # Also don't let them get too long. 45 chosen arbitrarily because yeah. display.printc(curs_loc + 30, 10, chr(inpt)) char_name += chr(inpt) curs_loc += 1 display.refresh() inpt = display.getch() # Wait for release while display.keyDown(display.CONST.VK_RETURN): pass if char_name == len(char_name) * ' ': char_name = "default" curs_loc = 0 password = "" inpt = display.getch() display.printc(30, 11, "Enter your Password:"******"Passwords must be at least 8 characters.") elif inpt != -1: display.printc(30, 13, " ") if inpt == 8: # Backspace if curs_loc != 0: curs_loc -= 1 password = password[:-1] # Remove last character display.printc(curs_loc + 30, 12, ' ') elif (inpt != -1) and (curs_loc < 45) and (inpt < 127) and (inpt > 31): # Most characters allowed in password. Just has to be a printable ASCI display.printc(curs_loc + 30, 12, chr(inpt)) password += chr(inpt) curs_loc += 1 display.refresh() inpt = display.getch() # Wait for release while display.keyDown(display.CONST.VK_RETURN): pass display.clear() display.draw_topbar() display.refresh() world.map = [[ [0, 1, '!'] for y in range(world.WORLD_Y)] for x in range(world.WORLD_X)] sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.settimeout(1) try: sock.sendto(bytes(char_name, 'utf-8'), ('localhost', 5000)) (data, new_addr) = sock.recvfrom(65507) last_update = time.clock() # All coord pairs to overwrite. to_overwrite = [] sidebar_lines = 0 # ID of current map we're in. Useful for server. current_map = 0 class states: WORLD = 0 INVENTORY = 1 class inventory: # Only one of these exists so we can just modify class stuff. class item: def __init__(this, name, desc, amount, value): this.name = name this.desc = desc this.value = value this.amount = amount selected_index = 0 current_type = "weapon" weapons = [] hats = [] shirts = [] pants = [] rings = [] consumables = [] def str_to_list(string): return [inventory.weapons, inventory.hats, inventory.shirts, inventory.pants, inventory.rings, inventory.consumables][["weapon", "hat", "shirt", "pants", "ring", "consumable"].index(string)] def clear(): # Clears entire inventory. inventory.weapons.clear() inventory.hats.clear() inventory.shirts.clear() inventory.pants.clear() inventory.rings.clear() inventory.consumables.clear() def add_item(data): # Adds an item based off of current data split_data = [bytearray(g) for k,g in itertools.groupby(data, lambda x: x == 0) if not k] # Data is packed as type, name, desc, amount, value. First 3 are null terminated strings type = split_data[0].decode('utf-8') name = split_data[1].decode('utf-8') desc = split_data[2].decode('utf-8') amount = struct.unpack("!I", data[len(data) - 8: len(data) - 4])[0] # Unpack last bytes. value = struct.unpack("!I", data[len(data) - 4: len(data)])[0] inventory.str_to_list(type).append(inventory.item(name, desc, amount, value)) state = states.WORLD while True: # Let players force quit with Ctrl+Q if display.keyDown(display.CONST.VK_CONTROL) and display.keyDown(ord('Q')) or (time.clock() - last_update > 1.0): while display.keyDown(ord('Q')): pass sock.close() return if select.select([sock], [], [], 0) != ([], [], []): data, addr = sock.recvfrom(65507) while select.select([sock], [], [], 0) != ([], [], []): sock.recvfrom(65507) last_update = time.clock() if state == states.WORLD: index = 1 # Current data index if data[0] == NEWMAP: current_map = data[index] index += 1 map_size = struct.unpack("!I", data[index:index + 4])[0] # 4 bytes for size of map index += 4 world.map = unpack_map(data[index: index + map_size]) index += map_size world.dispworld() display.refresh() elif data[0] == TO_INV: display.printc(0, 5, ((" " * 80) + "\n") * 25) # Should clear main screen. # Now print out inventory. display.printc(0, 5, "Inventory: \\fyWeapons(1)\\fw Hats(2) Shirts(3) Pants(4) Rings(5) Consumables(6)") display.printc(0, 6, "Name/Description Value Amount") display.printc(0, 7, '-' * 80) inventory.clear() # Clear old inv data. index = 1 # Current data index. while index < len(data): num_bytes = struct.unpack("!I", data[index: index + 4])[0] # Number of bytes in item index += 4 # increment index inventory.add_item(data[index: index + num_bytes]) # Add the item. index += num_bytes # Set last tracking vals inventory.current_type = "weapon" inventory.selected_index = 0 # Now print out inventory display.printc(0, 8, ">") # Draw cursor. loc = 8 # y location to print item at. for itm in inventory.weapons: # Default to weapons display.printc(1, loc, itm.name) display.printc(50, loc, str(itm.value)) display.printc(65, loc, str(itm.amount)) display.printc(2, loc + 1, itm.desc) loc += 2 if loc > 23: # Can't print more. So we get 12 items per sheet. break display.refresh() state = states.INVENTORY continue # Finish loop # Here we do our updating # So we need to redraw objects, HP/MP, gold, sidebar, and possibly equipment/spellbox/itembox # Remove all previous objects for elem in to_overwrite: display.printc(elem[0], elem[1], world.map[elem[0]][elem[1] - 5][2], world.map[elem[0]][elem[1] - 5][0]) to_overwrite.clear() num_objs = data[index] index += 1 # Redraw all new objects while num_objs > 0: x_loc = data[index] y_loc = data[index + 1] index += 2 char = data[index: index + unicode_bytes(data[index])].decode('utf-8') # Total char length for unicode char index += unicode_bytes(data[index]) # Increment counter color = data[index] index += 1 display.printc(x_loc, 5 + y_loc, char, color, world.map[x_loc][y_loc][1]) to_overwrite.append((x_loc, 5 + y_loc)) num_objs -= 1 # Draw HP and MP HP = struct.unpack("!I", data[index:index + 4])[0] maxHP = struct.unpack("!I", data[index + 4 : index + 8])[0] display.printc(8, 0, ' ' * 17) display.printc(8, 0, str(HP) + "/" + str(maxHP)) index += 8 MP = struct.unpack("!I", data[index:index + 4])[0] maxMP = struct.unpack("!I", data[index + 4 : index+8])[0] display.printc(8, 1, ' ' * 17) display.printc(8, 1, str(MP) + "/" + str(maxMP)) index += 8 # Draw level, EXP, gold: level = struct.unpack("!I", data[index: index + 4])[0] exp = struct.unpack("!I", data[index + 4: index + 8])[0] gold = struct.unpack("!I", data[index + 8: index + 12])[0] display.printc(12, 3, str(level)) display.printc(5, 4, ' ' * 20) display.printc(5, 4, str(int(exp)) + " to level") display.printc(10, 2, ' ' * 15) display.printc(10, 2, str(gold)) index += 12 # Print spell box, item box spell_len = struct.unpack("!I", data[index: index + 4])[0] index += 4 display.printc(display.SPELL_BOX_START + 1, 1, data[index: index + spell_len].decode('utf-8')) index += spell_len item_len = struct.unpack("!I", data[index: index + 4])[0] index += 4 display.printc(display.ITEM_BOX_START + 1, 1, data[index: index + item_len].decode('utf-8')) index += item_len # Prints equipment y_print = 0 for equip in [display.WEAPON_X, display.HAT_X, display.SHIRT_X, display.PANTS_X, display.RING_X]: equip_len = struct.unpack("!I", data[index : index + 4])[0] index += 4 display.printc(equip, y_print, ' ' * 37) display.printc(equip, y_print, data[index : index + equip_len].decode('utf-8')) index += equip_len y_print += 1 # Now, we see if we have sidebar stuff to print. # So overwrite previous sidebar for ind in range(sidebar_lines): display.printc(50, ind + 5, ' ' * 30) sidebar_length = struct.unpack("!I", data[index: index + 4])[0] index += 4 display.printc(50, 5, data[index : index + sidebar_length].decode('utf-8')) sidebar_lines = display.getyx(display.stdscr)[0] - 4 # We know how far down we printed by where the cursor is. display.refresh() elif state == states.INVENTORY: # We can ignore data sent. So all we do is check kbd input and update based on that last_a = False if last_a and not display.keyDown(ord('A')): display.printc(0, 0, 'B') if display.keyDown(ord('A')): display.printc(0, 0, 'A') last_a = True display.refresh() # Sends what keys are down. # Byte Key # 0 W # 1 A # 2 S # 3 D # 4 I # 5 J # 6 K # 7 L # 8 SHIFT # 9 SPACE # 10 ENTER # 11 Q/UP # 12 E/DOWN # 13 U # 14 O # 15 ESC # 16 Special: Current map ID. Not actually a key. to_send = bytearray(20) if state == states.WORLD: # Only send kbd input if we're in the world. to_send[0] = states.WORLD # Sending world input to_send[1] = display.keyDown(ord('W')) to_send[2] = display.keyDown(ord('A')) to_send[3] = display.keyDown(ord('S')) to_send[4] = display.keyDown(ord('D')) to_send[5] = display.keyDown(ord('I')) to_send[6] = display.keyDown(ord('J')) to_send[7] = display.keyDown(ord('K')) to_send[8] = display.keyDown(ord('L')) to_send[9] = display.keyDown(display.CONST.VK_LSHIFT) to_send[10] = display.keyDown(ord(' ')) to_send[11]= display.keyDown(display.CONST.VK_RETURN) to_send[12]= display.keyDown(ord('Q')) or display.keyDown(display.CONST.VK_UP) to_send[13]= display.keyDown(ord('E')) or display.keyDown(display.CONST.VK_DOWN) to_send[14]= display.keyDown(ord('E')) to_send[15]= display.keyDown(ord('U')) to_send[16]= display.keyDown(ord('O')) to_send[17]= display.keyDown(ord('V')) to_send[18]= display.keyDown(display.CONST.VK_ESCAPE) to_send[19] = current_map elif to_send == states.INVENTORY: to_send[0] = states.INVENTORY sock.sendto(to_send, new_addr) except ConnectionResetError as ex: sock.close() return except Exception as ex: return
def draw(this): "Draws the consumable icon. Only needed if it's a consumable" display.printc(display.SPELL_BOX_START + 7, 1, this.attributes["icon"][0], this.attributes["color"]) display.printc(display.SPELL_BOX_START + 7, 2, this.attributes["icon"][1], this.attributes["color"]) display.printc(display.SPELL_BOX_START + 7, 3, this.attributes["icon"][2], this.attributes["color"])
def update(this): """Updates the menu, returns None if no option selected, otherwise returns option.""" if this._end_val != -1: return this._end_val display.printc(50, this._cursor, ' ') # Update # Move cursor up if this._can_up: if keyDown(CONST.VK_UP) or keyDown(ord('Q')): # Go up in the menu. if this._page_opt == 0: # Top of page if this._page != 0: # Go to prev page this._page -= 1 # Redraw page for i in range(this._opt_start, 50): display.printc(50, i, ' ' * 29) linecount = 0 for elem in this._pages[this._page]: display.printc(51, linecount + this._opt_start, elem) linecount += elem.count('\n') + 1 # Reset cursor, page loc stuff this._page_opt = len(this._pages[this._page]) - 1 this._cursor = linecount + this._opt_start - 1 - this._pages[ this._page][this._page_opt].count('\n') this._opt -= 1 else: this._page_opt -= 1 # Track previous option # Move cursor up proper amount of lines this._cursor -= this._pages[this._page][ this._page_opt].count('\n') + 1 this._opt -= 1 # Select previous option. this._can_up = False elif not (keyDown(CONST.VK_UP) or keyDown(ord('Q'))): this._can_up = True # Move cursor down if this._can_down: if keyDown(CONST.VK_DOWN) or keyDown(ord('E')): # Go down in the menu. if this._page_opt == len( this._pages[this._page]) - 1: # Top of page if this._page != len(this._pages) - 1: # Go to next page this._page += 1 # Redraw page for i in range(this._opt_start, 50): display.printc(50, i, ' ' * 29) linecount = 0 for elem in this._pages[this._page]: display.printc(51, linecount + this._opt_start, elem) linecount += elem.count('\n') + 1 # Reset cursor, page loc stuff this._cursor = this._opt_start this._page_opt = 0 this._opt += 1 else: # Move cursor up proper amount of lines this._cursor += this._pages[this._page][ this._page_opt].count('\n') + 1 this._page_opt += 1 # Track next option this._opt += 1 # Select previous option. this._can_down = False elif not (keyDown(CONST.VK_DOWN) or keyDown(ord('E'))): this._can_down = True if keyDown(CONST.VK_RETURN): while keyDown(CONST.VK_RETURN): pass this._end_val = this._opt this.clear() return this._opt # Redraw cursor display.printc(50, this._cursor, '>')
def update(this, delta_time): # Reprint top bar status display.printc( 8, 0, str(int(this.attributes["HP"])) + "/" + str(int(this.attributes["maxHP"])) + " ") display.printc( 8, 1, str(int(this.attributes["MP"])) + "/" + str(int(this.attributes["maxMP"])) + " ") display.printc(10, 2, str(this.attributes["money"]) + " ") display.printc(12, 3, str(this.attributes["level"])) display.printc( 5, 4, str( int(0.5 * this.attributes["level"]**2 + 0.5 * this.attributes["level"] + 4 - this.attributes["EXP"])) + " to level ") # Check HP diff for flash on hit stuff if this.attributes["HP"] < this.attributes["lastHP"]: this.attributes["sincehit"] = 0 else: this.attributes["sincehit"] += delta_time # Check for movement if display.keyDown( ord('W')) and (not "del_up" in this.attributes["effects"]): if (this.Y > 0) and world.map[this.X][this.Y - 1][3]: this.Y -= 1 this.attributes["effects"]["del_up"] = effect.effect( this, 500 / (1 + 2.718**(.01 * this.attributes["mov_spd"]))) if display.keyDown( ord('S')) and (not "del_down" in this.attributes["effects"]): if (this.Y < world.WORLD_Y - 1) and world.map[this.X][this.Y + 1][3]: this.Y += 1 this.attributes["effects"]["del_down"] = effect.effect( this, 500 / (1 + 2.718**(.01 * this.attributes["mov_spd"]))) if display.keyDown( ord('A')) and (not "del_left" in this.attributes["effects"]): if (this.X > 0) and world.map[this.X - 1][this.Y][3]: this.X -= 1 this.attributes["effects"]["del_left"] = effect.effect( this, 500 / (1 + 2.718**(.01 * this.attributes["mov_spd"]))) if display.keyDown( ord('D')) and (not "del_right" in this.attributes["effects"]): if (this.X < world.WORLD_X - 1) and world.map[this.X + 1][this.Y][3]: this.X += 1 this.attributes["effects"]["del_right"] = effect.effect( this, 500 / (1 + 2.718**(.01 * this.attributes["mov_spd"]))) # Check for spell cast if display.keyDown(ord(' ')) and this.attributes["can_cast"]: this.attributes["spell"].cast(this) this.attributes["can_cast"] = False if not display.keyDown(ord(' ')): this.attributes["can_cast"] = True # Attacks! if (display.keyDown(ord('I'))) and (this.Y != 0) and ( world.map[this.X][this.Y - 1][3]) and ( not "del_atk" in this.attributes["effects"]): world.objects.append( attack.attack( this.X, this.Y - 1, 0, -1, (this.attributes["strength"] * this.attributes["weapon"].attributes["damage"] // 2), this.attributes["weapon"].attributes["range"], 100, this)) this.attributes["effects"]["del_atk"] = effect.effect( this, 500 / (1 + 2.718**(.01 * this.attributes["atk_spd"]))) if (display.keyDown(ord('J'))) and (this.X != 0) and ( world.map[this.X - 1][this.Y][3]) and ( not "del_atk" in this.attributes["effects"]): world.objects.append( attack.attack( this.X - 1, this.Y, -1, 0, (this.attributes["strength"] * this.attributes["weapon"].attributes["damage"] // 2), this.attributes["weapon"].attributes["range"], 100, this)) this.attributes["effects"]["del_atk"] = effect.effect( this, 500 / (1 + 2.718**(.01 * this.attributes["atk_spd"]))) if (display.keyDown(ord('K'))) and (this.Y != 19) and ( world.map[this.X][this.Y + 1][3]) and ( not "del_atk" in this.attributes["effects"]): world.objects.append( attack.attack( this.X, this.Y + 1, 0, 1, (this.attributes["strength"] * this.attributes["weapon"].attributes["damage"] // 2), this.attributes["weapon"].attributes["range"], 100, this)) this.attributes["effects"]["del_atk"] = effect.effect( this, 500 / (1 + 2.718**(.01 * this.attributes["atk_spd"]))) if (display.keyDown(ord('L'))) and (this.X != 49) and ( world.map[this.X + 1][this.Y][3]) and ( not "del_atk" in this.attributes["effects"]): world.objects.append( attack.attack( this.X + 1, this.Y, 1, 0, (this.attributes["strength"] * this.attributes["weapon"].attributes["damage"] // 2), this.attributes["weapon"].attributes["range"], 100, this)) this.attributes["effects"]["del_atk"] = effect.effect( this, 500 / (1 + 2.718**(.01 * this.attributes["atk_spd"]))) # Or with our constants in python, time = 500/(1+2.718^(.01x)), which is a nice logistic formula. # Check for item use if display.keyDown( display.CONST.VK_LSHIFT) and this.attributes["can_item"] and ( this.attributes["consumable"].name != "Nothing"): this.attributes["consumable"].use(this) this.attributes["can_item"] = False this.attributes["consumable"].amount -= 1 if this.attributes["consumable"].amount == 0: del this.attributes["items"][this.attributes["items"].index( this.attributes["consumable"])] this.attributes["consumable"] = item.item( "Nothing", "consumable", 0, 1, { "icon": [" ", " ", " "], "color": 0 }) this.attributes["consumable"].draw() if not display.keyDown(display.CONST.VK_SHIFT): this.attributes["can_item"] = True # Update all effects. eff_printed = 0 if display.sidebar_line < 10: # Must have room to show some effects display.printc(50, display.sidebar_line, "Effects:") eff_printed = display.sidebar_line display.sidebar_line += 1 eff_del_list = [] for eff_name in this.attributes["effects"]: eff = this.attributes["effects"][eff_name] eff.tick(delta_time) # Tick effect if eff.time <= 0: # Remove effect eff_del_list.append(eff_name) for eff_name in eff_del_list: this.attributes["effects"][eff_name].uneffect(this) del this.attributes["effects"][eff_name] del eff_del_list if eff_printed == display.sidebar_line - 1: display.printc(50, display.sidebar_line, " No effects") display.sidebar_line += 1 if this.attributes[ "HP"] <= 0: #TODO: Actually have things happen when you die. display.printc(33, 9, "+++++++++++++", display.RED) display.printc(33, 10, "+ You DIED! +", display.RED) display.printc(33, 11, "+++++++++++++", display.RED) display.refresh() time.sleep(1) display.flushinp() while display.getch() != -1: # Wait for key release pass while display.getch() == -1: # Wait for keypress pass display.end() # Finally, update lastHP. Done after effects because we don't want effects to make you constantly red this.attributes["lastHP"] = this.attributes["HP"]
def clear(this): for i in range(5, 25): display.printc(50, i, ' ' * 30)
def inventory_menu(): while True: menu = display.menu("Inventory\nMax HP: \\frRed\n\\fwMax MP: \\fbBlue\n\\fwMovement Speed: \\fgGreen\n\\fwAttack Speed: White\nMagic Power: \\fcCyan\n\\fwStrength: \\fmMagenta\n\\fwLuck: \\fyYellow", "Back", "Set Consumable", "Set Weapon", "Set Hat", "Set Shirt", "Set Pants", "Set Ring") while menu.update() is None: display.refresh() if menu.update() != 0: set_active([0, "consumable", "weapon", "hat", "shirt", "pants", "ring"][menu.update()]) # Redraw equip names. display.printc(display.WEAPON_X, display.WEAPON_Y, ' ' * 33) display.printc(display.WEAPON_X, display.WEAPON_Y, world.player.attributes["weapon"].name[:33]) display.printc(display.HAT_X, display.HAT_Y, ' ' * 36) display.printc(display.HAT_X, display.HAT_Y, world.player.attributes["hat"].name[:36]) display.printc(display.SHIRT_X, display.SHIRT_Y, ' ' * 34) display.printc(display.SHIRT_X, display.SHIRT_Y, world.player.attributes["shirt"].name[:34]) display.printc(display.PANTS_X, display.PANTS_Y, ' ' * 34) display.printc(display.PANTS_X, display.PANTS_Y, world.player.attributes["pants"].name[:34]) display.printc(display.RING_X, display.RING_Y, ' ' * 35) display.printc(display.RING_X, display.RING_Y, world.player.attributes["ring"].name[:35]) if menu.update() == 0: return
def dispworld(): for x in range(WORLD_X): for y in range(WORLD_Y): display.printc(x, y + 5, map[x][y][2], map[x][y][0]) # Print normal char with black bgc