Exemplo n.º 1
0
    def _distance_between_coordinates(lat1, lon1, lat2, lon2):
        # https://gis.stackexchange.com/questions/61924/python-gdal-degrees-to-meters-without-reprojecting
        # Calculate the great circle distance in meters between two points on the earth (specified in decimal degrees)

        next_level()
        message(
            "calculating distance between coordinates...", '(' + str(lat1) +
            ', ' + str(lon1) + ') - (' + str(lat2) + ', ' + str(lon2) + ')', 5)
        # convert decimal degrees to radians
        r_lat1, r_lon1, r_lat2, r_lon2 = math.radians(lat1), math.radians(
            lon1), math.radians(lat2), math.radians(lon2)
        # haversine formula
        d_r_lon = r_lon2 - r_lon1
        d_r_lat = r_lat2 - r_lat1
        a = math.sin(
            d_r_lat / 2.0)**2 + math.cos(r_lat1) * math.cos(r_lat2) * math.sin(
                d_r_lon / 2.0)**2
        c = 2.0 * math.asin(math.sqrt(a))
        earth_radius = 6371000.0  # radius of the earth in m
        dist = int(earth_radius * c)
        next_level()
        message("distance between coordinates calculated",
                str(dist) + " meters", 5)
        back_level()
        back_level()
        return dist
Exemplo n.º 2
0
 def tryDropItem(self, item):
     """
     Player attempts to drop an item.
     This function is meant to be called from the GUI.
     """
     if isinstance(item, Equipment):
         if item.isEquiped:
             message("You can't drop an equiped item.")
             return
     self.dropItem(item)
Exemplo n.º 3
0
 def unEquipItem(self, item):
     """
     basic implementation of equiping, doesn't take into account
     equipment slots. Should be overridden in subclass implementations.
     """
     #can only unequip if item is equiped
     if item in self.equipedItems:
         self.equipedItems.remove(item)
         item.isEquiped = False
         message(self.name.capitalize() + ' unequips a '
                     + item.name + '.', "GAME")
Exemplo n.º 4
0
 def applyTo(self, target):
     '''
     Confuse effect will be applied to target monster.
     :target: Monster object
     :return: None
     '''
     if not isinstance(target, Actors.Monster):
         raise GameError("Can not apply confuse effect to " + str(target))
     confusedTurns = self.effectDuration
     AI.ConfusedMonsterAI(self, target, confusedTurns)
     target.level.game.activeEffects.append(self)
     message(target.name + ' is confused for ' + str(confusedTurns) + ' turns.', "GAME")
Exemplo n.º 5
0
 def pickUpItem(self, item):
     """
     Make this character pick up an item.
     Arguments
         item - the item to be picked up
     """
     #remove the item from its tile and level
     item.removeFromLevel()
     #add the item to the inventory of this character
     self.addItem(item)
     #message
     message(self.name.capitalize() + ' picks up a '
                 + item.name + '.', "GAME")
Exemplo n.º 6
0
 def equipItem(self, item):
     """
     basic implementation of equiping, doesn't take into account
     equipment slots. Should be overridden in subclass implementations.
     """
     #can only equip if item is in inventory
     if item in self.inventory.items:
         #can only equip if not yet equiped
         if item not in self.equipedItems:
             self.equipedItems.append(item)
             item.isEquiped = True
             message(self.name.capitalize() + ' equips a '
                     + item.name + '.', "GAME")
Exemplo n.º 7
0
 def followPortal(self, portal):
     """
     Send player through specified portal.
     """
     #Game message
     message(portal.message, "GAME")
     #Move the player to the destination
     destinationLevel = portal.destinationPortal.level
     destinationTile = portal.destinationPortal.tile
     self.moveToLevel(destinationLevel, destinationTile)
     #change the current level of the game to the destinationlevel
     myGame = destinationLevel.game
     myGame.currentLevel = destinationLevel
