redid methods for firing shells

master
Soper Aylamo 2021-05-20 23:29:55 -04:00
parent 35f9279886
commit 44de70cb88
Signed by: Soper
GPG Key ID: A27AC885ACC3BEAE
5 changed files with 117 additions and 51 deletions

View File

@ -14,9 +14,6 @@ import xyz.soper.arty.debug.DebugCommand;
import xyz.soper.arty.event.Listener.MortarInteract; import xyz.soper.arty.event.Listener.MortarInteract;
import xyz.soper.arty.item.Shell; import xyz.soper.arty.item.Shell;
import java.util.ArrayList;
import java.util.List;
public class Artillery extends JavaPlugin { public class Artillery extends JavaPlugin {
@Override @Override

View File

@ -1,8 +1,5 @@
package xyz.soper.arty.event.Listener; package xyz.soper.arty.event.Listener;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.Nameable;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.Arrow; import org.bukkit.entity.Arrow;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -28,22 +25,14 @@ public class MortarInteract implements Listener {
boolean isBlockNull = (block == null); boolean isBlockNull = (block == null);
if(!isBlockNull){ if(!isBlockNull){
if(block.getBlockData().getMaterial() == Material.BREWING_STAND){ if(Mortar.isMortar(block)){
player.sendMessage("DEBUG: Block is an brewing stand."); player.sendMessage("DEBUG: Block is a mortar.");
Nameable brewingStandMortar = (Nameable) event.getClickedBlock().getState(); if(event.getAction() == Action.RIGHT_CLICK_BLOCK) event.setCancelled(true);
String blockName = brewingStandMortar.getCustomName(); if(Shell.isShell(item)){
if(blockName == null) return; player.sendMessage("DEBUG: Player has a shell in hand.");
if(blockName.equals(ChatColor.GRAY + "Basic Mortar") MortarHandler.fireShell(new Mortar(block), new Shell(item), player);
|| blockName.equals(ChatColor.GRAY + "Mortar")){ if(item.getAmount() > 1) item.setAmount(item.getAmount()-1);
player.sendMessage("DEBUG: Block is a mortar."); else player.getInventory().setItemInMainHand(null);
if(event.getAction() == Action.RIGHT_CLICK_BLOCK) event.setCancelled(true);
if(Shell.isShell(item)){
player.sendMessage("DEBUG: Player has a shell in hand.");
MortarHandler mortarHandler = new MortarHandler(new Mortar(block));
mortarHandler.fireShell(new Shell(item), player);
if(item.getAmount() > 1) item.setAmount(item.getAmount()-1);
else player.getInventory().setItemInMainHand(null);
}
} }
} }
} }

View File

@ -8,6 +8,9 @@ import org.bukkit.util.Vector;
import java.util.Random; import java.util.Random;
/**
* A wrapper class for a brewing stand. Represents a mortar.
*/
public class Mortar { public class Mortar {
/**The block that represents this mortar.*/ /**The block that represents this mortar.*/
@ -90,10 +93,38 @@ public class Mortar {
* Returns the Block that represents this mortar object * Returns the Block that represents this mortar object
* @return Mortar as a Block * @return Mortar as a Block
*/ */
public Block getBlock() { public Block getBlock(){
return block; return block;
} }
/**
* Sets the direction of this mortar to the specified vector.
* @param vector Direction vector to use for the mortar
*/
public void setDirection(Vector vector){
direction = vector;
}
/**
* Sets the direction of this mortar using three one-dimensional vectors.
* This will normalize the resultant directional vector.
* @param x Vector in the x-axis
* @param y Vector in the y-axis
* @param z Vector in the z-axis
*/
public void setDirection(double x, double y, double z){
Vector vector = new Vector(x, y, z).normalize();
setDirection(vector);
}
/**
* Returns the direction of this mortar as a normalized vector.
* @return Normalized vector that represents this mortar's direction.
*/
public Vector getDirection() {
return direction;
}
/** /**
* Determines type of failure the provided shell and this mortar experienced * Determines type of failure the provided shell and this mortar experienced
* @param shell Shell that interacted with this mortar object * @param shell Shell that interacted with this mortar object
@ -103,13 +134,22 @@ public class Mortar {
* 2 for no impact explosion dud; * 2 for no impact explosion dud;
* 3 for catastrophic failure * 3 for catastrophic failure
*/ */
public int getFailureType(Shell shell){ public int getShellInteraction(Shell shell){
if(isFailure(shell)){ if(isFailure(shell)){
Random random = new Random(block.getWorld().getSeed() + System.currentTimeMillis()); Random random = new Random(block.getWorld().getSeed() + System.currentTimeMillis());
double maxDouble; double maxDouble;
maxDouble = jamChance + dudChance + catastrophicFailChance;
if(!incendiaryCompatible(shell)) maxDouble += 2*catastrophicFailChance;
double randDouble = random.nextDouble(); double randDouble = random.nextDouble()*maxDouble;
//TODO: compare random double and create an algo to determine type of failure.
if(randDouble < jamChance){
return 1;
}
else if(randDouble < (jamChance + dudChance)){
return 2;
}
else return 3;
} }
else return 0; else return 0;
} }
@ -130,27 +170,28 @@ public class Mortar {
* @param shell Shell to test. * @param shell Shell to test.
* @return True if the shell and mortar are compatible. * @return True if the shell and mortar are compatible.
*/ */
public boolean incendiaryCompatible(Shell shell){ //TODO: check if this is right public boolean incendiaryCompatible(Shell shell){
return incendiaryCapable || !shell.incendiaryType; return incendiaryCapable || !shell.incendiaryType;
} }
/**
* Checks if the block is a mortar.
* @param block Block to check.
* @return True if block is a brewing stand with a name that matches a mortar.
*/
public static boolean isMortar(Block block){ public static boolean isMortar(Block block){
if(block != null return block != null
&& block.getBlockData().getMaterial() == Material.BREWING_STAND && block.getBlockData().getMaterial() == Material.BREWING_STAND
&& isStringMortar(((Nameable)block.getState()).getCustomName())){ && isStringMortar(((Nameable) block.getState()).getCustomName());
return true;
}
return false;
} }
private static boolean isStringMortar(String string){ private static boolean isStringMortar(String string){
if(string != null if(string == null){
|| string.equals(BASIC_MORTAR_NAME) return false;
}
return (string.equals(BASIC_MORTAR_NAME)
|| string.equals(NORMAL_MORTAR_NAME) || string.equals(NORMAL_MORTAR_NAME)
|| string.equals(REINFORCED_MORTAR_NAME) || string.equals(REINFORCED_MORTAR_NAME)
|| string.equals(INCENDIARY_CAPABLE_MORTAR_NAME)){ || string.equals(INCENDIARY_CAPABLE_MORTAR_NAME));
return true;
}
return false;
} }
} }

View File

@ -13,23 +13,49 @@ import java.util.List;
*/ */
public class Shell { public class Shell {
/**
* The shell's explosive power.
* 4f represents TNT, 3f represents a creeper explosion.
*/
public float explosivePower = 2.5f; public float explosivePower = 2.5f;
/**
* The shell's penetration value in blocks.
* This number represents how many blocks a shell can penetrate while keeping its velocity intact.
*/
public int penetration = 0; public int penetration = 0;
/**
* The shell's incendiary type.
* True means this shell is capable of creating fires on impact.
*/
public boolean incendiaryType = false; public boolean incendiaryType = false;
/**
* The shell's base initial velocity.
* 2.5 represents a normal shell in a normal mortar.
* Final velocity is determined via the mortar used to fire this shell.
*/
public double baseVelocity = 2.5; public double baseVelocity = 2.5;
/**
* The shell's base chance of having any kind of failure in percent.
* Final chance percentage and final fail type is determined by the mortar used to fire this shell.
*/
public double failChance = .01; public double failChance = .01;
public boolean isFired; /**
* True if this shell is already fired.
*/
public final boolean isFired;
/** /**
* Creates a shell item wrapper with default stats. Represents the first basic craftable shell in-game. * Creates a shell item wrapper with default stats.
* Represents the first basic craftable shell in-game.
*/ */
public Shell(){ public Shell(){
isFired = false; isFired = false;
} }
/** /**
* Creates a shell item wrapper from a pre-existing arrow ItemStack with lore. If arrow is not a Shell, will create a default shell. * Creates a shell item wrapper from a pre-existing arrow ItemStack with lore.
* If arrow is not a Shell, will create a default shell.
* @param shell The ItemStack with lore * @param shell The ItemStack with lore
*/ */
public Shell(ItemStack shell){ public Shell(ItemStack shell){
@ -102,7 +128,7 @@ public class Shell {
} }
/** /**
* Checks if the item stack is a shell * Checks if the item stack is a shell.
* @param item ItemStack to check against * @param item ItemStack to check against
* @return True if item is an arrow with a gray name "Shell" * @return True if item is an arrow with a gray name "Shell"
*/ */
@ -114,7 +140,7 @@ public class Shell {
} }
/** /**
* Checks if the projectile is a shell * Checks if the projectile is a shell.
* @param projectile Projectile to check against * @param projectile Projectile to check against
* @return True if projectile has a name that starts with "shell" * @return True if projectile has a name that starts with "shell"
*/ */
@ -162,12 +188,17 @@ public class Shell {
* @param location The location where the explosion will occur * @param location The location where the explosion will occur
*/ */
public void explodeShell(Location location){ public void explodeShell(Location location){
location.getWorld().createExplosion(location, explosivePower, incendiaryType, true);
float explosiveDamagePower = explosivePower; float explosiveDamagePower = explosivePower;
if(explosivePower < 4.5){ if(explosivePower == 0){ //SHRAPNEL TYPE
explosiveDamagePower = 5;
location.getWorld().createExplosion(location, explosiveDamagePower, false, false);
return;
}
else if(explosivePower < 4.5){
explosiveDamagePower = (float)((1/((-0.5*4.5)+4.5))*explosivePower*((-.5*explosivePower)+4.5)); explosiveDamagePower = (float)((1/((-0.5*4.5)+4.5))*explosivePower*((-.5*explosivePower)+4.5));
} }
location.getWorld().createExplosion(location, explosiveDamagePower, false, false); location.getWorld().createExplosion(location, explosiveDamagePower, false, false);
location.getWorld().createExplosion(location, explosivePower, incendiaryType, true);
} }
/** /**

View File

@ -11,13 +11,22 @@ import xyz.soper.arty.item.Shell;
public class MortarHandler { public class MortarHandler {
Mortar mortar; /**
* Fires a shell projectile from the specified mortar.
public MortarHandler(Mortar mortar){ * @param mortar
this.mortar = mortar; * @param shell
*/
public static void fireShell(Mortar mortar, Shell shell){
//TODO: Fire shell method
} }
public void fireShell(Shell shell, ProjectileSource shooter){ /**
* Fires a shell projectile from the specified mortar by the specified shooter.
* @param mortar
* @param shell
* @param shooter
*/
public static void fireShell(Mortar mortar, Shell shell, ProjectileSource shooter){
//TODO: Use linkProjectile method and finalize fireShell method to create a proper non-debug fireShell method. //TODO: Use linkProjectile method and finalize fireShell method to create a proper non-debug fireShell method.
//As it stands, this method creates a shell with no actual data so the Shell wrapper uses default values. //As it stands, this method creates a shell with no actual data so the Shell wrapper uses default values.
@ -36,7 +45,6 @@ public class MortarHandler {
shellProjectile.setShooter(shooter); shellProjectile.setShooter(shooter);
shellProjectile.setCustomName("shell"); shellProjectile.setCustomName("shell");
mortar.getBlock().getWorld().spawnParticle(Particle.SMOKE_NORMAL, mortarLocation, 500, .5, 0, .5, .5); mortar.getBlock().getWorld().spawnParticle(Particle.SMOKE_NORMAL, mortarLocation, 500, .5, 0, .5, .5);
//TODO: Experiment with spawnParticle offset parameters. This may create more realistic smoke.
if(shooter instanceof Player) if(shooter instanceof Player)
((Player) shooter).sendMessage("DEBUG: Shell fired with a velocity " + shell.baseVelocity); ((Player) shooter).sendMessage("DEBUG: Shell fired with a velocity " + shell.baseVelocity);
} }