def __create_unit(self): """Create the produced unit now.""" productions = self._productions.values() for production in productions: assert isinstance(production, UnitProduction) self.on_production_finished(production.get_produced_units()) for unit, amount in production.get_produced_units().iteritems(): for i in xrange(0, amount): radius = 1 found_tile = False # search for free water tile, and increase search radius if none is found while not found_tile: for coord in Circle(self.instance.position.center(), radius).tuple_iter(): point = Point(coord[0], coord[1]) if self.instance.island.get_tile(point) is None: tile = self.session.world.get_tile(point) if tile is not None and tile.is_water and coord not in self.session.world.ship_map: # execute bypassing the manager, it's simulated on every machine u = CreateUnit(self.instance.owner.worldid, unit, point.x, point.y)(issuer=self.instance.owner) # Fire a message indicating that the ship has been created name = u.get_component(NamedComponent).name self.session.ingame_gui.message_widget.add(string_id='NEW_UNIT', point=point, message_dict={'name' : name}) found_tile = True break radius += 1
def new_session(mapgen=create_map, rng_seed=RANDOM_SEED, human_player = True, ai_players = 0): """ Create a new session with a map, add one human player and a trader (it will crash otherwise). It returns both session and player to avoid making the function-baed tests too verbose. """ session = SPTestSession(horizons.main.db, rng_seed=rng_seed) human_difficulty = DifficultySettings.DEFAULT_LEVEL ai_difficulty = DifficultySettings.EASY_LEVEL players = [] if human_player: players.append({'id': 1, 'name': 'foobar', 'color': Color[1], 'local': True, 'is_ai': False, 'difficulty': human_difficulty}) for i in xrange(ai_players): id = i + human_player + 1 players.append({'id': id, 'name': ('AI' + str(i)), 'color': Color[id], 'local': id == 1, 'is_ai': True, 'difficulty': ai_difficulty}) session.load(mapgen(), players) session.world.init_fish_indexer() # use different trader id here, so that init_new_world can be called # (else there would be a worldid conflict) session.world.trader = Trader(session, 99999 + 42, 'Free Trader', Color()) if ai_players > 0: # currently only ai tests use the ships for player in session.world.players: point = session.world.get_random_possible_ship_position() ship = CreateUnit(player.worldid, UNITS.PLAYER_SHIP_CLASS, point.x, point.y)(issuer=player) # give ship basic resources for res, amount in session.db("SELECT resource, amount FROM start_resources"): ship.get_component(StorageComponent).inventory.alter(res, amount) AIPlayer.load_abstract_buildings(session.db) return session, session.world.player
def init_new_world(self, trader_enabled, pirate_enabled, natural_resource_multiplier): """ This should be called if a new map is loaded (not a savegame, a fresh map). In other words when it is loaded for the first time. NOTE: commands for creating the world objects are executed directly, bypassing the manager This is necessary because else the commands would be transmitted over the wire in network games. @return: the coordinates of the players first ship """ # workaround: the creation of all the objects causes a lot of logging output, we don't need # therefore, reset the levels for now loggers_to_silence = { 'world.production' : None } for logger_name in loggers_to_silence: logger = logging.getLogger(logger_name) loggers_to_silence[logger_name] = logger.getEffectiveLevel() logger.setLevel( logging.WARN ) # add a random number of environmental objects if natural_resource_multiplier != 0: self._add_nature_objects(natural_resource_multiplier) # reset loggers, see above for logger_name, level in loggers_to_silence.iteritems(): logging.getLogger(logger_name).setLevel(level) # add free trader if trader_enabled: self.trader = Trader(self.session, 99999, u"Free Trader", Color()) ret_coords = None for player in self.players: # Adding ships for the players # hack to place the ship on the development map point = self.get_random_possible_ship_position() # Execute command directly, not via manager, because else it would be transmitted over the # network to other players. Those however will do the same thing anyways. ship = CreateUnit(player.worldid, UNITS.PLAYER_SHIP, point.x, point.y)(issuer=self.session.world.player) # give ship basic resources for res, amount in self.session.db("SELECT resource, amount FROM start_resources"): ship.get_component(StorageComponent).inventory.alter(res, amount) if player is self.player: ret_coords = point.to_tuple() # load the AI stuff only when we have AI players if any(isinstance(player, AIPlayer) for player in self.players): AIPlayer.load_abstract_buildings(self.session.db) # TODO: find a better place for this # add a pirate ship if pirate_enabled: self.pirate = Pirate(self.session, 99998, "Captain Blackbeard", Color()) # Fire a message for new world creation self.session.ingame_gui.message_widget.add(None, None, 'NEW_WORLD') assert ret_coords is not None, "Return coords are None. No players loaded?" return ret_coords
def test_hunter_save_load(): """Save/loading hunter in different states""" session, player = new_session() settlement, island = settle(session) # setup hunter, trees (to keep animals close) and animals hunter = Build(BUILDINGS.HUNTER, 30, 30, island, settlement=settlement)(player) hunter_worldid = hunter.worldid del hunter # invalid after save/load for x in xrange(27, 29): for y in xrange(25, 28): assert Build(BUILDINGS.TREE, x, y, island, settlement=settlement)(player) CreateUnit(island.worldid, UNITS.WILD_ANIMAL, 27, 27)(issuer=None) CreateUnit(island.worldid, UNITS.WILD_ANIMAL, 28, 27)(issuer=None) CreateUnit(island.worldid, UNITS.WILD_ANIMAL, 29, 27)(issuer=None) def get_hunter_collector(session): hunter = WorldObject.get_object_by_id(hunter_worldid) return hunter.get_component( CollectingComponent)._CollectingComponent__collectors[0] def await_transition(session, collector, old_state, new_state): assert collector.state == old_state, "expected old state %s, got %s" % ( old_state, collector.state) while collector.state == old_state: session.run(seconds=1) assert collector.state == new_state, "expected new state %s, got %s" % ( old_state, collector.state) sequence = [ Collector.states.idle, Collector.states.waiting_for_animal_to_stop, Collector.states.moving_to_target, Collector.states.working, Collector.states.moving_home, Collector.states.idle ] # do full run without saveload collector = get_hunter_collector(session) for i in xrange(len(sequence) - 1): await_transition(session, collector, sequence[i], sequence[i + 1]) # do full run with saveload for i in xrange(len(sequence) - 1): collector = get_hunter_collector(session) await_transition(session, collector, sequence[i], sequence[i + 1]) session = saveload(session) # last state reached successfully 2 times -> finished session.end()
def setup_combat(s, ship): worldid = 10000000 p0 = Player(s, worldid, "p1", Color.get(1)) p1 = Player(s, worldid + 1, "p2", Color.get(2)) for p in (p0, p1): p.initialize(None) s.world.players.append(p) s0 = CreateUnit(p0.worldid, ship, 0, 0)(issuer=p0) s1 = CreateUnit(p1.worldid, ship, 3, 3)(issuer=p1) return ((p0, s0), (p1, s1))
def create_ship(self): """Create a ship and place it randomly""" self.log.debug("Trader %s: creating new ship", self.worldid) point = self.session.world.get_random_possible_ship_position() ship = CreateUnit(self.worldid, UNITS.TRADER_SHIP, point.x, point.y)(issuer=self) self.ships[ship] = self.shipStates.reached_warehouse Scheduler().add_new_object(Callback(self.ship_idle, ship), self, run_in=0)
def _place_unit(self, unit): radius = 1 found_tile = False while not found_tile: # search for a free tile around the building for tile in self.instance.island.get_surrounding_tiles(self.instance.position.center, radius): point = Point(tile.x, tile.y) if not (tile.is_water or tile.blocked) and (tile.x, tile.y) not in self.session.world.ground_unit_map: u = CreateUnit(self.instance.owner.worldid, unit, tile.x, tile.y)(issuer=self.instance.owner) # Fire a message indicating that the ship has been created name = u.get_component(NamedComponent).name self.session.ingame_gui.message_widget.add(string_id='NEW_SOLDIER', point=point, message_dict={'name': name}) found_tile = True break radius += 1
def __create_unit(self): """Create the produced unit now.""" productions = self._productions.values() for production in productions: assert isinstance(production, UnitProduction) self.on_building_production_finished( production.get_produced_units()) for unit, amount in production.get_produced_units().iteritems(): for i in xrange(0, amount): radius = 1 found_tile = False # search for free water tile, and increase search radius if none is found while not found_tile: for coord in Circle(self.position.center(), radius).tuple_iter(): point = Point(coord[0], coord[1]) if self.island.get_tile(point) is None: tile = self.session.world.get_tile(point) if tile is not None and tile.is_water and coord not in self.session.world.ship_map: CreateUnit(self.owner.worldid, unit, point.x, point.y).execute(self.session) found_tile = True break radius += 1
def add_nature_objects(world, natural_resource_multiplier): """ Place trees, wild animals, fish deposits, clay deposits, and mountains. @param natural_resource_multiplier: multiply the amount of fish deposits, clay deposits, and mountains by this. """ if not int(world.properties.get('RandomTrees', 1)): return add_resource_deposits(world, natural_resource_multiplier) Tree = Entities.buildings[BUILDINGS.TREE] FishDeposit = Entities.buildings[BUILDINGS.FISH_DEPOSIT] fish_directions = [(i, j) for i in xrange(-1, 2) for j in xrange(-1, 2)] # TODO HACK BAD THING hack the component template to make trees start finished Tree.component_templates[1]['ProducerComponent']['start_finished'] = True # add trees, wild animals, and fish for island in world.islands: for (x, y), tile in sorted(island.ground_map.iteritems()): # add tree to every nth tile and an animal to one in every M trees if world.session.random.randint(0, 2) == 0 and \ Tree.check_build(world.session, tile, check_settlement=False): building = Build(Tree, x, y, island, 45 + world.session.random.randint(0, 3) * 90, ownerless=True)(issuer=None) if world.session.random.randint( 0, WILD_ANIMAL.POPULATION_INIT_RATIO ) == 0: # add animal to every nth tree CreateUnit(island.worldid, UNITS.WILD_ANIMAL, x, y)(issuer=None) if world.session.random.random( ) > WILD_ANIMAL.FOOD_AVAILABLE_ON_START: building.get_component(StorageComponent).inventory.alter( RES.WILDANIMALFOOD, -1) if 'coastline' in tile.classes and world.session.random.random( ) < natural_resource_multiplier / 4.0: # try to place fish: from the current position go to a random directions twice for (x_dir, y_dir) in world.session.random.sample(fish_directions, 2): # move a random amount in both directions fish_x = x + x_dir * world.session.random.randint(3, 9) fish_y = y + y_dir * world.session.random.randint(3, 9) # now we have the location, check if we can build here if (fish_x, fish_y) in world.ground_map: Build(FishDeposit, fish_x, fish_y, world, 45 + world.session.random.randint(0, 3) * 90, ownerless=True)(issuer=None) # TODO HACK BAD THING revert hack so trees don't start finished Tree.component_templates[1]['ProducerComponent']['start_finished'] = False
def new_settlement(session, pos=Point(30, 20)): """ Creates a settlement at the given position. It returns the settlement and the island where it was created on, to avoid making function-baed tests too verbose. """ island = session.world.get_island(pos) assert island, "No island found at %s" % pos player = session.world.player ship = CreateUnit(player.worldid, UNITS.PLAYER_SHIP_CLASS, pos.x, pos.y)(player) for res, amount in session.db("SELECT resource, amount FROM start_resources"): ship.get_component(StorageComponent).inventory.alter(res, amount) building = Build(BUILDINGS.WAREHOUSE_CLASS, pos.x, pos.y, island, ship=ship)(player) assert building, "Could not build warehouse at %s" % pos return (building.settlement, island)
def new_settlement(session, pos=Point(30, 20)): """ Creates a settlement at the given position. It returns the settlement and the island where it was created on, to avoid making function-baed tests too verbose. """ island = session.world.get_island(pos) assert island, "No island found at %s" % pos player = session.world.player ship = CreateUnit(player.worldid, UNITS.PLAYER_SHIP, pos.x, pos.y)(player) for res, amount in session.db("SELECT resource, amount FROM start_resources"): ship.get_component(StorageComponent).inventory.alter(res, amount) building = Build(BUILDINGS.WAREHOUSE, pos.x, pos.y, island, ship=ship)(player) assert building, "Could not build warehouse at %s" % pos return (building.settlement, island)
def __place_unit(self, unit): radius = 1 found_tile = False # search for free water tile, and increase search radius if none is found while not found_tile: for coord in Circle(self.instance.position.center, radius).tuple_iter(): point = Point(coord[0], coord[1]) if self.instance.island.get_tile(point) is not None: continue tile = self.session.world.get_tile(point) if tile is not None and tile.is_water and coord not in self.session.world.ship_map: # execute bypassing the manager, it's simulated on every machine u = CreateUnit(self.instance.owner.worldid, unit, point.x, point.y)(issuer=self.instance.owner) # Fire a message indicating that the ship has been created name = u.get_component(NamedComponent).name self.session.ingame_gui.message_widget.add(string_id='NEW_UNIT', point=point, message_dict={'name' : name}) found_tile = True break radius += 1
def __init__(self, session, id, name, color, **kwargs): super(Pirate, self).__init__(session, id, name, color, **kwargs) # create a ship and place it randomly (temporary hack) point = self.session.world.get_random_possible_ship_position() ship = CreateUnit(self.worldid, UNITS.PIRATE_SHIP_CLASS, point.x, point.y)(issuer=self.session.world.player) self.ships[ship] = self.shipStates.idle for ship in self.ships.keys(): Scheduler().add_new_object(Callback(self.send_ship, ship), self) Scheduler().add_new_object(Callback(self.lookout, ship), self, 8, -1)
def reproduce(self): """Create another animal of our type on the place where we stand""" if not self.can_reproduce: return self.log.debug("%s REPRODUCING", self) # create offspring CreateUnit(self.owner.worldid, self.id, self.position.x, self.position.y, \ can_reproduce = self.next_clone_can_reproduce()) # reset own resources for res in self.get_consumed_resources(): self.inventory.reset(res)
def _place_unit(self, unit): radius = 1 found_tile = False while not found_tile: # search for a free tile around the building for tile in self.instance.island.get_surrounding_tiles( self.instance.position.center, radius): point = Point(tile.x, tile.y) if not (tile.is_water or tile.blocked) and ( tile.x, tile.y) not in self.session.world.ground_unit_map: u = CreateUnit(self.instance.owner.worldid, unit, tile.x, tile.y)(issuer=self.instance.owner) # Fire a message indicating that the ship has been created name = u.get_component(NamedComponent).name self.session.ingame_gui.message_widget.add( string_id='NEW_SOLDIER', point=point, message_dict={'name': name}) found_tile = True break radius += 1
def test_hunter(s, p): """ Hunter will produce food from dear meat. No animals were harmed in this test. """ settlement, island = settle(s) hunter = Build(BUILDINGS.HUNTER, 30, 30, island, settlement=settlement)(p) assert hunter assert hunter.get_component(StorageComponent).inventory[RES.FOOD] == 0 assert hunter.get_component(StorageComponent).inventory[RES.DEER_MEAT] == 0 for (x_off, y_off) in product([-5, -4, 4, 5], repeat=2): x = 30 + x_off y = 30 + y_off animal = CreateUnit(island.worldid, UNITS.WILD_ANIMAL, x, y)(None) # wild animals are slow eaters, we feed them directly animal.get_component(StorageComponent).inventory.alter(12, 10) animal.get_component(Producer).finish_production_now() assert animal s.run(seconds=30) assert hunter.get_component(StorageComponent).inventory[RES.FOOD]
def test_unfair(s, p): (p0, s0), (p1, s1) = setup_combat(s, UNITS.FRIGATE) # two against one s0_1 = CreateUnit(p0.worldid, UNITS.FRIGATE, 5, 5)(issuer=p0) AddEnemyPair(p0, p1).execute(s) Attack(s0, s1).execute(s) Attack(s0_1, s1).execute(s) s.run(seconds=60) assert health(s1) == 0 assert health(s0) > 0 assert health(s0_1) > 0
def test_ticket_1352(gui): """ Clicking on a frigate crashes the game. """ player = gui.session.world.player ship = CreateUnit(player.worldid, UNITS.FRIGATE, 68, 10)(player) x, y = ship.position.x, ship.position.y gui.session.view.center(x, y) """ # low-level selection # disabled because it is difficult to select the ship gui.cursor_move(x, y) gui.cursor_click(x, y, 'left') """ gui.select([ship])
def __init__(self, session, id, name, color, **kwargs): super(Pirate, self).__init__(session, id, name, color, **kwargs) # choose a random water tile on the coast and call it home self.home_point = self.session.world.get_random_possible_coastal_ship_position( ) self.log.debug( "Pirate: home at (%d, %d), radius %d" % (self.home_point.x, self.home_point.y, self.home_radius)) # create a ship and place it randomly (temporary hack) point = self.session.world.get_random_possible_ship_position() ship = CreateUnit(self.worldid, UNITS.PIRATE_SHIP_CLASS, point.x, point.y)(issuer=self.session.world.player) self.ships[ship] = self.shipStates.idle self.calculate_visibility_points(ship) for ship in self.ships.keys(): Scheduler().add_new_object(Callback(self.send_ship, ship), self) Scheduler().add_new_object(Callback(self.lookout, ship), self, 8, -1)
def spawn_ships(session, owner_id, ship_id, number, *position): """ Creates a number of ships controlled by a certain player around a position on the map. @param owner_id: the owner worldid @param ship_id: the ship id @param number: number of ships to be spawned @param position: position around the ships to be spawned """ center = Point(*position) player = WorldObject.get_object_by_id(owner_id) # calculate a radius that should fit all the ships # if it doesn't fit them all increase the radius radius = int(math.sqrt(number)) while number != 0: for point in Circle(center, radius): if (point.x, point.y) in session.world.ship_map \ or session.world.get_island(point) is not None: continue CreateUnit(owner_id, ship_id, point.x, point.y)(issuer=player) number -= 1 if number == 0: break radius += 1
def create_ship(type): return CreateUnit( player.worldid, type, *gui.session.world.get_random_possible_ship_position().to_tuple())( issuer=player)
def init_new_world(self, trader_enabled, pirate_enabled, natural_resource_multiplier): """ This should be called if a new map is loaded (not a savegame, a fresh map). In other words, when it is loaded for the first time. NOTE: commands for creating the world objects are executed directly, bypassing the manager. This is necessary because else the commands would be transmitted over the wire in network games. @return: the coordinates of the players first ship """ # workaround: the creation of all the objects causes a lot of logging output we don't need. # therefore, reset the levels for now loggers_to_silence = {'world.production': None} for logger_name in loggers_to_silence: logger = logging.getLogger(logger_name) loggers_to_silence[logger_name] = logger.getEffectiveLevel() logger.setLevel(logging.WARN) # add a random number of environmental objects if natural_resource_multiplier != 0: self._add_nature_objects(natural_resource_multiplier) # reset loggers, see above for logger_name, level in loggers_to_silence.items(): logging.getLogger(logger_name).setLevel(level) # add free trader if trader_enabled: self.trader = Trader(self.session, 99999, "Free Trader", Color()) ret_coords = None for player in self.players: # Adding ships for the players # hack to place the ship on the development map point = self.get_random_possible_ship_position() # Execute command directly, not via manager, because else it would be transmitted over the # network to other players. Those however will do the same thing anyways. ship = CreateUnit(player.worldid, UNITS.PLAYER_SHIP, point.x, point.y)(issuer=self.session.world.player) # give ship basic resources for res, amount in self.session.db( "SELECT resource, amount FROM start_resources"): ship.get_component(StorageComponent).inventory.alter( res, amount) if player is self.player: ret_coords = point.to_tuple() # HACK: Store starting ship as first unit group, and select it def _preselect_player_ship(player_ship): sel_comp = player_ship.get_component(SelectableComponent) sel_comp.select(reset_cam=True) self.session.selected_instances = {player_ship} self.session.ingame_gui.handle_selection_group(1, True) sel_comp.show_menu() select_ship = partial(_preselect_player_ship, ship) Scheduler().add_new_object(select_ship, ship, run_in=0) # load the AI stuff only when we have AI players if any(isinstance(player, AIPlayer) for player in self.players): AIPlayer.load_abstract_buildings( self.session.db) # TODO: find a better place for this # add a pirate ship if pirate_enabled: self.pirate = Pirate(self.session, 99998, "Captain Blackbeard", Color()) assert ret_coords is not None, "Return coords are None. No players loaded?" return ret_coords
def create_ship(type): position = gui.session.world.get_random_possible_ship_position() unit = CreateUnit(player.worldid, type, *position.to_tuple())(issuer=player) gui.run(seconds=0.1) return unit
def remove(s, p, before_ticks, after_ticks, tear_index): """ Place a couple of buildings and tear down one randomly, run a while afterwards. Called by test_removal with different parameters. """ settlement, island = settle(s) settlement.warehouse.get_component( StorageComponent).inventory.adjust_limit(sys.maxint) # Plant trees for (x, y) in product(range(23, 38), repeat=2): if s.random.randint(0, 1) == 1: tree = Build(BUILDINGS.TREE, x, y, island, settlement=settlement)(p) assert tree tree.get_component(Producer).finish_production_now() jack = Build(BUILDINGS.LUMBERJACK, 25, 30, island, settlement=settlement)(p) assert jack jack = Build(BUILDINGS.LUMBERJACK, 35, 30, island, settlement=settlement)(p) assert jack # Throw some fish into the water for x in (25, 30, 35): school = Build(BUILDINGS.FISH_DEPOSIT, x, 18, s.world, ownerless=True)(None) assert school school.get_component(Producer).finish_production_now() fisherman = Build(BUILDINGS.FISHER, 25, 20, island, settlement=settlement)(p) assert fisherman fisherman = Build(BUILDINGS.FISHER, 35, 20, island, settlement=settlement)(p) assert fisherman # Some wild animals in the forest for (x_off, y_off) in product([-5, -4, 4, 5], repeat=2): x = 30 + x_off y = 30 + y_off animal = CreateUnit(island.worldid, UNITS.WILD_ANIMAL, x, y)(None) assert animal animal.get_component(Producer).finish_production_now() hunter = Build(BUILDINGS.HUNTER, 30, 35, island, settlement=settlement)(p) assert hunter # Build a farm assert Build(BUILDINGS.FARM, 26, 33, island, settlement=settlement)(p) assert Build(BUILDINGS.PASTURE, 22, 33, island, settlement=settlement)(p) assert Build(BUILDINGS.PASTURE, 26, 37, island, settlement=settlement)(p) # Build roads for (start, dest) in [(Point(27, 30), Point(30, 23)), (Point(32, 23), Point(35, 29)), (Point(25, 22), Point(30, 23)), (Point(32, 23), Point(35, 22)), (Point(30, 34), Point(32, 25)), (Point(26, 32), Point(27, 30))]: path = RoadPathFinder()(island.path_nodes.nodes, start.to_tuple(), dest.to_tuple()) assert path for (x, y) in path: Build(BUILDINGS.TRAIL, x, y, island, settlement=settlement)(p) s.run(seconds=before_ticks) # Tear down a random building that is not a trail or tree. target = [ b for b in settlement.buildings if b.id not in (BUILDINGS.TRAIL, BUILDINGS.TREE) ][tear_index] Tear(target)(p) s.run(seconds=after_ticks)
def create_ship_at_random_position(self): point = self.session.world.get_random_possible_ship_position() ship = CreateUnit(self.worldid, UNITS.PIRATE_SHIP, point.x, point.y)(issuer=self.session.world.player) self.ships[ship] = self.shipStates.idle self.combat_manager.add_new_unit(ship)
def remove(s, p, before_ticks, after_ticks, tear_index): """ Place a couple of buildings and tear down one randomly, run a while afterwards. Called by test_removal with different parameters. """ settlement, island = settle(s) settlement.warehouse.get_component(StorageComponent).inventory.adjust_limit(sys.maxint) # Plant trees for (x, y) in product(range(23, 38), repeat=2): if s.random.randint(0, 1) == 1: tree = Build(BUILDINGS.TREE, x, y, island, settlement=settlement)(p) assert tree tree.get_component(Producer).finish_production_now() jack = Build(BUILDINGS.LUMBERJACK, 25, 30, island, settlement=settlement)(p) assert jack jack = Build(BUILDINGS.LUMBERJACK, 35, 30, island, settlement=settlement)(p) assert jack # Throw some fish into the water for x in (25, 30, 35): school = Build(BUILDINGS.FISH_DEPOSIT, x, 18, s.world, ownerless=True)(None) assert school school.get_component(Producer).finish_production_now() fisherman = Build(BUILDINGS.FISHER, 25, 20, island, settlement=settlement)(p) assert fisherman fisherman = Build(BUILDINGS.FISHER, 35, 20, island, settlement=settlement)(p) assert fisherman # Some wild animals in the forest for (x_off, y_off) in product([-5, -4, 4, 5], repeat=2): x = 30 + x_off y = 30 + y_off animal = CreateUnit(island.worldid, UNITS.WILD_ANIMAL, x, y)(None) assert animal animal.get_component(Producer).finish_production_now() hunter = Build(BUILDINGS.HUNTER, 30, 35, island, settlement=settlement)(p) assert hunter # Build a farm assert Build(BUILDINGS.FARM, 26, 33, island, settlement=settlement)(p) assert Build(BUILDINGS.PASTURE, 22, 33, island, settlement=settlement)(p) assert Build(BUILDINGS.PASTURE, 26, 37, island, settlement=settlement)(p) # Build roads for (start, dest) in [(Point(27, 30), Point(30, 23)), (Point(32, 23), Point(35, 29)), (Point(25, 22), Point(30, 23)), (Point(32, 23), Point(35, 22)), (Point(30, 34), Point(32, 25)), (Point(26, 32), Point(27, 30))]: path = RoadPathFinder()(island.path_nodes.nodes, start.to_tuple(), dest.to_tuple()) assert path for (x, y) in path: Build(BUILDINGS.TRAIL, x, y, island, settlement=settlement)(p) s.run(seconds=before_ticks) # Tear down a random building that is not a trail or tree. target = [b for b in settlement.buildings if b.id not in (BUILDINGS.TRAIL, BUILDINGS.TREE)][tear_index] Tear(target)(p) s.run(seconds=after_ticks)
def init_new_world(self): """This should be called if a new map is loaded (not a savegame, a fresh map). In other words when it is loaded for the first time. NOTE: commands for creating the world objects are executed directly, bypassing the manager this is necessary, because else the commands would be transmitted over the wire in network games. @return: Returs the coordinates of the players first ship """ # workaround: the creation of all the objects causes a lot of logging output, we don't need # therefore, reset the levels for now loggers_to_silence = {'world.production': None} for logger_name in loggers_to_silence: logger = logging.getLogger(logger_name) loggers_to_silence[logger_name] = logger.getEffectiveLevel() logger.setLevel(logging.WARN) from horizons.command.building import Build from horizons.command.unit import CreateUnit # add a random number of environmental objects to the gameworld if int(self.properties.get('RandomTrees', 1)) == 1: Tree = Entities.buildings[BUILDINGS.TREE_CLASS] Clay = Entities.buildings[BUILDINGS.CLAY_DEPOSIT_CLASS] Fish = Entities.buildings[BUILDINGS.FISH_DEPOSIT_CLASS] Mountain = Entities.buildings[BUILDINGS.MOUNTAIN_CLASS] for island in self.islands: max_clay_deposits = self.session.random.randint(2, 3) max_mountains = self.session.random.randint(1, 3) num_clay_deposits = 0 num_mountains = 0 # TODO: fix this sorted()-call. its slow but orderness of dict-loop isn't guaranteed for coords, tile in sorted(island.ground_map.iteritems()): # add tree to every nth tile if self.session.random.randint(0, 2) == 0 and Tree.check_build(self.session, tile, \ check_settlement=False): building = Build(Tree, coords[0], coords[1], ownerless=True, island=island)(issuer=None) building.finish_production_now( ) # make trees big and fill their inventory if self.session.random.randint( 0, 40) == 0: # add animal to every nth tree CreateUnit(island.worldid, UNITS.WILD_ANIMAL_CLASS, *coords)(issuer=None) elif num_clay_deposits < max_clay_deposits and \ self.session.random.randint(0, 40) == 0 and \ Clay.check_build(self.session, tile, check_settlement=False): num_clay_deposits += 1 Build(Clay, coords[0], coords[1], ownerless=True, island=island)(issuer=None) elif num_mountains < max_mountains and \ self.session.random.randint(0, 40) == 0 and \ Mountain.check_build(self.session, tile, check_settlement=False): num_mountains += 1 Build(Mountain, coords[0], coords[1], ownerless=True, island=island)(issuer=None) if 'coastline' in tile.classes and self.session.random.randint( 0, 4) == 0: # try to place fish # from the current position, go to random directions 2 times directions = [(i, j) for i in xrange(-1, 2) for j in xrange(-1, 2)] for (x_dir, y_dir) in self.session.random.sample( directions, 2): # move a random amount in both directions coord_to_check = ( coords[0] + x_dir * self.session.random.randint(3, 9), coords[1] + y_dir * self.session.random.randint(3, 9), ) # now we have the location, check if we can build here if coord_to_check in self.ground_map: Build(Fish, coord_to_check[0], coord_to_check[1], ownerless=True, \ island=self)(issuer=None) # reset loggers, see above for logger_name, level in loggers_to_silence.iteritems(): logging.getLogger(logger_name).setLevel(level) # add free trader self.trader = Trader(self.session, 99999, u"Free Trader", Color()) ret_coords = None for player in self.players: # Adding ships for the players point = self.get_random_possible_ship_position() # Execute command directly, not via manager, because else it would be transmitted over the # network to other players. Those however will do the same thing anyways. ship = CreateUnit(player.worldid, UNITS.PLAYER_SHIP_CLASS, point.x, point.y)(issuer=self.session.world.player) # give ship basic resources for res, amount in self.session.db( "SELECT resource, amount FROM start_resources"): ship.inventory.alter(res, amount) if player is self.player: ret_coords = (point.x, point.y) # add a pirate ship # TODO: enable pirate as soon as save/load for it is fixed # currently, it breaks human player selection on load #self.pirate = Pirate(self.session, 99998, "Captain Blackbeard", Color()) # Fire a message for new world creation self.session.ingame_gui.message_widget.add(self.max_x / 2, self.max_y / 2, 'NEW_WORLD') assert ret_coords is not None, "Return coords are none. No players loaded?" return ret_coords