def test_settler_level(s, p): """ Verify that settler level up works. """ settlement, island = settle(s) settler = Build(BUILDINGS.RESIDENTIAL, 22, 22, island, settlement=settlement)(p) # make it happy inv = settler.get_component(StorageComponent).inventory to_give = inv.get_free_space_for(RES.HAPPINESS) inv.alter(RES.HAPPINESS, to_give) level = settler.level s.run(seconds=GAME.INGAME_TICK_INTERVAL) # give upgrade res inv.alter(RES.BOARDS, 100) s.run(seconds=GAME.INGAME_TICK_INTERVAL) # should have leveled up assert settler.level == level + 1
def test_ticket_1693(s, p): settlement, island = settle(s) residence = Build(BUILDINGS.RESIDENTIAL, 30, 30, island, settlement=settlement)(p) assert residence.level == 0 # Run and wait until the settler levels down s.run(seconds=250) # get settler ruin tile = island.get_tile(Point(30, 30)) ruin = tile.object assert ruin is not None assert isinstance(ruin, SettlerRuin) assert ruin.owner is not None assert ruin.tearable assert ruin.buildable_upon # Build another one on top of the ruin residence2 = Build(BUILDINGS.RESIDENTIAL, 30, 30, island, settlement=settlement)(p) assert residence2
def test_settler_save_load(): """Save/loading """ session, player = new_session() settlement, island = settle(session) # setup: # 1) build settler # 2) save/load # 3) build main square # -> settler won't load properly and not use the resources and die settler = Build(BUILDINGS.RESIDENTIAL, 25, 22, island, settlement=settlement)(player) assert settler main_square = Build(BUILDINGS.MAIN_SQUARE, 23, 24, island, settlement=settlement)(player) assert main_square main_square.get_component(StorageComponent).inventory.alter(RES.FOOD, 100) session = saveload(session) session.run(seconds=500) tile = session.world.get_tile(Point(25, 22)) # tile will contain ruin in case of failure assert tile.object.id == BUILDINGS.RESIDENTIAL session.end()
def test_load_inactive_production(): """ create a savegame with a inactive production, load it """ session, player = new_session() settlement, island = settle(session) lj = Build(BUILDINGS.LUMBERJACK, 30, 30, island, settlement=settlement)(player) # Set lumberjack to inactive lj.get_component(Producer).set_active(active=False) worldid = lj.worldid session.run(seconds=1) # Save and reload game session = saveload(session) loadedlj = WorldObject.get_object_by_id(worldid) # Make sure it really is not active producer = loadedlj.get_component(Producer) assert not producer.is_active() # Trigger bug #1359 ToggleActive(producer).execute(session) session.end()
def test_productivity_low(session, player): settlement, island = settle(session) lj = Build(BUILDINGS.CHARCOAL_BURNER_CLASS, 30, 30, island, settlement=settlement)(player) called = [False] def add_icon(message): isinstance(message, AddStatusIcon) if message.icon.__class__ == ProductivityLowStatus: called.__setitem__(0, True) session.message_bus.subscribe_globally(AddStatusIcon, add_icon) # precondition assert abs(lj.get_component(Producer).capacity_utilisation) < 0.0001 # Not yet low assert not called[0] session.run(seconds=60) # Now low assert called[0]
def create_lumberjack_production_session(): """Create a saved game with a producing production and then load it.""" session, player = new_session() settlement, island = settle(session) for x in [29, 30, 31, 32]: Build( BUILDINGS.TREE, x, 29, island, settlement=settlement, )(player) building = Build(BUILDINGS.LUMBERJACK, 30, 30, island, settlement=settlement)(player) production = building.get_component(Producer).get_productions()[0] # wait for the lumberjack to start producing while True: if production.get_state() is PRODUCTION.STATES.producing: break session.run(ticks=1) fd1, filename1 = tempfile.mkstemp() os.close(fd1) assert session.save(savegamename=filename1) session.end(keep_map=True) # load the game session = load_session(filename1) return session
def test_settler_save_load(): """Save/loading """ session, player = new_session() settlement, island = settle(session) # setup: # 1) build settler # 2) save/load # 3) build main square # -> settler won't load properly and not use the resources and die settler = Build(BUILDINGS.RESIDENTIAL, 25, 22, island, settlement=settlement)(player) assert settler main_square = Build(BUILDINGS.MAIN_SQUARE, 23, 24, island, settlement=settlement)(player) assert main_square main_square.get_component(StorageComponent).inventory.alter(RES.FOOD, 100) session = saveload(session) session.run(seconds=500) tile = session.world.get_tile(Point(25, 22)) # tile will contain ruin in case of failure assert tile.object.id == BUILDINGS.RESIDENTIAL
def do_build(self): """Acctually builds the previews @return whether it was possible to build anything of the previews.""" # used to check if a building was built with this click, later used to play a sound built = False # acctually do the build and build preparations for building in self.buildings: # remove fife instance, the building will create a new one. # Check if there is a matching fife instance, could be missing # in case of trees, which are hidden if not buildable if building in self.buildings_fife_instances: fife_instance = self.buildings_fife_instances.pop(building) self.renderer.removeColored(fife_instance) self.renderer.removeOutlined(fife_instance) fife_instance.getLocationRef().getLayer().deleteInstance(fife_instance) if building.buildable: island = self.session.world.get_island(building.position.origin) for position in building.position: tile = island.get_tile(position) if tile in self._buildable_tiles: # for some kind of buildabilities, not every coord of the # building is buildable (e.g. fisher: only coastline is marked # as buildable). For those tiles, that are not buildable, # we don't need to do anything. self._buildable_tiles.remove(tile) self.renderer.removeColored(tile._instance) built = True self._remove_listeners() # Remove changelisteners for update_preview # create the command and execute it cmd = Build( building=self._class, x=building.position.origin.x, y=building.position.origin.y, rotation=building.rotation, island=island, settlement=self.session.world.get_settlement(building.position.origin), ship=self.ship, tearset=building.tearset, ) cmd.execute(self.session) else: # check whether to issue a missing res notification # we need the localized resource name here if building in self.buildings_missing_resources: res_name = self.session.db.get_res_name(self.buildings_missing_resources[building]) self.session.ingame_gui.message_widget.add( building.position.origin.x, building.position.origin.y, "NEED_MORE_RES", {"resource": _(res_name)}, ) if built: PlaySound("build").execute(self.session, True) if self.gui is not None: self.gui.hide() self.buildings = [] return built
def do_build(self): """Acctually builds the previews @return whether it was possible to build anything of the previews.""" # used to check if a building was built with this click, later used to play a sound built = False # acctually do the build and build preparations for building in self.buildings: # remove fife instance, the building will create a new one. # Check if there is a matching fife instance, could be missing # in case of trees, which are hidden if not buildable if building in self.buildings_fife_instances: fife_instance = self.buildings_fife_instances.pop(building) self.renderer.removeColored(fife_instance) self.renderer.removeOutlined(fife_instance) fife_instance.getLocationRef().getLayer().deleteInstance( fife_instance) if building.buildable: island = self.session.world.get_island( building.position.origin) for position in building.position: tile = island.get_tile(position) if tile in self._buildable_tiles: # for some kind of buildabilities, not every coord of the # building is buildable (e.g. fisher: only coastline is marked # as buildable). For those tiles, that are not buildable, # we don't need to do anything. self._buildable_tiles.remove(tile) self.renderer.removeColored(tile._instance) built = True self._remove_listeners( ) # Remove changelisteners for update_preview # create the command and execute it cmd = Build(building=self._class, \ x=building.position.origin.x, \ y=building.position.origin.y, \ rotation=building.rotation, \ island= island, \ settlement=self.session.world.get_settlement(building.position.origin), \ ship=self.ship, \ tearset=building.tearset \ ) cmd.execute(self.session) else: # check whether to issue a missing res notification # we need the localized resource name here if building in self.buildings_missing_resources: res_name = self.session.db.get_res_name( self.buildings_missing_resources[building]) self.session.ingame_gui.message_widget.add(building.position.origin.x, \ building.position.origin.y, \ 'NEED_MORE_RES', {'resource' : _(res_name)}) if built: PlaySound("build").execute(self.session, True) if self.gui is not None: self.gui.hide() self.buildings = [] return built
def _build_farm(x, y, island, settlement, owner, *field_type): """ Build a farm at (x, y) and 9 fields of field_type. F F F F X F (X - farm, F - field) F F F """ farm = Build(BUILDINGS.FARM, x, y, island, settlement=settlement)(owner) assert farm, "Failed to build a farm at ({:d}, {:d})".format(x, y) field_offsets = ((-3, -3), (-3, 0), (-3, 3), (0, 3), (3, 3), (3, 0), (3, -3), (0, -3)) assert len(field_type) <= 8, "Too many field types supplied {:d}.".format( len(field_type)) for (x_off, y_off), field_t in zip(field_offsets, field_type): fx = x + x_off fy = x + y_off field = Build(field_t, fx, fy, island, settlement=settlement)(owner) assert field, "Failed to build a field ({:d}) at ({:d}, {:d})".format( field_type, x, y) return farm
def create_lumberjack_production_session(): """Create a saved game with a producing production and then load it.""" session, player = new_session() settlement, island = settle(session) for x in [29, 30, 31, 32]: Build( BUILDINGS.TREE, x, 29, island, settlement=settlement, )(player) building = Build(BUILDINGS.LUMBERJACK, 30, 30, island, settlement=settlement)(player) production = building.get_component(Producer).get_productions()[0] # wait for the lumberjack to start producing while True: if production.get_state() is PRODUCTION.STATES.producing: break session.run(ticks=1) # Save and reload game session = saveload(session) return session
def test_load_inactive_production(): """ create a savegame with a inactive production, load it """ session, player = new_session() settlement, island = settle(session) lj = Build(BUILDINGS.LUMBERJACK, 30, 30, island, settlement=settlement)(player) # Set lumberjack to inactive lj.get_component(Producer).set_active(active = False) worldid = lj.worldid session.run(seconds=1) fd, filename = tempfile.mkstemp() os.close(fd) assert session.save(savegamename=filename) session.end(keep_map=True) # Load game session = load_session(filename) loadedlj = WorldObject.get_object_by_id(worldid) # Make sure it really is not active producer = loadedlj.get_component(Producer) assert not producer.is_active() # Trigger bug #1359 ToggleActive(producer).execute(session) session.end()
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 test_ticket_1427(): """Boatbuilder production progress should be saved properly""" session, player = new_session() settlement, island = settle(session) boat_builder = Build(BUILDINGS.BOATBUILDER_CLASS, 35, 20, island, settlement=settlement)(player) worldid = boat_builder.worldid # Make sure no boards are available settlement.get_component(StorageComponent).inventory.alter(RES.BOARDS_ID, -1000) bb_storage = boat_builder.get_component(StorageComponent) # Add production to use resources bb_producer = boat_builder.get_component(Producer) bb_producer.add_production_by_id(PRODUCTIONLINES.HUKER) production = bb_producer._productions[PRODUCTIONLINES.HUKER] assert production.progress == 0.0 bb_storage.inventory.alter(RES.TEXTILE_ID, 10) bb_storage.inventory.alter(RES.BOARDS_ID, 6) production_line = production._prod_line # Make sure the boatbuilder consumes everything in his inventory session.run(seconds=10) # Check if correctly consumed wood assert production_line.consumed_res[RES.BOARDS_ID] == -2 # Save all production process for later expected_consumed_res = production_line.consumed_res expected_produced_res = production_line.produced_res expected_production = production_line.production expected_progress = production.progress # Make sure the producer used the boards assert bb_storage.inventory[RES.BOARDS_ID] == 0 fd, filename = tempfile.mkstemp() os.close(fd) assert session.save(savegamename=filename) session.end(keep_map=True) # Load game session = load_session(filename) loadedbb = WorldObject.get_object_by_id(worldid) production_loaded = loadedbb.get_component(Producer)._productions[PRODUCTIONLINES.HUKER] production_line_loaded = production_loaded._prod_line # Make sure everything is loaded correctly assert expected_consumed_res == production_line_loaded.consumed_res assert expected_produced_res == production_line_loaded.produced_res assert expected_production == production_line_loaded.production assert expected_progress == production_loaded.progress
def test_ticket_1427(): """Boatbuilder production progress should be saved properly""" session, player = new_session() settlement, island = settle(session) boat_builder = Build(BUILDINGS.BOAT_BUILDER, 35, 20, island, settlement=settlement)(player) worldid = boat_builder.worldid # Make sure no boards are available settlement.get_component(StorageComponent).inventory.alter(RES.BOARDS, -1000) bb_storage = boat_builder.get_component(StorageComponent) # Add production to use resources bb_producer = boat_builder.get_component(Producer) bb_producer.add_production_by_id(PRODUCTIONLINES.HUKER) production = bb_producer._productions[PRODUCTIONLINES.HUKER] assert production.progress == 0.0 bb_storage.inventory.alter(RES.TEXTILE, 10) bb_storage.inventory.alter(RES.BOARDS, 6) production_line = production._prod_line # Make sure the boatbuilder consumes everything in its inventory session.run(seconds=10) # Check if correctly consumed wood assert production_line.consumed_res[RES.BOARDS] == -2 # Save all production process for later expected_consumed_res = production_line.consumed_res expected_produced_res = production_line.produced_res expected_production = production_line.production expected_progress = production.progress # Make sure the producer used the boards assert bb_storage.inventory[RES.BOARDS] == 0 # Save and reload game session = saveload(session) loadedbb = WorldObject.get_object_by_id(worldid) production_loaded = loadedbb.get_component(Producer)._productions[PRODUCTIONLINES.HUKER] production_line_loaded = production_loaded._prod_line # Make sure everything is loaded correctly assert expected_consumed_res == production_line_loaded.consumed_res assert expected_produced_res == production_line_loaded.produced_res assert expected_production == production_line_loaded.production assert expected_progress == production_loaded.progress # if you don't let the session run for a bit then collectors won't be fully initialized and can't be killed => another test will fail in session.end() session.run(seconds=1) session.end()
def test_ticket_1847(s, p): """Tearing down MineProducer (clay pit, mine) crashes game""" settlement, island = settle(s) assert Build(BUILDINGS.CLAY_DEPOSIT, 30, 30, island, ownerless=True)(None) claypit = Build(BUILDINGS.CLAY_PIT, 30, 30, island, settlement=settlement)(p) assert claypit Tear(claypit)(p) s.run(seconds=5)
def test_pavilion_production(s, p): """ Check whether the pavilion produces faith """ settlement, island = settle(s) pavilion = Build(BUILDINGS.PAVILION, 30, 30, island, settlement=settlement)(p) assert pavilion assert pavilion.get_component(StorageComponent).inventory[RES.FAITH] == 0 s.run(seconds=30) assert pavilion.get_component(StorageComponent).inventory[RES.FAITH]
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 test_school_production(s, p): """ Check whether schools produce education """ settlement, island = settle(s) school = Build(BUILDINGS.VILLAGE_SCHOOL, 30, 30, island, settlement=settlement)(p) assert school assert school.get_component(StorageComponent).inventory[RES.EDUCATION] == 0 s.run(seconds=30) assert school.get_component(StorageComponent).inventory[RES.EDUCATION]
def test_saltpond_production(s, p): """ Check whether saltponds produce salt """ settlement, island = settle(s) saltpond = Build(BUILDINGS.SALT_PONDS, 25, 20, island, settlement=settlement)(p) assert saltpond assert saltpond.get_component(StorageComponent).inventory[RES.SALT] == 0 s.run(seconds=60) assert saltpond.get_component(StorageComponent).inventory[RES.SALT] >= 2 # ponds produce salt in units of 2
def test_ticket_1005(s, p): settlement, island = settle(s) assert len(s.world.ships) == 2 builder = Build(BUILDINGS.BOATBUILDER_CLASS, 35, 20, island, settlement=settlement)(p) builder.inventory.alter(RES.TEXTILE_ID, 5) builder.inventory.alter(RES.BOARDS_ID, 4) builder.add_production_by_id(15) s.run(seconds=130) assert len(s.world.ships) == 3
def test_decommissioned(session, player): settlement, island = settle(session) lj = Build(BUILDINGS.LUMBERJACK, 30, 30, island, settlement=settlement)(player) cb = mock.Mock() AddStatusIcon.subscribe(cb) assert not cb.called ToggleActive(lj.get_component(Producer))(player) assert_called_with_icon(cb, DecommissionedStatus)
def test_ticket_1561(s, p): settlement, island = settle(s) residence = Build(BUILDINGS.RESIDENTIAL, 30, 30, island, settlement=settlement)(p) s.run(ticks=1) assert residence.level == 0 residence.level_up() s.run(ticks=1) assert residence.level == 1 residence2 = Build(BUILDINGS.RESIDENTIAL, 30, 32, island, settlement=settlement)(p) s.run(ticks=1) assert residence2.level == 0
def test_tool_production_chain(s, p): """ Check if a iron mine gathers raw iron, a smeltery produces iron ingots, boards are converted to charcoal and tools are produced. Pretty much for a single test, but these are rather trivial in their assertions anyway. """ settlement, island = settle(s) assert Build(BUILDINGS.MOUNTAIN, 30, 35, island, ownerless=True)(None) assert Build(BUILDINGS.IRON_MINE, 30, 35, island, settlement=settlement)(p) charcoal = Build(BUILDINGS.CHARCOAL_BURNER, 25, 35, island, settlement=settlement)(p) assert charcoal charcoal.get_component(StorageComponent).inventory.alter(RES.BOARDS, 10) # give him boards directly assert Build(BUILDINGS.SMELTERY, 25, 30, island, settlement=settlement)(p) toolmaker = Build(BUILDINGS.TOOLMAKER, 22, 32, island, settlement=settlement)(p) assert toolmaker toolmaker.get_component(StorageComponent).inventory.alter(RES.BOARDS, 10) # give him boards directly assert toolmaker.get_component(StorageComponent).inventory[RES.TOOLS] == 0 s.run(seconds=120) assert toolmaker.get_component(StorageComponent).inventory[RES.TOOLS]
def test_pastryshop_production_chain(s, p): """ The pastryshop makes candles and sugar out of honeycombs. Sugar is later used in combination with grapes and cocoa to produce confectioneries. Honeycombs, cocoa and grapes are generated at a farm. """ settlement, island = settle(s) assert Build(BUILDINGS.FARM, 30, 30, island, settlement=settlement)(p) assert Build(BUILDINGS.COCOA_FIELD, 26, 30, island, settlement=settlement)(p) assert Build(BUILDINGS.VINEYARD, 30, 34, island, settlement=settlement)(p) assert Build(BUILDINGS.ALVEARIES, 34, 30, island, settlement=settlement)(p) pastryshop = Build(BUILDINGS.PASTRY_SHOP, 30, 26, island, settlement=settlement)(p) assert pastryshop assert pastryshop.get_component(StorageComponent).inventory[RES.HONEYCOMBS] == 0 assert pastryshop.get_component(StorageComponent).inventory[RES.SUGAR] == 0 assert pastryshop.get_component(StorageComponent).inventory[RES.COCOA] == 0 assert pastryshop.get_component(StorageComponent).inventory[RES.GRAPES] == 0 assert pastryshop.get_component(StorageComponent).inventory[RES.CANDLES] == 0 assert pastryshop.get_component(StorageComponent).inventory[RES.CONFECTIONERY] == 0 s.run(seconds=120) # 30s alvearies, 30s vineyard, 30s cocoa field, 45s pastry shop assert pastryshop.get_component(StorageComponent).inventory[RES.CANDLES] assert pastryshop.get_component(StorageComponent).inventory[RES.CONFECTIONERY] >= 2
def test_ticket_979(s, p): settlement, island = settle(s) storage_collectors = settlement.warehouse.get_component(CollectingComponent).get_local_collectors() farm = _build_farm(30, 30, island, settlement, p, BUILDINGS.POTATO_FIELD) # Let it work for a bit s.run(seconds=60) assert farm.get_component(StorageComponent).inventory[RES.FOOD] # Depending on auto unloading (which we aren't interested in here), # the settlement inventory may already be full of food: dispose of it settlement.get_component(StorageComponent).inventory.alter(RES.FOOD, -settlement.get_component(StorageComponent).inventory[RES.FOOD]) assert settlement.get_component(StorageComponent).inventory[RES.FOOD] == 0 # Build a road, connecting farm and warehouse for y in range(23, 30): assert Build(BUILDINGS.TRAIL, 30, y, island, settlement=settlement)(p) # Step forward in time until a collector picked a job got_job = False while not got_job: s.run() if any(c.job for c in storage_collectors): got_job = True Tear(farm)(p) # Let the collector reach the not existing target s.run(seconds=10)
def test_distillery(s, p): """ Distillery produces liquor out of sugar. A farm will collect raw sugar from a sugar field and produce sugar. """ settlement, island = settle(s) _build_farm(30, 30, BUILDINGS.SUGARCANE_FIELD, island, settlement, p) distillery = Build(BUILDINGS.DISTILLERY, 27, 30, island, settlement=settlement)(p) assert distillery assert distillery.get_component(StorageComponent).inventory[RES.LIQUOR] == 0 s.run(seconds=60) # sugarfield 30s, farm 1s, distillery 12s assert distillery.get_component(StorageComponent).inventory[RES.LIQUOR]
def execute(self, land_manager, ship=None): """Build the building.""" building_class = Entities.buildings[self.building_id] building_level = building_class.get_initial_level(land_manager.owner) action_set_id = building_class.get_random_action_set( level=building_level) build_position = Entities.buildings[self.building_id].check_build( land_manager.session, Point(*self.coords), rotation=self.rotations[self.orientation], check_settlement=(ship is None), ship=ship, issuer=land_manager.owner) assert build_position.buildable cmd = Build(self.building_id, self.coords[0], self.coords[1], land_manager.island, self._get_rotation(land_manager.session, build_position.rotation), settlement=land_manager.settlement, ship=ship, tearset=build_position.tearset, action_set_id=action_set_id) result = cmd(land_manager.owner) assert result return result
def _set_entry(button, icon, building_id): """Configure a single build menu button""" if self.unlocking_strategy == self.__class__.unlocking_strategies.single_per_increment and \ self.get_building_increments()[building_id] > self.session.world.player.settler_level: return building = Entities.buildings[building_id] button.helptext = self.session.db.get_building_tooltip(building_id) enough_res = False # don't show building by default if settlement is not None: # settlement is None when the mouse has left the settlement res_overview = self.session.ingame_gui.resource_overview button.mapEvents({ button.name+"/mouseEntered/buildtab" : Callback(res_overview.set_construction_mode, settlement, building.costs), button.name+"/mouseExited/buildtab" : res_overview.close_construction_mode }) (enough_res, missing_res) = Build.check_resources({}, building.costs, settlement.owner, [settlement]) #check whether to disable build menu icon (not enough res available) if enough_res: icon.image = "content/gui/images/buttons/buildmenu_button_bg.png" path = "content/gui/icons/buildmenu/{id:03d}{{mode}}.png".format(id=building_id) button.down_image = path.format(mode='_h') button.hover_image = path.format(mode='_h') else: icon.image = "content/gui/images/buttons/buildmenu_button_bg_bw.png" path = "content/gui/icons/buildmenu/greyscale/{id:03d}{{mode}}.png".format(id=building_id) button.down_image = path.format(mode='') button.hover_image = path.format(mode='') button.up_image = path.format(mode='') button.capture(Callback(self.build_callback, building_id))
def test_settler_unhappy(session, player): settlement, island = settle(session) cb = mock.Mock() AddStatusIcon.subscribe(cb) settler = Build(BUILDINGS.RESIDENTIAL, 30, 30, island, settlement=settlement)(player) # certainly not unhappy assert settler.happiness > 0.45 assert not cb.called # make it unhappy settler.get_component(StorageComponent).inventory.alter(RES.HAPPINESS, -settler.happiness) assert settler.happiness < 0.1 assert_called_with_icon(cb, SettlerUnhappyStatus)
def test_weaver(s, p): """ A weaver produces textiles from wool. A pasture provides lamb wool for a farm, which it converts to wool for the weaver. """ settlement, island = settle(s) _build_farm(30, 30, BUILDINGS.PASTURE, island, settlement, p) weaver = Build(BUILDINGS.WEAVER, 27, 30, island, settlement=settlement)(p) assert weaver assert weaver.get_component(StorageComponent).inventory[RES.TEXTILE] == 0 s.run(seconds=60) # pasture 30s, farm 1s, weaver 12s assert weaver.get_component(StorageComponent).inventory[RES.TEXTILE]
def test_tree_production(s, p): """Check whether trees produce wood""" settlement, island = settle(s) tree = Build(BUILDINGS.TREE, 30, 35, island, settlement=settlement)(p) n = 20 inv = tree.get_component(StorageComponent).inventory for i in xrange(n): # we want n units while not inv[RES.TREES]: s.run(seconds=5) # take one away to free storage space #from tests import set_trace ; set_trace() inv.alter(RES.TREES, -1)
def place_objects(locations, max_objects, object_class): """Place at most max_objects objects of the given class.""" if not locations: return total_sum = [0] last_sum = 0 for value in zip(*locations)[0]: last_sum += value total_sum.append(last_sum) for _unused1 in xrange(max_objects): for _unused2 in xrange(7): # try to place the object 7 times object_sum = world.session.random.random() * last_sum pos = bisect.bisect_left(total_sum, object_sum, 0, len(total_sum) - 2) x, y = locations[pos][1] if object_class.check_build(world.session, Point(x, y), check_settlement=False): Build(object_class, x, y, locations[pos][2], 45 + world.session.random.randint(0, 3) * 90, ownerless=True)(issuer=None) break
def test_brick_production_chain(s, p): """ A brickyard makes bricks from clay. Clay is collected by a clay pit on a deposit. """ settlement, island = settle(s) assert Build(BUILDINGS.CLAY_DEPOSIT, 30, 30, island, ownerless=True)(None) assert Build(BUILDINGS.CLAY_PIT, 30, 30, island, settlement=settlement)(p) brickyard = Build(BUILDINGS.BRICKYARD, 30, 25, island, settlement=settlement)(p) assert brickyard.get_component(StorageComponent).inventory[RES.BRICKS] == 0 assert brickyard.get_component(StorageComponent).inventory[RES.CLAY] == 0 s.run(seconds=60) # 15s clay pit, 15s brickyard assert brickyard.get_component(StorageComponent).inventory[RES.BRICKS]
def test_saltpond_production(s, p): """ Check whether saltponds produce salt """ settlement, island = settle(s) saltpond = Build(BUILDINGS.SALT_PONDS, 25, 20, island, settlement=settlement)(p) assert saltpond assert saltpond.get_component(StorageComponent).inventory[RES.SALT] == 0 s.run(seconds=60) assert saltpond.get_component(StorageComponent).inventory[ RES.SALT] >= 2 # ponds produce salt in units of 2
def have_resources(self, extra_resources = None): """Return a boolean showing whether we have the resources to build the building right now.""" # the copy has to be made because Build.check_resources modifies it extra_resources = copy.copy(extra_resources) if extra_resources is not None else {} inventories = [self.land_manager.settlement, self.ship] (enough_res, _) = Build.check_resources(extra_resources, \ Entities.buildings[self.building_id].costs, self.land_manager.owner, inventories) return enough_res
def test_blender_production_chain(s, p): """ Spices are grown in spice fields and processed by the blender into condiments """ settlement, island = settle(s) assert Build(BUILDINGS.FARM, 30, 30, island, settlement=settlement)(p) assert Build(BUILDINGS.SPICE_FIELD, 26, 30, island, settlement=settlement)(p) blender = Build(BUILDINGS.BLENDER, 30, 26, island, settlement=settlement)(p) assert blender assert blender.get_component(StorageComponent).inventory[RES.CONDIMENTS] == 0 assert blender.get_component(StorageComponent).inventory[RES.SPICES] == 0 s.run(seconds=120) # 2x 30s spicefield, 15s blender assert blender.get_component(StorageComponent).inventory[RES.CONDIMENTS]
def test_winery_production_chain(s, p): """ Grapes are grown in a vineyard processed into liquor at a winery """ settlement, island = settle(s) assert Build(BUILDINGS.FARM, 30, 30, island, settlement=settlement)(p) assert Build(BUILDINGS.VINEYARD, 26, 30, island, settlement=settlement)(p) winery = Build(BUILDINGS.WINERY, 30, 26, island, settlement=settlement)(p) assert winery assert winery.get_component(StorageComponent).inventory[RES.GRAPES] == 0 assert winery.get_component(StorageComponent).inventory[RES.LIQUOR] == 0 s.run(seconds=120) # 2x 30s vineyard, 15s winery assert winery.get_component(StorageComponent).inventory[RES.LIQUOR]
def test_brewery_production_chain(s, p): """ Hops are generated by hop fields and transferred to the brewery for beer production """ settlement, island = settle(s) assert Build(BUILDINGS.FARM, 30, 30, island, settlement=settlement)(p) assert Build(BUILDINGS.HOP_FIELD, 26, 30, island, settlement=settlement)(p) brewery = Build(BUILDINGS.BREWERY, 30, 26, island, settlement=settlement)(p) assert brewery assert brewery.get_component(StorageComponent).inventory[RES.HOPS] == 0 assert brewery.get_component(StorageComponent).inventory[RES.BEER] == 0 s.run(seconds=60) # 26s hop field, 12s brewery assert brewery.get_component(StorageComponent).inventory[RES.BEER]
def remove(self): # build the deposit back here after remove() is finished deposit_build_data = {'inventory': self.inventory.get_dump()} build_cmd = Build(self.__deposit_class, self.position.origin.x, self.position.origin.y, \ self.island, ownerless=True, data = deposit_build_data) Scheduler().add_new_object(build_cmd, build_cmd, run_in=0) super(Mine, self).remove()
def test_stonemason_production_chain(s, p): """ Stone tops are collected at a stone pit from a stone deposit and processed into bricks by a stonemason """ settlement, island = settle(s) assert Build(BUILDINGS.STONE_DEPOSIT, 30, 30, island, ownerless=True)(None) assert Build(BUILDINGS.STONE_PIT, 30, 30, island, settlement=settlement)(p) stonemason = Build(BUILDINGS.STONEMASON, 30, 25, island, settlement=settlement)(p) assert stonemason assert stonemason.get_component(StorageComponent).inventory[RES.STONE_TOPS] == 0 assert stonemason.get_component(StorageComponent).inventory[RES.BRICKS] == 0 s.run(seconds=60) # 15s stone pit, 30s stonemason assert stonemason.get_component(StorageComponent).inventory[RES.BRICKS]
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 test_distillery_production_chain(s, p): """ Raw sugar is generated by sugarcane fields and transferred to the distillery for liquor production """ settlement, island = settle(s) assert Build(BUILDINGS.FARM, 30, 30, island, settlement=settlement)(p) assert Build(BUILDINGS.SUGARCANE_FIELD, 26, 30, island, settlement=settlement)(p) distillery = Build(BUILDINGS.DISTILLERY, 30, 26, island, settlement=settlement)(p) assert distillery assert distillery.get_component(StorageComponent).inventory[RES.SUGAR] == 0 assert distillery.get_component(StorageComponent).inventory[ RES.LIQUOR] == 0 s.run(seconds=60) # 30s sugarcane field, 12s distillery assert distillery.get_component(StorageComponent).inventory[RES.LIQUOR]
def test_tobbaconist_production_chain(s, p): """ Tobacco is generated by tobacco fields and transferred to the tobacconist for tobacco products making """ settlement, island = settle(s) assert Build(BUILDINGS.FARM, 30, 30, island, settlement=settlement)(p) assert Build(BUILDINGS.TOBACCO_FIELD, 26, 30, island, settlement=settlement)(p) tobacconist = Build(BUILDINGS.TOBACCONIST, 30, 26, island, settlement=settlement)(p) assert tobacconist assert tobacconist.get_component(StorageComponent).inventory[ RES.TOBACCO_LEAVES] == 0 assert tobacconist.get_component(StorageComponent).inventory[ RES.TOBACCO_PRODUCTS] == 0 s.run(seconds=120) # 30s tobacco field, 15s tobacconist assert tobacconist.get_component(StorageComponent).inventory[ RES.TOBACCO_PRODUCTS]
def test_settler_level_save_load(s, p): """ Verify that settler level up with save/load works """ # test all available upgrades: 0->1, 1->2, 2->3... for test_level in xrange(TIER.CURRENT_MAX): session, player = new_session() settlement, island = settle(s) settler = Build(BUILDINGS.RESIDENTIAL, 22, 22, island, settlement=settlement)(p) settler.level += test_level settler_worldid = settler.worldid # make it happy inv = settler.get_component(StorageComponent).inventory to_give = inv.get_free_space_for(RES.HAPPINESS) inv.alter(RES.HAPPINESS, to_give) level = settler.level # wait for it to realize it's supposed to upgrade s.run(seconds=GAME.INGAME_TICK_INTERVAL) session = saveload(session) settler = WorldObject.get_object_by_id(settler_worldid) inv = settler.get_component(StorageComponent).inventory # continue s.run(seconds=GAME.INGAME_TICK_INTERVAL) assert settler.level == level # give upgrade res inv.alter(RES.BOARDS, 100) inv.alter(RES.BRICKS, 100) # give it max population settler.inhabitants = settler.inhabitants_max s.run(seconds=GAME.INGAME_TICK_INTERVAL) # should have leveled up assert settler.level == level + 1
def test_bakery_production_chain(s, p): """ Corn is grown in cornfields, milled into flour in a windmill and finally turned into food by a bakery """ settlement, island = settle(s) assert Build(BUILDINGS.FARM, 30, 30, island, settlement=settlement)(p) assert Build(BUILDINGS.CORN_FIELD, 26, 30, island, settlement=settlement)(p) assert Build(BUILDINGS.WINDMILL, 30, 34, island, settlement=settlement)(p) bakery = Build(BUILDINGS.BAKERY, 30, 26, island, settlement=settlement)(p) assert bakery assert bakery.get_component(StorageComponent).inventory[RES.FLOUR] == 0 assert bakery.get_component(StorageComponent).inventory[RES.FOOD] == 0 s.run(seconds=120) # 26s cornfield, 15s windmill, 15s bakery assert bakery.get_component(StorageComponent).inventory[RES.FOOD]
def test_weaver_production_chain(s, p): """ Lamb wool is generated by sheep at a pasture to be later transferred to a weaver for textile production """ settlement, island = settle(s) assert Build(BUILDINGS.FARM, 30, 30, island, settlement=settlement)(p) assert Build(BUILDINGS.PASTURE, 26, 30, island, settlement=settlement)(p) weaver = Build(BUILDINGS.WEAVER, 30, 26, island, settlement=settlement)(p) assert weaver assert weaver.get_component(StorageComponent).inventory[RES.WOOL] == 0 assert weaver.get_component(StorageComponent).inventory[RES.TEXTILE] == 0 s.run(seconds=60) # 30s pasture, 30s weaver assert weaver.get_component(StorageComponent).inventory[RES.TEXTILE]
def test_distillery_production_chain(s, p): """ Raw sugar is generated by sugarcane fields and transferred to the distillery for liquor production """ settlement, island = settle(s) assert Build(BUILDINGS.FARM, 30, 30, island, settlement=settlement)(p) assert Build(BUILDINGS.SUGARCANE_FIELD, 26, 30, island, settlement=settlement)(p) distillery = Build(BUILDINGS.DISTILLERY, 30, 26, island, settlement=settlement)(p) assert distillery assert distillery.get_component(StorageComponent).inventory[RES.SUGAR] == 0 assert distillery.get_component(StorageComponent).inventory[RES.LIQUOR] == 0 s.run(seconds=60) # 30s sugarcane field, 12s distillery assert distillery.get_component(StorageComponent).inventory[RES.LIQUOR]
def make_ruin(self): """ Replaces itself with a ruin. """ command = Build(BUILDINGS.SETTLER_RUIN, self.position.origin.x, self.position.origin.y, island=self.island, settlement=self.settlement) # Remove the building and then place the Ruin Scheduler().add_new_object(Callback.ChainedCallbacks( self.remove, Callback(command, self.owner)), self, run_in=0)
def test_tobbaconist_production_chain(s, p): """ Tobacco is generated by tobacco fields and transferred to the tobacconist for tobacco products making """ settlement, island = settle(s) assert Build(BUILDINGS.FARM, 30, 30, island, settlement=settlement)(p) assert Build(BUILDINGS.TOBACCO_FIELD, 26, 30, island, settlement=settlement)(p) tobacconist = Build(BUILDINGS.TOBACCONIST, 30, 26, island, settlement=settlement)(p) assert tobacconist assert tobacconist.get_component(StorageComponent).inventory[RES.TOBACCO_LEAVES] == 0 assert tobacconist.get_component(StorageComponent).inventory[RES.TOBACCO_PRODUCTS] == 0 s.run(seconds=120) # 30s tobacco field, 15s tobacconist assert tobacconist.get_component(StorageComponent).inventory[RES.TOBACCO_PRODUCTS]