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.item.Shell;
import java.util.ArrayList;
import java.util.List;
public class Artillery extends JavaPlugin {
@Override

View File

@ -1,8 +1,5 @@
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.entity.Arrow;
import org.bukkit.entity.Player;
@ -28,22 +25,14 @@ public class MortarInteract implements Listener {
boolean isBlockNull = (block == null);
if(!isBlockNull){
if(block.getBlockData().getMaterial() == Material.BREWING_STAND){
player.sendMessage("DEBUG: Block is an brewing stand.");
Nameable brewingStandMortar = (Nameable) event.getClickedBlock().getState();
String blockName = brewingStandMortar.getCustomName();
if(blockName == null) return;
if(blockName.equals(ChatColor.GRAY + "Basic Mortar")
|| blockName.equals(ChatColor.GRAY + "Mortar")){
player.sendMessage("DEBUG: Block is a mortar.");
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);
}
if(Mortar.isMortar(block)){
player.sendMessage("DEBUG: Block is a mortar.");
if(event.getAction() == Action.RIGHT_CLICK_BLOCK) event.setCancelled(true);
if(Shell.isShell(item)){
player.sendMessage("DEBUG: Player has a shell in hand.");
MortarHandler.fireShell(new Mortar(block), 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;
/**
* A wrapper class for a brewing stand. Represents a mortar.
*/
public class Mortar {
/**The block that represents this mortar.*/
@ -90,10 +93,38 @@ public class Mortar {
* Returns the Block that represents this mortar object
* @return Mortar as a Block
*/
public Block getBlock() {
public Block getBlock(){
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
* @param shell Shell that interacted with this mortar object
@ -103,13 +134,22 @@ public class Mortar {
* 2 for no impact explosion dud;
* 3 for catastrophic failure
*/
public int getFailureType(Shell shell){
public int getShellInteraction(Shell shell){
if(isFailure(shell)){
Random random = new Random(block.getWorld().getSeed() + System.currentTimeMillis());
double maxDouble;
maxDouble = jamChance + dudChance + catastrophicFailChance;
if(!incendiaryCompatible(shell)) maxDouble += 2*catastrophicFailChance;
double randDouble = random.nextDouble();
//TODO: compare random double and create an algo to determine type of failure.
double randDouble = random.nextDouble()*maxDouble;
if(randDouble < jamChance){
return 1;
}
else if(randDouble < (jamChance + dudChance)){
return 2;
}
else return 3;
}
else return 0;
}
@ -130,27 +170,28 @@ public class Mortar {
* @param shell Shell to test.
* @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;
}
/**
* 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){
if(block != null
return block != null
&& block.getBlockData().getMaterial() == Material.BREWING_STAND
&& isStringMortar(((Nameable)block.getState()).getCustomName())){
return true;
}
return false;
&& isStringMortar(((Nameable) block.getState()).getCustomName());
}
private static boolean isStringMortar(String string){
if(string != null
|| string.equals(BASIC_MORTAR_NAME)
if(string == null){
return false;
}
return (string.equals(BASIC_MORTAR_NAME)
|| string.equals(NORMAL_MORTAR_NAME)
|| string.equals(REINFORCED_MORTAR_NAME)
|| string.equals(INCENDIARY_CAPABLE_MORTAR_NAME)){
return true;
}
return false;
|| string.equals(INCENDIARY_CAPABLE_MORTAR_NAME));
}
}

View File

@ -13,23 +13,49 @@ import java.util.List;
*/
public class Shell {
/**
* The shell's explosive power.
* 4f represents TNT, 3f represents a creeper explosion.
*/
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;
/**
* The shell's incendiary type.
* True means this shell is capable of creating fires on impact.
*/
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;
/**
* 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 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(){
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
*/
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
* @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
* @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
*/
public void explodeShell(Location location){
location.getWorld().createExplosion(location, explosivePower, incendiaryType, true);
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));
}
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 {
Mortar mortar;
public MortarHandler(Mortar mortar){
this.mortar = mortar;
/**
* Fires a shell projectile from the specified mortar.
* @param 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.
//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.setCustomName("shell");
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)
((Player) shooter).sendMessage("DEBUG: Shell fired with a velocity " + shell.baseVelocity);
}