def dimension_type(self, name_parts: ResourceIdentifier, fixed_time: int,
                    has_skylight: bool, has_ceiling: bool, ultrawarm: bool,
                    natural: bool, coordinate_scale: float,
                    piglin_safe: bool, bed_works: bool,
                    respawn_anchor_works: bool, has_raids: bool, min_y: int,
                    height: int, logical_height: int,
                    infiniburn: ResourceIdentifier,
                    effects: ResourceIdentifier, ambient_light: float):
     res = utils.resource_location(self.domain, name_parts)
     self.write(
         (*self.resource_dir, 'data', res.domain, 'dimension_type',
          res.path), {
              'fixed_time': fixed_time,
              'has_skylight': has_skylight,
              'has_ceiling': has_ceiling,
              'ultrawarm': ultrawarm,
              'natural': natural,
              'coordinate_scale': coordinate_scale,
              'piglin_safe': piglin_safe,
              'bed_works': bed_works,
              'respawn_anchor_works': respawn_anchor_works,
              'has_raids': has_raids,
              'min_y': min_y,
              'height': height,
              'logical_height': logical_height,
              'infiniburn': utils.resource_location(infiniburn).join(),
              'effects': utils.resource_location(effects).join(),
              'ambient_light': ambient_light
          })
 def item_model(self,
                name_parts: ResourceIdentifier,
                *textures: Union[Json, str],
                parent: ResourceIdentifier = 'item/generated',
                no_textures: bool = False) -> ItemContext:
     """
     Creates an item model file
     :param name_parts: the resource location, including path elements.
     :param textures: the textures for the model. Defaults to 'domain:item/name/parts'
     :param parent: the parent model.
     :param no_textures: if the textures element should be ignored
     """
     res = utils.resource_location(self.domain, name_parts)
     if no_textures:
         textures = None
     else:
         if textures is None or len(textures) == 0:
             textures = res.join('item/'),
         textures = utils.item_model_textures(textures)
     self.write(
         (*self.resource_dir, 'assets', res.domain, 'models', 'item',
          res.path), {
              'parent': utils.resource_location(parent).join(simple=True),
              'textures': textures
          })
     return ItemContext(self, res)
 def dimension(self, name_parts: ResourceIdentifier,
               dimension_type: ResourceIdentifier, generator: Json):
     res = utils.resource_location(self.domain, name_parts)
     self.write(
         (*self.resource_dir, 'data', res.domain, 'dimension', res.path), {
             'type': utils.resource_location(dimension_type).join(),
             'generator': generator
         })
 def custom_item_model(self, name_parts: ResourceIdentifier,
                       loader: ResourceIdentifier,
                       data: Dict[str, Any]) -> ItemContext:
     res = utils.resource_location(self.domain, name_parts)
     self.write((*self.resource_dir, 'assets', res.domain, 'models', 'item',
                 res.path), {
                     'loader': utils.resource_location(loader).join(),
                     **data
                 })
     return ItemContext(self, res)
 def placed_feature(self, name_parts: ResourceIdentifier,
                    feature: ResourceIdentifier,
                    *placements: TypeWithOptionalConfig):
     res = utils.resource_location(self.domain, name_parts)
     self.write(
         (*self.resource_dir, 'data', res.domain, 'worldgen',
          'placed_feature', res.path), {
              'feature': utils.resource_location(feature).join(),
              'placement':
              [utils.configured_placement(p) for p in placements]
          })
