Exemple #1
0
	def _do_save(self, savegame):
		"""Actual save code.
		@param savegame: absolute path"""
		assert os.path.isabs(savegame)
		self.log.debug("Session: Saving to %s", savegame)
		try:
			if os.path.exists(savegame):
				os.unlink(savegame)
			self.savecounter += 1

			db = DbReader(savegame)
		except IOError as e: # usually invalid filename
			headline = _("Failed to create savegame file")
			descr = _("There has been an error while creating your savegame file.")
			advice = _("This usually means that the savegame name contains unsupported special characters.")
			self.gui.show_error_popup(headline, descr, advice, unicode(e))
			return self.save() # retry with new savegamename entered by the user
			# this must not happen with quicksave/autosave
		except ZeroDivisionError as err:
			# TODO:
			# this should say WindowsError, but that somehow now leads to a NameError
			if err.winerror == 5:
				self.gui.show_error_popup(_("Access is denied"), \
				                          _("The savegame file is probably read-only."))
				return self.save()
			elif err.winerror == 32:
				self.gui.show_error_popup(_("File used by another process"), \
				                          _("The savegame file is currently used by another program."))
				return self.save()
			raise

		try:
			read_savegame_template(db)

			db("BEGIN")
			self.world.save(db)
			#self.manager.save(db)
			self.view.save(db)
			self.ingame_gui.save(db)
			self.scenario_eventhandler.save(db)
			LastActivePlayerSettlementManager().save(db)

			for instance in self.selected_instances:
				db("INSERT INTO selected(`group`, id) VALUES(NULL, ?)", instance.worldid)
			for group in xrange(len(self.selection_groups)):
				for instance in self.selection_groups[group]:
					db("INSERT INTO selected(`group`, id) VALUES(?, ?)", group, instance.worldid)

			rng_state = json.dumps( self.random.getstate() )
			SavegameManager.write_metadata(db, self.savecounter, rng_state)
			# make sure everything get's written now
			db("COMMIT")
			db.close()
			return True
		except:
			print "Save Exception"
			traceback.print_exc()
			db.close() # close db before delete
			os.unlink(savegame) # remove invalid savegamefile
			return False
	def _create_map_db(self, savepath):
		"""Returns a dbreader instance, that is connected to the main game data dbfiles."""
		horizons.main.PATHS.SAVEGAME_TEMPLATE = os.path.join(util.getUHPath(), horizons.main.PATHS.SAVEGAME_TEMPLATE)

		db = UhDbAccessor(savepath)
		read_savegame_template(db)
		return db
Exemple #3
0
    def _do_save(self, savegame):
        """Actual save code.
		@param savegame: absolute path"""
        assert os.path.isabs(savegame)
        self.log.debug("Session: Saving to %s", savegame)
        try:
            if os.path.exists(savegame):
                os.unlink(savegame)
            self.savecounter += 1

            db = DbReader(savegame)
        except IOError as e:  # usually invalid filename
            headline = T("Failed to create savegame file")
            descr = T(
                "There has been an error while creating your savegame file.")
            advice = T(
                "This usually means that the savegame name contains unsupported special characters."
            )
            self.ingame_gui.open_error_popup(headline, descr, advice,
                                             unicode(e))
            # retry with new savegamename entered by the user
            # (this must not happen with quicksave/autosave)
            return self.save()
        except OSError as e:
            if e.errno != errno.EACCES:
                raise
            self.ingame_gui.open_error_popup(
                T("Access is denied"),
                T("The savegame file could be read-only or locked by another process."
                  ))
            return self.save()

        try:
            read_savegame_template(db)

            db("BEGIN")
            self.world.save(db)
            self.view.save(db)
            self.ingame_gui.save(db)
            self.scenario_eventhandler.save(db)

            # Store RNG state
            rng_state = json.dumps(self.random.getstate())
            SavegameManager.write_metadata(db, self.savecounter, rng_state)

            # Make sure everything gets written now
            db("COMMIT")
            db.close()
            return True
        except Exception:
            self.log.error("Save Exception:")
            traceback.print_exc()
            # remove invalid savegamefile (but close db connection before deleting)
            db.close()
            os.unlink(savegame)
            return False
	def _do_save(self, savegame):
		"""Actual save code.
		@param savegame: absolute path"""
		assert os.path.isabs(savegame)
		self.log.debug("Session: Saving to %s", savegame)
		try:
			if os.path.exists(savegame):
				os.unlink(savegame)
			self.savecounter += 1

			db = DbReader(savegame)
		except IOError as e: # usually invalid filename
			headline = _("Failed to create savegame file")
			descr = _("There has been an error while creating your savegame file.")
			advice = _("This usually means that the savegame name contains unsupported special characters.")
			self.ingame_gui.show_error_popup(headline, descr, advice, unicode(e))
			# retry with new savegamename entered by the user
			# (this must not happen with quicksave/autosave)
			return self.save()
		except OSError as e:
			if e.errno != errno.EACCES:
				raise
			self.ingame_gui.show_error_popup(
				_("Access is denied"),
				_("The savegame file could be read-only or locked by another process.")
			)
			return self.save()

		try:
			read_savegame_template(db)

			db("BEGIN")
			self.world.save(db)
			self.view.save(db)
			self.ingame_gui.save(db)
			self.scenario_eventhandler.save(db)

			# Store RNG state
			rng_state = json.dumps(self.random.getstate())
			SavegameManager.write_metadata(db, self.savecounter, rng_state)

			# Make sure everything gets written now
			db("COMMIT")
			db.close()
			return True
		except Exception:
			self.log.error("Save Exception:")
			traceback.print_exc()
			# remove invalid savegamefile (but close db connection before deleting)
			db.close()
			os.unlink(savegame)
			return False