Exemplo n.º 8
0
 def takeHeal(self, amount, healer):
     """
     function to heal a given amount of hitpoints
     arguments
        amount - the number of hitpoints to heal
        healer - the source of teh healing
     """
     #heal by the given amount
     if amount > 0:
         self.currentHitPoints += amount
         message(self.name.capitalize() + ' gains '
                 + str(amount) + ' hitpoints from a ' +  healer.name
                 + '.', "GAME")
Exemplo n.º 9
0
 def attack(self, target):
     """
     Attack another Character
     Arguments
         target - the Character to be attacked
     """
     # Check if the attack hits
     hitRoll = rollHitDie("1d100")
     # In case of an equal accuracy and dodge rating there is a 50% chance to hit
     toHit = 100 - (50 + self.accuracy - target.dodge)
     message(self.name.capitalize() + ' attacks ' + target.name + ': ' + str(hitRoll) + ' vs ' + str(toHit), "COMBAT")
     if hitRoll < toHit:
         # Miss, no damage
         message(self.name.capitalize() + ' attacks ' + target.name + ' but misses!', "COMBAT")
     else:
         # Hit, there will be damage, bonusDamage depends on how strongly the hit connects
         bonusDamagePercent = (hitRoll - toHit) / 100.0
         damagePercent = 1 + bonusDamagePercent
         # targets armor neutralizes part of the damage
         damage = int(damagePercent * self.damage) - target.armor
         if damage > 0:
             message(self.name.capitalize() + ' attacks ' + target.name + ' and hits for ' + str(damage) + ' Damage (' + str(damagePercent) +' damage factor)', "COMBAT")
             target.takeDamage(damage, self)
         else:
             message(self.name.capitalize() + ' attacks ' + target.name + ' and hits but it has no effect.', "COMBAT")
Exemplo n.º 10
0
    def levelUp(self):
        '''
        Increase level of this player
        '''
        message("You feel stronger!", "GAME")
        self._playerLevel += 1
        self._nextLevelXp = CONSTANTS.GAME_XP_BASE + CONSTANTS.GAME_XP_BASE * CONSTANTS.GAME_XP_FACTOR * (self.playerLevel * self.playerLevel - 1)

        self._baseAccuracy += CONSTANTS.GAME_PLAYER_LEVEL_ACCURACY
        self._baseDodge += CONSTANTS.GAME_PLAYER_LEVEL_DODGE
        self._baseDamage += CONSTANTS.GAME_PLAYER_LEVEL_DAMAGE
        self._baseArmor += CONSTANTS.GAME_PLAYER_LEVEL_ARMOR
        self._baseBody += CONSTANTS.GAME_PLAYER_LEVEL_BODY
        self._baseMind += CONSTANTS.GAME_PLAYER_LEVEL_MIND
Exemplo n.º 11
0
    def __init__(self):
        if Options.config['get_geonames_online']:
            Geonames._base_nearby_url = "{}findNearbyJSON?lat={{}}&lng={{}}&featureClass=P&username={}&lang={}".format(
                self.GEONAMES_API, Options.config['geonames_user'],
                Options.config['geonames_language'])
        if self.cities == []:
            next_level()
            message("reading and processing local geonames files", "", 5)
            territories_file = os.path.join(os.path.dirname(__file__),
                                            'geonames/territories.json')
            countries_file = os.path.join(os.path.dirname(__file__),
                                          'geonames/countries.json')
            cities_file = os.path.join(os.path.dirname(__file__),
                                       'geonames/cities1000.txt')

            with open(territories_file, 'r') as territories_file_p:
                territories = json.load(territories_file_p)
            with open(countries_file, 'r') as countries_file_p:
                countries = json.load(countries_file_p)

            with open(cities_file, 'r') as all_cities:
                for line in all_cities:
                    col = line.split('\t')
                    country_code = col[8]
                    state_code = col[10]
                    try:
                        country_name = countries[country_code]
                    except KeyError:
                        country_name = ''
                    try:
                        state_name = territories[country_code + '.' +
                                                 state_code]
                    except KeyError:
                        state_name = ''
                    city_line = {
                        'country_name': country_name,
                        'country_code': country_code,
                        'region_name': state_name,
                        'region_code': state_code,
                        'place_name': col[1],
                        'place_code': col[0],
                        'latitude': float(col[4]),
                        'longitude': float(col[5])
                    }
                    self.cities.append(city_line)
            next_level()
            message("local geonames files read and processed", "", 5)
            back_level()
            back_level()