예제 #6
0
def configured_placement(data):
    if utils.is_sequence(data):
        res, cfg = utils.unordered_pair(data, str, dict)
        assert 'type' not in cfg, 'Type specified twice for placement'
        return {'type': utils.resource_location(res).join(), **cfg}
    elif isinstance(data, dict):
        assert 'type' in data, 'Missing \'type\' in placement'
        return data
    elif isinstance(data, str):
        return {'type': utils.resource_location(data).join()}
    else:
        raise ValueError('Unknown object %s at configured_placement' %
                         str(data))
 def advancement(self,
                 name_parts: ResourceIdentifier,
                 display: Json = None,
                 parent: str = None,
                 criteria: Dict[str, Dict[str, Json]] = None,
                 requirements: Sequence[Sequence[str]] = None,
                 rewards: Dict[str, Json] = None):
     """
     Creates a generic advancement. Performs basic filling in of data types
     :param name_parts: The resource location, including path elements.
     :param display: The display data. Inserted as is.
     :param parent: The parent advancement registry name
     :param criteria: The criteria for an advancement. Inserted as is.
     :param requirements: The requirements. If None, will default to a list of all the requirements (OR'd together).
     :param rewards: The rewards. Inserted as is.
     """
     res = utils.resource_location(self.domain, name_parts)
     if requirements is None:
         requirements = [[k for k in criteria.keys()]]
     self.write(
         (*self.resource_dir, 'data', res.domain, 'advancements', res.path),
         {
             'parent': parent,
             'criteria': criteria,
             'display': display,
             'requirements': requirements,
             'rewards': rewards
         })
 def crafting_shaped(self,
                     name_parts: ResourceIdentifier,
                     pattern: Sequence[str],
                     ingredients: Json,
                     result: Json,
                     group: str = None,
                     conditions: Optional[Json] = None) -> RecipeContext:
     """
     Creates a shaped crafting recipe.
     :param name_parts: The resource location, including path elements.
     :param pattern: The pattern for the recipe.
     :param ingredients: The ingredients, indexed by key in pattern.
     :param result: The result of crafting the recipe.
     :param group: The group.
     :param conditions: Any conditions for the recipe to be enabled.
     """
     res = utils.resource_location(self.domain, name_parts)
     self.write(
         (*self.resource_dir, 'data', res.domain, 'recipes', res.path), {
             'type': 'minecraft:crafting_shaped',
             'group': group,
             'pattern': pattern,
             'key': utils.item_stack_dict(ingredients, ''.join(pattern)[0]),
             'result': utils.item_stack(result),
             'conditions': utils.recipe_condition(conditions)
         })
     return RecipeContext(self, res)
 def block_model(self,
                 name_parts: ResourceIdentifier,
                 textures: Union[Dict[str, str], Sequence[str]] = None,
                 parent: Union[str, None] = 'block/cube_all',
                 elements: Json = None,
                 no_textures: bool = False) -> BlockContext:
     """
     Creates a block model file
     :param name_parts: the resource location, including path elements.
     :param textures: the textures for the model. Defaults to 'domain:block/name/parts'
     :param parent: the parent model. If none, it is omitted
     :param elements: elements of the model. Can be a single element, which will get expanded to a list of one element
     :param no_textures: If true, textures will be ignored.
     """
     res = utils.resource_location(self.domain, name_parts)
     if textures is None:
         if not no_textures:
             textures = {'all': res.join('block/')}
     elif isinstance(textures, str):
         textures = {'all': textures}
     elif isinstance(textures, Sequence):
         textures = dict((k, res.join('block')) for k in textures)
     if isinstance(elements, Dict):
         elements = [elements]
     self.write((*self.resource_dir, 'assets', res.domain, 'models',
                 'block', res.path), {
                     'parent': parent,
                     'textures': textures,
                     'elements': elements
                 })
     return BlockContext(self, res)
예제 #10
0
    def advancement(self,
                    name: str,
                    icon: Json,
                    title: str,
                    description: str,
                    parent: Optional[str],
                    criteria: Json,
                    requirements: Json = None,
                    frame: str = 'task',
                    toast: bool = True,
                    chat: bool = True,
                    hidden: bool = False):
        key = '%s.advancements.%s.%s' % (self.rm.domain, self.category, name)

        if parent is not None:
            parent = utils.resource_location(self.rm.domain, self.category +
                                             '/' + parent).join()

        self.rm.advancement(
            (self.category, name), {
                'icon': utils.item_stack(icon),
                'title': {
                    'translate': key + '.title'
                },
                'description': {
                    'translate': key + '.description'
                },
                'frame': frame,
                'show_toast': toast,
                'announce_to_chat': chat,
                'hidden': hidden,
                'background': self.background
            }, parent, criteria, requirements)
        self.rm.lang(key + '.title', title)
        self.rm.lang(key + '.description', description)