def save_map(world, path, prefix):
	map_file = os.path.join(path, prefix + '.sqlite')
	db = DbReader(map_file)
	read_savegame_template(db)
	db('BEGIN')
	for island in world.islands:
		island_name = '%s_island_%d_%d.sqlite' % (prefix, island.origin.x, island.origin.y)
		island_db_path = os.path.join(path, island_name)
		if os.path.exists(island_db_path):
			os.unlink(island_db_path) # the process relies on having an empty file
		db('INSERT INTO island (x, y, file) VALUES(?, ?, ?)', island.origin.x, island.origin.y, 'content/islands/' + island_name)
		island_db = DbReader(island_db_path)
		island.save_map(island_db)
		island_db.close()
	db('COMMIT')
	db.close()
Exemple #6
0
def save_map(world, path, prefix):
    map_file = os.path.join(path, prefix + '.sqlite')
    db = DbReader(map_file)
    read_savegame_template(db)
    db('BEGIN')
    for island in world.islands:
        island_name = '%s_island_%d_%d.sqlite' % (prefix, island.origin.x,
                                                  island.origin.y)
        island_db_path = os.path.join(path, island_name)
        if os.path.exists(island_db_path):
            os.unlink(
                island_db_path)  # the process relies on having an empty file
        db('INSERT INTO island (x, y, file) VALUES(?, ?, ?)', island.origin.x,
           island.origin.y, 'content/islands/' + island_name)
        island_db = DbReader(island_db_path)
        island.save_map(island_db)
        island_db.close()
    db('COMMIT')
    db.close()
Exemple #7
0
def create_map():
	"""
	Create a map with a square island (20x20) at position (20, 20) and return the path
	to the database file.
	"""

	# Create island.
	fd, islandfile = tempfile.mkstemp()
	os.close(fd)

	db = DbReader(islandfile)
	db("CREATE TABLE ground(x INTEGER NOT NULL, y INTEGER NOT NULL, ground_id INTEGER NOT NULL, action_id TEXT NOT NULL, rotation INTEGER NOT NULL)")
	db("CREATE TABLE island_properties(name TEXT PRIMARY KEY NOT NULL, value TEXT NOT NULL)")

	db("BEGIN TRANSACTION")
	tiles = []
	for x, y in Rect.init_from_topleft_and_size(0, 0, 20, 20).tuple_iter():
		if (0 < x < 20) and (0 < y < 20):
			ground = GROUND.DEFAULT_LAND
		else:
			# Add coastline at the borders.
			ground = GROUND.SHALLOW_WATER
		tiles.append([x, y] + list(ground))
	db.execute_many("INSERT INTO ground VALUES(?, ?, ?, ?, ?)", tiles)
	db("COMMIT")

	# Create savegame with the island above.
	fd, savegame = tempfile.mkstemp()
	os.close(fd)

	db = DbReader(savegame)
	read_savegame_template(db)
	db("BEGIN TRANSACTION")
	db("INSERT INTO island (x, y, file) VALUES(?, ?, ?)", 20, 20, islandfile)
	db("COMMIT")

	return savegame