Exemplo n.º 12
0
 def takeDamage(self, amount, attacker):
     """
     function to take damage from an attacker
     arguments
        damage - the incoming damage
        attacker - the attacking Actor
     """
     if self.state == Character.ACTIVE:
         #apply damage if possible
         if amount > 0:
             self.currentHitPoints -= amount
         #check for death
         if self.currentHitPoints <= 0:
             message(self.name.capitalize() + ' is killed!', "COMBAT")
             self._killedBy(attacker)
Exemplo n.º 13
0
 def dropItem(self, item):
     """
     Make this character drop an item on the current tile.
     Arguments
         item - the item to be dropped
     """
     #unequip it if required
     if item in self.equipedItems:
         self.unEquipItem(item)
     #if it is in the inventory remove it
     if item in self.inventory.items:
         self.inventory.remove(item)
     #add it to the current tile of the character
     item.moveToLevel(self.level, self.tile)
     #message
     message(self.name.capitalize() + ' drops a '
                 + item.name + '.', "GAME")
Exemplo n.º 14
0
 def _killedBy(self, attacker):
     """
     This function handles the death of this Character
     """
     if self.state == Character.ACTIVE:
         if type(attacker) is Player:
             #yield experience to the player
             message(attacker.name + ' gains ' + str(self.xpValue) + ' XP.', "GAME")
             attacker.gainXp(self.xpValue)
         if type(attacker) is Monster:
             if attacker.killedByText != '':
                 message(attacker.killedByText, "GAME")
         #transform this character into a corpse and remove AI
         self._char = '%'
         self._AI = None
         self._name = self.name + ' corpse'
         self._state = Character.DEAD
Exemplo n.º 15
0
 def tick(self):
     '''
     Apply one tick of damage
     :return: None
     '''
     # Update effectduration
     if self.effectDuration == 0: return
     self.effectDuration -= 1
     #find all targets in range
     self._actors = []
     for tile in self.tiles:
         for actor in tile.actors:
             self.actors.append(actor)
     #apply damage to every target
     damageAmount = rollHitDie(self.effectHitDie)
     for target in self.actors:
         message(self.source.name.capitalize() + ' hits '
                 + target.name + ' for ' + str(damageAmount) + ' Damage.', "GAME")
         target.takeDamage(damageAmount, self.source.owner)
Exemplo n.º 16
0
def main():
    # @python2
    if sys.version_info < (3, ):
        reload(sys)
        sys.setdefaultencoding("UTF-8")
    if len(sys.argv) != 3 and len(sys.argv) != 2:
        print("usage: {0} ALBUM_PATH CACHE_PATH - or {1} CONFIG_FILE".format(
            sys.argv[0], sys.argv[0]))
        return

    Options.initialize_opencv()
    Options.get_options()

    try:
        os.umask(0o02)
        TreeWalker()
        report_times(True)
        message("    The end!    ", "", 3)
    except KeyboardInterrupt:
        message("keyboard", "CTRL+C pressed, quitting.")
        sys.exit(-97)