예제 #11
0
def recipe_unlocked(recipe: ResourceIdentifier) -> Json:
    return {
        'trigger': 'minecraft:recipe_unlocked',
        'conditions': {
            'recipe': utils.resource_location(recipe).join()
        }
    }
 def configured(self,
                name_parts: ResourceIdentifier,
                feature: ResourceIdentifier,
                config: Json = None,
                root: str = ''):
     res = utils.resource_location(self.domain, name_parts)
     self.write((*self.resource_dir, 'data', res.domain, 'worldgen', root,
                 res.path), utils.configure(feature, config))
 def noise(self, name_parts: ResourceIdentifier, first_octave: float,
           *amplitudes: float):
     res = utils.resource_location(self.domain, name_parts)
     self.write((*self.resource_dir, 'data', res.domain, 'worldgen',
                 'noise', res.path), {
                     'firstOctave': first_octave,
                     'amplitudes': amplitudes
                 })
예제 #14
0
 def with_item_model(self) -> 'BlockContext':
     """
     Shortcut for a block item model, which generates a model with a single parent reference to the block model of the same name
     """
     self.rm.item_model(self.res,
                        parent=utils.resource_location(
                            self.rm.domain, 'block/' + self.res.path),
                        no_textures=True)
     return self
 def loot(self, name_parts: ResourceIdentifier, *loot_pools: Json,
          path: str, loot_type: str) -> ResourceLocation:
     res = utils.resource_location(self.domain, name_parts)
     self.write(
         (*self.resource_dir, 'data', res.domain, 'loot_tables', path,
          res.path), {
              'type': loot_type,
              'pools': [utils.loot_pool(pool, path) for pool in loot_pools]
          })
     return res
예제 #16
0
def noise_threshold_condition(noise: ResourceIdentifier, min_value: float,
                              max_value: float,
                              then: JsonObject) -> JsonObject:
    return condition(
        {
            'type': 'minecraft:noise_threshold',
            'noise': utils.resource_location(noise).join(),
            'min_threshold': min_value,
            'max_threshold': max_value
        }, then)
 def write(self, path_parts: Sequence[str], data_in: Json):
     m = self.modified_files
     super(ModificationLoggingResourceManager,
           self).write(path_parts, data_in)
     if m != self.modified_files:
         print('Modified: ' +
               utils.resource_location(self.domain, path_parts).join(),
               file=sys.stderr)
         traceback.print_stack()
         print('', file=sys.stderr)
예제 #18
0
 def bucket_item_model(name_parts, fluid):
     res = utils.resource_location(rm.domain, name_parts)
     rm.write(
         (*rm.resource_dir, 'assets', res.domain, 'models', 'item',
          res.path), {
              'parent': 'forge:item/bucket',
              'loader': 'forge:bucket',
              'fluid': fluid
          })
     return rm.item(name_parts)
    def biome(self,
              name_parts: ResourceIdentifier,
              precipitation: str = 'none',
              category: str = 'none',
              temperature: float = 0,
              temperature_modifier: str = 'none',
              downfall: float = 0.5,
              effects: Optional[Json] = None,
              air_carvers: Optional[Sequence[str]] = None,
              water_carvers: Optional[Sequence[str]] = None,
              features: Sequence[Sequence[str]] = None,
              structures: Sequence[str] = None,
              spawners: Optional[Json] = None,
              player_spawn_friendly: bool = True,
              creature_spawn_probability: float = 0.5,
              parent: Optional[str] = None,
              spawn_costs: Optional[Json] = None):
        """ Creates a biome, with all possible optional parameters filled in to the minimum required state. Parameters are exactly as they appear in the final biome. """
        if effects is None:
            effects = {}
        for required_effect in ('fog_color', 'sky_color', 'water_color',
                                'water_fog_color'):
            if required_effect not in effects:
                effects[required_effect] = 0

        if features is None:
            features = []
        if structures is None:
            structures = []
        if spawners is None:
            spawners = {}
        if spawn_costs is None:
            spawn_costs = {}
        res = utils.resource_location(self.domain, name_parts)
        self.write(
            (*self.resource_dir, 'data', res.domain, 'worldgen', 'biome',
             res.path), {
                 'precipitation': precipitation,
                 'category': category,
                 'temperature': temperature,
                 'temperature_modifier': temperature_modifier,
                 'downfall': downfall,
                 'effects': effects,
                 'carvers': {
                     'air': air_carvers,
                     'liquid': water_carvers
                 },
                 'features': features,
                 'starts': structures,
                 'spawners': spawners,
                 'player_spawn_friendly': player_spawn_friendly,
                 'creature_spawn_probability': creature_spawn_probability,
                 'parent': parent,
                 'spawn_costs': spawn_costs
             })
