diff --git a/build.gradle b/build.gradle index fa02b2b..84ada1f 100644 --- a/build.gradle +++ b/build.gradle @@ -167,6 +167,7 @@ dependencies { modImplementation("curse.maven:bendy-lib-623373:4550371") modImplementation("curse.maven:waystones-245755:6856603") modImplementation("curse.maven:balm-531761:7087245") +// modImplementation("curse.maven:kaleidoscope-doll-1233277:7201584") // modRuntimeOnly("curse.maven:luckperms-431733:4738950") modImplementation("software.bernie.geckolib:geckolib-forge-${minecraft_version}:${geckolib_version}") implementation("com.eliotlash.mclib:mclib:20") diff --git a/gradle.properties b/gradle.properties index 8c818cc..8a6c87f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -59,7 +59,7 @@ mod_name=Super Lead Rope # The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default. mod_license=GPLv3 # The mod version. See https://semver.org/ -mod_version=0.0.0.9 +mod_version=1.0.0 # The group ID for the mod. It is only important when publishing as an artifact to a Maven repository. # This should match the base package used for the mod sources. # See https://maven.apache.org/guides/mini/guide-naming-conventions.html diff --git a/res/doll.bbmodel b/res/doll.bbmodel new file mode 100644 index 0000000..1cbcd57 --- /dev/null +++ b/res/doll.bbmodel @@ -0,0 +1 @@ +{"meta":{"format_version":"5.0","model_format":"java_block","box_uv":false},"name":"doll","parent":"","java_block_version":"1.21.6","ambientocclusion":true,"front_gui_light":false,"visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"unhandled_root_fields":{"format_version":"1.21.6"},"resolution":{"width":16,"height":16},"elements":[{"name":"Toggle_Helmet","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[3.5,8.8,7.5],"to":[12.5,17.8,16.5],"autouv":0,"color":0,"origin":[8,9.3,12],"faces":{"north":{"uv":[10,2,12,4],"texture":0},"east":{"uv":[8,2,10,4],"texture":0},"south":{"uv":[14,2,16,4],"texture":0},"west":{"uv":[12,2,14,4],"texture":0},"up":{"uv":[10,2,12,0],"texture":0},"down":{"uv":[12,0,14,2],"texture":0}},"type":"cube","uuid":"4034240c-1bb7-3096-56d0-f9d9158bd705"},{"name":"Head","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[4,9.3,8],"to":[12,17.3,16],"autouv":0,"color":0,"origin":[8,9.3,12],"faces":{"north":{"uv":[2,2,4,4],"texture":0},"east":{"uv":[0,2,2,4],"texture":0},"south":{"uv":[6,2,8,4],"texture":0},"west":{"uv":[4,2,6,4],"texture":0},"up":{"uv":[4,2,2,0],"texture":0},"down":{"uv":[6,0,4,2],"texture":0}},"type":"cube","uuid":"5eca2c83-4481-ddf5-fafe-19abeb647c57"},{"name":"Toggle_Chest_Armor","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[4.75,2.05,9.75],"to":[11.25,9.55,13.25],"autouv":0,"color":0,"origin":[8,5.8,11.5],"faces":{"north":{"uv":[5,9,7,12],"texture":0},"east":{"uv":[4,9,5,12],"texture":0},"south":{"uv":[8,9,10,12],"texture":0},"west":{"uv":[7,9,8,12],"texture":0},"up":{"uv":[5,8,7,9],"texture":0},"down":{"uv":[7,8,9,9],"texture":0}},"type":"cube","uuid":"8ea34c7a-dcd8-ead4-07d1-ccab4438046e"},{"name":"Body","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[5,2.3,10],"to":[11,9.3,13],"autouv":0,"color":3,"origin":[8,5.8,11.5],"faces":{"north":{"uv":[5,5,7,8],"texture":0},"east":{"uv":[4,5,5,8],"texture":0},"south":{"uv":[8,5,10,8],"texture":0},"west":{"uv":[7,5,8,8],"texture":0},"up":{"uv":[7,5,5,4],"texture":0},"down":{"uv":[9,4,7,5],"texture":0}},"type":"cube","uuid":"fd16d848-4320-9a3f-6b3d-3f4884a92fbe"},{"name":"Toggle_Left_Arm_Armor","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[2.75,6.25,3.8],"to":[5.25,9.75,13.3],"autouv":0,"color":3,"rotation":[0,-22.5,0],"origin":[3,8,12.5],"faces":{"north":{"uv":[13.75,12,14.5,13],"rotation":180,"texture":0},"east":{"uv":[12,13,13,16],"rotation":270,"texture":0},"south":{"uv":[13,12,13.75,13],"texture":0},"west":{"uv":[13.75,13,14.75,16],"rotation":90,"texture":0},"up":{"uv":[13,13,13.75,16],"rotation":180,"texture":0},"down":{"uv":[14.75,13,15.5,16],"texture":0}},"type":"cube","uuid":"06ccbe71-f249-9062-076b-ea3f530fa945"},{"name":"Left_arm","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[3,6.5,3.8],"to":[5,9.5,12.8],"autouv":0,"color":6,"rotation":[0,-22.5,0],"origin":[4,8,12.5],"faces":{"north":{"uv":[10.5,12,9.75,13],"rotation":180,"texture":0},"east":{"uv":[8,13,9,16],"rotation":270,"texture":0},"south":{"uv":[9.75,13,9,12],"texture":0},"west":{"uv":[9.75,13,10.5,16],"rotation":90,"texture":0},"up":{"uv":[9,13,9.75,16],"rotation":180,"texture":0},"down":{"uv":[10.5,13,11.5,16],"texture":0}},"type":"cube","uuid":"15980f9e-f82b-d64a-eaa4-38789e0635cc"},{"name":"Toggle_Right_Arm_Armor","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[10.75,6.25,3.8],"to":[13.25,9.75,13.3],"autouv":0,"color":6,"rotation":[0,22.5,0],"origin":[12,8,11.5],"faces":{"north":{"uv":[11.75,8,12.5,9],"rotation":180,"texture":0},"east":{"uv":[10,9,11,12],"rotation":270,"texture":0},"south":{"uv":[11,8,11.75,9],"texture":0},"west":{"uv":[11.75,9,12.75,12],"rotation":90,"texture":0},"up":{"uv":[11,9,11.75,12],"rotation":180,"texture":0},"down":{"uv":[12.75,9,13.5,12],"texture":0}},"type":"cube","uuid":"7b6c1629-5993-798e-8a6e-bb9303f0e8da"},{"name":"Right_arm","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[11,6.5,3.8],"to":[13.5,9.5,12.8],"autouv":0,"color":0,"rotation":[0,22.5,0],"origin":[12,8,11.5],"faces":{"north":{"uv":[12.5,4,11.75,5],"rotation":180,"texture":0},"east":{"uv":[10,5,11,8],"rotation":270,"texture":0},"south":{"uv":[11.75,5,11,4],"texture":0},"west":{"uv":[11.75,5,12.5,8],"rotation":90,"texture":0},"up":{"uv":[11,5,11.75,8],"rotation":180,"texture":0},"down":{"uv":[12.5,5,13.5,8],"texture":0}},"type":"cube","uuid":"e5bd3372-f4e5-9cc0-1f38-726db3f86001"},{"name":"Toggle_Left_Leg_Armor","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[5.2,-0.25,3.05],"to":[8.7,3.25,12.55],"autouv":0,"color":1,"rotation":[0,22.5,0],"origin":[5.7,2,13],"faces":{"north":{"uv":[2,12,3,13],"rotation":180,"texture":0},"east":{"uv":[0,13,1,16],"rotation":270,"texture":0},"south":{"uv":[1,12,2,13],"texture":0},"west":{"uv":[2,13,3,16],"rotation":90,"texture":0},"up":{"uv":[1,13,2,16],"rotation":180,"texture":0},"down":{"uv":[3,13,4,16],"texture":0}},"type":"cube","uuid":"859ab26f-304d-1fc2-e695-7c65fa9746c5"},{"name":"Left_leg","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[5.5,0,3.3],"to":[8.5,3,12.3],"autouv":0,"color":5,"rotation":[0,22.5,0],"origin":[6,2,13],"faces":{"north":{"uv":[7,12,6,13],"rotation":180,"texture":0},"east":{"uv":[4,13,5,16],"rotation":270,"texture":0},"south":{"uv":[5.95,13,5,11.925],"texture":0},"west":{"uv":[6,13,7,16],"rotation":90,"texture":0},"up":{"uv":[5,13,6,16],"rotation":180,"texture":0},"down":{"uv":[7,13,8,16],"texture":0}},"type":"cube","uuid":"1fb83a23-bc95-d6de-1a60-b721c8922407"},{"name":"Toggle_Right_Leg_Armor","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[7.2,-0.25,3.05],"to":[10.7,3.25,12.55],"autouv":0,"color":7,"rotation":[0,-22.5,0],"origin":[8.7,2,13],"faces":{"north":{"uv":[2,8,3,9],"rotation":180,"texture":0},"east":{"uv":[0,9,1,12],"rotation":270,"texture":0},"south":{"uv":[1,8,2,9],"texture":0},"west":{"uv":[2,9,3,12],"rotation":90,"texture":0},"up":{"uv":[1,9,2,12],"rotation":180,"texture":0},"down":{"uv":[3,9,4,12],"texture":0}},"type":"cube","uuid":"7fb46a5a-407b-6e68-5395-edf7ec58c151"},{"name":"Right_leg","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[7.5,0,3.3],"to":[10.5,3,12.3],"autouv":0,"color":0,"rotation":[0,-22.5,0],"origin":[9,2,13],"faces":{"north":{"uv":[3,4,2,5],"rotation":180,"texture":0},"east":{"uv":[0,5,1,8],"rotation":270,"texture":0},"south":{"uv":[2,5,1,4],"texture":0},"west":{"uv":[2,5,3,8],"rotation":90,"texture":0},"up":{"uv":[1,5,2,8],"rotation":180,"texture":0},"down":{"uv":[3,5,4,8],"texture":0}},"type":"cube","uuid":"2977e3b7-0d36-5caf-3a69-4c0fb7895a71"},{"name":"cube","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[7,6,1],"to":[7,14,9],"autouv":0,"color":8,"rotation":[0,45,0],"origin":[7,10,3.5],"faces":{"north":{"uv":[0,0,0,0],"texture":null},"east":{"uv":[0,0,16,16],"texture":1},"south":{"uv":[0,0,0,0],"texture":null},"west":{"uv":[0,0,16,16],"texture":1},"up":{"uv":[0,0,0,0],"texture":null},"down":{"uv":[0,0,0,0],"texture":null}},"type":"cube","uuid":"ba8da4eb-b48e-0c2f-8240-95d681f387ff"},{"name":"cube","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[9,6,1],"to":[9,14,9],"autouv":0,"color":0,"rotation":[0,-45,0],"origin":[9,10,3.5],"faces":{"north":{"uv":[0,0,0,0],"texture":null},"east":{"uv":[0,0,16,16],"texture":1},"south":{"uv":[0,0,0,0],"texture":null},"west":{"uv":[0,0,16,16],"texture":1},"up":{"uv":[0,0,0,0],"texture":null},"down":{"uv":[0,0,0,0],"texture":null}},"type":"cube","uuid":"3644a889-b638-1c56-700d-f80c64cc474c"}],"groups":[{"uuid":"eda1d026-dfe0-f980-152d-71db37d8a5b3","export":true,"locked":false,"origin":[3,-6.7,6],"rotation":[0,0,0],"color":0,"name":"Player","children":[],"reset":false,"shade":true,"mirror_uv":false,"selected":false,"visibility":true,"autouv":0,"isOpen":true,"primary_selected":false},{"uuid":"5399b7c3-2eac-47ae-fb88-873e7e24a5d6","export":true,"locked":false,"origin":[8,16,8],"rotation":[0,0,0],"color":0,"name":"Head","children":[],"reset":false,"shade":true,"mirror_uv":false,"selected":false,"visibility":true,"autouv":0,"isOpen":false,"primary_selected":false},{"uuid":"0c759830-21cb-f6ec-e6d7-af3998e4bbd2","export":true,"locked":false,"origin":[8,11,8],"rotation":[0,0,0],"color":0,"name":"Body","children":[],"reset":false,"shade":true,"mirror_uv":false,"selected":false,"visibility":true,"autouv":0,"isOpen":false,"primary_selected":false},{"uuid":"b31348f5-2c4e-cfd0-cec3-4c11d4a5bee2","export":true,"locked":false,"origin":[5,15,6],"rotation":[0,0,0],"color":0,"name":"Left_Arm","children":[],"reset":false,"shade":true,"mirror_uv":false,"selected":false,"visibility":true,"autouv":0,"isOpen":true,"primary_selected":false},{"uuid":"eb158d47-d395-3084-947f-4101fa1eb833","export":true,"locked":false,"origin":[11,15,6],"rotation":[0,0,0],"color":0,"name":"Right_Arm","children":[],"reset":false,"shade":true,"mirror_uv":false,"selected":false,"visibility":true,"autouv":0,"isOpen":true,"primary_selected":false},{"uuid":"0022c2e4-2add-b938-2d45-0a8b8b95d53a","export":true,"locked":false,"origin":[7,13,7],"rotation":[0,0,0],"color":0,"name":"Left_Leg","children":[],"reset":false,"shade":true,"mirror_uv":false,"selected":false,"visibility":true,"autouv":0,"isOpen":true,"primary_selected":true},{"uuid":"c752460c-4cd8-aaae-17c7-d45bf46741e4","export":true,"locked":false,"origin":[10,13,7],"rotation":[0,0,0],"color":0,"name":"Right_Leg","children":[],"reset":false,"shade":true,"mirror_uv":false,"selected":false,"visibility":true,"autouv":0,"isOpen":true,"primary_selected":false},{"uuid":"6e676a00-56e1-2ec4-ecb9-00710aada58d","export":true,"locked":false,"origin":[0,4,2.5],"rotation":[0,0,0],"color":0,"name":"item","children":[],"reset":false,"shade":true,"mirror_uv":false,"selected":false,"visibility":true,"autouv":0,"isOpen":false,"primary_selected":false}],"outliner":[{"uuid":"eda1d026-dfe0-f980-152d-71db37d8a5b3","isOpen":true,"children":[{"uuid":"5399b7c3-2eac-47ae-fb88-873e7e24a5d6","isOpen":false,"children":["4034240c-1bb7-3096-56d0-f9d9158bd705","5eca2c83-4481-ddf5-fafe-19abeb647c57"]},{"uuid":"0c759830-21cb-f6ec-e6d7-af3998e4bbd2","isOpen":false,"children":["8ea34c7a-dcd8-ead4-07d1-ccab4438046e","fd16d848-4320-9a3f-6b3d-3f4884a92fbe"]},{"uuid":"b31348f5-2c4e-cfd0-cec3-4c11d4a5bee2","isOpen":true,"children":["06ccbe71-f249-9062-076b-ea3f530fa945","15980f9e-f82b-d64a-eaa4-38789e0635cc"]},{"uuid":"eb158d47-d395-3084-947f-4101fa1eb833","isOpen":true,"children":["7b6c1629-5993-798e-8a6e-bb9303f0e8da","e5bd3372-f4e5-9cc0-1f38-726db3f86001"]},{"uuid":"0022c2e4-2add-b938-2d45-0a8b8b95d53a","isOpen":true,"children":["859ab26f-304d-1fc2-e695-7c65fa9746c5","1fb83a23-bc95-d6de-1a60-b721c8922407"]},{"uuid":"c752460c-4cd8-aaae-17c7-d45bf46741e4","isOpen":true,"children":["7fb46a5a-407b-6e68-5395-edf7ec58c151","2977e3b7-0d36-5caf-3a69-4c0fb7895a71"]}]},{"uuid":"6e676a00-56e1-2ec4-ecb9-00710aada58d","isOpen":false,"children":["ba8da4eb-b48e-0c2f-8240-95d681f387ff","3644a889-b638-1c56-700d-f80c64cc474c"]}],"textures":[{"name":"author.png","relative_path":"H:/Download/2d9f724107b509db.png","folder":"H:/Download","namespace":"","id":"0","group":"","width":64,"height":64,"uv_width":16,"uv_height":16,"particle":true,"use_as_default":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","pbr_channel":"color","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"f5a406a9-0e83-e8e7-427a-4cf3e6991f20","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAOZ0lEQVR4AcyafWyV1R3Hf/dKW8rLtVAVKRSKDgWiVVmUCGhUdEZwVqJsWVYzndvYHDFz6pap29Rs/KHEMBNd3HTTbHFmThP+UBMZ4hDdNJnzLSooDixcKFq4XITSVnl2Pr/e3+25p899a3lZ088939/LOc9zzvNynreklPl7qqElemPSqdH2X39cAD5iz1z7nwjubXs18sEHZZovG8789pMIwkR8EPqrtcsOwMmj6wba7ByQKIu9u7sXs4A4X0FCFUb3ru5B2XG+QUkVOMoOwIQbVkvLHeulfny9vJ7t0ibR+IiV6mipmDZUwU/DD45PTLx9SiJMxUcs9Fdrlx0AGmS0QTvk9gI0EJs1rpYillKx2ApHwVnRAIjr9Osf9G999gLVzsf66qA4sfTGXvFxLrEY+v+Vigagfma9zJszWdiis6c3qsZHp/DRcbQPPmIXzr4s8vFzjob21wVd0QCwu8PsVKOuMxowzrvmMwoZ2dxQAE5i17Uvk4XNd8q6K66Ury5bhvuosvb15xI+ZQdgzNKUnHhbs7Dbs/tzOAA+Yg/dXysjT2sRmXpCAfiIXXPTQmk/Z6KMvHqW3HTdwiF1PnJ/YUXnikLfUOwkczlz+vYb3Txv5Ob8vZ9myi7k+4+cKl0PR9K1oqeAd2dfLCf94+vy9Lhp0vngJfLhqqmyY3mHbM+1zTJZNnM5yCH+o02fsHmLJZnLTx4jwjENJDLNARr6PnhHzl8xDamM+UVK8KnhfsgFJ3W6RNOmtj26TtB+DI2PONoOJ7QPWxkS7o+NYYOHdq4EMfDrmPbb9HUYTzKfb+o/jC2WL7dl9gsc6MjIulv+q34OAzQ+YqABfnIzA5I2aRvQ+HzwEdv75yuFOd2Pmf6sa48ANsukZHA/uzuL1JjF1eH90CZtA9oLqcRHLIm17ZInKPIwYrDpV50CL/1pjHBC88FHDMiFfANO+G3SUc4bzt3/7wZKfc7q2vyp+x34f/n0i6KOefP00Bt7XEMC2PI6pbp6ZLIR2IWJAT7qUBdt0DaYHZbEdAAI0AGgcV3Z3MKIrXjrNmm7dTlSQeNTgx9yHdSlDcDtQ8xsX5+5bUP+Ku+LNV+L5j57kjS//LL66DhwAr511Rz10faiR89KdL/XnT+f0C51qEsb2EDbgI6DWJIG86PrOkFi47110ni7Lk/oqE1lxMCmNGLY5FIHbYNHm7RtEIvTdJAYHLPgr4lE88P9C8bB+jjoMObE+90lsbMLdM7GR13aQANtG77t66SusPOwVYAVly075cA7m/VKbmZ9s+SnsuaG/rk+N6URI59c6qBpA1yTom2zgg5iZvtafZosEt490g7kwlroIKgSvTcJ4wVtuOVq+5TUoQRPJ2mAKzZdKQKO1cs/d7/9/9OOu176dm6VxlvcXWFurt89/RT1TXOx/iwRvw5t0SZtG+TFaXzE4mDLQ0Gncon4iEHONaigbYMgGnydpAHgGKNseeM2afj3zfLw9TfL3I9+Jut33ChLrrhalpx/hVx+5gVSWzchoUxoTlAHUgvOS1AXTeN0nkFAAxofev/aW4RlbHhxqaDhvpZzoienLojQ5ITQtvmiXdsj4ITc29kR9W58O8queUlPmuT4uWjDYti+zp8EccbRnc0KpLu6ZHdfX1zKIJ9dMvuBOJ8fr1Zz6V1zwmSpmX5a0aq93QeicpQdgPpUSupTKWlqbJRxNTVFF2YBv6NsJYiLme9wl+lJMwRsOaatLDsAVrGa0o4zttLY1qla1XxqHIIfLsQ4N/lXpMWabdr2fsEg+HlJjj0fP4j+yf7RYvxyxEThYoNjlpJ6nIzA7iWo49N3cGBWwz+/7Y8Cp17wkIy6cIWC3nzmctW0xbNFSujt6Yx8+kYnBWhLZx8nGGjOA2C5zp3/Z2szCDgosdGQbFu9Utpee7Qf9MbH5ey/PybLnn9ETl95VyzEzn7qN0Jddnl289FtW/LTEj4aZyvZSuJjLwByqYPPID9WZ7znjWg3RTPlkg+6DHepjlaCOL6w09j4Iam3sQ3usRYwzeH1NXYIecYEkfTUkxXO9iDOx1l/7EXzBdD4iIHl4zMsB9vXsicj2mE6hnbrUuNOfIkzTpc4iLmUgn+2uHUaDZYw+BzAKBuWVabsSmcF5t58rMDnz35DbErbOn++anzEgFwo06yG6VDIhk3b9SaNG7EQYuRrZfdDx8FJ/UcbOJI9e+ukpvYEBd1zzFjR6cVNMbalwtLPpxEj84dugREL/yIc039ruVj2PfakanzEwPIrKbnbo1OAhkkNo4pWJUaOJTS7GczAZ5oSO5lpWyRspTcnzxA0YL/y0gbpWtw+AFs5Z7/SukCIk8ul5l1LF8s9t36L9vKwG/9+VFp++s3F+iwxH3CCXOpQN4/zF/xzyQrOSafAyar/O9x1DPgVfTvZsOoZgX3jJ2mJhtZZJ4o88OAAtJCzW9c+LcTJw80FEhdKPDAFOnXn+iV6/cBFFBofMSCXOtQtgA6D5xzTeKzE4aUUSMs1J1sazKb07aRVmPvWmkELIjkOq0PJWX1l/RQBOgkfrb1WbaZPpk5i+IgBNlDX4ORoy0Kb33xhyTkkjjCPrQ3mR4PZg0+CFnFlY1NK4nCh/D/3DWaw0trRnGNKqkcgZwoxcsymLphNDMz2Y+artmzOnQOsXmiXHACrVKqkg0brB8u0w9jp7MAFEBof+DnYtE1HuUGiBNPEOKHFQSwOy7UYW9vAZ5oSO2kV4sq4XQyfn0sjw4FBANqgBF/riRaHAw1OivzwBsX2ULOJ5XOcwRZ3hRQrk+2LLpWrzjtXKEM4Uxs/+vblYtrPa7p7kvxr60gFDZOfmCkdib1CCaaJQTX5k9evz5+b0BNeeFrqxvbkr1CbtmwSsKtWzkvk0WkoR3LVq68mnn/vvQRlCH6oT/XfDaLBz+MR1JItaxKAhoR7rPXjza/p4y1fEwNyAQ1+jq81xvNvD30W4Z5J8AwiDkv1O25b33y+XdE5wDpsDZQruTEKc+J8Yc7hsDnWwdpGg9kVDUDbnDkRWKVSZamOloqVavNwxioagGpXwJ/KrG6cz2JHovS3Ossze9DzAO7xudcnyUr/EDAfJbnkAVsX0KUgB0rlHKpYbf3IRDmSS3InML+c9/YLOolb6a+Q+SipYzEeVwNbmvt6HmpYDI2PGDlgMUobEErwfejDybAPAV48+CuoT10niN4ARR3fiXhTw40R9/ka85LzdV2+uikBw0p0AC9EeUEaBzHSeXLsk8lkIh9yYNgDQCMhvHikswc3ZqXjnzsEjS/Mw84PAkYAMToUwlTHO8E4iJEvOzeLsmenfPrFCHmxZZZkpp+VxxaVZBTZSmwtNNAAvP9hOoqDGJBrDfklK85uv/+M30nLHesSaHx+TqWaDoWUq0v+9tRUUeqOl/SML8v4pB7Vg6omGUW2ElsLDTQAM77UlIiDGJDL3Z21yvEL2Lwk0bgz0K4QYoBWuPU11OH9FPN7KaVk7xnzBPa0nisHokj68q9OCmvpIXDMc18IV12FoSFYHLfAyofV8RGDMGY2OWC2K9nT4nCh2H/L7Y4OCnQdPCi7HCJF9gBxfx9n69zv0P45s+drsvKOAl8uqD4X8/cYfEYuLV8U8+cTyois2+LQ47b+zroaSY+ul043EIZV1z2AKc0c1Zac4KyOrbTvsxg+i/s+/GbHxS1Wbbnf7QGwtXaE9HR3S/pAtzsMDgo+sPZ0ADD4wsIHHxc7BnY56AzwQoNcaw+Njxhg+5iPEohZybkmDnLisFx2f6Dz++pqpdcNQtYNCj6wujoArChfWPjQcfYMA9sq+SV1Q3jo4eeg8YV5vk2O2b7mmMYGNKCZgQANaECTs3D3tgR8L9uZuOmTjsTP93WpjQ/IAx0AOo5hcONzz6h9ZmrJQKhwP8TBSf2chfohfszXYZ7Zfo6v2aLYgAY0MwygAQ1oy0GXQwcgTPKv/YnRWUBDGMdnsKfc13JORPmke+f/lZkz9U6S+mB5xUre79kVHJr3/3wHQH46nY7ebJwSrRs/yZ3i8Ayf2AEImy3V4TA3tHn8zWNwHo9DGA9tXnT6Pt7y8KIGX7k5nZxqqWgA2HJQbePkj6up0W8L6lMpfU+Ab6iUm9OH0m5FAzCUhodah7e9fl3e//MdAL75uzoSl2W2JRbs3hp/VUNSlQwaAI5d2qDkGIb2HWME0EDMctA++H2+u79J61IfrL6dJ/LHufetD+//YeT8U8TeXtt7f0rq+MsYjh40AHa2p+R+Pw5iLJTSnsb65bLnH9FvDNo2Pq7fEBR8f7B6pfBtATnUoR22OqAVXoVDpvS3AZo7zJ9BAzDM9vqr8+0A3xhgmcZG+7h4yXf8fA/AQADa5ddMP02/C3BS/5n7Q7gO0GDMDzHyLXR4BoAtZ9iSipTh+31sXoXT0TiIkWPNMfeHcB1AR+MgRr7VT5a732e0eFbAMwM0WMPUDb8dwGbaAr414JsD/3sC3ybXVsQveRVub5/oMJhNzM8tpuloHGF+stz9PqPFswKeGaDBGqaufkOQzg58R7C4Xb8d4BsDXlEB3x74Nt8W8I0BdcMVCm06DKH/UNkVHQI8K+CZQexCH3iw302Zo3XWicK3A0bctwd8Y6DfH/TXLvjl9VYpCpJjDNtDi5V+lYoGgArVPDMIVz7u2wNyaJeXrSH4S0F+qXg1sYoHgCkvrmF7O+uXcXlxPurE+Y+kLz8A4cWM3ZpaeSRXyk54xcpy62LnqGKlX18HgM6zhQ1su021koHwK5pmdwwptuKhn3q812dPALTiGufkCU7qPxrU4NsAFSLMSjmp2mw7/i3m25ZDTAeAjmMY97hnAeHNDwNhcWKAzTcD/rcD2O2LLpWQq2K+QSCXq8GmLYXv+OvG9gjfAfCen3MFoAFNHZYNzEqUgAa0bX00+Lbl4P8fAAAA///puc/hAAAABklEQVQDAPJ9OAtGaSsyAAAAAElFTkSuQmCC"},{"name":"allium.png","path":"","folder":"","namespace":"","id":"1","group":"","width":16,"height":16,"uv_width":16,"uv_height":16,"particle":false,"use_as_default":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","pbr_channel":"color","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":false,"uuid":"b68aca7b-f859-4cdb-5c04-2e5b1fcfe0b6","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAHlBMVEUAAADoz/7Spva4eO1Vqy2mXuFSmi5Kjyh7TqAXfAQSwnSGAAAAAXRSTlMAQObYZgAAADlJREFUeNpjwAqUAyA0k5AFhKGoGNQAZhgZmUIYrMrBUMXtBlAGO0w7G4zBgsFgQzDQdXEyMDAwAACVCARQ+FH48gAAAABJRU5ErkJggg=="}],"display":{"thirdperson_righthand":{"rotation":[75,45,0],"translation":[0,2.5,0],"scale":[0.375,0.375,0.375]},"thirdperson_lefthand":{"rotation":[75,45,0],"translation":[0,2.5,0],"scale":[0.375,0.375,0.375]},"firstperson_righthand":{"rotation":[0,124,0],"translation":[2,3,0],"scale":[0.4,0.4,0.4]},"firstperson_lefthand":{"rotation":[0,120,0],"translation":[1.5,2.75,0],"scale":[0.4,0.4,0.4]},"ground":{"translation":[0,2,0],"scale":[0.5,0.5,0.5]},"gui":{"rotation":[30,-135,0],"translation":[0.75,-1,0],"scale":[0.625,0.625,0.625]},"head":{"translation":[0,14,-0.75]},"fixed":{"translation":[0,0,-2.75],"scale":[0.5,0.5,0.5]},"on_shelf":{"rotation":[0,-180,0],"translation":[0,0,5.25]}}} \ No newline at end of file diff --git a/src/generated/resources/.cache/1de3d2ee724999f84a11b20b51c37030049be277 b/src/generated/resources/.cache/1de3d2ee724999f84a11b20b51c37030049be277 index 6001a3b..aaa0fa3 100644 --- a/src/generated/resources/.cache/1de3d2ee724999f84a11b20b51c37030049be277 +++ b/src/generated/resources/.cache/1de3d2ee724999f84a11b20b51c37030049be277 @@ -1,2 +1,2 @@ -// 1.20.1 2025-12-04T18:55:51.5054614 Languages: zh_tw -ff7556f7a8bd62a8c4cc776e45947835ffc19689 assets/superleadrope/lang/zh_tw.json +// 1.20.1 2025-12-11T17:31:55.2360112 Languages: zh_tw +d1253ab3534285cc6a4d6c0e5495720f48edd62f assets/superleadrope/lang/zh_tw.json diff --git a/src/generated/resources/.cache/2a65ee2815744be1ef1ffdae1c9a37f2a9cbe2ac b/src/generated/resources/.cache/2a65ee2815744be1ef1ffdae1c9a37f2a9cbe2ac index a3fe00e..95130d1 100644 --- a/src/generated/resources/.cache/2a65ee2815744be1ef1ffdae1c9a37f2a9cbe2ac +++ b/src/generated/resources/.cache/2a65ee2815744be1ef1ffdae1c9a37f2a9cbe2ac @@ -1,2 +1,2 @@ -// 1.20.1 2025-12-04T18:55:51.5004568 Languages: zh_cn -f5128cf6058db0e79f91aece8de7f5bdd8e04193 assets/superleadrope/lang/zh_cn.json +// 1.20.1 2025-12-11T17:31:55.2360112 Languages: zh_cn +7f4db04637eb656488388de206cad9070a53ae48 assets/superleadrope/lang/zh_cn.json diff --git a/src/generated/resources/.cache/31f65342fc4da49cb4df4f994bdb8a2aa9453b5d b/src/generated/resources/.cache/31f65342fc4da49cb4df4f994bdb8a2aa9453b5d index 0834274..bf13937 100644 --- a/src/generated/resources/.cache/31f65342fc4da49cb4df4f994bdb8a2aa9453b5d +++ b/src/generated/resources/.cache/31f65342fc4da49cb4df4f994bdb8a2aa9453b5d @@ -1,4 +1,5 @@ -// 1.20.1 2025-09-05T21:41:43.7307014 Item Models: superleadrope +// 1.20.1 2025-12-11T18:08:58.6978167 Item Models: superleadrope c982e91b60c03a6460d1cc7b516628cf09a28417 assets/superleadrope/models/item/broken_super_lead_rope.json +50782bef004ff1c69c09aa397a8ee92b71a8b858 assets/superleadrope/models/item/doll.json 7b072a8cc70b53d54e37e5fa72d705bd07780943 assets/superleadrope/models/item/eternal_potato.json 4fb737a5f8f15642212aa581a02a81cf649fc36f assets/superleadrope/models/item/super_lead_rope.json diff --git a/src/generated/resources/.cache/37795d5ddd279efaf18c4a7a336e7479b1a74e2a b/src/generated/resources/.cache/37795d5ddd279efaf18c4a7a336e7479b1a74e2a new file mode 100644 index 0000000..4730ffe --- /dev/null +++ b/src/generated/resources/.cache/37795d5ddd279efaf18c4a7a336e7479b1a74e2a @@ -0,0 +1,2 @@ +// 1.20.1 2025-12-11T17:31:55.2360112 Block States: superleadrope +6e9e15398c0d85d14941797931eb3f7c886a800a assets/superleadrope/blockstates/doll.json diff --git a/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d b/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d new file mode 100644 index 0000000..4a3d883 --- /dev/null +++ b/src/generated/resources/.cache/59eb3dbb5f86130e09b3c62d89b9525ee01cf52d @@ -0,0 +1,2 @@ +// 1.20.1 2025-12-11T17:31:55.2360112 Loot Tables +c31110372e9281cf7264482c2c89c8927fb67fe2 data/superleadrope/loot_tables/blocks/doll.json diff --git a/src/generated/resources/.cache/82018c5420b46ddbb7071e62df09fdecd98133e6 b/src/generated/resources/.cache/82018c5420b46ddbb7071e62df09fdecd98133e6 index 047fe92..ba37fdd 100644 --- a/src/generated/resources/.cache/82018c5420b46ddbb7071e62df09fdecd98133e6 +++ b/src/generated/resources/.cache/82018c5420b46ddbb7071e62df09fdecd98133e6 @@ -1,2 +1,2 @@ -// 1.20.1 2025-12-04T18:55:51.5034621 Languages: lzh -8dde976f77c0ca836ed66627ea2af29b20e5f7c5 assets/superleadrope/lang/lzh.json +// 1.20.1 2025-12-11T17:31:55.2360112 Languages: lzh +c03cdd0fb0e9a7bcf525fc0e18fe31e2b906f8f0 assets/superleadrope/lang/lzh.json diff --git a/src/generated/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 b/src/generated/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 index 5ebb78d..fc526c6 100644 --- a/src/generated/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 +++ b/src/generated/resources/.cache/c622617f6fabf890a00b9275cd5f643584a8a2c8 @@ -1,2 +1,2 @@ -// 1.20.1 2025-12-04T18:55:51.5024633 Languages: en_us -b1f5523a28ab74acc8bd5b0ec167bf254e0b0dea assets/superleadrope/lang/en_us.json +// 1.20.1 2025-12-11T17:31:55.2360112 Languages: en_us +d1d1d2a67f7602340c0f0e0dcf1ea1b93fdc23f4 assets/superleadrope/lang/en_us.json diff --git a/src/generated/resources/assets/superleadrope/blockstates/doll.json b/src/generated/resources/assets/superleadrope/blockstates/doll.json new file mode 100644 index 0000000..542cce5 --- /dev/null +++ b/src/generated/resources/assets/superleadrope/blockstates/doll.json @@ -0,0 +1,34 @@ +{ + "variants": { + "facing=east,waterlogged=false": { + "model": "superleadrope:block/doll", + "y": 90 + }, + "facing=east,waterlogged=true": { + "model": "superleadrope:block/doll", + "y": 90 + }, + "facing=north,waterlogged=false": { + "model": "superleadrope:block/doll" + }, + "facing=north,waterlogged=true": { + "model": "superleadrope:block/doll" + }, + "facing=south,waterlogged=false": { + "model": "superleadrope:block/doll", + "y": 180 + }, + "facing=south,waterlogged=true": { + "model": "superleadrope:block/doll", + "y": 180 + }, + "facing=west,waterlogged=false": { + "model": "superleadrope:block/doll", + "y": 270 + }, + "facing=west,waterlogged=true": { + "model": "superleadrope:block/doll", + "y": 270 + } + } +} \ No newline at end of file diff --git a/src/generated/resources/assets/superleadrope/lang/en_us.json b/src/generated/resources/assets/superleadrope/lang/en_us.json index c399501..d972657 100644 --- a/src/generated/resources/assets/superleadrope/lang/en_us.json +++ b/src/generated/resources/assets/superleadrope/lang/en_us.json @@ -1,6 +1,8 @@ { + "block.superleadrope.doll": "Doll", "death.attack.eternal_potato_not_complete": "§c%1$s was not the rightful owner, struck by lightning!", "death.attack.eternal_potato_not_owner": "§c%1$s was not the rightful owner, struck by lightning!", + "effect.superleadrope.no_super_leash": "No Super Leash", "entity.superleadrope.super_lead_knot": "Super Lead Knot", "gamerule.SLP.CreateSuperLeashKnotEntityIfAbsent": "Create Leash Fence Knot Entity if absent", "gamerule.SLP.CreateSuperLeashKnotEntityIfAbsent.description": "Create LeashKnot Entity if it's absent on fence or other supported positions", @@ -22,6 +24,9 @@ "item.eternal_potato.tooltip.punish": "§cOverdue punishments: §4%d §7(will be applied), grace exceeded: §4%d", "item.eternal_potato.tooltip.title": "§6Mythical Item §7- §6Eternal Potato", "item.eternal_potato.tooltip.unbound": "§cUnbound", + "item.minecraft.lingering_potion.effect.no_super_leash": "Splash No Super Leash Potion", + "item.minecraft.potion.effect.no_super_leash": "No Super Leash Potion", + "item.minecraft.splash_potion.effect.no_super_leash": "Splash No Super Leash Potion", "item.superleadrope.eternal_potato": "Eternal Potato", "item.superleadrope.super_lead_rope": "Super Lead Rope", "sound.superleadrope.subtitle.lead_break": "Lead Break", @@ -105,5 +110,6 @@ "superleadrope.command.motion.message.multiply.successful": "§bMultiply Successfully.§a%s§7:§f[§eVec§7:§a(§f%.2f§7,§f%.2f§7,§f%.2f§7)§f]§r", "superleadrope.command.motion.message.setter.successful": "§bSet Successfully.§a%s§7:§f[§eVec§7:§a(§f%.2f§7,§f%.2f§7,§f%.2f§7)§f]§r", "superleadrope.command.none": "", - "superleadrope.command.state": "State" + "superleadrope.command.state": "State", + "tooltip.superleadrope.author": "Author : R3944Realms" } \ No newline at end of file diff --git a/src/generated/resources/assets/superleadrope/lang/lzh.json b/src/generated/resources/assets/superleadrope/lang/lzh.json index 46c5c79..18cb8ab 100644 --- a/src/generated/resources/assets/superleadrope/lang/lzh.json +++ b/src/generated/resources/assets/superleadrope/lang/lzh.json @@ -1,6 +1,8 @@ { + "block.superleadrope.doll": "戲像", "death.attack.eternal_potato_not_complete": "§c%1$s 非汝所主,雷霆降身!", "death.attack.eternal_potato_not_owner": "§c%1$s 非汝所主,雷霆降身!", + "effect.superleadrope.no_super_leash": "禁系之效", "entity.superleadrope.super_lead_knot": "神駒羈縻索結", "gamerule.SLP.CreateSuperLeashKnotEntityIfAbsent": "若阙则创超级繫绳结", "gamerule.SLP.CreateSuperLeashKnotEntityIfAbsent.description": "若栅等支处阙超级繫绳结,则创之", @@ -22,6 +24,9 @@ "item.eternal_potato.tooltip.punish": "§c逾期责务尚未完成: §4%d §7(將受懲罰),超出寬限數: §4%d", "item.eternal_potato.tooltip.title": "§6永恒土豆 §7- §6传奇之物", "item.eternal_potato.tooltip.unbound": "§c尚未绑定主人", + "item.minecraft.lingering_potion.effect.no_super_leash": "缠绵禁系汤", + "item.minecraft.potion.effect.no_super_leash": "禁系汤剂", + "item.minecraft.splash_potion.effect.no_super_leash": "飞溅禁系汤", "item.superleadrope.eternal_potato": "不滅薯", "item.superleadrope.super_lead_rope": "神駒羈縻索", "sound.superleadrope.subtitle.lead_break": "索絕", @@ -105,5 +110,6 @@ "superleadrope.command.motion.message.multiply.successful": "§b倍乘既成.§a%s§7:§f[§e速勢§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r", "superleadrope.command.motion.message.setter.successful": "§b定值既成.§a%s§7:§f[§e速勢§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r", "superleadrope.command.none": "無", - "superleadrope.command.state": "狀" + "superleadrope.command.state": "狀", + "tooltip.superleadrope.author": "作者 : R3944Realms" } \ No newline at end of file diff --git a/src/generated/resources/assets/superleadrope/lang/zh_cn.json b/src/generated/resources/assets/superleadrope/lang/zh_cn.json index 53e71a1..638fb30 100644 --- a/src/generated/resources/assets/superleadrope/lang/zh_cn.json +++ b/src/generated/resources/assets/superleadrope/lang/zh_cn.json @@ -1,6 +1,8 @@ { + "block.superleadrope.doll": "玩偶", "death.attack.eternal_potato_not_complete": "§c%1$s 因使用非自己绑定物品,受到闪电惩罚!", "death.attack.eternal_potato_not_owner": "§c%1$s 因使用非自己绑定物品,受到闪电惩罚!", + "effect.superleadrope.no_super_leash": "禁拴", "entity.superleadrope.super_lead_knot": "超级拴绳结", "gamerule.SLP.CreateSuperLeashKnotEntityIfAbsent": "如果缺失则创建超级拴绳结", "gamerule.SLP.CreateSuperLeashKnotEntityIfAbsent.description": "如果在栅栏等支持处缺失超级拴绳结,则创建它", @@ -22,6 +24,9 @@ "item.eternal_potato.tooltip.punish": "§c逾期未完成责务: §4%d §7(将会受罚),超出宽限数: §4%d", "item.eternal_potato.tooltip.title": "§6神话物品 §7- §6永恒土豆", "item.eternal_potato.tooltip.unbound": "§c未绑定主人", + "item.minecraft.lingering_potion.effect.no_super_leash": "滞留型禁拴药水", + "item.minecraft.potion.effect.no_super_leash": "禁拴药水", + "item.minecraft.splash_potion.effect.no_super_leash": "喷溅型禁拴药水", "item.superleadrope.eternal_potato": "永恒土豆", "item.superleadrope.super_lead_rope": "超级拴绳", "sound.superleadrope.subtitle.lead_break": "拴绳断裂", @@ -105,5 +110,6 @@ "superleadrope.command.motion.message.multiply.successful": "§b倍乘成功.§a%s§7:§f[§e加速§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r", "superleadrope.command.motion.message.setter.successful": "§b设置成功.§a%s§7:§f[§e加速§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r", "superleadrope.command.none": "无", - "superleadrope.command.state": "状态" + "superleadrope.command.state": "状态", + "tooltip.superleadrope.author": "作者 : R3944Realms" } \ No newline at end of file diff --git a/src/generated/resources/assets/superleadrope/lang/zh_tw.json b/src/generated/resources/assets/superleadrope/lang/zh_tw.json index 83c0a11..0531872 100644 --- a/src/generated/resources/assets/superleadrope/lang/zh_tw.json +++ b/src/generated/resources/assets/superleadrope/lang/zh_tw.json @@ -1,6 +1,8 @@ { + "block.superleadrope.doll": "玩偶", "death.attack.eternal_potato_not_complete": "§c%1$s 因使用非自己綁定物品,受到閃電懲罰!", "death.attack.eternal_potato_not_owner": "§c%1$s 因使用非自己綁定物品,受到閃電懲罰!", + "effect.superleadrope.no_super_leash": "禁拴", "entity.superleadrope.super_lead_knot": "超級拴繩結", "gamerule.SLP.CreateSuperLeashKnotEntityIfAbsent": "如果缺失則創建超級拴繩結", "gamerule.SLP.CreateSuperLeashKnotEntityIfAbsent.description": "如果在柵欄等支持處缺失超級拴繩結,則創建它", @@ -22,6 +24,9 @@ "item.eternal_potato.tooltip.punish": "§c逾期未完成责務: §4%d §7(將會受罰),超出寬限數: §4%d", "item.eternal_potato.tooltip.title": "§6神話物品 §7- §6永恒土豆", "item.eternal_potato.tooltip.unbound": "§c未綁定主人", + "item.minecraft.lingering_potion.effect.no_super_leash": "滯留型禁拴藥水", + "item.minecraft.potion.effect.no_super_leash": "禁拴藥水", + "item.minecraft.splash_potion.effect.no_super_leash": "噴濺型禁拴藥水", "item.superleadrope.eternal_potato": "永恆馬鈴薯", "item.superleadrope.super_lead_rope": "超級拴繩", "sound.superleadrope.subtitle.lead_break": "拴繩斷裂", @@ -105,5 +110,6 @@ "superleadrope.command.motion.message.multiply.successful": "§b倍乘成功.§a%s§7:§f[§e加速§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r", "superleadrope.command.motion.message.setter.successful": "§b設置成功.§a%s§7:§f[§e加速§7:(§a%.2f§7,§a%.2f§7,§a%.2f§7)§f]§r", "superleadrope.command.none": "無", - "superleadrope.command.state": "狀態" + "superleadrope.command.state": "狀態", + "tooltip.superleadrope.author": "作者 : R3944Realms" } \ No newline at end of file diff --git a/src/generated/resources/assets/superleadrope/models/item/doll.json b/src/generated/resources/assets/superleadrope/models/item/doll.json new file mode 100644 index 0000000..0f0de50 --- /dev/null +++ b/src/generated/resources/assets/superleadrope/models/item/doll.json @@ -0,0 +1,3 @@ +{ + "parent": "superleadrope:block/doll" +} \ No newline at end of file diff --git a/src/generated/resources/data/superleadrope/loot_tables/blocks/doll.json b/src/generated/resources/data/superleadrope/loot_tables/blocks/doll.json new file mode 100644 index 0000000..f596819 --- /dev/null +++ b/src/generated/resources/data/superleadrope/loot_tables/blocks/doll.json @@ -0,0 +1,21 @@ +{ + "type": "minecraft:block", + "pools": [ + { + "bonus_rolls": 0.0, + "conditions": [ + { + "condition": "minecraft:survives_explosion" + } + ], + "entries": [ + { + "type": "minecraft:item", + "name": "superleadrope:doll" + } + ], + "rolls": 1.0 + } + ], + "random_sequence": "superleadrope:blocks/doll" +} \ No newline at end of file diff --git a/src/main/java/top/r3944realms/superleadrope/CommonEventHandler.java b/src/main/java/top/r3944realms/superleadrope/CommonEventHandler.java index e00c937..470b08e 100644 --- a/src/main/java/top/r3944realms/superleadrope/CommonEventHandler.java +++ b/src/main/java/top/r3944realms/superleadrope/CommonEventHandler.java @@ -74,6 +74,7 @@ import top.r3944realms.superleadrope.core.leash.LeashSyncManager; import top.r3944realms.superleadrope.core.potato.EternalPotatoFacade; import top.r3944realms.superleadrope.core.register.SLPGameruleRegistry; import top.r3944realms.superleadrope.core.register.SLPItems; +import top.r3944realms.superleadrope.core.register.SLPPotionRecipeRegistry; import top.r3944realms.superleadrope.core.util.PotatoMode; import top.r3944realms.superleadrope.core.util.PotatoModeHelper; import top.r3944realms.superleadrope.datagen.data.SLPLangKeyValue; @@ -499,6 +500,7 @@ public class CommonEventHandler { public static void onFMLCommonInit(FMLCommonSetupEvent event) { event.enqueueWork(Mod::checkAndSet); event.enqueueWork(SLPGameruleRegistry::register); + event.enqueueWork(SLPPotionRecipeRegistry::init); } /** diff --git a/src/main/java/top/r3944realms/superleadrope/SuperLeadRope.java b/src/main/java/top/r3944realms/superleadrope/SuperLeadRope.java index 9a46cc5..2eb7aa1 100644 --- a/src/main/java/top/r3944realms/superleadrope/SuperLeadRope.java +++ b/src/main/java/top/r3944realms/superleadrope/SuperLeadRope.java @@ -25,9 +25,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import top.r3944realms.superleadrope.compat.WayStoneCompat; import top.r3944realms.superleadrope.config.LeashCommonConfig; -import top.r3944realms.superleadrope.core.register.SLPEntityTypes; -import top.r3944realms.superleadrope.core.register.SLPItems; -import top.r3944realms.superleadrope.core.register.SLPSoundEvents; +import top.r3944realms.superleadrope.core.register.*; import top.r3944realms.superleadrope.network.NetworkHandler; import top.r3944realms.superleadrope.util.file.ConfigUtil; @@ -53,8 +51,11 @@ public class SuperLeadRope { public SuperLeadRope() { IEventBus eventBus = FMLJavaModLoadingContext.get().getModEventBus(); SLPItems.register(eventBus); + SLPBlocks.register(eventBus); SLPEntityTypes.register(eventBus); SLPSoundEvents.register(eventBus); + SLPEffects.register(eventBus); + SLPPotions.register(eventBus); NetworkHandler.register(); initialize(); diff --git a/src/main/java/top/r3944realms/superleadrope/compat/WayStoneCompat.java b/src/main/java/top/r3944realms/superleadrope/compat/WayStoneCompat.java index 44b37ba..60e97ce 100644 --- a/src/main/java/top/r3944realms/superleadrope/compat/WayStoneCompat.java +++ b/src/main/java/top/r3944realms/superleadrope/compat/WayStoneCompat.java @@ -1,26 +1,137 @@ package top.r3944realms.superleadrope.compat; +import com.ibm.icu.impl.Pair; import net.blay09.mods.waystones.api.WaystoneTeleportEvent; +import net.minecraft.server.level.ServerLevel; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.Pose; +import net.minecraft.world.phys.Vec3; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.fml.ModList; import org.jetbrains.annotations.NotNull; +import top.r3944realms.superleadrope.api.event.SuperLeadRopeEvent; +import top.r3944realms.superleadrope.api.type.capabilty.LeashInfo; import top.r3944realms.superleadrope.api.type.util.ILeashHelper; import top.r3944realms.superleadrope.api.workspace.Services; +import top.r3944realms.superleadrope.content.gamerule.server.TeleportWithLeashedEntities; +import top.r3944realms.superleadrope.core.leash.LeashSyncManager; +import top.r3944realms.superleadrope.core.register.SLPGameruleRegistry; +import top.r3944realms.superleadrope.util.capability.LeashDataInnerAPI; +import top.r3944realms.superleadrope.util.capability.LeashStateInnerAPI; +import top.r3944realms.superleadrope.util.entity.TeleportUtil; +import top.r3944realms.superleadrope.util.model.RidingRelationship; +import top.r3944realms.superleadrope.util.riding.RidingApplier; +import top.r3944realms.superleadrope.util.riding.RidingDismounts; +import top.r3944realms.superleadrope.util.riding.RidingFinder; +import top.r3944realms.superleadrope.util.riding.RidingSaver; -import java.util.Set; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicReference; public class WayStoneCompat { public final static boolean isModLoaded = ModList.get().isLoaded("waystones"); + public final static Map>> tempLeashMap = new ConcurrentHashMap<>(); + public final static Map uuidMap = new ConcurrentHashMap<>(); + public record OriginalState(Pose pose, boolean isSprinting, float yaw, float pitch, Vec3 deltaMovement, LeashInfo leashInfo, RidingRelationship ridingRelationship) {} public static void init() { if (isModLoaded) { - MinecraftForge.EVENT_BUS.addListener(WayStoneCompat::onWayStoneTeleport); + MinecraftForge.EVENT_BUS.addListener(WayStoneCompat::onWayStoneTeleport$Pre); + MinecraftForge.EVENT_BUS.addListener(WayStoneCompat::onWayStoneTeleport$Post); } } - public static void onWayStoneTeleport(WaystoneTeleportEvent.@NotNull Pre event) { - Entity entity = event.getContext().getEntity(); - ILeashHelper.IHolder holderHelper = Services.WORK_SPACE.getLeashHelper().getHolderHelper(entity); + public static void onWayStoneTeleport$Pre(WaystoneTeleportEvent.@NotNull Pre event) { + Entity telEntity = event.getContext().getEntity(); + ILeashHelper.IHolder holderHelper = Services.WORK_SPACE.getLeashHelper().getHolderHelper(telEntity); Set allLeashedEntities = holderHelper.getAllLeashedEntities(); - allLeashedEntities.forEach(event::addAdditionalEntity); + if(!SLPGameruleRegistry.getGameruleBoolValue(telEntity.level(), TeleportWithLeashedEntities.ID)) { + holderHelper.getAllLeashedEntities(); + return; + } + ServerLevel level = event.getContext().getDestination().getLevel(); + Vec3 destination = event.getContext().getDestination().getLocation(); + Set> set = new HashSet<>(); + for (Entity beLeashedEntity : allLeashedEntities) { + // --- 保存状态快照 --- + if (MinecraftForge.EVENT_BUS.post(new SuperLeadRopeEvent.teleportWithHolder(beLeashedEntity, telEntity, beLeashedEntity.level(), level, beLeashedEntity.position(), destination))) + continue; + Pose originalPose = beLeashedEntity.getPose(); + boolean originalIsSprinting = beLeashedEntity.isSprinting(); + float originalYaw = beLeashedEntity.getYRot(); + float originalPitch = beLeashedEntity.getXRot(); + Vec3 originalDeltaMovement = beLeashedEntity.getDeltaMovement(); + + AtomicReference originalLeashInfo = new AtomicReference<>(); + LeashDataInnerAPI.getLeashData(beLeashedEntity).ifPresent(data -> { + originalLeashInfo.set(data.getLeashInfo(telEntity).orElse(null)); + data.removeLeash(telEntity); + }); + + + // --- 保存骑乘关系(可修改列表) --- + RidingRelationship originalRidingRelationship = RidingSaver.save(beLeashedEntity, true); + + // --- 解除骑乘 --- + List allPassengers = RidingFinder.getEntityFromRidingShip(originalRidingRelationship, level::getEntity); + RidingDismounts.dismountEntities(allPassengers); + set.add(Pair.of(beLeashedEntity, new OriginalState( + originalPose, + originalIsSprinting, + originalYaw, + originalPitch, + originalDeltaMovement, + originalLeashInfo.get(), + originalRidingRelationship + ) + ) + ); + } + tempLeashMap.put(telEntity.getUUID(), set); + } + public static void onWayStoneTeleport$Post(WaystoneTeleportEvent.@NotNull Post event) { + Entity telEntity = event.getContext().getEntity(); + ServerLevel serverLevel = event.getContext().getDestination().getLevel(); + Vec3 destination = event.getContext().getDestination().getLocation(); + Set> set = tempLeashMap.get(telEntity.getUUID()); + Set shouldBeRemoved = new HashSet<>(); + if (set != null) { + HashSet> newSet = new HashSet<>(); + // --- 传送实体及乘客 --- + for (Pair entityPair : set) { + Entity beLeashedEntity = entityPair.first; + Entity newEntity = TeleportUtil.teleportEntity(beLeashedEntity, serverLevel, destination, beLeashedEntity.getDirection()); + if (!beLeashedEntity.getUUID().equals(newEntity.getUUID())){ + uuidMap.put(beLeashedEntity.getUUID(), newEntity.getUUID()); + } + newSet.add(Pair.of(newEntity, entityPair.second)); + } + for (Pair entityPair : newSet) { + // --- 恢复状态 --- + Entity beLeashedEntity = entityPair.first; + OriginalState originalState = entityPair.second; + LeashStateInnerAPI.getLeashState(beLeashedEntity).ifPresent(LeashSyncManager.State::track); + LeashDataInnerAPI.getLeashData(beLeashedEntity).ifPresent(LeashSyncManager.Data::track); + beLeashedEntity.setDeltaMovement(originalState.deltaMovement); + beLeashedEntity.setPose(originalState.pose); + beLeashedEntity.setSprinting(originalState.isSprinting); + // --- 将holder替换 --- + LeashInfo leashInfo = Optional.ofNullable(originalState.leashInfo) + .orElse(LeashInfo.EMPTY); + if (leashInfo.holderUUIDOpt().isPresent() && uuidMap.containsKey(leashInfo.holderUUIDOpt().get())) { + leashInfo.transferHolder(beLeashedEntity); + shouldBeRemoved.add(leashInfo.holderUUIDOpt().get()); + } + LeashDataInnerAPI.LeashOperations.attachWithInfo(beLeashedEntity, telEntity, leashInfo); + // --- 重新应用骑乘关系,仅保留白名单根载具 --- + uuidMap.forEach((oldUUID, newUUID) -> { + int andReplaceAll = originalState.ridingRelationship.findAndReplaceAll(oldUUID, newUUID); + if (andReplaceAll != 0) shouldBeRemoved.add(oldUUID); + }); + RidingRelationship filteredRelationship = RidingSaver.filterByWhitelistRoot(originalState.ridingRelationship); + RidingApplier.applyRidingRelationship(filteredRelationship, serverLevel::getEntity); + } + shouldBeRemoved.forEach(uuidMap::remove); + tempLeashMap.remove(telEntity.getUUID()); + } } } diff --git a/src/main/java/top/r3944realms/superleadrope/config/LeashCommonConfig.java b/src/main/java/top/r3944realms/superleadrope/config/LeashCommonConfig.java index bd50543..73006d0 100644 --- a/src/main/java/top/r3944realms/superleadrope/config/LeashCommonConfig.java +++ b/src/main/java/top/r3944realms/superleadrope/config/LeashCommonConfig.java @@ -55,6 +55,7 @@ public class LeashCommonConfig { */ // Leash settings public final ForgeConfigSpec.DoubleValue maxLeashLength; + public final ForgeConfigSpec.DoubleValue maxMovement; /** * The Elastic distance scale. */ @@ -155,7 +156,9 @@ public class LeashCommonConfig { maxLeashLength = builder .comment("Maximum leash distance (in blocks) for any entity") .defineInRange("maxLeashLength", 6.0, LeashConfigManager.MAX_DISTANCE_MIN_VALUE, LeashConfigManager.MAX_DISTANCE_MAX_VALUE); - + maxMovement = builder + .comment("Defines the maximum acceleration in standard coordinate directions (X/Y/Z axes)") + .defineInRange("maxMovement", 100.0, 10.0, Double.MAX_VALUE); elasticDistanceScale = builder .comment("Default elastic distance for the Super Lead rope") .defineInRange("elasticDistanceScale", 1.0, LeashConfigManager.ELASTIC_DISTANCE_MIN_VALUE, LeashConfigManager.ELASTIC_DISTANCE_MAX_VALUE); @@ -200,6 +203,8 @@ public class LeashCommonConfig { .defineInRange("mobSpringFactor", 0.5, 0.05, 2.0); builder.pop(); + + // ===== Leash State Offsets ===== builder.push("LeashStateSettings"); defaultApplyEntityLocationOffset = builder diff --git a/src/main/java/top/r3944realms/superleadrope/config/LeashConfigManager.java b/src/main/java/top/r3944realms/superleadrope/config/LeashConfigManager.java index b4e5c1d..8dd3cd6 100644 --- a/src/main/java/top/r3944realms/superleadrope/config/LeashConfigManager.java +++ b/src/main/java/top/r3944realms/superleadrope/config/LeashConfigManager.java @@ -88,6 +88,7 @@ public class LeashConfigManager { private volatile double mobSpringFactor = 0.5; private volatile double maxLeashLength = 12.0; + private volatile double maxMovement = 100.0; private volatile double elasticDistanceScale = 1.0; private volatile double extremeSnapFactor = 2.0; private volatile double springDampening = 0.7; @@ -318,6 +319,7 @@ public class LeashConfigManager { * @return the max leash length */ public double getMaxLeashLength() { return maxLeashLength; } + public double getMaxMovement() { return maxMovement; } /** * Gets elastic distance scale. @@ -399,6 +401,7 @@ public class LeashConfigManager { commandPrefixEnabledCache = LeashCommonConfig.COMMON.enableSLPModCommandPrefix.get(); maxLeashLength = LeashCommonConfig.COMMON.maxLeashLength.get(); + maxMovement = LeashCommonConfig.COMMON.maxMovement.get(); elasticDistanceScale = LeashCommonConfig.COMMON.elasticDistanceScale.get(); extremeSnapFactor = LeashCommonConfig.COMMON.extremeSnapFactor.get(); springDampening = LeashCommonConfig.COMMON.springDampening.get(); @@ -489,6 +492,7 @@ public class LeashConfigManager { tag.putDouble("mob_spring_factor", mobSpringFactor); tag.putDouble("max_leash_length", maxLeashLength); + tag.putDouble("max_movement", maxMovement); tag.putDouble("elastic_distance_scale", elasticDistanceScale); tag.putDouble("extreme_snap_factor", extremeSnapFactor); tag.putDouble("spring_dampening", springDampening); @@ -524,6 +528,7 @@ public class LeashConfigManager { // ========== 更新物理参数 ========== LeashCommonConfig.COMMON.maxLeashLength.set(maxLeashLength); + LeashCommonConfig.COMMON.maxMovement.set(maxMovement); LeashCommonConfig.COMMON.elasticDistanceScale.set(elasticDistanceScale); LeashCommonConfig.COMMON.extremeSnapFactor.set(extremeSnapFactor); LeashCommonConfig.COMMON.springDampening.set(springDampening); @@ -641,6 +646,9 @@ public class LeashConfigManager { if (tag.contains("max_leash_length", Tag.TAG_DOUBLE)) { maxLeashLength = tag.getDouble("max_leash_length"); } + if (tag.contains("max_movement", Tag.TAG_DOUBLE)) { + maxLeashLength = tag.getDouble("max_movement"); + } if (tag.contains("elastic_distance_scale", Tag.TAG_DOUBLE)) { elasticDistanceScale = tag.getDouble("elastic_distance_scale"); } @@ -696,6 +704,7 @@ public class LeashConfigManager { hash = fnv1aHashLong(hash, Double.doubleToLongBits(playerSpringFactor)); hash = fnv1aHashLong(hash, Double.doubleToLongBits(mobSpringFactor)); hash = fnv1aHashLong(hash, Double.doubleToLongBits(maxLeashLength)); + hash = fnv1aHashLong(hash, Double.doubleToLongBits(maxMovement)); hash = fnv1aHashLong(hash, Double.doubleToLongBits(elasticDistanceScale)); hash = fnv1aHashLong(hash, Double.doubleToLongBits(extremeSnapFactor)); hash = fnv1aHashLong(hash, Double.doubleToLongBits(springDampening)); diff --git a/src/main/java/top/r3944realms/superleadrope/content/block/DollBlock.java b/src/main/java/top/r3944realms/superleadrope/content/block/DollBlock.java new file mode 100644 index 0000000..38d6e66 --- /dev/null +++ b/src/main/java/top/r3944realms/superleadrope/content/block/DollBlock.java @@ -0,0 +1,144 @@ +package top.r3944realms.superleadrope.content.block; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.InteractionHand; +import net.minecraft.world.InteractionResult; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.item.context.BlockPlaceContext; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.LevelAccessor; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.HorizontalDirectionalBlock; +import net.minecraft.world.level.block.SimpleWaterloggedBlock; +import net.minecraft.world.level.block.SoundType; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.StateDefinition; +import net.minecraft.world.level.block.state.properties.BlockStateProperties; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.NoteBlockInstrument; +import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.material.Fluids; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.Vec3; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@SuppressWarnings("deprecation") +public class DollBlock extends HorizontalDirectionalBlock implements SimpleWaterloggedBlock { + private static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; + private static final VoxelShape DOLL_SHAPE = Block.box(2.0d, 0.0d, 2.0d, 14.0d, 12.0d, 14.0d); + + private static final double PARTICLE_OFFSET_RANGE = 0.25; + private static final double PARTICLE_HEIGHT_OFFSET = 1.0; + private static final double PARTICLE_HEIGHT_VARIANCE = 0.2; + private static final float NOTE_COLOR_DIVISOR = 24.0F; + private static final int MAX_NOTE_COLORS = 4; + + private static final float BASE_VOLUME = 1.0f; + private static final float PITCH_VARIANCE = 0.5f; + private static final float BASE_PITCH = 0.75f; + + public DollBlock() { + super(BlockBehaviour.Properties.of() + .instrument(NoteBlockInstrument.BASEDRUM) + .sound(SoundType.WOOL) + .strength(0f, 10f) + .noOcclusion()); + this.registerDefaultState(this.stateDefinition.any().setValue(FACING, Direction.SOUTH) + .setValue(WATERLOGGED, false)); + } + + @Override + public @NotNull BlockState updateShape(@NotNull BlockState currentState, @NotNull Direction direction, @NotNull BlockState neighborState, + @NotNull LevelAccessor level, @NotNull BlockPos currentPos, @NotNull BlockPos neighborPos) { + if (currentState.getValue(WATERLOGGED)) { + level.scheduleTick(currentPos, Fluids.WATER, Fluids.WATER.getTickDelay(level)); + } + return super.updateShape(currentState, direction, neighborState, level, currentPos, neighborPos); + } + + @Override + public @NotNull FluidState getFluidState(@NotNull BlockState blockState) { + return blockState.getValue(WATERLOGGED) ? Fluids.WATER.getSource(false) : super.getFluidState(blockState); + } + + @Override + public @NotNull InteractionResult use(@NotNull BlockState blockState, @NotNull Level level, @NotNull BlockPos blockPos, @NotNull Player player, + @NotNull InteractionHand hand, @NotNull BlockHitResult hitResult) { + if (level instanceof ServerLevel serverLevel) { + // 播放粒子效果 + spawnNoteParticles(serverLevel, blockPos); + // 播放音效 + playDollSound(serverLevel, blockPos); + } + return InteractionResult.SUCCESS; + } + + /** + * 在玩偶位置生成音符粒子效果 + */ + private void spawnNoteParticles(ServerLevel serverLevel, BlockPos blockPos) { + Vec3 particlePosition = calculateParticlePosition(serverLevel, blockPos); + float noteColor = calculateNoteColor(serverLevel); + + serverLevel.sendParticles(ParticleTypes.NOTE, + particlePosition.x(), particlePosition.y(), particlePosition.z(), + 0, noteColor, 0, 0, 1); + } + + /** + * 计算粒子生成位置,添加随机偏移 + */ + private @NotNull Vec3 calculateParticlePosition(@NotNull ServerLevel serverLevel, BlockPos blockPos) { + return Vec3.atBottomCenterOf(blockPos).add( + (serverLevel.getRandom().nextFloat() - 0.5) * PARTICLE_OFFSET_RANGE * 2, + PARTICLE_HEIGHT_OFFSET + serverLevel.getRandom().nextFloat() * PARTICLE_HEIGHT_VARIANCE, + (serverLevel.getRandom().nextFloat() - 0.5) * PARTICLE_OFFSET_RANGE * 2 + ); + } + + /** + * 计算音符粒子的颜色 + */ + private float calculateNoteColor(@NotNull ServerLevel serverLevel) { + return serverLevel.getRandom().nextInt(MAX_NOTE_COLORS) / NOTE_COLOR_DIVISOR; + } + + /** + * 播放玩偶音效 + */ + private void playDollSound(@NotNull ServerLevel serverLevel, BlockPos blockPos) { + float pitch = BASE_PITCH + serverLevel.random.nextFloat() * PITCH_VARIANCE; + serverLevel.playSound(null, blockPos, SoundEvents.NOTE_BLOCK_BASEDRUM.get(), + SoundSource.BLOCKS, BASE_VOLUME, pitch); + } + + @Override + public @Nullable BlockState getStateForPlacement(@NotNull BlockPlaceContext context) { + FluidState fluidState = context.getLevel().getFluidState(context.getClickedPos()); + boolean isWaterlogged = fluidState.getType() == Fluids.WATER; + + return this.defaultBlockState() + .setValue(FACING, context.getHorizontalDirection().getOpposite()) + .setValue(WATERLOGGED, isWaterlogged); + } + + @Override + public @NotNull VoxelShape getShape(@NotNull BlockState blockState, @NotNull BlockGetter level, @NotNull BlockPos blockPos, @NotNull CollisionContext context) { + return DOLL_SHAPE; + } + + @Override + protected void createBlockStateDefinition(StateDefinition.@NotNull Builder builder) { + builder.add(FACING, WATERLOGGED); + } +} diff --git a/src/main/java/top/r3944realms/superleadrope/content/capability/impi/LeashDataImpl.java b/src/main/java/top/r3944realms/superleadrope/content/capability/impi/LeashDataImpl.java index 9ac27cd..a3c8ff1 100644 --- a/src/main/java/top/r3944realms/superleadrope/content/capability/impi/LeashDataImpl.java +++ b/src/main/java/top/r3944realms/superleadrope/content/capability/impi/LeashDataImpl.java @@ -64,6 +64,7 @@ import java.util.stream.Stream; /** * 预期行为 + *
  * 
  *     
  *      
@@ -90,6 +91,7 @@ import java.util.stream.Stream;
  *         
  *     
  * 
+ *
*/ @SuppressWarnings("DuplicatedCode") public class LeashDataImpl implements ILeashData { @@ -804,7 +806,24 @@ public class LeashDataImpl implements ILeashData { boolean hasForce = !combinedForce.equals(Vec3.ZERO); Entity targetEntity = RindingLeash.getFinalEntityForLeashIfForce(entity, hasForce); if(targetEntity instanceof LocalPlayer && hasForce){ - entity.addDeltaMovement(combinedForce); + entity.addDeltaMovement(limitMovement(combinedForce)); + } + } + + public Vec3 limitMovement(@NotNull Vec3 movement) { + double maxMovement = CommonEventHandler.leashConfigManager.getMaxMovement(); + return new Vec3( + clamp(movement.x, maxMovement), + clamp(movement.y, maxMovement), + clamp(movement.z, maxMovement) + ); + } + + private double clamp(double value, double max) { + if (value > 0) { + return Math.min(value, max); + } else { + return Math.max(value, -max); } } @@ -842,6 +861,7 @@ public class LeashDataImpl implements ILeashData { boolean hasForce = !combinedForce.equals(Vec3.ZERO); Entity targetEntity = RindingLeash.getFinalEntityForLeashIfForce(entity, hasForce); if (targetEntity != null && hasForce) { + combinedForce = limitMovement(combinedForce); SuperLeadRopeEvent.hasFocus hasFocus = new SuperLeadRopeEvent.hasFocus(this.entity, targetEntity, combinedForce, vaildLeashHolders, vaildLeashKnots); if (MinecraftForge.EVENT_BUS.post(hasFocus)) return; combinedForce = hasFocus.getCombinedForce(); @@ -850,11 +870,11 @@ public class LeashDataImpl implements ILeashData { // 是真实玩家则交给客户端自行处理拴绳逻辑 // DO NOTHING if(targetEntity != entity){ - NetworkHandler.sendToPlayer(new UpdatePlayerMovementPacket(UpdatePlayerMovementPacket.Operation.ADD, combinedForce), player); + NetworkHandler.sendToPlayer(new UpdatePlayerMovementPacket(UpdatePlayerMovementPacket.Operation.ADD, limitMovement(combinedForce)), player); } return; } else { - applyForceToNonPlayerEntity(targetEntity, combinedForce, validLeashes, combinedDirection); + applyForceToNonPlayerEntity(targetEntity, limitMovement(combinedForce), validLeashes, combinedDirection); } } diff --git a/src/main/java/top/r3944realms/superleadrope/content/effect/NoSuperLeashEffect.java b/src/main/java/top/r3944realms/superleadrope/content/effect/NoSuperLeashEffect.java new file mode 100644 index 0000000..f58f15d --- /dev/null +++ b/src/main/java/top/r3944realms/superleadrope/content/effect/NoSuperLeashEffect.java @@ -0,0 +1,40 @@ +package top.r3944realms.superleadrope.content.effect; + +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectCategory; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.entity.LivingEntity; +import org.jetbrains.annotations.NotNull; +import top.r3944realms.superleadrope.api.type.capabilty.ILeashData; +import top.r3944realms.superleadrope.core.register.SLPEffects; +import top.r3944realms.superleadrope.core.register.SLPSoundEvents; +import top.r3944realms.superleadrope.util.capability.LeashDataInnerAPI; + +import java.util.Optional; + +public class NoSuperLeashEffect extends MobEffect { + public NoSuperLeashEffect(MobEffectCategory category, int color) { + super(category, color); + } + @Override + public void applyEffectTick(@NotNull LivingEntity pLivingEntity, int pAmplifier) { + MobEffectInstance effect = pLivingEntity.getEffect(SLPEffects.NO_SUPER_LEASH_EFFECT.get()); + if(effect != null && effect.getDuration() != 0) { + Optional leashData = LeashDataInnerAPI.getLeashData(pLivingEntity); + if (leashData.isPresent() && leashData.get().hasLeash()) { + LeashDataInnerAPI.LeashOperations.detachAll(pLivingEntity); + pLivingEntity.level().playSound(null, + pLivingEntity.getOnPos(), + SLPSoundEvents.LEAD_UNTIED.get(), + SoundSource.AMBIENT + ); + } + } + } + + @Override + public boolean isDurationEffectTick(int duration, int amplifier) { + return duration >= 1; + } +} diff --git a/src/main/java/top/r3944realms/superleadrope/content/item/DollItem.java b/src/main/java/top/r3944realms/superleadrope/content/item/DollItem.java new file mode 100644 index 0000000..8f123f1 --- /dev/null +++ b/src/main/java/top/r3944realms/superleadrope/content/item/DollItem.java @@ -0,0 +1,23 @@ +package top.r3944realms.superleadrope.content.item; + +import net.minecraft.network.chat.Component; +import net.minecraft.world.item.BlockItem; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.TooltipFlag; +import net.minecraft.world.level.Level; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import top.r3944realms.superleadrope.core.register.SLPBlocks; + +import java.util.List; + +public class DollItem extends BlockItem { + public DollItem(Properties properties) { + super(SLPBlocks.DOLL.get(), properties); + } + + @Override + public void appendHoverText(@NotNull ItemStack stack, @Nullable Level level, List tooltip, @NotNull TooltipFlag flag) { + tooltip.add(Component.translatable("tooltip.superleadrope.author")); + } +} diff --git a/src/main/java/top/r3944realms/superleadrope/content/item/SuperLeadRopeItem.java b/src/main/java/top/r3944realms/superleadrope/content/item/SuperLeadRopeItem.java index d282fca..0700000 100644 --- a/src/main/java/top/r3944realms/superleadrope/content/item/SuperLeadRopeItem.java +++ b/src/main/java/top/r3944realms/superleadrope/content/item/SuperLeadRopeItem.java @@ -20,6 +20,7 @@ import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; import net.minecraft.world.InteractionResultHolder; +import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; @@ -34,6 +35,7 @@ import top.r3944realms.superleadrope.api.SuperLeadRopeApi; import top.r3944realms.superleadrope.api.type.capabilty.ILeashData; import top.r3944realms.superleadrope.content.SLPToolTier; import top.r3944realms.superleadrope.content.entity.SuperLeashKnotEntity; +import top.r3944realms.superleadrope.core.register.SLPEffects; import top.r3944realms.superleadrope.core.register.SLPSoundEvents; import top.r3944realms.superleadrope.util.capability.LeashDataInnerAPI; @@ -195,6 +197,10 @@ public class SuperLeadRopeItem extends TieredItem implements IForgeItem { // 情况一:拴自己到新 knot if (shouldBindSelf && list.isEmpty()) { + MobEffectInstance effect = player.getEffect(SLPEffects.NO_SUPER_LEASH_EFFECT.get()); + if (effect != null && effect.getDuration() >= 1) { + return false; + } if (leashStack.isEmpty() || !canUse(leashStack)) { return false; } diff --git a/src/main/java/top/r3944realms/superleadrope/core/leash/LeashInteractHandler.java b/src/main/java/top/r3944realms/superleadrope/core/leash/LeashInteractHandler.java index a1ad3c4..9df491c 100644 --- a/src/main/java/top/r3944realms/superleadrope/core/leash/LeashInteractHandler.java +++ b/src/main/java/top/r3944realms/superleadrope/core/leash/LeashInteractHandler.java @@ -20,7 +20,9 @@ import net.minecraft.sounds.SoundEvents; import net.minecraft.sounds.SoundSource; import net.minecraft.world.InteractionHand; import net.minecraft.world.InteractionResult; +import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.item.ItemStack; import net.minecraft.world.level.Level; @@ -31,6 +33,7 @@ import top.r3944realms.superleadrope.api.SuperLeadRopeApi; import top.r3944realms.superleadrope.api.type.capabilty.ILeashData; import top.r3944realms.superleadrope.content.capability.impi.LeashDataImpl; import top.r3944realms.superleadrope.content.item.SuperLeadRopeItem; +import top.r3944realms.superleadrope.core.register.SLPEffects; import top.r3944realms.superleadrope.core.register.SLPItems; import top.r3944realms.superleadrope.core.register.SLPSoundEvents; import top.r3944realms.superleadrope.util.capability.LeashDataInnerAPI; @@ -53,7 +56,6 @@ public class LeashInteractHandler { //只有玩家可以互动触发(其它的暂不支持(考虑到0 Mixin) public static void onEntityRightInteract(Level level, InteractionHand hand, Entity target , Player player, PlayerInteractEvent.EntityInteract event) { //WARNING: 主手和副手都会触发一次该事件 - // ===== 卫语句 ===== if (level.isClientSide) { if (hand == InteractionHand.MAIN_HAND && @@ -63,6 +65,12 @@ public class LeashInteractHandler { event.setCanceled(true); event.setCancellationResult(InteractionResult.SUCCESS); } + if (target instanceof LivingEntity livingEntity) { //禁止拴绳效果存在则取消下面的逻辑 + MobEffectInstance effect = livingEntity.getEffect(SLPEffects.NO_SUPER_LEASH_EFFECT.get()); + if (effect != null && effect.getDuration() >= 1) { + return; + } + } if (SuperLeadRopeApi.isLeashHolder(target, player)) { event.setCanceled(true); event.setCancellationResult(InteractionResult.SUCCESS); @@ -97,6 +105,12 @@ public class LeashInteractHandler { event.setCancellationResult(InteractionResult.SUCCESS); } } else { + if (target instanceof LivingEntity livingEntity) { //禁止拴绳效果存在则取消下面的逻辑 + MobEffectInstance effect = livingEntity.getEffect(SLPEffects.NO_SUPER_LEASH_EFFECT.get()); + if (effect != null && effect.getDuration() >= 1) { + return; + } + } if (SuperLeadRopeApi.isLeashHolder(target, player)) { LeashCap.ifPresent( iLeashDataCapability -> iLeashDataCapability.removeLeash(player.getUUID()) diff --git a/src/main/java/top/r3944realms/superleadrope/core/register/SLPBlocks.java b/src/main/java/top/r3944realms/superleadrope/core/register/SLPBlocks.java new file mode 100644 index 0000000..5eb4134 --- /dev/null +++ b/src/main/java/top/r3944realms/superleadrope/core/register/SLPBlocks.java @@ -0,0 +1,22 @@ +package top.r3944realms.superleadrope.core.register; + +import net.minecraft.world.level.block.Block; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; +import top.r3944realms.superleadrope.SuperLeadRope; +import top.r3944realms.superleadrope.content.block.DollBlock; + +import java.util.Collection; + +public class SLPBlocks { + public static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, SuperLeadRope.MOD_ID); + public static final RegistryObject DOLL = BLOCKS.register("doll", DollBlock::new); + public static Collection> getEntries() { + return BLOCKS.getEntries(); + } + public static void register(IEventBus eventBus) { + BLOCKS.register(eventBus); + } +} diff --git a/src/main/java/top/r3944realms/superleadrope/core/register/SLPEffects.java b/src/main/java/top/r3944realms/superleadrope/core/register/SLPEffects.java new file mode 100644 index 0000000..9c0ecee --- /dev/null +++ b/src/main/java/top/r3944realms/superleadrope/core/register/SLPEffects.java @@ -0,0 +1,33 @@ +package top.r3944realms.superleadrope.core.register; + +import net.minecraft.core.registries.Registries; +import net.minecraft.world.effect.MobEffect; +import net.minecraft.world.effect.MobEffectCategory; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.RegistryObject; +import top.r3944realms.superleadrope.SuperLeadRope; +import top.r3944realms.superleadrope.content.effect.NoSuperLeashEffect; + +import java.util.function.Supplier; + +public class SLPEffects { + public static DeferredRegister MOB_EFFECT = DeferredRegister.create(Registries.MOB_EFFECT, SuperLeadRope.MOD_ID); + public static RegistryObject NO_SUPER_LEASH_EFFECT = register( + "no_super_leash", + () -> new NoSuperLeashEffect(MobEffectCategory.NEUTRAL, 12063764) + ); + public static RegistryObject register(String name, Supplier effect) { + return MOB_EFFECT.register(name, effect); + } + + public static String getEffectKey(MobEffect effect) { + return effect.getDescriptionId(); + } + public static String getModEffectKey(RegistryObject effect) { + return getEffectKey(effect.get()); + } + public static void register(IEventBus eventBus) { + MOB_EFFECT.register(eventBus); + } +} diff --git a/src/main/java/top/r3944realms/superleadrope/core/register/SLPItems.java b/src/main/java/top/r3944realms/superleadrope/core/register/SLPItems.java index 07ac61b..b9a8c90 100644 --- a/src/main/java/top/r3944realms/superleadrope/core/register/SLPItems.java +++ b/src/main/java/top/r3944realms/superleadrope/core/register/SLPItems.java @@ -16,11 +16,13 @@ package top.r3944realms.superleadrope.core.register; import net.minecraft.world.item.Item; +import net.minecraft.world.item.Rarity; import net.minecraftforge.eventbus.api.IEventBus; import net.minecraftforge.registries.DeferredRegister; import net.minecraftforge.registries.ForgeRegistries; import net.minecraftforge.registries.RegistryObject; import top.r3944realms.superleadrope.SuperLeadRope; +import top.r3944realms.superleadrope.content.item.DollItem; import top.r3944realms.superleadrope.content.item.EternalPotatoItem; import top.r3944realms.superleadrope.content.item.SuperLeadRopeItem; @@ -49,6 +51,15 @@ public class SLPItems { .stacksTo(1) // 只能有一颗 .fireResistant() // 防火 )); + public static final RegistryObject DOLL = + ITEMS.register("doll", + () -> new DollItem( + new Item.Properties() + .stacksTo(1) + .fireResistant() + .rarity(Rarity.EPIC) + ) + ); /** * Register. diff --git a/src/main/java/top/r3944realms/superleadrope/core/register/SLPPotionRecipeRegistry.java b/src/main/java/top/r3944realms/superleadrope/core/register/SLPPotionRecipeRegistry.java new file mode 100644 index 0000000..2d29c38 --- /dev/null +++ b/src/main/java/top/r3944realms/superleadrope/core/register/SLPPotionRecipeRegistry.java @@ -0,0 +1,59 @@ +package top.r3944realms.superleadrope.core.register; + +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.Items; +import net.minecraft.world.item.alchemy.Potion; +import net.minecraft.world.item.alchemy.PotionUtils; +import net.minecraft.world.item.alchemy.Potions; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraftforge.common.brewing.BrewingRecipe; +import net.minecraftforge.common.brewing.BrewingRecipeRegistry; +import net.minecraftforge.registries.RegistryObject; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; + + +public class SLPPotionRecipeRegistry { + public static class ProperBrewingRecipe extends BrewingRecipe { + private final Ingredient input; + + public ProperBrewingRecipe(Ingredient input, Ingredient ingredient, ItemStack output) { + super(input, ingredient, output); + this.input = input; + } + + + @Override + public boolean isInput(@NotNull ItemStack stack) { + ItemStack[] matchingStacks = input.getItems(); + if (matchingStacks.length == 0) { + return stack.isEmpty(); + } else { + for (ItemStack itemstack : matchingStacks) { + if (ItemStack.isSameItem(stack, itemstack) && ItemStack.isSameItemSameTags(itemstack, stack)) { + return true; + } + } + return false; + } + } + } + @Contract("_ -> new") + public static @NotNull ItemStack createPotion(@NotNull RegistryObject potion){ + return PotionUtils.setPotion(new ItemStack(Items.POTION), potion.get()); + } + + @Contract("_ -> new") + public static @NotNull ItemStack createPotion(Potion potion){ + return PotionUtils.setPotion(new ItemStack(Items.POTION), potion); + } + public static void init() { + BrewingRecipeRegistry.addRecipe( + new ProperBrewingRecipe(Ingredient.of(createPotion(Potions.INVISIBILITY)), Ingredient.of(Items.SLIME_BALL), createPotion(SLPPotions.NO_SUPER_LEASH))); + BrewingRecipeRegistry.addRecipe( + new ProperBrewingRecipe(Ingredient.of(createPotion(Potions.LONG_INVISIBILITY)), Ingredient.of(Items.SLIME_BALL), createPotion(SLPPotions.LONG_NO_SUPER_LEASH))); + BrewingRecipeRegistry.addRecipe( + new ProperBrewingRecipe(Ingredient.of(createPotion(SLPPotions.NO_SUPER_LEASH)), Ingredient.of(Items.REDSTONE), createPotion(SLPPotions.LONG_NO_SUPER_LEASH))); + } + +} diff --git a/src/main/java/top/r3944realms/superleadrope/core/register/SLPPotions.java b/src/main/java/top/r3944realms/superleadrope/core/register/SLPPotions.java new file mode 100644 index 0000000..d43b190 --- /dev/null +++ b/src/main/java/top/r3944realms/superleadrope/core/register/SLPPotions.java @@ -0,0 +1,44 @@ +package top.r3944realms.superleadrope.core.register; + +import net.minecraft.core.registries.Registries; +import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.item.alchemy.Potion; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.RegistryObject; +import top.r3944realms.superleadrope.SuperLeadRope; + +import java.util.function.Supplier; + +public class SLPPotions { + public static DeferredRegister POTIONS = DeferredRegister.create(Registries.POTION, SuperLeadRope.MOD_ID); + public static final RegistryObject NO_SUPER_LEASH = register("no_super_leash", + () -> new Potion("no_super_leash", new MobEffectInstance(SLPEffects.NO_SUPER_LEASH_EFFECT.get(), 1200, 0)) + ); + public static final RegistryObject LONG_NO_SUPER_LEASH = register("long_no_super_leash", + () -> new Potion("no_super_leash", new MobEffectInstance(SLPEffects.NO_SUPER_LEASH_EFFECT.get(), 3600, 0)) + ); + public static RegistryObject register(String Name, Supplier supplier) { + return POTIONS.register(Name, supplier); + } + /** + * + * @param name the Name of Potion + * @param type (char)
[
0 & 3 ~ 255 : potion
1 : lingering_potion
2 : splash_potion
] + * @return Language Key + */ + public static String getPotionNameKey(String name, char type) { + return "item.minecraft." + + (type == 1 ? "lingering_potion" : + (type == 2 ? "splash_potion" : "potion") + ) + + ".effect." + name; + } + public static String getTippedArrowNameKey(String Name) { + return "item.minecraft.tipped_arrow.effect." + Name; + } + + public static void register(IEventBus eventBus) { + POTIONS.register(eventBus); + } +} diff --git a/src/main/java/top/r3944realms/superleadrope/datagen/SLPDataGenEvent.java b/src/main/java/top/r3944realms/superleadrope/datagen/SLPDataGenEvent.java index 960b4d3..9203033 100644 --- a/src/main/java/top/r3944realms/superleadrope/datagen/SLPDataGenEvent.java +++ b/src/main/java/top/r3944realms/superleadrope/datagen/SLPDataGenEvent.java @@ -54,7 +54,9 @@ public class SLPDataGenEvent { LanguageGenerator(event, LanguageEnum.LiteraryChinese); RecipeGenerator(event); ModelDataGenerate(event); + BlockStateGenerate(event); TagsProvider(event, lookupProvider); + LootTableGenerate(event); SoundProvider(event); } private static void LanguageGenerator(GatherDataEvent event, LanguageEnum language) { @@ -97,4 +99,16 @@ public class SLPDataGenEvent { (DataProvider.Factory) pOutput -> new SLPItemModelProvider(pOutput, event.getExistingFileHelper()) ); } + private static void LootTableGenerate(GatherDataEvent event) { + event.getGenerator().addProvider( + event.includeClient(), + (DataProvider.Factory) SLPLootTableProvider::new + ); + } + private static void BlockStateGenerate(GatherDataEvent event) { + event.getGenerator().addProvider( + event.includeClient(), + (DataProvider.Factory) pOutput -> new SLPBlockStateGenerator(pOutput, event.getExistingFileHelper()) + ); + } } diff --git a/src/main/java/top/r3944realms/superleadrope/datagen/data/SLPLangKeyValue.java b/src/main/java/top/r3944realms/superleadrope/datagen/data/SLPLangKeyValue.java index 6a48784..a5d41e3 100644 --- a/src/main/java/top/r3944realms/superleadrope/datagen/data/SLPLangKeyValue.java +++ b/src/main/java/top/r3944realms/superleadrope/datagen/data/SLPLangKeyValue.java @@ -25,9 +25,7 @@ import top.r3944realms.superleadrope.content.command.MotionCommand; import top.r3944realms.superleadrope.content.gamerule.server.CreateSuperLeashKnotEntityIfAbsent; import top.r3944realms.superleadrope.content.gamerule.server.TeleportWithLeashedEntities; import top.r3944realms.superleadrope.content.item.EternalPotatoItem; -import top.r3944realms.superleadrope.core.register.SLPEntityTypes; -import top.r3944realms.superleadrope.core.register.SLPItems; -import top.r3944realms.superleadrope.core.register.SLPSoundEvents; +import top.r3944realms.superleadrope.core.register.*; import top.r3944realms.superleadrope.util.lang.LanguageEnum; import top.r3944realms.superleadrope.util.lang.ModPartEnum; @@ -917,6 +915,47 @@ public enum SLPLangKeyValue { "成功觸發%s的力", "%s之力,今已發" ), + NO_LEASH_EFFECT( + SLPEffects.getEffectKey(SLPEffects.NO_SUPER_LEASH_EFFECT.get()), ModPartEnum.NAME, + "No Super Leash", + "禁拴", + "禁拴", + "禁系之效" + ), + NO_LEASH_POTION( + SLPPotions.getPotionNameKey("no_super_leash", (char) 0), ModPartEnum.NAME, + "No Super Leash Potion", + "禁拴药水", + "禁拴藥水", + "禁系汤剂" + ), + NO_LEASH_POTION_SPLASH( + SLPPotions.getPotionNameKey("no_super_leash", (char) 2), ModPartEnum.NAME, + "Splash No Super Leash Potion", + "喷溅型禁拴药水", + "噴濺型禁拴藥水", + "飞溅禁系汤" + ), + NO_LEASH_POTION_LINGERING( + SLPPotions.getPotionNameKey("no_super_leash", (char) 1), ModPartEnum.NAME, + "Splash No Super Leash Potion", + "滞留型禁拴药水", + "滯留型禁拴藥水", + "缠绵禁系汤" + ), + DOLL_BLOCK( + SLPBlocks.DOLL, ModPartEnum.BLOCK, + "Doll", "玩偶", "玩偶", "戲像" + ), + DOLL_ITEM( + SLPItems.DOLL, ModPartEnum.ITEM, + "Doll", "玩偶", "玩偶", "戲像" + ), + AUTHOR_TOOLTIP( + "tooltip.superleadrope.author", ModPartEnum.DESCRIPTION, + "Author : R3944Realms", "作者 : R3944Realms", + "作者 : R3944Realms", "作者 : R3944Realms" + ) ; private final Supplier supplier; diff --git a/src/main/java/top/r3944realms/superleadrope/datagen/provider/SLPBlockLootTables.java b/src/main/java/top/r3944realms/superleadrope/datagen/provider/SLPBlockLootTables.java new file mode 100644 index 0000000..81e5f90 --- /dev/null +++ b/src/main/java/top/r3944realms/superleadrope/datagen/provider/SLPBlockLootTables.java @@ -0,0 +1,38 @@ +/* + * * + * * Copyright (c) 2025 R3944Realms. All rights reserved. + * * + * * This work is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License. + * * To view a copy of this license, visit http://creativecommons.org/licenses/by-nc-sa/4.0/ + * * or send a letter to Creative Commons, PO Box 1866, Mountain View, CA 94042, USA. + * * + * * 本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 + * + */ + +package top.r3944realms.superleadrope.datagen.provider; + +import net.minecraft.data.loot.BlockLootSubProvider; +import net.minecraft.world.flag.FeatureFlags; +import net.minecraft.world.level.block.Block; +import net.minecraftforge.registries.RegistryObject; +import org.jetbrains.annotations.NotNull; +import top.r3944realms.superleadrope.core.register.SLPBlocks; + +import java.util.Set; + + +public class SLPBlockLootTables extends BlockLootSubProvider { + public SLPBlockLootTables() { + super(Set.of(), FeatureFlags.REGISTRY.allFlags()); + } + + @Override + protected void generate() { + dropSelf(SLPBlocks.DOLL.get()); + } + @Override + protected @NotNull Iterable getKnownBlocks() { + return SLPBlocks.getEntries().stream().map(RegistryObject::get)::iterator; + } +} diff --git a/src/main/java/top/r3944realms/superleadrope/datagen/provider/SLPBlockStateGenerator.java b/src/main/java/top/r3944realms/superleadrope/datagen/provider/SLPBlockStateGenerator.java new file mode 100644 index 0000000..00b0949 --- /dev/null +++ b/src/main/java/top/r3944realms/superleadrope/datagen/provider/SLPBlockStateGenerator.java @@ -0,0 +1,18 @@ +package top.r3944realms.superleadrope.datagen.provider; + +import net.minecraft.data.PackOutput; +import net.minecraftforge.client.model.generators.BlockStateProvider; +import net.minecraftforge.common.data.ExistingFileHelper; +import top.r3944realms.superleadrope.SuperLeadRope; +import top.r3944realms.superleadrope.core.register.SLPBlocks; + +public class SLPBlockStateGenerator extends BlockStateProvider { + public SLPBlockStateGenerator(PackOutput output, ExistingFileHelper exFileHelper) { + super(output, SuperLeadRope.MOD_ID, exFileHelper); + } + + @Override + protected void registerStatesAndModels() { + horizontalBlock(SLPBlocks.DOLL.get(), models().getExistingFile(modLoc("block/doll"))); + } +} \ No newline at end of file diff --git a/src/main/java/top/r3944realms/superleadrope/datagen/provider/SLPItemModelProvider.java b/src/main/java/top/r3944realms/superleadrope/datagen/provider/SLPItemModelProvider.java index 7f669d8..98ed3bd 100644 --- a/src/main/java/top/r3944realms/superleadrope/datagen/provider/SLPItemModelProvider.java +++ b/src/main/java/top/r3944realms/superleadrope/datagen/provider/SLPItemModelProvider.java @@ -24,6 +24,7 @@ import net.minecraftforge.client.model.generators.ModelFile; import net.minecraftforge.common.data.ExistingFileHelper; import net.minecraftforge.registries.ForgeRegistries; import top.r3944realms.superleadrope.SuperLeadRope; +import top.r3944realms.superleadrope.core.register.SLPItems; import top.r3944realms.superleadrope.datagen.data.SLPLangKeyValue; import java.util.ArrayList; @@ -35,6 +36,7 @@ import java.util.Objects; */ public class SLPItemModelProvider extends ItemModelProvider { private static List objectList; + public static final ResourceLocation DOLL = new ResourceLocation(SuperLeadRope.MOD_ID, "block/doll"); /** * The constant GENERATED. */ @@ -60,6 +62,7 @@ public class SLPItemModelProvider extends ItemModelProvider { protected void registerModels() { DefaultModItemModelRegister(); superLeadRopeModel(); + generateDollItemModel(); } private void init() { for(SLPLangKeyValue obj : SLPLangKeyValue.values()) { @@ -93,6 +96,10 @@ public class SLPItemModelProvider extends ItemModelProvider { public void itemHandHeldModel(Item item, ResourceLocation location){ withExistingParent(itemName(item), HANDHELD).texture("layer0", location); } + private void generateDollItemModel() { + withExistingParent(itemName(SLPItems.DOLL.get()), DOLL); + + } /** * Super lead rope model. diff --git a/src/main/java/top/r3944realms/superleadrope/datagen/provider/SLPLootTableProvider.java b/src/main/java/top/r3944realms/superleadrope/datagen/provider/SLPLootTableProvider.java new file mode 100644 index 0000000..7c7b87a --- /dev/null +++ b/src/main/java/top/r3944realms/superleadrope/datagen/provider/SLPLootTableProvider.java @@ -0,0 +1,37 @@ +package top.r3944realms.superleadrope.datagen.provider; + +import net.minecraft.data.PackOutput; +import net.minecraft.data.loot.LootTableProvider; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.storage.loot.LootTable; +import net.minecraft.world.level.storage.loot.ValidationContext; +import net.minecraft.world.level.storage.loot.parameters.LootContextParamSets; +import org.jetbrains.annotations.NotNull; + +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * The type Simple loot table provider. + */ +public class SLPLootTableProvider extends LootTableProvider { + /** + * Instantiates a new Simple loot table provider. + * + * @param output the output + * @param subProvidersWrapper the sub providers wrapper + */ + public SLPLootTableProvider(PackOutput output) { + super(output, Set.of(), List.of(new LootTableProvider.SubProviderEntry( + SLPBlockLootTables::new, + LootContextParamSets.BLOCK + ))); + } + + + @Override + protected void validate(@NotNull Map map, @NotNull ValidationContext validationcontext) { + map.forEach((id, table) -> table.validate(validationcontext)); + } +} diff --git a/src/main/java/top/r3944realms/superleadrope/util/entity/TeleportUtil.java b/src/main/java/top/r3944realms/superleadrope/util/entity/TeleportUtil.java new file mode 100644 index 0000000..a9b3d30 --- /dev/null +++ b/src/main/java/top/r3944realms/superleadrope/util/entity/TeleportUtil.java @@ -0,0 +1,128 @@ +package top.r3944realms.superleadrope.util.entity; + +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.world.entity.*; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.network.protocol.game.ClientboundSetExperiencePacket; +import net.minecraft.util.Mth; +import net.minecraft.world.phys.Vec3; +import net.minecraft.server.level.TicketType; +import org.jetbrains.annotations.NotNull; + +import java.util.Collections; + +public class TeleportUtil { + + /** + * 通用实体传送(支持玩家、普通生物、跨维度、生物停飞、导航停止等) + */ + public static @NotNull Entity teleportEntity(Entity oldEntity, ServerLevel targetWorld, @NotNull Vec3 targetPos, @NotNull Direction direction) { + float yaw = direction.toYRot(); + double x = targetPos.x; + double y = targetPos.y; + double z = targetPos.z; + + if (oldEntity instanceof ServerPlayer player) { + teleportPlayer(player, targetWorld, x, y, z, yaw); + } else { + oldEntity = teleportNonPlayer(oldEntity, targetWorld, x, y, z, yaw); + } + + // 停止滑翔,否则 Elytra 无限飞 + if (!(oldEntity instanceof LivingEntity living) || !living.isFallFlying()) { + oldEntity.setDeltaMovement(oldEntity.getDeltaMovement().multiply(1.0, 0.0, 1.0)); + oldEntity.setOnGround(true); + } + + // 停止 AI 导航,避免卡行为树 + if (oldEntity instanceof PathfinderMob mob) { + mob.getNavigation().stop(); + } + + sendHackySyncPacketsAfterTeleport(oldEntity); + + return oldEntity; + } + + + // --- 分离后的子方法 ------------------------------------------------ + + private static void teleportPlayer(@NotNull ServerPlayer player, @NotNull ServerLevel targetWorld, + double x, double y, double z, float yaw) { + + ChunkPos chunkPos = new ChunkPos(BlockPos.containing(x, y, z)); + targetWorld.getChunkSource().addRegionTicket( + TicketType.POST_TELEPORT, + chunkPos, + 1, + player.getId() + ); + + // 玩家睡觉状态处理 + if (player.isSleeping()) { + player.stopSleepInBed(true, true); + } + + player.stopRiding(); + + // 同维度直接 connection.teleport + if (targetWorld == player.level()) { + player.connection.teleport(x, y, z, yaw, player.getXRot(), Collections.emptySet()); + } else { + player.teleportTo(targetWorld, x, y, z, yaw, player.getXRot()); + } + + player.setYHeadRot(yaw); + } + + + private static @NotNull Entity teleportNonPlayer(@NotNull Entity entity, ServerLevel targetWorld, + double x, double y, double z, float yaw) { + + float pitch = Mth.clamp(entity.getXRot(), -90, 90); + + // 同维度移动 + if (targetWorld == entity.level()) { + entity.moveTo(x, y, z, yaw, pitch); + entity.setYHeadRot(yaw); + return entity; + } + + // 跨维度传送 + entity.unRide(); + + Entity newEntity = entity.getType().create(targetWorld); + + if (newEntity == null) { + return entity; + } + + newEntity.restoreFrom(entity); + newEntity.moveTo(x, y, z, yaw, pitch); + newEntity.setYHeadRot(yaw); + + entity.setRemoved(Entity.RemovalReason.CHANGED_DIMENSION); + targetWorld.addDuringTeleport(newEntity); + + return newEntity; + } + + + /** + * 修复玩家经验条显示等问题的同步包 + */ + private static void sendHackySyncPacketsAfterTeleport(Entity entity) { + if (entity instanceof ServerPlayer player) { + player.connection.send( + new ClientboundSetExperiencePacket( + player.experienceProgress, + player.totalExperience, + player.experienceLevel + ) + ); + } + } +} diff --git a/src/main/java/top/r3944realms/superleadrope/util/model/RidingRelationship.java b/src/main/java/top/r3944realms/superleadrope/util/model/RidingRelationship.java index 22699d8..750235a 100644 --- a/src/main/java/top/r3944realms/superleadrope/util/model/RidingRelationship.java +++ b/src/main/java/top/r3944realms/superleadrope/util/model/RidingRelationship.java @@ -15,6 +15,8 @@ package top.r3944realms.superleadrope.util.model; +import org.jetbrains.annotations.NotNull; + import java.util.*; /** @@ -138,6 +140,121 @@ public class RidingRelationship { } return false; } + /** + * 查找并替换所有匹配的UUID + * + * @param oldUuid 要查找的旧UUID + * @param newUuid 要替换的新UUID + * @return 替换的数量 + */ + public int findAndReplaceAll(UUID oldUuid, UUID newUuid) { + int replacedCount = 0; + + // 替换当前节点的entityId + if (Objects.equals(this.entityId, oldUuid)) { + this.entityId = newUuid; + replacedCount++; + } + + // 替换当前节点的vehicleId + if (Objects.equals(this.vehicleId, oldUuid)) { + this.vehicleId = newUuid; + replacedCount++; + } + + // 递归替换所有乘客 + for (RidingRelationship passenger : passengers) { + replacedCount += passenger.findAndReplaceAll(oldUuid, newUuid); + } + + return replacedCount; + } + + /** + * 查找所有出现的UUID位置 + * + * @param targetUuid 要查找的UUID + * @return 包含位置的列表,格式为"角色(实体/载具)-索引" + */ + public List findAllOccurrences(UUID targetUuid) { + List occurrences = new ArrayList<>(); + findAllOccurrencesRecursive(targetUuid, this, occurrences, ""); + return occurrences; + } + + private void findAllOccurrencesRecursive(UUID targetUuid, @NotNull RidingRelationship node, + List occurrences, String path) { + // 检查当前节点的entityId + if (Objects.equals(node.entityId, targetUuid)) { + String fullPath = path.isEmpty() ? "根实体" : path + "->乘客"; + occurrences.add(fullPath + "(实体ID)"); + } + + // 检查当前节点的vehicleId + if (Objects.equals(node.vehicleId, targetUuid)) { + String fullPath = path.isEmpty() ? "根实体" : path; + occurrences.add(fullPath + "(载具ID)"); + } + + // 递归检查乘客 + for (int i = 0; i < node.passengers.size(); i++) { + String newPath = path.isEmpty() ? "乘客[" + i + "]" : path + "->乘客[" + i + "]"; + findAllOccurrencesRecursive(targetUuid, node.passengers.get(i), occurrences, newPath); + } + } + + /** + * 查找并替换所有UUID(支持批量替换) + * + * @param replacements 替换映射表,key为旧UUID,value为新UUID + * @return 总替换数量 + */ + public int batchFindAndReplace(Map replacements) { + int totalReplaced = 0; + + // 替换当前节点的entityId + if (this.entityId != null && replacements.containsKey(this.entityId)) { + this.entityId = replacements.get(this.entityId); + totalReplaced++; + } + + // 替换当前节点的vehicleId + if (this.vehicleId != null && replacements.containsKey(this.vehicleId)) { + this.vehicleId = replacements.get(this.vehicleId); + totalReplaced++; + } + + // 递归批量替换所有乘客 + for (RidingRelationship passenger : passengers) { + totalReplaced += passenger.batchFindAndReplace(replacements); + } + + return totalReplaced; + } + + /** + * 获取树中所有唯一的UUID集合 + * + * @return 包含所有UUID的集合 + */ + public Set getAllUniqueUUIDs() { + Set uuids = new HashSet<>(); + getAllUniqueUUIDsRecursive(this, uuids); + return uuids; + } + + private void getAllUniqueUUIDsRecursive(RidingRelationship node, Set uuids) { + if (node.entityId != null) { + uuids.add(node.entityId); + } + if (node.vehicleId != null) { + uuids.add(node.vehicleId); + } + + for (RidingRelationship passenger : node.passengers) { + getAllUniqueUUIDsRecursive(passenger, uuids); + } + } @Override public String toString() { diff --git a/src/main/java/top/r3944realms/superleadrope/util/riding/RidingSaver.java b/src/main/java/top/r3944realms/superleadrope/util/riding/RidingSaver.java index 47dc2a0..e8d7da1 100644 --- a/src/main/java/top/r3944realms/superleadrope/util/riding/RidingSaver.java +++ b/src/main/java/top/r3944realms/superleadrope/util/riding/RidingSaver.java @@ -17,7 +17,10 @@ package top.r3944realms.superleadrope.util.riding; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.NotNull; import top.r3944realms.superleadrope.CommonEventHandler; +import top.r3944realms.superleadrope.SuperLeadRope; import top.r3944realms.superleadrope.core.exception.RidingCycleException; import top.r3944realms.superleadrope.core.util.ImmutablePair; import top.r3944realms.superleadrope.util.model.RidingRelationship; @@ -36,7 +39,8 @@ public class RidingSaver { * @param entity the entity * @return the riding relationship */ - public static RidingRelationship save(@Nullable Entity entity) { + @Contract("null -> new") + public static @NotNull RidingRelationship save(@Nullable Entity entity) { return save(entity, true); } @@ -47,7 +51,8 @@ public class RidingSaver { * @param findRoot the find root * @return the riding relationship */ - public static RidingRelationship save(@Nullable Entity entity, boolean findRoot) { + @Contract("null, _ -> new") + public static @NotNull RidingRelationship save(@Nullable Entity entity, boolean findRoot) { if (entity == null) { return new RidingRelationship(Collections.emptyList(), null, null); } @@ -118,33 +123,37 @@ public class RidingSaver { */ public static RidingRelationship filterByWhitelistRoot(RidingRelationship relationship) { if (relationship == null) return null; - - // 如果当前根节点在白名单,则直接处理子节点 - if (CommonEventHandler.leashConfigManager.isEntityTeleportAllowed(Objects.requireNonNull(getEntityType(relationship.getEntityId())))) { - RidingRelationship filtered = new RidingRelationship(); - filtered.setEntityId(relationship.getEntityId()); - filtered.setVehicleId(relationship.getVehicleId()); - filtered.setPassengers(filterPassengers(relationship.getPassengers())); - return filtered; - } else { - // 根节点不在白名单,尝试找到合法的子节点作为新的根 - for (RidingRelationship child : relationship.getPassengers()) { - if (CommonEventHandler.leashConfigManager.isEntityTeleportAllowed(Objects.requireNonNull(getEntityType(child.getEntityId())))) { - // 设置父节点为当前节点的父(倒二叉逻辑) - RidingRelationship newRoot = new RidingRelationship(); - newRoot.setEntityId(child.getEntityId()); - newRoot.setVehicleId(relationship.getVehicleId()); - newRoot.setPassengers(filterPassengers(child.getPassengers())); - return newRoot; + try { + // 如果当前根节点在白名单,则直接处理子节点 + if (CommonEventHandler.leashConfigManager.isEntityTeleportAllowed(Objects.requireNonNull(getEntityType(relationship.getEntityId())))) { + RidingRelationship filtered = new RidingRelationship(); + filtered.setEntityId(relationship.getEntityId()); + filtered.setVehicleId(relationship.getVehicleId()); + filtered.setPassengers(filterPassengers(relationship.getPassengers())); + return filtered; + } else { + // 根节点不在白名单,尝试找到合法的子节点作为新的根 + for (RidingRelationship child : relationship.getPassengers()) { + if (CommonEventHandler.leashConfigManager.isEntityTeleportAllowed(Objects.requireNonNull(getEntityType(child.getEntityId())))) { + // 设置父节点为当前节点的父(倒二叉逻辑) + RidingRelationship newRoot = new RidingRelationship(); + newRoot.setEntityId(child.getEntityId()); + newRoot.setVehicleId(relationship.getVehicleId()); + newRoot.setPassengers(filterPassengers(child.getPassengers())); + return newRoot; + } } } + } catch (NullPointerException e) { + SuperLeadRope.logger.error("Catch null", e); } // 如果整个子树都不在白名单,返回空关系 return new RidingRelationship(new ArrayList<>(), null, null); } - private static List filterPassengers(List passengers) { + @Contract("null -> new") + private static @NotNull List filterPassengers(List passengers) { if (passengers == null || passengers.isEmpty()) return new ArrayList<>(); List filtered = new ArrayList<>(); for (RidingRelationship passenger : passengers) { diff --git a/src/main/resources/assets/superleadrope/models/block/doll.bbmodel b/src/main/resources/assets/superleadrope/models/block/doll.bbmodel new file mode 100644 index 0000000..b5dacee --- /dev/null +++ b/src/main/resources/assets/superleadrope/models/block/doll.bbmodel @@ -0,0 +1 @@ +{"meta":{"format_version":"5.0","model_format":"java_block","box_uv":false},"name":"doll","parent":"","java_block_version":"1.21.6","ambientocclusion":true,"front_gui_light":false,"visible_box":[1,1,0],"variable_placeholders":"","variable_placeholder_buttons":[],"unhandled_root_fields":{"format_version":"1.21.6"},"resolution":{"width":16,"height":16},"elements":[{"name":"Toggle_Helmet","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[3.5,8.8,7.5],"to":[12.5,17.8,16.5],"autouv":0,"color":0,"origin":[8,9.3,12],"faces":{"north":{"uv":[10,2,12,4],"texture":0},"east":{"uv":[8,2,10,4],"texture":0},"south":{"uv":[14,2,16,4],"texture":0},"west":{"uv":[12,2,14,4],"texture":0},"up":{"uv":[10,2,12,0],"texture":0},"down":{"uv":[12,0,14,2],"texture":0}},"type":"cube","uuid":"4034240c-1bb7-3096-56d0-f9d9158bd705"},{"name":"Head","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[4,9.3,8],"to":[12,17.3,16],"autouv":0,"color":0,"origin":[8,9.3,12],"faces":{"north":{"uv":[2,2,4,4],"texture":0},"east":{"uv":[0,2,2,4],"texture":0},"south":{"uv":[6,2,8,4],"texture":0},"west":{"uv":[4,2,6,4],"texture":0},"up":{"uv":[4,2,2,0],"texture":0},"down":{"uv":[6,0,4,2],"texture":0}},"type":"cube","uuid":"5eca2c83-4481-ddf5-fafe-19abeb647c57"},{"name":"Toggle_Chest_Armor","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[4.75,2.05,9.75],"to":[11.25,9.55,13.25],"autouv":0,"color":0,"origin":[8,5.8,11.5],"faces":{"north":{"uv":[5,9,7,12],"texture":0},"east":{"uv":[4,9,5,12],"texture":0},"south":{"uv":[8,9,10,12],"texture":0},"west":{"uv":[7,9,8,12],"texture":0},"up":{"uv":[5,8,7,9],"texture":0},"down":{"uv":[7,8,9,9],"texture":0}},"type":"cube","uuid":"8ea34c7a-dcd8-ead4-07d1-ccab4438046e"},{"name":"Body","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[5,2.3,10],"to":[11,9.3,13],"autouv":0,"color":3,"origin":[8,5.8,11.5],"faces":{"north":{"uv":[5,5,7,8],"texture":0},"east":{"uv":[4,5,5,8],"texture":0},"south":{"uv":[8,5,10,8],"texture":0},"west":{"uv":[7,5,8,8],"texture":0},"up":{"uv":[7,5,5,4],"texture":0},"down":{"uv":[9,4,7,5],"texture":0}},"type":"cube","uuid":"fd16d848-4320-9a3f-6b3d-3f4884a92fbe"},{"name":"Toggle_Left_Arm_Armor","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[2.75,6.25,3.8],"to":[5.25,9.75,13.3],"autouv":0,"color":3,"rotation":[0,-22.5,0],"origin":[3,8,12.5],"faces":{"north":{"uv":[13.75,12,14.5,13],"rotation":180,"texture":0},"east":{"uv":[12,13,13,16],"rotation":270,"texture":0},"south":{"uv":[13,12,13.75,13],"texture":0},"west":{"uv":[13.75,13,14.75,16],"rotation":90,"texture":0},"up":{"uv":[13,13,13.75,16],"rotation":180,"texture":0},"down":{"uv":[14.75,13,15.5,16],"texture":0}},"type":"cube","uuid":"06ccbe71-f249-9062-076b-ea3f530fa945"},{"name":"Left_arm","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[3,6.5,3.8],"to":[5,9.5,12.8],"autouv":0,"color":6,"rotation":[0,-22.5,0],"origin":[4,8,12.5],"faces":{"north":{"uv":[10.5,12,9.75,13],"rotation":180,"texture":0},"east":{"uv":[8,13,9,16],"rotation":270,"texture":0},"south":{"uv":[9.75,13,9,12],"texture":0},"west":{"uv":[9.75,13,10.5,16],"rotation":90,"texture":0},"up":{"uv":[9,13,9.75,16],"rotation":180,"texture":0},"down":{"uv":[10.5,13,11.5,16],"texture":0}},"type":"cube","uuid":"15980f9e-f82b-d64a-eaa4-38789e0635cc"},{"name":"Toggle_Right_Arm_Armor","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[10.75,6.25,3.8],"to":[13.25,9.75,13.3],"autouv":0,"color":6,"rotation":[0,22.5,0],"origin":[12,8,11.5],"faces":{"north":{"uv":[11.75,8,12.5,9],"rotation":180,"texture":0},"east":{"uv":[10,9,11,12],"rotation":270,"texture":0},"south":{"uv":[11,8,11.75,9],"texture":0},"west":{"uv":[11.75,9,12.75,12],"rotation":90,"texture":0},"up":{"uv":[11,9,11.75,12],"rotation":180,"texture":0},"down":{"uv":[12.75,9,13.5,12],"texture":0}},"type":"cube","uuid":"7b6c1629-5993-798e-8a6e-bb9303f0e8da"},{"name":"Right_arm","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[11,6.5,3.8],"to":[13.5,9.5,12.8],"autouv":0,"color":0,"rotation":[0,22.5,0],"origin":[12,8,11.5],"faces":{"north":{"uv":[12.5,4,11.75,5],"rotation":180,"texture":0},"east":{"uv":[10,5,11,8],"rotation":270,"texture":0},"south":{"uv":[11.75,5,11,4],"texture":0},"west":{"uv":[11.75,5,12.5,8],"rotation":90,"texture":0},"up":{"uv":[11,5,11.75,8],"rotation":180,"texture":0},"down":{"uv":[12.5,5,13.5,8],"texture":0}},"type":"cube","uuid":"e5bd3372-f4e5-9cc0-1f38-726db3f86001"},{"name":"Toggle_Left_Leg_Armor","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[5.2,-0.25,3.05],"to":[8.7,3.25,12.55],"autouv":0,"color":1,"rotation":[0,22.5,0],"origin":[5.7,2,13],"faces":{"north":{"uv":[2,12,3,13],"rotation":180,"texture":0},"east":{"uv":[0,13,1,16],"rotation":270,"texture":0},"south":{"uv":[1,12,2,13],"texture":0},"west":{"uv":[2,13,3,16],"rotation":90,"texture":0},"up":{"uv":[1,13,2,16],"rotation":180,"texture":0},"down":{"uv":[3,13,4,16],"texture":0}},"type":"cube","uuid":"859ab26f-304d-1fc2-e695-7c65fa9746c5"},{"name":"Left_leg","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[5.5,0,3.3],"to":[8.5,3,12.3],"autouv":0,"color":5,"rotation":[0,22.5,0],"origin":[6,2,13],"faces":{"north":{"uv":[7,12,6,13],"rotation":180,"texture":0},"east":{"uv":[4,13,5,16],"rotation":270,"texture":0},"south":{"uv":[5.95,13,5,11.925],"texture":0},"west":{"uv":[6,13,7,16],"rotation":90,"texture":0},"up":{"uv":[5,13,6,16],"rotation":180,"texture":0},"down":{"uv":[7,13,8,16],"texture":0}},"type":"cube","uuid":"1fb83a23-bc95-d6de-1a60-b721c8922407"},{"name":"Toggle_Right_Leg_Armor","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[7.2,-0.25,3.05],"to":[10.7,3.25,12.55],"autouv":0,"color":7,"rotation":[0,-22.5,0],"origin":[8.7,2,13],"faces":{"north":{"uv":[2,8,3,9],"rotation":180,"texture":0},"east":{"uv":[0,9,1,12],"rotation":270,"texture":0},"south":{"uv":[1,8,2,9],"texture":0},"west":{"uv":[2,9,3,12],"rotation":90,"texture":0},"up":{"uv":[1,9,2,12],"rotation":180,"texture":0},"down":{"uv":[3,9,4,12],"texture":0}},"type":"cube","uuid":"7fb46a5a-407b-6e68-5395-edf7ec58c151"},{"name":"Right_leg","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[7.5,0,3.3],"to":[10.5,3,12.3],"autouv":0,"color":0,"rotation":[0,-22.5,0],"origin":[9,2,13],"faces":{"north":{"uv":[3,4,2,5],"rotation":180,"texture":0},"east":{"uv":[0,5,1,8],"rotation":270,"texture":0},"south":{"uv":[2,5,1,4],"texture":0},"west":{"uv":[2,5,3,8],"rotation":90,"texture":0},"up":{"uv":[1,5,2,8],"rotation":180,"texture":0},"down":{"uv":[3,5,4,8],"texture":0}},"type":"cube","uuid":"2977e3b7-0d36-5caf-3a69-4c0fb7895a71"},{"name":"cube","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[7,6,1],"to":[7,14,9],"autouv":0,"color":8,"rotation":[0,45,0],"origin":[7,10,3.5],"faces":{"north":{"uv":[0,0,0,0],"texture":null},"east":{"uv":[0,0,16,16],"texture":2},"south":{"uv":[0,0,0,0],"texture":null},"west":{"uv":[0,0,16,16],"texture":2},"up":{"uv":[0,0,0,0],"texture":null},"down":{"uv":[0,0,0,0],"texture":null}},"type":"cube","uuid":"ba8da4eb-b48e-0c2f-8240-95d681f387ff"},{"name":"cube","box_uv":false,"render_order":"default","rescale":false,"locked":false,"shade":true,"light_emission":0,"allow_mirror_modeling":true,"from":[9,6,1],"to":[9,14,9],"autouv":0,"color":0,"rotation":[0,-45,0],"origin":[9,10,3.5],"faces":{"north":{"uv":[0,0,0,0],"texture":null},"east":{"uv":[0,0,16,16],"texture":2},"south":{"uv":[0,0,0,0],"texture":null},"west":{"uv":[0,0,16,16],"texture":2},"up":{"uv":[0,0,0,0],"texture":null},"down":{"uv":[0,0,0,0],"texture":null}},"type":"cube","uuid":"3644a889-b638-1c56-700d-f80c64cc474c"}],"groups":[{"uuid":"eda1d026-dfe0-f980-152d-71db37d8a5b3","export":true,"locked":false,"origin":[3,-6.7,6],"rotation":[0,0,0],"color":0,"name":"Player","children":[],"reset":false,"shade":true,"mirror_uv":false,"selected":false,"visibility":true,"autouv":0,"isOpen":true,"primary_selected":false},{"uuid":"5399b7c3-2eac-47ae-fb88-873e7e24a5d6","export":true,"locked":false,"origin":[8,16,8],"rotation":[0,0,0],"color":0,"name":"Head","children":[],"reset":false,"shade":true,"mirror_uv":false,"selected":false,"visibility":true,"autouv":0,"isOpen":false,"primary_selected":false},{"uuid":"0c759830-21cb-f6ec-e6d7-af3998e4bbd2","export":true,"locked":false,"origin":[8,11,8],"rotation":[0,0,0],"color":0,"name":"Body","children":[],"reset":false,"shade":true,"mirror_uv":false,"selected":false,"visibility":true,"autouv":0,"isOpen":false,"primary_selected":false},{"uuid":"b31348f5-2c4e-cfd0-cec3-4c11d4a5bee2","export":true,"locked":false,"origin":[5,15,6],"rotation":[0,0,0],"color":0,"name":"Left_Arm","children":[],"reset":false,"shade":true,"mirror_uv":false,"selected":false,"visibility":true,"autouv":0,"isOpen":true,"primary_selected":false},{"uuid":"eb158d47-d395-3084-947f-4101fa1eb833","export":true,"locked":false,"origin":[11,15,6],"rotation":[0,0,0],"color":0,"name":"Right_Arm","children":[],"reset":false,"shade":true,"mirror_uv":false,"selected":false,"visibility":true,"autouv":0,"isOpen":true,"primary_selected":false},{"uuid":"0022c2e4-2add-b938-2d45-0a8b8b95d53a","export":true,"locked":false,"origin":[7,13,7],"rotation":[0,0,0],"color":0,"name":"Left_Leg","children":[],"reset":false,"shade":true,"mirror_uv":false,"selected":false,"visibility":true,"autouv":0,"isOpen":true,"primary_selected":false},{"uuid":"c752460c-4cd8-aaae-17c7-d45bf46741e4","export":true,"locked":false,"origin":[10,13,7],"rotation":[0,0,0],"color":0,"name":"Right_Leg","children":[],"reset":false,"shade":true,"mirror_uv":false,"selected":false,"visibility":true,"autouv":0,"isOpen":true,"primary_selected":false},{"uuid":"6e676a00-56e1-2ec4-ecb9-00710aada58d","export":true,"locked":false,"origin":[0,4,2.5],"rotation":[0,0,0],"color":0,"name":"item","children":[],"reset":false,"shade":true,"mirror_uv":false,"selected":false,"visibility":true,"autouv":0,"isOpen":true,"primary_selected":false}],"outliner":[{"uuid":"eda1d026-dfe0-f980-152d-71db37d8a5b3","isOpen":true,"children":[{"uuid":"5399b7c3-2eac-47ae-fb88-873e7e24a5d6","isOpen":false,"children":["4034240c-1bb7-3096-56d0-f9d9158bd705","5eca2c83-4481-ddf5-fafe-19abeb647c57"]},{"uuid":"0c759830-21cb-f6ec-e6d7-af3998e4bbd2","isOpen":false,"children":["8ea34c7a-dcd8-ead4-07d1-ccab4438046e","fd16d848-4320-9a3f-6b3d-3f4884a92fbe"]},{"uuid":"b31348f5-2c4e-cfd0-cec3-4c11d4a5bee2","isOpen":true,"children":["06ccbe71-f249-9062-076b-ea3f530fa945","15980f9e-f82b-d64a-eaa4-38789e0635cc"]},{"uuid":"eb158d47-d395-3084-947f-4101fa1eb833","isOpen":true,"children":["7b6c1629-5993-798e-8a6e-bb9303f0e8da","e5bd3372-f4e5-9cc0-1f38-726db3f86001"]},{"uuid":"0022c2e4-2add-b938-2d45-0a8b8b95d53a","isOpen":true,"children":["859ab26f-304d-1fc2-e695-7c65fa9746c5","1fb83a23-bc95-d6de-1a60-b721c8922407"]},{"uuid":"c752460c-4cd8-aaae-17c7-d45bf46741e4","isOpen":true,"children":["7fb46a5a-407b-6e68-5395-edf7ec58c151","2977e3b7-0d36-5caf-3a69-4c0fb7895a71"]}]},{"uuid":"6e676a00-56e1-2ec4-ecb9-00710aada58d","isOpen":true,"children":["ba8da4eb-b48e-0c2f-8240-95d681f387ff","3644a889-b638-1c56-700d-f80c64cc474c"]}],"textures":[{"name":"author.png","relative_path":"H:/Download/2d9f724107b509db.png","folder":"H:/Download","namespace":"","id":"0","group":"","width":64,"height":64,"uv_width":16,"uv_height":16,"particle":true,"use_as_default":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","pbr_channel":"color","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":true,"uuid":"f5a406a9-0e83-e8e7-427a-4cf3e6991f20","source":"data:image/png;base64,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"},{"name":"allium.png","path":"","folder":"","namespace":"","id":"1","group":"","width":16,"height":16,"uv_width":16,"uv_height":16,"particle":false,"use_as_default":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","pbr_channel":"color","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":false,"uuid":"b68aca7b-f859-4cdb-5c04-2e5b1fcfe0b6","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAHlBMVEUAAADoz/7Spva4eO1Vqy2mXuFSmi5Kjyh7TqAXfAQSwnSGAAAAAXRSTlMAQObYZgAAADlJREFUeNpjwAqUAyA0k5AFhKGoGNQAZhgZmUIYrMrBUMXtBlAGO0w7G4zBgsFgQzDQdXEyMDAwAACVCARQ+FH48gAAAABJRU5ErkJggg=="},{"name":"pink_tulip.png","path":"","folder":"","namespace":"","id":"2","group":"","width":16,"height":16,"uv_width":16,"uv_height":16,"particle":false,"use_as_default":false,"layers_enabled":false,"sync_to_project":"","render_mode":"default","render_sides":"auto","pbr_channel":"color","frame_time":1,"frame_order_type":"loop","frame_order":"","frame_interpolate":false,"visible":true,"internal":true,"saved":false,"uuid":"87664580-654f-755e-6bb2-e6744cc372c0","source":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAGFBMVEUAAAD24v/rxf3kr/RVqy1Smi5KjygXfAQokMEAAAAAAXRSTlMAQObYZgAAADlJREFUeNpjwA8EFKAMRRjDyADKYIbSbOxQBks4G5Thxg5luKdDGKzu7lDFYVAGQ0gBlJECY4A1AQDvsQUd5qhYbgAAAABJRU5ErkJggg=="}],"display":{"thirdperson_righthand":{"rotation":[75,45,0],"translation":[0,2.5,0],"scale":[0.375,0.375,0.375]},"thirdperson_lefthand":{"rotation":[75,45,0],"translation":[0,2.5,0],"scale":[0.375,0.375,0.375]},"firstperson_righthand":{"rotation":[0,124,0],"translation":[2,3,0],"scale":[0.4,0.4,0.4]},"firstperson_lefthand":{"rotation":[0,120,0],"translation":[1.5,2.75,0],"scale":[0.4,0.4,0.4]},"ground":{"translation":[0,2,0],"scale":[0.5,0.5,0.5]},"gui":{"rotation":[30,-135,0],"translation":[0.75,-1,0],"scale":[0.625,0.625,0.625]},"head":{"translation":[0,14,-0.75]},"fixed":{"translation":[0,0,-2.75],"scale":[0.5,0.5,0.5]},"on_shelf":{"rotation":[0,-180,0],"translation":[0,0,5.25]}}} \ No newline at end of file diff --git a/src/main/resources/assets/superleadrope/models/block/doll.json b/src/main/resources/assets/superleadrope/models/block/doll.json new file mode 100644 index 0000000..5759715 --- /dev/null +++ b/src/main/resources/assets/superleadrope/models/block/doll.json @@ -0,0 +1,291 @@ +{ + "format_version": "1.21.6", + "credit": "3D Model © 2025 LeisureTimeDock", + "render_type": "cutout", + "textures": { + "0": "superleadrope:block/custom/author", + "1": "block/pink_tulip", + "particle": "block/white_wool" + }, + "elements": [ + { + "name": "Toggle_Helmet", + "from": [3.5, 8.8, 7.5], + "to": [12.5, 17.8, 16.5], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 9.3, 12]}, + "faces": { + "north": {"uv": [10, 2, 12, 4], "texture": "#0"}, + "east": {"uv": [8, 2, 10, 4], "texture": "#0"}, + "south": {"uv": [14, 2, 16, 4], "texture": "#0"}, + "west": {"uv": [12, 2, 14, 4], "texture": "#0"}, + "up": {"uv": [10, 2, 12, 0], "texture": "#0"}, + "down": {"uv": [12, 0, 14, 2], "texture": "#0"} + } + }, + { + "name": "Head", + "from": [4, 9.3, 8], + "to": [12, 17.3, 16], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 9.3, 12]}, + "faces": { + "north": {"uv": [2, 2, 4, 4], "texture": "#0"}, + "east": {"uv": [0, 2, 2, 4], "texture": "#0"}, + "south": {"uv": [6, 2, 8, 4], "texture": "#0"}, + "west": {"uv": [4, 2, 6, 4], "texture": "#0"}, + "up": {"uv": [4, 2, 2, 0], "texture": "#0"}, + "down": {"uv": [6, 0, 4, 2], "texture": "#0"} + } + }, + { + "name": "Toggle_Chest_Armor", + "from": [4.75, 2.05, 9.75], + "to": [11.25, 9.55, 13.25], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 5.8, 11.5]}, + "faces": { + "north": {"uv": [5, 9, 7, 12], "texture": "#0"}, + "east": {"uv": [4, 9, 5, 12], "texture": "#0"}, + "south": {"uv": [8, 9, 10, 12], "texture": "#0"}, + "west": {"uv": [7, 9, 8, 12], "texture": "#0"}, + "up": {"uv": [5, 8, 7, 9], "texture": "#0"}, + "down": {"uv": [7, 8, 9, 9], "texture": "#0"} + } + }, + { + "name": "Body", + "from": [5, 2.3, 10], + "to": [11, 9.3, 13], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 5.8, 11.5]}, + "faces": { + "north": {"uv": [5, 5, 7, 8], "texture": "#0"}, + "east": {"uv": [4, 5, 5, 8], "texture": "#0"}, + "south": {"uv": [8, 5, 10, 8], "texture": "#0"}, + "west": {"uv": [7, 5, 8, 8], "texture": "#0"}, + "up": {"uv": [7, 5, 5, 4], "texture": "#0"}, + "down": {"uv": [9, 4, 7, 5], "texture": "#0"} + } + }, + { + "name": "Toggle_Left_Arm_Armor", + "from": [2.75, 6.25, 3.8], + "to": [5.25, 9.75, 13.3], + "rotation": {"angle": -22.5, "axis": "y", "origin": [3, 8, 12.5]}, + "faces": { + "north": {"uv": [13.75, 12, 14.5, 13], "rotation": 180, "texture": "#0"}, + "east": {"uv": [12, 13, 13, 16], "rotation": 270, "texture": "#0"}, + "south": {"uv": [13, 12, 13.75, 13], "texture": "#0"}, + "west": {"uv": [13.75, 13, 14.75, 16], "rotation": 90, "texture": "#0"}, + "up": {"uv": [13, 13, 13.75, 16], "rotation": 180, "texture": "#0"}, + "down": {"uv": [14.75, 13, 15.5, 16], "texture": "#0"} + } + }, + { + "name": "Left_arm", + "from": [3, 6.5, 3.8], + "to": [5, 9.5, 12.8], + "rotation": {"angle": -22.5, "axis": "y", "origin": [4, 8, 12.5]}, + "faces": { + "north": {"uv": [10.5, 12, 9.75, 13], "rotation": 180, "texture": "#0"}, + "east": {"uv": [8, 13, 9, 16], "rotation": 270, "texture": "#0"}, + "south": {"uv": [9.75, 13, 9, 12], "texture": "#0"}, + "west": {"uv": [9.75, 13, 10.5, 16], "rotation": 90, "texture": "#0"}, + "up": {"uv": [9, 13, 9.75, 16], "rotation": 180, "texture": "#0"}, + "down": {"uv": [10.5, 13, 11.5, 16], "texture": "#0"} + } + }, + { + "name": "Toggle_Right_Arm_Armor", + "from": [10.75, 6.25, 3.8], + "to": [13.25, 9.75, 13.3], + "rotation": {"angle": 22.5, "axis": "y", "origin": [12, 8, 11.5]}, + "faces": { + "north": {"uv": [11.75, 8, 12.5, 9], "rotation": 180, "texture": "#0"}, + "east": {"uv": [10, 9, 11, 12], "rotation": 270, "texture": "#0"}, + "south": {"uv": [11, 8, 11.75, 9], "texture": "#0"}, + "west": {"uv": [11.75, 9, 12.75, 12], "rotation": 90, "texture": "#0"}, + "up": {"uv": [11, 9, 11.75, 12], "rotation": 180, "texture": "#0"}, + "down": {"uv": [12.75, 9, 13.5, 12], "texture": "#0"} + } + }, + { + "name": "Right_arm", + "from": [11, 6.5, 3.8], + "to": [13.5, 9.5, 12.8], + "rotation": {"angle": 22.5, "axis": "y", "origin": [12, 8, 11.5]}, + "faces": { + "north": {"uv": [12.5, 4, 11.75, 5], "rotation": 180, "texture": "#0"}, + "east": {"uv": [10, 5, 11, 8], "rotation": 270, "texture": "#0"}, + "south": {"uv": [11.75, 5, 11, 4], "texture": "#0"}, + "west": {"uv": [11.75, 5, 12.5, 8], "rotation": 90, "texture": "#0"}, + "up": {"uv": [11, 5, 11.75, 8], "rotation": 180, "texture": "#0"}, + "down": {"uv": [12.5, 5, 13.5, 8], "texture": "#0"} + } + }, + { + "name": "Toggle_Left_Leg_Armor", + "from": [5.2, -0.25, 3.05], + "to": [8.7, 3.25, 12.55], + "rotation": {"angle": 22.5, "axis": "y", "origin": [5.7, 2, 13]}, + "faces": { + "north": {"uv": [2, 12, 3, 13], "rotation": 180, "texture": "#0"}, + "east": {"uv": [0, 13, 1, 16], "rotation": 270, "texture": "#0"}, + "south": {"uv": [1, 12, 2, 13], "texture": "#0"}, + "west": {"uv": [2, 13, 3, 16], "rotation": 90, "texture": "#0"}, + "up": {"uv": [1, 13, 2, 16], "rotation": 180, "texture": "#0"}, + "down": {"uv": [3, 13, 4, 16], "texture": "#0"} + } + }, + { + "name": "Left_leg", + "from": [5.5, 0, 3.3], + "to": [8.5, 3, 12.3], + "rotation": {"angle": 22.5, "axis": "y", "origin": [6, 2, 13]}, + "faces": { + "north": {"uv": [7, 12, 6, 13], "rotation": 180, "texture": "#0"}, + "east": {"uv": [4, 13, 5, 16], "rotation": 270, "texture": "#0"}, + "south": {"uv": [5.95, 13, 5, 11.925], "texture": "#0"}, + "west": {"uv": [6, 13, 7, 16], "rotation": 90, "texture": "#0"}, + "up": {"uv": [5, 13, 6, 16], "rotation": 180, "texture": "#0"}, + "down": {"uv": [7, 13, 8, 16], "texture": "#0"} + } + }, + { + "name": "Toggle_Right_Leg_Armor", + "from": [7.2, -0.25, 3.05], + "to": [10.7, 3.25, 12.55], + "rotation": {"angle": -22.5, "axis": "y", "origin": [8.7, 2, 13]}, + "faces": { + "north": {"uv": [2, 8, 3, 9], "rotation": 180, "texture": "#0"}, + "east": {"uv": [0, 9, 1, 12], "rotation": 270, "texture": "#0"}, + "south": {"uv": [1, 8, 2, 9], "texture": "#0"}, + "west": {"uv": [2, 9, 3, 12], "rotation": 90, "texture": "#0"}, + "up": {"uv": [1, 9, 2, 12], "rotation": 180, "texture": "#0"}, + "down": {"uv": [3, 9, 4, 12], "texture": "#0"} + } + }, + { + "name": "Right_leg", + "from": [7.5, 0, 3.3], + "to": [10.5, 3, 12.3], + "rotation": {"angle": -22.5, "axis": "y", "origin": [9, 2, 13]}, + "faces": { + "north": {"uv": [3, 4, 2, 5], "rotation": 180, "texture": "#0"}, + "east": {"uv": [0, 5, 1, 8], "rotation": 270, "texture": "#0"}, + "south": {"uv": [2, 5, 1, 4], "texture": "#0"}, + "west": {"uv": [2, 5, 3, 8], "rotation": 90, "texture": "#0"}, + "up": {"uv": [1, 5, 2, 8], "rotation": 180, "texture": "#0"}, + "down": {"uv": [3, 5, 4, 8], "texture": "#0"} + } + }, + { + "from": [7, 6, 1], + "to": [7, 14, 9], + "rotation": {"angle": 45, "axis": "y", "origin": [7, 10, 3.5]}, + "faces": { + "east": {"uv": [0, 0, 16, 16], "texture": "#1"}, + "west": {"uv": [0, 0, 16, 16], "texture": "#1"} + } + }, + { + "from": [9, 6, 1], + "to": [9, 14, 9], + "rotation": {"angle": -45, "axis": "y", "origin": [9, 10, 3.5]}, + "faces": { + "east": {"uv": [0, 0, 16, 16], "texture": "#1"}, + "west": {"uv": [0, 0, 16, 16], "texture": "#1"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "thirdperson_lefthand": { + "rotation": [75, 45, 0], + "translation": [0, 2.5, 0], + "scale": [0.375, 0.375, 0.375] + }, + "firstperson_righthand": { + "rotation": [0, 124, 0], + "translation": [2, 3, 0], + "scale": [0.4, 0.4, 0.4] + }, + "firstperson_lefthand": { + "rotation": [0, 120, 0], + "translation": [1.5, 2.75, 0], + "scale": [0.4, 0.4, 0.4] + }, + "ground": { + "translation": [0, 2, 0], + "scale": [0.5, 0.5, 0.5] + }, + "gui": { + "rotation": [30, -135, 0], + "translation": [0.75, -1, 0], + "scale": [0.625, 0.625, 0.625] + }, + "head": { + "translation": [0, 14, -0.75] + }, + "fixed": { + "translation": [0, 0, -2.75], + "scale": [0.5, 0.5, 0.5] + }, + "on_shelf": { + "rotation": [0, -180, 0], + "translation": [0, 0, 5.25] + } + }, + "groups": [ + { + "name": "Player", + "origin": [3, -6.7, 6], + "color": 0, + "children": [ + { + "name": "Head", + "origin": [8, 16, 8], + "color": 0, + "children": [0, 1] + }, + { + "name": "Body", + "origin": [8, 11, 8], + "color": 0, + "children": [2, 3] + }, + { + "name": "Left_Arm", + "origin": [5, 15, 6], + "color": 0, + "children": [4, 5] + }, + { + "name": "Right_Arm", + "origin": [11, 15, 6], + "color": 0, + "children": [6, 7] + }, + { + "name": "Left_Leg", + "origin": [7, 13, 7], + "color": 0, + "children": [8, 9] + }, + { + "name": "Right_Leg", + "origin": [10, 13, 7], + "color": 0, + "children": [10, 11] + } + ] + }, + { + "name": "item", + "origin": [0, 4, 2.5], + "color": 0, + "children": [12, 13] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/superleadrope/textures/block/custom/author.png b/src/main/resources/assets/superleadrope/textures/block/custom/author.png new file mode 100644 index 0000000..7e8e949 Binary files /dev/null and b/src/main/resources/assets/superleadrope/textures/block/custom/author.png differ diff --git a/src/main/resources/assets/superleadrope/textures/mob_effect/no_super_leash.png b/src/main/resources/assets/superleadrope/textures/mob_effect/no_super_leash.png new file mode 100644 index 0000000..01e752a Binary files /dev/null and b/src/main/resources/assets/superleadrope/textures/mob_effect/no_super_leash.png differ