diff --git a/build.gradle b/build.gradle
index 658c32c3..5edbf4cc 100644
--- a/build.gradle
+++ b/build.gradle
@@ -67,6 +67,7 @@ dependencies {
compile "codechicken:CodeChickenLib:${config.minecraft_version}-${config.CCLIB_version}:dev"
compile "codechicken:CodeChickenCore:${config.minecraft_version}-${config.ccc_version}:dev"
compile "codechicken:NotEnoughItems:${config.minecraft_version}-${config.NEI_version}:dev"
+ compile "codechicken:ForgeMultipart:${config.minecraft_version}-${config.fmp_version}:dev"
//compile "mcp.mobius.waila:Waila:${config.waila_version}:dev"
deployerJars 'org.apache.maven.wagon:wagon-ssh:2.2'
}
diff --git a/build.properties b/build.properties
index 8e92d17e..5da4c5be 100644
--- a/build.properties
+++ b/build.properties
@@ -4,5 +4,6 @@ mantle_version=0.3.1.jenkins176
CCLIB_version=1.1.1.99
NEI_version=1.0.3.66
ccc_version=1.0.4.29
-mod_version=1.7.1
-waila_version=1.5.3_1.7.10
\ No newline at end of file
+mod_version=1.7.experimental
+waila_version=1.5.3_1.7.10
+fmp_version=1.1.0.314
\ No newline at end of file
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/lang/en_US.lang b/resources/assets/tinker/lang/en_US.lang
index 2143a9e0..a36e62bc 100644
--- a/resources/assets/tinker/lang/en_US.lang
+++ b/resources/assets/tinker/lang/en_US.lang
@@ -192,6 +192,10 @@ item.tconstruct.Pattern.fullguard.name=Full Guard Pattern
item.tconstruct.Pattern.bowstring.name=Bowstring Pattern
item.tconstruct.Pattern.fletching.name=Fletching Pattern
item.tconstruct.Pattern.arrowhead.name=Arrowhead Pattern
+item.tconstruct.Pattern.shuriken.name=Shuriken Pattern
+item.tconstruct.Pattern.crossbowlimb.name=Crossbow Limb Pattern
+item.tconstruct.Pattern.crossbowbody.name=Crossbow Body Pattern
+item.tconstruct.Pattern.bowlimb.name=Bow Limb Pattern
item.tconstruct.Pattern.blank_cast.name=Blank Cast
item.tconstruct.MetalPattern.rod.name=Tool Rod Cast
@@ -222,6 +226,10 @@ item.tconstruct.MetalPattern.arrowhead.name=Arrowhead Cast
item.tconstruct.MetalPattern.ingot.name=Ingot Cast
item.tconstruct.MetalPattern.gem.name=Gem Cast
item.tconstruct.MetalPattern.nugget.name=Nugget Cast
+item.tconstruct.MetalPattern.shuriken.name=Shuriken Cast
+item.tconstruct.MetalPattern.crossbowlimb.name=Crossbow Limb Cast
+item.tconstruct.MetalPattern.crossbowbody.name=Crossbow Body Cast
+item.tconstruct.MetalPattern.bowlimb.name=Bow Limb Cast
item.tconstruct.Materials.PaperStack.name=Paper Stack
item.tconstruct.Materials.SlimeCrystal.name=Slime Crystal
@@ -418,11 +426,13 @@ item.tconstruct.Fletching.feather.name=Feather Fletching
item.tconstruct.Fletching.leaf.name=Leaf Fletching
item.tconstruct.Fletching.slime.name=Slime Fletching
item.tconstruct.Fletching.blueslime.name=Slime Fletching
+item.tconstruct.Fletching.slimeleaf.name=Slimeleaf Fletching
item.tconstruct.manual.beginner.name=Materials and You: Volume 1
item.tconstruct.manual.toolstation.name=Materials and You: Volume 2
item.tconstruct.manual.smeltery.name=Mighty Smelting
item.tconstruct.manual.diary.name=Diary of a Tinker
+item.tconstruct.manual.weaponry.name=Tinkers' Weaponry
item.tconstruct.bucket.Iron.name=Molten Iron Bucket
item.tconstruct.bucket.Gold.name=Molten Gold Bucket
@@ -571,6 +581,11 @@ toolpart.HammerHead=%%material Hammer Head
toolpart.Bowstring=%%material Bowstring
toolpart.ArrowHead=%%material Arrowhead
toolpart.Fletching=%%material Fletching
+toolpart.Shuriken=%%material Shuriken
+toolpart.CrossbowLimb=%%material Crossbow Limb
+toolpart.CrossbowBody=%%material Crossbow Body
+toolpart.BowLimb=%%material Bow Limb
+toolpart.Bolt=%%material Bolt
# Now with translations of specific material and part combinations:
#toolpart.ToolRod.wood=Wooden Tool Rod
@@ -711,6 +726,7 @@ tconstruct.waila.subtanks=Subtanks:
tconstruct.waila.invalidstructure=Invalid structure
tconstruct.nei.toolmaterials=Tool Materials
+tconstruct.nei.projectilematerials=Bow & Arrow
tconstruct.nei.alloying=Smeltery Alloying
tconstruct.nei.castingbasin=Casting Basin
tconstruct.nei.castingtable=Casting Table
@@ -749,7 +765,7 @@ gui.toolstation6=Draw Speed:
gui.toolstation7=Arrow Speed:
gui.toolstation8=Weight:
gui.toolstation9=Accuracy:
-gui.toolstation10=Base Attack:
+gui.toolstation10=Base Damage:
gui.toolstation11=Shortbow Attack:
gui.toolstation12=Mining Speeds:
gui.toolstation13=Harvest Levels:
@@ -758,8 +774,11 @@ gui.toolstation15=Mining Level:
gui.toolstation16=Usage Speed:
gui.toolstation17=Modifiers
gui.toolstation18=Modifiers remaining:
-gui.toolstation19=Damage Reduction:
-gui.toolstation20=Protection:
+gui.toolstation19=Damage Reduction:
+gui.toolstation20=Protection:
+gui.toolstation21=Ammo:
+gui.toolstation22=Break Chance:
+gui.toolstation23=Max. Attack:
gui.mining1=Stone
gui.mining2=Iron
@@ -779,8 +798,6 @@ gui.toolstation.dagger.desc=The Dagger is a short blade that can be thrown.\n\nS
gui.toolstation.fryingpan.desc=The Frying Pan is a heavy weapon that uses sheer weight to stun foes.\n\nSpecial Ability: Block\nNatural Ability: Heavy\nShift+rClick: Place Frying Pan\nDamage: Low\nDurability: High\n\nRequired parts:\n- Pan\n- Handle
gui.toolstation.battlesign.desc=The Battlesign is an advance in weapon technology worthy of Zombie Pigmen everywhere.\n\nSpecial Ability:\nDamage Reflector\n\nNatural Ability: Writable\n\nDamage: Low\nDurability: Average
gui.toolstation.chisel.desc=The Chisel is a utility tool that carves shapes into blocks.\n\nCrafting Grid:\n- Shape Items\nSpecial Ability: Chisel\nDurability: Average\n\nRequired parts:\n- Chisel Head\n- Handle
-gui.toolstation.shortbow.desc=The Shortbow is a ranged weapon. It fires arrows quickly and precisely at its foes.\n\nDraw Speed: Quick\n\nRequired parts:\n- Tool Rod\n- Bowstring\n- Tool Rod
-gui.toolstation.arrow.desc=Arrows are projectiles usually fired from bows.\n\nRequired parts:\n- Arrowhead\n- Tool Rod\n- Fletching
gui.toolstation.hammer.desc=The Hammer is a broad mining tool. It harvests blocks in a wide range and is effective against undead.\n\nNatural Abilities:\nArea of Effect\n- (3x3)\n- Smite\n\nDurability: High
gui.toolstation.lumberaxe.desc=The Lumber Axe is a broad chopping tool. It can fell entire trees or gather wood in a wide range.\n\nNatural Abilities:\nArea of Effect\n- Fell Trees\n- (3x3x3)\n\nDurability: Average
gui.toolstation.excavator.desc=The Excavator is a broad digging tool. It harvests soil and snow in a wide range.\n\nNatural Ability:\n- Area of Effect\n- (3x3)\n\nDurability: Average
@@ -788,6 +805,16 @@ gui.toolstation.scythe.desc=The Scythe is a broad reaping tool. It is effective
gui.toolstation.cleaver.desc=The Cleaver is a heavy defensive weapon. It has powerful strikes, but is difficult to wield.\n\nSpecial Ability: Block\nNatural Ability:\n- Beheading\n\nDamage: High\nDurability: Average
gui.toolstation.battleaxe.desc=The Battleaxe is a heavy offensive weapon. It is capable of bringing down small trees and can send foes flying.\n\nSpecial Ability: Block\nNatural Abilities:\n- Knockback\n- Area of Effect\n- (1x9)\n\nDamage: Average\nDurability: Average
+gui.toolstation.shortbow.desc=The Shortbow is a ranged weapon. It fires arrows quickly and precisely at its foes.\n\nDraw Speed: Quick\n\nRequired parts:\n- Bow Limb\n- Bowstring\n- Bow Limb
+gui.toolstation.longbow.desc=The Longbow is a ranged weapon. It has greater range than a shortbow and is able to shoot heavier arrows, but performs worse with light arrows.\n\n Required parts:\n- Bow Limb\n- Bowstring\n- Bow Limb\n- Large Plate
+gui.toolstation.arrowammo.desc=Arrows are projectiles usually fired from bows.\n\nRequired parts:\n- Arrowhead\n- Tool Rod\n- Fletching
+gui.toolstation.crossbow.desc=The crossbow is a precise ranged weapon. It loads bolts, that are fired on trigger.\n\nSpecial Ability:\n- Reduced reload time with harder materials
+gui.toolstation.boltammo.desc=Bolts are projectiles fired from Crossbows.\n\nRequired Parts:\n- Bolt Core\n- Fletching\n\nBolt cores are obtained by pouring metal over a tool rod in a Casting Table.
+gui.toolstation.throwingknife.desc=Mid ranged throwing weapon. Hold to take aim, release to throw.\n\nDamage: Medium\nCapacity: Medium
+gui.toolstation.shuriken.desc=Short ranged throwing weapon. Thrown instantly.\n\nDamage: Low\nCapacity: High
+gui.toolstation.javelin.desc=Ranged Melee weapon hybrid. Potent as a melee weapon, devasting at range.\n\nDamage: High\nCapacity: Low
+
+
material.wood=Wood
material.wood.display=Wooden
material.stone=Stone
@@ -856,7 +883,8 @@ modifier.tool.beheading=Beheading
creativeModLock.tooltip=Target Lock:
-attribute.name.ammo.attackDamage=Average Shot Damage
+attribute.name.ammo.attackDamage=Base Damage
+attribute.name.ammo.maxAttackDamage=Max. Damage
tool.pickaxe=Pickaxe
tool.shovel=Shovel
@@ -877,7 +905,13 @@ tool.excavator=Excavator
tool.hammer=Hammer
tool.battleaxe=Battleaxe
tool.shortbow=Shortbow
-tool.arrow=Arrow
+tool.longbow=Longbow
+tool.crossbow=Crossbow
+tool.arrowammo=Arrows
+tool.boltammo=Bolts
+tool.shuriken=Shuriken
+tool.throwingknife=Throwing Knife
+tool.javelin=Javelin
# Customization of default tool names based on tool and material
#tool.shovel.wood=Wooden Shovel
diff --git a/resources/assets/tinker/manuals/en_US/weaponry.xml b/resources/assets/tinker/manuals/en_US/weaponry.xml
new file mode 100644
index 00000000..e030b512
--- /dev/null
+++ b/resources/assets/tinker/manuals/en_US/weaponry.xml
@@ -0,0 +1,144 @@
+
+
+
+
+Tinkers' Weaponry
+Brings the hurt whole new places
+
+By Sheriff Bownana
+
+
+
+Table of Contents
+
+ Introduction
+ weaponrybook
+ 3
+
+
+ Throwing Weapons
+ throwingknifeIcon
+ 5
+
+
+ Projectile Weapons
+ shortbowIcon
+ 7
+
+
+ Projectiles
+ arrowIcon
+ 10
+
+
+
+
+Why walk up to hit stuff, when you can do that while standing here!
+
+A tinkerer knows how to create varied ranged weapons. There are two big categories: Thrown weapons and weapons that shoot projectiles.
+
+Both types utilize an ammo system. Instead of having several items, these ranged weapons consist of one item that contains many of it. Why carry around 2 stacks of arrows, when you can have 200 in one stack!
+These Ammo-Items don't have a durability, but use up their ammo for each projectile thrown/shot.
+
+
+
+Throwing Weapons:
+* Throwing Knife
+* Shuriken
+* Javelin
+
+Projectile Weapons:
+* Shortbow
+* Longbow
+* Crossbow
+
+Projectiles:
+* Arrows
+* Bolts
+
+
+
+Throwing Weapons
+
+Throwing Knifes:
+These knifes are crafted from a knife blade and a handle.
+Hold rightclick to take aim, and release it to throw a knife.
+Throwing knifes stack up to a moderate amount, and deal moderate damage.
+
+Shuriken:
+Small delicate projectiles put together from 4 parts, that are thrown from the wrist. Because of this you don't need to take aim and can throw them directly.
+Since they're so small you can carry many of them, however they don't deal much damage.
+
+
+
+
+
+Javelin:
+This is a hybrid between a melee and a ranged weapon, consisting of an arrow head on two tough tool rods. It deals moderate damage as a melee weapon, but to unleash its true potential you have to throw it at your enemy.
+The throwing has a small windup. Because of their size you can only carry a few, but they pack a punch.
+
+
+
+Projectile Weapons
+
+Shortbow:
+Put together from two bow limbs and a bowstring, this weapon is a fast and handy bow. Keep in mind that inflexible materials like stone can hardly be drawn back and can't accelerate projectiles well. Organic materials are favoured for quick bows, while metals require lots of strengt to draw back, but provide more power.
+The bow requires arrows as ammo.
+Offensive modifiers on bows do not count for arrows. The only modifiers affecting its ranged performance are Redstone and lapis.
+
+
+
+
+
+Longbow:
+The big brother. This bow is much bigger, requiring more time to pull it back, but boy oh boy are those arrows fast.
+Because of this the longbow performs slightly better against armored targets. Furthermore this makes the longbow less accurate with very light arrows.
+The longbow is constructed from two bow limbs, a bowstring and a large plate.
+
+
+
+
+
+Crossbow:
+Those pesky metals are such a pain to pull back. Luckily a tinkerer knows how to help himself! The crossbow allows you to pre-load it with a bolt, and have it ready instantly to fire. Since this allows for much more power, it can shoot heavier projectiles, resulting in more damage and armor penetration.
+To load a crossbow simply rightclick and wait until the animation is done. The loading process can be stopped by pressing rightclick while sneaking. The crossbow can be unloaded in the same way.
+
+
+
+Projectiles
+For these projectiles goes: The heavier the projectile, the more damage carries through armor.
+
+Arrows:
+The bread and butter of every ranger. Arrows can be built from many different materials. It needs an arrow head, a shaft and a fletching.
+The choice of materials allows a balance between damage, arrow-count, accuracy and fragility. The head material is crucial for its weight.
+A fragile arrow has a chance to break on impact with terrain. Arrows always break when they hit a target, however the reinforced trait gives a chance for the arrow to survive the impact.
+
+
+
+
+
+Valid Shaft Materials:
+* Stick
+* Sugarcane
+* Bone
+* Blaze Rod
+
+Valid Fletching Materials:
+* Leaves
+* Slimeleaves
+* Feathers
+* Slime
+
+
+
+
+
+Bolts:
+Crafting bolts is a delicate process. First you need a core in the form of a tool rod.
+Take this tool rod to a smeltery and put it into a Casting Table. Pour some metal onto it to coat the tip with a more damaging material.
+After this process, add a fletching and your bolts are ready to be used.
+
+Since the bolts consist of a harder core and tip they carry more weight than regular arrows, making them perfect to fight armored targets.
+
+
+
\ No newline at end of file
diff --git a/resources/assets/tinker/sounds.json b/resources/assets/tinker/sounds.json
index 4374951c..af7090a4 100644
--- a/resources/assets/tinker/sounds.json
+++ b/resources/assets/tinker/sounds.json
@@ -16,5 +16,29 @@
"sounds": [
"launcher_clank"
]
+ },
+ "woodHit": {
+ "category": "block",
+ "sounds": [
+ "woodHit1",
+ "woodHit2",
+ "woodHit3",
+ "woodHit4",
+ "woodHit5"
+ ]
+ },
+ "stoneHit": {
+ "category": "block",
+ "sounds": [
+ "stoneHit1",
+ "stoneHit2",
+ "stoneHit3"
+ ]
+ },
+ "crossbowReload": {
+ "category": "neutral",
+ "sounds": [
+ "crossbowReload"
+ ]
}
}
\ No newline at end of file
diff --git a/resources/assets/tinker/sounds/Credits.txt b/resources/assets/tinker/sounds/Credits.txt
new file mode 100644
index 00000000..a22f86fa
--- /dev/null
+++ b/resources/assets/tinker/sounds/Credits.txt
@@ -0,0 +1,9 @@
+Stone-Hit:
+Pickaxe mining stone by ryanconway
+https://www.freesound.org/people/ryanconway/sounds/240801/
+metal falling on stone by p3n10
+https://www.freesound.org/people/p3n10/sounds/171294/
+
+Wood-Hit:
+Hitting Wood by altfuture
+https://www.freesound.org/people/altfuture/sounds/174633/
\ No newline at end of file
diff --git a/resources/assets/tinker/sounds/crossbowReload.ogg b/resources/assets/tinker/sounds/crossbowReload.ogg
new file mode 100644
index 00000000..32f37e65
Binary files /dev/null and b/resources/assets/tinker/sounds/crossbowReload.ogg differ
diff --git a/resources/assets/tinker/sounds/stoneHit1.ogg b/resources/assets/tinker/sounds/stoneHit1.ogg
new file mode 100644
index 00000000..04fe1bee
Binary files /dev/null and b/resources/assets/tinker/sounds/stoneHit1.ogg differ
diff --git a/resources/assets/tinker/sounds/stoneHit2.ogg b/resources/assets/tinker/sounds/stoneHit2.ogg
new file mode 100644
index 00000000..68ee1881
Binary files /dev/null and b/resources/assets/tinker/sounds/stoneHit2.ogg differ
diff --git a/resources/assets/tinker/sounds/stoneHit3.ogg b/resources/assets/tinker/sounds/stoneHit3.ogg
new file mode 100644
index 00000000..057eddfa
Binary files /dev/null and b/resources/assets/tinker/sounds/stoneHit3.ogg differ
diff --git a/resources/assets/tinker/sounds/woodHit1.ogg b/resources/assets/tinker/sounds/woodHit1.ogg
new file mode 100644
index 00000000..f978b0b8
Binary files /dev/null and b/resources/assets/tinker/sounds/woodHit1.ogg differ
diff --git a/resources/assets/tinker/sounds/woodHit2.ogg b/resources/assets/tinker/sounds/woodHit2.ogg
new file mode 100644
index 00000000..339ae097
Binary files /dev/null and b/resources/assets/tinker/sounds/woodHit2.ogg differ
diff --git a/resources/assets/tinker/sounds/woodHit3.ogg b/resources/assets/tinker/sounds/woodHit3.ogg
new file mode 100644
index 00000000..3b24d95b
Binary files /dev/null and b/resources/assets/tinker/sounds/woodHit3.ogg differ
diff --git a/resources/assets/tinker/sounds/woodHit4.ogg b/resources/assets/tinker/sounds/woodHit4.ogg
new file mode 100644
index 00000000..06279c66
Binary files /dev/null and b/resources/assets/tinker/sounds/woodHit4.ogg differ
diff --git a/resources/assets/tinker/sounds/woodHit5.ogg b/resources/assets/tinker/sounds/woodHit5.ogg
new file mode 100644
index 00000000..7b27b5f0
Binary files /dev/null and b/resources/assets/tinker/sounds/woodHit5.ogg differ
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..c0a0a8e4 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..2d49d531
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/slimeleaf_arrow_fletching.png b/resources/assets/tinker/textures/items/arrow/slimeleaf_arrow_fletching.png
new file mode 100644
index 00000000..0246e41a
Binary files /dev/null and b/resources/assets/tinker/textures/items/arrow/slimeleaf_arrow_fletching.png 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..e310f587 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/bolt/beheading_bolt_effect.png b/resources/assets/tinker/textures/items/bolt/beheading_bolt_effect.png
new file mode 100644
index 00000000..daa674fe
Binary files /dev/null and b/resources/assets/tinker/textures/items/bolt/beheading_bolt_effect.png differ
diff --git a/resources/assets/tinker/textures/items/bolt/blaze_bolt_effect.png b/resources/assets/tinker/textures/items/bolt/blaze_bolt_effect.png
new file mode 100644
index 00000000..1c506a3f
Binary files /dev/null and b/resources/assets/tinker/textures/items/bolt/blaze_bolt_effect.png differ
diff --git a/resources/assets/tinker/textures/items/bolt/complete.xcf b/resources/assets/tinker/textures/items/bolt/complete.xcf
new file mode 100644
index 00000000..ad50c0cf
Binary files /dev/null and b/resources/assets/tinker/textures/items/bolt/complete.xcf differ
diff --git a/resources/assets/tinker/textures/items/bolt/diamond_bolt_effect.png b/resources/assets/tinker/textures/items/bolt/diamond_bolt_effect.png
new file mode 100644
index 00000000..b9b340a9
Binary files /dev/null and b/resources/assets/tinker/textures/items/bolt/diamond_bolt_effect.png differ
diff --git a/resources/assets/tinker/textures/items/bolt/emerald_bolt_effect.png b/resources/assets/tinker/textures/items/bolt/emerald_bolt_effect.png
new file mode 100644
index 00000000..1fcca360
Binary files /dev/null and b/resources/assets/tinker/textures/items/bolt/emerald_bolt_effect.png differ
diff --git a/resources/assets/tinker/textures/items/bolt/lapis_bolt_effect.png b/resources/assets/tinker/textures/items/bolt/lapis_bolt_effect.png
new file mode 100644
index 00000000..703b698d
Binary files /dev/null and b/resources/assets/tinker/textures/items/bolt/lapis_bolt_effect.png differ
diff --git a/resources/assets/tinker/textures/items/bolt/lava_bolt_effect.png b/resources/assets/tinker/textures/items/bolt/lava_bolt_effect.png
new file mode 100644
index 00000000..cd04cca7
Binary files /dev/null and b/resources/assets/tinker/textures/items/bolt/lava_bolt_effect.png differ
diff --git a/resources/assets/tinker/textures/items/bolt/moss_bolt_effect.png b/resources/assets/tinker/textures/items/bolt/moss_bolt_effect.png
new file mode 100644
index 00000000..9a69cf1c
Binary files /dev/null and b/resources/assets/tinker/textures/items/bolt/moss_bolt_effect.png differ
diff --git a/resources/assets/tinker/textures/items/bolt/necrotic_bolt_effect.png b/resources/assets/tinker/textures/items/bolt/necrotic_bolt_effect.png
new file mode 100644
index 00000000..fedf3872
Binary files /dev/null and b/resources/assets/tinker/textures/items/bolt/necrotic_bolt_effect.png differ
diff --git a/resources/assets/tinker/textures/items/bolt/piston_bolt_effect.png b/resources/assets/tinker/textures/items/bolt/piston_bolt_effect.png
new file mode 100644
index 00000000..d448f532
Binary files /dev/null and b/resources/assets/tinker/textures/items/bolt/piston_bolt_effect.png differ
diff --git a/resources/assets/tinker/textures/items/bolt/quartz_bolt_effect.png b/resources/assets/tinker/textures/items/bolt/quartz_bolt_effect.png
new file mode 100644
index 00000000..00171742
Binary files /dev/null and b/resources/assets/tinker/textures/items/bolt/quartz_bolt_effect.png differ
diff --git a/resources/assets/tinker/textures/items/bolt/reinforced_bolt_effect.png b/resources/assets/tinker/textures/items/bolt/reinforced_bolt_effect.png
new file mode 100644
index 00000000..dfd1310b
Binary files /dev/null and b/resources/assets/tinker/textures/items/bolt/reinforced_bolt_effect.png differ
diff --git a/resources/assets/tinker/textures/items/bolt/silk_bolt_effect.png b/resources/assets/tinker/textures/items/bolt/silk_bolt_effect.png
new file mode 100644
index 00000000..05cb4b20
Binary files /dev/null and b/resources/assets/tinker/textures/items/bolt/silk_bolt_effect.png differ
diff --git a/resources/assets/tinker/textures/items/bolt/smite_bolt_effect.png b/resources/assets/tinker/textures/items/bolt/smite_bolt_effect.png
new file mode 100644
index 00000000..2e93179e
Binary files /dev/null and b/resources/assets/tinker/textures/items/bolt/smite_bolt_effect.png differ
diff --git a/resources/assets/tinker/textures/items/bolt/spider_bolt_effect.png b/resources/assets/tinker/textures/items/bolt/spider_bolt_effect.png
new file mode 100644
index 00000000..b9b5d1fb
Binary files /dev/null and b/resources/assets/tinker/textures/items/bolt/spider_bolt_effect.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..9de2a1db
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..4aedfb9e
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..2f7782ff
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..e4ffa75a
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..810abf2c
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..e7e9d892
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/crossbow/beheading_crossbow_effect.png b/resources/assets/tinker/textures/items/crossbow/beheading_crossbow_effect.png
new file mode 100644
index 00000000..18b16506
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/beheading_crossbow_effect.png differ
diff --git a/resources/assets/tinker/textures/items/crossbow/complete.xcf b/resources/assets/tinker/textures/items/crossbow/complete.xcf
new file mode 100644
index 00000000..0c5e75b3
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/complete.xcf differ
diff --git a/resources/assets/tinker/textures/items/crossbow/complete_1.xcf b/resources/assets/tinker/textures/items/crossbow/complete_1.xcf
new file mode 100644
index 00000000..58524bc7
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/complete_1.xcf differ
diff --git a/resources/assets/tinker/textures/items/crossbow/complete_2.xcf b/resources/assets/tinker/textures/items/crossbow/complete_2.xcf
new file mode 100644
index 00000000..abb57094
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/complete_2.xcf differ
diff --git a/resources/assets/tinker/textures/items/crossbow/complete_3.xcf b/resources/assets/tinker/textures/items/crossbow/complete_3.xcf
new file mode 100644
index 00000000..3517fb2e
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/complete_3.xcf differ
diff --git a/resources/assets/tinker/textures/items/crossbow/diamond_crossbow_effect.png b/resources/assets/tinker/textures/items/crossbow/diamond_crossbow_effect.png
new file mode 100644
index 00000000..6da1a0de
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/diamond_crossbow_effect.png differ
diff --git a/resources/assets/tinker/textures/items/crossbow/emerald_crossbow_effect.png b/resources/assets/tinker/textures/items/crossbow/emerald_crossbow_effect.png
new file mode 100644
index 00000000..7e1af109
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/emerald_crossbow_effect.png differ
diff --git a/resources/assets/tinker/textures/items/crossbow/emerald_crossbow_effect_1.png b/resources/assets/tinker/textures/items/crossbow/emerald_crossbow_effect_1.png
new file mode 100644
index 00000000..84376d9d
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/emerald_crossbow_effect_1.png differ
diff --git a/resources/assets/tinker/textures/items/crossbow/emerald_crossbow_effect_2.png b/resources/assets/tinker/textures/items/crossbow/emerald_crossbow_effect_2.png
new file mode 100644
index 00000000..2c8dc2b5
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/emerald_crossbow_effect_2.png differ
diff --git a/resources/assets/tinker/textures/items/crossbow/emerald_crossbow_effect_3.png b/resources/assets/tinker/textures/items/crossbow/emerald_crossbow_effect_3.png
new file mode 100644
index 00000000..7a086ec5
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/emerald_crossbow_effect_3.png differ
diff --git a/resources/assets/tinker/textures/items/crossbow/flux_crossbow_effect.png b/resources/assets/tinker/textures/items/crossbow/flux_crossbow_effect.png
new file mode 100644
index 00000000..4d258a7b
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/flux_crossbow_effect.png differ
diff --git a/resources/assets/tinker/textures/items/crossbow/lapis_crossbow_effect.png b/resources/assets/tinker/textures/items/crossbow/lapis_crossbow_effect.png
new file mode 100644
index 00000000..478f04a0
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/lapis_crossbow_effect.png differ
diff --git a/resources/assets/tinker/textures/items/crossbow/lava_crossbow_effect.png b/resources/assets/tinker/textures/items/crossbow/lava_crossbow_effect.png
new file mode 100644
index 00000000..2ff8e39e
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/lava_crossbow_effect.png differ
diff --git a/resources/assets/tinker/textures/items/crossbow/necrotic_crossbow_effect.png b/resources/assets/tinker/textures/items/crossbow/necrotic_crossbow_effect.png
new file mode 100644
index 00000000..9edc57e5
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/necrotic_crossbow_effect.png differ
diff --git a/resources/assets/tinker/textures/items/crossbow/piston_crossbow_effect.png b/resources/assets/tinker/textures/items/crossbow/piston_crossbow_effect.png
new file mode 100644
index 00000000..5d48bb5a
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/piston_crossbow_effect.png differ
diff --git a/resources/assets/tinker/textures/items/crossbow/quartz_crossbow_effect.png b/resources/assets/tinker/textures/items/crossbow/quartz_crossbow_effect.png
new file mode 100644
index 00000000..6ab7c238
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/quartz_crossbow_effect.png differ
diff --git a/resources/assets/tinker/textures/items/crossbow/quartz_crossbow_effect_1.png b/resources/assets/tinker/textures/items/crossbow/quartz_crossbow_effect_1.png
new file mode 100644
index 00000000..9dd3776f
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/quartz_crossbow_effect_1.png differ
diff --git a/resources/assets/tinker/textures/items/crossbow/quartz_crossbow_effect_2.png b/resources/assets/tinker/textures/items/crossbow/quartz_crossbow_effect_2.png
new file mode 100644
index 00000000..898f4021
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/quartz_crossbow_effect_2.png differ
diff --git a/resources/assets/tinker/textures/items/crossbow/quartz_crossbow_effect_3.png b/resources/assets/tinker/textures/items/crossbow/quartz_crossbow_effect_3.png
new file mode 100644
index 00000000..dc9f5b7b
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/quartz_crossbow_effect_3.png differ
diff --git a/resources/assets/tinker/textures/items/crossbow/redstone_crossbow_effect.png b/resources/assets/tinker/textures/items/crossbow/redstone_crossbow_effect.png
new file mode 100644
index 00000000..ebff98e7
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/redstone_crossbow_effect.png differ
diff --git a/resources/assets/tinker/textures/items/crossbow/redstone_crossbow_effect_1.png b/resources/assets/tinker/textures/items/crossbow/redstone_crossbow_effect_1.png
new file mode 100644
index 00000000..e36d6979
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/redstone_crossbow_effect_1.png differ
diff --git a/resources/assets/tinker/textures/items/crossbow/redstone_crossbow_effect_2.png b/resources/assets/tinker/textures/items/crossbow/redstone_crossbow_effect_2.png
new file mode 100644
index 00000000..5d6b61d0
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/redstone_crossbow_effect_2.png differ
diff --git a/resources/assets/tinker/textures/items/crossbow/redstone_crossbow_effect_3.png b/resources/assets/tinker/textures/items/crossbow/redstone_crossbow_effect_3.png
new file mode 100644
index 00000000..a34f368a
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/redstone_crossbow_effect_3.png differ
diff --git a/resources/assets/tinker/textures/items/crossbow/reinforced_crossbow_effect.png b/resources/assets/tinker/textures/items/crossbow/reinforced_crossbow_effect.png
new file mode 100644
index 00000000..e722b760
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/reinforced_crossbow_effect.png differ
diff --git a/resources/assets/tinker/textures/items/crossbow/silk_crossbow_effect.png b/resources/assets/tinker/textures/items/crossbow/silk_crossbow_effect.png
new file mode 100644
index 00000000..2b3faf1c
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/silk_crossbow_effect.png differ
diff --git a/resources/assets/tinker/textures/items/crossbow/smite_crossbow_effect.png b/resources/assets/tinker/textures/items/crossbow/smite_crossbow_effect.png
new file mode 100644
index 00000000..12722c50
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/smite_crossbow_effect.png differ
diff --git a/resources/assets/tinker/textures/items/crossbow/spider_crossbow_effect.png b/resources/assets/tinker/textures/items/crossbow/spider_crossbow_effect.png
new file mode 100644
index 00000000..66bb964c
Binary files /dev/null and b/resources/assets/tinker/textures/items/crossbow/spider_crossbow_effect.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/javelin/_javelin_head_broken.png b/resources/assets/tinker/textures/items/javelin/_javelin_head_broken.png
new file mode 100644
index 00000000..116f7485
Binary files /dev/null and b/resources/assets/tinker/textures/items/javelin/_javelin_head_broken.png differ
diff --git a/resources/assets/tinker/textures/items/javelin/beheading_javelin_effect.png b/resources/assets/tinker/textures/items/javelin/beheading_javelin_effect.png
new file mode 100644
index 00000000..8d0371aa
Binary files /dev/null and b/resources/assets/tinker/textures/items/javelin/beheading_javelin_effect.png differ
diff --git a/resources/assets/tinker/textures/items/javelin/blaze_javelin_effect.png b/resources/assets/tinker/textures/items/javelin/blaze_javelin_effect.png
new file mode 100644
index 00000000..83390104
Binary files /dev/null and b/resources/assets/tinker/textures/items/javelin/blaze_javelin_effect.png differ
diff --git a/resources/assets/tinker/textures/items/javelin/complete.xcf b/resources/assets/tinker/textures/items/javelin/complete.xcf
new file mode 100644
index 00000000..db4373ee
Binary files /dev/null and b/resources/assets/tinker/textures/items/javelin/complete.xcf differ
diff --git a/resources/assets/tinker/textures/items/javelin/diamond_javelin_effect.png b/resources/assets/tinker/textures/items/javelin/diamond_javelin_effect.png
new file mode 100644
index 00000000..133d4269
Binary files /dev/null and b/resources/assets/tinker/textures/items/javelin/diamond_javelin_effect.png differ
diff --git a/resources/assets/tinker/textures/items/javelin/emerald_javelin_effect.png b/resources/assets/tinker/textures/items/javelin/emerald_javelin_effect.png
new file mode 100644
index 00000000..061e97d0
Binary files /dev/null and b/resources/assets/tinker/textures/items/javelin/emerald_javelin_effect.png differ
diff --git a/resources/assets/tinker/textures/items/javelin/lapis_javelin_effect.png b/resources/assets/tinker/textures/items/javelin/lapis_javelin_effect.png
new file mode 100644
index 00000000..eb932c56
Binary files /dev/null and b/resources/assets/tinker/textures/items/javelin/lapis_javelin_effect.png differ
diff --git a/resources/assets/tinker/textures/items/javelin/lava_javelin_effect.png b/resources/assets/tinker/textures/items/javelin/lava_javelin_effect.png
new file mode 100644
index 00000000..e8b98edf
Binary files /dev/null and b/resources/assets/tinker/textures/items/javelin/lava_javelin_effect.png differ
diff --git a/resources/assets/tinker/textures/items/javelin/moss_javelin_effect.png b/resources/assets/tinker/textures/items/javelin/moss_javelin_effect.png
new file mode 100644
index 00000000..984b4087
Binary files /dev/null and b/resources/assets/tinker/textures/items/javelin/moss_javelin_effect.png differ
diff --git a/resources/assets/tinker/textures/items/javelin/necrotic_javelin_effect.png b/resources/assets/tinker/textures/items/javelin/necrotic_javelin_effect.png
new file mode 100644
index 00000000..bedeb37c
Binary files /dev/null and b/resources/assets/tinker/textures/items/javelin/necrotic_javelin_effect.png differ
diff --git a/resources/assets/tinker/textures/items/javelin/pigiron_javelin_head.png b/resources/assets/tinker/textures/items/javelin/pigiron_javelin_head.png
new file mode 100644
index 00000000..2eb03334
Binary files /dev/null and b/resources/assets/tinker/textures/items/javelin/pigiron_javelin_head.png differ
diff --git a/resources/assets/tinker/textures/items/javelin/piston_javelin_effect.png b/resources/assets/tinker/textures/items/javelin/piston_javelin_effect.png
new file mode 100644
index 00000000..d14a2e49
Binary files /dev/null and b/resources/assets/tinker/textures/items/javelin/piston_javelin_effect.png differ
diff --git a/resources/assets/tinker/textures/items/javelin/quartz_javelin_effect.png b/resources/assets/tinker/textures/items/javelin/quartz_javelin_effect.png
new file mode 100644
index 00000000..1e248670
Binary files /dev/null and b/resources/assets/tinker/textures/items/javelin/quartz_javelin_effect.png differ
diff --git a/resources/assets/tinker/textures/items/javelin/reinforced_javelin_effect.png b/resources/assets/tinker/textures/items/javelin/reinforced_javelin_effect.png
new file mode 100644
index 00000000..a5dea6c5
Binary files /dev/null and b/resources/assets/tinker/textures/items/javelin/reinforced_javelin_effect.png differ
diff --git a/resources/assets/tinker/textures/items/javelin/silk_javelin_effect.png b/resources/assets/tinker/textures/items/javelin/silk_javelin_effect.png
new file mode 100644
index 00000000..991cc3f8
Binary files /dev/null and b/resources/assets/tinker/textures/items/javelin/silk_javelin_effect.png differ
diff --git a/resources/assets/tinker/textures/items/javelin/smite_javelin_effect.png b/resources/assets/tinker/textures/items/javelin/smite_javelin_effect.png
new file mode 100644
index 00000000..468821c1
Binary files /dev/null and b/resources/assets/tinker/textures/items/javelin/smite_javelin_effect.png differ
diff --git a/resources/assets/tinker/textures/items/javelin/spider_javelin_effect.png b/resources/assets/tinker/textures/items/javelin/spider_javelin_effect.png
new file mode 100644
index 00000000..9c8fbc77
Binary files /dev/null and b/resources/assets/tinker/textures/items/javelin/spider_javelin_effect.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..d4e08f37
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..099bca21
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..d6681c65
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..8ea15279
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..70cb036f
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/_bowstring_broken.png differ
diff --git a/resources/assets/tinker/textures/items/shortbow/beheading_bow_effect_1.png b/resources/assets/tinker/textures/items/longbow/beheading_bow_effect.png
similarity index 100%
rename from resources/assets/tinker/textures/items/shortbow/beheading_bow_effect_1.png
rename to resources/assets/tinker/textures/items/longbow/beheading_bow_effect.png
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..0ebca956
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/complete.xcf differ
diff --git a/resources/assets/tinker/textures/items/longbow/diamond_bow_effect.png b/resources/assets/tinker/textures/items/longbow/diamond_bow_effect.png
new file mode 100644
index 00000000..288df910
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/diamond_bow_effect.png differ
diff --git a/resources/assets/tinker/textures/items/shortbow/emerald_bow_effect_1.png b/resources/assets/tinker/textures/items/longbow/emerald_bow_effect.png
similarity index 100%
rename from resources/assets/tinker/textures/items/shortbow/emerald_bow_effect_1.png
rename to resources/assets/tinker/textures/items/longbow/emerald_bow_effect.png
diff --git a/resources/assets/tinker/textures/items/shortbow/flux_bow_effect_1.png b/resources/assets/tinker/textures/items/longbow/flux_bow_effect.png
similarity index 100%
rename from resources/assets/tinker/textures/items/shortbow/flux_bow_effect_1.png
rename to resources/assets/tinker/textures/items/longbow/flux_bow_effect.png
diff --git a/resources/assets/tinker/textures/items/longbow/ice_bow_effect.png b/resources/assets/tinker/textures/items/longbow/ice_bow_effect.png
new file mode 100644
index 00000000..1b950f37
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/ice_bow_effect.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/ice_bow_effect_1.png b/resources/assets/tinker/textures/items/longbow/ice_bow_effect_1.png
new file mode 100644
index 00000000..1b950f37
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/ice_bow_effect_1.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/ice_bow_effect_2.png b/resources/assets/tinker/textures/items/longbow/ice_bow_effect_2.png
new file mode 100644
index 00000000..bde2464b
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/ice_bow_effect_2.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/ice_bow_effect_3.png b/resources/assets/tinker/textures/items/longbow/ice_bow_effect_3.png
new file mode 100644
index 00000000..bde2464b
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/ice_bow_effect_3.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/lapis_bow_effect.png b/resources/assets/tinker/textures/items/longbow/lapis_bow_effect.png
new file mode 100644
index 00000000..e2e28d61
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/lapis_bow_effect.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/lapis_bow_effect_1.png b/resources/assets/tinker/textures/items/longbow/lapis_bow_effect_1.png
new file mode 100644
index 00000000..98eb7dc6
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/lapis_bow_effect_1.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/lapis_bow_effect_2.png b/resources/assets/tinker/textures/items/longbow/lapis_bow_effect_2.png
new file mode 100644
index 00000000..7aea1599
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/lapis_bow_effect_2.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/lapis_bow_effect_3.png b/resources/assets/tinker/textures/items/longbow/lapis_bow_effect_3.png
new file mode 100644
index 00000000..e140341d
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/lapis_bow_effect_3.png differ
diff --git a/resources/assets/tinker/textures/items/shortbow/lava_bow_effect_1.png b/resources/assets/tinker/textures/items/longbow/lava_bow_effect.png
similarity index 100%
rename from resources/assets/tinker/textures/items/shortbow/lava_bow_effect_1.png
rename to resources/assets/tinker/textures/items/longbow/lava_bow_effect.png
diff --git a/resources/assets/tinker/textures/items/longbow/moss_bow_effect.png b/resources/assets/tinker/textures/items/longbow/moss_bow_effect.png
new file mode 100644
index 00000000..a8b74265
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/moss_bow_effect.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/moss_bow_effect_1.png b/resources/assets/tinker/textures/items/longbow/moss_bow_effect_1.png
new file mode 100644
index 00000000..88925a01
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/moss_bow_effect_1.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/moss_bow_effect_2.png b/resources/assets/tinker/textures/items/longbow/moss_bow_effect_2.png
new file mode 100644
index 00000000..9ce3c7f3
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/moss_bow_effect_2.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/moss_bow_effect_3.png b/resources/assets/tinker/textures/items/longbow/moss_bow_effect_3.png
new file mode 100644
index 00000000..57a14586
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/moss_bow_effect_3.png differ
diff --git a/resources/assets/tinker/textures/items/shortbow/necrotic_bow_effect_1.png b/resources/assets/tinker/textures/items/longbow/necrotic_bow_effect.png
similarity index 100%
rename from resources/assets/tinker/textures/items/shortbow/necrotic_bow_effect_1.png
rename to resources/assets/tinker/textures/items/longbow/necrotic_bow_effect.png
diff --git a/resources/assets/tinker/textures/items/shortbow/piston_bow_effect_1.png b/resources/assets/tinker/textures/items/longbow/piston_bow_effect.png
similarity index 100%
rename from resources/assets/tinker/textures/items/shortbow/piston_bow_effect_1.png
rename to resources/assets/tinker/textures/items/longbow/piston_bow_effect.png
diff --git a/resources/assets/tinker/textures/items/longbow/quartz_bow_effect.png b/resources/assets/tinker/textures/items/longbow/quartz_bow_effect.png
new file mode 100644
index 00000000..861f9944
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/quartz_bow_effect.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/quartz_bow_effect_1.png b/resources/assets/tinker/textures/items/longbow/quartz_bow_effect_1.png
new file mode 100644
index 00000000..861f9944
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/quartz_bow_effect_1.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/quartz_bow_effect_2.png b/resources/assets/tinker/textures/items/longbow/quartz_bow_effect_2.png
new file mode 100644
index 00000000..4e99eac5
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/quartz_bow_effect_2.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/quartz_bow_effect_3.png b/resources/assets/tinker/textures/items/longbow/quartz_bow_effect_3.png
new file mode 100644
index 00000000..ab6564e9
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/quartz_bow_effect_3.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/redstone_bow_effect.png b/resources/assets/tinker/textures/items/longbow/redstone_bow_effect.png
new file mode 100644
index 00000000..5cbf7e06
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/redstone_bow_effect.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/redstone_bow_effect_1.png b/resources/assets/tinker/textures/items/longbow/redstone_bow_effect_1.png
new file mode 100644
index 00000000..8cbb9024
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/redstone_bow_effect_1.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/redstone_bow_effect_2.png b/resources/assets/tinker/textures/items/longbow/redstone_bow_effect_2.png
new file mode 100644
index 00000000..166995a8
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/redstone_bow_effect_2.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/redstone_bow_effect_3.png b/resources/assets/tinker/textures/items/longbow/redstone_bow_effect_3.png
new file mode 100644
index 00000000..97e54a7d
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/redstone_bow_effect_3.png differ
diff --git a/resources/assets/tinker/textures/items/shortbow/reinforced_bow_effect_1.png b/resources/assets/tinker/textures/items/longbow/reinforced_bow_effect.png
similarity index 100%
rename from resources/assets/tinker/textures/items/shortbow/reinforced_bow_effect_1.png
rename to resources/assets/tinker/textures/items/longbow/reinforced_bow_effect.png
diff --git a/resources/assets/tinker/textures/items/longbow/silk_bow_effect.png b/resources/assets/tinker/textures/items/longbow/silk_bow_effect.png
new file mode 100644
index 00000000..bfc83c8f
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/silk_bow_effect.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/silk_bow_effect_1.png b/resources/assets/tinker/textures/items/longbow/silk_bow_effect_1.png
new file mode 100644
index 00000000..bfc83c8f
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/silk_bow_effect_1.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/silk_bow_effect_2.png b/resources/assets/tinker/textures/items/longbow/silk_bow_effect_2.png
new file mode 100644
index 00000000..e62b5a45
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/silk_bow_effect_2.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/silk_bow_effect_3.png b/resources/assets/tinker/textures/items/longbow/silk_bow_effect_3.png
new file mode 100644
index 00000000..6e5da9bd
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/silk_bow_effect_3.png differ
diff --git a/resources/assets/tinker/textures/items/shortbow/smite_bow_effect_1.png b/resources/assets/tinker/textures/items/longbow/smite_bow_effect.png
similarity index 100%
rename from resources/assets/tinker/textures/items/shortbow/smite_bow_effect_1.png
rename to resources/assets/tinker/textures/items/longbow/smite_bow_effect.png
diff --git a/resources/assets/tinker/textures/items/longbow/spider_bow_effect.png b/resources/assets/tinker/textures/items/longbow/spider_bow_effect.png
new file mode 100644
index 00000000..6b12a3c1
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/spider_bow_effect.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/spider_bow_effect_1.png b/resources/assets/tinker/textures/items/longbow/spider_bow_effect_1.png
new file mode 100644
index 00000000..6b12a3c1
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/spider_bow_effect_1.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/spider_bow_effect_2.png b/resources/assets/tinker/textures/items/longbow/spider_bow_effect_2.png
new file mode 100644
index 00000000..c474a568
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/spider_bow_effect_2.png differ
diff --git a/resources/assets/tinker/textures/items/longbow/spider_bow_effect_3.png b/resources/assets/tinker/textures/items/longbow/spider_bow_effect_3.png
new file mode 100644
index 00000000..dd07a1f7
Binary files /dev/null and b/resources/assets/tinker/textures/items/longbow/spider_bow_effect_3.png 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/slimeleaf_fletching.png b/resources/assets/tinker/textures/items/parts/slimeleaf_fletching.png
new file mode 100644
index 00000000..726b9c1b
Binary files /dev/null and b/resources/assets/tinker/textures/items/parts/slimeleaf_fletching.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..6c193029 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..1bfb1105 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..2c1fa344 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..e7793eb7 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..722baa87 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/shortbow/beheading_bow_effect_2.png b/resources/assets/tinker/textures/items/shortbow/beheading_bow_effect_2.png
deleted file mode 100644
index 440a4306..00000000
Binary files a/resources/assets/tinker/textures/items/shortbow/beheading_bow_effect_2.png and /dev/null differ
diff --git a/resources/assets/tinker/textures/items/shortbow/beheading_bow_effect_3.png b/resources/assets/tinker/textures/items/shortbow/beheading_bow_effect_3.png
deleted file mode 100644
index 440a4306..00000000
Binary files a/resources/assets/tinker/textures/items/shortbow/beheading_bow_effect_3.png and /dev/null differ
diff --git a/resources/assets/tinker/textures/items/shortbow/diamond_bow_effect_1.png b/resources/assets/tinker/textures/items/shortbow/diamond_bow_effect_1.png
deleted file mode 100644
index 8e818f54..00000000
Binary files a/resources/assets/tinker/textures/items/shortbow/diamond_bow_effect_1.png and /dev/null differ
diff --git a/resources/assets/tinker/textures/items/shortbow/diamond_bow_effect_2.png b/resources/assets/tinker/textures/items/shortbow/diamond_bow_effect_2.png
deleted file mode 100644
index 8e818f54..00000000
Binary files a/resources/assets/tinker/textures/items/shortbow/diamond_bow_effect_2.png and /dev/null differ
diff --git a/resources/assets/tinker/textures/items/shortbow/diamond_bow_effect_3.png b/resources/assets/tinker/textures/items/shortbow/diamond_bow_effect_3.png
deleted file mode 100644
index 8e818f54..00000000
Binary files a/resources/assets/tinker/textures/items/shortbow/diamond_bow_effect_3.png and /dev/null differ
diff --git a/resources/assets/tinker/textures/items/shortbow/emerald_bow_effect_2.png b/resources/assets/tinker/textures/items/shortbow/emerald_bow_effect_2.png
deleted file mode 100644
index fedf64cb..00000000
Binary files a/resources/assets/tinker/textures/items/shortbow/emerald_bow_effect_2.png and /dev/null differ
diff --git a/resources/assets/tinker/textures/items/shortbow/emerald_bow_effect_3.png b/resources/assets/tinker/textures/items/shortbow/emerald_bow_effect_3.png
deleted file mode 100644
index fedf64cb..00000000
Binary files a/resources/assets/tinker/textures/items/shortbow/emerald_bow_effect_3.png and /dev/null differ
diff --git a/resources/assets/tinker/textures/items/shortbow/flux_bow_effect_2.png b/resources/assets/tinker/textures/items/shortbow/flux_bow_effect_2.png
deleted file mode 100644
index f0e6a660..00000000
Binary files a/resources/assets/tinker/textures/items/shortbow/flux_bow_effect_2.png and /dev/null differ
diff --git a/resources/assets/tinker/textures/items/shortbow/flux_bow_effect_3.png b/resources/assets/tinker/textures/items/shortbow/flux_bow_effect_3.png
deleted file mode 100644
index dd15a505..00000000
Binary files a/resources/assets/tinker/textures/items/shortbow/flux_bow_effect_3.png and /dev/null differ
diff --git a/resources/assets/tinker/textures/items/shortbow/lava_bow_effect_2.png b/resources/assets/tinker/textures/items/shortbow/lava_bow_effect_2.png
deleted file mode 100644
index 5650ccbe..00000000
Binary files a/resources/assets/tinker/textures/items/shortbow/lava_bow_effect_2.png and /dev/null differ
diff --git a/resources/assets/tinker/textures/items/shortbow/lava_bow_effect_3.png b/resources/assets/tinker/textures/items/shortbow/lava_bow_effect_3.png
deleted file mode 100644
index 5650ccbe..00000000
Binary files a/resources/assets/tinker/textures/items/shortbow/lava_bow_effect_3.png and /dev/null differ
diff --git a/resources/assets/tinker/textures/items/shortbow/necrotic_bow_effect_2.png b/resources/assets/tinker/textures/items/shortbow/necrotic_bow_effect_2.png
deleted file mode 100644
index 9e2dcc59..00000000
Binary files a/resources/assets/tinker/textures/items/shortbow/necrotic_bow_effect_2.png and /dev/null differ
diff --git a/resources/assets/tinker/textures/items/shortbow/necrotic_bow_effect_3.png b/resources/assets/tinker/textures/items/shortbow/necrotic_bow_effect_3.png
deleted file mode 100644
index 9e2dcc59..00000000
Binary files a/resources/assets/tinker/textures/items/shortbow/necrotic_bow_effect_3.png and /dev/null differ
diff --git a/resources/assets/tinker/textures/items/shortbow/piston_bow_effect_2.png b/resources/assets/tinker/textures/items/shortbow/piston_bow_effect_2.png
deleted file mode 100644
index cfaee27f..00000000
Binary files a/resources/assets/tinker/textures/items/shortbow/piston_bow_effect_2.png and /dev/null differ
diff --git a/resources/assets/tinker/textures/items/shortbow/piston_bow_effect_3.png b/resources/assets/tinker/textures/items/shortbow/piston_bow_effect_3.png
deleted file mode 100644
index cfaee27f..00000000
Binary files a/resources/assets/tinker/textures/items/shortbow/piston_bow_effect_3.png and /dev/null differ
diff --git a/resources/assets/tinker/textures/items/shortbow/redstone_bow_effect.png b/resources/assets/tinker/textures/items/shortbow/redstone_bow_effect.png
index ab1281dc..8c933a6d 100644
Binary files a/resources/assets/tinker/textures/items/shortbow/redstone_bow_effect.png and b/resources/assets/tinker/textures/items/shortbow/redstone_bow_effect.png differ
diff --git a/resources/assets/tinker/textures/items/shortbow/redstone_bow_effect_1.png b/resources/assets/tinker/textures/items/shortbow/redstone_bow_effect_1.png
index ed6f7f94..3fee6c02 100644
Binary files a/resources/assets/tinker/textures/items/shortbow/redstone_bow_effect_1.png and b/resources/assets/tinker/textures/items/shortbow/redstone_bow_effect_1.png differ
diff --git a/resources/assets/tinker/textures/items/shortbow/redstone_bow_effect_2.png b/resources/assets/tinker/textures/items/shortbow/redstone_bow_effect_2.png
index 20dc0252..166995a8 100644
Binary files a/resources/assets/tinker/textures/items/shortbow/redstone_bow_effect_2.png and b/resources/assets/tinker/textures/items/shortbow/redstone_bow_effect_2.png differ
diff --git a/resources/assets/tinker/textures/items/shortbow/redstone_bow_effect_3.png b/resources/assets/tinker/textures/items/shortbow/redstone_bow_effect_3.png
index e7e2ae99..97e54a7d 100644
Binary files a/resources/assets/tinker/textures/items/shortbow/redstone_bow_effect_3.png and b/resources/assets/tinker/textures/items/shortbow/redstone_bow_effect_3.png differ
diff --git a/resources/assets/tinker/textures/items/shortbow/reinforced_bow_effect_2.png b/resources/assets/tinker/textures/items/shortbow/reinforced_bow_effect_2.png
deleted file mode 100644
index 96767628..00000000
Binary files a/resources/assets/tinker/textures/items/shortbow/reinforced_bow_effect_2.png and /dev/null differ
diff --git a/resources/assets/tinker/textures/items/shortbow/reinforced_bow_effect_3.png b/resources/assets/tinker/textures/items/shortbow/reinforced_bow_effect_3.png
deleted file mode 100644
index 96767628..00000000
Binary files a/resources/assets/tinker/textures/items/shortbow/reinforced_bow_effect_3.png and /dev/null differ
diff --git a/resources/assets/tinker/textures/items/shortbow/smite_bow_effect_2.png b/resources/assets/tinker/textures/items/shortbow/smite_bow_effect_2.png
deleted file mode 100644
index 5f771c69..00000000
Binary files a/resources/assets/tinker/textures/items/shortbow/smite_bow_effect_2.png and /dev/null differ
diff --git a/resources/assets/tinker/textures/items/shortbow/smite_bow_effect_3.png b/resources/assets/tinker/textures/items/shortbow/smite_bow_effect_3.png
deleted file mode 100644
index 5f771c69..00000000
Binary files a/resources/assets/tinker/textures/items/shortbow/smite_bow_effect_3.png and /dev/null 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/beheading_shuriken_effect.png b/resources/assets/tinker/textures/items/shuriken/beheading_shuriken_effect.png
new file mode 100644
index 00000000..4512b6b1
Binary files /dev/null and b/resources/assets/tinker/textures/items/shuriken/beheading_shuriken_effect.png differ
diff --git a/resources/assets/tinker/textures/items/shuriken/blaze_shuriken_effect.png b/resources/assets/tinker/textures/items/shuriken/blaze_shuriken_effect.png
new file mode 100644
index 00000000..b30e46fa
Binary files /dev/null and b/resources/assets/tinker/textures/items/shuriken/blaze_shuriken_effect.png differ
diff --git a/resources/assets/tinker/textures/items/shuriken/complete.png b/resources/assets/tinker/textures/items/shuriken/complete.png
new file mode 100644
index 00000000..8cf85266
Binary files /dev/null and b/resources/assets/tinker/textures/items/shuriken/complete.png differ
diff --git a/resources/assets/tinker/textures/items/shuriken/complete.xcf b/resources/assets/tinker/textures/items/shuriken/complete.xcf
new file mode 100644
index 00000000..76cc35a7
Binary files /dev/null and b/resources/assets/tinker/textures/items/shuriken/complete.xcf differ
diff --git a/resources/assets/tinker/textures/items/shuriken/diamond_shuriken_effect.png b/resources/assets/tinker/textures/items/shuriken/diamond_shuriken_effect.png
new file mode 100644
index 00000000..78dea30d
Binary files /dev/null and b/resources/assets/tinker/textures/items/shuriken/diamond_shuriken_effect.png differ
diff --git a/resources/assets/tinker/textures/items/shuriken/emerald_shuriken_effect.png b/resources/assets/tinker/textures/items/shuriken/emerald_shuriken_effect.png
new file mode 100644
index 00000000..2591a9c2
Binary files /dev/null and b/resources/assets/tinker/textures/items/shuriken/emerald_shuriken_effect.png differ
diff --git a/resources/assets/tinker/textures/items/shuriken/lapis_shuriken_effect.png b/resources/assets/tinker/textures/items/shuriken/lapis_shuriken_effect.png
new file mode 100644
index 00000000..7423654d
Binary files /dev/null and b/resources/assets/tinker/textures/items/shuriken/lapis_shuriken_effect.png differ
diff --git a/resources/assets/tinker/textures/items/shuriken/lava_shuriken_effect.png b/resources/assets/tinker/textures/items/shuriken/lava_shuriken_effect.png
new file mode 100644
index 00000000..c00071a8
Binary files /dev/null and b/resources/assets/tinker/textures/items/shuriken/lava_shuriken_effect.png differ
diff --git a/resources/assets/tinker/textures/items/shuriken/moss_shuriken_effect.png b/resources/assets/tinker/textures/items/shuriken/moss_shuriken_effect.png
new file mode 100644
index 00000000..ec267b9d
Binary files /dev/null and b/resources/assets/tinker/textures/items/shuriken/moss_shuriken_effect.png differ
diff --git a/resources/assets/tinker/textures/items/shuriken/necrotic_shuriken_effect.png b/resources/assets/tinker/textures/items/shuriken/necrotic_shuriken_effect.png
new file mode 100644
index 00000000..ce3a0fd9
Binary files /dev/null and b/resources/assets/tinker/textures/items/shuriken/necrotic_shuriken_effect.png differ
diff --git a/resources/assets/tinker/textures/items/shuriken/piston_shuriken_effect.png b/resources/assets/tinker/textures/items/shuriken/piston_shuriken_effect.png
new file mode 100644
index 00000000..7942da50
Binary files /dev/null and b/resources/assets/tinker/textures/items/shuriken/piston_shuriken_effect.png differ
diff --git a/resources/assets/tinker/textures/items/shuriken/quartz_shuriken_effect.png b/resources/assets/tinker/textures/items/shuriken/quartz_shuriken_effect.png
new file mode 100644
index 00000000..518c35c2
Binary files /dev/null and b/resources/assets/tinker/textures/items/shuriken/quartz_shuriken_effect.png differ
diff --git a/resources/assets/tinker/textures/items/shuriken/reinforced_shuriken_effect.png b/resources/assets/tinker/textures/items/shuriken/reinforced_shuriken_effect.png
new file mode 100644
index 00000000..059b078e
Binary files /dev/null and b/resources/assets/tinker/textures/items/shuriken/reinforced_shuriken_effect.png differ
diff --git a/resources/assets/tinker/textures/items/shuriken/silk_shuriken_effect.png b/resources/assets/tinker/textures/items/shuriken/silk_shuriken_effect.png
new file mode 100644
index 00000000..34bf94e5
Binary files /dev/null and b/resources/assets/tinker/textures/items/shuriken/silk_shuriken_effect.png differ
diff --git a/resources/assets/tinker/textures/items/shuriken/smite_shuriken_effect.png b/resources/assets/tinker/textures/items/shuriken/smite_shuriken_effect.png
new file mode 100644
index 00000000..28d8327a
Binary files /dev/null and b/resources/assets/tinker/textures/items/shuriken/smite_shuriken_effect.png differ
diff --git a/resources/assets/tinker/textures/items/shuriken/spider_shuriken_effect.png b/resources/assets/tinker/textures/items/shuriken/spider_shuriken_effect.png
new file mode 100644
index 00000000..5e4e0d0c
Binary files /dev/null and b/resources/assets/tinker/textures/items/shuriken/spider_shuriken_effect.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/beheading_knife_effect.png b/resources/assets/tinker/textures/items/throwingknife/beheading_knife_effect.png
new file mode 100644
index 00000000..934c352b
Binary files /dev/null and b/resources/assets/tinker/textures/items/throwingknife/beheading_knife_effect.png differ
diff --git a/resources/assets/tinker/textures/items/throwingknife/blaze_knife_effect.png b/resources/assets/tinker/textures/items/throwingknife/blaze_knife_effect.png
new file mode 100644
index 00000000..e7468a74
Binary files /dev/null and b/resources/assets/tinker/textures/items/throwingknife/blaze_knife_effect.png differ
diff --git a/resources/assets/tinker/textures/items/throwingknife/complete.png b/resources/assets/tinker/textures/items/throwingknife/complete.png
new file mode 100644
index 00000000..989898d6
Binary files /dev/null and b/resources/assets/tinker/textures/items/throwingknife/complete.png differ
diff --git a/resources/assets/tinker/textures/items/throwingknife/complete.xcf b/resources/assets/tinker/textures/items/throwingknife/complete.xcf
new file mode 100644
index 00000000..a6726bff
Binary files /dev/null and b/resources/assets/tinker/textures/items/throwingknife/complete.xcf differ
diff --git a/resources/assets/tinker/textures/items/throwingknife/diamond_knife_effect.png b/resources/assets/tinker/textures/items/throwingknife/diamond_knife_effect.png
new file mode 100644
index 00000000..a010b129
Binary files /dev/null and b/resources/assets/tinker/textures/items/throwingknife/diamond_knife_effect.png differ
diff --git a/resources/assets/tinker/textures/items/throwingknife/emerald_knife_effect.png b/resources/assets/tinker/textures/items/throwingknife/emerald_knife_effect.png
new file mode 100644
index 00000000..043abdec
Binary files /dev/null and b/resources/assets/tinker/textures/items/throwingknife/emerald_knife_effect.png differ
diff --git a/resources/assets/tinker/textures/items/throwingknife/lapis_knife_effect.png b/resources/assets/tinker/textures/items/throwingknife/lapis_knife_effect.png
new file mode 100644
index 00000000..033fec0c
Binary files /dev/null and b/resources/assets/tinker/textures/items/throwingknife/lapis_knife_effect.png differ
diff --git a/resources/assets/tinker/textures/items/throwingknife/lava_knife_effect.png b/resources/assets/tinker/textures/items/throwingknife/lava_knife_effect.png
new file mode 100644
index 00000000..66f46344
Binary files /dev/null and b/resources/assets/tinker/textures/items/throwingknife/lava_knife_effect.png differ
diff --git a/resources/assets/tinker/textures/items/throwingknife/moss_knife_effect.png b/resources/assets/tinker/textures/items/throwingknife/moss_knife_effect.png
new file mode 100644
index 00000000..533cf719
Binary files /dev/null and b/resources/assets/tinker/textures/items/throwingknife/moss_knife_effect.png differ
diff --git a/resources/assets/tinker/textures/items/throwingknife/necrotic_knife_effect.png b/resources/assets/tinker/textures/items/throwingknife/necrotic_knife_effect.png
new file mode 100644
index 00000000..45aa51ab
Binary files /dev/null and b/resources/assets/tinker/textures/items/throwingknife/necrotic_knife_effect.png differ
diff --git a/resources/assets/tinker/textures/items/throwingknife/piston_knife_effect.png b/resources/assets/tinker/textures/items/throwingknife/piston_knife_effect.png
new file mode 100644
index 00000000..211a0662
Binary files /dev/null and b/resources/assets/tinker/textures/items/throwingknife/piston_knife_effect.png differ
diff --git a/resources/assets/tinker/textures/items/throwingknife/quartz_knife_effect.png b/resources/assets/tinker/textures/items/throwingknife/quartz_knife_effect.png
new file mode 100644
index 00000000..e7410047
Binary files /dev/null and b/resources/assets/tinker/textures/items/throwingknife/quartz_knife_effect.png differ
diff --git a/resources/assets/tinker/textures/items/throwingknife/reinforced_knife_effect.png b/resources/assets/tinker/textures/items/throwingknife/reinforced_knife_effect.png
new file mode 100644
index 00000000..10f23183
Binary files /dev/null and b/resources/assets/tinker/textures/items/throwingknife/reinforced_knife_effect.png differ
diff --git a/resources/assets/tinker/textures/items/throwingknife/silk_knife_effect.png b/resources/assets/tinker/textures/items/throwingknife/silk_knife_effect.png
new file mode 100644
index 00000000..f9477cc8
Binary files /dev/null and b/resources/assets/tinker/textures/items/throwingknife/silk_knife_effect.png differ
diff --git a/resources/assets/tinker/textures/items/throwingknife/smite_knife_effect.png b/resources/assets/tinker/textures/items/throwingknife/smite_knife_effect.png
new file mode 100644
index 00000000..6f206daa
Binary files /dev/null and b/resources/assets/tinker/textures/items/throwingknife/smite_knife_effect.png differ
diff --git a/resources/assets/tinker/textures/items/throwingknife/spider_knife_effect.png b/resources/assets/tinker/textures/items/throwingknife/spider_knife_effect.png
new file mode 100644
index 00000000..b512455e
Binary files /dev/null and b/resources/assets/tinker/textures/items/throwingknife/spider_knife_effect.png differ
diff --git a/src/main/java/tconstruct/TConstruct.java b/src/main/java/tconstruct/TConstruct.java
index 0f8fbe01..28da0e31 100644
--- a/src/main/java/tconstruct/TConstruct.java
+++ b/src/main/java/tconstruct/TConstruct.java
@@ -32,6 +32,7 @@ import tconstruct.library.crafting.LiquidCasting;
import tconstruct.mechworks.TinkerMechworks;
import tconstruct.mechworks.landmine.behavior.Behavior;
import tconstruct.mechworks.landmine.behavior.stackCombo.SpecialStackHandler;
+import tconstruct.plugins.fmp.TinkerFMP;
import tconstruct.plugins.ic2.TinkerIC2;
import tconstruct.plugins.imc.TinkerAE2;
import tconstruct.plugins.imc.TinkerBuildCraft;
@@ -47,6 +48,7 @@ import tconstruct.util.IMCHandler;
import tconstruct.util.config.DimensionBlacklist;
import tconstruct.util.config.PHConstruct;
import tconstruct.util.network.PacketPipeline;
+import tconstruct.weaponry.TinkerWeaponry;
import tconstruct.world.TinkerWorld;
import tconstruct.world.gen.SlimeIslandGen;
import tconstruct.world.village.*;
@@ -124,6 +126,7 @@ public class TConstruct
pulsar.registerPulse(new TinkerSmeltery());
pulsar.registerPulse(new TinkerMechworks());
pulsar.registerPulse(new TinkerArmor());
+ pulsar.registerPulse(new TinkerWeaponry());
pulsar.registerPulse(new TinkerThaumcraft());
pulsar.registerPulse(new TinkerWaila());
pulsar.registerPulse(new TinkerBuildCraft());
@@ -132,6 +135,7 @@ public class TConstruct
pulsar.registerPulse(new TinkerMystcraft());
pulsar.registerPulse(new TinkerMFR());
pulsar.registerPulse(new TinkerTE4());
+ pulsar.registerPulse(new TinkerFMP());
/*pulsar.registerPulse(new TinkerPrayers());
pulsar.registerPulse(new TinkerCropify());*/
@@ -140,6 +144,7 @@ public class TConstruct
TConstructRegistry.partTab = new TConstructCreativeTab("TConstructParts");
TConstructRegistry.blockTab = new TConstructCreativeTab("TConstructBlocks");
TConstructRegistry.equipableTab = new TConstructCreativeTab("TConstructEquipables");
+ TConstructRegistry.weaponryTab = new TConstructCreativeTab("TConstructWeaponry");
tableCasting = new LiquidCasting();
basinCasting = new LiquidCasting();
diff --git a/src/main/java/tconstruct/armor/ArmorAbilities.java b/src/main/java/tconstruct/armor/ArmorAbilities.java
index 0bd1ab34..b6a5661f 100644
--- a/src/main/java/tconstruct/armor/ArmorAbilities.java
+++ b/src/main/java/tconstruct/armor/ArmorAbilities.java
@@ -21,11 +21,6 @@ import tconstruct.util.network.HealthUpdatePacket;
public class ArmorAbilities
{
- //Abilities
- boolean morphed;
- boolean morphLoaded = Loader.isModLoaded("Morph");
- boolean smartmoveLoaded = Loader.isModLoaded("SmartMoving");
-
public static List stepBoostedPlayers = new ArrayList();
//ItemStack prevFeet;
double prevMotionY;
@@ -91,34 +86,6 @@ public class ArmorAbilities
{
stack.getItem().onUpdate(stack, player.worldObj, player, 8, true);
}*/
-
- if (morphLoaded)
- {
- if (morph.api.Api.hasMorph(player.getCommandSenderName(), event.side.isClient()))
- {
- morphed = true;
- }
- }
-
- if (!player.isPlayerSleeping() && !smartmoveLoaded)
- {
- ItemStack chest = player.getCurrentArmor(2);
- if (chest == null || !(chest.getItem() instanceof IModifyable))
- {
- if (!(morphLoaded && morphed))
- PlayerAbilityHelper.setEntitySize(player, 0.6F, 1.8F);
- }
- else
- {
- NBTTagCompound tag = chest.getTagCompound().getCompoundTag(((IModifyable) chest.getItem()).getBaseTagName());
- int dodge = tag.getInteger("Perfect Dodge");
- if (dodge > 0)
- {
- if (!(morphLoaded && morphed))
- PlayerAbilityHelper.setEntitySize(player, Math.max(0.15F, 0.6F - (dodge * 0.09f)), 1.8F - (dodge * 0.04f));
- }
- }
- }
}
diff --git a/src/main/java/tconstruct/armor/TinkerArmorEvents.java b/src/main/java/tconstruct/armor/TinkerArmorEvents.java
index 13e904d7..1c984e5e 100644
--- a/src/main/java/tconstruct/armor/TinkerArmorEvents.java
+++ b/src/main/java/tconstruct/armor/TinkerArmorEvents.java
@@ -5,6 +5,7 @@ import cpw.mods.fml.common.gameevent.PlayerEvent;
import net.minecraft.entity.boss.*;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.monster.IMob;
+import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraftforge.event.entity.living.*;
@@ -97,4 +98,25 @@ public class TinkerArmorEvents
}
}
}
+
+ @SubscribeEvent
+ public void perfectDodge(LivingAttackEvent event)
+ {
+ if(!event.source.isProjectile())
+ return;
+
+ // perfect dodge?
+ if(!(event.entityLiving instanceof EntityPlayer))
+ return;
+
+ EntityPlayer player = (EntityPlayer) event.entityLiving;
+ ItemStack chest = player.getCurrentArmor(2);
+ if(chest == null || !(chest.getItem() instanceof IModifyable) || !chest.hasTagCompound())
+ return;
+
+ NBTTagCompound tags = chest.getTagCompound().getCompoundTag(((IModifyable) chest.getItem()).getBaseTagName());
+ int dodge = tags.getInteger("Perfect Dodge");
+ if(dodge > TConstruct.random.nextInt(10))
+ event.setCanceled(true);
+ }
}
diff --git a/src/main/java/tconstruct/armor/player/TPlayerStats.java b/src/main/java/tconstruct/armor/player/TPlayerStats.java
index d5bd3d77..41bd0b24 100644
--- a/src/main/java/tconstruct/armor/player/TPlayerStats.java
+++ b/src/main/java/tconstruct/armor/player/TPlayerStats.java
@@ -27,6 +27,7 @@ public class TPlayerStats implements IExtendedEntityProperties, IPlayerExtendedI
public boolean beginnerManual;
public boolean materialManual;
public boolean smelteryManual;
+ public boolean weaponryManual;
public boolean battlesignBonus;
// death-penality
@@ -61,6 +62,7 @@ public class TPlayerStats implements IExtendedEntityProperties, IPlayerExtendedI
tTag.setBoolean("beginnerManual", this.beginnerManual);
tTag.setBoolean("materialManual", this.materialManual);
tTag.setBoolean("smelteryManual", this.smelteryManual);
+ tTag.setBoolean("weaponryManual", this.weaponryManual);
tTag.setBoolean("battlesignBonus", this.battlesignBonus);
tTag.setInteger("derpLevel", this.derpLevel);
compound.setTag(PROP_NAME, tTag);
@@ -76,6 +78,7 @@ public class TPlayerStats implements IExtendedEntityProperties, IPlayerExtendedI
this.beginnerManual = properties.getBoolean("beginnerManual");
this.materialManual = properties.getBoolean("materialManual");
this.smelteryManual = properties.getBoolean("smelteryManual");
+ this.weaponryManual = properties.getBoolean("weaponryManual");
this.battlesignBonus = properties.getBoolean("battlesignBonus");
this.derpLevel = properties.getInteger("derpLevel");
}
@@ -95,6 +98,7 @@ public class TPlayerStats implements IExtendedEntityProperties, IPlayerExtendedI
this.beginnerManual = stats.beginnerManual;
this.materialManual = stats.materialManual;
this.smelteryManual = stats.smelteryManual;
+ this.weaponryManual = stats.weaponryManual;
this.battlesignBonus = stats.battlesignBonus;
this.derpLevel = stats.derpLevel;
diff --git a/src/main/java/tconstruct/client/AmmoItemRenderer.java b/src/main/java/tconstruct/client/AmmoItemRenderer.java
new file mode 100644
index 00000000..13d048c6
--- /dev/null
+++ b/src/main/java/tconstruct/client/AmmoItemRenderer.java
@@ -0,0 +1,56 @@
+package tconstruct.client;
+
+import tconstruct.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/client/FlexibleToolRenderer.java b/src/main/java/tconstruct/client/FlexibleToolRenderer.java
new file mode 100644
index 00000000..66a6e1a6
--- /dev/null
+++ b/src/main/java/tconstruct/client/FlexibleToolRenderer.java
@@ -0,0 +1,306 @@
+package tconstruct.client;
+
+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) {
+ specialAnimation(type, item);
+ }
+ else
+ GL11.glTranslatef(-0.5f, -0.25f, 0); // why? because.. minecraft.
+
+ // 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, 0, +depth, xMax[i], yMax[i]);
+ tess.addVertexWithUV(1, 0, +depth, xMin[i], yMax[i]);
+ tess.addVertexWithUV(1, 1, +depth, xMin[i], yMin[i]);
+ tess.addVertexWithUV(0, 1, +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, 1, -depth, xMax[i], yMin[i]);
+ tess.addVertexWithUV(1, 1, -depth, xMin[i], yMin[i]);
+ tess.addVertexWithUV(1, 0, -depth, xMin[i], yMax[i]);
+ tess.addVertexWithUV(0, 0, -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;
+ tess.addVertexWithUV(pos, 0, -depth, iconPos, yMax[i]);
+ tess.addVertexWithUV(pos, 0, +depth, iconPos, yMax[i]);
+ tess.addVertexWithUV(pos, 1, +depth, iconPos, yMin[i]);
+ tess.addVertexWithUV(pos, 1, -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;
+ posEnd = pos + d2;
+ tess.addVertexWithUV(posEnd, 1, -depth, iconPos, yMin[i]);
+ tess.addVertexWithUV(posEnd, 1, +depth, iconPos, yMin[i]);
+ tess.addVertexWithUV(posEnd, 0, +depth, iconPos, yMax[i]);
+ tess.addVertexWithUV(posEnd, 0, -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;
+ posEnd = pos + d2;
+ tess.addVertexWithUV(0, posEnd, +depth, xMax[i], iconPos);
+ tess.addVertexWithUV(1, posEnd, +depth, xMin[i], iconPos);
+ tess.addVertexWithUV(1, posEnd, -depth, xMin[i], iconPos);
+ tess.addVertexWithUV(0, 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;
+ tess.addVertexWithUV(1, pos, +depth, xMin[i], iconPos);
+ tess.addVertexWithUV(0, pos, +depth, xMax[i], iconPos);
+ tess.addVertexWithUV(0, pos, -depth, xMax[i], iconPos);
+ tess.addVertexWithUV(1, 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.glAlphaFunc(GL11.GL_GREATER, 0.1F);
+ 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/client/IconFlipped.java b/src/main/java/tconstruct/client/IconFlipped.java
new file mode 100644
index 00000000..64e14e08
--- /dev/null
+++ b/src/main/java/tconstruct/client/IconFlipped.java
@@ -0,0 +1,22 @@
+package tconstruct.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/client/TProxyClient.java b/src/main/java/tconstruct/client/TProxyClient.java
index c6307bfb..93f1fc1a 100644
--- a/src/main/java/tconstruct/client/TProxyClient.java
+++ b/src/main/java/tconstruct/client/TProxyClient.java
@@ -1,7 +1,9 @@
package tconstruct.client;
import java.io.InputStream;
+import java.text.DecimalFormat;
import javax.xml.parsers.*;
+
import mantle.client.SmallFontRenderer;
import mantle.lib.client.MantleClientRegistry;
import net.minecraft.client.Minecraft;
@@ -16,23 +18,22 @@ import tconstruct.armor.player.TPlayerStats;
import tconstruct.common.TProxyCommon;
import tconstruct.tools.items.ManualInfo;
-public class TProxyClient extends TProxyCommon
-{
+public class TProxyClient extends TProxyCommon {
+ public static DecimalFormat df = new DecimalFormat("##.#");
+
/* TODO: Split this class up into its respective parts */
public static SmallFontRenderer smallFontRenderer;
public static IIcon metalBall;
public static Minecraft mc;
public static RenderItem itemRenderer = new RenderItem();
- public void initialize ()
- {
+ public void initialize() {
registerRenderer();
readManuals();
}
/* Registers any rendering code. */
- public void registerRenderer ()
- {
+ public void registerRenderer() {
Minecraft mc = Minecraft.getMinecraft();
smallFontRenderer = new SmallFontRenderer(mc.gameSettings, new ResourceLocation("textures/font/ascii.png"), mc.renderEngine, false);
}
@@ -41,68 +42,45 @@ public class TProxyClient extends TProxyCommon
public static Document volume1;
public static Document volume2;
public static Document smelter;
+ public static Document weaponry;
public static ManualInfo manualData;
- public void readManuals ()
- {
+ public void readManuals() {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
- String CurrentLanguage = Minecraft.getMinecraft().getLanguageManager().getCurrentLanguage().getLanguageCode();
-
- Document diary_cl = readManual("/assets/tinker/manuals/" + CurrentLanguage + "/diary.xml", dbFactory);
- Document volume1_cl = readManual("/assets/tinker/manuals/" + CurrentLanguage + "/firstday.xml", dbFactory);
- Document volume2_cl = readManual("/assets/tinker/manuals/" + CurrentLanguage + "/materials.xml", dbFactory);
- Document smelter_cl = readManual("/assets/tinker/manuals/" + CurrentLanguage + "/smeltery.xml", dbFactory);
-
- diary = readManual("/assets/tinker/manuals/en_US/diary.xml", dbFactory);
- volume1 = readManual("/assets/tinker/manuals/en_US/firstday.xml", dbFactory);
- volume2 = readManual("/assets/tinker/manuals/en_US/materials.xml", dbFactory);
- smelter = readManual("/assets/tinker/manuals/en_US/smeltery.xml", dbFactory);
-
- if(diary_cl != null)
- {
- diary = diary_cl;
- }
-
- if(volume1_cl != null)
- {
- volume1 = volume1_cl;
- }
-
- if(volume2_cl != null)
- {
- volume2 = volume2_cl;
- }
-
- if(smelter_cl != null)
- {
- smelter = smelter_cl;
- }
-
- initManualIcons();
+ String CurrentLanguage = Minecraft.getMinecraft().getLanguageManager().getCurrentLanguage().getLanguageCode();
+
+ Document diary_cl = readManual("/assets/tinker/manuals/" + CurrentLanguage + "/diary.xml", dbFactory);
+ Document volume1_cl = readManual("/assets/tinker/manuals/" + CurrentLanguage + "/firstday.xml", dbFactory);
+ Document volume2_cl = readManual("/assets/tinker/manuals/" + CurrentLanguage + "/materials.xml", dbFactory);
+ Document smelter_cl = readManual("/assets/tinker/manuals/" + CurrentLanguage + "/smeltery.xml", dbFactory);
+ Document weaponry_cl = readManual("/assets/tinker/manuals/" + CurrentLanguage + "/weaponry.xml", dbFactory);
+
+ diary = diary_cl != null ? diary_cl : readManual("/assets/tinker/manuals/en_US/diary.xml", dbFactory);
+ volume1 = volume1_cl != null ? volume1_cl : readManual("/assets/tinker/manuals/en_US/firstday.xml", dbFactory);
+ volume2 = volume2_cl != null ? volume2_cl : readManual("/assets/tinker/manuals/en_US/materials.xml", dbFactory);
+ smelter = smelter_cl != null ? smelter_cl : readManual("/assets/tinker/manuals/en_US/smeltery.xml", dbFactory);
+ weaponry = weaponry_cl != null ? weaponry_cl : readManual("/assets/tinker/manuals/en_US/weaponry.xml", dbFactory);
+
+ initManualIcons();
initManualRecipes();
initManualPages();
manualData = new ManualInfo();
}
- Document readManual (String location, DocumentBuilderFactory dbFactory)
- {
- try
- {
+ Document readManual(String location, DocumentBuilderFactory dbFactory) {
+ try {
InputStream stream = TConstruct.class.getResourceAsStream(location);
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(stream);
doc.getDocumentElement().normalize();
return doc;
- }
- catch (Exception e)
- {
+ } catch (Exception e) {
e.printStackTrace();
return null;
}
}
- public void initManualIcons ()
- {
+ public void initManualIcons() {
MantleClientRegistry.registerManualIcon("torch", new ItemStack(Blocks.torch));
MantleClientRegistry.registerManualIcon("sapling", new ItemStack(Blocks.sapling));
MantleClientRegistry.registerManualIcon("workbench", new ItemStack(Blocks.crafting_table));
@@ -118,34 +96,29 @@ public class TProxyClient extends TProxyCommon
MantleClientRegistry.registerManualIcon("netherrack", new ItemStack(Blocks.netherrack));
}
- public void initManualRecipes ()
- {
+ public void initManualRecipes() {
}
- void initManualPages ()
- {
+ void initManualPages() {
}
- public static Document getManualFromStack (ItemStack stack)
- {
- switch (stack.getItemDamage())
- {
- case 0:
- return volume1;
- case 1:
- return volume2;
- case 2:
- return smelter;
- case 3:
- return diary;
+ public static Document getManualFromStack(ItemStack stack) {
+ switch (stack.getItemDamage()) {
+ case 0:
+ return volume1;
+ case 1:
+ return volume2;
+ case 2:
+ return smelter;
+ case 3:
+ return diary;
}
return null;
}
- public void recalculateHealth ()
- {
+ public void recalculateHealth() {
ArmorProxyClient.armorExtended.recalculateHealth(mc.thePlayer, TPlayerStats.get(mc.thePlayer));
}
diff --git a/src/main/java/tconstruct/client/entity/projectile/ArrowRender.java b/src/main/java/tconstruct/client/entity/projectile/ArrowRender.java
index 77c7e8d3..3a8ad104 100644
--- a/src/main/java/tconstruct/client/entity/projectile/ArrowRender.java
+++ b/src/main/java/tconstruct/client/entity/projectile/ArrowRender.java
@@ -15,6 +15,7 @@ import org.lwjgl.opengl.*;
import tconstruct.tools.entity.ArrowEntity;
@SideOnly(Side.CLIENT)
+@Deprecated
public class ArrowRender extends Render
{
private static final ResourceLocation RES_ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png");
diff --git a/src/main/java/tconstruct/client/entity/projectile/ArrowRenderCustom.java b/src/main/java/tconstruct/client/entity/projectile/ArrowRenderCustom.java
index 25a366b6..c20ec110 100644
--- a/src/main/java/tconstruct/client/entity/projectile/ArrowRenderCustom.java
+++ b/src/main/java/tconstruct/client/entity/projectile/ArrowRenderCustom.java
@@ -13,6 +13,7 @@ import org.lwjgl.opengl.*;
import tconstruct.tools.entity.ArrowEntity;
@SideOnly(Side.CLIENT)
+@Deprecated
public class ArrowRenderCustom extends Render
{
private static RenderItem renderer = new RenderItem();
diff --git a/src/main/java/tconstruct/client/entity/projectile/DaggerRender.java b/src/main/java/tconstruct/client/entity/projectile/DaggerRender.java
index 4f426331..3d085afd 100644
--- a/src/main/java/tconstruct/client/entity/projectile/DaggerRender.java
+++ b/src/main/java/tconstruct/client/entity/projectile/DaggerRender.java
@@ -17,6 +17,7 @@ import org.lwjgl.opengl.*;
import tconstruct.tools.entity.DaggerEntity;
@SideOnly(Side.CLIENT)
+@Deprecated
public class DaggerRender extends Render
{
private static final ResourceLocation RES_ITEM_GLINT = new ResourceLocation("textures/misc/enchanted_item_glint.png");
diff --git a/src/main/java/tconstruct/client/entity/projectile/DaggerRenderCustom.java b/src/main/java/tconstruct/client/entity/projectile/DaggerRenderCustom.java
index b36ea7f0..bfe43abf 100644
--- a/src/main/java/tconstruct/client/entity/projectile/DaggerRenderCustom.java
+++ b/src/main/java/tconstruct/client/entity/projectile/DaggerRenderCustom.java
@@ -14,6 +14,7 @@ import tconstruct.client.ToolCoreRenderer;
import tconstruct.tools.entity.DaggerEntity;
@SideOnly(Side.CLIENT)
+@Deprecated
public class DaggerRenderCustom extends Render
{
private static RenderItem renderer = new RenderItem();
diff --git a/src/main/java/tconstruct/items/tools/Arrow.java b/src/main/java/tconstruct/items/tools/Arrow.java
index e5677a87..8b776c25 100644
--- a/src/main/java/tconstruct/items/tools/Arrow.java
+++ b/src/main/java/tconstruct/items/tools/Arrow.java
@@ -10,12 +10,12 @@ import net.minecraft.util.StatCollector;
import net.minecraft.world.World;
import tconstruct.library.TConstructRegistry;
import tconstruct.library.crafting.ToolBuilder;
-import tconstruct.library.tools.BowstringMaterial;
import tconstruct.library.tools.CustomMaterial;
import tconstruct.library.tools.FletchingMaterial;
import tconstruct.library.tools.ToolCore;
-import tconstruct.tools.TinkerTools;
+import tconstruct.weaponry.TinkerWeaponry;
+@Deprecated
public class Arrow extends ToolCore
{
@@ -85,13 +85,13 @@ public class Arrow extends ToolCore
@Override
public Item getHeadItem ()
{
- return TinkerTools.arrowhead;
+ return TinkerWeaponry.arrowhead;
}
@Override
public Item getAccessoryItem ()
{
- return TinkerTools.fletching;
+ return TinkerWeaponry.fletching;
}
@Override
@@ -197,11 +197,11 @@ public class Arrow extends ToolCore
int head = tags.getCompoundTag("InfiTool").getInteger("Head");
int handle = tags.getCompoundTag("InfiTool").getInteger("Handle");
- String headName = getAbilityNameForType(head);
+ String headName = getAbilityNameForType(head, 0);
if (!headName.equals(""))
list.add(getStyleForType(head) + headName);
- String handleName = getAbilityNameForType(handle);
+ String handleName = getAbilityNameForType(handle, 0);
if (!handleName.equals("") && handle != head)
list.add(getStyleForType(handle) + handleName);
diff --git a/src/main/java/tconstruct/items/tools/BowBase.java b/src/main/java/tconstruct/items/tools/BowBase.java
index 2d651298..7d8bf8a2 100644
--- a/src/main/java/tconstruct/items/tools/BowBase.java
+++ b/src/main/java/tconstruct/items/tools/BowBase.java
@@ -19,6 +19,7 @@ import tconstruct.tools.TinkerTools;
import tconstruct.tools.entity.ArrowEntity;
import tconstruct.util.config.PHConstruct;
+@Deprecated
public abstract class BowBase extends ToolCore
{
public BowBase()
diff --git a/src/main/java/tconstruct/items/tools/Dagger.java b/src/main/java/tconstruct/items/tools/Dagger.java
index 34ee9da5..3b5685f6 100644
--- a/src/main/java/tconstruct/items/tools/Dagger.java
+++ b/src/main/java/tconstruct/items/tools/Dagger.java
@@ -21,9 +21,10 @@ public class Dagger extends Weapon
ItemStack stack = itemstack.copy();
if (!world.isRemote)
{
- DaggerEntity dagger = new DaggerEntity(stack, world, player);
+ DaggerEntity dagger = new DaggerEntity(world, player, 1.5f, 0, stack);
+ //dagger.motionY++;
if (player.capabilities.isCreativeMode)
- dagger.doNotRetrieve = true;
+ dagger.canBePickedUp = 2;
world.spawnEntityInWorld(dagger);
}
itemstack.stackSize--;
@@ -36,7 +37,8 @@ public class Dagger extends Weapon
ItemStack stack = itemstack.copy();
if (!world.isRemote)
{
- DaggerEntity dagger = new DaggerEntity(stack, world, player);
+ DaggerEntity dagger = new DaggerEntity(world, player, 1.5f, 0, stack);
+ //dagger.motionY++;
world.spawnEntityInWorld(dagger);
}
itemstack.stackSize--;
diff --git a/src/main/java/tconstruct/items/tools/Shortbow.java b/src/main/java/tconstruct/items/tools/Shortbow.java
index 0ad39270..c2cafe20 100644
--- a/src/main/java/tconstruct/items/tools/Shortbow.java
+++ b/src/main/java/tconstruct/items/tools/Shortbow.java
@@ -13,7 +13,9 @@ import tconstruct.library.TConstructRegistry;
import tconstruct.library.tools.BowstringMaterial;
import tconstruct.library.tools.CustomMaterial;
import tconstruct.tools.TinkerTools;
+import tconstruct.weaponry.TinkerWeaponry;
+@Deprecated
public class Shortbow extends BowBase
{
public Shortbow()
@@ -75,7 +77,7 @@ public class Shortbow extends BowBase
@Override
public Item getHandleItem ()
{
- return TinkerTools.bowstring;
+ return TinkerWeaponry.bowstring;
}
@Override
@@ -146,7 +148,7 @@ public class Shortbow extends BowBase
int binding = tags.getCompoundTag("InfiTool").getInteger("Accessory");
int extra = tags.getCompoundTag("InfiTool").getInteger("Extra");
- String headName = getAbilityNameForType(head);
+ String headName = getAbilityNameForType(head, 0);
if (!headName.equals(""))
list.add(getStyleForType(head) + headName);
@@ -156,14 +158,14 @@ public class Shortbow extends BowBase
if (getPartAmount() >= 3)
{
- String bindingName = getAbilityNameForType(binding);
+ String bindingName = getAbilityNameForType(binding, 0);
if (!bindingName.equals("") && binding != head && binding != handle)
list.add(getStyleForType(binding) + bindingName);
}
if (getPartAmount() >= 4)
{
- String extraName = getAbilityNameForType(extra);
+ String extraName = getAbilityNameForType(extra, 0);
if (!extraName.equals("") && extra != head && extra != handle && extra != binding)
list.add(getStyleForType(extra) + extraName);
}
diff --git a/src/main/java/tconstruct/library/TConstructRegistry.java b/src/main/java/tconstruct/library/TConstructRegistry.java
index 7f63baaa..13c18f6e 100644
--- a/src/main/java/tconstruct/library/TConstructRegistry.java
+++ b/src/main/java/tconstruct/library/TConstructRegistry.java
@@ -26,6 +26,7 @@ public class TConstructRegistry
public static TConstructCreativeTab materialTab;
public static TConstructCreativeTab blockTab;
public static TConstructCreativeTab equipableTab;
+ public static TConstructCreativeTab weaponryTab;
/* Items */
@@ -389,12 +390,18 @@ public class TConstructRegistry
// Bow materials
public static HashMap bowMaterials = new HashMap(40);
+ @Deprecated
public static void addBowMaterial (int materialID, int durability, int drawSpeed, float speedMax)
+ {
+ addBowMaterial(materialID, drawSpeed, speedMax);
+ }
+
+ public static void addBowMaterial (int materialID, int drawSpeed, float speedMax)
{
BowMaterial mat = bowMaterials.get(materialID);
if (mat == null)
{
- mat = new BowMaterial(durability, drawSpeed, speedMax);
+ mat = new BowMaterial(drawSpeed, speedMax);
bowMaterials.put(materialID, mat);
}
else
@@ -413,12 +420,18 @@ public class TConstructRegistry
public static HashMap arrowMaterials = new HashMap(40);
+ @Deprecated
public static void addArrowMaterial (int materialID, float mass, float breakChance, float accuracy)
+ {
+ addArrowMaterial(materialID, mass, breakChance);
+ }
+
+ public static void addArrowMaterial (int materialID, float mass, float breakChance)
{
ArrowMaterial mat = arrowMaterials.get(materialID);
if (mat == null)
{
- mat = new ArrowMaterial(mass, breakChance, accuracy);
+ mat = new ArrowMaterial(mass, breakChance);
arrowMaterials.put(materialID, mat);
}
else
@@ -451,9 +464,9 @@ public class TConstructRegistry
customMaterials.add(mat);
}
- public static void addFletchingMaterial (int materialID, int value, ItemStack input, ItemStack craftingMaterial, float accuracy, float breakChance, float mass, int color)
+ public static void addFletchingMaterial (int materialID, int value, ItemStack input, ItemStack craftingMaterial, float accuracy, float breakChance, float durabilityModifier, int color)
{
- FletchingMaterial mat = new FletchingMaterial(materialID, value, input, craftingMaterial, accuracy, breakChance, mass, color);
+ FletchingMaterial mat = new FletchingMaterial(materialID, value, input, craftingMaterial, accuracy, breakChance, durabilityModifier, color);
customMaterials.add(mat);
}
diff --git a/src/main/java/tconstruct/library/entity/ProjectileBase.java b/src/main/java/tconstruct/library/entity/ProjectileBase.java
new file mode 100644
index 00000000..aec11e9f
--- /dev/null
+++ b/src/main/java/tconstruct/library/entity/ProjectileBase.java
@@ -0,0 +1,593 @@
+package tconstruct.library.entity;
+
+import tconstruct.library.weaponry.AmmoItem;
+import tconstruct.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 boolean bounceOnNoDamage = true;
+ public boolean defused = false; // if this is true it wont hit any entities anymore
+
+ 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
+ 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)
+ {
+ float knockback = returnStack.getTagCompound().getCompoundTag("InfiTool").getFloat("Knockback");
+ if(shootingEntity instanceof EntityLivingBase)
+ knockback += EnchantmentHelper.getKnockbackModifier((EntityLivingBase) shootingEntity, entityHit);
+
+ if (!this.worldObj.isRemote)
+ {
+ entityHit.setArrowCountInEntity(entityHit.getArrowCountInEntity() + 1);
+ }
+
+ if (knockback > 0)
+ {
+ double horizontalSpeed = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ);
+
+ if (horizontalSpeed > 0.0F)
+ {
+ entityHit.addVelocity(this.motionX * (double) knockback * 0.6000000238418579D / horizontalSpeed, 0.1D, this.motionZ * (double) knockback * 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);
+ this.defused = true; // defuse it so it doesn't hit stuff anymore, being weird
+
+ 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");
+ float speed = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ);
+ float damage = speed * tags.getInteger("Attack"); // todo: potentially change this back to MathHelper.ceiling_float_int to get 1/2 heart steps back
+
+ // 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, (int)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 && movingobjectposition.entityHit instanceof EntityLivingBase)
+ 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, (int)damage, ammo, returnStack.getTagCompound(), tags, returnStack, (EntityPlayer)this.shootingEntity, movingobjectposition.entityHit);
+ }
+ damage += modDamage;
+
+ // calculate critical damaaage
+ if (this.getIsCritical())
+ damage += this.rand.nextFloat() * (damage / 2f + 2f);
+
+ // 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;
+ }
+ // we hit it, BURNNNNNN
+ else
+ AbilityHelper.processFiery(shootingEntity, movingobjectposition.entityHit, tags);
+
+
+ if (movingobjectposition.entityHit instanceof EntityLivingBase)
+ doLivingHit((EntityLivingBase)movingobjectposition.entityHit);
+
+ playHitEntitySound();
+
+ if (!(movingobjectposition.entityHit instanceof EntityEnderman))
+ {
+ // reinforced helps for them to not break!
+ if(rand.nextInt(10)+1 > tags.getInteger("Reinforced"))
+ this.setDead();
+ else
+ {
+ this.motionX = 0;
+ this.motionY = 0;
+ this.motionZ = 0;
+ this.ticksInAir = 0;
+ }
+ }
+ }
+
+ // 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
+ public void setVelocity(double p_70016_1_, double p_70016_3_, double p_70016_5_) {
+ // don't do anything, we set it ourselves at spawn
+ // Mojangs code has a hard cap of 3.9 speed, but our projectiles can go faster, which desyncs client and server speeds
+ // Packet that's causing it: S12PacketEntityVelocity
+ }
+
+ @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);
+
+
+ if(!defused) {
+ // 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) {
+ ByteBufUtils.writeItemStack(data, returnStack);
+ data.writeFloat(rotationYaw);
+
+ // shooting entity
+ int id = shootingEntity == null ? this.getEntityId() : shootingEntity.getEntityId();
+ data.writeInt(id);
+
+ // motion stuff. This has to be sent separately since MC seems to do hardcoded stuff to arrows with this
+ data.writeDouble(this.motionX);
+ data.writeDouble(this.motionY);
+ data.writeDouble(this.motionZ);
+ }
+
+ @Override
+ public void readSpawnData(ByteBuf data) {
+ returnStack = ByteBufUtils.readItemStack(data);
+ rotationYaw = data.readFloat();
+ shootingEntity = worldObj.getEntityByID(data.readInt());
+
+ this.motionX = data.readDouble();
+ this.motionY = data.readDouble();
+ this.motionZ = data.readDouble();
+ }
+}
diff --git a/src/main/java/tconstruct/library/tools/AbilityHelper.java b/src/main/java/tconstruct/library/tools/AbilityHelper.java
index 5004dbae..db244756 100644
--- a/src/main/java/tconstruct/library/tools/AbilityHelper.java
+++ b/src/main/java/tconstruct/library/tools/AbilityHelper.java
@@ -63,7 +63,6 @@ public class AbilityHelper
{
NBTTagCompound tags = stack.getTagCompound();
NBTTagCompound toolTags = stack.getTagCompound().getCompoundTag("InfiTool");
- int damage = toolTags.getInteger("Attack") + baseDamage;
boolean broken = toolTags.getBoolean("Broken");
int durability = tags.getCompoundTag("InfiTool").getInteger("Damage");
@@ -71,61 +70,17 @@ public class AbilityHelper
float stoneboundDamage = (float) Math.log(durability / 72f + 1) * -2 * stonebound;
- int earlyModDamage = 0;
- for (ActiveToolMod mod : TConstructRegistry.activeModifiers)
- {
- earlyModDamage = mod.baseAttackDamage(earlyModDamage, damage, tool, tags, toolTags, stack, player, entity);
- }
- damage += earlyModDamage;
+ int damage = calcDamage(player, entity, stack, tool, toolTags, baseDamage);
+ float knockback = calcKnockback(player, entity, stack, tool, toolTags, baseDamage);
- if (player.isPotionActive(Potion.damageBoost))
- {
- damage += 3 << player.getActivePotionEffect(Potion.damageBoost).getAmplifier();
- }
-
- if (player.isPotionActive(Potion.weakness))
- {
- damage -= 2 << player.getActivePotionEffect(Potion.weakness).getAmplifier();
- }
-
- float knockback = 0;
float enchantDamage = 0;
+ // magic extra damage
if (entity instanceof EntityLivingBase)
{
enchantDamage = EnchantmentHelper.getEnchantmentModifierLiving(player, (EntityLivingBase) entity);
- knockback += EnchantmentHelper.getKnockbackModifier(player, (EntityLivingBase) entity);
}
- damage += stoneboundDamage;
- if (damage < 1)
- damage = 1;
-
- if (player.isSprinting())
- {
- knockback++;
- float lunge = tool.chargeAttack();
- if (lunge > 1f)
- {
- knockback += lunge - 1.0f;
- damage *= lunge;
- }
- }
-
- float modKnockback = 0f;
- for (ActiveToolMod mod : TConstructRegistry.activeModifiers)
- {
- modKnockback = mod.knockback(modKnockback, knockback, tool, tags, toolTags, stack, player, entity);
- }
- knockback += modKnockback;
-
- int modDamage = 0;
- for (ActiveToolMod mod : TConstructRegistry.activeModifiers)
- {
- modDamage = mod.attackDamage(modDamage, damage, tool, tags, toolTags, stack, player, entity);
- }
- damage += modDamage;
-
if (damage > 0 || enchantDamage > 0)
{
boolean criticalHit = player.fallDistance > 0.0F && !player.onGround && !player.isOnLadder() && !player.isInWater() && !player.isPotionActive(Potion.blindness) && player.ridingEntity == null && entity instanceof EntityLivingBase;
@@ -147,14 +102,6 @@ public class AbilityHelper
{
damage *= tool.getDamageModifier();
}
- boolean var6 = false;
- int fireAspect = EnchantmentHelper.getFireAspectModifier(player);
-
- if (entity instanceof EntityLivingBase && fireAspect > 0 && !entity.isBurning())
- {
- var6 = true;
- entity.setFire(1);
- }
if (broken)
{
@@ -251,23 +198,8 @@ public class AbilityHelper
stack.getItem().hitEntity(stack, (EntityLivingBase) entity, player);
}
- if ((fireAspect > 0 || toolTags.hasKey("Fiery") || toolTags.hasKey("Lava")) && causedDamage)
- {
- fireAspect *= 4;
- if (toolTags.hasKey("Fiery"))
- {
- fireAspect += toolTags.getInteger("Fiery") / 5 + 1;
- }
- if (toolTags.getBoolean("Lava"))
- {
- fireAspect += 3;
- }
- entity.setFire(fireAspect);
- }
- else if (var6)
- {
- entity.extinguish();
- }
+ if(causedDamage)
+ processFiery(player, entity, toolTags);
}
if (entity instanceof EntityPlayer)
@@ -280,6 +212,105 @@ public class AbilityHelper
return false;
}
+ public static int calcDamage(Entity user, Entity entity, ItemStack stack, ToolCore tool, NBTTagCompound toolTags, int baseDamage)
+ {
+ EntityLivingBase living = user instanceof EntityLivingBase ? (EntityLivingBase)user : null;
+
+ int damage = toolTags.getInteger("Attack") + baseDamage;
+ int earlyModDamage = 0;
+ for (ActiveToolMod mod : TConstructRegistry.activeModifiers)
+ {
+ earlyModDamage = mod.baseAttackDamage(earlyModDamage, damage, tool, stack.getTagCompound(), toolTags, stack, living, entity);
+ }
+ damage += earlyModDamage;
+
+ if(living != null) {
+ if (living.isPotionActive(Potion.damageBoost)) {
+ damage += 3 << living.getActivePotionEffect(Potion.damageBoost).getAmplifier();
+ }
+
+ if (living.isPotionActive(Potion.weakness)) {
+ damage -= 2 << living.getActivePotionEffect(Potion.weakness).getAmplifier();
+ }
+ }
+
+ damage -= calcStoneboundBonus(tool, toolTags);
+ if (damage < 1)
+ damage = 1;
+
+ if (user.isSprinting())
+ {
+ float lunge = tool.chargeAttack();
+ if (lunge > 1f)
+ {
+ damage *= lunge;
+ }
+ }
+
+ int modDamage = 0;
+ for (ActiveToolMod mod : TConstructRegistry.activeModifiers)
+ {
+ modDamage = mod.attackDamage(modDamage, damage, tool, stack.getTagCompound(), toolTags, stack, living, entity);
+ }
+ damage += modDamage;
+
+ return damage;
+ }
+
+ public static float calcKnockback(Entity user, Entity entity, ItemStack stack, ToolCore tool, NBTTagCompound toolTags, int baseDamage)
+ {
+ float knockback = 0;
+
+ if (entity instanceof EntityLivingBase && user instanceof EntityLivingBase)
+ {
+ knockback += EnchantmentHelper.getKnockbackModifier((EntityLivingBase)user, (EntityLivingBase) entity);
+ }
+
+ if (user.isSprinting())
+ {
+ knockback++;
+ float lunge = tool.chargeAttack();
+ if (lunge > 1f)
+ {
+ knockback += lunge - 1.0f;
+ }
+ }
+
+ float modKnockback = 0f;
+ for (ActiveToolMod mod : TConstructRegistry.activeModifiers)
+ {
+ modKnockback = mod.knockback(modKnockback, knockback, tool, stack.getTagCompound(), toolTags, stack, user instanceof EntityLivingBase ? (EntityLivingBase)user : null, entity);
+ }
+ knockback += modKnockback;
+
+ return knockback;
+ }
+
+ public static void processFiery(Entity player, Entity target, NBTTagCompound toolTags)
+ {
+ // only living things burnnnn
+ if(!(target instanceof EntityLivingBase))
+ return;
+
+ int fireAspect = 0;
+ if(player instanceof EntityLivingBase)
+ fireAspect = EnchantmentHelper.getFireAspectModifier((EntityLivingBase)player);
+
+ if ((fireAspect > 0 || toolTags.hasKey("Fiery") || toolTags.hasKey("Lava")))
+ {
+ fireAspect *= 4;
+ if (toolTags.hasKey("Fiery"))
+ {
+ fireAspect += toolTags.getInteger("Fiery") / 5 + 1;
+ }
+ if (toolTags.getBoolean("Lava"))
+ {
+ fireAspect += 3;
+ }
+ target.setFire(fireAspect);
+ }
+ }
+
static void alertPlayerWolves (EntityPlayer player, EntityLivingBase living, boolean par2)
{
if (!(living instanceof EntityCreeper) && !(living instanceof EntityGhast))
@@ -710,6 +741,22 @@ public class AbilityHelper
return trueSpeed;
}
+ public static float calcDualToolSpeed (ToolCore tool, NBTTagCompound tags, boolean secondary)
+ {
+ String tag = "MiningSpeed";
+ if(secondary) tag += "2";
+
+ float mineSpeed = tags.getInteger(tag);
+ float speedMod = 1f;
+ if (tool instanceof HarvestTool)
+ speedMod = ((HarvestTool) tool).breakSpeedModifier();
+
+ float trueSpeed = mineSpeed / 100f * speedMod;
+ trueSpeed += calcStoneboundBonus(tool, tags);
+
+ return trueSpeed;
+ }
+
public static float calcStoneboundBonus (ToolCore tool, NBTTagCompound tags)
{
int durability = tags.getInteger("Damage");
diff --git a/src/main/java/tconstruct/library/tools/ArrowMaterial.java b/src/main/java/tconstruct/library/tools/ArrowMaterial.java
index 884e3edc..4f705b6d 100644
--- a/src/main/java/tconstruct/library/tools/ArrowMaterial.java
+++ b/src/main/java/tconstruct/library/tools/ArrowMaterial.java
@@ -4,12 +4,19 @@ public class ArrowMaterial
{
public final float mass;
public final float breakChance;
- public final float accuracy;
- public ArrowMaterial(float weight, float breakChance, float accuracy)
+ public ArrowMaterial(float weight, float breakChance)
{
this.mass = weight;
this.breakChance = breakChance;
- this.accuracy = accuracy;
}
+
+ @Deprecated
+ public ArrowMaterial(float weight, float breakChance, float accuraccy)
+ {
+ this(weight, breakChance);
+ }
+
+ @Deprecated
+ public float accuracy = 0f; // tic-tooltips compatibility
}
diff --git a/src/main/java/tconstruct/library/tools/BowMaterial.java b/src/main/java/tconstruct/library/tools/BowMaterial.java
index 89d0c80e..628dba52 100644
--- a/src/main/java/tconstruct/library/tools/BowMaterial.java
+++ b/src/main/java/tconstruct/library/tools/BowMaterial.java
@@ -2,14 +2,21 @@ package tconstruct.library.tools;
public class BowMaterial
{
- public final int durability;
public final int drawspeed;
public final float flightSpeedMax;
- public BowMaterial(int durability, int drawspeed, float attack)
+ public BowMaterial(int drawspeed, float attack)
{
- this.durability = durability;
this.drawspeed = drawspeed;
this.flightSpeedMax = attack;
}
+
+ @Deprecated
+ public BowMaterial(int durability, int drawspeed, float attack)
+ {
+ this(drawspeed, attack);
+ }
+
+ @Deprecated
+ public int durability = 0; // tic-tooltips compatibility
}
diff --git a/src/main/java/tconstruct/library/tools/DualHarvestTool.java b/src/main/java/tconstruct/library/tools/DualHarvestTool.java
index a41cd634..aa4bf76a 100644
--- a/src/main/java/tconstruct/library/tools/DualHarvestTool.java
+++ b/src/main/java/tconstruct/library/tools/DualHarvestTool.java
@@ -56,16 +56,8 @@ public abstract class DualHarvestTool extends HarvestTool
{
if (materials[i] == block.getMaterial())
{
- float speed = tags.getInteger("MiningSpeed");
- speed /= 100f;
- int hlvl = block.getHarvestLevel(meta);
- int durability = tags.getInteger("Damage");
-
- float shoddy = tags.getFloat("Shoddy");
- speed += shoddy * durability / 100f;
-
- if (hlvl <= tags.getInteger("HarvestLevel"))
- return speed;
+ if (block.getHarvestLevel(meta) <= tags.getInteger("HarvestLevel"))
+ return AbilityHelper.calcDualToolSpeed(this, tags, false);
return 0.1f;
}
}
@@ -74,16 +66,8 @@ public abstract class DualHarvestTool extends HarvestTool
{
if (materials[i] == block.getMaterial())
{
- float speed = tags.getInteger("MiningSpeed2");
- speed /= 100f;
- int hlvl = block.getHarvestLevel(meta);
- int durability = tags.getInteger("Damage");
-
- float shoddy = tags.getFloat("Shoddy");
- speed += shoddy * durability / 100f;
-
- if (hlvl <= tags.getInteger("HarvestLevel2"))
- return speed;
+ if (block.getHarvestLevel(meta) <= tags.getInteger("HarvestLevel2"))
+ return AbilityHelper.calcDualToolSpeed(this, tags, true);
return 0.1f;
}
}
diff --git a/src/main/java/tconstruct/library/tools/DualMaterialToolPart.java b/src/main/java/tconstruct/library/tools/DualMaterialToolPart.java
new file mode 100644
index 00000000..995a246a
--- /dev/null
+++ b/src/main/java/tconstruct/library/tools/DualMaterialToolPart.java
@@ -0,0 +1,122 @@
+package tconstruct.library.tools;
+
+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 DynamicToolPart {
+ 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/library/tools/FletchingMaterial.java b/src/main/java/tconstruct/library/tools/FletchingMaterial.java
index a165150a..9cb5b766 100644
--- a/src/main/java/tconstruct/library/tools/FletchingMaterial.java
+++ b/src/main/java/tconstruct/library/tools/FletchingMaterial.java
@@ -6,33 +6,36 @@ public class FletchingMaterial extends CustomMaterial
{
public final float accuracy;
public final float breakChance;
- public final float mass;
+ public final float durabilityModifier;
- public FletchingMaterial(int materialID, int value, ItemStack input, ItemStack craftingItem, float accuracy, float breakChance, float mass, int color)
+ public FletchingMaterial(int materialID, int value, ItemStack input, ItemStack craftingItem, float accuracy, float breakChance, float duribalityModifier, int color)
{
super(materialID, value, input, craftingItem, color);
this.accuracy = accuracy;
this.breakChance = breakChance;
- this.mass = mass;
+ this.durabilityModifier = duribalityModifier;
}
@Deprecated
public FletchingMaterial(int materialID, int value, ItemStack input, ItemStack craftingItem, float accuracy, float breakChance, float mass)
{
- this(materialID, value, input, craftingItem, accuracy, breakChance, mass, 0xffffffff);
+ this(materialID, value, input, craftingItem, accuracy, 0.01f, 1f, 0xffffffff);
}
- public FletchingMaterial(int materialID, int value, String oredict, ItemStack craftingItem, float accuracy, float breakChance, float mass, int color)
+ public FletchingMaterial(int materialID, int value, String oredict, ItemStack craftingItem, float accuracy, float breakChance, float duribalityModifier, int color)
{
super(materialID, value, oredict, craftingItem, color);
this.accuracy = accuracy;
this.breakChance = breakChance;
- this.mass = mass;
+ this.durabilityModifier = duribalityModifier;
}
@Deprecated
public FletchingMaterial(int materialID, int value, String oredict, ItemStack craftingItem, float accuracy, float breakChance, float mass)
{
- this(materialID, value, oredict, craftingItem, accuracy, breakChance, mass, 0xffffffff);
+ this(materialID, value, oredict, craftingItem, accuracy, 0.01f, 1f, 0xffffffff);
}
+
+ @Deprecated
+ public float mass = 0; // tic-tooltips compatibility
}
diff --git a/src/main/java/tconstruct/library/tools/FletchlingLeafMaterial.java b/src/main/java/tconstruct/library/tools/FletchlingLeafMaterial.java
index fff76f0c..d9546cc7 100644
--- a/src/main/java/tconstruct/library/tools/FletchlingLeafMaterial.java
+++ b/src/main/java/tconstruct/library/tools/FletchlingLeafMaterial.java
@@ -6,9 +6,9 @@ import net.minecraft.item.ItemStack;
public class FletchlingLeafMaterial extends FletchingMaterial
{
- public FletchlingLeafMaterial(int materialID, int value, String oredict, ItemStack craftingItem, float accuracy, float breakChance, float mass)
+ public FletchlingLeafMaterial(int materialID, int value, String oredict, ItemStack craftingItem, float accuracy, float breakChance, float durabilityModifier)
{
- super(materialID, value, oredict, craftingItem, accuracy, breakChance, mass, 0x5ece46);
+ super(materialID, value, oredict, craftingItem, accuracy, breakChance, durabilityModifier, 0x5ece46);
}
@Override
diff --git a/src/main/java/tconstruct/library/tools/ToolCore.java b/src/main/java/tconstruct/library/tools/ToolCore.java
index 61c42a4c..93feca0e 100644
--- a/src/main/java/tconstruct/library/tools/ToolCore.java
+++ b/src/main/java/tconstruct/library/tools/ToolCore.java
@@ -273,43 +273,11 @@ public abstract class ToolCore extends Item implements IEnergyContainerItem, IEq
return getCorrectIcon(extraIcons, tags.getInteger("RenderExtra"));
}
// Effects
- else
+ else if (renderPass <= 10)
{
- if (renderPass == getPartAmount())
- {
- if (tags.hasKey("Effect1"))
- return (effectIcons.get(tags.getInteger("Effect1")));
- }
-
- else if (renderPass == getPartAmount() + 1)
- {
- if (tags.hasKey("Effect2"))
- return (effectIcons.get(tags.getInteger("Effect2")));
- }
-
- else if (renderPass == getPartAmount() + 2)
- {
- if (tags.hasKey("Effect3"))
- return (effectIcons.get(tags.getInteger("Effect3")));
- }
-
- else if (renderPass == getPartAmount() + 3)
- {
- if (tags.hasKey("Effect4"))
- return (effectIcons.get(tags.getInteger("Effect4")));
- }
-
- else if (renderPass == getPartAmount() + 4)
- {
- if (tags.hasKey("Effect5"))
- return (effectIcons.get(tags.getInteger("Effect5")));
- }
-
- else if (renderPass == getPartAmount() + 5)
- {
- if (tags.hasKey("Effect6"))
- return (effectIcons.get(tags.getInteger("Effect6")));
- }
+ String effect = "Effect" + (1 + renderPass - getPartAmount());
+ if(tags.hasKey(effect))
+ return effectIcons.get(tags.getInteger(effect));
}
return blankSprite;
}
@@ -364,24 +332,24 @@ public abstract class ToolCore extends Item implements IEnergyContainerItem, IEq
int binding = tags.getCompoundTag("InfiTool").getInteger("Accessory");
int extra = tags.getCompoundTag("InfiTool").getInteger("Extra");
- String headName = getAbilityNameForType(head);
+ String headName = getAbilityNameForType(head, 0);
if (!headName.equals(""))
list.add(getStyleForType(head) + headName);
- String handleName = getAbilityNameForType(handle);
+ String handleName = getAbilityNameForType(handle, 1);
if (!handleName.equals("") && handle != head)
list.add(getStyleForType(handle) + handleName);
if (getPartAmount() >= 3)
{
- String bindingName = getAbilityNameForType(binding);
+ String bindingName = getAbilityNameForType(binding, 2);
if (!bindingName.equals("") && binding != head && binding != handle)
list.add(getStyleForType(binding) + bindingName);
}
if (getPartAmount() >= 4)
{
- String extraName = getAbilityNameForType(extra);
+ String extraName = getAbilityNameForType(extra, 3);
if (!extraName.equals("") && extra != head && extra != handle && extra != binding)
list.add(getStyleForType(extra) + extraName);
}
@@ -422,7 +390,7 @@ public abstract class ToolCore extends Item implements IEnergyContainerItem, IEq
/**
* Returns the localized name of the materials ability. Only use this for display purposes, not for logic.
*/
- public String getAbilityNameForType (int type)
+ public String getAbilityNameForType (int type, int part)
{
return TConstructRegistry.getMaterial(type).ability();
}
@@ -680,7 +648,7 @@ public abstract class ToolCore extends Item implements IEnergyContainerItem, IEq
switch(renderPass)
{
case 0: return getCorrectColor(stack, renderPass, tags, "Handle", handleIcons);
- case 1: return getCorrectColor(stack, renderPass, tags, "Head", headIcons);
+ case 1: return tags.getBoolean("Broken") ? getCorrectColor(stack, renderPass, tags, "Head", brokenIcons) : getCorrectColor(stack, renderPass, tags, "Head", headIcons);
case 2: return getCorrectColor(stack, renderPass, tags, "Accessory", accessoryIcons);
case 3: return getCorrectColor(stack, renderPass, tags, "Extra", extraIcons);
}
diff --git a/src/main/java/tconstruct/library/util/BehaviorProjectileBaseDispense.java b/src/main/java/tconstruct/library/util/BehaviorProjectileBaseDispense.java
new file mode 100644
index 00000000..784849cb
--- /dev/null
+++ b/src/main/java/tconstruct/library/util/BehaviorProjectileBaseDispense.java
@@ -0,0 +1,74 @@
+package tconstruct.library.util;
+
+import net.minecraft.block.BlockDispenser;
+import net.minecraft.dispenser.BehaviorDefaultDispenseItem;
+import net.minecraft.dispenser.IBlockSource;
+import net.minecraft.dispenser.IPosition;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.IProjectile;
+import net.minecraft.item.ItemStack;
+import net.minecraft.util.EnumFacing;
+import net.minecraft.world.World;
+import tconstruct.library.entity.ProjectileBase;
+import tconstruct.library.weaponry.IAmmo;
+
+public abstract class BehaviorProjectileBaseDispense extends BehaviorDefaultDispenseItem {
+ /**
+ * Dispense the specified stack, play the dispense sound and spawn particles.
+ */
+ @Override
+ public ItemStack dispenseStack(IBlockSource blockSource, ItemStack stack)
+ {
+ World world = blockSource.getWorld();
+ IPosition iposition = BlockDispenser.func_149939_a(blockSource);
+ EnumFacing enumfacing = BlockDispenser.func_149937_b(blockSource.getBlockMetadata());
+
+ ItemStack reference;
+
+ if(stack.getItem() instanceof IAmmo)
+ {
+ IAmmo ammo = (IAmmo) stack.getItem();
+ // needs ammo to shoot
+ if(ammo.getAmmoCount(stack) <= 0)
+ return stack;
+ ammo.consumeAmmo(1, stack);
+ reference = stack.copy();
+ ((IAmmo)reference.getItem()).setAmmo(1, reference);
+ }
+ else
+ reference = stack.splitStack(1);
+
+ ProjectileBase projectile = this.getProjectileEntity(world, iposition, reference);
+ projectile.setThrowableHeading((double)enumfacing.getFrontOffsetX(), (double)((float)enumfacing.getFrontOffsetY() + ballistic()), (double)enumfacing.getFrontOffsetZ(), this.accuraccy(), this.speed());
+ projectile.returnStack = reference;
+ projectile.canBePickedUp = 1;
+ world.spawnEntityInWorld(projectile);
+
+ return stack;
+ }
+
+ /**
+ * Play the dispense sound from the specified block.
+ */
+ protected void playDispenseSound(IBlockSource p_82485_1_)
+ {
+ p_82485_1_.getWorld().playAuxSFX(1002, p_82485_1_.getXInt(), p_82485_1_.getYInt(), p_82485_1_.getZInt(), 0);
+ }
+
+ /**
+ * Return the projectile entity spawned by this dispense behavior.
+ */
+ protected abstract ProjectileBase getProjectileEntity(World world, IPosition position, ItemStack stack);
+
+ protected float speed()
+ {
+ return 6.0F;
+ }
+
+ protected float accuraccy()
+ {
+ return 1.1F;
+ }
+
+ protected float ballistic() { return 0.1f; }
+}
diff --git a/src/main/java/tconstruct/library/util/PiercingArrowDamage.java b/src/main/java/tconstruct/library/util/PiercingArrowDamage.java
new file mode 100644
index 00000000..0ed99108
--- /dev/null
+++ b/src/main/java/tconstruct/library/util/PiercingArrowDamage.java
@@ -0,0 +1,12 @@
+package tconstruct.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/library/weaponry/AmmoItem.java b/src/main/java/tconstruct/library/weaponry/AmmoItem.java
new file mode 100644
index 00000000..aeb80b94
--- /dev/null
+++ b/src/main/java/tconstruct/library/weaponry/AmmoItem.java
@@ -0,0 +1,130 @@
+package tconstruct.library.weaponry;
+
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import net.minecraft.util.StatCollector;
+import tconstruct.library.TConstructRegistry;
+import tconstruct.weaponry.TinkerWeaponry;
+import tconstruct.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;
+
+import java.util.List;
+
+public abstract class AmmoItem extends ToolCore implements IAmmo {
+ public AmmoItem(int baseDamage, String name) {
+ super(baseDamage);
+ this.setCreativeTab(TConstructRegistry.weaponryTab);
+ }
+
+ @Override
+ public int getAmmoCount(ItemStack stack) {
+ if(!stack.hasTagCompound()) return 0;
+ NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool");
+ return tags.getInteger("Ammo");
+ }
+
+ @Override
+ public int getMaxAmmo(ItemStack stack) {
+ if(!stack.hasTagCompound()) return 0;
+ NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool");
+ return getMaxAmmo(tags);
+ }
+
+ @Override
+ public int getMaxAmmo(NBTTagCompound tags) {
+ float dur = tags.getInteger("TotalDurability");
+ return Math.max(1, (int)Math.ceil(dur*getAmmoModifier()));
+ }
+
+ @Override
+ public int addAmmo(int toAdd, ItemStack stack) {
+ if(!stack.hasTagCompound()) return toAdd;
+ 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) {
+ if(!stack.hasTagCompound()) return toUse;
+ 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);
+ }
+
+ @Override
+ public void setAmmo(int count, ItemStack stack) {
+ if(!stack.hasTagCompound()) return;
+
+ NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool");
+ tags.setInteger("Ammo", count);
+ }
+
+ public float getAmmoModifier() { return 0.1f; }
+
+ public boolean pickupAmmo(ItemStack stack, ItemStack candidate, EntityPlayer player)
+ {
+ if(stack.getItem() == null || !stack.hasTagCompound() || !(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;
+ }
+}
diff --git a/src/main/java/tconstruct/library/weaponry/AmmoWeapon.java b/src/main/java/tconstruct/library/weaponry/AmmoWeapon.java
new file mode 100644
index 00000000..9209d55e
--- /dev/null
+++ b/src/main/java/tconstruct/library/weaponry/AmmoWeapon.java
@@ -0,0 +1,137 @@
+package tconstruct.library.weaponry;
+
+import tconstruct.weaponry.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)
+ {
+ if(getAmmoCount(stack) > 0)
+ 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; }
+
+ @SideOnly(Side.CLIENT)
+ 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, int time)
+ {
+ float dif = minAccuracy(itemStack) - maxAccuracy(itemStack);
+
+ return minAccuracy(itemStack) - dif * getWindupProgress(itemStack, time);
+ }
+
+ @Override
+ public String[] getTraits() {
+ return new String[] {"weapon", "thrown", "ammo", "windup"};
+ }
+
+ @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, time);
+ }
+
+ protected void launchProjectile(ItemStack stack, World world, EntityPlayer player, int time) {
+ // spawn projectile on server
+ if(!world.isRemote) {
+ ItemStack reference = stack.copy();
+ reference.stackSize = 1;
+ ((IAmmo)reference.getItem()).setAmmo(1, reference);
+
+ Entity projectile = createProjectile(reference, world, player, getAccuracy(stack, time), time);
+ world.spawnEntityInWorld(projectile);
+ }
+
+ // reduce ammo
+ if(!player.capabilities.isCreativeMode)
+ this.consumeAmmo(1, stack);
+ }
+
+ protected abstract Entity createProjectile(ItemStack reference, World world, EntityPlayer player, float accuracy, int time);
+
+ /** used for displaying the damage, return the value used for pseed in createProjectile/ProjectileBase constructor
+ */
+ public abstract float getProjectileSpeed();
+
+ @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/library/weaponry/ArrowShaftMaterial.java b/src/main/java/tconstruct/library/weaponry/ArrowShaftMaterial.java
new file mode 100644
index 00000000..b83da4a9
--- /dev/null
+++ b/src/main/java/tconstruct/library/weaponry/ArrowShaftMaterial.java
@@ -0,0 +1,29 @@
+package tconstruct.library.weaponry;
+
+import tconstruct.weaponry.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/library/weaponry/BowBaseAmmo.java b/src/main/java/tconstruct/library/weaponry/BowBaseAmmo.java
new file mode 100644
index 00000000..ee645244
--- /dev/null
+++ b/src/main/java/tconstruct/library/weaponry/BowBaseAmmo.java
@@ -0,0 +1,173 @@
+package tconstruct.library.weaponry;
+
+import tconstruct.library.TConstructRegistry;
+import tconstruct.library.tools.BowMaterial;
+import tconstruct.library.tools.BowstringMaterial;
+import tconstruct.weaponry.ammo.ArrowAmmo;
+import tconstruct.weaponry.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, float windup) {
+ 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;
+
+ if(windup >= 1f)
+ arrow.setIsCritical(true);
+
+ 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)
+ {
+ // does the material have a bow material?
+ if(TConstructRegistry.getBowMaterial(id) == null)
+ return;
+
+ // 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
+ protected int getDefaultColor(int renderPass, int materialID) {
+ // bowstring uses custom material
+ if(renderPass == 0)
+ return TConstructRegistry.getCustomMaterial(materialID, BowstringMaterial.class).color;
+
+ return super.getDefaultColor(renderPass, materialID);
+ }
+
+ @Override
+ public String[] getTraits() {
+ return new String[] {"weapon", "bow", "windup"};
+ }
+}
diff --git a/src/main/java/tconstruct/library/weaponry/IAccuracy.java b/src/main/java/tconstruct/library/weaponry/IAccuracy.java
new file mode 100644
index 00000000..764ce990
--- /dev/null
+++ b/src/main/java/tconstruct/library/weaponry/IAccuracy.java
@@ -0,0 +1,10 @@
+package tconstruct.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, int time);
+}
diff --git a/src/main/java/tconstruct/library/weaponry/IAmmo.java b/src/main/java/tconstruct/library/weaponry/IAmmo.java
new file mode 100644
index 00000000..8c70a9c1
--- /dev/null
+++ b/src/main/java/tconstruct/library/weaponry/IAmmo.java
@@ -0,0 +1,45 @@
+package tconstruct.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);
+
+ /**
+ * Sets the Ammo amount to that absolute value. Behaviour for values below 0 or above the max ammo is undefined.
+ * @param count How much
+ * @param stack The itemstack to set the ammo for. Has to have proper NBT.
+ */
+ void setAmmo(int count, ItemStack stack);
+}
diff --git a/src/main/java/tconstruct/library/weaponry/IWindup.java b/src/main/java/tconstruct/library/weaponry/IWindup.java
new file mode 100644
index 00000000..31a6ae23
--- /dev/null
+++ b/src/main/java/tconstruct/library/weaponry/IWindup.java
@@ -0,0 +1,20 @@
+package tconstruct.library.weaponry;
+
+import tconstruct.weaponry.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/library/weaponry/ProjectileWeapon.java b/src/main/java/tconstruct/library/weaponry/ProjectileWeapon.java
new file mode 100644
index 00000000..5ed98a9a
--- /dev/null
+++ b/src/main/java/tconstruct/library/weaponry/ProjectileWeapon.java
@@ -0,0 +1,438 @@
+package tconstruct.library.weaponry;
+
+import net.minecraft.init.Items;
+import net.minecraft.util.StatCollector;
+import tconstruct.client.TProxyClient;
+import tconstruct.library.TConstructRegistry;
+import tconstruct.weaponry.client.CrosshairType;
+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.List;
+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.setCreativeTab(TConstructRegistry.weaponryTab);
+ }
+
+ @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, float windup);
+
+
+ /* 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 toolTag.getInteger("DrawSpeed");
+ }
+
+ 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");
+ }
+
+ /* 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;
+
+ // broken tool?
+ if(stack.hasTagCompound() && stack.getTagCompound().hasKey(getBaseTagName()) && stack.getTagCompound().getCompoundTag(getBaseTagName()).getBoolean("Broken"))
+ 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, windup);
+
+
+ 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(!player.capabilities.isCreativeMode) {
+ 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();
+ public HashMap animationEffectIcons = new HashMap();
+
+ /**
+ * 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) {
+ NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool");
+
+ if(tags == null || renderPass > 10)
+ return super.getIcon(stack, renderPass, player, usingItem, useRemaining);
+
+ // are we drawing an effect?
+ if(renderPass >= getPartAmount()) {
+ // is the effect animated?
+ String effect = "Effect" + (1 + renderPass - getPartAmount());
+ if(tags.hasKey(effect)) {
+ int index = tags.getInteger(effect);
+ if(animationEffectIcons.get(index) != null)
+ return getCorrectAnimationIcon(animationEffectIcons, index, getWindupProgress(usingItem, getMaxItemUseDuration(usingItem) - useRemaining));
+ else
+ // non-animated
+ return effectIcons.get(index);
+ }
+ return super.getIcon(stack, renderPass, player, usingItem, 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);
+
+ 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
+ @SideOnly(Side.CLIENT)
+ // exactly the same as the ToolCore one but with broken check for Handle instead of Head
+ public IIcon getIcon (ItemStack stack, int renderPass)
+ {
+ NBTTagCompound tags = stack.getTagCompound();
+
+ if (tags != null)
+ {
+ tags = stack.getTagCompound().getCompoundTag("InfiTool");
+ if (renderPass < getPartAmount())
+ {
+ // Handle
+ if (renderPass == 0) {
+ if (tags.getBoolean("Broken"))
+ return getCorrectIcon(brokenIcons, tags.getInteger("RenderHandle"));
+ else
+ return getCorrectIcon(handleIcons, tags.getInteger("RenderHandle"));
+ }
+ // Head
+ else if (renderPass == 1)
+ {
+ return getCorrectIcon(headIcons, tags.getInteger("RenderHead"));
+ }
+ // Accessory
+ else if (renderPass == 2)
+ return getCorrectIcon(accessoryIcons, tags.getInteger("RenderAccessory"));
+ // Extra
+ else if (renderPass == 3)
+ return getCorrectIcon(extraIcons, tags.getInteger("RenderExtra"));
+ }
+ // Effects
+ else if (renderPass <= 10)
+ {
+ String effect = "Effect" + (1 + renderPass - getPartAmount());
+ if(tags.hasKey(effect))
+ return effectIcons.get(tags.getInteger(effect));
+ }
+ return blankSprite;
+ }
+ return emptyIcon;
+ }
+
+ @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));
+
+ // animated effects...
+ // find out the longest animation
+ int count = 0;
+ if(animationHeadIcons.get(-1) != null)
+ count = Math.max(count, animationHeadIcons.get(-1).length);
+ if(animationHandleIcons.get(-1) != null)
+ count = Math.max(count, animationHandleIcons.get(-1).length);
+ if(animationAccessoryIcons.get(-1) != null)
+ count = Math.max(count, animationAccessoryIcons.get(-1).length);
+ if(animationExtraIcons.get(-1) != null)
+ count = Math.max(count, animationExtraIcons.get(-1).length);
+
+
+ for(Map.Entry entry : effectStrings.entrySet())
+ {
+ IIcon[] 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)
+ animationEffectIcons.put(entry.getKey(), anims);
+ }
+
+ // default for effects is blank
+ IIcon[] anims = new IIcon[count];
+ for(int i = 0; i < count; i++)
+ anims[i] = blankSprite;
+ animationEffectIcons.put(-1, anims);
+ }
+
+ 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);
+ }
+ }
+
+ @SideOnly(Side.CLIENT)
+ @Override
+ public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean par4) {
+ super.addInformation(stack, player, list, par4);
+
+ if(!stack.hasTagCompound())
+ return;
+
+ // also display max damage with current ammo
+ ItemStack currentAmmo = searchForAmmo(player, stack);
+ if(currentAmmo == null)
+ return;
+
+ float damage;
+ if(currentAmmo.getItem() == Items.arrow)
+ damage = 2;
+ else if(currentAmmo.getItem() instanceof AmmoItem && currentAmmo.hasTagCompound())
+ damage = currentAmmo.getTagCompound().getCompoundTag("InfiTool").getInteger("Attack");
+ else
+ return;
+
+ damage *= getProjectileSpeed(stack);
+ damage /= 2;
+
+ list.remove(list.size()-1); // remove last item (the damage of the bow itself)
+ list.add(currentAmmo.getDisplayName());
+ list.add(StatCollector.translateToLocal("attribute.name.ammo.maxAttackDamage") + ": " + TProxyClient.df.format(damage));
+ }
+}
diff --git a/src/main/java/tconstruct/modifiers/tools/ModAmmoRestock.java b/src/main/java/tconstruct/modifiers/tools/ModAmmoRestock.java
new file mode 100644
index 00000000..91a44a95
--- /dev/null
+++ b/src/main/java/tconstruct/modifiers/tools/ModAmmoRestock.java
@@ -0,0 +1,125 @@
+package tconstruct.modifiers.tools;
+
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import tconstruct.library.crafting.PatternBuilder;
+import tconstruct.library.modifier.IModifyable;
+import tconstruct.library.modifier.ItemModifier;
+import tconstruct.library.tools.AbilityHelper;
+import tconstruct.library.tools.ToolCore;
+import tconstruct.library.weaponry.AmmoItem;
+import tconstruct.library.weaponry.IAmmo;
+import tconstruct.weaponry.weapons.Shuriken;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class ModAmmoRestock extends ItemModifier {
+ public ModAmmoRestock()
+ {
+ super(new ItemStack[0], 0, "");
+ }
+
+ @Override
+ public boolean matches (ItemStack[] input, ItemStack tool)
+ {
+ return canModify(tool, input);
+ }
+
+ @Override
+ protected boolean canModify (ItemStack tool, ItemStack[] input)
+ {
+ if(!(tool.getItem() instanceof AmmoItem))
+ return false;
+
+ IAmmo ammo = (IAmmo)tool.getItem();
+
+ // full?
+ if(ammo.getAmmoCount(tool) >= ammo.getMaxAmmo(tool))
+ return false;
+
+ NBTTagCompound tags = tool.getTagCompound().getCompoundTag("InfiTool");
+ // correct material?
+
+ Set materials = new HashSet();
+ materials.add(tags.getInteger("Head"));
+ // shuriken allow all their components
+ if(tool.getItem() instanceof Shuriken) {
+ materials.add(tags.getInteger("Handle"));
+ materials.add(tags.getInteger("Accessory"));
+ materials.add(tags.getInteger("Extra"));
+ }
+
+ boolean areInputsValid = true;
+ for (ItemStack curInput : input)
+ {
+ if (curInput != null && !materials.contains(PatternBuilder.instance.getPartID(curInput)))
+ {
+ areInputsValid = false;
+ break;
+ }
+ }
+
+ return areInputsValid;
+ }
+
+ private int calculateIncrease (ItemStack tool, int materialValue, int itemsUsed)
+ {
+ NBTTagCompound tags = tool.getTagCompound().getCompoundTag("InfiTool");
+ float dur = tags.getInteger("BaseDurability") * ((AmmoItem)tool.getItem()).getAmmoModifier();
+ float increase = (5 * itemsUsed + (dur * 0.4f * materialValue/2f));
+
+ int modifiers = tags.getInteger("Modifiers");
+ float mods = 1.0f;
+ if (modifiers == 2)
+ mods = 0.9f;
+ else if (modifiers == 1)
+ mods = 0.8f;
+ else if (modifiers == 0)
+ mods = 0.7f;
+
+ increase *= mods;
+
+ int repair = tags.getInteger("RepairCount");
+ float repairCount = (100 - repair) / 100f;
+ if (repairCount < 0.5f)
+ repairCount = 0.5f;
+ increase *= repairCount;
+ increase /= ((ToolCore) tool.getItem()).getRepairCost();
+
+ return (int)increase;
+ }
+
+ @Override
+ public void modify (ItemStack[] input, ItemStack tool)
+ {
+ NBTTagCompound tags = tool.getTagCompound().getCompoundTag("InfiTool");
+ int itemsUsed = 0;
+ int materialValue = 0;
+ for (ItemStack curInput : input)
+ {
+ if (curInput != null)
+ {
+ materialValue += PatternBuilder.instance.getPartValue(curInput);
+ itemsUsed++;
+ }
+ }
+
+ int increase = calculateIncrease(tool, materialValue, itemsUsed);
+ int repair = tags.getInteger("RepairCount");
+ repair += itemsUsed;
+ tags.setInteger("RepairCount", repair);
+
+ ((IAmmo)tool.getItem()).addAmmo(increase, tool);
+ }
+
+ @Override
+ public void addMatchingEffect (ItemStack tool)
+ {
+ }
+
+ public boolean validType (IModifyable input)
+ {
+ return input.getModifyType().equals("Tool") || input.getModifyType().equals("Armor");
+ }
+}
diff --git a/src/main/java/tconstruct/modifiers/tools/ModAttack.java b/src/main/java/tconstruct/modifiers/tools/ModAttack.java
index 92337b18..8c7309bb 100644
--- a/src/main/java/tconstruct/modifiers/tools/ModAttack.java
+++ b/src/main/java/tconstruct/modifiers/tools/ModAttack.java
@@ -3,6 +3,9 @@ package tconstruct.modifiers.tools;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import tconstruct.library.modifier.IModifyable;
+import tconstruct.library.tools.ToolCore;
+
+import java.util.Arrays;
public class ModAttack extends ItemModTypeFilter
{
@@ -11,7 +14,9 @@ public class ModAttack extends ItemModTypeFilter
int threshold;
String guiType;
String modifierType;
+ boolean ammoOnly;
+ // Regular weapons
public ModAttack(String type, int effect, ItemStack[] items, int[] value)
{
super(effect, "ModAttack", items, value);
@@ -20,8 +25,22 @@ public class ModAttack extends ItemModTypeFilter
max = 72;
threshold = 24;
modifierType = "Tool";
+ ammoOnly = false;
}
+ // projectiles
+ public ModAttack(String type, int effect, ItemStack[] items, int[] value, boolean ammoOnly)
+ {
+ super(effect, "ModAttack", items, value);
+ tooltipName = "\u00a7fSharpness";
+ guiType = type;
+ max = 48;
+ threshold = 24;
+ modifierType = "Tool";
+ this.ammoOnly = ammoOnly;
+ }
+
+ // gloves
public ModAttack(String type, int effect, ItemStack[] items, int[] value, int max, int threshold, String modifierType)
{
super(effect, "ModAttack", items, value);
@@ -30,11 +49,18 @@ public class ModAttack extends ItemModTypeFilter
this.max = max;
this.threshold = threshold;
this.modifierType = modifierType;
+ ammoOnly = false;
}
@Override
protected boolean canModify (ItemStack tool, ItemStack[] input)
{
+ if(tool.getItem() instanceof ToolCore)
+ {
+ if(Arrays.asList(((ToolCore) tool.getItem()).getTraits()).contains("ammo") != ammoOnly)
+ return false;
+ }
+
if (tool.getItem() instanceof IModifyable)
{
IModifyable toolItem = (IModifyable) tool.getItem();
diff --git a/src/main/java/tconstruct/modifiers/tools/ModFlux.java b/src/main/java/tconstruct/modifiers/tools/ModFlux.java
index d1c0aa98..47a6713f 100644
--- a/src/main/java/tconstruct/modifiers/tools/ModFlux.java
+++ b/src/main/java/tconstruct/modifiers/tools/ModFlux.java
@@ -2,8 +2,12 @@ package tconstruct.modifiers.tools;
import cofh.api.energy.IEnergyContainerItem;
import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
+import tconstruct.library.modifier.IModifyable;
import tconstruct.library.tools.ToolCore;
import tconstruct.util.config.PHConstruct;
@@ -24,6 +28,12 @@ public class ModFlux extends ModBoolean
{
NBTTagCompound tags = tool.getTagCompound().getCompoundTag("InfiTool");
+ // not on ammo weapons, since they don't have durability technically
+ String[] traits = ((IModifyable)tool.getItem()).getTraits();
+ for(String trait : traits)
+ if("ammo".equals(trait))
+ return false;
+
ItemStack foundBattery = null;
// try to find the battery in the input
for (ItemStack stack : input)
diff --git a/src/main/java/tconstruct/modifiers/tools/ModLapis.java b/src/main/java/tconstruct/modifiers/tools/ModLapis.java
index 941bc894..8758769c 100644
--- a/src/main/java/tconstruct/modifiers/tools/ModLapis.java
+++ b/src/main/java/tconstruct/modifiers/tools/ModLapis.java
@@ -218,6 +218,6 @@ public class ModLapis extends ItemModTypeFilter
public boolean validType (ToolCore tool)
{
List list = Arrays.asList(tool.getTraits());
- return list.contains("weapon") || list.contains("harvest");
+ return !list.contains("ammo") && (list.contains("weapon") || list.contains("harvest"));
}
}
diff --git a/src/main/java/tconstruct/modifiers/tools/ModPiston.java b/src/main/java/tconstruct/modifiers/tools/ModPiston.java
index 8c54ede9..d850c48f 100644
--- a/src/main/java/tconstruct/modifiers/tools/ModPiston.java
+++ b/src/main/java/tconstruct/modifiers/tools/ModPiston.java
@@ -96,6 +96,6 @@ public class ModPiston extends ItemModTypeFilter
public boolean validType (ToolCore tool)
{
List list = Arrays.asList(tool.getTraits());
- return list.contains("weapon");
+ return list.contains("weapon") || list.contains("ammo");
}
}
diff --git a/src/main/java/tconstruct/modifiers/tools/ModRedstone.java b/src/main/java/tconstruct/modifiers/tools/ModRedstone.java
index 63782062..b40861f9 100644
--- a/src/main/java/tconstruct/modifiers/tools/ModRedstone.java
+++ b/src/main/java/tconstruct/modifiers/tools/ModRedstone.java
@@ -8,8 +8,8 @@ import tconstruct.library.tools.ToolCore;
public class ModRedstone extends ItemModTypeFilter
{
- String tooltipName;
- int max = 50;
+ public String tooltipName;
+ public int max = 50;
public ModRedstone(int effect, ItemStack[] items, int[] values)
{
@@ -111,13 +111,6 @@ public class ModRedstone extends ItemModTypeFilter
tags.setInteger(type[i], speed);
}
}
-
- if (tags.hasKey("DrawSpeed"))
- {
- int baseDrawSpeed = tags.getInteger("BaseDrawSpeed");
- int drawSpeed = (int) (baseDrawSpeed - (0.1f * baseDrawSpeed * (keyPair[0] / 50f)));
- tags.setInteger("DrawSpeed", drawSpeed);
- }
}
void updateModTag (ItemStack tool, int[] keys)
@@ -136,6 +129,10 @@ public class ModRedstone extends ItemModTypeFilter
public boolean validType (ToolCore tool)
{
List list = Arrays.asList(tool.getTraits());
- return list.contains("harvest") || list.contains("utility") || list.contains("bow");
+
+ // handled by the windup modifier
+ if(list.contains("windup"))
+ return false;
+ return list.contains("harvest") || list.contains("utility");
}
}
diff --git a/src/main/java/tconstruct/modifiers/tools/ModWindup.java b/src/main/java/tconstruct/modifiers/tools/ModWindup.java
new file mode 100644
index 00000000..a654b3d4
--- /dev/null
+++ b/src/main/java/tconstruct/modifiers/tools/ModWindup.java
@@ -0,0 +1,83 @@
+package tconstruct.modifiers.tools;
+
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import tconstruct.library.tools.ToolCore;
+
+import java.util.Arrays;
+import java.util.List;
+
+public class ModWindup extends ModRedstone {
+ public ModWindup(int effect, ItemStack[] items, int[] values) {
+ super(effect, items, values);
+ }
+
+ public boolean validType (ToolCore tool)
+ {
+ List list = Arrays.asList(tool.getTraits());
+ return list.contains("windup");
+ }
+
+ @Override
+ protected boolean canModify(ItemStack tool, ItemStack[] input) {
+ if(!super.canModify(tool, input))
+ return false;
+
+ float drawSSpeed = tool.getTagCompound().getCompoundTag("InfiTool").getFloat("DrawSpeed");
+ return drawSSpeed > 0.25f * 20f; // can't get below 1/4s
+ }
+
+ @Override
+ public void modify (ItemStack[] input, ItemStack tool)
+ {
+ NBTTagCompound tags = tool.getTagCompound().getCompoundTag("InfiTool");
+ int[] keyPair;
+ int increase = matchingAmount(input);
+ int current = 0;
+ if (tags.hasKey(key))
+ {
+ keyPair = tags.getIntArray(key);
+ if (keyPair[0] % max == 0)
+ {
+ keyPair[0] += increase;
+ keyPair[1] += max;
+ tags.setIntArray(key, keyPair);
+
+ int modifiers = tags.getInteger("Modifiers");
+ modifiers -= 1;
+ tags.setInteger("Modifiers", modifiers);
+ }
+ else
+ {
+ keyPair[0] += increase;
+ tags.setIntArray(key, keyPair);
+ }
+ current = keyPair[0];
+ updateModTag(tool, keyPair);
+ }
+ else
+ {
+ int modifiers = tags.getInteger("Modifiers");
+ modifiers -= 1;
+ tags.setInteger("Modifiers", modifiers);
+ String modName = "\u00a74Redstone (" + increase + "/" + max + ")";
+ int tooltipIndex = addToolTip(tool, tooltipName, modName);
+ keyPair = new int[] { increase, max, tooltipIndex };
+ current = keyPair[0];
+ tags.setIntArray(key, keyPair);
+ }
+
+ // 0.005 reduction per second, numbers are in ticks -> 0.10 == 0.005s
+ float boost = 0.10f * current;
+ // with added bonus for multiple modifiers of redstone
+ // so every 50 redstone you get a bonus speed
+ for(int i = 0; i < current/50; i++)
+ boost += 2.0f;
+
+ int baseDrawSpeed = tags.getInteger("BaseDrawSpeed");
+ int drawSpeed = baseDrawSpeed - (int)boost;
+ drawSpeed = Math.max(5, drawSpeed); // 0.25f is the minimum
+ tags.setInteger("DrawSpeed", drawSpeed);
+ }
+}
diff --git a/src/main/java/tconstruct/plugins/fmp/TinkerFMP.java b/src/main/java/tconstruct/plugins/fmp/TinkerFMP.java
new file mode 100644
index 00000000..8016b34b
--- /dev/null
+++ b/src/main/java/tconstruct/plugins/fmp/TinkerFMP.java
@@ -0,0 +1,56 @@
+package tconstruct.plugins.fmp;
+
+import codechicken.microblock.BlockMicroMaterial;
+import cpw.mods.fml.common.event.FMLInitializationEvent;
+import mantle.pulsar.pulse.Handler;
+import mantle.pulsar.pulse.Pulse;
+import tconstruct.TConstruct;
+import tconstruct.smeltery.TinkerSmeltery;
+import tconstruct.tools.TinkerTools;
+import tconstruct.world.TinkerWorld;
+
+@Pulse(id = "Tinkers FMP Compatibility", description = "Makes Tinkers Blocks Multipart compatible", modsRequired = "ForgeMultipart", forced = true)
+public class TinkerFMP {
+ @Handler
+ public void init(FMLInitializationEvent event)
+ {
+
+ TConstruct.logger.info("ForgeMultipart detected. Registering TConstruct decorative blocks with FMP.");
+
+ //make Tconstruct blocks multipartable!
+ if(TinkerWorld.metalBlock != null) {
+ // metal blocks
+ for (int i = 0; i < 11; i++)
+ BlockMicroMaterial.createAndRegister(TinkerWorld.metalBlock, i);
+ }
+
+ if(TinkerSmeltery.smeltery != null) {
+ // smeltery bricks
+ for (int i = 2; i < 12; i++) {
+ if (i == 3)
+ continue;
+ BlockMicroMaterial.createAndRegister(TinkerSmeltery.smeltery, i);
+ BlockMicroMaterial.createAndRegister(TinkerSmeltery.smelteryNether, i, TinkerSmeltery.smelteryNether.getUnlocalizedName() + "Nether");
+ }
+
+ // brownstone
+ for (int i = 0; i < 7; i++)
+ BlockMicroMaterial.createAndRegister(TinkerSmeltery.speedBlock, i);
+
+ // clear glass
+ BlockMicroMaterial.createAndRegister(TinkerSmeltery.clearGlass, 0);
+ for (int i = 0; i < 16; i++)
+ BlockMicroMaterial.createAndRegister(TinkerSmeltery.stainedGlassClear, i);
+ }
+
+ if(TinkerTools.multiBrick != null) {
+ // chisel bricks
+ for (int i = 0; i < 14; i++)
+ BlockMicroMaterial.createAndRegister(TinkerTools.multiBrick, i);
+
+ for (int i = 0; i < 16; i++)
+ BlockMicroMaterial.createAndRegister(TinkerTools.multiBrickFancy, i);
+ }
+
+ }
+}
diff --git a/src/main/java/tconstruct/plugins/nei/RecipeHandlerToolMaterials.java b/src/main/java/tconstruct/plugins/nei/RecipeHandlerToolMaterials.java
index 1e3ee128..15113caa 100644
--- a/src/main/java/tconstruct/plugins/nei/RecipeHandlerToolMaterials.java
+++ b/src/main/java/tconstruct/plugins/nei/RecipeHandlerToolMaterials.java
@@ -15,6 +15,8 @@ import tconstruct.library.crafting.CastingRecipe;
import tconstruct.library.crafting.PatternBuilder;
import tconstruct.library.crafting.PatternBuilder.ItemKey;
import tconstruct.library.crafting.PatternBuilder.MaterialSet;
+import tconstruct.library.tools.ArrowMaterial;
+import tconstruct.library.tools.BowMaterial;
import tconstruct.library.tools.DynamicToolPart;
import tconstruct.library.tools.ToolMaterial;
import tconstruct.library.util.HarvestLevels;
@@ -32,6 +34,8 @@ public class RecipeHandlerToolMaterials extends RecipeHandlerBase
public List toolParts;
public ToolMaterial material;
+ public BowMaterial bowMaterial;
+ public ArrowMaterial arrowMaterial;
public CachedToolMaterialsRecipe(List toolParts, int materialID)
{
@@ -43,6 +47,17 @@ public class RecipeHandlerToolMaterials extends RecipeHandlerBase
this.material = TConstructRegistry.getMaterial(materialID);
}
+ public CachedToolMaterialsRecipe(List toolParts, int materialID, boolean arrowBow)
+ {
+ this.toolParts = new ArrayList();
+ for (ItemStack stack : toolParts)
+ {
+ this.toolParts.add(new PositionedStack(stack, 10, 10));
+ }
+ this.arrowMaterial = TConstructRegistry.getArrowMaterial(materialID);
+ this.bowMaterial = TConstructRegistry.getBowMaterial(materialID);
+ }
+
@Override
public PositionedStack getIngredient ()
{
@@ -135,6 +150,23 @@ public class RecipeHandlerToolMaterials extends RecipeHandlerBase
}
}
}
+ if (crecipe.bowMaterial != null)
+ {
+ int y = 20;
+ int x = 35;
+ GuiDraw.drawString(EnumChatFormatting.BOLD + StatCollector.translateToLocal("tconstruct.nei.projectilematerials"), 35, 10, 0x404040, false);
+ GuiDraw.drawString(StatCollector.translateToLocal("gui.toolstation6") + crecipe.bowMaterial.drawspeed, x, y, 0x404040, false);
+ y += 10;
+ GuiDraw.drawString(StatCollector.translateToLocal("gui.toolstation7") + crecipe.bowMaterial.flightSpeedMax, x, y, 0x404040, false);
+ }
+ if (crecipe.arrowMaterial != null)
+ {
+ int y = 50;
+ int x = 35;
+ GuiDraw.drawString(StatCollector.translateToLocal("gui.toolstation8") + crecipe.arrowMaterial.mass, x, y, 0x404040, false);
+ y += 10;
+ GuiDraw.drawString(StatCollector.translateToLocal("gui.toolstation22") + crecipe.arrowMaterial.breakChance, x, y, 0x404040, false);
+ }
}
@Override
@@ -146,6 +178,7 @@ public class RecipeHandlerToolMaterials extends RecipeHandlerBase
for (int matID : TConstructRegistry.toolMaterials.keySet())
{
List toolParts = new ArrayList();
+
mat = TConstructRegistry.toolMaterials.get(matID);
for (ItemKey key : PatternBuilder.instance.materials)
{
@@ -178,8 +211,10 @@ public class RecipeHandlerToolMaterials extends RecipeHandlerBase
}
}
- if(toolParts.size() > 0)
+ if(toolParts.size() > 0) {
this.arecipes.add(new CachedToolMaterialsRecipe(toolParts, matID));
+ this.arecipes.add(new CachedToolMaterialsRecipe(toolParts, matID, true));
+ }
}
}
else
@@ -197,16 +232,20 @@ public class RecipeHandlerToolMaterials extends RecipeHandlerBase
if (materialID >= 0)
{
List toolParts = getSingleList(ingred);
- if(toolParts.size() > 0)
+ if(toolParts.size() > 0) {
this.arecipes.add(new CachedToolMaterialsRecipe(toolParts, materialID));
+ this.arecipes.add(new CachedToolMaterialsRecipe(toolParts, materialID, true));
+ }
}
}
else if (PatternBuilder.instance.getPartID(ingred) < Short.MAX_VALUE)
{
int materialID = PatternBuilder.instance.getPartID(ingred);
List toolParts = getSingleList(ingred);
- if(toolParts.size() > 0)
+ if(toolParts.size() > 0) {
this.arecipes.add(new CachedToolMaterialsRecipe(toolParts, materialID));
+ this.arecipes.add(new CachedToolMaterialsRecipe(toolParts, materialID, true));
+ }
}
else
{
diff --git a/src/main/java/tconstruct/tools/TActiveOmniMod.java b/src/main/java/tconstruct/tools/TActiveOmniMod.java
index 7cbcb30d..3d298301 100644
--- a/src/main/java/tconstruct/tools/TActiveOmniMod.java
+++ b/src/main/java/tconstruct/tools/TActiveOmniMod.java
@@ -15,6 +15,7 @@ import net.minecraft.world.World;
import net.minecraftforge.common.ForgeHooks;
import tconstruct.library.ActiveToolMod;
import tconstruct.library.tools.*;
+import tconstruct.library.weaponry.IAmmo;
import tconstruct.util.config.PHConstruct;
import tconstruct.world.TinkerWorld;
import tconstruct.world.entity.BlueSlime;
@@ -34,7 +35,15 @@ public class TActiveOmniMod extends ActiveToolMod
{
int chance = tags.getInteger("Moss");
int check = world.canBlockSeeTheSky((int) entity.posX, (int) entity.posY, (int) entity.posZ) ? 350 : 1150;
- if (random.nextInt(check) < chance)
+ // REGROWING AMMO :OOoo
+ if(tool instanceof IAmmo && random.nextInt(check*10) < chance) // ammo regenerates at a much slower rate
+ {
+ IAmmo ammothing = (IAmmo)tool;
+ if(ammothing.getAmmoCount(stack) > 0) // must have ammo
+ ammothing.addAmmo(1, stack);
+ }
+ // selfrepairing tool. LAAAAAME
+ else if (random.nextInt(check) < chance)
{
AbilityHelper.healTool(stack, 1, (EntityLivingBase) entity, true);
}
diff --git a/src/main/java/tconstruct/tools/TDispenserBehaviorArrow.java b/src/main/java/tconstruct/tools/TDispenserBehaviorArrow.java
deleted file mode 100644
index 917020e6..00000000
--- a/src/main/java/tconstruct/tools/TDispenserBehaviorArrow.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package tconstruct.tools;
-
-import net.minecraft.block.BlockDispenser;
-import net.minecraft.dispenser.*;
-import net.minecraft.item.ItemStack;
-import net.minecraft.util.EnumFacing;
-import net.minecraft.world.World;
-import tconstruct.tools.entity.ArrowEntity;
-
-public class TDispenserBehaviorArrow extends BehaviorDefaultDispenseItem
-{
-
- @Override
- public ItemStack dispenseStack (IBlockSource dispenser, ItemStack stack)
- {
- World world = dispenser.getWorld();
- // TODO getIPositionFromBlockSource
- IPosition iposition = BlockDispenser.func_149939_a(dispenser);
- // TODO getFacing
- EnumFacing enumfacing = BlockDispenser.func_149937_b(dispenser.getBlockMetadata());
-
- ItemStack arrowItem = stack.splitStack(1);
-
- ArrowEntity projectile = new ArrowEntity(world, iposition.getX(), iposition.getY(), iposition.getZ(), arrowItem);
- projectile.canBePickedUp = 1;
- projectile.setThrowableHeading((double) enumfacing.getFrontOffsetX(), (double) ((float) enumfacing.getFrontOffsetY() + 0.1F), (double) enumfacing.getFrontOffsetZ(), this.func_82500_b(), this.func_82498_a());
- world.spawnEntityInWorld(projectile);
-
- return stack;
- }
-
- @Override
- protected void playDispenseSound (IBlockSource dispenser)
- {
- dispenser.getWorld().playAuxSFX(1002, dispenser.getXInt(), dispenser.getYInt(), dispenser.getZInt(), 0);
- }
-
- protected float func_82498_a ()
- {
- return 6.0F;
- }
-
- protected float func_82500_b ()
- {
- return 1.1F;
- }
-}
diff --git a/src/main/java/tconstruct/tools/TinkerToolEvents.java b/src/main/java/tconstruct/tools/TinkerToolEvents.java
index 5b495c89..6a104b67 100644
--- a/src/main/java/tconstruct/tools/TinkerToolEvents.java
+++ b/src/main/java/tconstruct/tools/TinkerToolEvents.java
@@ -13,6 +13,7 @@ import net.minecraft.entity.projectile.EntityArrow;
import net.minecraft.init.Items;
import net.minecraft.item.*;
import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.network.play.server.S14PacketEntity;
import net.minecraft.util.*;
import net.minecraft.world.EnumDifficulty;
import net.minecraftforge.event.entity.living.*;
@@ -22,10 +23,12 @@ import net.minecraftforge.oredict.OreDictionary.OreRegisterEvent;
import tconstruct.TConstruct;
import tconstruct.armor.player.TPlayerStats;
import tconstruct.library.TConstructRegistry;
+import tconstruct.library.entity.ProjectileBase;
import tconstruct.library.event.*;
import tconstruct.library.tools.*;
import tconstruct.util.ItemHelper;
import tconstruct.util.config.PHConstruct;
+import tconstruct.util.network.MovementUpdatePacket;
public class TinkerToolEvents
{
@@ -104,57 +107,6 @@ public class TinkerToolEvents
handlePaper(toolTag, event.tool);
handleThaumium(toolTag, event.tool);
- if (event.tool == TinkerTools.shortbow)
- {
- BowMaterial top = TConstructRegistry.getBowMaterial(toolTag.getInteger("Head"));
- BowMaterial bottom = TConstructRegistry.getBowMaterial(toolTag.getInteger("Accessory"));
- BowstringMaterial string = (BowstringMaterial) TConstructRegistry.getCustomMaterial(toolTag.getInteger("Handle"), BowstringMaterial.class);
-
- if (top != null && bottom != null && string != null)
- {
- if (toolTag.getInteger("Handle") == 1)
- {
- int modifiers = toolTag.getInteger("Modifiers");
- modifiers += 1;
- toolTag.setInteger("Modifiers", modifiers);
- }
-
- int durability = (int) ((top.durability + bottom.durability) / 2 * string.durabilityModifier);
- toolTag.setInteger("TotalDurability", durability);
- toolTag.setInteger("BaseDurability", durability);
-
- int drawSpeed = (int) ((top.drawspeed + bottom.drawspeed) / 2 * string.drawspeedModifier);
- toolTag.setInteger("DrawSpeed", drawSpeed);
- toolTag.setInteger("BaseDrawSpeed", drawSpeed);
-
- float flightSpeed = (top.flightSpeedMax + bottom.flightSpeedMax) / 2f * string.flightSpeedModifier;
- toolTag.setFloat("FlightSpeed", flightSpeed);
- }
- }
-
- if (event.tool == TinkerTools.arrow)
- {
- ArrowMaterial head = TConstructRegistry.getArrowMaterial(toolTag.getInteger("Head"));
- ArrowMaterial shaft = TConstructRegistry.getArrowMaterial(toolTag.getInteger("Handle"));
- FletchingMaterial fletching = (FletchingMaterial) TConstructRegistry.getCustomMaterial(toolTag.getInteger("Accessory"), FletchingMaterial.class);
-
- if (head != null && shaft != null && fletching != null)
- {
- float mass = head.mass / 5f + shaft.mass + fletching.mass;
- float shatter = (head.breakChance + shaft.breakChance + fletching.breakChance) / 4f;
- float accuracy = (head.accuracy + shaft.accuracy + fletching.accuracy) / 3;
-
- ItemStack arrow = new ItemStack(event.tool, 4);
- toolTag.setInteger("TotalDurability", 0);
- toolTag.setFloat("Mass", mass);
- toolTag.setFloat("BreakChance", shatter);
- toolTag.setFloat("Accuracy", accuracy);
- toolTag.setInteger("Unbreaking", 10);
- arrow.setTagCompound(event.toolTag);
- event.overrideResult(arrow);
- }
- }
-
if (event.tool == TinkerTools.battlesign)
{
int modifiers = toolTag.getInteger("Modifiers");
@@ -271,40 +223,66 @@ public class TinkerToolEvents
EntityPlayer player = (EntityPlayer) event.entityLiving;
//Cutlass
ItemStack stack = player.getCurrentEquippedItem();
- if (stack != null && stack.getItem() == TinkerTools.battlesign && player.isUsingItem())
+ if (stack != null && stack.getItem() == TinkerTools.battlesign)
{
+ // broken battlesign?
+ if(!stack.hasTagCompound() || stack.getTagCompound().getCompoundTag("InfiTool").getBoolean("Broken"))
+ return;
+
DamageSource source = event.source;
if (!source.isUnblockable() && !source.isMagicDamage() && !source.isExplosion())
{
- if (source instanceof EntityDamageSourceIndirect)
+ if (source.isProjectile())
{
- if (TConstruct.random.nextInt(3) == 0)
- {
- Entity attacker = source.getEntity();
- Entity projectile = ((EntityDamageSourceIndirect) source).getSourceOfDamage();
- projectile.motionX *= -1;
- projectile.motionZ *= -1;
- projectile.setDead();
- event.setCanceled(true);
+ Entity projectile = source.getSourceOfDamage();
+ Vec3 motion = Vec3.createVectorHelper(projectile.motionX, projectile.motionY, projectile.motionZ);
+ Vec3 look = player.getLookVec();
- if (projectile.getClass() == EntityArrow.class && !player.worldObj.isRemote)
- {
- EntityArrow reflection = null;
- if (attacker instanceof EntityLivingBase)
- reflection = new EntityArrow(player.worldObj, (EntityLivingBase) attacker, 0);
- else
- reflection = new EntityArrow(player.worldObj, player, 0);
+ // this gives a factor of how much we're looking at the incoming arrow
+ double strength = -look.dotProduct(motion.normalize());
+ // we're looking away. oh no.
+ if(strength < 0.1)
+ return;
- Vec3 look = player.getLookVec();
- reflection.posX = projectile.posX;
- reflection.posY = projectile.posY;
- reflection.posZ = projectile.posZ;
- reflection.motionX = (projectile.motionX + (look.xCoord * 8)) / 6;
- reflection.motionY = (projectile.motionY + (look.yCoord * 8)) / 6;
- reflection.motionZ = (projectile.motionZ + (look.zCoord * 8)) / 6;
- reflection.damage = ((EntityArrow) projectile).damage;
- player.worldObj.spawnEntityInWorld(reflection);
- }
+ // no damage, hooraaay
+ event.setCanceled(true);
+
+ double speed = projectile.motionX*projectile.motionX + projectile.motionY*projectile.motionY + projectile.motionZ*projectile.motionZ;
+ speed = Math.sqrt(speed);
+
+ speed = (speed+2)*strength;
+
+
+
+ // now we simply set the look vector with the speed and get our new vector!
+ projectile.motionX = look.xCoord * speed;
+ projectile.motionY = look.yCoord * speed;
+ projectile.motionZ = look.zCoord * speed;
+
+ projectile.rotationYaw = (float)(Math.atan2(projectile.motionX, projectile.motionZ) * 180.0D / Math.PI);
+ projectile.rotationPitch = (float)(Math.atan2(projectile.motionY, speed) * 180.0D / Math.PI);
+
+ // send the current status to the client
+ TConstruct.packetPipeline.sendToAll(new MovementUpdatePacket(projectile));
+
+ if(projectile instanceof EntityArrow) {
+ ((EntityArrow) projectile).shootingEntity = player;
+
+ // the inverse is done when the event is cancelled in arrows etc.
+ // we reverse it so it has no effect. yay
+ projectile.motionX /= -0.10000000149011612D;
+ projectile.motionY /= -0.10000000149011612D;
+ projectile.motionZ /= -0.10000000149011612D;
+// projectile.rotationYaw -= 180.0F;
+// projectile.prevRotationYaw -= 180.0F;
+
+ // not needed at the client since it gets the absolute values sent
+
+
+ // tinker projectiles don't check for stuff hit to prevent weird behaviour.
+ // we have to de-defuse them so the reflected projectiles can hit stuff again
+ if(projectile instanceof ProjectileBase)
+ ((ProjectileBase) projectile).defused = false;
}
}
else
@@ -315,6 +293,9 @@ public class TinkerToolEvents
attacker.attackEntityFrom(DamageSource.causeThornsDamage(player), event.ammount);
}
}
+
+ // durability--
+ AbilityHelper.damageTool(stack, (int)Math.ceil(event.ammount/2f), player, false);
}
}
}
diff --git a/src/main/java/tconstruct/tools/TinkerTools.java b/src/main/java/tconstruct/tools/TinkerTools.java
index e3a9194c..945bb96e 100644
--- a/src/main/java/tconstruct/tools/TinkerTools.java
+++ b/src/main/java/tconstruct/tools/TinkerTools.java
@@ -31,6 +31,7 @@ import tconstruct.tools.items.*;
import tconstruct.tools.logic.*;
import tconstruct.util.ItemHelper;
import tconstruct.util.config.PHConstruct;
+import tconstruct.weaponry.TinkerWeaponry;
import tconstruct.world.TinkerWorld;
import tconstruct.world.blocks.SoilBlock;
import tconstruct.world.itemblocks.CraftedSoilItemBlock;
@@ -45,6 +46,18 @@ public class TinkerTools
@SidedProxy(clientSide = "tconstruct.tools.ToolProxyClient", serverSide = "tconstruct.tools.ToolProxyCommon")
public static ToolProxyCommon proxy;
+ // backwards compatibility
+ @Deprecated
+ public static Item bowstring;
+ @Deprecated
+ public static Item arrowhead;
+ @Deprecated
+ public static Item fletching;
+ @Deprecated
+ public static ToolCore shortbow;
+ @Deprecated
+ public static ToolCore arrow;
+
// Crafting blocks
public static Block toolStationWood;
public static Block toolStationStone;
@@ -100,15 +113,10 @@ public class TinkerTools
public static ToolCore cleaver;
public static ToolCore hammer;
public static ToolCore battleaxe;
- public static ToolCore shortbow;
- public static ToolCore arrow;
public static Item potionLauncher;
public static Item handGuard;
public static Item crossbar;
public static Item fullGuard;
- public static Item bowstring;
- public static Item arrowhead;
- public static Item fletching;
public static Block craftedSoil; //TODO: Untwine this
public static Block multiBrick;
public static Block multiBrickFancy;
@@ -215,11 +223,10 @@ public class TinkerTools
TinkerTools.hammer = new Hammer();
TinkerTools.battleaxe = new Battleaxe();
- TinkerTools.shortbow = new Shortbow();
- TinkerTools.arrow = new Arrow();
+ TinkerTools.arrow = new Arrow(); // to prevent nullpointers
- Item[] tools = { TinkerTools.pickaxe, TinkerTools.shovel, TinkerTools.hatchet, TinkerTools.broadsword, TinkerTools.longsword, TinkerTools.rapier, TinkerTools.dagger, TinkerTools.cutlass, TinkerTools.frypan, TinkerTools.battlesign, TinkerTools.mattock, TinkerTools.chisel, TinkerTools.lumberaxe, TinkerTools.cleaver, TinkerTools.scythe, TinkerTools.excavator, TinkerTools.hammer, TinkerTools.battleaxe, TinkerTools.shortbow, TinkerTools.arrow };
- String[] toolStrings = { "pickaxe", "shovel", "hatchet", "broadsword", "longsword", "rapier", "dagger", "cutlass", "frypan", "battlesign", "mattock", "chisel", "lumberaxe", "cleaver", "scythe", "excavator", "hammer", "battleaxe", "shortbow", "arrow" };
+ Item[] tools = { TinkerTools.pickaxe, TinkerTools.shovel, TinkerTools.hatchet, TinkerTools.broadsword, TinkerTools.longsword, TinkerTools.rapier, TinkerTools.dagger, TinkerTools.cutlass, TinkerTools.frypan, TinkerTools.battlesign, TinkerTools.mattock, TinkerTools.chisel, TinkerTools.lumberaxe, TinkerTools.cleaver, TinkerTools.scythe, TinkerTools.excavator, TinkerTools.hammer, TinkerTools.battleaxe};
+ String[] toolStrings = { "pickaxe", "shovel", "hatchet", "broadsword", "longsword", "rapier", "dagger", "cutlass", "frypan", "battlesign", "mattock", "chisel", "lumberaxe", "cleaver", "scythe", "excavator", "hammer", "battleaxe"};
for (int i = 0; i < tools.length; i++)
{
@@ -256,12 +263,10 @@ public class TinkerTools
TinkerTools.largeSwordBlade = new DynamicToolPart("_large_sword_blade", "LargeSwordBlade");
TinkerTools.hammerHead = new DynamicToolPart("_hammer_head", "HammerHead");
- TinkerTools.bowstring = new Bowstring().setUnlocalizedName("tconstruct.Bowstring");
- TinkerTools.arrowhead = new DynamicToolPart("_arrowhead", "ArrowHead");
- TinkerTools.fletching = new Fletching().setUnlocalizedName("tconstruct.Fletching");
- Item[] toolParts = { TinkerTools.toolRod, TinkerTools.toolShard, TinkerTools.pickaxeHead, TinkerTools.shovelHead, TinkerTools.hatchetHead, TinkerTools.binding, TinkerTools.toughBinding, TinkerTools.toughRod, TinkerTools.largePlate, TinkerTools.swordBlade, TinkerTools.wideGuard, TinkerTools.handGuard, TinkerTools.crossbar, TinkerTools.knifeBlade, TinkerTools.fullGuard, TinkerTools.frypanHead, TinkerTools.signHead, TinkerTools.chiselHead, TinkerTools.scytheBlade, TinkerTools.broadAxeHead, TinkerTools.excavatorHead, TinkerTools.largeSwordBlade, TinkerTools.hammerHead, TinkerTools.bowstring, TinkerTools.fletching, TinkerTools.arrowhead };
- String[] toolPartStrings = { "toolRod", "toolShard", "pickaxeHead", "shovelHead", "hatchetHead", "binding", "toughBinding", "toughRod", "heavyPlate", "swordBlade", "wideGuard", "handGuard", "crossbar", "knifeBlade", "fullGuard", "frypanHead", "signHead", "chiselHead", "scytheBlade", "broadAxeHead", "excavatorHead", "largeSwordBlade", "hammerHead", "bowstring", "fletching", "arrowhead" };
+
+ Item[] toolParts = { TinkerTools.toolRod, TinkerTools.toolShard, TinkerTools.pickaxeHead, TinkerTools.shovelHead, TinkerTools.hatchetHead, TinkerTools.binding, TinkerTools.toughBinding, TinkerTools.toughRod, TinkerTools.largePlate, TinkerTools.swordBlade, TinkerTools.wideGuard, TinkerTools.handGuard, TinkerTools.crossbar, TinkerTools.knifeBlade, TinkerTools.fullGuard, TinkerTools.frypanHead, TinkerTools.signHead, TinkerTools.chiselHead, TinkerTools.scytheBlade, TinkerTools.broadAxeHead, TinkerTools.excavatorHead, TinkerTools.largeSwordBlade, TinkerTools.hammerHead};
+ String[] toolPartStrings = { "toolRod", "toolShard", "pickaxeHead", "shovelHead", "hatchetHead", "binding", "toughBinding", "toughRod", "heavyPlate", "swordBlade", "wideGuard", "handGuard", "crossbar", "knifeBlade", "fullGuard", "frypanHead", "signHead", "chiselHead", "scytheBlade", "broadAxeHead", "excavatorHead", "largeSwordBlade", "hammerHead" };
for (int i = 0; i < toolParts.length; i++)
{
@@ -285,7 +290,7 @@ public class TinkerTools
registerStencils();
// this array is only used to register the remaining pattern-part-interactions
- TinkerTools.patternOutputs = new Item[] { TinkerTools.toolRod, TinkerTools.pickaxeHead, TinkerTools.shovelHead, TinkerTools.hatchetHead, TinkerTools.swordBlade, TinkerTools.wideGuard, TinkerTools.handGuard, TinkerTools.crossbar, TinkerTools.binding, TinkerTools.frypanHead, TinkerTools.signHead, TinkerTools.knifeBlade, TinkerTools.chiselHead, TinkerTools.toughRod, TinkerTools.toughBinding, TinkerTools.largePlate, TinkerTools.broadAxeHead, TinkerTools.scytheBlade, TinkerTools.excavatorHead, TinkerTools.largeSwordBlade, TinkerTools.hammerHead, TinkerTools.fullGuard, null, null, TinkerTools.arrowhead, null };
+ TinkerTools.patternOutputs = new Item[] { TinkerTools.toolRod, TinkerTools.pickaxeHead, TinkerTools.shovelHead, TinkerTools.hatchetHead, TinkerTools.swordBlade, TinkerTools.wideGuard, TinkerTools.handGuard, TinkerTools.crossbar, TinkerTools.binding, TinkerTools.frypanHead, TinkerTools.signHead, TinkerTools.knifeBlade, TinkerTools.chiselHead, TinkerTools.toughRod, TinkerTools.toughBinding, TinkerTools.largePlate, TinkerTools.broadAxeHead, TinkerTools.scytheBlade, TinkerTools.excavatorHead, TinkerTools.largeSwordBlade, TinkerTools.hammerHead, TinkerTools.fullGuard, null, null, TinkerWeaponry.arrowhead, null };
//Moved temporarily to deal with AE2 Quartz
TinkerTools.modFlux = new ModFlux();
@@ -405,10 +410,6 @@ public class TinkerTools
tb.addNormalToolRecipe(TinkerTools.hammer, TinkerTools.hammerHead, TinkerTools.toughRod, TinkerTools.largePlate, TinkerTools.largePlate);
tb.addNormalToolRecipe(TinkerTools.battleaxe, TinkerTools.broadAxeHead, TinkerTools.toughRod, TinkerTools.broadAxeHead, TinkerTools.toughBinding);
- BowRecipe recipe = new BowRecipe(TinkerTools.toolRod, TinkerTools.bowstring, TinkerTools.toolRod, TinkerTools.shortbow);
- tb.addCustomToolRecipe(recipe);
- tb.addNormalToolRecipe(TinkerTools.arrow, TinkerTools.arrowhead, TinkerTools.toolRod, TinkerTools.fletching);
-
ItemStack diamond = new ItemStack(Items.diamond);
ModifyBuilder.registerModifier(new ModToolRepair());
ModifyBuilder.registerModifier(new ModDurability(new ItemStack[] { diamond }, 0, 500, 0f, 3, "Diamond", "\u00a7b" + StatCollector.translateToLocal("modifier.tool.diamond"), "\u00a7b"));
@@ -620,7 +621,9 @@ public class TinkerTools
GameRegistry.addShapelessRecipe(new ItemStack(TinkerTools.manualBook, 2, 1), new ItemStack(TinkerTools.manualBook, 1, 1), Items.book);
GameRegistry.addShapelessRecipe(new ItemStack(TinkerTools.manualBook, 1, 2), new ItemStack(TinkerTools.manualBook, 1, 1));
GameRegistry.addShapelessRecipe(new ItemStack(TinkerTools.manualBook, 2, 2), new ItemStack(TinkerTools.manualBook, 1, 2), Items.book);
- GameRegistry.addShapelessRecipe(new ItemStack(TinkerTools.manualBook, 1, 3), new ItemStack(TinkerTools.manualBook, 1, 2));
+ GameRegistry.addShapelessRecipe(new ItemStack(TinkerTools.manualBook, 2, 4), new ItemStack(TinkerTools.manualBook, 1, 4), Items.book);
+ GameRegistry.addShapelessRecipe(new ItemStack(TinkerTools.manualBook, 1, 4), new ItemStack(TinkerTools.manualBook, 1, 2));
+ GameRegistry.addShapelessRecipe(new ItemStack(TinkerTools.manualBook, 1, 3), new ItemStack(TinkerTools.manualBook, 1, 4));
// alternative Vanilla Book Recipe
GameRegistry.addShapelessRecipe(new ItemStack(Items.book), Items.paper, Items.paper, Items.paper, Items.string, TinkerTools.blankPattern, TinkerTools.blankPattern);
GameRegistry.addRecipe(new ShapedOreRecipe(new ItemStack(Items.name_tag), "P~ ", "~O ", " ~", '~', Items.string, 'P', Items.paper, 'O', "slimeball"));
@@ -705,9 +708,18 @@ public class TinkerTools
TConstructRegistry.addPartMapping(TinkerTools.woodPattern, meta + 1, 31, new ItemStack(TinkerTools.patternOutputs[meta], 1, 31));
}
- TConstructRegistry.addBowstringMaterial(1, 2, new ItemStack((Item) obj, 1, 7), new ItemStack(TinkerTools.bowstring, 1, 1), 1F, 1F, 0.9f, 0x63bcd9);
- TConstructRegistry.addBowMaterial(31, 576, 40, 1.2f);
- TConstructRegistry.addArrowMaterial(31, 1.8F, 0.5F, 100F);
+ // Thaumium weaponry toolparts
+ if(TConstruct.pulsar.isPulseLoaded("Tinkers' Weaponry"))
+ {
+ for (int m = 0; m < TinkerWeaponry.patternOutputs.length; m++)
+ TConstructRegistry.addPartMapping(TinkerWeaponry.woodPattern, m, MaterialID.Thaumium, new ItemStack(TinkerWeaponry.patternOutputs[m], 1, MaterialID.Thaumium));
+
+ TConstructRegistry.addPartMapping(TinkerTools.woodPattern, 25, MaterialID.Thaumium, new ItemStack(TinkerWeaponry.arrowhead, 1, MaterialID.Thaumium));
+
+ TConstructRegistry.addBowstringMaterial(1, 2, new ItemStack((Item) obj, 1, 7), new ItemStack(TinkerWeaponry.bowstring, 1, 1), 1F, 0.8F, 0.9f, 0x63bcd9);
+ TConstructRegistry.addBowMaterial(31, 35, 4.75f);
+ TConstructRegistry.addArrowMaterial(31, 1.8F, 0.5F);
+ }
TConstructRegistry.addDefaultToolPartMaterial(MaterialID.Thaumium);
TConstructRegistry.addDefaultShardMaterial(MaterialID.Thaumium);
@@ -722,7 +734,7 @@ public class TinkerTools
try
{
Object plantItem = ItemHelper.getStaticItem("plantItem", "mods.natura.common.NContent");
- TConstructRegistry.addBowstringMaterial(2, 2, new ItemStack((Item) plantItem, 1, 7), new ItemStack(TinkerTools.bowstring, 1, 2), 1.2F, 0.8F, 1.3f, 0xd3414f);
+ TConstructRegistry.addBowstringMaterial(2, 2, new ItemStack((Item) plantItem, 1, 7), new ItemStack(TinkerWeaponry.bowstring, 1, 2), 1.2F, 1.1F, 1.2f, 0xd3414f);
}
catch (Exception e)
{
@@ -756,54 +768,6 @@ public class TinkerTools
TConstructRegistry.addToolMaterial(MaterialID.BlueSlime, "BlueSlime", 0, 1200, 150, 0, 2.0F, 0, 0f, AQUA.toString(), 0x66AEB0);
TConstructRegistry.addToolMaterial(MaterialID.PigIron, "PigIron", 3, 250, 600, 2, 1.3F, 1, 0f, RED.toString(), 0xF0A8A4);
- // Bow Materials: Material ID, durability, drawspeed, arrow speed
- TConstructRegistry.addBowMaterial(MaterialID.Wood, 384, 20, 1.0f); // Wood
- TConstructRegistry.addBowMaterial(MaterialID.Stone, 10, 80, 0.2f); // Stone
- TConstructRegistry.addBowMaterial(MaterialID.Iron, 576, 30, 1.2f); // Iron
- TConstructRegistry.addBowMaterial(MaterialID.Flint, 10, 80, 0.2f); // Flint
- TConstructRegistry.addBowMaterial(MaterialID.Cactus, 384, 20, 1.0f); // Cactus
- TConstructRegistry.addBowMaterial(MaterialID.Bone, 192, 30, 1.0f); // Bone
- TConstructRegistry.addBowMaterial(MaterialID.Obsidian, 10, 80, 0.2f); // Obsidian
- TConstructRegistry.addBowMaterial(MaterialID.Netherrack, 10, 80, 0.2f); // Netherrack
- TConstructRegistry.addBowMaterial(MaterialID.Slime, 1536, 30, 1.2f); // Slime
- TConstructRegistry.addBowMaterial(MaterialID.Paper, 48, 25, 0.5f); // Paper
- TConstructRegistry.addBowMaterial(MaterialID.Cobalt, 1152, 30, 1.2f); // Cobalt
- TConstructRegistry.addBowMaterial(MaterialID.Ardite, 960, 30, 1.2f); // Ardite
- TConstructRegistry.addBowMaterial(MaterialID.Manyullyn, 1536, 30, 1.2f); // Manyullyn
- TConstructRegistry.addBowMaterial(MaterialID.Copper, 384, 30, 1.2f); // Copper
- TConstructRegistry.addBowMaterial(MaterialID.Bronze, 576, 30, 1.2f); // Bronze
- TConstructRegistry.addBowMaterial(MaterialID.Alumite, 768, 30, 1.2f); // Alumite
- TConstructRegistry.addBowMaterial(MaterialID.Steel, 768, 30, 1.2f); // Steel
- TConstructRegistry.addBowMaterial(MaterialID.BlueSlime, 576, 20, 1.2f); // Blue Slime
- TConstructRegistry.addBowMaterial(MaterialID.PigIron, 384, 20, 1.2f); // Pig Iron
-
- // Fletchling 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, 100); //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
-
- TConstructRegistry.addBowstringMaterial(0, 2, new ItemStack(Items.string), new ItemStack(TinkerTools.bowstring, 1, 0), 1F, 1F, 1f, 0xeeeeee); // String
- TConstructRegistry.addFletchingMaterial(0, 2, new ItemStack(Items.feather), new ItemStack(TinkerTools.fletching, 1, 0), 100F, 0F, 0.05F, 0xffffff); // Feather
- TConstructRegistry.addCustomMaterial(new FletchlingLeafMaterial(1, 2, "treeLeaves", new ItemStack(TinkerTools.fletching, 1, 1), 75F, 0F, 0.2F)); // all vanilla and oredicted leaves. and all leaves in general.
- TConstructRegistry.addFletchingMaterial(2, 2, new ItemStack(TinkerTools.materials, 1, 1), new ItemStack(TinkerTools.fletching, 1, 2), 100F, 0F, 0.12F, 0x82c873); // Slime
- TConstructRegistry.addFletchingMaterial(3, 2, new ItemStack(TinkerTools.materials, 1, 17), new ItemStack(TinkerTools.fletching, 1, 3), 100F, 0F, 0.12F, 0x74c8c7); // BlueSlime
-
// Register all the materials for default toolparts
TConstructRegistry.addDefaultToolPartMaterial(MaterialID.Wood);
TConstructRegistry.addDefaultToolPartMaterial(MaterialID.Stone);
@@ -936,10 +900,6 @@ public class TinkerTools
StencilBuilder.registerStencil(18, TinkerTools.woodPattern, 8); // crossbar
StencilBuilder.registerStencil(19, TinkerTools.woodPattern, 7); // small guard
StencilBuilder.registerStencil(20, TinkerTools.woodPattern, 6); // wide guard
-
- StencilBuilder.registerStencil(21, TinkerTools.woodPattern, 25); // arrow head
- StencilBuilder.registerStencil(22, TinkerTools.woodPattern, 24); // fletchling
- StencilBuilder.registerStencil(23, TinkerTools.woodPattern, 23); // bowstring
}
public static final class MaterialID
diff --git a/src/main/java/tconstruct/tools/ToolProxyClient.java b/src/main/java/tconstruct/tools/ToolProxyClient.java
index d2f5979b..b8efe4c1 100644
--- a/src/main/java/tconstruct/tools/ToolProxyClient.java
+++ b/src/main/java/tconstruct/tools/ToolProxyClient.java
@@ -23,10 +23,12 @@ import tconstruct.library.client.*;
import tconstruct.library.crafting.*;
import tconstruct.library.tools.ToolCore;
import tconstruct.smeltery.TinkerSmeltery;
+import tconstruct.tools.client.DaggerEntityRenderer;
import tconstruct.tools.entity.*;
import tconstruct.tools.gui.*;
import tconstruct.tools.logic.*;
import tconstruct.tools.model.*;
+import tconstruct.weaponry.TinkerWeaponry;
import static tconstruct.tools.TinkerTools.*;
@@ -52,8 +54,9 @@ public class ToolProxyClient extends ToolProxyCommon
RenderingRegistry.registerBlockHandler(new BattlesignRender());
RenderingRegistry.registerEntityRenderingHandler(LaunchedPotion.class, new LaunchedItemRender(Items.potionitem, 16384));
- RenderingRegistry.registerEntityRenderingHandler(DaggerEntity.class, new DaggerRenderCustom());
- RenderingRegistry.registerEntityRenderingHandler(ArrowEntity.class, new ArrowRenderCustom());
+ RenderingRegistry.registerEntityRenderingHandler(DaggerEntity.class, new DaggerEntityRenderer());
+ //RenderingRegistry.registerEntityRenderingHandler(DaggerEntity.class, new DaggerRenderCustom());
+ //RenderingRegistry.registerEntityRenderingHandler(ArrowEntity.class, new ArrowRenderCustom());
RenderingRegistry.registerEntityRenderingHandler(FancyEntityItem.class, new FancyItemRender());
//MinecraftForgeClient.registerItemRenderer(TinkerTools.shortbow, new CustomBowRenderer());
@@ -76,10 +79,9 @@ public class ToolProxyClient extends ToolProxyCommon
MinecraftForgeClient.registerItemRenderer(TinkerTools.mattock, renderer);
MinecraftForgeClient.registerItemRenderer(TinkerTools.rapier, renderer);
MinecraftForgeClient.registerItemRenderer(TinkerTools.scythe, renderer);
- MinecraftForgeClient.registerItemRenderer(TinkerTools.shortbow, renderer);*/
+ */
renderer = new ToolCoreRenderer(true);
- MinecraftForgeClient.registerItemRenderer(TinkerTools.arrow, renderer);
- MinecraftForgeClient.registerItemRenderer(TinkerTools.dagger, renderer);
+ MinecraftForgeClient.registerItemRenderer(TinkerTools.dagger, renderer); // todo proper renderer
TileEntityRendererDispatcher.instance.mapSpecialRenderers.put(BattlesignLogic.class, new BattlesignTesr());
}
@@ -99,8 +101,8 @@ public class ToolProxyClient extends ToolProxyCommon
MantleClientRegistry.registerManualIcon("frypanicon", ToolBuilder.instance.buildTool(new ItemStack(TinkerTools.frypanHead, 1, 10), new ItemStack(TinkerTools.toolRod, 1, 11), null, ""));
MantleClientRegistry.registerManualIcon("battlesignicon", ToolBuilder.instance.buildTool(new ItemStack(TinkerTools.signHead, 1, 10), new ItemStack(TinkerTools.toolRod, 1, 11), null, ""));
MantleClientRegistry.registerManualIcon("chiselicon", ToolBuilder.instance.buildTool(new ItemStack(TinkerTools.chiselHead, 1, 10), new ItemStack(TinkerTools.toolRod, 1, 11), null, ""));
- MantleClientRegistry.registerManualIcon("shortbowIcon", ToolBuilder.instance.buildTool(new ItemStack(TinkerTools.toolRod, 1, 10), new ItemStack(TinkerTools.bowstring, 1, 0), new ItemStack(TinkerTools.toolRod, 1, 12), ""));
- MantleClientRegistry.registerManualIcon("arrowIcon", ToolBuilder.instance.buildTool(new ItemStack(TinkerTools.arrowhead, 1, 10), new ItemStack(TinkerTools.toolRod, 1, 11), new ItemStack(TinkerTools.fletching, 1, 0), ""));
+ //MantleClientRegistry.registerManualIcon("shortbowIcon", ToolBuilder.instance.buildTool(new ItemStack(TinkerTools.toolRod, 1, 10), new ItemStack(TinkerWeaponry.bowstring, 1, 0), new ItemStack(TinkerTools.toolRod, 1, 12), ""));
+ //MantleClientRegistry.registerManualIcon("arrowIcon", ToolBuilder.instance.buildTool(new ItemStack(TinkerWeaponry.arrowhead, 1, 10), new ItemStack(TinkerTools.toolRod, 1, 11), new ItemStack(TinkerWeaponry.fletching, 1, 0), ""));
MantleClientRegistry.registerManualIcon("hammericon", ToolBuilder.instance.buildTool(new ItemStack(TinkerTools.hammerHead, 1, 10), new ItemStack(TinkerTools.toughRod, 1, 11), new ItemStack(TinkerTools.largePlate, 1, 12), new ItemStack(TinkerTools.largePlate, 8), ""));
MantleClientRegistry.registerManualIcon("lumbericon", ToolBuilder.instance.buildTool(new ItemStack(TinkerTools.broadAxeHead, 1, 10), new ItemStack(TinkerTools.toughRod, 1, 11), new ItemStack(TinkerTools.largePlate, 1, 12), new ItemStack(TinkerTools.toughBinding, 8), ""));
@@ -136,9 +138,9 @@ public class ToolProxyClient extends ToolProxyCommon
MantleClientRegistry.registerManualIcon("toughbinding", new ItemStack(TinkerTools.toughBinding, 1, 17));
MantleClientRegistry.registerManualIcon("largeplate", new ItemStack(TinkerTools.largePlate, 1, 17));
- MantleClientRegistry.registerManualIcon("bowstring", new ItemStack(TinkerTools.bowstring, 1, 0));
- MantleClientRegistry.registerManualIcon("arrowhead", new ItemStack(TinkerTools.arrowhead, 1, 2));
- MantleClientRegistry.registerManualIcon("fletching", new ItemStack(TinkerTools.fletching, 1, 0));
+ MantleClientRegistry.registerManualIcon("bowstring", new ItemStack(TinkerWeaponry.bowstring, 1, 0));
+ MantleClientRegistry.registerManualIcon("arrowhead", new ItemStack(TinkerWeaponry.arrowhead, 1, 2));
+ MantleClientRegistry.registerManualIcon("fletching", new ItemStack(TinkerWeaponry.fletching, 1, 0));
//Tables
MantleClientRegistry.registerManualIcon("blankpattern", new ItemStack(TinkerTools.blankPattern, 1, 0));
@@ -340,10 +342,6 @@ public class ToolProxyClient extends ToolProxyCommon
{}, { 4, 3 }, // crossbar
{ 3, 3 }, // small guard
{ 2, 3 }, // wide guard
-
- {}, { 11, 3 }, // arrow head
- { 12, 3 }, // fletchling
- { 10, 3 }, // bowstring
};
int i = 0;
@@ -425,9 +423,6 @@ public class ToolProxyClient extends ToolProxyCommon
addToolButton(itemIconsT1[i][0], itemIconsT1[i][1], itemIconsT1[i][2], iconCoordsT1[i * 2], iconCoordsT1[i * 2 + 1], tier1Tools[i].getLocalizedToolName(), locString);
}
- addToolButton(3, 9, 1, new int[] { 0, 10, 0, 13 }, new int[] { 3, 3, 3, 13 }, TinkerTools.shortbow.getLocalizedToolName(), "gui.toolstation.shortbow.desc");
- addToolButton(7, 10, 1, new int[] { 11, 0, 12, 13 }, new int[] { 3, 3, 3, 13 }, TinkerTools.arrow.getLocalizedToolName(), "gui.toolstation.arrow.desc");
-
// tier 2 tools
for (int i = 0; i < tier2Tools.length; i++)
{
@@ -468,16 +463,5 @@ public class ToolProxyClient extends ToolProxyCommon
}
}
- String[] bowstringTypes = { "string", "magicfabric", "flamestring" };
- for (int bowIter = 0; bowIter < bowstringTypes.length; bowIter++)
- {
- TConstructClientRegistry.addAlternateMaterialRenderMapping(TinkerTools.shortbow, bowIter, "tinker", bowstringTypes[bowIter], true);
- }
-
- String[] fletching = { "feather", "leaf", "slime", "blueslime" };
- for (int arrowIter = 0; arrowIter < fletching.length; arrowIter++)
- {
- TConstructClientRegistry.addAlternateMaterialRenderMapping(TinkerTools.arrow, arrowIter, "tinker", fletching[arrowIter], true);
- }
}
}
diff --git a/src/main/java/tconstruct/tools/client/DaggerEntityRenderer.java b/src/main/java/tconstruct/tools/client/DaggerEntityRenderer.java
new file mode 100644
index 00000000..da953c91
--- /dev/null
+++ b/src/main/java/tconstruct/tools/client/DaggerEntityRenderer.java
@@ -0,0 +1,25 @@
+package tconstruct.tools.client;
+
+import org.lwjgl.opengl.GL11;
+import tconstruct.tools.entity.DaggerEntity;
+import tconstruct.weaponry.client.entity.ProjectileBaseRenderer;
+
+public class DaggerEntityRenderer extends ProjectileBaseRenderer {
+ @Override
+ public void customRendering(DaggerEntity 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 into a vertical position
+ GL11.glRotatef(90f, 0f, 1f, 0f);
+
+ // it rotates!
+ GL11.glRotatef(entity.roll, 0f, 0f, 1f);
+
+
+ // also make it a bit thicker
+ toolCoreRenderer.setDepth(1/20f);
+ }
+}
diff --git a/src/main/java/tconstruct/tools/entity/ArrowEntity.java b/src/main/java/tconstruct/tools/entity/ArrowEntity.java
index a721182a..cab20091 100644
--- a/src/main/java/tconstruct/tools/entity/ArrowEntity.java
+++ b/src/main/java/tconstruct/tools/entity/ArrowEntity.java
@@ -17,6 +17,7 @@ import net.minecraft.network.play.server.S2BPacketChangeGameState;
import net.minecraft.util.*;
import net.minecraft.world.World;
+@Deprecated
public class ArrowEntity extends EntityArrow implements IEntityAdditionalSpawnData
{
public ItemStack returnStack;
diff --git a/src/main/java/tconstruct/tools/entity/DaggerEntity.java b/src/main/java/tconstruct/tools/entity/DaggerEntity.java
index 94668b40..89fd24de 100644
--- a/src/main/java/tconstruct/tools/entity/DaggerEntity.java
+++ b/src/main/java/tconstruct/tools/entity/DaggerEntity.java
@@ -6,86 +6,60 @@ import net.minecraft.item.ItemStack;
import net.minecraft.util.*;
import net.minecraft.world.World;
import tconstruct.items.tools.Dagger;
+import tconstruct.library.entity.ProjectileBase;
import tconstruct.library.tools.*;
-public class DaggerEntity extends RotatingBase
+public class DaggerEntity extends ProjectileBase
{
+ public int roll;
- public DaggerEntity(World world)
- {
+ public DaggerEntity(World world) {
super(world);
}
- public DaggerEntity(ItemStack itemstack, World world, EntityPlayer entityplayer)
- {
- super(world, entityplayer, 0.75F, 0.8F);
- // TConstruct.logger.info("Stack: "+itemstack);
- returnStackSlot = entityplayer.inventory.currentItem;
- returnStack = itemstack;
+ public DaggerEntity(World world, double d, double d1, double d2) {
+ super(world, d, d1, d2);
}
- public DaggerEntity(World world, EntityPlayer entityplayer, float f, float g)
- {
- super(world, entityplayer, f, g);
- }
+ public DaggerEntity(World world, EntityPlayer player, float speed, float accuracy, ItemStack stack) {
+ super(world, player, speed, accuracy, stack);
- /*
- * public void entityInit () { super.entityInit(); }
- */
-
- @Override
- public void onHit (MovingObjectPosition movingobjectposition)
- {
- if (movingobjectposition.entityHit != null)
- {
- if (movingobjectposition.entityHit.attackEntityFrom(DamageSource.causeMobDamage(owner), damageDealt))
- {
- worldObj.playSoundAtEntity(this, "random.drr", 1.0F, 1.2F / (rand.nextFloat() * 0.2F + 0.9F));
- motionX *= -0.1D;
- motionY *= -0.1D;
- motionZ *= -0.1D;
- rotationYaw += 180F;
- prevRotationYaw += 180F;
- ticksInAir = 0;
- if (movingobjectposition.entityHit instanceof EntityLiving)
- {
- Dagger dagger = (Dagger) returnStack.getItem();
- this.hitEntity(returnStack, (EntityLiving) movingobjectposition.entityHit, owner, dagger);
- }
- }
- }
- else
- {
- onGround = true;
- xTile = movingobjectposition.blockX;
- yTile = movingobjectposition.blockY;
- zTile = movingobjectposition.blockZ;
- inTile = worldObj.getBlock(xTile, yTile, zTile);
- motionX = (float) (movingobjectposition.hitVec.xCoord - posX);
- motionY = (float) (movingobjectposition.hitVec.yCoord - posY);
- motionZ = (float) (movingobjectposition.hitVec.zCoord - posZ);
- float f = MathHelper.sqrt_double(motionX * motionX + motionY * motionY + motionZ * motionZ);
- posX -= (motionX / (double) f) * 0.05D;
- posY -= (motionY / (double) f) * 0.05D;
- posZ -= (motionZ / (double) f) * 0.05D;
- worldObj.playSoundAtEntity(this, "random.drr", 1.0F, 1.2F / (rand.nextFloat() * 0.2F + 0.9F));
- arrowShake = 7;
- if (!worldObj.isRemote)
- AbilityHelper.damageTool(returnStack, 1, owner, false);
- }
- }
-
- public boolean hitEntity (ItemStack stack, EntityLiving mob, EntityPlayer player, ToolCore weapon)
- {
- if (!worldObj.isRemote && player.canAttackWithItem())
- {
- AbilityHelper.onLeftClickEntity(stack, player, mob, weapon);
- }
- return true;
+ float pitch = Math.max(-90f, player.rotationPitch - 20f);
+ // same as in the others, but with pitch upped
+ this.setLocationAndAngles(player.posX, player.posY + (double)player.getEyeHeight(), player.posZ, player.rotationYaw, pitch);
+ 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);
}
@Override
- protected void dealFireDamage (int i)
- {
+ public void onUpdate() {
+ // you turn me right round baby
+ if(this.ticksInGround == 0)
+ roll = (roll + 20) % 360;
+
+ super.onUpdate();
+ }
+
+ @Override
+ public void onHitEntity(MovingObjectPosition movingobjectposition) {
+ AbilityHelper.onLeftClickEntity(returnStack, (EntityPlayer)shootingEntity, movingobjectposition.entityHit, (ToolCore)returnStack.getItem());
+ //super.onHitEntity(movingobjectposition);
+ }
+
+ @Override
+ protected double getGravity() {
+ return 0.1;
+ }
+
+ @Override
+ protected double getSlowdown() {
+ return 0.02;
}
}
diff --git a/src/main/java/tconstruct/tools/entity/RotatingBase.java b/src/main/java/tconstruct/tools/entity/RotatingBase.java
index c3e3fae3..f591a1b1 100644
--- a/src/main/java/tconstruct/tools/entity/RotatingBase.java
+++ b/src/main/java/tconstruct/tools/entity/RotatingBase.java
@@ -14,6 +14,7 @@ import net.minecraft.util.*;
import net.minecraft.world.World;
import tconstruct.library.tools.AbilityHelper;
+@Deprecated
public class RotatingBase extends Entity implements IEntityAdditionalSpawnData
{
diff --git a/src/main/java/tconstruct/tools/gui/CraftingStationGui.java b/src/main/java/tconstruct/tools/gui/CraftingStationGui.java
index e75ae7a8..6bd42bd7 100644
--- a/src/main/java/tconstruct/tools/gui/CraftingStationGui.java
+++ b/src/main/java/tconstruct/tools/gui/CraftingStationGui.java
@@ -22,6 +22,7 @@ import tconstruct.library.TConstructRegistry;
import tconstruct.library.accessory.AccessoryCore;
import tconstruct.library.armor.ArmorCore;
import tconstruct.library.crafting.PatternBuilder;
+import tconstruct.library.modifier.IModifyable;
import tconstruct.library.tools.*;
import tconstruct.library.util.HarvestLevels;
import tconstruct.tools.logic.CraftingStationLogic;
@@ -34,15 +35,6 @@ public class CraftingStationGui extends GuiContainer implements INEIGuiHandler
public GuiTextField text;
public String title, body = "";
CraftingStationLogic logic;
-
- boolean hasMaterial;
- boolean hasTool;
- boolean hasArmor;
- boolean hasAccessory;
- ItemStack centerStack;
- ToolMaterial materialEnum;
- String centerTitle;
- NBTTagCompound tags;
public static final int CHEST_WIDTH = 116;
@@ -139,394 +131,29 @@ public class CraftingStationGui extends GuiContainer implements INEIGuiHandler
void drawToolStats (ItemStack stack)
{
- int offsetX = descTextLeft + 63;
- int descX = descTextLeft + 10;
+ if(stack.getItem() instanceof IModifyable)
+ ToolStationGuiHelper.drawToolStats(stack, descTextLeft + 10, 0);
- if (centerStack != stack)
+
+ int matID = PatternBuilder.instance.getPartID(stack);
+
+ if (matID != Short.MAX_VALUE && matID > 0)
{
- centerStack = stack;
- hasAccessory = hasArmor = hasMaterial = hasTool = false;
+ ToolMaterial material = TConstructRegistry.getMaterial(matID);
- int matID = PatternBuilder.instance.getPartID(stack);
-
- if (matID != Short.MAX_VALUE)
- {
- materialEnum = TConstructRegistry.getMaterial(matID);
- hasMaterial = true;
- centerTitle = "\u00A7n" + materialEnum.localizedName();
- }
- else if (stack.getItem() instanceof ToolCore)
- {
- ToolCore tool = (ToolCore) stack.getItem();
- tags = stack.getTagCompound().getCompoundTag(tool.getBaseTagName());
- hasTool = true;
- centerTitle = "\u00A7n" + tool.getLocalizedToolName();
- }
- else if (stack.getItem() instanceof ArmorCore)
- {
- ArmorCore armor = (ArmorCore) stack.getItem();
- tags = stack.getTagCompound().getCompoundTag(armor.getBaseTagName());
- hasArmor = true;
- centerTitle = "\u00A7n" + stack.getDisplayName(); // todo: localize
- }
- else if (stack.getItem() instanceof AccessoryCore)
- {
- AccessoryCore accessory = (AccessoryCore) stack.getItem();
- tags = stack.getTagCompound().getCompoundTag(accessory.getBaseTagName());
- hasAccessory = true;
- centerTitle = "\u00A7n" + stack.getDisplayName(); // todo: localize
- }
- }
-
- if (hasAccessory || hasArmor || hasMaterial || hasTool)
- {
- this.drawCenteredString(fontRendererObj, centerTitle, offsetX, 8, 0xffffff);
-
- if (hasTool)
- {
- drawModularToolStats();
- }
- else if (hasArmor)
- {
- drawModularArmorStats();
- }
- else if (hasAccessory)
- {
- drawModularAccessoryStats();
- }
- else if (hasMaterial)
- {
- drawMaterialStats();
- }
- }
- else
- {
- drawToolInformation();
- }
- }
-
- protected void drawModularToolStats ()
- {
- ToolCore tool = (ToolCore)centerStack.getItem();
-
- List categories = Arrays.asList(tool.getTraits());
- final int durability = tags.getInteger("Damage");
- final int maxDur = tags.getInteger("TotalDurability");
- int availableDurability = maxDur - durability;
-
- // Durability
- final int baseX = descTextLeft + 10;
- final int baseY = 24;
- int offset = 0;
- if (maxDur > 0)
- {
- if (maxDur >= 10000)
- {
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation1"), baseX, baseY + offset * 11, 0xffffff);
- offset++;
- fontRendererObj.drawString("- " + availableDurability + "/" + maxDur, baseX, baseY + offset * 10, 0xffffff);
- offset++;
- }
- else
- {
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation2") + availableDurability + "/" + maxDur, baseX, baseY + offset * 10, 0xffffff);
- offset++;
- }
- }
-
- final float stonebound = tags.getFloat("Shoddy");
- // Attack
- if (categories.contains("weapon"))
- {
- int attack = (int) (tags.getInteger("Attack")) + 1;
- float stoneboundDamage = (float) Math.log(durability / 72f + 1) * -2 * stonebound;
- attack += stoneboundDamage;
- attack *= tool.getDamageModifier();
- if (attack < 1)
- attack = 1;
-
- String heart = attack == 2 ? StatCollector.translateToLocal("gui.partcrafter8") : StatCollector.translateToLocal("gui.partcrafter9");
- if (attack % 2 == 0)
- this.fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation3") + attack / 2 + heart, baseX, baseY + offset * 10, 0xffffff);
- else
- this.fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation3") + attack / 2f + heart, baseX, baseY + offset * 10, 0xffffff);
- offset++;
-
- if (stoneboundDamage != 0)
- {
- DecimalFormat df = new DecimalFormat("##.##");
- heart = stoneboundDamage == 2 ? StatCollector.translateToLocal("gui.partcrafter8") : StatCollector.translateToLocal("gui.partcrafter9");
- String bloss = stoneboundDamage > 0 ? StatCollector.translateToLocal("gui.toolstation4") : StatCollector.translateToLocal("gui.toolstation5");
- this.fontRendererObj.drawString(bloss + df.format(stoneboundDamage / 2f) + heart, baseX, baseY + offset * 10, 0xffffff);
- offset++;
- }
- offset++;
- }
-
- if (categories.contains("bow"))
- {
- DecimalFormat df = new DecimalFormat("##.##");
- df.setRoundingMode(RoundingMode.DOWN);
- int drawSpeed = tags.getInteger("DrawSpeed");
- float flightSpeed = tags.getFloat("FlightSpeed");
- float trueDraw = drawSpeed / 20f * flightSpeed;
- this.fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation6") + df.format(trueDraw) + "s", baseX, baseY + offset * 10, 0xffffff);
- offset++;
- this.fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation7") + df.format(flightSpeed) + "x", baseX, baseY + offset * 10, 0xffffff);
- offset++;
- offset++;
- }
-
- if (categories.contains("ammo"))
- {
- DecimalFormat df = new DecimalFormat("##.##");
- df.setRoundingMode(RoundingMode.DOWN);
- int attack = (int) (tags.getInteger("Attack"));
- float mass = tags.getFloat("Mass");
- float shatter = tags.getFloat("BreakChance");
- float accuracy = tags.getFloat("Accuracy");
-
- this.fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation10"), baseX, baseY + offset * 10, 0xffffff);
- offset++;
- String heart = attack == 2 ? StatCollector.translateToLocal("gui.partcrafter8") : StatCollector.translateToLocal("gui.partcrafter9");
- if (attack % 2 == 0)
- this.fontRendererObj.drawString("- " + attack / 2 + heart, baseX, baseY + offset * 10, 0xffffff);
- else
- this.fontRendererObj.drawString("- " + attack / 2f + heart, baseX, baseY + offset * 10, 0xffffff);
- offset++;
- int minAttack = attack;
- int maxAttack = attack * 2;
- heart = StatCollector.translateToLocal("gui.partcrafter9");
- this.fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation11"), baseX, baseY + offset * 10, 0xffffff);
- offset++;
- this.fontRendererObj.drawString(df.format(minAttack / 2f) + "-" + df.format(maxAttack / 2f) + heart, baseX, baseY + offset * 10, 0xffffff);
- offset++;
- offset++;
-
- this.fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation8") + df.format(mass), baseX, baseY + offset * 10, 0xffffff);
- offset++;
- this.fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation9") + df.format(accuracy - 4) + "%", baseX, baseY + offset * 10, 0xffffff);
- offset++;
- /*
- * this.fontRendererObj.drawString("Chance to break: " +
- * df.format(shatter)+"%", xSize + 8, base + offset * 10, 0xffffff);
- * offset++;
- */
- offset++;
- }
-
- // Mining
- if (categories.contains("dualharvest"))
- {
- float mineSpeed = tags.getInteger("MiningSpeed") / 100f * ((HarvestTool) tool).breakSpeedModifier();
- float mineSpeed2 = tags.getInteger("MiningSpeed2") / 100f * ((HarvestTool) tool).breakSpeedModifier();
- float stoneboundSpeed = (float) Math.log(durability / ((HarvestTool) tool).stoneboundModifier() + 1) * 2 * stonebound;
- DecimalFormat df = new DecimalFormat("##.##");
- df.setRoundingMode(RoundingMode.DOWN);
- float trueSpeed = mineSpeed + stoneboundSpeed;
- float trueSpeed2 = mineSpeed2 + stoneboundSpeed;
-
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation12"), baseX, baseY + offset * 10, 0xffffff);
- offset++;
- fontRendererObj.drawString("- " + df.format(trueSpeed) + ", " + df.format(trueSpeed2), baseX, baseY + offset * 10, 0xffffff);
- offset++;
- if (stoneboundSpeed != 0)
- {
- String bloss = stoneboundSpeed > 0 ? StatCollector.translateToLocal("gui.toolstation4") : StatCollector.translateToLocal("gui.toolstation5");
- fontRendererObj.drawString(bloss + df.format(stoneboundSpeed), baseX, baseY + offset * 10, 0xffffff);
- offset++;
- }
- offset++;
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation13"), baseX, baseY + offset * 10, 0xffffff);
- offset++;
- fontRendererObj.drawString("- " + HarvestLevels.getHarvestLevelName(tags.getInteger("HarvestLevel")) + ", " + HarvestLevels.getHarvestLevelName(tags.getInteger("HarvestLevel2")), baseX, baseY + offset * 10, 0xffffff);
- offset++;
- offset++;
- }
- else if (categories.contains("harvest"))
- {
- float trueSpeed = AbilityHelper.calcToolSpeed(tool, tags);
- float stoneboundSpeed = AbilityHelper.calcToolSpeed(tool, tags);
-
- DecimalFormat df = new DecimalFormat("##.##");
- df.setRoundingMode(RoundingMode.DOWN);
- trueSpeed += stoneboundSpeed;
- if (trueSpeed < 0)
- trueSpeed = 0;
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation14") + df.format(trueSpeed), baseX, baseY + offset * 10, 0xffffff);
- offset++;
- if (stoneboundSpeed != 0 && !Float.isNaN(stoneboundSpeed))
- {
- String bloss = stoneboundSpeed > 0 ? StatCollector.translateToLocal("gui.toolstation4") : StatCollector.translateToLocal("gui.toolstation5");
- fontRendererObj.drawString(bloss + df.format(stoneboundSpeed), baseX, baseY + offset * 10, 0xffffff);
- offset++;
- }
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation15") + HarvestLevels.getHarvestLevelName(tags.getInteger("HarvestLevel")), baseX, baseY + offset * 10, 0xffffff);
- offset++;
- offset++;
- }
- else if (categories.contains("utility"))
- {
- float mineSpeed = tags.getInteger("MiningSpeed");
- float trueSpeed = mineSpeed / (100f);
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation16") + trueSpeed, baseX, baseY + offset * 10, 0xffffff);
- offset++;
- offset++;
- }
-
- int modifiers = tags.getInteger("Modifiers");
- if (modifiers > 0)
- {
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation18") + tags.getInteger("Modifiers"), baseX, baseY + offset * 10, 0xffffff);
- offset++;
- }
- if (tags.hasKey("Tooltip1"))
- {
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation17"), baseX, baseY + offset * 10, 0xffffff);
- }
-
- boolean displayToolTips = true;
- int tipNum = 0;
- while (displayToolTips)
- {
- tipNum++;
- String tooltip = "ModifierTip" + tipNum;
- if (tags.hasKey(tooltip))
- {
- String tipName = tags.getString(tooltip);
- fontRendererObj.drawString("- " + tipName, baseX, baseY + (offset + tipNum) * 10, 0xffffff);
- }
- else
- displayToolTips = false;
- }
- }
-
- private static DecimalFormat df = new DecimalFormat("##.#");
-
- // todo: do this properly, quick and dirty fix
- protected void drawModularArmorStats ()
- {
- ArmorCore armor = (ArmorCore)centerStack.getItem();
- List categories = Arrays.asList(armor.getTraits());
- final int baseX = descTextLeft + 10;
- final int baseY = 24;
- int offset = 0;
-
- // durability
- final int durability = tags.getInteger("Damage");
- final int maxDur = tags.getInteger("TotalDurability");
- int availableDurability = maxDur - durability;
-
- // Durability
- if (maxDur > 0)
- {
- if (maxDur >= 10000)
- {
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation1"), baseX, baseY + offset * 11, 0xffffff);
- offset++;
- fontRendererObj.drawString("- " + availableDurability + "/" + maxDur, baseX, baseY + offset * 10, 0xffffff);
- offset++;
- }
- else
- {
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation2") + availableDurability + "/" + maxDur, baseX, baseY + offset * 10, 0xffffff);
- offset++;
- }
- }
- // Damage reduction
- double damageReduction = tags.getDouble("DamageReduction");
- if(damageReduction > 0.000001d)
- {
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation19") + df.format(damageReduction), baseX, baseY + offset * 10, 0xffffff);
- offset++;
- }
-
- // Protection
- double protection = armor.getProtection(centerStack);
- double maxProtection = tags.getDouble("MaxDefense");
- //if(maxProtection > protection)
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation20") + df.format(protection) + "/" + df.format(maxProtection), baseX, baseY + offset * 10, 0xffffff);
- //else
- // fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation20") + df.format(protection), x, base + offset * 10, 0xffffff);
- offset++;
-
- offset++;
- int modifiers = tags.getInteger("Modifiers");
- if (modifiers > 0)
- {
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation18") + tags.getInteger("Modifiers"), baseX, baseY + offset * 10, 0xffffff);
- offset++;
- }
- if (tags.hasKey("Tooltip1"))
- {
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation17"), baseX, baseY + offset * 10, 0xffffff);
- }
-
- boolean displayToolTips = true;
- int tipNum = 0;
- while (displayToolTips)
- {
- tipNum++;
- String tooltip = "ModifierTip" + tipNum;
- if (tags.hasKey(tooltip))
- {
- String tipName = tags.getString(tooltip);
- fontRendererObj.drawString("- " + tipName, baseX, baseY + (offset + tipNum) * 10, 0xffffff);
- }
- else
- displayToolTips = false;
- }
- }
-
- // todo: also quick and dirty fix
- protected void drawModularAccessoryStats ()
- {
- AccessoryCore accessory = (AccessoryCore)centerStack.getItem();
- List categories = Arrays.asList(accessory.getTraits());
- final int baseX = descTextLeft + 10;
- final int baseY = 24;
- int offset = 0;
-
- if (categories.contains("utility"))
- {
- float mineSpeed = tags.getInteger("MiningSpeed");
- float trueSpeed = mineSpeed / (100f);
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation16") + trueSpeed, baseX, baseY + offset * 10, 0xffffff);
- offset++;
- }
-
- offset++;
- int modifiers = tags.getInteger("Modifiers");
- if (modifiers > 0)
- {
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation18") + tags.getInteger("Modifiers"), baseX, baseY + offset * 10, 0xffffff);
- offset++;
- }
- if (tags.hasKey("Tooltip1"))
- {
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation17"), baseX, baseY + offset * 10, 0xffffff);
- }
-
- boolean displayToolTips = true;
- int tipNum = 0;
- while (displayToolTips)
- {
- tipNum++;
- String tooltip = "ModifierTip" + tipNum;
- if (tags.hasKey(tooltip))
- {
- String tipName = tags.getString(tooltip);
- fontRendererObj.drawString("- " + tipName, baseX, baseY + (offset + tipNum) * 10, 0xffffff);
- }
- else
- displayToolTips = false;
+ if(material != null)
+ drawMaterialStats(material);
}
}
- protected void drawMaterialStats()
+ protected void drawMaterialStats(ToolMaterial materialEnum)
{
final int baseX = descTextLeft + 8;
- final int baseY = 24;
+ final int baseY = 8;
+
+ String centerTitle = "\u00A7n" + materialEnum.localizedName();
+
+ drawCenteredString(this.fontRendererObj, centerTitle, baseX + 55, baseY, 16777215);
this.fontRendererObj.drawString(StatCollector.translateToLocal("gui.partcrafter4") + materialEnum.durability(), baseX, baseY + 16, 16777215);
this.fontRendererObj.drawString(StatCollector.translateToLocal("gui.partcrafter5") + materialEnum.handleDurability() + "x", baseX, baseY + 27, 16777215);
diff --git a/src/main/java/tconstruct/tools/gui/StencilTableGui.java b/src/main/java/tconstruct/tools/gui/StencilTableGui.java
index ac94c203..76e2c6a6 100644
--- a/src/main/java/tconstruct/tools/gui/StencilTableGui.java
+++ b/src/main/java/tconstruct/tools/gui/StencilTableGui.java
@@ -1,5 +1,9 @@
package tconstruct.tools.gui;
+import codechicken.nei.VisiblityData;
+import codechicken.nei.api.INEIGuiHandler;
+import codechicken.nei.api.TaggedInventoryArea;
+import cpw.mods.fml.common.Optional;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.entity.player.InventoryPlayer;
@@ -14,7 +18,11 @@ import tconstruct.tools.inventory.PatternShaperContainer;
import tconstruct.tools.logic.StencilTableLogic;
import tconstruct.util.network.PatternTablePacket;
-public class StencilTableGui extends GuiContainer
+import java.util.Collections;
+import java.util.List;
+
+@Optional.Interface(iface = "codechicken.nei.api.INEIGuiHandler", modid = "NotEnoughItems")
+public class StencilTableGui extends GuiContainer implements INEIGuiHandler
{
StencilTableLogic logic;
int activeButton;
@@ -135,4 +143,34 @@ public class StencilTableGui extends GuiContainer
{
TConstruct.packetPipeline.sendToServer(new PatternTablePacket(logic.xCoord, logic.yCoord, logic.zCoord, stack));
}
+
+ @Override
+ public VisiblityData modifyVisiblity(GuiContainer guiContainer, VisiblityData visiblityData) {
+ return visiblityData;
+ }
+
+ @Override
+ public Iterable getItemSpawnSlots(GuiContainer guiContainer, ItemStack itemStack) {
+ return null;
+ }
+
+ @Override
+ public List getInventoryAreas(GuiContainer guiContainer) {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean handleDragNDrop(GuiContainer guiContainer, int i, int i2, ItemStack itemStack, int i3) {
+ return false;
+ }
+
+ @Override
+ public boolean hideItemPanelSlot(GuiContainer guiContainer, int x, int y, int w, int h) {
+ // is it in the horizontal column of the right buttons?
+ if(x > this.guiLeft + this.xSize + 4 && x < this.guiLeft + this.xSize + 4 + 22*3 + 16)
+ if(y > this.guiTop - 10 && y < this.guiTop + 2 + 22*(TConstructClientRegistry.stencilButtons2.size()-1)/4 + 22*(TConstructClientRegistry.stencilButtons2.size()%4 > 0 ? 1 : 0))
+ return true;
+
+ return false;
+ }
}
\ No newline at end of file
diff --git a/src/main/java/tconstruct/tools/gui/ToolForgeGui.java b/src/main/java/tconstruct/tools/gui/ToolForgeGui.java
index 0891860b..46dd352f 100644
--- a/src/main/java/tconstruct/tools/gui/ToolForgeGui.java
+++ b/src/main/java/tconstruct/tools/gui/ToolForgeGui.java
@@ -117,6 +117,14 @@ public class ToolForgeGui extends ToolStationGui
slotX = new int[] { 56, 56, 56, 14 }; // Three parts reverse
slotY = new int[] { 19, 37, 55, 37 };
break;
+ case 8:
+ slotX = new int[] { 20, 38, 56, 38 }; // Double head middle
+ slotY = new int[] { 28, 46, 28, 28 };
+ break;
+ case 9:
+ slotX = new int[] { 38, 56, 47, 47 }; // Four parts, crossbow.
+ slotY = new int[] { 37, 37, 55, 19 };
+ break;
}
toolSlots.resetSlots(slotX, slotY);
}
diff --git a/src/main/java/tconstruct/tools/gui/ToolStationGui.java b/src/main/java/tconstruct/tools/gui/ToolStationGui.java
index 72726167..8f0602f3 100644
--- a/src/main/java/tconstruct/tools/gui/ToolStationGui.java
+++ b/src/main/java/tconstruct/tools/gui/ToolStationGui.java
@@ -7,6 +7,7 @@ import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;
+import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.*;
import net.minecraft.client.gui.inventory.GuiContainer;
import net.minecraft.entity.player.InventoryPlayer;
@@ -178,351 +179,11 @@ public class ToolStationGui extends GuiContainer implements INEIGuiHandler
this.fontRendererObj.drawString(toolName + "_", 180, 8, 0xffffff);
if (logic.isStackInSlot(0))
- drawToolStats();
+ ToolStationGuiHelper.drawToolStats(logic.getStackInSlot(0), 294, 0);
else
drawToolInformation();
}
- protected void drawToolStats ()
- {
- ItemStack stack = logic.getStackInSlot(0);
- if (stack.getItem() instanceof ToolCore)
- {
- ToolCore tool = (ToolCore) stack.getItem();
- NBTTagCompound tags = stack.getTagCompound().getCompoundTag(tool.getBaseTagName());
- this.drawCenteredString(fontRendererObj, "\u00A7n" + tool.getLocalizedToolName(), 349, 8, 0xffffff);
-
- drawModularToolStats(stack, tool, tags, 294, 24);
- }
- if(stack.getItem() instanceof ArmorCore)
- {
- ArmorCore armor = (ArmorCore) stack.getItem();
- NBTTagCompound tags = stack.getTagCompound().getCompoundTag(armor.getBaseTagName());
- this.drawCenteredString(fontRendererObj, "\u00A7n" + stack.getDisplayName(), 349, 8, 0xffffff); // todo: localize
-
- drawModularArmorStats(stack, armor, tags, 294, 24);
- }
- if(stack.getItem() instanceof AccessoryCore)
- {
- AccessoryCore accessory = (AccessoryCore) stack.getItem();
- NBTTagCompound tags = stack.getTagCompound().getCompoundTag(accessory.getBaseTagName());
- this.drawCenteredString(fontRendererObj, "\u00A7n" + stack.getDisplayName(), 349, 8, 0xffffff); // todo: localize
-
- drawModularAccessoryStats(stack, accessory, tags, 294, 24);
- }
- }
-
- protected void drawModularToolStats (ItemStack stack, ToolCore tool, NBTTagCompound tags, int x, int y)
- {
- List categories = Arrays.asList(tool.getTraits());
- final int durability = tags.getInteger("Damage");
- final int maxDur = tags.getInteger("TotalDurability");
- int availableDurability = maxDur - durability;
-
- // Durability
- int base = y;
- int offset = 0;
- if (maxDur > 0)
- {
- if (maxDur >= 10000)
- {
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation1"), x, base + offset * 11, 0xffffff);
- offset++;
- fontRendererObj.drawString("- " + availableDurability + "/" + maxDur, x, base + offset * 10, 0xffffff);
- offset++;
- }
- else
- {
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation2") + availableDurability + "/" + maxDur, x, base + offset * 10, 0xffffff);
- offset++;
- }
- }
-
- final float stonebound = tags.getFloat("Shoddy");
- // Attack
- if (categories.contains("weapon"))
- {
- int attack = (int) (tags.getInteger("Attack")) + 1;
- float stoneboundDamage = (float) Math.log(durability / 72f + 1) * -2 * stonebound;
- attack += stoneboundDamage;
- attack *= tool.getDamageModifier();
- if (attack < 1)
- attack = 1;
-
- String heart = attack == 2 ? StatCollector.translateToLocal("gui.partcrafter8") : StatCollector.translateToLocal("gui.partcrafter9");
- if (attack % 2 == 0)
- this.fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation3") + attack / 2 + heart, x, base + offset * 10, 0xffffff);
- else
- this.fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation3") + attack / 2f + heart, x, base + offset * 10, 0xffffff);
- offset++;
-
- if (stoneboundDamage != 0)
- {
- DecimalFormat df = new DecimalFormat("##.##");
- heart = stoneboundDamage == 2 ? StatCollector.translateToLocal("gui.partcrafter8") : StatCollector.translateToLocal("gui.partcrafter9");
- String bloss = stoneboundDamage > 0 ? StatCollector.translateToLocal("gui.toolstation4") : StatCollector.translateToLocal("gui.toolstation5");
- this.fontRendererObj.drawString(bloss + df.format(stoneboundDamage / 2f) + heart, x, base + offset * 10, 0xffffff);
- offset++;
- }
- offset++;
- }
-
- if (categories.contains("bow"))
- {
- DecimalFormat df = new DecimalFormat("##.##");
- df.setRoundingMode(RoundingMode.DOWN);
- int drawSpeed = tags.getInteger("DrawSpeed");
- float flightSpeed = tags.getFloat("FlightSpeed");
- float trueDraw = drawSpeed / 20f * flightSpeed;
- this.fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation6") + df.format(trueDraw) + "s", x, base + offset * 10, 0xffffff);
- offset++;
- this.fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation7") + df.format(flightSpeed) + "x", x, base + offset * 10, 0xffffff);
- offset++;
- offset++;
- }
-
- if (categories.contains("ammo"))
- {
- DecimalFormat df = new DecimalFormat("##.##");
- df.setRoundingMode(RoundingMode.DOWN);
- int attack = (int) (tags.getInteger("Attack"));
- float mass = tags.getFloat("Mass");
- float shatter = tags.getFloat("BreakChance");
- float accuracy = tags.getFloat("Accuracy");
-
- this.fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation10"), x, base + offset * 10, 0xffffff);
- offset++;
- String heart = attack == 2 ? StatCollector.translateToLocal("gui.partcrafter8") : StatCollector.translateToLocal("gui.partcrafter9");
- if (attack % 2 == 0)
- this.fontRendererObj.drawString("- " + attack / 2 + heart, x, base + offset * 10, 0xffffff);
- else
- this.fontRendererObj.drawString("- " + attack / 2f + heart, x, base + offset * 10, 0xffffff);
- offset++;
- int minAttack = attack;
- int maxAttack = attack * 2;
- heart = StatCollector.translateToLocal("gui.partcrafter9");
- this.fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation11"), x, base + offset * 10, 0xffffff);
- offset++;
- this.fontRendererObj.drawString(df.format(minAttack / 2f) + "-" + df.format(maxAttack / 2f) + heart, x, base + offset * 10, 0xffffff);
- offset++;
- offset++;
-
- this.fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation8") + df.format(mass), x, base + offset * 10, 0xffffff);
- offset++;
- this.fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation9") + df.format(accuracy - 4) + "%", x, base + offset * 10, 0xffffff);
- offset++;
- /*
- * this.fontRendererObj.drawString("Chance to break: " +
- * df.format(shatter)+"%", xSize + 8, base + offset * 10, 0xffffff);
- * offset++;
- */
- offset++;
- }
-
- // Mining
- if (categories.contains("dualharvest"))
- {
- float mineSpeed = tags.getInteger("MiningSpeed") / 100f * ((HarvestTool) tool).breakSpeedModifier();
- float mineSpeed2 = tags.getInteger("MiningSpeed2") / 100f * ((HarvestTool) tool).breakSpeedModifier();
- float stoneboundSpeed = (float) Math.log(durability / ((HarvestTool) tool).stoneboundModifier() + 1) * 2 * stonebound;
- DecimalFormat df = new DecimalFormat("##.##");
- df.setRoundingMode(RoundingMode.DOWN);
- float trueSpeed = mineSpeed + stoneboundSpeed;
- float trueSpeed2 = mineSpeed2 + stoneboundSpeed;
-
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation12"), x, base + offset * 10, 0xffffff);
- offset++;
- fontRendererObj.drawString("- " + df.format(trueSpeed) + ", " + df.format(trueSpeed2), x, base + offset * 10, 0xffffff);
- offset++;
- if (stoneboundSpeed != 0)
- {
- String bloss = stoneboundSpeed > 0 ? StatCollector.translateToLocal("gui.toolstation4") : StatCollector.translateToLocal("gui.toolstation5");
- fontRendererObj.drawString(bloss + df.format(stoneboundSpeed), x, base + offset * 10, 0xffffff);
- offset++;
- }
- offset++;
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation13"), x, base + offset * 10, 0xffffff);
- offset++;
- fontRendererObj.drawString("- " + HarvestLevels.getHarvestLevelName(tags.getInteger("HarvestLevel")) + ", " + HarvestLevels.getHarvestLevelName(tags.getInteger("HarvestLevel2")), x, base + offset * 10, 0xffffff);
- offset++;
- offset++;
- }
- else if (categories.contains("harvest"))
- {
- float trueSpeed = AbilityHelper.calcToolSpeed(tool, tags);
- float stoneboundSpeed = AbilityHelper.calcToolSpeed(tool, tags);
-
- DecimalFormat df = new DecimalFormat("##.##");
- df.setRoundingMode(RoundingMode.DOWN);
- trueSpeed += stoneboundSpeed;
- if (trueSpeed < 0)
- trueSpeed = 0;
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation14") + df.format(trueSpeed), x, base + offset * 10, 0xffffff);
- offset++;
- if (stoneboundSpeed != 0 && !Float.isNaN(stoneboundSpeed))
- {
- String bloss = stoneboundSpeed > 0 ? StatCollector.translateToLocal("gui.toolstation4") : StatCollector.translateToLocal("gui.toolstation5");
- fontRendererObj.drawString(bloss + df.format(stoneboundSpeed), x, base + offset * 10, 0xffffff);
- offset++;
- }
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation15") + HarvestLevels.getHarvestLevelName(tags.getInteger("HarvestLevel")), x, base + offset * 10, 0xffffff);
- offset++;
- offset++;
- }
- else if (categories.contains("utility"))
- {
- float mineSpeed = tags.getInteger("MiningSpeed");
- float trueSpeed = mineSpeed / (100f);
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation16") + trueSpeed, x, base + offset * 10, 0xffffff);
- offset++;
- offset++;
- }
-
- int modifiers = tags.getInteger("Modifiers");
- if (modifiers > 0)
- {
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation18") + tags.getInteger("Modifiers"), x, base + offset * 10, 0xffffff);
- offset++;
- }
- if (tags.hasKey("Tooltip1"))
- {
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation17"), x, base + offset * 10, 0xffffff);
- }
-
- boolean displayToolTips = true;
- int tipNum = 0;
- while (displayToolTips)
- {
- tipNum++;
- String tooltip = "ModifierTip" + tipNum;
- if (tags.hasKey(tooltip))
- {
- String tipName = tags.getString(tooltip);
- fontRendererObj.drawString("- " + tipName, x, base + (offset + tipNum) * 10, 0xffffff);
- }
- else
- displayToolTips = false;
- }
- }
-
- private static DecimalFormat df = new DecimalFormat("##.#");
-
- // todo: do this properly, quick and dirty fix
- protected void drawModularArmorStats (ItemStack stack, ArmorCore armor, NBTTagCompound tags, int x, int y)
- {
- List categories = Arrays.asList(armor.getTraits());
- int base = y;
- int offset = 0;
-
- // durability
- final int durability = tags.getInteger("Damage");
- final int maxDur = tags.getInteger("TotalDurability");
- int availableDurability = maxDur - durability;
-
- // Durability
- if (maxDur > 0)
- {
- if (maxDur >= 10000)
- {
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation1"), x, base + offset * 11, 0xffffff);
- offset++;
- fontRendererObj.drawString("- " + availableDurability + "/" + maxDur, x, base + offset * 10, 0xffffff);
- offset++;
- }
- else
- {
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation2") + availableDurability + "/" + maxDur, x, base + offset * 10, 0xffffff);
- offset++;
- }
- }
- // Damage reduction
- double damageReduction = tags.getDouble("DamageReduction");
- if(damageReduction > 0.000001d)
- {
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation19") + df.format(damageReduction), x, base + offset * 10, 0xffffff);
- offset++;
- }
-
- // Protection
- double protection = armor.getProtection(stack);
- double maxProtection = tags.getDouble("MaxDefense");
- //if(maxProtection > protection)
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation20") + df.format(protection) + "/" + df.format(maxProtection), 294, base + offset * 10, 0xffffff);
- //else
- // fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation20") + df.format(protection), x, base + offset * 10, 0xffffff);
- offset++;
-
- offset++;
- int modifiers = tags.getInteger("Modifiers");
- if (modifiers > 0)
- {
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation18") + tags.getInteger("Modifiers"), x, base + offset * 10, 0xffffff);
- offset++;
- }
- if (tags.hasKey("Tooltip1"))
- {
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation17"), x, base + offset * 10, 0xffffff);
- }
-
- boolean displayToolTips = true;
- int tipNum = 0;
- while (displayToolTips)
- {
- tipNum++;
- String tooltip = "ModifierTip" + tipNum;
- if (tags.hasKey(tooltip))
- {
- String tipName = tags.getString(tooltip);
- fontRendererObj.drawString("- " + tipName, x, base + (offset + tipNum) * 10, 0xffffff);
- }
- else
- displayToolTips = false;
- }
- }
-
- // todo: also quick and dirty fix
- protected void drawModularAccessoryStats (ItemStack stack, AccessoryCore accessory, NBTTagCompound tags, int x, int y)
- {
- List categories = Arrays.asList(accessory.getTraits());
- int base = y;
- int offset = 0;
-
- if (categories.contains("utility"))
- {
- float mineSpeed = tags.getInteger("MiningSpeed");
- float trueSpeed = mineSpeed / (100f);
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation16") + trueSpeed, x, base + offset * 10, 0xffffff);
- offset++;
- }
-
- offset++;
- int modifiers = tags.getInteger("Modifiers");
- if (modifiers > 0)
- {
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation18") + tags.getInteger("Modifiers"), x, base + offset * 10, 0xffffff);
- offset++;
- }
- if (tags.hasKey("Tooltip1"))
- {
- fontRendererObj.drawString(StatCollector.translateToLocal("gui.toolstation17"), x, base + offset * 10, 0xffffff);
- }
-
- boolean displayToolTips = true;
- int tipNum = 0;
- while (displayToolTips)
- {
- tipNum++;
- String tooltip = "ModifierTip" + tipNum;
- if (tags.hasKey(tooltip))
- {
- String tipName = tags.getString(tooltip);
- fontRendererObj.drawString("- " + tipName, x, base + (offset + tipNum) * 10, 0xffffff);
- }
- else
- displayToolTips = false;
- }
- }
-
protected void drawToolInformation ()
{
this.drawCenteredString(fontRendererObj, title, 349, 8, 0xffffff);
diff --git a/src/main/java/tconstruct/tools/gui/ToolStationGuiHelper.java b/src/main/java/tconstruct/tools/gui/ToolStationGuiHelper.java
new file mode 100644
index 00000000..28870932
--- /dev/null
+++ b/src/main/java/tconstruct/tools/gui/ToolStationGuiHelper.java
@@ -0,0 +1,298 @@
+package tconstruct.tools.gui;
+
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.gui.FontRenderer;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.StatCollector;
+import tconstruct.library.accessory.AccessoryCore;
+import tconstruct.library.armor.ArmorCore;
+import tconstruct.library.modifier.IModifyable;
+import tconstruct.library.tools.AbilityHelper;
+import tconstruct.library.tools.DualHarvestTool;
+import tconstruct.library.tools.HarvestTool;
+import tconstruct.library.tools.ToolCore;
+import tconstruct.library.util.HarvestLevels;
+import tconstruct.library.weaponry.AmmoWeapon;
+import tconstruct.library.weaponry.IAmmo;
+import tconstruct.library.weaponry.ProjectileWeapon;
+
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+public final class ToolStationGuiHelper {
+ // non-instantiable
+ private ToolStationGuiHelper() {}
+
+ private static final FontRenderer fontRendererObj = Minecraft.getMinecraft().fontRenderer;
+ private static int xPos, yPos;
+
+ private static final DecimalFormat df = new DecimalFormat("#.##");
+
+ private static void newline()
+ {
+ yPos += 10;
+ }
+
+
+ private static void write(String s)
+ {
+ fontRendererObj.drawString(s, xPos, yPos, 0xffffffff);
+ newline();
+ }
+
+ public static void drawToolStats (ItemStack stack, int x, int y)
+ {
+ String name = stack.getItem() instanceof ToolCore ? ((ToolCore) stack.getItem()).getLocalizedToolName() : stack.getDisplayName();
+ Item item = stack.getItem();
+ NBTTagCompound tags = stack.getTagCompound();
+ Collection categories = new LinkedList();
+
+ // initialize drawing variables
+ xPos = x;
+ yPos = y + 8;
+
+ // get the correct tags
+ if(item instanceof IModifyable) {
+ IModifyable modifyable = (IModifyable) item;
+ tags = tags.getCompoundTag(modifyable.getBaseTagName());
+ categories = Arrays.asList(modifyable.getTraits());
+ }
+
+ drawCenteredString(fontRendererObj, "\u00A7n" + name, xPos + 55, yPos, 0xffffffff);
+ newline();
+ newline();
+
+ // does it have ammo instead of durability?
+ if(item instanceof IAmmo)
+ drawAmmo((IAmmo) item, stack);
+ // regular durability?
+ else if(item instanceof ToolCore || item instanceof ArmorCore)
+ drawDurability(tags);
+
+ // tools
+ if(item instanceof ToolCore) {
+ ToolCore tool = (ToolCore) item;
+ // DualHarvest tool?
+ if (categories.contains("dualharvest"))
+ drawDualHarvestStats(tool, tags);
+ // or regular Harvest tool?
+ else if (categories.contains("harvest"))
+ drawHarvestStats(tool, tags);
+ // weapon?
+ if (categories.contains("weapon"))
+ drawWeaponStats(tool, tags);
+ // throwing weapon?
+ if (categories.contains("thrown") && tool instanceof AmmoWeapon)
+ drawThrowingWeaponStats((AmmoWeapon) tool, tags);
+ // projectile weapon?
+ if (categories.contains("bow") && tool instanceof ProjectileWeapon)
+ drawProjectileWeaponStats((ProjectileWeapon) tool, tags, stack);
+ // projectile?
+ if (categories.contains("projectile"))
+ drawProjectileStats(tags);
+ }
+ // armor
+ if(item instanceof ArmorCore)
+ {
+ ArmorCore armor = (ArmorCore) item;
+ drawArmorStats(armor, tags, stack);
+ }
+ // Accessory
+ if(item instanceof AccessoryCore)
+ {
+ AccessoryCore accessory = (AccessoryCore) item;
+ drawAccessoryStats(accessory, tags);
+ }
+
+ newline();
+
+ // Modifiers
+ drawModifiers(tags);
+ }
+
+ private static void drawDurability(NBTTagCompound tags) {
+ final int durability = tags.getInteger("Damage");
+ final int maxDur = tags.getInteger("TotalDurability");
+ final int availableDurability = maxDur - durability;
+
+ // big durabilities have to split to 2 lines
+ if (maxDur >= 10000)
+ {
+ write(StatCollector.translateToLocal("gui.toolstation1"));
+ write("- " + availableDurability + "/" + maxDur);
+ }
+ else
+ {
+ write(StatCollector.translateToLocal("gui.toolstation2") + availableDurability + "/" + maxDur);
+ }
+ }
+
+ private static void drawAmmo(IAmmo ammoItem, ItemStack stack)
+ {
+ final int max = ammoItem.getMaxAmmo(stack);
+ final int current = ammoItem.getAmmoCount(stack);
+
+ write(StatCollector.translateToLocal("gui.toolstation21") + current + "/" + max);
+ }
+
+ private static void drawModifiers(NBTTagCompound tags)
+ {
+ int modifiers = tags.getInteger("Modifiers");
+ // remaining modifiers
+ if (modifiers != 0)
+ write(StatCollector.translateToLocal("gui.toolstation18") + modifiers);
+
+ // Modifier-header (if we have modifiers)
+ if (tags.hasKey("ModifierTip1")) {
+ write(StatCollector.translateToLocal("gui.toolstation17"));
+
+ String tooltip = "ModifierTip";
+ int tipNum = 1;
+ while (tags.hasKey(tooltip + tipNum)) {
+ write("- " + tags.getString(tooltip + tipNum));
+ tipNum++;
+ }
+ }
+ }
+
+ private static void drawHarvestStats(ToolCore tool, NBTTagCompound tags)
+ {
+ float mineSpeed = AbilityHelper.calcToolSpeed(tool, tags);
+ float stoneboundSpeed = AbilityHelper.calcStoneboundBonus(tool, tags);
+
+ write(StatCollector.translateToLocal("gui.toolstation14") + df.format(mineSpeed));
+ if(stoneboundSpeed != 0)
+ {
+ String bloss = stoneboundSpeed > 0 ? StatCollector.translateToLocal("gui.toolstation4") : StatCollector.translateToLocal("gui.toolstation5");
+ write(bloss + df.format(stoneboundSpeed));
+ }
+ write(StatCollector.translateToLocal("gui.toolstation15") + HarvestLevels.getHarvestLevelName(tags.getInteger("HarvestLevel")));
+ }
+
+ private static void drawDualHarvestStats(ToolCore tool, NBTTagCompound tags)
+ {
+ float mineSpeed = AbilityHelper.calcDualToolSpeed(tool, tags, false);
+ float mineSpeed2 = AbilityHelper.calcDualToolSpeed(tool, tags, true);
+ float stoneboundSpeed = AbilityHelper.calcStoneboundBonus(tool, tags);
+
+ write(StatCollector.translateToLocal("gui.toolstation12"));
+ write("- " + df.format(mineSpeed) + ", " + df.format(mineSpeed2));
+ if (stoneboundSpeed != 0)
+ {
+ String bloss = stoneboundSpeed > 0 ? StatCollector.translateToLocal("gui.toolstation4") : StatCollector.translateToLocal("gui.toolstation5");
+ write(bloss + df.format(stoneboundSpeed));
+ }
+
+ write(StatCollector.translateToLocal("gui.toolstation13"));
+ write("- " + HarvestLevels.getHarvestLevelName(tags.getInteger("HarvestLevel")) + ", " + HarvestLevels.getHarvestLevelName(tags.getInteger("HarvestLevel2")));
+ }
+
+ private static void drawWeaponStats(ToolCore tool, NBTTagCompound tags)
+ {
+ // DAMAGE
+ int attack = (tags.getInteger("Attack"));
+
+ // factor in Stonebound
+ float stoneboundDamage = -AbilityHelper.calcStoneboundBonus(tool, tags);
+ attack += stoneboundDamage;
+ attack *= tool.getDamageModifier();
+
+ if (attack < 1)
+ attack = 1;
+
+ String heart = attack == 2 ? StatCollector.translateToLocal("gui.partcrafter8") : StatCollector.translateToLocal("gui.partcrafter9");
+ if (attack % 2 == 0)
+ write(StatCollector.translateToLocal("gui.toolstation3") + attack / 2 + heart);
+ else
+ write(StatCollector.translateToLocal("gui.toolstation3") + df.format(attack / 2f) + heart);
+
+ if (stoneboundDamage != 0)
+ {
+ heart = stoneboundDamage == 2 ? StatCollector.translateToLocal("gui.partcrafter8") : StatCollector.translateToLocal("gui.partcrafter9");
+ String bloss = stoneboundDamage > 0 ? StatCollector.translateToLocal("gui.toolstation4") : StatCollector.translateToLocal("gui.toolstation5");
+ write(bloss + df.format(stoneboundDamage / 2f) + heart);
+ }
+ }
+
+ private static void drawThrowingWeaponStats(AmmoWeapon weapon, NBTTagCompound tags) {
+ float attackf = (tags.getInteger("Attack"));
+ attackf *= weapon.getDamageModifier();
+ attackf *= weapon.getProjectileSpeed();
+
+ if (attackf < 1)
+ attackf = 1;
+
+ int attack = (int)attackf;
+
+ String heart = attack == 2 ? StatCollector.translateToLocal("gui.partcrafter8") : StatCollector.translateToLocal("gui.partcrafter9");
+ if (attack % 2 == 0)
+ write(StatCollector.translateToLocal("gui.toolstation23") + attack / 2 + heart);
+ else
+ write(StatCollector.translateToLocal("gui.toolstation23") + df.format(attack / 2f) + heart);
+ }
+
+ private static void drawProjectileWeaponStats(ProjectileWeapon weapon, NBTTagCompound tags, ItemStack stack)
+ {
+ // drawspeed
+ final int drawSpeed = weapon.getWindupTime(stack);
+ final float trueDraw = drawSpeed / 20f;
+ write(StatCollector.translateToLocal("gui.toolstation6") + df.format(trueDraw) + "s");
+
+ // flightspeed
+ final float flightSpeed = weapon.getProjectileSpeed(stack);
+ write(StatCollector.translateToLocal("gui.toolstation7") + df.format(flightSpeed) + "x");
+ }
+
+ private static void drawProjectileStats(NBTTagCompound tags)
+ {
+ // weight
+ final float weight = tags.getFloat("Mass");
+ write(StatCollector.translateToLocal("gui.toolstation8") + df.format(weight));
+
+ // accuracy
+ final float accuracy = tags.getFloat("Accuracy");
+ write(StatCollector.translateToLocal("gui.toolstation9") + df.format(accuracy) + "%");
+
+ // breakchance
+ final float breakChance = tags.getFloat("BreakChance") * 100;
+ write(StatCollector.translateToLocal("gui.toolstation22") + df.format(breakChance) + "%");
+ }
+
+ private static void drawArmorStats(ArmorCore armor, NBTTagCompound tags, ItemStack stack)
+ {
+ // Damage reduction
+ double damageReduction = tags.getDouble("DamageReduction");
+ if(damageReduction > 0)
+ write(StatCollector.translateToLocal("gui.toolstation19") + df.format(damageReduction));
+
+ // Protection
+ double protection = armor.getProtection(stack);
+ double maxProtection = tags.getDouble("MaxDefense");
+
+ write(StatCollector.translateToLocal("gui.toolstation20") + df.format(protection) + "/" + df.format(maxProtection));
+ }
+
+ private static void drawAccessoryStats(AccessoryCore core, NBTTagCompound tags)
+ {
+ if(tags.hasKey("MiningSpeed")) {
+ float mineSpeed = tags.getInteger("MiningSpeed");
+ float trueSpeed = mineSpeed / (100f);
+ write(StatCollector.translateToLocal("gui.toolstation16") + trueSpeed);
+ }
+ }
+
+ /**
+ * Renders the specified text to the screen, center-aligned.
+ * Copied out of GUI
+ */
+ public static void drawCenteredString(FontRenderer p_73732_1_, String p_73732_2_, int p_73732_3_, int p_73732_4_, int p_73732_5_)
+ {
+ p_73732_1_.drawStringWithShadow(p_73732_2_, p_73732_3_ - p_73732_1_.getStringWidth(p_73732_2_) / 2, p_73732_4_, p_73732_5_);
+ }
+}
diff --git a/src/main/java/tconstruct/tools/items/Fletching.java b/src/main/java/tconstruct/tools/items/Fletching.java
index c063f27f..0704f331 100644
--- a/src/main/java/tconstruct/tools/items/Fletching.java
+++ b/src/main/java/tconstruct/tools/items/Fletching.java
@@ -27,9 +27,9 @@ public class Fletching extends CraftingItem implements IToolPart
return names;
}
- public static final String[] toolMaterialNames = new String[] { "feather", "leaf", "slime", "blueslime" };
+ public static final String[] toolMaterialNames = new String[] { "feather", "leaf", "slime", "blueslime", "slimeleaf" };
- public static final String[] toolTextureNames = new String[] { "feather", "leaf", "slime", "blueslime" };
+ public static final String[] toolTextureNames = new String[] { "feather", "leaf", "slime", "blueslime", "slimeleaf" };
@Override
public int getMaterialID (ItemStack stack)
diff --git a/src/main/java/tconstruct/tools/items/Manual.java b/src/main/java/tconstruct/tools/items/Manual.java
index 1b8edc01..142cd5f6 100644
--- a/src/main/java/tconstruct/tools/items/Manual.java
+++ b/src/main/java/tconstruct/tools/items/Manual.java
@@ -18,8 +18,8 @@ import tconstruct.library.TConstructRegistry;
public class Manual extends CraftingItem
{
- static String[] name = new String[] { "beginner", "toolstation", "smeltery", "diary" };
- static String[] textureName = new String[] { "tinkerbook_diary", "tinkerbook_toolstation", "tinkerbook_smeltery", "tinkerbook_blue" };
+ static String[] name = new String[] { "beginner", "toolstation", "smeltery", "diary", "weaponry" };
+ static String[] textureName = new String[] { "tinkerbook_diary", "tinkerbook_toolstation", "tinkerbook_smeltery", "tinkerbook_blue", "tinkerbook_green" };
public Manual()
{
@@ -50,6 +50,8 @@ public class Manual extends CraftingItem
return TProxyClient.manualData.toolStation;
case 2:
return TProxyClient.manualData.smeltery;
+ case 4:
+ return TProxyClient.manualData.weaponry;
default:
return TProxyClient.manualData.diary;
}
diff --git a/src/main/java/tconstruct/tools/items/ManualInfo.java b/src/main/java/tconstruct/tools/items/ManualInfo.java
index 5c68e0f4..e97f2e2f 100644
--- a/src/main/java/tconstruct/tools/items/ManualInfo.java
+++ b/src/main/java/tconstruct/tools/items/ManualInfo.java
@@ -16,6 +16,7 @@ public class ManualInfo
BookData toolStation = new BookData();
BookData smeltery = new BookData();
BookData diary = new BookData();
+ BookData weaponry = new BookData();
/* diary = readManual("/assets/tinker/manuals/diary.xml", dbFactory);
volume1 = readManual("/assets/tinker/manuals/firstday.xml", dbFactory);
@@ -29,7 +30,7 @@ public class ManualInfo
toolStation = initManual(toolStation, "tconstruct.manual.toolstation", "\u00a7o" + StatCollector.translateToLocal("manual2.tooltip"), side == Side.CLIENT ? TProxyClient.volume2 : null, "tinker:tinkerbook_toolstation");
smeltery = initManual(smeltery, "tconstruct.manual.smeltery", "\u00a7o" + StatCollector.translateToLocal("manual3.tooltip"), side == Side.CLIENT ? TProxyClient.smelter : null, "tinker:tinkerbook_smeltery");
diary = initManual(diary, "tconstruct.manual.diary", "\u00a7o" + StatCollector.translateToLocal("manual4.tooltip"), side == Side.CLIENT ? TProxyClient.diary : null, "tinker:tinkerbook_blue");
-
+ weaponry = initManual(weaponry, "tconstruct.manual.weaponry", "\u00a7o" + StatCollector.translateToLocal("manual5.tooltip"), side == Side.CLIENT ? TProxyClient.weaponry : null, "tinker:tinkerbook_green");
}
public BookData initManual (BookData data, String unlocName, String toolTip, Document xmlDoc, String itemImage)
diff --git a/src/main/java/tconstruct/util/Reference.java b/src/main/java/tconstruct/util/Reference.java
new file mode 100644
index 00000000..ccbccbd8
--- /dev/null
+++ b/src/main/java/tconstruct/util/Reference.java
@@ -0,0 +1,18 @@
+package tconstruct.util;
+
+import tconstruct.TConstruct;
+
+public final class Reference {
+ private Reference() {}
+
+ public static final String MOD_ID = TConstruct.modID;
+ public static final String MOD_NAME = "Tinkers' Construct";
+
+ public static final String RESOURCE = "tinker";
+
+ public static String resource(String res)
+ {
+ return String.format("%s:%s", RESOURCE, res);
+ }
+ public static String prefix(String name) { return String.format("tconstruct.%s", name);}
+}
diff --git a/src/main/java/tconstruct/util/network/MovementUpdatePacket.java b/src/main/java/tconstruct/util/network/MovementUpdatePacket.java
new file mode 100644
index 00000000..5e11a46e
--- /dev/null
+++ b/src/main/java/tconstruct/util/network/MovementUpdatePacket.java
@@ -0,0 +1,66 @@
+package tconstruct.util.network;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.channel.ChannelHandlerContext;
+import mantle.common.network.AbstractPacket;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityList;
+import net.minecraft.entity.player.EntityPlayer;
+
+public class MovementUpdatePacket extends AbstractPacket {
+ public int entityID;
+ public double x;
+ public double y;
+ public double z;
+ public float yaw;
+ public float pitch;
+
+ public MovementUpdatePacket() {
+ }
+
+ public MovementUpdatePacket(Entity entity) {
+ this.entityID = entity.getEntityId();
+ this.x = entity.motionX;
+ this.y = entity.motionY;
+ this.z = entity.motionZ;
+ this.yaw = entity.rotationYaw;
+ this.pitch = entity.rotationPitch;
+ }
+
+ @Override
+ public void encodeInto(ChannelHandlerContext ctx, ByteBuf buffer) {
+ buffer.writeInt(entityID);
+ buffer.writeDouble(x);
+ buffer.writeDouble(y);
+ buffer.writeDouble(z);
+ buffer.writeFloat(yaw);
+ buffer.writeFloat(pitch);
+ }
+
+ @Override
+ public void decodeInto(ChannelHandlerContext ctx, ByteBuf buffer) {
+ this.entityID = buffer.readInt();
+ this.x = buffer.readDouble();
+ this.y = buffer.readDouble();
+ this.z = buffer.readDouble();
+ this.yaw = buffer.readFloat();
+ this.pitch = buffer.readFloat();
+ }
+
+ @Override
+ public void handleClientSide(EntityPlayer player) {
+ Entity entity = player.worldObj.getEntityByID(entityID);
+ if(entity != null) {
+ entity.motionX = x;
+ entity.motionY = y;
+ entity.motionZ = z;
+ entity.rotationYaw = yaw;
+ entity.rotationPitch = pitch;
+ }
+ }
+
+ @Override
+ public void handleServerSide(EntityPlayer player) {
+ // only sent to client
+ }
+}
diff --git a/src/main/java/tconstruct/util/network/PacketPipeline.java b/src/main/java/tconstruct/util/network/PacketPipeline.java
index 77c17c9b..c87eaa6b 100644
--- a/src/main/java/tconstruct/util/network/PacketPipeline.java
+++ b/src/main/java/tconstruct/util/network/PacketPipeline.java
@@ -133,6 +133,8 @@ public class PacketPipeline extends MessageToMessageCodec 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);
+ }
+ }
+ }
+
+ private void setupCreativeTab()
+ {
+ ItemStack tool = new ItemStack(TinkerWeaponry.longbow, 1, 0);
+
+ NBTTagCompound compound = new NBTTagCompound();
+ compound.setTag("InfiTool", new NBTTagCompound());
+ compound.getCompoundTag("InfiTool").setInteger("RenderHead", 0);
+ compound.getCompoundTag("InfiTool").setInteger("RenderHandle", 0);
+ compound.getCompoundTag("InfiTool").setInteger("RenderAccessory", 0);
+ compound.getCompoundTag("InfiTool").setInteger("RenderExtra", 1);
+ tool.setTagCompound(compound);
+
+ TConstructRegistry.weaponryTab.init(tool);
+ }
+
+ private void registerDispenserProjectiles() {
+ // shuriken
+ BlockDispenser.dispenseBehaviorRegistry.putObject(shuriken, new BehaviorProjectileBaseDispense() {
+
+ @Override
+ protected ProjectileBase getProjectileEntity(World world, IPosition position, ItemStack stack) {
+ return new ShurikenEntity(world, position.getX(), position.getY(), position.getZ());
+ }
+
+ @Override
+ protected float ballistic() {
+ // shurikens are shot out straight
+ return 0f;
+ }
+ });
+ // throwing knifes
+ BlockDispenser.dispenseBehaviorRegistry.putObject(throwingknife, new BehaviorProjectileBaseDispense() {
+
+ @Override
+ protected ProjectileBase getProjectileEntity(World world, IPosition position, ItemStack stack) {
+ return new ThrowingKnifeEntity(world, position.getX(), position.getY(), position.getZ());
+ }
+ });
+ // Javelin
+ BlockDispenser.dispenseBehaviorRegistry.putObject(javelin, new BehaviorProjectileBaseDispense() {
+
+ @Override
+ protected ProjectileBase getProjectileEntity(World world, IPosition position, ItemStack stack) {
+ return new JavelinEntity(world, position.getX(), position.getY(), position.getZ());
+ }
+ });
+
+ // arrows
+ BlockDispenser.dispenseBehaviorRegistry.putObject(arrowAmmo, new BehaviorProjectileBaseDispense() {
+ @Override
+ protected ProjectileBase getProjectileEntity(World world, IPosition position, ItemStack stack) {
+ return new ArrowEntity(world, position.getX(), position.getY(), position.getZ());
+ }
+ });
+
+ // bolts
+ BlockDispenser.dispenseBehaviorRegistry.putObject(boltAmmo, new BehaviorProjectileBaseDispense() {
+ @Override
+ protected ProjectileBase getProjectileEntity(World world, IPosition position, ItemStack stack) {
+ return new BoltEntity(world, position.getX(), position.getY(), position.getZ());
+ }
+ });
+ }
+}
diff --git a/src/main/java/tconstruct/weaponry/WeaponryActiveToolMod.java b/src/main/java/tconstruct/weaponry/WeaponryActiveToolMod.java
new file mode 100644
index 00000000..d07f9744
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/WeaponryActiveToolMod.java
@@ -0,0 +1,38 @@
+package tconstruct.weaponry;
+
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import tconstruct.library.ActiveToolMod;
+import tconstruct.library.weaponry.IAmmo;
+
+public class WeaponryActiveToolMod extends ActiveToolMod {
+ @Override
+ public boolean damageTool(ItemStack stack, int damage, EntityLivingBase entity) {
+ if(stack.getItem() == TinkerWeaponry.javelin && stack.hasTagCompound()) {
+ NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool");
+ IAmmo ammo =(IAmmo)stack.getItem();
+ if(tags.getInteger("Damage") == 0)
+ {
+ int rem = ammo.consumeAmmo(1, stack);
+ if(rem > 0)
+ return true;
+ }
+ else if(ammo.getAmmoCount(stack) > 0)
+ {
+ int d = tags.getInteger("Damage") + damage;
+ int max = tags.getInteger("TotalDurability");
+ if(d > max)
+ {
+ tags.setInteger("Damage", 0);
+ return true;
+ }
+ }
+ }
+ // all other ammo items can't be damaged
+ else if(stack.getItem() instanceof IAmmo)
+ return true;
+
+ return false;
+ }
+}
diff --git a/src/main/java/tconstruct/weaponry/WeaponryClientProxy.java b/src/main/java/tconstruct/weaponry/WeaponryClientProxy.java
new file mode 100644
index 00000000..0ea3e427
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/WeaponryClientProxy.java
@@ -0,0 +1,177 @@
+package tconstruct.weaponry;
+
+import mantle.lib.client.MantleClientRegistry;
+import net.minecraft.init.Items;
+import tconstruct.client.AmmoItemRenderer;
+import tconstruct.library.crafting.ToolBuilder;
+import tconstruct.library.entity.ProjectileBase;
+import tconstruct.weaponry.client.AmmoSlotHandler;
+import tconstruct.weaponry.client.CrosshairHandler;
+import tconstruct.weaponry.client.RenderEventHandler;
+import tconstruct.weaponry.client.entity.ArrowEntityRenderer;
+import tconstruct.weaponry.client.entity.JavelinEntityRenderer;
+import tconstruct.weaponry.client.entity.ProjectileBaseRenderer;
+import tconstruct.weaponry.client.entity.ShurikenEntityRenderer;
+import tconstruct.weaponry.client.item.*;
+import tconstruct.weaponry.entity.*;
+import tconstruct.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;
+
+import static tconstruct.weaponry.TinkerWeaponry.*;
+
+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();
+ registerManualIcons();
+ }
+
+ private void registerRenderers()
+ {
+ renderer = new AmmoItemRenderer();
+ 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.8f));
+ }
+
+ private void registerMaterialRendering()
+ {
+ ToolCore arrow = TinkerWeaponry.arrowAmmo;
+ String pre = Reference.resource(arrow.getDefaultFolder()) + "/";
+
+ String[] shaft = {"wood", "bone", "reed", "blaze", null};
+ String[] fletching = { "feather", "leaf", "slime", "blueslime", "slimeleaf" };
+
+ // we register different textures for the different parts per index
+ for(int i = 0; i < 5; 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 < 5; i++) {
+ String acctex = pre + fletching[i] + TinkerWeaponry.boltAmmo.getIconSuffix(3);
+ TinkerWeaponry.boltAmmo.registerAlternatePartPaths(i, new String[]{null, null, null, acctex});
+ }
+
+
+ // bowstring
+ String[] bowstringTypes = { "string", "magicfabric", "flamestring" };
+ for (int bowIter = 0; bowIter < bowstringTypes.length; bowIter++)
+ {
+ TConstructClientRegistry.addAlternateMaterialRenderMapping(TinkerWeaponry.shortbow, bowIter, Reference.RESOURCE, bowstringTypes[bowIter], true);
+ }
+ }
+
+ private void buttons()
+ {
+ final String tex = "textures/gui/icons.png";
+
+ // Stencil Table
+ TConstructClientRegistry.addStencilButton2(11, 3, 21, Reference.RESOURCE, tex); // arrow head
+ TConstructClientRegistry.addStencilButton2(12, 3, 22, Reference.RESOURCE, tex); // fletchling
+ TConstructClientRegistry.addStencilButton2(0,0, -1, null, null);
+ TConstructClientRegistry.addStencilButton2(0,0, -1, null, null);
+
+ TConstructClientRegistry.addStencilButton2(3, 4, 27, Reference.RESOURCE, tex); // bow limb
+ TConstructClientRegistry.addStencilButton2(10, 3, 23, Reference.RESOURCE, tex); // bowstring
+ TConstructClientRegistry.addStencilButton2(1, 4, 25, Reference.RESOURCE, tex); // crossbow limb
+ TConstructClientRegistry.addStencilButton2(2, 4, 26, Reference.RESOURCE, tex); // crossbow body
+
+ TConstructClientRegistry.addStencilButton2(0, 4, 24, Reference.RESOURCE, tex); // shuriken
+ //TConstructClientRegistry.addStencilButton2(4, 4, index, Reference.RESOURCE, "textures/gui/icons.png"); // bolt
+
+
+ // Tool Station
+ ToolCore[] tools = {shortbow, arrowAmmo, throwingknife, javelin};
+ int[][] icons = {
+ new int[] {3, 9, 1}, // shortbow
+ new int[] {7, 10, 1}, // arrow
+ new int[] {2, 1, 5}, // throwingknife
+ new int[] {1, 2, 5} // javelin
+ };
+ int[][] coords = {
+ new int[] { 3, 10, 3, 13 }, new int[] { 4, 3, 4, 13 }, // shortbow
+ new int[] { 11, 0, 12, 13 }, new int[] { 3, 3, 3, 13 }, // arrow
+ new int[] { 7, 0, 13, 13 }, new int[] { 2, 3, 13, 13 }, // throwingknife
+ new int[] { 11, 8, 8, 13 }, new int[] { 3, 3, 3, 13 } // javelin
+ };
+
+ for (int i = 0; i < tools.length; i++)
+ {
+ String locString = String.format("gui.toolstation.%s.desc", tools[i].getToolName().toLowerCase());
+ TConstructClientRegistry.addToolButton(icons[i][0], icons[i][1], icons[i][2], coords[i*2], coords[i*2+1], tools[i].getLocalizedToolName(), locString, Reference.RESOURCE, tex);
+ }
+
+ // Tool Forge
+ tools = new ToolCore[] {longbow, crossbow, boltAmmo, shuriken};
+ icons = new int[][] {
+ new int[] {8, 11, 1}, // longbow
+ new int[] {9, 12, 1}, // crossbow
+ new int[] {2, 13, 1}, // bolt
+ new int[] {4, 0, 5} // shuriken
+ };
+ coords = new int[][] {
+ new int[] { 3, 10, 3, 9 }, new int[] { 4, 3, 4, 2 }, // longbow
+ new int[] { 1, 2, 10, 9 }, new int[] { 4, 4, 3, 3 }, // crossbow
+ new int[] { 4, 12, 13, 13 }, new int[] { 4, 3, 13, 13 }, // bolt
+ new int[] { 0, 0, 0, 0 }, new int[] { 4, 4, 4, 4 } // shuriken
+ };
+
+ for (int i = 0; i < tools.length; i++)
+ {
+ String locString = String.format("gui.toolstation.%s.desc", tools[i].getToolName().toLowerCase());
+ TConstructClientRegistry.addTierTwoButton(icons[i][0], icons[i][1], icons[i][2], coords[i*2], coords[i*2+1], tools[i].getLocalizedToolName(), locString, Reference.RESOURCE, tex);
+ }
+ }
+
+
+ /* Manual Stuff */
+ public void registerManualIcons ()
+ {
+ MantleClientRegistry.registerManualIcon("throwingknifeIcon", ToolBuilder.instance.buildTool(new ItemStack(TinkerTools.knifeBlade, 1, TinkerTools.MaterialID.Iron), new ItemStack(TinkerTools.toolRod, 1, 11), null, ""));
+ MantleClientRegistry.registerManualIcon("shortbowIcon", ToolBuilder.instance.buildTool(new ItemStack(TinkerWeaponry.partBowLimb, 1, TinkerTools.MaterialID.Wood), new ItemStack(TinkerWeaponry.bowstring, 1, 0), new ItemStack(TinkerWeaponry.partBowLimb, 1, TinkerTools.MaterialID.Wood), ""));
+ MantleClientRegistry.registerManualIcon("arrowIcon", ToolBuilder.instance.buildTool(new ItemStack(TinkerWeaponry.arrowhead, 1, TinkerTools.MaterialID.Flint), new ItemStack(Items.stick), new ItemStack(TinkerWeaponry.fletching, 1, 0), ""));
+
+ MantleClientRegistry.registerManualIcon("weaponrybook", new ItemStack(TinkerTools.manualBook, 1, 4));
+ }
+}
diff --git a/src/main/java/tconstruct/weaponry/WeaponryCommonProxy.java b/src/main/java/tconstruct/weaponry/WeaponryCommonProxy.java
new file mode 100644
index 00000000..bce2b81b
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/WeaponryCommonProxy.java
@@ -0,0 +1,15 @@
+package tconstruct.weaponry;
+
+import tconstruct.TConstruct;
+import tconstruct.weaponry.entity.*;
+import cpw.mods.fml.common.registry.EntityRegistry;
+
+public class WeaponryCommonProxy {
+ public void init() {
+ EntityRegistry.registerModEntity(ShurikenEntity.class, "Shuriken", 20, TConstruct.instance, 32, 5, true);
+ EntityRegistry.registerModEntity(ThrowingKnifeEntity.class, "ThrowingKnife", 21, TConstruct.instance, 32, 5, true);
+ EntityRegistry.registerModEntity(JavelinEntity.class, "Javelin", 22, TConstruct.instance, 32, 5, true);
+ EntityRegistry.registerModEntity(ArrowEntity.class, "Arrow", 23, TConstruct.instance, 32, 5, true);
+ EntityRegistry.registerModEntity(BoltEntity.class, "Bolt", 24, TConstruct.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..a86171e0
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/WeaponryHandler.java
@@ -0,0 +1,245 @@
+package tconstruct.weaponry;
+
+import cpw.mods.fml.common.gameevent.PlayerEvent;
+import tconstruct.armor.player.TPlayerStats;
+import tconstruct.tools.TinkerTools;
+import tconstruct.weaponry.ammo.ArrowAmmo;
+import tconstruct.weaponry.ammo.BoltAmmo;
+import tconstruct.library.tools.DualMaterialToolPart;
+import tconstruct.library.weaponry.ArrowShaftMaterial;
+import tconstruct.library.weaponry.BowBaseAmmo;
+import tconstruct.library.weaponry.ProjectileWeapon;
+import tconstruct.library.weaponry.IAmmo;
+import tconstruct.weaponry.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.*;
+import tconstruct.weaponry.weapons.LongBow;
+import tconstruct.weaponry.weapons.ShortBow;
+
+public class WeaponryHandler {
+ @SubscribeEvent
+ public void onCrafting (PlayerEvent.ItemCraftedEvent event)
+ {
+ Item item = event.crafting.getItem();
+ if (!event.player.worldObj.isRemote)
+ {
+ if (item == Item.getItemFromBlock(TinkerTools.toolStationWood))
+ {
+ TPlayerStats stats = TPlayerStats.get(event.player);
+ if (!stats.weaponryManual)
+ {
+ stats.weaponryManual = true;
+ AbilityHelper.spawnItemAtPlayer(event.player, new ItemStack(TinkerTools.manualBook, 1, 4));
+ }
+ }
+ }
+ }
+
+ // 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 the fragility.
+ // the fletching defines the accuracy of the arrow and adds a bit breakchance. Mostly there for the durability modifier because availability
+
+ // 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 * fletching.durabilityModifier);
+ float weight = arrow.mass + shaft.weight;
+ float accuracy = fletching.accuracy;
+ float breakChance = shaft.fragility * arrow.breakChance + fletching.breakChance;
+
+ setAmmoData(tags, durability, weight, breakChance, accuracy, head.shoddy(), head.reinforced());
+
+ // Blaze shafts give fiery
+ if(tags.getInteger("Handle") == 3)
+ {
+ tags.setInteger("Fiery", 5);
+ }
+ // arrows get only 2 modifiers
+ tags.setInteger("Modifiers", 2);
+ }
+ 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() * fletching.durabilityModifier);
+ float weight = head.mass + core.mass*1.5f;
+ float accuracy = (100f + fletching.accuracy)/2f;
+ float breakChance = (fletching.breakChance*2 + 0.15f * core.breakChance) * head.breakChance/2f;
+ float shoddy = (headMat.shoddy() + coreMat.shoddy())/2f;
+ int reinforced = Math.max(headMat.reinforced(), coreMat.reinforced());
+
+ setAmmoData(tags, durability, weight, breakChance, accuracy, shoddy, reinforced);
+ tags.setInteger("Modifiers", 2);
+ }
+
+ // 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");
+ ProjectileWeapon weapon = (ProjectileWeapon)event.tool;
+
+ 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;
+
+ // SHORT bows have a SHORTER windup because they're SHORT. hahahaha.... get it?
+ if(event.tool instanceof ShortBow) {
+ drawSpeed *= 0.9;
+ }
+ // longbows have LONGER drawspeed. LOGIC!
+ if(event.tool instanceof LongBow) {
+ drawSpeed *= 1.8f;
+ flightSpeed *= 1.5f;
+ }
+ }
+ 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);
+
+ // crossbows are more efficient the higher the base drawspeed is. So the higher the drawspeed, the more bonus you get
+ drawSpeed *= 2.5f;
+ drawSpeed -= drawSpeed*0.25f;
+
+ // crossbows are stronk
+ flightSpeed *= 1.5;
+ }
+ 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.setInteger("BaseDrawSpeed", drawSpeed); // used to calculate correct speed increase with redstone modifier
+ 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;
+ }
+
+ private void setAmmoData(NBTTagCompound tags, int durability, float weight, float breakChance, float accuracy, float shoddy, int reinforced)
+ {
+ tags.setInteger("TotalDurability", durability);
+ tags.setFloat("Mass", weight);
+ tags.setFloat("BreakChance", breakChance);
+ tags.setFloat("Accuracy", accuracy);
+ tags.setFloat("Shoddy", shoddy); // we could actually always set this to 0 since it has zero impact on ammo
+ tags.setInteger("Unbreaking", reinforced);
+ }
+}
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..012762a0
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/ammo/ArrowAmmo.java
@@ -0,0 +1,159 @@
+package tconstruct.weaponry.ammo;
+
+import net.minecraft.util.StatCollector;
+import tconstruct.TConstruct;
+import tconstruct.library.TConstructRegistry;
+import tconstruct.library.tools.ArrowMaterial;
+import tconstruct.library.tools.CustomMaterial;
+import tconstruct.library.tools.FletchingMaterial;
+import tconstruct.library.tools.FletchlingLeafMaterial;
+import tconstruct.weaponry.TinkerWeaponry;
+import tconstruct.library.weaponry.AmmoItem;
+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 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 TinkerWeaponry.arrowhead;
+ }
+
+ @Override
+ public Item getHandleItem() {
+ return TinkerWeaponry.partArrowShaft;
+ }
+
+ @Override
+ public Item getAccessoryItem ()
+ {
+ return TinkerWeaponry.fletching;
+ }
+
+ // handle is custom material
+ @Override
+ public int durabilityTypeHandle() {
+ return 0;
+ }
+
+ @Override
+ public String[] getTraits ()
+ {
+ return new String[] { "ammo", "projectile", "weapon" };
+ }
+
+ @Override
+ public void buildTool (int id, String name, List list)
+ {
+ if(TConstructRegistry.getArrowMaterial(id) == null)
+ return;
+
+ 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
+ TConstruct.logger.error("Couldn't build vanilla equivalent of Tinker Arrow");
+ }
+
+ @Override
+ protected int getDefaultColor(int renderPass, int materialID) {
+ if(renderPass != 2)
+ return super.getDefaultColor(renderPass, materialID);
+
+ CustomMaterial mat = TConstructRegistry.getCustomMaterial(materialID, FletchingMaterial.class);
+ if(mat == null)
+ TConstructRegistry.getCustomMaterial(materialID, FletchlingLeafMaterial.class);
+ if(mat == null)
+ return 0xffffff;
+
+ return mat.color;
+ }
+
+ // fix tooltip custom materials
+ @Override
+ public String getAbilityNameForType(int type, int part) {
+ // blaze shaft?
+ if(part == 1 && type == 3)
+ return "\u00a76" + StatCollector.translateToLocal("modifier.tool.blaze");
+ if(part >= 1) // only head has ability otherwise
+ return "";
+ return super.getAbilityNameForType(type, part);
+ }
+}
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..3df4432f
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/ammo/BoltAmmo.java
@@ -0,0 +1,122 @@
+package tconstruct.weaponry.ammo;
+
+import tconstruct.library.TConstructRegistry;
+import tconstruct.library.tools.CustomMaterial;
+import tconstruct.library.tools.FletchingMaterial;
+import tconstruct.library.tools.FletchlingLeafMaterial;
+import tconstruct.weaponry.TinkerWeaponry;
+import tconstruct.library.tools.DualMaterialToolPart;
+import tconstruct.library.weaponry.AmmoItem;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import tconstruct.library.crafting.ToolBuilder;
+
+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 TinkerWeaponry.fletching;
+ }
+
+ @Override
+ public String[] getTraits ()
+ {
+ return new String[] { "ammo", "projectile", "weapon" };
+ }
+
+ @Override
+ public void buildTool (int id, String name, List list)
+ {
+ if(TConstructRegistry.getArrowMaterial(id) == null)
+ return;
+
+ // 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);
+ }
+ }
+
+ @Override
+ protected int getDefaultColor(int renderPass, int materialID) {
+ if(renderPass != 2)
+ return super.getDefaultColor(renderPass, materialID);
+
+ CustomMaterial mat = TConstructRegistry.getCustomMaterial(materialID, FletchingMaterial.class);
+ if(mat == null)
+ mat = TConstructRegistry.getCustomMaterial(materialID, FletchlingLeafMaterial.class);
+ if(mat == null)
+ return 0xffffff;
+
+ return mat.color;
+ }
+
+ // fix tooltip custom materials
+ @Override
+ public String getAbilityNameForType(int type, int part) {
+ if(part >= 2) // only head and handle have ability
+ return "";
+ return super.getAbilityNameForType(type, part);
+ }
+}
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..a36f6f4a
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/client/AmmoSlotHandler.java
@@ -0,0 +1,57 @@
+package tconstruct.weaponry.client;
+
+import tconstruct.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..df1d26ce
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/client/CrosshairHandler.java
@@ -0,0 +1,161 @@
+package tconstruct.weaponry.client;
+
+import tconstruct.util.Reference;
+import tconstruct.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..5b9a4b77
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/client/CrosshairType.java
@@ -0,0 +1,12 @@
+package tconstruct.weaponry.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/RenderEventHandler.java b/src/main/java/tconstruct/weaponry/client/RenderEventHandler.java
new file mode 100644
index 00000000..200ab7fa
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/client/RenderEventHandler.java
@@ -0,0 +1,44 @@
+package tconstruct.weaponry.client;
+
+import tconstruct.weaponry.TinkerWeaponry;
+import tconstruct.library.weaponry.BowBaseAmmo;
+import tconstruct.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/entity/ArrowEntityRenderer.java b/src/main/java/tconstruct/weaponry/client/entity/ArrowEntityRenderer.java
new file mode 100644
index 00000000..066675d7
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/client/entity/ArrowEntityRenderer.java
@@ -0,0 +1,51 @@
+package tconstruct.weaponry.client.entity;
+
+import tconstruct.weaponry.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/entity/JavelinEntityRenderer.java b/src/main/java/tconstruct/weaponry/client/entity/JavelinEntityRenderer.java
new file mode 100644
index 00000000..796e4a0f
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/client/entity/JavelinEntityRenderer.java
@@ -0,0 +1,29 @@
+package tconstruct.weaponry.client.entity;
+
+import tconstruct.weaponry.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/entity/ProjectileBaseRenderer.java b/src/main/java/tconstruct/weaponry/client/entity/ProjectileBaseRenderer.java
new file mode 100644
index 00000000..4f7651b3
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/client/entity/ProjectileBaseRenderer.java
@@ -0,0 +1,89 @@
+package tconstruct.weaponry.client.entity;
+
+import tconstruct.client.FlexibleToolRenderer;
+import tconstruct.library.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();
+
+ @SuppressWarnings("unchecked")
+ @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.glTranslated(x, y, 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
+ GL11.glTranslatef(0.0f, -0.25f, 0);
+ toolCoreRenderer.renderItem(IItemRenderer.ItemRenderType.ENTITY, entity.getEntityItem());
+ GL11.glTranslatef(0.0f, 0.25f, 0);
+
+ 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/entity/ShurikenEntityRenderer.java b/src/main/java/tconstruct/weaponry/client/entity/ShurikenEntityRenderer.java
new file mode 100644
index 00000000..ff6ed7c4
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/client/entity/ShurikenEntityRenderer.java
@@ -0,0 +1,30 @@
+package tconstruct.weaponry.client.entity;
+
+import tconstruct.weaponry.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/item/BowRenderer.java b/src/main/java/tconstruct/weaponry/client/item/BowRenderer.java
new file mode 100644
index 00000000..8d843ee2
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/client/item/BowRenderer.java
@@ -0,0 +1,120 @@
+package tconstruct.weaponry.client.item;
+
+import tconstruct.client.FlexibleToolRenderer;
+import tconstruct.weaponry.TinkerWeaponry;
+import tconstruct.weaponry.ammo.ArrowAmmo;
+import tconstruct.weaponry.entity.ArrowEntity;
+import tconstruct.library.weaponry.ProjectileWeapon;
+import tconstruct.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;
+
+ GL11.glTranslatef(0.5f, 0.5f, 0);
+ GL11.glScalef(0.5f, 0.5f, 0.5f);
+
+ 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);
+
+ GL11.glTranslatef(-0.5f, -0.5f, 0f);
+ }
+}
diff --git a/src/main/java/tconstruct/weaponry/client/item/CrossbowRenderer.java b/src/main/java/tconstruct/weaponry/client/item/CrossbowRenderer.java
new file mode 100644
index 00000000..587e5531
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/client/item/CrossbowRenderer.java
@@ -0,0 +1,78 @@
+package tconstruct.weaponry.client.item;
+
+import tconstruct.client.FlexibleToolRenderer;
+import tconstruct.weaponry.entity.ArrowEntity;
+import tconstruct.weaponry.entity.BoltEntity;
+import tconstruct.weaponry.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.glTranslatef(0.5f, 0.5f, 0);
+ GL11.glScalef(0.5f, 0.5f, 0.5f);
+
+ 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);
+ }
+
+ GL11.glTranslatef(-0.5f, -0.5f, 0f);
+ }
+}
diff --git a/src/main/java/tconstruct/weaponry/client/item/JavelinRenderer.java b/src/main/java/tconstruct/weaponry/client/item/JavelinRenderer.java
new file mode 100644
index 00000000..4731d528
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/client/item/JavelinRenderer.java
@@ -0,0 +1,30 @@
+package tconstruct.weaponry.client.item;
+
+import tconstruct.client.AmmoItemRenderer;
+import tconstruct.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) {
+ GL11.glTranslatef(0.5f, 0.5f, 0);
+ GL11.glScalef(0.5f, 0.5f, 0.5f);
+
+ 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);
+
+ GL11.glTranslatef(-0.5f, -0.5f, 0f);
+ }
+}
diff --git a/src/main/java/tconstruct/weaponry/client/item/ThrowingKnifeRenderer.java b/src/main/java/tconstruct/weaponry/client/item/ThrowingKnifeRenderer.java
new file mode 100644
index 00000000..9fad436c
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/client/item/ThrowingKnifeRenderer.java
@@ -0,0 +1,74 @@
+package tconstruct.weaponry.client.item;
+
+import tconstruct.client.AmmoItemRenderer;
+import tconstruct.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) {
+ GL11.glTranslatef(0.5f, 0.5f, 0);
+ GL11.glScalef(0.5f, 0.5f, 0.5f);
+
+ 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);
+
+
+ GL11.glTranslatef(-0.5f, -0.5f, 0f);
+ }
+}
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..8513ef95
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/entity/ArrowEntity.java
@@ -0,0 +1,112 @@
+package tconstruct.weaponry.entity;
+
+import tconstruct.library.entity.ProjectileBase;
+import tconstruct.library.util.PiercingArrowDamage;
+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.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() {
+ // we could use the fletchling material for the slowdown, hm
+ // note: not done because fletchlings also balance amount you get now. Rather use slowdown for different projectile types
+ 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);
+
+ if(defused)
+ return;
+
+ // we might break! oh noez!
+ float chance = returnStack.getTagCompound().getCompoundTag("InfiTool").getFloat("BreakChance");
+ if(chance > TConstruct.random.nextFloat()) {
+ this.setDead();
+ this.playSound("random.break", 1.0F, 1.5F / (this.rand.nextFloat() * 0.2F + 0.9F));
+ }
+ }
+
+ @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 = false;
+
+ //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)*armorPenetrationModifier();
+
+ if(shift < 0)
+ shift = 0;
+ if(shift > damage)
+ shift = damage;
+
+ damage -= shift;
+
+ // deal regular damage
+ if(damage > 0)
+ dealtDamage = super.dealDamage(damage, 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);
+
+ // piercing damage does not affect wether the entity was hit (return value), since it should go through always
+ entityHit.attackEntityFrom(damagesource, shift);
+ }
+
+ return dealtDamage;
+ }
+
+ protected float armorPenetrationModifier() { return 1.0f; }
+}
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..9e5936d3
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/entity/BoltEntity.java
@@ -0,0 +1,32 @@
+package tconstruct.weaponry.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);
+ }
+
+ @Override
+ protected float armorPenetrationModifier() {
+ return 1.5f;
+ }
+}
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..81a96c78
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/entity/JavelinEntity.java
@@ -0,0 +1,48 @@
+package tconstruct.weaponry.entity;
+
+import tconstruct.library.entity.ProjectileBase;
+import tconstruct.weaponry.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/ShurikenEntity.java b/src/main/java/tconstruct/weaponry/entity/ShurikenEntity.java
new file mode 100644
index 00000000..e242e924
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/entity/ShurikenEntity.java
@@ -0,0 +1,64 @@
+package tconstruct.weaponry.entity;
+
+import tconstruct.library.entity.ProjectileBase;
+import tconstruct.weaponry.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 getSlowdown() {
+ return 0.15f;
+ }
+
+ @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..e0768e0c
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/entity/ThrowingKnifeEntity.java
@@ -0,0 +1,26 @@
+package tconstruct.weaponry.entity;
+
+import tconstruct.library.entity.ProjectileBase;
+import tconstruct.weaponry.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/GlassArrows.java b/src/main/java/tconstruct/weaponry/items/GlassArrows.java
new file mode 100644
index 00000000..9f85f084
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/items/GlassArrows.java
@@ -0,0 +1,70 @@
+package tconstruct.weaponry.items;
+
+import net.minecraft.creativetab.CreativeTabs;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.util.EnumChatFormatting;
+import tconstruct.library.client.TConstructClientRegistry;
+import tconstruct.library.crafting.ToolBuilder;
+import tconstruct.util.Reference;
+import tconstruct.weaponry.TinkerWeaponry;
+import tconstruct.weaponry.ammo.ArrowAmmo;
+
+import java.util.List;
+
+public class GlassArrows extends ArrowAmmo {
+ public GlassArrows() {
+ super();
+ this.setUnlocalizedName(Reference.prefix("glassArrows"));
+ }
+
+ @Override
+ public float getAmmoModifier() {
+ return 1.0f;
+ }
+
+ @Override
+ public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean par4) {
+ super.addInformation(stack, player, list, par4);
+
+ list.add(EnumChatFormatting.DARK_PURPLE + "Crafted by a legendary Glassmaker");
+ }
+
+ @Override
+ public void getSubItems(Item id, CreativeTabs tab, List list) {
+ ItemStack headStack = new ItemStack(getHeadItem(), 1, 0);
+ 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);
+ }
+ else
+ return;
+
+ // now turn it into legendary glass arrows!
+ NBTTagCompound tags = tool.getTagCompound().getCompoundTag("InfiTool");
+ tags.setInteger("TotalDurability", 100); // 100 arrows
+ tags.setInteger("Ammo", 100); // full ammo
+ tags.setFloat("Mass", 5.0f); // durp
+ tags.setFloat("BreakChance", 200f); // 200% break chance!
+ tags.setFloat("Accuracy", 0.001f); // very full accuraccy
+ tags.setFloat("Shoddy", 0); // no stonebound/jagged
+ tags.setInteger("Unbreaking", 0); // no reinforced
+ tags.setInteger("Attack", 10); // insane damage!
+
+ // now make them look like glass
+ tags.setInteger("RenderHead", -1);
+ tags.setInteger("RenderHandle", -1);
+ tags.setInteger("RenderAccessory", -1);
+ tags.setInteger("HeadColor", 0xccfff3);
+ tags.setInteger("HandleColor", 0xbcfff3);
+ tags.setInteger("AccessoryColor", 0xccfff3);
+
+ list.add(tool);
+ }
+}
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..9de1b572
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/items/WeaponryPattern.java
@@ -0,0 +1,49 @@
+package tconstruct.weaponry.items;
+
+import tconstruct.util.Reference;
+import net.minecraft.creativetab.CreativeTabs;
+import net.minecraft.item.Item;
+import net.minecraft.item.ItemStack;
+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.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/weapons/Crossbow.java b/src/main/java/tconstruct/weaponry/weapons/Crossbow.java
new file mode 100644
index 00000000..3d7f3c90
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/weapons/Crossbow.java
@@ -0,0 +1,453 @@
+package tconstruct.weaponry.weapons;
+
+import tconstruct.TConstruct;
+import tconstruct.library.TConstructRegistry;
+import tconstruct.weaponry.TinkerWeaponry;
+import tconstruct.weaponry.ammo.BoltAmmo;
+import tconstruct.weaponry.entity.BoltEntity;
+import tconstruct.library.weaponry.AmmoItem;
+import tconstruct.library.weaponry.ProjectileWeapon;
+import tconstruct.util.Reference;
+import tconstruct.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 float getMinWindupProgress(ItemStack itemStack) {
+ return 1.0f;
+ }
+
+ @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, 1.0f);
+
+ 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, float windup) {
+ 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;
+
+ // 10% crit hit chance!
+ if(!world.isRemote && TConstruct.random.nextFloat() < 0.1f)
+ arrow.setIsCritical(true);
+
+ 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("crossbowReload"), 1.0f, 1.0f);
+ }
+
+ @Override
+ public void playFiringSound(World world, EntityPlayer player, ItemStack weapon, ItemStack ammo, float speed, float accuracy) {
+ world.playSoundAtEntity(player, "random.bow", 1.0F, 0.5F);
+ }
+
+ @Override
+ public IIcon getIcon(ItemStack stack, int renderPass) {
+ if(!animateLayer(renderPass) && renderPass < getPartAmount())
+ return super.getIcon(stack, renderPass);
+
+ if(!stack.hasTagCompound())
+ return super.getIcon(stack, renderPass);
+
+ NBTTagCompound tags = stack.getTagCompound().getCompoundTag("InfiTool");
+ if(tags == null || renderPass > 10)
+ return super.getIcon(stack, renderPass);
+
+ 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"));
+
+ // are we drawing an effect?
+ if(renderPass >= getPartAmount()) {
+ // is the effect animated?
+ String effect = "Effect" + (1 + renderPass - getPartAmount());
+ if(tags.hasKey(effect)) {
+ int index = tags.getInteger(effect);
+ if(animationEffectIcons.get(index) != null)
+ return getCorrectAnimationIcon(animationEffectIcons, index, progress);
+ else
+ // non-animated
+ return effectIcons.get(index);
+ }
+ 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 TinkerWeaponry.bowstring;
+ }
+
+ @Override
+ public Item getExtraItem() {
+ return TinkerTools.toughBinding;
+ }
+
+ @Override
+ public String[] getTraits() {
+ return new String[] {"weapon", "bow", "windup"};
+ }
+
+
+ @Override
+ public void buildTool (int id, String name, List list)
+ {
+ // does the material have a bow material?
+ if(TConstructRegistry.getBowMaterial(id) == null)
+ return;
+
+ // 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..3510e921
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/weapons/Javelin.java
@@ -0,0 +1,192 @@
+package tconstruct.weaponry.weapons;
+
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import tconstruct.weaponry.TinkerWeaponry;
+import tconstruct.weaponry.client.CrosshairType;
+import tconstruct.weaponry.entity.JavelinEntity;
+import tconstruct.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 17;
+ }
+
+ @Override
+ public int getPartAmount() {
+ return 3;
+ }
+
+ @Override
+ public String getIconSuffix(int partType) {
+ switch (partType)
+ {
+ case 0:
+ return "_javelin_head";
+ case 1:
+ return "_javelin_head_broken"; // 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.2f;
+ }
+
+ @Override
+ public float getDurabilityModifier() {
+ return 0.1f;
+ }
+
+ @Override
+ public Item getHeadItem() {
+ return TinkerWeaponry.arrowhead;
+ }
+
+ @Override
+ public Item getHandleItem() {
+ return TinkerTools.toughRod;
+ }
+
+ @Override
+ public Item getAccessoryItem() {
+ return TinkerTools.toughRod;
+ }
+
+ @Override
+ public String[] getTraits() {
+ return new String[] {"weapon", "thrown", "ammo", "windup"};
+ }
+
+ @Override
+ protected Entity createProjectile(ItemStack reference, World world, EntityPlayer player, float accuracy, int time) {
+ reference.getTagCompound().getCompoundTag("InfiTool").removeTag("Throwing"); // needed so the NBTs are equal
+ JavelinEntity entity = new JavelinEntity(world, player, getProjectileSpeed(), accuracy, reference);
+
+ return entity;
+ }
+
+ @Override
+ public float getProjectileSpeed() {
+ return 2.0f;
+ }
+
+ @SideOnly(Side.CLIENT)
+ @Override
+ public CrosshairType getCrosshairType() { return CrosshairType.WEIRD; }
+}
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..cc398296
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/weapons/LongBow.java
@@ -0,0 +1,116 @@
+package tconstruct.weaponry.weapons;
+
+import tconstruct.weaponry.TinkerWeaponry;
+import tconstruct.weaponry.ammo.ArrowAmmo;
+import tconstruct.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 3.33f;
+ }
+
+ @Override
+ public float getZoom(ItemStack itemStack) {
+ return 1.7f;
+ }
+
+ @Override
+ protected Entity createProjectile(ItemStack arrows, World world, EntityPlayer player, float speed, float accuracy, float windup) {
+ 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)/Math.max(1f, weight-1f);
+ if(accuracy < 0)
+ accuracy = 0;
+ }
+
+ return super.createProjectile(arrows, world, player, speed, accuracy, windup);
+ }
+
+ @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 TinkerWeaponry.bowstring;
+ }
+
+ @Override
+ public Item getAccessoryItem ()
+ {
+ return TinkerWeaponry.partBowLimb;
+ }
+
+ @Override
+ public Item getExtraItem() {
+ return TinkerTools.largePlate;
+ }
+}
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..2fb79333
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/weapons/ShortBow.java
@@ -0,0 +1,124 @@
+package tconstruct.weaponry.weapons;
+
+import cpw.mods.fml.relauncher.Side;
+import cpw.mods.fml.relauncher.SideOnly;
+import net.minecraft.client.entity.EntityPlayerSP;
+import tconstruct.weaponry.TinkerWeaponry;
+import tconstruct.weaponry.ammo.ArrowAmmo;
+import tconstruct.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;
+
+public class ShortBow extends BowBaseAmmo {
+ public ShortBow() {
+ super(0, "Shortbow");
+ }
+
+ @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, float windup) {
+ 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, windup);
+ }
+
+ @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 TinkerWeaponry.bowstring;
+ }
+
+ @Override
+ public Item getAccessoryItem ()
+ {
+ return TinkerWeaponry.partBowLimb;
+ }
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public void onUpdate (ItemStack stack, World world, Entity entity, int par4, boolean par5)
+ {
+ // shortbows are smaller and more mobile than longbows
+ super.onUpdate(stack, world, entity, par4, par5);
+ if (entity instanceof EntityPlayerSP)
+ {
+ EntityPlayerSP player = (EntityPlayerSP) entity;
+ ItemStack usingItem = player.getItemInUse();
+ if (usingItem != null && usingItem.getItem() == this)
+ {
+ player.movementInput.moveForward *= 1.5F;
+ player.movementInput.moveStrafe *= 1.5F;
+ }
+ }
+ }
+}
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..b8912f78
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/weapons/Shuriken.java
@@ -0,0 +1,194 @@
+package tconstruct.weaponry.weapons;
+
+import tconstruct.weaponry.TinkerWeaponry;
+import tconstruct.weaponry.client.CrosshairType;
+import tconstruct.client.IconFlipped;
+import tconstruct.weaponry.entity.ShurikenEntity;
+import tconstruct.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.8f;
+ }
+
+ @Override
+ public int getPartAmount() {
+ return 4;
+ }
+
+ @Override
+ public int durabilityTypeHandle() {
+ return 2;
+ }
+
+ @Override
+ public int durabilityTypeAccessory() {
+ return 2;
+ }
+
+ @Override
+ public int durabilityTypeExtra() {
+ return 2;
+ }
+
+ @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) {
+ if(getAmmoCount(stack) <= 0)
+ return stack;
+
+ launchProjectile(stack, world, player, 1);
+
+ // 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, int time) {
+ return new ShurikenEntity(world, player, getProjectileSpeed(), 0f, reference);
+ }
+
+ @Override
+ public float getProjectileSpeed() {
+ return 1.9f;
+ }
+
+ @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/ThrowingKnife.java b/src/main/java/tconstruct/weaponry/weapons/ThrowingKnife.java
new file mode 100644
index 00000000..862939e1
--- /dev/null
+++ b/src/main/java/tconstruct/weaponry/weapons/ThrowingKnife.java
@@ -0,0 +1,118 @@
+package tconstruct.weaponry.weapons;
+
+import net.minecraft.client.entity.EntityPlayerSP;
+import tconstruct.library.entity.ProjectileBase;
+import tconstruct.weaponry.client.CrosshairType;
+import tconstruct.weaponry.entity.ThrowingKnifeEntity;
+import tconstruct.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 "_knife_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 15; } // 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, int time) {
+ ProjectileBase knife = new ThrowingKnifeEntity(world, player, getProjectileSpeed(), accuracy, reference);
+ // if you aim long enough, it's a crit!
+ if(time >= this.getWindupTime(reference)*1.5f)
+ knife.setIsCritical(true);
+
+ return knife;
+ }
+
+ @Override
+ public float getProjectileSpeed() {
+ return 1.5f;
+ }
+
+ @SideOnly(Side.CLIENT)
+ @Override
+ public CrosshairType getCrosshairType() {
+ return CrosshairType.SPIKE;
+ }
+
+ @Override
+ @SideOnly(Side.CLIENT)
+ public void onUpdate (ItemStack stack, World world, Entity entity, int par4, boolean par5)
+ {
+ // aiming with throwing knives slows down much less than with a bow
+ super.onUpdate(stack, world, entity, par4, par5);
+ if (entity instanceof EntityPlayerSP)
+ {
+ EntityPlayerSP player = (EntityPlayerSP) entity;
+ ItemStack usingItem = player.getItemInUse();
+ if (usingItem != null && usingItem.getItem() == this)
+ {
+ player.movementInput.moveForward *= 3.0F;
+ player.movementInput.moveStrafe *= 3.0F;
+ }
+ }
+ }
+}
diff --git a/src/main/java/tconstruct/world/TinkerWorld.java b/src/main/java/tconstruct/world/TinkerWorld.java
index 24945fe8..6b62a1fc 100644
--- a/src/main/java/tconstruct/world/TinkerWorld.java
+++ b/src/main/java/tconstruct/world/TinkerWorld.java
@@ -564,8 +564,6 @@ public class TinkerWorld
BlockDispenser.dispenseBehaviorRegistry.putObject(TinkerTools.titleIcon, new TDispenserBehaviorSpawnEgg());
- BlockDispenser.dispenseBehaviorRegistry.putObject(TinkerTools.arrow, new TDispenserBehaviorArrow());
-
// Vanilla stuff
OreDictionary.registerOre("slimeball", new ItemStack(Items.slime_ball));
OreDictionary.registerOre("slimeball", new ItemStack(TinkerWorld.strangeFood, 1, 0));
diff --git a/weaponry.txt b/weaponry.txt
new file mode 100644
index 00000000..04f106fe
--- /dev/null
+++ b/weaponry.txt
@@ -0,0 +1,16 @@
+TODO:
+* Effect graphics for arrows, throwing knifes, javelins,... MOSTLY DONE
+* Partbuilder stuff for weaponry stuff?
+* Bring bowmaterial stats etc in line?
+* Knockback on projectiles knocks towards their moving direction DONEish
+* Javelins need lower durability. When leftclick attacking and it has no durability, it should use up 1 ammo and get durability.
+
+maybe give javelins slight armor piercing? or do they have that already?
+
+
+Ideas:
+* Liquid Purple Slime + Obsidian + Metal = Obslimite... Jademite, Obsidimite, Purplemite, Ironslime
+ - Lower durability than slime
+ - Bouncy.. harvested stuff gets knocked around? Maybe Knockback1?
+ - Jagged + Reinforced
+* Magma Cube -> Magma Slime Balls -> Tool Material. Slime + Fiery by default, high quality slime!