Exemple #1
0
def _create_loot_tables(ctx: Context, namespace: str, opts: HatsOptions):
    data = DataPack()

    registry = HatRegistry.get(opts.cmd_id)

    for category, hats in registry.categories.items():
        # Create category loot tables
        for model_type in ["hat", "hat_on_head"]:
            data.loot_tables[
                f"{namespace}/{model_type}/{category}/all"] = _create_all_hats_from_collection_loot_table(
                    ctx, hats, namespace, model_type)
            data.loot_tables[
                f"{namespace}/{model_type}/{category}/random"] = _create_random_hat_from_collection_loot_table(
                    ctx, hats, namespace, model_type)

        # Create hat loot tables
        for hat in hats:
            data.loot_tables[
                f"{namespace}/hat_on_head/{hat.type}"] = _create_hat_loot_table(
                    ctx, hat, hat.item_head or opts.default_item_head)
            data.loot_tables[
                f"{namespace}/hat/{hat.type}"] = _create_hat_loot_table(
                    ctx, hat, hat.item_inventory
                    or opts.default_item_inventory)

    return data
Exemple #2
0
def test_merge_nuke():
    def nuke(*args: Any) -> bool:
        raise Drop()

    p1 = DataPack(
        description="hello",
        merge_policy=MergePolicy(extra={"pack.mcmeta": [nuke]}),
    )

    p1.merge_policy.extend(MergePolicy(namespace={Function: [nuke]}))
    p1.merge_policy.extend_namespace_extra("foo.json", nuke)

    p1["demo:foo"] = Function()
    p1["demo"].extra["foo.json"] = JsonFile()
    p1["thing"].extra["foo.json"] = JsonFile()

    p2 = DataPack(description="world")
    p2["demo:foo"] = Function()
    p2["demo:bar"] = Function()
    p2["demo"].extra["foo.json"] = JsonFile()

    p1.merge(p2)

    assert p1.description == ""
    assert list(p1.functions) == ["demo:bar"]
    assert list(p1["demo"].extra) == []
    assert p1["thing"].extra["foo.json"] == JsonFile()
Exemple #3
0
def test_context_manager_load(tmp_path: Path):
    with DataPack(path=tmp_path / "foobar") as p1:
        p1["hello:world"] = Function(["say hello"], tags=["minecraft:load"])

    p2 = DataPack()
    p2.load(tmp_path / "foobar")
    assert p2 == p1
Exemple #4
0
def test_tag_replace():
    p1 = DataPack()
    p1["demo:foo"] = Function(["say hello"], tags=["minecraft:load"])

    p2 = DataPack()
    p2["minecraft:load"] = FunctionTag({
        "values": ["demo:bar"],
        "replace": True
    })

    p1.merge(p2)

    assert p1 == {
        "demo": {
            Function: {
                "foo": Function(["say hello"])
            }
        },
        "minecraft": {
            FunctionTag: {
                "load": FunctionTag({
                    "values": ["demo:bar"],
                    "replace": True
                })
            }
        },
    }
Exemple #5
0
def test_with_tags():
    p1 = DataPack()
    p2 = DataPack()

    p1["hello:world"] = Function(["say hello"], tags=["minecraft:load"])

    assert p1 != p2

    p2["hello"]["world"] = Function(["say hello"])
    p2["minecraft"].function_tags["load"] = FunctionTag(
        {"values": ["hello:world"]})
    assert p1 == p2
Exemple #6
0
def test_context_manager(tmp_path: Path):
    with DataPack(path=tmp_path / "foobar") as p1:
        p1["hello:world"] = Function(["say hello"], tags=["minecraft:load"])

    p2 = DataPack(path=tmp_path / "foobar")
    assert p2 == p1

    assert p2.functions["hello:world"].lines == ["say hello"]
    assert p2.function_tags["minecraft:load"].data == {
        "values": ["hello:world"]
    }
    assert p2 == p1
