def draw_targeting_boundary(self, game_data, gfx_data, main): # find player position s_player_x, s_player_y = gfx_data.camera.map_to_screen( game_data.player.pos.x, game_data.player.pos.y) orig = (s_player_x * CELL_WIDTH, s_player_y * CELL_HEIGHT) orig = (orig[0] + CELL_WIDTH / 2, orig[1] + CELL_HEIGHT / 2 ) # centered item = None if game_data.targeting_formula: item = game_data.targeting_formula elif game_data.targeting_consumable: item = game_data.targeting_consumable assert item for x in range(gfx_data.camera.x1, gfx_data.camera.x2): for y in range(gfx_data.camera.y1, gfx_data.camera.y2): visible = tcod.map_is_in_fov(game_data.fov_map, x, y) asset = game_data.map.tiles[x][y].get_drawable(visible) if not asset: continue rect = self.get_tile_rect(x, y, gfx_data) rect_center = rect[0] + CELL_WIDTH / 2, rect[ 1] + CELL_HEIGHT / 2 dist = distance(orig[0], orig[1], rect_center[0], rect_center[1]) max_dist = item.distance * CELL_WIDTH if dist <= max_dist: continue drawable = Drawable(asset) darken = 100 drawable.colorize((darken, darken, darken), pygame.BLEND_RGBA_SUB) sx, sy = gfx_data.camera.map_to_screen(x, y) main.blit(drawable.asset, (sx * CELL_WIDTH, sy * CELL_HEIGHT))
def place_decorations(m, chunks): for c in chunks: drawable_component = Drawable(Assets.get().red_carpet["topleft"]) m.tiles[c.x + 1][c.y + 1].decor.append(drawable_component) drawable_component = Drawable(Assets.get().red_carpet["topright"]) m.tiles[c.x + c.width - 2][c.y + 1].decor.append(drawable_component) drawable_component = Drawable(Assets.get().red_carpet["bottomleft"]) m.tiles[c.x + 1][c.y + c.height - 2].decor.append(drawable_component) drawable_component = Drawable(Assets.get().red_carpet["bottomright"]) m.tiles[c.x + c.width - 2][c.y + c.height - 2].decor.append(drawable_component) for x in range(c.x + 2, c.x + c.width - 2): drawable_component = Drawable(Assets.get().red_carpet["top"]) m.tiles[x][c.y + 1].decor.append(drawable_component) drawable_component = Drawable(Assets.get().red_carpet["bottom"]) m.tiles[x][c.y + c.height - 2].decor.append(drawable_component) for y in range(c.y + 2, c.y + c.height - 2): drawable_component = Drawable(Assets.get().red_carpet["left"]) m.tiles[c.x + 1][y].decor.append(drawable_component) drawable_component = Drawable(Assets.get().red_carpet["right"]) m.tiles[c.x + c.width - 2][y].decor.append(drawable_component) for x in range(c.x + 2, c.x + c.width - 2): for y in range(c.y + 2, c.y + c.height - 2): drawable_component = Drawable(Assets.get().red_carpet["center"]) m.tiles[x][y].decor.append(drawable_component)
def place_consumables(m, chunks, consumable_count): def has_consumables_left(): for val in consumable_count.values(): if val > 0: return True def get_consumable(): while True: itemtype = random.choice(list(consumable_count.keys())) if consumable_count[itemtype] > 0: consumable_count[itemtype] -= 1 return itemtype() placed_consumables = [] # not two consumables in the same square while has_consumables_left(): c = random.choice(chunks) occupied = True while occupied: x = random.randint(c.x + 1, c.x + c.width - 2) y = random.randint(c.y + 1, c.y + c.height - 2) occupied = False for ent in m.entities: if ent.pos == Pos(x, y): occupied = True if (x, y) in placed_consumables: occupied = True placed_consumables.append((x, y)) drawable_component = Drawable(Assets.get().consumable) consumable_component = get_consumable() name = consumable_component.name.capitalize() consumable = Entity( x, y, name, render_order=RenderOrder.ITEM, drawable=drawable_component, consumable=consumable_component, ) m.entities.append(consumable)
def add_light(x, y): drawable_component = Drawable(Assets.get().light) light_component = Light(brightness=4) light = Entity( x, y, "Light", render_order=RenderOrder.DECOR, drawable=drawable_component, light=light_component, ) m.entities.append(light)
def __init__(self, godmode): caster_component = Caster(num_slots=3, num_formulas=3) if godmode: fighter_component = Fighter(hp=10, defense=50, power=50) else: fighter_component = Fighter(hp=10, defense=0, power=3) level_component = Level() drawable_component = Drawable(Assets.get().player) super(Player, self).__init__( x=0, y=0, name="You", speed=100, blocks=True, render_order=RenderOrder.ACTOR, fighter=fighter_component, level=level_component, caster=caster_component, drawable=drawable_component, ) self.last_num_explored = None self.moving_towards = None self.godmode = godmode self.ignore_first_click = False
def kill_player(game_state, assets): game_state.player.drawable = Drawable(assets.monster_corpse) game_state.player.render_order = RenderOrder.CORPSE game_state.player.name = "Your corpse" game_state.state = GameStates.PLAYER_DEAD game_state.stats.end_time = datetime.datetime.now() game_state.player.effects.clear() return Message("You died", tcod.red), game_state
def place_stairs(m, chunks): stairs_component = Stairs(m.dungeon_level + 1) drawable_component = Drawable(Assets.get().stairs) posx = chunks[-1].x + chunks[-1].width // 2 posy = chunks[-1].y + chunks[-1].height // 2 down_stairs = Entity( posx, posy, "Stairs", render_order=RenderOrder.STAIRS, stairs=stairs_component, drawable=drawable_component, ) m.entities.append(down_stairs)
def kill_monster(monster, game_state, assets): msg = Message("{} is dead".format(monster.name), tcod.orange) monster.drawable = Drawable(assets.monster_corpse) monster.color = tcod.dark_red monster.blocks = False monster.fighter = None monster.ai = None monster.render_order = RenderOrder.CORPSE monster.name = "Remains of {}".format(monster.name) monster.active = False game_state.timesystem.release(monster) return msg, game_state
def place_stairs(game_map, stairs_data): x = stairs_data["x"] y = stairs_data["y"] stairs_component = Stairs(game_map.dungeon_level + 1) drawable_component = Drawable(Assets.get().stairs) stairs = Entity( x, y, "Stairs", render_order=RenderOrder.STAIRS, stairs=stairs_component, drawable=drawable_component, ) return [stairs]
def load_keys(data, game_map): retr = [] assets = Assets.get() for key_data in data["keys"]: drawable_component = Drawable(assets.key) key = Entity( key_data["x"], key_data["y"], "Key", render_order=RenderOrder.ITEM, key=Key(), drawable=drawable_component, ) retr.append(key) game_map.num_keys_total = len(retr) return retr
def create_pack(hp, defense, power, xp, asset, name): retr = [] packsize = random.randint(1, 3) diffs = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)] clean_diffs = [] for d in diffs: dpos = Pos(x + d[0], y + d[1]) occupied = False if game_map.is_blocked(dpos.x, dpos.y): occupied = True else: for e in entities: if (e.pos == dpos and dpos.x in range(room.x1 + 2, room.x2 - 2) and dpos.y in range(room.y1 + 2, room.y2 - 2)): occupied = True if not occupied: clean_diffs.append(d) if len(clean_diffs) < packsize and len(clean_diffs) < 3: packsize = len(clean_diffs) assert len(clean_diffs) >= packsize for w in range(packsize): diff_idx = random.randint(0, len(clean_diffs) - 1) diff = clean_diffs[diff_idx] wx, wy = x + diff[0], y + diff[1] clean_diffs.remove(diff) fighter_component = Fighter(hp=hp, defense=defense, power=power, xp=xp // packsize) ai = MeleeMonsterAI() drawable_component = Drawable(asset) # randname = "{}-{}".format(name, random.randint(0, 1000)) monster = Monster( wx, wy, name, speed=150, fighter=fighter_component, ai=ai, drawable=drawable_component, ) retr.append(monster) return retr
def add_temporary(self, pos, endpos, lifespan, asset, color=None, wait=None, transform=None): fps_lifespan = lifespan * self.fps_per_second if wait: fps_wait = wait * self.fps_per_second fps_lifespan += wait * self.fps_per_second else: fps_wait = 0 drawable = Drawable(asset) effect = TemporaryVisualEffect( pos, endpos, fps_lifespan, drawable, color, owner=self, wait=fps_wait, transform=transform(fps_lifespan) if transform else None, ) self.temporary_effects.append(effect) return effect
def place_ingredients(m, chunks, ingredient_count): def has_ingredients_left(): for val in ingredient_count.values(): if val > 0: return True def get_ingredient(): while True: ingredient = random.choice(list(ingredient_count.keys())) if ingredient_count[ingredient] > 0: ingredient_count[ingredient] -= 1 return ingredient placed_ingredients = [] # not two ingredients in the same square while has_ingredients_left(): c = random.choice(chunks) occupied = True while occupied: x = random.randint(c.x + 1, c.x + c.width - 2) y = random.randint(c.y + 1, c.y + c.height - 2) occupied = False for ent in m.entities: if ent.pos == Pos(x, y): occupied = True if (x, y) in placed_ingredients: occupied = True placed_ingredients.append((x, y)) drawable_component = Drawable(Assets.get().ingredient) ingredient_component = get_ingredient() name = ingredient_component.name.capitalize() ingredient = Entity( x, y, f"{name} ingredient", render_order=RenderOrder.ITEM, drawable=drawable_component, ingredient=ingredient_component, ) m.entities.append(ingredient)
def place_keys(m, chunks, key_ratio): num_rooms_with_keys = math.floor(len(chunks) * key_ratio) if num_rooms_with_keys > len(chunks[1:-1]): # if it's a map with few rooms num_rooms_with_keys = len(chunks[1:-1]) # sample random rooms but not in the first room, not in the room with stairs rooms_with_keys = random.sample(chunks[1:-1], k=num_rooms_with_keys) placed_keys = [] # not two keys in the same square for _, c in enumerate(rooms_with_keys): occupied = True while occupied: x = random.randint(c.x + 1, c.x + c.width - 2) y = random.randint(c.y + 1, c.y + c.height - 2) occupied = False for cm in c.monsters: if cm.pos == Pos(x, y): occupied = True if (x, y) in placed_keys: occupied = True placed_keys.append((x, y)) drawable_component = Drawable(Assets.get().key) key = Entity(x, y, "Key", render_order=RenderOrder.ITEM, key=Key(), drawable=drawable_component,) m.entities.append(key) m.num_keys_total = num_rooms_with_keys
def get_monster(x, y, game_map, room, monster_choice, entities): assets = Assets.get() def create_pack(hp, defense, power, xp, asset, name): retr = [] packsize = random.randint(1, 3) diffs = [(-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1)] clean_diffs = [] for d in diffs: dpos = Pos(x + d[0], y + d[1]) occupied = False if game_map.is_blocked(dpos.x, dpos.y): occupied = True else: for e in entities: if (e.pos == dpos and dpos.x in range(room.x1 + 2, room.x2 - 2) and dpos.y in range(room.y1 + 2, room.y2 - 2)): occupied = True if not occupied: clean_diffs.append(d) if len(clean_diffs) < packsize and len(clean_diffs) < 3: packsize = len(clean_diffs) assert len(clean_diffs) >= packsize for w in range(packsize): diff_idx = random.randint(0, len(clean_diffs) - 1) diff = clean_diffs[diff_idx] wx, wy = x + diff[0], y + diff[1] clean_diffs.remove(diff) fighter_component = Fighter(hp=hp, defense=defense, power=power, xp=xp // packsize) ai = MeleeMonsterAI() drawable_component = Drawable(asset) # randname = "{}-{}".format(name, random.randint(0, 1000)) monster = Monster( wx, wy, name, speed=150, fighter=fighter_component, ai=ai, drawable=drawable_component, ) retr.append(monster) return retr monsters = [] # tutorial if monster_choice == "idiot": fighter_component = Fighter(hp=1, defense=0, power=0, xp=0) ai = DummyMonsterAI() drawable_component = Drawable(assets.thug) monster = Monster( x, y, "Thug", speed=100, fighter=fighter_component, ai=ai, drawable=drawable_component, ) monsters.append(monster) # easy elif monster_choice == "thug": fighter_component = Fighter(hp=15, defense=0, power=3, xp=40) ai = MeleeMonsterAI() drawable_component = Drawable(assets.thug) monster = Monster( x, y, "Thug", speed=100, fighter=fighter_component, ai=ai, drawable=drawable_component, ) monsters.append(monster) elif monster_choice == "axe_thrower": fighter_component = Fighter(hp=10, defense=0, power=1, xp=40) ai = RangedMonsterAI() drawable_component = Drawable(assets.axe_thrower) monster = Monster( x, y, "Axe thrower", speed=100, fighter=fighter_component, ai=ai, drawable=drawable_component, range=5, ) monsters.append(monster) elif monster_choice == "dog_group": monsters.extend( create_pack(hp=5, defense=0, power=1, xp=40, asset=assets.dog, name="Hound")) # medium elif monster_choice == "mercenary": fighter_component = Fighter(hp=25, defense=5, power=5, xp=100) ai = MeleeMonsterAI() drawable_component = Drawable(assets.mercenary) monster = Monster( x, y, "Mercenary", speed=100, fighter=fighter_component, ai=ai, drawable=drawable_component, ) monsters.append(monster) elif monster_choice == "rifleman": fighter_component = Fighter(hp=15, defense=3, power=3, xp=100) ai = RangedMonsterAI() drawable_component = Drawable(assets.rifleman) monster = Monster( x, y, "Rifleman", speed=100, fighter=fighter_component, ai=ai, drawable=drawable_component, range=5, ) monsters.append(monster) elif monster_choice == "boar_group": monsters.extend( create_pack(hp=10, defense=2, power=3, xp=60, asset=assets.boar, name="Boar")) # hard elif monster_choice == "stalker": fighter_component = Fighter(hp=35, defense=5, power=7, xp=200) ai = MeleeMonsterAI() drawable_component = Drawable(assets.stalker) monster = Monster( x, y, "Stalker", speed=100, fighter=fighter_component, ai=ai, drawable=drawable_component, ) monsters.append(monster) elif monster_choice == "zapper": fighter_component = Fighter(hp=20, defense=3, power=3, xp=200) ai = RangedMonsterAI() drawable_component = Drawable(assets.zapper) monster = Monster( x, y, "Zapper", speed=100, fighter=fighter_component, ai=ai, drawable=drawable_component, range=5, ) monsters.append(monster) elif monster_choice == "armored_bear_group": monsters.extend( create_pack( hp=15, defense=4, power=5, xp=200, asset=assets.armored_bear, name="Panzerbear", )) # end of the world as we know it elif monster_choice == "boss": fighter_component = Fighter(hp=150, defense=15, power=8, xp=0) ai = MeleeMonsterAI() drawable_component = Drawable(assets.boss) monster = Monster( x, y, "Arina", speed=150, fighter=fighter_component, ai=ai, drawable=drawable_component, ) monsters.append(monster) else: raise ValueError("Unknown choice: '{}'".format(monster_choice)) assert monsters return monsters
def __init__( self, x, y ): Point2D.__init__( self, x, y ) Physical.__init__( self ) Drawable.__init__( self )
def doer(drawable): return Drawable([pygame.transform.rotate(drawable.asset, 90)])
def add_attached(self, owner, asset, color=None, transform=None): drawable = Drawable(asset) effect = AttachedVisualEffect(owner, drawable, color, transform) self.attached_effects.append(effect) return effect
def draw_terrain(self, game_data, gfx_data, main): surface = pygame.Surface(game_data.constants.game_window_size.tuple(), pygame.SRCALPHA) surface.fill(colors.BACKGROUND) for x in range(gfx_data.camera.x1, gfx_data.camera.x2): for y in range(gfx_data.camera.y1, gfx_data.camera.y2): visible = tcod.map_is_in_fov(game_data.fov_map, x, y) asset = game_data.map.tiles[x][y].get_drawable(self.show_all or visible) if visible: game_data.map.tiles[x][y].explored = True if asset: distance = (game_data.player.pos - Pos(x, y)).length() if visible: if distance < 3.5: # 1 range darken = 20 elif distance < 5.5: # 2 range darken = 40 elif distance < 7.5: # 3 range darken = 60 else: darken = 80 else: darken = 80 # if visible: darken -= game_data.map.tiles[x][y].light darken = max(0, min(255, darken)) drawable = Drawable(asset) drawable.colorize((darken, darken, darken), pygame.BLEND_RGBA_SUB) sx, sy = gfx_data.camera.map_to_screen(x, y) surface.blit(drawable.asset, (sx * CELL_WIDTH, sy * CELL_HEIGHT)) if game_data.map.tiles[x][y].decor: for decor_drawable in game_data.map.tiles[x][y].decor: drawable = Drawable(decor_drawable.asset) drawable.colorize((darken, darken, darken), pygame.BLEND_RGB_SUB) surface.blit(drawable.asset, (sx * CELL_WIDTH, sy * CELL_HEIGHT)) if game_data.map.tiles[x][y].trap: drawable = Drawable(gfx_data.assets.trap) drawable.colorize((darken, darken, darken), pygame.BLEND_RGB_SUB) surface.blit(drawable.asset, (sx * CELL_WIDTH, sy * CELL_HEIGHT)) main.blit(surface, (0, 0))