예제 #20
0
def biome_condition(biomes: Sequence[ResourceIdentifier],
                    then: JsonObject) -> JsonObject:
    return condition(
        {
            'type':
            'minecraft:biome',
            'biome_is': [
                utils.resource_location(r).join()
                for r in utils.str_list(biomes)
            ]
        }, then)
예제 #21
0
 def with_tag(self,
              tag_name_parts: Sequence[str] = None,
              replace: bool = None) -> 'BlockContext':
     """
     Shortcut for ResourceManager#block_tag
     """
     if tag_name_parts is None:
         tag_name_parts = self.res
     tag_res = utils.resource_location(self.rm.domain, tag_name_parts)
     self.rm.block_tag(tag_res, self.res, replace=replace)
     return self
 def blockstate_multipart(self, name_parts: ResourceIdentifier,
                          *parts: Json) -> BlockContext:
     """
     Creates a blockstate file, using the multipart model syntax
     :param name_parts: the resource location, including path elements.
     :param parts: The parts. Each element can be a 2-element sequence of a 'when' and 'apply' json, or a single 'apply' json.
     """
     res = utils.resource_location(self.domain, name_parts)
     self.write((*self.resource_dir, 'assets', res.domain, 'blockstates',
                 res.path),
                {'multipart': utils.blockstate_multipart_parts(parts)})
     return BlockContext(self, res)