Exemple #7
0
def test_merge_block_tags():
    p1 = DataPack()
    p1["custom:blocks"] = BlockTag({"values": ["minecraft:stone"]})

    p2 = DataPack()
    p2["custom:blocks"] = BlockTag({"values": ["minecraft:dirt"]})

    p1.merge(p2)

    assert dict(p1.block_tags) == {
        "custom:blocks":
        BlockTag({"values": ["minecraft:stone", "minecraft:dirt"]})
    }
Exemple #8
0
def _generate_function_for_hat(namespace: str, hat_type: str):
    data = DataPack()

    data.functions[f"{namespace}/event/recipe/{hat_type}"] = Function(
        textwrap.dedent(f"""
        loot give @s loot oran9eutan:hats/hat/{hat_type}
        clear @s knowledge_book 1

        # Reset
        advancement revoke @s only oran9eutan:hats/event/recipe/{hat_type}
        recipe take @s oran9eutan:hats/{hat_type}
    """)[1:])

    return data
Exemple #9
0
def test_merge_tags():
    p1 = DataPack()
    p1["hello:func1"] = Function(["say foo"], tags=["minecraft:tick"])

    p2 = DataPack()
    p2["hello:func2"] = Function(["say bar"], tags=["minecraft:tick"])

    p1.merge(p2)

    assert len(p1.functions) == 2
    assert len(p1.function_tags) == 1
    assert p1.function_tags["minecraft:tick"].data == {
        "values": ["hello:func1", "hello:func2"]
    }
Exemple #10
0
def create_livereload_data_pack() -> DataPack:
    data = DataPack("livereload")

    prefix = {"text": "[livereload]", "color": "red"}
    ready = ["", prefix, " ", {"text": "Ready", "color": "gold"}]
    changes = ["", prefix, " ", {"text": f"Changes detected", "color": "gold"}]
    reloaded = ["", prefix, " ", {"text": f"Reloaded", "color": "gold"}]

    data["livereload:load"] = Function(
        [
            "schedule clear livereload:poll",
            "scoreboard objectives add livereload dummy",
            f"execute unless score delta livereload matches 1.. run tellraw @a {json.dumps(ready)}",
            f"execute if score delta livereload matches 1.. run tellraw @a {json.dumps(reloaded)}",
            "schedule function livereload:poll 1s",
        ],
        tags=["minecraft:load"],
    )

    data["livereload:poll"] = Function([
        "execute store result score new_pack_count livereload run datapack list available",
        "scoreboard players operation delta livereload = new_pack_count livereload",
        "scoreboard players operation delta livereload -= pack_count livereload",
        "scoreboard players operation pack_count livereload = new_pack_count livereload",
        "execute unless score delta livereload matches 1.. run schedule function livereload:poll 1s",
        f"execute if score delta livereload matches 1.. run tellraw @a {json.dumps(changes)}",
        "execute if score delta livereload matches 1.. run schedule function livereload:reload 1s",
    ])

    data["livereload:reload"] = Function(["reload"])

    return data
Exemple #11
0
def test_on_bind_rename():
    @dataclass
    class RenameTo:
        name: str

        def __call__(self, instance: Function, pack: DataPack, path: str):
            if path != self.name:
                pack[self.name] = instance
                raise Drop()

    pack = DataPack()
    pack["hello:world"] = Function(["say hello"],
                                   tags=["minecraft:load"],
                                   on_bind=RenameTo("hello:other"))

    assert pack == {
        "hello": {
            Function: {
                "other": Function(["say hello"])
            }
        },
        "minecraft": {
            FunctionTag: {
                "load": FunctionTag({"values": ["hello:other"]})
            }
        },
    }
