def terrain(self): data = s11n.from_json(self._model.terrain) terrain = [] for row in data: terrain.append([]) for cell in row: terrain[-1].append(TERRAIN(cell)) return terrain
class GuideMobResource(MobResourceBase): @validator(code='mobs.mob_disabled', message='монстр находится вне игры', status_code=404) def validate_mob_disabled(self, *args, **kwargs): return not self.mob.state.is_DISABLED or self.can_create_mob or self.can_moderate_mob @validate_argument('state', argument_to_mob_state, 'mobs', 'неверное состояние записи о монстре') @validate_argument('terrain', lambda value: TERRAIN(int(value)), 'mobs', 'неверный тип территории') @validate_argument('order_by', INDEX_ORDER_TYPE, 'mobs', 'неверный тип сортировки') @validate_argument('archetype', argument_to_archetype, 'mobs', 'неверный архетип монстра') @validate_argument('type', argument_to_mob_type, 'mobs', 'неверный тип монстра') @handler('', method='get') def index(self, state=MOB_RECORD_STATE.ENABLED, terrain=None, order_by=INDEX_ORDER_TYPE.BY_NAME, type=None, archetype=None): mobs = mobs_storage.all() if not self.can_create_mob and not self.can_moderate_mob: mobs = [mob for mob in mobs if mob.state.is_ENABLED] # pylint: disable=W0110 is_filtering = False if not state.is_ENABLED: # if not default is_filtering = True mobs = [mob for mob in mobs if mob.state == state] # pylint: disable=W0110 if terrain is not None: is_filtering = True mobs = [mob for mob in mobs if terrain in mob.terrains] # pylint: disable=W0110 if order_by.is_BY_NAME: mobs = sorted(mobs, key=lambda mob: mob.name) elif order_by.is_BY_LEVEL: mobs = sorted(mobs, key=lambda mob: mob.level) if type is not None: mobs = [mob for mob in mobs if mob.type == type] # pylint: disable=W0110 if archetype is not None: mobs = [mob for mob in mobs if mob.archetype == archetype] # pylint: disable=W0110 url_builder = UrlBuilder( reverse('guide:mobs:'), arguments={ 'state': state.value if state is not None else None, 'terrain': terrain.value if terrain is not None else None, 'type': type.value if type is not None else None, 'archetype': archetype.value if archetype is not None else None, 'order_by': order_by.value }) IndexFilter = ModeratorIndexFilter if self.can_create_mob or self.can_moderate_mob else UnloginedIndexFilter #pylint: disable=C0103 index_filter = IndexFilter( url_builder=url_builder, values={ 'state': state.value if state is not None else None, 'terrain': terrain.value if terrain is not None else None, 'type': type.value if type is not None else None, 'archetype': archetype.value if archetype is not None else None, 'order_by': order_by.value }) return self.template( 'mobs/index.html', { 'mobs': mobs, 'is_filtering': is_filtering, 'MOB_RECORD_STATE': MOB_RECORD_STATE, 'TERRAIN': TERRAIN, 'state': state, 'terrain': terrain, 'order_by': order_by, 'INDEX_ORDER_TYPE': INDEX_ORDER_TYPE, 'url_builder': url_builder, 'index_filter': index_filter, 'section': 'mobs' }) @validate_mob_disabled() @handler('#mob', name='show', method='get') def show(self): return self.template( 'mobs/show.html', { 'mob': self.mob, 'mob_meta_object': meta_relations.Mob.create_from_object( self.mob), 'section': 'mobs' }) @validate_mob_disabled() @handler('#mob', 'info', method='get') def show_dialog(self): return self.template( 'mobs/info.html', { 'mob': self.mob, 'mob_meta_object': meta_relations.Mob.create_from_object( self.mob), })
'тип:', attribute='type', choices=[(None, 'все')] + sorted(list(game_relations.BEING_TYPE.select('value', 'text')), key=lambda x: x[1])), list_filter.choice_element( 'архетип:', attribute='archetype', choices=[(None, 'все')] + sorted(list(game_relations.ARCHETYPE.select('value', 'text')), key=lambda x: x[1])), list_filter.choice_element( 'территория:', attribute='terrain', choices=[(None, 'все')] + sorted(list(TERRAIN.select('value', 'text')), key=lambda x: x[1])), list_filter.choice_element('сортировка:', attribute='order_by', choices=INDEX_ORDER_TYPE.select( 'value', 'text'), default_value=INDEX_ORDER_TYPE.BY_NAME.value) ] MODERATOR_INDEX_FILTERS = BASE_INDEX_FILTERS + [ list_filter.choice_element('состояние:', attribute='state', default_value=MOB_RECORD_STATE.ENABLED.value, choices=MOB_RECORD_STATE.select( 'value', 'text')) ]
class MobRecordBaseForm(forms.Form): level = fields.IntegerField(label='минимальный уровень') name = WordField(word_type=utg_relations.WORD_TYPE.NOUN, label='Название') type = fields.TypedChoiceField( label='тип', choices=MOB_TYPE_CHOICES, coerce=game_relations.BEING_TYPE.get_from_name) archetype = fields.TypedChoiceField( label='тип', choices=game_relations.ARCHETYPE.choices(), coerce=game_relations.ARCHETYPE.get_from_name) global_action_probability = fields.FloatField( label= 'вероятность встретить монстра, если идёт его набег (от 0 до 1, 0 — нет набега)' ) terrains = fields.TypedMultipleChoiceField(label='места обитания', choices=TERRAIN.choices(), coerce=TERRAIN.get_from_name) abilities = fields.MultipleChoiceField(label='способности', choices=ABILITY_CHOICES) description = bbcode.BBField(label='Описание', required=False) is_mercenary = fields.BooleanField(label='может быть наёмником', required=False) is_eatable = fields.BooleanField(label='съедобный', required=False) communication_verbal = fields.RelationField( label='вербальное общение', relation=game_relations.COMMUNICATION_VERBAL) communication_gestures = fields.RelationField( label='невербальное общение', relation=game_relations.COMMUNICATION_GESTURES) communication_telepathic = fields.RelationField( label='телепатия', relation=game_relations.COMMUNICATION_TELEPATHIC) intellect_level = fields.RelationField( label='уровень интеллекта', relation=game_relations.INTELLECT_LEVEL) def clean_abilities(self): abilities_ids = self.cleaned_data['abilities'] if HIT.get_id() not in abilities_ids: abilities_ids.append(HIT.get_id()) if not abilities_ids: raise ValidationError('не указаны способности монстра') for ability_id in abilities_ids: if ability_id not in ABILITY_CHOICES_DICT: raise ValidationError( 'неверный идентификатор способности монстра') return frozenset(abilities_ids) def clean_terrains(self): terrains = self.cleaned_data['terrains'] if not terrains: raise ValidationError('не указаны места обитания монстра') return frozenset(terrains) @classmethod def get_initials(cls, mob): return { 'description': mob.description, 'type': mob.type, 'name': mob.utg_name, 'archetype': mob.archetype, 'level': mob.level, 'global_action_probability': mob.global_action_probability, 'terrains': mob.terrains, 'abilities': mob.abilities, 'communication_verbal': mob.communication_verbal, 'communication_gestures': mob.communication_gestures, 'communication_telepathic': mob.communication_telepathic, 'intellect_level': mob.intellect_level, 'is_mercenary': mob.is_mercenary, 'is_eatable': mob.is_eatable }
from the_tale.game.map.relations import TERRAIN from the_tale.game import relations as game_relations from . import forms from . import logic from . import storage from . import relations from . import meta_relations BASE_INDEX_FILTERS = [list_filter.reset_element(), list_filter.choice_element('тип:', attribute='type', choices=[(None, 'все')] + sorted(list(beings_relations.TYPE.select('value', 'text')), key=lambda x: x[1])), list_filter.choice_element('архетип:', attribute='archetype', choices=[(None, 'все')] + sorted(list(game_relations.ARCHETYPE.select('value', 'text')), key=lambda x: x[1])), list_filter.choice_element('территория:', attribute='terrain', choices=[(None, 'все')] + sorted(list(TERRAIN.select('value', 'text')), key=lambda x: x[1])), list_filter.choice_element('сортировка:', attribute='order_by', choices=relations.INDEX_ORDER_TYPE.select('value', 'text'), default_value=relations.INDEX_ORDER_TYPE.BY_NAME.value) ] MODERATOR_INDEX_FILTERS = BASE_INDEX_FILTERS + [list_filter.choice_element('состояние:', attribute='state', default_value=relations.MOB_RECORD_STATE.ENABLED.value, choices=relations.MOB_RECORD_STATE.select('value', 'text'))] class UnloginedIndexFilter(list_filter.ListFilter): ELEMENTS = BASE_INDEX_FILTERS
from the_tale.game.map.relations import TERRAIN from the_tale.game import relations as game_relations from .relations import MOB_RECORD_STATE, INDEX_ORDER_TYPE from .prototypes import MobRecordPrototype from .storage import mobs_storage from .forms import MobRecordForm, ModerateMobRecordForm from . import meta_relations BASE_INDEX_FILTERS = [list_filter.reset_element(), list_filter.choice_element('тип:', attribute='type', choices=[(None, 'все')] + sorted(list(game_relations.BEING_TYPE.select('value', 'text')), key=lambda x: x[1])), list_filter.choice_element('архетип:', attribute='archetype', choices=[(None, 'все')] + sorted(list(game_relations.ARCHETYPE.select('value', 'text')), key=lambda x: x[1])), list_filter.choice_element('территория:', attribute='terrain', choices=[(None, 'все')] + sorted(list(TERRAIN.select('value', 'text')), key=lambda x: x[1])), list_filter.choice_element('сортировка:', attribute='order_by', choices=INDEX_ORDER_TYPE.select('value', 'text'), default_value=INDEX_ORDER_TYPE.BY_NAME.value) ] MODERATOR_INDEX_FILTERS = BASE_INDEX_FILTERS + [list_filter.choice_element('состояние:', attribute='state', default_value=MOB_RECORD_STATE.ENABLED.value, choices=MOB_RECORD_STATE.select('value', 'text'))] class UnloginedIndexFilter(list_filter.ListFilter): ELEMENTS = BASE_INDEX_FILTERS class ModeratorIndexFilter(list_filter.ListFilter):
def handle(self, *args, **options): region = options['region'] if not region: region = map_settings.GEN_REGION_OUTPUT % map_info_storage.version output = options['output'] if not output: output = '/tmp/the-tale-map.png' with open(region) as region_file: data = json.loads(region_file.read()) terrain = data['terrain'] buildings = data['buildings'].values() places = data['places'].values() roads = data['roads'].values() width = data['width'] height = data['height'] roads_map = get_roads_map(width, height, roads, {place['id']: place for place in places}) image = PIL.Image.new( 'RGBA', (width * map_settings.CELL_SIZE, height * map_settings.CELL_SIZE)) texture = PIL.Image.open(map_settings.TEXTURE_PATH) for y, row in enumerate(terrain): for x, cell in enumerate(row): terrain_type = TERRAIN(cell) draw_sprite(image, texture, terrain_type.name, x, y) if roads_map[y][x]: draw_sprite(image, texture, terrain_type.name, x, y, base=True) road_sprite = get_road_sprite_info(roads_map, x, y) draw_sprite(image, texture, road_sprite['name'], x, y, rotate=road_sprite['rotate']) for place_info in places: size = place_info['size'] race = RACE(place_info['race']) if size < 3: verbose_size = 'small' elif size < 6: verbose_size = 'medium' elif size < 9: verbose_size = 'large' else: verbose_size = 'capital' sprite_name = ('city_%s_%s' % (race.name.lower(), verbose_size)).upper() draw_sprite(image, texture, sprite_name, place_info['pos']['x'], place_info['pos']['y']) for building_info in buildings: x, y = building_info['pos']['x'], building_info['pos']['y'] draw_sprite(image, texture, TERRAIN(terrain[y][x]).name, x, y, base=True) sprite_name = 'BUILDING_%s' % BUILDING_TYPE( building_info['type']).name draw_sprite(image, texture, sprite_name, x, y) image.crop(OUTPUT_RECTANGLE).resize(REAL_SIZE, PIL.Image.ANTIALIAS).save(output)
class MobRecordBaseForm(forms.Form): level = fields.IntegerField(label='минимальный уровень') name = WordField(word_type=utg_relations.WORD_TYPE.NOUN, label='Название') type = fields.TypedChoiceField(label='тип', choices=MOB_TYPE_CHOICES, coerce=beings_relations.TYPE.get_from_name) archetype = fields.TypedChoiceField( label='тип', choices=game_relations.ARCHETYPE.choices(), coerce=game_relations.ARCHETYPE.get_from_name) global_action_probability = fields.FloatField( label= 'вероятность встретить монстра, если идёт его набег (от 0 до 1, 0 — нет набега)' ) terrains = fields.TypedMultipleChoiceField(label='места обитания', choices=TERRAIN.choices(), coerce=TERRAIN.get_from_name) abilities = fields.MultipleChoiceField(label='способности', choices=ABILITY_CHOICES) description = bbcode.BBField(label='Описание', required=False) is_mercenary = fields.BooleanField(label='может быть наёмником', required=False) is_eatable = fields.BooleanField(label='съедобный', required=False) communication_verbal = fields.RelationField( label='вербальное общение', relation=beings_relations.COMMUNICATION_VERBAL) communication_gestures = fields.RelationField( label='невербальное общение', relation=beings_relations.COMMUNICATION_GESTURES) communication_telepathic = fields.RelationField( label='телепатия', relation=beings_relations.COMMUNICATION_TELEPATHIC) intellect_level = fields.RelationField( label='уровень интеллекта', relation=beings_relations.INTELLECT_LEVEL) structure = fields.RelationField(label='структура', relation=beings_relations.STRUCTURE) features = fields.TypedMultipleChoiceField( label='особенности', choices=beings_relations.FEATURE.choices(), coerce=beings_relations.FEATURE.get_from_name) movement = fields.RelationField(label='способ передвижения', relation=beings_relations.MOVEMENT) body = fields.RelationField(label='телосложение', relation=beings_relations.BODY) size = fields.RelationField(label='размер', relation=beings_relations.SIZE) weapon_1 = fields.RelationField( label='оружие 1', relation=artifacts_relations.STANDARD_WEAPON) material_1 = fields.RelationField(label='материал оружия 1', relation=tt_artifacts_relations.MATERIAL) power_type_1 = fields.RelationField( label='тип силы оружия 1', relation=artifacts_relations.ARTIFACT_POWER_TYPE) weapon_2 = fields.RelationField( label='оружие 2', required=False, relation=artifacts_relations.STANDARD_WEAPON) material_2 = fields.RelationField(label='материал оружия 2', required=False, relation=tt_artifacts_relations.MATERIAL) power_type_2 = fields.RelationField( label='тип силы оружия 2', required=False, relation=artifacts_relations.ARTIFACT_POWER_TYPE) weapon_3 = fields.RelationField( label='оружие 3', required=False, relation=artifacts_relations.STANDARD_WEAPON) material_3 = fields.RelationField(label='материал оружия 3', required=False, relation=tt_artifacts_relations.MATERIAL) power_type_3 = fields.RelationField( label='тип силы оружия 3', required=False, relation=artifacts_relations.ARTIFACT_POWER_TYPE) def clean_abilities(self): abilities_ids = self.cleaned_data['abilities'] if HIT.get_id() not in abilities_ids: abilities_ids.append(HIT.get_id()) if not abilities_ids: raise ValidationError('не указаны способности монстра') for ability_id in abilities_ids: if ability_id not in ABILITY_CHOICES_DICT: raise ValidationError( 'неверный идентификатор способности монстра') return frozenset(abilities_ids) def clean_terrains(self): terrains = self.cleaned_data['terrains'] if not terrains: raise ValidationError('не указаны места обитания монстра') return frozenset(terrains) def clean_features(self): features = self.cleaned_data['features'] if not features: return frozenset() return frozenset(features) def get_weapons(self): weapons = [] if self.c.weapon_1 and self.c.material_1 and self.c.power_type_1: weapons.append( artifacts_objects.Weapon(weapon=self.c.weapon_1, material=self.c.material_1, power_type=self.c.power_type_1)) if self.c.weapon_2 and self.c.material_2 and self.c.power_type_2: weapons.append( artifacts_objects.Weapon(weapon=self.c.weapon_2, material=self.c.material_2, power_type=self.c.power_type_2)) if self.c.weapon_3 and self.c.material_3 and self.c.power_type_3: weapons.append( artifacts_objects.Weapon(weapon=self.c.weapon_3, material=self.c.material_3, power_type=self.c.power_type_3)) return weapons @classmethod def get_initials(cls, mob): initials = { 'description': mob.description, 'type': mob.type, 'name': mob.utg_name, 'archetype': mob.archetype, 'level': mob.level, 'global_action_probability': mob.global_action_probability, 'terrains': mob.terrains, 'abilities': mob.abilities, 'communication_verbal': mob.communication_verbal, 'communication_gestures': mob.communication_gestures, 'communication_telepathic': mob.communication_telepathic, 'intellect_level': mob.intellect_level, 'structure': mob.structure, 'features': list(mob.features), 'movement': mob.movement, 'body': mob.body, 'size': mob.size, 'is_mercenary': mob.is_mercenary, 'is_eatable': mob.is_eatable } for i, weapon in enumerate(mob.weapons, start=1): initials['weapon_{}'.format(i)] = weapon.type initials['material_{}'.format(i)] = weapon.material initials['power_type_{}'.format(i)] = weapon.power_type return initials
def get_terrains(self): if not hasattr(self, '_terrains'): self._terrains = frozenset( TERRAIN(terrain) for terrain in s11n.from_json(self._model.terrains)) return self._terrains
class MobRecordBaseForm(forms.Form): level = fields.IntegerField(label=u'минимальный уровень') name = WordField(word_type=utg_relations.WORD_TYPE.NOUN, label=u'Название') type = fields.TypedChoiceField(label=u'тип', choices=MOB_TYPE_CHOICES, coerce=MOB_TYPE.get_from_name) archetype = fields.TypedChoiceField( label=u'тип', choices=game_relations.ARCHETYPE.choices(), coerce=game_relations.ARCHETYPE.get_from_name) global_action_probability = fields.FloatField( label= u'вероятность встретить монстра, если идёт его набег (от 0 до 1, 0 — нет набега)' ) terrains = fields.TypedMultipleChoiceField(label=u'места обитания', choices=TERRAIN.choices(), coerce=TERRAIN.get_from_name) abilities = fields.MultipleChoiceField(label=u'способности', choices=ABILITY_CHOICES) description = bbcode.BBField(label=u'Описание', required=False) def clean_abilities(self): abilities_ids = self.cleaned_data['abilities'] if HIT.get_id() not in abilities_ids: abilities_ids.append(HIT.get_id()) if not abilities_ids: raise ValidationError(u'не указаны способности монстра') for ability_id in abilities_ids: if ability_id not in ABILITY_CHOICES_DICT: raise ValidationError( u'неверный идентификатор способности монстра') return frozenset(abilities_ids) def clean_terrains(self): terrains = self.cleaned_data['terrains'] if not terrains: raise ValidationError(u'не указаны места обитания монстра') return frozenset(terrains) @classmethod def get_initials(cls, mob): return { 'description': mob.description, 'type': mob.type, 'name': mob.utg_name, 'archetype': mob.archetype, 'level': mob.level, 'global_action_probability': mob.global_action_probability, 'terrains': mob.terrains, 'abilities': mob.abilities }