def generate_map(seed, map_size, water_percent, max_island_size, preferred_island_size, island_size_deviation):
	"""
	Generates a random map.

	@param seed: random number generator seed
	@param map_size: maximum map side length
	@param water_percent: minimum percent of map covered with water
	@param max_island_size: maximum island side length
	@param preferred_island_size: mean of island side lengths
	@param island_size_deviation: deviation of island side lengths
	@return: filename of the SQLite database containing the map
	"""
	max_island_size = min(max_island_size, map_size)
	rand = random.Random(_simplify_seed(seed))
	min_island_size = 20 # minimum chosen island side length (the real size my be smaller)
	min_island_separation = 3 + map_size / 100 # minimum distance between two islands
	max_island_side_coefficient = 4 # maximum value of island's max(side length) / min(side length)

	islands = []
	estimated_land = 0
	max_land_amount = map_size * map_size * (100 - water_percent) / 100

	trial_number = 0
	while trial_number < 100:
		trial_number += 1
		width = max(min_island_size, min(max_island_size, int(round(rand.gauss(preferred_island_size, island_size_deviation)))))
		side_coefficient = min(1 + abs(rand.gauss(0, 0.2)), max_island_side_coefficient)
		side_coefficient = side_coefficient if rand.randint(0, 1) else 1.0 / side_coefficient
		height = max(min_island_size, min(max_island_size, int(round(width * side_coefficient))))
		size = width * height
		if estimated_land + size > max_land_amount:
			continue

		for _ in xrange(13):
			x = rand.randint(0, map_size - width)
			y = rand.randint(0, map_size - height)

			rect = Rect.init_from_topleft_and_size(x, y, width, height)
			blocked = False
			for existing_island in islands:
				if existing_island.distance_to_rect(rect) < min_island_separation:
					blocked = True
					break
			if not blocked:
				islands.append(rect)
				estimated_land += size
				trial_number = 0
				break

	handle, filename = tempfile.mkstemp()
	os.close(handle)
	db = DbReader(filename)
	read_savegame_template(db)

	# move some of the islands to stretch the map to the right size
	if len(islands) > 1:
		min_top = min(rect.top for rect in islands)
		rect = rand.choice([rect for rect in islands if rect.top == min_top])
		islands[islands.index(rect)] = Rect.init_from_borders(rect.left, rect.top - min_top, rect.right, rect.bottom - min_top)

		max_bottom = max(rect.bottom for rect in islands)
		rect = rand.choice([rect for rect in islands if rect.bottom == max_bottom])
		shift = map_size - max_bottom - 1
		islands[islands.index(rect)] = Rect.init_from_borders(rect.left, rect.top + shift, rect.right, rect.bottom + shift)

		min_left = min(rect.left for rect in islands)
		rect = rand.choice([rect for rect in islands if rect.left == min_left])
		islands[islands.index(rect)] = Rect.init_from_borders(rect.left - min_left, rect.top, rect.right - min_left, rect.bottom)

		max_right = max(rect.right for rect in islands)
		rect = rand.choice([rect for rect in islands if rect.right == max_right])
		shift = map_size - max_right - 1
		islands[islands.index(rect)] = Rect.init_from_borders(rect.left + shift, rect.top, rect.right + shift, rect.bottom)

	for rect in islands:
		island_seed = rand.randint(-sys.maxint, sys.maxint)
		island_params = {'creation_method': 2, 'seed': island_seed, 'width': rect.width, 'height': rect.height}
		island_string = string.Template(_random_island_id_template).safe_substitute(island_params)
		db("INSERT INTO island (x, y, file) VALUES(?, ?, ?)", rect.left, rect.top, island_string)

	return filename