Exemple #12
0
def test_merge_rules():
    def combine_description(
        pack: DataPack,
        path: str,
        current: JsonFile,
        conflict: JsonFile,
    ) -> bool:
        current.data["pack"]["description"] += conflict.data["pack"][
            "description"]
        return True

    pack = DataPack(description="hello")
    pack.merge_policy.extend_extra("pack.mcmeta", combine_description)

    pack.merge(DataPack(description="world"))

    assert pack.description == "helloworld"
Exemple #13
0
def _generate_recipes_for_hat(namespace: str, hat_type: str,
                              recipes: list[ShapelessHatRecipe]):
    data = DataPack()

    for i, recipe in enumerate(recipes, start=1):
        if isinstance(recipe, ShapelessHatRecipe):
            suffix = f"_{i}" if len(recipes) > 1 else ""
            data.recipes[f"{namespace}/{hat_type}{suffix}"] = Recipe({
                "type":
                "minecraft:crafting_shapeless",
                "ingredients":
                recipe.ingredients,
                "result": {
                    "item": "minecraft:knowledge_book",
                    "count": 1
                },
            })

    return data
Exemple #14
0
def test_empty():
    assert Document() == Document()
    assert Document().data == DataPack()
    assert Document().assets == ResourcePack()
    assert Document().get_text() == ""
    empty = "# Lectern snapshot\n\nThe data pack and resource pack are empty.\n"
    assert Document().get_markdown() == empty
    assert Document().get_markdown(emit_external_files=True) == (empty, {})
    assert Document(text="Nothing to see here") == Document()
    assert Document(markdown="Nothing to see here") == Document()
Exemple #15
0
def test_text_function():
    pack = DataPack()
    pack["demo:foo"] = Function(["say foo"])

    doc = Document(data=pack)
    doc.add_text("@function demo:bar\nsay bar\n")

    assert pack.functions == {
        "demo:foo": Function(["say foo"]),
        "demo:bar": Function(["say bar"]),
    }
Exemple #16
0
def test_equality():
    assert DataPack() == DataPack()
    assert DataPack("hello") == DataPack("hello")
    assert DataPack("hello") != DataPack("world")

    p1 = DataPack("foo", mcmeta=JsonFile({"pack": {"description": "bar"}}))
    p2 = DataPack("foo", mcmeta=JsonFile({"pack": {"description": "bar"}}))
    assert p1 == p2

    p1 = DataPack("foo",
                  mcmeta=JsonFile(
                      {"pack": {
                          "description": "bar",
                          "pack_format": 6
                      }}))
    p2 = DataPack("foo",
                  mcmeta=JsonFile(
                      {"pack": {
                          "description": "bar",
                          "pack_format": 5
                      }}))
    assert p1 != p2
Exemple #17
0
def _generate_category_fashion_show_functions(namespace: str,
                                              registry: HatRegistry):
    data = DataPack()

    for category, hats in registry.categories.items():
        lines = []
        for i, hat in enumerate(hats):
            lines += [
                f"execute if score #show_progress hats.math matches {i} run loot replace entity @e[tag=fashion_model] armor.head loot {namespace}/hat_on_head/{hat.type}",
                f'execute if score #show_progress hats.math matches {i} run title @a subtitle {{"translate": "item.hats.hat.{hat.type}.name"}}',
            ]

        lines += [
            f'title @a title {{"text": ""}}',
            "scoreboard players add #show_progress hats.math 1",
            f"execute if score #show_progress hats.math matches {len(hats)}.. run scoreboard players set #show_progress hats.math 0",
        ]

        data.functions[f"{namespace}/dev/fashion_show_{category}"] = Function(
            "\n".join(lines))

    return data
