diff --git a/.gitignore b/.gitignore index 9e7cd96..e24f122 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ textures/particle/damage.png textures/particle/flash.png textures/particle/nautilus.png textures/particle/bubble_pop.png -textures/particle/sweep_attack.png \ No newline at end of file +textures/particle/sweep_attack.png +textures/entity/illager/illusioner.png \ No newline at end of file diff --git a/developer_documentation.md b/developer_documentation.md index c4065a4..4e9adf1 100644 --- a/developer_documentation.md +++ b/developer_documentation.md @@ -3,6 +3,7 @@ * [Armor stands](#Armor-stands) * [Part visibility and rotation encoding](#Part-visibility-and-rotation-encoding) * [Geometry and attachables](#Geometry-and-attachables) + * [Illusioners](#Illusioners) * [Iron golems](#Iron-golems) * [Cracking](#Cracking) * [Materials](#Materials) @@ -107,6 +108,29 @@ In order to utilize multiple textures, a render controller containing a texture The trinary operator ensures that even if `max_health`, defined at 100, is overflowed, the expression will never produce a value outside the range of 0-3. As all data is derived resource pack side, this addition requires no modification by the server (though `query.is_bribed` enables the feature). The textures required for this to display can be retrieved during the build process. +### Illusioners + +The illusioner does not exist in Bedrock Edition. Full implementation, however, would require more than a simple texture swap. This is due to the illusioner's special attack, which creates four duplicate false illusioners, which lack a hit box. The actual illusioner remains invisible during this attack. Implementing this would likely be possible from a technical perspective, but it would require either some kind of helper entity attached to the illusioner by Geyser, such as an invisible armor stand, or the removal of invisibility during the illusioner's special attack. The former would be preferable, as it would maintain some degree of functionality for users without the pack. + +Currently, the optional pack uses a render controller to perform a simple texture swap on the illusioner. This is accomplished by replacing the evocation illager with the illusioner when the evocation illager returns true for the Molang query `q.is_bribed`. The following texture array is defined in the render controller: + +```json +{ + "arrays": { + "textures": { + "Array.skins": [ + "Texture.default", + "Texture.illusioner" + ] + } + } +} +``` + +The position used in the array for the texture is then defined by `Array.skins[q.is_bribed]`. + +The geometry of the evoker was also slightly modified to include the hat of the illusioner. Since Bedrock edition uses the textures of Java edition for all illagers, and the evoker has an unused hat on its Java edition texture, the render controller is also utilized to hide the the render controller is set to hide the helmet layer unless `q.is_bribed` is true. + ### Killer bunnies The killer bunny does not exist in Bedrock Edition. Nonetheless, this is primarily a simple texture swap. The "caerbannog" texture is the name of the texture in Java Edition, so that name has been used for consistency. This texture is added to the pack and the rabbit entity definition file. In order to construct the Molang query, the "Toast" rabbit must also be considered. In the event a rabbit is named "Toast", the texture is always overridden as the texture "Toast", including in the case of the killer bunny. Therefore, the query to select the texture is constructed with `q.is_bribed` being determined by Geyser: diff --git a/entity/evocation_illager.entity.json b/entity/evocation_illager.entity.json new file mode 100755 index 0000000..1ec39c3 --- /dev/null +++ b/entity/evocation_illager.entity.json @@ -0,0 +1,43 @@ +{ + "format_version": "1.10.0", + "minecraft:client_entity": { + "description": { + "identifier": "minecraft:evocation_illager", + "min_engine_version": "1.8.0", + "materials": { + "default": "evoker" + }, + "textures": { + "default": "textures/entity/illager/evoker", + "illusioner": "textures/entity/illager/illusioner" + }, + "geometry": { + "default": "geometry.evoker.v1.8" + }, + "scripts": { + "scale": "0.9375", + "animate": [ + "controller_general", + "controller_move" + ] + }, + "animations": { + "general": "animation.evoker.general", + "casting": "animation.evoker.casting", + "look_at_target": "animation.common.look_at_target", + "move": "animation.villager.move", + "celebrating": "animation.humanoid.celebrating", + "controller_general": "controller.animation.evoker.general", + "controller_move": "controller.animation.villager.move" + }, + "particle_effects": { + "spell": "minecraft:evoker_spell" + }, + "render_controllers": [ "controller.render.evoker" ], + "spawn_egg": { + "texture": "spawn_egg", + "texture_index": 40 + } + } + } +} diff --git a/models/entity/evoker.geo.json b/models/entity/evoker.geo.json new file mode 100755 index 0000000..1d891c3 --- /dev/null +++ b/models/entity/evoker.geo.json @@ -0,0 +1,99 @@ +{ + "format_version": "1.8.0", + "geometry.evoker.v1.8": { + "texturewidth": 64, + "textureheight": 64, + "visible_bounds_width": 2, + "visible_bounds_height": 3, + "visible_bounds_offset": [0, 1.5, 0], + "bones": [ + { + "name": "body", + "pivot": [0, 24, 0], + "cubes": [ + {"origin": [-4, 12, -3], "size": [8, 12, 6], "uv": [16, 20]}, + {"origin": [-4, 6, -3], "size": [8, 18, 6], "uv": [0, 38], "inflate": 0.5} + ] + }, + { + "name": "head", + "parent": "body", + "pivot": [0, 24, 0], + "cubes": [ + {"origin": [-4, 24, -4], "size": [8, 10, 8], "uv": [0, 0]} + ] + }, + { + "name": "nose", + "parent": "head", + "pivot": [0, 26, 0], + "cubes": [ + {"origin": [-1, 23, -6], "size": [2, 4, 2], "uv": [24, 0]} + ] + }, + { + "name": "helmet", + "parent": "head", + "pivot": [0, 24, 0], + "cubes": [ + {"origin": [-4, 24, -4], "size": [8, 10, 8], "uv": [32, 0], "inflate": 0.5} + ] + }, + { + "name": "arms", + "parent": "body", + "pivot": [0, 22, 0], + "cubes": [ + {"origin": [-8, 16, -2], "size": [4, 8, 4], "uv": [44, 22]}, + {"origin": [4, 16, -2], "size": [4, 8, 4], "uv": [44, 22]}, + {"origin": [-4, 16, -2], "size": [8, 4, 4], "uv": [40, 38]} + ] + }, + { + "name": "leg0", + "parent": "body", + "pivot": [-2, 12, 0], + "cubes": [ + {"origin": [-4, 0, -2], "size": [4, 12, 4], "uv": [0, 22]} + ] + }, + { + "name": "leg1", + "parent": "body", + "pivot": [2, 12, 0], + "mirror": true, + "cubes": [ + {"origin": [0, 0, -2], "size": [4, 12, 4], "uv": [0, 22]} + ] + }, + { + "name": "rightArm", + "parent": "body", + "pivot": [-5, 22, 0], + "cubes": [ + {"origin": [-8, 12, -2], "size": [4, 12, 4], "uv": [40, 46]} + ], + "locators": { + "right_hand": [-6, 12, 0] + } + }, + { + "name": "rightItem", + "parent": "rightArm", + "pivot": [-5.5, 16, 0.5] + }, + { + "name": "leftArm", + "parent": "body", + "pivot": [5, 22, 0], + "mirror": true, + "cubes": [ + {"origin": [4, 12, -2], "size": [4, 12, 4], "uv": [40, 46]} + ], + "locators": { + "left_hand": [6, 12, 0] + } + } + ] + } +} \ No newline at end of file diff --git a/render_controllers/evoker.render_controllers.json b/render_controllers/evoker.render_controllers.json new file mode 100755 index 0000000..93a1076 --- /dev/null +++ b/render_controllers/evoker.render_controllers.json @@ -0,0 +1,27 @@ +{ + "format_version": "1.8.0", + "render_controllers": { + "controller.render.evoker": { + "arrays": { + "textures": { + "Array.skins": [ + "Texture.default", + "Texture.illusioner" + ] + } + }, + "geometry": "Geometry.default", + "materials": [ { "*": "Material.default" } ], + "part_visibility": [ + { "*": true }, + { "arms": "!(q.is_casting || q.is_celebrating)" }, + { "leftarm": "q.is_casting || q.is_celebrating" }, + { "rightarm": "q.is_casting || q.is_celebrating" }, + { "helmet": "q.is_bribed" } + ], + "textures": [ + "Array.skins[q.is_bribed]" + ] + } + } +} diff --git a/required_files.txt b/required_files.txt index a2f4b0e..ef785c3 100644 --- a/required_files.txt +++ b/required_files.txt @@ -5,4 +5,5 @@ assets/minecraft/textures/entity/projectiles/spectral_arrow.png textures/entity/ assets/minecraft/textures/entity/rabbit/caerbannog.png textures/entity/rabbit/ assets/minecraft/textures/particle/damage.png textures/particle/ assets/minecraft/textures/particle/flash.png textures/particle/ -assets/minecraft/textures/particle/nautilus.png textures/particle/ \ No newline at end of file +assets/minecraft/textures/particle/nautilus.png textures/particle/ +assets/minecraft/textures/entity/illager/illusioner.png textures/entity/illager/ \ No newline at end of file