diff --git a/build.properties b/build.properties index 4e8f47c0..f9e660c2 100644 --- a/build.properties +++ b/build.properties @@ -1,5 +1,5 @@ minecraft_version=1.7.10 -forge_version=10.13.0.1208 +forge_version=10.13.1.1217 mantle_version=0.3.1.jenkins176 CCLIB_version=1.1.1.95 NEI_version=1.0.2.15 diff --git a/item_texture_backup.zip b/item_texture_backup.zip new file mode 100644 index 00000000..28c0ead2 Binary files /dev/null and b/item_texture_backup.zip differ diff --git a/resources/assets/tinker/sounds.json b/resources/assets/tinker/sounds.json index 4374951c..f2270a19 100644 --- a/resources/assets/tinker/sounds.json +++ b/resources/assets/tinker/sounds.json @@ -16,5 +16,23 @@ "sounds": [ "launcher_clank" ] + }, + "woodHit": { + "category": "block", + "sounds": [ + "woodHit1", + "woodHit2", + "woodHit3", + "woodHit4", + "woodHit5" + ] + }, + "stoneHit": { + "category": "block", + "sounds": [ + "stoneHit1", + "stoneHit2", + "stoneHit3" + ] } } \ No newline at end of file diff --git a/resources/assets/tinker/textures/gui/Crosshair.png b/resources/assets/tinker/textures/gui/Crosshair.png new file mode 100644 index 00000000..7f9268ad Binary files /dev/null and b/resources/assets/tinker/textures/gui/Crosshair.png differ diff --git a/resources/assets/tinker/textures/gui/Crosshair2.png b/resources/assets/tinker/textures/gui/Crosshair2.png new file mode 100644 index 00000000..0a9f5973 Binary files /dev/null and b/resources/assets/tinker/textures/gui/Crosshair2.png differ diff --git a/resources/assets/tinker/textures/gui/Crosshair3.png b/resources/assets/tinker/textures/gui/Crosshair3.png new file mode 100644 index 00000000..f1deeaea Binary files /dev/null and b/resources/assets/tinker/textures/gui/Crosshair3.png differ diff --git a/resources/assets/tinker/textures/gui/Crosshair4.png b/resources/assets/tinker/textures/gui/Crosshair4.png new file mode 100644 index 00000000..a77b10ae Binary files /dev/null and b/resources/assets/tinker/textures/gui/Crosshair4.png differ diff --git a/resources/assets/tinker/textures/gui/icons.png b/resources/assets/tinker/textures/gui/icons.png index a1cd9908..0ac16916 100644 Binary files a/resources/assets/tinker/textures/gui/icons.png and b/resources/assets/tinker/textures/gui/icons.png differ diff --git a/resources/assets/tinker/textures/items/arrow/_arrow_fletching.png b/resources/assets/tinker/textures/items/arrow/_arrow_fletching.png index 22451c93..ffc223a5 100644 Binary files a/resources/assets/tinker/textures/items/arrow/_arrow_fletching.png and b/resources/assets/tinker/textures/items/arrow/_arrow_fletching.png differ diff --git a/resources/assets/tinker/textures/items/arrow/_arrow_head.png b/resources/assets/tinker/textures/items/arrow/_arrow_head.png index 613ec83d..f6f59c5d 100644 Binary files a/resources/assets/tinker/textures/items/arrow/_arrow_head.png and b/resources/assets/tinker/textures/items/arrow/_arrow_head.png differ diff --git a/resources/assets/tinker/textures/items/arrow/_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/_arrow_shaft.png index 1d2ba201..8b3dfbaa 100644 Binary files a/resources/assets/tinker/textures/items/arrow/_arrow_shaft.png and b/resources/assets/tinker/textures/items/arrow/_arrow_shaft.png differ diff --git a/resources/assets/tinker/textures/items/arrow/alumite_arrow_head.png b/resources/assets/tinker/textures/items/arrow/alumite_arrow_head.png index 358e62bd..9b6026cc 100644 Binary files a/resources/assets/tinker/textures/items/arrow/alumite_arrow_head.png and b/resources/assets/tinker/textures/items/arrow/alumite_arrow_head.png differ diff --git a/resources/assets/tinker/textures/items/arrow/alumite_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/alumite_arrow_shaft.png deleted file mode 100644 index e9dcabed..00000000 Binary files a/resources/assets/tinker/textures/items/arrow/alumite_arrow_shaft.png and /dev/null differ diff --git a/resources/assets/tinker/textures/items/arrow/ardite_arrow_head.png b/resources/assets/tinker/textures/items/arrow/ardite_arrow_head.png index d6e407ab..08816645 100644 Binary files a/resources/assets/tinker/textures/items/arrow/ardite_arrow_head.png and b/resources/assets/tinker/textures/items/arrow/ardite_arrow_head.png differ diff --git a/resources/assets/tinker/textures/items/arrow/ardite_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/ardite_arrow_shaft.png deleted file mode 100644 index 28ae9352..00000000 Binary files a/resources/assets/tinker/textures/items/arrow/ardite_arrow_shaft.png and /dev/null differ diff --git a/resources/assets/tinker/textures/items/arrow/beheading_arrow_effect.png b/resources/assets/tinker/textures/items/arrow/beheading_arrow_effect.png index e8f62de9..b1200458 100644 Binary files a/resources/assets/tinker/textures/items/arrow/beheading_arrow_effect.png and b/resources/assets/tinker/textures/items/arrow/beheading_arrow_effect.png differ diff --git a/resources/assets/tinker/textures/items/arrow/blaze_arrow_effect.png b/resources/assets/tinker/textures/items/arrow/blaze_arrow_effect.png index 20114e40..a5fd2704 100644 Binary files a/resources/assets/tinker/textures/items/arrow/blaze_arrow_effect.png and b/resources/assets/tinker/textures/items/arrow/blaze_arrow_effect.png differ diff --git a/resources/assets/tinker/textures/items/arrow/blaze_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/blaze_arrow_shaft.png new file mode 100644 index 00000000..b040ecd7 Binary files /dev/null and b/resources/assets/tinker/textures/items/arrow/blaze_arrow_shaft.png differ diff --git a/resources/assets/tinker/textures/items/arrow/blueslime_arrow_fletching.png b/resources/assets/tinker/textures/items/arrow/blueslime_arrow_fletching.png index 2f0b1ac9..c551878c 100644 Binary files a/resources/assets/tinker/textures/items/arrow/blueslime_arrow_fletching.png and b/resources/assets/tinker/textures/items/arrow/blueslime_arrow_fletching.png differ diff --git a/resources/assets/tinker/textures/items/arrow/blueslime_arrow_head.png b/resources/assets/tinker/textures/items/arrow/blueslime_arrow_head.png index a643f863..e1598df3 100644 Binary files a/resources/assets/tinker/textures/items/arrow/blueslime_arrow_head.png and b/resources/assets/tinker/textures/items/arrow/blueslime_arrow_head.png differ diff --git a/resources/assets/tinker/textures/items/arrow/blueslime_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/blueslime_arrow_shaft.png deleted file mode 100644 index 077d3ed3..00000000 Binary files a/resources/assets/tinker/textures/items/arrow/blueslime_arrow_shaft.png and /dev/null differ diff --git a/resources/assets/tinker/textures/items/arrow/bone_arrow_head.png b/resources/assets/tinker/textures/items/arrow/bone_arrow_head.png index a50bfcc2..c91c17a9 100644 Binary files a/resources/assets/tinker/textures/items/arrow/bone_arrow_head.png and b/resources/assets/tinker/textures/items/arrow/bone_arrow_head.png differ diff --git a/resources/assets/tinker/textures/items/arrow/bone_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/bone_arrow_shaft.png index 36c2c70d..b205e810 100644 Binary files a/resources/assets/tinker/textures/items/arrow/bone_arrow_shaft.png and b/resources/assets/tinker/textures/items/arrow/bone_arrow_shaft.png differ diff --git a/resources/assets/tinker/textures/items/arrow/bronze_arrow_head.png b/resources/assets/tinker/textures/items/arrow/bronze_arrow_head.png index 18f80ff2..26e69804 100644 Binary files a/resources/assets/tinker/textures/items/arrow/bronze_arrow_head.png and b/resources/assets/tinker/textures/items/arrow/bronze_arrow_head.png differ diff --git a/resources/assets/tinker/textures/items/arrow/bronze_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/bronze_arrow_shaft.png deleted file mode 100644 index d097cffb..00000000 Binary files a/resources/assets/tinker/textures/items/arrow/bronze_arrow_shaft.png and /dev/null differ diff --git a/resources/assets/tinker/textures/items/arrow/cactus_arrow_head.png b/resources/assets/tinker/textures/items/arrow/cactus_arrow_head.png index 1f5aecb5..b68fc8bf 100644 Binary files a/resources/assets/tinker/textures/items/arrow/cactus_arrow_head.png and b/resources/assets/tinker/textures/items/arrow/cactus_arrow_head.png differ diff --git a/resources/assets/tinker/textures/items/arrow/cactus_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/cactus_arrow_shaft.png deleted file mode 100644 index 174d1c31..00000000 Binary files a/resources/assets/tinker/textures/items/arrow/cactus_arrow_shaft.png and /dev/null differ diff --git a/resources/assets/tinker/textures/items/arrow/cobalt_arrow_head.png b/resources/assets/tinker/textures/items/arrow/cobalt_arrow_head.png index 1d6d352e..b3466013 100644 Binary files a/resources/assets/tinker/textures/items/arrow/cobalt_arrow_head.png and b/resources/assets/tinker/textures/items/arrow/cobalt_arrow_head.png differ diff --git a/resources/assets/tinker/textures/items/arrow/cobalt_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/cobalt_arrow_shaft.png deleted file mode 100644 index 7d16c19b..00000000 Binary files a/resources/assets/tinker/textures/items/arrow/cobalt_arrow_shaft.png and /dev/null differ diff --git a/resources/assets/tinker/textures/items/arrow/copper_arrow_head.png b/resources/assets/tinker/textures/items/arrow/copper_arrow_head.png index 45d399c6..bedc2a11 100644 Binary files a/resources/assets/tinker/textures/items/arrow/copper_arrow_head.png and b/resources/assets/tinker/textures/items/arrow/copper_arrow_head.png differ diff --git a/resources/assets/tinker/textures/items/arrow/copper_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/copper_arrow_shaft.png deleted file mode 100644 index e27be7dc..00000000 Binary files a/resources/assets/tinker/textures/items/arrow/copper_arrow_shaft.png and /dev/null differ diff --git a/resources/assets/tinker/textures/items/arrow/diamond_arrow_effect.png b/resources/assets/tinker/textures/items/arrow/diamond_arrow_effect.png index a83fd965..27cc9197 100644 Binary files a/resources/assets/tinker/textures/items/arrow/diamond_arrow_effect.png and b/resources/assets/tinker/textures/items/arrow/diamond_arrow_effect.png differ diff --git a/resources/assets/tinker/textures/items/arrow/emerald_arrow_effect.png b/resources/assets/tinker/textures/items/arrow/emerald_arrow_effect.png index 828c6248..696306db 100644 Binary files a/resources/assets/tinker/textures/items/arrow/emerald_arrow_effect.png and b/resources/assets/tinker/textures/items/arrow/emerald_arrow_effect.png differ diff --git a/resources/assets/tinker/textures/items/arrow/feather_arrow_fletching.png b/resources/assets/tinker/textures/items/arrow/feather_arrow_fletching.png index 22451c93..fab341b0 100644 Binary files a/resources/assets/tinker/textures/items/arrow/feather_arrow_fletching.png and b/resources/assets/tinker/textures/items/arrow/feather_arrow_fletching.png differ diff --git a/resources/assets/tinker/textures/items/arrow/flint_arrow_head.png b/resources/assets/tinker/textures/items/arrow/flint_arrow_head.png index ce4e62d3..ffa643d5 100644 Binary files a/resources/assets/tinker/textures/items/arrow/flint_arrow_head.png and b/resources/assets/tinker/textures/items/arrow/flint_arrow_head.png differ diff --git a/resources/assets/tinker/textures/items/arrow/flint_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/flint_arrow_shaft.png deleted file mode 100644 index a5246c61..00000000 Binary files a/resources/assets/tinker/textures/items/arrow/flint_arrow_shaft.png and /dev/null differ diff --git a/resources/assets/tinker/textures/items/arrow/flux_arrow_effect.png b/resources/assets/tinker/textures/items/arrow/flux_arrow_effect.png index 0478ea41..28d52114 100644 Binary files a/resources/assets/tinker/textures/items/arrow/flux_arrow_effect.png and b/resources/assets/tinker/textures/items/arrow/flux_arrow_effect.png differ diff --git a/resources/assets/tinker/textures/items/arrow/ice_arrow_effect.png b/resources/assets/tinker/textures/items/arrow/ice_arrow_effect.png index 1b362937..f6d61463 100644 Binary files a/resources/assets/tinker/textures/items/arrow/ice_arrow_effect.png and b/resources/assets/tinker/textures/items/arrow/ice_arrow_effect.png differ diff --git a/resources/assets/tinker/textures/items/arrow/iron_arrow_head.png b/resources/assets/tinker/textures/items/arrow/iron_arrow_head.png index caf93359..a360f981 100644 Binary files a/resources/assets/tinker/textures/items/arrow/iron_arrow_head.png and b/resources/assets/tinker/textures/items/arrow/iron_arrow_head.png differ diff --git a/resources/assets/tinker/textures/items/arrow/iron_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/iron_arrow_shaft.png deleted file mode 100644 index 254ee4fa..00000000 Binary files a/resources/assets/tinker/textures/items/arrow/iron_arrow_shaft.png and /dev/null differ diff --git a/resources/assets/tinker/textures/items/arrow/lapis_arrow_effect.png b/resources/assets/tinker/textures/items/arrow/lapis_arrow_effect.png index 018bebc9..8096f8a0 100644 Binary files a/resources/assets/tinker/textures/items/arrow/lapis_arrow_effect.png and b/resources/assets/tinker/textures/items/arrow/lapis_arrow_effect.png differ diff --git a/resources/assets/tinker/textures/items/arrow/lava_arrow_effect.png b/resources/assets/tinker/textures/items/arrow/lava_arrow_effect.png index d020a471..d7d4f074 100644 Binary files a/resources/assets/tinker/textures/items/arrow/lava_arrow_effect.png and b/resources/assets/tinker/textures/items/arrow/lava_arrow_effect.png differ diff --git a/resources/assets/tinker/textures/items/arrow/leaf_arrow_fletching.png b/resources/assets/tinker/textures/items/arrow/leaf_arrow_fletching.png index 5854bbe3..97342bd4 100644 Binary files a/resources/assets/tinker/textures/items/arrow/leaf_arrow_fletching.png and b/resources/assets/tinker/textures/items/arrow/leaf_arrow_fletching.png differ diff --git a/resources/assets/tinker/textures/items/arrow/manyullyn_arrow_head.png b/resources/assets/tinker/textures/items/arrow/manyullyn_arrow_head.png index 18bc40ce..a4cd1c1a 100644 Binary files a/resources/assets/tinker/textures/items/arrow/manyullyn_arrow_head.png and b/resources/assets/tinker/textures/items/arrow/manyullyn_arrow_head.png differ diff --git a/resources/assets/tinker/textures/items/arrow/manyullyn_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/manyullyn_arrow_shaft.png deleted file mode 100644 index 1be08ff3..00000000 Binary files a/resources/assets/tinker/textures/items/arrow/manyullyn_arrow_shaft.png and /dev/null differ diff --git a/resources/assets/tinker/textures/items/arrow/moss_arrow_effect.png b/resources/assets/tinker/textures/items/arrow/moss_arrow_effect.png index 4e18d6e3..a014e849 100644 Binary files a/resources/assets/tinker/textures/items/arrow/moss_arrow_effect.png and b/resources/assets/tinker/textures/items/arrow/moss_arrow_effect.png differ diff --git a/resources/assets/tinker/textures/items/arrow/necrotic_arrow_effect.png b/resources/assets/tinker/textures/items/arrow/necrotic_arrow_effect.png index 49a1a02a..1fdf6a6f 100644 Binary files a/resources/assets/tinker/textures/items/arrow/necrotic_arrow_effect.png and b/resources/assets/tinker/textures/items/arrow/necrotic_arrow_effect.png differ diff --git a/resources/assets/tinker/textures/items/arrow/netherrack_arrow_head.png b/resources/assets/tinker/textures/items/arrow/netherrack_arrow_head.png index 8b5399e5..875d2e26 100644 Binary files a/resources/assets/tinker/textures/items/arrow/netherrack_arrow_head.png and b/resources/assets/tinker/textures/items/arrow/netherrack_arrow_head.png differ diff --git a/resources/assets/tinker/textures/items/arrow/netherrack_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/netherrack_arrow_shaft.png deleted file mode 100644 index d0577d08..00000000 Binary files a/resources/assets/tinker/textures/items/arrow/netherrack_arrow_shaft.png and /dev/null differ diff --git a/resources/assets/tinker/textures/items/arrow/obsidian_arrow_head.png b/resources/assets/tinker/textures/items/arrow/obsidian_arrow_head.png index d132f912..edbd0f0c 100644 Binary files a/resources/assets/tinker/textures/items/arrow/obsidian_arrow_head.png and b/resources/assets/tinker/textures/items/arrow/obsidian_arrow_head.png differ diff --git a/resources/assets/tinker/textures/items/arrow/obsidian_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/obsidian_arrow_shaft.png deleted file mode 100644 index a49e3fad..00000000 Binary files a/resources/assets/tinker/textures/items/arrow/obsidian_arrow_shaft.png and /dev/null differ diff --git a/resources/assets/tinker/textures/items/arrow/paper_arrow_head.png b/resources/assets/tinker/textures/items/arrow/paper_arrow_head.png index 6788f524..4678bffe 100644 Binary files a/resources/assets/tinker/textures/items/arrow/paper_arrow_head.png and b/resources/assets/tinker/textures/items/arrow/paper_arrow_head.png differ diff --git a/resources/assets/tinker/textures/items/arrow/paper_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/paper_arrow_shaft.png deleted file mode 100644 index 79dea14b..00000000 Binary files a/resources/assets/tinker/textures/items/arrow/paper_arrow_shaft.png and /dev/null differ diff --git a/resources/assets/tinker/textures/items/arrow/pigiron_arrow_fletching.png b/resources/assets/tinker/textures/items/arrow/pigiron_arrow_fletching.png deleted file mode 100644 index f3e6d655..00000000 Binary files a/resources/assets/tinker/textures/items/arrow/pigiron_arrow_fletching.png and /dev/null differ diff --git a/resources/assets/tinker/textures/items/arrow/pigiron_arrow_head.png b/resources/assets/tinker/textures/items/arrow/pigiron_arrow_head.png index b343c2c8..69b0b293 100644 Binary files a/resources/assets/tinker/textures/items/arrow/pigiron_arrow_head.png and b/resources/assets/tinker/textures/items/arrow/pigiron_arrow_head.png differ diff --git a/resources/assets/tinker/textures/items/arrow/pigiron_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/pigiron_arrow_shaft.png deleted file mode 100644 index 47a93bbd..00000000 Binary files a/resources/assets/tinker/textures/items/arrow/pigiron_arrow_shaft.png and /dev/null differ diff --git a/resources/assets/tinker/textures/items/arrow/piston_arrow_effect.png b/resources/assets/tinker/textures/items/arrow/piston_arrow_effect.png index 30fdff1d..b4e966e1 100644 Binary files a/resources/assets/tinker/textures/items/arrow/piston_arrow_effect.png and b/resources/assets/tinker/textures/items/arrow/piston_arrow_effect.png differ diff --git a/resources/assets/tinker/textures/items/arrow/quartz_arrow_effect.png b/resources/assets/tinker/textures/items/arrow/quartz_arrow_effect.png index a04b12fe..d724ede0 100644 Binary files a/resources/assets/tinker/textures/items/arrow/quartz_arrow_effect.png and b/resources/assets/tinker/textures/items/arrow/quartz_arrow_effect.png differ diff --git a/resources/assets/tinker/textures/items/arrow/redstone_arrow_effect.png b/resources/assets/tinker/textures/items/arrow/redstone_arrow_effect.png index 70550e7d..e607224b 100644 Binary files a/resources/assets/tinker/textures/items/arrow/redstone_arrow_effect.png and b/resources/assets/tinker/textures/items/arrow/redstone_arrow_effect.png differ diff --git a/resources/assets/tinker/textures/items/arrow/reed_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/reed_arrow_shaft.png new file mode 100644 index 00000000..bbd11187 Binary files /dev/null and b/resources/assets/tinker/textures/items/arrow/reed_arrow_shaft.png differ diff --git a/resources/assets/tinker/textures/items/arrow/reinforced_arrow_effect.png b/resources/assets/tinker/textures/items/arrow/reinforced_arrow_effect.png index 075fef0f..77a381cf 100644 Binary files a/resources/assets/tinker/textures/items/arrow/reinforced_arrow_effect.png and b/resources/assets/tinker/textures/items/arrow/reinforced_arrow_effect.png differ diff --git a/resources/assets/tinker/textures/items/arrow/silk_arrow_effect.png b/resources/assets/tinker/textures/items/arrow/silk_arrow_effect.png index 7f7d0dda..823eb23d 100644 Binary files a/resources/assets/tinker/textures/items/arrow/silk_arrow_effect.png and b/resources/assets/tinker/textures/items/arrow/silk_arrow_effect.png differ diff --git a/resources/assets/tinker/textures/items/arrow/slime_arrow_fletching.png b/resources/assets/tinker/textures/items/arrow/slime_arrow_fletching.png index 9fe78b41..dcafcf1e 100644 Binary files a/resources/assets/tinker/textures/items/arrow/slime_arrow_fletching.png and b/resources/assets/tinker/textures/items/arrow/slime_arrow_fletching.png differ diff --git a/resources/assets/tinker/textures/items/arrow/slime_arrow_head.png b/resources/assets/tinker/textures/items/arrow/slime_arrow_head.png index e214d56e..2644d05e 100644 Binary files a/resources/assets/tinker/textures/items/arrow/slime_arrow_head.png and b/resources/assets/tinker/textures/items/arrow/slime_arrow_head.png differ diff --git a/resources/assets/tinker/textures/items/arrow/slime_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/slime_arrow_shaft.png deleted file mode 100644 index afad823e..00000000 Binary files a/resources/assets/tinker/textures/items/arrow/slime_arrow_shaft.png and /dev/null differ diff --git a/resources/assets/tinker/textures/items/arrow/smite_arrow_effect.png b/resources/assets/tinker/textures/items/arrow/smite_arrow_effect.png index a8a89491..a27ec281 100644 Binary files a/resources/assets/tinker/textures/items/arrow/smite_arrow_effect.png and b/resources/assets/tinker/textures/items/arrow/smite_arrow_effect.png differ diff --git a/resources/assets/tinker/textures/items/arrow/spider_arrow_effect.png b/resources/assets/tinker/textures/items/arrow/spider_arrow_effect.png index f314c54f..8d6a4d9c 100644 Binary files a/resources/assets/tinker/textures/items/arrow/spider_arrow_effect.png and b/resources/assets/tinker/textures/items/arrow/spider_arrow_effect.png differ diff --git a/resources/assets/tinker/textures/items/arrow/steel_arrow_head.png b/resources/assets/tinker/textures/items/arrow/steel_arrow_head.png index 03d3177e..8af06bef 100644 Binary files a/resources/assets/tinker/textures/items/arrow/steel_arrow_head.png and b/resources/assets/tinker/textures/items/arrow/steel_arrow_head.png differ diff --git a/resources/assets/tinker/textures/items/arrow/steel_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/steel_arrow_shaft.png deleted file mode 100644 index 3fe4da06..00000000 Binary files a/resources/assets/tinker/textures/items/arrow/steel_arrow_shaft.png and /dev/null differ diff --git a/resources/assets/tinker/textures/items/arrow/stone_arrow_head.png b/resources/assets/tinker/textures/items/arrow/stone_arrow_head.png index d1bbdd82..6529ad2b 100644 Binary files a/resources/assets/tinker/textures/items/arrow/stone_arrow_head.png and b/resources/assets/tinker/textures/items/arrow/stone_arrow_head.png differ diff --git a/resources/assets/tinker/textures/items/arrow/stone_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/stone_arrow_shaft.png deleted file mode 100644 index 2d33b963..00000000 Binary files a/resources/assets/tinker/textures/items/arrow/stone_arrow_shaft.png and /dev/null differ diff --git a/resources/assets/tinker/textures/items/arrow/thaumium_arrow_head.png b/resources/assets/tinker/textures/items/arrow/thaumium_arrow_head.png index b5effc73..a300e529 100644 Binary files a/resources/assets/tinker/textures/items/arrow/thaumium_arrow_head.png and b/resources/assets/tinker/textures/items/arrow/thaumium_arrow_head.png differ diff --git a/resources/assets/tinker/textures/items/arrow/thaumium_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/thaumium_arrow_shaft.png deleted file mode 100644 index 50070b32..00000000 Binary files a/resources/assets/tinker/textures/items/arrow/thaumium_arrow_shaft.png and /dev/null differ diff --git a/resources/assets/tinker/textures/items/arrow/wood_arrow_head.png b/resources/assets/tinker/textures/items/arrow/wood_arrow_head.png index d891b2d8..192e47d8 100644 Binary files a/resources/assets/tinker/textures/items/arrow/wood_arrow_head.png and b/resources/assets/tinker/textures/items/arrow/wood_arrow_head.png differ diff --git a/resources/assets/tinker/textures/items/arrow/wood_arrow_shaft.png b/resources/assets/tinker/textures/items/arrow/wood_arrow_shaft.png index 6a36dc12..36ebe7b6 100644 Binary files a/resources/assets/tinker/textures/items/arrow/wood_arrow_shaft.png and b/resources/assets/tinker/textures/items/arrow/wood_arrow_shaft.png differ diff --git a/resources/assets/tinker/textures/items/bolt/_bolt_fletching.png b/resources/assets/tinker/textures/items/bolt/_bolt_fletching.png new file mode 100644 index 00000000..bb013bd9 Binary files /dev/null and b/resources/assets/tinker/textures/items/bolt/_bolt_fletching.png differ diff --git a/resources/assets/tinker/textures/items/bolt/_bolt_head - Kopie.png b/resources/assets/tinker/textures/items/bolt/_bolt_head - Kopie.png new file mode 100644 index 00000000..80dea98b Binary files /dev/null and b/resources/assets/tinker/textures/items/bolt/_bolt_head - Kopie.png differ diff --git a/resources/assets/tinker/textures/items/bolt/_bolt_head.png b/resources/assets/tinker/textures/items/bolt/_bolt_head.png new file mode 100644 index 00000000..bb974a0e Binary files /dev/null and b/resources/assets/tinker/textures/items/bolt/_bolt_head.png differ diff --git a/resources/assets/tinker/textures/items/bolt/_bolt_shaft.png b/resources/assets/tinker/textures/items/bolt/_bolt_shaft.png new file mode 100644 index 00000000..c908b521 Binary files /dev/null and b/resources/assets/tinker/textures/items/bolt/_bolt_shaft.png differ diff --git a/resources/assets/tinker/textures/items/crossbow/_crossbow.xcf b/resources/assets/tinker/textures/items/crossbow/_crossbow.xcf new file mode 100644 index 00000000..baecc712 Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/_crossbow.xcf differ diff --git a/resources/assets/tinker/textures/items/crossbow/_crossbow_1.xcf b/resources/assets/tinker/textures/items/crossbow/_crossbow_1.xcf new file mode 100644 index 00000000..b2ca3b26 Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/_crossbow_1.xcf differ diff --git a/resources/assets/tinker/textures/items/crossbow/_crossbow_2.xcf b/resources/assets/tinker/textures/items/crossbow/_crossbow_2.xcf new file mode 100644 index 00000000..bccdb71b Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/_crossbow_2.xcf differ diff --git a/resources/assets/tinker/textures/items/crossbow/_crossbow_3.xcf b/resources/assets/tinker/textures/items/crossbow/_crossbow_3.xcf new file mode 100644 index 00000000..2c9b2cc8 Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/_crossbow_3.xcf differ diff --git a/resources/assets/tinker/textures/items/crossbow/_crossbow_3_meh.xcf b/resources/assets/tinker/textures/items/crossbow/_crossbow_3_meh.xcf new file mode 100644 index 00000000..a2332435 Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/_crossbow_3_meh.xcf differ diff --git a/resources/assets/tinker/textures/items/crossbow/_crossbow_binding.png b/resources/assets/tinker/textures/items/crossbow/_crossbow_binding.png new file mode 100644 index 00000000..f1aa0914 Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/_crossbow_binding.png differ diff --git a/resources/assets/tinker/textures/items/crossbow/_crossbow_body.png b/resources/assets/tinker/textures/items/crossbow/_crossbow_body.png new file mode 100644 index 00000000..a5ebb6c4 Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/_crossbow_body.png differ diff --git a/resources/assets/tinker/textures/items/crossbow/_crossbow_bow.png b/resources/assets/tinker/textures/items/crossbow/_crossbow_bow.png new file mode 100644 index 00000000..54702314 Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/_crossbow_bow.png differ diff --git a/resources/assets/tinker/textures/items/crossbow/_crossbow_bow_1.png b/resources/assets/tinker/textures/items/crossbow/_crossbow_bow_1.png new file mode 100644 index 00000000..54702314 Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/_crossbow_bow_1.png differ diff --git a/resources/assets/tinker/textures/items/crossbow/_crossbow_bow_2.png b/resources/assets/tinker/textures/items/crossbow/_crossbow_bow_2.png new file mode 100644 index 00000000..de61cb12 Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/_crossbow_bow_2.png differ diff --git a/resources/assets/tinker/textures/items/crossbow/_crossbow_bow_3.png b/resources/assets/tinker/textures/items/crossbow/_crossbow_bow_3.png new file mode 100644 index 00000000..cbb09ec3 Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/_crossbow_bow_3.png differ diff --git a/resources/assets/tinker/textures/items/crossbow/_crossbow_string.png b/resources/assets/tinker/textures/items/crossbow/_crossbow_string.png new file mode 100644 index 00000000..a3b44903 Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/_crossbow_string.png differ diff --git a/resources/assets/tinker/textures/items/crossbow/_crossbow_string_1.png b/resources/assets/tinker/textures/items/crossbow/_crossbow_string_1.png new file mode 100644 index 00000000..220e6bea Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/_crossbow_string_1.png differ diff --git a/resources/assets/tinker/textures/items/crossbow/_crossbow_string_2.png b/resources/assets/tinker/textures/items/crossbow/_crossbow_string_2.png new file mode 100644 index 00000000..88265934 Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/_crossbow_string_2.png differ diff --git a/resources/assets/tinker/textures/items/crossbow/_crossbow_string_3.png b/resources/assets/tinker/textures/items/crossbow/_crossbow_string_3.png new file mode 100644 index 00000000..e2b87421 Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/_crossbow_string_3.png differ diff --git a/resources/assets/tinker/textures/items/javelin/_javelin_accessory.png b/resources/assets/tinker/textures/items/javelin/_javelin_accessory.png new file mode 100644 index 00000000..65820ace Binary files /dev/null and b/resources/assets/tinker/textures/items/javelin/_javelin_accessory.png differ diff --git a/resources/assets/tinker/textures/items/javelin/_javelin_handle.png b/resources/assets/tinker/textures/items/javelin/_javelin_handle.png new file mode 100644 index 00000000..1952f2f1 Binary files /dev/null and b/resources/assets/tinker/textures/items/javelin/_javelin_handle.png differ diff --git a/resources/assets/tinker/textures/items/javelin/_javelin_head.png b/resources/assets/tinker/textures/items/javelin/_javelin_head.png new file mode 100644 index 00000000..81d2a971 Binary files /dev/null and b/resources/assets/tinker/textures/items/javelin/_javelin_head.png differ diff --git a/resources/assets/tinker/textures/items/longbow/_bow_bottom.png b/resources/assets/tinker/textures/items/longbow/_bow_bottom.png new file mode 100644 index 00000000..0fb14173 Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/_bow_bottom.png differ diff --git a/resources/assets/tinker/textures/items/longbow/_bow_bottom_1.png b/resources/assets/tinker/textures/items/longbow/_bow_bottom_1.png new file mode 100644 index 00000000..e10febd0 Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/_bow_bottom_1.png differ diff --git a/resources/assets/tinker/textures/items/longbow/_bow_bottom_2.png b/resources/assets/tinker/textures/items/longbow/_bow_bottom_2.png new file mode 100644 index 00000000..b01cd43b Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/_bow_bottom_2.png differ diff --git a/resources/assets/tinker/textures/items/longbow/_bow_bottom_3.png b/resources/assets/tinker/textures/items/longbow/_bow_bottom_3.png new file mode 100644 index 00000000..3d0832f5 Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/_bow_bottom_3.png differ diff --git a/resources/assets/tinker/textures/items/longbow/_bow_grip.png b/resources/assets/tinker/textures/items/longbow/_bow_grip.png new file mode 100644 index 00000000..188c11bc Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/_bow_grip.png differ diff --git a/resources/assets/tinker/textures/items/longbow/_bow_top.png b/resources/assets/tinker/textures/items/longbow/_bow_top.png new file mode 100644 index 00000000..d7870326 Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/_bow_top.png differ diff --git a/resources/assets/tinker/textures/items/longbow/_bow_top_1.png b/resources/assets/tinker/textures/items/longbow/_bow_top_1.png new file mode 100644 index 00000000..6a77ec51 Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/_bow_top_1.png differ diff --git a/resources/assets/tinker/textures/items/longbow/_bow_top_2.png b/resources/assets/tinker/textures/items/longbow/_bow_top_2.png new file mode 100644 index 00000000..dadb2abb Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/_bow_top_2.png differ diff --git a/resources/assets/tinker/textures/items/longbow/_bow_top_3.png b/resources/assets/tinker/textures/items/longbow/_bow_top_3.png new file mode 100644 index 00000000..e563ceef Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/_bow_top_3.png differ diff --git a/resources/assets/tinker/textures/items/longbow/_bowstring.png b/resources/assets/tinker/textures/items/longbow/_bowstring.png new file mode 100644 index 00000000..cb478b82 Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/_bowstring.png differ diff --git a/resources/assets/tinker/textures/items/longbow/_bowstring_1.png b/resources/assets/tinker/textures/items/longbow/_bowstring_1.png new file mode 100644 index 00000000..76101727 Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/_bowstring_1.png differ diff --git a/resources/assets/tinker/textures/items/longbow/_bowstring_2.png b/resources/assets/tinker/textures/items/longbow/_bowstring_2.png new file mode 100644 index 00000000..e9e02e07 Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/_bowstring_2.png differ diff --git a/resources/assets/tinker/textures/items/longbow/_bowstring_3.png b/resources/assets/tinker/textures/items/longbow/_bowstring_3.png new file mode 100644 index 00000000..8f76ed1e Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/_bowstring_3.png differ diff --git a/resources/assets/tinker/textures/items/longbow/_bowstring_broken.png b/resources/assets/tinker/textures/items/longbow/_bowstring_broken.png new file mode 100644 index 00000000..8ccc79df Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/_bowstring_broken.png differ diff --git a/resources/assets/tinker/textures/items/longbow/complete.png b/resources/assets/tinker/textures/items/longbow/complete.png new file mode 100644 index 00000000..e10febd0 Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/complete.png differ diff --git a/resources/assets/tinker/textures/items/longbow/complete.xcf b/resources/assets/tinker/textures/items/longbow/complete.xcf new file mode 100644 index 00000000..312650dd Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/complete.xcf differ diff --git a/resources/assets/tinker/textures/items/parts/_arrow_shaft.png b/resources/assets/tinker/textures/items/parts/_arrow_shaft.png new file mode 100644 index 00000000..1d2ba201 Binary files /dev/null and b/resources/assets/tinker/textures/items/parts/_arrow_shaft.png differ diff --git a/resources/assets/tinker/textures/items/parts/_bolt.png b/resources/assets/tinker/textures/items/parts/_bolt.png new file mode 100644 index 00000000..c908b521 Binary files /dev/null and b/resources/assets/tinker/textures/items/parts/_bolt.png differ diff --git a/resources/assets/tinker/textures/items/parts/_bolt_2.png b/resources/assets/tinker/textures/items/parts/_bolt_2.png new file mode 100644 index 00000000..bb974a0e Binary files /dev/null and b/resources/assets/tinker/textures/items/parts/_bolt_2.png differ diff --git a/resources/assets/tinker/textures/items/parts/_bow_limb.png b/resources/assets/tinker/textures/items/parts/_bow_limb.png new file mode 100644 index 00000000..d23b89da Binary files /dev/null and b/resources/assets/tinker/textures/items/parts/_bow_limb.png differ diff --git a/resources/assets/tinker/textures/items/parts/_crossbow_body.png b/resources/assets/tinker/textures/items/parts/_crossbow_body.png new file mode 100644 index 00000000..fb2ca765 Binary files /dev/null and b/resources/assets/tinker/textures/items/parts/_crossbow_body.png differ diff --git a/resources/assets/tinker/textures/items/parts/_crossbow_limb.png b/resources/assets/tinker/textures/items/parts/_crossbow_limb.png new file mode 100644 index 00000000..18d4f0a3 Binary files /dev/null and b/resources/assets/tinker/textures/items/parts/_crossbow_limb.png differ diff --git a/resources/assets/tinker/textures/items/parts/_shuriken.png b/resources/assets/tinker/textures/items/parts/_shuriken.png new file mode 100644 index 00000000..960b154a Binary files /dev/null and b/resources/assets/tinker/textures/items/parts/_shuriken.png differ diff --git a/resources/assets/tinker/textures/items/parts/iron_shuriken.png b/resources/assets/tinker/textures/items/parts/iron_shuriken.png new file mode 100644 index 00000000..fd987cc3 Binary files /dev/null and b/resources/assets/tinker/textures/items/parts/iron_shuriken.png differ diff --git a/resources/assets/tinker/textures/items/patterns/cast_bowlimb.png b/resources/assets/tinker/textures/items/patterns/cast_bowlimb.png new file mode 100644 index 00000000..f8fc09b0 Binary files /dev/null and b/resources/assets/tinker/textures/items/patterns/cast_bowlimb.png differ diff --git a/resources/assets/tinker/textures/items/patterns/cast_crossbowbody.png b/resources/assets/tinker/textures/items/patterns/cast_crossbowbody.png new file mode 100644 index 00000000..7f749cbe Binary files /dev/null and b/resources/assets/tinker/textures/items/patterns/cast_crossbowbody.png differ diff --git a/resources/assets/tinker/textures/items/patterns/cast_crossbowlimb.png b/resources/assets/tinker/textures/items/patterns/cast_crossbowlimb.png new file mode 100644 index 00000000..6cbc48dd Binary files /dev/null and b/resources/assets/tinker/textures/items/patterns/cast_crossbowlimb.png differ diff --git a/resources/assets/tinker/textures/items/patterns/cast_shuriken.png b/resources/assets/tinker/textures/items/patterns/cast_shuriken.png new file mode 100644 index 00000000..ea3e806e Binary files /dev/null and b/resources/assets/tinker/textures/items/patterns/cast_shuriken.png differ diff --git a/resources/assets/tinker/textures/items/patterns/pattern_bowlimb.png b/resources/assets/tinker/textures/items/patterns/pattern_bowlimb.png new file mode 100644 index 00000000..528b0aa2 Binary files /dev/null and b/resources/assets/tinker/textures/items/patterns/pattern_bowlimb.png differ diff --git a/resources/assets/tinker/textures/items/patterns/pattern_crossbowbody.png b/resources/assets/tinker/textures/items/patterns/pattern_crossbowbody.png new file mode 100644 index 00000000..762cfc29 Binary files /dev/null and b/resources/assets/tinker/textures/items/patterns/pattern_crossbowbody.png differ diff --git a/resources/assets/tinker/textures/items/patterns/pattern_crossbowlimb.png b/resources/assets/tinker/textures/items/patterns/pattern_crossbowlimb.png new file mode 100644 index 00000000..0685851d Binary files /dev/null and b/resources/assets/tinker/textures/items/patterns/pattern_crossbowlimb.png differ diff --git a/resources/assets/tinker/textures/items/patterns/pattern_shuriken.png b/resources/assets/tinker/textures/items/patterns/pattern_shuriken.png new file mode 100644 index 00000000..2a64a4c1 Binary files /dev/null and b/resources/assets/tinker/textures/items/patterns/pattern_shuriken.png differ diff --git a/resources/assets/tinker/textures/items/shortbow/_bowstring.png b/resources/assets/tinker/textures/items/shortbow/_bowstring.png index ff07f728..540cb9c5 100644 Binary files a/resources/assets/tinker/textures/items/shortbow/_bowstring.png and b/resources/assets/tinker/textures/items/shortbow/_bowstring.png differ diff --git a/resources/assets/tinker/textures/items/shortbow/_bowstring_1.png b/resources/assets/tinker/textures/items/shortbow/_bowstring_1.png index f7ff4e54..72cf6b3e 100644 Binary files a/resources/assets/tinker/textures/items/shortbow/_bowstring_1.png and b/resources/assets/tinker/textures/items/shortbow/_bowstring_1.png differ diff --git a/resources/assets/tinker/textures/items/shortbow/_bowstring_2.png b/resources/assets/tinker/textures/items/shortbow/_bowstring_2.png index e8ba2a22..b8e3e5fb 100644 Binary files a/resources/assets/tinker/textures/items/shortbow/_bowstring_2.png and b/resources/assets/tinker/textures/items/shortbow/_bowstring_2.png differ diff --git a/resources/assets/tinker/textures/items/shortbow/_bowstring_3.png b/resources/assets/tinker/textures/items/shortbow/_bowstring_3.png index 8f76ed1e..5629a787 100644 Binary files a/resources/assets/tinker/textures/items/shortbow/_bowstring_3.png and b/resources/assets/tinker/textures/items/shortbow/_bowstring_3.png differ diff --git a/resources/assets/tinker/textures/items/shortbow/_bowstring_broken.png b/resources/assets/tinker/textures/items/shortbow/_bowstring_broken.png index 8ccc79df..84f13dba 100644 Binary files a/resources/assets/tinker/textures/items/shortbow/_bowstring_broken.png and b/resources/assets/tinker/textures/items/shortbow/_bowstring_broken.png differ diff --git a/resources/assets/tinker/textures/items/shuriken/_shuriken - Kopie.png b/resources/assets/tinker/textures/items/shuriken/_shuriken - Kopie.png new file mode 100644 index 00000000..20581f54 Binary files /dev/null and b/resources/assets/tinker/textures/items/shuriken/_shuriken - Kopie.png differ diff --git a/resources/assets/tinker/textures/items/shuriken/_shuriken.png b/resources/assets/tinker/textures/items/shuriken/_shuriken.png new file mode 100644 index 00000000..e0e08ab4 Binary files /dev/null and b/resources/assets/tinker/textures/items/shuriken/_shuriken.png differ diff --git a/resources/assets/tinker/textures/items/shuriken/iron_shuriken.png b/resources/assets/tinker/textures/items/shuriken/iron_shuriken.png new file mode 100644 index 00000000..e2ac4b08 Binary files /dev/null and b/resources/assets/tinker/textures/items/shuriken/iron_shuriken.png differ diff --git a/resources/assets/tinker/textures/items/throwingknife/_knife_blade.png b/resources/assets/tinker/textures/items/throwingknife/_knife_blade.png new file mode 100644 index 00000000..3029b804 Binary files /dev/null and b/resources/assets/tinker/textures/items/throwingknife/_knife_blade.png differ diff --git a/resources/assets/tinker/textures/items/throwingknife/_knife_handle.png b/resources/assets/tinker/textures/items/throwingknife/_knife_handle.png new file mode 100644 index 00000000..59cb1249 Binary files /dev/null and b/resources/assets/tinker/textures/items/throwingknife/_knife_handle.png differ diff --git a/resources/assets/tinker/textures/items/throwingknife/iron_knife_blade.png b/resources/assets/tinker/textures/items/throwingknife/iron_knife_blade.png new file mode 100644 index 00000000..76da8a10 Binary files /dev/null and b/resources/assets/tinker/textures/items/throwingknife/iron_knife_blade.png differ diff --git a/resources/assets/tinker/textures/items/throwingknife/iron_knife_handle.png b/resources/assets/tinker/textures/items/throwingknife/iron_knife_handle.png new file mode 100644 index 00000000..fc158163 Binary files /dev/null and b/resources/assets/tinker/textures/items/throwingknife/iron_knife_handle.png differ diff --git a/src/main/java/tconstruct/weaponry/TinkerWeaponry.java b/src/main/java/tconstruct/weaponry/TinkerWeaponry.java new file mode 100644 index 00000000..d0cfce04 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/TinkerWeaponry.java @@ -0,0 +1,317 @@ +package boni.tinkersweaponry; + +import boni.tinkersweaponry.ammo.ArrowAmmo; +import boni.tinkersweaponry.ammo.BoltAmmo; +import boni.tinkersweaponry.items.DualMaterialToolPart; +import boni.tinkersweaponry.items.WeaponryPattern; +import boni.tinkersweaponry.items.WeaponryToolPart; +import boni.tinkersweaponry.library.weaponry.AmmoItem; +import boni.tinkersweaponry.library.weaponry.AmmoWeapon; +import boni.tinkersweaponry.library.weaponry.ArrowShaftMaterial; +import boni.tinkersweaponry.library.weaponry.ProjectileWeapon; +import boni.tinkersweaponry.util.Reference; +import boni.tinkersweaponry.weapons.*; +import cpw.mods.fml.common.Mod; +import cpw.mods.fml.common.SidedProxy; +import cpw.mods.fml.common.event.FMLInitializationEvent; +import cpw.mods.fml.common.event.FMLPostInitializationEvent; +import cpw.mods.fml.common.event.FMLPreInitializationEvent; +import cpw.mods.fml.common.registry.GameRegistry; +import net.minecraft.init.Items; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fluids.Fluid; +import net.minecraftforge.fluids.FluidStack; +import org.apache.logging.log4j.Logger; +import tconstruct.TConstruct; +import tconstruct.library.TConstructCreativeTab; +import tconstruct.library.TConstructRegistry; +import tconstruct.library.crafting.*; +import tconstruct.library.tools.ToolCore; +import tconstruct.library.util.IPattern; +import tconstruct.library.util.IToolPart; +import tconstruct.smeltery.TinkerSmeltery; +import tconstruct.tools.TinkerTools; +import tconstruct.tools.items.Pattern; + +import java.util.Map; +import java.util.Random; + +import static tconstruct.tools.TinkerTools.MaterialID; + +@GameRegistry.ObjectHolder(Reference.MOD_ID) +@Mod(modid = Reference.MOD_ID, name = Reference.MOD_NAME, dependencies = "required-after:" + Reference.TCON_MOD_ID, version = "${version}") +public class TinkerWeaponry { + public static Logger Log; + + @Mod.Instance(Reference.MOD_ID) + public static TinkerWeaponry instance; + + @SidedProxy(clientSide = "boni.tinkersweaponry.ClientProxy", serverSide = "boni.tinkersweaponry.CommonProxy") + public static WeaponryCommonProxy proxy; + + // Throwing Weapons + public static ToolCore throwArrow; + public static AmmoWeapon shuriken; + public static AmmoWeapon throwingknife; + public static AmmoWeapon javelin; + // Projectile Weapons + public static ProjectileWeapon shortbow; + public static ProjectileWeapon longbow; + public static ProjectileWeapon crossbow; + + // Ammo + public static AmmoItem arrowAmmo; + public static AmmoItem boltAmmo; + + // Tool Parts + public static WeaponryToolPart partShuriken; + public static WeaponryToolPart partArrowShaft; // not craftable, used internally + public static WeaponryToolPart partBowLimb; + public static WeaponryToolPart partCrossbowLimb; + public static WeaponryToolPart partCrossbowBody; + public static DualMaterialToolPart partBolt; + + // patterns/casts + + public static Pattern woodPattern; + public static Pattern metalPattern; + + // other stuff + public static TConstructCreativeTab creativeTab = new TConstructCreativeTab("TConstructWeaponry"); + public static Random random = new Random(); + + + @Mod.EventHandler + public void preInit(FMLPreInitializationEvent event) + { + Log = event.getModLog(); + + registerItems(); + registerMaterials(); + } + + @Mod.EventHandler + public void init(FMLInitializationEvent event) + { + addPartRecipies(); + addWeaponRecipies(); + registerBoltCasting(); + } + + @Mod.EventHandler + public void postInit(FMLPostInitializationEvent event) + { + // this handler takes care that ammo weapons get ammo. + MinecraftForge.EVENT_BUS.register(new WeaponryHandler()); + + proxy.init(); + } + + private void registerItems() + { + // create tool part + partShuriken = new WeaponryToolPart("_shuriken", "Shuriken"); + partArrowShaft = new WeaponryToolPart("_arrow_shaft", "Shaft"); + partBowLimb = new WeaponryToolPart("_bow_limb", "BowLimb"); + partCrossbowLimb = new WeaponryToolPart("_crossbow_limb", "CrossbowLimb"); + partCrossbowBody = new WeaponryToolPart("_crossbow_body", "CrossbowBody"); + partBolt = new DualMaterialToolPart("_bolt", "Bolt"); + + // create throwing weapons + throwArrow = new ThrowArrowItem(); + shuriken = new Shuriken(); + throwingknife = new ThrowingKnife(); + javelin = new Javelin(); + // create projectile weapons + shortbow = new ShortBow(); + longbow = new LongBow(); + crossbow = new Crossbow(); + // create ammo + arrowAmmo = new ArrowAmmo(); + boltAmmo = new BoltAmmo(); + + woodPattern = new WeaponryPattern("pattern_", "Pattern"); + metalPattern = new WeaponryPattern("cast_", "Cast"); + + // register tool parts + GameRegistry.registerItem(partShuriken, "ShurikenPart"); + GameRegistry.registerItem(partBowLimb, "BowLimbPart"); + GameRegistry.registerItem(partCrossbowLimb, "CrossbowLimbPart"); + GameRegistry.registerItem(partCrossbowBody, "CrossbowBodyPart"); + GameRegistry.registerItem(partBolt, "BoltPart"); + // register throwing weapons + GameRegistry.registerItem(throwArrow, "ThrowArrow"); + GameRegistry.registerItem(shuriken, "Shuriken"); + GameRegistry.registerItem(throwingknife, "ThrowingKnife"); + GameRegistry.registerItem(javelin, "Javelin"); + // register projectile weapons + GameRegistry.registerItem(shortbow, "ShortBow"); + GameRegistry.registerItem(longbow, "LongBow"); + GameRegistry.registerItem(crossbow, "Crossbow"); + // register ammo + GameRegistry.registerItem(arrowAmmo, "ArrowAmmo"); + GameRegistry.registerItem(boltAmmo, "BoltAmmo"); + // register patterns/casts + GameRegistry.registerItem(woodPattern, "Pattern"); + GameRegistry.registerItem(metalPattern, "Cast"); + } + + private void addPartRecipies() + { + StencilBuilder.registerStencil(woodPattern, 0); + StencilBuilder.registerStencil(woodPattern, 1); + StencilBuilder.registerStencil(woodPattern, 2); + StencilBuilder.registerStencil(woodPattern, 3); + + PatternBuilder.instance.addToolPattern(woodPattern); + + // todo: integrate into tcon + int[] nonMetals = { 0, 1, 3, 4, 5, 6, 7, 8, 9, 17 }; + int[] liquidDamage = new int[] { 2, 13, 10, 11, 12, 14, 15, 6, 16, 18 }; + Item[] patternOutputs = new Item[] { partShuriken, partCrossbowLimb, partCrossbowBody, partBowLimb }; + + // register part crafting + for (int m = 0; m < patternOutputs.length; m++) + for (int nonMetal : nonMetals) + TConstructRegistry.addPartMapping(woodPattern, m, nonMetal, new ItemStack(patternOutputs[m], 1, nonMetal)); + + // register part casting + LiquidCasting tableCasting = TConstructRegistry.getTableCasting(); + for(int i = 0; i < patternOutputs.length; i++) + { + ItemStack cast = new ItemStack(metalPattern, 1, i); + + tableCasting.addCastingRecipe(cast, new FluidStack(TinkerSmeltery.moltenAlubrassFluid, TConstruct.ingotLiquidValue), new ItemStack(patternOutputs[i], 1, Short.MAX_VALUE), false, 50); + tableCasting.addCastingRecipe(cast, new FluidStack(TinkerSmeltery.moltenGoldFluid, TConstruct.ingotLiquidValue * 2), new ItemStack(patternOutputs[i], 1, Short.MAX_VALUE), false, 50); + + for (int iterTwo = 0; iterTwo < TinkerSmeltery.liquids.length; iterTwo++) + { + Fluid fs = TinkerSmeltery.liquids[iterTwo].getFluid(); + int fluidAmount = ((IPattern) TinkerSmeltery.metalPattern).getPatternCost(cast) * TConstruct.ingotLiquidValue / 2; + ItemStack metalCast = new ItemStack(patternOutputs[i], 1, liquidDamage[iterTwo]); + tableCasting.addCastingRecipe(metalCast, new FluidStack(fs, fluidAmount), cast, 50); + Smeltery.addMelting(FluidType.getFluidType(fs), metalCast, 0, fluidAmount); + } + } + + } + + private void registerMaterials() + { + // todo: un-hax + TConstructRegistry.arrowMaterials.clear(); + TConstructRegistry.bowMaterials.clear(); + + // todo: remove durability from this + // Bow Materials: Material ID, durability, drawspeed, arrow speed + // speed 3.0 == exactly the vanilla bow if 2 parts of speed 3 are used + // Wooden stuff is flexible, therefore good + TConstructRegistry.addBowMaterial(MaterialID.Wood, 0, 18, 3.0f); // Wood + // other organic materials also are good + TConstructRegistry.addBowMaterial(MaterialID.Cactus, 0, 20, 2.4f); // Cactus + TConstructRegistry.addBowMaterial(MaterialID.Bone, 0, 38, 2.0f); // Bone + TConstructRegistry.addBowMaterial(MaterialID.Slime, 0, 28, 4.0f); // Slime + TConstructRegistry.addBowMaterial(MaterialID.BlueSlime, 0, 21, 4.0f); // Blue Slime + TConstructRegistry.addBowMaterial(MaterialID.Paper, 0, 25, 2.3f); // Paper + // Metal stuff has a lot of POW, but takes LONG to wind up since it's so hard + TConstructRegistry.addBowMaterial(MaterialID.Iron, 0, 40, 5.2f); // Iron + TConstructRegistry.addBowMaterial(MaterialID.Steel, 0, 50, 5.5f); // Steel + TConstructRegistry.addBowMaterial(MaterialID.PigIron, 0, 30, 5.2f); // Pig Iron - it's meat! + TConstructRegistry.addBowMaterial(MaterialID.Ardite, 0, 50, 4.5f); // Ardite + TConstructRegistry.addBowMaterial(MaterialID.Cobalt, 0, 35, 5.2f); // Cobalt + TConstructRegistry.addBowMaterial(MaterialID.Manyullyn, 0, 45, 4.5f); // Manyullyn + TConstructRegistry.addBowMaterial(MaterialID.Copper, 0, 30, 5.1f); // Copper + TConstructRegistry.addBowMaterial(MaterialID.Bronze, 0, 35, 5.2f); // Bronze + TConstructRegistry.addBowMaterial(MaterialID.Alumite, 0, 35, 4.8f); // Alumite - a bit stone-ish since it has obsidian + // Stone doesn't bend. takes forever, has no pow. WHY WOULD YOU DO THAT + TConstructRegistry.addBowMaterial(MaterialID.Stone, 0, 80, 1.0f); // Stone + TConstructRegistry.addBowMaterial(MaterialID.Flint, 0, 80, 1.0f); // Flint + TConstructRegistry.addBowMaterial(MaterialID.Obsidian, 0, 99, 1.0f); // Obsidian + TConstructRegistry.addBowMaterial(MaterialID.Netherrack,0, 70, 1.0f); // Netherrack + + // Arrow Head Materials: Material ID, mass, fragility + TConstructRegistry.addArrowMaterial(MaterialID.Wood, 0.69F, 1.0F, 100F); //Wood + TConstructRegistry.addArrowMaterial(MaterialID.Stone, 2.05F, 5.0F, 100F); //Stone + TConstructRegistry.addArrowMaterial(MaterialID.Iron, 3.6F, 0.5F, 100F); //Iron + TConstructRegistry.addArrowMaterial(MaterialID.Flint, 1.325F, 1.0F, 100F); //Flint + TConstructRegistry.addArrowMaterial(MaterialID.Cactus, 0.76F, 1.0F, 100F); //Cactus + TConstructRegistry.addArrowMaterial(MaterialID.Bone, 0.69F, 1.0F, 100F); //Bone + TConstructRegistry.addArrowMaterial(MaterialID.Obsidian, 2.4F, 1.0F, 100F); //Obsidian + TConstructRegistry.addArrowMaterial(MaterialID.Netherrack, 1.5F, 1.0F, 100F); //Netherrack + TConstructRegistry.addArrowMaterial(MaterialID.Slime, 0.22F, 0.0F, 100F); //Slime + TConstructRegistry.addArrowMaterial(MaterialID.Paper, 0.69F, 3.0F, 90F); //Paper + TConstructRegistry.addArrowMaterial(MaterialID.Cobalt, 3.0F, 0.25F, 100F); //Cobalt + TConstructRegistry.addArrowMaterial(MaterialID.Ardite, 1.25F, 0.25F, 100F); //Ardite + TConstructRegistry.addArrowMaterial(MaterialID.Manyullyn, 2.25F, 0.1F, 100F); //Manyullyn + TConstructRegistry.addArrowMaterial(MaterialID.Copper, 2.7F, 0.5F, 100F); //Copper + TConstructRegistry.addArrowMaterial(MaterialID.Bronze, 3.6F, 0.25F, 100F); //Bronze + TConstructRegistry.addArrowMaterial(MaterialID.Alumite, 1.1F, 0.25F, 100F); //Alumite + TConstructRegistry.addArrowMaterial(MaterialID.Steel, 3.6F, 0.25F, 100F); //Steel + TConstructRegistry.addArrowMaterial(MaterialID.BlueSlime, 0.22F, 0.0F, 100F); //Blue Slime + TConstructRegistry.addArrowMaterial(MaterialID.PigIron, 3.6F, 0.5F, 100F); //Pigiron + + // Arrow Shaft Materials: Material ID, crafting item, durability-medifier, mass, fragility + TConstructRegistry.addCustomMaterial(ArrowShaftMaterial.createMaterial(0, Items.stick, 1.0f, 1.0f, 0.15f, 0x866526)); // wood: reference material, 10% break chance + TConstructRegistry.addCustomMaterial(ArrowShaftMaterial.createMaterial(1, Items.bone, 0.95f, 1.2f, 0.05f, 0xede6bf)); // bone: heavier, but durable + TConstructRegistry.addCustomMaterial(ArrowShaftMaterial.createMaterial(2, Items.reeds, 1.5f, 0.8f, 0.66f, 0xc7ff87)); // reed: light, but less durable + TConstructRegistry.addCustomMaterial(ArrowShaftMaterial.createMaterial(3, Items.blaze_rod, 1.2f, 0.9f, 0.08f, 0xfff32d)); // blaze: tad lighter, tad more durable, fieryyyy + // also add the tool rod variants, same stats + TConstructRegistry.addCustomMaterial(ArrowShaftMaterial.createMaterial(0, TinkerTools.toolRod, MaterialID.Wood, 1.0f, 1.0f, 0.15f, 0x866526)); // wood: reference material, 10% break chance + TConstructRegistry.addCustomMaterial(ArrowShaftMaterial.createMaterial(1, TinkerTools.toolRod, MaterialID.Bone, 0.95f, 1.2f, 0.01f, 0xede6bf)); // bone: heavier, but durable + + // Arrow Fletching Materials: Material ID + } + + private void addWeaponRecipies() + { + TConstructRegistry.addToolRecipe(shuriken, partShuriken, partShuriken, partShuriken, partShuriken); + TConstructRegistry.addToolRecipe(throwingknife, TinkerTools.knifeBlade, TinkerTools.toolRod); + TConstructRegistry.addToolRecipe(javelin, TinkerTools.arrowhead, TinkerTools.toughRod, TinkerTools.toughRod); + + // hax + //ToolRecipe recipe = ToolBuilder.instance.recipeList.get(TinkerTools.shortbow); + //ToolBuilder.instance.recipeList.remove(TinkerTools.shortbow); + //ToolBuilder.instance.combos.remove(recipe); + + // todo + TConstructRegistry.addToolRecipe(shortbow, partBowLimb, TinkerTools.bowstring, partBowLimb); + TConstructRegistry.addToolRecipe(longbow, partBowLimb, TinkerTools.bowstring, partBowLimb, TinkerTools.largePlate); + TConstructRegistry.addToolRecipe(crossbow, partCrossbowLimb, partCrossbowBody, TinkerTools.bowstring, TinkerTools.toughBinding); + + TConstructRegistry.addToolRecipe(arrowAmmo, TinkerTools.arrowhead, partArrowShaft, TinkerTools.fletching); + TConstructRegistry.addToolRecipe(boltAmmo, partBolt, partBolt, TinkerTools.fletching); + } + + private void registerBoltCasting() + { + LiquidCasting tb = TConstructRegistry.getTableCasting(); + + // any fluid that is a toolpart material can be used + for(Map.Entry entry : FluidType.fluidTypes.entrySet()) { + // is tool material? + if(!entry.getValue().isToolpart) + continue; + + // get a casting recipe for it D: + FluidStack liquid = new FluidStack(entry.getValue().fluid, TConstruct.ingotLiquidValue); + CastingRecipe recipe = tb.getCastingRecipe(liquid, new ItemStack(TinkerSmeltery.metalPattern, 1, 2)); // pickaxe + // no recipe found + if(recipe == null) + continue; + + // material id for the pickaxe head == material id for the fluid! such hack. wow. + int matID = recipe.getResult().getItemDamage(); + + // register our casting stuff + for(Integer id : TConstructRegistry.toolMaterials.keySet()) { + ItemStack rod = new ItemStack(TinkerTools.toolRod, 1, id); + if(((IToolPart)TinkerTools.toolRod).getMaterialID(rod) == -1) + continue; + + tb.addCastingRecipe(DualMaterialToolPart.createDualMaterial(partBolt, id, matID), liquid, rod, true, 150); + } + } + } +} diff --git a/src/main/java/tconstruct/weaponry/WeaponryClientProxy.java b/src/main/java/tconstruct/weaponry/WeaponryClientProxy.java new file mode 100644 index 00000000..95ed639e --- /dev/null +++ b/src/main/java/tconstruct/weaponry/WeaponryClientProxy.java @@ -0,0 +1,114 @@ +package boni.tinkersweaponry; + +import boni.tinkersweaponry.client.AmmoSlotHandler; +import boni.tinkersweaponry.client.CrosshairHandler; +import boni.tinkersweaponry.client.RenderEventHandler; +import boni.tinkersweaponry.client.entityrenderer.ArrowEntityRenderer; +import boni.tinkersweaponry.client.entityrenderer.JavelinEntityRenderer; +import boni.tinkersweaponry.client.entityrenderer.ProjectileBaseRenderer; +import boni.tinkersweaponry.client.entityrenderer.ShurikenEntityRenderer; +import boni.tinkersweaponry.client.renderer.*; +import boni.tinkersweaponry.entity.*; +import boni.tinkersweaponry.util.Reference; +import cpw.mods.fml.client.registry.RenderingRegistry; +import net.minecraft.item.ItemStack; +import net.minecraftforge.client.MinecraftForgeClient; +import net.minecraftforge.common.MinecraftForge; +import tconstruct.library.client.TConstructClientRegistry; +import tconstruct.library.crafting.StencilBuilder; +import tconstruct.library.tools.ToolCore; +import tconstruct.tools.TinkerTools; + +public class WeaponryClientProxy extends WeaponryCommonProxy { + public static AmmoItemRenderer renderer; + + @Override + public void init() { + super.init(); + + MinecraftForge.EVENT_BUS.register(new CrosshairHandler()); + MinecraftForge.EVENT_BUS.register(new AmmoSlotHandler()); + MinecraftForge.EVENT_BUS.register(new RenderEventHandler()); + + registerRenderers(); + registerEntityRendering(); + registerMaterialRendering(); + + buttons(); + } + + private void registerRenderers() + { + renderer = new AmmoItemRenderer(); + MinecraftForgeClient.registerItemRenderer(TinkerWeaponry.throwArrow, renderer); + MinecraftForgeClient.registerItemRenderer(TinkerWeaponry.shuriken, renderer); + MinecraftForgeClient.registerItemRenderer(TinkerWeaponry.throwingknife, new ThrowingKnifeRenderer()); + MinecraftForgeClient.registerItemRenderer(TinkerWeaponry.javelin, new JavelinRenderer()); + + MinecraftForgeClient.registerItemRenderer(TinkerWeaponry.shortbow, new BowRenderer()); + MinecraftForgeClient.registerItemRenderer(TinkerWeaponry.longbow, new BowRenderer()); + MinecraftForgeClient.registerItemRenderer(TinkerWeaponry.crossbow, new CrossbowRenderer()); + + MinecraftForgeClient.registerItemRenderer(TinkerWeaponry.arrowAmmo, renderer); + MinecraftForgeClient.registerItemRenderer(TinkerWeaponry.boltAmmo, renderer); + } + + private void registerEntityRendering() + { + ProjectileBaseRenderer defaultRenderer = new ProjectileBaseRenderer(); + RenderingRegistry.registerEntityRenderingHandler(ShurikenEntity.class, new ShurikenEntityRenderer()); + RenderingRegistry.registerEntityRenderingHandler(ThrowingKnifeEntity.class, defaultRenderer); + RenderingRegistry.registerEntityRenderingHandler(JavelinEntity.class, new JavelinEntityRenderer()); + RenderingRegistry.registerEntityRenderingHandler(ArrowEntity.class, new ArrowEntityRenderer()); + RenderingRegistry.registerEntityRenderingHandler(BoltEntity.class, new ArrowEntityRenderer(0.6f)); + } + + private void registerMaterialRendering() + { + ToolCore arrow = TinkerWeaponry.arrowAmmo; + String pre = Reference.resource(arrow.getDefaultFolder()) + "/"; + + String[] shaft = {"wood", "bone", "blaze", "reed"}; + String[] fletching = { "feather", "leaf", "slime", "blueslime" }; + + // we register different textures for the different parts per index + for(int i = 0; i < 4; i++) { + String handletex = pre + shaft[i] + arrow.getIconSuffix(2); + String acctex = pre + fletching[i] + arrow.getIconSuffix(3); + arrow.registerAlternatePartPaths(i, new String[]{null, null, handletex, acctex}); + TinkerWeaponry.boltAmmo.registerAlternatePartPaths(i, new String[]{null, null, null, acctex}); + } + + // for bolts too + pre = Reference.resource(TinkerWeaponry.boltAmmo.getDefaultFolder()) + "/"; + for(int i = 0; i < 4; i++) { + String acctex = pre + fletching[i] + TinkerWeaponry.boltAmmo.getIconSuffix(3); + TinkerWeaponry.boltAmmo.registerAlternatePartPaths(i, new String[]{null, null, null, acctex}); + } + + // todo: do properly when moving stuff into tinkers code + arrow.headStrings.clear(); + arrow.headStrings.put(TinkerTools.MaterialID.PigIron, Reference.resource(arrow.getDefaultFolder() + "/pigiron" + arrow.getIconSuffix(0))); + + /* + TConstructClientRegistry.addAlternateMaterialRenderMapping(TinkerWeaponry.shuriken, 2, Reference.RESOURCE, "iron", true); + TConstructClientRegistry.addAlternateMaterialRenderMapping(TinkerWeaponry.throwingknife, 2, Reference.RESOURCE, "iron", true); + + String[] fletching = { "feather", "leaf", "slime", "blueslime" }; + for (int arrowIter = 0; arrowIter < fletching.length; arrowIter++) + { + TConstructClientRegistry.addAlternateMaterialRenderMapping(TinkerWeaponry.throwArrow, arrowIter, "tinker", fletching[arrowIter], true); + } + */ + } + + private void buttons() + { + int base = StencilBuilder.getIndex(new ItemStack(TinkerWeaponry.woodPattern, 0, 0)); + TConstructClientRegistry.addStencilButton2(0, 4, base + 0, Reference.RESOURCE, "textures/gui/icons.png"); // shuriken + TConstructClientRegistry.addStencilButton2(1, 4, base + 1, Reference.RESOURCE, "textures/gui/icons.png"); // crossbow limb + TConstructClientRegistry.addStencilButton2(2, 4, base + 2, Reference.RESOURCE, "textures/gui/icons.png"); // crossbow body + TConstructClientRegistry.addStencilButton2(3, 4, base + 3, Reference.RESOURCE, "textures/gui/icons.png"); // bow limb + //TConstructClientRegistry.addStencilButton2(4, 4, index, Reference.RESOURCE, "textures/gui/icons.png"); // bolt + } +} diff --git a/src/main/java/tconstruct/weaponry/WeaponryCommonProxy.java b/src/main/java/tconstruct/weaponry/WeaponryCommonProxy.java new file mode 100644 index 00000000..caad6061 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/WeaponryCommonProxy.java @@ -0,0 +1,14 @@ +package boni.tinkersweaponry; + +import boni.tinkersweaponry.entity.*; +import cpw.mods.fml.common.registry.EntityRegistry; + +public class WeaponryCommonProxy { + public void init() { + EntityRegistry.registerModEntity(ShurikenEntity.class, "Shuriken", 0, TinkerWeaponry.instance, 32, 5, true); + EntityRegistry.registerModEntity(ThrowingKnifeEntity.class, "ThrowingKnife", 1, TinkerWeaponry.instance, 32, 5, true); + EntityRegistry.registerModEntity(JavelinEntity.class, "Javelin", 2, TinkerWeaponry.instance, 32, 5, true); + EntityRegistry.registerModEntity(ArrowEntity.class, "Arrow", 3, TinkerWeaponry.instance, 32, 5, true); + EntityRegistry.registerModEntity(BoltEntity.class, "Bolt", 4, TinkerWeaponry.instance, 32, 5, true); + } +} diff --git a/src/main/java/tconstruct/weaponry/WeaponryHandler.java b/src/main/java/tconstruct/weaponry/WeaponryHandler.java new file mode 100644 index 00000000..4936f36a --- /dev/null +++ b/src/main/java/tconstruct/weaponry/WeaponryHandler.java @@ -0,0 +1,189 @@ +package boni.tinkersweaponry; + +import boni.tinkersweaponry.ammo.ArrowAmmo; +import boni.tinkersweaponry.ammo.BoltAmmo; +import boni.tinkersweaponry.items.DualMaterialToolPart; +import boni.tinkersweaponry.library.weaponry.ArrowShaftMaterial; +import boni.tinkersweaponry.library.weaponry.BowBaseAmmo; +import boni.tinkersweaponry.library.weaponry.ProjectileWeapon; +import boni.tinkersweaponry.library.weaponry.IAmmo; +import boni.tinkersweaponry.weapons.Crossbow; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import tconstruct.library.TConstructRegistry; +import tconstruct.library.crafting.ToolBuilder; +import tconstruct.library.event.ToolBuildEvent; +import tconstruct.library.event.ToolCraftEvent; +import tconstruct.library.tools.*; + +public class WeaponryHandler { + // Provides ammo-items with the necessary NBT + @SubscribeEvent + public void onAmmoCrafted(ToolCraftEvent.NormalTool event) + { + if(!(event.tool instanceof IAmmo)) + return; + + NBTTagCompound tags = event.toolTag.getCompoundTag("InfiTool"); + + // calculate its stats + if(event.tool instanceof ArrowAmmo) + { + // arrows work like this: + // the head is responsible for the damage, but also adds weight + // the shaft defines how fragile the arrow is, and also adds to the weight a bit. But mostly it functions at the durability modifier + // the fletching defines the accuracy of the bow, adds a bit of durability and also breakchance + + // Shortbows work better with lighter arrows + // while Longbows require a bit heavier arrows, the lighter the arrow the more impact the accuracy has otherwise + + // summa sumarum: heavier arrows fall faster (less range) but accuracy has less impact + + // the materials + ToolMaterial head = TConstructRegistry.getMaterial(tags.getInteger("Head")); + ArrowMaterial arrow = TConstructRegistry.getArrowMaterial(tags.getInteger("Head")); + ArrowShaftMaterial shaft = (ArrowShaftMaterial) TConstructRegistry.getCustomMaterial(tags.getInteger("Handle"), ArrowShaftMaterial.class); + FletchingMaterial fletching = (FletchingMaterial) TConstructRegistry.getCustomMaterial(tags.getInteger("Accessory"), FletchingMaterial.class); + + // todo: fix leaf fletching + if(fletching == null) + fletching = (FletchingMaterial) TConstructRegistry.getCustomMaterial(tags.getInteger("Accessory"), FletchlingLeafMaterial.class); + + int durability = (int)((float)head.durability() * shaft.durabilityModifier); // todo: fletching durability + float weight = arrow.mass + shaft.weight/2f; + float accuracy = fletching.accuracy; + float breakChance = shaft.fragility + fletching.breakChance; + + tags.setInteger("TotalDurability", durability); + tags.setFloat("Mass", weight); + tags.setFloat("BreakChance", breakChance); + tags.setFloat("Accuracy", accuracy); + } + else if(event.tool instanceof BoltAmmo) + { + // bolts work like ammos, but have more weight as they have 2 main materials + // Crossbows work better with heavier bolts + + // the materials + ToolMaterial headMat = TConstructRegistry.getMaterial(tags.getInteger("Head")); + ToolMaterial coreMat = TConstructRegistry.getMaterial(tags.getInteger("Handle")); + ArrowMaterial head = TConstructRegistry.getArrowMaterial(tags.getInteger("Head")); + ArrowMaterial core = TConstructRegistry.getArrowMaterial(tags.getInteger("Handle")); + FletchingMaterial fletching = (FletchingMaterial) TConstructRegistry.getCustomMaterial(tags.getInteger("Accessory"), FletchingMaterial.class); + + // todo: fix leaf fletching + if(fletching == null) + fletching = (FletchingMaterial) TConstructRegistry.getCustomMaterial(tags.getInteger("Accessory"), FletchlingLeafMaterial.class); + + int durability = (int)((float)headMat.durability() * coreMat.handleDurability()); // todo: fletching durability + float weight = head.mass + core.mass; + float accuracy = fletching.accuracy; + float breakChance = fletching.breakChance; + + tags.setInteger("TotalDurability", durability); + tags.setFloat("Mass", weight); + tags.setFloat("BreakChance", breakChance); + tags.setFloat("Accuracy", accuracy); + } + + // now that durability has been handled... + // fill the ammo full and at the same time provide the missing NBT tag + IAmmo ammoItem = (IAmmo) event.tool; + tags.setInteger("Ammo", ammoItem.getMaxAmmo(tags)); + } + + @SubscribeEvent + public void onProjectileWeaponCrafted(ToolCraftEvent.NormalTool event) + { + if(!(event.tool instanceof ProjectileWeapon)) + return; + + NBTTagCompound tags = event.toolTag.getCompoundTag("InfiTool"); + + int drawSpeed = 0; + float flightSpeed = 0; + + BowMaterial top; + BowMaterial bottom; + BowstringMaterial string; + + if(event.tool instanceof BowBaseAmmo) { + top = TConstructRegistry.getBowMaterial(tags.getInteger("Head")); + bottom = TConstructRegistry.getBowMaterial(tags.getInteger("Accessory")); + string = (BowstringMaterial) TConstructRegistry.getCustomMaterial(tags.getInteger("Handle"), BowstringMaterial.class); + + drawSpeed = (int) ((top.drawspeed + bottom.drawspeed) / 2f * string.drawspeedModifier); + flightSpeed = (top.flightSpeedMax + bottom.flightSpeedMax)/2 * string.flightSpeedModifier; + } + else if(event.tool instanceof Crossbow) + { + top = TConstructRegistry.getBowMaterial(tags.getInteger("Head")); + string = (BowstringMaterial) TConstructRegistry.getCustomMaterial(tags.getInteger("Accessory"), BowstringMaterial.class); + + drawSpeed = (int) ((float)top.drawspeed * string.drawspeedModifier); + flightSpeed = (top.flightSpeedMax * string.flightSpeedModifier); + } + else + return; + + // enchanted fabric + /* + if (tags.getInteger("Handle") == 1) { + int modifiers = tags.getInteger("Modifiers"); + modifiers += 1; + tags.setInteger("Modifiers", modifiers); + }*/ + + tags.setInteger("DrawSpeed", drawSpeed); + tags.setFloat("FlightSpeed", flightSpeed); + } + + + // arrows use custom materials. But we don't allow the creation of those items + // we therefore replace the items with their toolpart counterparts here + @SubscribeEvent + public void buildArrow(ToolBuildEvent event) + { + if(event.headStack == null || event.handleStack == null || event.accessoryStack == null) + return; + + // are we building an arrow? + CustomMaterial mat = TConstructRegistry.getCustomMaterial(event.handleStack, ArrowShaftMaterial.class); + if(mat == null) + return; + Item extra = event.extraStack != null ? event.extraStack.getItem() : null; + ToolCore tool = ToolBuilder.instance.getMatchingRecipe(event.headStack.getItem(), mat.craftingItem.getItem(), event.accessoryStack.getItem(), extra); + + // it's an arrow! + if(tool == TinkerWeaponry.arrowAmmo) + event.handleStack = mat.craftingItem.copy(); + } + + // bolts require special treatment because of their dual-material cores + @SubscribeEvent + public void buildBolt(ToolBuildEvent event) + { + if(event.headStack == null || event.handleStack == null) + return; + + if(event.headStack.getItem() != TinkerWeaponry.partBolt) + return; + + // split the bolt into its two parts + ItemStack bolt1 = event.headStack.copy(); + ItemStack bolt2 = event.headStack; + ItemStack fletching = event.handleStack; + + + // set the correct material on the 2nd part + DualMaterialToolPart dualPart = (DualMaterialToolPart) bolt2.getItem(); + bolt1.setItemDamage(dualPart.getMaterialID2(bolt1)); + + // update the part positions xX + event.headStack = bolt1; + event.handleStack = bolt2; + event.accessoryStack = fletching; + } +} diff --git a/src/main/java/tconstruct/weaponry/ammo/ArrowAmmo.java b/src/main/java/tconstruct/weaponry/ammo/ArrowAmmo.java new file mode 100644 index 00000000..d367ddc3 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/ammo/ArrowAmmo.java @@ -0,0 +1,124 @@ +package boni.tinkersweaponry.ammo; + +import boni.tinkersweaponry.TinkerWeaponry; +import boni.tinkersweaponry.library.weaponry.AmmoItem; +import boni.tinkersweaponry.util.Reference; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import tconstruct.library.crafting.ToolBuilder; +import tconstruct.tools.TinkerTools; + +import java.util.List; + +public class ArrowAmmo extends AmmoItem { + public static ItemStack vanillaArrow; + + public ArrowAmmo() { + super(0, "Arrows"); + } + + @Override + public String getIconSuffix (int partType) + { + switch (partType) + { + case 0: + return "_arrow_head"; + case 1: + return ""; // Doesn't break + case 2: + return "_arrow_shaft"; + case 3: + return "_arrow_fletching"; + default: + return ""; + } + } + + @Override + public String getEffectSuffix () + { + return "_arrow_effect"; + } + + @Override + public String getDefaultFolder () + { + return "arrow"; + } + + @Override + public String getDefaultTexturePath() { + return Reference.RESOURCE + ":" + getDefaultFolder(); + } + + @Override + public void registerPartPaths (int index, String[] location) + { + headStrings.put(index, location[0]); + } + + @Override + public void registerAlternatePartPaths (int index, String[] location) + { + handleStrings.put(index, location[2]); + accessoryStrings.put(index, location[3]); + } + + @Override + public Item getHeadItem () + { + return TinkerTools.arrowhead; + } + + @Override + public Item getHandleItem() { + return TinkerWeaponry.partArrowShaft; + } + + @Override + public Item getAccessoryItem () + { + return TinkerTools.fletching; + } + + @Override + public String[] getTraits () + { + return new String[] { "ammo" }; + } + + @Override + public void buildTool (int id, String name, List list) + { + ItemStack handleStack = new ItemStack(getHandleItem(), 1, 0); // wooden shaft + ItemStack accessoryStack = new ItemStack(getAccessoryItem(), 1, 0); // feather fletchling + + ItemStack tool = ToolBuilder.instance.buildTool(new ItemStack(getHeadItem(), 1, id), handleStack, accessoryStack, null, ""); + if (tool != null) + { + tool.getTagCompound().getCompoundTag("InfiTool").setBoolean("Built", true); + list.add(tool); + } + } + + @Override + public void getSubItems(Item id, CreativeTabs tab, List list) { + super.getSubItems(id, tab, list); + + // vanilla arrow + ItemStack headStack = new ItemStack(getHeadItem(), 1, TinkerTools.MaterialID.Flint); // flint arrow head + ItemStack handleStack = new ItemStack(getHandleItem(), 1, 0); // wooden shaft + ItemStack accessoryStack = new ItemStack(getAccessoryItem(), 1, 0); // feather fletchling + + ItemStack tool = ToolBuilder.instance.buildTool(headStack, handleStack, accessoryStack, null, ""); + if (tool != null) + { + tool.getTagCompound().getCompoundTag("InfiTool").setBoolean("Built", true); + vanillaArrow = tool; + } + else + TinkerWeaponry.Log.error("Couldn't build vanilla equivalent of Tinker Arrow"); + } +} diff --git a/src/main/java/tconstruct/weaponry/ammo/BoltAmmo.java b/src/main/java/tconstruct/weaponry/ammo/BoltAmmo.java new file mode 100644 index 00000000..03c63e42 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/ammo/BoltAmmo.java @@ -0,0 +1,93 @@ +package boni.tinkersweaponry.ammo; + +import boni.tinkersweaponry.TinkerWeaponry; +import boni.tinkersweaponry.items.DualMaterialToolPart; +import boni.tinkersweaponry.library.weaponry.AmmoItem; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import tconstruct.library.crafting.ToolBuilder; +import tconstruct.tools.TinkerTools; + +import java.util.List; + +public class BoltAmmo extends AmmoItem { + public BoltAmmo() { + super(0, "Bolts"); + } + + @Override + public String getIconSuffix(int partType) { + switch (partType) + { + case 0: + return "_bolt_head"; + case 1: + return ""; // Doesn't break + case 2: + return "_bolt_shaft"; + case 3: + return "_bolt_fletching"; + default: + return ""; + } + } + + @Override + public String getEffectSuffix() { + return "_bolt_effect"; + } + + @Override + public String getDefaultFolder() { + return "bolt"; + } + + @Override + public void registerPartPaths (int index, String[] location) + { + headStrings.put(index, location[0]); + handleStrings.put(index, location[2]); + } + + @Override + public void registerAlternatePartPaths (int index, String[] location) + { + accessoryStrings.put(index, location[3]); + } + + @Override + public Item getHeadItem() { + return TinkerWeaponry.partBolt; + } + + @Override + public Item getHandleItem() { + return TinkerWeaponry.partBolt; + } + + @Override + public Item getAccessoryItem() { + return TinkerTools.fletching; + } + + @Override + public String[] getTraits() { + return new String[] {"ammo"}; + } + + @Override + public void buildTool (int id, String name, List list) + { + // dual material head: we use wooden shafts + ItemStack headStack = DualMaterialToolPart.createDualMaterial(getHeadItem(), 0, id); // wooden shaft, material head + ItemStack handleStack = new ItemStack(getAccessoryItem(), 1, 0); // feather Fletchling + //ItemStack accessoryStack = new ItemStack(getAccessoryItem(), 1, 0); // feather fletchling + + ItemStack tool = ToolBuilder.instance.buildTool(headStack, handleStack, null, null, ""); + if (tool != null) + { + tool.getTagCompound().getCompoundTag("InfiTool").setBoolean("Built", true); + list.add(tool); + } + } +} diff --git a/src/main/java/tconstruct/weaponry/client/AmmoSlotHandler.java b/src/main/java/tconstruct/weaponry/client/AmmoSlotHandler.java new file mode 100644 index 00000000..6b1d740e --- /dev/null +++ b/src/main/java/tconstruct/weaponry/client/AmmoSlotHandler.java @@ -0,0 +1,57 @@ +package boni.tinkersweaponry.client; + +import boni.tinkersweaponry.library.weaponry.ProjectileWeapon; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraftforge.client.event.RenderGameOverlayEvent; + +public class AmmoSlotHandler { + @SubscribeEvent + public void onRenderOverlay(RenderGameOverlayEvent.Pre event) + { + if(event.type != RenderGameOverlayEvent.ElementType.HOTBAR) + return; + + EntityPlayer player = Minecraft.getMinecraft().thePlayer; + ItemStack equipped = player.getCurrentEquippedItem(); + + if(equipped == null || equipped.getItem() == null) + return; + if(!(equipped.getItem() instanceof ProjectileWeapon)) + return; + + // find ammo + // todo: cache this somehow? + ItemStack ammo = ((ProjectileWeapon) equipped.getItem()).searchForAmmo(player, equipped); + if(ammo == null) + return; + + // check if it's in the inventory + int slot = -1; + for(int i = 0; i < 9; i++) + if(player.inventory.mainInventory[i] == ammo) + { + slot = i; + break; + } + + // not in the hotbar + if(slot == -1) + return; + + int x = event.resolution.getScaledWidth() / 2 - 90 + slot * 20 + 2; + int z = event.resolution.getScaledHeight() - 16 - 3; + + int col = 0; + col |= 120 << 16; // red + col |= 150 << 8; // green + col |= 200 << 0; // blue + col |= 200 << 24; // alpha + + // render a cool underlay thing + Gui.drawRect(x,z, x+16, z+16, col); + } +} diff --git a/src/main/java/tconstruct/weaponry/client/CrosshairHandler.java b/src/main/java/tconstruct/weaponry/client/CrosshairHandler.java new file mode 100644 index 00000000..304116da --- /dev/null +++ b/src/main/java/tconstruct/weaponry/client/CrosshairHandler.java @@ -0,0 +1,161 @@ +package boni.tinkersweaponry.client; + +import boni.tinkersweaponry.util.Reference; +import boni.tinkersweaponry.library.weaponry.IWindup; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.item.ItemStack; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.event.RenderGameOverlayEvent; +import org.lwjgl.opengl.GL11; + +public class CrosshairHandler { + private static Minecraft mc = Minecraft.getMinecraft(); + + private static ResourceLocation crossHairSquare = new ResourceLocation(Reference.RESOURCE, "textures/gui/Crosshair.png"); + private static ResourceLocation crossHairTip = new ResourceLocation(Reference.RESOURCE, "textures/gui/Crosshair2.png"); + private static ResourceLocation crossHairWeird = new ResourceLocation(Reference.RESOURCE, "textures/gui/Crosshair3.png"); + private static ResourceLocation crossHairSpike = new ResourceLocation(Reference.RESOURCE, "textures/gui/Crosshair4.png"); + + @SubscribeEvent + public void onRenderOverlay(RenderGameOverlayEvent.Pre event) + { + if(event.type != RenderGameOverlayEvent.ElementType.CROSSHAIRS) + return; + + ItemStack equipped = mc.thePlayer.getCurrentEquippedItem(); + if(equipped == null || equipped.getItem() == null) + return; + if(!(equipped.getItem() instanceof IWindup)) + return; + + IWindup weapon = (IWindup) equipped.getItem(); + + float width = event.resolution.getScaledWidth(); + float height = event.resolution.getScaledHeight(); + + int type = 0; + ResourceLocation tex; + switch (weapon.getCrosshairType()) + { + case SQUARE: tex = crossHairSquare; break; + case TIP: tex = crossHairTip; break; + case WEIRD: tex = crossHairWeird; type = 1; break; + case SPIKE: tex = crossHairSpike; type = 1; break; + default: tex = crossHairSquare; type = 0; + } + + mc.getTextureManager().bindTexture(tex); + GL11.glEnable(GL11.GL_BLEND); + OpenGlHelper.glBlendFunc(GL11.GL_ONE_MINUS_DST_COLOR, GL11.GL_ONE_MINUS_SRC_COLOR, 1, 0); + + float spread = ((1.0f - weapon.getWindupProgress(equipped, mc.thePlayer)) * 25f); + + // 4 square crosshair + if(type == 0) { + drawCrosshairPart(width / 2f - spread, height / 2f - spread, 0); + drawCrosshairPart(width / 2f + spread, height / 2f - spread, 1); + drawCrosshairPart(width / 2f - spread, height / 2f + spread, 2); + drawCrosshairPart(width / 2f + spread, height / 2f + spread, 3); + } + // 4 triangle crosshair + else { + drawAlternateCrosshairPart(width/2f, height/2f - spread, 0); + drawAlternateCrosshairPart(width/2f - spread, height/2f, 1); + drawAlternateCrosshairPart(width/2f + spread, height/2f, 2); + drawAlternateCrosshairPart(width/2f, height/2f + spread, 3); + } + + OpenGlHelper.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA, 1, 0); + GL11.glDisable(GL11.GL_BLEND); + + event.setCanceled(true); + } + + private void drawCrosshairPart(float width, float height, int part) + { + double w = (double)width; + double h = (double)height; + + double s = 4; + double z = -90; + + double u1 = 0; + double v1 = 0; + + switch(part) + { + // top left + case 0: + w -= s; + h -= s; + break; + case 1: + u1 = 0.5; + w += s; + h -= s; + break; + case 2: + v1 = 0.5; + w -= s; + h += s; + break; + case 3: + u1 = 0.5; + v1 = 0.5; + w += s; + h += s; + break; + } + + double u2 = u1 + 0.5; + double v2 = v1 + 0.5; + + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawingQuads(); + tessellator.addVertexWithUV(w - s, h - s, z, u1, v1); + tessellator.addVertexWithUV(w - s, h + s, z, u1, v2); + tessellator.addVertexWithUV(w + s, h + s, z, u2, v2); + tessellator.addVertexWithUV(w + s, h - s, z, u2, v1); + tessellator.draw(); + } + + private void drawAlternateCrosshairPart(float width, float height, int part) + { + double w = (double)width; + double h = (double)height; + + final double s = 8d; + final double z = -90; + + Tessellator tessellator = Tessellator.instance; + tessellator.startDrawing(GL11.GL_TRIANGLES); // 4 + // top part + if(part == 0) { + tessellator.addVertexWithUV(w - s, h - s, z, 0, 0); + tessellator.addVertexWithUV(w, h, z, 0.5, 0.5); + tessellator.addVertexWithUV(w + s, h - s, z, 1, 0); + } + // left part + else if(part == 1) { + tessellator.addVertexWithUV(w - s, h - s, z, 0, 0); + tessellator.addVertexWithUV(w - s, h + s, z, 0, 1); + tessellator.addVertexWithUV(w, h, z, 0.5, 0.5); + } + // right part + else if(part == 2) { + tessellator.addVertexWithUV(w, h, z, 0.5, 0.5); + tessellator.addVertexWithUV(w + s, h + s, z, 1, 1); + tessellator.addVertexWithUV(w + s, h - s, z, 1, 0); + } + // bottom part + else if(part == 3) { + tessellator.addVertexWithUV(w, h, z, 0.5, 0.5); + tessellator.addVertexWithUV(w - s, h + s, z, 0, 1); + tessellator.addVertexWithUV(w + s, h + s, z, 1, 1); + } + tessellator.draw(); + } +} diff --git a/src/main/java/tconstruct/weaponry/client/CrosshairType.java b/src/main/java/tconstruct/weaponry/client/CrosshairType.java new file mode 100644 index 00000000..d747e2fb --- /dev/null +++ b/src/main/java/tconstruct/weaponry/client/CrosshairType.java @@ -0,0 +1,12 @@ +package boni.tinkersweaponry.client; + +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; + +@SideOnly(Side.CLIENT) +public enum CrosshairType { + SQUARE, + TIP, + WEIRD, + SPIKE +} diff --git a/src/main/java/tconstruct/weaponry/client/IconFlipped.java b/src/main/java/tconstruct/weaponry/client/IconFlipped.java new file mode 100644 index 00000000..6201caf0 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/client/IconFlipped.java @@ -0,0 +1,22 @@ +package boni.tinkersweaponry.client; + +import net.minecraft.util.IIcon; + +// required to fix Mojansg bugs... +public class IconFlipped extends net.minecraft.client.renderer.IconFlipped { + private final IIcon baseIcon; + private final boolean flipV; + + public IconFlipped(IIcon p_i1560_1_, boolean p_i1560_2_, boolean p_i1560_3_) { + super(p_i1560_1_, p_i1560_2_, p_i1560_3_); + + this.baseIcon = p_i1560_1_; + this.flipV = p_i1560_3_; + } + + // has a faulty implementation in original class + public float getMinV() + { + return this.flipV ? this.baseIcon.getMaxV() : this.baseIcon.getMinV(); + } +} diff --git a/src/main/java/tconstruct/weaponry/client/RenderEventHandler.java b/src/main/java/tconstruct/weaponry/client/RenderEventHandler.java new file mode 100644 index 00000000..00e350be --- /dev/null +++ b/src/main/java/tconstruct/weaponry/client/RenderEventHandler.java @@ -0,0 +1,44 @@ +package boni.tinkersweaponry.client; + +import boni.tinkersweaponry.TinkerWeaponry; +import boni.tinkersweaponry.library.weaponry.BowBaseAmmo; +import boni.tinkersweaponry.library.weaponry.IWindup; +import cpw.mods.fml.common.eventhandler.SubscribeEvent; +import net.minecraft.item.ItemStack; +import net.minecraftforge.client.event.FOVUpdateEvent; +import net.minecraftforge.client.event.RenderPlayerEvent; + +public class RenderEventHandler { + @SubscribeEvent + public void onAimZoom(FOVUpdateEvent event) + { + if(!event.entity.isUsingItem()) + return; + + if(!(event.entity.getItemInUse().getItem() instanceof IWindup)) + return; + + ItemStack weapon = event.entity.getItemInUse(); + IWindup item = (IWindup) weapon.getItem(); + + if(item.zoomOnWindup(weapon)) + event.newfov = event.fov / (event.fov + (item.getZoom(weapon)-1.0f) * item.getWindupProgress(weapon, event.entity)); + } + + @SubscribeEvent + public void onRenderPlayer(RenderPlayerEvent.Pre event) + { + if(event.entityPlayer.getCurrentEquippedItem() != null && event.entityPlayer.getCurrentEquippedItem().getItem() == TinkerWeaponry.javelin) { + + } + + if(event.entityPlayer.getItemInUse() == null) + return; + + if(event.entityPlayer.getItemInUse().getItem() instanceof BowBaseAmmo) { + event.renderer.modelBipedMain.aimedBow = true; + event.renderer.modelArmor.aimedBow = true; + event.renderer.modelArmorChestplate.aimedBow = true; + } + } +} diff --git a/src/main/java/tconstruct/weaponry/client/entityrenderer/ArrowEntityRenderer.java b/src/main/java/tconstruct/weaponry/client/entityrenderer/ArrowEntityRenderer.java new file mode 100644 index 00000000..7e7fe862 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/client/entityrenderer/ArrowEntityRenderer.java @@ -0,0 +1,51 @@ +package boni.tinkersweaponry.client.entityrenderer; + +import boni.tinkersweaponry.entity.ArrowEntity; +import org.lwjgl.opengl.GL11; + +public class ArrowEntityRenderer extends ProjectileBaseRenderer { + private int count = 0; + private final float size; + + public ArrowEntityRenderer(float size) { + this.size = size; + } + + public ArrowEntityRenderer() { + this(1.0f); + } + + @Override + public void doRender(ArrowEntity entity, double x, double y, double z, float p_76986_8_, float p_76986_9_) { + count = 0; + super.doRender(entity, x, y, z, p_76986_8_, p_76986_9_); + count = 1; + super.doRender(entity, x, y, z, p_76986_8_, p_76986_9_); + } + + @Override + public void customRendering(ArrowEntity entity, double x, double y, double z, float p_76986_8_, float p_76986_9_) { + // flip it, flop it, pop it, pull it, push it, rotate it, translate it, TECHNOLOGY + + GL11.glScalef(size, size, size); + + // rotate it into the direction we threw it + GL11.glRotatef(entity.rotationYaw, 0f, 1f, 0f); + GL11.glRotatef(-entity.rotationPitch, 1f, 0f, 0f); + + // rotate it so it's "upright" + if(count == 0) + GL11.glRotatef(90, 0f, 0f, 1f); + + GL11.glRotatef(45, 0f, 0f, 1f); + + // rotate it so it faces forward + GL11.glRotatef(90f, 1f, 0f, 0f); + + // rotate the projectile it so it faces upwards (because the graphic itself is rotated by 45°) + GL11.glRotatef(-45, 0f, 0f, 1f); + + // thinner arrows + toolCoreRenderer.setDepth(1/64f); + } +} diff --git a/src/main/java/tconstruct/weaponry/client/entityrenderer/JavelinEntityRenderer.java b/src/main/java/tconstruct/weaponry/client/entityrenderer/JavelinEntityRenderer.java new file mode 100644 index 00000000..6e7c828a --- /dev/null +++ b/src/main/java/tconstruct/weaponry/client/entityrenderer/JavelinEntityRenderer.java @@ -0,0 +1,29 @@ +package boni.tinkersweaponry.client.entityrenderer; + +import boni.tinkersweaponry.entity.JavelinEntity; +import org.lwjgl.opengl.GL11; + +public class JavelinEntityRenderer extends ProjectileBaseRenderer { + @Override + public void customRendering(JavelinEntity entity, double x, double y, double z, float p_76986_8_, float p_76986_9_) { + + // rotate it into the direction we threw it + GL11.glRotatef(entity.rotationYaw, 0f, 1f, 0f); + GL11.glRotatef(-entity.rotationPitch, 1f, 0f, 0f); + + // rotate it so it faces forward + GL11.glRotatef(90f, 1f, 0f, 0f); + + // roll it all aroun + GL11.glRotated(entity.roll, 0, 1, 0); + + // make it looooong + GL11.glScalef(1.5F, 3.0F, 1.5F); + GL11.glTranslatef(0f, -0.5f, 0f); + + // rotate the projectile it so it faces upwards (because the graphic itself is rotated by 45°) + GL11.glRotatef(45, 0f, 0f, 1f); + + toolCoreRenderer.setDepth(1/16f); + } +} diff --git a/src/main/java/tconstruct/weaponry/client/entityrenderer/ProjectileBaseRenderer.java b/src/main/java/tconstruct/weaponry/client/entityrenderer/ProjectileBaseRenderer.java new file mode 100644 index 00000000..f79c45c3 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/client/entityrenderer/ProjectileBaseRenderer.java @@ -0,0 +1,86 @@ +package boni.tinkersweaponry.client.entityrenderer; + +import boni.tinkersweaponry.client.renderer.FlexibleToolRenderer; +import boni.tinkersweaponry.entity.ProjectileBase; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.entity.Entity; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.client.IItemRenderer; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; + +public class ProjectileBaseRenderer extends Render { + protected static FlexibleToolRenderer toolCoreRenderer = new FlexibleToolRenderer(); + + @Override + public void doRender(Entity p_76986_1_, double p_76986_2_, double p_76986_4_, double p_76986_6_, float p_76986_8_, float p_76986_9_) { + doRender((T)p_76986_1_, p_76986_2_, p_76986_4_, p_76986_6_, p_76986_8_, p_76986_9_); + } + + public void doRender(T entity, double x, double y, double z, float p_76986_8_, float p_76986_9_) { + // preface: Remember that the rotations are applied in reverse order. + // the rendering call does not apply any transformations. + // That'd screw things up, since it'd be applied before our transformations + // So remember to read this from the rendering call up to this line + + // can be overwritten in customRendering + toolCoreRenderer.setDepth(1/32f); + + GL11.glPushMatrix(); + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + + // last step: translate from 0/0/0 to correct position in world + GL11.glTranslatef((float) x, (float) y, (float) z); + // mkae it smaller + GL11.glScalef(0.5F, 0.5F, 0.5F); + + customRendering(entity, x, y, z, p_76986_8_, p_76986_9_); + + // arrow shake + float f11 = (float)entity.arrowShake - p_76986_9_; + if (f11 > 0.0F) + { + float f12 = -MathHelper.sin(f11 * 3.0F) * f11; + GL11.glRotatef(f12, 0.0F, 0.0F, 1.0F); + } + + // draw correct texture. not some weird block fragments. + renderManager.renderEngine.bindTexture(TextureMap.locationItemsTexture); + // rendering code has been optimized to be exactly at the center and without translation + toolCoreRenderer.renderItem(IItemRenderer.ItemRenderType.ENTITY, entity.getEntityItem()); + + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + GL11.glPopMatrix(); + } + + public void customRendering(T entity, double x, double y, double z, float p_76986_8_, float p_76986_9_) + { + // flip it, flop it, pop it, pull it, push it, rotate it, translate it, TECHNOLOGY + + // rotate it into the direction we threw it + GL11.glRotatef(entity.rotationYaw, 0f, 1f, 0f); + GL11.glRotatef(-entity.rotationPitch, 1f, 0f, 0f); + + // rotate it so it's "upright" + GL11.glRotatef(90, 0f, 0f, 1f); + + // rotate it so it faces forward + GL11.glRotatef(90f, 1f, 0f, 0f); + + // rotate the projectile it so it faces upwards + GL11.glRotatef(-45, 0f, 0f, 1f); + } + + @Override + protected ResourceLocation getEntityTexture (Entity par1Entity) + { + return this.func_110796_a((ProjectileBase) par1Entity); + } + + protected ResourceLocation func_110796_a (ProjectileBase par1ArrowEntity) + { + return this.renderManager.renderEngine.getResourceLocation(par1ArrowEntity.getEntityItem().getItemSpriteNumber()); + } +} diff --git a/src/main/java/tconstruct/weaponry/client/entityrenderer/ShurikenEntityRenderer.java b/src/main/java/tconstruct/weaponry/client/entityrenderer/ShurikenEntityRenderer.java new file mode 100644 index 00000000..a2aa33f8 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/client/entityrenderer/ShurikenEntityRenderer.java @@ -0,0 +1,30 @@ +package boni.tinkersweaponry.client.entityrenderer; + +import boni.tinkersweaponry.entity.ShurikenEntity; +import org.lwjgl.opengl.GL11; + +public class ShurikenEntityRenderer extends ProjectileBaseRenderer { + + @Override + public void customRendering(ShurikenEntity entity, double x, double y, double z, float p_76986_8_, float p_76986_9_) { + // make it smaller + GL11.glScalef(0.6F, 0.6F, 0.6F); + + // rotate it into the direction we threw it + GL11.glRotatef(entity.rotationYaw, 0f, 1f, 0f); + GL11.glRotatef(-entity.rotationPitch, 1f, 0f, 0f); + + // add some diversity + GL11.glRotatef(entity.rollAngle, 0f, 0f, 1f); + + // rotate it into a horizontal position + GL11.glRotatef(90f, 1f, 0f, 0f); + + // shurikens spin around their center a lot. *spin* + GL11.glRotatef(entity.spin, 0f, 0f, 1f); + + + // also make it a bit thicker + toolCoreRenderer.setDepth(1/20f); + } +} diff --git a/src/main/java/tconstruct/weaponry/client/renderer/AmmoItemRenderer.java b/src/main/java/tconstruct/weaponry/client/renderer/AmmoItemRenderer.java new file mode 100644 index 00000000..1763e3e1 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/client/renderer/AmmoItemRenderer.java @@ -0,0 +1,56 @@ +package boni.tinkersweaponry.client.renderer; + +import boni.tinkersweaponry.library.weaponry.IAmmo; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; +import net.minecraft.item.ItemStack; +import org.lwjgl.opengl.GL11; + +public class AmmoItemRenderer extends FlexibleToolRenderer { + //public static FontRenderer fontRenderer; + + public AmmoItemRenderer() { +// super(true); + //fontRenderer = new FontRenderer(Minecraft.getMinecraft().gameSettings, new ResourceLocation(Reference.RESOURCE, "textures/font/border_numbers.png"), Minecraft.getMinecraft().renderEngine, false); + } + + @Override + public boolean handleRenderType(ItemStack item, ItemRenderType type) { + if(type == ItemRenderType.INVENTORY) + return true; + + return super.handleRenderType(item, type); + } + + @Override + public void renderItem(ItemRenderType type, ItemStack item, Object... data) { + // render the item regularly + super.renderItem(type, item, data); + //RenderItem.getInstance().renderItemIntoGUI(Minecraft.getMinecraft().fontRenderer, Minecraft.getMinecraft().renderEngine, item, 0,0); + + if(item.getTagCompound() == null || type != ItemRenderType.INVENTORY) + return; + + // render custom stacksize + renderAmmoCount(item); + } + + public void renderAmmoCount(ItemStack item) + { + if(!(item.getItem() instanceof IAmmo)) + return; + int amount = ((IAmmo) item.getItem()).getAmmoCount(item); + String str = String.valueOf(amount); + + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glDisable(GL11.GL_DEPTH_TEST); + GL11.glDisable(GL11.GL_BLEND); + + GL11.glScalef(0.7f, 0.7f, 0.7f); + FontRenderer fontRenderer = Minecraft.getMinecraft().fontRenderer; + fontRenderer.drawStringWithShadow(str, 7 + 19 - 2 - fontRenderer.getStringWidth(str), 7 + 6 + 3, 16777215); + + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_DEPTH_TEST); + } +} diff --git a/src/main/java/tconstruct/weaponry/client/renderer/BowRenderer.java b/src/main/java/tconstruct/weaponry/client/renderer/BowRenderer.java new file mode 100644 index 00000000..089630c4 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/client/renderer/BowRenderer.java @@ -0,0 +1,114 @@ +package boni.tinkersweaponry.client.renderer; + +import boni.tinkersweaponry.TinkerWeaponry; +import boni.tinkersweaponry.ammo.ArrowAmmo; +import boni.tinkersweaponry.entity.ArrowEntity; +import boni.tinkersweaponry.library.weaponry.ProjectileWeapon; +import boni.tinkersweaponry.library.weaponry.IWindup; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import org.lwjgl.opengl.GL11; + +public class BowRenderer extends FlexibleToolRenderer { + private static final ArrowEntity dummy = new ArrowEntity(null); + + @Override + protected void specialAnimation(ItemRenderType type, ItemStack item) { + EntityPlayer player = Minecraft.getMinecraft().thePlayer; + + if(type == ItemRenderType.EQUIPPED) + { + //GL11.glTranslatef(0.0F, 0.125F, 0.3125F); + GL11.glTranslatef(0.2F, -0.4F, 0.2f); + GL11.glRotatef(-20.0F, 0.0F, 1.0F, 0.0F); + //GL11.glScalef(f1, -f1, f1); + //GL11.glRotatef(-100.0F, 1.0F, 0.0F, 0.0F); + GL11.glRotatef(45.0F, 0.0F, 1.0F, 0.0F); + } + + // windup animation + if(type == ItemRenderType.EQUIPPED_FIRST_PERSON && player.isUsingItem()) + { + float progress = ((IWindup) item.getItem()).getWindupProgress(item, player); + + //GL11.glScalef(1.2f, 1.2f, 1.2f); + //float progress = ((IWindup) item.getItem()).getWindupProgress(item, Minecraft.getMinecraft().thePlayer);; + GL11.glRotatef(-18.0F, 0.0F, 0.0F, 1.0F); // tilts the bow forward a bit + GL11.glRotatef(-6.0F, 0.0F, 1.0F, 0.0F); // rotates the bow so it faces more forward + GL11.glRotatef(8.0F, 1.0F, 0.0F, 0.0F); // rotates the bow forward + GL11.glTranslatef(-0.9F, 0.2F, -1.0F); + + + // this does the "zoom closer to the bow" thing + GL11.glTranslatef(progress * -0.1f, progress * -0.125f, 0.0F); + + + + // we're crazy, so.. render the arrow =D + ItemStack ammo = ((ProjectileWeapon) item.getItem()).searchForAmmo(player, item); // we know it's a projectile weapon, it's a bow! + if(ammo != null) { + if(ammo.getItem() == Items.arrow) + dummy.returnStack = ArrowAmmo.vanillaArrow; + else + dummy.returnStack = ammo; + Render renderer = RenderManager.instance.getEntityClassRenderObject(ArrowEntity.class); + + GL11.glPushMatrix(); + // adjust position + GL11.glScalef(2, 2, 2); // bigger + GL11.glRotatef(90, 0, 1, 0); // rotate it into the same direction as the bow + GL11.glRotatef(15, 0, 1, 0); // rotate it a bit more so it's not directly inside the bow + GL11.glRotatef(-45, 1, 0, 0); // sprite is rotated by 45° in the graphics, correct that + GL11.glTranslatef(0.05f, 0, 0); // same as the not-inside-bow-rotation + + // move the arrow with the charging process + float offset = 0.075f - 0.15f * progress; + + GL11.glTranslatef(0, 0, offset); + + // render iiit + renderer.doRender(dummy, 0, 0, 0, 0, 0); + GL11.glPopMatrix(); + } + } + else if(type == ItemRenderType.EQUIPPED && player.isUsingItem()) + { + // we're crazy, so.. render the arrow =D + ItemStack ammo = ((ProjectileWeapon) item.getItem()).searchForAmmo(player, item); // we know it's a projectile weapon, it's a bow! + if(ammo != null) { + if(ammo.getItem() == Items.arrow) + dummy.returnStack = ArrowAmmo.vanillaArrow; + else + dummy.returnStack = ammo; + Render renderer = RenderManager.instance.getEntityClassRenderObject(ArrowEntity.class); + + GL11.glPushMatrix(); + // adjust position + GL11.glScalef(2, 2, 2); // bigger + GL11.glRotatef(90, 0, 1, 0); // rotate it into the same direction as the bow + GL11.glRotatef(15, 0, 1, 0); // rotate it a bit more so it's not directly inside the bow + GL11.glRotatef(-45, 1, 0, 0); // sprite is rotated by 45° in the graphics, correct that + GL11.glTranslatef(0.05f, 0, 0); // same as the not-inside-bow-rotation + + // move the arrow with the charging process + float offset = 0.075f - 0.15f * 1; + + GL11.glTranslatef(0, 0, offset); + + // render iiit + renderer.doRender(dummy, 0, 0, 0, 0, 0); + GL11.glPopMatrix(); + } + } + + + if(item.getItem() == TinkerWeaponry.longbow) + GL11.glScalef(2.3f, 2.3f, 1.0f); + else if(item.getItem() == TinkerWeaponry.shortbow) + GL11.glScalef(1.7f, 1.7f, 1.0f); + } +} diff --git a/src/main/java/tconstruct/weaponry/client/renderer/CrossbowRenderer.java b/src/main/java/tconstruct/weaponry/client/renderer/CrossbowRenderer.java new file mode 100644 index 00000000..ecd0b5d2 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/client/renderer/CrossbowRenderer.java @@ -0,0 +1,72 @@ +package boni.tinkersweaponry.client.renderer; + +import boni.tinkersweaponry.entity.ArrowEntity; +import boni.tinkersweaponry.entity.BoltEntity; +import boni.tinkersweaponry.weapons.Crossbow; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.entity.Render; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import org.lwjgl.opengl.GL11; + +public class CrossbowRenderer extends FlexibleToolRenderer { + private static final BoltEntity dummy = new BoltEntity(null); + + @Override + protected void specialAnimation(ItemRenderType type, ItemStack item) { + EntityPlayer player = Minecraft.getMinecraft().thePlayer; + Crossbow crossbow = (Crossbow)item.getItem(); + + GL11.glScalef(1.5f, 1.5f, 1.5f); + + if(type == ItemRenderType.EQUIPPED_FIRST_PERSON) { + // we're crazy, so.. render the arrow =D + ItemStack ammo = crossbow.getLoadedAmmo(item); + + if(crossbow.isLoaded(item)) + { + GL11.glTranslatef(0.0f, 0.0f, -0.3f); + GL11.glRotatef(80f, 1f, 0f, 0f); + GL11.glRotatef(15f, 0f, 1f, 0f); + GL11.glRotatef(-20, 0, 0, 1); + } + else { + GL11.glScalef(1.1f, 1.1f, 1.1f); + GL11.glTranslatef(0.1f, 0f, 0f); + GL11.glRotatef(50f, 1f, 0f, 0f); + } + + if(ammo != null) { + //float progress = crossbow.getWindupProgress(item, player); + float progress = 1f; + dummy.returnStack = ammo; + Render renderer = RenderManager.instance.getEntityClassRenderObject(ArrowEntity.class); + + GL11.glPushMatrix(); + // adjust position + //GL11.glScalef(2, 2, 2); // bigger + GL11.glRotatef(95, 0, 1, 0); // rotate it into the same direction as the bow + //GL11.glRotatef(15, 0, 1, 0); // rotate it a bit more so it's not directly inside the bow + GL11.glRotatef(-45, 1, 0, 0); // sprite is rotated by 45° in the graphics, correct that + GL11.glTranslatef(0.05f, 0, 0); // same as the not-inside-bow-rotation + + // move the arrow with the charging process + float offset = -0.15f; + + GL11.glTranslatef(0, 0, offset); + + // render iiit + renderer.doRender(dummy, 0, 0, 0, 0, 0); + GL11.glPopMatrix(); + } + } + + + if(type == ItemRenderType.EQUIPPED) + { + GL11.glTranslatef(0.25f, 0, 0); + GL11.glRotatef(45.0F, 0.0F, 0.0F, 1.0F); + } + } +} diff --git a/src/main/java/tconstruct/weaponry/client/renderer/FlexibleToolRenderer.java b/src/main/java/tconstruct/weaponry/client/renderer/FlexibleToolRenderer.java new file mode 100644 index 00000000..dea43d0a --- /dev/null +++ b/src/main/java/tconstruct/weaponry/client/renderer/FlexibleToolRenderer.java @@ -0,0 +1,310 @@ +package boni.tinkersweaponry.client.renderer; + +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraftforge.client.IItemRenderer; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; +import tconstruct.TConstruct; +import tconstruct.library.tools.ToolCore; + +public class FlexibleToolRenderer implements IItemRenderer { + public float depth = 1/32f; + + public void setDepth(float d) { depth = d; } + + @Override + public boolean handleRenderType (ItemStack item, ItemRenderType type) + { + if(!item.hasTagCompound()) + return false; + + switch (type) + { + case ENTITY: + //GL11.glTranslatef(-0.0625F, -0.0625F, 0F); + return true; + case EQUIPPED: + //GL11.glTranslatef(0.03f, 0F, -0.09375F); + case EQUIPPED_FIRST_PERSON: + return true; + case INVENTORY: + return true; + default: + TConstruct.logger.warn("[TCon] Unhandled render case!"); + case FIRST_PERSON_MAP: + return false; + } + } + + @Override + public boolean shouldUseRenderHelper (ItemRenderType type, ItemStack item, ItemRendererHelper helper) + { + return handleRenderType(item, type) & helper.ordinal() < ItemRendererHelper.EQUIPPED_BLOCK.ordinal(); + } + + private static final int toolIcons = 10; + + protected void specialAnimation(ItemRenderType type, ItemStack item) {} + + @Override + public void renderItem (ItemRenderType type, ItemStack item, Object... data) { + Entity ent = null; + if (data.length > 1) + ent = (Entity) data[1]; + + IIcon[] parts = new IIcon[toolIcons]; + int iconParts = getIcons(item, type, ent, parts); + + // drawing the inventory is a simple procedure + if (type == ItemRenderType.INVENTORY) { + renderInventory(iconParts, parts, item); + return; + } + + Tessellator tess = Tessellator.instance; + float[] xMax = new float[iconParts]; + float[] yMin = new float[iconParts]; + float[] xMin = new float[iconParts]; + float[] yMax = new float[iconParts]; + + float[] width = new float[iconParts]; + float[] height = new float[iconParts]; + float[] xDiff = new float[iconParts]; + float[] yDiff = new float[iconParts]; + float[] xSub = new float[iconParts]; + float[] ySub = new float[iconParts]; + for (int i = 0; i < iconParts; ++i) + { + IIcon icon = parts[i]; + xMin[i] = icon.getMinU(); + xMax[i] = icon.getMaxU(); + yMin[i] = icon.getMinV(); + yMax[i] = icon.getMaxV(); + width[i] = icon.getIconWidth(); + height[i] = icon.getIconHeight(); + xDiff[i] = xMin[i] - xMax[i]; + yDiff[i] = yMin[i] - yMax[i]; + xSub[i] = 0.5f * (xMax[i] - xMin[i]) / width[i]; + ySub[i] = 0.5f * (yMax[i] - yMin[i]) / height[i]; + } + + GL11.glPushMatrix(); + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + + if(type != ItemRenderType.ENTITY) { + GL11.glTranslatef(0.5f, 0.5f, 0); + GL11.glScalef(0.5f, 0.5f, 0.5f); + + specialAnimation(type, item); + } + + // prepare colors + int[] color = new int[iconParts]; + for(int i = 0; i < iconParts; i++) + color[i] = item.getItem().getColorFromItemStack(item, i); + + // one side + tess.startDrawingQuads(); + tess.setNormal(0, 0, 1); + for (int i = 0; i < iconParts; ++i) + { + tess.setColorOpaque_I(color[i]); + tess.addVertexWithUV(-0.5, -0.5, +depth, xMax[i], yMax[i]); + tess.addVertexWithUV(+0.5, -0.5, +depth, xMin[i], yMax[i]); + tess.addVertexWithUV(+0.5, +0.5, +depth, xMin[i], yMin[i]); + tess.addVertexWithUV(-0.5, +0.5, +depth, xMax[i], yMin[i]); + } + tess.draw(); + + // other side + tess.startDrawingQuads(); + tess.setNormal(0, 0, -1); + for (int i = 0; i < iconParts; ++i) + { + tess.setColorOpaque_I(color[i]); + tess.addVertexWithUV(-0.5, +0.5, -depth, xMax[i], yMin[i]); + tess.addVertexWithUV(+0.5, +0.5, -depth, xMin[i], yMin[i]); + tess.addVertexWithUV(+0.5, -0.5, -depth, xMin[i], yMax[i]); + tess.addVertexWithUV(-0.5, -0.5, -depth, xMax[i], yMax[i]); + } + tess.draw(); + + // make it have "depth" + tess.startDrawingQuads(); + tess.setNormal(-1, 0, 0); + float pos; + float iconPos; + + for (int i = 0; i < iconParts; ++i) + { + tess.setColorOpaque_I(color[i]); + float w = width[i], m = xMax[i], d = xDiff[i], s = xSub[i]; + for (int k = 0, e = (int)w; k < e; ++k) + { + pos = k / w; + iconPos = m + d * pos - s; + pos -= 0.5f; + tess.addVertexWithUV(pos, -0.5, -depth, iconPos, yMax[i]); + tess.addVertexWithUV(pos, -0.5, +depth, iconPos, yMax[i]); + tess.addVertexWithUV(pos, +0.5, +depth, iconPos, yMin[i]); + tess.addVertexWithUV(pos, +0.5, -depth, iconPos, yMin[i]); + } + } + + tess.draw(); + tess.startDrawingQuads(); + tess.setNormal(1, 0, 0); + float posEnd; + + for (int i = 0; i < iconParts; ++i) + { + tess.setColorOpaque_I(color[i]); + float w = width[i], m = xMax[i], d = xDiff[i], s = xSub[i]; + float d2 = 1f / w; + for (int k = 0, e = (int)w; k < e; ++k) + { + pos = k / w; + iconPos = m + d * pos - s; + pos -= 0.5f; + posEnd = pos + d2; + tess.addVertexWithUV(posEnd, +0.5, -depth, iconPos, yMin[i]); + tess.addVertexWithUV(posEnd, +0.5, +depth, iconPos, yMin[i]); + tess.addVertexWithUV(posEnd, -0.5, +depth, iconPos, yMax[i]); + tess.addVertexWithUV(posEnd, -0.5, -depth, iconPos, yMax[i]); + } + } + + tess.draw(); + tess.startDrawingQuads(); + tess.setNormal(0, 1, 0); + + for (int i = 0; i < iconParts; ++i) + { + tess.setColorOpaque_I(color[i]); + float h = height[i], m = yMax[i], d = yDiff[i], s = ySub[i]; + float d2 = 1f / h; + for (int k = 0, e = (int)h; k < e; ++k) + { + pos = k / h; + iconPos = m + d * pos - s; + pos -= 0.5f; + posEnd = pos + d2; + tess.addVertexWithUV(-0.5, posEnd, +depth, xMax[i], iconPos); + tess.addVertexWithUV(+0.5, posEnd, +depth, xMin[i], iconPos); + tess.addVertexWithUV(+0.5, posEnd, -depth, xMin[i], iconPos); + tess.addVertexWithUV(-0.5, posEnd, -depth, xMax[i], iconPos); + } + } + + tess.draw(); + tess.startDrawingQuads(); + tess.setNormal(0, -1, 0); + + for (int i = 0; i < iconParts; ++i) + { + tess.setColorOpaque_I(color[i]); + float h = height[i], m = yMax[i], d = yDiff[i], s = ySub[i]; + for (int k = 0, e = (int)h; k < e; ++k) + { + pos = k / h; + iconPos = m + d * pos - s; + pos -= 0.5f; + tess.addVertexWithUV(+0.5, pos, +depth, xMin[i], iconPos); + tess.addVertexWithUV(-0.5, pos, +depth, xMax[i], iconPos); + tess.addVertexWithUV(-0.5, pos, -depth, xMax[i], iconPos); + tess.addVertexWithUV(+0.5, pos, -depth, xMin[i], iconPos); + } + } + + tess.draw(); + GL11.glDisable(GL12.GL_RESCALE_NORMAL); + GL11.glPopMatrix(); + } + + public void renderInventory(int count, IIcon[] icons, ItemStack item) + { + Tessellator tess = Tessellator.instance; + GL11.glPushMatrix(); + + GL11.glDisable(GL11.GL_LIGHTING); + GL11.glEnable(GL11.GL_ALPHA_TEST); + GL11.glAlphaFunc(GL11.GL_GREATER, 0.5F); + GL11.glDisable(GL11.GL_BLEND); + + tess.startDrawingQuads(); + + // draw a simple rectangle for the inventory icon + for (int i = 0; i < count; ++i) + { + tess.setColorOpaque_I(item.getItem().getColorFromItemStack(item, i)); + + final IIcon icon = icons[i]; + final float xmin = icon.getMinU(); + final float xmax = icon.getMaxU(); + final float ymin = icon.getMinV(); + final float ymax = icon.getMaxV(); + tess.addVertexWithUV( 0, 16, 0, xmin, ymax); + tess.addVertexWithUV(16, 16, 0, xmax, ymax); + tess.addVertexWithUV(16, 0, 0, xmax, ymin); + tess.addVertexWithUV( 0, 0, 0, xmin, ymin); + } + tess.draw(); + + GL11.glEnable(GL11.GL_BLEND); + GL11.glDisable(GL11.GL_ALPHA_TEST); + GL11.glEnable(GL11.GL_LIGHTING); + GL11.glPopMatrix(); + } + + public int getIcons(ItemStack item, ItemRenderType type, Entity ent, IIcon[] parts) + { + int iconParts = toolIcons;//tool.getRenderPasses(item.getItemDamage()); + // TODO: have the tools define how many render passes they have + // (requires more logic rewrite than it sounds like) + + boolean isInventory = type == ItemRenderType.INVENTORY; + ToolCore tool = (ToolCore) item.getItem(); + + IIcon[] tempParts = new IIcon[iconParts]; + label: + { + if (!isInventory && ent instanceof EntityPlayer) + { + EntityPlayer player = (EntityPlayer) ent; + ItemStack itemInUse = player.getItemInUse(); + if (itemInUse != null) + { + int useCount = player.getItemInUseCount(); + for (int i = iconParts; i-- > 0;) + tempParts[i] = tool.getIcon(item, i, player, itemInUse, useCount); + break label; + } + } + for (int i = iconParts; i-- > 0;) + tempParts[i] = tool.getIcon(item, i); + } + + int count = 0; + for (int i = 0; i < iconParts; ++i) + { + IIcon part = tempParts[i]; + if (part == null || part == ToolCore.blankSprite || part == ToolCore.emptyIcon) + ++count; + else + parts[i - count] = part; + } + iconParts -= count; + + if (iconParts <= 0) + { + iconParts = 1; + parts[0] = ToolCore.blankSprite; + } + + return iconParts; + } +} diff --git a/src/main/java/tconstruct/weaponry/client/renderer/JavelinRenderer.java b/src/main/java/tconstruct/weaponry/client/renderer/JavelinRenderer.java new file mode 100644 index 00000000..966262d0 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/client/renderer/JavelinRenderer.java @@ -0,0 +1,24 @@ +package boni.tinkersweaponry.client.renderer; + +import boni.tinkersweaponry.library.weaponry.IWindup; +import net.minecraft.client.Minecraft; +import net.minecraft.item.ItemStack; +import org.lwjgl.opengl.GL11; + +public class JavelinRenderer extends AmmoItemRenderer { + + @Override + protected void specialAnimation(ItemRenderType type, ItemStack item) { + float progress = ((IWindup)item.getItem()).getWindupProgress(item, Minecraft.getMinecraft().thePlayer); // 0.5 while not winding + + if(type == ItemRenderType.EQUIPPED) + GL11.glRotatef(90, 0, 0, 1); + + GL11.glRotatef(-45, 0, 0, 1); + GL11.glScalef(1.5F, 2F, 1.5F); + + if(type == ItemRenderType.EQUIPPED_FIRST_PERSON) + GL11.glTranslatef(0, progress * 0.4f, 0); + GL11.glRotatef(45, 0, 0, 1); + } +} diff --git a/src/main/java/tconstruct/weaponry/client/renderer/ThrowingKnifeRenderer.java b/src/main/java/tconstruct/weaponry/client/renderer/ThrowingKnifeRenderer.java new file mode 100644 index 00000000..feb40f6d --- /dev/null +++ b/src/main/java/tconstruct/weaponry/client/renderer/ThrowingKnifeRenderer.java @@ -0,0 +1,68 @@ +package boni.tinkersweaponry.client.renderer; + +import boni.tinkersweaponry.library.weaponry.IWindup; +import net.minecraft.client.Minecraft; +import net.minecraft.client.renderer.entity.RenderManager; +import net.minecraft.client.renderer.entity.RenderPlayer; +import net.minecraft.client.renderer.texture.TextureMap; +import net.minecraft.item.ItemStack; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL12; + +public class ThrowingKnifeRenderer extends AmmoItemRenderer { + private static Minecraft mc = Minecraft.getMinecraft(); + + @Override + protected void specialAnimation(ItemRenderType type, ItemStack item) { + float progress = ((IWindup)item.getItem()).getWindupProgress(item, mc.thePlayer); + + if(type == ItemRenderType.EQUIPPED_FIRST_PERSON) { + GL11.glPushMatrix(); + GL11.glScalef(2.5f, 2.5f, 2.5f); + // rotate it, otherwise it's drawn over our item :( + GL11.glTranslatef(0.5f, -0.6f, 0f); + //GL11.glRotatef(90.0F, 0.0F, 1.0F, 0.0F); + //GL11.glRotatef(-85.0F, 0.0F, 0.0F, 1.0F); + + GL11.glRotatef(-25.0F, 0.0F, 0.0F, 1.0F); + + GL11.glRotatef(progress * 35.0F, 0.0F, 0.0F, 1.0F); + + GL11.glEnable(GL12.GL_RESCALE_NORMAL); + mc.getTextureManager().bindTexture(mc.thePlayer.getLocationSkin()); + RenderPlayer plrRender = (RenderPlayer) RenderManager.instance.getEntityRenderObject(mc.thePlayer); + plrRender.renderFirstPersonArm(mc.thePlayer); + + GL11.glPopMatrix(); + mc.getTextureManager().bindTexture(TextureMap.locationItemsTexture); + + // rotate it aroooound + //GL11.glRotatef(-180, 0, 0, 1); + //GL11.glTranslatef(0.5f, -0.6f, 0f); + //GL11.glRotatef(-25.0F, 0.0F, 0.0F, 1.0F); + + GL11.glTranslatef(1.3f, 0.4f, -0.2f); + + //GL11.glTranslatef(-0.5f, 0.6f, 0f); + //GL11.glTranslatef(0.f, 1f, 0f); + //GL11.glTranslatef(progress * -1.5f, 0.0f, 0f); + GL11.glTranslatef(0.0f, -1.85f, 0f); + GL11.glRotatef(progress * 35.0F, 0.0F, 0.0F, 1.0F); + GL11.glTranslatef(0.0f, 1.85f, 0f); + GL11.glRotatef(progress * -15.0F, 0.0F, 0.0F, 1.0F); + //GL11.glTranslatef(-0.f, -1f, 0f); + //GL11.glTranslatef(0.5f, -0.6f, 0f); + + + GL11.glScalef(1.5f, 1.5f, 1.5f); + + GL11.glRotatef(-180, 0, 0, 1); + GL11.glTranslatef(0.5f, -0.6f, 0f); + GL11.glRotatef(-25.0F, 0.0F, 0.0F, 1.0F); + } + + if(type == ItemRenderType.EQUIPPED) + GL11.glRotatef(-180, 0, 0, 1); + + } +} diff --git a/src/main/java/tconstruct/weaponry/entity/ArrowEntity.java b/src/main/java/tconstruct/weaponry/entity/ArrowEntity.java new file mode 100644 index 00000000..477d042e --- /dev/null +++ b/src/main/java/tconstruct/weaponry/entity/ArrowEntity.java @@ -0,0 +1,103 @@ +package boni.tinkersweaponry.entity; + +import boni.tinkersweaponry.library.util.PiercingArrowDamage; +import cpw.mods.fml.common.network.ByteBufUtils; +import io.netty.buffer.ByteBuf; +import net.minecraft.client.Minecraft; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.DamageSource; +import net.minecraft.util.MovingObjectPosition; +import net.minecraft.world.World; +import tconstruct.TConstruct; +import tconstruct.library.tools.AbilityHelper; +import tconstruct.library.tools.ToolCore; + +public class ArrowEntity extends ProjectileBase { + public ArrowEntity(World world) { + super(world); + } + + public ArrowEntity(World world, double d, double d1, double d2) { + super(world, d, d1, d2); + } + + public ArrowEntity(World world, EntityPlayer player, float speed, float accuracy, ItemStack stack) { + super(world, player, speed, accuracy, stack); + } + + @Override + protected double getStuckDepth() { + return 0.25d; + } + + @Override + protected double getSlowdown() { + // todo: fletchling material of arrows impact + return super.getSlowdown(); + } + + @Override + protected double getGravity() { + float mass = returnStack.getTagCompound().getCompoundTag("InfiTool").getFloat("Mass"); + mass /= 36f; // why 36? simple because it's roughly 0.05 with flint head and wooden arrow shaft! Yes, that's the only reason. + return mass; + } + + @Override + public void onHitBlock(MovingObjectPosition movingobjectposition) { + super.onHitBlock(movingobjectposition); + + // we might break! oh noez! + float chance = returnStack.getTagCompound().getCompoundTag("InfiTool").getFloat("BreakChance"); + if(chance > TConstruct.random.nextFloat()) + this.setDead(); + } + + @Override + protected void playHitBlockSound(int x, int y, int z) { + this.playSound("random.bowhit", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); + } + + @Override + protected void playHitEntitySound() { + this.playSound("random.bowhit", 1.0F, 1.2F / (this.rand.nextFloat() * 0.2F + 0.9F)); + } + + // returns true if it was successful + @Override + public boolean dealDamage(float damage, ToolCore ammo, NBTTagCompound tags, Entity entityHit) + { + boolean dealtDamage; + + //Minecraft.getMinecraft().thePlayer.sendChatMessage("Damage/Weight: " + damage + " - " + tags.getFloat("Mass")); + + // we take the weight, and shift the damage done towards armor piercing, the more weight the arrow/bolt has! + float shift = (tags.getFloat("Mass") - 0.7f); + + if(shift < 0) + shift = 0; + if(shift > damage) + shift = damage; + + // deal regular damage + dealtDamage = super.dealDamage(damage-shift, ammo, tags, entityHit); + + // deal armor piercing damage + if(shift > 0) { + DamageSource damagesource; + if (this.shootingEntity == null) + damagesource = new PiercingArrowDamage("arrow", this, this); + else + damagesource = new PiercingArrowDamage("arrow", this, this.shootingEntity); + + //Minecraft.getMinecraft().thePlayer.sendChatMessage("Piercing Damage: " + shift); + + dealtDamage |= entityHit.attackEntityFrom(damagesource, shift); + } + + return dealtDamage; + } +} diff --git a/src/main/java/tconstruct/weaponry/entity/BoltEntity.java b/src/main/java/tconstruct/weaponry/entity/BoltEntity.java new file mode 100644 index 00000000..1e4759ce --- /dev/null +++ b/src/main/java/tconstruct/weaponry/entity/BoltEntity.java @@ -0,0 +1,27 @@ +package boni.tinkersweaponry.entity; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +public class BoltEntity extends ArrowEntity { + public BoltEntity(World world) { + super(world); + this.setSize(0.3f, 0.3f); + } + + public BoltEntity(World world, double d, double d1, double d2) { + super(world, d, d1, d2); + this.setSize(0.3f, 0.3f); + } + + public BoltEntity(World world, EntityPlayer player, float speed, float accuracy, ItemStack stack) { + super(world, player, speed, accuracy, stack); + this.setSize(0.3f, 0.3f); + } + + @Override + protected void playHitBlockSound(int x, int y, int z) { + this.playSound("random.bowhit", 1.0F, 1.0F); + } +} diff --git a/src/main/java/tconstruct/weaponry/entity/JavelinEntity.java b/src/main/java/tconstruct/weaponry/entity/JavelinEntity.java new file mode 100644 index 00000000..3badab8c --- /dev/null +++ b/src/main/java/tconstruct/weaponry/entity/JavelinEntity.java @@ -0,0 +1,47 @@ +package boni.tinkersweaponry.entity; + +import boni.tinkersweaponry.TinkerWeaponry; +import io.netty.buffer.ByteBuf; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +public class JavelinEntity extends ProjectileBase { + public int roll = 0; + + public JavelinEntity(World world) { + super(world); + } + + public JavelinEntity(World world, double d, double d1, double d2) { + super(world, d, d1, d2); + } + + public JavelinEntity(World world, EntityPlayer player, float speed, float accuracy, ItemStack stack) { + super(world, player, speed, accuracy, stack); + } + + @Override + public void onUpdate() { + // you turn me right round baby + if(this.ticksInGround == 0) + roll = (roll + 13) % 360; + + super.onUpdate(); + } + + @Override + public void readSpawnData(ByteBuf data) { + super.readSpawnData(data); + + // this is only relevant clientside only, so we don't actually have it on the server + roll = TinkerWeaponry.random.nextInt(360); + } + + protected double getGravity() { return 0.07; } + + @Override + protected double getStuckDepth() { + return 0.5f; + } +} diff --git a/src/main/java/tconstruct/weaponry/entity/ProjectileBase.java b/src/main/java/tconstruct/weaponry/entity/ProjectileBase.java new file mode 100644 index 00000000..0adb84e8 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/entity/ProjectileBase.java @@ -0,0 +1,627 @@ +package boni.tinkersweaponry.entity; + +import boni.tinkersweaponry.library.weaponry.AmmoItem; +import boni.tinkersweaponry.util.Reference; +import cpw.mods.fml.common.network.ByteBufUtils; +import cpw.mods.fml.common.registry.IEntityAdditionalSpawnData; +import io.netty.buffer.ByteBuf; +import net.minecraft.block.Block; +import net.minecraft.block.material.Material; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.monster.EntityEnderman; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.entity.projectile.EntityArrow; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.network.play.server.S2BPacketChangeGameState; +import net.minecraft.util.*; +import net.minecraft.world.World; +import tconstruct.library.ActiveToolMod; +import tconstruct.library.TConstructRegistry; +import tconstruct.library.tools.AbilityHelper; +import tconstruct.library.tools.ToolCore; + +import java.util.List; + +// have to base this on EntityArrow, otherwise minecraft does derp things because everything is handled based on class. +public abstract class ProjectileBase extends EntityArrow implements IEntityAdditionalSpawnData { + public final static String woodSound = Reference.resource("woodHit"); + public final static String stoneSound = Reference.resource("stoneHit"); + + public ItemStack returnStack; + public int returnStackSlot; + + public boolean bounceOnNoDamage = true; + + public ProjectileBase(World world) { + super(world); + } + + public ProjectileBase(World world, double d, double d1, double d2) { + this(world); + this.setPosition(d, d1, d2); + } + + public ProjectileBase(World world, EntityPlayer player, float speed, float accuracy, ItemStack stack) { + this(world); + + this.shootingEntity = player; + + canBePickedUp = 1; + + // stuff from the arrow + this.setLocationAndAngles(player.posX, player.posY + (double)player.getEyeHeight(), player.posZ, player.rotationYaw, player.rotationPitch); + this.posX -= MathHelper.cos(this.rotationYaw / 180.0F * (float)Math.PI) * 0.16F; + this.posY -= 0.10000000149011612D; + this.posZ -= MathHelper.sin(this.rotationYaw / 180.0F * (float)Math.PI) * 0.16F; + this.setPosition(this.posX, this.posY, this.posZ); + this.yOffset = 0.0F; + this.motionX = -MathHelper.sin(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float)Math.PI); + this.motionZ = +MathHelper.cos(this.rotationYaw / 180.0F * (float)Math.PI) * MathHelper.cos(this.rotationPitch / 180.0F * (float)Math.PI); + this.motionY = -MathHelper.sin(this.rotationPitch / 180.0F * (float)Math.PI); + this.setThrowableHeading(this.motionX, this.motionY, this.motionZ, speed, accuracy); + + // our stuff + returnStackSlot = player.inventory.currentItem; + returnStack = stack; + +/* + // fix upward default angle + motionY = -MathHelper.sin((rotationPitch / 180F) * 3.141593F - 0.2f); + setArrowHeading(motionX, motionY, motionZ, speed, 0.0f); + + // set better position and move it a tad so we don't hit ourselves. + this.setPosition(player.posX, player.posY + player.getEyeHeight(), player.posZ); + */ + /* + double l = Math.sqrt(motionX*motionX + motionY*motionY + motionZ*motionZ); + double vx = motionX/l; + double vy = motionY/l; + double vz = motionZ/l; + + posX += vx*1.5f; + posY += vy*1.5f; + posZ += vz*1.5f; + */ + + //init(); + } + + public ItemStack getEntityItem () + { + return returnStack; + } + + protected void playHitBlockSound(int x, int y, int z) + { + Block block = worldObj.getBlock(x,y,z); + if(block != null && block.blockMaterial == Material.wood) + worldObj.playSoundAtEntity(this, woodSound, 1.0f, 1.0f); + else { + worldObj.playSoundAtEntity(this, stoneSound, 1.0f, 1.0f); + } + + if(block != null) + worldObj.playSoundAtEntity(this, block.stepSound.getBreakSound(), 0.7f, 1.0f); + } + + protected void playHitEntitySound() + { + + } + + /** + * How deep the item enters stuff it hits. Should be bigger for bigger objects, and smaller for smaller objects. + * 1.0f is exactly halfway in. + */ + protected double getStuckDepth() { return 0.5f; } + + protected void doLivingHit(EntityLivingBase entityHit) + { + if (!this.worldObj.isRemote) + { + entityHit.setArrowCountInEntity(entityHit.getArrowCountInEntity() + 1); + } + + if (this.knockbackStrength > 0) + { + double horizontalSpeed = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + + if (horizontalSpeed > 0.0F) + { + entityHit.addVelocity(this.motionX * (double) this.knockbackStrength * 0.6000000238418579D / (double) horizontalSpeed, 0.1D, this.motionZ * (double) this.knockbackStrength * 0.6000000238418579D / (double) horizontalSpeed); + } + } + + if (this.shootingEntity != null && this.shootingEntity instanceof EntityLivingBase) + { + EnchantmentHelper.func_151384_a(entityHit, this.shootingEntity); + EnchantmentHelper.func_151385_b((EntityLivingBase)this.shootingEntity, entityHit); + } + + if (this.shootingEntity != null && entityHit != this.shootingEntity && entityHit instanceof EntityPlayer && this.shootingEntity instanceof EntityPlayerMP) + { + ((EntityPlayerMP)this.shootingEntity).playerNetServerHandler.sendPacket(new S2BPacketChangeGameState(6, 0.0F)); + } + } + + public void onHitBlock(MovingObjectPosition movingobjectposition) { + this.field_145791_d = movingobjectposition.blockX; + this.field_145792_e = movingobjectposition.blockY; + this.field_145789_f = movingobjectposition.blockZ; + this.field_145790_g = this.worldObj.getBlock(this.field_145791_d, this.field_145792_e, this.field_145789_f); + this.inData = this.worldObj.getBlockMetadata(this.field_145791_d, this.field_145792_e, this.field_145789_f); + this.motionX = movingobjectposition.hitVec.xCoord - this.posX; + this.motionY = movingobjectposition.hitVec.yCoord - this.posY; + this.motionZ = movingobjectposition.hitVec.zCoord - this.posZ; + double speed = getStuckDepth() * MathHelper.sqrt_double(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ); + this.posX -= this.motionX / speed * 0.05000000074505806D; + this.posY -= this.motionY / speed * 0.05000000074505806D; + this.posZ -= this.motionZ / speed * 0.05000000074505806D; + + playHitBlockSound(movingobjectposition.blockX, movingobjectposition.blockY, movingobjectposition.blockZ); + + this.inGround = true; + this.arrowShake = 7; + this.setIsCritical(false); + + if (this.field_145790_g.getMaterial() != Material.air) + { + this.field_145790_g.onEntityCollidedWithBlock(this.worldObj, this.field_145791_d, this.field_145792_e, this.field_145789_f, this); + } + } + + public void onHitEntity(MovingObjectPosition movingobjectposition) { + NBTTagCompound tags = returnStack.getTagCompound().getCompoundTag("InfiTool"); + double speed = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ); + int damage = MathHelper.ceiling_double_int(speed * tags.getInteger("Attack")); + + // Damage calculations and stuff. For reference see AbilityHelper.onLeftClickEntity + ToolCore ammo = (ToolCore)returnStack.getItem(); + + // factor in modified stuff for base damage + // basically we pass the base damage to all modifiers and take the highest one + int baseDamage = 0; + for(ActiveToolMod toolmod : TConstructRegistry.activeModifiers) { + int dmg = toolmod.baseAttackDamage(baseDamage, damage, ammo, returnStack.getTagCompound(), tags, returnStack, (EntityPlayer)this.shootingEntity, movingobjectposition.entityHit); + if(dmg > baseDamage) + baseDamage = dmg; + } + damage += baseDamage; + + // damage modification from the weapon itself + damage *= ammo.getDamageModifier(); + + // unlike the regular weapons, we do no gain more damage from potion of strength/weakness since we don't hit stuff directly + + // stonebound decreases, jagged increases damage too + float bonusDamage = -AbilityHelper.calcStoneboundBonus(ammo, tags); + // enchantments might add too + if(shootingEntity != null) + bonusDamage += EnchantmentHelper.getEnchantmentModifierLiving((EntityLivingBase)this.shootingEntity, (EntityLivingBase)movingobjectposition.entityHit); + damage += bonusDamage; + + // ensure we still have damage + if(damage < 1) + damage = 1; + + // the regular tool modifier damage stuff + int modDamage = 0; + for (ActiveToolMod mod : TConstructRegistry.activeModifiers) + { + modDamage += mod.attackDamage(modDamage, damage, ammo, returnStack.getTagCompound(), tags, returnStack, (EntityPlayer)this.shootingEntity, movingobjectposition.entityHit); + } + damage += modDamage; + + // calculate critical damaaage + if (this.getIsCritical()) + damage += this.rand.nextInt(damage / 2 + 2); + + // and now we come to the part where we actually deal the damage! + if(!dealDamage(damage, ammo, tags, movingobjectposition.entityHit)) + { + if(!bounceOnNoDamage) + this.setDead(); + + // bounce off if we didn't deal damage + this.motionX *= -0.10000000149011612D; + this.motionY *= -0.10000000149011612D; + this.motionZ *= -0.10000000149011612D; + this.rotationYaw += 180.0F; + this.prevRotationYaw += 180.0F; + this.ticksInAir = 0; + return; + } + + + if (movingobjectposition.entityHit instanceof EntityLivingBase) + doLivingHit((EntityLivingBase)movingobjectposition.entityHit); + + playHitEntitySound(); + + if (!(movingobjectposition.entityHit instanceof EntityEnderman)) + { + this.setDead(); + } + } + + // returns true if it was successful + public boolean dealDamage(float damage, ToolCore ammo, NBTTagCompound tags, Entity entityHit) + { + boolean dealtDamage = false; + + // deal regular damage + DamageSource damagesource; + if (this.shootingEntity == null) + damagesource = DamageSource.causeArrowDamage(this, this); + else + damagesource = DamageSource.causeArrowDamage(this, this.shootingEntity); + dealtDamage = entityHit.attackEntityFrom(damagesource, damage); + + return dealtDamage; + } + + @Override + // this function is the same as the vanilla EntityArrow + public void onUpdate() { + // call the entity update routine + // luckily we can call this directly and take the arrow-code, since we'd have to call super.onUpdate otherwise. Which would not work. + onEntityUpdate(); + + // boioioiooioing + if (this.arrowShake > 0) + --this.arrowShake; + + // If we don't have our rotation set correctly, infer it from our motion direction + if (this.prevRotationPitch == 0.0F && this.prevRotationYaw == 0.0F) + { + float f = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + this.prevRotationYaw = this.rotationYaw = (float)(Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI); + this.prevRotationPitch = this.rotationPitch = (float)(Math.atan2(this.motionY, (double)f) * 180.0D / Math.PI); + } + + // we previously hit something. Check if the block is still there. + Block block = this.worldObj.getBlock(this.field_145791_d, this.field_145792_e, this.field_145789_f); + if (block.getMaterial() != Material.air) + { + block.setBlockBoundsBasedOnState(this.worldObj, this.field_145791_d, this.field_145792_e, this.field_145789_f); + AxisAlignedBB axisalignedbb = block.getCollisionBoundingBoxFromPool(this.worldObj, this.field_145791_d, this.field_145792_e, this.field_145789_f); + + // we are stuck in a block. yay. + if (axisalignedbb != null && axisalignedbb.isVecInside(Vec3.createVectorHelper(this.posX, this.posY, this.posZ))) + this.inGround = true; + } + + if (this.inGround) + updateInGround(); + else + updateInAir(); + } + + // Update while we're stuck in a block + protected void updateInGround() + { + Block block = this.worldObj.getBlock(this.field_145791_d, this.field_145792_e, this.field_145789_f); + int j = this.worldObj.getBlockMetadata(this.field_145791_d, this.field_145792_e, this.field_145789_f); + + // check if it's still the same block + if (block == this.field_145790_g && j == this.inData) + { + ++this.ticksInGround; + + if (this.ticksInGround == 1200) + { + this.setDead(); + } + } + else + { + this.inGround = false; + this.motionX *= (double)(this.rand.nextFloat() * 0.2F); + this.motionY *= (double)(this.rand.nextFloat() * 0.2F); + this.motionZ *= (double)(this.rand.nextFloat() * 0.2F); + this.ticksInGround = 0; + this.ticksInAir = 0; + } + } + + // update while traveling + protected void updateInAir() + { + // tick tock + ++this.ticksInAir; + + // do a raytrace from old to new position + Vec3 curPos = Vec3.createVectorHelper(this.posX, this.posY, this.posZ); + Vec3 newPos = Vec3.createVectorHelper(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); + MovingObjectPosition movingobjectposition = this.worldObj.func_147447_a(curPos, newPos, false, true, false); + + // raytrace messes with the positions. get new ones! + curPos = Vec3.createVectorHelper(this.posX, this.posY, this.posZ); + + // if we hit something, the collision point is our new position + if (movingobjectposition != null) + newPos = Vec3.createVectorHelper(movingobjectposition.hitVec.xCoord, movingobjectposition.hitVec.yCoord, movingobjectposition.hitVec.zCoord); + else + newPos = Vec3.createVectorHelper(this.posX + this.motionX, this.posY + this.motionY, this.posZ + this.motionZ); + + + // Check all the entities we on our way + Entity entity = null; + List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.addCoord(this.motionX, this.motionY, this.motionZ).expand(1.0D, 1.0D, 1.0D)); + double distance = 0.0D; + float f1; + + for(Entity ent : list) + { + if(!ent.canBeCollidedWith()) + continue; + // we don't shoot ourselves into the foot. + if(ent == this.shootingEntity && this.ticksInAir < 5) + continue; + + f1 = 0.3F; + AxisAlignedBB axisalignedbb1 = ent.boundingBox.expand((double)f1, (double)f1, (double)f1); + MovingObjectPosition movingobjectposition1 = axisalignedbb1.calculateIntercept(curPos, newPos); + + // did we actually collide with the entity, or was it just really close nearby? + if (movingobjectposition1 != null) + { + // check if this entity is closer than the other one we already hit + double otherDistance = curPos.distanceTo(movingobjectposition1.hitVec); + + if (otherDistance < distance || distance == 0.0D) + { + entity = ent; + distance = otherDistance; + } + } + } + + // if we hit something, new collision point! + if (entity != null) + movingobjectposition = new MovingObjectPosition(entity); + + // did we hit a player? + if (movingobjectposition != null && movingobjectposition.entityHit != null && movingobjectposition.entityHit instanceof EntityPlayer) + { + EntityPlayer entityplayer = (EntityPlayer)movingobjectposition.entityHit; + + // can we attack said player? + if (entityplayer.capabilities.disableDamage || this.shootingEntity instanceof EntityPlayer && !((EntityPlayer)this.shootingEntity).canAttackPlayer(entityplayer)) + movingobjectposition = null; + + // this check should probably done inside of the loop for accuracy.. + } + + + // time to hit the object + if (movingobjectposition != null) + { + if (movingobjectposition.entityHit != null) + onHitEntity(movingobjectposition); + else + onHitBlock(movingobjectposition); + } + + // crithit particles + if (this.getIsCritical()) + drawCritParticles(); + + // MOVEMENT! yay. + doMoveUpdate(); + double slowdown = 1.0d - getSlowdown(); + + // bubblez + if (this.isInWater()) + { + for (int l = 0; l < 4; ++l) + { + float f4 = 0.25F; + this.worldObj.spawnParticle("bubble", this.posX - this.motionX * (double)f4, this.posY - this.motionY * (double)f4, this.posZ - this.motionZ * (double)f4, this.motionX, this.motionY, this.motionZ); + } + + // more slowdown in water + slowdown = 1d - 20d*getSlowdown(); + } + + // phshshshshshs + if (this.isWet()) + this.extinguish(); + + // minimalistic slowdown! + this.motionX *= slowdown; + this.motionY *= slowdown; + this.motionZ *= slowdown; + // gravity + this.motionY -= getGravity(); + this.setPosition(this.posX, this.posY, this.posZ); + + // tell blocks we collided with, that we collided with them! + this.func_145775_I(); + } + + public void drawCritParticles() + { + for (int i = 0; i < 4; ++i) + { + this.worldObj.spawnParticle("crit", this.posX + this.motionX * (double)i / 4.0D, this.posY + this.motionY * (double)i / 4.0D, this.posZ + this.motionZ * (double)i / 4.0D, -this.motionX, -this.motionY + 0.2D, -this.motionZ); + } + } + + protected void doMoveUpdate() + { + this.posX += this.motionX; + this.posY += this.motionY; + this.posZ += this.motionZ; + double f2 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); + this.rotationYaw = (float)(Math.atan2(this.motionX, this.motionZ) * 180.0D / Math.PI); + this.rotationPitch = (float)(Math.atan2(this.motionY, f2) * 180.0D / Math.PI); + + // normalize rotations + while (this.rotationPitch - this.prevRotationPitch < -180.0F) + this.prevRotationPitch -= 360.0F; + + while (this.rotationPitch - this.prevRotationPitch >= 180.0F) + this.prevRotationPitch += 360.0F; + + while (this.rotationYaw - this.prevRotationYaw < -180.0F) + this.prevRotationYaw -= 360.0F; + + while (this.rotationYaw - this.prevRotationYaw >= 180.0F) + this.prevRotationYaw += 360.0F; + + this.rotationPitch = this.prevRotationPitch + (this.rotationPitch - this.prevRotationPitch) * 0.2F; + this.rotationYaw = this.prevRotationYaw + (this.rotationYaw - this.prevRotationYaw) * 0.2F; + } + + /** + * Factor for the slowdown. 0 = no slowdown, >0 = (1-slowdown)*speed slowdown, <0 = speedup + */ + protected double getSlowdown() { return 0.01; } + + /** + * Added to the y-velocity as gravitational pull. Otherwise stuff would simply float midair. + */ + protected double getGravity() { return 0.05; } + + /** + * Called by a player entity when they collide with an entity + */ + public void onCollideWithPlayer(EntityPlayer player) + { + if (!this.worldObj.isRemote && this.inGround && this.arrowShake <= 0) + { + boolean flag = this.canBePickedUp == 1 || this.canBePickedUp == 2 && player.capabilities.isCreativeMode; + + if (this.canBePickedUp == 1) + { + // ammo pickup + if(this.returnStack != null && this.returnStack.getItem() instanceof AmmoItem) + { + if(!((AmmoItem) this.returnStack.getItem()).pickupAmmo(returnStack, null, player)) + flag = false; + } + // regular pickup. + // Note that you can't pick up ammo items without the proper itemstack in your inventory to prevent dupes + else if(!player.inventory.addItemStackToInventory(new ItemStack(Items.arrow, 1))) + { + flag = false; + } + } + + if (flag) + { + this.playSound("random.pop", 0.2F, ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.0F) * 2.0F); + player.onItemPickup(this, 1); + this.setDead(); + } + } + } + + + /** NBT stuff **/ + + @Override + public void writeEntityToNBT (NBTTagCompound tags) + { + super.writeEntityToNBT(tags); + + tags.setTag("Throwable", this.returnStack.writeToNBT(new NBTTagCompound())); + tags.setByte("onGround", (byte) (onGround ? 1 : 0)); + //tags.setBoolean("Retrieval", doNotRetrieve); + } + + @Override + public void readEntityFromNBT(NBTTagCompound tags) { + super.readEntityFromNBT(tags); + + this.returnStack = ItemStack.loadItemStackFromNBT(tags.getCompoundTag("Throwable")); + onGround = tags.getByte("onGround") == 1; + //doNotRetrieve = tags.getBoolean("Retrieval"); + } + + @Override + public void writeSpawnData(ByteBuf data) { + NBTTagCompound tags = returnStack.getTagCompound().getCompoundTag("InfiTool"); + ByteBufUtils.writeItemStack(data, returnStack); + data.writeFloat(rotationYaw); + /* + data.writeInt(tags.getInteger("RenderHandle")); + data.writeInt(tags.getInteger("RenderHead")); + data.writeInt(tags.getInteger("RenderAccessory")); + data.writeInt(tags.getInteger("RenderExtra")); + + int effects = 0; + if (tags.hasKey("Effect1")) + effects++; + if (tags.hasKey("Effect2")) + effects++; + if (tags.hasKey("Effect3")) + effects++; + if (tags.hasKey("Effect4")) + effects++; + if (tags.hasKey("Effect5")) + effects++; + if (tags.hasKey("Effect6")) + effects++; + data.writeInt(effects); + + switch (effects) + { + case 6: + data.writeInt(tags.getInteger("Effect6")); + case 5: + data.writeInt(tags.getInteger("Effect5")); + case 4: + data.writeInt(tags.getInteger("Effect4")); + case 3: + data.writeInt(tags.getInteger("Effect3")); + case 2: + data.writeInt(tags.getInteger("Effect2")); + case 1: + data.writeInt(tags.getInteger("Effect1")); + } +*/ + // shooting entity + int id = shootingEntity == null ? this.getEntityId() : shootingEntity.getEntityId(); + data.writeInt(id); + } + + @Override + public void readSpawnData(ByteBuf data) { + returnStack = ByteBufUtils.readItemStack(data); + rotationYaw = data.readFloat(); + /* + NBTTagCompound compound = new NBTTagCompound(); + NBTTagCompound toolTag = new NBTTagCompound(); + toolTag.setInteger("RenderHandle", data.readInt()); + toolTag.setInteger("RenderHead", data.readInt()); + toolTag.setInteger("RenderAccessory", data.readInt()); + toolTag.setInteger("RenderExtra", data.readInt()); + + switch (data.readInt()) + { + case 6: + toolTag.setInteger("Effect6", data.readInt()); + case 5: + toolTag.setInteger("Effect5", data.readInt()); + case 4: + toolTag.setInteger("Effect4", data.readInt()); + case 3: + toolTag.setInteger("Effect3", data.readInt()); + case 2: + toolTag.setInteger("Effect2", data.readInt()); + case 1: + toolTag.setInteger("Effect1", data.readInt()); + } + compound.setTag("InfiTool", toolTag); + returnStack.setTagCompound(compound); +*/ + shootingEntity = worldObj.getEntityByID(data.readInt()); + } +} diff --git a/src/main/java/tconstruct/weaponry/entity/ShurikenEntity.java b/src/main/java/tconstruct/weaponry/entity/ShurikenEntity.java new file mode 100644 index 00000000..46af84cb --- /dev/null +++ b/src/main/java/tconstruct/weaponry/entity/ShurikenEntity.java @@ -0,0 +1,58 @@ +package boni.tinkersweaponry.entity; + +import boni.tinkersweaponry.TinkerWeaponry; +import io.netty.buffer.ByteBuf; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +public class ShurikenEntity extends ProjectileBase { + public int spin = 0; + public int rollAngle = 0; + + public ShurikenEntity(World world) { + super(world); + setSize(0.3f, 0.1f); + this.bounceOnNoDamage = false; + } + + public ShurikenEntity(World world, double d, double d1, double d2) { + super(world, d, d1, d2); + setSize(0.3f, 0.1f); + this.bounceOnNoDamage = false; + } + + public ShurikenEntity(World world, EntityPlayer player, float speed, float accuracy, ItemStack stack) { + super(world, player, speed, accuracy, stack); + setSize(0.3f, 0.1f); + this.bounceOnNoDamage = false; + } + + @Override + public void onUpdate() { + // you turn me right round baby + if(this.ticksInGround == 0) + spin = (spin + 33) % 360; + + super.onUpdate(); + } + + @Override + public void readSpawnData(ByteBuf data) { + super.readSpawnData(data); + + // this is only relevant clientside only, so we don't actually have it on the server + rollAngle = (TinkerWeaponry.random.nextInt(3)-1)*45 + TinkerWeaponry.random.nextInt(30)-15; + spin = TinkerWeaponry.random.nextInt(360); + } + + @Override + protected double getGravity() { + return (this.ticksExisted/8) * 0.018d; // integer division. so the first 20 ticks it will have no gravity at all. + } + + @Override + protected double getStuckDepth() { + return 0.8d; + } +} diff --git a/src/main/java/tconstruct/weaponry/entity/ThrowingKnifeEntity.java b/src/main/java/tconstruct/weaponry/entity/ThrowingKnifeEntity.java new file mode 100644 index 00000000..70cd9523 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/entity/ThrowingKnifeEntity.java @@ -0,0 +1,25 @@ +package boni.tinkersweaponry.entity; + +import boni.tinkersweaponry.TinkerWeaponry; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +public class ThrowingKnifeEntity extends ProjectileBase { + public ThrowingKnifeEntity(World world) { + super(world); + } + + public ThrowingKnifeEntity(World world, double d, double d1, double d2) { + super(world, d, d1, d2); + } + + public ThrowingKnifeEntity(World world, EntityPlayer player, float speed, float accuracy, ItemStack stack) { + super(world, player, speed, accuracy, stack); + } + + @Override + protected double getStuckDepth() { + return 0.3d + TinkerWeaponry.random.nextDouble(); + } +} diff --git a/src/main/java/tconstruct/weaponry/items/CustomToolPart.java b/src/main/java/tconstruct/weaponry/items/CustomToolPart.java new file mode 100644 index 00000000..12d906eb --- /dev/null +++ b/src/main/java/tconstruct/weaponry/items/CustomToolPart.java @@ -0,0 +1,26 @@ +package boni.tinkersweaponry.items; + +import net.minecraft.item.ItemStack; +import tconstruct.TConstruct; +import tconstruct.library.TConstructRegistry; +import tconstruct.library.tools.CustomMaterial; +import tconstruct.library.tools.DynamicToolPart; + +public class CustomToolPart extends WeaponryToolPart { + private final Class customMat; + + public CustomToolPart(String texture, String name, Class customMatClass) { + super(texture, name); + + this.customMat = customMatClass; + } + + @Override + public int getMaterialID (ItemStack stack) + { + if(TConstructRegistry.getCustomMaterial(stack.getItemDamage(), customMat) != null) + return stack.getItemDamage(); + + return -1; + } +} diff --git a/src/main/java/tconstruct/weaponry/items/DualMaterialToolPart.java b/src/main/java/tconstruct/weaponry/items/DualMaterialToolPart.java new file mode 100644 index 00000000..e6fea053 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/items/DualMaterialToolPart.java @@ -0,0 +1,124 @@ +package boni.tinkersweaponry.items; + +import boni.tinkersweaponry.TinkerWeaponry; +import boni.tinkersweaponry.util.Reference; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.IIcon; +import tconstruct.library.TConstructRegistry; +import tconstruct.library.tools.DynamicToolPart; +import tconstruct.library.util.TextureHelper; +import tconstruct.tools.TinkerTools; +import tconstruct.util.config.PHConstruct; + +import java.util.List; +import java.util.Map; + +public class DualMaterialToolPart extends WeaponryToolPart { + public IIcon defaultIcon2; + public IIcon[] icons2; + + public DualMaterialToolPart(String textureType, String name) { + super(textureType, name); + } + + public static ItemStack createDualMaterial(Item item, int mat1, int mat2) + { + ItemStack stack = new ItemStack(item, 1, mat1); + NBTTagCompound tags = new NBTTagCompound(); + NBTTagCompound subtag = new NBTTagCompound(); + subtag.setInteger("Material2", mat2); + + tags.setTag("DualMat", subtag); + stack.setTagCompound(tags); + + return stack; + } + + public int getMaterialID2(ItemStack stack) + { + if(!stack.hasTagCompound()) + return -1; + + int id = stack.getTagCompound().getCompoundTag("DualMat").getInteger("Material2"); + + if (TConstructRegistry.toolMaterials.keySet().contains(id)) + return id; + + return -1; + } + + @Override + public void getSubItems (Item item, CreativeTabs tab, List list) + { + // material id == metadata + for(Integer matID : TConstructRegistry.toolMaterials.keySet()) + list.add(createDualMaterial(item, matID, TinkerTools.MaterialID.Iron)); + } + + @Override + public int getRenderPasses(int metadata) { + return 2; + } + + @Override + public boolean requiresMultipleRenderPasses() { + return true; + } + + @SideOnly(Side.CLIENT) + @Override + public void registerIcons(IIconRegister iconRegister) { + super.registerIcons(iconRegister); + + // same as in super, secondary icon :I + this.icons2 = new IIcon[icons.length]; + + // register icon for each material that has one + if(!PHConstruct.minimalTextures) + for(Map.Entry entry : TConstructRegistry.toolMaterials.entrySet()) + { + String tex = modTexPrefix + ":" + folder + entry.getValue().materialName.toLowerCase() + texture + "_2"; + if(TextureHelper.itemTextureExists(tex)) + this.icons2[entry.getKey()] = iconRegister.registerIcon(tex); + } + + this.defaultIcon2 = iconRegister.registerIcon(modTexPrefix + ":" + folder + texture + "_2"); + } + + @Override + public IIcon getIconFromDamageForRenderPass(int meta, int pass) { + // secondary item + if(pass > 0) { + if(meta > icons.length) + return defaultIcon2; + + if(icons2[meta] == null) + return defaultIcon2; + + return icons2[meta]; + } + return super.getIconFromDamageForRenderPass(meta, pass); + } + + @Override + public int getColorFromItemStack(ItemStack stack, int renderpass) { + if(renderpass > 0) + { + int matId = getMaterialID2(stack); + if(matId > icons2.length) + return super.getColorFromItemStack(stack, renderpass); + + if(icons[matId] == null) + return TConstructRegistry.getMaterial(matId).primaryColor(); + + return super.getColorFromItemStack(stack, renderpass); + } + return super.getColorFromItemStack(stack, renderpass); + } +} diff --git a/src/main/java/tconstruct/weaponry/items/WeaponryPattern.java b/src/main/java/tconstruct/weaponry/items/WeaponryPattern.java new file mode 100644 index 00000000..465c87a0 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/items/WeaponryPattern.java @@ -0,0 +1,52 @@ +package boni.tinkersweaponry.items; + +import boni.tinkersweaponry.util.Reference; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import tconstruct.library.TConstructRegistry; +import tconstruct.library.crafting.PatternBuilder; +import tconstruct.tools.items.Pattern; + +import java.util.List; + +public class WeaponryPattern extends Pattern { + private static final String[] patternName = new String[] { "shuriken", "crossbowlimb", "crossbowbody", "bowlimb" }; + + public WeaponryPattern(String patternType, String name) { + super(patternName, getPatternNames(patternName, patternType), "patterns/"); + this.modTexPrefix = Reference.RESOURCE; + + this.setUnlocalizedName(Reference.prefix(name)); + } + + public static String[] getPatternNames (String[] patternName, String partType) + { + String[] names = new String[patternName.length]; + for (int i = 0; i < patternName.length; i++) + names[i] = partType + patternName[i]; + return names; + } + + @Override + public void getSubItems (Item b, CreativeTabs tab, List list) + { + for (int i = 0; i < patternName.length; i++) + { + // if (i != 23) + list.add(new ItemStack(b, 1, i)); + } + } + + @Override + public int getPatternCost(ItemStack pattern) { + switch(pattern.getItemDamage()) + { + case 0: return 1; // shuriken + case 1: return 8; // crossbow limb + case 2: return 10; // crossbow body + case 3: return 3; // bowlimb + } + return 0; + } +} diff --git a/src/main/java/tconstruct/weaponry/items/WeaponryToolPart.java b/src/main/java/tconstruct/weaponry/items/WeaponryToolPart.java new file mode 100644 index 00000000..b8ef74ea --- /dev/null +++ b/src/main/java/tconstruct/weaponry/items/WeaponryToolPart.java @@ -0,0 +1,14 @@ +package boni.tinkersweaponry.items; + +import boni.tinkersweaponry.TinkerWeaponry; +import boni.tinkersweaponry.util.Reference; +import tconstruct.library.tools.DynamicToolPart; + +public class WeaponryToolPart extends DynamicToolPart { + public WeaponryToolPart(String textureType, String name) { + super(textureType, name, Reference.RESOURCE); + + this.setUnlocalizedName(Reference.prefix(name)); + this.setCreativeTab(TinkerWeaponry.creativeTab); + } +} diff --git a/src/main/java/tconstruct/weaponry/library/util/PiercingArrowDamage.java b/src/main/java/tconstruct/weaponry/library/util/PiercingArrowDamage.java new file mode 100644 index 00000000..bf27a794 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/library/util/PiercingArrowDamage.java @@ -0,0 +1,12 @@ +package boni.tinkersweaponry.library.util; + +import net.minecraft.entity.Entity; +import net.minecraft.util.EntityDamageSourceIndirect; + +public class PiercingArrowDamage extends EntityDamageSourceIndirect { + public PiercingArrowDamage(String p_i1568_1_, Entity p_i1568_2_, Entity p_i1568_3_) { + super(p_i1568_1_, p_i1568_2_, p_i1568_3_); + this.setDamageBypassesArmor(); + this.setProjectile(); + } +} diff --git a/src/main/java/tconstruct/weaponry/library/weaponry/AmmoItem.java b/src/main/java/tconstruct/weaponry/library/weaponry/AmmoItem.java new file mode 100644 index 00000000..5ee30d58 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/library/weaponry/AmmoItem.java @@ -0,0 +1,118 @@ +package boni.tinkersweaponry.library.weaponry; + +import boni.tinkersweaponry.TinkerWeaponry; +import boni.tinkersweaponry.util.Reference; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import tconstruct.library.tools.ToolCore; + +public abstract class AmmoItem extends ToolCore implements IAmmo { + public AmmoItem(int baseDamage, String name) { + super(baseDamage); + this.setUnlocalizedName(Reference.prefix(name)); + this.setCreativeTab(TinkerWeaponry.creativeTab); + } + + @Override + public int getAmmoCount(ItemStack stack) { + NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool"); + return tags.getInteger("Ammo"); + } + + @Override + public int getMaxAmmo(ItemStack stack) { + NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool"); + return getMaxAmmo(tags); + } + + @Override + public int getMaxAmmo(NBTTagCompound tags) { + float dur = tags.getInteger("TotalDurability"); + return (int)Math.ceil(dur*getAmmoModifier()); + } + + @Override + public int addAmmo(int toAdd, ItemStack stack) { + NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool"); + int oldCount = tags.getInteger("Ammo"); + int newCount = Math.min(oldCount + toAdd, getMaxAmmo(stack)); + tags.setInteger("Ammo", newCount); + return toAdd - (newCount - oldCount); + } + + @Override + public int consumeAmmo(int toUse, ItemStack stack) { + NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool"); + int oldCount = tags.getInteger("Ammo"); + int newCount = Math.max(oldCount - toUse, 0); + tags.setInteger("Ammo", newCount); + return toUse - (oldCount - newCount); + } + + public float getAmmoModifier() { return 0.1f; } + + public boolean pickupAmmo(ItemStack stack, ItemStack candidate, EntityPlayer player) + { + if(stack.getItem() == null || !(stack.getItem() instanceof IAmmo)) + return false; + + // check if our candidate fits + if(candidate != null) + { + // same item + if(testIfAmmoMatches(stack, candidate)) { + IAmmo pickedup = ((IAmmo) stack.getItem()); + IAmmo ininventory = ((IAmmo) candidate.getItem()); + // we can be sure that it's ammo, since stack is ammo and they're equal + ininventory.addAmmo(pickedup.getAmmoCount(stack), candidate); + + return true; + } + } + + // search the players inventory + for(ItemStack invItem : player.inventory.mainInventory) { + if (testIfAmmoMatches(stack, invItem)) { + IAmmo pickedup = ((IAmmo) stack.getItem()); + IAmmo ininventory = ((IAmmo) invItem.getItem()); + // we can be sure that it's ammo, since stack is ammo and they're equal + ininventory.addAmmo(pickedup.getAmmoCount(stack), invItem); + + return true; + } + } + + // couldn't find a matching thing. + return false; + } + + private boolean testIfAmmoMatches(ItemStack reference, ItemStack candidate) + { + if(candidate == null) + return false; + if(!candidate.hasTagCompound() || !candidate.getTagCompound().hasKey("InfiTool")) + return false; + + // create a stack to test against + ItemStack testsubject = candidate.copy(); + // all NBT has to match, but the ammo-count obviously differs. So we set our testsubject to the same + // this ensures that it's the one to collect and the one we have matches. + testsubject.getTagCompound().getCompoundTag("InfiTool").setInteger("Ammo", getAmmoCount(reference)); + + return ItemStack.areItemStacksEqual(reference, testsubject); + } + + @Override + public boolean onLeftClickEntity (ItemStack stack, EntityPlayer player, Entity entity) + { + // ammo doesn't hurt on smacking stuff with it + return false; + } + + @Override + public String getDefaultTexturePath() { + return Reference.RESOURCE + ":" + getDefaultFolder(); + } +} diff --git a/src/main/java/tconstruct/weaponry/library/weaponry/AmmoWeapon.java b/src/main/java/tconstruct/weaponry/library/weaponry/AmmoWeapon.java new file mode 100644 index 00000000..1eb4dc57 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/library/weaponry/AmmoWeapon.java @@ -0,0 +1,146 @@ +package boni.tinkersweaponry.library.weaponry; + +import boni.tinkersweaponry.client.CrosshairType; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumAction; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; + +/** + * Throwing weapons that utilize the ammo system on themselves. + * Throwing knifes etc. + */ +public abstract class AmmoWeapon extends AmmoItem implements IAccuracy, IWindup { + public AmmoWeapon(int baseDamage, String name) { + super(baseDamage, name); + } + + @Override + public EnumAction getItemUseAction(ItemStack par1ItemStack) { + return EnumAction.none; + } // we use custom animation renderiiing! + + @Override + public int getMaxItemUseDuration(ItemStack par1ItemStack) { + return 72000; + } + + @Override + public ItemStack onItemRightClick (ItemStack stack, World world, EntityPlayer player) + { + player.setItemInUse(stack, this.getMaxItemUseDuration(stack)); + return stack; + } + + @Override + public boolean onItemUse (ItemStack stack, EntityPlayer player, World world, int x, int y, int z, int side, float clickX, float clickY, float clickZ) + { + return false; + } + + /** + * How long it takes to "ready" the weapon. To reach the point, where holding the right mouse button any longer doesn't have an impact. + */ + @Override + public int getWindupTime(ItemStack itemStack) { return 0; } + + @Override + public float getMinWindupProgress(ItemStack itemStack) { + return 0; + } + + public float getWindupProgress(ItemStack itemStack, int timeInUse) + { + float time = (float) timeInUse; + float windup = getWindupTime(itemStack); + if(time > windup) + time = windup; + + return time/windup; + } + + + public float minAccuracy(ItemStack itemStack) { return 0.5f; } + public float maxAccuracy(ItemStack itemStack) { return 0.5f; } + + public float getWindupProgress(ItemStack itemStack, EntityPlayer player) + { + // what are you doing! + if(player.inventory.getCurrentItem() != itemStack) + return 0f; + + // are we using it? + if(player.getItemInUse() == null) + return 0f; + + return getWindupProgress(itemStack, getMaxItemUseDuration(itemStack) - player.getItemInUseCount()); + } + + public float getAccuracy(ItemStack itemStack, EntityPlayer player) + { + float dif = minAccuracy(itemStack) - maxAccuracy(itemStack); + + return minAccuracy(itemStack) - dif * getWindupProgress(itemStack, player); + } + + @Override + public String[] getTraits() { + return new String[] {"weapon", "throwing", "ammo"}; + } + + @Override + public void onPlayerStoppedUsing(ItemStack stack, World world, EntityPlayer player, int durationLeft) { + int time = this.getMaxItemUseDuration(stack) - durationLeft; + if(getWindupProgress(stack, time) >= getMinWindupProgress(stack)) + launchProjectile(stack, world, player); + } + + protected void launchProjectile(ItemStack stack, World world, EntityPlayer player) { + // spawn projectile on server + if(!world.isRemote) { + ItemStack reference = stack.copy(); + reference.stackSize = 1; + reference.getTagCompound().getCompoundTag("InfiTool").setInteger("Ammo", 1); + Entity projectile = createProjectile(reference, world, player, getAccuracy(stack, player)); + world.spawnEntityInWorld(projectile); + } + + // reduce ammo + this.consumeAmmo(1, stack); + } + + protected abstract Entity createProjectile(ItemStack reference, World world, EntityPlayer player, float accuracy); + + @Override + public void registerPartPaths(int index, String[] location) { + + } + + @Override + public void registerAlternatePartPaths(int index, String[] location) { + headStrings.put(index, location[0]); + brokenPartStrings.put(index, location[1]); + handleStrings.put(index, location[2]); + if (location.length > 3) + accessoryStrings.put(index, location[3]); + if (location.length > 4) + extraStrings.put(index, location[4]); + } + + + @SideOnly(Side.CLIENT) + public CrosshairType getCrosshairType() { return CrosshairType.SQUARE; } + + @Override + public boolean zoomOnWindup(ItemStack itemStack) { + return false; + } + + @Override + public float getZoom(ItemStack itemStack) { + return 1.0f; + } +} diff --git a/src/main/java/tconstruct/weaponry/library/weaponry/ArrowShaftMaterial.java b/src/main/java/tconstruct/weaponry/library/weaponry/ArrowShaftMaterial.java new file mode 100644 index 00000000..fdd888b3 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/library/weaponry/ArrowShaftMaterial.java @@ -0,0 +1,29 @@ +package boni.tinkersweaponry.library.weaponry; + +import boni.tinkersweaponry.TinkerWeaponry; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import tconstruct.library.tools.CustomMaterial; + +public class ArrowShaftMaterial extends CustomMaterial { + public final float durabilityModifier; // like the durability modifier of handles, but for arrows! + public final float fragility; // 1.0 = breaks 100%, 0.0 = never breaks + public final float weight; // baseline: 1.0 = default, smaller = lighter, higher = heavier + + public ArrowShaftMaterial(int materialID, int value, ItemStack input, ItemStack craftingItem, float durabilityModifier, float weight, float fragility, int color) { + super(materialID, value, input, craftingItem, color); + this.durabilityModifier = durabilityModifier; + this.fragility = fragility; + this.weight = weight; + } + + public static ArrowShaftMaterial createMaterial(int id, Item input, float durabilityModifier, float weight, float fragility, int color) + { + return createMaterial(id, input, 0, durabilityModifier, weight, fragility, color); + } + + public static ArrowShaftMaterial createMaterial(int id, Item input, int inputMeta, float durabilityModifier, float weight, float fragility, int color) + { + return new ArrowShaftMaterial(id, 2, new ItemStack(input, 1, inputMeta), new ItemStack(TinkerWeaponry.partArrowShaft, 0, id), durabilityModifier, weight, fragility, color); + } +} diff --git a/src/main/java/tconstruct/weaponry/library/weaponry/BowBaseAmmo.java b/src/main/java/tconstruct/weaponry/library/weaponry/BowBaseAmmo.java new file mode 100644 index 00000000..25aae575 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/library/weaponry/BowBaseAmmo.java @@ -0,0 +1,167 @@ +package boni.tinkersweaponry.library.weaponry; + +import boni.tinkersweaponry.ammo.ArrowAmmo; +import boni.tinkersweaponry.entity.ArrowEntity; +import net.minecraft.enchantment.Enchantment; +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.entity.projectile.EntityArrow; +import net.minecraft.init.Items; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import tconstruct.library.crafting.ToolBuilder; + +import java.util.List; + +public abstract class BowBaseAmmo extends ProjectileWeapon { + public BowBaseAmmo(int baseDamage, String name) { + super(baseDamage, name); + } + + @Override + public int durabilityTypeAccessory() { + return 2; // head-type + } + + @Override + public int durabilityTypeExtra() { + return 1; // handle-type + } + + @Override + public boolean zoomOnWindup(ItemStack itemStack) { + return true; + } + + @Override + public float getZoom(ItemStack itemStack) { + return 1.2f; + } + + @Override + public float getMinWindupProgress(ItemStack itemStack) { + return 0.5f; + } + + @Override + public ItemStack searchForAmmo(EntityPlayer player, ItemStack weapon) + { + // arrow priority: hotbar > inventory, tinker arrows > regular arrows + ItemStack[] inventory = player.inventory.mainInventory; + + // check hotbar for tinker arrows + for(int i = 0; i < InventoryPlayer.getHotbarSize(); i++) + if(checkTinkerArrow(inventory[i])) + return inventory[i]; + + // check hotbar for vanilla arrows + for(int i = 0; i < InventoryPlayer.getHotbarSize(); i++) + if(checkVanillaArrow(inventory[i])) + return inventory[i]; + + // check the rest of the inventory for tinker arrows + for(int i = InventoryPlayer.getHotbarSize(); i < inventory.length; i++) + if(checkTinkerArrow(inventory[i])) + return inventory[i]; + + // check the rest of the inventory for vanilla arrows + for(int i = InventoryPlayer.getHotbarSize(); i < inventory.length; i++) + if(checkVanillaArrow(inventory[i])) + return inventory[i]; + + // creative mode + if(player.capabilities.isCreativeMode || EnchantmentHelper.getEnchantmentLevel(Enchantment.infinity.effectId, weapon) > 0) + return new ItemStack(Items.arrow); + + return null; + } + + private boolean checkTinkerArrow(ItemStack stack) + { + // null + if(stack == null) + return false; + // no tinker arrow + if(!(stack.getItem() instanceof ArrowAmmo)) + return false; + // no ammo left + if(((IAmmo) stack.getItem()).getAmmoCount(stack) <= 0) + return false; + + return true; + } + + private boolean checkVanillaArrow(ItemStack stack) + { + // null + if(stack == null) + return false; + // no arrow + if(!(stack.getItem() == Items.arrow)) + return false; + // inventory shouldn't contain stacksize 0 items so we don't have to check that. + + return true; + } + + @Override + protected Entity createProjectile(ItemStack arrows, World world, EntityPlayer player, float speed, float accuracy) { + EntityArrow arrow; + + if(arrows.getItem() == Items.arrow) { + arrow = new EntityArrow(world, player, speed/1.5f); // vanilla arrows internally do x1.5 + } + else { + ItemStack reference = arrows.copy(); + reference.stackSize = 1; + reference.getTagCompound().getCompoundTag("InfiTool").setInteger("Ammo", 1); + arrow = new ArrowEntity(world, player, speed, accuracy, reference); + } + + if(player.capabilities.isCreativeMode) + arrow.canBePickedUp = 2; + + return arrow; + } + + @Override + public void playFiringSound(World world, EntityPlayer player, ItemStack weapon, ItemStack ammo, float speed, float accuracy) { + world.playSoundAtEntity(player, "random.bow", 1.0F, 1.0F / (itemRand.nextFloat() * 0.4F + 1.2F) + speed * 0.5F); + } + + @Override + public void buildTool (int id, String name, List list) + { + // all creative bows use regular bowstring + ItemStack handleStack = new ItemStack(getHandleItem(), 1, 0); // regular bowstring + ItemStack accessoryStack = getPartAmount() > 2 ? new ItemStack(getAccessoryItem(), 1, id) : null; + ItemStack extraStack = getPartAmount() > 3 ? new ItemStack(getExtraItem(), 1, id) : null; + + ItemStack tool = ToolBuilder.instance.buildTool(new ItemStack(getHeadItem(), 1, id), handleStack, accessoryStack, extraStack, ""); + if (tool != null) + { + tool.getTagCompound().getCompoundTag("InfiTool").setBoolean("Built", true); + list.add(tool); + } + } +/* + @Override + public int getColorFromItemStack(ItemStack stack, int renderPass) { + if(renderPass != 0 || !stack.hasTagCompound()) + return super.getColorFromItemStack(stack, renderPass); + + // bowstring: custom material -> custom coloring + // todo: move this into the custom material itself + int mat = stack.getTagCompound().getCompoundTag("InfiTool").getInteger("Handle"); + switch(mat) + { + case 0: return 0xffffffff; // string = white + case 1: return 0xffccccff; // macig string = light blue + case 2: return 0xffffcccc; // flamestring = light red + } + return super.getColorFromItemStack(stack, renderPass); + } + */ +} diff --git a/src/main/java/tconstruct/weaponry/library/weaponry/IAccuracy.java b/src/main/java/tconstruct/weaponry/library/weaponry/IAccuracy.java new file mode 100644 index 00000000..30ab05ba --- /dev/null +++ b/src/main/java/tconstruct/weaponry/library/weaponry/IAccuracy.java @@ -0,0 +1,10 @@ +package boni.tinkersweaponry.library.weaponry; + +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +public interface IAccuracy { + public float minAccuracy(ItemStack itemStack); + public float maxAccuracy(ItemStack itemStack); + public float getAccuracy(ItemStack itemStack, EntityPlayer player); +} diff --git a/src/main/java/tconstruct/weaponry/library/weaponry/IAmmo.java b/src/main/java/tconstruct/weaponry/library/weaponry/IAmmo.java new file mode 100644 index 00000000..ae06eba9 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/library/weaponry/IAmmo.java @@ -0,0 +1,38 @@ +package boni.tinkersweaponry.library.weaponry; + +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +public interface IAmmo { + /** + * Returns the current ammo amount of the item. + */ + int getAmmoCount(ItemStack stack); + + /** + * Returns the maximum amount of ammo the item can have + */ + int getMaxAmmo(ItemStack stack); + + /** + * Returns the maximum amount of ammo the item can have + * @param tags InfiTool tag compound of the item + */ + int getMaxAmmo(NBTTagCompound tags); + + /** + * Adds the given amount of ammo cache. Will not go over max-ammo. + * @param count How much to add + * @param stack The itemstack to add the ammo to. Has to have the proper NBT. + * @return The amount of ammo that couldn't be added. + */ + int addAmmo(int count, ItemStack stack); + + /** + * Removes the given amount fro the ammo cache. Will not go below zero. + * @param count How much to remove + * @param stack The itemstack to add the ammo to. Has to have the proper NBT. + * @return The amount of ammo that couldn't be removed. If you try to remove 5, but only 3 are left, it'll return 2. + */ + int consumeAmmo(int count, ItemStack stack); +} diff --git a/src/main/java/tconstruct/weaponry/library/weaponry/IWindup.java b/src/main/java/tconstruct/weaponry/library/weaponry/IWindup.java new file mode 100644 index 00000000..4b72714a --- /dev/null +++ b/src/main/java/tconstruct/weaponry/library/weaponry/IWindup.java @@ -0,0 +1,20 @@ +package boni.tinkersweaponry.library.weaponry; + +import boni.tinkersweaponry.client.CrosshairType; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; + +/** + * This class has a windup time, meaning it takes some time to reach full potency. + * Windup progress is visualized with a special crosshair. + */ +public interface IWindup { + public int getWindupTime(ItemStack itemStack); // how long it takes to fully wind up + public float getWindupProgress(ItemStack itemStack, EntityPlayer player); // how far we've winded up, 0.0-1.0 + public float getMinWindupProgress(ItemStack itemStack); // how long it has been winded up at least to fire (0.0-1.0) + + public CrosshairType getCrosshairType(); + + public boolean zoomOnWindup(ItemStack itemStack); + public float getZoom(ItemStack itemStack); +} diff --git a/src/main/java/tconstruct/weaponry/library/weaponry/ProjectileWeapon.java b/src/main/java/tconstruct/weaponry/library/weaponry/ProjectileWeapon.java new file mode 100644 index 00000000..ec4fc2c0 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/library/weaponry/ProjectileWeapon.java @@ -0,0 +1,320 @@ +package boni.tinkersweaponry.library.weaponry; + +import boni.tinkersweaponry.TinkerWeaponry; +import boni.tinkersweaponry.client.CrosshairType; +import boni.tinkersweaponry.util.Reference; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumAction; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.entity.player.ArrowLooseEvent; +import tconstruct.library.tools.AbilityHelper; +import tconstruct.library.tools.ToolCore; +import tconstruct.library.util.TextureHelper; + +import java.util.HashMap; +import java.util.Map; + +/** + * Weapons that utilize ammo that uses the ammo system to shoot projectiles. + * Bows,... + */ +public abstract class ProjectileWeapon extends ToolCore implements IAccuracy, IWindup { + public ProjectileWeapon(int baseDamage, String name) { + super(baseDamage); + this.setUnlocalizedName(Reference.prefix(name)); + this.setCreativeTab(TinkerWeaponry.creativeTab); + } + + @SideOnly(Side.CLIENT) + public CrosshairType getCrosshairType() { + return CrosshairType.SQUARE; + } + + @Override + public boolean zoomOnWindup(ItemStack itemStack) { + return false; + } + + @Override + public float getZoom(ItemStack itemStack) { + return 1.0f; + } + + /** + * Searches the player for ammo to use + * @param player the player + * @return the itemstack found to be ammo + */ + public abstract ItemStack searchForAmmo(EntityPlayer player, ItemStack weapon); + + /** + * Creates the projectile to be fired. + * @param ammo The ammo used + * @param world world. + * @param player player. + * @param speed the speed calculated for the projectile + * @param accuracy the accuracy calculated for the projectile + * @return A banana. + */ + protected abstract Entity createProjectile(ItemStack ammo, World world, EntityPlayer player, float speed, float accuracy); + + + /* Accuracy */ + public abstract float minAccuracy(ItemStack itemStack); + public abstract float maxAccuracy(ItemStack itemStack); + + public float getAccuracy(ItemStack itemStack, EntityPlayer player) + { + return getAccuracy(itemStack, getMaxItemUseDuration(itemStack) - player.getItemInUseCount()); + } + + public float getAccuracy(ItemStack itemStack, int time) + { + float dif = minAccuracy(itemStack) - maxAccuracy(itemStack); + + return minAccuracy(itemStack) - dif * getWindupProgress(itemStack, time); + } + + /* Windup */ + public int getWindupTime(ItemStack itemStack) { + NBTTagCompound toolTag = itemStack.getTagCompound().getCompoundTag("InfiTool"); + return (int)((float)toolTag.getInteger("DrawSpeed")*windupModifier(itemStack)); + } + + protected float windupModifier(ItemStack itemStack) { return 1.0f; } + + public float getWindupProgress(ItemStack itemStack, EntityPlayer player) + { + // what are you doing! + if(player.inventory.getCurrentItem() != itemStack) + return 0f; + + // are we using it? + if(player.getItemInUse() == null) + return 0f; + + return getWindupProgress(itemStack, getMaxItemUseDuration(itemStack) - player.getItemInUseCount()); + } + + public float getWindupProgress(ItemStack itemStack, int timeInUse) + { + float time = (float) timeInUse; + float windup = getWindupTime(itemStack); + if(time > windup) + return 1.0f; + + return time/windup; + } + + public float getProjectileSpeed(ItemStack itemStack) + { + NBTTagCompound toolTag = itemStack.getTagCompound().getCompoundTag("InfiTool"); + return toolTag.getFloat("FlightSpeed") * projectileSpeedModifier(itemStack); + } + + protected float projectileSpeedModifier(ItemStack itemStack) { return 1.0f; } + + /* Bow usage */ + @Override + public EnumAction getItemUseAction(ItemStack par1ItemStack) { + return EnumAction.none; + } + + @Override + public int getMaxItemUseDuration(ItemStack par1ItemStack) { + return 72000; + } + + @Override + public ItemStack onItemRightClick (ItemStack stack, World world, EntityPlayer player) + { + if(getWindupTime(stack) == 0.0f) + return stack; + + // only if ammo is present + if(searchForAmmo(player, stack) != null) + player.setItemInUse(stack, this.getMaxItemUseDuration(stack)); + return stack; + } + + @Override + public void onPlayerStoppedUsing (ItemStack weapon, World world, EntityPlayer player, int useRemaining) + { + int time = this.getMaxItemUseDuration(weapon) - useRemaining; + + // we abuse the arrowLooseEvent for all projectiles + ArrowLooseEvent event = new ArrowLooseEvent(player, weapon, time); + MinecraftForge.EVENT_BUS.post(event); + if (event.isCanceled()) + { + return; + } + time = event.charge; + + // find ammo + ItemStack ammo = searchForAmmo(player, weapon); + + // no ammo found. :( + if(ammo == null) + return; + + NBTTagCompound toolTag = weapon.getTagCompound().getCompoundTag("InfiTool"); + float projectileSpeed = getProjectileSpeed(weapon); + float windup = getWindupProgress(weapon, time); + float accuracy = getAccuracy(weapon, time); + + // needs a minimum windup + if(windup < this.getMinWindupProgress(weapon)) + return; + + // take windup time into account + projectileSpeed *= windup; + + Entity projectile = createProjectile(ammo, world, player, projectileSpeed, accuracy); + + + int reinforced = 0; + if (toolTag.hasKey("Unbreaking")) + reinforced = toolTag.getInteger("Unbreaking"); + + if (random.nextInt(10) < 10 - reinforced) + AbilityHelper.damageTool(weapon, 1, player, false); + + playFiringSound(world, player, weapon, ammo, projectileSpeed, accuracy); + + + // use up ammo + if(ammo.getItem() instanceof IAmmo) + ((IAmmo) ammo.getItem()).consumeAmmo(1, ammo); + else + player.inventory.consumeInventoryItem(ammo.getItem()); + + // FIREEEEEEE + if (!world.isRemote) + world.spawnEntityInWorld(projectile); + } + + public abstract void playFiringSound(World world, EntityPlayer player, ItemStack weapon, ItemStack ammo, float speed, float accuracy); + + public HashMap animationHeadIcons = new HashMap(); + public HashMap animationHandleIcons = new HashMap(); + public HashMap animationAccessoryIcons = new HashMap(); + public HashMap animationExtraIcons = new HashMap(); + + // todo: animated effects + + @Override + public String getDefaultTexturePath() { + return Reference.RESOURCE + ":" + getDefaultFolder(); + } + + /** + * return true if the current renderpass should use animations. + * 0 == handle + * 1 == head + * 2 == accessory + * 3 == extra + */ + protected boolean animateLayer(int renderPass) + { + return false; + } + + @Override + public IIcon getIcon(ItemStack stack, int renderPass, EntityPlayer player, ItemStack usingItem, int useRemaining) { + // animate? + if(!animateLayer(renderPass)) + return super.getIcon(stack, renderPass, player, usingItem, useRemaining); + + if(usingItem == null || stack != usingItem || !stack.hasTagCompound()) + return super.getIcon(stack, renderPass, player, usingItem, useRemaining); + + NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool"); + + // effects aren't animated + // todo: make effects animated + if(renderPass >= getPartAmount() || tags == null) + return super.getIcon(stack, renderPass, player, usingItem, useRemaining); + + float progress = getWindupProgress(usingItem, getMaxItemUseDuration(usingItem) - useRemaining); + // get the correct icon + switch (renderPass) + { + case 0: return getCorrectAnimationIcon(animationHandleIcons, tags.getInteger("RenderHandle"), progress); + case 1: return getCorrectAnimationIcon(animationHeadIcons, tags.getInteger("renderHead"), progress); + case 2: return getCorrectAnimationIcon(animationAccessoryIcons, tags.getInteger("renderAccessory"), progress); + case 3: return getCorrectAnimationIcon(animationExtraIcons, tags.getInteger("renderExtra"), progress); + } + + return emptyIcon; + } + + protected IIcon getCorrectAnimationIcon(Map icons, int id, float progress) + { + // animation count, standard texture as reference + float count = icons.get(-1).length - 1; + int step = Math.round(progress * count); + + if(icons.containsKey(id)) + return icons.get(id)[step]; + + // default icon + return icons.get(-1)[step]; + } + + @Override + public void registerIcons(IIconRegister iconRegister) { + super.registerIcons(iconRegister); + + addAnimationIcons(headStrings, animationHeadIcons, iconRegister, getIconSuffix(0)); + addAnimationIcons(handleStrings, animationHandleIcons, iconRegister, getIconSuffix(2)); + addAnimationIcons(accessoryStrings, animationAccessoryIcons, iconRegister, getIconSuffix(3)); + addAnimationIcons(extraStrings, animationExtraIcons, iconRegister, getIconSuffix(4)); + } + + private void addAnimationIcons(HashMap textures, HashMap icons, IIconRegister iconRegister, String standard) + { + icons.clear(); + + // we use the standard to determine how many animations there are + if(standard == null || standard.isEmpty()) + return; + + int count = 1; + standard = getDefaultTexturePath() + "/" + standard; + while(TextureHelper.itemTextureExists(standard + "_" + count)) + count++; + + count--; + + // add the standard icons + IIcon[] anims = new IIcon[count]; + for(int i = 0; i < count; i++) + anims[i] = iconRegister.registerIcon(standard + "_" + (i+1)); + icons.put(-1, anims); + + // now do the same for each entry + for(Map.Entry entry : textures.entrySet()) + { + anims = new IIcon[count]; + boolean empty = true; + for(int i = 0; i < count; i++) { + String tex = entry.getValue() + "_" + (i+1); + if (TextureHelper.itemTextureExists(tex)) { + anims[i] = iconRegister.registerIcon(tex); + empty = false; + } + } + if(!empty) + icons.put(entry.getKey(), anims); + } + } +} diff --git a/src/main/java/tconstruct/weaponry/util/Config.java b/src/main/java/tconstruct/weaponry/util/Config.java new file mode 100644 index 00000000..053634fb --- /dev/null +++ b/src/main/java/tconstruct/weaponry/util/Config.java @@ -0,0 +1,4 @@ +package boni.tinkersweaponry.util; + +public class Config { +} diff --git a/src/main/java/tconstruct/weaponry/util/Reference.java b/src/main/java/tconstruct/weaponry/util/Reference.java new file mode 100644 index 00000000..f69f03cb --- /dev/null +++ b/src/main/java/tconstruct/weaponry/util/Reference.java @@ -0,0 +1,17 @@ +package boni.tinkersweaponry.util; + +public final class Reference { + private Reference() {} + + public static final String MOD_ID = "tinkersweaponry"; + public static final String MOD_NAME = "Tinker's Weaponry"; + public static final String TCON_MOD_ID = "TConstruct"; + + public static final String RESOURCE = MOD_ID.toLowerCase(); + + public static String resource(String res) + { + return String.format("%s:%s", RESOURCE, res); + } + public static String prefix(String name) { return String.format("tcon.weaponry.%s", name);} +} diff --git a/src/main/java/tconstruct/weaponry/weapons/Crossbow.java b/src/main/java/tconstruct/weaponry/weapons/Crossbow.java new file mode 100644 index 00000000..24bd92d1 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/weapons/Crossbow.java @@ -0,0 +1,442 @@ +package boni.tinkersweaponry.weapons; + +import boni.tinkersweaponry.TinkerWeaponry; +import boni.tinkersweaponry.ammo.BoltAmmo; +import boni.tinkersweaponry.entity.BoltEntity; +import boni.tinkersweaponry.library.weaponry.AmmoItem; +import boni.tinkersweaponry.library.weaponry.ProjectileWeapon; +import boni.tinkersweaponry.util.Reference; +import boni.tinkersweaponry.library.weaponry.IAmmo; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.projectile.EntityArrow; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; +import tconstruct.library.crafting.ToolBuilder; +import tconstruct.library.tools.AbilityHelper; +import tconstruct.tools.TinkerTools; + +import java.util.List; + +public class Crossbow extends ProjectileWeapon { + public Crossbow() { + super(0, "Crossbow"); + this.setMaxDamage(100); + } + + public boolean isLoaded(ItemStack itemStack) + { + if(itemStack.hasTagCompound()) + return isLoaded(itemStack.getTagCompound().getCompoundTag("InfiTool")); + + return false; + } + + public boolean isLoaded(NBTTagCompound tags) + { + return tags.getBoolean("Loaded"); + } + + public ItemStack getLoadedAmmo(ItemStack itemStack) + { + NBTTagCompound tags = itemStack.getTagCompound().getCompoundTag("InfiTool"); + if(!isLoaded(tags)) + return null; + + return ItemStack.loadItemStackFromNBT(tags.getCompoundTag("LoadedItem")); + } + + @Override + public int getWindupTime(ItemStack itemStack) { + NBTTagCompound toolTag = itemStack.getTagCompound().getCompoundTag("InfiTool"); + return (int)((float)toolTag.getInteger("DrawSpeed") * 2.5f); + } + + @Override + public float getMinWindupProgress(ItemStack itemStack) { + return 1.0f; + } + + @Override + public float getProjectileSpeed(ItemStack itemStack) { + return super.getProjectileSpeed(itemStack); + } + + @Override + public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player) { + NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool"); + + // unload on shift-rightclick + if(player.isSneaking()) + if(unload(stack, player, tags)) + return stack; + + // loaded + if(tags.getBoolean("Loaded")) + fire(stack, world, player); + + // reload (automatically after firing) + initiateReload(stack, player, tags); + + return stack; + } + + @Override + public void onUpdate(ItemStack stack, World world, Entity entity, int par4, boolean par5) { + super.onUpdate(stack, world, entity, par4, par5); + + if(!stack.hasTagCompound()) + return; + + if(!(entity instanceof EntityPlayer)) + return; + + EntityPlayer player = (EntityPlayer) entity; + if(player.inventory.getCurrentItem() != stack) + return; + + NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool"); + if(tags.hasKey("Reloading")) + { + int timeLeft = tags.getInteger("Reloading"); + timeLeft--; + if(timeLeft > 0) + tags.setInteger("Reloading", timeLeft); + else { + tags.removeTag("Reloading"); + reload(stack, player, world, tags); + } + } + } + + @Override + public float getWindupProgress(ItemStack itemStack, EntityPlayer player) { + NBTTagCompound tags = itemStack.getTagCompound().getCompoundTag("InfiTool"); + + // loaded, full accuracy + if(tags.getBoolean("Loaded")) + return 1.0f; + // not loaded, but reloading -> progress + else if(tags.hasKey("Reloading")) + return 1.0f - ((float)tags.getInteger("Reloading"))/((float)getWindupTime(itemStack)); + // not loaded and not reloading -> no accuracy! + else + return 0.0f; + } + + public void initiateReload(ItemStack stack, EntityPlayer player, NBTTagCompound tags) { + if(tags.getBoolean("Broken")) + return; + + // has ammo? + if(searchForAmmo(player, stack) != null) + if(!tags.hasKey("Reloading")) + // start reloading + tags.setInteger("Reloading", getWindupTime(stack)); + } + + // called after the reloading is done. Does the actual loading + public boolean reload(ItemStack weapon, EntityPlayer player, World world, NBTTagCompound tags) + { + ItemStack ammo = searchForAmmo(player, weapon); + // no ammo present + if(ammo == null) + return false; + + // already loaded + if(tags.getBoolean("Loaded")) + return false; + + ItemStack copy = ammo.copy(); + copy.getTagCompound().getCompoundTag("InfiTool").setInteger("Ammo", 1); + + + // load ammo into nbt + NBTTagCompound ammotag = new NBTTagCompound(); + copy.writeToNBT(ammotag); + //ammotag.getCompoundTag("tag"; // set ammo count to 1 + tags.setTag("LoadedItem", ammotag); + tags.setBoolean("Loaded", true); + + // remove loaded item + if(ammo.getItem() instanceof IAmmo) + ((IAmmo) ammo.getItem()).consumeAmmo(1, ammo); + else + player.inventory.consumeInventoryItem(ammo.getItem()); + + playReloadSound(world, player, weapon, ammo); + + return true; + } + + // stops reloading, or unloads the ammo if it has been loaded + public boolean unload(ItemStack weapon, EntityPlayer player, NBTTagCompound tags) + { + // is reloading? + if(tags.hasKey("Reloading")) + { + // stop it + tags.removeTag("Reloading"); + return true; + } + + // loaded? + if(tags.getBoolean("Loaded")) + { + // unload + ItemStack loadedItem = ItemStack.loadItemStackFromNBT(tags.getCompoundTag("LoadedItem")); + AmmoItem ammo = (AmmoItem) loadedItem.getItem(); + // try to pick it up + ammo.pickupAmmo(loadedItem, searchForAmmo(player, weapon), player); + + // unloaded + tags.setBoolean("Loaded", false); + tags.removeTag("LoadedItem"); + + return true; + } + + // nothing to unload + return false; + } + + // called if loaded to SHOOOOOOOT + public void fire(ItemStack weapon, World world, EntityPlayer player) + { + NBTTagCompound tags = weapon.getTagCompound().getCompoundTag("InfiTool"); + // not loaded + if(!tags.getBoolean("Loaded")) + return; + + // get ammo + ItemStack ammo = ItemStack.loadItemStackFromNBT(tags.getCompoundTag("LoadedItem")); + + // unload + tags.setBoolean("Loaded", false); + tags.removeTag("LoadedItem"); + + // safety + if(ammo == null) + return; + + float projectileSpeed = getProjectileSpeed(weapon); + float windup = getWindupTime(weapon); // max windup time + float accuracy = getAccuracy(weapon, (int)windup); + + Entity projectile = createProjectile(ammo, world, player, projectileSpeed, accuracy); + + int reinforced = 0; + + if (tags.hasKey("Unbreaking")) + reinforced = tags.getInteger("Unbreaking"); + + if (random.nextInt(10) < 10 - reinforced) + AbilityHelper.damageTool(weapon, 1, player, false); + + playFiringSound(world, player, weapon, ammo, projectileSpeed, accuracy); + + // thwock + if (!world.isRemote) + world.spawnEntityInWorld(projectile); + } + + @Override + public ItemStack searchForAmmo(EntityPlayer player, ItemStack weapon) { + // arrow priority: hotbar > inventory, tinker arrows > regular arrows + ItemStack[] inventory = player.inventory.mainInventory; + + // check hotbar for tinker arrows + for(int i = 0; i < inventory.length; i++) + { + ItemStack stack = inventory[i]; + if(stack == null) + continue; + if(!(stack.getItem() instanceof BoltAmmo)) + continue; + if(((IAmmo) stack.getItem()).getAmmoCount(stack) <= 0) + continue; + + return stack; + } + + return null; + } + + @Override + protected Entity createProjectile(ItemStack ammo, World world, EntityPlayer player, float speed, float accuracy) { + EntityArrow arrow; + + ItemStack reference = ammo.copy(); + reference.stackSize = 1; + reference.getTagCompound().getCompoundTag("InfiTool").setInteger("Ammo", 1); + arrow = new BoltEntity(world, player, speed, accuracy, reference); + + if(player.capabilities.isCreativeMode) + arrow.canBePickedUp = 2; + + return arrow; + } + + @Override + public float minAccuracy(ItemStack itemStack) { + return 0; + } + + @Override + public float maxAccuracy(ItemStack itemStack) { + return 0; + } + + public void playReloadSound(World world, EntityPlayer player, ItemStack weapon, ItemStack ammo) { + world.playSoundAtEntity(player, Reference.resource("woodHit"), 1.0f, 1.0f); + } + + @Override + public void playFiringSound(World world, EntityPlayer player, ItemStack weapon, ItemStack ammo, float speed, float accuracy) { + // todo: THWOCK + } + + @Override + public IIcon getIcon(ItemStack stack, int renderPass) { + if(!animateLayer(renderPass)) + return super.getIcon(stack, renderPass); + + if(!stack.hasTagCompound()) + return super.getIcon(stack, renderPass); + + NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool"); + + float progress; + + if(tags.getBoolean("Loaded")) + progress = 1; + else if(!tags.hasKey("Reloading")) + return super.getIcon(stack, renderPass); + else + progress = getWindupProgress(stack, getWindupTime(stack) - tags.getInteger("Reloading")); + + // effects aren't animated + // todo: make effects animated + if(renderPass >= getPartAmount()) + return super.getIcon(stack, renderPass); + + // get the correct icon + switch (renderPass) + { + case 0: return getCorrectAnimationIcon(animationHandleIcons, tags.getInteger("RenderHandle"), progress); + case 1: return getCorrectAnimationIcon(animationHeadIcons, tags.getInteger("renderHead"), progress); + case 2: return getCorrectAnimationIcon(animationAccessoryIcons, tags.getInteger("renderAccessory"), progress); + case 3: return getCorrectAnimationIcon(animationExtraIcons, tags.getInteger("renderExtra"), progress); + } + + return emptyIcon; + } + + @Override + public String getIconSuffix (int partType) + { + switch (partType) + { + case 0: + return "_crossbow_bow"; // head + case 1: + return ""; // broken + case 2: + return "_crossbow_body"; // handle + case 3: + return "_crossbow_string"; // accessory + case 4: + return "_crossbow_binding"; // extra + default: + return ""; + } + } + + @Override + public String getEffectSuffix () + { + return "_crossbow_effect"; + } + + @Override + public String getDefaultFolder () + { + return "crossbow"; + } + + @Override + public int getPartAmount() { + return 4; + } + + @Override + protected boolean animateLayer(int renderPass) { + return renderPass == 1 || renderPass == 2; + } + + @Override + public Item getHeadItem () + { + return TinkerWeaponry.partCrossbowLimb; + } + + @Override + public Item getHandleItem () + { + return TinkerWeaponry.partCrossbowBody; + } + + @Override + public Item getAccessoryItem () + { + return TinkerTools.bowstring; + } + + @Override + public Item getExtraItem() { + return TinkerTools.toughBinding; + } + + @Override + public String[] getTraits() { + return new String[] {"weapon", "ranged", "crossbow"}; + } + + + @Override + public void buildTool (int id, String name, List list) + { + // all creative bows use regular bowstring + ItemStack headStack = new ItemStack(getHeadItem(), 1, id); + ItemStack handleStack = new ItemStack(getHandleItem(), 1, id); + ItemStack accessoryStack = new ItemStack(getAccessoryItem(), 1, 0); // bowstring + ItemStack extraStack = getPartAmount() > 3 ? new ItemStack(getExtraItem(), 1, id) : null; + + ItemStack tool = ToolBuilder.instance.buildTool(headStack, handleStack, accessoryStack, extraStack, ""); + if (tool != null) + { + tool.getTagCompound().getCompoundTag("InfiTool").setBoolean("Built", true); + list.add(tool); + } + } + + @Override + public int getColorFromItemStack(ItemStack stack, int renderPass) { + if(renderPass != 2 || !stack.hasTagCompound()) + return super.getColorFromItemStack(stack, renderPass); + + // bowstring: custom material -> custom coloring + // todo: move this into the custom material itself + int mat = stack.getTagCompound().getCompoundTag("InfiTool").getInteger("Accessory"); + switch(mat) + { + case 0: return 0xffffffff; // string = white + case 1: return 0xffccccff; // macig string = light blue + case 2: return 0xffffcccc; // flamestring = light red + } + return super.getColorFromItemStack(stack, renderPass); + } +} diff --git a/src/main/java/tconstruct/weaponry/weapons/Javelin.java b/src/main/java/tconstruct/weaponry/weapons/Javelin.java new file mode 100644 index 00000000..49bc11ed --- /dev/null +++ b/src/main/java/tconstruct/weaponry/weapons/Javelin.java @@ -0,0 +1,169 @@ +package boni.tinkersweaponry.weapons; + +import boni.tinkersweaponry.entity.JavelinEntity; +import boni.tinkersweaponry.library.weaponry.AmmoWeapon; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; +import tconstruct.library.tools.AbilityHelper; +import tconstruct.tools.TinkerTools; + +public class Javelin extends AmmoWeapon { + public Javelin() { + super(3, "Javelin"); + } + + @Override + public boolean onLeftClickEntity (ItemStack stack, EntityPlayer player, Entity entity) + { + // javelin is the only throwing/ammo weapon that hurts on leftclicking + return AbilityHelper.onLeftClickEntity(stack, player, entity, this, 0); + } + + @Override + public float getWindupProgress(ItemStack itemStack, EntityPlayer player) { + if(!itemStack.hasTagCompound()) + return super.getWindupProgress(itemStack, player); + + if(!itemStack.getTagCompound().getCompoundTag("InfiTool").hasKey("Throwing")) + return 0.5f; + + float timeleft = itemStack.getTagCompound().getCompoundTag("InfiTool").getInteger("Throwing"); + float threshold = getWindupTime(itemStack)/5; + if(timeleft < threshold) + return (threshold-timeleft)/threshold; + else + return 0.5f - 0.25f * ((float)getWindupTime(itemStack)-timeleft)/threshold; + } + + @Override + public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player) { + NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool"); + + // already throwing + if(tags.hasKey("Throwing")) + return stack; + + // has ammo? + if(this.getAmmoCount(stack) <= 0) + return stack; + + // start throwing + tags.setInteger("Throwing", getWindupTime(stack)); + + return stack; + } + + @Override + public void onUpdate(ItemStack stack, World world, Entity entity, int par4, boolean par5) { + super.onUpdate(stack, world, entity, par4, par5); + + if(!stack.hasTagCompound()) + return; + + NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool"); + if(!tags.hasKey("Throwing")) + return; + + EntityPlayer player = (EntityPlayer) entity; + if(player.inventory.getCurrentItem() != stack) + return; + + int timeLeft = tags.getInteger("Throwing"); + timeLeft--; + if(timeLeft > 0) + tags.setInteger("Throwing", timeLeft); + else { + onPlayerStoppedUsing(stack, world, player, 0); + tags.removeTag("Throwing"); + } + } + + @Override + public boolean zoomOnWindup(ItemStack itemStack) { + return true; + } + + @Override + public float getZoom(ItemStack itemStack) { + return 1.5f; + } + + @Override + public float minAccuracy(ItemStack itemStack) { + return 2.5f; + } + + @Override + public float maxAccuracy(ItemStack itemStack) { + return 0.5f; + } + + @Override + public int getWindupTime(ItemStack itemStack) { + return 20; + } + + @Override + public int getPartAmount() { + return 3; + } + + @Override + public String getIconSuffix(int partType) { + switch (partType) + { + case 0: + return "_javelin_head"; + case 1: + return ""; // no broken, since it runs out of ammo + case 2: + return "_javelin_handle"; + case 3: + return "_javelin_accessory"; + default: + return ""; + } + } + + @Override + public String getEffectSuffix() { + return "_javelin_effect"; + } + + @Override + public String getDefaultFolder() { + return "javelin"; + } + + @Override + public float getAmmoModifier() { + return 0.02f; + } + + @Override + public Item getHeadItem() { + return TinkerTools.arrowhead; + } + + @Override + public Item getHandleItem() { + return TinkerTools.toughRod; + } + + @Override + public Item getAccessoryItem() { + return TinkerTools.toughRod; + } + + @Override + protected Entity createProjectile(ItemStack reference, World world, EntityPlayer player, float accuracy) { + reference.getTagCompound().getCompoundTag("InfiTool").removeTag("Throwing"); // needed so the NBTs are equal + JavelinEntity entity = new JavelinEntity(world, player, 2.0f, accuracy, reference); + + return entity; + } +} diff --git a/src/main/java/tconstruct/weaponry/weapons/LongBow.java b/src/main/java/tconstruct/weaponry/weapons/LongBow.java new file mode 100644 index 00000000..d3302d90 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/weapons/LongBow.java @@ -0,0 +1,131 @@ +package boni.tinkersweaponry.weapons; + +import boni.tinkersweaponry.TinkerWeaponry; +import boni.tinkersweaponry.ammo.ArrowAmmo; +import boni.tinkersweaponry.library.weaponry.BowBaseAmmo; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; +import tconstruct.tools.TinkerTools; + +public class LongBow extends BowBaseAmmo { + public LongBow() { + super(0, "Longbow"); + } + + @Override + public float minAccuracy(ItemStack itemStack) { + return 7.5f; + } + + @Override + public float maxAccuracy(ItemStack itemStack) { + return 0.5f; + } + + @Override + public float getZoom(ItemStack itemStack) { + return 1.7f; + } + + @Override + protected float windupModifier(ItemStack itemStack) { + return 1.5f; + } + + @Override + protected float projectileSpeedModifier(ItemStack itemStack) { + return 1.5f; + } + + @Override + protected Entity createProjectile(ItemStack arrows, World world, EntityPlayer player, float speed, float accuracy) { + if(arrows.getItem() instanceof ArrowAmmo) + { + // modify accuraccy of the arrow depending on its accuraccy and weight + NBTTagCompound tags = arrows.getTagCompound().getCompoundTag("InfiTool"); + float matAccuracy = tags.getFloat("Accuracy"); + float weight = tags.getFloat("Mass"); + + // we need heavier arrows because we have POW. therefore we increase the weight penality on accuracy + accuracy += ((100f-matAccuracy)/10f)/(weight-1f); + if(accuracy < 0) + accuracy = 0; + } + + return super.createProjectile(arrows, world, player, speed, accuracy); + } + + @Override + public String getIconSuffix (int partType) + { + switch (partType) + { + case 0: + return "_bow_top"; + case 1: + return "_bowstring_broken"; + case 2: + return "_bowstring"; + case 3: + return "_bow_bottom"; + case 4: + return "_bow_grip"; + default: + return ""; + } + } + + @Override + public String getEffectSuffix () + { + return "_bow_effect"; + } + + @Override + public String getDefaultFolder () + { + return "longbow"; + } + + @Override + public int getPartAmount() { + return 4; + } + + @Override + protected boolean animateLayer(int renderPass) { + return renderPass < 3; + } + + @Override + public Item getHeadItem () + { + return TinkerWeaponry.partBowLimb; + } + + @Override + public Item getHandleItem () + { + return TinkerTools.bowstring; + } + + @Override + public Item getAccessoryItem () + { + return TinkerWeaponry.partBowLimb; + } + + @Override + public Item getExtraItem() { + return TinkerTools.largePlate; + } + + @Override + public String[] getTraits() { + return new String[] {"weapon", "ranged", "bow"}; + } +} diff --git a/src/main/java/tconstruct/weaponry/weapons/ShortBow.java b/src/main/java/tconstruct/weaponry/weapons/ShortBow.java new file mode 100644 index 00000000..82e33676 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/weapons/ShortBow.java @@ -0,0 +1,114 @@ +package boni.tinkersweaponry.weapons; + +import boni.tinkersweaponry.TinkerWeaponry; +import boni.tinkersweaponry.ammo.ArrowAmmo; +import boni.tinkersweaponry.library.weaponry.BowBaseAmmo; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.world.World; +import tconstruct.tools.TinkerTools; + +public class ShortBow extends BowBaseAmmo { + public ShortBow() { + super(0, "Shortbow"); + } + + @Override + protected float windupModifier(ItemStack itemStack) { + return 0.9f; // SHORT bows have a SHORTER windup because they're SHORT. hahahaha.... get it? + } + + @Override + public float minAccuracy(ItemStack itemStack) { + return 1; + } + + @Override + public float maxAccuracy(ItemStack itemStack) { + return 1; + } + + @Override + protected Entity createProjectile(ItemStack arrows, World world, EntityPlayer player, float speed, float accuracy) { + if(arrows.getItem() instanceof ArrowAmmo) + { + // modify accuraccy of the arrow depending on its accuraccy and weight + NBTTagCompound tags = arrows.getTagCompound().getCompoundTag("InfiTool"); + float matAccuracy = tags.getFloat("Accuracy"); + float weight = tags.getFloat("Mass"); + + // weight influences the accuracy too, but only a little bit. + accuracy += ((100f-matAccuracy)/10f)/(weight); + if(accuracy < 0) + accuracy = 0; + } + + return super.createProjectile(arrows, world, player, speed, accuracy); + } + + @Override + public String getIconSuffix (int partType) + { + switch (partType) + { + case 0: + return "_bow_top"; + case 1: + return "_bowstring_broken"; + case 2: + return "_bowstring"; + case 3: + return "_bow_bottom"; + default: + return ""; + } + } + + @Override + public String getEffectSuffix () + { + return "_bow_effect"; + } + + @Override + public String getDefaultFolder () + { + return "shortbow"; + } + + @Override + public int getPartAmount() { + return 3; + } + + @Override + protected boolean animateLayer(int renderPass) { + return renderPass < 3; + } + + @Override + public Item getHeadItem () + { + return TinkerWeaponry.partBowLimb; + } + + @Override + public Item getHandleItem () + { + return TinkerTools.bowstring; + } + + @Override + public Item getAccessoryItem () + { + return TinkerWeaponry.partBowLimb; + } + + @Override + public String[] getTraits() { + return new String[] {"weapon", "ranged", "bow"}; + } +} diff --git a/src/main/java/tconstruct/weaponry/weapons/Shuriken.java b/src/main/java/tconstruct/weaponry/weapons/Shuriken.java new file mode 100644 index 00000000..6384c0e2 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/weapons/Shuriken.java @@ -0,0 +1,169 @@ +package boni.tinkersweaponry.weapons; + +import boni.tinkersweaponry.TinkerWeaponry; +import boni.tinkersweaponry.client.CrosshairType; +import boni.tinkersweaponry.client.IconFlipped; +import boni.tinkersweaponry.entity.ShurikenEntity; +import boni.tinkersweaponry.library.weaponry.AmmoWeapon; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.client.renderer.texture.IIconRegister; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.EnumAction; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.util.IIcon; +import net.minecraft.world.World; + +import java.util.Iterator; +import java.util.Map; + +public class Shuriken extends AmmoWeapon { + + public Shuriken() { + super(1, "shuriken"); + } + + @Override + public float getDamageModifier() { + return 0.4f; + } + + @Override + public int getPartAmount() { + return 4; + } + + @Override + public String getIconSuffix(int partType) { + switch (partType) + { + case 0: + return "_shuriken"; + case 1: + return ""; // no broken, since it runs out of ammo + case 2: + return "_shuriken"; + case 3: + return "_shuriken"; + case 4: + return "_shuriken"; + default: + return ""; + } + } + + @Override + public String getEffectSuffix() { + return "_shuriken_effect"; + } + + @Override + public String getDefaultFolder() { + return "shuriken"; + } + + @Override + public Item getHeadItem() { + return TinkerWeaponry.partShuriken; + } + + @Override + public Item getHandleItem() { + return TinkerWeaponry.partShuriken; + } + + @Override + public Item getAccessoryItem() { + return TinkerWeaponry.partShuriken; + } + + @Override + public Item getExtraItem() { + return TinkerWeaponry.partShuriken; + } + + @Override + public float minAccuracy(ItemStack itemStack) { + return 0; + } + + @Override + public float maxAccuracy(ItemStack itemStack) { + return 0; + } + + @Override + public float getWindupProgress(ItemStack itemStack, EntityPlayer player) { + return 1.0f; // always fully winded! + } + + @Override + public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player) { + launchProjectile(stack, world, player); + + // this is only used for the animation + player.setItemInUse(stack, this.getMaxItemUseDuration(stack)); + + return stack; + } + + @Override + protected Entity createProjectile(ItemStack reference, World world, EntityPlayer player, float accuracy) { + return new ShurikenEntity(world, player, 1.9f, 0f, reference); + } + + @Override + public void onPlayerStoppedUsing(ItemStack stack, World world, EntityPlayer player, int durationLeft) { + // do nothing, or we'd throw double-shurikens! + } + + @Override + public int getMaxItemUseDuration(ItemStack par1ItemStack) { + return 2; + } + + @Override + public EnumAction getItemUseAction(ItemStack par1ItemStack) { + return EnumAction.block; + } + + @Override + public void registerIcons(IIconRegister iconRegister) { + // register icons as usually + super.registerIcons(iconRegister); + + // now we flip all the different part icons, so we only need 1 graphic for 4 different orientations \o/ + // handle first: flip x + Iterator> iter = handleIcons.entrySet().iterator(); + while(iter.hasNext()) + { + Map.Entry entry = iter.next(); + entry.setValue(new IconFlipped(entry.getValue(), true, false)); + // the entry object should reference the direct object in the map, no further updating needed + } + + // accessory: flip y + iter = accessoryIcons.entrySet().iterator(); + while(iter.hasNext()) + { + Map.Entry entry = iter.next(); + entry.setValue(new IconFlipped(entry.getValue(), false, true)); + } + + // extra: flip x and y + iter = extraIcons.entrySet().iterator(); + while(iter.hasNext()) + { + Map.Entry entry = iter.next(); + entry.setValue(new IconFlipped(entry.getValue(), true, true)); + } + } + + @SideOnly(Side.CLIENT) + @Override + public CrosshairType getCrosshairType() { + return CrosshairType.TIP; + } +} diff --git a/src/main/java/tconstruct/weaponry/weapons/ThrowArrow.java b/src/main/java/tconstruct/weaponry/weapons/ThrowArrow.java new file mode 100644 index 00000000..980142c9 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/weapons/ThrowArrow.java @@ -0,0 +1,92 @@ +package boni.tinkersweaponry.weapons; + +import boni.tinkersweaponry.entity.ArrowEntity; +import boni.tinkersweaponry.library.weaponry.AmmoWeapon; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import tconstruct.tools.TinkerTools; + +public class ThrowArrow extends AmmoWeapon { + public ThrowArrow() { + super(1, "ThrowArrow"); + + headIcons = TinkerTools.arrow.headIcons; + handleIcons = TinkerTools.arrow.handleIcons; + accessoryIcons = TinkerTools.arrow.accessoryIcons; + extraIcons = TinkerTools.arrow.extraIcons; + } + + @Override + public String getIconSuffix (int partType) + { + switch (partType) + { + case 0: + return "_arrow_head"; + case 1: + return ""; // Doesn't break + case 2: + return "_arrow_shaft"; + case 3: + case 4: + return "_arrow_fletching"; + default: + return ""; + } + } + + @Override + public String getEffectSuffix () + { + return "_arrow_effect"; + } + + @Override + public String getDefaultFolder () + { + return "arrow"; + } + + @Override + public int getPartAmount() { + return 4; + } + + @Override + public Item getHeadItem () + { + return TinkerTools.arrowhead; + } + + @Override + public Item getAccessoryItem () + { + return TinkerTools.fletching; + } + + @Override + public Item getExtraItem () + { + return TinkerTools.fletching; + } + + @Override + public ItemStack onItemRightClick(ItemStack stack, World world, EntityPlayer player) { + ItemStack reference = stack.copy(); + reference.stackSize = 1; + Entity projectile = new ArrowEntity(world, player, 1.9f, 0f, reference); + + if(!world.isRemote) + world.spawnEntityInWorld(projectile); + + return stack; + } + + @Override + protected Entity createProjectile(ItemStack reference, World world, EntityPlayer player, float accuracy) { + return new ArrowEntity(world, player, 1.0f, accuracy, reference); + } +} diff --git a/src/main/java/tconstruct/weaponry/weapons/ThrowArrowItem.java b/src/main/java/tconstruct/weaponry/weapons/ThrowArrowItem.java new file mode 100644 index 00000000..7793a059 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/weapons/ThrowArrowItem.java @@ -0,0 +1,128 @@ +package boni.tinkersweaponry.weapons; + +import boni.tinkersweaponry.entity.ArrowEntity; +import boni.tinkersweaponry.util.Reference; +import net.minecraft.creativetab.CreativeTabs; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.projectile.EntityArrow; +import net.minecraft.item.EnumAction; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import tconstruct.library.crafting.ToolBuilder; +import tconstruct.library.tools.Weapon; +import tconstruct.tools.TinkerTools; + +import java.util.List; + +public class ThrowArrowItem extends Weapon { + public ThrowArrowItem() { + super(1); + this.setUnlocalizedName(Reference.prefix("ThrowArrow")); + + headIcons = TinkerTools.arrow.headIcons; + handleIcons = TinkerTools.arrow.handleIcons; + accessoryIcons = TinkerTools.arrow.accessoryIcons; + extraIcons = TinkerTools.arrow.extraIcons; + } + + @Override + public ItemStack onItemRightClick (ItemStack itemstack, World world, EntityPlayer player) + { + ItemStack stack = itemstack.copy(); + if (!world.isRemote) + { + EntityArrow arrow = new ArrowEntity(world, player, 1.0f, 1.0f, stack); + world.spawnEntityInWorld(arrow); + } + + return itemstack; + } + + @Override + public String getIconSuffix (int partType) + { + switch (partType) + { + case 0: + return "_arrow_head"; + case 1: + return ""; // Doesn't break + case 2: + return "_arrow_shaft"; + case 3: + return "_arrow_fletching"; + default: + return ""; + } + } + + @Override + public String getEffectSuffix () + { + return "_arrow_effect"; + } + + @Override + public String getDefaultFolder () + { + return "arrow"; + } + + @Override + public void registerPartPaths (int index, String[] location) + { + headStrings.put(index, location[0]); + handleStrings.put(index, location[2]); + } + + @Override + public void registerAlternatePartPaths (int index, String[] location) + { + accessoryStrings.put(index, location[3]); + } + + @Override + public Item getHeadItem () + { + return TinkerTools.arrowhead; + } + + @Override + public Item getAccessoryItem () + { + return TinkerTools.fletching; + } + + @Override + public EnumAction getItemUseAction (ItemStack par1ItemStack) + { + return EnumAction.bow; + } + + @Override + public String[] getTraits () + { + return new String[] { "weapon", "throwing" }; + } + + @Override + public void getSubItems (Item id, CreativeTabs tab, List list) + { + ItemStack toolMine = new ItemStack(this); + + Item accessory = getAccessoryItem(); + ItemStack accessoryStack = accessory != null ? new ItemStack(getAccessoryItem(), 1, 0) : null; + Item extra = getExtraItem(); + ItemStack extraStack = extra != null ? new ItemStack(extra, 1, 0) : null; + ItemStack tool = ToolBuilder.instance.buildTool(new ItemStack(getHeadItem(), 1, 3), new ItemStack(getHandleItem(), 1, 0), accessoryStack, extraStack, ""); + if (tool != null) + { + tool.stackSize = 1; + tool.getTagCompound().getCompoundTag("InfiTool").setBoolean("Built", true); + + toolMine.setTagCompound(tool.getTagCompound()); + list.add(toolMine); + } + } +} diff --git a/src/main/java/tconstruct/weaponry/weapons/ThrowingKnife.java b/src/main/java/tconstruct/weaponry/weapons/ThrowingKnife.java new file mode 100644 index 00000000..c21b9571 --- /dev/null +++ b/src/main/java/tconstruct/weaponry/weapons/ThrowingKnife.java @@ -0,0 +1,90 @@ +package boni.tinkersweaponry.weapons; + +import boni.tinkersweaponry.client.CrosshairType; +import boni.tinkersweaponry.entity.ThrowingKnifeEntity; +import boni.tinkersweaponry.library.weaponry.AmmoWeapon; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.world.World; +import tconstruct.tools.TinkerTools; + +public class ThrowingKnife extends AmmoWeapon { + public ThrowingKnife() { + super(1, "throwingknife"); + } + + @Override + public int getPartAmount() { + return 2; + } + + @Override + public String getIconSuffix(int partType) { + switch (partType) + { + case 0: + return "_knife_blade"; + case 1: + return ""; // no broken, since it runs out of ammo + case 2: + return "_knife_handle"; + default: + return ""; + } + } + + @Override + public String getEffectSuffix() { + return "_throwingknife_effect"; + } + + @Override + public String getDefaultFolder() { + return "throwingknife"; + } + + @Override + public Item getHeadItem() { + return TinkerTools.knifeBlade; + } + + @Override + public Item getAccessoryItem() { + return null; + } + + @Override + public int getWindupTime(ItemStack itemStack) { return 30; } // 1 1/2 seconds + + @Override + public float getMinWindupProgress(ItemStack itemStack) { + return 0.6f; + } + + @Override + public float maxAccuracy(ItemStack itemStack) { + return 1f; + } + + @Override + public float minAccuracy(ItemStack itemStack) { + return 10f; + } + + @Override + protected Entity createProjectile(ItemStack reference, World world, EntityPlayer player, float accuracy) { + float speed = 1.5f; + + return new ThrowingKnifeEntity(world, player, speed, accuracy, reference); + } + + @SideOnly(Side.CLIENT) + @Override + public CrosshairType getCrosshairType() { + return CrosshairType.SPIKE; + } +}