Exemple #18
0
def test_proxy_match():
    pack = DataPack()
    custom = pack["custom"]
    hey = pack["hey"]

    for i in range(100):
        custom[f"path/to/func_{i:02d}"] = Function([f"say {i}"])
        hey[f"path/to/func_{i:02d}"] = Function([f"say {i}"])

    custom["path/to/end"] = Function(["say end"])

    custom["other/subdir/hello"] = Function(["say hello"])
    custom["other/subdir/world"] = Function(["say world"])
    custom["other/thing"] = Function(["say thing"])

    hey["other/subdir/hello"] = Function(["say hello"])

    custom_funcs = [f"custom:path/to/func_{i:02d}" for i in range(100)]
    hey_funcs = [f"hey:path/to/func_{i:02d}" for i in range(100)]

    assert pack.functions.match() == set()

    assert pack.functions.match("*") == set(custom_funcs) | set(hey_funcs) | {
        "custom:path/to/end",
        "custom:other/subdir/hello",
        "custom:other/subdir/world",
        "custom:other/thing",
        "hey:other/subdir/hello",
    }

    assert pack.functions.match("custom:*") == set(custom_funcs) | {
        "custom:path/to/end",
        "custom:other/subdir/hello",
        "custom:other/subdir/world",
        "custom:other/thing",
    }

    assert pack.functions.match("*:other/subdir") == {
        "custom:other/subdir/hello",
        "custom:other/subdir/world",
        "hey:other/subdir/hello",
    }

    assert pack.functions.match(
        "*:path/to/func_0*", "*:path/to/end",
        "hey:other") == set(custom_funcs[:10]) | set(hey_funcs[:10]) | {
            "custom:path/to/end",
            "hey:other/subdir/hello",
        }
Exemple #19
0
def _generate_advancement_for_hat(namespace: str, hat_type: str,
                                  recipes: list[ShapelessHatRecipe]):
    data = DataPack()

    criteria = {}
    for i, recipe in enumerate(recipes, start=1):
        suffix = f"_{i}" if len(recipes) > 1 else ""
        criteria[f"recipe{suffix}"] = {
            "trigger": "minecraft:recipe_unlocked",
            "conditions": {
                "recipe": f"{namespace}/{hat_type}{suffix}"
            },
        }

    data.advancements[f"{namespace}/event/recipe/{hat_type}"] = Advancement({
        "criteria":
        criteria,
        "requirements": [[c for c in criteria.keys()]],
        "rewards": {
            "function": f"{namespace}/event/recipe/{hat_type}"
        },
    })

    return data
Exemple #20
0
def test_on_bind():
    def on_bind_callback(instance: Function, pack: DataPack, path: str):
        pack[path + "_alias"] = Function([f"function {path}"])

    pack = DataPack()
    pack["hello:world"] = Function(["say hello"],
                                   tags=["minecraft:load"],
                                   on_bind=on_bind_callback)

    assert pack.functions == {
        "hello:world": Function(["say hello"]),
        "hello:world_alias": Function(["function hello:world"]),
    }

    assert pack.function_tags == {
        "minecraft:load": FunctionTag({"values": ["hello:world"]})
    }
Exemple #21
0
    def apply_directives(
        self,
        directives: Mapping[str, Directive],
        fragments: Iterable[Fragment],
        loaders: Iterable[FragmentLoader] = (),
    ) -> Tuple[ResourcePack, DataPack]:
        """Apply directives into a blank data pack and a blank resource pack."""
        assets, data = ResourcePack(), DataPack()

        for fragment in fragments:
            for loader in loaders:
                fragment = loader(fragment, directives)
                if not fragment:
                    break
            if fragment:
                directives[fragment.directive](fragment, assets, data)

        return assets, data
Exemple #22
0
    def __init__(
        self,
        assets: Optional[ResourcePack] = None,
        data: Optional[DataPack] = None,
    ):
        super().__init__()
        self.resolvers = []
        self.assets = assets or ResourcePack()
        self.data = data or DataPack()

        self["data_pack"] = DataPackDirective()
        self["resource_pack"] = ResourcePackDirective()
        self["skip"] = SkipDirective()

        @self.add_resolver
        def _(self: DirectiveRegistry):
            for pack in [self.assets, self.data]:
                for file_type in pack.resolve_scope_map().values():
                    name = snake_case(file_type.__name__)
                    self[name] = NamespacedResourceDirective(file_type)
