diff --git a/src/main/java/com/flansmod/client/ClientProxy.java b/src/main/java/com/flansmod/client/ClientProxy.java index 3ce2e421f..21b71b0f3 100644 --- a/src/main/java/com/flansmod/client/ClientProxy.java +++ b/src/main/java/com/flansmod/client/ClientProxy.java @@ -215,6 +215,7 @@ public void registerModels(ModelRegistryEvent event) ModelLoader.setCustomModelResourceLocation(Item.getItemFromBlock(FlansMod.paintjobTable), 0, new ModelResourceLocation("flansmod:paintjobTable", "inventory")); ModelLoader.registerItemVariants(Item.getItemFromBlock(FlansMod.paintjobTable), new ResourceLocation("flansmod:paintjobTable")); + ModelLoader.setCustomModelResourceLocation(FlansMod.crosshairsymbol, 0, new ModelResourceLocation("flansmod:crosshairsymbol", "inventory")); } /** diff --git a/src/main/java/com/flansmod/client/ClientRenderHooks.java b/src/main/java/com/flansmod/client/ClientRenderHooks.java index 92121e8df..bd236c43a 100644 --- a/src/main/java/com/flansmod/client/ClientRenderHooks.java +++ b/src/main/java/com/flansmod/client/ClientRenderHooks.java @@ -921,8 +921,9 @@ private void renderKillMessages(int i, int j) { for(KillMessage killMessage : killMessages) { - mc.fontRenderer.drawString("\u00a7" + killMessage.killerName + " " + "\u00a7" + killMessage.killedName, - i - mc.fontRenderer.getStringWidth(killMessage.killerName + " " + killMessage.killedName) - 6, + String message = "\u00a7" + killMessage.killerName + (killMessage.headshot ? " ":" ") + "\u00a7" + killMessage.killedName; + mc.fontRenderer.drawString(message, + i - mc.fontRenderer.getStringWidth(message) - 6, j - 32 - killMessage.line * 16, 0xffffff); } @@ -935,10 +936,14 @@ private void renderKillMessages(int i, int j) for(KillMessage killMessage : killMessages) { drawSlotInventory(mc.fontRenderer, new ItemStack(killMessage.weapon.item, 1, killMessage.paint), - i - mc.fontRenderer.getStringWidth(" " + killMessage.killedName) - 12, + i - mc.fontRenderer.getStringWidth((killMessage.headshot ? " ":" ") + killMessage.killedName), + j - 36 - killMessage.line * 16); + if (killMessage.headshot) + drawSlotInventory(mc.fontRenderer, new ItemStack(FlansMod.crosshairsymbol), + i - mc.fontRenderer.getStringWidth(" " + killMessage.killedName), j - 36 - killMessage.line * 16); } - GL11.glDisable(3042 /*GL_BLEND*/); + GL11.glDisable(GL11.GL_BLEND); RenderHelper.disableStandardItemLighting(); } @@ -1022,6 +1027,6 @@ public KillMessage(boolean head, InfoType infoType, String killer, String killed public int paint = 0; public int timer = 0; public int line = 0; - public boolean headshot = false; + public boolean headshot; } } diff --git a/src/main/java/com/flansmod/common/FlansMod.java b/src/main/java/com/flansmod/common/FlansMod.java index 62d53cca9..e1d189151 100644 --- a/src/main/java/com/flansmod/common/FlansMod.java +++ b/src/main/java/com/flansmod/common/FlansMod.java @@ -170,6 +170,7 @@ public class FlansMod public static ItemBlockManyNames spawnerItem; public static ItemOpStick opStick; public static ItemFlagpole flag; + public static Item crosshairsymbol; public static ArrayList partItems = new ArrayList<>(); public static ArrayList mechaItems = new ArrayList<>(); public static ArrayList toolItems = new ArrayList<>(); @@ -240,7 +241,7 @@ public void preInit(FMLPreInitializationEvent event) paintjobTable = new BlockPaintjobTable(); workbenchItem = new ItemBlockManyNames(workbench); spawnerItem = new ItemBlockManyNames(spawner); - + crosshairsymbol = new Item().setTranslationKey("crosshairsymbol").setRegistryName("crosshairsymbol"); GameRegistry.registerTileEntity(TileEntitySpawner.class, new ResourceLocation("flansmod:teamsSpawner")); GameRegistry.registerTileEntity(TileEntityPaintjobTable.class, new ResourceLocation("flansmod:paintjobTable")); @@ -350,6 +351,7 @@ public void registerItems(RegistryEvent.Register event) event.getRegistry().register(workbenchItem); event.getRegistry().register(spawnerItem); + event.getRegistry().register(crosshairsymbol); } @SubscribeEvent diff --git a/src/main/java/com/flansmod/common/FlansModExplosion.java b/src/main/java/com/flansmod/common/FlansModExplosion.java index 521ef4841..78aced6fa 100644 --- a/src/main/java/com/flansmod/common/FlansModExplosion.java +++ b/src/main/java/com/flansmod/common/FlansModExplosion.java @@ -2,6 +2,7 @@ import java.util.List; import java.util.Map; +import java.util.Optional; import java.util.Random; import java.util.Set; @@ -30,7 +31,7 @@ import net.minecraft.world.World; import net.minecraftforge.event.ForgeEventFactory; -import com.flansmod.common.guns.EntityDamageSourceGun; +import com.flansmod.common.guns.EntityDamageSourceFlan; import com.flansmod.common.teams.TeamsManager; import com.flansmod.common.types.InfoType; @@ -42,7 +43,7 @@ public class FlansModExplosion extends Explosion private final Random random; private final World world; private final double x, y, z; - private final EntityLivingBase detonator; + private final Optional player; private final Entity explosive; private final float size; private final List affectedBlockPositions; @@ -50,14 +51,14 @@ public class FlansModExplosion extends Explosion private final Vec3d position; private final InfoType type; // type of Flan's Mod weapon causing explosion - public FlansModExplosion(World world, Entity entity, EntityLivingBase detonator, InfoType type, double x, double y, double z, float size, boolean causesFire, boolean smoking, boolean breaksBlocks) + public FlansModExplosion(World world, Entity entity, Optional player, InfoType type, double x, double y, double z, float size, boolean causesFire, boolean smoking, boolean breaksBlocks) { super(world, entity, x, y, z, size, causesFire, smoking); this.random = new Random(); this.affectedBlockPositions = Lists.newArrayList(); this.playerKnockbackMap = Maps.newHashMap(); this.world = world; - this.detonator = detonator; + this.player = player; this.size = size; this.x = x; this.y = y; @@ -168,9 +169,9 @@ public void doExplosionA() d9 /= d13; double d14 = (double)this.world.getBlockDensity(vec3d, entity.getEntityBoundingBox()); double d10 = (1.0D - d12) * d14; - if(detonator instanceof EntityPlayer) + if(player.isPresent()) { - entity.attackEntityFrom(new EntityDamageSourceGun(type.shortName, explosive, (EntityPlayer)detonator, type, false), + entity.attackEntityFrom(new EntityDamageSourceFlan(type.shortName, explosive, player.get(), type), (float)((int)((d10 * d10 + d10) / 2.0D * 7.0D * (double)f3 + 1.0D))); } else { entity.attackEntityFrom(DamageSource.causeExplosionDamage(this), (float)((int)((d10 * d10 + d10) / 2.0D * 7.0D * (double)f3 + 1.0D))); @@ -275,15 +276,6 @@ public Map getPlayerKnockbackMap() return this.playerKnockbackMap; } - /** - * Returns either the entity that placed the explosive block, the entity that caused the explosion or null. - */ - @Override - public EntityLivingBase getExplosivePlacedBy() - { - return detonator; - } - @Override public void clearAffectedBlockPositions() { diff --git a/src/main/java/com/flansmod/common/driveables/mechas/EntityMecha.java b/src/main/java/com/flansmod/common/driveables/mechas/EntityMecha.java index 448b6fca3..702c09c1e 100644 --- a/src/main/java/com/flansmod/common/driveables/mechas/EntityMecha.java +++ b/src/main/java/com/flansmod/common/driveables/mechas/EntityMecha.java @@ -1,14 +1,13 @@ package com.flansmod.common.driveables.mechas; import java.util.ArrayList; +import java.util.Optional; import io.netty.buffer.ByteBuf; import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.block.state.IBlockState; -import net.minecraft.client.Minecraft; import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLiving; import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.MoverType; import net.minecraft.entity.item.EntityItem; @@ -46,20 +45,21 @@ import com.flansmod.common.driveables.EntitySeat; import com.flansmod.common.driveables.EnumDriveablePart; import com.flansmod.common.guns.BulletType; +import com.flansmod.common.guns.EntityGrenade; import com.flansmod.common.guns.EnumFireMode; import com.flansmod.common.guns.FireableGun; import com.flansmod.common.guns.FiredShot; +import com.flansmod.common.guns.GrenadeType; import com.flansmod.common.guns.GunType; import com.flansmod.common.guns.InventoryHelper; import com.flansmod.common.guns.ItemBullet; +import com.flansmod.common.guns.ItemGrenade; import com.flansmod.common.guns.ItemGun; import com.flansmod.common.guns.ItemShootable; import com.flansmod.common.guns.ShootableType; import com.flansmod.common.guns.ShotHandler; import com.flansmod.common.network.PacketDriveableDamage; import com.flansmod.common.network.PacketDriveableGUI; -import com.flansmod.common.network.PacketDriveableKey; -import com.flansmod.common.network.PacketGunAnimation; import com.flansmod.common.network.PacketMechaControl; import com.flansmod.common.network.PacketPlaySound; import com.flansmod.common.teams.TeamsManager; @@ -335,7 +335,7 @@ else if(heldItem instanceof ItemGun) gunItem.Reload(heldStack, world, this, driveableData, left ? EnumHand.MAIN_HAND : EnumHand.OFF_HAND, true, true, (infiniteAmmo() || creative())); } //A bullet stack was found, so try shooting with it - else if(bulletStack.getItem() instanceof ItemBullet) + else if(bulletStack.getItem() instanceof ItemBullet || bulletStack.getItem() instanceof ItemGrenade) { //Shoot shoot(heldStack, gunType, bulletStack, creative(), left); @@ -391,10 +391,22 @@ private void shoot(ItemStack stack, GunType gunType, ItemStack bulletStack, bool if(!world.isRemote) { ShootableType shootableType = ((ItemShootable)bulletStack.getItem()).type; - FireableGun fireableGun = new FireableGun(gunType, gunType.getDamage(stack), gunType.getSpread(stack), gunType.getBulletSpeed(stack)); - //TODO unchecked cast, grenades will cause an error - FiredShot shot = new FiredShot(fireableGun, (BulletType)shootableType, this, (EntityPlayerMP) getDriver()); - ShotHandler.fireGun(world, shot, gunType.numBullets*bulletType.numBullets, bulletOrigin, armVector); + if (shootableType instanceof BulletType) + { + FireableGun fireableGun = new FireableGun(gunType, gunType.getDamage(stack), gunType.getSpread(stack), gunType.getBulletSpeed(stack)); + FiredShot shot = new FiredShot(fireableGun, (BulletType)shootableType, this, (EntityPlayerMP) getDriver()); + ShotHandler.fireGun(world, shot, gunType.numBullets*bulletType.numBullets, bulletOrigin, armVector); + } + else if (shootableType instanceof GrenadeType) + { + double yaw = Math.atan2(armVector.z, armVector.x); + double pitch = Math.atan2(Math.sqrt(armVector.z * armVector.z + armVector.x * armVector.x), armVector.y) - Math.PI/2; + Optional ent = Optional.of(this); + Optional player = Optional.of(getDriver()); + + EntityGrenade grenade = new EntityGrenade(world, bulletOrigin, (GrenadeType) shootableType, (float)Math.toDegrees(pitch), (float)Math.toDegrees(yaw + Math.PI*1.5), player, ent); + world.spawnEntity(grenade); + } } if(left) diff --git a/src/main/java/com/flansmod/common/eventhandlers/PlayerDeathEventListener.java b/src/main/java/com/flansmod/common/eventhandlers/PlayerDeathEventListener.java index c8080fd85..490123aaa 100644 --- a/src/main/java/com/flansmod/common/eventhandlers/PlayerDeathEventListener.java +++ b/src/main/java/com/flansmod/common/eventhandlers/PlayerDeathEventListener.java @@ -8,8 +8,7 @@ import com.flansmod.common.FlansMod; import com.flansmod.common.PlayerHandler; -import com.flansmod.common.guns.EntityBullet; -import com.flansmod.common.guns.EntityGrenade; +import com.flansmod.common.guns.EntityDamageSourceFlan; import com.flansmod.common.network.PacketKillMessage; import com.flansmod.common.teams.Team; @@ -24,49 +23,18 @@ public PlayerDeathEventListener() @SubscribeEvent public void PlayerDied(LivingDeathEvent event) { - if((event.getSource().getDamageType().equalsIgnoreCase("explosion") && - ((event.getSource().getTrueSource() instanceof EntityGrenade) || (event.getSource().getTrueSource() instanceof EntityBullet))) - && event.getEntityLiving() instanceof EntityPlayer) + if (event.getEntity().world.isRemote) + return; + + if (event.getSource() instanceof EntityDamageSourceFlan && event.getEntity() instanceof EntityPlayer) { - boolean isGrenade; - if(event.getSource().getTrueSource() instanceof EntityGrenade) - { - isGrenade = true; - } - else - { - isGrenade = false; - } - EntityPlayer killer = null; - EntityPlayer killed = (EntityPlayer)event.getEntityLiving(); - Team killerTeam = null; - Team killedTeam = null; - if(isGrenade) - { - killer = (EntityPlayer)((EntityGrenade)event.getSource().getTrueSource()).thrower; - } - else - { - killer = (EntityPlayer)((EntityBullet)event.getSource().getTrueSource()).getFiredShot().getPlayerOptional().orElse(null); - } - killerTeam = PlayerHandler.getPlayerData(killer).team; - killedTeam = PlayerHandler.getPlayerData(killed).team; - if(event.getEntityLiving() instanceof EntityPlayer && !isGrenade) - { - FlansMod.getPacketHandler().sendToDimension( - new PacketKillMessage(false, ((EntityBullet)event.getSource().getTrueSource()).getFiredShot().getBulletType(), - (killedTeam == null ? "f" : killedTeam.textColour) + event.getEntity().getDisplayName().getFormattedText(), - (killerTeam == null ? "f" : killedTeam.textColour) + event.getSource().getTrueSource().getDisplayName().getFormattedText()), - event.getEntityLiving().dimension); - } - if(event.getEntityLiving() instanceof EntityPlayer && isGrenade) - { - FlansMod.getPacketHandler().sendToDimension( - new PacketKillMessage(false, ((EntityGrenade)event.getSource().getTrueSource()).type, - (killedTeam == null ? "f" : killedTeam.textColour) + event.getEntity().getDisplayName().getFormattedText(), - (killerTeam == null ? "f" : killedTeam.textColour) + event.getSource().getTrueSource().getDisplayName().getFormattedText()), - event.getEntityLiving().dimension); - } + EntityDamageSourceFlan source = (EntityDamageSourceFlan) event.getSource(); + EntityPlayer died = (EntityPlayer) event.getEntity(); + + Team killedTeam = PlayerHandler.getPlayerData(died).team; + Team killerTeam = PlayerHandler.getPlayerData(source.getCausedPlayer()).team; + + FlansMod.getPacketHandler().sendToDimension(new PacketKillMessage(source.isHeadshot(), source.getWeapon(), (killedTeam == null ? "f" : killedTeam.textColour) + died.getName(), (killerTeam == null ? "f" : killerTeam.textColour) + source.getCausedPlayer().getName()), died.dimension); } } } diff --git a/src/main/java/com/flansmod/common/guns/EntityDamageSourceFlan.java b/src/main/java/com/flansmod/common/guns/EntityDamageSourceFlan.java new file mode 100644 index 000000000..27c6b295c --- /dev/null +++ b/src/main/java/com/flansmod/common/guns/EntityDamageSourceFlan.java @@ -0,0 +1,78 @@ +package com.flansmod.common.guns; + +import com.flansmod.common.PlayerHandler; +import com.flansmod.common.types.InfoType; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.util.EntityDamageSourceIndirect; +import net.minecraft.util.text.ITextComponent; +import net.minecraft.util.text.TextComponentString; + +public class EntityDamageSourceFlan extends EntityDamageSourceIndirect{ + + private InfoType weapon; + private EntityPlayer shooter; + private boolean headshot; + /** + * @param s Name of the damage source (Usually the shortName of the gun) + * @param entity The Entity causing the damage (e.g. Grenade). Can be the same as 'player' + * @param player The Player responsible for the damage + * @param wep The InfoType of weapon used + */ + public EntityDamageSourceFlan(String s, Entity entity, EntityPlayer player, InfoType wep) + { + this(s, entity, player, wep, false); + } + + /** + * @param s Name of the damage source (Usually the shortName of the gun) + * @param entity The Entity causing the damage (e.g. Grenade). Can be the same as 'player' + * @param player The Player responsible for the damage + * @param wep The InfoType of weapon used + * @param headshot True if this was a headshot, false if not + */ + public EntityDamageSourceFlan(String s, Entity entity, EntityPlayer player, InfoType wep, boolean headshot) + { + super(s, entity, player); + weapon = wep; + shooter = player; + this.headshot = headshot; + } + + @Override + public ITextComponent getDeathMessage(EntityLivingBase living) + { + if(!(living instanceof EntityPlayer) || shooter == null || PlayerHandler.getPlayerData(shooter) == null) + { + return super.getDeathMessage(living); + } + + return new TextComponentString("#flansmod"); + } + + /** + * @return The weapon (InfoType) used to cause this damage + */ + public InfoType getWeapon() + { + return weapon; + } + + /** + * @return The Player responsible for this damage + */ + public EntityPlayer getCausedPlayer() + { + return shooter; + } + + /** + * @return True if this is a headshot, false if not + */ + public boolean isHeadshot() + { + return headshot; + } +} diff --git a/src/main/java/com/flansmod/common/guns/EntityDamageSourceGun.java b/src/main/java/com/flansmod/common/guns/EntityDamageSourceGun.java deleted file mode 100644 index e2ffb88e1..000000000 --- a/src/main/java/com/flansmod/common/guns/EntityDamageSourceGun.java +++ /dev/null @@ -1,53 +0,0 @@ -package com.flansmod.common.guns; - -import net.minecraft.entity.Entity; -import net.minecraft.entity.EntityLivingBase; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.util.EntityDamageSourceIndirect; -import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.TextComponentString; - -import com.flansmod.common.FlansMod; -import com.flansmod.common.PlayerHandler; -import com.flansmod.common.network.PacketKillMessage; -import com.flansmod.common.teams.Team; -import com.flansmod.common.types.InfoType; - -public class EntityDamageSourceGun extends EntityDamageSourceIndirect -{ - - public InfoType weapon; - public EntityPlayer shooter; - public boolean headshot; - - public EntityDamageSourceGun(String s, Entity entity, EntityPlayer player, InfoType wep, boolean head) - { - super(s, entity, player); - weapon = wep; - shooter = player; - headshot = head; - } - - @Override - public Entity getTrueSource() - { - return shooter; - } - - @Override - public ITextComponent getDeathMessage(EntityLivingBase living) - { - if(!(living instanceof EntityPlayer) || shooter == null || PlayerHandler.getPlayerData(shooter) == null) - { - return super.getDeathMessage(living); - } - EntityPlayer player = (EntityPlayer)living; - - Team killedTeam = PlayerHandler.getPlayerData(player).team; - Team killerTeam = PlayerHandler.getPlayerData(shooter).team; - - FlansMod.getPacketHandler().sendToDimension(new PacketKillMessage(headshot, weapon, (killedTeam == null ? "f" : killedTeam.textColour) + player.getName(), (killerTeam == null ? "f" : killerTeam.textColour) + shooter.getName()), living.dimension); - - return new TextComponentString("#flansmod");//flanDeath." + weapon.shortName + "." + (killedTeam == null ? "f" : killedTeam.textColour) + player.getCommandSenderName() + "." + (killerTeam == null ? "f" : killerTeam.textColour) + shooter.getCommandSenderName()); - } -} diff --git a/src/main/java/com/flansmod/common/guns/EntityGrenade.java b/src/main/java/com/flansmod/common/guns/EntityGrenade.java index 5b73d32ca..2a0048c53 100644 --- a/src/main/java/com/flansmod/common/guns/EntityGrenade.java +++ b/src/main/java/com/flansmod/common/guns/EntityGrenade.java @@ -1,9 +1,9 @@ package com.flansmod.common.guns; import java.util.List; +import java.util.Optional; import io.netty.buffer.ByteBuf; -import net.minecraft.block.Block; import net.minecraft.block.material.Material; import net.minecraft.client.particle.Particle; import net.minecraft.entity.Entity; @@ -16,12 +16,13 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.potion.PotionEffect; import net.minecraft.util.DamageSource; -import net.minecraft.util.EntityDamageSourceIndirect; +import net.minecraft.util.EntityDamageSource; import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumHand; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.RayTraceResult; +import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; import net.minecraft.world.WorldServer; import net.minecraftforge.fml.common.network.ByteBufUtils; @@ -32,7 +33,6 @@ import com.flansmod.client.handlers.FlansModResourceHandler; import com.flansmod.common.FlansMod; import com.flansmod.common.FlansModExplosion; -import com.flansmod.common.PlayerHandler; import com.flansmod.common.RotatedAxes; import com.flansmod.common.driveables.EntityDriveable; import com.flansmod.common.network.PacketFlak; @@ -41,17 +41,23 @@ import com.flansmod.common.teams.Team; import com.flansmod.common.teams.TeamsManager; import com.flansmod.common.types.InfoType; +import com.flansmod.common.util.BlockUtil; import com.flansmod.common.vector.Vector3f; -import static com.flansmod.common.util.BlockUtil.destroyBlock; - public class EntityGrenade extends EntityShootable implements IEntityAdditionalSpawnData { public GrenadeType type; + /** - * The entity that threw them + * Contains the player who is responsible for the thrown grenade */ - public EntityLivingBase thrower; + private Optional player = Optional.empty(); + + /** + * The Entity who has thrown the grenade + */ + private Optional thrower = Optional.empty(); + /** * This is to avoid players grenades teamkilling after they switch team */ @@ -92,22 +98,26 @@ public EntityGrenade(World w) super(w); } - public EntityGrenade(World w, GrenadeType g, EntityLivingBase t) + /** + * General constructor. Example usecase: grenades spawned via console command + * + * @param w World in which the grenade will spawn in + * @param pos Position the grenade will spawn at + * @param g GrenadeType of the grenade + * @param rotationPitch Pitch of the direction the grenade will fly + * @param rotationYaw Yaw of the direction the grenade will fly + */ + public EntityGrenade(World w, Vector3f pos, GrenadeType g, float rotationPitch, float rotationYaw) { this(w); - setPosition(t.posX, t.posY + t.getEyeHeight(), t.posZ); + setPosition(pos.getX(), pos.getY(), pos.getZ()); type = g; numUsesRemaining = type.numUses; - thrower = t; - if(thrower instanceof EntityPlayer && PlayerHandler.getPlayerData((EntityPlayer)thrower) != null) - { - teamOfThrower = PlayerHandler.getPlayerData((EntityPlayer)thrower).team; - } setSize(g.hitBoxSize, g.hitBoxSize); - //Set the grenade to be facing the way the player is looking - axes.setAngles(t.rotationYaw + 90F, g.spinWhenThrown ? t.rotationPitch : 0F, 0F); - rotationYaw = prevRotationYaw = g.spinWhenThrown ? t.rotationYaw + 90F : 0F; - rotationPitch = prevRotationPitch = t.rotationPitch; + //Set the grenade to be facing the way the Pitch and Yaw variables define + axes.setAngles(rotationYaw + 90F, g.spinWhenThrown ? rotationPitch : 0F, 0F); + this.rotationYaw = prevRotationYaw = g.spinWhenThrown ? rotationYaw + 90F : 0F; + this.rotationPitch = prevRotationPitch = rotationPitch; //Give the grenade velocity in the direction the player is looking float speed = 0.5F * type.throwSpeed; motionX = axes.getXAxis().x * speed; @@ -119,6 +129,49 @@ public EntityGrenade(World w, GrenadeType g, EntityLivingBase t) PacketPlaySound.sendSoundPacket(posX, posY, posZ, FlansMod.soundRange, dimension, type.throwSound, true); } + /** + * General constructor for entitys throwing grenades. This should not be used when a player throws the grenade + * + * @param entity Entity throwing the grenade + * @param g GrenadeType of the grenade + */ + public EntityGrenade(EntityLivingBase entity, GrenadeType g) + { + this(entity.world, new Vector3f(entity.getPositionVector().add(new Vec3d(0, entity.getEyeHeight(), 0))), g, entity.rotationPitch, entity.rotationYaw); + this.thrower = Optional.of(entity); + } + + /** + * When a player throws a grenade directly this constructor should be used + * + * @param player Player throwing the grenade + * @param g GrenadeType of the grenade + */ + public EntityGrenade(EntityPlayer player, GrenadeType g) + { + this((EntityLivingBase)player, g); + this.player = Optional.of(player); + } + + /** + * Constructor for grenades thrown where a player and/or a entity can be associated with. + * E.g. mecha using a grenade launcher. In this case the 'entity' is the mecha and the 'player' the player controlling the mecha + * + * @param w World in which the grenade will spawn in + * @param pos Position the grenade will spawn at + * @param g GrenadeType of the grenade + * @param rotationPitch Pitch of the direction the grenade will fly + * @param rotationYaw Yaw of the direction the grenade will fly + * @param player The player that is responsible for throwing the grenade + * @param entity The entity throwing the grenade. Can be the same as 'player' + */ + public EntityGrenade(World w, Vector3f pos, GrenadeType g, float rotationPitch, float rotationYaw, Optional player, Optional entity) + { + this(w, pos, g, rotationPitch, rotationYaw); + this.thrower = entity; + this.player = player; + } + @Override public void onUpdate() { @@ -159,7 +212,7 @@ public void onUpdate() //Send flak packet to spawn particles FlansMod.getPacketHandler().sendToAllAround(new PacketFlak(posX, posY, posZ, 50, type.smokeParticleType), posX, posY, posZ, 30, dimension); // - List list = world.getEntitiesWithinAABB(EntityLivingBase.class, getEntityBoundingBox().expand(type.smokeRadius, type.smokeRadius, type.smokeRadius)); + List list = world.getEntitiesWithinAABB(EntityLivingBase.class, getEntityBoundingBox().expand(type.smokeRadius, type.smokeRadius, type.smokeRadius)); for(Object obj : list) { EntityLivingBase entity = ((EntityLivingBase)obj); @@ -198,7 +251,7 @@ public void onUpdate() if(type.livingProximityTrigger > 0 || type.driveableProximityTrigger > 0) { float checkRadius = Math.max(type.livingProximityTrigger, type.driveableProximityTrigger); - List list = world.getEntitiesWithinAABBExcludingEntity(this, getEntityBoundingBox().expand(checkRadius, checkRadius, checkRadius)); + List list = world.getEntitiesWithinAABBExcludingEntity(this, getEntityBoundingBox().expand(checkRadius, checkRadius, checkRadius)); for(Object obj : list) { if(obj == thrower && ticksExisted < 10) @@ -206,9 +259,9 @@ public void onUpdate() if(obj instanceof EntityLivingBase && getDistanceSq((Entity)obj) < type.livingProximityTrigger * type.livingProximityTrigger) { //If we are in a gametype and both thrower and triggerer are playing, check for friendly fire - if(TeamsManager.getInstance() != null && TeamsManager.getInstance().currentRound != null && obj instanceof EntityPlayerMP && thrower instanceof EntityPlayer) + if(TeamsManager.getInstance() != null && TeamsManager.getInstance().currentRound != null && obj instanceof EntityPlayerMP && player.isPresent()) { - if(!TeamsManager.getInstance().currentRound.gametype.playerAttacked((EntityPlayerMP)obj, new EntityDamageSourceGun(type.shortName, this, (EntityPlayer)thrower, type, false))) + if(!TeamsManager.getInstance().currentRound.gametype.playerAttacked((EntityPlayerMP)obj, new EntityDamageSourceFlan(type.shortName, this, player.get(), type))) continue; } if(type.damageToTriggerer > 0) @@ -249,8 +302,7 @@ public void onUpdate() //If we hit block if(hit != null && hit.typeOfHit == RayTraceResult.Type.BLOCK) { - //Get the blockID and block material - Block block = world.getBlockState(hit.getBlockPos()).getBlock(); + //Get block material Material mat = world.getBlockState(hit.getBlockPos()).getMaterial(); //If this grenade detonates on impact, do so @@ -263,7 +315,7 @@ else if(type.breaksGlass && mat == Material.GLASS && TeamsManager.canBreakGlass) if(!world.isRemote) { WorldServer worldServer = (WorldServer)world; - destroyBlock(worldServer, hit.getBlockPos(), thrower, false); + BlockUtil.destroyBlock(worldServer, hit.getBlockPos(), player.orElse(null), false); } } @@ -385,9 +437,15 @@ else if(!type.penetratesBlocks) if(type.stickToThrower) { - if(thrower == null || thrower.isDead) + if (!thrower.isPresent() || thrower.get().isDead || !(thrower.get() instanceof EntityLivingBase)) + { setDead(); - else setPosition(thrower.posX, thrower.posY, thrower.posZ); + } + else + { + EntityLivingBase entity = (EntityLivingBase) thrower.get(); + setPosition(entity.posX, entity.posY, entity.posZ); + } } //If throwing this grenade at an entity should hurt them, this bit checks for entities in the way and does so @@ -395,7 +453,7 @@ else if(!type.penetratesBlocks) if(type.damageVsLiving > 0 && !stuck) { Vector3f motVec = new Vector3f(motionX, motionY, motionZ); - List list = world.getEntitiesWithinAABBExcludingEntity(this, getEntityBoundingBox()); + List list = world.getEntitiesWithinAABBExcludingEntity(this, getEntityBoundingBox()); for(Object obj : list) { if(obj == thrower && ticksExisted < 10 || motVec.lengthSquared() < 0.01D) @@ -438,7 +496,7 @@ public void detonate() //Explode if(!world.isRemote && type.explosionRadius > 0.1F) { - new FlansModExplosion(world, this, thrower, type, posX, posY, posZ, type.explosionRadius, type.fireRadius > 0, type.smokeRadius > 0, type.explosionBreaksBlocks); + new FlansModExplosion(world, this, player, type, posX, posY, posZ, type.explosionRadius, type.fireRadius > 0, type.smokeRadius > 0, type.explosionBreaksBlocks); } //Make fire @@ -514,9 +572,11 @@ public void setPositionAndRotationDirect(double x, double y, double z, float yaw private DamageSource getGrenadeDamage() { - if(thrower instanceof EntityPlayer) - return (new EntityDamageSourceGun(type.shortName, this, (EntityPlayer)thrower, type, false)).setProjectile(); - else return (new EntityDamageSourceIndirect(type.shortName, this, thrower)).setProjectile(); + if (player.isPresent()) + { + return new EntityDamageSourceFlan(type.shortName, this, player.get(), type).setProjectile(); + } + return new EntityDamageSource(type.shortName, this).setProjectile(); } @Override @@ -529,7 +589,7 @@ protected void entityInit() protected void readEntityFromNBT(NBTTagCompound tags) { type = GrenadeType.getGrenade(tags.getString("Type")); - thrower = world.getPlayerEntityByName(tags.getString("Thrower")); + player = Optional.ofNullable(world.getPlayerEntityByName(tags.getString("Player"))); rotationYaw = tags.getFloat("RotationYaw"); rotationPitch = tags.getFloat("RotationPitch"); axes.setAngles(rotationYaw, rotationPitch, 0F); @@ -543,8 +603,8 @@ protected void writeEntityToNBT(NBTTagCompound tags) else { tags.setString("Type", type.shortName); - if(thrower != null) - tags.setString("Thrower", thrower.getName()); + if(player.isPresent()) + tags.setString("Player", player.get().getName()); tags.setFloat("RotationYaw", axes.getYaw()); tags.setFloat("RotationPitch", axes.getPitch()); } @@ -554,7 +614,8 @@ protected void writeEntityToNBT(NBTTagCompound tags) public void writeSpawnData(ByteBuf data) { ByteBufUtils.writeUTF8String(data, type.shortName); - data.writeInt(thrower == null ? 0 : thrower.getEntityId()); + data.writeInt(player.isPresent() ? player.get().getEntityId() : -1); + data.writeInt(thrower.isPresent() ? thrower.get().getEntityId() : -1); data.writeFloat(axes.getYaw()); data.writeFloat(axes.getPitch()); } @@ -563,7 +624,11 @@ public void writeSpawnData(ByteBuf data) public void readSpawnData(ByteBuf data) { type = GrenadeType.getGrenade(ByteBufUtils.readUTF8String(data)); - thrower = (EntityLivingBase)world.getEntityByID(data.readInt()); + { + Entity ent = world.getEntityByID(data.readInt()); + player = ent instanceof EntityPlayer ? Optional.of((EntityPlayer) ent) : Optional.empty(); + } + thrower = Optional.ofNullable(world.getEntityByID(data.readInt())); setRotation(data.readFloat(), data.readFloat()); prevRotationYaw = rotationYaw; prevRotationPitch = rotationPitch; diff --git a/src/main/java/com/flansmod/common/guns/FiredShot.java b/src/main/java/com/flansmod/common/guns/FiredShot.java index 2812c0178..d7fd71614 100644 --- a/src/main/java/com/flansmod/common/guns/FiredShot.java +++ b/src/main/java/com/flansmod/common/guns/FiredShot.java @@ -112,7 +112,7 @@ public DamageSource getDamageSource() public DamageSource getDamageSource(Boolean headshot) { if (player.isPresent()) { - return new EntityDamageSourceGun(weapon.getShortName(), player.get(), player.get(), weapon.getInfoType(), headshot); + return new EntityDamageSourceFlan(weapon.getShortName(), player.get(), player.get(), weapon.getInfoType(), headshot); } return DamageSource.GENERIC; } diff --git a/src/main/java/com/flansmod/common/guns/ItemGrenade.java b/src/main/java/com/flansmod/common/guns/ItemGrenade.java index 76c4b0436..49e2933cf 100644 --- a/src/main/java/com/flansmod/common/guns/ItemGrenade.java +++ b/src/main/java/com/flansmod/common/guns/ItemGrenade.java @@ -72,7 +72,7 @@ public ActionResult onItemRightClick(World world, EntityPlayer player //Delay the next throw / weapon fire / whatnot data.shootTimeRight = type.throwDelay; //Create a new grenade entity - EntityGrenade grenade = new EntityGrenade(world, type, player); + EntityGrenade grenade = new EntityGrenade(player, this.type); //Spawn the entity server side if(!world.isRemote) world.spawnEntity(grenade); @@ -106,10 +106,10 @@ public InfoType getInfoType() return type; } - public EntityGrenade getGrenade(World world, EntityLivingBase thrower) + private EntityGrenade getGrenade(World world, EntityLivingBase thrower) { //Create a new grenade entity - EntityGrenade grenade = new EntityGrenade(world, type, thrower); + EntityGrenade grenade = new EntityGrenade(thrower, type); //If this can be remotely detonated, add it to the players detonate list if(type.remote && thrower instanceof EntityPlayer) PlayerHandler.getPlayerData((EntityPlayer)thrower).remoteExplosives.add(grenade); diff --git a/src/main/java/com/flansmod/common/guns/ItemGun.java b/src/main/java/com/flansmod/common/guns/ItemGun.java index 0041e0621..4608b0628 100644 --- a/src/main/java/com/flansmod/common/guns/ItemGun.java +++ b/src/main/java/com/flansmod/common/guns/ItemGun.java @@ -1074,7 +1074,7 @@ public boolean getShareTag() public DamageSource getMeleeDamage(EntityPlayer attacker) { - return new EntityDamageSourceGun(type.shortName, attacker, attacker, type, false); + return new EntityDamageSourceFlan(type.shortName, attacker, attacker, type); } private boolean isSolid(World world, int i, int j, int k) diff --git a/src/main/java/com/flansmod/common/guns/ShotHandler.java b/src/main/java/com/flansmod/common/guns/ShotHandler.java index de5bf637e..8f7174908 100644 --- a/src/main/java/com/flansmod/common/guns/ShotHandler.java +++ b/src/main/java/com/flansmod/common/guns/ShotHandler.java @@ -191,15 +191,12 @@ else if(bulletHit instanceof PlayerBulletHit) TeamsRound round; if(TeamsManager.getInstance() != null && (round = TeamsManager.getInstance().currentRound) != null) { - if (round != null) - { - Optional shooterTeam = round.getTeam(player); - Optional victimTeam = round.getTeam(playerHit.hitbox.player); + Optional shooterTeam = round.getTeam(player); + Optional victimTeam = round.getTeam(playerHit.hitbox.player); - if (!shooterTeam.isPresent() || !victimTeam.isPresent() || !shooterTeam.get().equals(victimTeam.get())) - { - FlansMod.getPacketHandler().sendTo(new PacketHitMarker(), player); - } + if (!shooterTeam.isPresent() || !victimTeam.isPresent() || !shooterTeam.get().equals(victimTeam.get())) + { + FlansMod.getPacketHandler().sendTo(new PacketHitMarker(), player); } } else // No teams mod, just add marker @@ -299,7 +296,7 @@ public static void onDetonate(World world, FiredShot shot, Vector3f detonatePos) if(bulletType.explosionRadius > 0) { - new FlansModExplosion(world, shot.getShooterOptional().orElse(null), shot.getPlayerOptional().orElse(null), bulletType, + new FlansModExplosion(world, shot.getShooterOptional().orElse(null), shot.getPlayerOptional(), bulletType, detonatePos.x, detonatePos.y, detonatePos.z, bulletType.explosionRadius, bulletType.fireRadius > 0, bulletType.flak > 0, bulletType.explosionBreaksBlocks); } if(bulletType.fireRadius > 0) diff --git a/src/main/java/com/flansmod/common/guns/raytracing/PlayerHitbox.java b/src/main/java/com/flansmod/common/guns/raytracing/PlayerHitbox.java index e5986d10d..344e057f3 100644 --- a/src/main/java/com/flansmod/common/guns/raytracing/PlayerHitbox.java +++ b/src/main/java/com/flansmod/common/guns/raytracing/PlayerHitbox.java @@ -5,6 +5,7 @@ import net.minecraft.item.ItemStack; import net.minecraft.potion.PotionEffect; import net.minecraft.util.DamageSource; +import net.minecraft.util.text.TextComponentString; import net.minecraft.world.World; import net.minecraftforge.fml.relauncher.Side; import net.minecraftforge.fml.relauncher.SideOnly; @@ -161,6 +162,7 @@ public float hitByBullet(FiredShot shot, Float damage, Float penetratingPower) player.addPotionEffect(new PotionEffect(effect)); } float damageModifier = bulletType.penetratingPower < 0.1F ? penetratingPower / bulletType.penetratingPower : 1; + switch(type) { case BODY: break; @@ -181,7 +183,7 @@ public float hitByBullet(FiredShot shot, Float damage, Float penetratingPower) //Calculate the hit damage float hitDamage = damage * shot.getBulletType().damageVsLiving * damageModifier; //Create a damage source object - DamageSource damagesource = shot.getDamageSource(); + DamageSource damagesource = shot.getDamageSource(type.equals(EnumHitboxType.HEAD)); //When the damage is 0 (such as with Nerf guns) the entityHurt Forge hook is not called, so this hacky thing is here if(!player.world.isRemote && hitDamage == 0 && TeamsManager.getInstance().currentRound != null) diff --git a/src/main/resources/assets/flansmod/models/item/crosshairsymbol.json b/src/main/resources/assets/flansmod/models/item/crosshairsymbol.json new file mode 100644 index 000000000..d4d46c392 --- /dev/null +++ b/src/main/resources/assets/flansmod/models/item/crosshairsymbol.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "flansmod:items/crosshair" + } +} diff --git a/src/main/resources/assets/flansmod/textures/items/crosshair.png b/src/main/resources/assets/flansmod/textures/items/crosshair.png new file mode 100644 index 000000000..df31a26c6 Binary files /dev/null and b/src/main/resources/assets/flansmod/textures/items/crosshair.png differ