Resource [1.8] MoreProjectiles

Discussion in 'Plugin Help/Development/Requests' started by stirante, Sep 1, 2013.

Thread Status:
Not open for further replies.
  1. Offline

    stirante

    Hey!
    I created lib in which you can create more projectiles.

    Right now there are 5 types of custom projectiles:
    • ItemProjectile - extends EntityItem
    • BlockProjectile - extends EntityFallingBlock
    • OrbProjectile - extends EntityExperienceOrb (it's a little buggy)
    • TNTProjectile - extends EntityTNTPrimed
    • ProjectileScheduler - creates projectile from every possible entity passed as parameter in constructor(head rotation of mobs is a little bit bugged right now)
    To spawn simple projectile just type something like this:
    Code:
    ItemProjectile projectile = new ItemProjectile("name", shooter, item, power);
    It automagiclly gives velocity, position and direction from shooter to EntityItem and spawns it in world.
    If you want to modify behavior of projectile when it hits something add this event:
    Code:
        @EventHandler
        public void onHit(CustomProjectileHitEvent e){
            if (e.getHitType() == HitType.ENTITY){
                e.getHitEntity().damage(3D, e.getProjectile().getShooter());
            }
        }
    If you want to play with some variables like velocity then get bukkit entity from projectile like this:
    Code:
    projectile.getEntity().setVelocity(velocity);
    It uses DarkBladee12 's particle lib.
    Download: Link
    Sources: Link
    Maven:
    Code:
        <repositories>
            <repository>
                <id>repo</id>
                <url>https://github.com/stirante/mvn-repo/raw/master/snapshots</url>
            </repository>
        </repositories>
    
        <dependencies>
            <dependency>
                <groupId>com.stirante</groupId>
                <artifactId>MoreProjectiles</artifactId>
                <version>1.0-SNAPSHOT</version>
            </dependency>
        </dependencies>
    
     
    Last edited: Dec 11, 2014
  2. Offline

    Chinwe

    By creating projectiles from items, do you mean it shoots the itemdrop at the velocity/power that you specify (like launchProjectile(Item.class) would do) ?

    Very nice though :)
     
    Omletowy likes this.
  3. Offline

    stirante

    Exactly, but it's not just Item. It's custom EntityItem, so I disabled picking up items and merging with other items, changed a little some despawn and added detecting colissions with blocks and entities, event when item hits something and some cool particles :D
     
  4. Offline

    Chinwe

    Ahhh ok, even better! Will definitely be using this :)
     
  5. Offline

    jorisk322

    Is this something that will break on updates?

    I'm now watching this thread, as I'm sure I will want to use this some day.
     
  6. Offline

    stirante

    Yes, it will break on updates :/ And becouse one class extends class from nms it would be hard to do it version proof. I'll try to update it as soon as any update will be.
     
  7. Offline

    lx3krypticx

    Well then.. I'll be using this ;) Thanks.
     
  8. Offline

    stirante

    I'm glad someone found it useful :D
     
  9. Offline

    jorisk322

    That's too bad. I wouldn't really want to rely on a library that has to be updated every mc-update. I'm guessing this kind of functionality will never be added to the API though, so that's a shame.
     
  10. Offline

    stirante

    I'm also working on simple app which will replace packages in compiled jar for quick updating any plugin.
     
  11. Offline

    jorisk322

    Ooh, nice. It would be even more awesome if it could check if the methods you use have changed (breaking your plugin), but I don't know if that's possible from a technical point of view.
     
  12. Offline

    stirante

    No, it would be too difficult. Just checked it. That would be too perfect.
     
  13. Offline

    bobacadodl

    Add the ability to set the name of the projectile in the constructor, then get its name onProjectileHit! :)

    So that you can differentiate between projectiles
     
  14. Offline

    stirante

    Great idea, i'll add it tomorrow :D
     
  15. Offline

    bobacadodl

    Here, I added the ability to get the ItemStack from the event :), and name the projectiles and get the name from the event. Few classes you need to update though

    New class: ItemProjectileHitEvent.java Listen to this instead~! It extends CustomProjectileHitEvent, and has ability to get the ItemStack of the projectile
    Code:java
    1.  
    2. import org.bukkit.Bukkit;
    3. import org.bukkit.block.Block;
    4. import org.bukkit.block.BlockFace;
    5. import org.bukkit.entity.LivingEntity;
    6. import org.bukkit.inventory.ItemStack;
    7.  
    8. import com.stirante.MoreProjectiles.projectile.CustomProjectile;
    9.  
    10. public class ItemProjectileHitEvent extends CustomProjectileHitEvent{
    11. private ItemStack i;
    12. public ItemProjectileHitEvent(CustomProjectile pro, Block b, BlockFace f, ItemStack i) {
    13. super(pro, b, f);
    14. this.i=i;
    15. Bukkit.getServer().getPluginManager().callEvent(new CustomProjectileHitEvent(pro,b,f));
    16. }
    17. public ItemProjectileHitEvent(CustomProjectile pro, LivingEntity ent, ItemStack i) {
    18. super(pro,ent);
    19. Bukkit.getServer().getPluginManager().callEvent(new CustomProjectileHitEvent(pro,ent));
    20. }
    21.  
    22. public ItemStack getItem(){
    23. return i;
    24. }
    25. }
    26.  


    Updated ItemProjectile.java

    Code:java
    1.  
    2. import java.util.List;
    3.  
    4. import net.minecraft.server.v1_6_R2.AxisAlignedBB;
    5. import net.minecraft.server.v1_6_R2.Block;
    6. import net.minecraft.server.v1_6_R2.Entity;
    7. import net.minecraft.server.v1_6_R2.EntityHuman;
    8. import net.minecraft.server.v1_6_R2.EntityItem;
    9. import net.minecraft.server.v1_6_R2.EntityLiving;
    10. import net.minecraft.server.v1_6_R2.EnumMovingObjectType;
    11. import net.minecraft.server.v1_6_R2.IProjectile;
    12. import net.minecraft.server.v1_6_R2.MathHelper;
    13. import net.minecraft.server.v1_6_R2.MinecraftServer;
    14. import net.minecraft.server.v1_6_R2.MovingObjectPosition;
    15. import net.minecraft.server.v1_6_R2.Vec3D;
    16.  
    17. import org.bukkit.Bukkit;
    18. import org.bukkit.Location;
    19. import org.bukkit.Material;
    20. import org.bukkit.craftbukkit.v1_6_R2.CraftWorld;
    21. import org.bukkit.craftbukkit.v1_6_R2.block.CraftBlock;
    22. import org.bukkit.craftbukkit.v1_6_R2.entity.CraftLivingEntity;
    23. import org.bukkit.craftbukkit.v1_6_R2.event.CraftEventFactory;
    24. import org.bukkit.craftbukkit.v1_6_R2.inventory.CraftItemStack;
    25. import org.bukkit.entity.EntityType;
    26. import org.bukkit.entity.LivingEntity;
    27. import org.bukkit.inventory.ItemStack;
    28.  
    29. import com.stirante.MoreProjectiles.Particles;
    30. import com.stirante.MoreProjectiles.event.CustomProjectileHitEvent;
    31. import com.stirante.MoreProjectiles.event.ItemProjectileHitEvent;
    32.  
    33. public class ItemProjectile extends EntityItem implements IProjectile, CustomProjectile {
    34.  
    35. private EntityLiving shooter;
    36. private int lastTick;
    37. private String name;
    38. private ItemStack item;
    39. public ItemProjectile(String name, Location loc, org.bukkit.inventory.ItemStack itemstack, LivingEntity shooter, float power) {
    40. super(((CraftWorld) loc.getWorld()).getHandle(), loc.getX(), loc.getY(), loc.getZ(), CraftItemStack.asNMSCopy(itemstack));
    41. lastTick = MinecraftServer.currentTick;
    42. this.pickupDelay = Integer.MAX_VALUE;
    43. this.shooter = ((CraftLivingEntity)shooter).getHandle();
    44. this.name=name;
    45. this.item=itemstack;
    46. this.a(0.25F, 0.25F);
    47. setPositionRotation(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch());
    48. locX -= (MathHelper.cos(yaw / 180.0F * 3.1415927F) * 0.16F);
    49. locY -= 0.10000000149011612D;
    50. locZ -= (MathHelper.sin(yaw / 180.0F * 3.1415927F) * 0.16F);
    51. setPosition(locX, locY, locZ);
    52. height = 0.0F;
    53. float f = 0.4F;
    54. motX = (-MathHelper.sin(yaw / 180.0F * 3.1415927F) * MathHelper.cos(pitch / 180.0F * 3.1415927F) * f);
    55. motZ = (MathHelper.cos(yaw / 180.0F * 3.1415927F) * MathHelper.cos(pitch / 180.0F * 3.1415927F) * f);
    56. motY = (-MathHelper.sin(pitch / 180.0F * 3.1415927F) * f);
    57. shoot(motX, motY, motZ, power * 1.5F, 1.0F);
    58. world.addEntity(this);
    59. }
    60.  
    61. public ItemProjectile(LivingEntity shooter, org.bukkit.inventory.ItemStack item, float power) {
    62. super(((CraftLivingEntity)shooter).getHandle().world);
    63. lastTick = MinecraftServer.currentTick;
    64. this.pickupDelay = Integer.MAX_VALUE;
    65. setItemStack(CraftItemStack.asNMSCopy(item));
    66. this.shooter = ((CraftLivingEntity)shooter).getHandle();
    67. this.a(0.25F, 0.25F);
    68. setPositionRotation(shooter.getLocation().getX(), shooter.getLocation().getY() + shooter.getEyeHeight(), shooter.getLocation().getZ(), shooter.getLocation().getYaw(), shooter.getLocation().getPitch());
    69. locX -= (MathHelper.cos(yaw / 180.0F * 3.1415927F) * 0.16F);
    70. locY -= 0.10000000149011612D;
    71. locZ -= (MathHelper.sin(yaw / 180.0F * 3.1415927F) * 0.16F);
    72. setPosition(locX, locY, locZ);
    73. height = 0.0F;
    74. float f = 0.4F;
    75. motX = (-MathHelper.sin(yaw / 180.0F * 3.1415927F) * MathHelper.cos(pitch / 180.0F * 3.1415927F) * f);
    76. motZ = (MathHelper.cos(yaw / 180.0F * 3.1415927F) * MathHelper.cos(pitch / 180.0F * 3.1415927F) * f);
    77. motY = (-MathHelper.sin(pitch / 180.0F * 3.1415927F) * f);
    78. shoot(motX, motY, motZ, power * 1.5F, 1.0F);
    79. world.addEntity(this);
    80. }
    81.  
    82. @SuppressWarnings("rawtypes")
    83. @Override
    84. public void l_() {
    85. x();
    86. int elapsedTicks = MinecraftServer.currentTick - this.lastTick;
    87. this.pickupDelay -= elapsedTicks;
    88. this.age += elapsedTicks;
    89. lastTick = MinecraftServer.currentTick;
    90.  
    91. this.lastX = this.locX;
    92. this.lastY = this.locY;
    93. this.lastZ = this.locZ;
    94. this.motY -= 0.03999999910593033D;
    95. this.Z = i(this.locX, (this.boundingBox.b + this.boundingBox.e) / 2.0D, this.locZ);
    96. move(this.motX, this.motY, this.motZ);
    97. boolean flag = ((int)this.lastX != (int)this.locX) || ((int)this.lastY != (int)this.locY) || ((int)this.lastZ != (int)this.locZ);
    98.  
    99. if ((flag) || (this.ticksLived % 25 == 0)) {
    100. if (this.world.getMaterial(MathHelper.floor(this.locX), MathHelper.floor(this.locY), MathHelper.floor(this.locZ)) == net.minecraft.server.v1_6_R2.Material.LAVA) {
    101. this.motY = 0.2000000029802322D;
    102. this.motX = ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F);
    103. this.motZ = ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F);
    104. makeSound("random.fizz", 0.4F, 2.0F + this.random.nextFloat() * 0.4F);
    105. }
    106. }
    107.  
    108. float f = 0.98F;
    109.  
    110. if (this.onGround) {
    111. f = 0.5880001F;
    112. int i = this.world.getTypeId(MathHelper.floor(this.locX), MathHelper.floor(this.boundingBox.b) - 1, MathHelper.floor(this.locZ));
    113.  
    114. if (i > 0) {
    115. f = Block.byId.frictionFactor * 0.98F;
    116. }
    117. }
    118.  
    119. this.motX *= f;
    120. this.motY *= 0.9800000190734863D;
    121. this.motZ *= f;
    122. if (this.onGround) {
    123. this.motY *= -0.5D;
    124. }
    125.  
    126. if (this.age >= 1000){
    127. die();
    128. }
    129. if (CraftEventFactory.callItemDespawnEvent(this).isCancelled()) {
    130. this.age = 0;
    131. return;
    132. }
    133.  
    134. Vec3D vec3d = world.getVec3DPool().create(locX, locY, locZ);
    135. Vec3D vec3d1 = world.getVec3DPool().create(locX + motX, locY + motY, locZ + motZ);
    136. MovingObjectPosition movingobjectposition = world.a(vec3d, vec3d1);
    137.  
    138. vec3d = world.getVec3DPool().create(locX, locY, locZ);
    139. vec3d1 = world.getVec3DPool().create(locX + motX, locY + motY, locZ + motZ);
    140. if (movingobjectposition != null) vec3d1 = world.getVec3DPool().create(movingobjectposition.pos.c, movingobjectposition.pos.d, movingobjectposition.pos.e);
    141.  
    142. if (!world.isStatic) {
    143. Entity entity = null;
    144. List list = world.getEntities(this, boundingBox.a(motX, motY, motZ).grow(1.0D, 1.0D, 1.0D));
    145. double d0 = 0.0D;
    146. EntityLiving entityliving = shooter;
    147.  
    148. for (int j = 0; j < list.size(); ++j) {
    149. Entity entity1 = (Entity) list.get(j);
    150.  
    151. if (entity1.L() && entity1 != entityliving) {
    152. float f1 = 0.3F;
    153. AxisAlignedBB axisalignedbb = entity1.boundingBox.grow(f1, f1, f1);
    154. MovingObjectPosition movingobjectposition1 = axisalignedbb.a(vec3d, vec3d1);
    155.  
    156. if (movingobjectposition1 != null) {
    157. double d1 = vec3d.distanceSquared(movingobjectposition1.pos);
    158.  
    159. if (d1 < d0 || d0 == 0.0D) {
    160. entity = entity1;
    161. d0 = d1;
    162. }
    163. }
    164. }
    165. }
    166.  
    167. if (entity != null) movingobjectposition = new MovingObjectPosition(entity);
    168. }
    169.  
    170. if (movingobjectposition != null) if (movingobjectposition.type == EnumMovingObjectType.TILE) {
    171. ItemProjectileHitEvent event = new ItemProjectileHitEvent(this, world.getWorld().getBlockAt(movingobjectposition.b, movingobjectposition.c, movingobjectposition.d), CraftBlock.notchToBlockFace(movingobjectposition.face),item);
    172. Bukkit.getPluginManager().callEvent(event);
    173. if (Material.getMaterial(getItemStack().id).isBlock())
    174. Particles.playTileCrack(getBukkitEntity().getLocation(), getItemStack().id, (byte) 0, 0, 0, 0, 20);
    175. else
    176. Particles.playIconCrack(getBukkitEntity().getLocation(), getItemStack().id, 0, 0, 0, 20);
    177. die();
    178. }
    179. else if (movingobjectposition.entity != null && movingobjectposition.entity instanceof EntityLiving) {
    180. LivingEntity living = (LivingEntity) movingobjectposition.entity.getBukkitEntity();
    181. CustomProjectileHitEvent event = new CustomProjectileHitEvent(this, living);
    182. Bukkit.getPluginManager().callEvent(event);
    183. if (Material.getMaterial(getItemStack().id).isBlock())
    184. Particles.playTileCrack(getBukkitEntity().getLocation(), getItemStack().id, (byte) 0, 0, 0, 0, 20);
    185. else
    186. Particles.playIconCrack(getBukkitEntity().getLocation(), getItemStack().id, 0, 0, 0, 20);
    187. die();
    188. }
    189. }
    190.  
    191. public void shoot(double d0, double d1, double d2, float f, float f1) {
    192. float f2 = MathHelper.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
    193.  
    194. d0 /= f2;
    195. d1 /= f2;
    196. d2 /= f2;
    197. d0 += random.nextGaussian() * 0.007499999832361937D * f1;
    198. d1 += random.nextGaussian() * 0.007499999832361937D * f1;
    199. d2 += random.nextGaussian() * 0.007499999832361937D * f1;
    200. d0 *= f;
    201. d1 *= f;
    202. d2 *= f;
    203. motX = d0;
    204. motY = d1;
    205. motZ = d2;
    206. float f3 = MathHelper.sqrt(d0 * d0 + d2 * d2);
    207.  
    208. lastYaw = yaw = (float) (Math.atan2(d0, d2) * 180.0D / 3.1415927410125732D);
    209. lastPitch = pitch = (float) (Math.atan2(d1, f3) * 180.0D / 3.1415927410125732D);
    210. }
    211.  
    212. @Override
    213. public EntityType getEntityType() {
    214. return EntityType.DROPPED_ITEM;
    215. }
    216.  
    217. @Override
    218. public org.bukkit.entity.Entity getEntity() {
    219. return getBukkitEntity();
    220. }
    221.  
    222. @Override
    223. public LivingEntity getShooter() {
    224. return (LivingEntity) shooter.getBukkitEntity();
    225. }
    226.  
    227. @Override
    228. public String getName() {
    229. return name;
    230. }
    231.  
    232. public ItemStack getItem() {
    233. return item;
    234. }
    235.  
    236. @Override
    237. public void b_(EntityHuman entityhuman) {
    238. if (entityhuman == shooter && age <= 3) return ;
    239. LivingEntity living = (LivingEntity) entityhuman.getBukkitEntity();
    240. CustomProjectileHitEvent event = new CustomProjectileHitEvent(this, living);
    241. Bukkit.getPluginManager().callEvent(event);
    242. if (Material.getMaterial(getItemStack().id).isBlock())
    243. Particles.playTileCrack(getBukkitEntity().getLocation(), getItemStack().id, (byte) 0, 0, 0, 0, 20);
    244. else
    245. Particles.playIconCrack(getBukkitEntity().getLocation(), getItemStack().id, 0, 0, 0, 20);
    246. die();
    247. }
    248. }


    Now to spawn projectile, do:
    Code:
    new ItemProjectile("Grenade",player.getLocation(),new ItemStack(Material.SLIME_BALL),player);
    And to listen for projectiles, do:
    Code:
    @EventHandler
    public void onItemProjectileHit(ItemProjectileHitEvent e){
      if(e.getName().equals("Grenade"){
        //do stuff :)
      }
    }
     
  16. Offline

    stirante


    I added this, but I wrote it myself depending on your code. I don't have time for testing it. Also I added BlockProjectile which is falling block (and it's also not tested at all)
     
    bobacadodl likes this.
  17. What does it implement the Particles class for?
    And how can I get the hit location when it hits a block?
     
  18. Offline

    stirante

    Particles class makes particles when projectile hits entity or block. To get location, do CustomProjectileHitEvent and if getHitType is HitType.BLOCK then do event.getBlock().getLocation(). You can also get block face hit by projectile.

    Also i was thinking about xp orb projectile :D
     
    bobacadodl likes this.
  19. Offline

    michidk

    Hi,
    love this lib so much...

    how about adding this to ItemProjectileHitEvent:
    Code:java
    1.  
    2. public Block getHitBlock() {
    3. return block;
    4. }
    5.  
    6. public Location getHitLocation() {
    7. Location l = null;
    8. if (getHitType() == HitType.ENTITY) {
    9. l = getHitEntity().getLocation();
    10. } else if (getHitType() == HitType.BLOCK) {
    11. l = getHitBlock().getLocation();
    12. }
    13. return l;
    14. }
    15.  


    and i also would recommend to change the projectile identifier (i mean the name of a projectile) from String to a ItemStack...
     
    Europia79 likes this.
  20. Offline

    stirante

    In ItemProjectileHitEvent you have getItemStack() so no need for changing name to itemstack. Also if you want to get projectile's location do event.getProjectile().getEntity().getLocation().
     
  21. Offline

    michidk

    hmm.. fuck .. you are right... in my modified version of your lib, i have a ItemStack, that has the ItemStack from the tool that triggered the projectile... but i dont thing about that you can use the libary without tools >.<

    and yes, but my getHitLocation() returns the location of the target... event.getProjectile().getEntity().getLocation() returns the location of the entity.... there is a different...
    for example if i use a arrow as projectile... and the arrow stucks in a block... the arrow is on another block (air) as the hitted block
     
  22. Offline

    stirante

    michidk Haha, i just saw that i forgot to add getHitBlock() and getHitFace(). I added it now with new projectile type. I also added orb projectile from experience orb, but it's right now a bit buggy, becouse of delay after spawning it. To see it try spawning orb projectile straight into the air.
     
    michidk likes this.
  23. Offline

    michidk

    is there a way to make the projectile invulnerable?
    cause my projectiles get destroyed by lava...
     
  24. Offline

    stirante

    I can add it.
     
    michidk likes this.
  25. Offline

    stirante

    Made all events cancellable which cancels particles and keeps particle alive, cause I wanted to make it bounce when it hits ground :D Also added setInvulnerable and isInvulnerable. Orb projectiles still bugged, someone on irc told me that it's minecraft's bug, not bukkit so i can't fix it :/
     
  26. Offline

    michidk

    update plz
     
  27. Offline

    TrollTaylor

    Does this work with 1.6.4? Cause its giving me a error when i try to put the itemstack.
     
  28. Offline

    stirante

  29. Offline

    stirante

  30. Offline

    PizzaPixel

    How do I make deal damage to an entity
     
Thread Status:
Not open for further replies.

Share This Page