Exemple #9
0
    def _do_save(self, savegame):
        """Actual save code.
		@param savegame: absolute path"""
        assert os.path.isabs(savegame)
        self.log.debug("Session: Saving to %s", savegame)
        try:
            if os.path.exists(savegame):
                os.unlink(savegame)
            self.savecounter += 1

            db = DbReader(savegame)
        except IOError as e:  # usually invalid filename
            headline = _("Failed to create savegame file")
            descr = _(
                "There has been an error while creating your savegame file.")
            advice = _(
                "This usually means that the savegame name contains unsupported special characters."
            )
            self.gui.show_error_popup(headline, descr, advice, unicode(e))
            return self.save(
            )  # retry with new savegamename entered by the user
            # this must not happen with quicksave/autosave
        except OSError as e:
            if e.errno == errno.EACCES:
                self.gui.show_error_popup(
                    _("Access is denied"),
                    _("The savegame file could be read-only or locked by another process."
                      ))
                return self.save()
            raise

        try:
            read_savegame_template(db)

            db("BEGIN")
            self.world.save(db)
            #self.manager.save(db)
            self.view.save(db)
            self.ingame_gui.save(db)
            self.scenario_eventhandler.save(db)
            LastActivePlayerSettlementManager().save(db)

            for instance in self.selected_instances:
                db("INSERT INTO selected(`group`, id) VALUES(NULL, ?)",
                   instance.worldid)
            for group in xrange(len(self.selection_groups)):
                for instance in self.selection_groups[group]:
                    db("INSERT INTO selected(`group`, id) VALUES(?, ?)", group,
                       instance.worldid)

            rng_state = json.dumps(self.random.getstate())
            SavegameManager.write_metadata(db, self.savecounter, rng_state)
            # make sure everything gets written now
            db("COMMIT")
            db.close()
            return True
        except:
            print "Save Exception"
            traceback.print_exc()
            db.close()  # close db before delete
            os.unlink(savegame)  # remove invalid savegamefile
            return False
Exemple #10
0
    def _do_save(self, savegame):
        """Actual save code.
		@param savegame: absolute path"""
        assert os.path.isabs(savegame)
        self.log.debug("Session: Saving to %s", savegame)
        try:
            if os.path.exists(savegame):
                os.unlink(savegame)
            self.savecounter += 1

            db = DbReader(savegame)
        except IOError as e:  # usually invalid filename
            headline = _("Failed to create savegame file")
            descr = _("There has been an error while creating your savegame file.")
            advice = _("This usually means that the savegame name contains unsupported special characters.")
            self.ingame_gui.show_error_popup(headline, descr, advice, unicode(e))
            # retry with new savegamename entered by the user
            # (this must not happen with quicksave/autosave)
            return self.save()
        except OSError as e:
            if e.errno != errno.EACCES:
                raise
            self.ingame_gui.show_error_popup(
                _("Access is denied"), _("The savegame file could be read-only or locked by another process.")
            )
            return self.save()

        try:
            read_savegame_template(db)

            db("BEGIN")
            self.world.save(db)
            self.view.save(db)
            self.ingame_gui.save(db)
            self.scenario_eventhandler.save(db)

            # Store instances that are selected right now.
            for instance in self.selected_instances:
                db("INSERT INTO selected (`group`, id) VALUES (NULL, ?)", instance.worldid)

                # If a single instance is selected, also store the currently displayed tab.
                # (Else, upon restoring, we display a multi-selection tab.)
            tabname = None
            if len(self.selected_instances) == 1:
                tabclass = self.ingame_gui.get_cur_menu().current_tab
                tabname = tabclass.__class__.__name__
            db("INSERT INTO metadata (name, value) VALUES (?, ?)", "selected_tab", tabname)

            # Store user defined unit selection groups (Ctrl+number)
            for (number, group) in enumerate(self.selection_groups):
                for instance in group:
                    db("INSERT INTO selected (`group`, id) VALUES (?, ?)", number, instance.worldid)

                    # Store RNG state
            rng_state = json.dumps(self.random.getstate())
            SavegameManager.write_metadata(db, self.savecounter, rng_state)

            # Make sure everything gets written now
            db("COMMIT")
            db.close()
            return True
        except Exception:
            self.log.error("Save Exception:")
            traceback.print_exc()
            # remove invalid savegamefile (but close db connection before deleting)
            db.close()
            os.unlink(savegame)
            return False