/*
* This file is part of Matter Overdrive
* Copyright (c) 2015., Simeon Radivoev, All rights reserved.
*
* Matter Overdrive is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Matter Overdrive is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Matter Overdrive. If not, see <http://www.gnu.org/licenses>.
*/
package matteroverdrive.items.weapon;/* Created by Simeon on 10/17/2015. */
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import matteroverdrive.MatterOverdrive;
import matteroverdrive.Reference;
import matteroverdrive.api.weapon.WeaponShot;
import matteroverdrive.client.data.Color;
import matteroverdrive.client.sound.MOPositionedSound;
import matteroverdrive.client.sound.WeaponSound;
import matteroverdrive.entity.weapon.PlasmaBolt;
import matteroverdrive.fx.PhaserBoltRecoil;
import matteroverdrive.handler.weapon.ClientWeaponHandler;
import matteroverdrive.init.MatterOverdriveItems;
import matteroverdrive.items.weapon.module.WeaponModuleBarrel;
import matteroverdrive.network.packet.server.PacketDigBlock;
import matteroverdrive.util.WeaponHelper;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.util.MathHelper;
import net.minecraft.util.MovingObjectPosition;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Vec3;
import net.minecraft.world.World;
import org.lwjgl.input.Mouse;
import org.lwjgl.util.vector.Vector2f;
import java.util.List;
public class OmniTool extends EnergyWeapon
{
private static float BLOCK_DAMAGE,STEP_SOUND_COUNTER,LAST_BRAKE_TIME;
private static int CURRENT_BLOCK_X,CURRENT_BLOCK_Y,CURRENT_BLOCK_Z,LAST_SIDE;
public static final int RANGE = 24;
private static final int MAX_USE_TIME = 240;
private static final int ENERGY_PER_SHOT = 512;
private static final float DIG_POWER_MULTIPLY = 0.007f;
public OmniTool(String name)
{
super(name,32000,128,128,RANGE);
setHarvestLevel("pickaxe",3);
setHarvestLevel("axe",3);
this.bFull3D = true;
this.leftClickFire = true;
}
@Override
public int getMaxItemUseDuration(ItemStack item)
{
return MAX_USE_TIME;
}
public int getItemEnchantability()
{
return 1;
}
@Override
public ItemStack onItemRightClick(ItemStack item, World world, EntityPlayer player)
{
this.TagCompountCheck(item);
if (canDig(item, world))
{
player.setItemInUse(item, getMaxItemUseDuration(item));
if (world.isRemote) {
stopMiningLastBlock();
}
}
if (needsRecharge(item))
{
chargeFromEnergyPack(item,player);
}
return item;
}
@Override
public void onUsingTick(ItemStack itemStack, EntityPlayer player, int count)
{
if (player.worldObj.isRemote && player.equals(Minecraft.getMinecraft().thePlayer)) {
if (canDig(itemStack, player.worldObj))
{
MovingObjectPosition movingObjectPosition = player.rayTrace(getRange(itemStack),1);
if (movingObjectPosition != null && movingObjectPosition.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK )
{
int x = movingObjectPosition.blockX;
int y = movingObjectPosition.blockY;
int z = movingObjectPosition.blockZ;
Block block = player.worldObj.getBlock(x, y, z);
boolean canMine = player.worldObj.canMineBlock(player,x,y,z) && player.isCurrentToolAdventureModeExempt(x,y,z);
if (block != null && block.getMaterial() != Material.air && canMine) {
float percent = (1-(float)count/(float)getMaxItemUseDuration(itemStack));
//MatterOverdrive.log.info("Percent %s",percent);
++STEP_SOUND_COUNTER;
LAST_SIDE = movingObjectPosition.sideHit;
if (isSameBlock(x,y,z))
{
if (BLOCK_DAMAGE >= 1.0F)
{
//this.isHittingBlock = false;
MatterOverdrive.packetPipeline.sendToServer(new PacketDigBlock(x,y,z,2,movingObjectPosition.sideHit));
Minecraft.getMinecraft().playerController.onPlayerDestroyBlock(x, y, z, movingObjectPosition.sideHit);
BLOCK_DAMAGE = 0.0F;
STEP_SOUND_COUNTER = 0.0F;
//this.blockHitDelay = 5;
}else if (BLOCK_DAMAGE == 0)
{
MatterOverdrive.packetPipeline.sendToServer(new PacketDigBlock(x,y,z,0,movingObjectPosition.sideHit));
}
BLOCK_DAMAGE = MathHelper.clamp_float(modifyStatFromModules(Reference.WS_DAMAGE,itemStack,BLOCK_DAMAGE+block.getPlayerRelativeBlockHardness(player, player.worldObj, x, y, z)),0,1);
player.worldObj.destroyBlockInWorldPartially(player.getEntityId(), x, y, z, (int)(BLOCK_DAMAGE * 10));
}else
{
stopMiningLastBlock();
setLastBlock(x,y,z);
}
}
}
}
}else
{
DrainEnergy(itemStack,DIG_POWER_MULTIPLY,false);
}
}
boolean isSameBlock(int x,int y,int z)
{
return x == CURRENT_BLOCK_X && y == CURRENT_BLOCK_Y && z == CURRENT_BLOCK_Z;
}
@SideOnly(Side.CLIENT)
void setLastBlock(int x,int y,int z)
{
CURRENT_BLOCK_X = x;
CURRENT_BLOCK_Y = y;
CURRENT_BLOCK_Z = z;
}
@Override
public void onPlayerStoppedUsing(ItemStack itemStack, World world, EntityPlayer entityPlayer, int count)
{
super.onPlayerStoppedUsing(itemStack,world,entityPlayer,count);
if (world.isRemote)
{
stopMiningLastBlock();
}
}
@SideOnly(Side.CLIENT)
private void stopMiningLastBlock()
{
BLOCK_DAMAGE = 0;
STEP_SOUND_COUNTER = 0.0F;
MatterOverdrive.packetPipeline.sendToServer(new PacketDigBlock(CURRENT_BLOCK_X, CURRENT_BLOCK_Y, CURRENT_BLOCK_Z, 1, LAST_SIDE));
}
@Override
public boolean onItemUse(ItemStack itemStack, EntityPlayer entityPlayer, World world, int x, int y, int z, int p_77648_7_, float p_77648_8_, float p_77648_9_, float p_77648_10_)
{
return false;
}
public PlasmaBolt spawnProjectile(ItemStack weapon,EntityLivingBase shooter,Vec3 position,Vec3 dir,WeaponShot shot)
{
PlasmaBolt fire = new PlasmaBolt(shooter.worldObj, shooter,position,dir, shot,getShotSpeed(weapon,shooter));
fire.setWeapon(weapon);
fire.setFireDamageMultiply(WeaponHelper.modifyStat(Reference.WS_FIRE_DAMAGE,weapon,0));
fire.setKnockBack(0.05f);
shooter.worldObj.spawnEntityInWorld(fire);
return fire;
}
@Override
@SideOnly(Side.CLIENT)
public void onClientShot(ItemStack weapon, EntityLivingBase shooter, Vec3 position, Vec3 dir,WeaponShot shot)
{
//ClientProxy.weaponHandler.addShootDelay(this);
MOPositionedSound sound = new MOPositionedSound(new ResourceLocation(Reference.MOD_ID + ":" + "laser_fire_0"),0.5f + itemRand.nextFloat() * 0.2f, 1.2f + itemRand.nextFloat() * 0.2f);
sound.setPosition((float) position.xCoord,(float)position.yCoord,(float)position.zCoord);
Minecraft.getMinecraft().getSoundHandler().playSound(sound);
spawnProjectile(weapon,shooter,position,dir,shot);
}
@Override
@SideOnly(Side.CLIENT)
public void onProjectileHit(MovingObjectPosition hit, ItemStack weapon, World world,float amount)
{
if (hit.typeOfHit == MovingObjectPosition.MovingObjectType.BLOCK && amount == 1) {
if (itemRand.nextFloat() < 0.8f)
{
Minecraft.getMinecraft().effectRenderer.addEffect(new PhaserBoltRecoil(world, hit.hitVec.xCoord, hit.hitVec.yCoord, hit.hitVec.zCoord, new Color(255, 255, 255)));
}
}
}
@Override
public float getWeaponBaseAccuracy(ItemStack weapon,boolean zoomed)
{
return 0.3f + getHeat(weapon)/getMaxHeat(weapon)*5;
}
//Dig speed
public float func_150893_a(ItemStack p_150893_1_, Block p_150893_2_)
{
return 8.0F;
}
//Can harvest block ?
@Override
public boolean func_150897_b(Block p_150897_1_)
{
return true;
}
private boolean sameToolAndBlock(int x, int y, int z)
{
return x == CURRENT_BLOCK_X && y == CURRENT_BLOCK_Y && z == CURRENT_BLOCK_Z;
}
@Override
@SideOnly(Side.CLIENT)
protected void addCustomDetails(ItemStack weapon, EntityPlayer player, List infos) {
}
@Override
protected int getBaseEnergyUse(ItemStack item) {
return ENERGY_PER_SHOT / getShootCooldown(item);
}
@Override
protected int getBaseMaxHeat(ItemStack item) {
return 80;
}
@Override
public float getWeaponBaseDamage(ItemStack weapon) {
return 7;
}
@Override
public boolean canFire(ItemStack itemStack, World world,EntityLivingBase shooter) {
return !isOverheated(itemStack) && DrainEnergy(itemStack,getShootCooldown(itemStack),true);
}
@Override
public float getShotSpeed(ItemStack weapon, EntityLivingBase shooter) {
return 3;
}
public boolean canDig(ItemStack itemStack,World world)
{
return !isOverheated(itemStack) && DrainEnergy(itemStack,DIG_POWER_MULTIPLY,true);
}
@Override
@SideOnly(Side.CLIENT)
public Vector2f getSlotPosition(int slot, ItemStack weapon) {
switch (slot)
{
case Reference.MODULE_BATTERY:
return new Vector2f(170,115);
case Reference.MODULE_COLOR:
return new Vector2f(80,40);
case Reference.MODULE_BARREL:
return new Vector2f(60,115);
case Reference.MODULE_OTHER:
return new Vector2f(200,45);
}
return new Vector2f(0,0);
}
@Override
@SideOnly(Side.CLIENT)
public Vector2f getModuleScreenPosition(int slot, ItemStack weapon) {
switch(slot)
{
case Reference.MODULE_BATTERY:
return new Vector2f(173,90);
case Reference.MODULE_COLOR:
return new Vector2f(125,72);
case Reference.MODULE_BARREL:
return new Vector2f(85,105);
}
return getSlotPosition(slot,weapon);
}
@Override
public boolean supportsModule(int slot, ItemStack weapon) {
return slot != Reference.MODULE_SIGHTS;
}
@Override
public boolean supportsModule(ItemStack weapon, ItemStack module)
{
if (module != null)
{
return module.getItem() == MatterOverdriveItems.weapon_module_color || (module.getItem() == MatterOverdriveItems.weapon_module_barrel && module.getItemDamage() != WeaponModuleBarrel.EXPLOSION_BARREL_ID && module.getItemDamage() != WeaponModuleBarrel.HEAL_BARREL_ID);
}
return false;
}
@Override
@SideOnly(Side.CLIENT)
public void onShooterClientUpdate(ItemStack itemStack, World world, EntityPlayer entityPlayer, boolean sendServerTick)
{
if (Mouse.isButtonDown(0) && hasShootDelayPassed())
{
if (canFire(itemStack, world, entityPlayer)) {
itemStack.getTagCompound().setLong("LastShot", world.getTotalWorldTime());
if (Minecraft.getMinecraft().gameSettings.thirdPersonView == 0) {
ClientWeaponHandler.RECOIL_AMOUNT = 6 + getAccuracy(itemStack, entityPlayer, isWeaponZoomed(entityPlayer, itemStack)) * 2;
ClientWeaponHandler.RECOIL_TIME = 1;
Minecraft.getMinecraft().renderViewEntity.hurtTime = 8;
Minecraft.getMinecraft().renderViewEntity.maxHurtTime = 20;
}
Vec3 dir = entityPlayer.getLook(1);
Vec3 pos = getFirePosition(entityPlayer, dir, Mouse.isButtonDown(1));
WeaponShot shot = createShot(itemStack, entityPlayer, Mouse.isButtonDown(1));
onClientShot(itemStack, entityPlayer, pos, dir, shot);
addShootDelay(itemStack);
sendShootTickToServer(world, shot, dir, pos);
return;
} else if (needsRecharge(itemStack)) {
chargeFromEnergyPack(itemStack, entityPlayer);
}
}
super.onShooterClientUpdate(itemStack,world,entityPlayer,sendServerTick);
}
@SideOnly(Side.CLIENT)
private Vec3 getFirePosition(EntityPlayer entityPlayer,Vec3 dir,boolean isAiming)
{
Vec3 pos = Vec3.createVectorHelper(entityPlayer.posX, entityPlayer.posY, entityPlayer.posZ);
if (!isAiming) {
pos.xCoord -= (double)(MathHelper.cos(entityPlayer.rotationYaw / 180.0F * (float) Math.PI) * 0.16F);
pos.zCoord -= (double)(MathHelper.sin(entityPlayer.rotationYaw / 180.0F * (float) Math.PI) * 0.16F);
pos.yCoord -= (double)(MathHelper.cos(entityPlayer.rotationPitch / 180.0F * (float) Math.PI) * 0.16F);
}
pos = pos.addVector(dir.xCoord,dir.yCoord,dir.zCoord);
return pos;
}
@Override
public boolean onServerFire(ItemStack weapon, EntityLivingBase shooter, WeaponShot shot, Vec3 position, Vec3 dir,int delay) {
DrainEnergy(weapon, getShootCooldown(weapon), false);
float newHeat = (getHeat(weapon)+4) * 2.7f;
setHeat(weapon, newHeat);
manageOverheat(weapon, shooter.worldObj, shooter);
PlasmaBolt fire = spawnProjectile(weapon,shooter,position,dir,shot);
fire.simulateDelay(delay);
weapon.getTagCompound().setLong("LastShot", shooter.worldObj.getTotalWorldTime());
return true;
}
@Override
public boolean isAlwaysEquipped(ItemStack weapon) {
return false;
}
@Override
public int getBaseShootCooldown(ItemStack itemStack) {
return 18;
}
@Override
public float getBaseZoom(ItemStack weapon, EntityLivingBase shooter)
{
return 0;
}
@SideOnly(Side.CLIENT)
@Override
public boolean isWeaponZoomed(EntityPlayer entityPlayer,ItemStack weapon)
{
return false;
}
@Override
@SideOnly(Side.CLIENT)
public WeaponSound getFireSound(ItemStack weapon, EntityLivingBase entity)
{
//return Reference.MOD_ID + ":" +"omni_tool_hum";
return new WeaponSound(new ResourceLocation(Reference.MOD_ID + ":" +"omni_tool_hum"),(float)entity.posX,(float)entity.posY,(float)entity.posZ,itemRand.nextFloat() * 0.04f + 0.06f,itemRand.nextFloat() * 0.1f + 0.95f);
}
}