def kill_monster(monster: Entity) -> Message: death_message = Message(f'{monster.name.capitalize()} is dead!', tcod.orange) monster.char = '%' monster.color = tcod.dark_red monster.blocks = False monster.fighter = None monster.ai = None monster.name = f'remains of {monster.name}' monster.render_order = RenderOrder.CORPSE return death_message
def kill_monster(monster: Entity): death_message = Message(f"{monster.name.capitalize()} is dead!", Colors.ORANGE) monster.char = "%" monster.color = Colors.RED monster.blocks = False monster.fighter = None monster.ai = None monster.name = f"remains of {monster.name}" monster.render_order = RenderLayer.CORPSE return death_message
def main(): screen_width = 80 screen_height = 50 bar_width = 20 panel_height = 7 panel_y = screen_height - panel_height message_x = bar_width + 2 message_width = screen_width - bar_width - 2 message_height = panel_height - 1 map_width = 80 map_height = 43 fov_algorithm = 'BASIC' fov_light_walls = True fov_radius = 10 colors = { 'dark_wall': (0, 0, 100), 'dark_ground': (50, 50, 150), 'light_wall': (130, 110, 50), 'light_ground': (200, 180, 50), 'white': (255, 255, 255), 'black': (0, 0, 0), 'light red': (255, 100, 100), 'red': (255, 0, 0), 'yellow': (255, 255, 0), 'orange': (255, 127, 0), 'green': ( 0, 255, 0, ), 'light_red': (255, 114, 114), 'darker_red': (127, 0, 0), 'highlight': (199, 234, 70) } mech_component = Mech(hp=30, peak_momentum=6) weapon_component = Weapon(name="Laser", damage=5, min_targets=0, max_targets=5, color=colors.get('green'), range=10) player = Entity(int(screen_width / 2), int(screen_height / 2), '@', colors.get('white'), "player", mech=mech_component, weapon=weapon_component) npc = Entity(int(screen_width / 2 - 5), int(screen_height / 2), '@', colors.get('yellow'), "NPC") cursor_component = Cursor() cursor = Entity( -1, -1, ' ', colors.get('red'), "cursor", cursor=cursor_component ) # The ' ' isn't actually "nothing". To have nothing, I would have to mess with a render order. entities = [npc, player, cursor] tdl.set_font('arial10x10.png', greyscale=True, altLayout=True) root_console = tdl.init(screen_width, screen_height, title='MVP v0.0') con = tdl.Console(screen_width, screen_height) panel = tdl.Console(screen_width, panel_height) game_map = GameMap(map_width, map_height) make_map(game_map) message_log = MessageLog(message_x, message_width, message_height) mouse_coordinates = (0, 0) game_state = GameStates.PLAYER_TURN previous_game_state = game_state turn_state = TurnStates.UPKEEP_PHASE fov_recompute = True while not tdl.event.is_window_closed(): if fov_recompute: game_map.compute_fov(player.x, player.y, fov=fov_algorithm, radius=fov_radius, light_walls=fov_light_walls) render_all(con, panel, entities, game_map, fov_recompute, root_console, message_log, screen_width, screen_height, bar_width, panel_height, panel_y, mouse_coordinates, colors) tdl.flush() clear_all(con, entities) for event in tdl.event.get(): if event.type == 'KEYDOWN': user_input = event break elif event.type == 'MOUSEMOTION': mouse_coordinates = event.cell else: user_input = None fov_recompute = False action = handle_keys(user_input, game_state) impulse = None # This is to avoid logic problems. change_game_state = None # This is to avoid logic problems. move = action.get('move') # Attempt to move. impulse = action.get('impulse') # Adjust mech impulse. next_turn_phase = action.get( 'next turn phase') # Move to the next phase. change_game_state = action.get( 'change game state') # Go to different game_state select = action.get( 'select') # A target has been selected via keyboard. exit = action.get('exit') # Exit whatever screen is open. fullscreen = action.get('fullscreen') # Set game to full screen. if exit: if game_state == GameStates.TARGETING: # Turn off cursor cursor.char = ' ' cursor.x = -1 cursor.y = -1 fov_recompute = True game_state = previous_game_state else: return True if fullscreen: tdl.set_fullscreen(not tdl.get_fullscreen()) if game_state == GameStates.PLAYER_TURN: # See game_states.py for the turn structure. # Turns order is reversed so ensure that the loop runs once for each if turn_state == TurnStates.POST_ATTACK_PHASE: # Reset map flags and remove targets. reset_flags(game_map) for x, y in player.weapon.targets: erase_cell(con, x, y) turn_state = TurnStates.UPKEEP_PHASE game_state = GameStates.ENEMY_TURN if turn_state == TurnStates.ATTACK_PHASE: if change_game_state == GameStates.TARGETING: # Turn on cursor. cursor.char = 'X' # If there were no previous targets, start on the player. if len(player.weapon.targets) == 0: cursor.x = player.x cursor.y = player.y else: cursor.x, cursor.y = player.weapon.targets[-1] fov_recompute = True previous_game_state = game_state game_state = GameStates.TARGETING if next_turn_phase: turn_state = TurnStates.POST_ATTACK_PHASE if turn_state == TurnStates.PRE_ATTACK_PHASE: message_log.add_message( Message('Begin ATTACK PHASE.', colors.get('white'))) message_log.add_message( Message( 'Press f to target. Press ESC to stop targeting. Enter to change phase.', colors.get('orange'))) fov_recompute = True turn_state = TurnStates.ATTACK_PHASE if turn_state == TurnStates.POST_MOVEMENT_PHASE: reset_flags(game_map) player.reset( ) # Reset the mech for the next turn. ### Move this to the post-attack phase fov_recompute = True turn_state = TurnStates.PRE_ATTACK_PHASE if turn_state == TurnStates.MOVEMENT_PHASE: if move: dx, dy = move if game_map.walkable[player.x + dx, player.y + dy]: player.move(dx, dy) fov_recompute = True if next_turn_phase and player.mech.has_spent_minimum_momentum( ): turn_state = TurnStates.POST_MOVEMENT_PHASE elif next_turn_phase and not player.mech.has_spent_minimum_momentum( ): message_log.add_message( Message('Must spend more momentum.', colors.get('red'))) if turn_state == TurnStates.PRE_MOVEMENT_PHASE: if impulse is not None: player.mech.impulse = impulse turn_state = TurnStates.MOVEMENT_PHASE message_log.add_message( Message('Impulse set to {0}.'.format(impulse), colors.get('orange'))) fov_recompute = True highlight_legal_moves(player, game_map) if turn_state == TurnStates.UPKEEP_PHASE and game_state == GameStates.PLAYER_TURN: # This is added to avoid starting the Upkeep Phase when the turn just ended. message_log.add_message( Message('Begin PLAYER TURN.', colors.get('white'))) message_log.add_message( Message('Begin MOVEMENT PHASE.', colors.get('white'))) message_log.add_message( Message('Choose impulse. PAGEUP, PAGEDOWN or HOME.', colors.get('orange'))) turn_state = TurnStates.PRE_MOVEMENT_PHASE fov_recompute = True if game_state == GameStates.ENEMY_TURN: message_log.add_message( Message('Begin ENEMY TURN.', colors.get('white'))) fov_recompute = True game_state = GameStates.PLAYER_TURN if game_state == GameStates.TARGETING: if move: dx, dy = move # Ensure the first target is in firing range. if len(player.weapon.targets) == 0: if player.distance(cursor.x + dx, cursor.y + dy) <= player.weapon.range: cursor.fly(dx, dy) fov_recompute = True else: message_log.add_message( Message('Out of range.', colors.get('red'))) # Ensure that the next targets are adjacent to the previous target elif len(player.weapon.targets) > 0: tar_x, tar_y = player.weapon.targets[ -1] # Get the most recent target added. if abs(tar_x - (cursor.x + dx)) + abs(tar_y - (cursor.y + dy)) <= 1: cursor.fly(dx, dy) fov_recompute = True else: message_log.add_message( Message('Invalid target.', colors.get('red'))) if select: if len(player.weapon.targets) < player.weapon.max_targets: if set_targeted( game_map, cursor.x, cursor.y ): # At the moment, this always returns True. In the future, this may change. fov_recompute = True player.weapon.targets.append((cursor.x, cursor.y)) else: message_log.add_message( Message('Targeting failed.', colors.get('red')))
def kill_player(player: Entity): player.char = "%" player.color = Colors.RED return Message("You died!", Colors.RED)
def get_game_variables(constants, names_list, colors_list): #Build player entity fighter_component = Fighter(hp=100, defense=0, power=1, speed=5) inventory_component = Inventory(24) level_component = Level() equipment_component = Equipment() player = Entity(0, 0, 256, libtcod.white, "Player", blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, inventory=inventory_component, level=level_component, equipment=equipment_component) player.character_name = constants['player_name'] entities = [player] #Starting Inventory, sprite origin = constants['options_origin'] #HEKIN QUIVER item_component = Item(use_function=use_quiver, stackable=False, flammable=True, description="A quiver for storing arrows.", effect="Firing preference is currently unassigned.") item = Entity(0, 0, 394, colors_list[names_list['Quiver']], 'Quiver', item=item_component) player.inventory.items.append(item) if origin == "Adventurer": player.char = 256 #sword item_component = Item(use_function=None, stackable=False, description="A short, one-handed sword.") equippable_component = Equippable(EquipmentSlots.MAIN_HAND, power_bonus=3) item = Entity(0, 0, 369, colors_list[names_list['Sword']], 'Sword', equippable=equippable_component, item=item_component) player.equipment.list.append(item) #shield item_component = Item(use_function=None, stackable=False, description="A small, round, metal shield.") equippable_component = Equippable(EquipmentSlots.OFF_HAND, defense_bonus=1) item = Entity(0, 0, 375, colors_list[names_list['Shield']], 'Shield', equippable=equippable_component, item=item_component) player.equipment.list.append(item) #10 gold item_component = Item( use_function=None, stackable=True, count=20, description= "Yanno, gold coins! For procuring goods and/or services!") item = Entity(0, 0, 365, colors_list[names_list['Gold']], 'Gold', render_order=RenderOrder.ITEM, item=item_component) player.inventory.add_item(item, names_list) player.gold_collected = 20 elif origin == "Ranger": player.char = 258 #3x Pos. Arrow hit_component = PoisonShot(2, 1, 10) ammo_component = Ammo(hit_function=hit_component, retrievable=True) item_component = Item(use_function=use_arrow(), stackable=True, count=3, ammo=ammo_component, flammable=True, range=0, description="Poison-coated arrow. Icky!") item = Entity(0, 0, 378, colors_list[names_list['Arrow']], 'Poison Arrow', item=item_component) player.inventory.items.append(item) #10x. Arrow hit_component = BasicShot(2) ammo_component = Ammo(hit_function=hit_component, retrievable=True) item_component = Item(use_function=None, stackable=True, count=10, ammo=ammo_component, flammable=True, range=0, description="Arrow. Pewpew!") item = Entity(0, 0, 378, colors_list[names_list['Arrow']], 'Arrow', item=item_component) player.inventory.items.append(item) #Bow item_component = Item(use_function=None, stackable=False, flammable=True, ammo=["Arrow", "Poison Arrow"], range=5, description="A small, low-range bow.") equippable_component = Equippable(EquipmentSlots.MAIN_HAND, power_bonus=0) item = Entity(0, 0, 377, colors_list[names_list['Short Bow']], 'Short Bow', equippable=equippable_component, item=item_component) player.equipment.list.append(item) elif origin == "Merchant": player.char = 260 #staff item_component = Item( use_function=None, stackable=False, description= "A two-handed (but actually one-handed) wooden staff, perfect for whacking things with." ) equippable_component = Equippable(EquipmentSlots.MAIN_HAND, power_bonus=1) item = Entity(0, 0, 372, libtcod.sky, 'Staff', equippable=equippable_component, item=item_component) player.equipment.list.append(item) #merchants bag item_component = Item( use_function=None, stackable=False, description= "A large leather satchel with many pockets and reinforced compartments.", effect="Increases carrying capacity by 24.") equippable_component = Equippable(EquipmentSlots.ACC1, capacity_bonus=24) item = Entity(0, 0, 364, libtcod.darker_orange, 'Merchants Bag', equippable=equippable_component, item=item_component) player.equipment.list.append(item) #100 gold item_component = Item( use_function=None, stackable=True, count=100, description= "Yanno, gold coins! For procuring goods and/or services!") item = Entity(0, 0, 365, libtcod.dark_yellow, 'Gold', render_order=RenderOrder.ITEM, item=item_component) player.inventory.add_item(item, names_list) player.gold_collected = 100 elif origin == "Criminal": player.char = 262 #dagger item_component = Item( use_function=None, stackable=False, description="A small, rusty dagger. Probably unsafe to handle.", effect="This thing was made for doing stabs.") equippable_component = Equippable(EquipmentSlots.MAIN_HAND, power_bonus=2) item = Entity(0, 0, 368, libtcod.sky, 'Dagger', equippable=equippable_component, item=item_component) player.equipment.list.append(item) #fingerless gloves item_component = Item( use_function=None, stackable=False, description= "These definitely had fingers when they were made, but they don't now.", effect="Increases speed by 3") equippable_component = Equippable(EquipmentSlots.ACC1, speed_bonus=3) item = Entity(0, 0, 382, libtcod.darker_orange, 'Fingerless Gloves', equippable=equippable_component, item=item_component) player.equipment.list.append(item) #30 gold item_component = Item( use_function=None, stackable=True, count=30, description= "Yanno, gold coins! For procuring goods and/or services!") item = Entity(0, 0, 365, libtcod.dark_yellow, 'Gold', render_order=RenderOrder.ITEM, item=item_component) player.inventory.add_item(item, names_list) player.gold_collected = 30 elif origin == "Tourist": player.char = 264 #cargo shorts item_component = Item( use_function=None, stackable=False, description= "These are more pockets than they are shorts, which you're ok with.", effect="Increases carrying capacity by 8.") equippable_component = Equippable(EquipmentSlots.ACC1, capacity_bonus=8) item = Entity(0, 0, 395, libtcod.darker_orange, 'Cargo Shorts', equippable=equippable_component, item=item_component) player.equipment.list.append(item) #10 gold item_component = Item( use_function=None, stackable=True, count=10, description= "Yanno, gold coins! For procuring goods and/or services!") item = Entity(0, 0, 365, libtcod.dark_yellow, 'Gold', render_order=RenderOrder.ITEM, item=item_component) player.inventory.add_item(item, names_list) player.gold_collected = 10 game_map = GameMap(constants['map_width'], constants['map_height']) game_map.make_map(constants['max_rooms'], constants['room_min_size'], constants['room_max_size'], constants['map_width'], constants['map_height'], player, entities, names_list, colors_list) message_log = MessageLog(constants['message_x'], constants['message_width'], constants['message_height']) game_state = GameStates.PLAYERS_TURN return player, entities, game_map, message_log, game_state
def kill_player(player: Entity) -> Tuple[Message, GameStates]: player.char = '%' player.color = tcod.dark_red return (Message('You died!', tcod.red), GameStates.PLAYER_DEAD)