예제 #23
0
 def damage_shapeless(name_parts: utils.ResourceIdentifier, ingredients: utils.Json, result: utils.Json, group: str = None, conditions: utils.Json = None) -> RecipeContext:
     res = utils.resource_location(rm.domain, name_parts)
     rm.write((*rm.resource_dir, 'data', res.domain, 'recipes', res.path), {
         'type': 'tfc:damage_inputs_crafting',
         'recipe': {
             'type': 'minecraft:crafting_shapeless',
             'group': group,
             'ingredients': utils.item_stack_list(ingredients),
             'result': utils.item_stack(result),
             'conditions': utils.recipe_condition(conditions)
         }
     })
     return RecipeContext(rm, res)
 def data(self,
          name_parts: ResourceIdentifier,
          data_in: Dict[str, Any],
          root_domain: str = 'data'):
     """
     Creates a generic data file. Used for anything and everything under the sun.
     :param name_parts: The resource location, including path elements.
     :param data_in: Data to be inserted into the json
     :param root_domain: The root location (either data or assets) to insert into
     """
     res = utils.resource_location(self.domain, name_parts)
     self.write((*self.resource_dir, root_domain, res.domain, res.path),
                data_in)
 def tag(self,
         name_parts: ResourceIdentifier,
         root_domain: str,
         *values: ResourceIdentifier,
         replace: bool = None):
     """
     Creates or appends to a tag entry
     :param name_parts: The resource location, including path elements.
     :param root_domain: The root domain of the tag. Should be 'blocks', 'items', 'fluids', or 'entity_types'
     :param values: The resource location values for the tag
     :param replace: If the tag should replace previous values
     """
     res = utils.resource_location(self.domain, name_parts)
     values = [utils.resource_location(self.domain, v) for v in values]
     if res not in self.tags_buffer[root_domain]:
         if replace is None:
             replace = False
         tag = Tag(replace)
         tag.add_all(values)
         self.tags_buffer[root_domain][res] = tag
     else:
         self.tags_buffer[root_domain][res].add_all(values)
         if replace is not None:
             self.tags_buffer[root_domain][res].replace = replace
 def recipe(self,
            name_parts: ResourceIdentifier,
            type_in: str,
            data_in: Dict[str, Any],
            group: str = None,
            conditions: Json = None) -> RecipeContext:
     """
     Creates a non-crafting recipe file, used for custom mod recipes using vanilla's data pack system
     :param name_parts: The resource location, including path elements.
     :param type_in: The type of the recipe.
     :param data_in: Data required by the recipe, as present in json
     :param group: The group.
     :param conditions: Any conditions for the recipe to be enabled.
     """
     res = utils.resource_location(self.domain, name_parts)
     self.write(
         (*self.resource_dir, 'data', res.domain, 'recipes', res.path), {
             'type': type_in,
             'group': group,
             **data_in, 'conditions': utils.recipe_condition(conditions)
         })
     return RecipeContext(self, res)
 def crafting_shapeless(self,
                        name_parts: ResourceIdentifier,
                        ingredients: Json,
                        result: Json,
                        group: str = None,
                        conditions: Optional[Json] = None) -> RecipeContext:
     """
     Creates a shapeless crafting recipe.
     :param name_parts: The resource location, including path elements.
     :param ingredients: The ingredients.
     :param result: The result of crafting the recipe.
     :param group: The group.
     :param conditions: Any conditions for the recipe to be enabled.
     """
     res = utils.resource_location(self.domain, name_parts)
     self.write(
         (*self.resource_dir, 'data', res.domain, 'recipes', res.path), {
             'type': 'minecraft:crafting_shapeless',
             'group': group,
             'ingredients': utils.item_stack_list(ingredients),
             'result': utils.item_stack(result),
             'conditions': utils.recipe_condition(conditions)
         })
     return RecipeContext(self, res)
 def blockstate(self,
                name_parts: ResourceIdentifier,
                model: str = None,
                variants: Dict[str, Json] = None,
                use_default_model: bool = True) -> BlockContext:
     """
     Creates a blockstate file
     :param name_parts: the resource location, including path elements.
     :param model: the model, used if there are no variants. Defaults to 'domain:block/name/parts'
     :param variants: the variants, as they would be present in json
     :param use_default_model: if a model is missing for a variant, should this populate the variant using the assumed model
     """
     res = utils.resource_location(self.domain, name_parts)
     if model is None:
         model = res.join('block/')
     if variants is None:
         variants = {'': {'model': model}}
     if use_default_model:
         for key, prop in variants.items():
             if 'model' not in prop:
                 prop['model'] = model
     self.write((*self.resource_dir, 'assets', res.domain, 'blockstates',
                 res.path), {'variants': variants})
     return BlockContext(self, res)
 def noise_settings(self, name_parts: ResourceIdentifier,
                    ore_veins_enabled: bool, noodle_caves_enabled: bool,
                    legacy_random_source: bool,
                    disable_mob_generation: bool, aquifers_enabled: bool,
                    noise_caves_enabled: bool, default_block: Json,
                    default_fluid: Json, sea_level: int, noise: Json,
                    surface_rule: Json, structures: Json):
     res = utils.resource_location(self.domain, name_parts)
     self.write(
         (*self.resource_dir, 'data', res.domain, 'worldgen',
          'noise_settings', res.path), {
              'ore_veins_enabled': ore_veins_enabled,
              'noodle_caves_enabled': noodle_caves_enabled,
              'legacy_random_source': legacy_random_source,
              'disable_mob_generation': disable_mob_generation,
              'aquifers_enabled': aquifers_enabled,
              'noise_caves_enabled': noise_caves_enabled,
              'default_block': utils.block_state(default_block),
              'default_fluid': utils.block_state(default_fluid),
              'sea_level': sea_level,
              'noise': noise,
              'surface_rule': surface_rule,
              'structures': structures
          })
 def item(self, name_parts: ResourceIdentifier) -> ItemContext:
     return ItemContext(self,
                        utils.resource_location(self.domain, name_parts))