Exemplo n.º 17
0
    def lookup_nearby_place(latitude, longitude):
        """
		Looks up places near a specific geographic location
		"""

        next_level()
        message("looking for geonames in cache...", "", 5)
        for _ in range(len(Geonames.geonames_cache) - 1, -1, -1):
            ((c_latitude, c_longitude), result) = Geonames.geonames_cache[_]
            distance = Geonames._distance_between_coordinates(
                c_latitude, c_longitude, latitude, longitude)
            if distance < Geonames.MAX_DISTANCE_METERS:
                # ok with value from cache!
                next_level()
                message("geoname got from cache", "", 5)
                back_level()
                back_level()
                # # add to cache only if not too close to existing point
                # if distance > Geonames.MAX_DISTANCE_METERS / 2.0:
                # 	Geonames.geonames_cache[(latitude, longitude)] = result
                return result
        next_level()
        message("geonames not found in cache", "", 5)
        back_level()

        got = False
        if Options.config['get_geonames_online']:
            message("getting geonames online...", "", 5)
            # get country, region (state for federal countries), and place
            try_number = 0
            while True:
                response = requests.get(
                    Geonames._base_nearby_url.format(str(latitude),
                                                     str(longitude)))
                try:
                    result = Geonames._decode_nearby_place(response.text)
                    if isinstance(result, dict):
                        got = True
                        next_level()
                        message("geonames got from geonames.org online", "", 5)
                        back_level()
                        break
                    else:
                        # result is a number, which means that the request to geonames.org produced  an error
                        try_number += 1
                        next_level()
                        message(
                            "geonames.org returned error code, retrying...",
                            "try = " + str(try_number) + ", error code = " +
                            str(result), 5)
                        back_level()
                except json.decoder.JSONDecodeError:
                    # error when decoding
                    # once the json.loads() function inside _decode_nearby_place() throwed the error:
                    # json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
                    try_number += 1
                    if try_number <= 3:
                        next_level()
                        message(
                            "error deconding geonames.org response, retrying...",
                            "try = " + str(try_number), 5)
                        back_level()
                if try_number == 3:
                    next_level()
                    message("three errors", "giving up", 5)
                    back_level()
                    break

        if not got:
            # get country, region (state for federal countries), and place
            message("getting geonames from local files...", "", 5)
            result = min(
                [city for city in Geonames.cities],
                key=lambda c: Geonames.quick_distance_between_coordinates(
                    c['latitude'], c['longitude'], latitude, longitude))
            result['distance'] = Geonames._distance_between_coordinates(
                latitude, longitude, result['latitude'], result['longitude'])
            next_level()
            message("geonames got from local files", "", 5)
            back_level()

        # add to cache
        message("adding geonames to cache...", "", 5)
        Geonames.geonames_cache.append(((latitude, longitude), result))
        next_level()
        message("geonames added to cache", "", 5)
        back_level()

        back_level()

        return result
Exemplo n.º 18
0
def initialize_opencv():
	global face_cascade, eye_cascade

	try:
		import cv2

		message("importer", "opencv library available, using it!", 3)
		next_level()
		FACE_CONFIG_FILE = "haarcascade_frontalface_default.xml"
		message("looking for file...", FACE_CONFIG_FILE + " in /usr/share", 5)
		face_config_file_with_path = find_in_usr_share(FACE_CONFIG_FILE)
		if not face_config_file_with_path:
			message("face xml file not found", FACE_CONFIG_FILE + " not found in /usr/share", 5)
			message("looking for file...", FACE_CONFIG_FILE + " in /", 5)
			face_config_file_with_path = find(FACE_CONFIG_FILE)
		if not face_config_file_with_path:
			next_level()
			message("face xml file not found", FACE_CONFIG_FILE, 5)
			back_level()
			config['cv2_installed'] = False
		else:
			face_cascade = cv2.CascadeClassifier(face_config_file_with_path)

			next_level()
			message("face xml file found and initialized:", face_config_file_with_path, 5)
			back_level()
			EYE_CONFIG_FILE = "haarcascade_eye.xml"
			message("looking for file...", EYE_CONFIG_FILE, 5)
			eye_config_file_with_path = find_in_usr_share(EYE_CONFIG_FILE)
			if not eye_config_file_with_path:
				eye_config_file_with_path = find(EYE_CONFIG_FILE)
			if not eye_config_file_with_path:
				next_level()
				message("eyes xml file not found", EYE_CONFIG_FILE, 5)
				back_level()
				config['cv2_installed'] = False
			else:
				eye_cascade = cv2.CascadeClassifier(eye_config_file_with_path)
				next_level()
				message("found and initialized:", eye_config_file_with_path, 5)
				back_level()
		back_level()
	except ImportError:
		config['cv2_installed'] = False
		message("importer", "No opencv library available, not using it", 2)
