From 1a4278539bb334bca17277aa31fdb340e456f3c5 Mon Sep 17 00:00:00 2001 From: Magistu <77356543+Magistu@users.noreply.github.com> Date: Thu, 17 Nov 2022 00:46:50 +0300 Subject: [PATCH] init --- .gitattributes | 5 + .gitignore | 25 + CREDITS.txt | 65 + LICENSE.txt | 520 ++++ README.txt | 46 + build.gradle | 206 ++ changelog.txt | 2442 +++++++++++++++++ gradle.properties | 6 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59203 bytes gradle/wrapper/gradle-wrapper.properties | 5 + gradlew | 185 ++ gradlew.bat | 89 + .../java/magistu/plugins/jei/JeiSupport.java | 51 + .../jei/SiegeWorkbenchRecipeCategory.java | 96 + .../magistu/siegemachines/SiegeMachines.java | 123 + .../siegemachines/block/ModBlocks.java | 39 + .../siegemachines/block/SiegeWorkbench.java | 50 + .../block/StacksCraftingInventory.java | 12 + .../siegemachines/client/ClientListener.java | 27 + .../siegemachines/client/ClientProxy.java | 37 + .../siegemachines/client/KeyBindings.java | 17 + .../siegemachines/client/SoundTypes.java | 44 + .../client/renderer/BallistaGeoRenderer.java | 55 + .../renderer/BallistaItemGeoRenderer.java | 11 + .../renderer/BatteringRamGeoRenderer.java | 32 + .../renderer/BatteringRamItemGeoRenderer.java | 11 + .../client/renderer/CatapultGeoRenderer.java | 26 + .../renderer/CatapultItemGeoRenderer.java | 11 + .../client/renderer/CulverinGeoRenderer.java | 32 + .../renderer/CulverinItemGeoRenderer.java | 11 + .../client/renderer/GiantArrowRenderer.java | 54 + .../client/renderer/MachineGeoRenderer.java | 21 + .../renderer/MachineItemGeoRenderer.java | 26 + .../client/renderer/MortarGeoRenderer.java | 44 + .../renderer/MortarItemGeoRenderer.java | 12 + .../client/renderer/TrebuchetGeoRenderer.java | 47 + .../renderer/TrebuchetItemGeoRenderer.java | 12 + .../renderer/model/GiantArrowModel.java | 58 + .../renderer/model/MachineItemModel.java | 42 + .../client/renderer/model/MachineModel.java | 42 + .../siegemachines/config/MissileSpecs.java | 21 + .../config/SiegeMachineSpecs.java | 27 + .../siegemachines/config/SpecsConfig.java | 52 + .../data/recipes/ISiegeWorkbenchRecipe.java | 32 + .../data/recipes/ModRecipes.java | 25 + .../data/recipes/SiegeWorkbenchRecipe.java | 580 ++++ .../siegemachines/entity/Breakdown.java | 326 +++ .../siegemachines/entity/EntityTypes.java | 54 + .../siegemachines/entity/IReloading.java | 11 + .../entity/machine/Ballista.java | 190 ++ .../entity/machine/BatteringRam.java | 254 ++ .../entity/machine/Catapult.java | 207 ++ .../entity/machine/Culverin.java | 260 ++ .../siegemachines/entity/machine/Machine.java | 862 ++++++ .../entity/machine/MachinePartEntity.java | 54 + .../entity/machine/MachineType.java | 96 + .../siegemachines/entity/machine/Mortar.java | 277 ++ .../entity/machine/ShootingMachine.java | 195 ++ .../entity/machine/Trebuchet.java | 256 ++ .../entity/projectile/Cannonball.java | 22 + .../entity/projectile/FlightType.java | 8 + .../entity/projectile/GiantArrow.java | 41 + .../entity/projectile/GiantStone.java | 22 + .../entity/projectile/IProjectileFactory.java | 13 + .../entity/projectile/Missile.java | 188 ++ .../entity/projectile/MissileType.java | 27 + .../entity/projectile/ProjectileBuilder.java | 51 + .../entity/projectile/Stone.java | 22 + .../siegemachines/event/ClientEvents.java | 82 + .../event/ModEventBusEvents.java | 23 + .../siegemachines/gui/AlignmentHelper.java | 33 + .../siegemachines/gui/ContainerTypes.java | 22 + .../magistu/siegemachines/gui/Crosshair.java | 26 + .../magistu/siegemachines/gui/HudElement.java | 73 + .../siegemachines/gui/MachineContainer.java | 137 + .../gui/MachineInventoryScreen.java | 81 + .../siegemachines/gui/ReloadingCrosshair.java | 67 + .../gui/SiegeWorkbenchContainer.java | 615 +++++ .../gui/SiegeWorkbenchScreen.java | 75 + .../siegemachines/item/MachineItem.java | 272 ++ .../magistu/siegemachines/item/ModItems.java | 59 + .../siegemachines/network/PacketHandler.java | 66 + .../siegemachines/network/PacketMachine.java | 81 + .../network/PacketMachineControl.java | 54 + .../network/PacketMachineInventorySlot.java | 83 + .../network/PacketMachineUse.java | 75 + .../network/PacketMachineUseRealise.java | 75 + .../network/PacketOpenMachineInventory.java | 54 + .../magistu/siegemachines/proxy/IProxy.java | 13 + .../siegemachines/server/ServerProxy.java | 14 + src/main/resources/META-INF/mods.toml | 16 + .../animations/ballista.animation.json | 195 ++ .../animations/battering_ram.animation.json | 443 +++ .../animations/catapult.animation.json | 119 + .../animations/mortar.animation.json | 38 + .../animations/none.animation.json | 5 + .../animations/trebuchet.animation.json | 210 ++ .../blockstates/siege_workbench.json | 5 + .../siegemachines/geo/ballista.geo.json | 139 + .../siegemachines/geo/ballista_item.geo.json | 139 + .../siegemachines/geo/battering_ram.geo.json | 294 ++ .../geo/battering_ram_item.geo.json | 294 ++ .../siegemachines/geo/catapult.geo.json | 116 + .../siegemachines/geo/catapult_item.geo.json | 116 + .../assets/siegemachines/geo/mortar.geo.json | 102 + .../siegemachines/geo/mortar_item.geo.json | 102 + .../siegemachines/geo/trebuchet.geo.json | 130 + .../siegemachines/geo/trebuchet_item.geo.json | 130 + .../assets/siegemachines/lang/en_us.json | 38 + .../assets/siegemachines/lang/ru_ru.json | 36 + .../models/block/crafting_table.json | 12 + .../models/block/siege_workbench.json | 12 + .../siegemachines/models/item/ballista.json | 75 + .../siegemachines/models/item/barrel.json | 6 + .../models/item/battering_ram.json | 79 + .../siegemachines/models/item/beam.json | 6 + .../siegemachines/models/item/cannonball.json | 39 + .../siegemachines/models/item/catapult.json | 75 + .../models/item/counterweight.json | 6 + .../siegemachines/models/item/culverine.json | 6 + .../models/item/giant_arrow.json | 103 + .../models/item/giant_stone.json | 48 + .../siegemachines/models/item/mortar.json | 75 + .../models/item/siege_workbench.json | 3 + .../siegemachines/models/item/stone.json | 53 + .../siegemachines/models/item/trebuchet.json | 75 + .../models/item/turret_base.json | 6 + .../siegemachines/models/item/wheel.json | 6 + .../assets/siegemachines/sounds.json | 197 ++ .../sounds/ballista_reloading_0.ogg | Bin 0 -> 37152 bytes .../sounds/ballista_reloading_1.ogg | Bin 0 -> 36399 bytes .../sounds/ballista_reloading_2.ogg | Bin 0 -> 35466 bytes .../sounds/ballista_reloading_3.ogg | Bin 0 -> 36415 bytes .../sounds/ballista_shooting_0.ogg | Bin 0 -> 41093 bytes .../sounds/ballista_shooting_1.ogg | Bin 0 -> 43546 bytes .../sounds/ballista_shooting_2.ogg | Bin 0 -> 44007 bytes .../sounds/ballista_shooting_3.ogg | Bin 0 -> 40619 bytes .../sounds/ballista_shooting_4.ogg | Bin 0 -> 40441 bytes .../siegemachines/sounds/cannon_wheels_0.ogg | Bin 0 -> 18985 bytes .../siegemachines/sounds/cannon_wheels_1.ogg | Bin 0 -> 19640 bytes .../siegemachines/sounds/cannon_wheels_2.ogg | Bin 0 -> 18820 bytes .../siegemachines/sounds/cannon_wheels_3.ogg | Bin 0 -> 18576 bytes .../sounds/catapult_reloading_0.ogg | Bin 0 -> 36232 bytes .../sounds/catapult_reloading_1.ogg | Bin 0 -> 31812 bytes .../sounds/catapult_reloading_2.ogg | Bin 0 -> 29304 bytes .../sounds/catapult_reloading_3.ogg | Bin 0 -> 32132 bytes .../sounds/catapult_reloading_4.ogg | Bin 0 -> 32642 bytes .../sounds/catapult_reloading_5.ogg | Bin 0 -> 31733 bytes .../sounds/catapult_shooting_0.ogg | Bin 0 -> 34971 bytes .../sounds/catapult_shooting_1.ogg | Bin 0 -> 28554 bytes .../assets/siegemachines/sounds/fuse.ogg | Bin 0 -> 20278 bytes .../siegemachines/sounds/mortar_shooting.ogg | Bin 0 -> 9779 bytes .../siegemachines/sounds/ram_hitting.ogg | Bin 0 -> 52622 bytes .../siegemachines/sounds/ram_wheels_0.ogg | Bin 0 -> 18985 bytes .../siegemachines/sounds/ram_wheels_1.ogg | Bin 0 -> 19640 bytes .../siegemachines/sounds/ram_wheels_2.ogg | Bin 0 -> 18820 bytes .../siegemachines/sounds/ram_wheels_3.ogg | Bin 0 -> 18576 bytes .../sounds/trebuchet_reloading_1.ogg | Bin 0 -> 48288 bytes .../sounds/trebuchet_reloading_2.ogg | Bin 0 -> 40056 bytes .../sounds/trebuchet_reloading_3.ogg | Bin 0 -> 41719 bytes .../sounds/trebuchet_reloading_4.ogg | Bin 0 -> 48696 bytes .../sounds/trebuchet_reloading_5.ogg | Bin 0 -> 50821 bytes .../sounds/trebuchet_reloading_6.ogg | Bin 0 -> 55252 bytes .../sounds/trebuchet_shooting.ogg | Bin 0 -> 243725 bytes .../textures/block/siege_workbench_bottom.png | Bin 0 -> 291 bytes .../textures/block/siege_workbench_front.png | Bin 0 -> 511 bytes .../textures/block/siege_workbench_side.png | Bin 0 -> 511 bytes .../textures/block/siege_workbench_top.png | Bin 0 -> 579 bytes .../textures/entity/ballista.png | Bin 0 -> 4681 bytes .../textures/entity/battering_ram.png | Bin 0 -> 30426 bytes .../textures/entity/cannonball.png | Bin 0 -> 202 bytes .../textures/entity/catapult.png | Bin 0 -> 12864 bytes .../textures/entity/giant_arrow.png | Bin 0 -> 464 bytes .../siegemachines/textures/entity/mortar.png | Bin 0 -> 7679 bytes .../siegemachines/textures/entity/stone.png | Bin 0 -> 265 bytes .../textures/entity/trebuchet.png | Bin 0 -> 114781 bytes .../siegemachines/textures/gui/crosshairs.png | Bin 0 -> 1287 bytes .../textures/gui/machine_inventory_1.png | Bin 0 -> 1072 bytes .../textures/gui/machine_inventory_2.png | Bin 0 -> 1093 bytes .../textures/gui/machine_inventory_3.png | Bin 0 -> 1057 bytes .../textures/gui/siege_workbench.png | Bin 0 -> 1143 bytes .../siegemachines/textures/item/barrel.png | Bin 0 -> 324 bytes .../siegemachines/textures/item/beam.png | Bin 0 -> 306 bytes .../textures/item/counterweight.png | Bin 0 -> 508 bytes .../textures/item/turret_base.png | Bin 0 -> 346 bytes .../siegemachines/textures/item/wheel.png | Bin 0 -> 461 bytes .../minecraft/tags/entity_types/arrows.json | 6 + .../data/siegemachines/recipes/ballista.json | 42 + .../data/siegemachines/recipes/barrel.json | 26 + .../siegemachines/recipes/battering_ram.json | 42 + .../data/siegemachines/recipes/beam.json | 16 + .../siegemachines/recipes/cannonball.json | 16 + .../data/siegemachines/recipes/catapult.json | 42 + .../siegemachines/recipes/counterweight.json | 25 + .../siegemachines/recipes/giant_arrow.json | 26 + .../data/siegemachines/recipes/mortar.json | 42 + .../recipes/siege_workbench.json | 26 + .../data/siegemachines/recipes/trebuchet.json | 46 + .../siegemachines/recipes/turret_base.json | 20 + .../data/siegemachines/recipes/wheel.json | 22 + src/main/resources/pack.mcmeta | 7 + 201 files changed, 14843 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 CREDITS.txt create mode 100644 LICENSE.txt create mode 100644 README.txt create mode 100644 build.gradle create mode 100644 changelog.txt create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 src/main/java/magistu/plugins/jei/JeiSupport.java create mode 100644 src/main/java/magistu/plugins/jei/SiegeWorkbenchRecipeCategory.java create mode 100644 src/main/java/magistu/siegemachines/SiegeMachines.java create mode 100644 src/main/java/magistu/siegemachines/block/ModBlocks.java create mode 100644 src/main/java/magistu/siegemachines/block/SiegeWorkbench.java create mode 100644 src/main/java/magistu/siegemachines/block/StacksCraftingInventory.java create mode 100644 src/main/java/magistu/siegemachines/client/ClientListener.java create mode 100644 src/main/java/magistu/siegemachines/client/ClientProxy.java create mode 100644 src/main/java/magistu/siegemachines/client/KeyBindings.java create mode 100644 src/main/java/magistu/siegemachines/client/SoundTypes.java create mode 100644 src/main/java/magistu/siegemachines/client/renderer/BallistaGeoRenderer.java create mode 100644 src/main/java/magistu/siegemachines/client/renderer/BallistaItemGeoRenderer.java create mode 100644 src/main/java/magistu/siegemachines/client/renderer/BatteringRamGeoRenderer.java create mode 100644 src/main/java/magistu/siegemachines/client/renderer/BatteringRamItemGeoRenderer.java create mode 100644 src/main/java/magistu/siegemachines/client/renderer/CatapultGeoRenderer.java create mode 100644 src/main/java/magistu/siegemachines/client/renderer/CatapultItemGeoRenderer.java create mode 100644 src/main/java/magistu/siegemachines/client/renderer/CulverinGeoRenderer.java create mode 100644 src/main/java/magistu/siegemachines/client/renderer/CulverinItemGeoRenderer.java create mode 100644 src/main/java/magistu/siegemachines/client/renderer/GiantArrowRenderer.java create mode 100644 src/main/java/magistu/siegemachines/client/renderer/MachineGeoRenderer.java create mode 100644 src/main/java/magistu/siegemachines/client/renderer/MachineItemGeoRenderer.java create mode 100644 src/main/java/magistu/siegemachines/client/renderer/MortarGeoRenderer.java create mode 100644 src/main/java/magistu/siegemachines/client/renderer/MortarItemGeoRenderer.java create mode 100644 src/main/java/magistu/siegemachines/client/renderer/TrebuchetGeoRenderer.java create mode 100644 src/main/java/magistu/siegemachines/client/renderer/TrebuchetItemGeoRenderer.java create mode 100644 src/main/java/magistu/siegemachines/client/renderer/model/GiantArrowModel.java create mode 100644 src/main/java/magistu/siegemachines/client/renderer/model/MachineItemModel.java create mode 100644 src/main/java/magistu/siegemachines/client/renderer/model/MachineModel.java create mode 100644 src/main/java/magistu/siegemachines/config/MissileSpecs.java create mode 100644 src/main/java/magistu/siegemachines/config/SiegeMachineSpecs.java create mode 100644 src/main/java/magistu/siegemachines/config/SpecsConfig.java create mode 100644 src/main/java/magistu/siegemachines/data/recipes/ISiegeWorkbenchRecipe.java create mode 100644 src/main/java/magistu/siegemachines/data/recipes/ModRecipes.java create mode 100644 src/main/java/magistu/siegemachines/data/recipes/SiegeWorkbenchRecipe.java create mode 100644 src/main/java/magistu/siegemachines/entity/Breakdown.java create mode 100644 src/main/java/magistu/siegemachines/entity/EntityTypes.java create mode 100644 src/main/java/magistu/siegemachines/entity/IReloading.java create mode 100644 src/main/java/magistu/siegemachines/entity/machine/Ballista.java create mode 100644 src/main/java/magistu/siegemachines/entity/machine/BatteringRam.java create mode 100644 src/main/java/magistu/siegemachines/entity/machine/Catapult.java create mode 100644 src/main/java/magistu/siegemachines/entity/machine/Culverin.java create mode 100644 src/main/java/magistu/siegemachines/entity/machine/Machine.java create mode 100644 src/main/java/magistu/siegemachines/entity/machine/MachinePartEntity.java create mode 100644 src/main/java/magistu/siegemachines/entity/machine/MachineType.java create mode 100644 src/main/java/magistu/siegemachines/entity/machine/Mortar.java create mode 100644 src/main/java/magistu/siegemachines/entity/machine/ShootingMachine.java create mode 100644 src/main/java/magistu/siegemachines/entity/machine/Trebuchet.java create mode 100644 src/main/java/magistu/siegemachines/entity/projectile/Cannonball.java create mode 100644 src/main/java/magistu/siegemachines/entity/projectile/FlightType.java create mode 100644 src/main/java/magistu/siegemachines/entity/projectile/GiantArrow.java create mode 100644 src/main/java/magistu/siegemachines/entity/projectile/GiantStone.java create mode 100644 src/main/java/magistu/siegemachines/entity/projectile/IProjectileFactory.java create mode 100644 src/main/java/magistu/siegemachines/entity/projectile/Missile.java create mode 100644 src/main/java/magistu/siegemachines/entity/projectile/MissileType.java create mode 100644 src/main/java/magistu/siegemachines/entity/projectile/ProjectileBuilder.java create mode 100644 src/main/java/magistu/siegemachines/entity/projectile/Stone.java create mode 100644 src/main/java/magistu/siegemachines/event/ClientEvents.java create mode 100644 src/main/java/magistu/siegemachines/event/ModEventBusEvents.java create mode 100644 src/main/java/magistu/siegemachines/gui/AlignmentHelper.java create mode 100644 src/main/java/magistu/siegemachines/gui/ContainerTypes.java create mode 100644 src/main/java/magistu/siegemachines/gui/Crosshair.java create mode 100644 src/main/java/magistu/siegemachines/gui/HudElement.java create mode 100644 src/main/java/magistu/siegemachines/gui/MachineContainer.java create mode 100644 src/main/java/magistu/siegemachines/gui/MachineInventoryScreen.java create mode 100644 src/main/java/magistu/siegemachines/gui/ReloadingCrosshair.java create mode 100644 src/main/java/magistu/siegemachines/gui/SiegeWorkbenchContainer.java create mode 100644 src/main/java/magistu/siegemachines/gui/SiegeWorkbenchScreen.java create mode 100644 src/main/java/magistu/siegemachines/item/MachineItem.java create mode 100644 src/main/java/magistu/siegemachines/item/ModItems.java create mode 100644 src/main/java/magistu/siegemachines/network/PacketHandler.java create mode 100644 src/main/java/magistu/siegemachines/network/PacketMachine.java create mode 100644 src/main/java/magistu/siegemachines/network/PacketMachineControl.java create mode 100644 src/main/java/magistu/siegemachines/network/PacketMachineInventorySlot.java create mode 100644 src/main/java/magistu/siegemachines/network/PacketMachineUse.java create mode 100644 src/main/java/magistu/siegemachines/network/PacketMachineUseRealise.java create mode 100644 src/main/java/magistu/siegemachines/network/PacketOpenMachineInventory.java create mode 100644 src/main/java/magistu/siegemachines/proxy/IProxy.java create mode 100644 src/main/java/magistu/siegemachines/server/ServerProxy.java create mode 100644 src/main/resources/META-INF/mods.toml create mode 100644 src/main/resources/assets/siegemachines/animations/ballista.animation.json create mode 100644 src/main/resources/assets/siegemachines/animations/battering_ram.animation.json create mode 100644 src/main/resources/assets/siegemachines/animations/catapult.animation.json create mode 100644 src/main/resources/assets/siegemachines/animations/mortar.animation.json create mode 100644 src/main/resources/assets/siegemachines/animations/none.animation.json create mode 100644 src/main/resources/assets/siegemachines/animations/trebuchet.animation.json create mode 100644 src/main/resources/assets/siegemachines/blockstates/siege_workbench.json create mode 100644 src/main/resources/assets/siegemachines/geo/ballista.geo.json create mode 100644 src/main/resources/assets/siegemachines/geo/ballista_item.geo.json create mode 100644 src/main/resources/assets/siegemachines/geo/battering_ram.geo.json create mode 100644 src/main/resources/assets/siegemachines/geo/battering_ram_item.geo.json create mode 100644 src/main/resources/assets/siegemachines/geo/catapult.geo.json create mode 100644 src/main/resources/assets/siegemachines/geo/catapult_item.geo.json create mode 100644 src/main/resources/assets/siegemachines/geo/mortar.geo.json create mode 100644 src/main/resources/assets/siegemachines/geo/mortar_item.geo.json create mode 100644 src/main/resources/assets/siegemachines/geo/trebuchet.geo.json create mode 100644 src/main/resources/assets/siegemachines/geo/trebuchet_item.geo.json create mode 100644 src/main/resources/assets/siegemachines/lang/en_us.json create mode 100644 src/main/resources/assets/siegemachines/lang/ru_ru.json create mode 100644 src/main/resources/assets/siegemachines/models/block/crafting_table.json create mode 100644 src/main/resources/assets/siegemachines/models/block/siege_workbench.json create mode 100644 src/main/resources/assets/siegemachines/models/item/ballista.json create mode 100644 src/main/resources/assets/siegemachines/models/item/barrel.json create mode 100644 src/main/resources/assets/siegemachines/models/item/battering_ram.json create mode 100644 src/main/resources/assets/siegemachines/models/item/beam.json create mode 100644 src/main/resources/assets/siegemachines/models/item/cannonball.json create mode 100644 src/main/resources/assets/siegemachines/models/item/catapult.json create mode 100644 src/main/resources/assets/siegemachines/models/item/counterweight.json create mode 100644 src/main/resources/assets/siegemachines/models/item/culverine.json create mode 100644 src/main/resources/assets/siegemachines/models/item/giant_arrow.json create mode 100644 src/main/resources/assets/siegemachines/models/item/giant_stone.json create mode 100644 src/main/resources/assets/siegemachines/models/item/mortar.json create mode 100644 src/main/resources/assets/siegemachines/models/item/siege_workbench.json create mode 100644 src/main/resources/assets/siegemachines/models/item/stone.json create mode 100644 src/main/resources/assets/siegemachines/models/item/trebuchet.json create mode 100644 src/main/resources/assets/siegemachines/models/item/turret_base.json create mode 100644 src/main/resources/assets/siegemachines/models/item/wheel.json create mode 100644 src/main/resources/assets/siegemachines/sounds.json create mode 100644 src/main/resources/assets/siegemachines/sounds/ballista_reloading_0.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/ballista_reloading_1.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/ballista_reloading_2.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/ballista_reloading_3.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/ballista_shooting_0.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/ballista_shooting_1.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/ballista_shooting_2.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/ballista_shooting_3.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/ballista_shooting_4.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/cannon_wheels_0.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/cannon_wheels_1.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/cannon_wheels_2.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/cannon_wheels_3.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/catapult_reloading_0.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/catapult_reloading_1.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/catapult_reloading_2.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/catapult_reloading_3.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/catapult_reloading_4.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/catapult_reloading_5.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/catapult_shooting_0.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/catapult_shooting_1.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/fuse.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/mortar_shooting.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/ram_hitting.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/ram_wheels_0.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/ram_wheels_1.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/ram_wheels_2.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/ram_wheels_3.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/trebuchet_reloading_1.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/trebuchet_reloading_2.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/trebuchet_reloading_3.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/trebuchet_reloading_4.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/trebuchet_reloading_5.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/trebuchet_reloading_6.ogg create mode 100644 src/main/resources/assets/siegemachines/sounds/trebuchet_shooting.ogg create mode 100644 src/main/resources/assets/siegemachines/textures/block/siege_workbench_bottom.png create mode 100644 src/main/resources/assets/siegemachines/textures/block/siege_workbench_front.png create mode 100644 src/main/resources/assets/siegemachines/textures/block/siege_workbench_side.png create mode 100644 src/main/resources/assets/siegemachines/textures/block/siege_workbench_top.png create mode 100644 src/main/resources/assets/siegemachines/textures/entity/ballista.png create mode 100644 src/main/resources/assets/siegemachines/textures/entity/battering_ram.png create mode 100644 src/main/resources/assets/siegemachines/textures/entity/cannonball.png create mode 100644 src/main/resources/assets/siegemachines/textures/entity/catapult.png create mode 100644 src/main/resources/assets/siegemachines/textures/entity/giant_arrow.png create mode 100644 src/main/resources/assets/siegemachines/textures/entity/mortar.png create mode 100644 src/main/resources/assets/siegemachines/textures/entity/stone.png create mode 100644 src/main/resources/assets/siegemachines/textures/entity/trebuchet.png create mode 100644 src/main/resources/assets/siegemachines/textures/gui/crosshairs.png create mode 100644 src/main/resources/assets/siegemachines/textures/gui/machine_inventory_1.png create mode 100644 src/main/resources/assets/siegemachines/textures/gui/machine_inventory_2.png create mode 100644 src/main/resources/assets/siegemachines/textures/gui/machine_inventory_3.png create mode 100644 src/main/resources/assets/siegemachines/textures/gui/siege_workbench.png create mode 100644 src/main/resources/assets/siegemachines/textures/item/barrel.png create mode 100644 src/main/resources/assets/siegemachines/textures/item/beam.png create mode 100644 src/main/resources/assets/siegemachines/textures/item/counterweight.png create mode 100644 src/main/resources/assets/siegemachines/textures/item/turret_base.png create mode 100644 src/main/resources/assets/siegemachines/textures/item/wheel.png create mode 100644 src/main/resources/data/minecraft/tags/entity_types/arrows.json create mode 100644 src/main/resources/data/siegemachines/recipes/ballista.json create mode 100644 src/main/resources/data/siegemachines/recipes/barrel.json create mode 100644 src/main/resources/data/siegemachines/recipes/battering_ram.json create mode 100644 src/main/resources/data/siegemachines/recipes/beam.json create mode 100644 src/main/resources/data/siegemachines/recipes/cannonball.json create mode 100644 src/main/resources/data/siegemachines/recipes/catapult.json create mode 100644 src/main/resources/data/siegemachines/recipes/counterweight.json create mode 100644 src/main/resources/data/siegemachines/recipes/giant_arrow.json create mode 100644 src/main/resources/data/siegemachines/recipes/mortar.json create mode 100644 src/main/resources/data/siegemachines/recipes/siege_workbench.json create mode 100644 src/main/resources/data/siegemachines/recipes/trebuchet.json create mode 100644 src/main/resources/data/siegemachines/recipes/turret_base.json create mode 100644 src/main/resources/data/siegemachines/recipes/wheel.json create mode 100644 src/main/resources/pack.mcmeta diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..f811f6a --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +# Disable autocrlf on generated files, they always generate with LF +# Add any extra files or paths here to make git stop saying they +# are changed when only line endings change. +src/generated/**/.cache/cache text eol=lf +src/generated/**/*.json text eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..12f8644 --- /dev/null +++ b/.gitignore @@ -0,0 +1,25 @@ +# eclipse +bin +*.launch +.settings +.metadata +.classpath +.project + +# idea +out +*.ipr +*.iws +*.iml +.idea + +# gradle +build +.gradle + +# other +eclipse +run + +# Files from Forge MDK +forge*changelog.txt diff --git a/CREDITS.txt b/CREDITS.txt new file mode 100644 index 0000000..a70c53d --- /dev/null +++ b/CREDITS.txt @@ -0,0 +1,65 @@ +Minecraft Forge: Credits/Thank You + +Forge is a set of tools and modifications to the Minecraft base game code to assist +mod developers in creating new and exciting content. It has been in development for +several years now, but I would like to take this time thank a few people who have +helped it along it's way. + +First, the people who originally created the Forge projects way back in Minecraft +alpha. Eloraam of RedPower, and SpaceToad of Buildcraft, without their acceptiance +of me taking over the project, who knows what Minecraft modding would be today. + +Secondly, someone who has worked with me, and developed some of the core features +that allow modding to be as functional, and as simple as it is, cpw. For developing +FML, which stabelized the client and server modding ecosystem. As well as the base +loading system that allows us to modify Minecraft's code as elegently as possible. + +Mezz, who has stepped up as the issue and pull request manager. Helping to keep me +sane as well as guiding the community into creating better additions to Forge. + +Searge, Bspks, Fesh0r, ProfMobious, and all the rest over on the MCP team {of which +I am a part}. For creating some of the core tools needed to make Minecraft modding +both possible, and as stable as can be. + On that note, here is some specific information of the MCP data we use: + * Minecraft Coder Pack (MCP) * + Forge Mod Loader and Minecraft Forge have permission to distribute and automatically + download components of MCP and distribute MCP data files. This permission is not + transitive and others wishing to redistribute the Minecraft Forge source independently + should seek permission of MCP or remove the MCP data files and request their users + to download MCP separately. + +And lastly, the countless community members who have spent time submitting bug reports, +pull requests, and just helping out the community in general. Thank you. + +--LexManos + +========================================================================= + +This is Forge Mod Loader. + +You can find the source code at all times at https://github.com/MinecraftForge/MinecraftForge/tree/1.12.x/src/main/java/net/minecraftforge/fml + +This minecraft mod is a clean open source implementation of a mod loader for minecraft servers +and minecraft clients. + +The code is authored by cpw. + +It began by partially implementing an API defined by the client side ModLoader, authored by Risugami. +http://www.minecraftforum.net/topic/75440- +This support has been dropped as of Minecraft release 1.7, as Risugami no longer maintains ModLoader. + +It also contains suggestions and hints and generous helpings of code from LexManos, author of MinecraftForge. +http://www.minecraftforge.net/ + +Additionally, it contains an implementation of topological sort based on that +published at http://keithschwarz.com/interesting/code/?dir=topological-sort + +It also contains code from the Maven project for performing versioned dependency +resolution. http://maven.apache.org/ + +It also contains a partial repackaging of the javaxdelta library from http://sourceforge.net/projects/javaxdelta/ +with credit to it's authors. + +Forge Mod Loader downloads components from the Minecraft Coder Pack +(http://mcp.ocean-labs.de/index.php/Main_Page) with kind permission from the MCP team. + diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..b0cbe2b --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,520 @@ +Unless noted below, Minecraft Forge, Forge Mod Loader, and all +parts herein are licensed under the terms of the LGPL 2.1 found +here http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt and +copied below. + +Homepage: http://minecraftforge.net/ + https://github.com/MinecraftForge/MinecraftForge + + +A note on authorship: +All source artifacts are property of their original author, with +the exclusion of the contents of the patches directory and others +copied from it from time to time. Authorship of the contents of +the patches directory is retained by the Minecraft Forge project. +This is because the patches are partially machine generated +artifacts, and are changed heavily due to the way forge works. +Individual attribution within them is impossible. + +Consent: +All contributions to Forge must consent to the release of any +patch content to the Forge project. + +A note on infectivity: +The LGPL is chosen specifically so that projects may depend on Forge +features without being infected with its license. That is the +purpose of the LGPL. Mods and others using this code via ordinary +Java mechanics for referencing libraries are specifically not bound +by Forge's license for the Mod code. + + +=== MCP Data === +This software includes data from the Minecraft Coder Pack (MCP), with kind permission +from them. The license to MCP data is not transitive - distribution of this data by +third parties requires independent licensing from the MCP team. This data is not +redistributable without permission from the MCP team. + +=== Sharing === +I grant permission for some parts of FML to be redistributed outside the terms of the LGPL, for the benefit of +the minecraft modding community. All contributions to these parts should be licensed under the same additional grant. + +-- Runtime patcher -- +License is granted to redistribute the runtime patcher code (src/main/java/net/minecraftforge/fml/common/patcher +and subdirectories) under any alternative open source license as classified by the OSI (http://opensource.org/licenses) + +-- ASM transformers -- +License is granted to redistribute the ASM transformer code (src/main/java/net/minecraftforge/common/asm/ and subdirectories) +under any alternative open source license as classified by the OSI (http://opensource.org/licenses) + +========================================================================= +This software includes portions from the Apache Maven project at +http://maven.apache.org/ specifically the ComparableVersion.java code. It is +included based on guidelines at +http://www.softwarefreedom.org/resources/2007/gpl-non-gpl-collaboration.html +with notices intact. The only change is a non-functional change of package name. + +This software contains a partial repackaging of javaxdelta, a BSD licensed program for generating +binary differences and applying them, sourced from the subversion at http://sourceforge.net/projects/javaxdelta/ +authored by genman, heikok, pivot. +The only changes are to replace some Trove collection types with standard Java collections, and repackaged. +========================================================================= + + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..344bca7 --- /dev/null +++ b/README.txt @@ -0,0 +1,46 @@ + +Source installation information for modders +------------------------------------------- +This code follows the Minecraft Forge installation methodology. It will apply +some small patches to the vanilla MCP source code, giving you and it access +to some of the data and functions you need to build a successful mod. + +Note also that the patches are built against "un-renamed" MCP source code (aka +SRG Names) - this means that you will not be able to read them directly against +normal code. + +Setup Process: +============================== + +Step 1: Open your command-line and browse to the folder where you extracted the zip file. + +Step 2: You're left with a choice. +If you prefer to use Eclipse: +1. Run the following command: `gradlew genEclipseRuns` (`./gradlew genEclipseRuns` if you are on Mac/Linux) +2. Open Eclipse, Import > Existing Gradle Project > Select Folder + or run `gradlew eclipse` to generate the project. + +If you prefer to use IntelliJ: +1. Open IDEA, and import project. +2. Select your build.gradle file and have it import. +3. Run the following command: `gradlew genIntellijRuns` (`./gradlew genIntellijRuns` if you are on Mac/Linux) +4. Refresh the Gradle Project in IDEA if required. + +If at any point you are missing libraries in your IDE, or you've run into problems you can +run `gradlew --refresh-dependencies` to refresh the local cache. `gradlew clean` to reset everything +{this does not affect your code} and then start the process again. + +Mapping Names: +============================= +By default, the MDK is configured to use the official mapping names from Mojang for methods and fields +in the Minecraft codebase. These names are covered by a specific license. All modders should be aware of this +license, if you do not agree with it you can change your mapping names to other crowdsourced names in your +build.gradle. For the latest license text, refer to the mapping file itself, or the reference copy here: +https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md + +Additional Resources: +========================= +Community Documentation: http://mcforge.readthedocs.io/en/latest/gettingstarted/ +LexManos' Install Video: https://www.youtube.com/watch?v=8VEdtQLuLO0 +Forge Forum: https://forums.minecraftforge.net/ +Forge Discord: https://discord.gg/UvedJ9m \ No newline at end of file diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..270e3a5 --- /dev/null +++ b/build.gradle @@ -0,0 +1,206 @@ + + +buildscript { + repositories { + maven { url = 'https://maven.minecraftforge.net' } + mavenCentral() + } + dependencies { + classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '5.1.+', changing: true + } +} + +apply plugin: 'net.minecraftforge.gradle' +// Only edit below this line, the above code adds and enables the necessary things for Forge to be setup. +apply plugin: 'eclipse' +apply plugin: 'maven-publish' + +version = '1.0' +group = 'com.yourname.modid' // http://maven.apache.org/guides/mini/guide-naming-conventions.html +archivesBaseName = 'modid' + +java.toolchain.languageVersion = JavaLanguageVersion.of(8) // Mojang ships Java 8 to end users, so your mod should target Java 8. + +println('Java: ' + System.getProperty('java.version') + ' JVM: ' + System.getProperty('java.vm.version') + '(' + System.getProperty('java.vendor') + ') Arch: ' + System.getProperty('os.arch')) +minecraft { + // The mappings can be changed at any time, and must be in the following format. + // Channel: Version: + // snapshot YYYYMMDD Snapshot are built nightly. + // stable # Stables are built at the discretion of the MCP team. + // official MCVersion Official field/method names from Mojang mapping files + // + // You must be aware of the Mojang license when using the 'official' mappings. + // See more information here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md + // + // Use non-default mappings at your own risk. they may not always work. + // Simply re-run your setup task after changing the mappings to update your workspace. + mappings channel: 'official', version: '1.16.5' + // makeObfSourceJar = false // an Srg named sources jar is made by default. uncomment this to disable. + + // accessTransformer = file('src/main/resources/META-INF/accesstransformer.cfg') + + // Default run configurations. + // These can be tweaked, removed, or duplicated as needed. + runs { + client { + workingDirectory project.file('run') + + // Recommended logging data for a userdev environment + // The markers can be changed as needed. + // "SCAN": For mods scan. + // "REGISTRIES": For firing of registry events. + // "REGISTRYDUMP": For getting the contents of all registries. + property 'forge.logging.markers', 'REGISTRIES' + + // Recommended logging level for the console + // You can set various levels here. + // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels + property 'forge.logging.console.level', 'debug' + + mods { + examplemod { + source sourceSets.main + } + } + } + + server { + workingDirectory project.file('run') + + // Recommended logging data for a userdev environment + // The markers can be changed as needed. + // "SCAN": For mods scan. + // "REGISTRIES": For firing of registry events. + // "REGISTRYDUMP": For getting the contents of all registries. + property 'forge.logging.markers', 'REGISTRIES' + + // Recommended logging level for the console + // You can set various levels here. + // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels + property 'forge.logging.console.level', 'debug' + + mods { + examplemod { + source sourceSets.main + } + } + } + + data { + workingDirectory project.file('run') + + // Recommended logging data for a userdev environment + // The markers can be changed as needed. + // "SCAN": For mods scan. + // "REGISTRIES": For firing of registry events. + // "REGISTRYDUMP": For getting the contents of all registries. + property 'forge.logging.markers', 'REGISTRIES' + + // Recommended logging level for the console + // You can set various levels here. + // Please read: https://stackoverflow.com/questions/2031163/when-to-use-the-different-log-levels + property 'forge.logging.console.level', 'debug' + + // Specify the modid for data generation, where to output the resulting resource, and where to look for existing resources. + args '--mod', 'examplemod', '--all', '--output', file('src/generated/resources/'), '--existing', file('src/main/resources/') + + mods { + examplemod { + source sourceSets.main + } + } + } + } +} + +// Include resources generated by data generators. +sourceSets.main.resources { srcDir 'src/generated/resources' } + +dependencies { + // Specify the version of Minecraft to use, If this is any group other then 'net.minecraft' it is assumed + // that the dep is a ForgeGradle 'patcher' dependency. And it's patches will be applied. + // The userdev artifact is a special name and will get all sorts of transformations applied to it. + minecraft 'net.minecraftforge:forge:1.16.5-36.2.9' + + // You may put jars on which you depend on in ./libs or you may define them like so.. + // compile "some.group:artifact:version:classifier" + // compile "some.group:artifact:version" + + // Real examples + // compile 'com.mod-buildcraft:buildcraft:6.0.8:dev' // adds buildcraft to the dev env + // compile 'com.googlecode.efficient-java-matrix-library:ejml:0.24' // adds ejml to the dev env + + // The 'provided' configuration is for optional dependencies that exist at compile-time but might not at runtime. + // provided 'com.mod-buildcraft:buildcraft:6.0.8:dev' + + // These dependencies get remapped to your current MCP mappings + // deobf 'com.mod-buildcraft:buildcraft:6.0.8:dev' + + // For more info... + // http://www.gradle.org/docs/current/userguide/artifact_dependencies_tutorial.html + // http://www.gradle.org/docs/current/userguide/dependency_management.html + +} + +// Example for how to get properties into the manifest for reading by the runtime.. +jar { + manifest { + attributes([ + "Specification-Title": "examplemod", + "Specification-Vendor": "examplemodsareus", + "Specification-Version": "1", // We are version 1 of ourselves + "Implementation-Title": project.name, + "Implementation-Version": "${version}", + "Implementation-Vendor" :"examplemodsareus", + "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ") + ]) + } +} + +// Example configuration to allow publishing using the maven-publish task +// This is the preferred method to reobfuscate your jar file +jar.finalizedBy('reobfJar') +// However if you are in a multi-project build, dev time needs unobfed jar files, so you can delay the obfuscation until publishing by doing +//publish.dependsOn('reobfJar') + +publishing { + publications { + mavenJava(MavenPublication) { + artifact jar + } + } + repositories { + maven { + url "file:///${project.projectDir}/mcmodsrepo" + } + } +} + + + + + +repositories { + maven { + url 'https://dl.cloudsmith.io/public/geckolib3/geckolib/maven/' + } + maven { + // location of the maven that hosts JEI files + name = "Progwml6 maven" + url = "https://dvs1.progwml6.com/files/maven/" + } + maven { + // location of a maven mirror for JEI files, as a fallback + name = "ModMaven" + url = "https://modmaven.dev" + } +} +dependencies { + implementation 'org.jetbrains:annotations:20.1.0' + implementation fg.deobf('software.bernie.geckolib:geckolib-forge-1.16.5:3.0.56') + + // compile against the JEI API but do not include it at runtime + compileOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}:api") + // at runtime, use the full JEI jar + runtimeOnly fg.deobf("mezz.jei:jei-${mc_version}:${jei_version}") +} \ No newline at end of file diff --git a/changelog.txt b/changelog.txt new file mode 100644 index 0000000..b22f4ae --- /dev/null +++ b/changelog.txt @@ -0,0 +1,2442 @@ +Build: 1.16.5-36.2.9 - Thu Nov 04 07:09:52 GMT 2021 + gigaherz: + Implement GUI Stacking feature. (#6927) + + * Implement GUI Stacking feature. + You can now use `mc.pushGuiLayer` and `mc.popGuiLayer` to manage the layers. + mc.displayGuiScreen behaves such that if called with a non-null screen it replaces the entire stack, and if called with null it closes the entire stack. + + * Apply review comment fixes from 1.17 counterpart. + + * Revert unintended changes. + + * Missed these reverts. + +========= +Build: 1.16.5-36.2.8 - Sun Oct 03 16:51:54 GMT 2021 + sciwhiz12: + Add workaround for pairs of `'` being stripped (#8074) + + Backport of #8050 + + ititus: + Fix typo in FluidBlockWrapper (#7880) + +========= +Build: 1.16.5-36.2.6 - Mon Sep 27 20:24:54 GMT 2021 + brandon4261: + Backport MC-209819 (#7923) + + Backport fix for mc bug https://bugs.mojang.com/browse/MC-209819 + +========= +Build: 1.16.5-36.2.5 - Sun Sep 19 23:50:14 GMT 2021 + zml: + [1.16.5] Bump Mixin to 0.8.4 (#8098) + +========= +Build: 1.16.5-36.2.4 - Tue Aug 31 16:32:40 GMT 2021 + djbake101: + [1.16.5] Backport OnDatapackSyncEvent from 1.17.1 (#7985) + +========= +Build: 1.16.5-36.2.3 - Tue Aug 31 15:35:00 GMT 2021 + sciwhiz12: + [1.16.x] Fix all layers of ItemLayerModel being fullbright (#8040) + + * Fix all layers of ItemLayerModel being fullbright + + Backport of #8039 + + * Remove duplicate test resources + + These resources have corresponding equivalents in the generated tests + resources folder. + +========= +Build: 1.16.5-36.2.2 - Mon Jul 26 21:37:03 GMT 2021 + onelemonyboi: + Fix rounding related errors with small entity pathfinding. Closes #7730 + +========= +Build: 1.16.5-36.2.1 - Sat Jul 24 17:39:23 GMT 2021 + supermartijn642: + Pass the 'includeName' flag to the ItemTossEvent (#7758) + +========= +Build: 1.16.5-36.2.0 - Thu Jul 22 01:45:10 GMT 2021 + lexmanos: + New 1.16.5 RB. + +========= +Build: 1.16.5-36.1.66 - Wed Jul 21 21:21:25 GMT 2021 + sizableshrimp: + ForgeGradle 5.1 and Gradle 7, which allows development on J16. Runtime still targets J8. (#7877) + +========= +Build: 1.16.5-36.1.65 - Tue Jul 20 05:01:10 GMT 2021 + lexmanos: + Work around javac scoping issue. + + lexmanos: + Fix LAN worlds where registry entries have been removed. + +========= +Build: 1.16.5-36.1.63 - Mon Jul 19 19:54:59 GMT 2021 + william: + Fix FakePlayers having null `connection` and add FakePlayer test mod (#7733) + +========= +Build: - Sat Jul 17 16:23:44 GMT 2021 + ateranimavis: + Use '{assets_root}' rather than task output path for userdev config (#7873) + + Signed-off-by: AterAnimAvis + +========= +Build: 1.16.5-36.1.61 - Sat Jul 17 11:14:53 GMT 2021 + thelnfamous1: + Patch several mob classes to let them use modded versions of their ranged weapons (#7845) + + baileyholl: + Adds a damage float in Lightning Entity and patches Entity to use it. (#7849) + + thesilkminer: + Fix missing userdev config for datagen runs (#7871) + + Signed-off-by: TheSilkMiner + +========= +Build: 1.16.5-36.1.58 - Sat Jul 17 02:45:36 GMT 2021 + awsomesauce239: + Add Fishing bobber projectile impact event (#7842) + + onelemonyboi: + Removes misleading Nullable annotation from canCreatureSpawn (#7840) + + onelemonyboi: + Removes misapplied patch in Entity (#7841) + + onelemonyboi: + Updates MouseHelper to allow for Horizontal Scroll to be recognized as Vertical Scroll (#7834) + + onelemonyboi: + Corrects the assigning of mob kills, Fixes MC-121048 (#7836) + +========= +Build: 1.16.5-36.1.53 - Sat Jul 17 02:30:47 GMT 2021 + diesieben07: + Fix entities losing their scoreboard data when they are unloaded (#7826) + +========= +Build: 1.16.5-36.1.52 - Sat Jul 17 02:23:52 GMT 2021 + diesieben07: + [1.16] Allow blocks other than beds or respawn anchors to act as respawn points (#7824) + +========= +Build: 1.16.5-36.1.51 - Sat Jul 17 02:13:02 GMT 2021 + queekusme: + Changed AbstractFurnaceTileEntity's canBurn and burn functions to use IRecipe's 'assemble' instead of 'getResultItem' (#7756) + + judge40: + [1.16.x] Remove redundant mobgriefing check in SmallFireaballEntity. (#7761) + + judge40: + Use MobGriefingEvent for PiglinEntity when determining whether Piglins want to pick up items. (#7762) + + diesieben07: + Add IRecipeType parameter to burn time hooks (#7771) + + mike.kok: + Fixes tryFluidTransfer_Internal to respect the FluidStack drainable when draining fluidSource. (#7782) + + personthecat: + Synchronize `ResourcePackList#addPackFinder` (#7799) + + github: + Fix vanilla rotation/mirroring issues (#7803) + + Patch minecraft to fix MC-227255 and MC-134110, which are block + rotation and mirroring issues. I noticed this from problems with + Structurize, but this probably affects any other mods that allow + rotating or mirroring structures (as well as vanilla structure blocks). + + sekwah41: + Fix mod menu URL click bounds (#7804) + + thelnfamous1: + Adds knockback attribute to players and updated knockback calculation to PlayerEntity#attack (#7806) + + kinglemming: + Convenience change for potion enumeration - does not change patch size in any meaningful way! (#7811) + + cech12: + New hook to allow Trapdoors be climbable for custom ladders (#7816) + + won-ton: + Add AT entries for DimensionSettings to make them easier for mods to work with (#7817) + + lexmanos: + Regen patches + + daemonumbra: + Removed sidedness from PacketBuffer methods. (#7236) + + Affected methods: + * readLongArray (x2) + * readSectionPos + * readString (no-arg variant) + + covers1624: + Bypass chunk future chain when processing loads and getChunk called. (#7697) + +========= +Build: 1.16.5-36.1.36 - Sat Jul 17 00:24:32 GMT 2021 + thesilkminer: + Add data generators for sounds.json (#6982) + +========= +Build: 1.16.5-36.1.35 - Thu Jul 15 23:56:00 GMT 2021 + diesieben07: + Add custom TextureAtlasSprite loaders (#7822) + + Adds a system for mods to specify custom texture loaders which can be requested by the resource pack through a metadata section in the .mcmeta file. Due to technical reasons, png file is still required for MC to identify a texture as existing, even if the loader doesn't use it. + +========= +Build: 1.16.5-36.1.34 - Thu Jul 15 23:40:24 GMT 2021 + commoble: + Fix PlayerGameModeEventTest and ForgeWorldTypeTest so they don't crash the dedicated server when running forge_test_server in forgedev (#7869) + +========= +Build: 1.16.5-36.1.33 - Wed Jul 14 01:16:19 GMT 2021 + lexmanos: + Add userdev to run config. + +========= +Build: 1.16.5-36.1.32 - Thu Jun 17 02:23:34 GMT 2021 + diesieben07: + Add truncation to FMLStatusPing to work around protocol limits (#7818) + +========= +Build: 1.16.5-36.1.31 - Wed Jun 09 16:35:21 GMT 2021 + sizableshrimp: + Remove ModelResourceLocation patch for SAS entry (#7813) + +========= +Build: 1.16.5-36.1.30 - Tue Jun 08 20:34:06 GMT 2021 + diesieben07: + Fix jar file path detection if the path contains a "!" (#7790) + +========= +Build: 1.16.5-36.1.29 - Tue Jun 08 19:54:50 GMT 2021 + mrp-v2: + Add method to get the number of elements in a model builder (#7792) + +========= +Build: 1.16.5-36.1.28 - Tue Jun 08 19:47:54 GMT 2021 + diesieben07: + Fix vanilla packet splitter remote detection and add advancement packet splitting (#7802) + +========= +Build: 1.16.5-36.1.27 - Tue Jun 08 19:33:44 GMT 2021 + 17338378+nightenom: + Add option for linear filtering of text texture (#7645) + +========= +Build: 1.16.5-36.1.26 - Tue Jun 08 19:07:49 GMT 2021 + mrp-v2: + Use empty model instead of missing model for non-existant layers in multilayer models (#7750) + + Fixes issues when using multi-layer models as part of composite models + +========= +Build: 1.16.5-36.1.25 - Thu Jun 03 17:30:10 GMT 2021 + lexmanos: + Add debug logging to packet compression encoder. + Should make figuring out who is sending large packets easier. + Disable with -Pforge.disablePacketCompressionDebug=true + +========= +Build: 1.16.5-36.1.24 - Sun May 23 18:09:00 GMT 2021 + lexmanos: + Removed signature line from mod list screen. #7500 + +========= +Build: 1.16.5-36.1.23 - Mon May 17 20:56:15 GMT 2021 + curle: + Reinstate the MinecartCollisionHandler field to AbstractMinecartEntity (#7748) Closes #7506. + +========= +Build: 1.16.5-36.1.22 - Mon May 17 20:50:05 GMT 2021 + curle: + Fix PlayerEvent.BreakSpeed's pos being nullable. (#7747) Closes #7615. + +========= +Build: 1.16.5-36.1.21 - Mon May 17 20:43:50 GMT 2021 + curle: + Fix OBJ Loader data gen string (#7746) Closes #7616 + +========= +Build: 1.16.5-36.1.20 - Mon May 17 20:17:14 GMT 2021 + noeppi-noeppi: + Add an event similar to PlayerEvent.NameFormat but for the name shown in the tab list. (#7740) + +========= +Build: 1.16.5-36.1.19 - Mon May 17 20:10:45 GMT 2021 + curle: + Fix filling buckets with fluids without bucket items consuming the fluid (#7745) Closes #7670 + +========= +Build: 1.16.5-36.1.18 - Thu May 13 22:12:02 GMT 2021 + gigaherz: + Work around crash while loading flatworld with modded structures. (#7764) + + * Work around crash while loading flatworld with modded structures. + + * Maybe fix issue with gradle daemon leaking memory and slowing down CI builds. + +========= +Build: 1.16.5-36.1.17 - Wed May 12 21:33:59 GMT 2021 + gigaherz: + Update Forge to Gradle 6.9 + +========= +Build: 1.16.5-36.1.16 - Fri Apr 30 17:59:06 GMT 2021 + trikzon: + Add barrels and barrels/wooden block and item tag (#7676) + +========= +Build: 1.16.5-36.1.15 - Fri Apr 30 17:52:19 GMT 2021 + knightminer: + Fix shears not properly breaking tripwire (MC-129055) (#7718) + +========= +Build: 1.16.5-36.1.14 - Fri Apr 30 17:42:34 GMT 2021 + cpw: + try gradleVersion + + cpw: + trim? + + cpw: + toString? + + cpw: + fiddle + + cpw: + split ? + + cpw: + try better? + + cpw: + with + + cpw: + debug + + cpw: + debug + + cpw: + debug + + cpw: + debug + + cpw: + tokenize + + cpw: + map + + cpw: + trims + + cpw: + tidy + + cpw: + try passing in env + + cpw: + try passing in env + + s8johost: + Fix Line endings in tooltips not handled properly in multiplayer screen Closes #7738 (#7739) + +========= +Build: 1.16.5-36.1.13 - Fri Apr 23 20:28:12 GMT 2021 + shroomdog27: + Fix cats, phantoms and pillagers saying they're at BlockPos.ZERO during LivingSpawnEvent.CheckSpawn (#7722) + +========= +Build: 1.16.5-36.1.12 - Fri Apr 23 05:59:08 GMT 2021 + xfacthd: + Pass BlockPos to BlockParticleData used for "fall impact" particle (#7705) + + mrp-v2: + [1.16] Add missing Multipart Blockstate Builder feature: Nested condition groups (#7677) + +========= +Build: 1.16.5-36.1.10 - Fri Apr 23 05:52:41 GMT 2021 + sciwhiz12: + Check version ranges of optional dependencies when present (#7710) + + If an optional dependency is present, but it does not conform to the version range, + it will now error out in the same fashion as missing required dependencies, instead + of a more cryptic error down the line due to a missing method/class/field/etc. + + Implements and closes #7696 + +========= +Build: 1.16.5-36.1.9 - Fri Apr 23 05:45:51 GMT 2021 + diesieben07: + Fix ClientVisualization crashing on systems without monitors (#7719) + +========= +Build: 1.16.5-36.1.8 - Fri Apr 23 05:34:56 GMT 2021 + atkarimarton: + Fix Furnace Minecarts going faster then vanilla (#7725) + +========= +Build: 1.16.5-36.1.7 - Fri Apr 23 05:28:36 GMT 2021 + ateranimavis: + Update for Forge's new maven (#7723) + +========= +Build: 1.16.5-36.1.6 - Sun Apr 18 15:47:08 GMT 2021 + cpw: + A bloody quote FFS + + Signed-off-by: cpw + + cpw: + Update for new maven + + Signed-off-by: cpw + +========= +Build: 1.16.5-36.1.4 - Fri Apr 02 18:31:07 GMT 2021 + cpw: + Fix broken java9hacks for j16 handling.. + + Signed-off-by: cpw + +========= +Build: 1.16.5-36.1.3 - Tue Mar 30 01:05:30 GMT 2021 + sizableshrimp: + Add generic EntityTeleportEvent (#7694) + +========= +Build: 1.16.5-36.1.2 - Mon Mar 22 06:24:40 GMT 2021 + covers1624: + Restore SS version, fixes findFieldInstanceChecks + +========= +Build: 1.16.5-36.1.1 - Wed Mar 17 17:04:46 GMT 2021 + diesieben07: + Fix sign textures being stitched onto every texture atlas (#7690) + +========= +Build: 1.16.5-36.1.0 - Mon Mar 15 22:11:58 GMT 2021 + lexmanos: + Fix AT order, missed exec line and bump for RB. + +========= +Build: 1.16.5-36.0.63 - Mon Mar 15 21:08:56 GMT 2021 + diesieben07: + Fix wrong eye height when entity size changes (esp. baby animals) (#7628) + +========= +Build: 1.16.5-36.0.62 - Mon Mar 15 21:02:36 GMT 2021 + diesieben07: + Allow ITeleporter to override the vanilla teleport sound (#7682) + +========= +Build: 1.16.5-36.0.61 - Mon Mar 15 20:20:21 GMT 2021 + sizableshrimp: + Fix datapack exception related to EnumArgument with siblings (#7686) + + Invalid enum constants are now properly thrown as a CommandSyntaxException + +========= +Build: 1.16.5-36.0.60 - Mon Mar 15 19:29:01 GMT 2021 + 42383791+kaydogz: + Add support for custom WoodTypes (#7623) + +========= +Build: 1.16.5-36.0.59 - Mon Mar 15 19:19:16 GMT 2021 + lexmanos: + Use JGit instead of GrGit now that jcenter is going away. + Update missed mapped name in MDK. + +========= +Build: 1.16.5-36.0.58 - Sat Mar 13 19:07:24 GMT 2021 + diesieben07: + Fix incorrectly replaced SRG names + + gigaherz: + Fix yet another copypasta. + + gigaherz: + Bump nashorn wrapper version. + +========= +Build: 1.16.5-36.0.55 - Fri Mar 12 18:51:48 GMT 2021 + ateranimavis: + Fix potential Deadlock when using custom Item entities. (#7532) + + Be careful when adding Entities during Chunk Load (#7519) + +========= +Build: 1.16.5-36.0.54 - Fri Mar 12 02:04:32 GMT 2021 + gigaherz: + Fix copypasta. + +========= +Build: 1.16.5-36.0.53 - Fri Mar 12 00:11:22 GMT 2021 + curle: + Automatically fix some issues with configurations deemed invalid for simple reasons (#7671) + +========= +Build: 1.16.5-36.0.52 - Thu Mar 11 20:59:54 GMT 2021 + gigaherz: + Introduce a new feature that lets mods know if optional mods and optional network channels are present in the remote. + Allow connections from forge versions that don't have the vanilla splitter. + + gigaherz: + Bulk update license year, and use replacement variable so that the current year is always used. + + gigaherz: + Bump SpecialSource + + gigaherz: + Add coremod that injects bouncer methods to work around name conflicts with official names. + Fixes a binary break. + +========= +Build: 1.16.5-36.0.48 - Tue Mar 09 22:22:20 GMT 2021 + lexmanos: + Update to FG4, and Gradle 6.8. + + lexmanos: + Regenerate patches with relative headers. This should lower conflicts in future PRs. + Convert Forge to use Official mappings. + Mojang released their obfuscation mappings but we have not used them up until now due to wanting to get their license to be more explicitly permissive. + It is clear that their intent is to allow us to use their names for developing mods like this. + See the full wording, and our interpretation here: https://github.com/MinecraftForge/MCPConfig/blob/master/Mojang.md + +========= +Build: 1.16.5-36.0.46 - Thu Mar 04 20:15:10 GMT 2021 + diesieben07: + Support splitting vanilla packets that are too large on forge<->forge connections (#7485) + + Currently only for SUpdateRecipesPacket and STagsListPacket that blow up with huge datapacks + +========= +Build: 1.16.5-36.0.45 - Wed Mar 03 20:50:47 GMT 2021 + pupnewfster: + Fix a few places where the vanilla method was being called instead of the forge one (#7535) + + Cleanup javadocs references slightly, fix a couple spots not using the proper forge hooks, and remove a couple unneeded patches + Update deprecation comment on isAir + +========= +Build: 1.16.5-36.0.44 - Wed Mar 03 05:29:04 GMT 2021 + firecontroller1847: + Add Opacity to ForgeHooksClient#renderMainMenu (#7660) + +========= +Build: 1.16.5-36.0.43 - Thu Feb 25 02:37:09 GMT 2021 + oriondevelopment: + Add support for caching of configuration values. (#7608) + +========= +Build: 1.16.5-36.0.42 - Tue Feb 16 02:43:01 GMT 2021 + kovac1066: + Added entity attribute setup and creation events + +========= +Build: 1.16.5-36.0.41 - Tue Feb 16 01:28:51 GMT 2021 + knightminer: + Fix updateItemStackNBT not properly being called (#7646) + + Re-added ItemStack delegate redirect transformer + +========= +Build: 1.16.5-36.0.40 - Tue Feb 16 01:08:21 GMT 2021 + pupnewfster: + Fix a few FluidUtil issues that were causing DispenseFluidContainer to not function properly (#7422) + +========= +Build: 1.16.5-36.0.39 - Tue Feb 16 00:49:27 GMT 2021 + daemonumbra: + Fixed Configs not correcting when hot-loaded from changes on disk (#7427) + + ichttt: + Add a way to specify a custom background texture with namespaces in the Creative GUI. (#7404) + +========= +Build: 1.16.5-36.0.37 - Tue Feb 16 00:39:15 GMT 2021 + xzk0701: + Reduce default logging markers in the MDK. Modders can re-enable these for better debugging. (#7432) + + Modders PLEASE read your damn log, and fix the errors we point out. Spamming modpacks with stack traces is just lazy programming. + +========= +Build: 1.16.5-36.0.36 - Tue Feb 16 00:19:30 GMT 2021 + sciwhiz12: + Deprecate Forge's setdimension command, vanilla execute command can do this now. (#7459) + +========= +Build: 1.16.5-36.0.35 - Mon Feb 15 23:38:35 GMT 2021 + spb.max2: + Fix ItemTextureQuadConverter.convertTexture generating wrong quads, fixes #7620 (#7650) + +========= +Build: 1.16.5-36.0.34 - Mon Feb 15 23:22:40 GMT 2021 + florian: + Added MultipartBakedModel.getModelData(). (#7595) + + This allows custom IBakedModel implementations to use the IModelData provided by their IBakedModel.getModelData() when used in the context of a multipart model. + +========= +Build: 1.16.5-36.0.33 - Mon Feb 15 23:15:50 GMT 2021 + cyborgmas: + fix global cache not being a block render type (#7648) + +========= +Build: 1.16.5-36.0.32 - Mon Feb 15 22:52:15 GMT 2021 + 35673674+alcatrazescapee: + Allow mods to use additional custom LootParameter when querying existing loot tables (#7515) + +========= +Build: 1.16.5-36.0.31 - Mon Feb 15 21:40:16 GMT 2021 + shroomdog27: + Add ForgeHooks.canEntitySpawn to Cat, Phantom, and Patrol spawners. (#7569) + +========= +Build: 1.16.5-36.0.30 - Mon Feb 15 21:26:11 GMT 2021 + dev: + Fix/Replace player visibility event (#7573) + +========= +Build: 1.16.5-36.0.29 - Mon Feb 15 21:16:26 GMT 2021 + ateranimavis: + Fix: Clear the last error from glfwInit to prevent vanilla from throwing an exception later in the chain when glfw errors. (#7587) + +========= +Build: 1.16.5-36.0.28 - Mon Feb 15 20:56:51 GMT 2021 + 55965249+seymourimadeit: + Fix MC-181464 persisting for modded shields (#7602) + +========= +Build: 1.16.5-36.0.27 - Mon Feb 15 20:11:46 GMT 2021 + malte0811: + FIx race condition in LazyOptional (#7611) + +========= +Build: 1.16.5-36.0.26 - Mon Feb 15 03:16:02 GMT 2021 + xfacthd: + [1.16.5] Fix shaders breaking almost every overlay that uses textures, fixes #7575 (#7624) + +========= +Build: 1.16.5-36.0.25 - Mon Feb 15 03:10:24 GMT 2021 + telepathicgrunt: + Disable syncing of Feature and Biome registries (#7639) + +========= +Build: 1.16.5-36.0.24 - Mon Feb 15 03:04:46 GMT 2021 + drullkus: + Add IExtensibleEnum to GrassColorModifier (#7641) + +========= +Build: 1.16.5-36.0.23 - Mon Feb 15 02:36:26 GMT 2021 + shroomdog27: + Log stacktraces in NettyPacketEncoder. (#7654) + +========= +Build: 1.16.5-36.0.22 - Wed Feb 10 19:05:16 GMT 2021 + xfacthd: + Lower logging level for datafixer warning to debug (#7636) + +========= +Build: 1.16.5-36.0.21 - Tue Feb 09 22:19:29 GMT 2021 + pupnewfster: + Reintroduce forge's chunk manager to allow mods to force chunks with either a block position or entity (UUID) "owner" and have them properly persist between restarts (#7642) + +========= +Build: 1.16.5-36.0.20 - Tue Feb 09 21:28:24 GMT 2021 + pupnewfster: + Fix two places where querying an object for the new "valid" capability from a capability invalidation listener could cause the object to return the old invalid capability. (#7643) + +========= +Build: 1.16.5-36.0.19 - Tue Feb 09 21:21:44 GMT 2021 + cyborgmas: + Fix config spec in cases of enum class discrepancies (#7635) + +========= +Build: 1.16.5-36.0.18 - Tue Feb 09 21:06:36 GMT 2021 + diesieben07: + Fix onBlockAdded being called twice for ItemEntity placing non-TE blocks (#7607) + +========= +Build: 1.16.5-36.0.17 - Tue Feb 09 21:00:57 GMT 2021 + lachney: + Prevent NullPointerException when adding new loot pool. (#7605) + +========= +Build: 1.16.5-36.0.16 - Tue Feb 09 20:53:48 GMT 2021 + brandon4261: + Added generic multi part entity API (#7554) + +========= +Build: 1.16.5-36.0.15 - Sun Feb 07 03:41:41 GMT 2021 + cyborgmas: + Fix IAngerable entities crashing when reading nbt on client (#7618) + +========= +Build: 1.16.5-36.0.14 - Tue Feb 02 20:28:08 GMT 2021 + thesilkminer: + [1.16.x] Add loot table ID in Global Loot Modifiers (#7428) + + thesilkminer: + [1.16.x] Add loot table ID in Global Loot Modifiers (#7428) + +========= +Build: 1.16.5-36.0.13 - Sat Jan 30 02:07:17 GMT 2021 + pupnewfster: + Add a block tag to allow mods to blacklist blocks endermen should not be able to place blocks on top of, similar to how vanilla hardcodes against them being able to place things on bedrock (#7548) + +========= +Build: 1.16.5-36.0.12 - Sat Jan 30 02:01:35 GMT 2021 + 7419378+hellfirepvp: + Fix translucent model parts of MultiLayerModels rendering as missing models due to differing rendertypes when rendering block model (#7579) + + Signed-off-by: HellFirePvP <7419378+HellFirePvP@users.noreply.github.com> + +========= +Build: 1.16.5-36.0.11 - Sat Jan 30 01:35:10 GMT 2021 + pupnewfster: + Fix existing file tag provider support looking in the wrong folder for custom tag types (#7576) + +========= +Build: 1.16.5-36.0.10 - Thu Jan 28 21:07:30 GMT 2021 + cyborgmas: + Propery re-encode registries (#7629) + +========= +Build: 1.16.5-36.0.9 - Thu Jan 28 01:23:13 GMT 2021 + cyborgmas: + Properly encode registries. (#7626) + +========= +Build: 1.16.5-36.0.8 - Thu Jan 28 00:00:43 GMT 2021 + cyborgmas: + Inject vanilla dimensions inside worlds missing them (#7599) + +========= +Build: 1.16.5-36.0.7 - Wed Jan 27 00:32:53 GMT 2021 + lexmanos: + Update Coremods, ASM, and include standalone Nashorn to load on J15. + + lexmanos: + Introduce a new field_to_instanceof transformer to reduce some simple patches. + +========= +Build: 1.16.5-36.0.4 - Tue Jan 26 02:53:10 GMT 2021 + lexmanos: + Fix broken build. + + dev: + Add modded biomes to overworld biome list (#7360) + +========= +Build: 1.16.5-36.0.2 - Tue Jan 26 02:25:10 GMT 2021 + lexmanos: + Fix dynamic registries not getting ids assigned correctly from old worlds in specific unordered value insertions. Closes #7586 + +========= +Build: 1.16.5-36.0.1 - Sun Jan 17 21:05:36 GMT 2021 + knightminer: + Optionally add a milk fluid to the vanilla bucket (#7294) + + Fixes the previous broken code that was supposed to make mod registered milk returned by the vanilla bucket by allowing mods to enable a milk fluid. + +========= +Build: 1.16.5-36.0.0 - Fri Jan 15 19:42:24 GMT 2021 + lexmanos: + 1.16.5 Initial Update. + +========= +Build: 1.16.4-35.1.37 - Thu Jan 14 23:58:35 GMT 2021 + lexmanos: + Update Coremods, ASM, and include standalone Nashorn to load on J15. + +========= +Build: 1.16.4-35.1.36 - Thu Jan 07 20:24:49 GMT 2021 + rehwinkel: + Added IWeatherParticleRenderHandler to allow a mod to take control over weather particles and sounds. (#7522) + +========= +Build: 1.16.4-35.1.35 - Thu Jan 07 20:16:03 GMT 2021 + covers1624: + Allow Chunk loading Tickets to opt-into forcing chunk ticks. (#7525) + +========= +Build: 1.16.4-35.1.34 - Thu Jan 07 20:10:18 GMT 2021 + malte0811: + Fix crash when mods add goals to skeleton horses (MC-206338) (#7509) + +========= +Build: 1.16.4-35.1.33 - Thu Jan 07 20:03:59 GMT 2021 + diesieben07: + Set WM_CLASS and WM_INSTANCE_NAME for early progress window (#7534) + +========= +Build: 1.16.4-35.1.32 - Wed Jan 06 03:17:35 GMT 2021 + 35673674+alcatrazescapee: + Make UnboundedMapCodec more lenient in decoding dimensions. Fixes MC-197860 (#7527) + +========= +Build: 1.16.4-35.1.31 - Tue Jan 05 19:59:52 GMT 2021 + lexmanos: + Prevent NPE and deprecated MissingMappings.getMappings function. Closes #6252 + + lexmanos: + Fix FML's Config Sync packet not allowing same length filenames in encoder and decoder. Closes #7584 + +========= +Build: 1.16.4-35.1.29 - Sun Jan 03 11:02:59 GMT 2021 + lexmanos: + Fix entities not correctly being able to be ridden under water. + +========= +Build: 1.16.4-35.1.28 - Mon Dec 28 21:56:51 GMT 2020 + git: + Fix crash when beehive is broken by fake player (#7566) + +========= +Build: 1.16.4-35.1.27 - Mon Dec 28 21:46:04 GMT 2020 + 35673674+alcatrazescapee: + Add supplier variant to `AbstractBlock.Properties#lootFrom` (#7563) + +========= +Build: 1.16.4-35.1.26 - Mon Dec 28 21:40:18 GMT 2020 + diesieben07: + Fix missing serializers when deserializing global loot modifiers (#7561) + + diesieben07: + Fix ModFileResourcePack.getAllResourceLocations ignoring resourceNamespace. (#7562) + + Fixes #7405 + +========= +Build: 1.16.4-35.1.24 - Mon Dec 28 21:34:39 GMT 2020 + diesieben07: + Fix VanillaConnectionNetworkFilter sending out invalid entity properties packets without an entity ID (#7560) + +========= +Build: 1.16.4-35.1.23 - Mon Dec 28 21:17:01 GMT 2020 + richard: + Make shear interactions extend to subclasses (#7544) + +========= +Build: 1.16.4-35.1.22 - Mon Dec 28 21:09:38 GMT 2020 + sciwhiz12: + Add a SoundType subclass that uses suppliers (#7538) + +========= +Build: 1.16.4-35.1.21 - Mon Dec 28 21:03:56 GMT 2020 + sciwhiz12: + Fix compound ingredient in shapeless recipes (#7537) Fixes #7530 + +========= +Build: 1.16.4-35.1.20 - Mon Dec 28 20:19:04 GMT 2020 + mrp-v2: + Fix modded PointOfInterestType's not populating blockstate map when registered (#7503) + + 35673674+alcatrazescapee: + Fix potential NPE in ForgeHooks.onItemPlaceIntoWorld when passing in null player. (#7505) + +========= +Build: 1.16.4-35.1.18 - Mon Dec 28 20:13:15 GMT 2020 + 48399898+poopoodice: + Add new LivingConversionEvent to control mobs turning into other mobs. (#7386) + +========= +Build: 1.16.4-35.1.17 - Mon Dec 28 20:01:42 GMT 2020 + knightminer: + Add ItemAttributeModifierEvent (#7484) + +========= +Build: 1.16.4-35.1.16 - Mon Dec 28 19:54:38 GMT 2020 + bward7864: + Fix RightClickBlock ALLOW not being implemented (#7426) + +========= +Build: 1.16.4-35.1.15 - Sat Dec 26 19:39:35 GMT 2020 + lexmanos: + Make mod data packs able to be disabled. It'll break things, but that's on you. Closes #6776 + + lexmanos: + Quiet down errors related to modders not changing their update urls from the default. + +========= +Build: 1.16.4-35.1.13 - Sat Dec 12 17:34:07 GMT 2020 + tterrag: + Add generated resource tracking to ExistingFileHelper + +========= +Build: 1.16.4-35.1.12 - Fri Dec 11 02:39:41 GMT 2020 + tterrag: + Fix BlockStateProvider item models not knowing about block models + + Add tests for this case + +========= +Build: 1.16.4-35.1.11 - Tue Dec 08 19:54:40 GMT 2020 + richard: + Override invalidateCaps instead of remove for vanilla TE capability invalidation (#7536) + + Properly invalidate patched in vanilla TE caps in invalidateCaps instead of remove so that they get invalidated on chunk unload + +========= +Build: 1.16.4-35.1.10 - Sat Dec 05 20:07:14 GMT 2020 + richard: + Make TEs invalidate capabilities when the chunk they are in unloads (#7529) + + Fixed LazyOptional potentially notifying invalidation listeners multiple times. + +========= +Build: 1.16.4-35.1.9 - Sat Dec 05 20:01:00 GMT 2020 + cordonfreeman: + Fixed entity navigation to stop entities spinning - MC-94054 (#7520) + +========= +Build: 1.16.4-35.1.8 - Sat Dec 05 19:52:56 GMT 2020 + Unbekannt1998: + Fix wrong function call in BlockStateProvider::horizontalFaceBlock (#7514) + +========= +Build: 1.16.4-35.1.7 - Sun Nov 29 02:11:08 GMT 2020 + tterrag: + Fix datagen order of multipart conditions being unstable + +========= +Build: 1.16.4-35.1.6 - Sat Nov 28 02:56:55 GMT 2020 + 35673674+alcatrazescapee: + Fix forge config option for default world type not applying unless you change the default world type (#7521) + +========= +Build: 1.16.4-35.1.5 - Fri Nov 27 23:57:23 GMT 2020 + gigaherz: + Implement feature for mods to define new world types (#7448) + + * Mods can now register world types via a new forge registry, and optionally register a settings screen to tweak them. + * The default world type for dedicated servers and singleplayer world creation is configurable via forge's common config. + +========= +Build: 1.16.4-35.1.4 - Tue Nov 24 17:14:21 GMT 2020 + csh2001331: + Fix dimType not encode to registries (#7513) + +========= +Build: 1.16.4-35.1.3 - Mon Nov 23 03:45:21 GMT 2020 + richard: + Add support for referencing forge's resources and specifying existing mods to data generators (#7456) + +========= +Build: 1.16.4-35.1.2 - Sun Nov 22 22:01:29 GMT 2020 + cpw: + Fix #6692 + + Thanks @AterAnimAvis for help and suggestions + + Signed-off-by: cpw + +========= +Build: 1.16.4-35.1.1 - Sat Nov 21 19:57:45 GMT 2020 + cyborgmas: + Fix translucent blocks not rendering properly when moved by pistons on fabulous (#7441) + +========= +Build: 1.16.4-35.1.0 - Fri Nov 20 20:54:30 GMT 2020 + lexmanos: + Bump version for RB. + +========= +Build: 1.16.4-35.0.22 - Fri Nov 20 18:24:46 GMT 2020 + 35673674+alcatrazescapee: + Fix MC-194811 - Removing structures causes chunk save errors. + + diesieben07: + Fix food bar not rendering when non-living entities are mounted (#7446) + +========= +Build: 1.16.4-35.0.20 - Fri Nov 20 18:18:37 GMT 2020 + diesieben07: + Fix concurrency issue in StartupMessageManager (#7483) + +========= +Build: 1.16.4-35.0.19 - Fri Nov 20 18:11:25 GMT 2020 + 35673674+alcatrazescapee: + Fix forge registry types that have private constructors (BlockStateProviderType, BlockPlacerType, FoliagePlacerType, TreeDecoratorType) (#7482) + +========= +Build: 1.16.4-35.0.18 - Sun Nov 15 16:08:55 GMT 2020 + cpw: + Fix problem where the absence of forge and MC in later loading triggered a weird crash. + + Signed-off-by: cpw + +========= +Build: 1.16.4-35.0.17 - Sat Nov 14 01:41:38 GMT 2020 + cpw: + Fix NPE problem when modid is mismatched. + + Signed-off-by: cpw + +========= +Build: 1.16.4-35.0.16 - Sat Nov 14 00:18:29 GMT 2020 + cpw: + Return the processed modlist data to the upstream system, not the raw unprocessed data. Should resolve the problem + that mixin complains about missing info when it's in a "crashed" situation. + + Signed-off-by: cpw + +========= +Build: 1.16.4-35.0.15 - Wed Nov 11 09:09:45 GMT 2020 + cyborgmas: + Fix dims on servers not loading the first run (#7445) + +========= +Build: 1.16.4-35.0.14 - Tue Nov 10 20:24:33 GMT 2020 + diesieben07: + Allow for custom argument types by filtering them on vanilla connections (#7463) + +========= +Build: 1.16.4-35.0.13 - Tue Nov 10 20:13:34 GMT 2020 + bward7864: + Add Player context to AnvilUpdateEvent (#7442) + +========= +Build: 1.16.4-35.0.12 - Tue Nov 10 20:02:33 GMT 2020 + git: + Don't overwrite PlayerAdvancement's player with a fake one (#7454) + + If a FakePlayer is constructed with the same UUID/GameProfile as a + currently active player, the player object within PlayerAdvancement is + set to the fake player. + + As fake players cannot receive advancements (see grantCriterion), this + prevents the actual player from receiving any advancements until they + change dimension/relog. + +========= +Build: 1.16.4-35.0.11 - Tue Nov 10 19:46:01 GMT 2020 + curle: + Add BannerBlock.forColor to SAS to fix banner.toItem() on servers. + +========= +Build: 1.16.4-35.0.10 - Tue Nov 10 19:36:40 GMT 2020 + boy132: + Call Harvest check event even if the block doesn't require any tool (#7414) + +========= +Build: 1.16.4-35.0.9 - Tue Nov 10 19:25:26 GMT 2020 + lexmanos: + Use linked collections to stabilize order when adding new registry entries. + + xfacthd: + Render local player when the renderViewEntity is not the local player (#7216) + +========= +Build: 1.16.4-35.0.7 - Sun Nov 08 04:12:02 GMT 2020 + cpw: + Some help in ExtensionPoint regarding DISPLAYTEST. Let's improve those tick rates! + + Signed-off-by: cpw + +========= +Build: 1.16.4-35.0.6 - Sun Nov 08 03:30:37 GMT 2020 + cpw: + Handle erroring during early mod construction phases, and actually report that into the error UI + by doing armslength exception handling and propagation. + + Signed-off-by: cpw + +========= +Build: 1.16.4-35.0.5 - Sun Nov 08 01:48:22 GMT 2020 + cpw: + Support backwards loading 1.16.3 mods in 1.16.4, because we are able to do that. Tweak loading a bit to be smarter about dependency errors of various kinds. + + Signed-off-by: cpw + +========= +Build: 1.16.4-35.0.4 - Sat Nov 07 20:10:44 GMT 2020 + gigaherz: + Add FluidStack codec, and a test mod that verifies its behaviour matches the existing write/read logic. + Add missing license headers. + +========= +Build: 1.16.4-35.0.3 - Sat Nov 07 02:11:47 GMT 2020 + cpw: + Update event bus version (should be 3.0.5) + + Tweak MDK to automatically populate recommended values for things like forge version, loader version and minecraft version. + + Signed-off-by: cpw + +========= +Build: 1.16.4-35.0.2 - Wed Nov 04 00:07:58 GMT 2020 + diesieben07: + Workaround for modded attributes on vanilla entities logging warnings on vanilla clients + + Switch to a handler-based approach per packet class, simplify patch, add some docs + + Add license header and docs + + Switch to a network handler based approach + + Switch to a network handler based approach + + revert build gradle change + + Simplify Packet patch + + Add license header to IForgePacket + + Revert ForgeHooks changes + + Less hacky and more generic way to filter packets for vanilla connections + + _Actually_ Order SAS. + It's early + + Order SAS + + simplify vanilla connection check + + Remove unneeded import change + +========= +Build: 1.16.4-35.0.1 - Mon Nov 02 19:57:45 GMT 2020 + cpw: + Fix early sorting bug that meant the file deduping was causing an error, to, well, not cause it, so we can get to an error screen. + + Signed-off-by: cpw + +========= +Build: 1.16.4-35.0.0 - Mon Nov 02 19:15:50 GMT 2020 + lexmanos: + 1.16.4 Initial Update + +========= +Build: 1.16.3-34.1.42 - Mon Nov 02 04:30:53 GMT 2020 + lexmanos: + Fix Biomes not properly copying over ids loaded from the save to the new Dynamic Registry. + +========= +Build: 1.16.3-34.1.41 - Mon Nov 02 01:09:57 GMT 2020 + gigaherz: + Introduce custom loader additions to the model data generators. (#7450) + + Currently implemented loaders: + * OBJ + * Composite + * Multi-layer + * Item layers (vanilla item/generated but with fullbright texture support) + * Bucket + * Separate Perspective + +========= +Build: 1.16.3-34.1.40 - Mon Nov 02 00:52:12 GMT 2020 + cpw: + actually rollback on error in registry events. + + Signed-off-by: cpw + +========= +Build: 1.16.3-34.1.39 - Sun Nov 01 22:09:32 GMT 2020 + cpw: + Update modlauncher. fixes #7452 + + Signed-off-by: cpw + + cpw: + Return client resources even if no data pack found on server. Closes #6225 (Pull request) + + Signed-off-by: cpw + + tobias.hotz: + Auto-detect ansi support for log4j2 + + move to fml.loading subpackage + + Add license header + + cpw: + Fix config parse failure causing crash in building exception message. fixes #7438 + + Signed-off-by: cpw + +========= +Build: 1.16.3-34.1.35 - Thu Oct 29 17:09:31 GMT 2020 + malte0811: + Fix (NonNull)Lazy.Concurrent using a global lock (#7403) + + * Fix Lazy.Concurrent using a global lock, thus preventing multiple threads from resolving independent Lazy's at the same time + * Use Lazy with an added null check to implement NonNullLazy + +========= +Build: 1.16.3-34.1.34 - Thu Oct 29 00:12:09 GMT 2020 + gigaherz: + Update forge mappings to 20201028-1.16.3 (#7435) + +========= +Build: 1.16.3-34.1.33 - Tue Oct 27 16:01:02 GMT 2020 + 35673674+alcatrazescapee: + Fix breaking changes from the Biome rename PR #7434 (#7439) + +========= +Build: 1.16.3-34.1.32 - Mon Oct 26 23:52:47 GMT 2020 + sciwhiz12: + Reimplement nametag distance attribute, fix attribute translation keys (#7387) + +========= +Build: 1.16.3-34.1.31 - Mon Oct 26 22:07:02 GMT 2020 + 35673674+alcatrazescapee: + Fix data pack biomes failing to load in SingleBiomeProvider (#7434) + +========= +Build: 1.16.3-34.1.30 - Mon Oct 26 22:00:28 GMT 2020 + cpw: + Add in proper handling of equals and hashcode for modjar urls. Fixes very slow loading on windows. + + Signed-off-by: cpw + +========= +Build: 1.16.3-34.1.29 - Mon Oct 26 12:51:24 GMT 2020 + cpw: + Force 8.0.5 ML + + Signed-off-by: cpw + +========= +Build: 1.16.3-34.1.28 - Mon Oct 26 11:32:40 GMT 2020 + cpw: + Restore FingerprintViolationEvent with appropriate THIS IS F*CKING DEAD DELET WARNINGS. + Also, notify in UI if using legacy JDK without capability to read out security data from mod jars. + + Signed-off-by: cpw + +========= +Build: 1.16.3-34.1.27 - Mon Oct 26 02:27:48 GMT 2020 + cpw: + Rollback registries to vanilla state if something happens during loading, so subsequent activities can still run and not generate false reports.. + + Signed-off-by: cpw + + cpw: + Add signature reporting for mods, using new signature capture from ModLauncher. Need to figure out + how to reflect Minecraft's JAR signatures into here. + + Signed-off-by: cpw + +========= +Build: 1.16.3-34.1.25 - Tue Oct 20 19:32:40 GMT 2020 + lexmanos: + Fix mcp_snapshot mapping issue causing unneeded patches. Closes #7424 + +========= +Build: 1.16.3-34.1.24 - Tue Oct 20 11:26:03 GMT 2020 + gigaherz: + Fix resource leak in the OBJ loader. + +========= +Build: 1.16.3-34.1.23 - Fri Oct 16 19:10:02 GMT 2020 + djbake101: + Fix issue with ITeleporter allowing easier use of vanilla logic. (#7317) + +========= +Build: 1.16.3-34.1.22 - Thu Oct 15 19:49:26 GMT 2020 + richard: + Adds tag support for Enchantments, Potions, and TileEntityTypes (#7379) + +========= +Build: 1.16.3-34.1.21 - Thu Oct 15 19:43:33 GMT 2020 + lexmanos: + Resuscitate BiomeDictionary using RegistryKeys instead of biome references. + +========= +Build: 1.16.3-34.1.20 - Thu Oct 15 17:15:15 GMT 2020 + ocelot5836: + Add event for player changing game mode (#7355) + +========= +Build: 1.16.3-34.1.19 - Mon Oct 12 18:11:22 GMT 2020 + cpw: + Fix RCON multipacket responses not actually understanding UTF8. + + Signed-off-by: cpw + +========= +Build: 1.16.3-34.1.18 - Mon Oct 12 01:49:09 GMT 2020 + cpw: + Fix RCON not sending newlines in output for multiline. Fixes https://bugs.mojang.com/browse/MC-7569, a very old bug that is really annoying if you use RCON. + + Signed-off-by: cpw + +========= +Build: 1.16.3-34.1.17 - Sat Oct 10 16:45:26 GMT 2020 + championash5357: + Fix Texture Presence String (#7408) + +========= +Build: 1.16.3-34.1.16 - Fri Oct 09 19:57:26 GMT 2020 + lexmanos: + Fix typo causing potential error in vine growth. Closes #7406 + Sort missing registry dumps by name, making it easier to read. + +========= +Build: 1.16.3-34.1.15 - Fri Oct 09 13:58:36 GMT 2020 + gigaherz: + Fixed conditional advancement loading when using the "advancements" array. + Added automatic generation of conditional advancements from the criteria in the conditional recipe entries. + Added advancement name calculation from the recipe ID. + +========= +Build: 1.16.3-34.1.14 - Thu Oct 08 21:08:45 GMT 2020 + 32142731+flanks255: + Additions to the mdk build.gradle to accommodate datagens. (#7398) + +========= +Build: 1.16.3-34.1.13 - Thu Oct 08 21:02:59 GMT 2020 + daemonumbra: + Added Basic Class-Level SAS Capability to checkSAS, added Vector4f to SAS (#7385) + +========= +Build: 1.16.3-34.1.12 - Wed Oct 07 20:04:11 GMT 2020 + richard: + Add hooks to allow modification of structures spawn lists (#7344) + +========= +Build: 1.16.3-34.1.11 - Tue Oct 06 19:38:36 GMT 2020 + richard: + Add back patches to Screen allowing for item tooltips to be auto wrapped again (#7378) + + Only deals with the methods receiving an ItemStack or ITextComponent(s), the methods that take IReorderingProcessor(s) are left alone. + +========= +Build: 1.16.3-34.1.10 - Mon Oct 05 14:34:56 GMT 2020 + adam: + Bump mixin version to 0.8.2 + +========= +Build: 1.16.3-34.1.9 - Mon Oct 05 10:30:12 GMT 2020 + cpw: + Remove redundant call to CrashReport generator - Vanilla is doing a crashreport for itself at startup now. + + Add a UUID into crashreport that is also logged in all channels at crash report generation time. This will allow to associate crash reports and the logs. + + Signed-off-by: cpw + + cpw: + Add in extra debug logging + + Signed-off-by: cpw + +========= +Build: 1.16.3-34.1.7 - Sun Oct 04 19:51:37 GMT 2020 + cpw: + Modify how ModLoadingStage handles dispatch to Registry Events. Stops the objectholder spam and generally improves performance on larger packs. + + Signed-off-by: cpw + + cpw: + Fix doc README and answer lex's question + + Signed-off-by: cpw + +========= +Build: 1.16.3-34.1.5 - Fri Oct 02 23:40:14 GMT 2020 + daemonumbra: + Added "Bukkit Plugin" to InvalidModIdentifier (#7384) + +========= +Build: 1.16.3-34.1.4 - Fri Oct 02 23:34:26 GMT 2020 + richard: + Fix vanilla Campfire smoke bug. MC-201374 (#7381) + +========= +Build: 1.16.3-34.1.3 - Fri Oct 02 23:28:31 GMT 2020 + sciwhiz12: + Fix toggleable keybindings still being active while in GUI Fixes #7370 (#7373) + +========= +Build: 1.16.3-34.1.2 - Fri Oct 02 22:06:59 GMT 2020 + dev: + Fix modded EntityClassifications not being useable in the codec. (#7337) + +========= +Build: 1.16.3-34.1.1 - Mon Sep 28 18:02:11 GMT 2020 + cech12: + Support effective materials of vanilla AxeItem (#7351) + +========= +Build: 1.16.3-34.1.0 - Thu Sep 24 07:05:13 GMT 2020 + lexmanos: + Prep new RB. + +========= +Build: 1.16.3-34.0.21 - Thu Sep 24 06:46:57 GMT 2020 + ichttt: + Fix grass disappearing when alwaysSetupTerrainOffThread is true (#7291) + +========= +Build: 1.16.3-34.0.20 - Thu Sep 24 06:41:41 GMT 2020 + 35673674+alcatrazescapee: + Accessors for inspecting and removal of biome generation settings. Fixed carvers still being immutable. (#7339) + +========= +Build: 1.16.3-34.0.19 - Thu Sep 24 06:36:25 GMT 2020 + lexmanos: + Revive BiomeManager and BiomeLayer hooks. + +========= +Build: 1.16.3-34.0.18 - Thu Sep 24 03:12:19 GMT 2020 + richard: + Fix a few minor issues with custom tag types and fix OptionalNamedTags (#7316) + +========= +Build: 1.16.3-34.0.17 - Wed Sep 23 22:10:11 GMT 2020 + diesieben07: + Fix ToggleableKeyBinding differences to vanilla. (#7338) + +========= +Build: 1.16.3-34.0.16 - Wed Sep 23 21:34:47 GMT 2020 + yunus1903: + Updated build badge versions to 1.16.3 in readme (#7325) + + diesieben07: + Fix forge light pipeline applying block offsets twice (#7323) + +========= +Build: 1.16.3-34.0.14 - Wed Sep 23 21:16:46 GMT 2020 + ichttt: + Add a better license error screen (#7350) + +========= +Build: 1.16.3-34.0.13 - Tue Sep 22 19:14:17 GMT 2020 + darklime: + Fixed container item being consumed in brewing stand. #7307 (#7314) + +========= +Build: 1.16.3-34.0.12 - Tue Sep 22 19:06:10 GMT 2020 + sciwhiz12: + Fix parse results of CommandEvent being disregarded (#7303) + +========= +Build: 1.16.3-34.0.11 - Tue Sep 22 18:58:28 GMT 2020 + 17338378+nightenom: + [1.16] Fix possible crash when using rendering regionCache (#7207) + +========= +Build: 1.16.3-34.0.10 - Tue Sep 22 18:41:16 GMT 2020 + 35673674+alcatrazescapee: + [1.16] Reimplement ICloudRenderHandler, ISkyRenderHandler and IWeatherRenderHandler (#6994) + +========= +Build: 1.16.3-34.0.9 - Fri Sep 18 00:58:08 GMT 2020 + 35673674+alcatrazescapee: + Make Biome.Climate and BiomeAmbiance fields accessible (#7336) + +========= +Build: 1.16.3-34.0.8 - Thu Sep 17 20:42:53 GMT 2020 + cpw: + Use mixin 0.8.1. Should fix problems with mixin not working properly with latest modlauncher. + + Signed-off-by: cpw + +========= +Build: 1.16.3-34.0.7 - Tue Sep 15 20:07:25 GMT 2020 + sebastian: + Sets the empty/fill sounds for vanilla fluids. + Use Fluid's fillSound rather than emptySound when filling buckets. + +========= +Build: 1.16.3-34.0.6 - Tue Sep 15 19:47:08 GMT 2020 + cyborgmas: + Add MatrixStack-aware alternatives to the methods in GuiUtils (#7127) + +========= +Build: 1.16.3-34.0.5 - Tue Sep 15 16:51:58 GMT 2020 + thelonedevil: + Fix json biomes not setting registry name correctly for the BiomeLoadingEvent. (#7329) + +========= +Build: 1.16.3-34.0.4 - Tue Sep 15 14:18:16 GMT 2020 + gigaherz: + Fix inconsistencies in how the values from the model are passed into the baked model. + This puts them in line with vanilla, as intended. + +========= +Build: 1.16.3-34.0.3 - Tue Sep 15 13:23:05 GMT 2020 + yunus1903: + Reimplemented drawHoveringText (#7268) + +========= +Build: 1.16.3-34.0.2 - Tue Sep 15 00:43:19 GMT 2020 + lexmanos: + New BiomeLoadingEvent that allows modders to edit biomes as they are being deserialized. + +========= +Build: 1.16.3-34.0.1 - Fri Sep 11 15:55:28 GMT 2020 + lexmanos: + Bump MCP version for lambda issue. + +========= +Build: 1.16.3-34.0.0 - Thu Sep 10 19:10:33 GMT 2020 + lexmanos: + 1.16.3 Update + Also included a bunch of warning cleanups. + +========= +Build: 1.16.2-33.0.61 - Thu Sep 10 18:54:56 GMT 2020 + redstonedubstep: + Fix tile entities being replaced when not needed. (#7318) + +========= +Build: 1.16.2-33.0.60 - Thu Sep 10 18:02:15 GMT 2020 + malte0811: + Fix exception when getting rendering box for tile entities with no collision boxes. (#7301) + +========= +Build: 1.16.2-33.0.59 - Wed Sep 09 23:05:21 GMT 2020 + cpw: + More crash reporting tweaks. Don't crash when trying to show warnings. Also, put the exception name in the error screen on the second line! + + Signed-off-by: cpw + +========= +Build: 1.16.2-33.0.58 - Wed Sep 09 17:09:09 GMT 2020 + diesieben07: + Fix Minecart speed cap on rail being initialized to 0 (#7315) + +========= +Build: 1.16.2-33.0.57 - Wed Sep 09 02:10:45 GMT 2020 + richard: + Add support for custom tag types (#7289) + +========= +Build: 1.16.2-33.0.56 - Wed Sep 09 00:06:22 GMT 2020 + cpw: + More crash report tweaks. Put a button to open the generated crash report on the error screen, tweak formatting of crash report, and add the enhanced stack trace data (transformers et al) + + Signed-off-by: cpw + +========= +Build: 1.16.2-33.0.55 - Tue Sep 08 21:00:19 GMT 2020 + championash5357: + New hook for better custom scaffolding movement (#7261) + +========= +Build: 1.16.2-33.0.54 - Tue Sep 08 20:47:48 GMT 2020 + mrtschipp: + Add partialTicks to RenderNameplateEvent (#7277) + + cyborgmas: + Prevent duplicate wrapper tags from crashing (#7283) + + mrp-v2: + Fix custom teleporters NPE (#7296) + + cyborgmas: + Fixed crash with zip paths (#7300) + +========= +Build: 1.16.2-33.0.50 - Tue Sep 08 20:23:27 GMT 2020 + nrbeech: + Fixing logic in getCurrentRailPosition to correctly identify the rail… (#7276) + +========= +Build: 1.16.2-33.0.49 - Tue Sep 08 20:14:58 GMT 2020 + sciwhiz12: + Remove dead ForgeHooks.canToolHarvestBlock function. (#7262) + + sciwhiz12: + Bump resource pack version to 6 (#7299) + + edwin.mindcraft: + [1.16.x] Fixes for Bamboo, Enchantments and Conduits, small adjustments to bring some patches closer to the vanilla code. (#7239) + +========= +Build: 1.16.2-33.0.46 - Tue Sep 08 19:50:14 GMT 2020 + championash5357: + Re-implement DrawHighlightEvent$HighlightEntity Firing (#7233) + +========= +Build: 1.16.2-33.0.45 - Tue Sep 08 19:25:58 GMT 2020 + ichttt: + Reimplement FarmlandWaterManager (#7213) + +========= +Build: 1.16.2-33.0.44 - Tue Sep 08 19:11:16 GMT 2020 + cyborgmas: + Add dataprovider for Global Loot Modifiers (#6960) + +========= +Build: 1.16.2-33.0.43 - Tue Sep 08 19:01:09 GMT 2020 + ichttt: + Fix crash when dumping crash report for an exception that has a null cause (#7308) + +========= +Build: 1.16.2-33.0.42 - Mon Sep 07 01:29:40 GMT 2020 + cpw: + Tweak crash report dump to visit all the causes up to the top. + + Signed-off-by: cpw + +========= +Build: 1.16.2-33.0.41 - Sun Sep 06 23:39:13 GMT 2020 + cpw: + Fix ExplodedDirectoryLocator visiting non-existent paths. Closes #7203 + + Also, bump modlauncher to 7.0.1 to fix resources. + + Signed-off-by: cpw + +========= +Build: 1.16.2-33.0.40 - Sun Sep 06 22:08:22 GMT 2020 + cpw: + Use new enumeration mechanism in ModLauncher, to allow getResources to work. This enables serviceloader-in-mods, and other stuff that might need to visit multiple mod jars. Also, tweaked the visitor code slightly, may result in a trivial performance change. Closing #7302 as it's not really relevant any more. + + Signed-off-by: cpw + + cpw: + Park the polling thread for a bit, if we're not the one driving the task list forwards. This allows for the actual driver to work on low cpu count machines. + + Signed-off-by: cpw + + cpw: + Fix some potential issues in crash dumping during mod loading + + Signed-off-by: cpw + +========= +Build: 1.16.2-33.0.37 - Thu Sep 03 16:37:38 GMT 2020 + cpw: + Fix compiler issue in eclipse properly + + Signed-off-by: cpw + +========= +Build: 1.16.2-33.0.36 - Thu Sep 03 12:40:52 GMT 2020 + sciwhiz12: + Fix crash caused by previous commit (#7298) + +========= +Build: 1.16.2-33.0.35 - Thu Sep 03 04:15:27 GMT 2020 + lexmanos: + Dirty casting hacks to fix eclipse compiler inference issue. I'm sorry cpw. + +========= +Build: 1.16.2-33.0.34 - Thu Sep 03 03:38:16 GMT 2020 + tterrag: + Fix broken ExistingFileHelper import + + Add licenses to some new files + + tterrag: + Add validation via resources for tag providers (#7271) + + BREAKING CHANGE: Moved ExistingFileHelper to common package + Remove various workarounds from forge tag providers + +========= +Build: 1.16.2-33.0.32 - Tue Sep 01 18:36:21 GMT 2020 + cpw: + Move the "modloading" thread activity onto _our_ worker pool. It turns out that the vanilla worker pool can deadlock during stitching if it's insufficiently large, if modloader "waitForTransition" is also a worker member of that pool. + + Closes #7293 (to reproduce issue easily, modify Util.func_240979_a_ and change the values in the MathHelper.clamp call). I've verified that 3 and below for "max" cause the problem. (I didn't test a whole range of values, just sufficient to reproduce problem and verify fix). Note that setting it to zero (and using the "direct executor" that's inaccessible in normal operation) works as well with this fix. + + Signed-off-by: cpw + +========= +Build: 1.16.2-33.0.31 - Tue Sep 01 02:27:07 GMT 2020 + cpw: + Fix missed debugging code. Read the config from the config. + + Signed-off-by: cpw + +========= +Build: 1.16.2-33.0.30 - Tue Sep 01 01:31:57 GMT 2020 + cpw: + Revert "Shut down all other mod handlers if the loading cycle errors. This prevents other mods from throwing errors and being blamed for initial cause. This is a temporary hack until cpw re-writes the mod event dispatcher." + + This reverts commit 7592bbe8 + + Signed-off-by: cpw + + cpw: + Revert "Properly shutdown FMLModContainer's event bus when an error in a lifecycle event is detected." + + This reverts commit 30bad1e2 + + Signed-off-by: cpw + + cpw: + Redo event dispatch, removes a bunch of nonsense, and tries to integrate with the vanilla CF system where possible + + Signed-off-by: cpw + + cpw: + Fix up all the things. Removed SidedProvider because it served no real purpose anymore. + + Signed-off-by: cpw + + cpw: + Fix up slight registry change and other 1.16.2 stuffs. + + Signed-off-by: cpw + +========= +Build: 1.16.2-33.0.23 - Sun Aug 30 23:05:24 GMT 2020 + ichttt: + Add particle culling (#6981) + +========= +Build: 1.16.2-33.0.22 - Wed Aug 26 16:50:02 GMT 2020 + lexmanos: + Wrap vanilla's 'default' biome registry in ForgeRegistry. + This should allow registering mod dimensions like in 1.16.1, while the data driven system is fleshed out. + +========= +Build: 1.16.2-33.0.21 - Tue Aug 25 01:11:38 GMT 2020 + gigaherz: + Clarify in the LazyOptional which methods carry the lazyness over to the returned value and which don't. (#6750) + + For consistency, this meant making a few changes: + - Renamed the existing lazy mapping method to lazyMap, to indicate that it doesn't run the mapping immediately. + - Added a new implementation of map(), which returns Optional, and resolves the value in the process. + - Changed filter() to return Optional, since there's no way to filter lazily. + - Added a new method resolve(), which helps convert the custom LazyOptional class into a standard Optional, for use + with library methods that expect Optional. + + * Update License headers. + +========= +Build: 1.16.2-33.0.20 - Fri Aug 21 21:27:21 GMT 2020 + sciwhiz12: + Add user-friendly exceptions when config loading fails (#7214) + +========= +Build: 1.16.2-33.0.19 - Fri Aug 21 18:53:46 GMT 2020 + dev: + Replace EntityHeight event with EntitySize event (#6858) + +========= +Build: 1.16.2-33.0.18 - Fri Aug 21 18:38:31 GMT 2020 + davide2910: + [1.16] ForgeEventFactory#canCreateFluidSource reintroduced (#7181) + +========= +Build: - Fri Aug 21 18:31:19 GMT 2020 + cyborgmas: + Cleanup and expand Forge tags (#7004) + +========= +Build: 1.16.2-33.0.16 - Fri Aug 21 18:25:49 GMT 2020 + sciwhiz12: + Fix modproperties property in mods.toml causing exception (#7192) + +========= +Build: 1.16.2-33.0.15 - Fri Aug 21 18:15:53 GMT 2020 + me: + Log info about server list warning (#7209) + + Make it easier to figure out what mods are missing or have to be marked as client/server side only. + +========= +Build: 1.16.2-33.0.14 - Fri Aug 21 18:06:47 GMT 2020 + goto.minecraft: + Fix ItemStack#isDamageable is not calling Item#isDamagable (#7221) + +========= +Build: 1.16.2-33.0.13 - Fri Aug 21 17:48:58 GMT 2020 + diesieben07: + Improve performance and cleanup code for DelegatingResourcePack (#7228) + +========= +Build: 1.16.2-33.0.12 - Fri Aug 21 17:29:33 GMT 2020 + cyborgmas: + Fix small logging issues with loading pack.png for mods (#7265) + +========= +Build: 1.16.2-33.0.11 - Fri Aug 21 17:23:30 GMT 2020 + diesieben07: + Fix config iteration order (#7230) + +========= +Build: 1.16.2-33.0.10 - Fri Aug 21 09:47:23 GMT 2020 + lexmanos: + Cleanup Forge's build script, fix some unneeded patches. + Add checkExcscheckAll tasks. + +========= +Build: 1.16.2-33.0.9 - Fri Aug 21 04:35:17 GMT 2020 + championash5357: + Readding DifficultyChangeEvent hooks (#7240) + +========= +Build: 1.16.2-33.0.8 - Fri Aug 21 04:29:10 GMT 2020 + malte0811: + Improve startup time by caching the manifest data for mod jars (#7256) + +========= +Build: 1.16.2-33.0.7 - Wed Aug 19 05:47:46 GMT 2020 + yunus1903: + Removed HarvestDropsEvent (#7193) + +========= +Build: 1.16.2-33.0.6 - Wed Aug 19 05:22:45 GMT 2020 + cyborgmas: + Remove forge optional tags in favor of Vanilla's new system. (#7246) + +========= +Build: 1.16.2-33.0.5 - Fri Aug 14 19:05:15 GMT 2020 + lexmanos: + Fix creating nether portals. + + lexmanos: + New method for creating modded tag references, fix connecting to vanilla servers. + +========= +Build: 1.16.2-33.0.3 - Fri Aug 14 02:17:01 GMT 2020 + 43609023+spnda: + Print mod file name on InvalidModFileException (#7241) + +========= +Build: 1.16.2-33.0.2 - Thu Aug 13 19:26:22 GMT 2020 + cyborgmas: + Fix server connection, misapplied patch (#7245) + + yunus1903: + Updated MDK and README for 1.16.2 (#7243) + +========= +Build: 1.16.2-33.0.0 - Thu Aug 13 07:37:04 GMT 2020 + lexmanos: + Initial 1.16.2 Update + +========= +Build: 1.16.1-32.0.108 - Sun Aug 09 20:05:01 GMT 2020 + gigaherz: + Fix ModelRegistryEvent firing every time resources reload instead of just once. + +========= +Build: 1.16.1-32.0.107 - Sat Aug 08 01:00:42 GMT 2020 + gigaherz: + Move ModelRegistryEvent invocation to when the model loading is about to start. + Freeze the ModelLoaderRegistry right after this event happens, just before model loading actually begins. + This means ModelRegistryEvent is now the correct place to register loaders, as it was intended. + This is a slight breaking change, but any mod that used FMLClientSetupEvent before will need to be updated regardless due to the existing race condition. + +========= +Build: 1.16.1-32.0.106 - Tue Aug 04 00:19:22 GMT 2020 + diesieben07: + Fix wrong BlockState param passed into canSustainPlant from FarmlandBlock (#7212) + +========= +Build: 1.16.1-32.0.105 - Tue Aug 04 00:06:45 GMT 2020 + sciwhiz12: + Add harvest levels for hoes and new 1.16 blocks for pickaxes Fixes #7187 (#7189) + +========= +Build: 1.16.1-32.0.104 - Tue Aug 04 00:00:40 GMT 2020 + sciwhiz12: + Fix debug world not generating modded blocks (#6926) + + championash5357: + New IForgeBlock#getToolModifiedState hook allow better control over tools interacting with blocks. (#7176) + + email.squishling: + Added new hook to allow Biomes to control their Edge biomes (#7000) + +========= +Build: 1.16.1-32.0.101 - Mon Aug 03 22:55:18 GMT 2020 + diesieben07: + Re-introduce "outdated" notification on Mods button in main menu (#7123) + + brandon4261: + Add support for custom elytra (#7202) + +========= +Build: 1.16.1-32.0.99 - Mon Aug 03 18:53:31 GMT 2020 + sciwhiz12: + Fix RenderTickEvent using wrong partial ticks value when game is paused. Fixes #6991 (#7208) + +========= +Build: 1.16.1-32.0.98 - Thu Jul 30 03:18:00 GMT 2020 + tterrag: + Implement forge IBakedModel methods in vanilla wrapper models + +========= +Build: 1.16.1-32.0.97 - Tue Jul 28 23:44:41 GMT 2020 + lexmanos: + Fix another case of swallowed errors not shutting down mods. + +========= +Build: 1.16.1-32.0.96 - Tue Jul 28 21:40:06 GMT 2020 + lexmanos: + Shut down all other mod handlers if the loading cycle errors. + This prevents other mods from throwing errors and being blamed for initial cause. + This is a temporary hack until cpw re-writes the mod event dispatcher. + +========= +Build: - Tue Jul 28 19:01:27 GMT 2020 + lexmanos: + Properly shutdown FMLModContainer's event bus when an error in a lifecycle event is detected. + + lexmanos: + Enable EventBus type check during ForgeDev, and add IModBusEvent marker to ModelRegistryEvent. + +========= +Build: 1.16.1-32.0.93 - Tue Jul 28 07:16:31 GMT 2020 + lexmanos: + Make license toml entry optional during 1.16.1 + There are to many existing mods to make this required. + Yes, we are technically before a RB and can do breaking changes. However this is too large. + +========= +Build: 1.16.1-32.0.92 - Tue Jul 28 01:14:20 GMT 2020 + cpw: + Missed one event. NewRegistry needs the marker. + + Signed-off-by: cpw + +========= +Build: 1.16.1-32.0.91 - Tue Jul 28 01:07:03 GMT 2020 + cpw: + Update MDK license to default to All rights reserved, and offer a link to chooseyourlicense.com as a place to research appropriate licenses. + + Note: the license field _is_ backwards compatible and will simply be ignored on older forge versions. + Signed-off-by: cpw + +========= +Build: 1.16.1-32.0.90 - Tue Jul 28 00:47:35 GMT 2020 + cpw: + Update modlauncher, eventbus, accesstransformers and more to use a newer mechanism for generating ASM. + + Introduced IModBusEvent as a marker interface for events on the ModBus. Expect exceptions if you use + the modbus for events not listened there. + + Signed-off-by: cpw + + cpw: + Update coremods and spi, include mandatory license field in metadata. Added at top level of mods.toml file. + + Signed-off-by: cpw + +========= +Build: 1.16.1-32.0.88 - Mon Jul 27 23:35:24 GMT 2020 + ray.neiheiser: + Fix rail 180 rotations (#7177) + + jmansfield: + Fire AnimalTameEvent for cats (#7172) Closes #7171 + +========= +Build: 1.16.1-32.0.86 - Mon Jul 27 22:56:16 GMT 2020 + lexmanos: + Fix Biome generation error. + +========= +Build: 1.16.1-32.0.85 - Mon Jul 27 21:36:07 GMT 2020 + dev: + Fix SleepingTimeCheckEvent not being fired in initial sleep test. (#7005) + +========= +Build: 1.16.1-32.0.84 - Mon Jul 27 21:30:24 GMT 2020 + yunus1903: + Fix ClimberPathNavigator spinning when width is small. Closes #6993 (#6997) + +========= +Build: 1.16.1-32.0.83 - Mon Jul 27 21:19:50 GMT 2020 + mrtschipp: + Re-added PlayerEvent.NameFormat (#6992) + +========= +Build: 1.16.1-32.0.82 - Mon Jul 27 21:14:02 GMT 2020 + email.squishling: + Fixed modded overworld biomes not spawning [1.16.x] (#6990) + +========= +Build: 1.16.1-32.0.81 - Mon Jul 27 21:08:23 GMT 2020 + christ.klinge: + Added EntityLeaveWorldEvent (#6984) + +========= +Build: 1.16.1-32.0.80 - Mon Jul 27 21:02:53 GMT 2020 + aqscode: + Re-implement moddable flammabilities (#6983) + +========= +Build: 1.16.1-32.0.79 - Mon Jul 27 20:46:11 GMT 2020 + diesieben07: + Re-add patch for PlayerSetSpawnEvent (#6977) + + yunus1903: + Updated versions in README and removed flocker.tv mentions (#6978) + +========= +Build: 1.16.1-32.0.77 - Mon Jul 27 20:40:33 GMT 2020 + sciwhiz12: + Fix ChunkDataEvents using different data tags (#6961) Fixes #6957 + +========= +Build: - Mon Jul 27 20:27:00 GMT 2020 + sm0keysa1m0n: + Post SoundLoadEvent on mod bus instead of forge bus (#6955) + +========= +Build: 1.16.1-32.0.75 - Wed Jul 22 01:26:19 GMT 2020 + cpw: + Remove startupquery. Currently wasn't functional, and 1.16 has out of band state loading in all cases, so the complex functionality there is no longer needed. Going to research using the Lifecycle indicator from DFU as a proxy/replacement. Probably with some codec FUN. + + Signed-off-by: cpw + +========= +Build: 1.16.1-32.0.74 - Wed Jul 22 00:34:43 GMT 2020 + lexmanos: + Run Forge's data generators to sync 1.16 vanilla changes. + +========= +Build: 1.16.1-32.0.73 - Wed Jul 22 00:13:48 GMT 2020 + cpw: + Don't show the early launcher GUI when running data. It's not needed and prevents use on automated builds. + + Need to investigate why a bunch of tags seem to be being blown away by rerunning on forge. + + Signed-off-by: cpw + +========= +Build: 1.16.1-32.0.72 - Tue Jul 21 23:56:54 GMT 2020 + cpw: + Add mixin + + Signed-off-by: cpw + +========= +Build: 1.16.1-32.0.71 - Mon Jul 20 22:56:31 GMT 2020 + cyborgmas: + Load Modded Datapacks in DatapackScreen, before world creation (#6913) + +========= +Build: 1.16.1-32.0.70 - Sat Jul 18 22:35:53 GMT 2020 + tterrag: + Fix inconsistencies with model/blockstate datagen + +========= +Build: 1.16.1-32.0.69 - Fri Jul 17 17:35:47 GMT 2020 + dev: + Filter duplicate mod files from mod file scan data (#6855) + +========= +Build: 1.16.1-32.0.68 - Thu Jul 16 21:56:30 GMT 2020 + lexmanos: + Fixed Forge commands. Closes #6973 Closes #6974 Closes #6976 + +========= +Build: 1.16.1-32.0.67 - Wed Jul 15 19:30:53 GMT 2020 + jaredlll08: + Added an event for registering commands. closes #6968 (#6969) + +========= +Build: 1.16.1-32.0.66 - Tue Jul 14 00:15:41 GMT 2020 + darklime: + Make all functions in Style common. (#6931) + +========= +Build: 1.16.1-32.0.65 - Mon Jul 13 22:44:53 GMT 2020 + 55965249+seymourimadeit: + Mark Raid.WaveMembers as an extensible enum. (#6878) + +========= +Build: 1.16.1-32.0.64 - Mon Jul 13 22:17:58 GMT 2020 + lexmanos: + Fix checkPatches task. Closes #6956 + Fix patched in method using srg name. Closes #6965 + Fix capabilities not being collected for ClientWorld. Closes #6966 + Fix TagEmptyCondition using client side copy of tags instead of server. Closes #6949 + Fix ExtendedButton using narrator text. Closes #6958, Closes #6959 + Fix misaligned patch in RepairContainer. Closes #6950, Closes #6953 + Fix LivingJumpEvent not being fired for players jumping horses. Closes #6929 + Remove extra getToughness method in ArmorItem. Closes #6970 + Remove GetCollisionBoxesEvent. Closes #6921 + +========= +Build: 1.16.1-32.0.63 - Fri Jul 10 22:28:22 GMT 2020 + richard: + Fix race condition with DeferredRegister for custom registries (#6951) + +========= +Build: 1.16.1-32.0.62 - Fri Jul 10 17:49:51 GMT 2020 + sciwhiz12: + Remove hooks into beacon base/payments. Vanilla uses tags now for extensibility. (#6948) + +========= +Build: 1.16.1-32.0.61 - Wed Jul 08 21:33:38 GMT 2020 + jaredlll08: + Expose the DataPackRegistries instance to the AddReloadListenerEvent (#6933) + +========= +Build: 1.16.1-32.0.60 - Wed Jul 08 21:13:18 GMT 2020 + sciwhiz12: + Fix canRepair not being set true as default (#6936) + + Closes #6934 and #6935 + +========= +Build: 1.16.1-32.0.59 - Wed Jul 08 14:56:39 GMT 2020 + gigaherz: + Fix particles sometimes "losing" the lightmap and drawing fullbright. + + gigaherz: + Fix misaligned patch causing LivingEquipmentChangeEvent to never be posted. + +========= +Build: 1.16.1-32.0.57 - Mon Jul 06 21:32:33 GMT 2020 + jdlogic: + Add simple patch checker and cleanup patches (#6851) + + * Add simple patch checker and cleanup patches + + * Address comments + * move task implementation + * genPatches is now finalized by checkPatches + * the S2S artifacts are automatically removed + * added class and method access checking + +========= +Build: 1.16.1-32.0.56 - Mon Jul 06 21:27:02 GMT 2020 + richard: + Fix the modifier combined name for keybinds displaying two pluses outside of forgedev #6901 (#6902) + +========= +Build: 1.16.1-32.0.55 - Mon Jul 06 21:12:45 GMT 2020 + richard: + Fix harvest level and tool type not actually getting set #6906 (#6922) + +========= +Build: 1.16.1-32.0.54 - Mon Jul 06 20:46:01 GMT 2020 + richard: + Reimplement ITeleporter Patches (#6886) + +========= +Build: 1.16.1-32.0.53 - Mon Jul 06 20:39:37 GMT 2020 + 40738104+mysterious-dev: + Add function to add items with the same behavior as the pumpkin for enderman (#6890) + +========= +Build: 1.16.1-32.0.52 - Mon Jul 06 20:33:17 GMT 2020 + richard: + Custom Item integration with Piglins (#6914) + +========= +Build: 1.16.1-32.0.51 - Mon Jul 06 20:20:02 GMT 2020 + ichttt: + Some dead code cleanup, and re-implement some bed hooks. (#6903) + +========= +Build: 1.16.1-32.0.50 - Mon Jul 06 20:06:39 GMT 2020 + diesieben07: + Fix missing null checks in ForgeIngameGui (#6907) + +========= +Build: 1.16.1-32.0.49 - Mon Jul 06 19:50:02 GMT 2020 + sciwhiz12: + Fix swap offhand keybind not working in GUIs (#6920) + +========= +Build: 1.16.1-32.0.48 - Mon Jul 06 19:42:07 GMT 2020 + cyborgmas: + New AddReloadListenerEvent that gathers server side data reload handlers. (#6849) + +========= +Build: 1.16.1-32.0.47 - Fri Jul 03 12:40:42 GMT 2020 + gigaherz: + Attempt to use a more compatible method to initialize stencil support. + In case the separate attachments don't work for everyone, there's a new setting to choose the combined attachment. + +========= +Build: 1.16.1-32.0.46 - Fri Jul 03 04:00:22 GMT 2020 + gigaherz: + Update copyright year to 2020. + + gigaherz: + Fix multi-layer item rendering. + +========= +Build: 1.16.1-32.0.44 - Thu Jul 02 17:17:45 GMT 2020 + gigaherz: + Model system improvements: + - Port some things I did in 1.14 which I couldn't do in 1.15 due to breaking changes. + - Fix multi-layer block models not working (1.16 RenderType doesn't override toString the same way anymore) + - Implement multi-layer item rendering. + - Improve CompositeModel submodel data passing. + +========= +Build: 1.16.1-32.0.43 - Thu Jul 02 12:54:03 GMT 2020 + supermartijn642: + Include model data in getQuads call (#6884) + + The model data wasn't included when getting quads from specific sides, but was when getting quads for side = null. + + cyborgmas: + Pass matrixstack in tooltip render events (#6885) + +========= +Build: 1.16.1-32.0.41 - Thu Jul 02 05:54:25 GMT 2020 + tterrag: + Fix improper handling of baked lighting in forge light pipeline + + Closes #6812 + +========= +Build: 1.16.1-32.0.40 - Thu Jul 02 01:59:30 GMT 2020 + pupnewfster: + Fix FMLServerAboutToStartEvent being fired too late on the integrated server https://github.com/MinecraftForge/MinecraftForge/issues/6859 + +========= +Build: 1.16.1-32.0.39 - Wed Jul 01 18:14:25 GMT 2020 + ichttt: + Fix miss-aligned patch ItemEntity (#6895) + +========= +Build: 1.16.1-32.0.38 - Tue Jun 30 20:19:32 GMT 2020 + melanx: + Add hoe tool type (#6872) + +========= +Build: 1.16.1-32.0.36 - Tue Jun 30 20:09:21 GMT 2020 + curle: + Allow any armor to have custom knockback resistance (#6877) + +========= +Build: 1.16.1-32.0.35 - Tue Jun 30 19:57:32 GMT 2020 + diesieben07: + Add senderUUID to ClientChatReceivedEvent (#6881) + +========= +Build: 1.16.1-32.0.34 - Tue Jun 30 02:33:58 GMT 2020 + lexmanos: + Re-write checkATs function and automate making Items/Blocks public. + +========= +Build: 1.16.1-32.0.33 - Tue Jun 30 02:10:14 GMT 2020 + cpw: + Reorganize modloading on the dediserver. This removes the DedicatedServer parameter from the FMLDedicatedServerSetupEvent. + Code for customizing the server instance should be moved to the ServerAboutToStartEvent or similar, where the server instance + is available. + + This reorganization means that mods will load fully before the server is even constructed, or the server properties loaded. We also move the EULA right to the front so we don't have to wait for bootstrap. + + This should fix the problems with mods which customize world data and other things. + + Signed-off-by: cpw + +========= +Build: 1.16.1-32.0.32 - Mon Jun 29 23:43:01 GMT 2020 + cyborgmas: + Fix datagen resolving tags and exploding. (#6865) + +========= +Build: 1.16.1-32.0.31 - Mon Jun 29 23:37:30 GMT 2020 + mattmess1221: + Fix Language.javaLocale parsing (#6862) + +========= +Build: 1.16.1-32.0.30 - Mon Jun 29 22:58:30 GMT 2020 + diesieben07: + Fix IItemHandler wrappers for chests not updating both chests (#6875) + +========= +Build: 1.16.1-32.0.29 - Mon Jun 29 21:08:55 GMT 2020 + lexmanos: + Fix missed patch in PlayerList and EntitySelectioonContext. Closes #6846 Closes #6850 + +========= +Build: 1.16.1-32.0.27 - Mon Jun 29 20:09:12 GMT 2020 + richard: + Fix access levels being hardcoded to private via patch overriding AT entry (#6848) + +========= +Build: 1.16.1-32.0.26 - Mon Jun 29 19:42:50 GMT 2020 + lexmanos: + Fix tag related issues when connecting to a vanilla server. + +========= +Build: 1.16.1-32.0.25 - Sun Jun 28 22:08:15 GMT 2020 + lexmanos: + Fix Forge's internal handler being registered in wrong place. + Fix double call to loader end. + +========= +Build: 1.16.1-32.0.24 - Sat Jun 27 22:50:54 GMT 2020 + gigaherz: + Add a model loader that lets mods specify different models for different perspectives. + Allow custom models to reference vanilla item models as child models. + +========= +Build: 1.16.1-32.0.23 - Fri Jun 26 23:55:23 GMT 2020 + cyborgmas: + fix misapplied patch + + also sneak in an import patch removal + +========= +Build: 1.16.1-32.0.21 - Fri Jun 26 22:40:19 GMT 2020 + lexmanos: + Fix blocks being harvested with incorrect tools. + +========= +Build: 1.16.1-32.0.20 - Fri Jun 26 19:53:02 GMT 2020 + lexmanos: + Make installer use MCPConfig version to identify MC assets. + +========= +Build: 1.16.1-32.0.19 - Fri Jun 26 18:27:49 GMT 2020 + cpw: + Tweak the server startup a bit, make sure methods that can't work because they run before a server exists explode saying so. + Also fix other launch profiles. + + Signed-off-by: cpw + +========= +Build: 1.16.1-32.0.18 - Fri Jun 26 16:56:37 GMT 2020 + lexmanos: + Fix dedicated server loading by constructing mods before data packs are created. + +========= +Build: 1.16.1-32.0.17 - Fri Jun 26 15:20:37 GMT 2020 + gigaherz: + Fix create method. + Fix test mods not loading correctly. + +========= +Build: 1.16.1-32.0.16 - Fri Jun 26 14:43:19 GMT 2020 + gigaherz: + Reintroduce missed patch in EntityClassification. + +========= +Build: 1.16.1-32.0.15 - Fri Jun 26 13:55:42 GMT 2020 + cyborgmas: + Include a getter for the matrix stack in OverlayEvent (#6834) + +========= +Build: 1.16.1-32.0.14 - Fri Jun 26 13:23:07 GMT 2020 + cyborgmas: + Fix block render types not being properly applied to item entities (#6832) + +========= +Build: 1.16.1-32.0.13 - Fri Jun 26 13:05:18 GMT 2020 + mods.itsmeow: + [1.16.x] Allow GlobalEntityTypeAttributes' EntityType -> AttributeModifierMap to be added to (#6822) + + * Make GlobalEntityTypeAttributes map able to be added to + + * Split get patch into two lines + + * Favor Forge's map over vanilla + +========= +Build: 1.16.1-32.0.12 - Fri Jun 26 12:59:19 GMT 2020 + cyborgmas: + Fixed creative screen arrows (#6827) + + yunus1903: + Added call to method for tooltip with FontRenderer (#6831) + +========= +Build: 1.16.1-32.0.10 - Fri Jun 26 12:36:59 GMT 2020 + curle: + Retarget Block.Properties patch to the new AbstractBlock, reintroduce harvestLevel and harvestTool fields (#6819) + + * Retarget Block.Properties patch to the new AbstractBlock, reintroduces the harvestLevel and harvestTool fields. + + * Slight adjustment to fix the lootTableSupplier. + +========= +Build: 1.16.1-32.0.9 - Fri Jun 26 12:31:37 GMT 2020 + yunus1903: + Fixed sneaking while swimming (#6817) + +========= +Build: - Fri Jun 26 12:25:07 GMT 2020 + cyborgmas: + Fixed tooltip rendering issues (#6815) + +========= +Build: 1.16.1-32.0.7 - Fri Jun 26 02:30:54 GMT 2020 + cyborgmas: + Fixed villager trades having non-applicable enchants + + Also added an AT at lex's request + +========= +Build: 1.16.1-32.0.6 - Fri Jun 26 01:52:19 GMT 2020 + cyborgmas: + Fix locate command (#6811) + + cyborgmas: + Fix block drops (#6810) + + contact: + Add missing patch to ScreenShotHelper (#6809) + + Adds the missed patch back + + yunus1903: + Updated MDK mods.toml versions (#6808) + + cyborgmas: + Fix locate command (#6811) + + cyborgmas: + Fix block drops (#6810) + + contact: + Add missing patch to ScreenShotHelper (#6809) + + Adds the missed patch back + + yunus1903: + Updated MDK mods.toml versions (#6808) + + cyborgmas: + Fix locate command (#6811) + + cyborgmas: + Fix block drops (#6810) + + contact: + Add missing patch to ScreenShotHelper (#6809) + + Adds the missed patch back + + yunus1903: + Updated MDK mods.toml versions (#6808) + +========= +Build: 1.16.1-32.0.2 - Fri Jun 26 01:41:51 GMT 2020 + lexmanos: + Rework BlockSnapshot and fix client notifications. Closes #6807 + +========= +Build: 1.16.1-32.0.1 - Thu Jun 25 23:24:48 GMT 2020 + lexmanos: + Bump MCPConfig version. diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 0000000..a7bcc4b --- /dev/null +++ b/gradle.properties @@ -0,0 +1,6 @@ +# Sets default memory used for gradle commands. Can be overridden by user or command line properties. +# This is required to provide enough memory for the Minecraft decompilation process. +org.gradle.jvmargs=-Xmx3G +org.gradle.daemon=false +mc_version=1.16.5 +jei_version=7.7.1.152 \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..e708b1c023ec8b20f512888fe07c5bd3ff77bb8f GIT binary patch literal 59203 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

K7UpUK$>l@ zw`1S}(D?mUXu_C{wupRS-jiX~w=Uqqhf|Vb3Cm9L=T+w91Cu^ z*&Ty%sN?x*h~mJc4g~k{xD4ZmF%FXZNC;oVDwLZ_WvrnzY|{v8hc1nmx4^}Z;yriXsAf+Lp+OFLbR!&Ox?xABwl zu8w&|5pCxmu#$?Cv2_-Vghl2LZ6m7}VLEfR5o2Ou$x02uA-%QB2$c(c1rH3R9hesc zfpn#oqpbKuVsdfV#cv@5pV4^f_!WS+F>SV6N0JQ9E!T90EX((_{bSSFv9ld%I0&}9 zH&Jd4MEX1e0iqDtq~h?DBrxQX1iI0lIs<|kB$Yrh&cpeK0-^K%=FBsCBT46@h#yi!AyDq1V(#V}^;{{V*@T4WJ&U-NTq43w=|K>z8%pr_nC>%C(Wa_l78Ufib$r8Od)IIN=u>417 z`Hl{9A$mI5A(;+-Q&$F&h-@;NR>Z<2U;Y21>>Z;s@0V@SbkMQQj%_;~+qTuQ?c|AV zcWm3XZQHhP&R%QWarS%mJ!9R^&!_)*s(v+VR@I#QrAT}`17Y+l<`b-nvmDNW`De%y zrwTZ9EJrj1AFA>B`1jYDow}~*dfPs}IZMO3=a{Fy#IOILc8F0;JS4x(k-NSpbN@qM z`@aE_e}5{!$v3+qVs7u?sOV(y@1Os*Fgu`fCW9=G@F_#VQ%xf$hj0~wnnP0$hFI+@ zkQj~v#V>xn)u??YutKsX>pxKCl^p!C-o?+9;!Nug^ z{rP!|+KsP5%uF;ZCa5F;O^9TGac=M|=V z_H(PfkV1rz4jl?gJ(ArXMyWT4y(86d3`$iI4^l9`vLdZkzpznSd5Ikfrs8qcSy&>z zTIZgWZGXw0n9ibQxYWE@gI0(3#KA-dAdPcsL_|hg2@~C!VZDM}5;v_Nykfq!*@*Zf zE_wVgx82GMDryKO{U{D>vSzSc%B~|cjDQrt5BN=Ugpsf8H8f1lR4SGo#hCuXPL;QQ z#~b?C4MoepT3X`qdW2dNn& zo8)K}%Lpu>0tQei+{>*VGErz|qjbK#9 zvtd8rcHplw%YyQCKR{kyo6fgg!)6tHUYT(L>B7er5)41iG`j$qe*kSh$fY!PehLcD zWeKZHn<492B34*JUQh=CY1R~jT9Jt=k=jCU2=SL&&y5QI2uAG2?L8qd2U(^AW#{(x zThSy=C#>k+QMo^7caQcpU?Qn}j-`s?1vXuzG#j8(A+RUAY})F@=r&F(8nI&HspAy4 z4>(M>hI9c7?DCW8rw6|23?qQMSq?*Vx?v30U%luBo)B-k2mkL)Ljk5xUha3pK>EEj z@(;tH|M@xkuN?gsz;*bygizwYR!6=(Xgcg^>WlGtRYCozY<rFX2E>kaZo)O<^J7a`MX8Pf`gBd4vrtD|qKn&B)C&wp0O-x*@-|m*0egT=-t@%dD zgP2D+#WPptnc;_ugD6%zN}Z+X4=c61XNLb7L1gWd8;NHrBXwJ7s0ce#lWnnFUMTR& z1_R9Fin4!d17d4jpKcfh?MKRxxQk$@)*hradH2$3)nyXep5Z;B z?yX+-Bd=TqO2!11?MDtG0n(*T^!CIiF@ZQymqq1wPM_X$Iu9-P=^}v7npvvPBu!d$ z7K?@CsA8H38+zjA@{;{kG)#AHME>Ix<711_iQ@WWMObXyVO)a&^qE1GqpP47Q|_AG zP`(AD&r!V^MXQ^e+*n5~Lp9!B+#y3#f8J^5!iC@3Y@P`;FoUH{G*pj*q7MVV)29+j z>BC`a|1@U_v%%o9VH_HsSnM`jZ-&CDvbiqDg)tQEnV>b%Ptm)T|1?TrpIl)Y$LnG_ zzKi5j2Fx^K^PG1=*?GhK;$(UCF-tM~^=Z*+Wp{FSuy7iHt9#4n(sUuHK??@v+6*|10Csdnyg9hAsC5_OrSL;jVkLlf zHXIPukLqbhs~-*oa^gqgvtpgTk_7GypwH><53riYYL*M=Q@F-yEPLqQ&1Sc zZB%w}T~RO|#jFjMWcKMZccxm-SL)s_ig?OC?y_~gLFj{n8D$J_Kw%{r0oB8?@dWzn zB528d-wUBQzrrSSLq?fR!K%59Zv9J4yCQhhDGwhptpA5O5U?Hjqt>8nOD zi{)0CI|&Gu%zunGI*XFZh(ix)q${jT8wnnzbBMPYVJc4HX*9d^mz|21$=R$J$(y7V zo0dxdbX3N#=F$zjstTf*t8vL)2*{XH!+<2IJ1VVFa67|{?LP&P41h$2i2;?N~RA30LV`BsUcj zfO9#Pg1$t}7zpv#&)8`mis3~o+P(DxOMgz-V*(?wWaxi?R=NhtW}<#^Z?(BhSwyar zG|A#Q7wh4OfK<|DAcl9THc-W4*>J4nTevsD%dkj`U~wSUCh15?_N@uMdF^Kw+{agk zJ`im^wDqj`Ev)W3k3stasP`88-M0ZBs7;B6{-tSm3>I@_e-QfT?7|n0D~0RRqDb^G zyHb=is;IwuQ&ITzL4KsP@Z`b$d%B0Wuhioo1CWttW8yhsER1ZUZzA{F*K=wmi-sb#Ju+j z-l@In^IKnb{bQG}Ps>+Vu_W#grNKNGto+yjA)?>0?~X`4I3T@5G1)RqGUZuP^NJCq&^HykuYtMDD8qq+l8RcZNJsvN(10{ zQ1$XcGt}QH-U^WU!-wRR1d--{B$%vY{JLWIV%P4-KQuxxDeJaF#{eu&&r!3Qu{w}0f--8^H|KwE>)ORrcR+2Qf zb})DRcH>k0zWK8@{RX}NYvTF;E~phK{+F;MkIP$)T$93Ba2R2TvKc>`D??#mv9wg$ zd~|-`Qx5LwwsZ2hb*Rt4S9dsF%Cny5<1fscy~)d;0m2r$f=83<->c~!GNyb!U)PA; zq^!`@@)UaG)Ew(9V?5ZBq#c%dCWZrplmuM`o~TyHjAIMh0*#1{B>K4po-dx$Tk-Cq z=WZDkP5x2W&Os`N8KiYHRH#UY*n|nvd(U>yO=MFI-2BEp?x@=N<~CbLJBf6P)}vLS?xJXYJ2^<3KJUdrwKnJnTp{ zjIi|R=L7rn9b*D#Xxr4*R<3T5AuOS+#U8hNlfo&^9JO{VbH!v9^JbK=TCGR-5EWR@ zN8T-_I|&@A}(hKeL4_*eb!1G8p~&_Im8|wc>Cdir+gg90n1dw?QaXcx6Op_W1r=axRw>4;rM*UOpT#Eb9xU1IiWo@h?|5uP zka>-XW0Ikp@dIe;MN8B01a7+5V@h3WN{J=HJ*pe0uwQ3S&MyWFni47X32Q7SyCTNQ z+sR!_9IZa5!>f&V$`q!%H8ci!a|RMx5}5MA_kr+bhtQy{-^)(hCVa@I!^TV4RBi zAFa!Nsi3y37I5EK;0cqu|9MRj<^r&h1lF}u0KpKQD^5Y+LvFEwM zLU@@v4_Na#Axy6tn3P%sD^5P#<7F;sd$f4a7LBMk zGU^RZHBcxSA%kCx*eH&wgA?Qwazm8>9SCSz_!;MqY-QX<1@p$*T8lc?@`ikEqJ>#w zcG``^CoFMAhdEXT9qt47g0IZkaU)4R7wkGs^Ax}usqJ5HfDYAV$!=6?>J6+Ha1I<5 z|6=9soU4>E))tW$<#>F ziZ$6>KJf0bPfbx_)7-}tMINlc=}|H+$uX)mhC6-Hz+XZxsKd^b?RFB6et}O#+>Wmw9Ec9) z{q}XFWp{3@qmyK*Jvzpyqv57LIR;hPXKsrh{G?&dRjF%Zt5&m20Ll?OyfUYC3WRn{cgQ?^V~UAv+5 z&_m#&nIwffgX1*Z2#5^Kl4DbE#NrD&Hi4|7SPqZ}(>_+JMz=s|k77aEL}<=0Zfb)a z%F(*L3zCA<=xO)2U3B|pcTqDbBoFp>QyAEU(jMu8(jLA61-H!ucI804+B!$E^cQQa z)_ERrW3g!B9iLb3nn3dlkvD7KsY?sRvls3QC0qPi>o<)GHx%4Xb$5a3GBTJ(k@`e@ z$RUa^%S15^1oLEmA=sayrP5;9qtf!Z1*?e$ORVPsXpL{jL<6E)0sj&swP3}NPmR%FM?O>SQgN5XfHE< zo(4#Cv11(%Nnw_{_Ro}r6=gKd{k?NebJ~<~Kv0r(r0qe4n3LFx$5%x(BKvrz$m?LG zjLIc;hbj0FMdb9aH9Lpsof#yG$(0sG2%RL;d(n>;#jb!R_+dad+K;Ccw!|RY?uS(a zj~?=&M!4C(5LnlH6k%aYvz@7?xRa^2gml%vn&eKl$R_lJ+e|xsNfXzr#xuh(>`}9g zLHSyiFwK^-p!;p$yt7$F|3*IfO3Mlu9e>Dpx8O`37?fA`cj`C0B-m9uRhJjs^mRp# zWB;Aj6|G^1V6`jg7#7V9UFvnB4((nIwG?k%c7h`?0tS8J3Bn0t#pb#SA}N-|45$-j z$R>%7cc2ebAClXc(&0UtHX<>pd)akR3Kx_cK+n<}FhzmTx!8e9^u2e4%x{>T6pQ`6 zO182bh$-W5A3^wos0SV_TgPmF4WUP-+D25KjbC{y_6W_9I2_vNKwU(^qSdn&>^=*t z&uvp*@c8#2*paD!ZMCi3;K{Na;I4Q35zw$YrW5U@Kk~)&rw;G?d7Q&c9|x<Hg|CNMsxovmfth*|E*GHezPTWa^Hd^F4!B3sF;)? z(NaPyAhocu1jUe(!5Cy|dh|W2=!@fNmuNOzxi^tE_jAtzNJ0JR-avc_H|ve#KO}#S z#a(8secu|^Tx553d4r@3#6^MHbH)vmiBpn0X^29xEv!Vuh1n(Sr5I0V&`jA2;WS|Y zbf0e}X|)wA-Pf5gBZ>r4YX3Mav1kKY(ulAJ0Q*jB)YhviHK)w!TJsi3^dMa$L@^{` z_De`fF4;M87vM3Ph9SzCoCi$#Fsd38u!^0#*sPful^p5oI(xGU?yeYjn;Hq1!wzFk zG&2w}W3`AX4bxoVm03y>ts{KaDf!}b&7$(P4KAMP=vK5?1In^-YYNtx1f#}+2QK@h zeSeAI@E6Z8a?)>sZ`fbq9_snl6LCu6g>o)rO;ijp3|$vig+4t} zylEo7$SEW<_U+qgVcaVhk+4k+C9THI5V10qV*dOV6pPtAI$)QN{!JRBKh-D zk2^{j@bZ}yqW?<#VVuI_27*cI-V~sJiqQv&m07+10XF+#ZnIJdr8t`9s_EE;T2V;B z4UnQUH9EdX%zwh-5&wflY#ve!IWt0UE-My3?L#^Bh%kcgP1q{&26eXLn zTkjJ*w+(|_>Pq0v8{%nX$QZbf)tbJaLY$03;MO=Ic-uqYUmUCuXD>J>o6BCRF=xa% z3R4SK9#t1!K4I_d>tZgE>&+kZ?Q}1qo4&h%U$GfY058s%*=!kac{0Z+4Hwm!)pFLR zJ+5*OpgWUrm0FPI2ib4NPJ+Sk07j(`diti^i#kh&f}i>P4~|d?RFb#!JN)~D@)beox}bw?4VCf^y*`2{4`-@%SFTry2h z>9VBc9#JxEs1+0i2^LR@B1J`B9Ac=#FW=(?2;5;#U$0E0UNag_!jY$&2diQk_n)bT zl5Me_SUvqUjwCqmVcyb`igygB_4YUB*m$h5oeKv3uIF0sk}~es!{D>4r%PC*F~FN3owq5e0|YeUTSG#Vq%&Gk7uwW z0lDo#_wvflqHeRm*}l?}o;EILszBt|EW*zNPmq#?4A+&i0xx^?9obLyY4xx=Y9&^G;xYXYPxG)DOpPg!i_Ccl#3L}6xAAZzNhPK1XaC_~ z!A|mlo?Be*8Nn=a+FhgpOj@G7yYs(Qk(8&|h@_>w8Y^r&5nCqe0V60rRz?b5%J;GYeBqSAjo|K692GxD4` zRZyM2FdI+-jK2}WAZTZ()w_)V{n5tEb@>+JYluDozCb$fA4H)$bzg(Ux{*hXurjO^ zwAxc+UXu=&JV*E59}h3kzQPG4M)X8E*}#_&}w*KEgtX)cU{vm9b$atHa;s>| z+L6&cn8xUL*OSjx4YGjf6{Eq+Q3{!ZyhrL&^6Vz@jGbI%cAM9GkmFlamTbcQGvOlL zmJ?(FI)c86=JEs|*;?h~o)88>12nXlpMR4@yh%qdwFNpct;vMlc=;{FSo*apJ;p}! zAX~t;3tb~VuP|ZW;z$=IHf->F@Ml)&-&Bnb{iQyE#;GZ@C$PzEf6~q}4D>9jic@mTO5x76ulDz@+XAcm35!VSu zT*Gs>;f0b2TNpjU_BjHZ&S6Sqk6V1370+!eppV2H+FY!q*n=GHQ!9Rn6MjY!Jc77A zG7Y!lFp8?TIHN!LXO?gCnsYM-gQxsm=Ek**VmZu7vnuufD7K~GIxfxbsQ@qv2T zPa`tvHB$fFCyZl>3oYg?_wW)C>^_iDOc^B7klnTOoytQH18WkOk)L2BSD0r%xgRSW zQS9elF^?O=_@|58zKLK;(f77l-Zzu}4{fXed2saq!5k#UZAoDBqYQS{sn@j@Vtp|$ zG%gnZ$U|9@u#w1@11Sjl8ze^Co=)7yS(}=;68a3~g;NDe_X^}yJj;~s8xq9ahQ5_r zxAlTMnep*)w1e(TG%tWsjo3RR;yVGPEO4V{Zp?=a_0R#=V^ioQu4YL=BO4r0$$XTX zZfnw#_$V}sDAIDrezGQ+h?q24St0QNug_?{s-pI(^jg`#JRxM1YBV;a@@JQvH8*>> zIJvku74E0NlXkYe_624>znU0J@L<-c=G#F3k4A_)*;ky!C(^uZfj%WB3-*{*B$?9+ zDm$WFp=0(xnt6`vDQV3Jl5f&R(Mp};;q8d3I%Kn>Kx=^;uSVCw0L=gw53%Bp==8Sw zxtx=cs!^-_+i{2OK`Q;913+AXc_&Z5$@z3<)So0CU3;JAv=H?@Zpi~riQ{z-zLtVL z!oF<}@IgJp)Iyz1zVJ42!SPHSkjYNS4%ulVVIXdRuiZ@5Mx8LJS}J#qD^Zi_xQ@>DKDr-_e#>5h3dtje*NcwH_h;i{Sx7}dkdpuW z(yUCjckQsagv*QGMSi9u1`Z|V^}Wjf7B@q%j2DQXyd0nOyqg%m{CK_lAoKlJ7#8M} z%IvR?Vh$6aDWK2W!=i?*<77q&B8O&3?zP(Cs@kapc)&p7En?J;t-TX9abGT#H?TW? ztO5(lPKRuC7fs}zwcUKbRh=7E8wzTsa#Z{a`WR}?UZ%!HohN}d&xJ=JQhpO1PI#>X zHkb>pW04pU%Bj_mf~U}1F1=wxdBZu1790>3Dm44bQ#F=T4V3&HlOLsGH)+AK$cHk6 zia$=$kog?)07HCL*PI6}DRhpM^*%I*kHM<#1Se+AQ!!xyhcy6j7`iDX7Z-2i73_n# zas*?7LkxS-XSqv;YBa zW_n*32D(HTYQ0$feV_Fru1ZxW0g&iwqixPX3=9t4o)o|kOo79V$?$uh?#8Q8e>4e)V6;_(x&ViUVxma+i25qea;d-oK7ouuDsB^ab{ zu1qjQ%`n56VtxBE#0qAzb7lph`Eb-}TYpXB!H-}3Ykqyp`otprp7{VEuW*^IR2n$Fb99*nAtqT&oOFIf z@w*6>YvOGw@Ja?Pp1=whZqydzx@9X4n^2!n83C5{C?G@|E?&$?p*g68)kNvUTJ)I6 z1Q|(#UuP6pj78GUxq11m-GSszc+)X{C2eo-?8ud9sB=3(D47v?`JAa{V(IF zPZQ_0AY*9M97>Jf<o%#O_%Wq}8>YM=q0|tGY+hlXcpE=Z4Od z`NT7Hu2hnvRoqOw@g1f=bv`+nba{GwA$Ak0INlqI1k<9!x_!sL()h?hEWoWrdU3w` zZ%%)VR+Bc@_v!C#koM1p-3v_^L6)_Ktj4HE>aUh%2XZE@JFMOn)J~c`_7VWNb9c-N z2b|SZMR4Z@E7j&q&9(6H3yjEu6HV7{2!1t0lgizD;mZ9$r(r7W5G$ky@w(T_dFnOD z*p#+z$@pKE+>o@%eT(2-p_C}wbQ5s(%Sn_{$HDN@MB+Ev?t@3dPy`%TZ!z}AThZSu zN<1i$siJhXFdjV zP*y|V<`V8t=h#XTRUR~5`c`Z9^-`*BZf?WAehGdg)E2Je)hqFa!k{V(u+(hTf^Yq& zoruUh2(^3pe)2{bvt4&4Y9CY3js)PUHtd4rVG57}uFJL)D(JfSIo^{P=7liFXG zq5yqgof0V8paQcP!gy+;^pp-DA5pj=gbMN0eW=-eY+N8~y+G>t+x}oa!5r>tW$xhI zPQSv=pi;~653Gvf6~*JcQ%t1xOrH2l3Zy@8AoJ+wz@daW@m7?%LXkr!bw9GY@ns3e zSfuWF_gkWnesv?s3I`@}NgE2xwgs&rj?kH-FEy82=O8`+szN ziHch`vvS`zNfap14!&#i9H@wF7}yIPm=UB%(o(}F{wsZ(wA0nJ2aD^@B41>>o-_U6 zUqD~vdo48S8~FTb^+%#zcbQiiYoDKYcj&$#^;Smmb+Ljp(L=1Kt_J!;0s%1|JK}Wi z;={~oL!foo5n8=}rs6MmUW~R&;SIJO3TL4Ky?kh+b2rT9B1Jl4>#Uh-Bec z`Hsp<==#UEW6pGPhNk8H!!DUQR~#F9jEMI6T*OWfN^Ze&X(4nV$wa8QUJ>oTkruH# zm~O<`J7Wxseo@FqaZMl#Y(mrFW9AHM9Kb|XBMqaZ2a)DvJgYipkDD_VUF_PKd~dT7 z#02}bBfPn9a!X!O#83=lbJSK#E}K&yx-HI#T6ua)6o0{|={*HFusCkHzs|Fn&|C3H zBck1cmfcWVUN&i>X$YU^Sn6k2H;r3zuXbJFz)r5~3$d$tUj(l1?o={MM){kjgqXRO zc5R*#{;V7AQh|G|)jLM@wGAK&rm2~@{Pewv#06pHbKn#wL0P6F1!^qw9g&cW3Z=9} zj)POhOlwsh@eF=>z?#sIs*C-Nl(yU!#DaiaxhEs#iJqQ8w%(?+6lU02MYSeDkr!B- zPjMv+on6OLXgGnAtl(ao>|X2Y8*Hb}GRW5}-IzXnoo-d0!m4Vy$GS!XOLy>3_+UGs z2D|YcQx@M#M|}TDOetGi{9lGo9m-=0-^+nKE^*?$^uHkxZh}I{#UTQd;X!L+W@jm( zDg@N4+lUqI92o_rNk{3P>1gxAL=&O;x)ZT=q1mk0kLlE$WeWuY_$0`0jY-Kkt zP*|m3AF}Ubd=`<>(Xg0har*_@x2YH}bn0Wk*OZz3*e5;Zc;2uBdnl8?&XjupbkOeNZsNh6pvsq_ydmJI+*z**{I{0K)-;p1~k8cpJXL$^t!-`E}=*4G^-E8>H!LjTPxSx zcF+cS`ommfKMhNSbas^@YbTpH1*RFrBuATUR zt{oFWSk^$xU&kbFQ;MCX22RAN5F6eq9UfR$ut`Jw--p2YX)A*J69m^!oYfj2y7NYcH6&r+0~_sH^c^nzeN1AU4Ga7=FlR{S|Mm~MpzY0$Z+p2W(a={b-pR9EO1Rs zB%KY|@wLcAA@)KXi!d2_BxrkhDn`DT1=Dec}V!okd{$+wK z4E{n8R*xKyci1(CnNdhf$Dp2(Jpof0-0%-38X=Dd9PQgT+w%Lshx9+loPS~MOm%ZT zt%2B2iL_KU_ita%N>xjB!#71_3=3c}o zgeW~^U_ZTJQ2!PqXulQd=3b=XOQhwATK$y(9$#1jOQ4}4?~l#&nek)H(04f(Sr=s| zWv7Lu1=%WGk4FSw^;;!8&YPM)pQDCY9DhU`hMty1@sq1=Tj7bFsOOBZOFlpR`W>-J$-(kezWJj;`?x-v>ev{*8V z8p|KXJPV$HyQr1A(9LVrM47u-XpcrIyO`yWvx1pVYc&?154aneRpLqgx)EMvRaa#|9?Wwqs2+W8n5~79G z(}iCiLk;?enn}ew`HzhG+tu+Ru@T+K5juvZN)wY;x6HjvqD!&!)$$;1VAh~7fg0K| zEha#aN=Yv|3^~YFH}cc38ovVb%L|g@9W6fo(JtT6$fa?zf@Ct88e}m?i)b*Jgc{fl zExfdvw-BYDmH6>(4QMt#p0;FUIQqkhD}aH?a7)_%JtA~soqj{ppP_82yi9kaxuK>~ ze_)Zt>1?q=ZH*kF{1iq9sr*tVuy=u>Zev}!gEZx@O6-fjyu9X00gpIl-fS_pzjpqJ z1yqBmf9NF!jaF<+YxgH6oXBdK)sH(>VZ)1siyA$P<#KDt;8NT*l_0{xit~5j1P)FN zI8hhYKhQ)i z37^aP13B~u65?sg+_@2Kr^iWHN=U;EDSZ@2W2!5ALhGNWXnFBY%7W?1 z=HI9JzQ-pLKZDYTv<0-lt|6c-RwhxZ)mU2Os{bsX_i^@*fKUj8*aDO5pks=qn3Dv6 zwggpKLuyRCTVPwmw1r}B#AS}?X7b837UlXwp~E2|PJw2SGVueL7){Y&z!jL!XN=0i zU^Eig`S2`{+gU$68aRdWx?BZ{sU_f=8sn~>s~M?GU~`fH5kCc; z8ICp+INM3(3{#k32RZdv6b9MQYdZXNuk7ed8;G?S2nT+NZBG=Tar^KFl2SvhW$bGW#kdWL-I)s_IqVnCDDM9fm8g;P;8 z7t4yZn3^*NQfx7SwmkzP$=fwdC}bafQSEF@pd&P8@H#`swGy_rz;Z?Ty5mkS%>m#% zp_!m9e<()sfKiY(nF<1zBz&&`ZlJf6QLvLhl`_``%RW&{+O>Xhp;lwSsyRqGf=RWd zpftiR`={2(siiPAS|p}@q=NhVc0ELprt%=fMXO3B)4ryC2LT(o=sLM7hJC!}T1@)E zA3^J$3&1*M6Xq>03FX`R&w*NkrZE?FwU+Muut;>qNhj@bX17ZJxnOlPSZ=Zeiz~T_ zOu#yc3t6ONHB;?|r4w+pI)~KGN;HOGC)txxiUN8#mexj+W(cz%9a4sx|IRG=}ia zuEBuba3AHsV2feqw-3MvuL`I+2|`Ud4~7ZkN=JZ;L20|Oxna5vx1qbIh#k2O4$RQF zo`tL()zxaqibg^GbB+BS5#U{@K;WWQj~GcB1zb}zJkPwH|5hZ9iH2308!>_;%msji zJHSL~s)YHBR=Koa1mLEOHos*`gp=s8KA-C zu0aE+W!#iJ*0xqKm3A`fUGy#O+X+5W36myS>Uh2!R*s$aCU^`K&KKLCCDkejX2p=5 z%o7-fl03x`gaSNyr?3_JLv?2RLS3F*8ub>Jd@^Cc17)v8vYEK4aqo?OS@W9mt%ITJ z9=S2%R8M){CugT@k~~0x`}Vl!svYqX=E)c_oU6o}#Hb^%G1l3BudxA{F*tbjG;W_>=xV73pKY53v%>I)@D36I_@&p$h|Aw zonQS`07z_F#@T-%@-Tb|)7;;anoD_WH>9ewFy(ZcEOM$#Y)8>qi7rCnsH9GO-_7zF zu*C87{Df1P4TEOsnzZ@H%&lvV(3V@;Q!%+OYRp`g05PjY^gL$^$-t0Y>H*CDDs?FZly*oZ&dxvsxaUWF!{em4{A>n@vpXg$dwvt@_rgmHF z-MER`ABa8R-t_H*kv>}CzOpz;!>p^^9ztHMsHL|SRnS<-y5Z*r(_}c4=fXF`l^-i}>e7v!qs_jv zqvWhX^F=2sDNWA9c@P0?lUlr6ecrTKM%pNQ^?*Lq?p-0~?_j50xV%^(+H>sMul#Tw zeciF*1=?a7cI(}352%>LO96pD+?9!fNyl^9v3^v&Y4L)mNGK0FN43&Xf8jUlxW1Bw zyiu2;qW-aGNhs=zbuoxnxiwZ3{PFZM#Kw)9H@(hgX23h(`Wm~m4&TvoZoYp{plb^> z_#?vXcxd>r7K+1HKJvhed>gtK`TAbJUazUWQY6T~t2af%#<+Veyr%7-#*A#@&*;@g58{i|E%6yC_InGXCOd{L0;$)z#?n7M`re zh!kO{6=>7I?*}czyF7_frt#)s1CFJ_XE&VrDA?Dp3XbvF{qsEJgb&OLSNz_5g?HpK z9)8rsr4JN!Af3G9!#Qn(6zaUDqLN(g2g8*M)Djap?WMK9NKlkC)E2|-g|#-rp%!Gz zAHd%`iq|81efi93m3yTBw3g0j#;Yb2X{mhRAI?&KDmbGqou(2xiRNb^sV}%%Wu0?< z?($L>(#BO*)^)rSgyNRni$i`R4v;GhlCZ8$@e^ROX(p=2_v6Y!%^As zu022)fHdv_-~Yu_H6WVPLpHQx!W%^6j)cBhS`O3QBW#x(eX54d&I22op(N59b*&$v zFiSRY6rOc^(dgSV1>a7-5C;(5S5MvKcM2Jm-LD9TGqDpP097%52V+0>Xqq!! zq4e3vj53SE6i8J`XcQB|MZPP8j;PAOnpGnllH6#Ku~vS42xP*Nz@~y%db7Xi8s09P z1)e%8ys6&M8D=Dt6&t`iKG_4X=!kgRQoh%Z`dc&mlOUqXk-k`jKv9@(a^2-Upw>?< zt5*^DV~6Zedbec4NVl($2T{&b)zA@b#dUyd>`2JC0=xa_fIm8{5um zr-!ApXZhC8@=vC2WyxO|!@0Km)h8ep*`^he92$@YwP>VcdoS5OC^s38e#7RPsg4j+ zbVGG}WRSET&ZfrcR(x~k8n1rTP%CnfUNKUonD$P?FtNFF#cn!wEIab-;jU=B1dHK@ z(;(yAQJ`O$sMn>h;pf^8{JISW%d+@v6@CnXh9n5TXGC}?FI9i-D0OMaIg&mAg=0Kn zNJ7oz5*ReJukD55fUsMuaP+H4tDN&V9zfqF@ zr=#ecUk9wu{0;!+gl;3Bw=Vn^)z$ahVhhw)io!na&9}LmWurLb0zubxK=UEnU*{5P z+SP}&*(iBKSO4{alBHaY^)5Q=mZ+2OwIooJ7*Q5XJ+2|q`9#f?6myq!&oz?klihLq z4C)$XP!BNS0G_Z1&TM>?Jk{S~{F3n83ioli=IO6f%wkvCl(RFFw~j0tb{GvXTx>*sB0McY0s&SNvj4+^h`9nJ_wM>F!Uc>X}9PifQekn0sKI2SAJP!a4h z5cyGTuCj3ZBM^&{dRelIlT^9zcfaAuL5Y~bl!ppSf`wZbK$z#6U~rdclk``e+!qhe z6Qspo*%<)eu6?C;Bp<^VuW6JI|Ncvyn+LlSl;Mp22Bl7ARQ0Xc24%29(ZrdsIPw&-=yHQ7_Vle|5h>AST0 zUGX2Zk34vp?U~IHT|;$U86T+UUHl_NE4m|}>E~6q``7hccCaT^#y+?wD##Q%HwPd8 zV3x4L4|qqu`B$4(LXqDJngNy-{&@aFBvVsywt@X^}iH7P%>bR?ciC$I^U-4Foa`YKI^qDyGK7k%E%c_P=yzAi`YnxGA%DeNd++j3*h^ z=rn>oBd0|~lZ<6YvmkKY*ZJlJ;Im0tqgWu&E92eqt;+NYdxx`eS(4Hw_Jb5|yVvBg z*tbdY^!AN;luEyN4VRhS@-_DC{({ziH{&Z}iGElSV~qvT>L-8G%+yEL zX#MFOhj{InyKG=mvW-<1B@c-}x$vA(nU?>S>0*eN#!SLzQ)Ex7fvQ)S4D<8|I#N$3 zT5Ei`Z?cxBODHX8(Xp73v`IsAYC@9b;t}z0wxVuQSY1J^GRwDPN@qbM-ZF48T$GZ< z8WU+;Pqo?{ghI-KZ-i*ydXu`Ep0Xw^McH_KE9J0S7G;x8Fe`DVG?j3Pv=0YzJ}yZR z%2=oqHiUjvuk0~Ca>Kol4CFi0_xQT~;_F?=u+!kIDl-9g`#ZNZ9HCy17Ga1v^Jv9# z{T4Kb1-AzUxq*MutfOWWZgD*HnFfyYg0&e9f(5tZ>krPF6{VikNeHoc{linPPt#Si z&*g>(c54V8rT_AX!J&bNm-!umPvOR}vDai#`CX___J#=zeB*{4<&2WpaDncZsOkp* zsg<%@@rbrMkR_ux9?LsQxzoBa1s%$BBn6vk#{&&zUwcfzeCBJUwFYSF$08qDsB;gWQN*g!p8pxjofWbqNSZOEKOaTx@+* zwdt5*Q47@EOZ~EZL9s?1o?A%9TJT=Ob_13yyugvPg*e&ZU(r6^k4=2+D-@n=Hv5vu zSXG|hM(>h9^zn=eQ=$6`JO&70&2|%V5Lsx>)(%#;pcOfu>*nk_3HB_BNaH$`jM<^S zcSftDU1?nL;jy)+sfonQN}(}gUW?d_ikr*3=^{G)=tjBtEPe>TO|0ddVB zTklrSHiW+!#26frPXQQ(YN8DG$PZo?(po(QUCCf_OJC`pw*uey00%gmH!`WJkrKXj2!#6?`T25mTu9OJp2L8z3! z=arrL$ZqxuE{%yV)14Kd>k}j7pxZ6#$Dz8$@WV5p8kTqN<-7W)Q7Gt2{KoOPK_tZ| zf2WG~O5@{qPI+W<4f_;reuFVdO^5`ADC1!JQE|N`s3cq@(0WB!n0uh@*c{=LAd;~} zyGK@hbF-Oo+!nN)@i*O(`@FA#u?o=~e{`4O#5}z&=UkU*50fOrzi11D^&FOqe>wii z?*k+2|EcUs;Gx{!@KBT~>PAwLrIDT7Th=Utu?~?np@t^gFs?zgX=D${RwOY^WGh-+ z+#4$066ISh8eYW#FXWp~S`<*%O^ZuItL1Tyqt8#tZ zY120E;^VG`!lZn&3sPd$RkdHpU#|w+bYV)pJC|SH9g%|5IkxVTQcBA4CL0}$&}ef@ zW^Vtj%M;;_1xxP9x#ex17&4N*{ksO*_4O}xYu(p*JkL#yr}@7b)t5X?%CY<+s5_MJ zuiqt+N_;A(_)%lumoyRFixWa-M7qK_9s6<1X?JDa9fP!+_6u~~M$5L=ipB=7(j#f< zZ34J%=bs549%~_mA(|={uZNs_0?o7;-LBP(ZRnkd{-^|2|=4vUTmtByHL8 zEph`(LSEzQj68a+`d$V<45J7cyv^#|^|%fD#si1Nx!4NW*`l*{->HEWNh6-|g>-=r zXmQ|-i}Ku$ndUeHQ^&ieT!Lf}vf6GaqW9$DJ2NWrqwPY%%4nip$@vK$nRp*_C-v<| zuKz~ZyN&<%!NS26&x?jhy+@awJipMQ-8(X4#Ae5??U<1QMt1l9R=w9fAnEF}NYu$2 z>6}Vkc zIb*A?G*z8^IvibmBKn_u^5&T_1oey0gZS2~obf(#xk=erZGTEdQnt3DMGM+0oPwss zj5zXD;(oWhB_T@~Ig#9@v)AKtXu3>Inmgf@A|-lD-1U>cNyl3h?ADD9)GG4}zUGPk zZzaXe!~Kf?<~@$G?Uql3t8jy9{2!doq4=J}j9ktTxss{p6!9UdjyDERlA*xZ!=Q)KDs5O)phz>Vq3BNGoM(H|=1*Q4$^2fTZw z(%nq1P|5Rt81}SYJpEEzMPl5VJsV5&4e)ZWKDyoZ>1EwpkHx-AQVQc8%JMz;{H~p{=FXV>jIxvm4X*qv52e?Y-f%DJ zxEA165GikEASQ^fH6K#d!Tpu2HP{sFs%E=e$gYd$aj$+xue6N+Wc(rAz~wUsk2`(b z8Kvmyz%bKQxpP}~baG-rwYcYCvkHOi zlkR<=>ZBTU*8RF_d#Bl@zZsRIhx<%~Z@Z=ik z>adw3!DK(8R|q$vy{FTxw%#xliD~6qXmY^7_9kthVPTF~Xy1CfBqbU~?1QmxmU=+k z(ggxvEuA;0e&+ci-zQR{-f7aO{O(Pz_OsEjLh_K>MbvoZ4nxtk5u{g@nPv)cgW_R} z9}EA4K4@z0?7ue}Z(o~R(X&FjejUI2g~08PH1E4w>9o{)S(?1>Z0XMvTb|;&EuyOE zGvWNpYX)Nv<8|a^;1>bh#&znEcl-r!T#pn= z4$?Yudha6F%4b>*8@=BdtXXY4N+`U4Dmx$}>HeVJk-QdTG@t!tVT#0(LeV0gvqyyw z2sEp^9eY0N`u10Tm4n8No&A=)IeEC|gnmEXoNSzu!1<4R<%-9kY_8~5Ej?zRegMn78wuMs#;i&eUA0Zk_RXQ3b&TT} z;SCI=7-FUB@*&;8|n>(_g^HGf3@QODE3LpmX~ELnymQm{Sx9xrKS zK29p~?v@R$0=v6Dr5aW>-!{+h@?Q58|Kz8{{W`%J+lDAdb&M5VHrX_mDY;1-JLnf)ezmPau$)1;=`-FU=-r-83tX=C`S#}GZufju zQ>sXNT0Ny=k@nc%cFnvA_i4SC)?_ORXHq8B4D%el1uPX`c~uG#S1M7C+*MMqLw78E zhY2dI8@+N^qrMI1+;TUda(vGqGSRyU{Fnm`aqrr7bz42c5xsOO-~oZpkzorD1g}Y<6rk&3>PsSGy}W?MtqFky@A(X# zIuNZK0cK?^=;PUAu>j0#HtjbHCV*6?jzA&OoE$*Jlga*}LF`SF?WLhv1O|zqC<>*> zYB;#lsYKx0&kH@BFpW8n*yDcc6?;_zaJs<-jPSkCsSX-!aV=P5kUgF@Nu<{a%#K*F z134Q{9|YX7X(v$62_cY3^G%t~rD>Q0z@)1|zs)vjJ6Jq9;7#Ki`w+eS**En?7;n&7 zu==V3T&eFboN3ZiMx3D8qYc;VjFUk_H-WWCau(VFXSQf~viH0L$gwD$UfFHqNcgN`x}M+YQ6RnN<+@t>JUp#)9YOkqst-Ga?{FsDpEeX0(5v{0J~SEbWiL zXC2}M4?UH@u&|;%0y`eb33ldo4~z-x8zY!oVmV=c+f$m?RfDC35mdQ2E>Pze7KWP- z>!Bh<&57I+O_^s}9Tg^k)h7{xx@0a0IA~GAOt2yy!X%Q$1rt~LbTB6@Du!_0%HV>N zlf)QI1&gvERKwso23mJ!Ou6ZS#zCS5W`gxE5T>C#E|{i<1D35C222I33?Njaz`On7 zi<+VWFP6D{e-{yiN#M|Jgk<44u1TiMI78S5W`Sdb5f+{zu34s{CfWN7a3Cf^@L%!& zN$?|!!9j2c)j$~+R6n#891w-z8(!oBpL2K=+%a$r2|~8-(vQj5_XT`<0Ksf;oP+tz z9CObS!0m)Tgg`K#xBM8B(|Z)Wb&DYL{WTYv`;A=q6~Nnx2+!lTIXtj8J7dZE!P_{z z#f8w6F}^!?^KE#+ZDv+xd5O&3EmomZzsv?>E-~ygGum45fk!SBN&|eo1rKw^?aZJ4 E2O(~oYXATM literal 0 HcmV?d00001 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..05679dc --- /dev/null +++ b/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,5 @@ +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.1.1-bin.zip +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..4f906e0 --- /dev/null +++ b/gradlew @@ -0,0 +1,185 @@ +#!/usr/bin/env sh + +# +# Copyright 2015 the original author or authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=`expr $i + 1` + done + case $i in + 0) set -- ;; + 1) set -- "$args0" ;; + 2) set -- "$args0" "$args1" ;; + 3) set -- "$args0" "$args1" "$args2" ;; + 4) set -- "$args0" "$args1" "$args2" "$args3" ;; + 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=`save "$@"` + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..107acd3 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,89 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/src/main/java/magistu/plugins/jei/JeiSupport.java b/src/main/java/magistu/plugins/jei/JeiSupport.java new file mode 100644 index 0000000..96ab78e --- /dev/null +++ b/src/main/java/magistu/plugins/jei/JeiSupport.java @@ -0,0 +1,51 @@ +package magistu.plugins.jei; + +import magistu.siegemachines.SiegeMachines; +import magistu.siegemachines.data.recipes.ModRecipes; +import mezz.jei.api.registration.IRecipeRegistration; +import net.minecraft.client.Minecraft; +import net.minecraft.item.crafting.IRecipeType; +import net.minecraft.item.crafting.RecipeManager; +import net.minecraft.util.ResourceLocation; + +import mezz.jei.api.IModPlugin; +import mezz.jei.api.JeiPlugin; +import mezz.jei.api.helpers.IGuiHelper; +import mezz.jei.api.registration.IRecipeCategoryRegistration; + +import java.util.Collection; +import java.util.stream.Collectors; + +@JeiPlugin +public class JeiSupport implements IModPlugin +{ + private static final ResourceLocation PLUGIN_ID = new ResourceLocation(SiegeMachines.ID, "jei_plugin"); + + @Override + public ResourceLocation getPluginUid() + { + return PLUGIN_ID; + } + + @SuppressWarnings("resource") + @Override + public void registerRecipes(IRecipeRegistration registration) + { + RecipeManager manager = Minecraft.getInstance().level.getRecipeManager(); + + registration.addRecipes(getRecipes(manager, ModRecipes.SIEGE_WORKBENCH_RECIPE), SiegeWorkbenchRecipeCategory.ID); + } + + @Override + public void registerCategories(IRecipeCategoryRegistration registration) + { + IGuiHelper helper = registration.getJeiHelpers().getGuiHelper(); + + registration.addRecipeCategories(new SiegeWorkbenchRecipeCategory(helper)); + } + + private static Collection getRecipes(RecipeManager manager, IRecipeType type) + { + return manager.getRecipes().parallelStream().filter(recipe -> recipe.getType() == type).collect(Collectors.toList()); + } +} diff --git a/src/main/java/magistu/plugins/jei/SiegeWorkbenchRecipeCategory.java b/src/main/java/magistu/plugins/jei/SiegeWorkbenchRecipeCategory.java new file mode 100644 index 0000000..54491a9 --- /dev/null +++ b/src/main/java/magistu/plugins/jei/SiegeWorkbenchRecipeCategory.java @@ -0,0 +1,96 @@ +package magistu.plugins.jei; + +import com.mojang.blaze3d.matrix.MatrixStack; +import magistu.siegemachines.SiegeMachines; +import magistu.siegemachines.block.ModBlocks; +import magistu.siegemachines.data.recipes.SiegeWorkbenchRecipe; +import mezz.jei.api.constants.VanillaTypes; +import mezz.jei.api.gui.IRecipeLayout; +import mezz.jei.api.gui.drawable.IDrawable; +import mezz.jei.api.gui.ingredient.IGuiItemStackGroup; +import mezz.jei.api.helpers.IGuiHelper; +import mezz.jei.api.ingredients.IIngredients; +import mezz.jei.api.recipe.category.IRecipeCategory; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.TranslationTextComponent; +import org.jetbrains.annotations.NotNull; + +public class SiegeWorkbenchRecipeCategory implements IRecipeCategory +{ + public static final ResourceLocation ID = new ResourceLocation(SiegeMachines.ID, ".siege_workbench_recipe_category"); + + private final IDrawable background; + private final IDrawable overlay; + private final IDrawable icon; + + public SiegeWorkbenchRecipeCategory(IGuiHelper helper) + { + this.background = helper.createBlankDrawable(116, 54); + this.overlay = helper.createDrawable(new ResourceLocation(SiegeMachines.ID, "textures/gui/siege_workbench.png"), 29, 16, 116, 54); + this.icon = helper.createDrawableIngredient(new ItemStack(ModBlocks.SIEGE_WORKBENCH.get())); + } + + @Override + public @NotNull ResourceLocation getUid() + { + return ID; + } + + @Override + public @NotNull Class getRecipeClass() + { + return SiegeWorkbenchRecipe.class; + } + + @Override + public @NotNull String getTitle() + { + return new TranslationTextComponent("category." + SiegeMachines.ID + ".siege_workbench_crafting").getString(); + } + + @Override + public @NotNull IDrawable getBackground() + { + return background; + } + + @Override + public void draw(SiegeWorkbenchRecipe recipe, MatrixStack matrixStack, double mouseX, double mouseY) + { + this.overlay.draw(matrixStack, 0, 0); + } + + @Override + public @NotNull IDrawable getIcon() + { + return icon; + } + + @Override + public void setIngredients(SiegeWorkbenchRecipe recipe, IIngredients ingredients) + { + ingredients.setInputIngredients(recipe.getIngredients()); + ingredients.setOutput(VanillaTypes.ITEM, recipe.getResultItem()); + } + + @Override + public void setRecipe(IRecipeLayout recipeLayout, SiegeWorkbenchRecipe recipe, IIngredients ingredients) + { + IGuiItemStackGroup group = recipeLayout.getItemStacks(); + + int n = 0; + + group.init(n++, false, 94, 18); + + for (int i = 0; i < 3; ++i) + { + for (int j = 0; j < 3; ++j) + { + group.init(n++, true, j * 18, i * 18); + } + } + + group.set(ingredients); + } +} diff --git a/src/main/java/magistu/siegemachines/SiegeMachines.java b/src/main/java/magistu/siegemachines/SiegeMachines.java new file mode 100644 index 0000000..8fd3b1c --- /dev/null +++ b/src/main/java/magistu/siegemachines/SiegeMachines.java @@ -0,0 +1,123 @@ +package magistu.siegemachines; + +import magistu.siegemachines.block.ModBlocks; +import magistu.siegemachines.client.ClientProxy; +import magistu.siegemachines.client.SoundTypes; +import magistu.siegemachines.config.SpecsConfig; +import magistu.siegemachines.data.recipes.ModRecipes; +import magistu.siegemachines.gui.ContainerTypes; +import magistu.siegemachines.entity.EntityTypes; +import magistu.siegemachines.item.ModItems; +import magistu.siegemachines.network.PacketHandler; +import magistu.siegemachines.proxy.IProxy; +import magistu.siegemachines.server.ServerProxy; +import net.minecraft.block.Block; +import net.minecraft.block.Blocks; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.DistExecutor; +import net.minecraftforge.fml.InterModComms; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; +import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; +import net.minecraftforge.fml.event.lifecycle.InterModEnqueueEvent; +import net.minecraftforge.fml.event.lifecycle.InterModProcessEvent; +import net.minecraftforge.fml.event.server.FMLServerStartingEvent; +import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.UUID; +import java.util.stream.Collectors; + +// The value here should match an entry in the META-INF/mods.toml file +@Mod("siegemachines") +public class SiegeMachines +{ + public static final String ID = "siegemachines"; + + public static final IProxy PROXY = DistExecutor.safeRunForDist(() -> ClientProxy::new, () -> ServerProxy::new); + public static final int RENDER_UPDATE_RANGE = 128; + public static final int RENDER_UPDATE_TIME = 20; + public static final int RENDER_UPDATE_RANGE_SQR = RENDER_UPDATE_RANGE * RENDER_UPDATE_RANGE; + + public static final UUID CHAT_UUID = new UUID(100L, 100L); + + // Directly reference a log4j logger. + private static final Logger LOGGER = LogManager.getLogger(); + + + public SiegeMachines() + { + IEventBus eventBus = FMLJavaModLoadingContext.get().getModEventBus(); + + FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup); + FMLJavaModLoadingContext.get().getModEventBus().addListener(this::enqueueIMC); + FMLJavaModLoadingContext.get().getModEventBus().addListener(this::processIMC); + FMLJavaModLoadingContext.get().getModEventBus().addListener(this::doClientStuff); + + EntityTypes.register(eventBus); + SoundTypes.register(eventBus); + ContainerTypes.register(eventBus); + ModBlocks.register(eventBus); + ModItems.register(eventBus); + ModRecipes.register(eventBus); + SpecsConfig.register(); + + PacketHandler.init(); + + MinecraftForge.EVENT_BUS.register(this); + } + + + private void setup(final FMLCommonSetupEvent event) + { + // some preinit code + LOGGER.info("HELLO FROM PREINIT"); + LOGGER.info("DIRT BLOCK >> {}", Blocks.DIRT.getRegistryName()); + } + + private void doClientStuff(final FMLClientSetupEvent event) + { + // do something that can only be done on the client + LOGGER.info("Got game settings {}", event.getMinecraftSupplier().get().options); + + PROXY.clientSetup(event); + } + + private void enqueueIMC(final InterModEnqueueEvent event) + { + // some example code to dispatch IMC to another mod + InterModComms.sendTo("examplemod", "helloworld", () -> { LOGGER.info("Hello world from the MDK"); return "Hello world";}); + } + + private void processIMC(final InterModProcessEvent event) + { + // some example code to receive and process InterModComms from other mods + LOGGER.info("Got IMC {}", event.getIMCStream(). + map(m->m.getMessageSupplier().get()). + collect(Collectors.toList())); + } + // You can use SubscribeEvent and let the Event Bus discover methods to call + @SubscribeEvent + public void onServerStarting(FMLServerStartingEvent event) + { + // do something when the server starts + LOGGER.info("HELLO from server starting"); + } + + // You can use EventBusSubscriber to automatically subscribe events on the contained class (this is subscribing to the MOD + // Event bus for receiving Registry Events) + @Mod.EventBusSubscriber(bus=Mod.EventBusSubscriber.Bus.MOD) + public static class RegistryEvents + { + @SubscribeEvent + public static void onBlocksRegistry(final RegistryEvent.Register blockRegistryEvent) + { + // register a new block here + LOGGER.info("HELLO from Register Block"); + } + } +} diff --git a/src/main/java/magistu/siegemachines/block/ModBlocks.java b/src/main/java/magistu/siegemachines/block/ModBlocks.java new file mode 100644 index 0000000..3f20189 --- /dev/null +++ b/src/main/java/magistu/siegemachines/block/ModBlocks.java @@ -0,0 +1,39 @@ +package magistu.siegemachines.block; + +import magistu.siegemachines.SiegeMachines; +import magistu.siegemachines.item.ModItems; +import net.minecraft.block.AbstractBlock; +import net.minecraft.block.Block; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.Material; +import net.minecraft.item.BlockItem; +import net.minecraft.item.Item; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.fml.RegistryObject; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; + +import java.util.function.Supplier; + +public class ModBlocks +{ + public static final DeferredRegister BLOCKS = DeferredRegister.create(ForgeRegistries.BLOCKS, SiegeMachines.ID); + public static final RegistryObject SIEGE_WORKBENCH = registerBlock("siege_workbench", () -> new SiegeWorkbench(AbstractBlock.Properties.of(Material.WOOD).strength(2.5f).sound(SoundType.WOOD))); + + private static RegistryObject registerBlock(String name, Supplier block) + { + RegistryObject toReturn = BLOCKS.register(name, block); + registerBlockItem(name, toReturn); + return toReturn; + } + + private static void registerBlockItem(String name, RegistryObject block) + { + ModItems.ITEMS.register(name, () -> new BlockItem(block.get(), new Item.Properties().tab(ModItems.GROUP_SM))); + } + + public static void register(IEventBus eventBus) + { + BLOCKS.register(eventBus); + } +} diff --git a/src/main/java/magistu/siegemachines/block/SiegeWorkbench.java b/src/main/java/magistu/siegemachines/block/SiegeWorkbench.java new file mode 100644 index 0000000..3664427 --- /dev/null +++ b/src/main/java/magistu/siegemachines/block/SiegeWorkbench.java @@ -0,0 +1,50 @@ +package magistu.siegemachines.block; + +import magistu.siegemachines.gui.SiegeWorkbenchContainer; +import net.minecraft.block.BlockState; +import net.minecraft.block.CraftingTableBlock; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.inventory.container.INamedContainerProvider; +import net.minecraft.inventory.container.SimpleNamedContainerProvider; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Hand; +import net.minecraft.util.IWorldPosCallable; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.BlockRayTraceResult; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TranslationTextComponent; +import net.minecraft.world.World; +import net.minecraftforge.fml.network.NetworkHooks; +import org.jetbrains.annotations.NotNull; + +public class SiegeWorkbench extends CraftingTableBlock +{ + private static final ITextComponent CONTAINER_TITLE = new TranslationTextComponent("container.crafting"); + + public SiegeWorkbench(Properties p_i48422_1_) + { + super(p_i48422_1_); + } + + public @NotNull ActionResultType use(BlockState blockstate, World level, BlockPos blockpos, PlayerEntity player, Hand hand, BlockRayTraceResult result) + { + if (level.isClientSide) + { + return ActionResultType.SUCCESS; + } + else + { + NetworkHooks.openGui((ServerPlayerEntity) player, this.getMenuProvider(blockstate, level, blockpos)); + return ActionResultType.CONSUME; + } + } + + public INamedContainerProvider getMenuProvider(BlockState blockstate, World level, BlockPos blockpos) + { + return new SimpleNamedContainerProvider((p_220270_2_, p_220270_3_, p_220270_4_) -> + new SiegeWorkbenchContainer(p_220270_2_, p_220270_3_, IWorldPosCallable.create(level, blockpos)), CONTAINER_TITLE); + } + + +} diff --git a/src/main/java/magistu/siegemachines/block/StacksCraftingInventory.java b/src/main/java/magistu/siegemachines/block/StacksCraftingInventory.java new file mode 100644 index 0000000..f984472 --- /dev/null +++ b/src/main/java/magistu/siegemachines/block/StacksCraftingInventory.java @@ -0,0 +1,12 @@ +package magistu.siegemachines.block; + +import net.minecraft.inventory.CraftingInventory; +import net.minecraft.inventory.container.Container; + +public class StacksCraftingInventory extends CraftingInventory +{ + public StacksCraftingInventory(Container p_i1807_1_, int p_i1807_2_, int p_i1807_3_) + { + super(p_i1807_1_, p_i1807_2_, p_i1807_3_); + } +} diff --git a/src/main/java/magistu/siegemachines/client/ClientListener.java b/src/main/java/magistu/siegemachines/client/ClientListener.java new file mode 100644 index 0000000..be81344 --- /dev/null +++ b/src/main/java/magistu/siegemachines/client/ClientListener.java @@ -0,0 +1,27 @@ +package magistu.siegemachines.client; + +import magistu.siegemachines.SiegeMachines; +import magistu.siegemachines.client.renderer.*; +import magistu.siegemachines.entity.EntityTypes; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.client.registry.RenderingRegistry; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; + +@Mod.EventBusSubscriber(modid = SiegeMachines.ID, bus = Mod.EventBusSubscriber.Bus.MOD) +public class ClientListener +{ + @OnlyIn(Dist.CLIENT) + @SubscribeEvent + public static void registerRenderers(final FMLClientSetupEvent event) + { + RenderingRegistry.registerEntityRenderingHandler(EntityTypes.MORTAR.get(), MortarGeoRenderer::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTypes.CULVERIN.get(), CulverinGeoRenderer::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTypes.TREBUCHET.get(), TrebuchetGeoRenderer::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTypes.CATAPULT.get(), CatapultGeoRenderer::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTypes.BALLISTA.get(), BallistaGeoRenderer::new); + RenderingRegistry.registerEntityRenderingHandler(EntityTypes.BATTERING_RAM.get(), BatteringRamGeoRenderer::new); + } +} diff --git a/src/main/java/magistu/siegemachines/client/ClientProxy.java b/src/main/java/magistu/siegemachines/client/ClientProxy.java new file mode 100644 index 0000000..72dbe90 --- /dev/null +++ b/src/main/java/magistu/siegemachines/client/ClientProxy.java @@ -0,0 +1,37 @@ +package magistu.siegemachines.client; + +import magistu.siegemachines.client.renderer.GiantArrowRenderer; +import magistu.siegemachines.entity.EntityTypes; +import magistu.siegemachines.gui.ContainerTypes; +import magistu.siegemachines.gui.MachineInventoryScreen; +import magistu.siegemachines.gui.SiegeWorkbenchScreen; +import magistu.siegemachines.proxy.IProxy; +import net.minecraft.client.gui.ScreenManager; +import net.minecraft.client.renderer.ItemRenderer; +import net.minecraft.client.renderer.entity.SpriteRenderer; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.fml.client.registry.RenderingRegistry; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; + +public class ClientProxy implements IProxy +{ + public void setup(IEventBus modEventBus, IEventBus forgeEventBus) + { + modEventBus.addListener(this::clientSetup); + } + + public void clientSetup(FMLClientSetupEvent event) + { + ScreenManager.register(ContainerTypes.MACHINE_CONTAINER.get(), MachineInventoryScreen::new); + ScreenManager.register(ContainerTypes.SIEGE_WORKBENCH_CONTAINER.get(), SiegeWorkbenchScreen::new); + + ItemRenderer renderer = event.getMinecraftSupplier().get().getItemRenderer(); + RenderingRegistry.registerEntityRenderingHandler(EntityTypes.CANNONBALL.get(), (renderManager) -> new SpriteRenderer<>(renderManager, renderer)); + RenderingRegistry.registerEntityRenderingHandler(EntityTypes.STONE.get(), (renderManager) -> new SpriteRenderer<>(renderManager, renderer)); + RenderingRegistry.registerEntityRenderingHandler(EntityTypes.GIANT_STONE.get(), (renderManager) -> new SpriteRenderer<>(renderManager, renderer)); + RenderingRegistry.registerEntityRenderingHandler(EntityTypes.GIANT_ARROW.get(), GiantArrowRenderer::new); + KeyBindings.register(); + } + + public void onPreInit() {} +} diff --git a/src/main/java/magistu/siegemachines/client/KeyBindings.java b/src/main/java/magistu/siegemachines/client/KeyBindings.java new file mode 100644 index 0000000..0778a95 --- /dev/null +++ b/src/main/java/magistu/siegemachines/client/KeyBindings.java @@ -0,0 +1,17 @@ +package magistu.siegemachines.client; + +import magistu.siegemachines.SiegeMachines; +import net.minecraft.client.settings.KeyBinding; +import net.minecraftforge.fml.client.registry.ClientRegistry; + +public class KeyBindings +{ + public static KeyBinding MACHINE_USE = new KeyBinding(SiegeMachines.ID + ".machine_use", 70, SiegeMachines.ID + ".category"); + public static KeyBinding MACHINE_INVENTORY = new KeyBinding(SiegeMachines.ID + ".machine_inventory", 73, SiegeMachines.ID + ".category"); + + public static void register() + { + ClientRegistry.registerKeyBinding(MACHINE_USE); + ClientRegistry.registerKeyBinding(MACHINE_INVENTORY); + } +} diff --git a/src/main/java/magistu/siegemachines/client/SoundTypes.java b/src/main/java/magistu/siegemachines/client/SoundTypes.java new file mode 100644 index 0000000..f9084e7 --- /dev/null +++ b/src/main/java/magistu/siegemachines/client/SoundTypes.java @@ -0,0 +1,44 @@ +package magistu.siegemachines.client; + +import magistu.siegemachines.SiegeMachines; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.SoundEvent; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.fml.RegistryObject; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import software.bernie.geckolib3.GeckoLib; + +public class SoundTypes +{ + public static final DeferredRegister SOUNDS = DeferredRegister.create(ForgeRegistries.SOUND_EVENTS, + SiegeMachines.ID); + + public static RegistryObject TREBUCHET_SHOOTING = SOUNDS.register("trebuchet_shooting", + () -> new SoundEvent(new ResourceLocation(SiegeMachines.ID, "trebuchet_shooting"))); + public static RegistryObject TREBUCHET_RELOADING = SOUNDS.register("trebuchet_reloading", + () -> new SoundEvent(new ResourceLocation(SiegeMachines.ID, "trebuchet_reloading"))); + public static RegistryObject CATAPULT_SHOOTING = SOUNDS.register("catapult_shooting", + () -> new SoundEvent(new ResourceLocation(SiegeMachines.ID, "catapult_shooting"))); + public static RegistryObject CATAPULT_RELOADING = SOUNDS.register("catapult_reloading", + () -> new SoundEvent(new ResourceLocation(SiegeMachines.ID, "catapult_reloading"))); + public static RegistryObject BALLISTA_SHOOTING = SOUNDS.register("ballista_shooting", + () -> new SoundEvent(new ResourceLocation(SiegeMachines.ID, "ballista_shooting"))); + public static RegistryObject BALLISTA_RELOADING = SOUNDS.register("ballista_reloading", + () -> new SoundEvent(new ResourceLocation(SiegeMachines.ID, "ballista_reloading"))); + public static RegistryObject MORTAR_SHOOTING = SOUNDS.register("mortar_shooting", + () -> new SoundEvent(new ResourceLocation(SiegeMachines.ID, "mortar_shooting"))); + public static RegistryObject FUSE = SOUNDS.register("fuse", + () -> new SoundEvent(new ResourceLocation(SiegeMachines.ID, "fuse"))); + public static RegistryObject CANNON_WHEELS = SOUNDS.register("cannon_wheels", + () -> new SoundEvent(new ResourceLocation(SiegeMachines.ID, "cannon_wheels"))); + public static RegistryObject RAM_WHEELS = SOUNDS.register("ram_wheels", + () -> new SoundEvent(new ResourceLocation(SiegeMachines.ID, "ram_wheels"))); + public static RegistryObject RAM_HITTING = SOUNDS.register("ram_hitting", + () -> new SoundEvent(new ResourceLocation(SiegeMachines.ID, "ram_hitting"))); + + public static void register(IEventBus eventBus) + { + SOUNDS.register(eventBus); + } +} diff --git a/src/main/java/magistu/siegemachines/client/renderer/BallistaGeoRenderer.java b/src/main/java/magistu/siegemachines/client/renderer/BallistaGeoRenderer.java new file mode 100644 index 0000000..a3012d9 --- /dev/null +++ b/src/main/java/magistu/siegemachines/client/renderer/BallistaGeoRenderer.java @@ -0,0 +1,55 @@ +package magistu.siegemachines.client.renderer; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.vertex.IVertexBuilder; +import magistu.siegemachines.client.renderer.model.MachineModel; +import magistu.siegemachines.entity.machine.Ballista; +import magistu.siegemachines.entity.projectile.ProjectileBuilder; +import magistu.siegemachines.item.ModItems; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.EntityRendererManager; +import net.minecraft.util.ResourceLocation; +import software.bernie.geckolib3.geo.render.built.GeoBone; +import software.bernie.geckolib3.geo.render.built.GeoModel; +import software.bernie.geckolib3.model.provider.GeoModelProvider; + +import java.util.Optional; + +public class BallistaGeoRenderer extends MachineGeoRenderer +{ + public BallistaGeoRenderer(EntityRendererManager renderManager) + { + super(renderManager, new MachineModel<>("ballista")); + } + + @Override + public RenderType getRenderType(Ballista animatable, float partialTicks, MatrixStack stack, + IRenderTypeBuffer renderTypeBuffer, IVertexBuilder vertexBuilder, int packedLightIn, + ResourceLocation textureLocation) + { + return RenderType.entityTranslucent(getTextureLocation(animatable)); + } + + @Override + public void renderEarly(Ballista animatable, MatrixStack stackIn, float ticks, IRenderTypeBuffer renderTypeBuffer, IVertexBuilder vertexBuilder, int packedLightIn, int packedOverlayIn, float red, float green, float blue, float partialTicks) + { + GeoModelProvider modelProvider = this.getGeoModelProvider(); + GeoModel model = modelProvider.getModel(modelProvider.getModelLocation(animatable)); + + Optional turret = model.getBone("Balliste"); + turret.ifPresent(bone -> bone.setRotationX(-animatable.getTurretPitch() * (float) Math.PI / 180.0f)); + turret.ifPresent(bone -> bone.setRotationY(-animatable.getTurretYaw() * (float) Math.PI / 180.0f)); + + Optional projectile = model.getBone("BallistaArrow"); + projectile.ifPresent(bone -> bone.setRotationX(-animatable.getTurretPitch() * (float) Math.PI / 180.0f)); + projectile.ifPresent(bone -> bone.setRotationY(-animatable.getTurretYaw() * (float) Math.PI / 180.0f)); + boolean shouldrender = ((animatable.useticks <= 0 && animatable.shootingticks <= 0) || (animatable.useticks > 0 && animatable.shootingticks > 0)) && animatable.delayticks <= 0; + int projectilesize = shouldrender && animatable.hasAmmo() ? 1 : 0; + projectile.ifPresent(bone -> bone.setScaleX(projectilesize)); + projectile.ifPresent(bone -> bone.setScaleY(projectilesize)); + projectile.ifPresent(bone -> bone.setScaleZ(projectilesize)); + + super.renderEarly(animatable, stackIn, ticks, renderTypeBuffer, vertexBuilder, packedLightIn, packedOverlayIn, red, green, blue, partialTicks); + } +} diff --git a/src/main/java/magistu/siegemachines/client/renderer/BallistaItemGeoRenderer.java b/src/main/java/magistu/siegemachines/client/renderer/BallistaItemGeoRenderer.java new file mode 100644 index 0000000..5b7556d --- /dev/null +++ b/src/main/java/magistu/siegemachines/client/renderer/BallistaItemGeoRenderer.java @@ -0,0 +1,11 @@ +package magistu.siegemachines.client.renderer; + +import magistu.siegemachines.client.renderer.model.MachineItemModel; + +public class BallistaItemGeoRenderer extends MachineItemGeoRenderer +{ + public BallistaItemGeoRenderer() + { + super(new MachineItemModel<>("ballista")); + } +} diff --git a/src/main/java/magistu/siegemachines/client/renderer/BatteringRamGeoRenderer.java b/src/main/java/magistu/siegemachines/client/renderer/BatteringRamGeoRenderer.java new file mode 100644 index 0000000..dbc8fcc --- /dev/null +++ b/src/main/java/magistu/siegemachines/client/renderer/BatteringRamGeoRenderer.java @@ -0,0 +1,32 @@ +package magistu.siegemachines.client.renderer; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.vertex.IVertexBuilder; +import magistu.siegemachines.client.renderer.model.MachineModel; +import magistu.siegemachines.entity.machine.Ballista; +import magistu.siegemachines.entity.machine.BatteringRam; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.EntityRendererManager; +import net.minecraft.util.ResourceLocation; +import software.bernie.geckolib3.geo.render.built.GeoBone; +import software.bernie.geckolib3.geo.render.built.GeoModel; +import software.bernie.geckolib3.model.provider.GeoModelProvider; + +import java.util.Optional; + +public class BatteringRamGeoRenderer extends MachineGeoRenderer +{ + public BatteringRamGeoRenderer(EntityRendererManager renderManager) + { + super(renderManager, new MachineModel<>("battering_ram")); + } + + @Override + public RenderType getRenderType(BatteringRam animatable, float partialTicks, MatrixStack stack, + IRenderTypeBuffer renderTypeBuffer, IVertexBuilder vertexBuilder, int packedLightIn, + ResourceLocation textureLocation) + { + return RenderType.entityTranslucent(getTextureLocation(animatable)); + } +} diff --git a/src/main/java/magistu/siegemachines/client/renderer/BatteringRamItemGeoRenderer.java b/src/main/java/magistu/siegemachines/client/renderer/BatteringRamItemGeoRenderer.java new file mode 100644 index 0000000..dc4fb63 --- /dev/null +++ b/src/main/java/magistu/siegemachines/client/renderer/BatteringRamItemGeoRenderer.java @@ -0,0 +1,11 @@ +package magistu.siegemachines.client.renderer; + +import magistu.siegemachines.client.renderer.model.MachineItemModel; + +public class BatteringRamItemGeoRenderer extends MachineItemGeoRenderer +{ + public BatteringRamItemGeoRenderer() + { + super(new MachineItemModel<>("battering_ram")); + } +} diff --git a/src/main/java/magistu/siegemachines/client/renderer/CatapultGeoRenderer.java b/src/main/java/magistu/siegemachines/client/renderer/CatapultGeoRenderer.java new file mode 100644 index 0000000..b116e92 --- /dev/null +++ b/src/main/java/magistu/siegemachines/client/renderer/CatapultGeoRenderer.java @@ -0,0 +1,26 @@ +package magistu.siegemachines.client.renderer; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.vertex.IVertexBuilder; +import magistu.siegemachines.client.renderer.model.MachineModel; +import magistu.siegemachines.entity.machine.Catapult; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.EntityRendererManager; +import net.minecraft.util.ResourceLocation; + +public class CatapultGeoRenderer extends MachineGeoRenderer +{ + public CatapultGeoRenderer(EntityRendererManager renderManager) + { + super(renderManager, new MachineModel<>("catapult")); + } + + @Override + public RenderType getRenderType(Catapult animatable, float partialTicks, MatrixStack stack, + IRenderTypeBuffer renderTypeBuffer, IVertexBuilder vertexBuilder, int packedLightIn, + ResourceLocation textureLocation) + { + return RenderType.entityTranslucent(getTextureLocation(animatable)); + } +} diff --git a/src/main/java/magistu/siegemachines/client/renderer/CatapultItemGeoRenderer.java b/src/main/java/magistu/siegemachines/client/renderer/CatapultItemGeoRenderer.java new file mode 100644 index 0000000..1d6eef1 --- /dev/null +++ b/src/main/java/magistu/siegemachines/client/renderer/CatapultItemGeoRenderer.java @@ -0,0 +1,11 @@ +package magistu.siegemachines.client.renderer; + +import magistu.siegemachines.client.renderer.model.MachineItemModel; + +public class CatapultItemGeoRenderer extends MachineItemGeoRenderer +{ + public CatapultItemGeoRenderer() + { + super(new MachineItemModel<>("catapult")); + } +} diff --git a/src/main/java/magistu/siegemachines/client/renderer/CulverinGeoRenderer.java b/src/main/java/magistu/siegemachines/client/renderer/CulverinGeoRenderer.java new file mode 100644 index 0000000..34aa563 --- /dev/null +++ b/src/main/java/magistu/siegemachines/client/renderer/CulverinGeoRenderer.java @@ -0,0 +1,32 @@ +package magistu.siegemachines.client.renderer; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.vertex.IVertexBuilder; +import magistu.siegemachines.client.renderer.model.MachineModel; +import magistu.siegemachines.entity.machine.Culverin; +import magistu.siegemachines.entity.machine.Mortar; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.EntityRendererManager; +import net.minecraft.util.ResourceLocation; +import software.bernie.geckolib3.geo.render.built.GeoBone; +import software.bernie.geckolib3.geo.render.built.GeoModel; +import software.bernie.geckolib3.model.provider.GeoModelProvider; + +import java.util.Optional; + +public class CulverinGeoRenderer extends MachineGeoRenderer +{ + public CulverinGeoRenderer(EntityRendererManager renderManager) + { + super(renderManager, new MachineModel<>("culverin")); + } + + @Override + public RenderType getRenderType(Culverin animatable, float partialTicks, MatrixStack stack, + IRenderTypeBuffer renderTypeBuffer, IVertexBuilder vertexBuilder, int packedLightIn, + ResourceLocation textureLocation) + { + return RenderType.entityTranslucent(getTextureLocation(animatable)); + } +} diff --git a/src/main/java/magistu/siegemachines/client/renderer/CulverinItemGeoRenderer.java b/src/main/java/magistu/siegemachines/client/renderer/CulverinItemGeoRenderer.java new file mode 100644 index 0000000..4246e39 --- /dev/null +++ b/src/main/java/magistu/siegemachines/client/renderer/CulverinItemGeoRenderer.java @@ -0,0 +1,11 @@ +package magistu.siegemachines.client.renderer; + +import magistu.siegemachines.client.renderer.model.MachineItemModel; + +public class CulverinItemGeoRenderer extends MachineItemGeoRenderer +{ + public CulverinItemGeoRenderer() + { + super(new MachineItemModel<>("culverin")); + } +} diff --git a/src/main/java/magistu/siegemachines/client/renderer/GiantArrowRenderer.java b/src/main/java/magistu/siegemachines/client/renderer/GiantArrowRenderer.java new file mode 100644 index 0000000..c618c7b --- /dev/null +++ b/src/main/java/magistu/siegemachines/client/renderer/GiantArrowRenderer.java @@ -0,0 +1,54 @@ +package magistu.siegemachines.client.renderer; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.vertex.IVertexBuilder; +import magistu.siegemachines.SiegeMachines; +import magistu.siegemachines.client.renderer.model.GiantArrowModel; +import magistu.siegemachines.entity.projectile.GiantArrow; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.entity.EntityRenderer; +import net.minecraft.client.renderer.entity.EntityRendererManager; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.MathHelper; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import org.jetbrains.annotations.NotNull; + +@OnlyIn(Dist.CLIENT) +public class GiantArrowRenderer extends EntityRenderer +{ + public static final ResourceLocation TEXTURE_LOCATION = new ResourceLocation(SiegeMachines.ID, "textures/entity/giant_arrow.png"); +// public static final ResourceLocation TEXTURE_LOCATION = new ResourceLocation("textures/entity/projectiles/arrow.png"); + + public GiantArrowModel model = new GiantArrowModel(); + + public GiantArrowRenderer(EntityRendererManager p_i46547_1_) + { + super(p_i46547_1_); + } + + @Override + public @NotNull ResourceLocation getTextureLocation(@NotNull GiantArrow p_110775_1_) + { + return TEXTURE_LOCATION; + } + + public void render(@NotNull GiantArrow giantarrow, float p_225623_2_, float p_225623_3_, @NotNull MatrixStack matrixstack, @NotNull IRenderTypeBuffer buffer, int n) + { + matrixstack.pushPose(); + matrixstack.scale(-1.0F, -1.0F, -1.0F); + float f = MathHelper.lerp(p_225623_3_, giantarrow.yRotO, giantarrow.yRot); + float f1 = -MathHelper.lerp(p_225623_3_, giantarrow.xRotO, giantarrow.xRot); + float f2 = (float) giantarrow.shakeTime - p_225623_3_; + if (f2 > 0.0F) + { + f1 -= MathHelper.sin(f2 * 3.0F) * f2; + } + IVertexBuilder ivertexbuilder = buffer.getBuffer(this.model.renderType(this.getTextureLocation(giantarrow))); + this.model.setupAnim(0.0F, f, f1); + this.model.renderToBuffer(matrixstack, ivertexbuilder, n, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F, 1.0F); + matrixstack.popPose(); + super.render(giantarrow, p_225623_2_, p_225623_3_, matrixstack, buffer, n); + } +} diff --git a/src/main/java/magistu/siegemachines/client/renderer/MachineGeoRenderer.java b/src/main/java/magistu/siegemachines/client/renderer/MachineGeoRenderer.java new file mode 100644 index 0000000..bf93a0e --- /dev/null +++ b/src/main/java/magistu/siegemachines/client/renderer/MachineGeoRenderer.java @@ -0,0 +1,21 @@ +package magistu.siegemachines.client.renderer; + +import magistu.siegemachines.entity.machine.Machine; +import net.minecraft.client.renderer.entity.EntityRendererManager; +import software.bernie.geckolib3.core.IAnimatable; +import software.bernie.geckolib3.model.AnimatedGeoModel; +import software.bernie.geckolib3.renderers.geo.GeoEntityRenderer; + +public abstract class MachineGeoRenderer extends GeoEntityRenderer +{ + protected MachineGeoRenderer(EntityRendererManager rendermanager, AnimatedGeoModel model) + { + super(rendermanager, model); + } + + @Override + protected float getDeathMaxRotation(T entity) + { + return 0.0F; + } +} diff --git a/src/main/java/magistu/siegemachines/client/renderer/MachineItemGeoRenderer.java b/src/main/java/magistu/siegemachines/client/renderer/MachineItemGeoRenderer.java new file mode 100644 index 0000000..c5502b8 --- /dev/null +++ b/src/main/java/magistu/siegemachines/client/renderer/MachineItemGeoRenderer.java @@ -0,0 +1,26 @@ +package magistu.siegemachines.client.renderer; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.vertex.IVertexBuilder; +import magistu.siegemachines.client.renderer.MachineGeoRenderer; +import magistu.siegemachines.client.renderer.model.MachineItemModel; +import magistu.siegemachines.entity.machine.Mortar; +import magistu.siegemachines.item.MachineItem; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.EntityRendererManager; +import net.minecraft.util.ResourceLocation; +import software.bernie.geckolib3.geo.render.built.GeoBone; +import software.bernie.geckolib3.geo.render.built.GeoModel; +import software.bernie.geckolib3.model.provider.GeoModelProvider; +import software.bernie.geckolib3.renderers.geo.GeoItemRenderer; + +import java.util.Optional; + +public class MachineItemGeoRenderer extends GeoItemRenderer +{ + public MachineItemGeoRenderer(MachineItemModel model) + { + super(model); + } +} diff --git a/src/main/java/magistu/siegemachines/client/renderer/MortarGeoRenderer.java b/src/main/java/magistu/siegemachines/client/renderer/MortarGeoRenderer.java new file mode 100644 index 0000000..13e2672 --- /dev/null +++ b/src/main/java/magistu/siegemachines/client/renderer/MortarGeoRenderer.java @@ -0,0 +1,44 @@ +package magistu.siegemachines.client.renderer; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.vertex.IVertexBuilder; +import magistu.siegemachines.client.renderer.model.MachineModel; +import magistu.siegemachines.entity.machine.Mortar; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.EntityRendererManager; +import net.minecraft.util.ResourceLocation; +import software.bernie.geckolib3.geo.render.built.GeoBone; +import software.bernie.geckolib3.geo.render.built.GeoModel; +import software.bernie.geckolib3.model.provider.GeoModelProvider; + +import java.util.Optional; + +public class MortarGeoRenderer extends MachineGeoRenderer +{ + public MortarGeoRenderer(EntityRendererManager renderManager) + { + super(renderManager, new MachineModel<>("mortar")); + } + + @Override + public RenderType getRenderType(Mortar animatable, float partialTicks, MatrixStack stack, + IRenderTypeBuffer renderTypeBuffer, IVertexBuilder vertexBuilder, int packedLightIn, + ResourceLocation textureLocation) + { + return RenderType.entityTranslucent(getTextureLocation(animatable)); + } + + @Override + public void renderEarly(Mortar animatable, MatrixStack stackIn, float ticks, IRenderTypeBuffer renderTypeBuffer, IVertexBuilder vertexBuilder, int packedLightIn, int packedOverlayIn, float red, float green, float blue, float partialTicks) + { + GeoModelProvider modelProvider = this.getGeoModelProvider(); + GeoModel model = modelProvider.getModel(modelProvider.getModelLocation(animatable)); + + Optional bone0 = model.getBone("Barrel"); + bone0.ifPresent(bone -> bone.setRotationX(-animatable.getTurretPitch() * (float) Math.PI / 180.0f)); + bone0.ifPresent(bone -> bone.setRotationY(-animatable.getTurretYaw() * (float) Math.PI / 180.0f)); + + super.renderEarly(animatable, stackIn, ticks, renderTypeBuffer, vertexBuilder, packedLightIn, packedOverlayIn, red, green, blue, partialTicks); + } +} diff --git a/src/main/java/magistu/siegemachines/client/renderer/MortarItemGeoRenderer.java b/src/main/java/magistu/siegemachines/client/renderer/MortarItemGeoRenderer.java new file mode 100644 index 0000000..4553e06 --- /dev/null +++ b/src/main/java/magistu/siegemachines/client/renderer/MortarItemGeoRenderer.java @@ -0,0 +1,12 @@ +package magistu.siegemachines.client.renderer; + +import magistu.siegemachines.client.renderer.MachineItemGeoRenderer; +import magistu.siegemachines.client.renderer.model.MachineItemModel; + +public class MortarItemGeoRenderer extends MachineItemGeoRenderer +{ + public MortarItemGeoRenderer() + { + super(new MachineItemModel<>("mortar")); + } +} diff --git a/src/main/java/magistu/siegemachines/client/renderer/TrebuchetGeoRenderer.java b/src/main/java/magistu/siegemachines/client/renderer/TrebuchetGeoRenderer.java new file mode 100644 index 0000000..997c680 --- /dev/null +++ b/src/main/java/magistu/siegemachines/client/renderer/TrebuchetGeoRenderer.java @@ -0,0 +1,47 @@ +package magistu.siegemachines.client.renderer; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.vertex.IVertexBuilder; +import magistu.siegemachines.client.renderer.model.MachineModel; +import magistu.siegemachines.entity.machine.Trebuchet; +import net.minecraft.client.renderer.IRenderTypeBuffer; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.entity.EntityRendererManager; +import net.minecraft.item.Items; +import net.minecraft.util.ResourceLocation; +import software.bernie.geckolib3.geo.render.built.GeoBone; +import software.bernie.geckolib3.geo.render.built.GeoModel; +import software.bernie.geckolib3.model.provider.GeoModelProvider; + +import java.util.Optional; + +public class TrebuchetGeoRenderer extends MachineGeoRenderer +{ + public TrebuchetGeoRenderer(EntityRendererManager renderManager) + { + super(renderManager, new MachineModel<>("trebuchet")); + } + + @Override + public RenderType getRenderType(Trebuchet animatable, float partialTicks, MatrixStack stack, + IRenderTypeBuffer renderTypeBuffer, IVertexBuilder vertexBuilder, int packedLightIn, + ResourceLocation textureLocation) + { + return RenderType.entityTranslucent(getTextureLocation(animatable)); + } + + @Override + public void renderEarly(Trebuchet animatable, MatrixStack stackIn, float ticks, IRenderTypeBuffer renderTypeBuffer, IVertexBuilder vertexBuilder, int packedLightIn, int packedOverlayIn, float red, float green, float blue, float partialTicks) + { + GeoModelProvider modelProvider = this.getGeoModelProvider(); + GeoModel model = modelProvider.getModel(modelProvider.getModelLocation(animatable)); + + Optional projectile = model.getBone("Cobblestone"); + int projectilesize = (animatable.state == Trebuchet.State.IDLE_RELOADED || animatable.shootingticks > 0) && animatable.hasAmmo() ? 1 : 0; + projectile.ifPresent(bone -> bone.setScaleX(projectilesize)); + projectile.ifPresent(bone -> bone.setScaleY(projectilesize)); + projectile.ifPresent(bone -> bone.setScaleZ(projectilesize)); + + super.renderEarly(animatable, stackIn, ticks, renderTypeBuffer, vertexBuilder, packedLightIn, packedOverlayIn, red, green, blue, partialTicks); + } +} diff --git a/src/main/java/magistu/siegemachines/client/renderer/TrebuchetItemGeoRenderer.java b/src/main/java/magistu/siegemachines/client/renderer/TrebuchetItemGeoRenderer.java new file mode 100644 index 0000000..ffce04a --- /dev/null +++ b/src/main/java/magistu/siegemachines/client/renderer/TrebuchetItemGeoRenderer.java @@ -0,0 +1,12 @@ +package magistu.siegemachines.client.renderer; + +import magistu.siegemachines.client.renderer.MachineItemGeoRenderer; +import magistu.siegemachines.client.renderer.model.MachineItemModel; + +public class TrebuchetItemGeoRenderer extends MachineItemGeoRenderer +{ + public TrebuchetItemGeoRenderer() + { + super(new MachineItemModel<>("trebuchet")); + } +} diff --git a/src/main/java/magistu/siegemachines/client/renderer/model/GiantArrowModel.java b/src/main/java/magistu/siegemachines/client/renderer/model/GiantArrowModel.java new file mode 100644 index 0000000..adbd928 --- /dev/null +++ b/src/main/java/magistu/siegemachines/client/renderer/model/GiantArrowModel.java @@ -0,0 +1,58 @@ +package magistu.siegemachines.client.renderer.model; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.vertex.IVertexBuilder; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.model.Model; +import net.minecraft.client.renderer.model.ModelRenderer; + +public class GiantArrowModel extends Model +{ + private final ModelRenderer cube_r0; + private final ModelRenderer cube_r1; + private final ModelRenderer cube_r2; + + public GiantArrowModel() + { + super(RenderType::entityCutout); + texWidth = 64; + texHeight = 64; + + cube_r0 = new ModelRenderer(this); + cube_r0.setPos(0.0F, 0.0F, 0.0F); + setRotationAngle(cube_r0, 0.0F, 0.0F, 0.0F); + + cube_r1 = new ModelRenderer(this); + cube_r1.setPos(0.0F, 0.0F, 3.0F); + cube_r0.addChild(cube_r1); + setRotationAngle(cube_r1, 0.0F, 0.0F, -0.7854F); + cube_r1.texOffs(15, 0).addBox(-2.0F, 0.0F, -10.0F, 4.0F, 0.0F, 4.0F, 0.0F, false); + cube_r1.texOffs(-34, 0).addBox(-2.5F, 0.0F, -7.0F, 5.0F, 0.0F, 34.0F, 0.0F, false); + + cube_r2 = new ModelRenderer(this); + cube_r2.setPos(0.0F, 0.0F, 3.0F); + cube_r0.addChild(cube_r2); + setRotationAngle(cube_r2, 0.0F, 0.0F, 0.7854F); + cube_r2.texOffs(7, 0).addBox(-2.0F, 0.0F, -10.0F, 4.0F, 0.0F, 4.0F, 0.0F, false); + cube_r2.texOffs(-34, 0).addBox(-2.5F, 0.0F, -7.0F, 5.0F, 0.0F, 34.0F, 0.0F, false); + } + + public void setupAnim(float p_225603_1_, float p_225603_2_, float p_225603_3_) + { + this.cube_r0.yRot = p_225603_2_ * ((float)Math.PI / 180F); + this.cube_r0.xRot = p_225603_3_ * ((float)Math.PI / 180F); + } + + public void setRotationAngle(ModelRenderer modelRenderer, float x, float y, float z) + { + modelRenderer.xRot = x; + modelRenderer.yRot = y; + modelRenderer.zRot = z; + } + + @Override + public void renderToBuffer(MatrixStack p_225598_1_, IVertexBuilder p_225598_2_, int p_225598_3_, int p_225598_4_, float p_225598_5_, float p_225598_6_, float p_225598_7_, float p_225598_8_) + { + cube_r0.render(p_225598_1_, p_225598_2_, p_225598_3_, p_225598_4_, p_225598_5_, p_225598_6_, p_225598_7_, p_225598_8_); + } +} diff --git a/src/main/java/magistu/siegemachines/client/renderer/model/MachineItemModel.java b/src/main/java/magistu/siegemachines/client/renderer/model/MachineItemModel.java new file mode 100644 index 0000000..2937861 --- /dev/null +++ b/src/main/java/magistu/siegemachines/client/renderer/model/MachineItemModel.java @@ -0,0 +1,42 @@ +package magistu.siegemachines.client.renderer.model; + +import magistu.siegemachines.SiegeMachines; +import magistu.siegemachines.item.MachineItem; +import net.minecraft.util.ResourceLocation; +import software.bernie.geckolib3.core.IAnimatable; +import software.bernie.geckolib3.model.AnimatedGeoModel; + + +public class MachineItemModel extends AnimatedGeoModel +{ + public final String name; + public final ResourceLocation animationlocation; + public final ResourceLocation modellocation; + public final ResourceLocation texturelocation; + + public MachineItemModel(String name) + { + this.name = name; + this.animationlocation = new ResourceLocation(SiegeMachines.ID, "animations/none.animation.json"); + this.modellocation = new ResourceLocation(SiegeMachines.ID, "geo/" + this.name + "_item.geo.json"); + this.texturelocation = new ResourceLocation(SiegeMachines.ID, "textures/entity/" + this.name + ".png"); + } + + @Override + public ResourceLocation getAnimationFileLocation(T entity) + { + return this.animationlocation; + } + + @Override + public ResourceLocation getModelLocation(T entity) + { + return this.modellocation; + } + + @Override + public ResourceLocation getTextureLocation(T entity) + { + return this.texturelocation; + } +} diff --git a/src/main/java/magistu/siegemachines/client/renderer/model/MachineModel.java b/src/main/java/magistu/siegemachines/client/renderer/model/MachineModel.java new file mode 100644 index 0000000..54b0733 --- /dev/null +++ b/src/main/java/magistu/siegemachines/client/renderer/model/MachineModel.java @@ -0,0 +1,42 @@ +package magistu.siegemachines.client.renderer.model; + +import magistu.siegemachines.SiegeMachines; +import magistu.siegemachines.entity.machine.Machine; +import net.minecraft.util.ResourceLocation; +import software.bernie.geckolib3.core.IAnimatable; +import software.bernie.geckolib3.model.AnimatedGeoModel; + + +public class MachineModel extends AnimatedGeoModel +{ + public final String name; + public final ResourceLocation animationlocation; + public final ResourceLocation modellocation; + public final ResourceLocation texturelocation; + + public MachineModel(String name) + { + this.name = name; + this.animationlocation = new ResourceLocation(SiegeMachines.ID, "animations/" + this.name + ".animation.json"); + this.modellocation = new ResourceLocation(SiegeMachines.ID, "geo/" + this.name + ".geo.json"); + this.texturelocation = new ResourceLocation(SiegeMachines.ID, "textures/entity/" + this.name + ".png"); + } + + @Override + public ResourceLocation getAnimationFileLocation(T entity) + { + return this.animationlocation; + } + + @Override + public ResourceLocation getModelLocation(T entity) + { + return this.modellocation; + } + + @Override + public ResourceLocation getTextureLocation(T entity) + { + return this.texturelocation; + } +} diff --git a/src/main/java/magistu/siegemachines/config/MissileSpecs.java b/src/main/java/magistu/siegemachines/config/MissileSpecs.java new file mode 100644 index 0000000..3eae88c --- /dev/null +++ b/src/main/java/magistu/siegemachines/config/MissileSpecs.java @@ -0,0 +1,21 @@ +package magistu.siegemachines.config; + +import net.minecraftforge.common.ForgeConfigSpec; + +public class MissileSpecs +{ + public final ForgeConfigSpec.ConfigValue mass; + public final ForgeConfigSpec.ConfigValue explosionpower; + public final ForgeConfigSpec.ConfigValue destroysground; + + public MissileSpecs(ForgeConfigSpec.Builder builder, String name, float mass, float explosionpower, boolean destroysground) + { + builder.push(name); + + this.mass = builder.define("mass", mass); + this.explosionpower = builder.define("explosionRadius", explosionpower); + this.destroysground = builder.define("destroysGround", destroysground); + + builder.pop(); + } +} diff --git a/src/main/java/magistu/siegemachines/config/SiegeMachineSpecs.java b/src/main/java/magistu/siegemachines/config/SiegeMachineSpecs.java new file mode 100644 index 0000000..b63ab47 --- /dev/null +++ b/src/main/java/magistu/siegemachines/config/SiegeMachineSpecs.java @@ -0,0 +1,27 @@ +package magistu.siegemachines.config; + +import net.minecraftforge.common.ForgeConfigSpec; + +public final class SiegeMachineSpecs +{ + private final String name; + + public final ForgeConfigSpec.ConfigValue durability; + public final ForgeConfigSpec.ConfigValue delaytime; + public final ForgeConfigSpec.ConfigValue projectilespeed; + public final ForgeConfigSpec.ConfigValue inaccuracy; + + public SiegeMachineSpecs(ForgeConfigSpec.Builder builder, String name, int durability, int delaytime, float projectilespeed, float inaccuracy) + { + this.name = name; + + builder.push(name); + + this.durability = builder.define("durability", durability); + this.delaytime = builder.define("reloadTime", delaytime); + this.projectilespeed = builder.define("projectileSpeed", projectilespeed); + this.inaccuracy = builder.define("inaccuracy", inaccuracy); + + builder.pop(); + } +} diff --git a/src/main/java/magistu/siegemachines/config/SpecsConfig.java b/src/main/java/magistu/siegemachines/config/SpecsConfig.java new file mode 100644 index 0000000..b7f7e65 --- /dev/null +++ b/src/main/java/magistu/siegemachines/config/SpecsConfig.java @@ -0,0 +1,52 @@ +package magistu.siegemachines.config; + +import net.minecraftforge.common.ForgeConfigSpec; +import net.minecraftforge.fml.ModLoadingContext; +import net.minecraftforge.fml.config.ModConfig; + +public final class SpecsConfig +{ + public static final ForgeConfigSpec.Builder BUILDER = new ForgeConfigSpec.Builder(); + public static final ForgeConfigSpec SPEC; + + public static final SiegeMachineSpecs MORTAR; + public static final SiegeMachineSpecs CULVERIN; + public static final SiegeMachineSpecs TREBUCHET; + public static final SiegeMachineSpecs CATAPULT; + public static final SiegeMachineSpecs BALLISTA; + public static final SiegeMachineSpecs BATTERING_RAM; + + public static final MissileSpecs CANNONBALL; + public static final MissileSpecs STONE; + public static final MissileSpecs GIANT_STONE; + + static + { + BUILDER.push("siege_machines"); + + MORTAR = new SiegeMachineSpecs(BUILDER, "mortar", 80, 200, 2.5f, 0.2f); + CULVERIN = new SiegeMachineSpecs(BUILDER, "culverin", 80, 200, 3.0f, 0.2f); + TREBUCHET = new SiegeMachineSpecs(BUILDER, "trebuchet", 300, 400, 2.8f, 0.2f); + CATAPULT = new SiegeMachineSpecs(BUILDER, "catapult", 100, 200, 2.0f, 0.2f); + BALLISTA = new SiegeMachineSpecs(BUILDER, "ballista", 50, 120, 4.5f, 0.04f); + BATTERING_RAM = new SiegeMachineSpecs(BUILDER, "battering_ram", 250, 100, 0.0f, 0.5f); + + BUILDER.pop(); + + BUILDER.push("missiles"); + + CANNONBALL = new MissileSpecs(BUILDER, "cannonball", 15.0f, 3.0f, false); + STONE = new MissileSpecs(BUILDER, "stone", 50.0f, 2.0f, false); + GIANT_STONE = new MissileSpecs(BUILDER, "giant_stone", 70.0f, 5.0f, false); + + BUILDER.pop(); + + SPEC = BUILDER.build(); + } + + + public static void register() + { + ModLoadingContext.get().registerConfig(ModConfig.Type.COMMON, SPEC, "siege-machines-specs.toml"); + } +} diff --git a/src/main/java/magistu/siegemachines/data/recipes/ISiegeWorkbenchRecipe.java b/src/main/java/magistu/siegemachines/data/recipes/ISiegeWorkbenchRecipe.java new file mode 100644 index 0000000..1d3e3ca --- /dev/null +++ b/src/main/java/magistu/siegemachines/data/recipes/ISiegeWorkbenchRecipe.java @@ -0,0 +1,32 @@ +package magistu.siegemachines.data.recipes; + +import magistu.siegemachines.SiegeMachines; +import net.minecraft.inventory.CraftingInventory; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.item.crafting.IRecipeType; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.registry.Registry; +import org.jetbrains.annotations.NotNull; + +public interface ISiegeWorkbenchRecipe extends IRecipe +{ + ResourceLocation TYPE_ID = new ResourceLocation(SiegeMachines.ID, "siege_workbench"); + + @Override + default @NotNull IRecipeType getType(){ + return Registry.RECIPE_TYPE.getOptional(TYPE_ID).get(); + } + + @Override + default boolean canCraftInDimensions(int width, int height) + { + return true; + } + + @Override + default boolean isSpecial() + { + return true; + } +} diff --git a/src/main/java/magistu/siegemachines/data/recipes/ModRecipes.java b/src/main/java/magistu/siegemachines/data/recipes/ModRecipes.java new file mode 100644 index 0000000..b866b87 --- /dev/null +++ b/src/main/java/magistu/siegemachines/data/recipes/ModRecipes.java @@ -0,0 +1,25 @@ +package magistu.siegemachines.data.recipes; + +import magistu.siegemachines.SiegeMachines; +import net.minecraft.item.crafting.IRecipeSerializer; +import net.minecraft.item.crafting.IRecipeType; +import net.minecraft.util.registry.Registry; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.fml.RegistryObject; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; + +public class ModRecipes +{ + public static final DeferredRegister> RECIPE_SERIALIZER = DeferredRegister.create(ForgeRegistries.RECIPE_SERIALIZERS, SiegeMachines.ID); + public static final RegistryObject SIEGE_WORKBENCH_SERIALIZER = RECIPE_SERIALIZER.register("siege_workbench", SiegeWorkbenchRecipe.Serializer::new); + + public static IRecipeType SIEGE_WORKBENCH_RECIPE = new SiegeWorkbenchRecipe.SiegeWorkbenchRecipeType(); + + public static void register(IEventBus eventBus) + { + RECIPE_SERIALIZER.register(eventBus); + + Registry.register(Registry.RECIPE_TYPE, SiegeWorkbenchRecipe.TYPE_ID, SIEGE_WORKBENCH_RECIPE); + } +} diff --git a/src/main/java/magistu/siegemachines/data/recipes/SiegeWorkbenchRecipe.java b/src/main/java/magistu/siegemachines/data/recipes/SiegeWorkbenchRecipe.java new file mode 100644 index 0000000..0bfcd16 --- /dev/null +++ b/src/main/java/magistu/siegemachines/data/recipes/SiegeWorkbenchRecipe.java @@ -0,0 +1,580 @@ +package magistu.siegemachines.data.recipes; + +import com.google.common.annotations.VisibleForTesting; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.google.gson.*; +import magistu.siegemachines.SiegeMachines; +import magistu.siegemachines.block.ModBlocks; +import net.minecraft.inventory.CraftingInventory; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.*; +import net.minecraft.network.PacketBuffer; +import net.minecraft.tags.ITag; +import net.minecraft.tags.TagCollectionManager; +import net.minecraft.util.JSONUtils; +import net.minecraft.util.NonNullList; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.World; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nullable; +import java.util.*; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + + +public class SiegeWorkbenchRecipe implements ISiegeWorkbenchRecipe, net.minecraftforge.common.crafting.IShapedRecipe +{ + static int MAX_WIDTH = 3; + static int MAX_HEIGHT = 3; + /** + * Expand the max width and height allowed in the deserializer. + * This should be called by modders who add custom crafting tables that are larger than the vanilla 3x3. + * @param width your max recipe width + * @param height your max recipe height + */ + public static void setCraftingSize(int width, int height) + { + if (MAX_WIDTH < width) MAX_WIDTH = width; + if (MAX_HEIGHT < height) MAX_HEIGHT = height; + } + + private final int width; + private final int height; + private final NonNullList recipeItems; + private final ItemStack result; + private final ResourceLocation id; + private final String group; + + public SiegeWorkbenchRecipe(ResourceLocation p_i48162_1_, String p_i48162_2_, int p_i48162_3_, int p_i48162_4_, NonNullList p_i48162_5_, ItemStack p_i48162_6_) + { + this.id = p_i48162_1_; + this.group = p_i48162_2_; + this.width = p_i48162_3_; + this.height = p_i48162_4_; + this.recipeItems = p_i48162_5_; + this.result = p_i48162_6_; + } + + public static class SiegeWorkbenchRecipeType implements IRecipeType + { + @Override + public String toString() + { + return SiegeWorkbenchRecipe.TYPE_ID.toString(); + } + } + + public ResourceLocation getId() + { + return this.id; + } + + public IRecipeSerializer getSerializer() + { + return ModRecipes.SIEGE_WORKBENCH_SERIALIZER.get(); + } + + public String getGroup() + { + return this.group; + } + + public ItemStack getResultItem() + { + return this.result; + } + + public @NotNull NonNullList getIngredients() + { + return this.recipeItems; + } + + public boolean canCraftInDimensions(int p_194133_1_, int p_194133_2_) + { + return p_194133_1_ >= this.width && p_194133_2_ >= this.height; + } + + public boolean testIngredient(Ingredient ingredient, @Nullable ItemStack p_test_1_) + { + if (p_test_1_ == null) + { + return false; + } + else + { + if (ingredient.getItems().length == 0) + { + return p_test_1_.isEmpty(); + } + else + { + for (ItemStack itemstack : ingredient.getItems()) + { + if (itemstack.getItem() == p_test_1_.getItem() && itemstack.getCount() == p_test_1_.getCount()) + { + return true; + } + } + + return false; + } + } + } + + public boolean matches(CraftingInventory p_77569_1_, World p_77569_2_) + { + for (int i = 0; i <= p_77569_1_.getWidth() - this.width; ++i) + { + for (int j = 0; j <= p_77569_1_.getHeight() - this.height; ++j) + { + if (this.matches(p_77569_1_, i, j, true)) + { + return true; + } + + if (this.matches(p_77569_1_, i, j, false)) + { + return true; + } + } + } + + return false; + } + + private boolean matches(CraftingInventory p_77573_1_, int p_77573_2_, int p_77573_3_, boolean p_77573_4_) + { + for (int i = 0; i < p_77573_1_.getWidth(); ++i) + { + for (int j = 0; j < p_77573_1_.getHeight(); ++j) + { + int k = i - p_77573_2_; + int l = j - p_77573_3_; + Ingredient ingredient = Ingredient.EMPTY; + if (k >= 0 && l >= 0 && k < this.width && l < this.height) + { + if (p_77573_4_) + { + ingredient = this.recipeItems.get(this.width - k - 1 + l * this.width); + } + else + { + ingredient = this.recipeItems.get(k + l * this.width); + } + } + ItemStack itemstack = p_77573_1_.getItem(i + j * p_77573_1_.getWidth()); + + if (!this.testIngredient(ingredient, itemstack)) + { + return false; + } + } + } + + return true; + } + + public ItemStack assemble(CraftingInventory p_77572_1_) + { + return this.getResultItem().copy(); + } + + public int getWidth() + { + return this.width; + } + + @Override + public int getRecipeWidth() + { + return getWidth(); + } + + public int getHeight() + { + return this.height; + } + + @Override + public int getRecipeHeight() + { + return getHeight(); + } + + @Override + public @NotNull ItemStack getToastSymbol() + { + return new ItemStack(ModBlocks.SIEGE_WORKBENCH.get()); + } + + private static NonNullList dissolvePattern(String[] p_192402_0_, Map p_192402_1_, int p_192402_2_, int p_192402_3_) + { + NonNullList nonnulllist = NonNullList.withSize(p_192402_2_ * p_192402_3_, Ingredient.EMPTY); + Set set = Sets.newHashSet(p_192402_1_.keySet()); + set.remove(" "); + + for (int i = 0; i < p_192402_0_.length; ++i) + { + for (int j = 0; j < p_192402_0_[i].length(); ++j) + { + String s = p_192402_0_[i].substring(j, j + 1); + Ingredient ingredient = p_192402_1_.get(s); + if (ingredient == null) + { + throw new JsonSyntaxException("Pattern references symbol '" + s + "' but it's not defined in the key"); + } + + set.remove(s); + nonnulllist.set(j + p_192402_2_ * i, ingredient); + } + } + + if (!set.isEmpty()) + { + throw new JsonSyntaxException("Key defines symbols that aren't used in pattern: " + set); + } + else + { + return nonnulllist; + } + } + + @VisibleForTesting + static String[] shrink(String... p_194134_0_) + { + int i = Integer.MAX_VALUE; + int j = 0; + int k = 0; + int l = 0; + + for (int i1 = 0; i1 < p_194134_0_.length; ++i1) + { + String s = p_194134_0_[i1]; + i = Math.min(i, firstNonSpace(s)); + int j1 = lastNonSpace(s); + j = Math.max(j, j1); + if (j1 < 0) + { + if (k == i1) + { + ++k; + } + + ++l; + } + else + { + l = 0; + } + } + + if (p_194134_0_.length == l) + { + return new String[0]; + } + else + { + String[] astring = new String[p_194134_0_.length - l - k]; + + for (int k1 = 0; k1 < astring.length; ++k1) + { + astring[k1] = p_194134_0_[k1 + k].substring(i, j + 1); + } + + return astring; + } + } + + private static int firstNonSpace(String p_194135_0_) + { + int i; + for (i = 0; i < p_194135_0_.length() && p_194135_0_.charAt(i) == ' '; ++i) + { + } + + return i; + } + + private static int lastNonSpace(String p_194136_0_) + { + int i; + for (i = p_194136_0_.length() - 1; i >= 0 && p_194136_0_.charAt(i) == ' '; --i) + { + } + + return i; + } + + private static String[] patternFromJson(JsonArray p_192407_0_) + { + String[] astring = new String[p_192407_0_.size()]; + if (astring.length > MAX_HEIGHT) + { + throw new JsonSyntaxException("Invalid pattern: too many rows, " + MAX_HEIGHT + " is maximum"); + } else if (astring.length == 0) + { + throw new JsonSyntaxException("Invalid pattern: empty pattern not allowed"); + } + else + { + for (int i = 0; i < astring.length; ++i) + { + String s = JSONUtils.convertToString(p_192407_0_.get(i), "pattern[" + i + "]"); + if (s.length() > MAX_WIDTH) + { + throw new JsonSyntaxException("Invalid pattern: too many columns, " + MAX_WIDTH + " is maximum"); + } + + if (i > 0 && astring[0].length() != s.length()) + { + throw new JsonSyntaxException("Invalid pattern: each row must be the same width"); + } + + astring[i] = s; + } + + return astring; + } + } + + public static class TagStackList extends Ingredient.TagList + { + private final int count; + + public TagStackList(ITag p_i48193_1_, int count) + { + super(p_i48193_1_); + this.count = count; + } + + public Collection getItems() + { + Collection list = super.getItems(); + list.forEach(ele -> ele.setCount(this.count)); + return list; + } + + public @NotNull JsonObject serialize() + { + JsonObject jsonobject = super.serialize(); + return jsonobject; + } + } + + + public static Ingredient.IItemList valueFromJson(JsonObject p_199803_0_) + { + int count = JSONUtils.getAsInt(p_199803_0_, "count", 1); + if (p_199803_0_.has("item") && p_199803_0_.has("tag")) + { + throw new JsonParseException("An ingredient entry is either a tag or an item, not both"); + } + else if (p_199803_0_.has("item")) + { + ResourceLocation resourcelocation1 = new ResourceLocation(JSONUtils.getAsString(p_199803_0_, "item")); + Item item = Registry.ITEM.getOptional(resourcelocation1).orElseThrow(() -> new JsonSyntaxException("Unknown item '" + resourcelocation1 + "'")); + return new Ingredient.SingleItemList(new ItemStack(item, count)); + } + else if (p_199803_0_.has("tag")) + { + ResourceLocation resourcelocation = new ResourceLocation(JSONUtils.getAsString(p_199803_0_, "tag")); + ITag itag = TagCollectionManager.getInstance().getItems().getTag(resourcelocation); + if (itag == null) + { + throw new JsonSyntaxException("Unknown item tag '" + resourcelocation + "'"); + } + else + { + return new TagStackList(itag, count); + } + } + else + { + throw new JsonParseException("An ingredient entry needs either a tag or an item"); + } + } + + +// public static class CompoundIngredientE extends CompoundIngredient +// { +// protected CompoundIngredientE(List children) +// { +// super(children); +// } +// } +// +// +// public static Ingredient getIngredient(JsonElement json) +// { +// if (json == null || json.isJsonNull()) +// throw new JsonSyntaxException("Json cannot be null"); +// +// if (json.isJsonArray()) +// { +// List ingredients = Lists.newArrayList(); +// List vanilla = Lists.newArrayList(); +// json.getAsJsonArray().forEach((ele) -> +// { +// Ingredient ing = getIngredient(ele); +// +// if (ing.getClass() == Ingredient.class) //Vanilla, Due to how we read it splits each itemstack, so we pull out to re-merge later +// vanilla.add(ing); +// else +// ingredients.add(ing); +// }); +// +// if (!vanilla.isEmpty()) +// ingredients.add(Ingredient.merge(vanilla)); +// +// if (ingredients.size() == 0) +// throw new JsonSyntaxException("Item array cannot be empty, at least one item must be defined"); +// +// if (ingredients.size() == 1) +// return ingredients.get(0); +// +// return new CompoundIngredientE(ingredients); +// } +// +// if (!json.isJsonObject()) +// throw new JsonSyntaxException("Expcted ingredient to be a object or array of objects"); +// +// JsonObject obj = (JsonObject)json; +// +// String type = JSONUtils.getAsString(obj, "type", "minecraft:item"); +// if (type.isEmpty()) +// throw new JsonSyntaxException("Ingredient type can not be an empty string"); +// +// IIngredientSerializer serializer = ingredients.get(new ResourceLocation(type)); +// if (serializer == null) +// throw new JsonSyntaxException("Unknown ingredient type: " + type); +// +// return serializer.parse(obj); +// } + + + public static Ingredient ingredientFromJson(@Nullable JsonElement p_199802_0_) + { + if (p_199802_0_ != null && !p_199802_0_.isJsonNull()) + { +// Ingredient ret = CraftingHelper.getIngredient(p_199802_0_); +// if (ret != null) return ret; + + if (p_199802_0_.isJsonObject()) + { + return Ingredient.fromValues(Stream.of(valueFromJson(p_199802_0_.getAsJsonObject()))); + } + else if (p_199802_0_.isJsonArray()) + { + JsonArray jsonarray = p_199802_0_.getAsJsonArray(); + if (jsonarray.size() == 0) + { + throw new JsonSyntaxException("Item array cannot be empty, at least one item must be defined"); + } + else + { + return Ingredient.fromValues(StreamSupport.stream(jsonarray.spliterator(), false).map((p_209355_0_) -> valueFromJson(JSONUtils.convertToJsonObject(p_209355_0_, "item")))); + } + } + else + { + throw new JsonSyntaxException("Expected item to be object or array of objects"); + } + } + else + { + throw new JsonSyntaxException("Item cannot be null"); + } + } + + + private static Map keyFromJson(JsonObject p_192408_0_) + { + Map map = Maps.newHashMap(); + + for (Map.Entry entry : p_192408_0_.entrySet()) + { + if (entry.getKey().length() != 1) + { + throw new JsonSyntaxException("Invalid key entry: '" + entry.getKey() + "' is an invalid symbol (must be 1 character only)."); + } + + if (" ".equals(entry.getKey())) + { + throw new JsonSyntaxException("Invalid key entry: ' ' is a reserved symbol."); + } + + Ingredient ingredient = ingredientFromJson(entry.getValue()); + + map.put(entry.getKey(), ingredient); + } + + map.put(" ", Ingredient.EMPTY); + return map; + } + + public static ItemStack itemFromJson(JsonObject p_199798_0_) + { + String s = JSONUtils.getAsString(p_199798_0_, "item"); + Item item = Registry.ITEM.getOptional(new ResourceLocation(s)).orElseThrow(() -> new JsonSyntaxException("Unknown item '" + s + "'")); + if (p_199798_0_.has("data")) + { + throw new JsonParseException("Disallowed data tag found"); + } + else + { + int i = JSONUtils.getAsInt(p_199798_0_, "count", 1); + return net.minecraftforge.common.crafting.CraftingHelper.getItemStack(p_199798_0_, true); + } + } + + public static class Serializer extends net.minecraftforge.registries.ForgeRegistryEntry> implements IRecipeSerializer + { + private static final ResourceLocation NAME = new ResourceLocation(SiegeMachines.ID, "siege_workbench"); + + public SiegeWorkbenchRecipe fromJson(ResourceLocation p_199425_1_, JsonObject p_199425_2_) + { + String s = JSONUtils.getAsString(p_199425_2_, "group", ""); + Map map = SiegeWorkbenchRecipe.keyFromJson(JSONUtils.getAsJsonObject(p_199425_2_, "key")); + String[] astring = SiegeWorkbenchRecipe.shrink(SiegeWorkbenchRecipe.patternFromJson(JSONUtils.getAsJsonArray(p_199425_2_, "pattern"))); + int i = astring[0].length(); + int j = astring.length; + NonNullList nonnulllist = SiegeWorkbenchRecipe.dissolvePattern(astring, map, i, j); + ItemStack itemstack = SiegeWorkbenchRecipe.itemFromJson(JSONUtils.getAsJsonObject(p_199425_2_, "result")); + return new SiegeWorkbenchRecipe(p_199425_1_, s, i, j, nonnulllist, itemstack); + } + + public SiegeWorkbenchRecipe fromNetwork(ResourceLocation p_199426_1_, PacketBuffer p_199426_2_) + { + int i = p_199426_2_.readVarInt(); + int j = p_199426_2_.readVarInt(); + String s = p_199426_2_.readUtf(32767); + NonNullList nonnulllist = NonNullList.withSize(i * j, Ingredient.EMPTY); + + for (int k = 0; k < nonnulllist.size(); ++k) + { + nonnulllist.set(k, Ingredient.fromNetwork(p_199426_2_)); + } + + ItemStack itemstack = p_199426_2_.readItem(); + return new SiegeWorkbenchRecipe(p_199426_1_, s, i, j, nonnulllist, itemstack); + } + + public void toNetwork(PacketBuffer p_199427_1_, SiegeWorkbenchRecipe p_199427_2_) + { + p_199427_1_.writeVarInt(p_199427_2_.width); + p_199427_1_.writeVarInt(p_199427_2_.height); + p_199427_1_.writeUtf(p_199427_2_.group); + + for (Ingredient ingredient : p_199427_2_.recipeItems) + { + ingredient.toNetwork(p_199427_1_); + } + + p_199427_1_.writeItem(p_199427_2_.result); + } + } +} diff --git a/src/main/java/magistu/siegemachines/entity/Breakdown.java b/src/main/java/magistu/siegemachines/entity/Breakdown.java new file mode 100644 index 0000000..c94ba50 --- /dev/null +++ b/src/main/java/magistu/siegemachines/entity/Breakdown.java @@ -0,0 +1,326 @@ +package magistu.siegemachines.entity; + +import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.mojang.datafixers.util.Pair; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; +import net.minecraft.block.AbstractFireBlock; +import net.minecraft.block.Block; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.enchantment.ProtectionEnchantment; +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.item.ItemEntity; +import net.minecraft.entity.item.TNTEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.projectile.ProjectileEntity; +import net.minecraft.fluid.FluidState; +import net.minecraft.item.ItemStack; +import net.minecraft.loot.LootContext; +import net.minecraft.loot.LootParameters; +import net.minecraft.particles.ParticleTypes; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.DamageSource; +import net.minecraft.util.math.*; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.world.EntityExplosionContext; +import net.minecraft.world.Explosion; +import net.minecraft.world.ExplosionContext; +import net.minecraft.world.World; +import net.minecraft.world.server.ServerWorld; +import org.jetbrains.annotations.Nullable; + +import java.util.*; + +public class Breakdown +{ + private static final ExplosionContext EXPLOSION_DAMAGE_CALCULATOR = new ExplosionContext(); + private final boolean fire; + private final Explosion.Mode blockInteraction; + private final Random random = new Random(); + private final World level; + private final double x; + private final double y; + private final double z; + @Nullable + private final Entity source; + private final float radius; + private final DamageSource damageSource; + private final ExplosionContext damageCalculator; + private final List toBlow = Lists.newArrayList(); + private final Map hitPlayers = Maps.newHashMap(); + private final Vector3d position; + private final Explosion explosion; + private final Entity machine; + private final float power; + + public Breakdown(World p_i50007_1_, @Nullable Entity machine, @Nullable Entity p_i50007_2_, double p_i50007_3_, double p_i50007_5_, double p_i50007_7_, float p_i50007_9_, boolean p_i50007_10_, float power, Explosion.Mode p_i50007_11_) { + this(p_i50007_1_, p_i50007_2_, machine, (DamageSource)null, (ExplosionContext)null, p_i50007_3_, p_i50007_5_, p_i50007_7_, p_i50007_9_, p_i50007_10_, power, p_i50007_11_); + } + + public Breakdown(World p_i231610_1_, @Nullable Entity machine, @Nullable Entity p_i231610_2_, @Nullable DamageSource p_i231610_3_, @Nullable ExplosionContext p_i231610_4_, double p_i231610_5_, double p_i231610_7_, double p_i231610_9_, float p_i231610_11_, boolean p_i231610_12_, float power, Explosion.Mode p_i231610_13_) { + this.explosion = new Explosion(p_i231610_1_, p_i231610_2_, p_i231610_3_, p_i231610_4_, p_i231610_5_, p_i231610_7_, p_i231610_9_, p_i231610_11_, p_i231610_12_, p_i231610_13_); + this.level = p_i231610_1_; + this.machine = machine; + this.source = p_i231610_2_; + this.radius = p_i231610_11_; + this.x = p_i231610_5_; + this.y = p_i231610_7_; + this.z = p_i231610_9_; + this.fire = p_i231610_12_; + this.power = power; + this.blockInteraction = p_i231610_13_; + this.damageSource = p_i231610_3_ == null && p_i231610_2_ instanceof LivingEntity ? DamageSource.explosion((LivingEntity) p_i231610_2_) : p_i231610_3_; + this.damageCalculator = p_i231610_4_ == null ? this.makeDamageCalculator(p_i231610_2_) : p_i231610_4_; + this.position = new Vector3d(this.x, this.y, this.z); + } + + private ExplosionContext makeDamageCalculator(@Nullable Entity p_234894_1_) { + return (ExplosionContext)(p_234894_1_ == null ? EXPLOSION_DAMAGE_CALCULATOR : new EntityExplosionContext(p_234894_1_)); + } + + public static float getSeenPercent(Vector3d p_222259_0_, Entity p_222259_1_) { + AxisAlignedBB axisalignedbb = p_222259_1_.getBoundingBox(); + double d0 = 1.0D / ((axisalignedbb.maxX - axisalignedbb.minX) * 2.0D + 1.0D); + double d1 = 1.0D / ((axisalignedbb.maxY - axisalignedbb.minY) * 2.0D + 1.0D); + double d2 = 1.0D / ((axisalignedbb.maxZ - axisalignedbb.minZ) * 2.0D + 1.0D); + double d3 = (1.0D - Math.floor(1.0D / d0) * d0) / 2.0D; + double d4 = (1.0D - Math.floor(1.0D / d2) * d2) / 2.0D; + if (!(d0 < 0.0D) && !(d1 < 0.0D) && !(d2 < 0.0D)) { + int i = 0; + int j = 0; + + for(float f = 0.0F; f <= 1.0F; f = (float)((double)f + d0)) { + for(float f1 = 0.0F; f1 <= 1.0F; f1 = (float)((double)f1 + d1)) { + for(float f2 = 0.0F; f2 <= 1.0F; f2 = (float)((double)f2 + d2)) { + double d5 = MathHelper.lerp((double)f, axisalignedbb.minX, axisalignedbb.maxX); + double d6 = MathHelper.lerp((double)f1, axisalignedbb.minY, axisalignedbb.maxY); + double d7 = MathHelper.lerp((double)f2, axisalignedbb.minZ, axisalignedbb.maxZ); + Vector3d vector3d = new Vector3d(d5 + d3, d6, d7 + d4); + if (p_222259_1_.level.clip(new RayTraceContext(vector3d, p_222259_0_, RayTraceContext.BlockMode.COLLIDER, RayTraceContext.FluidMode.NONE, p_222259_1_)).getType() == RayTraceResult.Type.MISS) { + ++i; + } + + ++j; + } + } + } + + return (float)i / (float)j; + } else { + return 0.0F; + } + } + + public void explode() + { + Set set = Sets.newHashSet(); + int i = 16; + + for(int j = 0; j < 16; ++j) { + for(int k = 0; k < 16; ++k) { + for(int l = 0; l < 16; ++l) { + if (j == 0 || j == 15 || k == 0 || k == 15 || l == 0 || l == 15) { + double d0 = (double)((float)j / 15.0F * 2.0F - 1.0F); + double d1 = (double)((float)k / 15.0F * 2.0F - 1.0F); + double d2 = (double)((float)l / 15.0F * 2.0F - 1.0F); + double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2); + d0 = d0 / d3; + d1 = d1 / d3; + d2 = d2 / d3; + float f = this.power * this.radius * (0.7F + this.level.random.nextFloat() * 0.6F); + double d4 = this.x; + double d6 = this.y; + double d8 = this.z; + + for(float f1 = 0.3F; f > 0.0F; f -= this.power * 0.5F) { + BlockPos blockpos = new BlockPos(d4, d6, d8); + BlockState blockstate = this.level.getBlockState(blockpos); + FluidState fluidstate = this.level.getFluidState(blockpos); + Optional optional = this.damageCalculator.getBlockExplosionResistance(this.explosion, this.level, blockpos, blockstate, fluidstate); + if (optional.isPresent()) { + f -= (optional.get() + 0.3F) * 0.3F; + } + + if (f > 0.0F && this.damageCalculator.shouldBlockExplode(this.explosion, this.level, blockpos, blockstate, f)) { + set.add(blockpos); + } + + d4 += d0 * (double)0.3F; + d6 += d1 * (double)0.3F; + d8 += d2 * (double)0.3F; + } + } + } + } + } + + this.toBlow.addAll(set); + float f2 = 1.5f * this.radius; + int k1 = MathHelper.floor(this.x - (double)f2 - 1.0D); + int l1 = MathHelper.floor(this.x + (double)f2 + 1.0D); + int i2 = MathHelper.floor(this.y - (double)f2 - 1.0D); + int i1 = MathHelper.floor(this.y + (double)f2 + 1.0D); + int j2 = MathHelper.floor(this.z - (double)f2 - 1.0D); + int j1 = MathHelper.floor(this.z + (double)f2 + 1.0D); + List list = this.level.getEntities(this.source, new AxisAlignedBB((double)k1, (double)i2, (double)j2, (double)l1, (double)i1, (double)j1)); + Vector3d vector3d = new Vector3d(this.x, this.y, this.z); + + for(int k2 = 0; k2 < list.size(); ++k2) { + Entity entity = list.get(k2); + if (!entity.ignoreExplosion() && !entity.equals(this.machine) && !entity.equals(this.source)) { + double d12 = (MathHelper.sqrt(entity.distanceToSqr(vector3d)) / f2); + if (d12 <= 1.0D) { + double d5 = entity.getX() - this.x; + double d7 = (entity instanceof TNTEntity ? entity.getY() : entity.getEyeY()) - this.y; + double d9 = entity.getZ() - this.z; + double d13 = (double)MathHelper.sqrt(d5 * d5 + d7 * d7 + d9 * d9); + if (d13 != 0.0D) { + d5 = d5 / d13; + d7 = d7 / d13; + d9 = d9 / d13; + double d14 = (double)getSeenPercent(vector3d, entity); + double d10 = (1.0D - d12) * d14; + if (!(entity instanceof ItemEntity)) { + entity.hurt(this.getDamageSource(), (float) ((int) ((d10 * d10 + d10) / 2.0D * 7.0D * (double) f2 + 1.0D))); + } + double d11 = d10; + if (entity instanceof LivingEntity) { + d11 = ProtectionEnchantment.getExplosionKnockbackAfterDampener((LivingEntity)entity, d10); + } + + entity.setDeltaMovement(entity.getDeltaMovement().add(d5 * d11, d7 * d11, d9 * d11)); + if (entity instanceof PlayerEntity) { + PlayerEntity playerentity = (PlayerEntity)entity; + if (!playerentity.isSpectator() && (!playerentity.isCreative() || !playerentity.abilities.flying)) { + this.hitPlayers.put(playerentity, new Vector3d(d5 * d10, d7 * d10, d9 * d10)); + } + } + } + } + } + } + + } + + public void finalizeExplosion(boolean p_77279_1_) { + if (this.level.isClientSide) { + //this.level.playLocalSound(this.x, this.y, this.z, SoundEvents.GENERIC_EXPLODE, SoundCategory.BLOCKS, 4.0F, (1.0F + (this.level.random.nextFloat() - this.level.random.nextFloat()) * 0.2F) * 0.7F, false); + } + + boolean flag = this.blockInteraction != Explosion.Mode.NONE; + if (p_77279_1_) { + if (!(this.radius < 2.0F) && flag) { + this.level.addParticle(ParticleTypes.EXPLOSION_EMITTER, this.x, this.y, this.z, 1.0D, 0.0D, 0.0D); + } else { + this.level.addParticle(ParticleTypes.EXPLOSION, this.x, this.y, this.z, 1.0D, 0.0D, 0.0D); + } + } + + if (flag) { + ObjectArrayList> objectarraylist = new ObjectArrayList<>(); + Collections.shuffle(this.toBlow, this.level.random); + + for(BlockPos blockpos : this.toBlow) { + BlockState blockstate = this.level.getBlockState(blockpos); + Block block = blockstate.getBlock(); + if (!blockstate.isAir(this.level, blockpos)) { + BlockPos blockpos1 = blockpos.immutable(); + this.level.getProfiler().push("explosion_blocks"); + if (this.level instanceof ServerWorld) { + TileEntity tileentity = blockstate.hasTileEntity() ? this.level.getBlockEntity(blockpos) : null; + LootContext.Builder lootcontext$builder = (new LootContext.Builder((ServerWorld)this.level)).withRandom(this.level.random).withParameter(LootParameters.ORIGIN, Vector3d.atCenterOf(blockpos)).withParameter(LootParameters.TOOL, ItemStack.EMPTY).withOptionalParameter(LootParameters.BLOCK_ENTITY, tileentity).withOptionalParameter(LootParameters.THIS_ENTITY, this.source); + if (this.blockInteraction == Explosion.Mode.DESTROY) { + lootcontext$builder.withParameter(LootParameters.EXPLOSION_RADIUS, this.radius); + } + + blockstate.getDrops(lootcontext$builder).forEach((p_229977_2_) -> { + addBlockDrops(objectarraylist, p_229977_2_, blockpos1); + }); + } + + this.level.setBlock(blockpos, Blocks.AIR.defaultBlockState(), 3); + this.level.getProfiler().pop(); + } + } + + for(Pair pair : objectarraylist) { + Block.popResource(this.level, pair.getSecond(), pair.getFirst()); + } + } + + if (this.fire) { + for(BlockPos blockpos2 : this.toBlow) { + if (this.random.nextInt(3) == 0 && this.level.getBlockState(blockpos2).isAir() && this.level.getBlockState(blockpos2.below()).isSolidRender(this.level, blockpos2.below())) { + this.level.setBlockAndUpdate(blockpos2, AbstractFireBlock.getState(this.level, blockpos2)); + } + } + } + + } + + private static void addBlockDrops(ObjectArrayList> p_229976_0_, ItemStack p_229976_1_, BlockPos p_229976_2_) { + int i = p_229976_0_.size(); + + for(int j = 0; j < i; ++j) { + Pair pair = p_229976_0_.get(j); + ItemStack itemstack = pair.getFirst(); + if (ItemEntity.areMergable(itemstack, p_229976_1_)) { + ItemStack itemstack1 = ItemEntity.merge(itemstack, p_229976_1_, 16); + p_229976_0_.set(j, Pair.of(itemstack1, pair.getSecond())); + if (p_229976_1_.isEmpty()) { + return; + } + } + } + + p_229976_0_.add(Pair.of(p_229976_1_, p_229976_2_)); + } + + public DamageSource getDamageSource() { + return this.damageSource; + } + + public Map getHitPlayers() { + return this.hitPlayers; + } + + @Nullable + public LivingEntity getSourceMob() { + if (this.source == null) { + return null; + } else if (this.source instanceof TNTEntity) { + return ((TNTEntity)this.source).getOwner(); + } else if (this.source instanceof LivingEntity) { + return (LivingEntity)this.source; + } else { + if (this.source instanceof ProjectileEntity) { + Entity entity = ((ProjectileEntity)this.source).getOwner(); + if (entity instanceof LivingEntity) { + return (LivingEntity)entity; + } + } + + return null; + } + } + + public void clearToBlow() { + this.toBlow.clear(); + } + + public List getToBlow() { + return this.toBlow; + } + + public Vector3d getPosition() { + return this.position; + } + + @Nullable + public Entity getExploder() { + return this.source; + } +} diff --git a/src/main/java/magistu/siegemachines/entity/EntityTypes.java b/src/main/java/magistu/siegemachines/entity/EntityTypes.java new file mode 100644 index 0000000..608f26c --- /dev/null +++ b/src/main/java/magistu/siegemachines/entity/EntityTypes.java @@ -0,0 +1,54 @@ +package magistu.siegemachines.entity; + +import magistu.siegemachines.SiegeMachines; +import magistu.siegemachines.entity.machine.*; +import magistu.siegemachines.entity.projectile.Cannonball; +import magistu.siegemachines.entity.projectile.GiantArrow; +import magistu.siegemachines.entity.projectile.GiantStone; +import magistu.siegemachines.entity.projectile.Stone; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityClassification; +import net.minecraft.entity.EntityType; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.fml.RegistryObject; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; + +public class EntityTypes +{ + public static final DeferredRegister> DEFERRED_REGISTER = DeferredRegister.create(ForgeRegistries.ENTITIES, SiegeMachines.ID); + + public static final RegistryObject> CANNONBALL = addRegistry("cannonball", Cannonball::new, 0.5f, 0.5f, 8); + public static final RegistryObject> STONE = addRegistry("stone", Stone::new, 0.6f, 0.6f, 8); + public static final RegistryObject> GIANT_STONE = addRegistry("giant_stone", GiantStone::new, 1.1f, 1.1f, 8); + public static final RegistryObject> GIANT_ARROW = addRegistry("giant_arrow", GiantArrow::new, 0.5f, 0.5f, 8, 20); + + public static final RegistryObject> MORTAR = addRegistry("mortar", Mortar::new, 2.0f, 1.0f, 8); + public static final RegistryObject> CULVERIN = addRegistry("culverin", Culverin::new, 2.0f, 1.0f, 8); + public static final RegistryObject> TREBUCHET = addRegistry("trebuchet", Trebuchet::new, 5.0f, 9.0f, 8); + public static final RegistryObject> CATAPULT = addRegistry("catapult", Catapult::new, 3.0f, 3.0f, 8); + public static final RegistryObject> BALLISTA = addRegistry("ballista", Ballista::new, 1.5f, 1.5f, 8); + public static final RegistryObject> BATTERING_RAM = addRegistry("battering_ram", BatteringRam::new, 4.0f, 3.0f); + + + public static RegistryObject> addRegistry(String name, EntityType.IFactory constructor, float sizex, float sizey) + { + return DEFERRED_REGISTER.register(name, () -> EntityType.Builder.of(constructor, EntityClassification.MISC).sized(sizex, sizey).build(new ResourceLocation(SiegeMachines.ID, name).toString())); + } + + public static RegistryObject> addRegistry(String name, EntityType.IFactory constructor, float sizex, float sizey, int trackingrange) + { + return DEFERRED_REGISTER.register(name, () -> EntityType.Builder.of(constructor, EntityClassification.MISC).clientTrackingRange(trackingrange).sized(sizex, sizey).build(new ResourceLocation(SiegeMachines.ID, name).toString())); + } + + public static RegistryObject> addRegistry(String name, EntityType.IFactory constructor, float sizex, float sizey, int trackingrange, int updateinterval) + { + return DEFERRED_REGISTER.register(name, () -> EntityType.Builder.of(constructor, EntityClassification.MISC).clientTrackingRange(trackingrange).updateInterval(updateinterval).sized(sizex, sizey).build(new ResourceLocation(SiegeMachines.ID, name).toString())); + } + + public static void register(IEventBus eventBus) + { + DEFERRED_REGISTER.register(eventBus); + } +} \ No newline at end of file diff --git a/src/main/java/magistu/siegemachines/entity/IReloading.java b/src/main/java/magistu/siegemachines/entity/IReloading.java new file mode 100644 index 0000000..58d5154 --- /dev/null +++ b/src/main/java/magistu/siegemachines/entity/IReloading.java @@ -0,0 +1,11 @@ +package magistu.siegemachines.entity; + +import magistu.siegemachines.gui.Crosshair; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +public interface IReloading +{ + @OnlyIn(Dist.CLIENT) + Crosshair createCrosshair(); +} diff --git a/src/main/java/magistu/siegemachines/entity/machine/Ballista.java b/src/main/java/magistu/siegemachines/entity/machine/Ballista.java new file mode 100644 index 0000000..d70f50a --- /dev/null +++ b/src/main/java/magistu/siegemachines/entity/machine/Ballista.java @@ -0,0 +1,190 @@ +package magistu.siegemachines.entity.machine; + +import magistu.siegemachines.SiegeMachines; +import magistu.siegemachines.client.SoundTypes; +import magistu.siegemachines.gui.Crosshair; +import magistu.siegemachines.gui.ReloadingCrosshair; +import magistu.siegemachines.item.ModItems; +import net.minecraft.entity.*; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.DamageSource; +import net.minecraft.util.Hand; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.world.World; +import net.minecraft.world.server.ServerWorld; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import software.bernie.geckolib3.core.IAnimatable; +import software.bernie.geckolib3.core.PlayState; +import software.bernie.geckolib3.core.builder.AnimationBuilder; +import software.bernie.geckolib3.core.controller.AnimationController; +import software.bernie.geckolib3.core.event.predicate.AnimationEvent; +import software.bernie.geckolib3.core.manager.AnimationData; +import software.bernie.geckolib3.core.manager.AnimationFactory; + +public class Ballista extends ShootingMachine implements IAnimatable +{ + private final AnimationFactory factory = new AnimationFactory(this); + + static AnimationBuilder SHOOTING_ANIM = new AnimationBuilder().addAnimation("Shooting", true); + static AnimationBuilder RELOADING_ANIM = new AnimationBuilder().addAnimation("Reloading", true); + + public enum State + { + SHOOTING, + RELOADING + } + public State state = State.RELOADING; + + public Ballista(EntityType entitytype, World level) + { + super(entitytype, level, MachineType.BALLISTA); + } + + private PlayState predicate(AnimationEvent event) + { + switch (state) + { + case SHOOTING: + event.getController().setAnimation(SHOOTING_ANIM); + return PlayState.CONTINUE; + case RELOADING: + event.getController().setAnimation(RELOADING_ANIM); + return PlayState.CONTINUE; + } + return PlayState.CONTINUE; + } + + @Override + public void registerControllers(AnimationData data) + { + AnimationController controller = new AnimationController<>(this, "controller", 1, (t) -> + { + if (this.state.equals(State.RELOADING)) + { + return (double) (this.type.specs.delaytime.get() - this.delayticks) / this.type.specs.delaytime.get(); + } + return t; + }, this::predicate); + data.addAnimationController(controller); + } + + @Override + public AnimationFactory getFactory() + { + return this.factory; + } + + @Override + protected ActionResultType mobInteract(PlayerEntity player, Hand hand) + { + if (super.mobInteract(player, hand) == ActionResultType.SUCCESS) + { + return ActionResultType.SUCCESS; + } + if (!this.level.isClientSide() && !this.isVehicle()) + { + player.startRiding(this); + return ActionResultType.SUCCESS; + } + + return ActionResultType.PASS; + } + + public void startShooting(PlayerEntity player) + { + if (this.delayticks <= 0 && this.useticks <= 0 && this.shootingticks <= 0) + { + this.state = State.SHOOTING; + this.useticks = this.type.usetime; + this.shootingticks = this.type.userealisetime; + + Vector3d pos = this.position(); + this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.BALLISTA_SHOOTING.get(), SoundCategory.BLOCKS, 1.4f, 1.0f, false); + } + } + + @Override + public void shoot() + { + if (!level.isClientSide()) + { + super.shoot(); + } + } + + @Override + public void travel(Vector3d pos) + { + if (this.isAlive()) + { + if (this.isVehicle()) + { + LivingEntity livingentity = (LivingEntity) this.getControllingPassenger(); + + this.setTurretRotationsDest(livingentity.xRot, livingentity.yRot - this.getYaw()); + this.updateTurretRotations(); + } + super.travel(pos); + } + + } + + @Override + public void tick() + { + if (this.useticks != 0 && --this.useticks <= 0) + { + this.state = State.RELOADING; + this.useticks = 0; + this.delayticks = this.type.specs.delaytime.get(); + } + + if (this.shootingticks != 0 && --this.shootingticks <= 0) + { + this.useRealise(); + this.shootingticks = 0; + } + + if (!level.isClientSide() && (this.isOnGround() || this.isInWater())) + { + this.setDeltaMovement(this.getDeltaMovement().multiply(0.0, 1.0, 0.0)); + } + + if (this.delayticks > 0 && this.isVehicle()) + { + if (this.delayticks % 21 == 0) + { + Vector3d pos = this.position(); + this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.BALLISTA_RELOADING.get(), SoundCategory.BLOCKS, 1.0f, 1.0f, false); + } + --this.delayticks; + } + + if (this.renderupdateticks-- <= 0) + { + this.updateMachineRender(); + this.renderupdateticks = SiegeMachines.RENDER_UPDATE_TIME; + } + + super.tick(); + } + + @Override + @OnlyIn(Dist.CLIENT) + public Crosshair createCrosshair() + { + return new ReloadingCrosshair(); + } + + @Override + public Item getMachineItem() + { + return ModItems.BALLISTA.get(); + } +} \ No newline at end of file diff --git a/src/main/java/magistu/siegemachines/entity/machine/BatteringRam.java b/src/main/java/magistu/siegemachines/entity/machine/BatteringRam.java new file mode 100644 index 0000000..08f628d --- /dev/null +++ b/src/main/java/magistu/siegemachines/entity/machine/BatteringRam.java @@ -0,0 +1,254 @@ +package magistu.siegemachines.entity.machine; + +import magistu.siegemachines.SiegeMachines; +import magistu.siegemachines.client.SoundTypes; +import magistu.siegemachines.entity.Breakdown; +import magistu.siegemachines.item.ModItems; +import magistu.siegemachines.network.PacketHandler; +import magistu.siegemachines.network.PacketMachineUse; +import magistu.siegemachines.network.PacketMachineUseRealise; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.MobEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Hand; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.world.Explosion; +import net.minecraft.world.World; +import software.bernie.geckolib3.core.IAnimatable; +import software.bernie.geckolib3.core.PlayState; +import software.bernie.geckolib3.core.builder.AnimationBuilder; +import software.bernie.geckolib3.core.controller.AnimationController; +import software.bernie.geckolib3.core.event.predicate.AnimationEvent; +import software.bernie.geckolib3.core.manager.AnimationData; +import software.bernie.geckolib3.core.manager.AnimationFactory; + + +public class BatteringRam extends Machine implements IAnimatable +{ + private final AnimationFactory factory = new AnimationFactory(this); + + static AnimationBuilder MOVING_ANIM = new AnimationBuilder().addAnimation("Moving", true); + static AnimationBuilder HITTING_ANIM = new AnimationBuilder().addAnimation("Hitting", true); + static AnimationBuilder RELOADING_ANIM = new AnimationBuilder().addAnimation("Reloading", true); + + public int hittingticks = 0; + private int wheelssoundticks = 10; + + public enum State + { + HITTING, + RELOADING + } + public State state = State.RELOADING; + + private double wheelspitch = 0.0; + private double wheelsspeed = 0.0; + + public BatteringRam(EntityType entitytype, World level) + { + super(entitytype, level, MachineType.BATTERING_RAM); + } + + private PlayState wheels_predicate(AnimationEvent event) + { + event.getController().setAnimation(MOVING_ANIM); + + return PlayState.CONTINUE; + } + + private PlayState reloading_predicate(AnimationEvent event) + { + switch (state) + { + case HITTING: + event.getController().setAnimation(HITTING_ANIM); + return PlayState.CONTINUE; + case RELOADING: + event.getController().setAnimation(RELOADING_ANIM); + return PlayState.CONTINUE; + } + return PlayState.CONTINUE; + } + + @Override + public void registerControllers(AnimationData data) + { + AnimationController wheels_controller = new AnimationController<>(this, "wheels_controller", 1, (t) -> { + double d = this.getWheelsSpeed(); + this.wheelsspeed = d > 0 ? Math.min(d, 1.0) : Math.max(d, -1.0); + return wheelspitch += 0.015 * this.wheelsspeed; + }, this::wheels_predicate); + data.addAnimationController(wheels_controller); + + AnimationController reloading_controller = new AnimationController<>(this, "controller", 1, (t) -> + { + if (this.state.equals(State.RELOADING)) + { + return (double) (this.type.specs.delaytime.get() - this.delayticks) / this.type.specs.delaytime.get(); + } + return t; + }, this::reloading_predicate); + data.addAnimationController(reloading_controller); + } + + @Override + public AnimationFactory getFactory() + { + return this.factory; + } + + @Override + protected ActionResultType mobInteract(PlayerEntity player, Hand hand) + { + if (!this.level.isClientSide() && !this.isVehicle()) + { + player.startRiding(this); + return ActionResultType.SUCCESS; + } + + return ActionResultType.PASS; + } + + @Override + public void travel(Vector3d pos) + { + if (this.isAlive()) + { + if (this.isVehicle()) + { + LivingEntity livingentity = (LivingEntity) this.getControllingPassenger(); + + this.setYawDest(livingentity.yRot); + + this.updateYaw(); + + float f1 = livingentity.zza; + if (f1 <= 0.0f) + { + f1 *= 0.25f; + } + this.setSpeed(0.04f); + + pos = new Vector3d(0.0f, pos.y, f1); + } + super.travel(pos); + } + } + + @Override + public void tick() + { + if (this.useticks != 0 && --this.useticks <= 0) + { + this.state = State.RELOADING; + this.useticks = 0; + this.delayticks = this.type.specs.delaytime.get(); + } + + if (this.hittingticks != 0 && --this.hittingticks <= 0) + { + this.useRealise(); + this.hittingticks = 0; + } + + if (!level.isClientSide() && (this.isOnGround() || this.isInWater())) + { + this.setDeltaMovement(this.getDeltaMovement().multiply(0.0, 1.0, 0.0)); + } + + if (this.delayticks > 0 && this.isVehicle()) + { + --this.delayticks; + } + + if (this.renderupdateticks-- <= 0) + { + this.updateMachineRender(); + this.renderupdateticks = SiegeMachines.RENDER_UPDATE_TIME; + } + +// if (this.getWheelsSpeed() > 0.0081 && this.wheelssoundticks-- <= 0) +// { +// this.level.playLocalSound(this.getX(), this.getY(), this.getZ(), SoundTypes.RAM_WHEELS.get(), SoundCategory.NEUTRAL, 0.6f, 1.0f, true); +// this.wheelssoundticks = 20; +// } + + super.tick(); + } + + @Override + public void use(PlayerEntity player) + { + if (!this.level.isClientSide()) + { + PacketHandler.sendPacketToAllInArea(new PacketMachineUse(this.getId()), this.blockPosition(), SiegeMachines.RENDER_UPDATE_RANGE_SQR); + } + + if (this.delayticks <= 0 && this.useticks <= 0 && this.hittingticks <= 0) + { + this.state = State.HITTING; + this.useticks = this.type.usetime; + this.hittingticks = this.type.userealisetime; + + Vector3d pos = this.position(); + this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.RAM_HITTING.get(), SoundCategory.BLOCKS, 0.5f, 0.9f, false); + } + } + + public void ramHit(BlockPos blockpos) + { + if (!this.level.isClientSide()) + { + Breakdown breakdown = new Breakdown(this.level, this, this.getControllingPassenger(), blockpos.getX(), blockpos.getY(), blockpos.getZ(), 2, false, 3.0f, Explosion.Mode.BREAK); + breakdown.explode(); + breakdown.finalizeExplosion(true); + } + } + + @Override + public void useRealise() + { + if (!this.level.isClientSide()) + { + PacketHandler.sendPacketToAllInArea(new PacketMachineUseRealise(this.getId()), this.blockPosition(), SiegeMachines.RENDER_UPDATE_RANGE_SQR); + + BlockPos blockpos = new BlockPos(this.getHitPos()); + this.ramHit(blockpos); + } + } + + public double getWheelsSpeed() + { + if (this.isOnGround()) + { + return this.getViewVector(5.0f).multiply(1, 0, 1).dot(this.getDeltaMovement()); + } + + return 0.0; + } + + @Override + public void push(double p_70024_1_, double p_70024_3_, double p_70024_5_) { +// this.setDeltaMovement(this.getDeltaMovement().add(p_70024_1_, p_70024_3_, p_70024_5_)); +// this.hasImpulse = true; + } + + @Override + public Item getMachineItem() + { + return ModItems.BATTERING_RAM.get(); + } + + protected Vector3d getHitPos() + { + double pitch = this.getTurretPitch() * Math.PI / 180.0; + double yaw = (this.getViewYRot(0.5f) + this.getTurretYaw()) * Math.PI / 180.0; + + return this.position().add(applyRotations(this.type.turretpivot, 0.0, yaw).add(applyRotations(this.type.turretvector, pitch, yaw))); + } +} diff --git a/src/main/java/magistu/siegemachines/entity/machine/Catapult.java b/src/main/java/magistu/siegemachines/entity/machine/Catapult.java new file mode 100644 index 0000000..a4ac636 --- /dev/null +++ b/src/main/java/magistu/siegemachines/entity/machine/Catapult.java @@ -0,0 +1,207 @@ +package magistu.siegemachines.entity.machine; + +import magistu.siegemachines.SiegeMachines; +import magistu.siegemachines.client.SoundTypes; +import magistu.siegemachines.gui.Crosshair; +import magistu.siegemachines.gui.ReloadingCrosshair; +import magistu.siegemachines.item.ModItems; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.MobEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Hand; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import software.bernie.geckolib3.core.IAnimatable; +import software.bernie.geckolib3.core.PlayState; +import software.bernie.geckolib3.core.builder.AnimationBuilder; +import software.bernie.geckolib3.core.controller.AnimationController; +import software.bernie.geckolib3.core.event.predicate.AnimationEvent; +import software.bernie.geckolib3.core.manager.AnimationData; +import software.bernie.geckolib3.core.manager.AnimationFactory; + +public class Catapult extends ShootingMachine implements IAnimatable +{ + private final AnimationFactory factory = new AnimationFactory(this); + + static AnimationBuilder SHOOTING_ANIM = new AnimationBuilder().addAnimation("Shooting", true); + static AnimationBuilder RELOADING_ANIM = new AnimationBuilder().addAnimation("Reloading", true); + static AnimationBuilder IDLE_RELOADED_ANIM = new AnimationBuilder().addAnimation("IdleReloaded", true); + static AnimationBuilder IDLE_NOT_RELOADED_ANIM = new AnimationBuilder().addAnimation("IdleNotReloaded", true); + + public enum State + { + SHOOTING, + RELOADING, + IDLE_RELOADED, + IDLE_NOT_RELOADED + } + public State state = State.RELOADING; + + public Catapult(EntityType entitytype, World level) + { + super(entitytype, level, MachineType.CATAPULT); + } + + private PlayState predicate(AnimationEvent event) + { + switch (state) + { + case SHOOTING: + event.getController().setAnimation(SHOOTING_ANIM); + return PlayState.CONTINUE; + case IDLE_RELOADED: + event.getController().setAnimation(IDLE_RELOADED_ANIM); + return PlayState.CONTINUE; + case RELOADING: + event.getController().setAnimation(RELOADING_ANIM); + return PlayState.CONTINUE; + case IDLE_NOT_RELOADED: + event.getController().setAnimation(IDLE_NOT_RELOADED_ANIM); + return PlayState.CONTINUE; + } + + return PlayState.CONTINUE; + } + + @Override + public void registerControllers(AnimationData data) + { + AnimationController controller = new AnimationController<>(this, "controller", 1, (t) -> + { + if (this.state.equals(State.RELOADING)) + { + return (double) (this.type.specs.delaytime.get() - this.delayticks) / this.type.specs.delaytime.get(); + } + return t; + }, this::predicate); + data.addAnimationController(controller); + } + + @Override + public AnimationFactory getFactory() + { + return this.factory; + } + + @Override + protected ActionResultType mobInteract(PlayerEntity player, Hand hand) + { + ItemStack stack = player.getItemInHand(hand); + + if (super.mobInteract(player, hand) == ActionResultType.SUCCESS) + { + return ActionResultType.SUCCESS; + } + if (!this.level.isClientSide() && !this.isVehicle()) + { + player.startRiding(this); + return ActionResultType.SUCCESS; + } + + return ActionResultType.PASS; + } + + public void startShooting(PlayerEntity player) + { + if (this.delayticks <= 0 && this.useticks <= 0 && this.shootingticks <= 0) + { + this.state = State.SHOOTING; + this.useticks = this.type.usetime; + this.shootingticks = this.type.userealisetime; + + Vector3d pos = this.position(); + this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.CATAPULT_SHOOTING.get(), SoundCategory.BLOCKS, 1.5f, 1.0f, false); + } + } + + @Override + public void shoot() + { + if (!level.isClientSide()) + { + super.shoot(); + } + } + + @Override + public void travel(Vector3d pos) + { + if (this.isAlive()) + { + if (this.isVehicle() && this.useticks <= 0 && this.delayticks <= 0) + { + LivingEntity livingentity = (LivingEntity) this.getControllingPassenger(); + + this.setTurretRotations(livingentity.xRot, this.getTurretYaw()); + this.updateTurretRotations(); + + this.setYawDest(livingentity.yRot); + this.updateYaw(); + } + super.travel(pos); + } + } + + @Override + public void tick() + { + if (this.useticks != 0 && --this.useticks <= 0) + { + this.state = State.RELOADING; + this.useticks = 0; + this.delayticks = this.type.specs.delaytime.get(); + } + + if (this.shootingticks != 0 && --this.shootingticks <= 0) + { + this.useRealise(); + this.shootingticks = 0; + } + + if (!level.isClientSide() && (this.isOnGround() || this.isInWater())) + { + this.setDeltaMovement(this.getDeltaMovement().multiply(0.0, 1.0, 0.0)); + } + + if (this.delayticks > 0 && this.isVehicle()) + { + if (this.delayticks % 20 == 0) + { + Vector3d pos = this.position(); + this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.CATAPULT_RELOADING.get(), SoundCategory.BLOCKS, 1.0f, 1.0f, false); + } + if (--this.delayticks <= 0) + { + this.state = State.IDLE_RELOADED; + } + } + + if (this.renderupdateticks-- <= 0) + { + this.updateMachineRender(); + this.renderupdateticks = SiegeMachines.RENDER_UPDATE_TIME; + } + + super.tick(); + } + + @Override + @OnlyIn(Dist.CLIENT) + public Crosshair createCrosshair() + { + return new ReloadingCrosshair(); + } + + @Override + public Item getMachineItem() + { + return ModItems.CATAPULT.get(); + } +} \ No newline at end of file diff --git a/src/main/java/magistu/siegemachines/entity/machine/Culverin.java b/src/main/java/magistu/siegemachines/entity/machine/Culverin.java new file mode 100644 index 0000000..b1b2867 --- /dev/null +++ b/src/main/java/magistu/siegemachines/entity/machine/Culverin.java @@ -0,0 +1,260 @@ +package magistu.siegemachines.entity.machine; + +import magistu.siegemachines.SiegeMachines; +import magistu.siegemachines.client.SoundTypes; +import magistu.siegemachines.entity.IReloading; +import magistu.siegemachines.gui.Crosshair; +import magistu.siegemachines.gui.ReloadingCrosshair; +import magistu.siegemachines.item.ModItems; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.MobEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.particles.ParticleTypes; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Hand; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import software.bernie.geckolib3.core.IAnimatable; +import software.bernie.geckolib3.core.PlayState; +import software.bernie.geckolib3.core.builder.AnimationBuilder; +import software.bernie.geckolib3.core.controller.AnimationController; +import software.bernie.geckolib3.core.event.SoundKeyframeEvent; +import software.bernie.geckolib3.core.event.predicate.AnimationEvent; +import software.bernie.geckolib3.core.manager.AnimationData; +import software.bernie.geckolib3.core.manager.AnimationFactory; + +public class Culverin extends ShootingMachine implements IAnimatable, IReloading +{ + private final AnimationFactory factory = new AnimationFactory(this); + + static AnimationBuilder MOVING_ANIM = new AnimationBuilder().addAnimation("Moving", true); +// static AnimationBuilder TILTING_ANIM = new AnimationBuilder().addAnimation("Tilting", true); + + private double wheelspitch = 0.0; + private double wheelsspeed = 0.0; + + public Culverin(EntityType entitytype, World level) + { + super(entitytype, level, MachineType.CULVERIN); + } + + private PlayState wheels_predicate(AnimationEvent event) + { + event.getController().setAnimation(MOVING_ANIM); + + return PlayState.CONTINUE; + } + + @Override + public void registerControllers(AnimationData data) + { + AnimationController wheels_controller = new AnimationController<>(this, "wheels_controller", 1, (t) -> { + double d = this.getWheelsSpeed(); + this.wheelsspeed = d > 0 ? Math.min(d, 1.0) : Math.max(d, -1.0); + return wheelspitch += 0.015 * this.wheelsspeed; + }, this::wheels_predicate); + wheels_controller.registerSoundListener(this::soundListener); + data.addAnimationController(wheels_controller); + } + + private void soundListener(SoundKeyframeEvent event) + { + //ClientPlayerEntity player = Minecraft.getInstance().player; + if (/*player != null && */this.getWheelsSpeed() > 0.0081) + { + Vector3d pos = this.position(); + this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.CANNON_WHEELS.get(), SoundCategory.BLOCKS, 0.5f/*this.getVolumeFromDist(0.5f, 16.0f, this.distanceTo(player))*/, 1.0f, false); + } + } + + @Override + public AnimationFactory getFactory() + { + return this.factory; + } + + @Override + protected ActionResultType mobInteract(PlayerEntity player, Hand hand) + { + ItemStack stack = player.getItemInHand(hand); + + if (stack.getItem().equals(Items.FLINT_AND_STEEL)) + { + if (this.useticks < 0) + { + stack.hurtAndBreak(1, player, (p_213833_1_) -> + { + p_213833_1_.broadcastBreakEvent(hand); + net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(player, this.useItem, hand); + }); + this.startShooting(player); + } + return ActionResultType.SUCCESS; + } + if (stack.getItem().equals(Items.GUNPOWDER)) + { + if (!this.inventory.containsItem(Items.GUNPOWDER)) + { + if (!player.isCreative()) + { + stack.shrink(1); + } + this.inventory.putItem(Items.GUNPOWDER); + } + return ActionResultType.SUCCESS; + } + if (super.mobInteract(player, hand) == ActionResultType.SUCCESS) + { + return ActionResultType.SUCCESS; + } + if (!this.level.isClientSide() && !this.isVehicle()) + { + player.startRiding(this); + return ActionResultType.SUCCESS; + } + + return ActionResultType.PASS; + } + + @Override + public void travel(Vector3d pos) + { + if (this.isAlive()) + { + if (this.isVehicle()) + { + LivingEntity livingentity = (LivingEntity) this.getControllingPassenger(); + + this.setTurretRotationsDest(livingentity.xRot, livingentity.yRot - this.getYaw()); + this.setYawDest(livingentity.yRot); + + this.updateYaw(); + this.updateTurretRotations(); + + float f0 = livingentity.xxa * 0.2f; + float f1 = livingentity.zza; + if (f1 <= 0.0f) + { + f1 *= 0.5f; + } + this.setSpeed(0.04f); + + pos = new Vector3d(f0, pos.y, f1); + } + super.travel(pos); + } + } + + @Override + public void tick() + { + if (this.useticks != 0 && --this.useticks <= 0) + { + if (this.inventory.containsItem(Items.GUNPOWDER)) + { + this.useRealise(); + } + this.useticks = 0; + } + if (!level.isClientSide() && (this.isOnGround() || this.isInWater())) + { + this.setDeltaMovement(this.getWheelsDeltaMovement()); + } + if (this.delayticks > 0 && this.isVehicle()) + { + --this.delayticks; + } + + if (this.renderupdateticks-- <= 0) + { + this.updateMachineRender(); + this.renderupdateticks = SiegeMachines.RENDER_UPDATE_TIME; + } + + super.tick(); + } + + @Override + public void startShooting(PlayerEntity player) + { + if (this.delayticks <= 0 && this.useticks <= 0) + { + if (!this.level.isClientSide()) + { + this.level.playSound(null, this.getX(), this.getY(), this.getZ(), SoundTypes.FUSE.get(), SoundCategory.BLOCKS, this.getVolumeFromDist(0.5f, 6.0f, this.distanceTo(player)), 0.8f); + } + this.useticks = this.type.usetime; + } + } + + @Override + public void shoot() + { + if (!level.isClientSide()) + { + super.shoot(); + this.setDeltaMovement(this.getDeltaMovement().subtract(this.getShotView().scale(0.25))); + this.hasImpulse = true; + this.inventory.shrinkItem(Items.GUNPOWDER); + } + else + { + this.blowParticles(ParticleTypes.FLAME, 0.035, 25); + this.blowParticles(ParticleTypes.CLOUD, 0.2, 60); + Vector3d pos = this.position(); + this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.MORTAR_SHOOTING.get(), SoundCategory.BLOCKS, 1.5f/*this.getVolumeFromDist(1.5f, 64.0f, this.distanceTo(player))*/, 0.85f + this.level.random.nextFloat() * 0.3f, false); + } + + this.delayticks = this.type.specs.delaytime.get(); + } + + public double getWheelsSpeed() + { + if (this.isOnGround()) + { + return this.getViewVector(5.0f).multiply(1, 0, 1).dot(this.getDeltaMovement()); + } + + return 0.0; + } + + public Vector3d getWheelsDeltaMovement() + { + if (this.isOnGround()) + { + Vector3d view = this.getViewVector(1.0f); + Vector3d movement = this.getDeltaMovement(); + + double d0 = movement.x * view.x + movement.z * view.z; + + double d1 = d0 * view.x; + double d2 = 0.0; + double d3 = d0 * view.z; + + return new Vector3d(d1, d2, d3); + } + + return Vector3d.ZERO; + } + + @Override + @OnlyIn(Dist.CLIENT) + public Crosshair createCrosshair() + { + return new ReloadingCrosshair(); + } + + @Override + public Item getMachineItem() + { + return null; +// return ModItems.CULVERIN.get(); + } +} \ No newline at end of file diff --git a/src/main/java/magistu/siegemachines/entity/machine/Machine.java b/src/main/java/magistu/siegemachines/entity/machine/Machine.java new file mode 100644 index 0000000..ee21fc3 --- /dev/null +++ b/src/main/java/magistu/siegemachines/entity/machine/Machine.java @@ -0,0 +1,862 @@ +package magistu.siegemachines.entity.machine; + +import magistu.siegemachines.SiegeMachines; +import magistu.siegemachines.gui.MachineContainer; +import magistu.siegemachines.item.ModItems; +import magistu.siegemachines.network.PacketHandler; +import magistu.siegemachines.network.PacketMachine; +import net.minecraft.advancements.CriteriaTriggers; +import net.minecraft.block.HoneyBlock; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.MobEntity; +import net.minecraft.entity.ai.attributes.AttributeModifierMap; +import net.minecraft.entity.ai.attributes.Attributes; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.entity.projectile.AbstractArrowEntity; +import net.minecraft.inventory.Inventory; +import net.minecraft.inventory.container.Container; +import net.minecraft.inventory.container.INamedContainerProvider; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.nbt.ListNBT; +import net.minecraft.particles.ParticleTypes; +import net.minecraft.potion.Effects; +import net.minecraft.util.*; +import net.minecraft.util.math.MathHelper; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.fml.network.NetworkHooks; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nullable; +import java.util.Arrays; +import java.util.Random; + +public abstract class Machine extends MobEntity implements INamedContainerProvider +{ + public MachineInventory inventory; + + public final MachineType type; + + private float turretpitch = -25.0f; + private float turretpitchprev = this.turretpitch; + protected float turretpitchdest = this.turretpitch; + private float turretyaw = 0.0f; + private float turretyawprev = this.turretyaw; + protected float turretyawdest = this.turretyaw; + protected float yawdest = this.yRot; + + public int useticks = -1; + public int delayticks; + protected int renderupdateticks = 0; + public int deploymentticks = 0; + + protected Machine(EntityType entitytype, World level, MachineType type) + { + super(entitytype, level); + this.type = type; + this.delayticks = this.type.specs.delaytime.get(); + inventory = new MachineInventory(this.type.containersize); + + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(type.specs.durability.get()); + this.setHealth(type.specs.durability.get()); + } + + public static AttributeModifierMap.MutableAttribute setEntityAttributes(MachineType type) + { + return MobEntity.createMobAttributes() + .add(Attributes.MAX_HEALTH, type.specs.durability.get()) + .add(Attributes.KNOCKBACK_RESISTANCE, 0.5F) + .add(Attributes.MOVEMENT_SPEED, 0.0D) + .add(Attributes.ATTACK_DAMAGE, 0.0D) + .add(Attributes.FOLLOW_RANGE, 0.0D); + } + + public ItemStack getMachineItemWithData() + { + ItemStack stack = new ItemStack(this.getMachineItem()); + CompoundNBT nbt = this.saveWithoutId(new CompoundNBT()); + nbt.remove("Pos"); + nbt.remove("Motion"); + nbt.remove("FallDistance"); + nbt.remove("Fire"); + nbt.remove("Air"); + nbt.remove("OnGround"); + nbt.remove("Invulnerable"); + nbt.remove("PortalCooldown"); + nbt.remove("UUID"); + nbt.remove("Passengers"); + nbt.remove("DelayTicks"); + nbt.remove("UseTicks"); + stack.addTagElement("EntityTag", nbt); + return stack; + } + + @Override + public boolean isInvulnerableTo(DamageSource damagesource) + { + return damagesource == DamageSource.CACTUS || + damagesource == DamageSource.WITHER || + damagesource == DamageSource.MAGIC || + damagesource == DamageSource.DROWN || + damagesource == DamageSource.STARVE || + super.isInvulnerableTo(damagesource); + } + + public float adjustDamage(DamageSource damagesource, float f) + { + if (damagesource.isFire()) + { + f *= 1.5f; + } + if (damagesource.isExplosion()) + { + f *= 1.25f; + } + if (damagesource.getEntity() instanceof AbstractArrowEntity) + { + f *= 0.5; + } + return f; + } + + public abstract Item getMachineItem(); + + @Override + public void tick() + { + if (this.deploymentticks > 0) + { + this.deploymentticks--; + } + super.tick(); + } + + @Override + public boolean hurt(@NotNull DamageSource damagesource, float f) + { + if (!net.minecraftforge.common.ForgeHooks.onLivingAttack(this, damagesource, f)) return false; + if (damagesource.getEntity() instanceof PlayerEntity && !damagesource.isProjectile() && !damagesource.isExplosion() && !damagesource.isMagic() && this.getPassengers().isEmpty()) + { + this.spawnAtLocation(this.getMachineItemWithData()); + this.remove(); + return false; + } + if (this.isInvulnerableTo(damagesource)) + { + return false; + } + else if (this.level.isClientSide) + { + return false; + } + else if (this.isDeadOrDying()) + { + return false; + } + else if (damagesource.isFire() && this.hasEffect(Effects.FIRE_RESISTANCE)) + { + return false; + } + else + { + f = adjustDamage(damagesource, f); + + this.noActionTime = 0; + + this.animationSpeed = 1.5F; + boolean flag1 = true; + if ((float) this.invulnerableTime > 10.0F) + { + if (f <= this.lastHurt) + { + return false; + } + + this.actuallyHurt(damagesource, f - this.lastHurt); + this.lastHurt = f; + flag1 = false; + } + else + { + this.lastHurt = f; + this.invulnerableTime = 20; + this.actuallyHurt(damagesource, f); + this.hurtDuration = 10; + this.hurtTime = this.hurtDuration; + } + + this.hurtDir = 0.0F; + Entity entity1 = damagesource.getEntity(); + if (entity1 != null) + { + if (entity1 instanceof LivingEntity) + { + this.setLastHurtByMob((LivingEntity) entity1); + } + + if (entity1 instanceof PlayerEntity) + { + this.lastHurtByPlayerTime = 100; + this.lastHurtByPlayer = (PlayerEntity) entity1; + } + else if (entity1 instanceof net.minecraft.entity.passive.TameableEntity) + { + net.minecraft.entity.passive.TameableEntity wolfentity = (net.minecraft.entity.passive.TameableEntity) entity1; + if (wolfentity.isTame()) + { + this.lastHurtByPlayerTime = 100; + LivingEntity livingentity = wolfentity.getOwner(); + if (livingentity != null && livingentity.getType() == EntityType.PLAYER) + { + this.lastHurtByPlayer = (PlayerEntity) livingentity; + } + else + { + this.lastHurtByPlayer = null; + } + } + } + } + + if (flag1) + { + if (damagesource instanceof EntityDamageSource && ((EntityDamageSource) damagesource).isThorns()) + { + this.level.broadcastEntityEvent(this, (byte) 33); + } + else + { + byte b0; + if (damagesource.isFire()) + { + b0 = 37; + } + else if (damagesource == DamageSource.SWEET_BERRY_BUSH) + { + b0 = 44; + } + else + { + b0 = 2; + } + + this.level.broadcastEntityEvent(this, b0); + } + + this.markHurt(); + + if (entity1 != null) + { + double d1 = entity1.getX() - this.getX(); + + double d0; + for (d0 = entity1.getZ() - this.getZ(); d1 * d1 + d0 * d0 < 1.0E-4D; d0 = (Math.random() - Math.random()) * 0.01D) + { + d1 = (Math.random() - Math.random()) * 0.01D; + } + + this.hurtDir = (float) (MathHelper.atan2(d0, d1) * (double) (180F / (float) Math.PI) - (double) this.yRot); + } + else + { + this.hurtDir = (float) ((int) (Math.random() * 2.0D) * 180); + } + } + + if (this.isDeadOrDying()) + { + SoundEvent soundevent = this.getDeathSound(); + if (flag1 && soundevent != null) + { + this.playSound(soundevent, this.getSoundVolume(), this.getVoicePitch()); + } + + this.die(damagesource); + } + else if (flag1) + { + this.playHurtSound(damagesource); + } + + if (entity1 instanceof ServerPlayerEntity) + { + CriteriaTriggers.PLAYER_HURT_ENTITY.trigger((ServerPlayerEntity) entity1, this, damagesource, f, f, false); + } + + return true; + } + } + + @Override + @Nullable + protected SoundEvent getHurtSound(@NotNull DamageSource p_184601_1_) + { + return null; + } + + @Override + @Nullable + protected SoundEvent getDeathSound() + { + return null; + } + + @Override + protected @NotNull SoundEvent getFallDamageSound(int n) + { + return SoundEvents.WOOD_FALL; + } + + @Override + public boolean removeWhenFarAway(double p_213397_1_) + { + return false; + } + + @Nullable + @Override + public Entity getControllingPassenger() + { + return this.getPassengers().isEmpty() ? null : this.getPassengers().get(0); + } + + @Override + public boolean canBeControlledByRider() + { + return true; + } + + @Override + public void addAdditionalSaveData(@NotNull CompoundNBT nbt) + { + super.addAdditionalSaveData(nbt); + + ListNBT listnbt = new ListNBT(); + for(ItemStack itemstack : this.inventory.items) + { + CompoundNBT compoundnbt = new CompoundNBT(); + if (!itemstack.isEmpty()) + { + itemstack.save(compoundnbt); + } + listnbt.add(compoundnbt); + } + nbt.put("Items", listnbt); + nbt.put("TurretRotations", this.newFloatList(this.turretpitch, this.turretyaw)); + nbt.putInt("DealyTicks", this.delayticks); + nbt.putInt("UseTicks", this.useticks); + } + + @Override + protected void dropCustomDeathLoot(DamageSource p_213333_1_, int p_213333_2_, boolean p_213333_3_) + { + super.dropCustomDeathLoot(p_213333_1_, p_213333_2_, p_213333_3_); + this.dropWreckage(p_213333_1_, p_213333_2_, p_213333_3_); + this.inventory.items.forEach(this::spawnAtLocation); + this.inventory.removeAllItems(); + } + + protected void dropWreckage(DamageSource p_213333_1_, int p_213333_2_, boolean p_213333_3_) + { + if (p_213333_1_.isFire()) + { + Arrays.stream(this.type.wreckage).forEach(itemstack -> { + if (itemstack.getItem().equals(Items.OAK_PLANKS)) + { + itemstack = new ItemStack(Items.CHARCOAL, (int) (0.25f * new Random().nextInt(itemstack.getCount() + 1) - 1)); + } + else if (!itemstack.getItem().equals(Items.STICK) && !itemstack.getItem().equals(ModItems.BEAM.get())) + { + itemstack.setCount(new Random().nextInt(itemstack.getCount() + 1) - 1); + } + spawnAtLocation(itemstack); + }); + + return; + } + Arrays.stream(this.type.wreckage).forEach(itemstack -> { + itemstack.setCount(new Random().nextInt(itemstack.getCount() + 1) - 1); + spawnAtLocation(itemstack); + }); + } + + public void remove() + { + if (!this.removed && !this.dead) + { + this.dead = true; + this.level.broadcastEntityEvent(this, (byte)3); + } + super.remove(); + } + + @Override + @OnlyIn(Dist.CLIENT) + public void handleEntityEvent(byte p_70103_1_) + { + switch(p_70103_1_) + { + case 2: + case 33: + case 36: + case 37: + case 44: + boolean flag1 = p_70103_1_ == 33; + boolean flag2 = p_70103_1_ == 36; + boolean flag3 = p_70103_1_ == 37; + boolean flag = p_70103_1_ == 44; + this.animationSpeed = 1.5F; + this.invulnerableTime = 20; + this.hurtDuration = 10; + this.hurtTime = this.hurtDuration; + this.hurtDir = 0.0F; + if (flag1) + { + this.playSound(SoundEvents.THORNS_HIT, this.getSoundVolume(), (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); + } + + DamageSource damagesource; + if (flag3) + { + damagesource = DamageSource.ON_FIRE; + } else if (flag2) + { + damagesource = DamageSource.DROWN; + } else if (flag) + { + damagesource = DamageSource.SWEET_BERRY_BUSH; + } else + { + damagesource = DamageSource.GENERIC; + } + + SoundEvent soundevent1 = this.getHurtSound(damagesource); + if (soundevent1 != null) + { + this.playSound(soundevent1, this.getSoundVolume(), (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); + } + + this.hurt(DamageSource.GENERIC, 0.0F); + break; + case 3: + SoundEvent soundevent = this.getDeathSound(); + if (soundevent != null) + { + this.playSound(soundevent, this.getSoundVolume(), (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F); + } + this.setHealth(0.0F); + this.remove(); + break; + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + case 10: + case 11: + case 12: + case 13: + case 14: + case 15: + case 16: + case 17: + case 18: + case 19: + case 20: + case 21: + case 22: + case 23: + case 24: + case 25: + case 26: + case 27: + case 28: + case 31: + case 32: + case 34: + case 35: + case 38: + case 39: + case 40: + case 41: + case 42: + case 43: + case 45: + case 53: + default: + super.handleEntityEvent(p_70103_1_); + break; + case 29: + case 30: + case 46: + int i = 128; + + for (int j = 0; j < 128; ++j) + { + double d0 = (double) j / 127.0D; + float f = (this.random.nextFloat() - 0.5F) * 0.2F; + float f1 = (this.random.nextFloat() - 0.5F) * 0.2F; + float f2 = (this.random.nextFloat() - 0.5F) * 0.2F; + double d1 = MathHelper.lerp(d0, this.xo, this.getX()) + (this.random.nextDouble() - 0.5D) * (double) this.getBbWidth() * 2.0D; + double d2 = MathHelper.lerp(d0, this.yo, this.getY()) + this.random.nextDouble() * (double) this.getBbHeight(); + double d3 = MathHelper.lerp(d0, this.zo, this.getZ()) + (this.random.nextDouble() - 0.5D) * (double) this.getBbWidth() * 2.0D; + this.level.addParticle(ParticleTypes.PORTAL, d1, d2, d3, (double) f, (double) f1, (double) f2); + } + break; + case 54: + HoneyBlock.showJumpParticles(this); + break; + } + } + + @Override + public void readAdditionalSaveData(@NotNull CompoundNBT nbt) + { + super.readAdditionalSaveData(nbt); + if (nbt.contains("Items", 9)) + { + ListNBT listnbt = nbt.getList("Items", 10); + + for(int i = 0; i < this.inventory.items.size(); ++i) + { + this.inventory.items.set(i, ItemStack.of(listnbt.getCompound(i))); + } + } + if (nbt.contains("TurretRotations", 5)) + { + ListNBT turretrotations = nbt.getList("TurretRotations", 5); + setTurretRotations(turretrotations.getFloat(0), turretrotations.getFloat(1)); + } + if (nbt.contains("DealyTicks")) + { + this.delayticks = nbt.getInt("DealyTicks"); + } + if (nbt.contains("UseTicks")) + { + this.useticks = nbt.getInt("UseTicks"); + } + } + + public float getGlobalTurretYaw() + { + return MathHelper.lerp(0.5f, this.yRotO, this.yRot) + MathHelper.lerp(0.5f, this.turretyawprev, this.turretyaw); + } + + public float getYaw() + { + return this.yRot; + } + public void setYaw(float yaw) + { + this.yRot = yaw; + this.yRotO = this.yRot; + this.yBodyRot = this.yRot; + this.yHeadRot = this.yBodyRot; + + this.setRot(this.yRot, this.xRot); + } + + public float getYawDest() + { + return this.yawdest; + } + + public void setYawDest(float yaw) + { + this.yawdest = yaw; + } + + public float getTurretPitch(float f) + { + return MathHelper.lerp(f, this.turretpitchprev, this.turretpitch); + } + + public float getTurretYaw(float f) + { + return MathHelper.lerp(f, this.turretyawprev, this.turretyaw); + } + + public float getTurretPitch() + { + return this.getTurretPitch(0.5f); + } + + public float getTurretYaw() + { + return this.getTurretYaw(0.5f); + } + + public void setTurretRotations(float pitch, float yaw) + { + this.turretpitchprev = this.turretpitch; + this.turretyawprev = this.turretyaw; + this.turretpitch = pitch; + this.turretyaw = yaw; + } + + public float getTurretPitchDest() + { + return this.turretpitchdest; + } + + public float getTurretYawDest() + { + return this.turretyawdest; + } + + public void setTurretRotationsDest(float pitch, float yaw) + { + this.turretpitchdest = pitch; + this.turretyawdest = yaw; + } + + public void updateMachineRender() + { + if (!this.level.isClientSide()) + { + PacketHandler.sendPacketToAllInArea(new PacketMachine( + this.getId(), + this.delayticks, + this.useticks, + this.turretpitch, + this.turretyaw), this.blockPosition(), SiegeMachines.RENDER_UPDATE_RANGE_SQR); + } + } + + public void updateYaw() + { + float newyaw = this.turn(this.getYaw(), this.getYawDest(), this.type.rotationspeed); + + if (this.getYaw() != newyaw) + this.setYaw(newyaw); + } + + public void updateTurretRotations() + { + float newyaw = this.turn(this.getTurretYaw(), this.getTurretYawDest(), this.type.turretspeed, this.type.turretminyaw, this.type.turretmaxyaw); + boolean shouldrotate = this.checkYaw(newyaw, this.getTurretYaw(), this.type.turretspeed, this.type.turretminyaw, this.type.turretmaxyaw); + float newpitch = shouldrotate ? this.turn(this.getTurretPitch(), this.getTurretPitchDest(), this.type.turretspeed, this.type.turretminpitch, this.type.turretmaxpitch) : this.getTurretPitch(); + + if (this.turretpitch != newpitch || this.turretyaw != newyaw) + this.setTurretRotations(newpitch, newyaw); + } + + public boolean checkYaw(float yaw, float currentyaw, float speed, float minyaw, float maxuaw) + { + return !this.type.yawfirst || Math.abs(yaw - currentyaw) <= speed / 2 || yaw <= this.type.turretminyaw || yaw >= this.type.turretmaxyaw; + } + + public float turn(float rotation, float rotationdest, float speed) + { + return this.turn(rotation, rotationdest, speed, -180, 180); + } + + public float turn(float rotation, float rotationdest, float speed, float minrotation, float maxrotation) + { + boolean haslimit = maxrotation - minrotation < 360; + + float deltarotation = rotationdest - rotation; + deltarotation = MathHelper.wrapDegrees(deltarotation); + + float newrotation; + if (deltarotation > speed / 2) + { + newrotation = rotation + speed; + } + else if (deltarotation < -speed / 2) + { + newrotation = rotation - speed; + } + else + { + newrotation = rotation + deltarotation / 2; + } + + if (haslimit) + { + if (newrotation > -minrotation) + { + newrotation = -minrotation; + } + if (newrotation < -maxrotation) + { + newrotation = -maxrotation; + } + } + + return newrotation; + } + + protected static Vector3d applyRotations(Vector3d vec, double pitch, double yaw) + { + double d0 = vec.x * Math.cos(yaw) - vec.y * Math.sin(pitch) * Math.sin(yaw) - vec.z * Math.sin(yaw) * Math.cos(pitch); + double d1 = vec.y * Math.cos(pitch) - vec.z * Math.sin(pitch); + double d2 = vec.x * Math.sin(yaw) + vec.y * Math.sin(pitch) * Math.cos(yaw) + vec.z * Math.cos(yaw) * Math.cos(pitch); + return new Vector3d(d0, d1, d2); + } + + protected float getVolumeFromDist(float maxvolume, float maxdist, float dist) + { + return maxvolume * Math.max(maxdist - dist, 0.0f) / maxdist; + } + + public abstract void use(PlayerEntity player); + + public abstract void useRealise(); + + @Override + public Container createMenu(int id, @NotNull PlayerInventory inv, @NotNull PlayerEntity player) + { + return new MachineContainer(id, inv, this); + } + + public void openInventoryGui() + { + Entity passenger = this.getControllingPassenger(); + if (passenger instanceof ServerPlayerEntity) + { + this.stopRiding(); + NetworkHooks.openGui((ServerPlayerEntity) passenger, this, this.blockPosition()); + } + } + + @Override + public @NotNull Vector3d getDismountLocationForPassenger(LivingEntity entity) + { + double yaw = (this.getGlobalTurretYaw()) * Math.PI / 180.0; + + return this.position().add(applyRotations(this.type.passengerpos, 0.0, yaw)); + } + + @Override + public boolean shouldRiderSit() + { + return false; + } + + @Override + public void positionRider(@NotNull Entity entity) + { + IMoveCallback setpos = Entity::setPos; + if (this.hasPassenger(entity)) + { + double yaw = (this.getGlobalTurretYaw()) * Math.PI / 180.0; + + Vector3d pos = this.position().add(applyRotations(this.type.passengerpos, 0.0, yaw)); + setpos.accept(entity, pos.x, pos.y, pos.z); + } + } + + public class MachineInventory extends Inventory + { + private final int containersize; + public NonNullList items; + + public MachineInventory(int containersize) + { + this.containersize = containersize; + items = NonNullList.withSize(this.containersize, ItemStack.EMPTY); + } + + @Override + public int getContainerSize() + { + return this.containersize; + } + + @Override + public boolean isEmpty() + { + return false; + } + + @Override + public @NotNull ItemStack getItem(int id) + { + return this.items.get(id); + } + + @Override + public @NotNull ItemStack removeItem(int id, int p_70298_2_) + { + return this.items.set(id, ItemStack.EMPTY); + } + + @Override + public @NotNull ItemStack removeItemNoUpdate(int id) + { + return this.items.remove(id); + } + + @Override + public void setItem(int id, @NotNull ItemStack item) + { + this.items.set(id, item); + } + + @Override + public void setChanged() + { + + } + + @Override + public boolean stillValid(@NotNull PlayerEntity player) + { + return true; + } + + @Override + public void clearContent() + { + this.items = NonNullList.withSize(this.containersize, ItemStack.EMPTY); + } + + public boolean containsItem(Item item) + { + return this.items.stream().anyMatch(itemstack -> itemstack.getItem().equals(item)); + } + + public void putItem(Item item) + { + for (int i = 0; i < this.items.size(); ++i) + { + ItemStack itemstack = this.items.get(i); + if (itemstack.isEmpty()) + { + this.items.set(i, new ItemStack(item)); + break; + } + if (itemstack.getItem().equals(item) && itemstack.getCount() < itemstack.getMaxStackSize()) + { + itemstack.setCount(itemstack.getCount() + 1); + break; + } + } + } + + public int shrinkItem(Item item) + { + for (int i = 0; i < this.containersize; ++i) + { + ItemStack itemstack = this.items.get(i); + if (itemstack.getItem().equals(item)) + { + itemstack.shrink(1); + return i; + } + } + return -1; + } + } +} \ No newline at end of file diff --git a/src/main/java/magistu/siegemachines/entity/machine/MachinePartEntity.java b/src/main/java/magistu/siegemachines/entity/machine/MachinePartEntity.java new file mode 100644 index 0000000..46f29b0 --- /dev/null +++ b/src/main/java/magistu/siegemachines/entity/machine/MachinePartEntity.java @@ -0,0 +1,54 @@ +package magistu.siegemachines.entity.machine; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntitySize; +import net.minecraft.entity.Pose; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.network.IPacket; +import net.minecraft.util.DamageSource; +import org.jetbrains.annotations.NotNull; + +public class MachinePartEntity extends net.minecraftforge.entity.PartEntity +{ + public final Machine parentmob; + public final String name; + private final EntitySize size; + + public MachinePartEntity(Machine parent, String name, float width, float height) + { + super(parent); + this.size = EntitySize.scalable(width, height); + this.refreshDimensions(); + this.parentmob = parent; + this.name = name; + } + + @Override + protected void defineSynchedData() {} + + @Override + protected void readAdditionalSaveData(@NotNull CompoundNBT p_70037_1_) {} + + @Override + protected void addAdditionalSaveData(@NotNull CompoundNBT p_213281_1_) {} + + public boolean hurt(@NotNull DamageSource source, float value) + { + return !this.isInvulnerableTo(source) && this.parentmob.hurt(source, value); + } + + public boolean is(@NotNull Entity entity) + { + return this == entity || this.parentmob == entity; + } + + public IPacket getAddEntityPacket() + { + throw new UnsupportedOperationException(); + } + + public @NotNull EntitySize getDimensions(@NotNull Pose p_213305_1_) + { + return this.size; + } +} diff --git a/src/main/java/magistu/siegemachines/entity/machine/MachineType.java b/src/main/java/magistu/siegemachines/entity/machine/MachineType.java new file mode 100644 index 0000000..9ebeb0d --- /dev/null +++ b/src/main/java/magistu/siegemachines/entity/machine/MachineType.java @@ -0,0 +1,96 @@ +package magistu.siegemachines.entity.machine; + +import magistu.siegemachines.config.SiegeMachineSpecs; +import magistu.siegemachines.config.SpecsConfig; +import magistu.siegemachines.entity.projectile.ProjectileBuilder; +import magistu.siegemachines.item.ModItems; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.util.math.vector.Vector3d; + +public enum MachineType +{ + MORTAR(SpecsConfig.MORTAR, 18, 0.0f, 85.0f, 0.0f, 0.0f, 0.5f, 0.5f, true, 10, 10, + new Vector3d(-0.5, 0.0, -20.0).scale(1 / 16.0), new Vector3d(0.0, 17.0, 7.0).scale(1 / 16.0), new Vector3d(0.0, 0.0, 12.0).scale(1 / 16.0), + ProjectileBuilder.CANNON_AMMO, true, + new ItemStack[] {new ItemStack(Items.OAK_PLANKS, 2), new ItemStack(ModItems.BEAM.get(), 1), new ItemStack(Items.STICK, 5), new ItemStack(Items.IRON_NUGGET, 21)}), + CULVERIN(SpecsConfig.CULVERIN, 9, 0.0f, 85.0f, 0.0f, 0.0f, 0.5f, 0.5f, true, 10, 10, + new Vector3d(-0.5, 0.0, -20.0).scale(1 / 16.0), new Vector3d(0.0, 17.0, 7.0).scale(1 / 16.0), new Vector3d(0.0, 0.0, 12.0).scale(1 / 16.0), + ProjectileBuilder.CANNON_AMMO, true, + new ItemStack[] {new ItemStack(Items.OAK_PLANKS, 2), new ItemStack(ModItems.BEAM.get(), 1), new ItemStack(Items.STICK, 5), new ItemStack(Items.IRON_NUGGET, 21)}), + TREBUCHET(SpecsConfig.TREBUCHET, 9, -45.0f, 75.0f, 0.0f, 0.0f, 0.05f, 0.5f, true, 38, 137, + new Vector3d(-34.0, 0.0, -94.0).scale(1 / 16.0), new Vector3d(0.0, 19.0, -3.0), new Vector3d(0.0, 10.0, -1.0), + ProjectileBuilder.GIANT_THROWING_AMMO, false, + new ItemStack[] {new ItemStack(Items.OAK_PLANKS, 8), new ItemStack(ModItems.BEAM.get(), 12), new ItemStack(Items.STICK, 20), new ItemStack(Items.IRON_NUGGET, 36), new ItemStack(Items.COBBLESTONE, 2)}), + CATAPULT(SpecsConfig.CATAPULT, 9, 0.0f, 75.0f, 0.0f, 0.0f, 0.2f, 1.0f, true, 2, 10, + new Vector3d(30.0, 0.0, -40.0).scale(1 / 16.0), new Vector3d(0.0, 51.0, -5.0).scale(1 / 16.0), new Vector3d(0.0, 0.0, 0.0), + ProjectileBuilder.THROWING_AMMO, false, + new ItemStack[] {new ItemStack(Items.OAK_PLANKS, 5), new ItemStack(ModItems.BEAM.get(), 6), new ItemStack(Items.STICK, 10), new ItemStack(Items.IRON_NUGGET, 14)}), + BALLISTA(SpecsConfig.BALLISTA, 9, -30.0f, 60.0f, -180.0f, 180.0f, 0.0f, 3.0f, false, 1, 20, + new Vector3d(0.0, 0.0, -30.0).scale(1 / 16.0), new Vector3d(0.0, 22.5, 0.0).scale(1 / 16.0), new Vector3d(0.0, 0.0, 17.0).scale(1 / 16.0), + ProjectileBuilder.BALLISTA_AMMO, false, + new ItemStack[] {new ItemStack(Items.OAK_PLANKS, 2), new ItemStack(ModItems.BEAM.get(), 1), new ItemStack(Items.STICK, 5), new ItemStack(Items.IRON_NUGGET, 8)}), + BATTERING_RAM(SpecsConfig.BATTERING_RAM, 9, 0.0f, 0.0f, 0.0f, 0.0f, 0.1f, 0.0f, false, 5, 5, + new Vector3d(12.0, 0.0, -48.0).scale(1 / 16.0), new Vector3d(0.0, 26.0, 36.0).scale(1 / 16.0), new Vector3d(0.0, 0.0, 32.0).scale(1 / 16.0), + ProjectileBuilder.NO_AMMO, false, + new ItemStack[] {new ItemStack(Items.OAK_PLANKS, 6), new ItemStack(ModItems.BEAM.get(), 8), new ItemStack(Items.STICK, 12), new ItemStack(Items.IRON_NUGGET, 8)}); + + public final SiegeMachineSpecs specs; + public final int containersize; + public final float turretminpitch; + public final float turretmaxpitch; + public final float turretminyaw; + public final float turretmaxyaw; + public final float rotationspeed; + public final float turretspeed; + public final boolean yawfirst; + public final int userealisetime; + public final int usetime; + + public final Vector3d passengerpos; + public final Vector3d turretpivot; + public final Vector3d turretvector; + + public final ProjectileBuilder[] ammo; + public final boolean usesgunpowder; + + public final ItemStack[] wreckage; + + MachineType( + SiegeMachineSpecs specs, + int containersize, + float turretminpitch, + float turretmaxpitch, + float turretminyaw, + float turretmaxyaw, + float rotationspeed, + float turretspeed, + boolean yawfirst, + int shootingtime, + int usetime, + Vector3d passengerpos, + Vector3d turretpivot, + Vector3d turretvector, + ProjectileBuilder[] ammo, + boolean usesgunpowder, + ItemStack[] wreckage) + { + this.specs = specs; + this.containersize = containersize; + this.turretminpitch = turretminpitch; + this.turretmaxpitch = turretmaxpitch; + this.turretminyaw = turretminyaw; + this.turretmaxyaw = turretmaxyaw; + this.rotationspeed = rotationspeed; + this.turretspeed = turretspeed; + this.yawfirst = yawfirst; + this.userealisetime = shootingtime; + this.usetime = usetime; + this.passengerpos = passengerpos; + this.turretpivot = turretpivot; + this.turretvector = turretvector; + this.ammo = ammo; + this.usesgunpowder = usesgunpowder; + this.wreckage = wreckage; + } +} \ No newline at end of file diff --git a/src/main/java/magistu/siegemachines/entity/machine/Mortar.java b/src/main/java/magistu/siegemachines/entity/machine/Mortar.java new file mode 100644 index 0000000..cb7d6ba --- /dev/null +++ b/src/main/java/magistu/siegemachines/entity/machine/Mortar.java @@ -0,0 +1,277 @@ +package magistu.siegemachines.entity.machine; + +import magistu.siegemachines.SiegeMachines; +import magistu.siegemachines.client.SoundTypes; +import magistu.siegemachines.entity.IReloading; +import magistu.siegemachines.entity.projectile.Cannonball; +import magistu.siegemachines.entity.projectile.Missile; +import magistu.siegemachines.gui.Crosshair; +import magistu.siegemachines.gui.ReloadingCrosshair; +import magistu.siegemachines.item.ModItems; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.MobEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.projectile.ProjectileEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Items; +import net.minecraft.particles.ParticleTypes; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Hand; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.util.text.TranslationTextComponent; +import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import software.bernie.geckolib3.core.IAnimatable; +import software.bernie.geckolib3.core.PlayState; +import software.bernie.geckolib3.core.builder.AnimationBuilder; +import software.bernie.geckolib3.core.controller.AnimationController; +import software.bernie.geckolib3.core.event.SoundKeyframeEvent; +import software.bernie.geckolib3.core.event.predicate.AnimationEvent; +import software.bernie.geckolib3.core.manager.AnimationData; +import software.bernie.geckolib3.core.manager.AnimationFactory; + +public class Mortar extends ShootingMachine implements IAnimatable, IReloading +{ + private final AnimationFactory factory = new AnimationFactory(this); + + static AnimationBuilder MOVING_ANIM = new AnimationBuilder().addAnimation("Moving", true); + + public int shootingticks = 0; + + private double wheelspitch = 0.0; + private double wheelsspeed = 0.0; + private int wheelssoundticks = 10; + + public Mortar(EntityType entitytype, World level) + { + super(entitytype, level, MachineType.MORTAR); + } + + private PlayState wheels_predicate(AnimationEvent event) + { + event.getController().setAnimation(MOVING_ANIM); + + return PlayState.CONTINUE; + } + + @Override + public void registerControllers(AnimationData data) + { + AnimationController wheels_controller = new AnimationController<>(this, "wheels_controller", 1, (t) -> { + double d = this.getWheelsSpeed(); + this.wheelsspeed = d > 0 ? Math.min(d, 1.0) : Math.max(d, -1.0); + return wheelspitch += 0.013 * this.wheelsspeed; + }, this::wheels_predicate); + data.addAnimationController(wheels_controller); + } + + @Override + public AnimationFactory getFactory() + { + return this.factory; + } + + @Override + protected ActionResultType mobInteract(PlayerEntity player, Hand hand) + { + ItemStack stack = player.getItemInHand(hand); + + if (stack.getItem().equals(Items.FLINT_AND_STEEL)) + { + if (this.useticks <= 0 && this.shootingticks <= 0) + { + stack.hurtAndBreak(1, player, (p_213833_1_) -> + { + p_213833_1_.broadcastBreakEvent(hand); + net.minecraftforge.event.ForgeEventFactory.onPlayerDestroyItem(player, this.useItem, hand); + }); + this.startShooting(player); + } + return ActionResultType.SUCCESS; + } + if (stack.getItem().equals(Items.GUNPOWDER)) + { + if (!this.inventory.containsItem(Items.GUNPOWDER)) + { + if (!player.isCreative()) + { + stack.shrink(1); + } + this.inventory.putItem(Items.GUNPOWDER); + } + return ActionResultType.SUCCESS; + } + if (super.mobInteract(player, hand) == ActionResultType.SUCCESS) + { + return ActionResultType.SUCCESS; + } + if (!this.level.isClientSide() && !this.isVehicle()) + { + player.startRiding(this); + return ActionResultType.SUCCESS; + } + + return ActionResultType.PASS; + } + + @Override + public void travel(Vector3d pos) + { + if (this.isAlive()) + { + if (this.isVehicle()) + { + LivingEntity livingentity = (LivingEntity) this.getControllingPassenger(); + + this.setTurretRotationsDest(livingentity.xRot, livingentity.yRot - this.getYaw()); + this.setYawDest(livingentity.yRot); + + this.updateYaw(); + this.updateTurretRotations(); + + float f0 = livingentity.xxa * 0.2f; + float f1 = livingentity.zza; + if (f1 <= 0.0f) + { + f1 *= 0.5f; + } + this.setSpeed(0.04f); + + pos = new Vector3d(f0, pos.y, f1); + } + super.travel(pos); + } + } + + @Override + public void tick() + { + if (this.useticks != 0 && --this.useticks <= 0) + { + this.useticks = 0; + this.delayticks = this.type.specs.delaytime.get(); + } + + if (this.shootingticks != 0 && --this.shootingticks <= 0) + { + if (this.inventory.containsItem(Items.GUNPOWDER)) + { + this.useRealise(); + } + else if (!this.level.isClientSide()) + { + Entity passenger = this.getControllingPassenger(); + if (passenger instanceof PlayerEntity) + { + passenger.sendMessage(new TranslationTextComponent(SiegeMachines.ID + ".no_gunpowder").withStyle(TextFormatting.RED), SiegeMachines.CHAT_UUID); + } + } + this.shootingticks = 0; + } + + if (!level.isClientSide() && this.isOnGround()) + { + this.setDeltaMovement(this.getWheelsDeltaMovement()); + } + + if (this.delayticks > 0 && this.isVehicle()) + { + --this.delayticks; + } + + if (this.renderupdateticks-- <= 0) + { + this.updateMachineRender(); + this.renderupdateticks = SiegeMachines.RENDER_UPDATE_TIME; + } + + if (this.getWheelsSpeed() > 0.0081 && this.wheelssoundticks-- <= 0) + { + this.level.playLocalSound(this.getX(), this.getY(), this.getZ(), SoundTypes.CANNON_WHEELS.get(), SoundCategory.NEUTRAL, 0.3f, 1.0f, true); + this.wheelssoundticks = 20; + } + + super.tick(); + } + + @Override + public void startShooting(PlayerEntity player) + { + if (this.delayticks <= 0 && this.useticks <= 0 && this.shootingticks <= 0) + { + if (!this.level.isClientSide()) + { + this.level.playSound(null, this.getX(), this.getY(), this.getZ(), SoundTypes.FUSE.get(), SoundCategory.BLOCKS, this.getVolumeFromDist(0.5f, 6.0f, this.distanceTo(player)), 0.8f); + } + this.useticks = this.type.usetime; + this.shootingticks = this.type.userealisetime; + } + } + + @Override + public void shoot() + { + if (!level.isClientSide()) + { + super.shoot(); + this.setDeltaMovement(this.getDeltaMovement().subtract(this.getShotView().scale(0.25))); + this.hasImpulse = true; + this.inventory.shrinkItem(Items.GUNPOWDER); + } + else + { + this.blowParticles(ParticleTypes.FLAME, 0.035, 25); + this.blowParticles(ParticleTypes.CLOUD, 0.2, 60); + Vector3d pos = this.position(); + this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.MORTAR_SHOOTING.get(), SoundCategory.BLOCKS, 1.5f/*this.getVolumeFromDist(1.5f, 64.0f, this.distanceTo(player))*/, 0.85f + this.level.random.nextFloat() * 0.3f, false); + } + } + + public double getWheelsSpeed() + { + if (this.isOnGround()) + { + return this.getViewVector(5.0f).multiply(1, 0, 1).dot(this.getDeltaMovement()); + } + + return 0.0; + } + + public Vector3d getWheelsDeltaMovement() + { + if (this.isOnGround() || this.isInWater()) + { + Vector3d view = this.getViewVector(1.0f); + Vector3d movement = this.getDeltaMovement(); + + double d0 = movement.x * view.x + movement.z * view.z; + + double d1 = d0 * view.x; + double d2 = 0.0; + double d3 = d0 * view.z; + + return new Vector3d(d1, d2, d3); + } + + return Vector3d.ZERO; + } + + @Override + @OnlyIn(Dist.CLIENT) + public Crosshair createCrosshair() + { + return new ReloadingCrosshair(); + } + + @Override + public Item getMachineItem() + { + return ModItems.MORTAR.get(); + } +} \ No newline at end of file diff --git a/src/main/java/magistu/siegemachines/entity/machine/ShootingMachine.java b/src/main/java/magistu/siegemachines/entity/machine/ShootingMachine.java new file mode 100644 index 0000000..615cce0 --- /dev/null +++ b/src/main/java/magistu/siegemachines/entity/machine/ShootingMachine.java @@ -0,0 +1,195 @@ +package magistu.siegemachines.entity.machine; + +import magistu.siegemachines.SiegeMachines; +import magistu.siegemachines.entity.IReloading; +import magistu.siegemachines.entity.projectile.Missile; +import magistu.siegemachines.entity.projectile.ProjectileBuilder; +import magistu.siegemachines.network.*; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.MobEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.projectile.ProjectileEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.particles.IParticleData; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Hand; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.util.text.TranslationTextComponent; +import net.minecraft.world.World; + +import java.util.Arrays; +import java.util.Random; + +public abstract class ShootingMachine extends Machine implements IReloading +{ + public int shootingticks = 0; + + protected ShootingMachine(EntityType entitytype, World level, MachineType type) + { + super(entitytype, level, type); + } + + public abstract void startShooting(PlayerEntity player); + + public void shoot() + { + if (this.type.ammo.length == 0) + { + return; + } + ProjectileBuilder projectilebuilder = this.getProjectileBuilder(); + if (projectilebuilder.equals(ProjectileBuilder.NONE)) + { + Entity passenger = this.getControllingPassenger(); + if (passenger instanceof PlayerEntity) + { + passenger.sendMessage(new TranslationTextComponent(SiegeMachines.ID + ".no_ammo").withStyle(TextFormatting.RED), SiegeMachines.CHAT_UUID); + } + return; + } + LivingEntity livingentity = (LivingEntity) this.getControllingPassenger(); + ProjectileEntity projectile = projectilebuilder.factory.create(projectilebuilder.entitytype, this.level, this.getShotPos(), livingentity == null ? this : livingentity, projectilebuilder.projectileitem); + if (projectile instanceof Missile) + { + Missile missile = (Missile) projectile; + missile.setItem(new ItemStack(missile.getDefaultItem())); + } + projectile.shootFromRotation(this, this.getTurretPitch(), this.getGlobalTurretYaw(), 0.0f, this.type.specs.projectilespeed.get(), this.type.specs.inaccuracy.get()); + this.level.addFreshEntity(projectile); + if (!this.level.isClientSide) + { + int i = this.inventory.shrinkItem(projectilebuilder.item); + PacketHandler.sendPacketToAll( + new PacketMachineInventorySlot(this.getId(), i, this.inventory.getItem(i))); + } + } + + @Override + public void use(PlayerEntity player) + { + if (!this.level.isClientSide) + { + PacketHandler.sendPacketToAllInArea(new PacketMachineUse(this.getId()), this.blockPosition(), SiegeMachines.RENDER_UPDATE_RANGE_SQR); + } + + this.startShooting(player); + } + + @Override + public void useRealise() + { + if (!this.level.isClientSide) + { + PacketHandler.sendPacketToAllInArea(new PacketMachineUseRealise(this.getId()), this.blockPosition(), SiegeMachines.RENDER_UPDATE_RANGE_SQR); + } + + this.shoot(); + } + + @Override + protected ActionResultType mobInteract(PlayerEntity player, Hand hand) + { + ItemStack stack = player.getItemInHand(hand); + + if (this.isValidAmmo(stack)) + { + if (!this.hasAmmo()) + { + if (!player.isCreative()) + { + stack.shrink(1); + } + this.inventory.putItem(stack.getItem()); + } + return ActionResultType.SUCCESS; + } + return ActionResultType.PASS; + } + + protected Vector3d getShotPos() + { + double pitch = this.getTurretPitch() * Math.PI / 180.0; + double yaw = (this.getViewYRot(0.5f) + this.getTurretYaw()) * Math.PI / 180.0; + + return this.position().add(applyRotations(this.type.turretpivot, 0.0, yaw).add(applyRotations(this.type.turretvector, pitch, yaw))); + } + + protected Vector3d getShotView() + { + double pitch = this.getTurretPitch() * Math.PI / 180.0; + double yaw = this.getGlobalTurretYaw() * Math.PI / 180.0; + + double d0 = -Math.sin(yaw) * Math.cos(pitch); + double d1 = -Math.sin(pitch); + double d2 = Math.cos(yaw) * Math.cos(pitch); + + return new Vector3d(d0, d1, d2).normalize(); + } + + protected void blowParticles(IParticleData particle, double speed, int amount) + { + for (int i = 0; i < amount; ++i) + { + Vector3d pos = this.getShotPos(); + Vector3d inaccuracy = new Vector3d(new Random().nextGaussian() * 0.2, + new Random().nextGaussian() * 0.2, + new Random().nextGaussian() * 0.2); + Vector3d velocity = this.getShotView().add(inaccuracy).scale(speed); + + this.level.addParticle(particle, pos.x, pos.y, pos.z, velocity.x, velocity.y, velocity.z); + } + } + + @Override + public void updateMachineRender() + { + super.updateMachineRender(); + if (!this.level.isClientSide()) + { + for (int i = 0; i < this.inventory.getContainerSize(); ++i) + { + if (this.isValidAmmo(this.inventory.getItem(i))) + { + PacketHandler.sendPacketToAllInArea( + new PacketMachineInventorySlot(this.getId(), i, this.inventory.getItem(i)), + this.blockPosition(), + SiegeMachines.RENDER_UPDATE_RANGE_SQR); + } + } + } + } + + public boolean isValidAmmo(ItemStack stack) + { + return this.isValidAmmo(stack.getItem()); + } + + public boolean isValidAmmo(Item entry) + { + return Arrays.stream(this.type.ammo).anyMatch(builder -> builder.item.equals(entry)); + } + + public ItemStack getAmmo() + { + return this.inventory.items.stream().filter(this::isValidAmmo).findFirst().orElse(ItemStack.EMPTY); + } + + public boolean hasAmmo() + { + return this.inventory.items.stream().anyMatch(this::isValidAmmo); + } + + public ProjectileBuilder getProjectileBuilder() + { + ItemStack ammo = this.getAmmo(); + if (ammo.equals(ItemStack.EMPTY)) + { + return ProjectileBuilder.NONE; + } + return Arrays.stream(this.type.ammo).filter(builder -> builder.item.equals(ammo.getItem())).findFirst().orElse(ProjectileBuilder.NONE); + } +} diff --git a/src/main/java/magistu/siegemachines/entity/machine/Trebuchet.java b/src/main/java/magistu/siegemachines/entity/machine/Trebuchet.java new file mode 100644 index 0000000..8010961 --- /dev/null +++ b/src/main/java/magistu/siegemachines/entity/machine/Trebuchet.java @@ -0,0 +1,256 @@ +package magistu.siegemachines.entity.machine; + +import magistu.siegemachines.SiegeMachines; +import magistu.siegemachines.client.SoundTypes; +import magistu.siegemachines.gui.Crosshair; +import magistu.siegemachines.gui.ReloadingCrosshair; +import magistu.siegemachines.item.ModItems; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.MobEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Hand; +import net.minecraft.util.SoundCategory; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import software.bernie.geckolib3.core.IAnimatable; +import software.bernie.geckolib3.core.PlayState; +import software.bernie.geckolib3.core.builder.AnimationBuilder; +import software.bernie.geckolib3.core.controller.AnimationController; +import software.bernie.geckolib3.core.event.predicate.AnimationEvent; +import software.bernie.geckolib3.core.manager.AnimationData; +import software.bernie.geckolib3.core.manager.AnimationFactory; + +public class Trebuchet extends ShootingMachine implements IAnimatable +{ + private final AnimationFactory factory = new AnimationFactory(this); + + static AnimationBuilder SHOOTING_ANIM = new AnimationBuilder().addAnimation("Shooting", true); + static AnimationBuilder RELOADING_ANIM = new AnimationBuilder().addAnimation("Reloading", true); + static AnimationBuilder IDLE_RELOADED_ANIM = new AnimationBuilder().addAnimation("IdleReloaded", true); + static AnimationBuilder IDLE_NOT_RELOADED_ANIM = new AnimationBuilder().addAnimation("IdleNotReloaded", true); + + private final MachinePartEntity[] subentities; + private final MachinePartEntity backside; + + private final Vector3d backsidepos; + + public enum State + { + SHOOTING, + RELOADING, + IDLE_RELOADED, + IDLE_NOT_RELOADED + } + public State state = State.RELOADING; + + public Trebuchet(EntityType entitytype, World level) + { + super(entitytype, level, MachineType.TREBUCHET); + this.backside = new MachinePartEntity(this, "backside", 5.0F, 2.0F); + this.backsidepos = new Vector3d(0.0, 0.0, -85.0).scale(1.0 / 16.0); + this.subentities = new MachinePartEntity[] { this.backside }; + } + + private PlayState predicate(AnimationEvent event) + { + switch (state) + { + case SHOOTING: + event.getController().setAnimation(SHOOTING_ANIM); + return PlayState.CONTINUE; + case IDLE_RELOADED: + event.getController().setAnimation(IDLE_RELOADED_ANIM); + return PlayState.CONTINUE; + case RELOADING: + event.getController().setAnimation(RELOADING_ANIM); + return PlayState.CONTINUE; + case IDLE_NOT_RELOADED: + event.getController().setAnimation(IDLE_NOT_RELOADED_ANIM); + return PlayState.CONTINUE; + } + + return PlayState.CONTINUE; + } + + private void tickPart(MachinePartEntity subentity, double p_226526_2_, double p_226526_4_, double p_226526_6_) + { + subentity.setPos(this.getX() + p_226526_2_, this.getY() + p_226526_4_, this.getZ() + p_226526_6_); + } + + @Override + public void aiStep() + { + Vector3d[] avector3d = new Vector3d[this.subentities.length]; + + Vector3d pos = this.position().add(applyRotations(this.backsidepos, 0.0, this.getYaw())); + this.tickPart(this.backside, pos.x, pos.y, pos.z); + + for(int i = 0; i < this.subentities.length; ++i) + { + avector3d[i] = new Vector3d(this.subentities[i].getX(), this.subentities[i].getY(), this.subentities[i].getZ()); + } + + for(int i = 0; i < this.subentities.length; ++i) + { + this.subentities[i].xo = avector3d[i].x; + this.subentities[i].yo = avector3d[i].y; + this.subentities[i].zo = avector3d[i].z; + this.subentities[i].xOld = avector3d[i].x; + this.subentities[i].yOld = avector3d[i].y; + this.subentities[i].zOld = avector3d[i].z; + } + + super.aiStep(); + } + + public MachinePartEntity[] getSubEntities() { + return this.subentities; + } + + @Override + public net.minecraftforge.entity.PartEntity[] getParts() + { + return this.subentities; + } + + @Override + public void registerControllers(AnimationData data) + { + AnimationController controller = new AnimationController<>(this, "controller", 1, (t) -> + { + if (this.state.equals(State.RELOADING)) + { + return (double) (this.type.specs.delaytime.get() - this.delayticks) / this.type.specs.delaytime.get(); + } + return t; + }, this::predicate); + data.addAnimationController(controller); + } + + @Override + public AnimationFactory getFactory() + { + return this.factory; + } + + @Override + protected ActionResultType mobInteract(PlayerEntity player, Hand hand) + { + ItemStack stack = player.getItemInHand(hand); + + if (super.mobInteract(player, hand) == ActionResultType.SUCCESS) + { + return ActionResultType.SUCCESS; + } + if (!this.level.isClientSide() && !this.isVehicle()) + { + player.startRiding(this); + return ActionResultType.SUCCESS; + } + + return ActionResultType.PASS; + } + + public void startShooting(PlayerEntity player) + { + if (this.delayticks <= 0 && this.useticks <= 0 && this.shootingticks <= 0) + { + this.state = State.SHOOTING; + this.useticks = this.type.usetime; + this.shootingticks = this.type.userealisetime; + + Vector3d pos = this.position(); + this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.TREBUCHET_SHOOTING.get(), SoundCategory.BLOCKS, 1.0f, 1.0f, false); + } + } + + @Override + public void shoot() + { + if (!level.isClientSide()) + { + super.shoot(); + } + } + + @Override + public void travel(Vector3d pos) + { + if (this.isAlive()) + { + if (this.isVehicle() && this.useticks <= 0 && this.delayticks <= 0) + { + LivingEntity livingentity = (LivingEntity) this.getControllingPassenger(); + + this.setTurretRotations(livingentity.xRot, this.getTurretYaw()); + this.updateTurretRotations(); + + this.setYawDest(livingentity.yRot); + this.updateYaw(); + } + super.travel(pos); + } + } + + @Override + public void tick() + { + if (this.useticks != 0 && --this.useticks <= 0) + { + this.state = State.RELOADING; + this.useticks = 0; + this.delayticks = this.type.specs.delaytime.get(); + } + + if (this.shootingticks != 0 && --this.shootingticks <= 0) + { + this.useRealise(); + this.shootingticks = 0; + } + + if (!level.isClientSide() && (this.isOnGround() || this.isInWater())) + { + this.setDeltaMovement(this.getDeltaMovement().multiply(0.0, 1.0, 0.0)); + } + + if (this.delayticks > 0 && this.isVehicle()) + { + if (this.delayticks % 40 == 0) + { + Vector3d pos = this.position(); + this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.TREBUCHET_RELOADING.get(), SoundCategory.BLOCKS, 1.0f, 1.0f, false); + } + if (--this.delayticks <= 0) + { + this.state = State.IDLE_RELOADED; + } + } + + if (this.renderupdateticks-- <= 0) + { + this.updateMachineRender(); + this.renderupdateticks = SiegeMachines.RENDER_UPDATE_TIME; + } + + super.tick(); + } + + @Override + @OnlyIn(Dist.CLIENT) + public Crosshair createCrosshair() + { + return new ReloadingCrosshair(); + } + + @Override + public Item getMachineItem() + { + return ModItems.TREBUCHET.get(); + } +} \ No newline at end of file diff --git a/src/main/java/magistu/siegemachines/entity/projectile/Cannonball.java b/src/main/java/magistu/siegemachines/entity/projectile/Cannonball.java new file mode 100644 index 0000000..48a828b --- /dev/null +++ b/src/main/java/magistu/siegemachines/entity/projectile/Cannonball.java @@ -0,0 +1,22 @@ +package magistu.siegemachines.entity.projectile; + +import magistu.siegemachines.item.ModItems; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.Item; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.world.World; + +public class Cannonball extends Missile +{ + public Cannonball(EntityType type, World level) + { + super(type, level); + this.item = ModItems.CANNONBALL.get(); + } + + public Cannonball(EntityType entitytype, World level, Vector3d pos, LivingEntity entity, Item item) + { + super(entitytype, level, pos, entity, MissileType.CANNONBALL, item); + } +} diff --git a/src/main/java/magistu/siegemachines/entity/projectile/FlightType.java b/src/main/java/magistu/siegemachines/entity/projectile/FlightType.java new file mode 100644 index 0000000..c113b65 --- /dev/null +++ b/src/main/java/magistu/siegemachines/entity/projectile/FlightType.java @@ -0,0 +1,8 @@ +package magistu.siegemachines.entity.projectile; + +public enum FlightType +{ + NONE, + AHEAD, + SPINNING +} diff --git a/src/main/java/magistu/siegemachines/entity/projectile/GiantArrow.java b/src/main/java/magistu/siegemachines/entity/projectile/GiantArrow.java new file mode 100644 index 0000000..212aeeb --- /dev/null +++ b/src/main/java/magistu/siegemachines/entity/projectile/GiantArrow.java @@ -0,0 +1,41 @@ +package magistu.siegemachines.entity.projectile; + +import magistu.siegemachines.item.ModItems; +import net.minecraft.entity.*; +import net.minecraft.entity.projectile.AbstractArrowEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.network.IPacket; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.world.World; +import net.minecraftforge.fml.network.NetworkHooks; +import org.jetbrains.annotations.NotNull; + +public class GiantArrow extends AbstractArrowEntity +{ + private final IPacket spawningpacket = NetworkHooks.getEntitySpawningPacket(this); + + public GiantArrow(EntityType type, World level) + { + super(type, level); + } + + public GiantArrow(EntityType entitytype, World level, Vector3d pos, LivingEntity entity, Item item) + { + super(entitytype, entity, level); + this.setPos(pos.x, pos.y, pos.z); + this.setBaseDamage(15.0f); + } + + @Override + protected @NotNull ItemStack getPickupItem() + { + return new ItemStack(ModItems.GIANT_ARROW.get()); + } + + @Override + public @NotNull IPacket getAddEntityPacket() + { + return spawningpacket; + } +} \ No newline at end of file diff --git a/src/main/java/magistu/siegemachines/entity/projectile/GiantStone.java b/src/main/java/magistu/siegemachines/entity/projectile/GiantStone.java new file mode 100644 index 0000000..6d1bf51 --- /dev/null +++ b/src/main/java/magistu/siegemachines/entity/projectile/GiantStone.java @@ -0,0 +1,22 @@ +package magistu.siegemachines.entity.projectile; + +import magistu.siegemachines.item.ModItems; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.Item; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.world.World; + +public class GiantStone extends Missile +{ + public GiantStone(EntityType entitytype, World level) + { + super(entitytype, level); + this.item = ModItems.GIANT_STONE.get(); + } + + public GiantStone(EntityType entitytype, World level, Vector3d pos, LivingEntity entity, Item item) + { + super(entitytype, level, pos, entity, MissileType.GIANT_STONE, item); + } +} diff --git a/src/main/java/magistu/siegemachines/entity/projectile/IProjectileFactory.java b/src/main/java/magistu/siegemachines/entity/projectile/IProjectileFactory.java new file mode 100644 index 0000000..df8568c --- /dev/null +++ b/src/main/java/magistu/siegemachines/entity/projectile/IProjectileFactory.java @@ -0,0 +1,13 @@ +package magistu.siegemachines.entity.projectile; + +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.projectile.ProjectileEntity; +import net.minecraft.item.Item; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.world.World; + +public interface IProjectileFactory +{ + T create(EntityType entitytype, World level, Vector3d pos, LivingEntity entity, Item item); +} diff --git a/src/main/java/magistu/siegemachines/entity/projectile/Missile.java b/src/main/java/magistu/siegemachines/entity/projectile/Missile.java new file mode 100644 index 0000000..c7083f4 --- /dev/null +++ b/src/main/java/magistu/siegemachines/entity/projectile/Missile.java @@ -0,0 +1,188 @@ +package magistu.siegemachines.entity.projectile; + +import magistu.siegemachines.item.ModItems; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.ai.attributes.Attributes; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.projectile.ProjectileItemEntity; +import net.minecraft.item.Item; +import net.minecraft.particles.BlockParticleData; +import net.minecraft.network.IPacket; +import net.minecraft.particles.IParticleData; +import net.minecraft.util.*; +import net.minecraft.particles.ParticleTypes; +import net.minecraft.util.math.*; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.world.Explosion; +import net.minecraft.world.ExplosionContext; +import net.minecraft.world.World; +import net.minecraftforge.fml.network.NetworkHooks; +import org.jetbrains.annotations.NotNull; + +public abstract class Missile extends ProjectileItemEntity +{ + public MissileType type = MissileType.STONE; + public Item item = ModItems.STONE.get(); + + public Missile(EntityType entitytype, World level) + { + super(entitytype, level); + } + + public Missile(EntityType entitytype, World level, Vector3d pos, LivingEntity entity, MissileType type, Item item) + { + super(entitytype, entity, level); + this.type = type; + this.item = item; + this.setPos(pos.x, pos.y, pos.z); + } + + @Override + public @NotNull Item getDefaultItem() + { + return this.item; + } + + @Override + public @NotNull IPacket getAddEntityPacket() + { + return NetworkHooks.getEntitySpawningPacket(this); + } + + @Override + public void onHit(RayTraceResult result) + { + if (result.getType() == RayTraceResult.Type.ENTITY) + { + EntityRayTraceResult entityRTR = (EntityRayTraceResult)result; + Vector3d pos = entityRTR.getLocation(); + Entity entity = entityRTR.getEntity(); + float damage = this.type.specs.mass.get() * (float) this.getDeltaMovement().length(); + + DamageSource damagesource = DamageSource.thrown(this, this.getOwner()); + if (this.type.armorpiercing >= 1.0f) + { + damagesource = damagesource.bypassArmor(); + } + else if (this.type.armorpiercing > 0.0f && entity instanceof LivingEntity) + { + LivingEntity livingentity = (LivingEntity) entity; + damage -= (1.0f - this.type.armorpiercing) * (damage - CombatRules.getDamageAfterAbsorb(damage, (float) livingentity.getArmorValue(), (float) livingentity.getAttributeValue(Attributes.ARMOR_TOUGHNESS))); + damagesource = damagesource.bypassArmor(); + } + + if (!this.level.isClientSide() && this.type.explosive) + { + this.level.explode(this.getOwner(), pos.x, pos.y, pos.z, 3.0F, Explosion.Mode.NONE); + this.remove(); + } + + entity.hurt(damagesource, damage); + Vector3d vector3d = this.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D).normalize().scale((double) this.type.knockback * 0.6D); + if (vector3d.lengthSqr() > 0.0D) + { + entity.push(vector3d.x, 0.1D, vector3d.z); + } + } + + if (result.getType() == RayTraceResult.Type.BLOCK) + { + BlockRayTraceResult blockRTR = (BlockRayTraceResult)result; + BlockPos blockpos = blockRTR.getBlockPos(); + BlockState blockstate = this.level.getBlockState(blockpos); + boolean smoothimpact = + !this.type.specs.destroysground.get() && ( + blockstate == Blocks.SAND.defaultBlockState() || + blockstate == Blocks.RED_SAND.defaultBlockState() || + blockstate == Blocks.DIRT.defaultBlockState() || + blockstate == Blocks.GRASS_BLOCK.defaultBlockState() || + blockstate == Blocks.GRASS_PATH.defaultBlockState() || + blockstate == Blocks.COARSE_DIRT.defaultBlockState() || + blockstate == Blocks.SNOW_BLOCK.defaultBlockState()) && + blockRTR.getDirection() == Direction.UP; + + if (blockRTR.getDirection() == Direction.UP) + { + if (this.type.explosive) + { + for (int r = 0; r < this.type.specs.explosionpower.get(); ++r) + { + for (float a = 0; a < 2 * Math.PI; a += Math.PI / 4) + { + BlockPos pos = blockRTR.getBlockPos().offset(r * MathHelper.cos(a), 0, -r * MathHelper.sin(a)); + if (this.level.getBlockState(pos) == Blocks.GRASS_BLOCK.defaultBlockState()) + { + this.level.setBlockAndUpdate(pos, Blocks.DIRT.defaultBlockState()); + } + } + } + } + if (!this.level.isClientSide()) + { + this.remove(); + if (smoothimpact && this.type.explosive) + { + this.level.explode(this.getOwner(), blockpos.getX(), blockpos.getY(), blockpos.getZ(), this.type.specs.explosionpower.get(), Explosion.Mode.NONE); + } + } + else if (smoothimpact) + { + this.dustExplosion(new BlockParticleData(ParticleTypes.BLOCK, blockstate).setPos(blockpos), blockpos, this.type.specs.explosionpower.get() / 2, 50); + } + } + if (!this.level.isClientSide() && !smoothimpact && this.type.explosive) + { + this.level.explode(this.getOwner(), blockpos.getX(), blockpos.getY(), blockpos.getZ(), this.type.specs.explosionpower.get(), Explosion.Mode.BREAK); + } + } + + if (result.getType() == RayTraceResult.Type.MISS) + { + this.level.playSound((PlayerEntity)this.getOwner(), this.getOnPos(), SoundEvents.ANVIL_BREAK, SoundCategory.AMBIENT, 1.0f, 1.0f); + if(!this.level.isClientSide()) + { + this.remove(); + } + } + if (!this.level.isClientSide()) + { + this.remove(); + } + } + + private void dustExplosion(IParticleData particle, BlockPos blockpos, double speed, int amount) + { + this.dustExplosion(particle, blockpos.getX(), blockpos.getY(), blockpos.getZ(), speed, amount); + } + + private void dustExplosion(IParticleData particle, double x, double y, double z, double speed, int amount) + { + for (int i = 0; i < amount; ++i) + { + Vector3d movement = this.getDeltaMovement(); + double d0 = x - 0.05 + this.level.random.nextDouble() * 0.3; + double d1 = y + 1.0; + double d2 = z - 0.05 + this.level.random.nextDouble() * 0.3; + double d3 = movement.x * this.level.random.nextDouble() * speed; + double d4 = -movement.y * this.level.random.nextDouble() * speed * 10.0f; + double d5 = movement.z * this.level.random.nextDouble() * speed; + this.level.addParticle(particle, d0, d1, d2, d3, d4, d5); + } + } + + @Override + public void tick() + { + if (this.type.flighttype == FlightType.SPINNING) + { + this.xRot += 0.5; + this.setRot(this.yRot, this.xRot); + } + + super.tick(); + } +} diff --git a/src/main/java/magistu/siegemachines/entity/projectile/MissileType.java b/src/main/java/magistu/siegemachines/entity/projectile/MissileType.java new file mode 100644 index 0000000..610ca92 --- /dev/null +++ b/src/main/java/magistu/siegemachines/entity/projectile/MissileType.java @@ -0,0 +1,27 @@ +package magistu.siegemachines.entity.projectile; + +import magistu.siegemachines.config.MissileSpecs; +import magistu.siegemachines.config.SpecsConfig; + +public enum MissileType +{ + CANNONBALL(SpecsConfig.CANNONBALL, 1.5f, true, FlightType.SPINNING, 1.0f), + STONE(SpecsConfig.STONE, 1.5f, true, FlightType.SPINNING, 1.0f), + GIANT_STONE(SpecsConfig.GIANT_STONE, 3.0f, true, FlightType.SPINNING, 1.0f); + //GIANT_ARROW(SpecsConfig.GIANT_ARROW, 1.5f, false, FlightType.AHEAD, 0.5f); + + public final MissileSpecs specs; + public final float knockback; + public final boolean explosive; + public final FlightType flighttype; + public final float armorpiercing; + + MissileType(MissileSpecs specs, float knockback, boolean explosive, FlightType headingtype, float armorpiercing) + { + this.specs = specs; + this.knockback = knockback; + this.explosive = explosive; + this.flighttype = headingtype; + this.armorpiercing = armorpiercing; + } +} diff --git a/src/main/java/magistu/siegemachines/entity/projectile/ProjectileBuilder.java b/src/main/java/magistu/siegemachines/entity/projectile/ProjectileBuilder.java new file mode 100644 index 0000000..33f18e8 --- /dev/null +++ b/src/main/java/magistu/siegemachines/entity/projectile/ProjectileBuilder.java @@ -0,0 +1,51 @@ +package magistu.siegemachines.entity.projectile; + +import magistu.siegemachines.entity.EntityTypes; +import magistu.siegemachines.item.ModItems; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.projectile.ArrowEntity; +import net.minecraft.entity.projectile.ProjectileEntity; +import net.minecraft.item.Item; +import net.minecraft.item.Items; + + +public class ProjectileBuilder +{ + public final static ProjectileBuilder NONE = new ProjectileBuilder<>(Items.AIR, EntityTypes.STONE.get(), Stone::new); + + public final static ProjectileBuilder[] NO_AMMO = new ProjectileBuilder[]{}; + public final static ProjectileBuilder[] CANNON_AMMO = new ProjectileBuilder[]{ + new ProjectileBuilder(ModItems.CANNONBALL.get(), EntityTypes.CANNONBALL.get(), Cannonball::new)}; + public final static ProjectileBuilder[] GIANT_THROWING_AMMO = new ProjectileBuilder[]{ + new ProjectileBuilder(Items.COBBLESTONE, ModItems.GIANT_STONE.get(), EntityTypes.GIANT_STONE.get(), GiantStone::new)}; + public final static ProjectileBuilder[] THROWING_AMMO = new ProjectileBuilder[]{ + new ProjectileBuilder(Items.COBBLESTONE, ModItems.STONE.get(), EntityTypes.STONE.get(), Stone::new)}; + public final static ProjectileBuilder[] BALLISTA_AMMO = new ProjectileBuilder[]{ + new ProjectileBuilder(ModItems.GIANT_ARROW.get(), EntityTypes.GIANT_ARROW.get(), GiantArrow::new), + new ProjectileBuilder(Items.ARROW, EntityType.ARROW, (entitytype, level, pos, entity, item) -> + { + ArrowEntity arrow = new ArrowEntity(level, entity); + arrow.setPos(pos.x, pos.y, pos.z); + return arrow; + })}; + + public final Item item; + public final Item projectileitem; + public final EntityType entitytype; + public final IProjectileFactory factory; + + public ProjectileBuilder(Item item, EntityType entitytype, IProjectileFactory factory) + { + this(item, item, entitytype, factory); + } + + public ProjectileBuilder(Item item, Item projectileitem, EntityType entitytype, IProjectileFactory factory) + { + this.item = item; + this.projectileitem = projectileitem; + this.entitytype = entitytype; + this.factory = factory; + } + + +} diff --git a/src/main/java/magistu/siegemachines/entity/projectile/Stone.java b/src/main/java/magistu/siegemachines/entity/projectile/Stone.java new file mode 100644 index 0000000..d709625 --- /dev/null +++ b/src/main/java/magistu/siegemachines/entity/projectile/Stone.java @@ -0,0 +1,22 @@ +package magistu.siegemachines.entity.projectile; + +import magistu.siegemachines.item.ModItems; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.Item; +import net.minecraft.util.math.vector.Vector3d; +import net.minecraft.world.World; + +public class Stone extends Missile +{ + public Stone(EntityType entitytype, World level) + { + super(entitytype, level); + this.item = ModItems.STONE.get(); + } + + public Stone(EntityType entitytype, World level, Vector3d pos, LivingEntity entity, Item item) + { + super(entitytype, level, pos, entity, MissileType.STONE, item); + } +} diff --git a/src/main/java/magistu/siegemachines/event/ClientEvents.java b/src/main/java/magistu/siegemachines/event/ClientEvents.java new file mode 100644 index 0000000..0fe5daf --- /dev/null +++ b/src/main/java/magistu/siegemachines/event/ClientEvents.java @@ -0,0 +1,82 @@ +package magistu.siegemachines.event; + +import magistu.siegemachines.client.KeyBindings; +import magistu.siegemachines.entity.IReloading; +import magistu.siegemachines.entity.machine.Machine; +import magistu.siegemachines.gui.Crosshair; +import magistu.siegemachines.network.PacketHandler; +import magistu.siegemachines.network.PacketOpenMachineInventory; +import magistu.siegemachines.network.PacketMachineUse; +import net.minecraft.client.GameSettings; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.player.ClientPlayerEntity; +import net.minecraft.client.settings.PointOfView; +import net.minecraft.entity.Entity; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.client.event.InputEvent; +import net.minecraftforge.client.event.RenderGameOverlayEvent; +import net.minecraftforge.eventbus.api.EventPriority; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + + +@Mod.EventBusSubscriber +public class ClientEvents +{ + public static Crosshair crosshair = null; + + @SubscribeEvent(priority = EventPriority.NORMAL, receiveCanceled = true) + @OnlyIn(Dist.CLIENT) + public static void onKeyPressedEvent(InputEvent.KeyInputEvent ev) + { + if (KeyBindings.MACHINE_USE.isDown()) + { + ClientPlayerEntity player = Minecraft.getInstance().player; + if (player != null && player.isPassenger() && player.getVehicle() instanceof Machine) + { + PacketHandler.sendToServer(new PacketMachineUse(player.getVehicle().getId())); + } + } + + if (KeyBindings.MACHINE_INVENTORY.isDown()) + { + ClientPlayerEntity player = Minecraft.getInstance().player; + if (player != null && player.isPassenger() && player.getVehicle() instanceof Machine) + { + PacketHandler.sendToServer(new PacketOpenMachineInventory()); + } + } + } + + @SubscribeEvent + @OnlyIn(Dist.CLIENT) + public static void onRenderOverlayPre(RenderGameOverlayEvent.Pre ev) + { + if (ev.getType() == RenderGameOverlayEvent.ElementType.CROSSHAIRS) + { + Minecraft mc = Minecraft.getInstance(); + GameSettings settings = mc.options; + ClientPlayerEntity player = mc.player; + + if ((settings.renderDebug && !settings.hideGui && !player.isReducedDebugInfo() && !settings.reducedDebugInfo) || settings.getCameraType().compareTo(PointOfView.FIRST_PERSON) != 0) + { + return; + } + + if (player.isPassenger()) + { + Entity entity = player.getVehicle(); + if (entity instanceof IReloading) + { + if (crosshair == null) + { + crosshair = ((IReloading) entity).createCrosshair(); + } + crosshair.render(ev.getMatrixStack(), ev.getPartialTicks(), mc, player); + ev.setCanceled(true); + } + } + } + } +} diff --git a/src/main/java/magistu/siegemachines/event/ModEventBusEvents.java b/src/main/java/magistu/siegemachines/event/ModEventBusEvents.java new file mode 100644 index 0000000..29beef5 --- /dev/null +++ b/src/main/java/magistu/siegemachines/event/ModEventBusEvents.java @@ -0,0 +1,23 @@ +package magistu.siegemachines.event; + +import magistu.siegemachines.SiegeMachines; +import magistu.siegemachines.entity.EntityTypes; +import magistu.siegemachines.entity.machine.*; +import net.minecraftforge.event.entity.EntityAttributeCreationEvent; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.common.Mod; + +@Mod.EventBusSubscriber(modid = SiegeMachines.ID, bus = Mod.EventBusSubscriber.Bus.MOD) +public class ModEventBusEvents +{ + @SubscribeEvent + public static void addEntityAttributes(EntityAttributeCreationEvent event) + { + event.put(EntityTypes.MORTAR.get(), Mortar.setEntityAttributes(MachineType.MORTAR).build()); + event.put(EntityTypes.CULVERIN.get(), Mortar.setEntityAttributes(MachineType.CULVERIN).build()); + event.put(EntityTypes.TREBUCHET.get(), Trebuchet.setEntityAttributes(MachineType.TREBUCHET).build()); + event.put(EntityTypes.CATAPULT.get(), Catapult.setEntityAttributes(MachineType.CATAPULT).build()); + event.put(EntityTypes.BALLISTA.get(), Ballista.setEntityAttributes(MachineType.BALLISTA).build()); + event.put(EntityTypes.BATTERING_RAM.get(), Ballista.setEntityAttributes(MachineType.BATTERING_RAM).build()); + } +} diff --git a/src/main/java/magistu/siegemachines/gui/AlignmentHelper.java b/src/main/java/magistu/siegemachines/gui/AlignmentHelper.java new file mode 100644 index 0000000..559ba0e --- /dev/null +++ b/src/main/java/magistu/siegemachines/gui/AlignmentHelper.java @@ -0,0 +1,33 @@ +package magistu.siegemachines.gui; + +import java.util.Arrays; +import java.util.List; + +public class AlignmentHelper +{ + public static final List validAlignmentValues = Arrays.asList(new String[] { "top_left", "top_center", "top_right", "center_left", "center", "center_right", "bottom_left", "bottom_center", "bottom_right" }); + + public enum Alignment + { + TOP_LEFT, + TOP_CENTER, + TOP_RIGHT, + CENTER_LEFT, + CENTER, + CENTER_RIGHT, + BOTTOM_LEFT, + BOTTOM_CENTER, + BOTTOM_RIGHT; + + + public static Alignment fromString(String align) + { + int idx = AlignmentHelper.validAlignmentValues.indexOf(align); + if (idx != -1) + { + return values()[idx]; + } + return CENTER; + } + } +} \ No newline at end of file diff --git a/src/main/java/magistu/siegemachines/gui/ContainerTypes.java b/src/main/java/magistu/siegemachines/gui/ContainerTypes.java new file mode 100644 index 0000000..66a8d11 --- /dev/null +++ b/src/main/java/magistu/siegemachines/gui/ContainerTypes.java @@ -0,0 +1,22 @@ +package magistu.siegemachines.gui; + +import magistu.siegemachines.SiegeMachines; +import net.minecraft.inventory.container.ContainerType; +import net.minecraftforge.common.extensions.IForgeContainerType; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.fml.RegistryObject; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; + +public class ContainerTypes +{ + public static final DeferredRegister> CONTAINER_TYPES = DeferredRegister.create(ForgeRegistries.CONTAINERS, SiegeMachines.ID); + + public static final RegistryObject> MACHINE_CONTAINER = CONTAINER_TYPES.register("machine", () -> IForgeContainerType.create(MachineContainer::new)); + public static final RegistryObject> SIEGE_WORKBENCH_CONTAINER = CONTAINER_TYPES.register("siege_workbench", () -> IForgeContainerType.create(SiegeWorkbenchContainer::new)); + + public static void register(IEventBus eventBus) + { + CONTAINER_TYPES.register(eventBus); + } +} diff --git a/src/main/java/magistu/siegemachines/gui/Crosshair.java b/src/main/java/magistu/siegemachines/gui/Crosshair.java new file mode 100644 index 0000000..003cea6 --- /dev/null +++ b/src/main/java/magistu/siegemachines/gui/Crosshair.java @@ -0,0 +1,26 @@ +package magistu.siegemachines.gui; + +import com.mojang.blaze3d.matrix.MatrixStack; +import magistu.siegemachines.SiegeMachines; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + + +@OnlyIn(Dist.CLIENT) +public abstract class Crosshair extends HudElement +{ + protected static final ResourceLocation CROSSHAIR_TEXTURES = new ResourceLocation(SiegeMachines.ID, "textures/gui/crosshairs.png"); + + public Crosshair(int width, int height) + { + super(width, height); + } + + public final void render(MatrixStack matrixstack, float partialticks) {} + + public abstract void render(MatrixStack matrixstack, float ticks, Minecraft mc, PlayerEntity player); +} \ No newline at end of file diff --git a/src/main/java/magistu/siegemachines/gui/HudElement.java b/src/main/java/magistu/siegemachines/gui/HudElement.java new file mode 100644 index 0000000..8adfd08 --- /dev/null +++ b/src/main/java/magistu/siegemachines/gui/HudElement.java @@ -0,0 +1,73 @@ +package magistu.siegemachines.gui; + +import com.mojang.blaze3d.matrix.MatrixStack; +import net.minecraft.client.Minecraft; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + + +@OnlyIn(Dist.CLIENT) +public abstract class HudElement +{ + protected int width; + protected int height; + + public int getAlignedX(AlignmentHelper.Alignment align, int offset) + { + switch (align) + { + case TOP_LEFT: + case CENTER_LEFT: + case BOTTOM_LEFT: + return 5 + offset; + case TOP_CENTER: + case CENTER: + case BOTTOM_CENTER: + return Minecraft.getInstance().getWindow().getGuiScaledWidth() / 2 - this.width / 2 + offset; + case TOP_RIGHT: + case CENTER_RIGHT: + case BOTTOM_RIGHT: + return Minecraft.getInstance().getWindow().getGuiScaledWidth() - this.width - 5 + offset; + } + return 0; + } + + public int getAlignedY(AlignmentHelper.Alignment align, int offset) + { + switch (align) + { + case TOP_LEFT: + case TOP_CENTER: + case TOP_RIGHT: + return 5 + offset; + case CENTER_LEFT: + case CENTER: + case CENTER_RIGHT: + return Minecraft.getInstance().getWindow().getGuiScaledHeight() / 2 - this.height / 2 + 16 + offset; + case BOTTOM_CENTER: + return Minecraft.getInstance().getWindow().getGuiScaledHeight() - this.height - 65 + offset; + case BOTTOM_LEFT: + case BOTTOM_RIGHT: + return Minecraft.getInstance().getWindow().getGuiScaledHeight() - this.height - 5 + offset; + } + return 0; + } + + public HudElement(int elementWidth, int elementHeight) + { + this.width = elementWidth; + this.height = elementHeight; + } + + public int getWidth() + { + return this.width; + } + + public int getHeight() + { + return this.height; + } + + public abstract void render(MatrixStack paramMatrixStack, float paramFloat); +} \ No newline at end of file diff --git a/src/main/java/magistu/siegemachines/gui/MachineContainer.java b/src/main/java/magistu/siegemachines/gui/MachineContainer.java new file mode 100644 index 0000000..543767b --- /dev/null +++ b/src/main/java/magistu/siegemachines/gui/MachineContainer.java @@ -0,0 +1,137 @@ +package magistu.siegemachines.gui; + +import magistu.siegemachines.entity.machine.Machine; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.container.Container; +import net.minecraft.inventory.container.Slot; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraft.world.World; +import net.minecraftforge.items.IItemHandler; +import org.jetbrains.annotations.NotNull; + +import java.util.Objects; + +public class MachineContainer extends Container +{ + private final int containersize; + private final Machine machine; + + public MachineContainer(final int id, final PlayerInventory inv, final Machine machine) + { + super(ContainerTypes.MACHINE_CONTAINER.get(), id); + this.containersize = machine.inventory.getContainerSize(); + this.machine = machine; + + for (int row = 0; row < 3; row++) + { + for (int col = 0; col < 9; col++) + { + this.addSlot(new Slot(inv, col + row * 9 + 9, 8 + col * 18, 166 - (4 - row) * 18 - 10)); + } + } + + for (int col = 0; col < 9; col++) + { + this.addSlot(new Slot(inv, col, 8 + col * 18, 142)); + } + + int n = 0; + int col_size = (int) Math.ceil((double)this.containersize / 9); + for (int row = 0; row < col_size; row++) + { + for (int col = 0; col < 9 && n < this.containersize; col++) + { + this.addSlot(new Slot(machine.inventory, col + row * 9, 8 + col * 18, 18 + row * 18)); + n++; + } + } + } + + public MachineContainer(final int id, final PlayerInventory inv, final PacketBuffer data) + { + this(id, inv, getMachine(inv)); + } + + private static Machine getMachine(final PlayerInventory inv) + { + Objects.requireNonNull(inv, "Player Inventory Cannot Be Null."); + PlayerEntity player = inv.player; + Entity entity; + if (player.isPassenger()) + { + entity = player.getVehicle(); + if (entity instanceof Machine) + { + return (Machine) player.getVehicle(); + } + } + + throw new IllegalStateException("Entity Is Not Correct."); + } + + @Override + public boolean stillValid(PlayerEntity player) + { + return machine.inventory.stillValid(player); + } + + @Override + public @NotNull ItemStack quickMoveStack(@NotNull PlayerEntity player, int index) + { + ItemStack itemstack = ItemStack.EMPTY; + Slot slot = this.slots.get(index); + if (slot != null && slot.hasItem()) + { + ItemStack itemstack1 = slot.getItem(); + itemstack = itemstack1.copy(); + if (index < 9) + { + if (!this.moveItemStackTo(itemstack1, 9, this.slots.size(), true)) + { + return ItemStack.EMPTY; + } + slot.onQuickCraft(itemstack1, itemstack); + } + else if (!this.moveItemStackTo(itemstack1, 0, 9, false)) + { + if (index < 9 + 27) + { + if (!this.moveItemStackTo(itemstack1, 9 + 27, this.slots.size(), true)) + { + return ItemStack.EMPTY; + } + } + else + { + if (!this.moveItemStackTo(itemstack1, 9, 9 + 27, false)) + { + return ItemStack.EMPTY; + } + } + return ItemStack.EMPTY; + } + if (itemstack1.getCount() == 0) + { + slot.set(ItemStack.EMPTY); + } + else + { + slot.setChanged(); + } + if (itemstack1.getCount() == itemstack.getCount()) + { + return ItemStack.EMPTY; + } + slot.onTake(player, itemstack1); + } + return itemstack; + } + + public int getContainerSize() + { + return this.containersize; + } +} diff --git a/src/main/java/magistu/siegemachines/gui/MachineInventoryScreen.java b/src/main/java/magistu/siegemachines/gui/MachineInventoryScreen.java new file mode 100644 index 0000000..6f93a71 --- /dev/null +++ b/src/main/java/magistu/siegemachines/gui/MachineInventoryScreen.java @@ -0,0 +1,81 @@ +package magistu.siegemachines.gui; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; +import magistu.siegemachines.SiegeMachines; +import net.minecraft.client.gui.screen.inventory.ContainerScreen; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.ITextComponent; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.api.distmarker.Dist; +import org.jetbrains.annotations.NotNull; + +@OnlyIn(Dist.CLIENT) +public class MachineInventoryScreen extends ContainerScreen +{ + private final ResourceLocation displaceCaseGui; + + public MachineInventoryScreen(MachineContainer container, PlayerInventory inv, ITextComponent titleIn) + { + super(container, inv, titleIn); + + this.leftPos = 0; + this.topPos = 0; + this.imageWidth = 176; + this.imageHeight = 166; + switch (container.getContainerSize()) + { + case 18: + this.displaceCaseGui = new ResourceLocation(SiegeMachines.ID, "textures/gui/machine_inventory_2.png"); + break; + case 27: + this.displaceCaseGui = new ResourceLocation(SiegeMachines.ID, "textures/gui/machine_inventory_3.png"); + break; + default: + this.displaceCaseGui = new ResourceLocation(SiegeMachines.ID, "textures/gui/machine_inventory_1.png"); + break; + } + } + + @Override + public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) + { + this.renderBackground(matrixStack); + super.render(matrixStack, mouseX, mouseY, partialTicks); + this.renderTooltip(matrixStack, mouseX, mouseY); + } + + @Override + protected void renderTooltip(@NotNull MatrixStack matrixStack, int x, int y) + { + if (this.minecraft.player.inventory.getCarried().isEmpty() && this.hoveredSlot != null && this.hoveredSlot.hasItem()) + { + this.renderTooltip(matrixStack, this.hoveredSlot.getItem(), x, y); + } + } + + @SuppressWarnings("deprecation") + @Override + protected void renderBg(@NotNull MatrixStack matrixStack, float partialTicks, int mouseX, int mouseY) + { + RenderSystem.color4f(1f, 1f, 1f, 1f); + assert this.minecraft != null; + this.minecraft.textureManager.bind(this.displaceCaseGui); + int x = (this.width - this.imageWidth) / 2; + int y = (this.height - this.imageHeight) / 2; + this.blit(matrixStack, x, y, 0, 0, this.imageWidth, this.imageHeight); + } + + @Override + public boolean keyPressed(int key, int b, int c) + { + assert this.minecraft != null; + if (key == 256) + { + this.minecraft.player.closeContainer(); + return true; + } + return super.keyPressed(key, b, c); + } +} diff --git a/src/main/java/magistu/siegemachines/gui/ReloadingCrosshair.java b/src/main/java/magistu/siegemachines/gui/ReloadingCrosshair.java new file mode 100644 index 0000000..20f193c --- /dev/null +++ b/src/main/java/magistu/siegemachines/gui/ReloadingCrosshair.java @@ -0,0 +1,67 @@ +package magistu.siegemachines.gui; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; +import magistu.siegemachines.entity.machine.Machine; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; + +@OnlyIn(Dist.CLIENT) +public class ReloadingCrosshair extends Crosshair +{ + //public static ResourceLocation TYPE = new ResourceLocation(SiegeMachines.ID, "siege_machine"); + public int x; + public int y; + + public ReloadingCrosshair() + { + super(9, 9); + this.x = Minecraft.getInstance().getWindow().getGuiScaledWidth() / 2; + this.y = Minecraft.getInstance().getWindow().getGuiScaledHeight() / 2; + } + + public void render(MatrixStack matrixstack, float ticks, Minecraft mc, PlayerEntity player) + { + RenderSystem.assertThread(RenderSystem::isOnRenderThread); + + if (!player.isPassenger()) + { + return; + } + Entity entity = player.getVehicle(); + + if (entity instanceof Machine) + { + Machine machine = (Machine) entity; + + int width = 11; + int height = 11; + int imagex = 0; + int imagey = 0; + int originx = (mc.getWindow().getGuiScaledWidth() - width) / 2; + int originy = (mc.getWindow().getGuiScaledHeight() - height) / 2; + int animationsize = 23; + if (machine.useticks > 0) + { + imagey = height; + } + else if (machine.delayticks > 0) + { + int number = (int) (((double) animationsize) * ((double) (machine.type.specs.delaytime.get() - machine.delayticks) / (double) machine.type.specs.delaytime.get())); + imagex = width; + imagey = height * number; + } + + RenderSystem.pushMatrix(); + + mc.getTextureManager().bind(CROSSHAIR_TEXTURES); + + mc.gui.blit(matrixstack, originx, originy, imagex, imagey, width, height); + + RenderSystem.popMatrix(); + } + } +} \ No newline at end of file diff --git a/src/main/java/magistu/siegemachines/gui/SiegeWorkbenchContainer.java b/src/main/java/magistu/siegemachines/gui/SiegeWorkbenchContainer.java new file mode 100644 index 0000000..3add138 --- /dev/null +++ b/src/main/java/magistu/siegemachines/gui/SiegeWorkbenchContainer.java @@ -0,0 +1,615 @@ +package magistu.siegemachines.gui; + +import com.google.common.collect.Sets; +import magistu.siegemachines.block.ModBlocks; +import magistu.siegemachines.data.recipes.ModRecipes; +import magistu.siegemachines.data.recipes.SiegeWorkbenchRecipe; +import net.minecraft.crash.CrashReport; +import net.minecraft.crash.CrashReportCategory; +import net.minecraft.crash.ReportedException; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.inventory.CraftResultInventory; +import net.minecraft.inventory.CraftingInventory; +import net.minecraft.inventory.IInventory; +import net.minecraft.inventory.container.*; +import net.minecraft.item.ItemStack; +import net.minecraft.item.crafting.IRecipe; +import net.minecraft.item.crafting.IRecipeType; +import net.minecraft.network.PacketBuffer; +import net.minecraft.network.play.server.SSetSlotPacket; +import net.minecraft.util.IWorldPosCallable; +import net.minecraft.util.NonNullList; +import net.minecraft.util.Util; +import net.minecraft.world.World; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import org.jetbrains.annotations.NotNull; + +import java.util.Optional; +import java.util.Set; + +public class SiegeWorkbenchContainer extends Container +{ + private final CraftingInventory craftSlots = new CraftingInventory(this, 3, 3); + private final CraftResultInventory resultSlots = new CraftResultInventory(); + private final IWorldPosCallable access; + private final PlayerEntity player; + + private int quickcraftType = -1; + private int quickcraftStatus; + private final Set quickcraftSlots = Sets.newHashSet(); + + public SiegeWorkbenchContainer(int p_i50089_1_, PlayerInventory p_i50089_2_, PacketBuffer buffer) + { + this(p_i50089_1_, p_i50089_2_, IWorldPosCallable.NULL); + } + + public SiegeWorkbenchContainer(int p_i50090_1_, PlayerInventory p_i50090_2_, IWorldPosCallable p_i50090_3_) + { + super(ContainerTypes.SIEGE_WORKBENCH_CONTAINER.get(), p_i50090_1_); + this.access = p_i50090_3_; + this.player = p_i50090_2_.player; + this.addSlot(new CraftingResultSlot(p_i50090_2_.player, this.craftSlots, this.resultSlots, 0, 124, 35)); + + for (int i = 0; i < 3; ++i) + { + for (int j = 0; j < 3; ++j) + { + this.addSlot(new Slot(this.craftSlots, j + i * 3, 30 + j * 18, 17 + i * 18)); + } + } + + for (int k = 0; k < 3; ++k) + { + for (int i1 = 0; i1 < 9; ++i1) + { + this.addSlot(new Slot(p_i50090_2_, i1 + k * 9 + 9, 8 + i1 * 18, 84 + k * 18)); + } + } + + for (int l = 0; l < 9; ++l) + { + this.addSlot(new Slot(p_i50090_2_, l, 8 + l * 18, 142)); + } + + } + + // to create resulting item + protected static void slotChangedCraftingGrid(int p_217066_0_, World p_217066_1_, PlayerEntity p_217066_2_, CraftingInventory p_217066_3_, CraftResultInventory p_217066_4_) + { + if (!p_217066_1_.isClientSide) + { + ServerPlayerEntity serverplayerentity = (ServerPlayerEntity) p_217066_2_; + ItemStack itemstack = ItemStack.EMPTY; + Optional optional = p_217066_1_.getServer().getRecipeManager().getRecipeFor(ModRecipes.SIEGE_WORKBENCH_RECIPE, p_217066_3_, p_217066_1_); + if (optional.isPresent()) + { + SiegeWorkbenchRecipe icraftingrecipe = optional.get(); + if (p_217066_4_.setRecipeUsed(p_217066_1_, serverplayerentity, icraftingrecipe)) + { + itemstack = icraftingrecipe.assemble(p_217066_3_); + } + } + + p_217066_4_.setItem(0, itemstack); + serverplayerentity.connection.send(new SSetSlotPacket(p_217066_0_, 0, itemstack)); + } + } + + @Override + public void slotsChanged(@NotNull IInventory p_75130_1_) + { + this.access.execute((p_217069_1_, p_217069_2_) -> slotChangedCraftingGrid(this.containerId, p_217069_1_, this.player, this.craftSlots, this.resultSlots)); + } + + @Override + public void removed(@NotNull PlayerEntity p_75134_1_) + { + super.removed(p_75134_1_); + this.access.execute((p_217068_2_, p_217068_3_) -> this.clearContainer(p_75134_1_, p_217068_2_, this.craftSlots)); + } + + @Override + public boolean stillValid(PlayerEntity p_75145_1_) + { + return stillValid(this.access, p_75145_1_, ModBlocks.SIEGE_WORKBENCH.get()); + } + + + public ItemStack onTakeFromSlot(Slot slot, PlayerEntity p_190901_1_, ItemStack p_190901_2_) + { + if (slot instanceof CraftingResultSlot) + { + return this.onCraft(p_190901_1_, p_190901_2_); + } + return slot.onTake(p_190901_1_, p_190901_2_); + } + + public > NonNullList getRemainingItemsFor(IRecipeType p_215369_1_, C p_215369_2_, World p_215369_3_) + { + Optional optional = p_215369_3_.getRecipeManager().getRecipeFor(p_215369_1_, p_215369_2_, p_215369_3_); + if (optional.isPresent()) + { + return optional.get().getRemainingItems(p_215369_2_); + } + else + { + NonNullList nonnulllist = NonNullList.withSize(p_215369_2_.getContainerSize(), ItemStack.EMPTY); + for (int i = 0; i < nonnulllist.size(); ++i) + { + nonnulllist.set(i, p_215369_2_.getItem(i)); + } + + return nonnulllist; + } + } + + public ItemStack onCraft(PlayerEntity p_190901_1_, ItemStack p_190901_2_) + { + //slot.checkTakeAchievements(p_190901_2_); + net.minecraftforge.common.ForgeHooks.setCraftingPlayer(p_190901_1_); + NonNullList nonnulllist = this.getRemainingItemsFor(IRecipeType.CRAFTING, this.craftSlots, p_190901_1_.level); + net.minecraftforge.common.ForgeHooks.setCraftingPlayer(null); + for(int i = 0; i < nonnulllist.size(); ++i) + { + ItemStack itemstack = this.craftSlots.getItem(i); + ItemStack itemstack1 = nonnulllist.get(i); + if (!itemstack.isEmpty()) + { + this.craftSlots.removeItem(i, 64); + itemstack = this.craftSlots.getItem(i); + } + + if (!itemstack1.isEmpty()) + { + if (itemstack.isEmpty()) + { + this.craftSlots.setItem(i, itemstack1); + } + else if (ItemStack.isSame(itemstack, itemstack1) && ItemStack.tagMatches(itemstack, itemstack1)) + { + itemstack1.grow(itemstack.getCount()); + this.craftSlots.setItem(i, itemstack1); + } + else if (!this.player.inventory.add(itemstack1)) + { + this.player.drop(itemstack1, false); + } + } + } + + return p_190901_2_; + } + + @Override + public @NotNull ItemStack quickMoveStack(PlayerEntity p_82846_1_, int p_82846_2_) + { + ItemStack itemstack = ItemStack.EMPTY; + Slot slot = this.slots.get(p_82846_2_); + if (slot != null && slot.hasItem()) + { + ItemStack itemstack1 = slot.getItem(); + itemstack = itemstack1.copy(); + if (p_82846_2_ == 0) + { + this.access.execute((p_217067_2_, p_217067_3_) -> itemstack1.getItem().onCraftedBy(itemstack1, p_217067_2_, p_82846_1_)); + if (!this.moveItemStackTo(itemstack1, 10, 46, true)) + { + return ItemStack.EMPTY; + } + + slot.onQuickCraft(itemstack1, itemstack); + } + else if (p_82846_2_ >= 10 && p_82846_2_ < 46) + { + if (!this.moveItemStackTo(itemstack1, 1, 10, false)) + { + if (p_82846_2_ < 37) + { + if (!this.moveItemStackTo(itemstack1, 37, 46, false)) + { + return ItemStack.EMPTY; + } + } + else if (!this.moveItemStackTo(itemstack1, 10, 37, false)) + { + return ItemStack.EMPTY; + } + } + } + else if (!this.moveItemStackTo(itemstack1, 10, 46, false)) + { + return ItemStack.EMPTY; + } + + if (itemstack1.isEmpty()) + { + slot.set(ItemStack.EMPTY); + } + else + { + slot.setChanged(); + } + + if (itemstack1.getCount() == itemstack.getCount()) + { + return ItemStack.EMPTY; + } + + ItemStack itemstack2 = onTakeFromSlot(slot, p_82846_1_, itemstack1); + if (p_82846_2_ == 0) + { + p_82846_1_.drop(itemstack2, false); + } + } + + return itemstack; + } + + public boolean canTakeItemForPickAll(ItemStack p_94530_1_, Slot p_94530_2_) + { + return p_94530_2_.container != this.resultSlots && super.canTakeItemForPickAll(p_94530_1_, p_94530_2_); + } + + @OnlyIn(Dist.CLIENT) + public int getSize() + { + return 10; + } + + @Override + public @NotNull ItemStack clicked(int p_184996_1_, int p_184996_2_, ClickType p_184996_3_, PlayerEntity p_184996_4_) + { + try + { + ItemStack result = this.doClick(p_184996_1_, p_184996_2_, p_184996_3_, p_184996_4_); + this.slotsChanged(this.craftSlots); + this.slotsChanged(this.resultSlots); + return result; + } + catch (Exception exception) + { + CrashReport crashreport = CrashReport.forThrowable(exception, "Container click"); + CrashReportCategory crashreportcategory = crashreport.addCategory("Click info"); + crashreportcategory.setDetail("Menu Class", () -> this.getClass().getCanonicalName()); + crashreportcategory.setDetail("Slot Count", this.slots.size()); + crashreportcategory.setDetail("Slot", p_184996_1_); + crashreportcategory.setDetail("Button", p_184996_2_); + crashreportcategory.setDetail("Type", p_184996_3_); + throw new ReportedException(crashreport); + } + } + + @Override + protected void resetQuickCraft() + { + this.quickcraftStatus = 0; + this.quickcraftSlots.clear(); + } + + private ItemStack doClick(int index1, int index2, ClickType clicktype, PlayerEntity player) + { + ItemStack itemstack = ItemStack.EMPTY; + PlayerInventory playerinventory = player.inventory; + if (clicktype == ClickType.QUICK_CRAFT) + { + int i1 = this.quickcraftStatus; + this.quickcraftStatus = getQuickcraftHeader(index2); + if ((i1 != 1 || this.quickcraftStatus != 2) && i1 != this.quickcraftStatus) + { + this.resetQuickCraft(); + } + else if (playerinventory.getCarried().isEmpty()) + { + this.resetQuickCraft(); + } + else if (this.quickcraftStatus == 0) + { + this.quickcraftType = getQuickcraftType(index2); + if (isValidQuickcraftType(this.quickcraftType, player)) + { + this.quickcraftStatus = 1; + this.quickcraftSlots.clear(); + } + else + { + this.resetQuickCraft(); + } + } + else if (this.quickcraftStatus == 1) + { + Slot slot7 = this.slots.get(index1); + ItemStack itemstack12 = playerinventory.getCarried(); + if (slot7 != null && canItemQuickReplace(slot7, itemstack12, true) && slot7.mayPlace(itemstack12) && (this.quickcraftType == 2 || itemstack12.getCount() > this.quickcraftSlots.size()) && this.canDragTo(slot7)) + { + this.quickcraftSlots.add(slot7); + } + } + else if (this.quickcraftStatus == 2) + { + if (!this.quickcraftSlots.isEmpty()) + { + ItemStack itemstack10 = playerinventory.getCarried().copy(); + int k1 = playerinventory.getCarried().getCount(); + + for(Slot slot8 : this.quickcraftSlots) + { + ItemStack itemstack13 = playerinventory.getCarried(); + if (slot8 != null && canItemQuickReplace(slot8, itemstack13, true) && slot8.mayPlace(itemstack13) && (this.quickcraftType == 2 || itemstack13.getCount() >= this.quickcraftSlots.size()) && this.canDragTo(slot8)) + { + ItemStack itemstack14 = itemstack10.copy(); + int j3 = slot8.hasItem() ? slot8.getItem().getCount() : 0; + getQuickCraftSlotCount(this.quickcraftSlots, this.quickcraftType, itemstack14, j3); + int k3 = Math.min(itemstack14.getMaxStackSize(), slot8.getMaxStackSize(itemstack14)); + if (itemstack14.getCount() > k3) + { + itemstack14.setCount(k3); + } + + k1 -= itemstack14.getCount() - j3; + slot8.set(itemstack14); + } + } + + itemstack10.setCount(k1); + playerinventory.setCarried(itemstack10); + } + + this.resetQuickCraft(); + } + else + { + this.resetQuickCraft(); + } + } + else if (this.quickcraftStatus != 0) + { + this.resetQuickCraft(); + } + else if ((clicktype == ClickType.PICKUP || clicktype == ClickType.QUICK_MOVE) && (index2 == 0 || index2 == 1)) + { + if (index1 == -999) + { + if (!playerinventory.getCarried().isEmpty()) + { + if (index2 == 0) + { + player.drop(playerinventory.getCarried(), true); + playerinventory.setCarried(ItemStack.EMPTY); + } + + if (index2 == 1) + { + player.drop(playerinventory.getCarried().split(1), true); + } + } + } + else if (clicktype == ClickType.QUICK_MOVE) + { + if (index1 < 0) + { + return ItemStack.EMPTY; + } + + Slot slot5 = this.slots.get(index1); + if (slot5 == null || !slot5.mayPickup(player)) + { + return ItemStack.EMPTY; + } + + for(ItemStack itemstack8 = this.quickMoveStack(player, index1); !itemstack8.isEmpty() && ItemStack.isSame(slot5.getItem(), itemstack8); itemstack8 = this.quickMoveStack(player, index1)) + { + itemstack = itemstack8.copy(); + } + } + else + { + if (index1 < 0) + { + return ItemStack.EMPTY; + } + + Slot slot6 = this.slots.get(index1); + if (slot6 != null) + { + ItemStack itemstack9 = slot6.getItem(); + ItemStack itemstack11 = playerinventory.getCarried(); + if (!itemstack9.isEmpty()) + { + itemstack = itemstack9.copy(); + } + + if (itemstack9.isEmpty()) + { + if (!itemstack11.isEmpty() && slot6.mayPlace(itemstack11)) + { + int j2 = index2 == 0 ? itemstack11.getCount() : 1; + if (j2 > slot6.getMaxStackSize(itemstack11)) + { + j2 = slot6.getMaxStackSize(itemstack11); + } + + slot6.set(itemstack11.split(j2)); + } + } + else if (slot6.mayPickup(player)) + { + if (itemstack11.isEmpty()) + { + if (itemstack9.isEmpty()) + { + slot6.set(ItemStack.EMPTY); + playerinventory.setCarried(ItemStack.EMPTY); + } + else + { + int k2 = index2 == 0 ? itemstack9.getCount() : (itemstack9.getCount() + 1) / 2; + playerinventory.setCarried(slot6.remove(k2)); + if (itemstack9.isEmpty()) + { + slot6.set(ItemStack.EMPTY); + } + + onTakeFromSlot(slot6, player, playerinventory.getCarried()); + } + } + else if (slot6.mayPlace(itemstack11)) + { + if (consideredTheSameItem(itemstack9, itemstack11)) + { + int l2 = index2 == 0 ? itemstack11.getCount() : 1; + if (l2 > slot6.getMaxStackSize(itemstack11) - itemstack9.getCount()) + { + l2 = slot6.getMaxStackSize(itemstack11) - itemstack9.getCount(); + } + + if (l2 > itemstack11.getMaxStackSize() - itemstack9.getCount()) + { + l2 = itemstack11.getMaxStackSize() - itemstack9.getCount(); + } + itemstack11.shrink(l2); + itemstack9.grow(l2); + } + else if (itemstack11.getCount() <= slot6.getMaxStackSize(itemstack11)) + { + slot6.set(itemstack11); + playerinventory.setCarried(itemstack9); + } + } + else if (itemstack11.getMaxStackSize() > 1 && consideredTheSameItem(itemstack9, itemstack11) && !itemstack9.isEmpty()) + { + int i3 = itemstack9.getCount(); + if (i3 + itemstack11.getCount() <= itemstack11.getMaxStackSize()) + { + itemstack11.grow(i3); + itemstack9 = slot6.remove(i3); + if (itemstack9.isEmpty()) + { + slot6.set(ItemStack.EMPTY); + } + + onTakeFromSlot(slot6, player, playerinventory.getCarried()); + } + } + } + + slot6.setChanged(); + } + } + } + else if (clicktype == ClickType.SWAP) + { + Slot slot = this.slots.get(index1); + ItemStack itemstack1 = playerinventory.getItem(index2); + ItemStack itemstack2 = slot.getItem(); + if (!itemstack1.isEmpty() || !itemstack2.isEmpty()) + { + if (itemstack1.isEmpty()) + { + if (slot.mayPickup(player)) + { + playerinventory.setItem(index2, itemstack2); + //slot.onSwapCraft(itemstack2.getCount()); + slot.set(ItemStack.EMPTY); + onTakeFromSlot(slot, player, itemstack2); + } + } + else if (itemstack2.isEmpty()) + { + if (slot.mayPlace(itemstack1)) + { + int i = slot.getMaxStackSize(itemstack1); + if (itemstack1.getCount() > i) + { + slot.set(itemstack1.split(i)); + } + else + { + slot.set(itemstack1); + playerinventory.setItem(index2, ItemStack.EMPTY); + } + } + } + else if (slot.mayPickup(player) && slot.mayPlace(itemstack1)) + { + int l1 = slot.getMaxStackSize(itemstack1); + if (itemstack1.getCount() > l1) + { + slot.set(itemstack1.split(l1)); + onTakeFromSlot(slot, player, itemstack2); + if (!playerinventory.add(itemstack2)) + { + player.drop(itemstack2, true); + } + } + else + { + slot.set(itemstack1); + playerinventory.setItem(index2, itemstack2); + onTakeFromSlot(slot, player, itemstack2); + } + } + } + } + else if (clicktype == ClickType.CLONE && player.abilities.instabuild && playerinventory.getCarried().isEmpty() && index1 >= 0) + { + Slot slot4 = this.slots.get(index1); + if (slot4 != null && slot4.hasItem()) + { + ItemStack itemstack7 = slot4.getItem().copy(); + itemstack7.setCount(itemstack7.getMaxStackSize()); + playerinventory.setCarried(itemstack7); + } + } + else if (clicktype == ClickType.THROW && playerinventory.getCarried().isEmpty() && index1 >= 0) + { + Slot slot3 = this.slots.get(index1); + if (slot3 != null && slot3.hasItem() && slot3.mayPickup(player)) + { + ItemStack itemstack6 = slot3.remove(index2 == 0 ? 1 : slot3.getItem().getCount()); + onTakeFromSlot(slot3, player, itemstack6); + player.drop(itemstack6, true); + } + } + else if (clicktype == ClickType.PICKUP_ALL && index1 >= 0) + { + Slot slot2 = this.slots.get(index1); + ItemStack itemstack5 = playerinventory.getCarried(); + if (!itemstack5.isEmpty() && (slot2 == null || !slot2.hasItem() || !slot2.mayPickup(player))) + { + int j1 = index2 == 0 ? 0 : this.slots.size() - 1; + int i2 = index2 == 0 ? 1 : -1; + + for(int j = 0; j < 2; ++j) + { + for(int k = j1; k >= 0 && k < this.slots.size() && itemstack5.getCount() < itemstack5.getMaxStackSize(); k += i2) + { + Slot slot1 = this.slots.get(k); + if (slot1.hasItem() && canItemQuickReplace(slot1, itemstack5, true) && slot1.mayPickup(player) && this.canTakeItemForPickAll(itemstack5, slot1)) + { + ItemStack itemstack3 = slot1.getItem(); + if (j != 0 || itemstack3.getCount() != itemstack3.getMaxStackSize()) + { + int l = Math.min(itemstack5.getMaxStackSize() - itemstack5.getCount(), itemstack3.getCount()); + ItemStack itemstack4 = slot1.remove(l); + itemstack5.grow(l); + if (itemstack4.isEmpty()) + { + slot1.set(ItemStack.EMPTY); + } + + onTakeFromSlot(slot1, player, itemstack4); + } + } + } + } + } + + this.broadcastChanges(); + } + + return itemstack; + } +} diff --git a/src/main/java/magistu/siegemachines/gui/SiegeWorkbenchScreen.java b/src/main/java/magistu/siegemachines/gui/SiegeWorkbenchScreen.java new file mode 100644 index 0000000..ebb8724 --- /dev/null +++ b/src/main/java/magistu/siegemachines/gui/SiegeWorkbenchScreen.java @@ -0,0 +1,75 @@ +package magistu.siegemachines.gui; + +import com.mojang.blaze3d.matrix.MatrixStack; +import com.mojang.blaze3d.systems.RenderSystem; +import magistu.siegemachines.SiegeMachines; +import net.minecraft.client.gui.screen.inventory.ContainerScreen; +import net.minecraft.client.gui.widget.button.ImageButton; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.container.WorkbenchContainer; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.text.ITextComponent; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import org.jetbrains.annotations.NotNull; + +@OnlyIn(Dist.CLIENT) +public class SiegeWorkbenchScreen extends ContainerScreen +{ + private static final ResourceLocation DISPLAY_CASE_GUI = new ResourceLocation(SiegeMachines.ID, + "textures/gui/siege_workbench.png"); + + public SiegeWorkbenchScreen(SiegeWorkbenchContainer screenContainer, PlayerInventory inv, ITextComponent titleIn) + { + super(screenContainer, inv, titleIn); + } + + @Override + public void render(MatrixStack matrixStack, int mouseX, int mouseY, float partialTicks) + { + this.renderBackground(matrixStack); + super.render(matrixStack, mouseX, mouseY, partialTicks); + this.renderTooltip(matrixStack, mouseX, mouseY); + } + + @Override + protected void renderTooltip(@NotNull MatrixStack matrixStack, int x, int y) + { + if (this.minecraft.player.inventory.getCarried().isEmpty() && this.hoveredSlot != null && this.hoveredSlot.hasItem()) + { + this.renderTooltip(matrixStack, this.hoveredSlot.getItem(), x, y); + } + } + + @Override + protected void init() + { + super.init(); + this.titleLabelX = 29; + } + + @SuppressWarnings("deprecation") + @Override + protected void renderBg(@NotNull MatrixStack matrixStack, float partialTicks, int mouseX, int mouseY) + { + RenderSystem.color4f(1.0F, 1.0F, 1.0F, 1.0F); + assert this.minecraft != null; + this.minecraft.getTextureManager().bind(DISPLAY_CASE_GUI); + int i = this.leftPos; + int j = (this.height - this.imageHeight) / 2; + this.blit(matrixStack, i, j, 0, 0, this.imageWidth, this.imageHeight); + } + + @Override + public boolean keyPressed(int key, int b, int c) + { + assert this.minecraft != null; + if (key == 256) + { + assert this.minecraft.player != null; + this.minecraft.player.closeContainer(); + return true; + } + return super.keyPressed(key, b, c); + } +} diff --git a/src/main/java/magistu/siegemachines/item/MachineItem.java b/src/main/java/magistu/siegemachines/item/MachineItem.java new file mode 100644 index 0000000..68eab29 --- /dev/null +++ b/src/main/java/magistu/siegemachines/item/MachineItem.java @@ -0,0 +1,272 @@ +package magistu.siegemachines.item; + +import magistu.siegemachines.SiegeMachines; +import magistu.siegemachines.entity.EntityTypes; +import magistu.siegemachines.entity.machine.Machine; +import magistu.siegemachines.entity.machine.MachineType; +import magistu.siegemachines.entity.projectile.ProjectileBuilder; +import net.minecraft.block.BlockState; +import net.minecraft.block.Blocks; +import net.minecraft.block.FlowingFluidBlock; +import net.minecraft.client.util.ITooltipFlag; +import net.minecraft.entity.*; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.ItemUseContext; +import net.minecraft.nbt.CompoundNBT; +import net.minecraft.stats.Stats; +import net.minecraft.tileentity.MobSpawnerTileEntity; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.ActionResult; +import net.minecraft.util.ActionResultType; +import net.minecraft.util.Direction; +import net.minecraft.util.Hand; +import net.minecraft.util.math.*; +import net.minecraft.util.math.shapes.VoxelShape; +import net.minecraft.util.math.shapes.VoxelShapes; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.StringTextComponent; +import net.minecraft.util.text.TextFormatting; +import net.minecraft.util.text.TranslationTextComponent; +import net.minecraft.world.IWorldReader; +import net.minecraft.world.World; +import net.minecraft.world.server.ServerWorld; +import net.minecraft.world.spawner.AbstractSpawner; +import org.jetbrains.annotations.NotNull; +import software.bernie.geckolib3.core.IAnimatable; +import software.bernie.geckolib3.core.manager.AnimationData; +import software.bernie.geckolib3.core.manager.AnimationFactory; + +import javax.annotation.Nullable; +import java.util.List; +import java.util.Locale; +import java.util.Objects; +import java.util.stream.Stream; + +public class MachineItem extends Item implements IAnimatable +{ + private final AnimationFactory factory = new AnimationFactory(this); + + private final String entitykey; + private final String typekey; + + public MachineItem(Item.Properties prop, String entitykey, String typekey) + { + super(prop.stacksTo(1)); + this.entitykey = entitykey; + this.typekey = typekey; + } + + @Override + public void appendHoverText(@NotNull ItemStack stack, @Nullable World worldIn, List tooltip, ITooltipFlag flagIn) + { + ProjectileBuilder[] ammo = MachineType.valueOf(this.typekey).ammo; + if (ammo.length > 0) + { + tooltip.add(new TranslationTextComponent(SiegeMachines.ID + ".ammo").withStyle(TextFormatting.BLUE)); + for (ProjectileBuilder builder : ammo) + { + if (MachineType.valueOf(this.typekey).usesgunpowder) + { + tooltip.add(new StringTextComponent("Uses gunpowder").withStyle(TextFormatting.BLUE)); + } + tooltip.add(new StringTextComponent(" ").append(new TranslationTextComponent(builder.item.getDescriptionId())).withStyle(TextFormatting.BLUE)); + } + } + } + + @Override + public @NotNull ActionResultType useOn(ItemUseContext p_195939_1_) + { + World world = p_195939_1_.getLevel(); + if (!(world instanceof ServerWorld)) + { + return ActionResultType.SUCCESS; + } + else + { + ItemStack itemstack = p_195939_1_.getItemInHand(); + BlockPos blockpos = p_195939_1_.getClickedPos(); + Direction direction = p_195939_1_.getClickedFace(); + BlockState blockstate = world.getBlockState(blockpos); + if (blockstate.is(Blocks.SPAWNER)) + { + TileEntity tileentity = world.getBlockEntity(blockpos); + if (tileentity instanceof MobSpawnerTileEntity) + { + AbstractSpawner abstractspawner = ((MobSpawnerTileEntity)tileentity).getSpawner(); + EntityType entitytype1 = this.getType(itemstack.getTag()); + abstractspawner.setEntityId(entitytype1); + tileentity.setChanged(); + world.sendBlockUpdated(blockpos, blockstate, blockstate, 3); + itemstack.shrink(1); + return ActionResultType.CONSUME; + } + } + + BlockPos blockpos1; + if (blockstate.getCollisionShape(world, blockpos).isEmpty()) + { + blockpos1 = blockpos; + } + else + { + blockpos1 = blockpos.relative(direction); + } + + EntityType entitytype = this.getType(itemstack.getTag()); + Entity entity = this.spawn(entitytype, (ServerWorld)world, itemstack, p_195939_1_.getPlayer(), blockpos1, SpawnReason.SPAWN_EGG, true, !Objects.equals(blockpos, blockpos1) && direction == Direction.UP, p_195939_1_.getRotation()); + + if (entity instanceof Machine) + { + ((Machine)entity).deploymentticks = 200; + } + if (entity != null) + { + itemstack.shrink(1); + } + + return ActionResultType.CONSUME; + } + } + + protected static double getYOffset(IWorldReader p_208051_0_, BlockPos p_208051_1_, boolean p_208051_2_, AxisAlignedBB p_208051_3_) { + AxisAlignedBB axisalignedbb = new AxisAlignedBB(p_208051_1_); + if (p_208051_2_) { + axisalignedbb = axisalignedbb.expandTowards(0.0D, -1.0D, 0.0D); + } + + Stream stream = p_208051_0_.getCollisions((Entity)null, axisalignedbb, (p_233596_0_) -> { + return true; + }); + return 1.0D + VoxelShapes.collide(Direction.Axis.Y, p_208051_3_, stream, p_208051_2_ ? -2.0D : -1.0D); + } + + @Nullable + public Entity spawn(EntityType entitytype, ServerWorld p_220331_1_, @Nullable ItemStack p_220331_2_, @Nullable PlayerEntity p_220331_3_, BlockPos p_220331_4_, SpawnReason p_220331_5_, boolean p_220331_6_, boolean p_220331_7_, float yaw) { + return this.spawn(entitytype, p_220331_1_, p_220331_2_ == null ? null : p_220331_2_.getTag(), p_220331_2_ != null && p_220331_2_.hasCustomHoverName() ? p_220331_2_.getHoverName() : null, p_220331_3_, p_220331_4_, p_220331_5_, p_220331_6_, p_220331_7_, yaw); + } + + @Nullable + public Entity spawn(EntityType entitytype, ServerWorld p_220342_1_, @Nullable CompoundNBT p_220342_2_, @Nullable ITextComponent p_220342_3_, @Nullable PlayerEntity p_220342_4_, BlockPos p_220342_5_, SpawnReason p_220342_6_, boolean p_220342_7_, boolean p_220342_8_, float yaw) { + Entity t = this.create(entitytype, p_220342_1_, p_220342_2_, p_220342_3_, p_220342_4_, p_220342_5_, p_220342_6_, p_220342_7_, p_220342_8_, yaw); + if (t != null) { + if (t instanceof net.minecraft.entity.MobEntity && net.minecraftforge.event.ForgeEventFactory.doSpecialSpawn((net.minecraft.entity.MobEntity) t, p_220342_1_, p_220342_5_.getX(), p_220342_5_.getY(), p_220342_5_.getZ(), null, p_220342_6_)) return null; + p_220342_1_.addFreshEntityWithPassengers(t); + } + + return t; + } + + @Nullable + public Entity create(EntityType entitytype, ServerWorld p_220349_1_, @Nullable CompoundNBT p_220349_2_, @Nullable ITextComponent p_220349_3_, @Nullable PlayerEntity p_220349_4_, BlockPos p_220349_5_, SpawnReason p_220349_6_, boolean p_220349_7_, boolean p_220349_8_, float yaw) { + Entity t = entitytype.create(p_220349_1_); + if (t == null) { + return null; + } else { + double d0; + if (p_220349_7_) { + t.setPos((double)p_220349_5_.getX() + 0.5D, (double)(p_220349_5_.getY() + 1), (double)p_220349_5_.getZ() + 0.5D); + d0 = getYOffset(p_220349_1_, p_220349_5_, p_220349_8_, t.getBoundingBox()); + } else { + d0 = 0.0D; + } + + EntityType.updateCustomEntityTag(p_220349_1_, p_220349_4_, t, p_220349_2_); + + if (p_220349_3_ != null && t instanceof LivingEntity) { + t.setCustomName(p_220349_3_); + } + + t.moveTo((double)p_220349_5_.getX() + 0.5D, (double)p_220349_5_.getY() + d0, (double)p_220349_5_.getZ() + 0.5D, MathHelper.wrapDegrees(yaw), 0.0F); + if (t instanceof MobEntity) { + MobEntity mobentity = (MobEntity)t; + mobentity.yHeadRot = mobentity.yRot; + mobentity.yBodyRot = mobentity.yRot; + mobentity.finalizeSpawn(p_220349_1_, p_220349_1_.getCurrentDifficultyAt(mobentity.blockPosition()), p_220349_6_, (ILivingEntityData)null, p_220349_2_); + mobentity.playAmbientSound(); + } + + return t; + } + } + + @Override + public @NotNull ActionResult use(@NotNull World level, PlayerEntity player, @NotNull Hand hand) + { + ItemStack itemstack = player.getItemInHand(hand); + BlockRayTraceResult raytraceresult = getPlayerPOVHitResult(level, player, RayTraceContext.FluidMode.SOURCE_ONLY); + if (raytraceresult.getType() != RayTraceResult.Type.BLOCK) + { + return ActionResult.pass(itemstack); + } + else if (!(level instanceof ServerWorld)) + { + return ActionResult.success(itemstack); + } + else + { + BlockPos blockpos = raytraceresult.getBlockPos(); + if (!(level.getBlockState(blockpos).getBlock() instanceof FlowingFluidBlock)) + { + return ActionResult.pass(itemstack); + } + else if (level.mayInteract(player, blockpos) && player.mayUseItemAt(blockpos, raytraceresult.getDirection(), itemstack)) + { + EntityType entitytype = this.getType(itemstack.getTag()); + Entity entity = this.spawn(entitytype, (ServerWorld) level, itemstack, player, blockpos, SpawnReason.SPAWN_EGG, false, false, player.yRot); + if (entity instanceof Machine) + { + ((Machine)entity).deploymentticks = 200; + } + if (entity != null) + { + if (!player.isCreative()) + { + itemstack.shrink(1); + } + player.awardStat(Stats.ITEM_USED.get(this)); + return ActionResult.consume(itemstack); + } + else + { + return ActionResult.pass(itemstack); + } + + } + else + { + return ActionResult.fail(itemstack); + } + } + } + + public EntityType getType(@Nullable CompoundNBT nbt) + { + EntityType defaulttype = EntityTypes.DEFERRED_REGISTER.getEntries().stream().filter(r -> r.get().getRegistryName().getPath().equals(this.entitykey)).findFirst().get().get(); + + if (nbt != null && nbt.contains("EntityTag", 10)) + { + CompoundNBT compoundnbt = nbt.getCompound("EntityTag"); + if (compoundnbt.contains("id", 8)) + { + return EntityType.byString(compoundnbt.getString("id")).orElse(defaulttype); + } + } + + return defaulttype; + } + + @Override + public void registerControllers(AnimationData data) + { + + } + + @Override + public AnimationFactory getFactory() + { + return this.factory; + } +} diff --git a/src/main/java/magistu/siegemachines/item/ModItems.java b/src/main/java/magistu/siegemachines/item/ModItems.java new file mode 100644 index 0000000..45c6766 --- /dev/null +++ b/src/main/java/magistu/siegemachines/item/ModItems.java @@ -0,0 +1,59 @@ +package magistu.siegemachines.item; + +import magistu.siegemachines.SiegeMachines; +import magistu.siegemachines.block.ModBlocks; +import magistu.siegemachines.client.renderer.*; +import net.minecraft.block.AbstractBlock; +import net.minecraft.block.CraftingTableBlock; +import net.minecraft.block.SoundType; +import net.minecraft.block.material.Material; +import net.minecraft.item.BlockItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemGroup; +import net.minecraft.item.ItemStack; +import net.minecraftforge.event.RegistryEvent; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.eventbus.api.SubscribeEvent; +import net.minecraftforge.fml.RegistryObject; +import net.minecraftforge.fml.common.Mod; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.IForgeRegistry; +import org.jetbrains.annotations.NotNull; + +@Mod.EventBusSubscriber(bus = Mod.EventBusSubscriber.Bus.MOD) +public class ModItems +{ + public static final ItemGroup GROUP_SM = new ItemGroup(SiegeMachines.ID + ".medieval_siege_machines") + { + public @NotNull ItemStack makeIcon() + { + return new ItemStack(ModItems.MORTAR.get()); + } + }; + + public static final DeferredRegister ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, SiegeMachines.ID); + + public static final RegistryObject MORTAR = ITEMS.register("mortar", () -> new MachineItem(new Item.Properties().tab(ModItems.GROUP_SM).setISTER(() -> MortarItemGeoRenderer::new), "mortar", "MORTAR")); + //public static final RegistryObject CULVERIN = ITEMS.register("culverin", () -> new MachineItem(new Item.Properties().tab(ModItems.GROUP_SM).setISTER(() -> CulverinItemGeoRenderer::new), "culverin", "CULVERIN")); + public static final RegistryObject CATAPULT = ITEMS.register("catapult", () -> new MachineItem(new Item.Properties().tab(ModItems.GROUP_SM).setISTER(() -> CatapultItemGeoRenderer::new), "catapult", "CATAPULT")); + public static final RegistryObject TREBUCHET = ITEMS.register("trebuchet", () -> new MachineItem(new Item.Properties().tab(ModItems.GROUP_SM).setISTER(() -> TrebuchetItemGeoRenderer::new), "trebuchet", "TREBUCHET")); + public static final RegistryObject BALLISTA = ITEMS.register("ballista", () -> new MachineItem(new Item.Properties().tab(ModItems.GROUP_SM).setISTER(() -> BallistaItemGeoRenderer::new), "ballista", "BALLISTA")); + public static final RegistryObject BATTERING_RAM = ITEMS.register("battering_ram", () -> new MachineItem(new Item.Properties().tab(ModItems.GROUP_SM).setISTER(() -> BatteringRamItemGeoRenderer::new), "battering_ram", "BATTERING_RAM")); + + public static final RegistryObject CANNONBALL = ITEMS.register("cannonball", () -> new Item(new Item.Properties().stacksTo(16).tab(ModItems.GROUP_SM))); + public static final RegistryObject STONE = ITEMS.register("stone", () -> new Item(new Item.Properties().stacksTo(16))); + public static final RegistryObject GIANT_STONE = ITEMS.register("giant_stone", () -> new Item(new Item.Properties().stacksTo(16))); + public static final RegistryObject GIANT_ARROW = ITEMS.register("giant_arrow", () -> new Item(new Item.Properties().stacksTo(16).tab(ModItems.GROUP_SM))); + + public static final RegistryObject TURRET_BASE = ITEMS.register("turret_base", () -> new Item(new Item.Properties().tab(ModItems.GROUP_SM))); + public static final RegistryObject BEAM = ITEMS.register("beam", () -> new Item(new Item.Properties().tab(ModItems.GROUP_SM))); + public static final RegistryObject COUNTERWEIGHT = ITEMS.register("counterweight", () -> new Item(new Item.Properties().tab(ModItems.GROUP_SM))); + public static final RegistryObject BARREL = ITEMS.register("barrel", () -> new Item(new Item.Properties().tab(ModItems.GROUP_SM))); + public static final RegistryObject WHEEL = ITEMS.register("wheel", () -> new Item(new Item.Properties().tab(ModItems.GROUP_SM))); + + public static void register(IEventBus eventBus) + { + ITEMS.register(eventBus); + } +} diff --git a/src/main/java/magistu/siegemachines/network/PacketHandler.java b/src/main/java/magistu/siegemachines/network/PacketHandler.java new file mode 100644 index 0000000..c46c9f7 --- /dev/null +++ b/src/main/java/magistu/siegemachines/network/PacketHandler.java @@ -0,0 +1,66 @@ +package magistu.siegemachines.network; + +import magistu.siegemachines.SiegeMachines; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.math.BlockPos; +import net.minecraftforge.fml.network.NetworkDirection; +import net.minecraftforge.fml.network.NetworkRegistry; +import net.minecraftforge.fml.network.simple.SimpleChannel; +import net.minecraftforge.fml.server.ServerLifecycleHooks; + +public class PacketHandler +{ + private static final String PROTOCOL_VERSION = "1"; + + public static final SimpleChannel INSTANCE = NetworkRegistry.newSimpleChannel(new ResourceLocation(SiegeMachines.ID, "main"), () -> "1", "1"::equals, "1"::equals); + + protected static int currentId = 0; + + public static void init() + { + INSTANCE.registerMessage(getNextId(), PacketMachine.class, PacketMachine::write, PacketMachine::read, PacketMachine.Handler::handle); + INSTANCE.registerMessage(getNextId(), PacketMachineControl.class, PacketMachineControl::write, PacketMachineControl::read, PacketMachineControl.Handler::handle); + INSTANCE.registerMessage(getNextId(), PacketMachineUse.class, PacketMachineUse::write, PacketMachineUse::read, PacketMachineUse.Handler::handle); + INSTANCE.registerMessage(getNextId(), PacketMachineUseRealise.class, PacketMachineUseRealise::write, PacketMachineUseRealise::read, PacketMachineUseRealise.Handler::handle); + INSTANCE.registerMessage(getNextId(), PacketOpenMachineInventory.class, PacketOpenMachineInventory::write, PacketOpenMachineInventory::read, PacketOpenMachineInventory.Handler::handle); + INSTANCE.registerMessage(getNextId(), PacketMachineInventorySlot.class, PacketMachineInventorySlot::write, PacketMachineInventorySlot::read, PacketMachineInventorySlot.Handler::handle); + + } + + public static int getNextId() + { + int id = currentId; + currentId++; + return id; + } + + public static void sendToServer(Object packet) { + INSTANCE.sendToServer(packet); + } + + public static void sendTo(Object packet, ServerPlayerEntity player) + { + if (!(player instanceof net.minecraftforge.common.util.FakePlayer)) + INSTANCE.sendTo(packet, player.connection.connection, NetworkDirection.PLAY_TO_CLIENT); + } + + public static void sendPacketToAllInArea(Object packet, BlockPos center, int rangesqr) + { + for (ServerPlayerEntity player : ServerLifecycleHooks.getCurrentServer().getPlayerList().getPlayers()) + { + if (player.distanceToSqr(center.getX(), center.getY(), center.getZ()) < rangesqr) + { + sendTo(packet, player); + } + } + } + + public static void sendPacketToAll(Object packet) + { + for (ServerPlayerEntity player : ServerLifecycleHooks.getCurrentServer().getPlayerList().getPlayers()) + { + sendTo(packet, player); + } + } +} diff --git a/src/main/java/magistu/siegemachines/network/PacketMachine.java b/src/main/java/magistu/siegemachines/network/PacketMachine.java new file mode 100644 index 0000000..130583a --- /dev/null +++ b/src/main/java/magistu/siegemachines/network/PacketMachine.java @@ -0,0 +1,81 @@ +package magistu.siegemachines.network; + +import io.netty.channel.ChannelHandler; +import magistu.siegemachines.entity.machine.Machine; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.player.ClientPlayerEntity; +import net.minecraft.entity.Entity; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.fml.LogicalSide; +import net.minecraftforge.fml.network.NetworkEvent; + +import java.util.function.Supplier; + +@ChannelHandler.Sharable +public class PacketMachine +{ + private final int entityid; + private final int delayticks; + private final int useticks; + private final float turretyaw; + private final float turretpitch; + + public PacketMachine(int entityid, int delayticks, int useticks, float turretpitch, float turretyaw) + { + this.entityid = entityid; + this.delayticks = delayticks; + this.useticks = useticks; + this.turretpitch = turretpitch; + this.turretyaw = turretyaw; + } + + public static PacketMachine read(PacketBuffer buf) + { + return new PacketMachine(buf.readInt(), buf.readInt(), buf.readInt(), buf.readFloat(), buf.readFloat()); + } + + public static void write(PacketMachine message, PacketBuffer buf) + { + buf.writeInt(message.entityid); + buf.writeInt(message.delayticks); + buf.writeInt(message.useticks); + buf.writeFloat(message.turretpitch); + buf.writeFloat(message.turretyaw); + } + + public static class Handler + { + public static void handle(PacketMachine packet, Supplier ctx) + { + NetworkEvent.Context context = ctx.get(); + if (context.getDirection().getReceptionSide() == LogicalSide.CLIENT) + { + context.enqueueWork(() -> PacketMachine.handleClientSide(packet)); + } + context.setPacketHandled(true); + } + } + + @OnlyIn(Dist.CLIENT) + public static void handleClientSide(PacketMachine packet) + { + ClientPlayerEntity player = Minecraft.getInstance().player; + if(packet == null || player == null || player.level == null) + { + return; + } + + Entity entity = player.level.getEntity(packet.entityid); + if (!(entity instanceof Machine)) + { + return; + } + Machine machine = (Machine) entity; + + machine.delayticks = packet.delayticks; + machine.useticks = packet.useticks; + machine.setTurretRotations(packet.turretpitch, packet.turretyaw); + } +} diff --git a/src/main/java/magistu/siegemachines/network/PacketMachineControl.java b/src/main/java/magistu/siegemachines/network/PacketMachineControl.java new file mode 100644 index 0000000..613542c --- /dev/null +++ b/src/main/java/magistu/siegemachines/network/PacketMachineControl.java @@ -0,0 +1,54 @@ +package magistu.siegemachines.network; + +import io.netty.channel.ChannelHandler; +import magistu.siegemachines.entity.machine.Machine; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fml.LogicalSide; +import net.minecraftforge.fml.network.NetworkEvent; + +import java.util.function.Supplier; + +@ChannelHandler.Sharable +public class PacketMachineControl +{ + public PacketMachineControl() {} + + public static PacketMachineControl read(PacketBuffer buf) + { + return new PacketMachineControl(); + } + + public static void write(PacketMachineControl message, PacketBuffer buf) {} + + public static class Handler + { + public static void handle(PacketMachineControl packet, Supplier ctx) + { + NetworkEvent.Context context = ctx.get(); + if (context.getDirection().getReceptionSide() == LogicalSide.SERVER) + { + context.enqueueWork(() -> PacketMachineControl.handleServerSide(packet, context.getSender())); + } + context.setPacketHandled(true); + } + } + + public static void handleServerSide(PacketMachineControl packet, ServerPlayerEntity player) + { + if(packet == null || player == null || !player.isPassenger()) + { + return; + } + + Entity entity = player.getVehicle(); + if (!(entity instanceof Machine)) + { + return; + } + Machine machine = (Machine) entity; + + machine.setTurretRotations(player.xRot, player.yRot); + } +} diff --git a/src/main/java/magistu/siegemachines/network/PacketMachineInventorySlot.java b/src/main/java/magistu/siegemachines/network/PacketMachineInventorySlot.java new file mode 100644 index 0000000..1fabd13 --- /dev/null +++ b/src/main/java/magistu/siegemachines/network/PacketMachineInventorySlot.java @@ -0,0 +1,83 @@ +package magistu.siegemachines.network; + +import io.netty.channel.ChannelHandler; +import magistu.siegemachines.entity.machine.Machine; +import net.minecraft.client.Minecraft; +import net.minecraft.client.entity.player.ClientPlayerEntity; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.fml.LogicalSide; +import net.minecraftforge.fml.network.NetworkEvent; + +import java.util.function.Supplier; + +@ChannelHandler.Sharable +public class PacketMachineInventorySlot +{ + private final int entityid; + private final int slot; + private ItemStack itemstack = ItemStack.EMPTY; + + public PacketMachineInventorySlot(int entityid, int slot, ItemStack itemstack) + { + this.entityid = entityid; + this.slot = slot; + this.itemstack = itemstack.copy(); + } + + public static PacketMachineInventorySlot read(PacketBuffer buf) + { + return new PacketMachineInventorySlot(buf.readInt(), buf.readInt(), buf.readItem()); + } + + public static void write(PacketMachineInventorySlot message, PacketBuffer buf) + { + buf.writeInt(message.entityid); + buf.writeInt(message.slot); + buf.writeItemStack(message.itemstack, false); + } + + public static class Handler + { + public static void handle(PacketMachineInventorySlot packet, Supplier ctx) + { + NetworkEvent.Context context = ctx.get(); + if (context.getDirection().getReceptionSide() == LogicalSide.SERVER) + { + context.enqueueWork(() -> PacketMachineInventorySlot.handleEachSide(packet, context.getSender())); + } + else if (context.getDirection().getReceptionSide() == LogicalSide.CLIENT) + { + context.enqueueWork(() -> PacketMachineInventorySlot.handleClientSide(packet)); + } + context.setPacketHandled(true); + } + } + + @OnlyIn(Dist.CLIENT) + public static void handleClientSide(PacketMachineInventorySlot packet) + { + handleEachSide(packet, Minecraft.getInstance().player); + } + + public static void handleEachSide(PacketMachineInventorySlot packet, PlayerEntity player) + { + if(packet == null || player == null || player.level == null) + { + return; + } + + Entity entity = player.level.getEntity(packet.entityid); + if (!(entity instanceof Machine)) + { + return; + } + Machine machine = (Machine) entity; + + machine.inventory.setItem(packet.slot, packet.itemstack); + } +} diff --git a/src/main/java/magistu/siegemachines/network/PacketMachineUse.java b/src/main/java/magistu/siegemachines/network/PacketMachineUse.java new file mode 100644 index 0000000..4a37cce --- /dev/null +++ b/src/main/java/magistu/siegemachines/network/PacketMachineUse.java @@ -0,0 +1,75 @@ +package magistu.siegemachines.network; + +import io.netty.channel.ChannelHandler; +import magistu.siegemachines.entity.machine.Machine; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.fml.LogicalSide; +import net.minecraftforge.fml.network.NetworkEvent; + +import java.util.function.Supplier; + +@ChannelHandler.Sharable +public class PacketMachineUse +{ + private final int entityid; + + public PacketMachineUse(int entityid) + { + this.entityid = entityid; + } + + public static PacketMachineUse read(PacketBuffer buf) + { + return new PacketMachineUse(buf.readInt()); + } + + public static void write(PacketMachineUse message, PacketBuffer buf) + { + buf.writeInt(message.entityid); + } + + public static class Handler + { + public static void handle(PacketMachineUse packet, Supplier ctx) + { + NetworkEvent.Context context = ctx.get(); + if (context.getDirection().getReceptionSide() == LogicalSide.SERVER) + { + context.enqueueWork(() -> PacketMachineUse.handleEachSide(packet, context.getSender())); + } + else if (context.getDirection().getReceptionSide() == LogicalSide.CLIENT) + { + context.enqueueWork(() -> PacketMachineUse.handleClientSide(packet)); + } + context.setPacketHandled(true); + } + } + + @OnlyIn(Dist.CLIENT) + public static void handleClientSide(PacketMachineUse packet) + { + handleEachSide(packet, Minecraft.getInstance().player); + } + + public static void handleEachSide(PacketMachineUse packet, PlayerEntity player) + { + if(packet == null || player == null || player.level == null) + { + return; + } + + Entity entity = player.level.getEntity(packet.entityid); + if (!(entity instanceof Machine)) + { + return; + } + Machine machine = (Machine) entity; + + machine.use(player); + } +} diff --git a/src/main/java/magistu/siegemachines/network/PacketMachineUseRealise.java b/src/main/java/magistu/siegemachines/network/PacketMachineUseRealise.java new file mode 100644 index 0000000..a7db98d --- /dev/null +++ b/src/main/java/magistu/siegemachines/network/PacketMachineUseRealise.java @@ -0,0 +1,75 @@ +package magistu.siegemachines.network; + +import io.netty.channel.ChannelHandler; +import magistu.siegemachines.entity.machine.Machine; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.api.distmarker.Dist; +import net.minecraftforge.api.distmarker.OnlyIn; +import net.minecraftforge.fml.LogicalSide; +import net.minecraftforge.fml.network.NetworkEvent; + +import java.util.function.Supplier; + +@ChannelHandler.Sharable +public class PacketMachineUseRealise +{ + private final int entityid; + + public PacketMachineUseRealise(int entityid) + { + this.entityid = entityid; + } + + public static PacketMachineUseRealise read(PacketBuffer buf) + { + return new PacketMachineUseRealise(buf.readInt()); + } + + public static void write(PacketMachineUseRealise message, PacketBuffer buf) + { + buf.writeInt(message.entityid); + } + + public static class Handler + { + public static void handle(PacketMachineUseRealise packet, Supplier ctx) + { + NetworkEvent.Context context = ctx.get(); + if (context.getDirection().getReceptionSide() == LogicalSide.SERVER) + { + context.enqueueWork(() -> PacketMachineUseRealise.handleEachSide(packet, context.getSender())); + } + else if (context.getDirection().getReceptionSide() == LogicalSide.CLIENT) + { + context.enqueueWork(() -> PacketMachineUseRealise.handleClientSide(packet)); + } + context.setPacketHandled(true); + } + } + + @OnlyIn(Dist.CLIENT) + public static void handleClientSide(PacketMachineUseRealise packet) + { + handleEachSide(packet, Minecraft.getInstance().player); + } + + public static void handleEachSide(PacketMachineUseRealise packet, PlayerEntity player) + { + if(packet == null || player == null || player.level == null) + { + return; + } + + Entity entity = player.level.getEntity(packet.entityid); + if (!(entity instanceof Machine)) + { + return; + } + Machine machine = (Machine) entity; + + machine.useRealise(); + } +} diff --git a/src/main/java/magistu/siegemachines/network/PacketOpenMachineInventory.java b/src/main/java/magistu/siegemachines/network/PacketOpenMachineInventory.java new file mode 100644 index 0000000..d942679 --- /dev/null +++ b/src/main/java/magistu/siegemachines/network/PacketOpenMachineInventory.java @@ -0,0 +1,54 @@ +package magistu.siegemachines.network; + +import io.netty.channel.ChannelHandler; +import magistu.siegemachines.entity.machine.Machine; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.ServerPlayerEntity; +import net.minecraft.network.PacketBuffer; +import net.minecraftforge.fml.LogicalSide; +import net.minecraftforge.fml.network.NetworkEvent; + +import java.util.function.Supplier; + +@ChannelHandler.Sharable +public class PacketOpenMachineInventory +{ + public PacketOpenMachineInventory() {} + + public static PacketOpenMachineInventory read(PacketBuffer buf) + { + return new PacketOpenMachineInventory(); + } + + public static void write(PacketOpenMachineInventory message, PacketBuffer buf) {} + + public static class Handler + { + public static void handle(PacketOpenMachineInventory packet, Supplier ctx) + { + NetworkEvent.Context context = ctx.get(); + if (context.getDirection().getReceptionSide() == LogicalSide.SERVER) + { + context.enqueueWork(() -> PacketOpenMachineInventory.handleServerSide(packet, context.getSender())); + } + context.setPacketHandled(true); + } + } + + public static void handleServerSide(PacketOpenMachineInventory packet, ServerPlayerEntity player) + { + if(packet == null || player == null || !player.isPassenger()) + { + return; + } + + Entity entity = player.getVehicle(); + if (!(entity instanceof Machine)) + { + return; + } + Machine machine = (Machine) entity; + + machine.openInventoryGui(); + } +} diff --git a/src/main/java/magistu/siegemachines/proxy/IProxy.java b/src/main/java/magistu/siegemachines/proxy/IProxy.java new file mode 100644 index 0000000..8ea1eec --- /dev/null +++ b/src/main/java/magistu/siegemachines/proxy/IProxy.java @@ -0,0 +1,13 @@ +package magistu.siegemachines.proxy; + +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; + +public interface IProxy +{ + void setup(IEventBus paramIEventBus1, IEventBus paramIEventBus2); + + public void clientSetup(FMLClientSetupEvent event); + + public void onPreInit(); +} diff --git a/src/main/java/magistu/siegemachines/server/ServerProxy.java b/src/main/java/magistu/siegemachines/server/ServerProxy.java new file mode 100644 index 0000000..ca35ec8 --- /dev/null +++ b/src/main/java/magistu/siegemachines/server/ServerProxy.java @@ -0,0 +1,14 @@ +package magistu.siegemachines.server; + +import magistu.siegemachines.proxy.IProxy; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; + +public class ServerProxy implements IProxy +{ + public void setup(IEventBus modEventBus, IEventBus forgeEventBus) {} + + public void clientSetup(FMLClientSetupEvent event) {} + + public void onPreInit() {} +} diff --git a/src/main/resources/META-INF/mods.toml b/src/main/resources/META-INF/mods.toml new file mode 100644 index 0000000..689352a --- /dev/null +++ b/src/main/resources/META-INF/mods.toml @@ -0,0 +1,16 @@ +modLoader="javafml" #mandatory +loaderVersion="[31,)" #mandatory This is typically bumped every Minecraft version by Forge. See our download page for lists of versions. +license="All rights reserved" +[[mods]] #mandatory +modId="siegemachines" #mandatory +version="1.16-1.17" #mandatory +displayName="Medieval Siege Machines" #mandatory +authors="Magistu" #optional +credits="Lexiolty" #optional +description='''Adds medieval siege machines''' +[[dependencies.siegemachines]] + modId="geckolib3" + mandatory=true + versionRange="[3.0.56,]" + ordering="NONE" + side="BOTH" \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/animations/ballista.animation.json b/src/main/resources/assets/siegemachines/animations/ballista.animation.json new file mode 100644 index 0000000..368cde3 --- /dev/null +++ b/src/main/resources/assets/siegemachines/animations/ballista.animation.json @@ -0,0 +1,195 @@ +{ + "format_version": "1.8.0", + "animations": { + "Reloading": { + "animation_length": 5.0, + "bones": { + "ArcDroit": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "5.0": { + "vector": [0, 20, 0] + } + } + }, + "ArcGauche": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "5.0": { + "vector": [0, -20, 0] + } + } + }, + "Manivelles": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "5.0": { + "vector": [-720, 0, 0] + } + } + }, + "CordeGuide": { + "position": { + "0.0": { + "vector": [0, 0, 1] + }, + "5.0": { + "vector": [0, 0, 17] + } + }, + "scale": { + "0.0": { + "vector": [1, 1, 1] + }, + "5.0": { + "vector": [1, 1, 0.2] + } + } + }, + "Guide": { + "position": { + "0.0": { + "vector": [0, 0, 0] + }, + "5.0": { + "vector": [0, 0, 17] + } + } + }, + "CordeDroite": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "5.0": { + "vector": [0, -42.5, 0] + } + }, + "position": { + "0.0": { + "vector": [0, 0, 0] + }, + "5.0": { + "vector": [4.4, 0, 5] + } + } + }, + "CordeGauche": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "5.0": { + "vector": [0, 42.5, 0] + } + }, + "position": { + "0.0": { + "vector": [0, 0, 0] + }, + "5.0": { + "vector": [-4.4, 0, 5] + } + } + } + } + }, + "Shooting": { + "loop": true, + "animation_length": 1.0, + "bones": { + "ArcDroit": { + "rotation": { + "0.0": { + "vector": [0, 20, 0] + }, + "0.05": { + "vector": [0, 0, 0] + } + } + }, + "ArcGauche": { + "rotation": { + "0.0": { + "vector": [0, -20, 0] + }, + "0.05": { + "vector": [0, 0, 0] + } + } + }, + "Guide": { + "position": { + "0.0": { + "vector": [0, 0, 17] + }, + "0.05": { + "vector": [0, 0, 0] + } + } + }, + "CordeDroite": { + "rotation": { + "0.0": { + "vector": [0, -42.5, 0] + }, + "0.05": { + "vector": [0, 0, 0] + } + }, + "position": { + "0.0": { + "vector": [4.4, 0, 5] + }, + "0.05": { + "vector": [0, 0, 0] + } + } + }, + "CordeGauche": { + "rotation": { + "0.0": { + "vector": [0, 42.5, 0] + }, + "0.05": { + "vector": [0, 0, 0] + } + }, + "position": { + "0.0": { + "vector": [-4.4, 0, 5] + }, + "0.05": { + "vector": [0, 0, 0] + } + } + }, + "CordeGuide": { + "position": { + "0.0": { + "vector": [0, 0, 17] + }, + "0.05": { + "vector": [0, 0, 1] + } + }, + "scale": { + "0.0": { + "vector": [1, 1, "0.2+0.9s"] + }, + "0.05": { + "vector": [1, 1, 1] + } + } + } + } + } + }, + "geckolib_format_version": 2 +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/animations/battering_ram.animation.json b/src/main/resources/assets/siegemachines/animations/battering_ram.animation.json new file mode 100644 index 0000000..acab657 --- /dev/null +++ b/src/main/resources/assets/siegemachines/animations/battering_ram.animation.json @@ -0,0 +1,443 @@ +{ + "format_version": "1.8.0", + "animations": { + "Moving": { + "loop": true, + "animation_length": 4, + "bones": { + "Wheel1": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "4.0": { + "vector": [360, 0, 0] + } + } + }, + "Wheel2": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "4.0": { + "vector": [360, 0, 0] + } + } + }, + "Wheel3": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "4.0": { + "vector": [360, 0, 0] + } + } + }, + "Wheel4": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "4.0": { + "vector": [360, 0, 0] + } + } + }, + "Wheel5": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "4.0": { + "vector": [360, 0, 0] + } + } + }, + "Wheel6": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "4.0": { + "vector": [360, 0, 0] + } + } + } + } + }, + "TurningRight": { + "loop": true, + "animation_length": 2, + "bones": { + "Wheel1": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "0.5": { + "vector": [90, 0, 0] + }, + "1.0": { + "vector": [180, 0, 0] + }, + "1.5": { + "vector": [270, 0, 0] + }, + "2.0": { + "vector": [360, 0, 0] + } + } + }, + "Wheel2": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "0.5": { + "vector": [90, 0, 0] + }, + "1.0": { + "vector": [180, 0, 0] + }, + "1.5": { + "vector": [270, 0, 0] + }, + "2.0": { + "vector": [360, 0, 0] + } + } + }, + "Wheel3": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "0.5": { + "vector": [90, 0, 0] + }, + "1.0": { + "vector": [180, 0, 0] + }, + "1.5": { + "vector": [270, 0, 0] + }, + "2.0": { + "vector": [360, 0, 0] + } + } + }, + "Wheel4": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "0.5": { + "vector": [-90, 0, 0] + }, + "1.0": { + "vector": [-180, 0, 0] + }, + "1.5": { + "vector": [-270, 0, 0] + }, + "2.0": { + "vector": [-360, 0, 0] + } + } + }, + "Wheel5": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "0.5": { + "vector": [-90, 0, 0] + }, + "1.0": { + "vector": [-180, 0, 0] + }, + "1.5": { + "vector": [-270, 0, 0] + }, + "2.0": { + "vector": [-360, 0, 0] + } + } + }, + "Wheel6": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "0.5": { + "vector": [-90, 0, 0] + }, + "1.0": { + "vector": [-180, 0, 0] + }, + "1.5": { + "vector": [-270, 0, 0] + }, + "2.0": { + "vector": [-360, 0, 0] + } + } + } + } + }, + "TurningLeft": { + "loop": true, + "animation_length": 2, + "bones": { + "Wheel1": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "0.5": { + "vector": [-90, 0, 0] + }, + "1.0": { + "vector": [-180, 0, 0] + }, + "1.5": { + "vector": [-270, 0, 0] + }, + "2.0": { + "vector": [-360, 0, 0] + } + } + }, + "Wheel2": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "0.5": { + "vector": [-90, 0, 0] + }, + "1.0": { + "vector": [-180, 0, 0] + }, + "1.5": { + "vector": [-270, 0, 0] + }, + "2.0": { + "vector": [-360, 0, 0] + } + } + }, + "Wheel3": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "0.5": { + "vector": [-90, 0, 0] + }, + "1.0": { + "vector": [-180, 0, 0] + }, + "1.5": { + "vector": [-270, 0, 0] + }, + "2.0": { + "vector": [-360, 0, 0] + } + } + }, + "Wheel4": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "0.5": { + "vector": [90, 0, 0] + }, + "1.0": { + "vector": [180, 0, 0] + }, + "1.5": { + "vector": [270, 0, 0] + }, + "2.0": { + "vector": [360, 0, 0] + } + } + }, + "Wheel5": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "0.5": { + "vector": [90, 0, 0] + }, + "1.0": { + "vector": [180, 0, 0] + }, + "1.5": { + "vector": [270, 0, 0] + }, + "2.0": { + "vector": [360, 0, 0] + } + } + }, + "Wheel6": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "0.5": { + "vector": [90, 0, 0] + }, + "1.0": { + "vector": [180, 0, 0] + }, + "1.5": { + "vector": [270, 0, 0] + }, + "2.0": { + "vector": [360, 0, 0] + } + } + } + } + }, + "Reloading": { + "animation_length": 5, + "bones": { + "Ram": { + "position": { + "0.0": { + "vector": [0, 0, 0] + }, + "5.0": { + "vector": [0, 3.7, 12], + "easing": "linear" + } + } + }, + "FirstDuoRopes": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "5.0": { + "vector": [45, 0, 0] + } + } + }, + "SecondDuoRopes": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "5.0": { + "vector": [45, 0, 0] + } + } + }, + "ThirdDuoRopes": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "5.0": { + "vector": [45, 0, 0] + } + } + } + } + }, + "ReloadedIdle": { + "animation_length": 5, + "bones": { + "Ram": { + "position": { + "vector": [0, 3.7, 12], + "easing": "linear" + } + }, + "FirstDuoRopes": { + "rotation": { + "vector": [45, 0, 0] + } + }, + "SecondDuoRopes": { + "rotation": { + "vector": [45, 0, 0] + } + }, + "ThirdDuoRopes": { + "rotation": { + "vector": [45, 0, 0] + } + } + } + }, + "Hitting": { + "loop": true, + "animation_length": 0.25, + "bones": { + "Ram": { + "position": { + "0.0": { + "vector": [0, 3.7, 12], + "easing": "linear" + }, + "0.15": { + "vector": [0, 0, 0] + }, + "0.25": { + "vector": [0, 3, -10] + } + } + }, + "FirstDuoRopes": { + "rotation": { + "0.0": { + "vector": [45, 0, 0] + }, + "0.15": { + "vector": [0, 0, 0] + }, + "0.25": { + "vector": [-40, 0, 0] + } + } + }, + "SecondDuoRopes": { + "rotation": { + "0.0": { + "vector": [45, 0, 0] + }, + "0.15": { + "vector": [0, 0, 0] + }, + "0.25": { + "vector": [-40, 0, 0] + } + } + }, + "ThirdDuoRopes": { + "rotation": { + "0.0": { + "vector": [45, 0, 0] + }, + "0.15": { + "vector": [0, 0, 0] + }, + "0.25": { + "vector": [-40, 0, 0] + } + } + } + } + } + }, + "geckolib_format_version": 2 +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/animations/catapult.animation.json b/src/main/resources/assets/siegemachines/animations/catapult.animation.json new file mode 100644 index 0000000..e70994c --- /dev/null +++ b/src/main/resources/assets/siegemachines/animations/catapult.animation.json @@ -0,0 +1,119 @@ +{ + "format_version": "1.8.0", + "animations": { + "Reloading": { + "animation_length": 10.0, + "bones": { + "Lever": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "10.0": { + "vector": [-67.5, 0, 0] + } + } + }, + "Crank": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "10.0": { + "vector": [-360, 0, 0] + } + } + }, + "LittleLevers": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "0.8333": { + "vector": [15, 0, 0] + }, + "1.0": { + "vector": [0, 0, 0] + }, + "2.2": { + "vector": [15, 0, 0] + }, + "2.3": { + "vector": [0, 0, 0] + }, + "3.5": { + "vector": [15, 0, 0] + }, + "3.7": { + "vector": [0, 0, 0] + }, + "4.8": { + "vector": [15, 0, 0] + }, + "5.0": { + "vector": [0, 0, 0] + }, + "6.1": { + "vector": [15, 0, 0] + }, + "6.3": { + "vector": [0, 0, 0] + }, + "7.5": { + "vector": [15, 0, 0] + }, + "7.6": { + "vector": [0, 0, 0] + }, + "8.8": { + "vector": [15, 0, 0] + }, + "8.9": { + "vector": [0, 0, 0] + } + } + } + } + }, + "IdleReloaded": { + "loop": true, + "bones": { + "Lever": { + "rotation": { + "vector": [-67.5, 0, 0] + } + }, + "Rope": { + "scale": { + "vector": [0, 0, 0] + } + }, + "Crank": { + "rotation": { + "vector": [-360, 0, 0] + } + } + } + }, + "IdleNotReloaded": { + "loop": true + }, + "Shooting": { + "loop": true, + "animation_length": 0.4, + "bones": { + "Lever": { + "rotation": { + "0.0": { + "vector": [-67.5, 0, 0] + }, + "0.1": { + "vector": [0, 0, 0] + } + } + } + } + } + }, + "geckolib_format_version": 2 +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/animations/mortar.animation.json b/src/main/resources/assets/siegemachines/animations/mortar.animation.json new file mode 100644 index 0000000..ac2dae2 --- /dev/null +++ b/src/main/resources/assets/siegemachines/animations/mortar.animation.json @@ -0,0 +1,38 @@ +{ + "format_version": "1.8.0", + "animations": { + "Tilting": { + "loop": true, + "animation_length": 4, + "bones": { + "Barrel": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "4.0": { + "vector": [360, 0, 0] + } + } + } + } + }, + "Moving": { + "loop": true, + "animation_length": 4, + "bones": { + "Wheels": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "4.0": { + "vector": [360, 0, 0] + } + } + } + } + } + }, + "geckolib_format_version": 2 +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/animations/none.animation.json b/src/main/resources/assets/siegemachines/animations/none.animation.json new file mode 100644 index 0000000..5ac4bc1 --- /dev/null +++ b/src/main/resources/assets/siegemachines/animations/none.animation.json @@ -0,0 +1,5 @@ +{ + "format_version": "1.8.0", + "animations": {}, + "geckolib_format_version": 2 +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/animations/trebuchet.animation.json b/src/main/resources/assets/siegemachines/animations/trebuchet.animation.json new file mode 100644 index 0000000..d4b72ae --- /dev/null +++ b/src/main/resources/assets/siegemachines/animations/trebuchet.animation.json @@ -0,0 +1,210 @@ +{ + "format_version": "1.8.0", + "animations": { + "Shooting": { + "loop": "hold_on_last_frame", + "animation_length": 6.83333, + "bones": { + "Lever": { + "rotation": { + "0.0": { + "vector": [-120, 0, 0] + }, + "2.0417": { + "vector": [37.2, 0, 0], + "easing": "easeInExpo" + }, + "2.25": { + "vector": [34.83, 0, 0] + }, + "2.3333": { + "vector": [32.56, 0, 0] + }, + "2.4167": { + "vector": [29.53, 0, 0] + }, + "2.5": { + "vector": [25.74, 0, 0] + }, + "2.5833": { + "vector": [21.19, 0, 0] + }, + "2.6667": { + "vector": [15.89, 0, 0] + }, + "2.75": { + "vector": [9.82, 0, 0] + }, + "2.8333": { + "vector": [3, 0, 0] + }, + "2.9167": { + "vector": [-4.57, 0, 0] + }, + "3.0": { + "vector": [-12.91, 0, 0] + }, + "3.0833": { + "vector": [-22, 0, 0], + "easing": "easeInQuad" + }, + "3.9583": { + "vector": [27, 0, 0], + "easing": "easeInSine" + }, + "5.1667": { + "vector": [-14.5, 0, 0], + "easing": "easeInSine" + }, + "6.8333": { + "vector": [0, 0, 0] + } + } + }, + "CounterWeight": { + "rotation": { + "0.0": { + "vector": [120, 0, 0] + }, + "2.0417": { + "vector": [-31.96, 0, 0], + "easing": "easeInExpo" + }, + "2.75": { + "vector": [7.19, 0, 0], + "easing": "easeOutQuad" + }, + "3.0833": { + "vector": [27.74, 0, 0] + }, + "3.9583": { + "vector": [-24.38, 0, 0] + }, + "5.1667": { + "vector": [13.12, 0, 0] + }, + "6.8333": { + "vector": [0, 0, 0] + } + } + }, + "Rope_Projectile": { + "rotation": { + "0.0": { + "vector": [35, 0, 0] + }, + "1.5833": { + "vector": [57.5, 0, 0], + "easing": "easeInExpo" + }, + "3.0833": { + "vector": [386.91598, 0, 0], + "easing": "easeOutQuad" + }, + "3.9583": { + "vector": [359.87276, 0, 0], + "easing": "easeInQuad" + }, + "5.1667": { + "vector": [375.39, 0, 0], + "easing": "easeInQuad" + }, + "6.8333": { + "vector": [360, 0, 0], + "easing": "easeInQuad" + } + } + } + } + }, + "Reloading": { + "loop": "hold_on_last_frame", + "animation_length": 20, + "bones": { + "Crank": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "20.0": { + "vector": [-720, 0, 0] + } + } + }, + "Lever": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "20.0": { + "vector": [-120, 0, 0] + } + } + }, + "CounterWeight": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "20.0": { + "vector": [120, 0, 0] + } + } + }, + "Rope_Projectile": { + "rotation": { + "0.0": { + "vector": [0, 0, 0] + }, + "20.0": { + "vector": [35, 0, 0] + } + } + } + } + }, + "IdleReloaded": { + "loop": "hold_on_last_frame", + "animation_length": 6.83333, + "bones": { + "Rope_Projectile": { + "rotation": { + "vector": [35, 0, 0] + } + }, + "Lever": { + "rotation": { + "vector": [-122.5, 0, 0] + } + }, + "CounterWeight": { + "rotation": { + "vector": [122.5, 0, 0] + } + } + } + }, + "IdleNotReloaded": { + "loop": "hold_on_last_frame", + "animation_length": 20, + "bones": { + "CounterWeight": { + "rotation": { + "vector": [0, 0, 0] + } + }, + "Lever": { + "rotation": { + "vector": [0, 0, 0] + } + }, + "Rope_Projectile": { + "rotation": { + "vector": [0, 0, 0] + } + } + } + } + }, + "geckolib_format_version": 2 +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/blockstates/siege_workbench.json b/src/main/resources/assets/siegemachines/blockstates/siege_workbench.json new file mode 100644 index 0000000..63f5426 --- /dev/null +++ b/src/main/resources/assets/siegemachines/blockstates/siege_workbench.json @@ -0,0 +1,5 @@ +{ + "variants": { + "": { "model": "siegemachines:block/siege_workbench" } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/geo/ballista.geo.json b/src/main/resources/assets/siegemachines/geo/ballista.geo.json new file mode 100644 index 0000000..a1b8814 --- /dev/null +++ b/src/main/resources/assets/siegemachines/geo/ballista.geo.json @@ -0,0 +1,139 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.unknown", + "texture_width": 128, + "texture_height": 128, + "visible_bounds_width": 5, + "visible_bounds_height": 4, + "visible_bounds_offset": [0, 1, 0] + }, + "bones": [ + { + "name": "bb_main", + "pivot": [0, 0, 0], + "cubes": [ + {"origin": [0, 3, 30], "size": [0, 0, 1], "uv": [0, 0]} + ] + }, + { + "name": "Structure", + "pivot": [0, 4.18198, -8.1], + "cubes": [ + {"origin": [-1.5, 0, -1.4], "size": [3, 20, 3], "uv": [44, 0]}, + {"origin": [-8.90381, 1.28198, -4.4], "size": [1, 2, 11], "pivot": [-7.40381, 4.28198, -0.9], "rotation": [0, 90, -45], "uv": [0, 0]}, + {"origin": [-0.5, -0.81802, 0.83223], "size": [1, 2, 11], "pivot": [-4, 4.18198, 10.33223], "rotation": [-45, 0, 0], "uv": [0, 39]}, + {"origin": [-1.5, -1, -11.9], "size": [3, 2, 24], "uv": [44, 0]}, + {"origin": [7.90381, 1.28198, -4.4], "size": [1, 2, 11], "pivot": [7.40381, 4.28198, -0.9], "rotation": [0, -90, 45], "uv": [33, 40]}, + {"origin": [-12, -0.9, -1.4], "size": [24, 2, 3], "uv": [44, 27]}, + {"origin": [-0.5, 6.41726, -8.63528], "size": [1, 2, 11], "pivot": [0, 4.18198, 0.1], "rotation": [45, 0, 0], "uv": [0, 13]} + ] + }, + { + "name": "Balliste", + "pivot": [0, 20, 0], + "cubes": [ + {"origin": [-2.4, 20, -1.9], "size": [5, 1, 4], "uv": [12, 52]}, + {"origin": [-0.4, 19.8, -0.4], "size": [1, 2, 1], "uv": [0, 5]}, + {"origin": [2, 20.3, -1.4], "size": [1, 4, 3], "uv": [13, 13]}, + {"origin": [-2.8, 20.3, -1.4], "size": [1, 4, 3], "uv": [0, 13]}, + {"origin": [-2.9, 16.3, -7.3], "size": [2, 13, 1], "uv": [31, 0]}, + {"origin": [-5.9, 17.3, -7.3], "size": [2, 11, 1], "pivot": [-4.9, 22.8, -6.8], "rotation": [0, 45, 0], "uv": [55, 53]}, + {"origin": [1.1, 16.3, -7.3], "size": [2, 13, 1], "uv": [31, 14]}, + {"origin": [4.1, 17.3, -7.3], "size": [2, 11, 1], "pivot": [5.1, 22.8, -6.8], "rotation": [0, -45, 0], "uv": [23, 12]}, + {"origin": [-5.9, 26.3, -7.6], "size": [12, 1, 1], "uv": [0, 33]}, + {"origin": [-5.9, 18.3, -7.6], "size": [12, 1, 1], "uv": [0, 26]}, + {"origin": [-1.4, 21.5, -12.4], "size": [3, 1, 38], "uv": [0, 0]}, + {"origin": [0.7, 20.4, 17.6], "size": [1, 2, 10], "uv": [33, 53]}, + {"origin": [-1.9, 21.4, 26.1], "size": [4, 2, 1], "uv": [0, 8]}, + {"origin": [-1.5, 20.4, 17.6], "size": [1, 2, 10], "uv": [0, 52]}, + {"origin": [0.8, 22, -12.5], "size": [1, 1, 31], "uv": [33, 40]}, + {"origin": [0.8, 22, 18.5], "size": [1, 1, 8], "uv": [46, 40]}, + {"origin": [-1.6, 22, 18.5], "size": [1, 1, 8], "uv": [13, 39]}, + {"origin": [-1.6, 22, -12.5], "size": [1, 1, 31], "uv": [0, 39]} + ] + }, + { + "name": "ArcDroit", + "parent": "Balliste", + "pivot": [-1.07597, 23.3, -6.48107], + "cubes": [ + {"origin": [-11.1, 22, -5.9], "size": [10, 2, 1], "pivot": [-5.1, 23, -6.4], "rotation": [0, 20, 0], "uv": [0, 35]}, + {"origin": [-19.07597, 22.5, -0.78107], "size": [10, 1, 1], "pivot": [-14.07597, 23, -0.28107], "rotation": [0, 40, 0], "uv": [44, 35]} + ] + }, + { + "name": "ArcGauche", + "parent": "Balliste", + "pivot": [1.07597, 23.3, -6.48107], + "cubes": [ + {"origin": [1.1, 22, -5.9], "size": [10, 2, 1], "pivot": [5.1, 23, -6.4], "rotation": [0, -20, 0], "uv": [44, 32]}, + {"origin": [9.07597, 22.5, -0.78107], "size": [10, 1, 1], "pivot": [14.07597, 23, -0.28107], "rotation": [0, -40, 0], "uv": [0, 64]} + ] + }, + { + "name": "Manivelles", + "parent": "Balliste", + "pivot": [0.14545, 21.9, 24.6], + "cubes": [ + {"origin": [-2.9, 21.4, 24.1], "size": [6, 1, 1], "uv": [13, 8]}, + {"origin": [-3.7, 13.4, 28.1], "size": [1, 4, 1], "pivot": [-3.2, 21.9, 28.6], "rotation": [-90, 0, 0], "uv": [0, 39]}, + {"origin": [-4.1, 20.9, 23.6], "size": [1, 2, 2], "uv": [21, 0]}, + {"origin": [-3.7, 22.4, 24.1], "size": [1, 4, 1], "uv": [17, 39]}, + {"origin": [-3.7, 17.4, 24.1], "size": [1, 4, 1], "uv": [13, 39]}, + {"origin": [-3.7, 18.4, 28.1], "size": [1, 4, 1], "pivot": [-3.2, 21.9, 28.6], "rotation": [-90, 0, 0], "uv": [4, 39]}, + {"origin": [3, 13.4, 28.1], "size": [1, 4, 1], "pivot": [3.5, 21.9, 28.6], "rotation": [-90, 0, 0], "uv": [30, 33]}, + {"origin": [3.4, 20.9, 23.6], "size": [1, 2, 2], "uv": [13, 20]}, + {"origin": [3, 18.4, 28.1], "size": [1, 4, 1], "pivot": [3.5, 21.9, 28.6], "rotation": [-90, 0, 0], "uv": [34, 33]}, + {"origin": [3, 17.4, 24.1], "size": [1, 4, 1], "uv": [0, 0]}, + {"origin": [3, 22.4, 24.1], "size": [1, 4, 1], "uv": [26, 33]} + ] + }, + { + "name": "CordeGuide", + "parent": "Balliste", + "pivot": [0, 0, 5.2], + "cubes": [ + {"origin": [0.07, 22, 5.2], "size": [0.03, 1, 21], "uv": [44, 5]} + ] + }, + { + "name": "Guide", + "parent": "Balliste", + "pivot": [0, 0, -3], + "cubes": [ + {"origin": [-0.9, 22.4, 3.4], "size": [2, 1, 3], "uv": [0, 20]} + ] + }, + { + "name": "CordeDroite", + "parent": "Balliste", + "pivot": [-17.5, 23, 3.3], + "cubes": [ + {"origin": [-17.5848, 22.5, 3.31489], "size": [18, 1, 0.03], "uv": [0, 32]} + ] + }, + { + "name": "CordeGauche", + "parent": "Balliste", + "pivot": [17.6, 22.5, 3.3], + "cubes": [ + {"origin": [-0.4152, 22.5, 3.31489], "size": [18, 1, 0.03], "uv": [0, 31]} + ] + }, + { + "name": "BallistaArrow", + "pivot": [0, 20, 0], + "cubes": [ + {"origin": [-31.4, 20.5, 17.2], "size": [34, 5, 0.03], "pivot": [0.1, 23, 17.2], "rotation": [0, -90, -45], "uv": [0, 72]}, + {"origin": [-31.4, 20.5, 17.2], "size": [34, 5, 0.03], "pivot": [0.1, 23, 17.2], "rotation": [0, -90, 45], "uv": [0, 72]}, + {"origin": [-34.4, 21, 17.2], "size": [4, 4, 0.03], "pivot": [0.1, 23, 17.2], "rotation": [0, -90, 45], "uv": [76, 72]}, + {"origin": [-34.4, 21, 17.2], "size": [4, 4, 0.03], "pivot": [0.1, 23, 17.2], "rotation": [0, -90, -45], "uv": [68, 72]} + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/geo/ballista_item.geo.json b/src/main/resources/assets/siegemachines/geo/ballista_item.geo.json new file mode 100644 index 0000000..a1b8814 --- /dev/null +++ b/src/main/resources/assets/siegemachines/geo/ballista_item.geo.json @@ -0,0 +1,139 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.unknown", + "texture_width": 128, + "texture_height": 128, + "visible_bounds_width": 5, + "visible_bounds_height": 4, + "visible_bounds_offset": [0, 1, 0] + }, + "bones": [ + { + "name": "bb_main", + "pivot": [0, 0, 0], + "cubes": [ + {"origin": [0, 3, 30], "size": [0, 0, 1], "uv": [0, 0]} + ] + }, + { + "name": "Structure", + "pivot": [0, 4.18198, -8.1], + "cubes": [ + {"origin": [-1.5, 0, -1.4], "size": [3, 20, 3], "uv": [44, 0]}, + {"origin": [-8.90381, 1.28198, -4.4], "size": [1, 2, 11], "pivot": [-7.40381, 4.28198, -0.9], "rotation": [0, 90, -45], "uv": [0, 0]}, + {"origin": [-0.5, -0.81802, 0.83223], "size": [1, 2, 11], "pivot": [-4, 4.18198, 10.33223], "rotation": [-45, 0, 0], "uv": [0, 39]}, + {"origin": [-1.5, -1, -11.9], "size": [3, 2, 24], "uv": [44, 0]}, + {"origin": [7.90381, 1.28198, -4.4], "size": [1, 2, 11], "pivot": [7.40381, 4.28198, -0.9], "rotation": [0, -90, 45], "uv": [33, 40]}, + {"origin": [-12, -0.9, -1.4], "size": [24, 2, 3], "uv": [44, 27]}, + {"origin": [-0.5, 6.41726, -8.63528], "size": [1, 2, 11], "pivot": [0, 4.18198, 0.1], "rotation": [45, 0, 0], "uv": [0, 13]} + ] + }, + { + "name": "Balliste", + "pivot": [0, 20, 0], + "cubes": [ + {"origin": [-2.4, 20, -1.9], "size": [5, 1, 4], "uv": [12, 52]}, + {"origin": [-0.4, 19.8, -0.4], "size": [1, 2, 1], "uv": [0, 5]}, + {"origin": [2, 20.3, -1.4], "size": [1, 4, 3], "uv": [13, 13]}, + {"origin": [-2.8, 20.3, -1.4], "size": [1, 4, 3], "uv": [0, 13]}, + {"origin": [-2.9, 16.3, -7.3], "size": [2, 13, 1], "uv": [31, 0]}, + {"origin": [-5.9, 17.3, -7.3], "size": [2, 11, 1], "pivot": [-4.9, 22.8, -6.8], "rotation": [0, 45, 0], "uv": [55, 53]}, + {"origin": [1.1, 16.3, -7.3], "size": [2, 13, 1], "uv": [31, 14]}, + {"origin": [4.1, 17.3, -7.3], "size": [2, 11, 1], "pivot": [5.1, 22.8, -6.8], "rotation": [0, -45, 0], "uv": [23, 12]}, + {"origin": [-5.9, 26.3, -7.6], "size": [12, 1, 1], "uv": [0, 33]}, + {"origin": [-5.9, 18.3, -7.6], "size": [12, 1, 1], "uv": [0, 26]}, + {"origin": [-1.4, 21.5, -12.4], "size": [3, 1, 38], "uv": [0, 0]}, + {"origin": [0.7, 20.4, 17.6], "size": [1, 2, 10], "uv": [33, 53]}, + {"origin": [-1.9, 21.4, 26.1], "size": [4, 2, 1], "uv": [0, 8]}, + {"origin": [-1.5, 20.4, 17.6], "size": [1, 2, 10], "uv": [0, 52]}, + {"origin": [0.8, 22, -12.5], "size": [1, 1, 31], "uv": [33, 40]}, + {"origin": [0.8, 22, 18.5], "size": [1, 1, 8], "uv": [46, 40]}, + {"origin": [-1.6, 22, 18.5], "size": [1, 1, 8], "uv": [13, 39]}, + {"origin": [-1.6, 22, -12.5], "size": [1, 1, 31], "uv": [0, 39]} + ] + }, + { + "name": "ArcDroit", + "parent": "Balliste", + "pivot": [-1.07597, 23.3, -6.48107], + "cubes": [ + {"origin": [-11.1, 22, -5.9], "size": [10, 2, 1], "pivot": [-5.1, 23, -6.4], "rotation": [0, 20, 0], "uv": [0, 35]}, + {"origin": [-19.07597, 22.5, -0.78107], "size": [10, 1, 1], "pivot": [-14.07597, 23, -0.28107], "rotation": [0, 40, 0], "uv": [44, 35]} + ] + }, + { + "name": "ArcGauche", + "parent": "Balliste", + "pivot": [1.07597, 23.3, -6.48107], + "cubes": [ + {"origin": [1.1, 22, -5.9], "size": [10, 2, 1], "pivot": [5.1, 23, -6.4], "rotation": [0, -20, 0], "uv": [44, 32]}, + {"origin": [9.07597, 22.5, -0.78107], "size": [10, 1, 1], "pivot": [14.07597, 23, -0.28107], "rotation": [0, -40, 0], "uv": [0, 64]} + ] + }, + { + "name": "Manivelles", + "parent": "Balliste", + "pivot": [0.14545, 21.9, 24.6], + "cubes": [ + {"origin": [-2.9, 21.4, 24.1], "size": [6, 1, 1], "uv": [13, 8]}, + {"origin": [-3.7, 13.4, 28.1], "size": [1, 4, 1], "pivot": [-3.2, 21.9, 28.6], "rotation": [-90, 0, 0], "uv": [0, 39]}, + {"origin": [-4.1, 20.9, 23.6], "size": [1, 2, 2], "uv": [21, 0]}, + {"origin": [-3.7, 22.4, 24.1], "size": [1, 4, 1], "uv": [17, 39]}, + {"origin": [-3.7, 17.4, 24.1], "size": [1, 4, 1], "uv": [13, 39]}, + {"origin": [-3.7, 18.4, 28.1], "size": [1, 4, 1], "pivot": [-3.2, 21.9, 28.6], "rotation": [-90, 0, 0], "uv": [4, 39]}, + {"origin": [3, 13.4, 28.1], "size": [1, 4, 1], "pivot": [3.5, 21.9, 28.6], "rotation": [-90, 0, 0], "uv": [30, 33]}, + {"origin": [3.4, 20.9, 23.6], "size": [1, 2, 2], "uv": [13, 20]}, + {"origin": [3, 18.4, 28.1], "size": [1, 4, 1], "pivot": [3.5, 21.9, 28.6], "rotation": [-90, 0, 0], "uv": [34, 33]}, + {"origin": [3, 17.4, 24.1], "size": [1, 4, 1], "uv": [0, 0]}, + {"origin": [3, 22.4, 24.1], "size": [1, 4, 1], "uv": [26, 33]} + ] + }, + { + "name": "CordeGuide", + "parent": "Balliste", + "pivot": [0, 0, 5.2], + "cubes": [ + {"origin": [0.07, 22, 5.2], "size": [0.03, 1, 21], "uv": [44, 5]} + ] + }, + { + "name": "Guide", + "parent": "Balliste", + "pivot": [0, 0, -3], + "cubes": [ + {"origin": [-0.9, 22.4, 3.4], "size": [2, 1, 3], "uv": [0, 20]} + ] + }, + { + "name": "CordeDroite", + "parent": "Balliste", + "pivot": [-17.5, 23, 3.3], + "cubes": [ + {"origin": [-17.5848, 22.5, 3.31489], "size": [18, 1, 0.03], "uv": [0, 32]} + ] + }, + { + "name": "CordeGauche", + "parent": "Balliste", + "pivot": [17.6, 22.5, 3.3], + "cubes": [ + {"origin": [-0.4152, 22.5, 3.31489], "size": [18, 1, 0.03], "uv": [0, 31]} + ] + }, + { + "name": "BallistaArrow", + "pivot": [0, 20, 0], + "cubes": [ + {"origin": [-31.4, 20.5, 17.2], "size": [34, 5, 0.03], "pivot": [0.1, 23, 17.2], "rotation": [0, -90, -45], "uv": [0, 72]}, + {"origin": [-31.4, 20.5, 17.2], "size": [34, 5, 0.03], "pivot": [0.1, 23, 17.2], "rotation": [0, -90, 45], "uv": [0, 72]}, + {"origin": [-34.4, 21, 17.2], "size": [4, 4, 0.03], "pivot": [0.1, 23, 17.2], "rotation": [0, -90, 45], "uv": [76, 72]}, + {"origin": [-34.4, 21, 17.2], "size": [4, 4, 0.03], "pivot": [0.1, 23, 17.2], "rotation": [0, -90, -45], "uv": [68, 72]} + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/geo/battering_ram.geo.json b/src/main/resources/assets/siegemachines/geo/battering_ram.geo.json new file mode 100644 index 0000000..e5e483a --- /dev/null +++ b/src/main/resources/assets/siegemachines/geo/battering_ram.geo.json @@ -0,0 +1,294 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.unknown", + "texture_width": 512, + "texture_height": 512, + "visible_bounds_width": 7, + "visible_bounds_height": 4.5, + "visible_bounds_offset": [0, 1.75, 0] + }, + "bones": [ + { + "name": "Structure", + "pivot": [-0.51631, 26.92321, 0.01667], + "cubes": [ + {"origin": [-24.5, 5.5, -37.4], "size": [2, 2, 2], "uv": [44, 112]}, + {"origin": [21.5, 5.5, -37.4], "size": [2, 2, 2], "uv": [152, 0]}, + {"origin": [21.5, 5.5, -1], "size": [2, 2, 2], "uv": [40, 149]}, + {"origin": [21.5, 5.5, 35.6], "size": [2, 2, 2], "uv": [59, 112]}, + {"origin": [-24.5, 5.5, -1], "size": [2, 2, 2], "uv": [32, 112]}, + {"origin": [-24.5, 5.5, 35.6], "size": [2, 2, 2], "uv": [20, 112]}, + {"origin": [17, 4, -40], "size": [4, 5, 80], "uv": [168, 256]}, + {"origin": [-18, 4.5, -1.5], "size": [35, 4, 3], "uv": [0, 41]}, + {"origin": [-18, 4.6, -38], "size": [35, 4, 3], "uv": [0, 27]}, + {"origin": [-18, 4.5, 35], "size": [35, 4, 3], "uv": [0, 34]}, + {"origin": [-18, 32.5, 33], "size": [35, 4, 5], "uv": [0, 18]}, + {"origin": [-18, 32.5, -38], "size": [35, 4, 5], "uv": [0, 9]}, + {"origin": [-18, 32.5, -2.5], "size": [35, 4, 5], "uv": [0, 0]}, + {"origin": [-28.5, 46.5, -1], "size": [32, 4, 2], "pivot": [-1, 38.5, 0], "rotation": [0, 0, -30], "uv": [0, 106]}, + {"origin": [-4.5, 46.5, -1], "size": [32, 4, 2], "pivot": [0, 38.5, 0], "rotation": [0, 0, 30], "uv": [0, 100]}, + {"origin": [-4.5, 46.5, -36.5], "size": [32, 4, 2], "pivot": [0, 38.5, -35.5], "rotation": [0, 0, 30], "uv": [0, 88]}, + {"origin": [-28.5, 46.5, -36.5], "size": [32, 4, 2], "pivot": [-1, 38.5, -35.5], "rotation": [0, 0, -30], "uv": [0, 94]}, + {"origin": [-4.5, 46.5, 34.5], "size": [32, 4, 2], "pivot": [0, 38.5, 35.5], "rotation": [0, 0, 30], "uv": [0, 72]}, + {"origin": [-28.5, 46.5, 34.5], "size": [32, 4, 2], "pivot": [-1, 38.5, 35.5], "rotation": [0, 0, -30], "uv": [0, 82]}, + {"origin": [-26.5, 49, -40.5], "size": [30, 1, 81], "pivot": [-1, 38.5, 35.5], "rotation": [0, 0, -30], "uv": [0, 82]}, + {"origin": [-4.5, 49, -40.5], "size": [30, 1, 81], "pivot": [0, 38.5, 35.5], "rotation": [0, 0, 30], "uv": [0, 0]}, + {"origin": [-4.5, 46.5, 17], "size": [32, 4, 2], "pivot": [0, 38.5, 18], "rotation": [0, 0, 30], "uv": [0, 60]}, + {"origin": [-28.5, 46.5, 17], "size": [32, 4, 2], "pivot": [-1, 38.5, 18], "rotation": [0, 0, -30], "uv": [0, 66]}, + {"origin": [-4.5, 46.5, -19], "size": [32, 4, 2], "pivot": [0, 38.5, -18], "rotation": [0, 0, 30], "uv": [0, 48]}, + {"origin": [-28.5, 46.5, -19], "size": [32, 4, 2], "pivot": [-1, 38.5, -18], "rotation": [0, 0, -30], "uv": [0, 54]}, + {"origin": [17, 32, -40], "size": [4, 5, 80], "uv": [236, 0]}, + {"origin": [-22, 32, -40], "size": [4, 5, 80], "uv": [172, 171]}, + {"origin": [-2.5, 47, -41], "size": [4, 7, 82], "uv": [0, 164]}, + {"origin": [-2.5, 36, -37.5], "size": [4, 11, 4], "uv": [157, 35]}, + {"origin": [-2.5, 36, 33.5], "size": [4, 11, 4], "uv": [157, 20]}, + {"origin": [-2.5, 36, -2], "size": [4, 11, 4], "uv": [62, 147]}, + {"origin": [-22, 4, -40], "size": [4, 5, 80], "uv": [0, 253]}, + {"origin": [-21.5, 9, 34], "size": [3, 23, 5], "uv": [141, 110]}, + {"origin": [17.5, 9, 34], "size": [3, 23, 5], "uv": [141, 82]}, + {"origin": [18, 9.7868, 11.95837], "size": [2, 33, 4], "pivot": [1, 10.7868, 9.95837], "rotation": [-45, 0, 0], "uv": [36, 112]}, + {"origin": [-21, 9.7868, 11.95837], "size": [2, 33, 4], "pivot": [1, 10.7868, 9.95837], "rotation": [-45, 0, 0], "uv": [24, 112]}, + {"origin": [18, -4.94975, -35.43554], "size": [2, 33, 4], "pivot": [1.5, 27.05025, -37.43554], "rotation": [45, 0, 0], "uv": [0, 112]}, + {"origin": [-21, -4.94975, -35.43554], "size": [2, 33, 4], "pivot": [1.5, 27.05025, -37.43554], "rotation": [45, 0, 0], "uv": [68, 82]}, + {"origin": [17.5, 9, -2.5], "size": [3, 23, 5], "uv": [141, 0]}, + {"origin": [-21.5, 9, -2.5], "size": [3, 23, 5], "uv": [141, 28]}, + {"origin": [17.5, 9, -38.9], "size": [3, 23, 5], "uv": [48, 112]}, + {"origin": [-21.5, 9, -38.9], "size": [3, 23, 5], "uv": [64, 119]}, + {"origin": [-23.5, 21, -36.5], "size": [3, 13, 2], "pivot": [-17, 20.5, -35.5], "rotation": [0, 0, 45], "uv": [20, 164]}, + {"origin": [-23.5, 21, -1], "size": [3, 13, 2], "pivot": [-17, 20.5, -35.5], "rotation": [0, 0, 45], "uv": [10, 164]}, + {"origin": [-23.5, 21, 34.5], "size": [3, 13, 2], "pivot": [-17, 20.5, -35.5], "rotation": [0, 0, 45], "uv": [0, 164]}, + {"origin": [38.8, -13.9, 34.5], "size": [3, 13, 2], "pivot": [-17, -20.4, -35.5], "rotation": [0, 0, -45], "uv": [68, 48]}, + {"origin": [38.8, -13.9, -1], "size": [3, 13, 2], "pivot": [-17, -20.4, -35.5], "rotation": [0, 0, -45], "uv": [68, 48]}, + {"origin": [38.8, -13.9, -36.5], "size": [3, 13, 2], "pivot": [-17, -20.4, -35.5], "rotation": [0, 0, -45], "uv": [68, 63]} + ] + }, + { + "name": "Ram", + "pivot": [-0.47327, 15.57665, -1.94129], + "cubes": [ + {"origin": [-4, 12.2, -48], "size": [7, 7, 85], "uv": [137, 79]}, + {"origin": [-4.5, 11.7, -34.5], "size": [8, 8, 2], "uv": [157, 92]}, + {"origin": [-4.5, 11.7, -47], "size": [8, 8, 2], "uv": [0, 149]}, + {"origin": [-4.5, 11.7, 3.5], "size": [8, 8, 2], "uv": [157, 82]}, + {"origin": [-4.5, 11.7, -16.5], "size": [8, 8, 2], "uv": [20, 149]}, + {"origin": [-4.5, 11.7, 20.5], "size": [8, 8, 2], "uv": [155, 153]}, + {"origin": [-4.5, 11.7, 32], "size": [8, 8, 2], "uv": [155, 71]}, + {"origin": [-5.75, 16.85, 21], "size": [2, 1, 1], "pivot": [-5.89368, 17.83599, 21.5], "rotation": [0, 0, -22.5], "uv": [6, 78]}, + {"origin": [-6.27846, 13.0441, 20.999], "size": [1, 5, 1], "uv": [64, 116]}, + {"origin": [-5.20971, 13.17119, 21], "size": [2, 1, 1], "pivot": [-5.60971, 14.47119, 21.5], "rotation": [0, 0, 22.5], "uv": [12, 78]}, + {"origin": [-5.20971, 13.17119, 4], "size": [2, 1, 1], "pivot": [-5.60971, 14.47119, 4.5], "rotation": [0, 0, 22.5], "uv": [54, 78]}, + {"origin": [-6.27846, 13.0441, 3.999], "size": [1, 5, 1], "uv": [171, 124]}, + {"origin": [-5.75, 16.85, 4], "size": [2, 1, 1], "pivot": [-5.89368, 17.83599, 4.5], "rotation": [0, 0, -22.5], "uv": [60, 78]}, + {"origin": [-5.75, 16.85, -16], "size": [2, 1, 1], "pivot": [-5.89368, 17.83599, -15.5], "rotation": [0, 0, -22.5], "uv": [48, 78]}, + {"origin": [-6.37846, 13.0441, -16.001], "size": [1, 5, 1], "uv": [164, 132]}, + {"origin": [-5.20971, 13.17119, -16], "size": [2, 1, 1], "pivot": [-5.60971, 14.47119, -15.5], "rotation": [0, 0, 22.5], "uv": [42, 78]}, + {"origin": [-5.75, 16.85, -34], "size": [2, 1, 1], "pivot": [-5.89368, 17.83599, -33.5], "rotation": [0, 0, -22.5], "uv": [66, 78]}, + {"origin": [-6.37846, 13.0441, -34.001], "size": [1, 5, 1], "uv": [179, 26]}, + {"origin": [-5.20971, 13.17119, -34], "size": [2, 1, 1], "pivot": [-5.60971, 14.47119, -33.5], "rotation": [0, 0, 22.5], "uv": [72, 78]}, + {"origin": [2.2, 12.9, -34], "size": [2, 1, 1], "pivot": [4, 14.5, -33.5], "rotation": [0, 0, -22.5], "uv": [28, 159]}, + {"origin": [4.43126, 13.04405, -34.001], "size": [1, 5, 1], "uv": [179, 32]}, + {"origin": [1.45, 17, -34], "size": [2, 1, 1], "pivot": [4, 14.5, -33.5], "rotation": [0, 0, 22.5], "uv": [22, 159]}, + {"origin": [1.45, 17, -16], "size": [2, 1, 1], "pivot": [4, 14.5, -15.5], "rotation": [0, 0, 22.5], "uv": [36, 78]}, + {"origin": [4.43126, 13.04405, -16.001], "size": [1, 5, 1], "uv": [164, 50]}, + {"origin": [2.2, 12.9, -16], "size": [2, 1, 1], "pivot": [4, 14.5, -15.5], "rotation": [0, 0, -22.5], "uv": [30, 78]}, + {"origin": [1.45, 17, 4], "size": [2, 1, 1], "pivot": [4, 14.5, 4.5], "rotation": [0, 0, 22.5], "uv": [152, 82]}, + {"origin": [4.43126, 13.04405, 4.001], "size": [1, 5, 1], "uv": [30, 179]}, + {"origin": [2.2, 12.9, 4], "size": [2, 1, 1], "pivot": [4, 14.5, 4.5], "rotation": [0, 0, -22.5], "uv": [66, 82]}, + {"origin": [1.45, 17, 21], "size": [2, 1, 1], "pivot": [4, 14.5, 21.5], "rotation": [0, 0, 22.5], "uv": [18, 78]}, + {"origin": [4.43126, 13.04405, 21.001], "size": [1, 5, 1], "uv": [44, 153]}, + {"origin": [2.2, 12.9, 21], "size": [2, 1, 1], "pivot": [4, 14.5, 21.5], "rotation": [0, 0, -22.5], "uv": [24, 78]}, + {"origin": [-1, 16.7, 37], "size": [1, 2, 1], "uv": [48, 140]}, + {"origin": [-1, 13.7, 38], "size": [1, 4, 1], "uv": [0, 0]}, + {"origin": [-1, 12.7, 37], "size": [1, 2, 1], "uv": [141, 0]} + ] + }, + { + "name": "RamHead", + "parent": "Ram", + "pivot": [-0.5, 15.7, -48.5], + "cubes": [ + {"origin": [-3.5, 12.7, -49], "size": [6, 6, 1], "pivot": [-0.5, 15.7, -48.5], "rotation": [0, 0, 45], "uv": [169, 132]}, + {"origin": [-3, 13.2, -50], "size": [5, 5, 2], "uv": [167, 102]}, + {"origin": [-2.5, 14.6, -53], "size": [4, 4, 5], "uv": [157, 115]}, + {"origin": [-3, 14.7, -57], "size": [5, 5, 4], "uv": [153, 106]}, + {"origin": [-2, 11.68577, -56.55346], "size": [3, 4, 4], "pivot": [-2, 14.18577, -54.55346], "rotation": [25, 0, 0], "uv": [157, 124]}, + {"origin": [-3.5, 17.9802, -56.97694], "size": [1, 2, 2], "pivot": [-4.04095, 18.89274, -44.46597], "rotation": [0, 0, 0], "uv": [18, 159]}, + {"origin": [-3.8, 25.75482, -53.19506], "size": [1, 2, 2], "pivot": [-4.04095, 18.89274, -44.46597], "rotation": [40, 0, 0], "uv": [12, 159]}, + {"origin": [-4.3, 27.90091, -46.10157], "size": [1, 2, 2], "pivot": [-4.04095, 18.89274, -44.46597], "rotation": [80, 0, 0], "uv": [6, 159]}, + {"origin": [-4.5, 23.04473, -52.89218], "size": [1, 2, 2], "pivot": [-4.04095, 18.89274, -44.46597], "rotation": [32.5, 0, 0], "uv": [0, 159]}, + {"origin": [-4.7, 8.59591, -48.77453], "size": [1, 2, 1], "pivot": [-4.04095, 18.89274, -44.46597], "rotation": [-51, 0, 0], "uv": [0, 112]}, + {"origin": [-4.5, 7.79591, -49.17453], "size": [1, 2, 1], "pivot": [-4.04095, 18.89274, -44.46597], "rotation": [-51, 0, 0], "uv": [76, 82]}, + {"origin": [-4.7, 15.75231, -54.13208], "size": [1, 2, 2], "pivot": [-4.04095, 18.89274, -44.46597], "rotation": [-9.5, 0, 0], "uv": [147, 158]}, + {"origin": [-4.6, 11.41741, -52.67737], "size": [1, 2, 2], "pivot": [-4.04095, 18.89274, -44.46597], "rotation": [-29.5, 0, 0], "uv": [141, 158]}, + {"origin": [2.5, 14.07813, -55.42837], "size": [1, 2, 1], "pivot": [3.15, 15.47813, -54.17837], "rotation": [-51, 0, 0], "uv": [0, 18]}, + {"origin": [2.7, 14.87813, -55.02837], "size": [1, 2, 1], "pivot": [3.15, 15.47813, -54.17837], "rotation": [-51, 0, 0], "uv": [0, 9]}, + {"origin": [2.6, 15.71199, -54.1665], "size": [1, 2, 2], "pivot": [3.2, 18.21199, -53.3665], "rotation": [-29.5, 0, 0], "uv": [157, 102]}, + {"origin": [2.7, 17.24779, -54.19734], "size": [1, 2, 2], "pivot": [3, 19.24779, -53.49734], "rotation": [-9.5, 0, 0], "uv": [57, 140]}, + {"origin": [2.5, 17.4864, -53.10952], "size": [1, 2, 2], "pivot": [3, 16.4864, -54.10952], "rotation": [32.5, 0, 0], "uv": [75, 119]}, + {"origin": [2.3, 19.08734, -55.33398], "size": [1, 2, 2], "pivot": [2.9, 19.98734, -54.33398], "rotation": [80, 0, 0], "uv": [75, 18]}, + {"origin": [1.8, 18.79545, -54.33116], "size": [1, 2, 2], "pivot": [2.78333, 16.97378, -54.59438], "rotation": [40, 0, 0], "uv": [75, 9]}, + {"origin": [1.5, 17.9802, -56.97694], "size": [1, 2, 2], "pivot": [2.78333, 16.97378, -54.59438], "rotation": [0, 0, 0], "uv": [75, 0]}, + {"origin": [-3.2, 14.4, -50], "size": [4, 4, 1], "pivot": [-0.5, 15.7, -48.5], "rotation": [0, 0, 45], "uv": [141, 76]}, + {"origin": [-1.5, 14, -53], "size": [2, 1, 5], "pivot": [-0.5, 15.1, -50.5], "rotation": [-22.5, 0, 0], "uv": [35, 155]}, + {"origin": [-2.9, 15.1, -51], "size": [3, 3, 1], "pivot": [-0.5, 15.7, -48.5], "rotation": [0, 0, 45], "uv": [8, 112]}, + {"origin": [-2.7, 15.9, -52], "size": [2, 2, 1], "pivot": [-0.5, 15.7, -48.5], "rotation": [0, 0, 45], "uv": [0, 78]} + ] + }, + { + "name": "FirstDuoRopes", + "pivot": [-0.4, 34, -35] + }, + { + "name": "Rope1", + "parent": "FirstDuoRopes", + "pivot": [-12.05025, 22.62132, -1], + "cubes": [ + {"origin": [-6.61724, 17.23735, -35.3], "size": [1, 17, 0], "pivot": [-6.11724, 26.23735, -35.3], "rotation": [0, 0, -22.5], "uv": [76, 27]} + ] + }, + { + "name": "Rope4", + "parent": "FirstDuoRopes", + "pivot": [0, 0, 0], + "cubes": [ + {"origin": [4.70405, 17.41619, -35.5], "size": [1, 16, 0], "pivot": [5.20405, 25.41619, -35.5], "rotation": [0, 0, 22.5], "uv": [78, 61]} + ] + }, + { + "name": "SecondDuoRopes", + "pivot": [-0.4, 34, 0] + }, + { + "name": "Rope2", + "parent": "SecondDuoRopes", + "pivot": [-12.05025, 22.62132, -1], + "cubes": [ + {"origin": [-6.61724, 17.23735, 0.2], "size": [1, 17, 0], "pivot": [-6.11724, 26.23735, 0.2], "rotation": [0, 0, -22.5], "uv": [78, 27]} + ] + }, + { + "name": "Rope5", + "parent": "SecondDuoRopes", + "pivot": [0, 0, 0], + "cubes": [ + {"origin": [4.70405, 17.41619, -0.2], "size": [1, 16, 0], "pivot": [5.20405, 25.41619, -0.2], "rotation": [0, 0, 22.5], "uv": [78, 147]} + ] + }, + { + "name": "ThirdDuoRopes", + "pivot": [-0.4, 34, 35] + }, + { + "name": "Rope3", + "parent": "ThirdDuoRopes", + "pivot": [-7.05025, 25.62132, 70], + "rotation": [0, 0, 40], + "cubes": [ + {"origin": [-0.44646, 20.25331, 35.5], "size": [1, 17, 0], "pivot": [-0.41995, 22.40128, -44.46597], "rotation": [0, 0, -60], "uv": [78, 44]} + ] + }, + { + "name": "Rope6", + "parent": "ThirdDuoRopes", + "pivot": [0, 0, 0], + "cubes": [ + {"origin": [4.87033, 17.90959, 35.3], "size": [1, 16, 0], "pivot": [5.37033, 25.90959, 35.3], "rotation": [0, 0, 22.5], "uv": [78, 164]} + ] + }, + { + "name": "Wheel1", + "pivot": [22, 6.5, 36.6], + "cubes": [ + {"origin": [21, 4, 29.1], "size": [2, 5, 1], "uv": [169, 65]}, + {"origin": [21, 2, 30.1], "size": [2, 9, 1], "uv": [171, 109]}, + {"origin": [21, 1, 31.1], "size": [2, 11, 1], "uv": [130, 164]}, + {"origin": [21, 0, 32.1], "size": [2, 13, 2], "uv": [30, 164]}, + {"origin": [21, -1, 34.1], "size": [2, 15, 5], "uv": [48, 140]}, + {"origin": [21, 0, 39.1], "size": [2, 13, 2], "uv": [38, 164]}, + {"origin": [21, 1, 41.1], "size": [2, 11, 1], "uv": [169, 139]}, + {"origin": [21, 2, 42.1], "size": [2, 9, 1], "uv": [173, 36]}, + {"origin": [21, 4, 43.1], "size": [2, 5, 1], "uv": [175, 75]} + ] + }, + { + "name": "Wheel2", + "pivot": [22, 6.5, 0], + "cubes": [ + {"origin": [21, 4, -7.5], "size": [2, 5, 1], "uv": [177, 56]}, + {"origin": [21, 2, -6.5], "size": [2, 9, 1], "uv": [175, 65]}, + {"origin": [21, 1, -5.5], "size": [2, 11, 1], "uv": [171, 0]}, + {"origin": [21, 0, -4.5], "size": [2, 13, 2], "uv": [46, 164]}, + {"origin": [21, -1, -2.5], "size": [2, 15, 5], "uv": [141, 56]}, + {"origin": [21, 0, 2.5], "size": [2, 13, 2], "uv": [54, 164]}, + {"origin": [21, 1, 4.5], "size": [2, 11, 1], "uv": [171, 12]}, + {"origin": [21, 2, 5.5], "size": [2, 9, 1], "uv": [175, 119]}, + {"origin": [21, 4, 6.5], "size": [2, 5, 1], "uv": [177, 109]} + ] + }, + { + "name": "Wheel3", + "pivot": [22, 6.5, -36.4], + "cubes": [ + {"origin": [21, 4, -29.9], "size": [2, 5, 1], "uv": [178, 171]}, + {"origin": [21, 2, -30.9], "size": [2, 9, 1], "uv": [175, 139]}, + {"origin": [21, 1, -31.9], "size": [2, 11, 1], "uv": [136, 171]}, + {"origin": [21, 0, -33.9], "size": [2, 13, 2], "uv": [62, 164]}, + {"origin": [21, -1, -38.9], "size": [2, 15, 5], "uv": [141, 138]}, + {"origin": [21, 0, -40.9], "size": [2, 13, 2], "uv": [70, 164]}, + {"origin": [21, 1, -41.9], "size": [2, 11, 1], "uv": [142, 171]}, + {"origin": [21, 2, -42.9], "size": [2, 9, 1], "uv": [175, 149]}, + {"origin": [21, 4, -43.9], "size": [2, 5, 1], "uv": [178, 177]} + ] + }, + { + "name": "Wheel4", + "pivot": [-23, 6.5, 36.6], + "cubes": [ + {"origin": [-24, 1, 41.1], "size": [2, 11, 1], "uv": [154, 171]}, + {"origin": [-24, 2, 42.1], "size": [2, 9, 1], "uv": [177, 0]}, + {"origin": [-24, 0, 39.1], "size": [2, 13, 2], "uv": [98, 164]}, + {"origin": [-24, -1, 34.1], "size": [2, 15, 5], "uv": [155, 51]}, + {"origin": [-24, 0, 32.1], "size": [2, 13, 2], "uv": [90, 164]}, + {"origin": [-24, 1, 31.1], "size": [2, 11, 1], "uv": [148, 171]}, + {"origin": [-24, 2, 30.1], "size": [2, 9, 1], "uv": [130, 176]}, + {"origin": [-24, 4, 29.1], "size": [2, 5, 1], "uv": [0, 179]}, + {"origin": [-24, 4, 43.1], "size": [2, 5, 1], "uv": [6, 179]} + ] + }, + { + "name": "Wheel5", + "pivot": [-23, 6.5, 0], + "cubes": [ + {"origin": [-24, 4, 6.5], "size": [2, 5, 1], "uv": [24, 179]}, + {"origin": [-24, 1, 4.5], "size": [2, 11, 1], "uv": [173, 24]}, + {"origin": [-24, 2, 5.5], "size": [2, 9, 1], "uv": [177, 82]}, + {"origin": [-24, 0, 2.5], "size": [2, 13, 2], "uv": [122, 164]}, + {"origin": [-24, -1, -2.5], "size": [2, 15, 5], "uv": [157, 0]}, + {"origin": [-24, 0, -4.5], "size": [2, 13, 2], "uv": [169, 50]}, + {"origin": [-24, 1, -5.5], "size": [2, 11, 1], "uv": [172, 171]}, + {"origin": [-24, 2, -6.5], "size": [2, 9, 1], "uv": [177, 92]}, + {"origin": [-24, 4, -7.5], "size": [2, 5, 1], "uv": [179, 20]} + ] + }, + { + "name": "Wheel6", + "pivot": [-23, 6.5, -36.4], + "cubes": [ + {"origin": [-24, 4, -29.9], "size": [2, 5, 1], "uv": [18, 179]}, + {"origin": [-24, 2, -30.9], "size": [2, 9, 1], "uv": [177, 46]}, + {"origin": [-24, 1, -31.9], "size": [2, 11, 1], "uv": [166, 171]}, + {"origin": [-24, 0, -33.9], "size": [2, 13, 2], "uv": [114, 164]}, + {"origin": [-24, -1, -38.9], "size": [2, 15, 5], "uv": [155, 133]}, + {"origin": [-24, 0, -40.9], "size": [2, 13, 2], "uv": [106, 164]}, + {"origin": [-24, 1, -41.9], "size": [2, 11, 1], "uv": [160, 171]}, + {"origin": [-24, 2, -42.9], "size": [2, 9, 1], "uv": [177, 10]}, + {"origin": [-24, 4, -43.9], "size": [2, 5, 1], "uv": [12, 179]} + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/geo/battering_ram_item.geo.json b/src/main/resources/assets/siegemachines/geo/battering_ram_item.geo.json new file mode 100644 index 0000000..e5e483a --- /dev/null +++ b/src/main/resources/assets/siegemachines/geo/battering_ram_item.geo.json @@ -0,0 +1,294 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.unknown", + "texture_width": 512, + "texture_height": 512, + "visible_bounds_width": 7, + "visible_bounds_height": 4.5, + "visible_bounds_offset": [0, 1.75, 0] + }, + "bones": [ + { + "name": "Structure", + "pivot": [-0.51631, 26.92321, 0.01667], + "cubes": [ + {"origin": [-24.5, 5.5, -37.4], "size": [2, 2, 2], "uv": [44, 112]}, + {"origin": [21.5, 5.5, -37.4], "size": [2, 2, 2], "uv": [152, 0]}, + {"origin": [21.5, 5.5, -1], "size": [2, 2, 2], "uv": [40, 149]}, + {"origin": [21.5, 5.5, 35.6], "size": [2, 2, 2], "uv": [59, 112]}, + {"origin": [-24.5, 5.5, -1], "size": [2, 2, 2], "uv": [32, 112]}, + {"origin": [-24.5, 5.5, 35.6], "size": [2, 2, 2], "uv": [20, 112]}, + {"origin": [17, 4, -40], "size": [4, 5, 80], "uv": [168, 256]}, + {"origin": [-18, 4.5, -1.5], "size": [35, 4, 3], "uv": [0, 41]}, + {"origin": [-18, 4.6, -38], "size": [35, 4, 3], "uv": [0, 27]}, + {"origin": [-18, 4.5, 35], "size": [35, 4, 3], "uv": [0, 34]}, + {"origin": [-18, 32.5, 33], "size": [35, 4, 5], "uv": [0, 18]}, + {"origin": [-18, 32.5, -38], "size": [35, 4, 5], "uv": [0, 9]}, + {"origin": [-18, 32.5, -2.5], "size": [35, 4, 5], "uv": [0, 0]}, + {"origin": [-28.5, 46.5, -1], "size": [32, 4, 2], "pivot": [-1, 38.5, 0], "rotation": [0, 0, -30], "uv": [0, 106]}, + {"origin": [-4.5, 46.5, -1], "size": [32, 4, 2], "pivot": [0, 38.5, 0], "rotation": [0, 0, 30], "uv": [0, 100]}, + {"origin": [-4.5, 46.5, -36.5], "size": [32, 4, 2], "pivot": [0, 38.5, -35.5], "rotation": [0, 0, 30], "uv": [0, 88]}, + {"origin": [-28.5, 46.5, -36.5], "size": [32, 4, 2], "pivot": [-1, 38.5, -35.5], "rotation": [0, 0, -30], "uv": [0, 94]}, + {"origin": [-4.5, 46.5, 34.5], "size": [32, 4, 2], "pivot": [0, 38.5, 35.5], "rotation": [0, 0, 30], "uv": [0, 72]}, + {"origin": [-28.5, 46.5, 34.5], "size": [32, 4, 2], "pivot": [-1, 38.5, 35.5], "rotation": [0, 0, -30], "uv": [0, 82]}, + {"origin": [-26.5, 49, -40.5], "size": [30, 1, 81], "pivot": [-1, 38.5, 35.5], "rotation": [0, 0, -30], "uv": [0, 82]}, + {"origin": [-4.5, 49, -40.5], "size": [30, 1, 81], "pivot": [0, 38.5, 35.5], "rotation": [0, 0, 30], "uv": [0, 0]}, + {"origin": [-4.5, 46.5, 17], "size": [32, 4, 2], "pivot": [0, 38.5, 18], "rotation": [0, 0, 30], "uv": [0, 60]}, + {"origin": [-28.5, 46.5, 17], "size": [32, 4, 2], "pivot": [-1, 38.5, 18], "rotation": [0, 0, -30], "uv": [0, 66]}, + {"origin": [-4.5, 46.5, -19], "size": [32, 4, 2], "pivot": [0, 38.5, -18], "rotation": [0, 0, 30], "uv": [0, 48]}, + {"origin": [-28.5, 46.5, -19], "size": [32, 4, 2], "pivot": [-1, 38.5, -18], "rotation": [0, 0, -30], "uv": [0, 54]}, + {"origin": [17, 32, -40], "size": [4, 5, 80], "uv": [236, 0]}, + {"origin": [-22, 32, -40], "size": [4, 5, 80], "uv": [172, 171]}, + {"origin": [-2.5, 47, -41], "size": [4, 7, 82], "uv": [0, 164]}, + {"origin": [-2.5, 36, -37.5], "size": [4, 11, 4], "uv": [157, 35]}, + {"origin": [-2.5, 36, 33.5], "size": [4, 11, 4], "uv": [157, 20]}, + {"origin": [-2.5, 36, -2], "size": [4, 11, 4], "uv": [62, 147]}, + {"origin": [-22, 4, -40], "size": [4, 5, 80], "uv": [0, 253]}, + {"origin": [-21.5, 9, 34], "size": [3, 23, 5], "uv": [141, 110]}, + {"origin": [17.5, 9, 34], "size": [3, 23, 5], "uv": [141, 82]}, + {"origin": [18, 9.7868, 11.95837], "size": [2, 33, 4], "pivot": [1, 10.7868, 9.95837], "rotation": [-45, 0, 0], "uv": [36, 112]}, + {"origin": [-21, 9.7868, 11.95837], "size": [2, 33, 4], "pivot": [1, 10.7868, 9.95837], "rotation": [-45, 0, 0], "uv": [24, 112]}, + {"origin": [18, -4.94975, -35.43554], "size": [2, 33, 4], "pivot": [1.5, 27.05025, -37.43554], "rotation": [45, 0, 0], "uv": [0, 112]}, + {"origin": [-21, -4.94975, -35.43554], "size": [2, 33, 4], "pivot": [1.5, 27.05025, -37.43554], "rotation": [45, 0, 0], "uv": [68, 82]}, + {"origin": [17.5, 9, -2.5], "size": [3, 23, 5], "uv": [141, 0]}, + {"origin": [-21.5, 9, -2.5], "size": [3, 23, 5], "uv": [141, 28]}, + {"origin": [17.5, 9, -38.9], "size": [3, 23, 5], "uv": [48, 112]}, + {"origin": [-21.5, 9, -38.9], "size": [3, 23, 5], "uv": [64, 119]}, + {"origin": [-23.5, 21, -36.5], "size": [3, 13, 2], "pivot": [-17, 20.5, -35.5], "rotation": [0, 0, 45], "uv": [20, 164]}, + {"origin": [-23.5, 21, -1], "size": [3, 13, 2], "pivot": [-17, 20.5, -35.5], "rotation": [0, 0, 45], "uv": [10, 164]}, + {"origin": [-23.5, 21, 34.5], "size": [3, 13, 2], "pivot": [-17, 20.5, -35.5], "rotation": [0, 0, 45], "uv": [0, 164]}, + {"origin": [38.8, -13.9, 34.5], "size": [3, 13, 2], "pivot": [-17, -20.4, -35.5], "rotation": [0, 0, -45], "uv": [68, 48]}, + {"origin": [38.8, -13.9, -1], "size": [3, 13, 2], "pivot": [-17, -20.4, -35.5], "rotation": [0, 0, -45], "uv": [68, 48]}, + {"origin": [38.8, -13.9, -36.5], "size": [3, 13, 2], "pivot": [-17, -20.4, -35.5], "rotation": [0, 0, -45], "uv": [68, 63]} + ] + }, + { + "name": "Ram", + "pivot": [-0.47327, 15.57665, -1.94129], + "cubes": [ + {"origin": [-4, 12.2, -48], "size": [7, 7, 85], "uv": [137, 79]}, + {"origin": [-4.5, 11.7, -34.5], "size": [8, 8, 2], "uv": [157, 92]}, + {"origin": [-4.5, 11.7, -47], "size": [8, 8, 2], "uv": [0, 149]}, + {"origin": [-4.5, 11.7, 3.5], "size": [8, 8, 2], "uv": [157, 82]}, + {"origin": [-4.5, 11.7, -16.5], "size": [8, 8, 2], "uv": [20, 149]}, + {"origin": [-4.5, 11.7, 20.5], "size": [8, 8, 2], "uv": [155, 153]}, + {"origin": [-4.5, 11.7, 32], "size": [8, 8, 2], "uv": [155, 71]}, + {"origin": [-5.75, 16.85, 21], "size": [2, 1, 1], "pivot": [-5.89368, 17.83599, 21.5], "rotation": [0, 0, -22.5], "uv": [6, 78]}, + {"origin": [-6.27846, 13.0441, 20.999], "size": [1, 5, 1], "uv": [64, 116]}, + {"origin": [-5.20971, 13.17119, 21], "size": [2, 1, 1], "pivot": [-5.60971, 14.47119, 21.5], "rotation": [0, 0, 22.5], "uv": [12, 78]}, + {"origin": [-5.20971, 13.17119, 4], "size": [2, 1, 1], "pivot": [-5.60971, 14.47119, 4.5], "rotation": [0, 0, 22.5], "uv": [54, 78]}, + {"origin": [-6.27846, 13.0441, 3.999], "size": [1, 5, 1], "uv": [171, 124]}, + {"origin": [-5.75, 16.85, 4], "size": [2, 1, 1], "pivot": [-5.89368, 17.83599, 4.5], "rotation": [0, 0, -22.5], "uv": [60, 78]}, + {"origin": [-5.75, 16.85, -16], "size": [2, 1, 1], "pivot": [-5.89368, 17.83599, -15.5], "rotation": [0, 0, -22.5], "uv": [48, 78]}, + {"origin": [-6.37846, 13.0441, -16.001], "size": [1, 5, 1], "uv": [164, 132]}, + {"origin": [-5.20971, 13.17119, -16], "size": [2, 1, 1], "pivot": [-5.60971, 14.47119, -15.5], "rotation": [0, 0, 22.5], "uv": [42, 78]}, + {"origin": [-5.75, 16.85, -34], "size": [2, 1, 1], "pivot": [-5.89368, 17.83599, -33.5], "rotation": [0, 0, -22.5], "uv": [66, 78]}, + {"origin": [-6.37846, 13.0441, -34.001], "size": [1, 5, 1], "uv": [179, 26]}, + {"origin": [-5.20971, 13.17119, -34], "size": [2, 1, 1], "pivot": [-5.60971, 14.47119, -33.5], "rotation": [0, 0, 22.5], "uv": [72, 78]}, + {"origin": [2.2, 12.9, -34], "size": [2, 1, 1], "pivot": [4, 14.5, -33.5], "rotation": [0, 0, -22.5], "uv": [28, 159]}, + {"origin": [4.43126, 13.04405, -34.001], "size": [1, 5, 1], "uv": [179, 32]}, + {"origin": [1.45, 17, -34], "size": [2, 1, 1], "pivot": [4, 14.5, -33.5], "rotation": [0, 0, 22.5], "uv": [22, 159]}, + {"origin": [1.45, 17, -16], "size": [2, 1, 1], "pivot": [4, 14.5, -15.5], "rotation": [0, 0, 22.5], "uv": [36, 78]}, + {"origin": [4.43126, 13.04405, -16.001], "size": [1, 5, 1], "uv": [164, 50]}, + {"origin": [2.2, 12.9, -16], "size": [2, 1, 1], "pivot": [4, 14.5, -15.5], "rotation": [0, 0, -22.5], "uv": [30, 78]}, + {"origin": [1.45, 17, 4], "size": [2, 1, 1], "pivot": [4, 14.5, 4.5], "rotation": [0, 0, 22.5], "uv": [152, 82]}, + {"origin": [4.43126, 13.04405, 4.001], "size": [1, 5, 1], "uv": [30, 179]}, + {"origin": [2.2, 12.9, 4], "size": [2, 1, 1], "pivot": [4, 14.5, 4.5], "rotation": [0, 0, -22.5], "uv": [66, 82]}, + {"origin": [1.45, 17, 21], "size": [2, 1, 1], "pivot": [4, 14.5, 21.5], "rotation": [0, 0, 22.5], "uv": [18, 78]}, + {"origin": [4.43126, 13.04405, 21.001], "size": [1, 5, 1], "uv": [44, 153]}, + {"origin": [2.2, 12.9, 21], "size": [2, 1, 1], "pivot": [4, 14.5, 21.5], "rotation": [0, 0, -22.5], "uv": [24, 78]}, + {"origin": [-1, 16.7, 37], "size": [1, 2, 1], "uv": [48, 140]}, + {"origin": [-1, 13.7, 38], "size": [1, 4, 1], "uv": [0, 0]}, + {"origin": [-1, 12.7, 37], "size": [1, 2, 1], "uv": [141, 0]} + ] + }, + { + "name": "RamHead", + "parent": "Ram", + "pivot": [-0.5, 15.7, -48.5], + "cubes": [ + {"origin": [-3.5, 12.7, -49], "size": [6, 6, 1], "pivot": [-0.5, 15.7, -48.5], "rotation": [0, 0, 45], "uv": [169, 132]}, + {"origin": [-3, 13.2, -50], "size": [5, 5, 2], "uv": [167, 102]}, + {"origin": [-2.5, 14.6, -53], "size": [4, 4, 5], "uv": [157, 115]}, + {"origin": [-3, 14.7, -57], "size": [5, 5, 4], "uv": [153, 106]}, + {"origin": [-2, 11.68577, -56.55346], "size": [3, 4, 4], "pivot": [-2, 14.18577, -54.55346], "rotation": [25, 0, 0], "uv": [157, 124]}, + {"origin": [-3.5, 17.9802, -56.97694], "size": [1, 2, 2], "pivot": [-4.04095, 18.89274, -44.46597], "rotation": [0, 0, 0], "uv": [18, 159]}, + {"origin": [-3.8, 25.75482, -53.19506], "size": [1, 2, 2], "pivot": [-4.04095, 18.89274, -44.46597], "rotation": [40, 0, 0], "uv": [12, 159]}, + {"origin": [-4.3, 27.90091, -46.10157], "size": [1, 2, 2], "pivot": [-4.04095, 18.89274, -44.46597], "rotation": [80, 0, 0], "uv": [6, 159]}, + {"origin": [-4.5, 23.04473, -52.89218], "size": [1, 2, 2], "pivot": [-4.04095, 18.89274, -44.46597], "rotation": [32.5, 0, 0], "uv": [0, 159]}, + {"origin": [-4.7, 8.59591, -48.77453], "size": [1, 2, 1], "pivot": [-4.04095, 18.89274, -44.46597], "rotation": [-51, 0, 0], "uv": [0, 112]}, + {"origin": [-4.5, 7.79591, -49.17453], "size": [1, 2, 1], "pivot": [-4.04095, 18.89274, -44.46597], "rotation": [-51, 0, 0], "uv": [76, 82]}, + {"origin": [-4.7, 15.75231, -54.13208], "size": [1, 2, 2], "pivot": [-4.04095, 18.89274, -44.46597], "rotation": [-9.5, 0, 0], "uv": [147, 158]}, + {"origin": [-4.6, 11.41741, -52.67737], "size": [1, 2, 2], "pivot": [-4.04095, 18.89274, -44.46597], "rotation": [-29.5, 0, 0], "uv": [141, 158]}, + {"origin": [2.5, 14.07813, -55.42837], "size": [1, 2, 1], "pivot": [3.15, 15.47813, -54.17837], "rotation": [-51, 0, 0], "uv": [0, 18]}, + {"origin": [2.7, 14.87813, -55.02837], "size": [1, 2, 1], "pivot": [3.15, 15.47813, -54.17837], "rotation": [-51, 0, 0], "uv": [0, 9]}, + {"origin": [2.6, 15.71199, -54.1665], "size": [1, 2, 2], "pivot": [3.2, 18.21199, -53.3665], "rotation": [-29.5, 0, 0], "uv": [157, 102]}, + {"origin": [2.7, 17.24779, -54.19734], "size": [1, 2, 2], "pivot": [3, 19.24779, -53.49734], "rotation": [-9.5, 0, 0], "uv": [57, 140]}, + {"origin": [2.5, 17.4864, -53.10952], "size": [1, 2, 2], "pivot": [3, 16.4864, -54.10952], "rotation": [32.5, 0, 0], "uv": [75, 119]}, + {"origin": [2.3, 19.08734, -55.33398], "size": [1, 2, 2], "pivot": [2.9, 19.98734, -54.33398], "rotation": [80, 0, 0], "uv": [75, 18]}, + {"origin": [1.8, 18.79545, -54.33116], "size": [1, 2, 2], "pivot": [2.78333, 16.97378, -54.59438], "rotation": [40, 0, 0], "uv": [75, 9]}, + {"origin": [1.5, 17.9802, -56.97694], "size": [1, 2, 2], "pivot": [2.78333, 16.97378, -54.59438], "rotation": [0, 0, 0], "uv": [75, 0]}, + {"origin": [-3.2, 14.4, -50], "size": [4, 4, 1], "pivot": [-0.5, 15.7, -48.5], "rotation": [0, 0, 45], "uv": [141, 76]}, + {"origin": [-1.5, 14, -53], "size": [2, 1, 5], "pivot": [-0.5, 15.1, -50.5], "rotation": [-22.5, 0, 0], "uv": [35, 155]}, + {"origin": [-2.9, 15.1, -51], "size": [3, 3, 1], "pivot": [-0.5, 15.7, -48.5], "rotation": [0, 0, 45], "uv": [8, 112]}, + {"origin": [-2.7, 15.9, -52], "size": [2, 2, 1], "pivot": [-0.5, 15.7, -48.5], "rotation": [0, 0, 45], "uv": [0, 78]} + ] + }, + { + "name": "FirstDuoRopes", + "pivot": [-0.4, 34, -35] + }, + { + "name": "Rope1", + "parent": "FirstDuoRopes", + "pivot": [-12.05025, 22.62132, -1], + "cubes": [ + {"origin": [-6.61724, 17.23735, -35.3], "size": [1, 17, 0], "pivot": [-6.11724, 26.23735, -35.3], "rotation": [0, 0, -22.5], "uv": [76, 27]} + ] + }, + { + "name": "Rope4", + "parent": "FirstDuoRopes", + "pivot": [0, 0, 0], + "cubes": [ + {"origin": [4.70405, 17.41619, -35.5], "size": [1, 16, 0], "pivot": [5.20405, 25.41619, -35.5], "rotation": [0, 0, 22.5], "uv": [78, 61]} + ] + }, + { + "name": "SecondDuoRopes", + "pivot": [-0.4, 34, 0] + }, + { + "name": "Rope2", + "parent": "SecondDuoRopes", + "pivot": [-12.05025, 22.62132, -1], + "cubes": [ + {"origin": [-6.61724, 17.23735, 0.2], "size": [1, 17, 0], "pivot": [-6.11724, 26.23735, 0.2], "rotation": [0, 0, -22.5], "uv": [78, 27]} + ] + }, + { + "name": "Rope5", + "parent": "SecondDuoRopes", + "pivot": [0, 0, 0], + "cubes": [ + {"origin": [4.70405, 17.41619, -0.2], "size": [1, 16, 0], "pivot": [5.20405, 25.41619, -0.2], "rotation": [0, 0, 22.5], "uv": [78, 147]} + ] + }, + { + "name": "ThirdDuoRopes", + "pivot": [-0.4, 34, 35] + }, + { + "name": "Rope3", + "parent": "ThirdDuoRopes", + "pivot": [-7.05025, 25.62132, 70], + "rotation": [0, 0, 40], + "cubes": [ + {"origin": [-0.44646, 20.25331, 35.5], "size": [1, 17, 0], "pivot": [-0.41995, 22.40128, -44.46597], "rotation": [0, 0, -60], "uv": [78, 44]} + ] + }, + { + "name": "Rope6", + "parent": "ThirdDuoRopes", + "pivot": [0, 0, 0], + "cubes": [ + {"origin": [4.87033, 17.90959, 35.3], "size": [1, 16, 0], "pivot": [5.37033, 25.90959, 35.3], "rotation": [0, 0, 22.5], "uv": [78, 164]} + ] + }, + { + "name": "Wheel1", + "pivot": [22, 6.5, 36.6], + "cubes": [ + {"origin": [21, 4, 29.1], "size": [2, 5, 1], "uv": [169, 65]}, + {"origin": [21, 2, 30.1], "size": [2, 9, 1], "uv": [171, 109]}, + {"origin": [21, 1, 31.1], "size": [2, 11, 1], "uv": [130, 164]}, + {"origin": [21, 0, 32.1], "size": [2, 13, 2], "uv": [30, 164]}, + {"origin": [21, -1, 34.1], "size": [2, 15, 5], "uv": [48, 140]}, + {"origin": [21, 0, 39.1], "size": [2, 13, 2], "uv": [38, 164]}, + {"origin": [21, 1, 41.1], "size": [2, 11, 1], "uv": [169, 139]}, + {"origin": [21, 2, 42.1], "size": [2, 9, 1], "uv": [173, 36]}, + {"origin": [21, 4, 43.1], "size": [2, 5, 1], "uv": [175, 75]} + ] + }, + { + "name": "Wheel2", + "pivot": [22, 6.5, 0], + "cubes": [ + {"origin": [21, 4, -7.5], "size": [2, 5, 1], "uv": [177, 56]}, + {"origin": [21, 2, -6.5], "size": [2, 9, 1], "uv": [175, 65]}, + {"origin": [21, 1, -5.5], "size": [2, 11, 1], "uv": [171, 0]}, + {"origin": [21, 0, -4.5], "size": [2, 13, 2], "uv": [46, 164]}, + {"origin": [21, -1, -2.5], "size": [2, 15, 5], "uv": [141, 56]}, + {"origin": [21, 0, 2.5], "size": [2, 13, 2], "uv": [54, 164]}, + {"origin": [21, 1, 4.5], "size": [2, 11, 1], "uv": [171, 12]}, + {"origin": [21, 2, 5.5], "size": [2, 9, 1], "uv": [175, 119]}, + {"origin": [21, 4, 6.5], "size": [2, 5, 1], "uv": [177, 109]} + ] + }, + { + "name": "Wheel3", + "pivot": [22, 6.5, -36.4], + "cubes": [ + {"origin": [21, 4, -29.9], "size": [2, 5, 1], "uv": [178, 171]}, + {"origin": [21, 2, -30.9], "size": [2, 9, 1], "uv": [175, 139]}, + {"origin": [21, 1, -31.9], "size": [2, 11, 1], "uv": [136, 171]}, + {"origin": [21, 0, -33.9], "size": [2, 13, 2], "uv": [62, 164]}, + {"origin": [21, -1, -38.9], "size": [2, 15, 5], "uv": [141, 138]}, + {"origin": [21, 0, -40.9], "size": [2, 13, 2], "uv": [70, 164]}, + {"origin": [21, 1, -41.9], "size": [2, 11, 1], "uv": [142, 171]}, + {"origin": [21, 2, -42.9], "size": [2, 9, 1], "uv": [175, 149]}, + {"origin": [21, 4, -43.9], "size": [2, 5, 1], "uv": [178, 177]} + ] + }, + { + "name": "Wheel4", + "pivot": [-23, 6.5, 36.6], + "cubes": [ + {"origin": [-24, 1, 41.1], "size": [2, 11, 1], "uv": [154, 171]}, + {"origin": [-24, 2, 42.1], "size": [2, 9, 1], "uv": [177, 0]}, + {"origin": [-24, 0, 39.1], "size": [2, 13, 2], "uv": [98, 164]}, + {"origin": [-24, -1, 34.1], "size": [2, 15, 5], "uv": [155, 51]}, + {"origin": [-24, 0, 32.1], "size": [2, 13, 2], "uv": [90, 164]}, + {"origin": [-24, 1, 31.1], "size": [2, 11, 1], "uv": [148, 171]}, + {"origin": [-24, 2, 30.1], "size": [2, 9, 1], "uv": [130, 176]}, + {"origin": [-24, 4, 29.1], "size": [2, 5, 1], "uv": [0, 179]}, + {"origin": [-24, 4, 43.1], "size": [2, 5, 1], "uv": [6, 179]} + ] + }, + { + "name": "Wheel5", + "pivot": [-23, 6.5, 0], + "cubes": [ + {"origin": [-24, 4, 6.5], "size": [2, 5, 1], "uv": [24, 179]}, + {"origin": [-24, 1, 4.5], "size": [2, 11, 1], "uv": [173, 24]}, + {"origin": [-24, 2, 5.5], "size": [2, 9, 1], "uv": [177, 82]}, + {"origin": [-24, 0, 2.5], "size": [2, 13, 2], "uv": [122, 164]}, + {"origin": [-24, -1, -2.5], "size": [2, 15, 5], "uv": [157, 0]}, + {"origin": [-24, 0, -4.5], "size": [2, 13, 2], "uv": [169, 50]}, + {"origin": [-24, 1, -5.5], "size": [2, 11, 1], "uv": [172, 171]}, + {"origin": [-24, 2, -6.5], "size": [2, 9, 1], "uv": [177, 92]}, + {"origin": [-24, 4, -7.5], "size": [2, 5, 1], "uv": [179, 20]} + ] + }, + { + "name": "Wheel6", + "pivot": [-23, 6.5, -36.4], + "cubes": [ + {"origin": [-24, 4, -29.9], "size": [2, 5, 1], "uv": [18, 179]}, + {"origin": [-24, 2, -30.9], "size": [2, 9, 1], "uv": [177, 46]}, + {"origin": [-24, 1, -31.9], "size": [2, 11, 1], "uv": [166, 171]}, + {"origin": [-24, 0, -33.9], "size": [2, 13, 2], "uv": [114, 164]}, + {"origin": [-24, -1, -38.9], "size": [2, 15, 5], "uv": [155, 133]}, + {"origin": [-24, 0, -40.9], "size": [2, 13, 2], "uv": [106, 164]}, + {"origin": [-24, 1, -41.9], "size": [2, 11, 1], "uv": [160, 171]}, + {"origin": [-24, 2, -42.9], "size": [2, 9, 1], "uv": [177, 10]}, + {"origin": [-24, 4, -43.9], "size": [2, 5, 1], "uv": [12, 179]} + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/geo/catapult.geo.json b/src/main/resources/assets/siegemachines/geo/catapult.geo.json new file mode 100644 index 0000000..a213da1 --- /dev/null +++ b/src/main/resources/assets/siegemachines/geo/catapult.geo.json @@ -0,0 +1,116 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.unknown", + "texture_width": 256, + "texture_height": 256, + "visible_bounds_width": 7, + "visible_bounds_height": 5.5, + "visible_bounds_offset": [0, 2.25, 0] + }, + "bones": [ + { + "name": "bb_main", + "pivot": [0, 0, 0], + "cubes": [ + {"origin": [0, 51, 5], "size": [0, 0, 0], "uv": [0, 0]} + ] + }, + { + "name": "Structure", + "pivot": [0, 0, 0], + "cubes": [ + {"origin": [15.9, 0, -27.4], "size": [7, 9, 69], "uv": [0, 78]}, + {"origin": [-23.1, 0, -27.4], "size": [7, 9, 69], "uv": [0, 0]}, + {"origin": [-22.1, 1, -3.5], "size": [7, 36, 7], "uv": [28, 0]}, + {"origin": [14.9, 1, -3.5], "size": [7, 36, 7], "uv": [0, 0]}, + {"origin": [18.9, 3, 9.7], "size": [2, 16, 5], "pivot": [16.9, 4, 7.6], "rotation": [45, 0, 0], "uv": [55, 38]}, + {"origin": [-21.1, 3, 9.7], "size": [2, 16, 5], "pivot": [6.9, 4, 7.6], "rotation": [45, 0, 0], "uv": [32, 78]}, + {"origin": [-21.1, -7.17193, -19.15751], "size": [3, 27, 5], "pivot": [8.4, 4.82807, -1.25751], "rotation": [-45, 0, 0], "uv": [0, 78]}, + {"origin": [17.9, -7.17193, -19.15751], "size": [3, 27, 5], "pivot": [19.9, 4.82807, -1.25751], "rotation": [-45, 0, 0], "uv": [16, 78]}, + {"origin": [-16.1, 2.8, 19.6], "size": [32, 5, 5], "pivot": [-0.1, 4.9, 22.1], "rotation": [15, 0, 0], "uv": [83, 57]}, + {"origin": [22, 2.4, 30.55], "size": [1, 5, 9], "uv": [83, 0]}, + {"origin": [-23.2, 2.4, 30.55], "size": [1, 5, 9], "uv": [46, 78]}, + {"origin": [-10.1, 29.9, -0.9], "size": [20, 7, 5], "uv": [0, 43]}, + {"origin": [-17.1, 30.9, -2.5], "size": [34, 5, 5], "uv": [83, 47]}, + {"origin": [-16.1, 2.4, -20.4], "size": [32, 5, 5], "uv": [83, 88]} + ] + }, + { + "name": "Rope", + "pivot": [-0.1, 5.9, 34.6] + }, + { + "name": "Lever", + "pivot": [0, 6, 0], + "rotation": [58.5, 0, 0], + "cubes": [ + {"origin": [-1.6, 1.72611, -3.53117], "size": [3, 4, 43], "pivot": [-12, 9.37606, -7.46607], "rotation": [20, 0, 0], "uv": [83, 0]}, + {"origin": [-1.6, 12.21129, 28.20686], "size": [3, 6, 1], "pivot": [-12, 22.59284, 33.09693], "rotation": [90, 0, 0], "uv": [60, 0]}, + {"origin": [-0.6, 19.43576, 30.09292], "size": [1, 6, 1], "pivot": [-12, 24.26847, 38.70068], "rotation": [130, 0, 0], "uv": [83, 0]}, + {"origin": [-2.1, 15.43297, 35.47561], "size": [4, 6, 1], "pivot": [-12, 25.08293, 31.54071], "rotation": [20, 0, 0], "uv": [57, 78]}, + {"origin": [-0.6, 15.43297, 45.47561], "size": [1, 6, 1], "pivot": [-12, 25.08293, 31.54071], "rotation": [20, 0, 0], "uv": [83, 21]}, + {"origin": [-1.1, 14.63297, 39.97561], "size": [2, 1, 2], "pivot": [-12, 25.08293, 31.54071], "rotation": [20, 0, 0], "uv": [60, 17]}, + {"origin": [-7.42323, 16.65448, 27.99163], "size": [1, 6, 1], "pivot": [-12.01042, 25.97334, 35.44963], "rotation": [92.66618, -69.09177, -93.29662], "uv": [64, 34]}, + {"origin": [-7.41281, 34.32762, 31.11341], "size": [1, 6, 1], "pivot": [-12, 24.62556, 35.96389], "rotation": [-157.33382, -69.09177, -93.29662], "uv": [64, 59]}, + {"origin": [-7.41281, 33.39717, 22.93366], "size": [1, 6, 1], "pivot": [-12, 24.62556, 35.96389], "rotation": [162.66618, -69.09177, -93.29662], "uv": [46, 78]}, + {"origin": [-7.42323, 16.65448, 17.99163], "size": [1, 6, 1], "pivot": [-12.01042, 25.97334, 35.44963], "rotation": [92.66618, -69.09177, -93.29662], "uv": [50, 78]}, + {"origin": [-16.83845, 16.65448, 27.69642], "size": [1, 6, 1], "pivot": [-12.01042, 25.97334, 35.44963], "rotation": [151.00855, -42.64975, -159.86565], "uv": [64, 20]}, + {"origin": [-16.83845, 16.65448, 17.69642], "size": [1, 6, 1], "pivot": [-12.01042, 25.97334, 35.44963], "rotation": [151.00855, -42.64975, -159.86565], "uv": [64, 27]}, + {"origin": [-24.56318, 16.65448, 44.80802], "size": [1, 6, 1], "pivot": [-12.01042, 25.97334, 35.44963], "rotation": [151.21351, 42.24362, 159.28371], "uv": [60, 20]}, + {"origin": [-23.11894, 15.31228, 35.05579], "size": [1, 1, 6], "pivot": [-10.56618, 22.84138, 35.18209], "rotation": [170.21351, 42.24362, 159.28371], "uv": [83, 14]}, + {"origin": [-18.35269, 21.01973, 18.90389], "size": [1, 1, 6], "pivot": [-13.42566, 22.79617, 35.20929], "rotation": [170.21351, -42.24362, -159.28371], "uv": [21, 0]}, + {"origin": [-24.56318, 16.65448, 34.80802], "size": [1, 6, 1], "pivot": [-12.01042, 25.97334, 35.44963], "rotation": [151.21351, 42.24362, 159.28371], "uv": [60, 27]}, + {"origin": [-25.97064, 28.15444, 42.00861], "size": [1, 6, 1], "pivot": [-13.41788, 23.75685, 37.76264], "rotation": [41.21351, 42.24362, 159.28371], "uv": [49, 0]}, + {"origin": [-15.48196, 12.15045, 47.87351], "size": [1, 6, 1], "pivot": [-10.55493, 23.76274, 37.75571], "rotation": [40.21351, -42.24362, -159.28371], "uv": [0, 0]}, + {"origin": [-0.6, 15.89855, 29.78131], "size": [1, 1, 3], "pivot": [-12, 17.72855, 23.51505], "rotation": [-15, 0, 0], "uv": [60, 13]}, + {"origin": [-0.6, 11.48751, 29.16706], "size": [1, 1, 2], "pivot": [-12, 18.1427, 25.02468], "rotation": [22, 0, 0], "uv": [27, 78]}, + {"origin": [-0.6, 11.53967, 21.06497], "size": [1, 1, 2], "pivot": [-12, 18.77575, 25.79499], "rotation": [85, 0, 0], "uv": [31, 79]}, + {"origin": [-16.1, 3.38599, -2.68452], "size": [32, 5, 5], "uv": [83, 78]} + ] + }, + { + "name": "Crank", + "pivot": [-0.1, 5, 37.05217], + "cubes": [ + {"origin": [23, 4.4, 37.1], "size": [1, 1, 2], "uv": [60, 65]}, + {"origin": [23, 4.4, 35], "size": [1, 1, 2], "pivot": [23.5, 4.9, 37.05], "rotation": [-135, 0, 0], "uv": [24, 65]}, + {"origin": [22.9, 3.4, 35.55], "size": [1, 3, 3], "uv": [60, 7]}, + {"origin": [23, 4.4, 35], "size": [1, 1, 2], "pivot": [23.5, 4.9, 37.05], "rotation": [135, 0, 0], "uv": [36, 65]}, + {"origin": [23, 4.4, 35], "size": [1, 1, 2], "pivot": [23.5, 4.9, 37.05], "rotation": [90, 0, 0], "uv": [48, 65]}, + {"origin": [23, 4.4, 37.1], "size": [1, 1, 2], "pivot": [23.5, 4.9, 37.05], "rotation": [-135, 0, 0], "uv": [18, 65]}, + {"origin": [10.1, 3.9, 36.05], "size": [14, 2, 2], "pivot": [21.9, 4.9, 37.05], "rotation": [-45, 0, 0], "uv": [32, 61]}, + {"origin": [23.8, 4.4, 36.55], "size": [1, 1, 1], "uv": [45, 45]}, + {"origin": [23, 4.4, 35], "size": [1, 1, 2], "uv": [54, 65]}, + {"origin": [23, 4.4, 37.1], "size": [1, 1, 2], "pivot": [23.5, 4.9, 37.05], "rotation": [135, 0, 0], "uv": [30, 65]}, + {"origin": [23, 4.4, 37.1], "size": [1, 1, 2], "pivot": [23.5, 4.9, 37.05], "rotation": [90, 0, 0], "uv": [42, 65]}, + {"origin": [-24.1, 3.4, 35.55], "size": [1, 3, 3], "uv": [47, 52]}, + {"origin": [-24.2, 4.4, 37.1], "size": [1, 1, 2], "pivot": [-23.7, 4.9, 37.05], "rotation": [90, 0, 0], "uv": [12, 65]}, + {"origin": [-24.2, 4.4, 35], "size": [1, 1, 2], "pivot": [-23.7, 4.9, 37.05], "rotation": [-135, 0, 0], "uv": [6, 65]}, + {"origin": [-24.2, 4.4, 37.1], "size": [1, 1, 2], "uv": [0, 65]}, + {"origin": [-24.2, 4.4, 35], "size": [1, 1, 2], "pivot": [-23.7, 4.9, 37.05], "rotation": [135, 0, 0], "uv": [50, 58]}, + {"origin": [-24.2, 4.4, 35], "size": [1, 1, 2], "pivot": [-23.7, 4.9, 37.05], "rotation": [90, 0, 0], "uv": [29, 3]}, + {"origin": [-24.2, 4.4, 35], "size": [1, 1, 2], "uv": [21, 3]}, + {"origin": [-24.2, 4.4, 37.1], "size": [1, 1, 2], "pivot": [-23.7, 4.9, 37.05], "rotation": [-135, 0, 0], "uv": [29, 0]}, + {"origin": [-24.3, 3.9, 36.05], "size": [14, 2, 2], "pivot": [-22.1, 4.9, 37.05], "rotation": [-45, 0, 0], "uv": [0, 61]}, + {"origin": [-25, 4.4, 36.55], "size": [1, 1, 1], "uv": [0, 45]}, + {"origin": [-24.2, 4.4, 37.1], "size": [1, 1, 2], "pivot": [-23.7, 4.9, 37.05], "rotation": [135, 0, 0], "uv": [21, 0]}, + {"origin": [-11.1, 3.4, 35.6], "size": [22, 3, 3], "uv": [0, 55]} + ] + }, + { + "name": "LittleLevers", + "pivot": [-0.1, 5, 32.86918], + "cubes": [ + {"origin": [23.1, 4.9, 31.25], "size": [1, 1, 4], "pivot": [23.5, 5.6, 33.55], "rotation": [19, 0, 0], "uv": [11, 78]}, + {"origin": [23, 4.4, 31.6], "size": [1, 1, 1], "pivot": [23.5, 5.6, 33.55], "rotation": [19, 0, 0], "uv": [45, 43]}, + {"origin": [-24.2, 4.4, 31.6], "size": [1, 1, 1], "pivot": [-23.7, 5.6, 33.55], "rotation": [19, 0, 0], "uv": [0, 43]}, + {"origin": [-24.3, 4.9, 31.25], "size": [1, 1, 4], "pivot": [-23.7, 5.6, 33.55], "rotation": [19, 0, 0], "uv": [45, 43]} + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/geo/catapult_item.geo.json b/src/main/resources/assets/siegemachines/geo/catapult_item.geo.json new file mode 100644 index 0000000..a213da1 --- /dev/null +++ b/src/main/resources/assets/siegemachines/geo/catapult_item.geo.json @@ -0,0 +1,116 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.unknown", + "texture_width": 256, + "texture_height": 256, + "visible_bounds_width": 7, + "visible_bounds_height": 5.5, + "visible_bounds_offset": [0, 2.25, 0] + }, + "bones": [ + { + "name": "bb_main", + "pivot": [0, 0, 0], + "cubes": [ + {"origin": [0, 51, 5], "size": [0, 0, 0], "uv": [0, 0]} + ] + }, + { + "name": "Structure", + "pivot": [0, 0, 0], + "cubes": [ + {"origin": [15.9, 0, -27.4], "size": [7, 9, 69], "uv": [0, 78]}, + {"origin": [-23.1, 0, -27.4], "size": [7, 9, 69], "uv": [0, 0]}, + {"origin": [-22.1, 1, -3.5], "size": [7, 36, 7], "uv": [28, 0]}, + {"origin": [14.9, 1, -3.5], "size": [7, 36, 7], "uv": [0, 0]}, + {"origin": [18.9, 3, 9.7], "size": [2, 16, 5], "pivot": [16.9, 4, 7.6], "rotation": [45, 0, 0], "uv": [55, 38]}, + {"origin": [-21.1, 3, 9.7], "size": [2, 16, 5], "pivot": [6.9, 4, 7.6], "rotation": [45, 0, 0], "uv": [32, 78]}, + {"origin": [-21.1, -7.17193, -19.15751], "size": [3, 27, 5], "pivot": [8.4, 4.82807, -1.25751], "rotation": [-45, 0, 0], "uv": [0, 78]}, + {"origin": [17.9, -7.17193, -19.15751], "size": [3, 27, 5], "pivot": [19.9, 4.82807, -1.25751], "rotation": [-45, 0, 0], "uv": [16, 78]}, + {"origin": [-16.1, 2.8, 19.6], "size": [32, 5, 5], "pivot": [-0.1, 4.9, 22.1], "rotation": [15, 0, 0], "uv": [83, 57]}, + {"origin": [22, 2.4, 30.55], "size": [1, 5, 9], "uv": [83, 0]}, + {"origin": [-23.2, 2.4, 30.55], "size": [1, 5, 9], "uv": [46, 78]}, + {"origin": [-10.1, 29.9, -0.9], "size": [20, 7, 5], "uv": [0, 43]}, + {"origin": [-17.1, 30.9, -2.5], "size": [34, 5, 5], "uv": [83, 47]}, + {"origin": [-16.1, 2.4, -20.4], "size": [32, 5, 5], "uv": [83, 88]} + ] + }, + { + "name": "Rope", + "pivot": [-0.1, 5.9, 34.6] + }, + { + "name": "Lever", + "pivot": [0, 6, 0], + "rotation": [58.5, 0, 0], + "cubes": [ + {"origin": [-1.6, 1.72611, -3.53117], "size": [3, 4, 43], "pivot": [-12, 9.37606, -7.46607], "rotation": [20, 0, 0], "uv": [83, 0]}, + {"origin": [-1.6, 12.21129, 28.20686], "size": [3, 6, 1], "pivot": [-12, 22.59284, 33.09693], "rotation": [90, 0, 0], "uv": [60, 0]}, + {"origin": [-0.6, 19.43576, 30.09292], "size": [1, 6, 1], "pivot": [-12, 24.26847, 38.70068], "rotation": [130, 0, 0], "uv": [83, 0]}, + {"origin": [-2.1, 15.43297, 35.47561], "size": [4, 6, 1], "pivot": [-12, 25.08293, 31.54071], "rotation": [20, 0, 0], "uv": [57, 78]}, + {"origin": [-0.6, 15.43297, 45.47561], "size": [1, 6, 1], "pivot": [-12, 25.08293, 31.54071], "rotation": [20, 0, 0], "uv": [83, 21]}, + {"origin": [-1.1, 14.63297, 39.97561], "size": [2, 1, 2], "pivot": [-12, 25.08293, 31.54071], "rotation": [20, 0, 0], "uv": [60, 17]}, + {"origin": [-7.42323, 16.65448, 27.99163], "size": [1, 6, 1], "pivot": [-12.01042, 25.97334, 35.44963], "rotation": [92.66618, -69.09177, -93.29662], "uv": [64, 34]}, + {"origin": [-7.41281, 34.32762, 31.11341], "size": [1, 6, 1], "pivot": [-12, 24.62556, 35.96389], "rotation": [-157.33382, -69.09177, -93.29662], "uv": [64, 59]}, + {"origin": [-7.41281, 33.39717, 22.93366], "size": [1, 6, 1], "pivot": [-12, 24.62556, 35.96389], "rotation": [162.66618, -69.09177, -93.29662], "uv": [46, 78]}, + {"origin": [-7.42323, 16.65448, 17.99163], "size": [1, 6, 1], "pivot": [-12.01042, 25.97334, 35.44963], "rotation": [92.66618, -69.09177, -93.29662], "uv": [50, 78]}, + {"origin": [-16.83845, 16.65448, 27.69642], "size": [1, 6, 1], "pivot": [-12.01042, 25.97334, 35.44963], "rotation": [151.00855, -42.64975, -159.86565], "uv": [64, 20]}, + {"origin": [-16.83845, 16.65448, 17.69642], "size": [1, 6, 1], "pivot": [-12.01042, 25.97334, 35.44963], "rotation": [151.00855, -42.64975, -159.86565], "uv": [64, 27]}, + {"origin": [-24.56318, 16.65448, 44.80802], "size": [1, 6, 1], "pivot": [-12.01042, 25.97334, 35.44963], "rotation": [151.21351, 42.24362, 159.28371], "uv": [60, 20]}, + {"origin": [-23.11894, 15.31228, 35.05579], "size": [1, 1, 6], "pivot": [-10.56618, 22.84138, 35.18209], "rotation": [170.21351, 42.24362, 159.28371], "uv": [83, 14]}, + {"origin": [-18.35269, 21.01973, 18.90389], "size": [1, 1, 6], "pivot": [-13.42566, 22.79617, 35.20929], "rotation": [170.21351, -42.24362, -159.28371], "uv": [21, 0]}, + {"origin": [-24.56318, 16.65448, 34.80802], "size": [1, 6, 1], "pivot": [-12.01042, 25.97334, 35.44963], "rotation": [151.21351, 42.24362, 159.28371], "uv": [60, 27]}, + {"origin": [-25.97064, 28.15444, 42.00861], "size": [1, 6, 1], "pivot": [-13.41788, 23.75685, 37.76264], "rotation": [41.21351, 42.24362, 159.28371], "uv": [49, 0]}, + {"origin": [-15.48196, 12.15045, 47.87351], "size": [1, 6, 1], "pivot": [-10.55493, 23.76274, 37.75571], "rotation": [40.21351, -42.24362, -159.28371], "uv": [0, 0]}, + {"origin": [-0.6, 15.89855, 29.78131], "size": [1, 1, 3], "pivot": [-12, 17.72855, 23.51505], "rotation": [-15, 0, 0], "uv": [60, 13]}, + {"origin": [-0.6, 11.48751, 29.16706], "size": [1, 1, 2], "pivot": [-12, 18.1427, 25.02468], "rotation": [22, 0, 0], "uv": [27, 78]}, + {"origin": [-0.6, 11.53967, 21.06497], "size": [1, 1, 2], "pivot": [-12, 18.77575, 25.79499], "rotation": [85, 0, 0], "uv": [31, 79]}, + {"origin": [-16.1, 3.38599, -2.68452], "size": [32, 5, 5], "uv": [83, 78]} + ] + }, + { + "name": "Crank", + "pivot": [-0.1, 5, 37.05217], + "cubes": [ + {"origin": [23, 4.4, 37.1], "size": [1, 1, 2], "uv": [60, 65]}, + {"origin": [23, 4.4, 35], "size": [1, 1, 2], "pivot": [23.5, 4.9, 37.05], "rotation": [-135, 0, 0], "uv": [24, 65]}, + {"origin": [22.9, 3.4, 35.55], "size": [1, 3, 3], "uv": [60, 7]}, + {"origin": [23, 4.4, 35], "size": [1, 1, 2], "pivot": [23.5, 4.9, 37.05], "rotation": [135, 0, 0], "uv": [36, 65]}, + {"origin": [23, 4.4, 35], "size": [1, 1, 2], "pivot": [23.5, 4.9, 37.05], "rotation": [90, 0, 0], "uv": [48, 65]}, + {"origin": [23, 4.4, 37.1], "size": [1, 1, 2], "pivot": [23.5, 4.9, 37.05], "rotation": [-135, 0, 0], "uv": [18, 65]}, + {"origin": [10.1, 3.9, 36.05], "size": [14, 2, 2], "pivot": [21.9, 4.9, 37.05], "rotation": [-45, 0, 0], "uv": [32, 61]}, + {"origin": [23.8, 4.4, 36.55], "size": [1, 1, 1], "uv": [45, 45]}, + {"origin": [23, 4.4, 35], "size": [1, 1, 2], "uv": [54, 65]}, + {"origin": [23, 4.4, 37.1], "size": [1, 1, 2], "pivot": [23.5, 4.9, 37.05], "rotation": [135, 0, 0], "uv": [30, 65]}, + {"origin": [23, 4.4, 37.1], "size": [1, 1, 2], "pivot": [23.5, 4.9, 37.05], "rotation": [90, 0, 0], "uv": [42, 65]}, + {"origin": [-24.1, 3.4, 35.55], "size": [1, 3, 3], "uv": [47, 52]}, + {"origin": [-24.2, 4.4, 37.1], "size": [1, 1, 2], "pivot": [-23.7, 4.9, 37.05], "rotation": [90, 0, 0], "uv": [12, 65]}, + {"origin": [-24.2, 4.4, 35], "size": [1, 1, 2], "pivot": [-23.7, 4.9, 37.05], "rotation": [-135, 0, 0], "uv": [6, 65]}, + {"origin": [-24.2, 4.4, 37.1], "size": [1, 1, 2], "uv": [0, 65]}, + {"origin": [-24.2, 4.4, 35], "size": [1, 1, 2], "pivot": [-23.7, 4.9, 37.05], "rotation": [135, 0, 0], "uv": [50, 58]}, + {"origin": [-24.2, 4.4, 35], "size": [1, 1, 2], "pivot": [-23.7, 4.9, 37.05], "rotation": [90, 0, 0], "uv": [29, 3]}, + {"origin": [-24.2, 4.4, 35], "size": [1, 1, 2], "uv": [21, 3]}, + {"origin": [-24.2, 4.4, 37.1], "size": [1, 1, 2], "pivot": [-23.7, 4.9, 37.05], "rotation": [-135, 0, 0], "uv": [29, 0]}, + {"origin": [-24.3, 3.9, 36.05], "size": [14, 2, 2], "pivot": [-22.1, 4.9, 37.05], "rotation": [-45, 0, 0], "uv": [0, 61]}, + {"origin": [-25, 4.4, 36.55], "size": [1, 1, 1], "uv": [0, 45]}, + {"origin": [-24.2, 4.4, 37.1], "size": [1, 1, 2], "pivot": [-23.7, 4.9, 37.05], "rotation": [135, 0, 0], "uv": [21, 0]}, + {"origin": [-11.1, 3.4, 35.6], "size": [22, 3, 3], "uv": [0, 55]} + ] + }, + { + "name": "LittleLevers", + "pivot": [-0.1, 5, 32.86918], + "cubes": [ + {"origin": [23.1, 4.9, 31.25], "size": [1, 1, 4], "pivot": [23.5, 5.6, 33.55], "rotation": [19, 0, 0], "uv": [11, 78]}, + {"origin": [23, 4.4, 31.6], "size": [1, 1, 1], "pivot": [23.5, 5.6, 33.55], "rotation": [19, 0, 0], "uv": [45, 43]}, + {"origin": [-24.2, 4.4, 31.6], "size": [1, 1, 1], "pivot": [-23.7, 5.6, 33.55], "rotation": [19, 0, 0], "uv": [0, 43]}, + {"origin": [-24.3, 4.9, 31.25], "size": [1, 1, 4], "pivot": [-23.7, 5.6, 33.55], "rotation": [19, 0, 0], "uv": [45, 43]} + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/geo/mortar.geo.json b/src/main/resources/assets/siegemachines/geo/mortar.geo.json new file mode 100644 index 0000000..7c64f5e --- /dev/null +++ b/src/main/resources/assets/siegemachines/geo/mortar.geo.json @@ -0,0 +1,102 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.mortar", + "texture_width": 128, + "texture_height": 128, + "visible_bounds_width": 5, + "visible_bounds_height": 3.5, + "visible_bounds_offset": [0, 1.25, 0] + }, + "bones": [ + { + "name": "Wheels", + "pivot": [-6.6, 9.55433, -9.77039], + "cubes": [ + {"origin": [-16.1, 1.25433, -14.97039], "size": [31, 2, 2], "pivot": [6, -4.34567, 6.22961], "rotation": [-22.5, 0, 0], "uv": [39, 0]} + ] + }, + { + "name": "LeftWheel", + "parent": "Wheels", + "pivot": [-8, 8, -8], + "cubes": [ + {"origin": [10.9, -0.88545, -13.27201], "size": [2, 21, 7], "uv": [29, 74]}, + {"origin": [10.9, 0.11455, -15.27201], "size": [2, 19, 2], "uv": [63, 75]}, + {"origin": [10.9, 1.11455, -16.27201], "size": [2, 17, 1], "uv": [77, 83]}, + {"origin": [10.9, 1.11455, -4.27201], "size": [2, 17, 1], "uv": [71, 83]}, + {"origin": [10.9, 2.11455, -17.27201], "size": [2, 15, 1], "uv": [0, 87]}, + {"origin": [10.9, 2.11455, -3.27201], "size": [2, 15, 1], "uv": [83, 83]}, + {"origin": [10.9, 3.11455, -18.27201], "size": [2, 13, 1], "uv": [60, 55]}, + {"origin": [10.9, 3.11455, -2.27201], "size": [2, 13, 1], "uv": [54, 54]}, + {"origin": [10.9, 4.11455, -19.27201], "size": [2, 11, 1], "uv": [87, 35]}, + {"origin": [10.9, 4.11455, -1.27201], "size": [2, 11, 1], "uv": [87, 15]}, + {"origin": [10.9, 6.11455, -20.27201], "size": [2, 7, 1], "uv": [41, 58]}, + {"origin": [10.9, 6.11455, -0.27201], "size": [2, 7, 1], "uv": [45, 11]}, + {"origin": [10.9, 0.11455, -6.27201], "size": [2, 19, 2], "uv": [55, 75]} + ] + }, + { + "name": "RightWheel", + "parent": "Wheels", + "pivot": [-8, 8, -8], + "cubes": [ + {"origin": [-14.1, -0.88545, -13.27201], "size": [2, 21, 7], "uv": [0, 0]}, + {"origin": [-14.1, 0.11455, -15.27201], "size": [2, 19, 2], "uv": [47, 74]}, + {"origin": [-14.1, 1.11455, -16.27201], "size": [2, 17, 1], "uv": [22, 79]}, + {"origin": [-14.1, 1.11455, -4.27201], "size": [2, 17, 1], "uv": [16, 79]}, + {"origin": [-14.1, 2.11455, -17.27201], "size": [2, 15, 1], "uv": [6, 58]}, + {"origin": [-14.1, 2.11455, -3.27201], "size": [2, 15, 1], "uv": [0, 58]}, + {"origin": [-14.1, 3.11455, -18.27201], "size": [2, 13, 1], "uv": [6, 41]}, + {"origin": [-14.1, 3.11455, -2.27201], "size": [2, 13, 1], "uv": [0, 41]}, + {"origin": [-14.1, 4.11455, -19.27201], "size": [2, 11, 1], "uv": [6, 87]}, + {"origin": [-14.1, 4.11455, -1.27201], "size": [2, 11, 1], "uv": [70, 35]}, + {"origin": [-14.1, 6.11455, -20.27201], "size": [2, 7, 1], "uv": [33, 41]}, + {"origin": [-14.1, 6.11455, -0.27201], "size": [2, 7, 1], "uv": [45, 11]}, + {"origin": [-14.1, 0.11455, -6.27201], "size": [2, 19, 2], "uv": [47, 74]} + ] + }, + { + "name": "MortarBase", + "pivot": [-8, 8, -8], + "cubes": [ + {"origin": [-3.2, 1.6892, 15.73904], "size": [5.2, 3, 3.6], "pivot": [-0.6, 2.1892, 15.53904], "rotation": [-15, 0, 0], "uv": [79, 63]}, + {"origin": [-1.7, 3.23128, 8.45818], "size": [2.2, 2.2, 8], "pivot": [-0.6, 4.33128, 10.95818], "rotation": [-15, 0, 0], "uv": [10, 20]}, + {"origin": [5.9, 7.3, -20], "size": [4, 7, 31], "pivot": [7.9, 12.3, -4.5], "rotation": [-15, 0, 0], "uv": [0, 0], "mirror": true}, + {"origin": [-11.1, 7.3, -20], "size": [4, 7, 31], "pivot": [7.9, 12.3, -4.5], "rotation": [-15, 0, 0], "uv": [0, 0]}, + {"origin": [-7.1, 7.3, 1], "size": [13, 4, 9], "pivot": [7.9, 12.3, -4.5], "rotation": [-15, 0, 0], "uv": [33, 41]}, + {"origin": [-7.1, 10.24923, -19.40164], "size": [13, 4, 9], "pivot": [-0.6, 12.24923, -15.90164], "rotation": [-15, 0, 0], "uv": [33, 41]}, + {"origin": [-11.1, 13, -9], "size": [4, 5, 6], "inflate": 0.2, "pivot": [7.9, 19.3, -2.5], "rotation": [-15, 0, 0], "uv": [108, 0]}, + {"origin": [5.9, 13, -9], "size": [4, 5, 6], "inflate": 0.2, "pivot": [24.9, 19.3, -2.5], "rotation": [-15, 0, 0], "uv": [108, 0], "mirror": true} + ] + }, + { + "name": "Barrel", + "pivot": [-0.5, 16.8732, -6.8456], + "cubes": [ + {"origin": [-3.2, 22.1, -21], "size": [5, 1, 15], "uv": [62, 39]}, + {"origin": [-3.2, 12.1, -21], "size": [5, 1, 15], "uv": [54, 59]}, + {"origin": [-5.2, 20.1, -21], "size": [9, 2, 15], "uv": [0, 41]}, + {"origin": [-5.2, 13.1, -21], "size": [9, 2, 15], "uv": [39, 4]}, + {"origin": [1.8, 15.1, -21], "size": [3, 5, 15], "uv": [0, 59]}, + {"origin": [-6.2, 15.1, -21], "size": [3, 5, 15], "uv": [33, 54]}, + {"origin": [-11.5, 15.87318, -7.84558], "size": [22, 2, 2], "uv": [45, 0]}, + {"origin": [-4.2, 14.1, 1], "size": [7, 7, 0], "uv": [39, 4]}, + {"origin": [-5.2, 13.1, -19], "size": [9, 9, 0], "uv": [21, 58]}, + {"origin": [-3.2, 21.1, -6], "size": [5, 1, 7], "uv": [56, 22]}, + {"origin": [-3.2, 13.1, -6], "size": [5, 1, 7], "uv": [39, 21]}, + {"origin": [1.8, 14.1, -6], "size": [1, 1, 7], "uv": [79, 55]}, + {"origin": [-4.2, 14.1, -6], "size": [1, 1, 7], "uv": [0, 79]}, + {"origin": [1.8, 20.1, -6], "size": [1, 1, 7], "uv": [71, 75]}, + {"origin": [-2.2, 16.1, 1], "size": [3, 3, 2], "uv": [11, 0]}, + {"origin": [-4.2, 20.1, -6], "size": [1, 1, 7], "uv": [32, 60]}, + {"origin": [2.8, 15.1, -6], "size": [1, 5, 7], "uv": [73, 23]}, + {"origin": [-5.2, 15.1, -6], "size": [1, 5, 7], "uv": [72, 4]} + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/geo/mortar_item.geo.json b/src/main/resources/assets/siegemachines/geo/mortar_item.geo.json new file mode 100644 index 0000000..094f8ff --- /dev/null +++ b/src/main/resources/assets/siegemachines/geo/mortar_item.geo.json @@ -0,0 +1,102 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.mortar", + "texture_width": 128, + "texture_height": 128, + "visible_bounds_width": 5, + "visible_bounds_height": 3.5, + "visible_bounds_offset": [0, 1.25, 0] + }, + "bones": [ + { + "name": "Wheels", + "pivot": [-6.6, 9.55433, -9.77039], + "cubes": [ + {"origin": [-16.1, 1.25433, -14.97039], "size": [31, 2, 2], "pivot": [6, -4.34567, 6.22961], "rotation": [-22.5, 0, 0], "uv": [39, 0]} + ] + }, + { + "name": "LeftWheel", + "parent": "Wheels", + "pivot": [-8, 8, -8], + "cubes": [ + {"origin": [10.9, -0.88545, -13.27201], "size": [2, 21, 7], "uv": [29, 74]}, + {"origin": [10.9, 0.11455, -15.27201], "size": [2, 19, 2], "uv": [63, 75]}, + {"origin": [10.9, 1.11455, -16.27201], "size": [2, 17, 1], "uv": [77, 83]}, + {"origin": [10.9, 1.11455, -4.27201], "size": [2, 17, 1], "uv": [71, 83]}, + {"origin": [10.9, 2.11455, -17.27201], "size": [2, 15, 1], "uv": [0, 87]}, + {"origin": [10.9, 2.11455, -3.27201], "size": [2, 15, 1], "uv": [83, 83]}, + {"origin": [10.9, 3.11455, -18.27201], "size": [2, 13, 1], "uv": [60, 55]}, + {"origin": [10.9, 3.11455, -2.27201], "size": [2, 13, 1], "uv": [54, 54]}, + {"origin": [10.9, 4.11455, -19.27201], "size": [2, 11, 1], "uv": [87, 35]}, + {"origin": [10.9, 4.11455, -1.27201], "size": [2, 11, 1], "uv": [87, 15]}, + {"origin": [10.9, 6.11455, -20.27201], "size": [2, 7, 1], "uv": [41, 58]}, + {"origin": [10.9, 6.11455, -0.27201], "size": [2, 7, 1], "uv": [45, 11]}, + {"origin": [10.9, 0.11455, -6.27201], "size": [2, 19, 2], "uv": [55, 75]} + ] + }, + { + "name": "RightWheel", + "parent": "Wheels", + "pivot": [-8, 8, -8], + "cubes": [ + {"origin": [-14.1, -0.88545, -13.27201], "size": [2, 21, 7], "uv": [0, 0]}, + {"origin": [-14.1, 0.11455, -15.27201], "size": [2, 19, 2], "uv": [47, 74]}, + {"origin": [-14.1, 1.11455, -16.27201], "size": [2, 17, 1], "uv": [22, 79]}, + {"origin": [-14.1, 1.11455, -4.27201], "size": [2, 17, 1], "uv": [16, 79]}, + {"origin": [-14.1, 2.11455, -17.27201], "size": [2, 15, 1], "uv": [6, 58]}, + {"origin": [-14.1, 2.11455, -3.27201], "size": [2, 15, 1], "uv": [0, 58]}, + {"origin": [-14.1, 3.11455, -18.27201], "size": [2, 13, 1], "uv": [6, 41]}, + {"origin": [-14.1, 3.11455, -2.27201], "size": [2, 13, 1], "uv": [0, 41]}, + {"origin": [-14.1, 4.11455, -19.27201], "size": [2, 11, 1], "uv": [6, 87]}, + {"origin": [-14.1, 4.11455, -1.27201], "size": [2, 11, 1], "uv": [70, 35]}, + {"origin": [-14.1, 6.11455, -20.27201], "size": [2, 7, 1], "uv": [33, 41]}, + {"origin": [-14.1, 6.11455, -0.27201], "size": [2, 7, 1], "uv": [45, 11]}, + {"origin": [-14.1, 0.11455, -6.27201], "size": [2, 19, 2], "uv": [47, 74]} + ] + }, + { + "name": "MortarBase", + "pivot": [-8, 8, -8], + "cubes": [ + {"origin": [-3.2, 1.6892, 15.73904], "size": [5.2, 3, 3.6], "pivot": [-0.6, 2.1892, 15.53904], "rotation": [-15, 0, 0], "uv": [79, 63]}, + {"origin": [-1.7, 3.23128, 8.45818], "size": [2.2, 2.2, 8], "pivot": [-0.6, 4.33128, 10.95818], "rotation": [-15, 0, 0], "uv": [10, 20]}, + {"origin": [5.9, 7.3, -20], "size": [4, 7, 31], "pivot": [7.9, 12.3, -4.5], "rotation": [-15, 0, 0], "uv": [0, 0], "mirror": true}, + {"origin": [-11.1, 7.3, -20], "size": [4, 7, 31], "pivot": [7.9, 12.3, -4.5], "rotation": [-15, 0, 0], "uv": [0, 0]}, + {"origin": [-7.1, 7.3, 1], "size": [13, 4, 9], "pivot": [7.9, 12.3, -4.5], "rotation": [-15, 0, 0], "uv": [33, 41]}, + {"origin": [-7.1, 10.24923, -19.40164], "size": [13, 4, 9], "pivot": [-0.6, 12.24923, -15.90164], "rotation": [-15, 0, 0], "uv": [33, 41]}, + {"origin": [-11.1, 13, -9], "size": [4, 5, 6], "inflate": 0.2, "pivot": [7.9, 19.3, -2.5], "rotation": [-15, 0, 0], "uv": [108, 0]}, + {"origin": [5.9, 13, -9], "size": [4, 5, 6], "inflate": 0.2, "pivot": [24.9, 19.3, -2.5], "rotation": [-15, 0, 0], "uv": [108, 0], "mirror": true} + ] + }, + { + "name": "Barrel", + "pivot": [-0.5, 16.8732, -6.8456], + "cubes": [ + {"origin": [-3.2, 22.1, -21], "size": [5, 1, 15], "uv": [62, 39]}, + {"origin": [-3.2, 12.1, -21], "size": [5, 1, 15], "uv": [54, 59]}, + {"origin": [-5.2, 20.1, -21], "size": [9, 2, 15], "uv": [0, 41]}, + {"origin": [-5.2, 13.1, -21], "size": [9, 2, 15], "uv": [39, 4]}, + {"origin": [1.8, 15.1, -21], "size": [3, 5, 15], "uv": [0, 59]}, + {"origin": [-6.2, 15.1, -21], "size": [3, 5, 15], "uv": [33, 54]}, + {"origin": [-11.5, 15.87318, -7.84558], "size": [22, 2, 2], "uv": [45, 0]}, + {"origin": [-4.2, 14.1, 0], "size": [7, 7, 1], "inflate": -0.01, "uv": [30, 3]}, + {"origin": [-5.2, 13.1, -19], "size": [9, 9, 0], "uv": [21, 58]}, + {"origin": [-3.2, 21.1, -6], "size": [5, 1, 7], "uv": [56, 22]}, + {"origin": [-3.2, 13.1, -6], "size": [5, 1, 7], "uv": [39, 21]}, + {"origin": [1.8, 14.1, -6], "size": [1, 1, 7], "uv": [79, 55]}, + {"origin": [-4.2, 14.1, -6], "size": [1, 1, 7], "uv": [0, 79]}, + {"origin": [1.8, 20.1, -6], "size": [1, 1, 7], "uv": [71, 75]}, + {"origin": [-2.2, 16.1, 1], "size": [3, 3, 2], "uv": [11, 0]}, + {"origin": [-4.2, 20.1, -6], "size": [1, 1, 7], "uv": [32, 60]}, + {"origin": [2.8, 15.1, -6], "size": [1, 5, 7], "uv": [73, 23]}, + {"origin": [-5.2, 15.1, -6], "size": [1, 5, 7], "uv": [72, 4]} + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/geo/trebuchet.geo.json b/src/main/resources/assets/siegemachines/geo/trebuchet.geo.json new file mode 100644 index 0000000..8eb127f --- /dev/null +++ b/src/main/resources/assets/siegemachines/geo/trebuchet.geo.json @@ -0,0 +1,130 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.unknown", + "texture_width": 1024, + "texture_height": 1024, + "visible_bounds_width": 49, + "visible_bounds_height": 64, + "visible_bounds_offset": [0, 26, 0] + }, + "bones": [ + { + "name": "Structure", + "pivot": [0, 0, 0], + "cubes": [ + {"origin": [12, 8, -17], "size": [7, 121, 7], "uv": [168, 0]}, + {"origin": [-24, -1, -19], "size": [48, 12, 11], "uv": [321, 69]}, + {"origin": [-12, 0, -61], "size": [24, 7, 7], "uv": [201, 152]}, + {"origin": [-16, 0, 141], "size": [32, 7, 7], "uv": [201, 138]}, + {"origin": [-1, 5, -8], "size": [12, 1, 149], "pivot": [16, 6, -8], "rotation": [0, 0, -12.5], "uv": [510, 468]}, + {"origin": [-11, 5, -8], "size": [12, 1, 149], "pivot": [-16, 6, -8], "rotation": [0, 0, 12.5], "uv": [510, 268]}, + {"origin": [-24, 124, -15.6], "size": [48, 4, 4], "uv": [0, 167]}, + {"origin": [-64, -1, -17], "size": [45, 7, 7], "uv": [201, 88]}, + {"origin": [-129.52995, 227, -15], "size": [126, 5, 3], "pivot": [64.77005, 165.36472, -20], "rotation": [0, 0, -73], "uv": [30, 745]}, + {"origin": [-112.52995, 227, -23], "size": [3, 3, 19], "pivot": [64.77005, 165.36472, -20], "rotation": [0, 0, -73], "uv": [0, 203]}, + {"origin": [-100.52995, 227, -23], "size": [3, 3, 19], "pivot": [64.77005, 165.36472, -20], "rotation": [0, 0, -73], "uv": [0, 203]}, + {"origin": [-88.52995, 227, -23], "size": [3, 3, 19], "pivot": [64.77005, 165.36472, -20], "rotation": [0, 0, -73], "uv": [0, 203]}, + {"origin": [-76.52995, 227, -23], "size": [3, 3, 19], "pivot": [64.77005, 165.36472, -20], "rotation": [0, 0, -73], "uv": [0, 203]}, + {"origin": [-64.52995, 227, -23], "size": [3, 3, 19], "pivot": [64.77005, 165.36472, -20], "rotation": [0, 0, -73], "uv": [0, 203]}, + {"origin": [-52.52995, 227, -23], "size": [3, 3, 19], "pivot": [64.77005, 165.36472, -20], "rotation": [0, 0, -73], "uv": [0, 203]}, + {"origin": [-40.52995, 227, -23], "size": [3, 3, 19], "pivot": [64.77005, 165.36472, -20], "rotation": [0, 0, -73], "uv": [0, 203]}, + {"origin": [-28.52995, 227, -23], "size": [3, 3, 19], "pivot": [64.77005, 165.36472, -20], "rotation": [0, 0, -73], "uv": [0, 203]}, + {"origin": [-16.52995, 227, -23], "size": [3, 3, 19], "pivot": [64.77005, 165.36472, -20], "rotation": [0, 0, -73], "uv": [0, 203]}, + {"origin": [19, -1, -17], "size": [45, 7, 7], "uv": [0, 175]}, + {"origin": [-19, -1, -62], "size": [7, 10, 48], "uv": [88, 311]}, + {"origin": [12, -1, -62], "size": [7, 10, 48], "uv": [194, 202]}, + {"origin": [-19, -1, -8.2], "size": [7, 10, 159], "uv": [362, 49]}, + {"origin": [12, -1, -8.2], "size": [7, 10, 159], "uv": [49, 360]}, + {"origin": [14, 9, 83.8], "size": [3, 22, 9], "uv": [24, 69]}, + {"origin": [-17, 9, 83.8], "size": [3, 22, 9], "uv": [0, 69]}, + {"origin": [48.3697, 0, -13.96784], "size": [5, 5, 103], "pivot": [50.8697, 2.5, -13.46784], "rotation": [0, -24, 0], "uv": [227, 709]}, + {"origin": [67.1887, 0, -16.71609], "size": [5, 5, 60], "pivot": [61, -1, -17], "rotation": [-180, -40, 180], "uv": [317, 4]}, + {"origin": [-53.36968, 0, -13.96785], "size": [5, 5, 103], "pivot": [-50.86968, 2.5, -13.46785], "rotation": [0, 24, 0], "uv": [25, 94]}, + {"origin": [-72.1887, 0, -14.71609], "size": [5, 5, 60], "pivot": [-61, -1, -17], "rotation": [-180, 40, 180], "uv": [6, 4]}, + {"origin": [-18, 0.1101, -57.2], "size": [5, 7, 129], "pivot": [-15.5, 3.1101, -56.95027], "rotation": [70, 0, 0], "uv": [31, 560], "mirror": true}, + {"origin": [13, 0.1101, -57.1], "size": [5, 7, 129], "pivot": [15.5, 3.1101, -56.95027], "rotation": [70, 0, 0], "uv": [31, 560]}, + {"origin": [-18, -0.24603, 30.29206], "size": [5, 7, 129], "pivot": [-15.5, 3.25397, 30.29206], "rotation": [-110, 0, 180], "uv": [31, 560], "mirror": true}, + {"origin": [13, -0.24603, 30.29206], "size": [5, 7, 129], "pivot": [15.5, 3.25397, 30.2921], "rotation": [-110, 0, 180], "uv": [31, 560]}, + {"origin": [14, 23.75906, 4.55558], "size": [3, 7, 69], "pivot": [15.5, 27.25906, 39.05558], "rotation": [-138, 0, 180], "uv": [13, 324]}, + {"origin": [-17, 23.75906, 4.55558], "size": [3, 7, 69], "pivot": [-15.5, 27.25906, 39.05558], "rotation": [-138, 0, 180], "uv": [119, 215]}, + {"origin": [-19, 8, -17], "size": [7, 121, 7], "uv": [140, 0]} + ] + }, + { + "name": "Crank", + "pivot": [0, 25.5, 88.3], + "cubes": [ + {"origin": [-27, 23, 85.8], "size": [54, 5, 5], "pivot": [0.5, 25.5, 88.3], "rotation": [45, 0, 0], "uv": [0, 157]}, + {"origin": [-13, 21, 83.8], "size": [26, 9, 9], "pivot": [0, 25.5, 88.3], "rotation": [45, 0, 0], "uv": [201, 102]}, + {"origin": [-25, 11, 87.8], "size": [2, 12, 1], "pivot": [0.5, 25.5, 88.3], "rotation": [45, 0, 0], "uv": [116, 69]}, + {"origin": [-25, 28, 87.8], "size": [2, 12, 1], "pivot": [0.5, 25.5, 88.3], "rotation": [45, 0, 0], "uv": [110, 69]}, + {"origin": [23, 11, 87.8], "size": [2, 12, 1], "pivot": [0.5, 25.5, 88.3], "rotation": [45, 0, 0], "uv": [62, 69]}, + {"origin": [23, 28, 87.8], "size": [2, 12, 1], "pivot": [0.5, 25.5, 88.3], "rotation": [45, 0, 0], "uv": [104, 69]}, + {"origin": [23, 11, 87.8], "size": [2, 12, 1], "pivot": [24, 25.5, 88.3], "rotation": [137.5, 0, 0], "uv": [58, 26]}, + {"origin": [23, 28, 87.8], "size": [2, 12, 1], "pivot": [24, 25.5, 88.3], "rotation": [137.5, 0, 0], "uv": [56, 69]}, + {"origin": [-25, 11, 87.8], "size": [2, 12, 1], "pivot": [24, 25.5, 88.3], "rotation": [137.5, 0, 0], "uv": [58, 0]}, + {"origin": [-25, 28, 87.8], "size": [2, 12, 1], "pivot": [24, 25.5, 88.3], "rotation": [137.5, 0, 0], "uv": [58, 13]} + ] + }, + { + "name": "Lever", + "pivot": [-8, 126, -14], + "cubes": [ + {"origin": [-11.7, 124, -45.9], "size": [23, 4, 4], "pivot": [-8, 126, -14], "rotation": [90, 0, 0], "uv": [56, 101]}, + {"origin": [-2.75, 121.4, 106.8], "size": [5, 8, 76], "pivot": [-8, 126, -14], "rotation": [90, 0, 0], "uv": [222, 311]}, + {"origin": [-4.75, 120.4, -50.2], "size": [9, 11, 90], "pivot": [-8, 126, -14], "rotation": [90, 0, 0], "uv": [340, 583]}, + {"origin": [-3.75, 121.4, 39.8], "size": [7, 9, 67], "pivot": [-8, 126, -14], "rotation": [90, 0, 0], "uv": [25, 227]}, + {"origin": [-0.75, 326, -9.7], "size": [1, 1, 3], "inflate": 0.2, "pivot": [-0.25, 326.5237, -9.28356], "rotation": [102.5, 0, 0], "uv": [16, 57]}, + {"origin": [-0.75, 323.94926, -11.32443], "size": [1, 1, 4], "inflate": 0.2, "pivot": [-0.25, 324.44926, -9.32443], "rotation": [82.5, 0, 0], "uv": [20, 57]} + ] + }, + { + "name": "CounterWeight", + "parent": "Lever", + "pivot": [-8.2, 95.99641, -13.89692], + "cubes": [ + {"origin": [8.8, 72, -16.9], "size": [2, 28, 6], "uv": [201, 0]}, + {"origin": [-11.2, 72, -16.9], "size": [2, 28, 6], "uv": [104, 109]}, + {"origin": [-11.2, 48, -38.9], "size": [22, 24, 4], "uv": [201, 166]}, + {"origin": [7.8, 32.1, -37.9], "size": [4, 40, 48], "uv": [201, 0]}, + {"origin": [-12.2, 32.1, -37.9], "size": [4, 40, 48], "uv": [0, 69]}, + {"origin": [-11.2, 48, 7.1], "size": [22, 24, 4], "uv": [138, 158]}, + {"origin": [-12.1, 49.73205, 7.8], "size": [23.8, 24, 4], "pivot": [-8.2, 49.73205, 10.1], "rotation": [120, 0, 0], "uv": [80, 0]}, + {"origin": [-11.5, 61.7, 12.054], "size": [23, 9, 4], "pivot": [-8.2, 38, 14.31539], "rotation": [90, 0, 0], "uv": [5, 44]}, + {"origin": [-8.2, 44.7, 40.31539], "size": [22, 43, 1], "pivot": [-8.2, 38, 14.31539], "rotation": [90, 0, 0], "uv": [0, 0]}, + {"origin": [-12.1, 49.73205, -39.6], "size": [23.8, 24, 4], "pivot": [-8.2, 49.73205, -37.9], "rotation": [-120, 0, 0], "uv": [80, 28]} + ] + }, + { + "name": "Rope_Projectile", + "parent": "Lever", + "pivot": [-8.25, 321.0872, -8.87572], + "rotation": [92.5, 0, 0], + "cubes": [ + {"origin": [-0.25, 315.0872, -137.87572], "size": [0, 2, 130], "pivot": [-8.2, 320.9872, 106.72428], "rotation": [-2.5, 0, 0], "uv": [222, 381]}, + {"origin": [-1.25, 316.0872, -137.87572], "size": [2, 0, 130], "pivot": [-8.2, 320.9872, 106.72428], "rotation": [-2.5, 0, 0], "uv": [179, 175]}, + {"origin": [-0.25, 325.02631, -137.48123], "size": [0, 2, 130], "pivot": [-8.2, 320.9872, 106.72428], "rotation": [3.5, 0, 0], "uv": [222, 381]}, + {"origin": [-1.25, 314.63912, -137.41784], "size": [2, 0, 130], "pivot": [-0.25, 316.04548, -85.81234], "rotation": [3.5, 0, 0], "uv": [178, 175]}, + {"origin": [-8.2, -317, 123.78511], "size": [16, 20, 16], "inflate": 0.3, "pivot": [-0.2, 142, 308.78511], "rotation": [-90, 0, 0], "uv": [387, 0]} + ] + }, + { + "name": "Cobblestone", + "parent": "Rope_Projectile", + "pivot": [-8.25, 321.0872, -8.87572], + "cubes": [ + {"origin": [-8.25, 311.0872, -149.87572], "size": [16, 16, 16], "uv": [0, 225]} + ] + }, + { + "name": "Rope_Lever", + "pivot": [-8.25, 26.66803, 103.76811], + "rotation": [90, 0, 0] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/geo/trebuchet_item.geo.json b/src/main/resources/assets/siegemachines/geo/trebuchet_item.geo.json new file mode 100644 index 0000000..8eb127f --- /dev/null +++ b/src/main/resources/assets/siegemachines/geo/trebuchet_item.geo.json @@ -0,0 +1,130 @@ +{ + "format_version": "1.12.0", + "minecraft:geometry": [ + { + "description": { + "identifier": "geometry.unknown", + "texture_width": 1024, + "texture_height": 1024, + "visible_bounds_width": 49, + "visible_bounds_height": 64, + "visible_bounds_offset": [0, 26, 0] + }, + "bones": [ + { + "name": "Structure", + "pivot": [0, 0, 0], + "cubes": [ + {"origin": [12, 8, -17], "size": [7, 121, 7], "uv": [168, 0]}, + {"origin": [-24, -1, -19], "size": [48, 12, 11], "uv": [321, 69]}, + {"origin": [-12, 0, -61], "size": [24, 7, 7], "uv": [201, 152]}, + {"origin": [-16, 0, 141], "size": [32, 7, 7], "uv": [201, 138]}, + {"origin": [-1, 5, -8], "size": [12, 1, 149], "pivot": [16, 6, -8], "rotation": [0, 0, -12.5], "uv": [510, 468]}, + {"origin": [-11, 5, -8], "size": [12, 1, 149], "pivot": [-16, 6, -8], "rotation": [0, 0, 12.5], "uv": [510, 268]}, + {"origin": [-24, 124, -15.6], "size": [48, 4, 4], "uv": [0, 167]}, + {"origin": [-64, -1, -17], "size": [45, 7, 7], "uv": [201, 88]}, + {"origin": [-129.52995, 227, -15], "size": [126, 5, 3], "pivot": [64.77005, 165.36472, -20], "rotation": [0, 0, -73], "uv": [30, 745]}, + {"origin": [-112.52995, 227, -23], "size": [3, 3, 19], "pivot": [64.77005, 165.36472, -20], "rotation": [0, 0, -73], "uv": [0, 203]}, + {"origin": [-100.52995, 227, -23], "size": [3, 3, 19], "pivot": [64.77005, 165.36472, -20], "rotation": [0, 0, -73], "uv": [0, 203]}, + {"origin": [-88.52995, 227, -23], "size": [3, 3, 19], "pivot": [64.77005, 165.36472, -20], "rotation": [0, 0, -73], "uv": [0, 203]}, + {"origin": [-76.52995, 227, -23], "size": [3, 3, 19], "pivot": [64.77005, 165.36472, -20], "rotation": [0, 0, -73], "uv": [0, 203]}, + {"origin": [-64.52995, 227, -23], "size": [3, 3, 19], "pivot": [64.77005, 165.36472, -20], "rotation": [0, 0, -73], "uv": [0, 203]}, + {"origin": [-52.52995, 227, -23], "size": [3, 3, 19], "pivot": [64.77005, 165.36472, -20], "rotation": [0, 0, -73], "uv": [0, 203]}, + {"origin": [-40.52995, 227, -23], "size": [3, 3, 19], "pivot": [64.77005, 165.36472, -20], "rotation": [0, 0, -73], "uv": [0, 203]}, + {"origin": [-28.52995, 227, -23], "size": [3, 3, 19], "pivot": [64.77005, 165.36472, -20], "rotation": [0, 0, -73], "uv": [0, 203]}, + {"origin": [-16.52995, 227, -23], "size": [3, 3, 19], "pivot": [64.77005, 165.36472, -20], "rotation": [0, 0, -73], "uv": [0, 203]}, + {"origin": [19, -1, -17], "size": [45, 7, 7], "uv": [0, 175]}, + {"origin": [-19, -1, -62], "size": [7, 10, 48], "uv": [88, 311]}, + {"origin": [12, -1, -62], "size": [7, 10, 48], "uv": [194, 202]}, + {"origin": [-19, -1, -8.2], "size": [7, 10, 159], "uv": [362, 49]}, + {"origin": [12, -1, -8.2], "size": [7, 10, 159], "uv": [49, 360]}, + {"origin": [14, 9, 83.8], "size": [3, 22, 9], "uv": [24, 69]}, + {"origin": [-17, 9, 83.8], "size": [3, 22, 9], "uv": [0, 69]}, + {"origin": [48.3697, 0, -13.96784], "size": [5, 5, 103], "pivot": [50.8697, 2.5, -13.46784], "rotation": [0, -24, 0], "uv": [227, 709]}, + {"origin": [67.1887, 0, -16.71609], "size": [5, 5, 60], "pivot": [61, -1, -17], "rotation": [-180, -40, 180], "uv": [317, 4]}, + {"origin": [-53.36968, 0, -13.96785], "size": [5, 5, 103], "pivot": [-50.86968, 2.5, -13.46785], "rotation": [0, 24, 0], "uv": [25, 94]}, + {"origin": [-72.1887, 0, -14.71609], "size": [5, 5, 60], "pivot": [-61, -1, -17], "rotation": [-180, 40, 180], "uv": [6, 4]}, + {"origin": [-18, 0.1101, -57.2], "size": [5, 7, 129], "pivot": [-15.5, 3.1101, -56.95027], "rotation": [70, 0, 0], "uv": [31, 560], "mirror": true}, + {"origin": [13, 0.1101, -57.1], "size": [5, 7, 129], "pivot": [15.5, 3.1101, -56.95027], "rotation": [70, 0, 0], "uv": [31, 560]}, + {"origin": [-18, -0.24603, 30.29206], "size": [5, 7, 129], "pivot": [-15.5, 3.25397, 30.29206], "rotation": [-110, 0, 180], "uv": [31, 560], "mirror": true}, + {"origin": [13, -0.24603, 30.29206], "size": [5, 7, 129], "pivot": [15.5, 3.25397, 30.2921], "rotation": [-110, 0, 180], "uv": [31, 560]}, + {"origin": [14, 23.75906, 4.55558], "size": [3, 7, 69], "pivot": [15.5, 27.25906, 39.05558], "rotation": [-138, 0, 180], "uv": [13, 324]}, + {"origin": [-17, 23.75906, 4.55558], "size": [3, 7, 69], "pivot": [-15.5, 27.25906, 39.05558], "rotation": [-138, 0, 180], "uv": [119, 215]}, + {"origin": [-19, 8, -17], "size": [7, 121, 7], "uv": [140, 0]} + ] + }, + { + "name": "Crank", + "pivot": [0, 25.5, 88.3], + "cubes": [ + {"origin": [-27, 23, 85.8], "size": [54, 5, 5], "pivot": [0.5, 25.5, 88.3], "rotation": [45, 0, 0], "uv": [0, 157]}, + {"origin": [-13, 21, 83.8], "size": [26, 9, 9], "pivot": [0, 25.5, 88.3], "rotation": [45, 0, 0], "uv": [201, 102]}, + {"origin": [-25, 11, 87.8], "size": [2, 12, 1], "pivot": [0.5, 25.5, 88.3], "rotation": [45, 0, 0], "uv": [116, 69]}, + {"origin": [-25, 28, 87.8], "size": [2, 12, 1], "pivot": [0.5, 25.5, 88.3], "rotation": [45, 0, 0], "uv": [110, 69]}, + {"origin": [23, 11, 87.8], "size": [2, 12, 1], "pivot": [0.5, 25.5, 88.3], "rotation": [45, 0, 0], "uv": [62, 69]}, + {"origin": [23, 28, 87.8], "size": [2, 12, 1], "pivot": [0.5, 25.5, 88.3], "rotation": [45, 0, 0], "uv": [104, 69]}, + {"origin": [23, 11, 87.8], "size": [2, 12, 1], "pivot": [24, 25.5, 88.3], "rotation": [137.5, 0, 0], "uv": [58, 26]}, + {"origin": [23, 28, 87.8], "size": [2, 12, 1], "pivot": [24, 25.5, 88.3], "rotation": [137.5, 0, 0], "uv": [56, 69]}, + {"origin": [-25, 11, 87.8], "size": [2, 12, 1], "pivot": [24, 25.5, 88.3], "rotation": [137.5, 0, 0], "uv": [58, 0]}, + {"origin": [-25, 28, 87.8], "size": [2, 12, 1], "pivot": [24, 25.5, 88.3], "rotation": [137.5, 0, 0], "uv": [58, 13]} + ] + }, + { + "name": "Lever", + "pivot": [-8, 126, -14], + "cubes": [ + {"origin": [-11.7, 124, -45.9], "size": [23, 4, 4], "pivot": [-8, 126, -14], "rotation": [90, 0, 0], "uv": [56, 101]}, + {"origin": [-2.75, 121.4, 106.8], "size": [5, 8, 76], "pivot": [-8, 126, -14], "rotation": [90, 0, 0], "uv": [222, 311]}, + {"origin": [-4.75, 120.4, -50.2], "size": [9, 11, 90], "pivot": [-8, 126, -14], "rotation": [90, 0, 0], "uv": [340, 583]}, + {"origin": [-3.75, 121.4, 39.8], "size": [7, 9, 67], "pivot": [-8, 126, -14], "rotation": [90, 0, 0], "uv": [25, 227]}, + {"origin": [-0.75, 326, -9.7], "size": [1, 1, 3], "inflate": 0.2, "pivot": [-0.25, 326.5237, -9.28356], "rotation": [102.5, 0, 0], "uv": [16, 57]}, + {"origin": [-0.75, 323.94926, -11.32443], "size": [1, 1, 4], "inflate": 0.2, "pivot": [-0.25, 324.44926, -9.32443], "rotation": [82.5, 0, 0], "uv": [20, 57]} + ] + }, + { + "name": "CounterWeight", + "parent": "Lever", + "pivot": [-8.2, 95.99641, -13.89692], + "cubes": [ + {"origin": [8.8, 72, -16.9], "size": [2, 28, 6], "uv": [201, 0]}, + {"origin": [-11.2, 72, -16.9], "size": [2, 28, 6], "uv": [104, 109]}, + {"origin": [-11.2, 48, -38.9], "size": [22, 24, 4], "uv": [201, 166]}, + {"origin": [7.8, 32.1, -37.9], "size": [4, 40, 48], "uv": [201, 0]}, + {"origin": [-12.2, 32.1, -37.9], "size": [4, 40, 48], "uv": [0, 69]}, + {"origin": [-11.2, 48, 7.1], "size": [22, 24, 4], "uv": [138, 158]}, + {"origin": [-12.1, 49.73205, 7.8], "size": [23.8, 24, 4], "pivot": [-8.2, 49.73205, 10.1], "rotation": [120, 0, 0], "uv": [80, 0]}, + {"origin": [-11.5, 61.7, 12.054], "size": [23, 9, 4], "pivot": [-8.2, 38, 14.31539], "rotation": [90, 0, 0], "uv": [5, 44]}, + {"origin": [-8.2, 44.7, 40.31539], "size": [22, 43, 1], "pivot": [-8.2, 38, 14.31539], "rotation": [90, 0, 0], "uv": [0, 0]}, + {"origin": [-12.1, 49.73205, -39.6], "size": [23.8, 24, 4], "pivot": [-8.2, 49.73205, -37.9], "rotation": [-120, 0, 0], "uv": [80, 28]} + ] + }, + { + "name": "Rope_Projectile", + "parent": "Lever", + "pivot": [-8.25, 321.0872, -8.87572], + "rotation": [92.5, 0, 0], + "cubes": [ + {"origin": [-0.25, 315.0872, -137.87572], "size": [0, 2, 130], "pivot": [-8.2, 320.9872, 106.72428], "rotation": [-2.5, 0, 0], "uv": [222, 381]}, + {"origin": [-1.25, 316.0872, -137.87572], "size": [2, 0, 130], "pivot": [-8.2, 320.9872, 106.72428], "rotation": [-2.5, 0, 0], "uv": [179, 175]}, + {"origin": [-0.25, 325.02631, -137.48123], "size": [0, 2, 130], "pivot": [-8.2, 320.9872, 106.72428], "rotation": [3.5, 0, 0], "uv": [222, 381]}, + {"origin": [-1.25, 314.63912, -137.41784], "size": [2, 0, 130], "pivot": [-0.25, 316.04548, -85.81234], "rotation": [3.5, 0, 0], "uv": [178, 175]}, + {"origin": [-8.2, -317, 123.78511], "size": [16, 20, 16], "inflate": 0.3, "pivot": [-0.2, 142, 308.78511], "rotation": [-90, 0, 0], "uv": [387, 0]} + ] + }, + { + "name": "Cobblestone", + "parent": "Rope_Projectile", + "pivot": [-8.25, 321.0872, -8.87572], + "cubes": [ + {"origin": [-8.25, 311.0872, -149.87572], "size": [16, 16, 16], "uv": [0, 225]} + ] + }, + { + "name": "Rope_Lever", + "pivot": [-8.25, 26.66803, 103.76811], + "rotation": [90, 0, 0] + } + ] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/lang/en_us.json b/src/main/resources/assets/siegemachines/lang/en_us.json new file mode 100644 index 0000000..06a8f5f --- /dev/null +++ b/src/main/resources/assets/siegemachines/lang/en_us.json @@ -0,0 +1,38 @@ +{ + "item.siegemachines.mortar": "Mortar", + "item.siegemachines.culverin": "Culverin", + "item.siegemachines.trebuchet": "Trebuchet", + "item.siegemachines.catapult": "Catapult", + "item.siegemachines.ballista": "Ballista", + "item.siegemachines.battering_ram": "Battering Ram", + "item.siegemachines.cannonball": "Cannonball", + "item.siegemachines.giant_arrow": "Giant Arrow", + "item.siegemachines.stone": "Stone", + + "entity.siegemachines.mortar": "Mortar", + "entity.siegemachines.culverin": "Culverin", + "entity.siegemachines.trebuchet": "Trebuchet", + "entity.siegemachines.catapult": "Catapult", + "entity.siegemachines.ballista": "Ballista", + "entity.siegemachines.battering_ram": "Battering Ram", + + "item.siegemachines.turret_base": "Turret Base", + "item.siegemachines.beam": "Beam", + "item.siegemachines.counterweight": "Counterweight", + "item.siegemachines.barrel": "Barrel", + "item.siegemachines.wheel": "Wheel", + + "block.siegemachines.siege_workbench": "Siege Workbench", + + "itemGroup.siegemachines.medieval_siege_machines": "Medieval Siege Machines", + + "siegemachines.uses_gunpowder": "Uses Gunpowder", + "siegemachines.ammo": "Ammo:", + "siegemachines.category": "Medieval Siege Machines", + "siegemachines.machine_use": "Use Machine", + "siegemachines.machine_inventory": "Open Inventory", + "siegemachines.no_ammo": "No ammo!", + "siegemachines.no_gunpowder": "No gunpowder!", + + "category.siegemachines.siege_workbench_crafting": "Crafting" +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/lang/ru_ru.json b/src/main/resources/assets/siegemachines/lang/ru_ru.json new file mode 100644 index 0000000..3ff6f42 --- /dev/null +++ b/src/main/resources/assets/siegemachines/lang/ru_ru.json @@ -0,0 +1,36 @@ +{ + "item.siegemachines.mortar": "Мортира", + "item.siegemachines.culverin": "Кулеврина", + "item.siegemachines.trebuchet": "Требушет", + "item.siegemachines.catapult": "Катапульта", + "item.siegemachines.ballista": "Баллиста", + "item.siegemachines.battering_ram": "Таран", + "item.siegemachines.cannonball": "Пушечное ядро", + "item.siegemachines.giant_arrow": "Гигантская стрела", + "item.siegemachines.stone": "Валун", + + "entity.siegemachines.mortar": "Мортира", + "entity.siegemachines.culverin": "Кулеврина", + "entity.siegemachines.trebuchet": "Требушет", + "entity.siegemachines.catapult": "Катапульта", + "entity.siegemachines.ballista": "Баллиста", + "entity.siegemachines.battering_ram": "Таран", + + "item.siegemachines.turret_base": "Рама", + "item.siegemachines.beam": "Балка", + "item.siegemachines.counterweight": "Противовес", + "item.siegemachines.barrel": "Ствол", + "item.siegemachines.wheel": "Колесо", + + "block.siegemachines.siege_workbench": "Осадный верстак", + + "siegemachines.uses_gunpowder": "Требуется порох", + "siegemachines.ammo": "Боеприпасы:", + "siegemachines.category": "Medieval Siege Machines", + "siegemachines.machine_use": "Использовать машину", + "siegemachines.machine_inventory": "Открыть инвентарь", + "siegemachines.no_ammo": "Нет боеприпасов!", + "siegemachines.no_gunpowder":"Нет пороха!", + + "category.siegemachines.siege_workbench_crafting": "Крафт" +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/models/block/crafting_table.json b/src/main/resources/assets/siegemachines/models/block/crafting_table.json new file mode 100644 index 0000000..50ec456 --- /dev/null +++ b/src/main/resources/assets/siegemachines/models/block/crafting_table.json @@ -0,0 +1,12 @@ +{ + "parent": "siegemachines:block/cube", + "textures": { + "particle": "siegemachines:block/siege_workbench_front", + "north": "siegemachines:block/siege_workbench_front", + "south": "siegemachines:block/siege_workbench_side", + "east": "siegemachines:block/siege_workbench_side", + "west": "siegemachines:block/siege_workbench_front", + "up": "siegemachines:block/siege_workbench_top", + "down": "siegemachines:block/siege_workbench_bottom" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/models/block/siege_workbench.json b/src/main/resources/assets/siegemachines/models/block/siege_workbench.json new file mode 100644 index 0000000..9cb47f2 --- /dev/null +++ b/src/main/resources/assets/siegemachines/models/block/siege_workbench.json @@ -0,0 +1,12 @@ +{ + "parent": "minecraft:block/cube", + "textures": { + "particle": "siegemachines:block/siege_workbench_front", + "north": "siegemachines:block/siege_workbench_front", + "south": "siegemachines:block/siege_workbench_side", + "east": "siegemachines:block/siege_workbench_side", + "west": "siegemachines:block/siege_workbench_front", + "up": "siegemachines:block/siege_workbench_top", + "down": "siegemachines:block/siege_workbench_bottom" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/models/item/ballista.json b/src/main/resources/assets/siegemachines/models/item/ballista.json new file mode 100644 index 0000000..fcf8cc3 --- /dev/null +++ b/src/main/resources/assets/siegemachines/models/item/ballista.json @@ -0,0 +1,75 @@ +{ + "credit": "Made with Blockbench", + "gui_light": "side", + "parent": "builtin/entity", + "texture_size": [ + 128, + 128 + ], + "display": { + "thirdperson_righthand": { + "scale": [ + 0.3, + 0.3, + 0.3 + ] + }, + "thirdperson_lefthand": { + "scale": [ + 0.3, + 0.3, + 0.3 + ] + }, + "firstperson_righthand": { + "scale": [ + 0.3, + 0.3, + 0.3 + ] + }, + "firstperson_lefthand": { + "scale": [ + 0.3, + 0.3, + 0.3 + ] + }, + "ground": { + "scale": [ + 0.3, + 0.3, + 0.3 + ] + }, + "gui": { + "rotation": [ + 29, + 126, + 0 + ], + "translation": [ + -1.75, + -5, + 0 + ], + "scale": [ + 0.35, + 0.35, + 0.35 + ] + }, + "fixed": { + "translation": [ + 0, + -3, + 0 + ], + "scale": [ + 0.3, + 0.3, + 0.3 + ] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/models/item/barrel.json b/src/main/resources/assets/siegemachines/models/item/barrel.json new file mode 100644 index 0000000..be7c5a8 --- /dev/null +++ b/src/main/resources/assets/siegemachines/models/item/barrel.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "siegemachines:item/barrel" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/models/item/battering_ram.json b/src/main/resources/assets/siegemachines/models/item/battering_ram.json new file mode 100644 index 0000000..713f8ad --- /dev/null +++ b/src/main/resources/assets/siegemachines/models/item/battering_ram.json @@ -0,0 +1,79 @@ +{ + "credit": "Made with Blockbench", + "parent": "builtin/entity", + "texture_size": [ + 512, + 512 + ], + "display": { + "thirdperson_righthand": { + "scale": [ + 0.1, + 0.1, + 0.1 + ] + }, + "thirdperson_lefthand": { + "scale": [ + 0.1, + 0.1, + 0.1 + ] + }, + "firstperson_righthand": { + "scale": [ + 0.1, + 0.1, + 0.1 + ] + }, + "firstperson_lefthand": { + "scale": [ + 0.1, + 0.1, + 0.1 + ] + }, + "ground": { + "scale": [ + 0.1, + 0.1, + 0.1 + ] + }, + "gui": { + "rotation": [ + 29, + 126, + 0 + ], + "translation": [ + 0.25, + -4, + 0 + ], + "scale": [ + 0.155, + 0.155, + 0.155 + ] + }, + "fixed": { + "rotation": [ + 0, + 90, + 0 + ], + "translation": [ + 0, + -3, + -2.25 + ], + "scale": [ + 0.1, + 0.1, + 0.1 + ] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/models/item/beam.json b/src/main/resources/assets/siegemachines/models/item/beam.json new file mode 100644 index 0000000..29bd83c --- /dev/null +++ b/src/main/resources/assets/siegemachines/models/item/beam.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "siegemachines:item/beam" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/models/item/cannonball.json b/src/main/resources/assets/siegemachines/models/item/cannonball.json new file mode 100644 index 0000000..ce89e66 --- /dev/null +++ b/src/main/resources/assets/siegemachines/models/item/cannonball.json @@ -0,0 +1,39 @@ +{ + "credit": "Made with Blockbench", + "gui_light": "side", + "textures": { + "0": "siegemachines:entity/cannonball", + "particle": "siegemachines:entity/cannonball" + }, + "elements": [ + { + "from": [4, 4, 4], + "to": [12, 12, 12], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 8, 8], "texture": "#0"}, + "east": {"uv": [0, 0, 8, 8], "texture": "#0"}, + "south": {"uv": [0, 0, 8, 8], "texture": "#0"}, + "west": {"uv": [0, 0, 8, 8], "texture": "#0"}, + "up": {"uv": [0, 0, 8, 8], "texture": "#0"}, + "down": {"uv": [0, 0, 8, 8], "texture": "#0"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [18, 0, 0], + "translation": [0, 0, -1.5] + }, + "thirdperson_lefthand": { + "rotation": [18, 0, 0], + "translation": [0, 0, -1.5] + }, + "ground": { + "scale": [0.6, 0.6, 0.6] + }, + "gui": { + "rotation": [45, -45, 0] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/models/item/catapult.json b/src/main/resources/assets/siegemachines/models/item/catapult.json new file mode 100644 index 0000000..09603e0 --- /dev/null +++ b/src/main/resources/assets/siegemachines/models/item/catapult.json @@ -0,0 +1,75 @@ +{ + "credit": "Made with Blockbench", + "parent": "builtin/entity", + "gui_light": "side", + "texture_size": [ + 256, + 256 + ], + "display": { + "thirdperson_righthand": { + "scale": [ + 0.15, + 0.15, + 0.15 + ] + }, + "thirdperson_lefthand": { + "scale": [ + 0.15, + 0.15, + 0.15 + ] + }, + "firstperson_righthand": { + "scale": [ + 0.15, + 0.15, + 0.15 + ] + }, + "firstperson_lefthand": { + "scale": [ + 0.15, + 0.15, + 0.15 + ] + }, + "ground": { + "scale": [ + 0.15, + 0.15, + 0.15 + ] + }, + "gui": { + "rotation": [ + 29, + 126, + 0 + ], + "translation": [ + -1, + -3.25, + 0 + ], + "scale": [ + 0.18, + 0.18, + 0.18 + ] + }, + "fixed": { + "translation": [ + 0, + -3, + -2 + ], + "scale": [ + 0.15, + 0.15, + 0.15 + ] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/models/item/counterweight.json b/src/main/resources/assets/siegemachines/models/item/counterweight.json new file mode 100644 index 0000000..43d60d0 --- /dev/null +++ b/src/main/resources/assets/siegemachines/models/item/counterweight.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "siegemachines:item/counterweight" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/models/item/culverine.json b/src/main/resources/assets/siegemachines/models/item/culverine.json new file mode 100644 index 0000000..b0fda69 --- /dev/null +++ b/src/main/resources/assets/siegemachines/models/item/culverine.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "siegemachines:items/culverine" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/models/item/giant_arrow.json b/src/main/resources/assets/siegemachines/models/item/giant_arrow.json new file mode 100644 index 0000000..8f4325f --- /dev/null +++ b/src/main/resources/assets/siegemachines/models/item/giant_arrow.json @@ -0,0 +1,103 @@ +{ + "credit": "Made with Blockbench", + "gui_light": "front", + "texture_size": [64, 64], + "textures": { + "0": "siegemachines:entity/giant_arrow" + }, + "elements": [ + { + "from": [5.5, 8, -10], + "to": [10.5, 8, 24], + "rotation": {"angle": 45, "axis": "z", "origin": [8, 8, 4]}, + "faces": { + "north": {"uv": [0, 8.5, 1.25, 8.5], "texture": "#0"}, + "east": {"uv": [-8.5, 8.5, 0, 8.5], "texture": "#0"}, + "south": {"uv": [9.75, 8.5, 11, 8.5], "texture": "#0"}, + "west": {"uv": [1.25, 8.5, 9.75, 8.5], "texture": "#0"}, + "up": {"uv": [1.25, 8.5, 0, 0], "texture": "#0"}, + "down": {"uv": [2.5, 0, 1.25, 8.5], "texture": "#0"} + } + }, + { + "from": [5.5, 8, -10], + "to": [10.5, 8, 24], + "rotation": {"angle": -45, "axis": "z", "origin": [8, 8, 4]}, + "faces": { + "north": {"uv": [0, 8.5, 1.25, 8.5], "texture": "#0"}, + "east": {"uv": [-8.5, 8.5, 0, 8.5], "texture": "#0"}, + "south": {"uv": [9.75, 8.5, 11, 8.5], "texture": "#0"}, + "west": {"uv": [1.25, 8.5, 9.75, 8.5], "texture": "#0"}, + "up": {"uv": [1.25, 8.5, 0, 0], "texture": "#0"}, + "down": {"uv": [2.5, 0, 1.25, 8.5], "texture": "#0"} + } + }, + { + "from": [6, 8, -13], + "to": [10, 8, -9], + "rotation": {"angle": 45, "axis": "z", "origin": [8, 8, 1]}, + "faces": { + "north": {"uv": [2.75, 1, 3.75, 1], "texture": "#0"}, + "east": {"uv": [1.75, 1, 2.75, 1], "texture": "#0"}, + "south": {"uv": [4.75, 1, 5.75, 1], "texture": "#0"}, + "west": {"uv": [3.75, 1, 4.75, 1], "texture": "#0"}, + "up": {"uv": [3.75, 1, 2.75, 0], "texture": "#0"}, + "down": {"uv": [4.75, 0, 3.75, 1], "texture": "#0"} + } + }, + { + "from": [6, 8, -13], + "to": [10, 8, -9], + "rotation": {"angle": -45, "axis": "z", "origin": [8, 8, 1]}, + "faces": { + "north": {"uv": [4.75, 1, 5.75, 1], "texture": "#0"}, + "east": {"uv": [3.75, 1, 4.75, 1], "texture": "#0"}, + "south": {"uv": [6.75, 1, 7.75, 1], "texture": "#0"}, + "west": {"uv": [5.75, 1, 6.75, 1], "texture": "#0"}, + "up": {"uv": [5.75, 1, 4.75, 0], "texture": "#0"}, + "down": {"uv": [6.75, 0, 5.75, 1], "texture": "#0"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [90, 0, 0], + "translation": [0, 0, 1] + }, + "thirdperson_lefthand": { + "rotation": [90, 0, 0], + "translation": [0, 0, 1] + }, + "firstperson_righthand": { + "rotation": [60, 0, 0] + }, + "firstperson_lefthand": { + "rotation": [60, 0, 0] + }, + "ground": { + "scale": [0.5, 0.5, 0.5] + }, + "gui": { + "rotation": [90, -45, -45], + "translation": [-0.75, -1, 0], + "scale": [0.6, 0.6, 0.6] + }, + "head": { + "rotation": [-180, 0, 0], + "translation": [0, 4.25, -11.75] + }, + "fixed": { + "rotation": [-180, 0, 0], + "translation": [0, 0, -37.25], + "scale": [2, 2, 2] + } + }, + "groups": [ + { + "name": "GiantArrow", + "origin": [0, 0, 4], + "color": 0, + "children": [0, 1, 2, 3] + } + ] +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/models/item/giant_stone.json b/src/main/resources/assets/siegemachines/models/item/giant_stone.json new file mode 100644 index 0000000..48736d0 --- /dev/null +++ b/src/main/resources/assets/siegemachines/models/item/giant_stone.json @@ -0,0 +1,48 @@ +{ + "credit": "Made with Blockbench", + "textures": { + "0": "siegemachines:entity/stone", + "particle": "siegemachines:entity/stone" + }, + "elements": [ + { + "from": [-7, -7, -7], + "to": [23, 23, 23], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 16, 16], "texture": "#0"}, + "east": {"uv": [0, 0, 16, 16], "texture": "#0"}, + "south": {"uv": [0, 0, 16, 16], "texture": "#0"}, + "west": {"uv": [0, 0, 16, 16], "texture": "#0"}, + "up": {"uv": [0, 0, 16, 16], "texture": "#0"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#0"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [18, 0, 0], + "translation": [-6, 5, 1] + }, + "thirdperson_lefthand": { + "rotation": [18, 0, 0], + "translation": [-6, 5, 1] + }, + "firstperson_righthand": { + "translation": [-9, 0, 0] + }, + "firstperson_lefthand": { + "translation": [-9, 0, 0] + }, + "ground": { + "scale": [0.5, 0.5, 0.5] + }, + "gui": { + "rotation": [45, -45, 0], + "scale": [0.5, 0.5, 0.5] + }, + "fixed": { + "scale": [0.5, 0.5, 0.5] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/models/item/mortar.json b/src/main/resources/assets/siegemachines/models/item/mortar.json new file mode 100644 index 0000000..015a084 --- /dev/null +++ b/src/main/resources/assets/siegemachines/models/item/mortar.json @@ -0,0 +1,75 @@ +{ + "credit": "Made with Blockbench", + "parent": "builtin/entity", + "gui_light": "side", + "texture_size": [ + 128, + 128 + ], + "display": { + "thirdperson_righthand": { + "scale": [ + 0.3, + 0.3, + 0.3 + ] + }, + "thirdperson_lefthand": { + "scale": [ + 0.3, + 0.3, + 0.3 + ] + }, + "firstperson_righthand": { + "scale": [ + 0.3, + 0.3, + 0.3 + ] + }, + "firstperson_lefthand": { + "scale": [ + 0.3, + 0.3, + 0.3 + ] + }, + "ground": { + "scale": [ + 0.3, + 0.3, + 0.3 + ] + }, + "gui": { + "rotation": [ + 29, + 126, + 0 + ], + "translation": [ + 1.25, + -2.75, + 0 + ], + "scale": [ + 0.35, + 0.35, + 0.35 + ] + }, + "fixed": { + "translation": [ + 0, + -3, + 0 + ], + "scale": [ + 0.3, + 0.3, + 0.3 + ] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/models/item/siege_workbench.json b/src/main/resources/assets/siegemachines/models/item/siege_workbench.json new file mode 100644 index 0000000..87dedab --- /dev/null +++ b/src/main/resources/assets/siegemachines/models/item/siege_workbench.json @@ -0,0 +1,3 @@ +{ + "parent": "siegemachines:block/siege_workbench" +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/models/item/stone.json b/src/main/resources/assets/siegemachines/models/item/stone.json new file mode 100644 index 0000000..23fa58f --- /dev/null +++ b/src/main/resources/assets/siegemachines/models/item/stone.json @@ -0,0 +1,53 @@ +{ + "credit": "Made with Blockbench", + "gui_light": "side", + "textures": { + "0": "siegemachines:entity/stone", + "particle": "siegemachines:entity/stone" + }, + "elements": [ + { + "from": [-2, -2, -2], + "to": [18, 18, 18], + "rotation": {"angle": 0, "axis": "y", "origin": [8, 8, 8]}, + "faces": { + "north": {"uv": [0, 0, 16, 16], "texture": "#0"}, + "east": {"uv": [0, 0, 16, 16], "texture": "#0"}, + "south": {"uv": [0, 0, 16, 16], "texture": "#0"}, + "west": {"uv": [0, 0, 16, 16], "texture": "#0"}, + "up": {"uv": [0, 0, 16, 16], "texture": "#0"}, + "down": {"uv": [0, 0, 16, 16], "texture": "#0"} + } + } + ], + "display": { + "thirdperson_righthand": { + "rotation": [18, 0, 0], + "translation": [-6, 5, 1], + "scale": [0.7, 0.7, 0.7] + }, + "thirdperson_lefthand": { + "rotation": [18, 0, 0], + "translation": [-6, 5, 1], + "scale": [0.7, 0.7, 0.7] + }, + "firstperson_righthand": { + "translation": [-9, 0, 0], + "scale": [0.7, 0.7, 0.7] + }, + "firstperson_lefthand": { + "translation": [-9, 0, 0], + "scale": [0.7, 0.7, 0.7] + }, + "ground": { + "scale": [0.3, 0.3, 0.3] + }, + "gui": { + "rotation": [45, -45, 0], + "scale": [0.5, 0.5, 0.5] + }, + "fixed": { + "scale": [0.5, 0.5, 0.5] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/models/item/trebuchet.json b/src/main/resources/assets/siegemachines/models/item/trebuchet.json new file mode 100644 index 0000000..8c4f0cf --- /dev/null +++ b/src/main/resources/assets/siegemachines/models/item/trebuchet.json @@ -0,0 +1,75 @@ +{ + "credit": "Made with Blockbench", + "parent": "builtin/entity", + "gui_light": "side", + "texture_size": [ + 1024, + 1024 + ], + "display": { + "thirdperson_righthand": { + "scale": [ + 0.05, + 0.05, + 0.05 + ] + }, + "thirdperson_lefthand": { + "scale": [ + 0.05, + 0.05, + 0.05 + ] + }, + "firstperson_righthand": { + "scale": [ + 0.05, + 0.05, + 0.05 + ] + }, + "firstperson_lefthand": { + "scale": [ + 0.05, + 0.05, + 0.05 + ] + }, + "ground": { + "scale": [ + 0.05, + 0.05, + 0.05 + ] + }, + "gui": { + "rotation": [ + 29, + 126, + 0 + ], + "translation": [ + -0.75, + -6.75, + 0 + ], + "scale": [ + 0.055, + 0.055, + 0.055 + ] + }, + "fixed": { + "translation": [ + 0, + -5.5, + -2 + ], + "scale": [ + 0.05, + 0.05, + 0.05 + ] + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/models/item/turret_base.json b/src/main/resources/assets/siegemachines/models/item/turret_base.json new file mode 100644 index 0000000..9f870c5 --- /dev/null +++ b/src/main/resources/assets/siegemachines/models/item/turret_base.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "siegemachines:item/turret_base" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/models/item/wheel.json b/src/main/resources/assets/siegemachines/models/item/wheel.json new file mode 100644 index 0000000..6120f6e --- /dev/null +++ b/src/main/resources/assets/siegemachines/models/item/wheel.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "siegemachines:item/wheel" + } +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/sounds.json b/src/main/resources/assets/siegemachines/sounds.json new file mode 100644 index 0000000..a15263f --- /dev/null +++ b/src/main/resources/assets/siegemachines/sounds.json @@ -0,0 +1,197 @@ +{ + "trebuchet_shooting": { + "category": "record", + "sounds": [ + { + "name": "siegemachines:trebuchet_shooting", + "stream": true + } + ] + }, + "trebuchet_reloading": { + "category": "record", + "sounds": [ + { + "name": "siegemachines:trebuchet_reloading_1", + "stream": true + }, + { + "name": "siegemachines:trebuchet_reloading_2", + "stream": true + }, + { + "name": "siegemachines:trebuchet_reloading_3", + "stream": true + }, + { + "name": "siegemachines:trebuchet_reloading_4", + "stream": true + }, + { + "name": "siegemachines:trebuchet_reloading_5", + "stream": true + }, + { + "name": "siegemachines:trebuchet_reloading_6", + "stream": true + } + ] + }, + "catapult_shooting": { + "category": "record", + "sounds": [ + { + "name": "siegemachines:catapult_shooting_0", + "stream": true + }, + { + "name": "siegemachines:catapult_shooting_1", + "stream": true + } + ] + }, + "catapult_reloading": { + "category": "record", + "sounds": [ + { + "name": "siegemachines:catapult_reloading_0", + "stream": true + }, + { + "name": "siegemachines:catapult_reloading_1", + "stream": true + }, + { + "name": "siegemachines:catapult_reloading_2", + "stream": true + }, + { + "name": "siegemachines:catapult_reloading_3", + "stream": true + }, + { + "name": "siegemachines:catapult_reloading_4", + "stream": true + }, + { + "name": "siegemachines:catapult_reloading_5", + "stream": true + } + ] + }, + "ballista_shooting": { + "category": "record", + "sounds": [ + { + "name": "siegemachines:ballista_shooting_0", + "stream": true + }, + { + "name": "siegemachines:ballista_shooting_1", + "stream": true + }, + { + "name": "siegemachines:ballista_shooting_2", + "stream": true + }, + { + "name": "siegemachines:ballista_shooting_3", + "stream": true + }, + { + "name": "siegemachines:ballista_shooting_4", + "stream": true + } + ] + }, + "ballista_reloading": { + "category": "record", + "sounds": [ + { + "name": "siegemachines:ballista_reloading_0", + "stream": true + }, + { + "name": "siegemachines:ballista_reloading_1", + "stream": true + }, + { + "name": "siegemachines:ballista_reloading_2", + "stream": true + }, + { + "name": "siegemachines:ballista_reloading_3", + "stream": true + } + ] + }, + "mortar_shooting": { + "category": "record", + "sounds": [ + { + "name": "siegemachines:mortar_shooting", + "stream": true + } + ] + }, + "fuse": { + "category": "record", + "sounds": [ + { + "name": "siegemachines:fuse", + "stream": true + } + ] + }, + "cannon_wheels": { + "category": "record", + "sounds": [ + { + "name": "siegemachines:cannon_wheels_0", + "stream": true + }, + { + "name": "siegemachines:cannon_wheels_1", + "stream": true + }, + { + "name": "siegemachines:cannon_wheels_2", + "stream": true + }, + { + "name": "siegemachines:cannon_wheels_3", + "stream": true + } + ] + }, + "ram_wheels": { + "category": "record", + "sounds": [ + { + "name": "siegemachines:ram_wheels_0", + "stream": true + }, + { + "name": "siegemachines:ram_wheels_1", + "stream": true + }, + { + "name": "siegemachines:ram_wheels_2", + "stream": true + }, + { + "name": "siegemachines:ram_wheels_3", + "stream": true + } + ] + }, + "ram_hitting": { + "category": "record", + "sounds": [ + { + "name": "siegemachines:ram_hitting", + "stream": true + } + ] + } +} \ No newline at end of file diff --git a/src/main/resources/assets/siegemachines/sounds/ballista_reloading_0.ogg b/src/main/resources/assets/siegemachines/sounds/ballista_reloading_0.ogg new file mode 100644 index 0000000000000000000000000000000000000000..d887b1ffa94270af46d078d935eb4b2c72fcc42e GIT binary patch literal 37152 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 UT4yWKtJz@!V-*mJ=NJG00EZSV$N&HU literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/siegemachines/sounds/ballista_reloading_1.ogg b/src/main/resources/assets/siegemachines/sounds/ballista_reloading_1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..8b45d97835cf763a3a48573ba7711d8db6493741 GIT binary patch literal 36399 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/siegemachines/sounds/ballista_reloading_2.ogg b/src/main/resources/assets/siegemachines/sounds/ballista_reloading_2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..bc44acecccc24130e8cc5bdda5baf8bb47301a1d GIT binary patch literal 35466 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¥M$UD1Z6K3>$>!w+O);YYtvD<^De1;Q5FmhN(#c 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 XYt7HQBUcZt`8q{=&l|4{N3{U}Q7axq literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/siegemachines/sounds/ballista_reloading_3.ogg b/src/main/resources/assets/siegemachines/sounds/ballista_reloading_3.ogg new file mode 100644 index 0000000000000000000000000000000000000000..81e2f99be2d783853098e7ff445b93d344709339 GIT binary patch literal 36415 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%0D$$oX#yT> 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 a^np`1U_}594h{|u4h{|u4h{|u4h{~|Erxag literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/siegemachines/sounds/ballista_shooting_1.ogg b/src/main/resources/assets/siegemachines/sounds/ballista_shooting_1.ogg new file mode 100644 index 0000000000000000000000000000000000000000..f6a45c74a86c9a657b3de2ffbf18db13f83d7416 GIT binary patch literal 43546 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 literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/siegemachines/sounds/ballista_shooting_2.ogg b/src/main/resources/assets/siegemachines/sounds/ballista_shooting_2.ogg new file mode 100644 index 0000000000000000000000000000000000000000..47d76e5856ddbe24d819d5f93ebbfafb64f90483 GIT binary patch literal 44007 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