Exemple #23
0
def test_namespaces():
    p1 = DataPack()
    p2 = DataPack()

    assert p1 == p2
    assert p1["hello"] == p2["hello"]

    del p1["hello"]

    assert dict(p1) != dict(p2)
    assert p1.keys() != p2.keys()
    assert p1 == p2

    del p1["hello"]

    p1["hello:world"] = Function(["say hello"])

    assert p1 != p2
    assert p1.keys() == p2.keys()
    assert p1["hello"] != p2["hello"]

    p2["hello:world"] = Function(["say hello"])

    assert p1 == p2
    assert p1["hello"] == p2["hello"]

    p2.functions["hello:world"].lines.append("say world")

    assert p1.functions["hello:world"] != p2.functions["hello:world"]
    assert p1["hello"] != p2["hello"]
    assert p1 != p2

    p1["hello"].functions["world"].lines.append("say world")

    assert p1.functions["hello:world"] == p2.functions["hello:world"]
    assert p1["hello"] == p2["hello"]
    assert p1 == p2
Exemple #24
0
def test_match():
    pack = DataPack()
    custom = pack["custom"]

    for i in range(100):
        custom[f"path/to/func_{i:02d}"] = Function([f"say {i}"])

    custom["path/to/end"] = Function(["say end"])

    custom["other/subdir/hello"] = Function(["say hello"])
    custom["other/subdir/world"] = Function(["say world"])
    custom["other/thing"] = Function(["say thing"])

    funcs = [f"path/to/func_{i:02d}" for i in range(100)]

    assert custom.functions.match() == set()

    assert custom.functions.match("*") == set(funcs) | {
        "path/to/end",
        "other/subdir/hello",
        "other/subdir/world",
        "other/thing",
    }

    assert custom.functions.match("path/to/func_0*") == set(funcs[:10])
    assert custom.functions.match("path/to/func_*") == set(funcs)

    assert custom.functions.match("path/to") == set(funcs) | {"path/to/end"}
    assert custom.functions.match("path/to/func_*", "other") == set(funcs) | {
        "other/subdir/hello",
        "other/subdir/world",
        "other/thing",
    }

    assert custom.functions.match("other/subdir") == {
        "other/subdir/hello",
        "other/subdir/world",
    }
Exemple #25
0
def test_vanilla_compare(minecraft_data_pack: Path):
    assert DataPack(path=minecraft_data_pack) == DataPack(
        path=minecraft_data_pack)
Exemple #26
0
def test_vanilla_zip(minecraft_data_pack: Path, tmp_path: Path):
    pack = DataPack(path=minecraft_data_pack)
    zipped_pack = pack.save(tmp_path, zipped=True)
    assert DataPack(path=zipped_pack) == DataPack(path=zipped_pack)
Exemple #27
0
def test_vanilla_content(minecraft_data_pack: Path):
    pack = DataPack(path=minecraft_data_pack)
    assert len(list(pack.content)) > 3000
Exemple #28
0
def test_vanilla_igloo(minecraft_data_pack: Path):
    pack = DataPack(path=minecraft_data_pack)
    assert pack.structures["minecraft:igloo/top"].data["size"] == [7, 5, 8]
Exemple #29
0
def test_merge_extra():
    pack = DataPack()
    pack.merge(DataPack(description="hello", pack_format=88))
    assert pack.description == "hello"
    assert pack.pack_format == 88
Exemple #30
0
def test_vanilla_igloo_content(minecraft_data_pack: Path):
    pack = DataPack(path=minecraft_data_pack)
    content = dict(pack.content)
    igloo_structure = content["minecraft:igloo/top"]
    assert isinstance(igloo_structure, Structure)
    assert igloo_structure.data["size"] == [7, 5, 8]