Create Custom Projectile Class

Discussion in 'Plugin Development' started by MrDaniel, Apr 4, 2021.

  1. Offline

    MrDaniel

    Hello there,

    This is a little bit advanced, but I was wondering how to create a projectile class.

    I am currently launching a projectile like this:
    Code:
    p.launchProjectile(Snowball.class, calculateInacurracy(p.getLocation()).multiply(3));
    But I would like to launch it like this
    Code:
    p.launchProjectile(Bullet.class, calculateInacurracy(p.getLocation()).multiply(3));
    The reason that I want to do this, is so when the projectile hits something, I can check whether it's an instance of Bullet, and if so do some garbage.

    The place that I am stuck now is this. The snowball class is a interface. I cannot extend it and create my own class, I need to implement it. And if I try to implement it, well then I have to use my custom implementation of the methods that I will inherit, for example this:
    Code:
         public void setShooter(ProjectileSource arg0) {
         }
    
    How would I do this?

    ----- SOLVED -----

    All I had to do is go through the pain staking process of changing the methods from
    Code:
         public void setShooter(ProjectileSource arg0) {
         }
    
    to
    Code:
    @Override
         public void setShooter(ProjectileSource arg0) {
           this.setShooter(arg0);
         }
    

    If anybody wants the entire class and not have to go through the 1h process of doing that here:
    the pain (open)

    Code:
    private class Bullet implements Snowball {
    
         @Override
         public ItemStack getItem() {
           return this.getItem();
         }
    
         @Override
         public void setItem(ItemStack arg0) {
           this.setItem(arg0);
         }
    
         @Override
         public boolean doesBounce() {
           return this.doesBounce();
         }
    
         @Override
         public ProjectileSource getShooter() {
           return this.getShooter();
         }
    
         @Override
         public void setBounce(boolean arg0) {
           this.setBounce(arg0);
         }
    
         @Override
         public void setShooter(ProjectileSource arg0) {
           this.setShooter(arg0);
         }
    
         @Override
         public boolean addPassenger(Entity arg0) {
           return this.addPassenger(arg0);
         }
    
         @Override
         public boolean addScoreboardTag(String arg0) {
           return this.addScoreboardTag(arg0);
         }
    
         @Override
         public boolean eject() {
           return this.eject();
         }
    
         @Override
         public BoundingBox getBoundingBox() {
           return this.getBoundingBox();
         }
    
         @Override
         public int getEntityId() {
           return this.getEntityId();
         }
    
         @Override
         public BlockFace getFacing() {
           return this.getFacing();
         }
    
         @Override
         public float getFallDistance() {
           return this.getFallDistance();
         }
    
         @Override
         public int getFireTicks() {
           return this.getFireTicks();
         }
    
         @Override
         public double getHeight() {
           return this.getHeight();
         }
    
         @Override
         public EntityDamageEvent getLastDamageCause() {
           return this.getLastDamageCause();
         }
    
         @Override
         public Location getLocation() {
           return this.getLocation();
         }
    
         @Override
         public Location getLocation(Location arg0) {
           return this.getLocation(arg0);
         }
    
         @Override
         public int getMaxFireTicks() {
           return this.getMaxFireTicks();
         }
    
         @Override
         public List<Entity> getNearbyEntities(double arg0, double arg1, double arg2) {
           return this.getNearbyEntities(arg0, arg1, arg2);
         }
    
         @Override
         public Entity getPassenger() {
           return this.getPassenger();
         }
    
         @Override
         public List<Entity> getPassengers() {
           return this.getPassengers();
         }
    
         @Override
         public PistonMoveReaction getPistonMoveReaction() {
           return this.getPistonMoveReaction();
         }
    
         @Override
         public int getPortalCooldown() {
           return this.getPortalCooldown();
         }
    
         @Override
         public Pose getPose() {
           return this.getPose();
         }
    
         @Override
         public Set<String> getScoreboardTags() {
           return this.getScoreboardTags();
         }
    
         @Override
         public Server getServer() {
           return this.getServer();
         }
    
         @Override
         public int getTicksLived() {
           return this.getTicksLived();
         }
    
         @Override
         public EntityType getType() {
           return this.getType();
         }
    
         @Override
         public UUID getUniqueId() {
           return this.getUniqueId();
         }
    
         @Override
         public Entity getVehicle() {
           return this.getVehicle();
         }
    
         @Override
         public Vector getVelocity() {
           return this.getVelocity();
         }
    
         @Override
         public double getWidth() {
           return this.getWidth();
         }
    
         @Override
         public World getWorld() {
           return this.getWorld();
         }
    
         @Override
         public boolean hasGravity() {
           return this.hasGravity();
         }
    
         @Override
         public boolean isCustomNameVisible() {
           return this.isCustomNameVisible();
         }
    
         @Override
         public boolean isDead() {
           return this.isDead();
         }
    
         @Override
         public boolean isEmpty() {
           return this.isEmpty();
         }
    
         @Override
         public boolean isGlowing() {
           return this.isGlowing();
         }
    
         @Override
         public boolean isInWater() {
           return this.isInWater();
         }
    
         @Override
         public boolean isInsideVehicle() {
           return this.isInsideVehicle();
         }
    
         @Override
         public boolean isInvulnerable() {
           return this.isInvulnerable();
         }
    
         @Override
         public boolean isOnGround() {
           return this.isOnGround();
         }
    
         @Override
         public boolean isPersistent() {
           return this.isPersistent();
         }
    
         @Override
         public boolean isSilent() {
           return this.isSilent();
         }
    
         @Override
         public boolean isValid() {
           return this.isValid();
         }
    
         @Override
         public boolean leaveVehicle() {
           return this.leaveVehicle();
         }
    
         @Override
         public void playEffect(EntityEffect arg0) {
           this.playEffect(arg0);
         }
    
         @Override
         public void remove() {
           this.remove();
         }
    
         @Override
         public boolean removePassenger(Entity arg0) {
           return this.removePassenger(arg0);
         }
    
         @Override
         public boolean removeScoreboardTag(String arg0) {
           return this.removeScoreboardTag(arg0);
         }
    
         @Override
         public void setCustomNameVisible(boolean arg0) {
           this.setCustomName(getCustomName());
         }
    
         @Override
         public void setFallDistance(float arg0) {
           this.setFallDistance(arg0);
         }
    
         @Override
         public void setFireTicks(int arg0) {
           this.setFireTicks(arg0);
         }
    
         @Override
         public void setGlowing(boolean arg0) {
           this.setGlowing(arg0);
         }
    
         @Override
         public void setGravity(boolean arg0) {
           this.setGravity(arg0);
         }
    
         @Override
         public void setInvulnerable(boolean arg0) {
           this.setInvulnerable(arg0);
         }
    
         @Override
         public void setLastDamageCause(EntityDamageEvent arg0) {
           this.setLastDamageCause(arg0);
         }
    
         @Override
         public boolean setPassenger(Entity arg0) {
           return this.setPassenger(arg0);
         }
    
         @Override
         public void setPersistent(boolean arg0) {
           this.setPersistent(arg0);
         }
    
         @Override
         public void setPortalCooldown(int arg0) {
           this.setPortalCooldown(arg0);
         }
    
         @Override
         public void setRotation(float arg0, float arg1) {
           this.setRotation(arg0, arg1);
         }
    
         @Override
         public void setSilent(boolean arg0) {
           this.setSilent(arg0);
         }
    
         @Override
         public void setTicksLived(int arg0) {
           this.setTicksLived(arg0);
         }
    
         @Override
         public void setVelocity(Vector arg0) {
           this.setVelocity(arg0);
         }
    
         @Override
         public Spigot spigot() {
           return this.spigot();
         }
    
         @Override
         public boolean teleport(Location arg0) {
           return this.teleport(arg0);
         }
    
         @Override
         public boolean teleport(Entity arg0) {
           return this.teleport(arg0);
         }
    
         @Override
         public boolean teleport(Location arg0, TeleportCause arg1) {
           return this.teleport(arg0, arg1);
         }
    
         @Override
         public boolean teleport(Entity arg0, TeleportCause arg1) {
           return this.teleport(arg0, arg1);
         }
    
         @Override
         public List<MetadataValue> getMetadata(String arg0) {
           return this.getMetadata(arg0);
         }
    
         @Override
         public boolean hasMetadata(String arg0) {
           return this.hasMetadata(arg0);
         }
    
         @Override
         public void removeMetadata(String arg0, Plugin arg1) {
           this.removeMetadata(arg0, arg1);
         
         }
    
         @Override
         public void setMetadata(String arg0, MetadataValue arg1) {
           this.setMetadata(arg0, arg1);
         }
    
         @Override
         public String getName() {
           return this.getName();
         }
    
         @Override
         public void sendMessage(String arg0) {
           this.sendMessage(arg0);
         
         }
    
         @Override
         public void sendMessage(String[] arg0) {
           this.sendMessage(arg0);
         
         }
    
         @Override
         public void sendMessage(UUID arg0, String arg1) {
           this.sendMessage(arg0, arg1);
         
         }
    
         @Override
         public void sendMessage(UUID arg0, String[] arg1) {
           this.sendMessage(arg0, arg1);
         }
    
         @Override
         public PermissionAttachment addAttachment(Plugin arg0) {
           return this.addAttachment(arg0);
         }
    
         @Override
         public PermissionAttachment addAttachment(Plugin arg0, int arg1) {
           return this.addAttachment(arg0, arg1);     }
    
         @Override
         public PermissionAttachment addAttachment(Plugin arg0, String arg1, boolean arg2) {
           return this.addAttachment(arg0, arg1, arg2);
         }
    
         @Override
         public PermissionAttachment addAttachment(Plugin arg0, String arg1, boolean arg2, int arg3) {
           return this.addAttachment(arg0, arg1, arg2, arg3);
         }
    
         @Override
         public Set<PermissionAttachmentInfo> getEffectivePermissions() {
           return this.getEffectivePermissions();
         }
    
         @Override
         public boolean hasPermission(String arg0) {
           return this.hasPermission(arg0);
         }
    
         @Override
         public boolean hasPermission(Permission arg0) {
           return this.hasPermission(arg0);
         }
    
         @Override
         public boolean isPermissionSet(String arg0) {
           return this.isPermissionSet(arg0);
         }
    
         @Override
         public boolean isPermissionSet(Permission arg0) {
           return this.isPermissionSet(arg0);
         }
    
         @Override
         public void recalculatePermissions() {
           this.recalculatePermissions();
         }
    
         @Override
         public void removeAttachment(PermissionAttachment arg0) {
           this.removeAttachment(arg0);
         }
    
         @Override
         public boolean isOp() {
           return this.isOp();
         }
    
         @Override
         public void setOp(boolean arg0) {
           this.setOp(arg0);
         }
    
         @Override
         public String getCustomName() {
           return this.getCustomName();
         }
    
         @Override
         public void setCustomName(String arg0) {
           this.setCustomName(arg0);
         }
    
         @Override
         public PersistentDataContainer getPersistentDataContainer() {
           return this.getPersistentDataContainer();
         }
       }
    
     
  2. Offline

    KarimAKL

    @MrDaniel, I believe your solution would cause a stack overflow error. When making a class that implements an interface, you should have the class do something with those methods by itself since methods from an interface have no actual implementations.
     
  3. Offline

    MrDaniel

    @KarimAKL what do you mean? I tested it and it works as intended. I think what it does is call the methods from it's parent class (Projectile/Entity) and not the methods that it created itself. I could be wrong, but it works.

    Sent from my motorola one vision using Tapatalk
     
  4. Offline

    KarimAKL

    It is a projectile, so of course, you can spawn it using launchProjectile(), but did you try calling any of your Bullet class' methods? I believe calling any of them should cause a stack overflow error.

    An interface cannot have a parent class.
     
  5. Offline

    MrDaniel

    Yep I tried. It did not cause stack overflow, after firing 1000 projectiles server was running just fine.

    You're right, it has a parent interface.

    How in the world does this work then?
     
  6. Offline

    KarimAKL

    I guess the compiler or JVM avoids that for you.

    The methods should be doing nothing, so they are not "working," they are simply not erroring.
     
  7. Offline

    MrDaniel

    getLocation is being overrriden and when I call the method I do get the location of the projectile, and not a stack overflow error or anything unexpected.
     
  8. Offline

    KarimAKL

    Oh, interesting. I wonder what Bukkit does with it. However, I am too lazy to check the source code right now. :p
     
    MrDaniel likes this.
  9. Offline

    MrDaniel

    Oh boy can I relate
     
    KarimAKL likes this.

Share This Page