Exemplo n.º 19
0
def get_options():
	project_dir = os.path.dirname(os.path.realpath(os.path.join(__file__, "..")))
	default_config_file = os.path.join(project_dir, "myphotoshare.conf.defaults")
	default_config = configparser.ConfigParser()
	default_config.readfp(open(default_config_file, "r"))
	usr_config = configparser.ConfigParser()
	usr_config.add_section("options")
	for option in default_config.options('options'):
		usr_config.set("options", option, default_config.get("options", option))

	if len(sys.argv) == 2:
		# 1 arguments: the config files
		# which modifies the default options
		usr_config.readfp(open(sys.argv[1], "r"))
	else:
		usr_config.set('options', 'album_path', sys.argv[1])
		usr_config.set('options', 'cache_path', sys.argv[2])

	message("Options", "asterisk denotes options changed by config file", 0)
	next_level()
	# pass config values to a dict, because ConfigParser objects are not reliable
	for option in default_config.options('options'):
		if option in ('max_verbose',
				'photo_map_zoom_level',
				'jpeg_quality',
				'video_crf',
				'thumb_spacing',
				'album_thumb_size',
				'media_thumb_size',
				'big_virtual_folders_threshold',
				'max_search_album_number',
				# the following option will be converted to integer further on
				'num_processors',
				'max_album_share_thumbnails_number',
				'min_album_thumbnail',
				'piwik_id'
		):
			try:
				if option != 'piwik_id' or config['piwik_server']:
					# piwik_id must be evaluated here because otherwise an error is produced if it's not set
					config[option] = usr_config.getint('options', option)
				else:
					config[option] = ""
			except configparser.Error:
				next_level()
				message("WARNING: option " + option + " in user config file", "is not integer, using default value", 2)
				back_level()
				config[option] = default_config.getint('options', option)
		elif option in ('follow_symlinks',
				'checksum',
				'different_album_thumbnails',
				'albums_slide_style',
				'show_media_names_below_thumbs',
				'show_album_names_below_thumbs',
				'show_album_media_count',
				'persistent_metadata',
				'default_album_name_sort',
				'default_media_name_sort',
				'default_album_reverse_sort',
				'default_media_reverse_sort',
				'recreate_fixed_height_thumbnails',
				'get_geonames_online',
				'show_faces',
				'use_stop_words'
		):
			try:
				config[option] = usr_config.getboolean('options', option)
			except ValueError:
				next_level()
				message("WARNING: option " + option + " in user config file", "is not boolean, using default value", 2)
				back_level()
				config[option] = default_config.getboolean('options', option)
		elif option in ('reduced_sizes', 'map_zoom_levels', 'metadata_tools_preference'):
			config[option] = ast.literal_eval(usr_config.get('options', option))
		elif option in ('mobile_thumbnail_factor', 'face_cascade_scale_factor'):
			config[option] = usr_config.getfloat('options', option)
			if config[option] < 1:
				config[option] = 1
		else:
			config[option] = usr_config.get('options', option)

		option_value = str(config[option])
		option_length = len(option_value)
		max_length = 40
		spaces = ""
		#pylint
		for _ in range(max_length - option_length):
			spaces += " "
		max_spaces = ""
		#pylint
		for _ in range(max_length):
			max_spaces += " "

		default_option_value = str(default_config.get('options', option))
		default_option_length = len(default_option_value)
		default_spaces = ""
		for _ in range(max_length - default_option_length - 2):
			default_spaces += " "
		if default_config.get('options', option) == usr_config.get('options', option):
			option_value = "  " + option_value + spaces + "[DEFAULT" + max_spaces + "]"
		else:
			option_value = "* " + option_value + spaces + "[DEFAULT: " + default_option_value + default_spaces + "]"

		message(option, option_value, 0)

	# all cache names are lower case => bit rate must be lower case too
	config['video_transcode_bitrate'] = config['video_transcode_bitrate'].lower()

	# set default values
	if config['geonames_language'] == '':
		if config['language'] != '':
			config['geonames_language'] = config['language']
			message("geonames_language option unset", "using language value: " + config['language'], 3)
		else:
			config['geonames_language'] = os.getenv('LANG')[:2]
			message("geonames_language and language options unset", "using system language (" + config['geonames_language'] + ") for geonames_language option", 3)
	if config['get_geonames_online']:
		# warn if using demo geonames user
		if config['geonames_user'] == str(default_config.get('options', 'geonames_user')):
			message("WARNING!", "You are using the myphotoshare demo geonames user, get and use your own user as soon as possible", 0)

	# values that have type != string
	back_level()

	# @python2
	if sys.version_info < (3, ):
		if config['index_html_path']:
			config['index_html_path'] = os.path.abspath(config['index_html_path']).decode(sys.getfilesystemencoding())
		if config['album_path']:
			config['album_path'] = os.path.abspath(config['album_path']).decode(sys.getfilesystemencoding())
		if config['cache_path']:
			config['cache_path'] = os.path.abspath(config['cache_path']).decode(sys.getfilesystemencoding())
	else:
		if config['index_html_path']:
			config['index_html_path'] = os.fsdecode(os.path.abspath(config['index_html_path']))
		if config['album_path']:
			config['album_path'] = os.fsdecode(os.path.abspath(config['album_path']))
		if config['cache_path']:
			config['cache_path'] = os.fsdecode(os.path.abspath(config['cache_path']))

	# try to guess value not given
	guessed_index_dir = False
	guessed_album_dir = False
	guessed_cache_dir = False
	if (
		not config['index_html_path'] and
		not config['album_path'] and
		not config['cache_path']
	):
		message("options", "neither index_html_path nor album_path or cache_path have been defined, assuming default positions", 3)
		# default position for index_html_path is script_path/../web
		# default position for album path is script_path/../web/albums
		# default position for cache path is script_path/../web/cache
		script_path = os.path.dirname(os.path.realpath(sys.argv[0]))
		config['index_html_path'] = os.path.abspath(os.path.join(script_path, "..", "web"))
		config['album_path'] = os.path.abspath(os.path.join(config['index_html_path'], "albums"))
		config['cache_path'] = os.path.abspath(os.path.join(config['index_html_path'], "cache"))
		guessed_index_dir = True
		guessed_album_dir = True
		guessed_cache_dir = True
	elif (
		config['index_html_path'] and
		not config['album_path'] and
		not config['cache_path']
	):
		message("options", "only index_html_path is given, using its subfolder 'albums' for album_path and 'cache' for cache_path", 3)
		config['album_path'] = os.path.join(config['index_html_path'], "albums")
		config['cache_path'] = os.path.join(config['index_html_path'], "cache")
		guessed_album_dir = True
		guessed_cache_dir = True
	elif (
		not config['index_html_path'] and
		config['album_path'] and
		config['cache_path'] and
		config['album_path'][:config['album_path']
			.rfind("/")] == config['cache_path'][:config['cache_path'].rfind("/")]
	):
		guessed_index_dir = True
		message("options", "only album_path or cache_path has been given, using their common parent folder for index_html_path", 3)
		config['index_html_path'] = config['album_path'][:config['album_path'].rfind("/")]
	elif not (
		config['index_html_path'] and
		config['album_path'] and
		config['cache_path']
	):
		message("options", "you must define at least some of index_html_path, album_path and cache_path, and correctly; quitting", 0)
		sys.exit(-97)

	if guessed_index_dir or guessed_album_dir or guessed_cache_dir:
		message("options", "guessed value(s):", 2)
		next_level()
		if guessed_index_dir:
			message('index_html_path', config['index_html_path'], 2)
		if guessed_album_dir:
			message('album_path', config['album_path'], 2)
		if guessed_cache_dir:
			message('cache_path', config['cache_path'], 2)
		back_level()

	# the album directory must exist and be readable
	try:
		os.stat(config['album_path'])
	except OSError:
		message("FATAL ERROR", config['album_path'] + " doesn't exist or unreadable, quitting", 0)
		sys.exit(-97)

	# the cache directory must exist and be writable, or we'll try to create it
	try:
		os.stat(config['cache_path'])
		if not os.access(config['cache_path'], os.W_OK):
			message("FATAL ERROR", config['cache_path'] + " not writable, quitting", 0)
			sys.exit(-97)
	except OSError:
		try:
			os.mkdir(config['cache_path'])
			message("directory created", config['cache_path'], 4)
			os.chmod(config['cache_path'], 0o777)
			message("permissions set", config['cache_path'], 4)
		except OSError:
			message("FATAL ERROR", config['cache_path'] + " inexistent and couldn't be created, quitting", 0)
			sys.exit(-97)

	# create the directory where php will put album composite images
	album_cache_dir = os.path.join(config['cache_path'], config['cache_album_subdir'])
	try:
		os.stat(album_cache_dir)
	except OSError:
		try:
			message("creating cache directory for composite images", album_cache_dir, 4)
			os.mkdir(album_cache_dir)
			os.chmod(album_cache_dir, 0o777)
		except OSError:
			message("FATAL ERROR", config['cache_path'] + " not writable, quitting", 0)
			sys.exit(-97)

	# get old options: they are revised in order to decide whether to recreate something
	json_options_file = os.path.join(config['cache_path'], "options.json")
	try:
		with open(json_options_file) as old_options_file:
			old_options = json.load(old_options_file)
	except IOError:
		old_options = config

	config['recreate_reduced_photos'] = False
	for option in options_requiring_reduced_images_regeneration:
		try:
			if old_options[option] != config[option]:
				config['recreate_reduced_photos'] = True
				message("options", "'" + option + "' has changed from previous scanner run, forcing recreation of reduced size images", 3)
		except KeyError:
			config['recreate_reduced_photos'] = True
			message("options", "'" + option + "' wasn't set on previous scanner run, forcing recreation of reduced size images", 3)

	config['recreate_thumbnails'] = False
	for option in options_requiring_thumbnails_regeneration:
		try:
			if old_options[option] != config[option]:
				config['recreate_thumbnails'] = True
				message("options", "'" + option + "' has changed from previous scanner run, forcing recreation of thumbnails", 3)
		except KeyError:
			config['recreate_thumbnails'] = True
			message("options", "'" + option + "' wasn't set on previous scanner run, forcing recreation of thumbnails", 3)


	config['recreate_json_files'] = False
	for option in options_requiring_json_regeneration:
		try:
			if old_options[option] != config[option]:
				config['recreate_json_files'] = True
				message("options", "'" + option + "' has changed from previous scanner run, forcing recreation of json files", 3)
				break
		except KeyError:
			config['recreate_json_files'] = True
			message("options", "'" + option + "' wasn't set on previous scanner run, forcing recreation of json files", 3)
			break
Exemplo n.º 20
0
    def takeTurn(self):
        """
        Take one turn
        """
        message(self.character.name + ' at ' + str(self.character.tile) +
                ' takes turn.', "AI")
        #Only take action if we are in a level
        if self.character.level is None:
            message("   Not in a level, can't take action.", "AI")
            return

        #Only take action if we find the player
        if self.player is None:
            for c in self.character.level.characters:
                if type(c) is Player:
                    self._player = c
            if self.player is None:
                message("   No player found, staying put", "AI")
                return

        #Only take action if player is not dead.
        if self.player.state == Character.DEAD:
            message("   Player is dead, no action needed", "AI")
            return

        #TODO medium: read this from the config file via monsterlibrary via
        #new class variable in Character class
        RoS = 8  # Range of Sight
        RoA = 2  # Range of Attack
        distance = Utilities.distanceBetween(self.character, self.player)
        #message('   Player ' + self.player.name + ' found at ' + \
        #        str(self.player.tile) + ' distance: ' + str(distance), "AI")

        #Only take action if player is within range of sight
        if distance > RoS:
            #message("   Player out of range of sight", "AI")
            return
        #Attack if player is within range of attack
        elif distance < RoA:
            message("   Attacking player", "AI")
            self.character.attack(self.player)
            return
        else:
            message("   Moving towards player", "AI")
            self.character.moveTowards(self.player)
            return