diff --git a/src/main/java/com/atsuishio/superbwarfare/client/ClickHandler.java b/src/main/java/com/atsuishio/superbwarfare/client/ClickHandler.java index 6d295cc55..d4525ef15 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/ClickHandler.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/ClickHandler.java @@ -8,7 +8,6 @@ import com.atsuishio.superbwarfare.entity.ICannonEntity; import com.atsuishio.superbwarfare.entity.MortarEntity; import com.atsuishio.superbwarfare.event.ClientEventHandler; import com.atsuishio.superbwarfare.init.*; -import com.atsuishio.superbwarfare.item.common.ammo.CannonShellItem; import com.atsuishio.superbwarfare.network.ModVariables; import com.atsuishio.superbwarfare.network.message.*; import com.atsuishio.superbwarfare.tools.GunsTool; @@ -288,7 +287,7 @@ public class ClickHandler { ModUtils.PACKET_HANDLER.sendToServer(new DroneFireMessage(0)); } - if (player.getVehicle() != null && player.getVehicle() instanceof ICannonEntity && player.getMainHandItem().getItem() instanceof CannonShellItem) { + if (player.getVehicle() != null && player.getVehicle() instanceof ICannonEntity) { ModUtils.PACKET_HANDLER.sendToServer(new VehicleFireMessage(0)); return; } diff --git a/src/main/java/com/atsuishio/superbwarfare/client/screens/CannonHudOverlay.java b/src/main/java/com/atsuishio/superbwarfare/client/screens/CannonHudOverlay.java index b91977e6d..aa63b18db 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/screens/CannonHudOverlay.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/screens/CannonHudOverlay.java @@ -37,7 +37,11 @@ public class CannonHudOverlay { public static float maxHealth = 0; public static float indicatorPosH = 0; + public static float energy = 0; + public static float maxEnergy = 0; + private static final ResourceLocation ARMOR = ModUtils.loc("textures/screens/armor.png"); + private static final ResourceLocation ENERGY = ModUtils.loc("textures/screens/energy.png"); private static final ResourceLocation HEALTH = ModUtils.loc("textures/screens/armor_value.png"); private static final ResourceLocation HEALTH_FRAME = ModUtils.loc("textures/screens/armor_value_frame.png"); @@ -58,6 +62,7 @@ public class CannonHudOverlay { RenderSystem.setShader(GameRenderer::getPositionTexShader); RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO); RenderSystem.setShaderColor(1, 1, 1, 1); + GuiGraphics guiGraphics = event.getGuiGraphics(); if (cannon instanceof Mk42Entity) { health = cannon.getEntityData().get(Mk42Entity.HEALTH); @@ -74,9 +79,23 @@ public class CannonHudOverlay { if (cannon instanceof AnnihilatorEntity) { health = cannon.getEntityData().get(AnnihilatorEntity.HEALTH); maxHealth = CannonConfig.ANNIHILATOR_HP.get(); + energy = cannon.getEntityData().get(AnnihilatorEntity.ENERGY); + maxEnergy = CannonConfig.ANNIHILATOR_MAX_ENERGY.get().floatValue(); indicatorPosH = 0.2f; + + guiGraphics.pose().pushPose(); + guiGraphics.blit(ENERGY, w - 96, h - 28, 0, 0, 12, 12, 12, 12); + guiGraphics.blit(HEALTH_FRAME, w - 83, h - 26, 0, 0, 80, 8, 80, 8); + guiGraphics.blit(HEALTH, w - 83, h - 26, 0, 0, (int) (80 * energy / maxEnergy), 8, 80, 8); + guiGraphics.pose().popPose(); } + guiGraphics.pose().pushPose(); + guiGraphics.blit(ARMOR, w - 96, h - 14, 0, 0, 12, 12, 12, 12); + guiGraphics.blit(HEALTH_FRAME, w - 83, h - 12, 0, 0, 80, 8, 80, 8); + guiGraphics.blit(HEALTH, w - 83, h - 12, 0, 0, (int) (80 * health / maxHealth), 8, 80, 8); + guiGraphics.pose().popPose(); + float yRotOffset = Mth.lerp(event.getPartialTick(), player.yRotO, player.getYRot()); float xRotOffset = Mth.lerp(event.getPartialTick(), player.xRotO, player.getXRot()); float diffY = cannon.getViewYRot(event.getPartialTick()) - yRotOffset; @@ -94,7 +113,7 @@ public class CannonHudOverlay { int k = (w - i) / 2; int l = (h - j) / 2; if (ClientEventHandler.zoom) { - Entity lookingEntity = TraceTool.cannonFindLookingEntity(player, 512); + Entity lookingEntity = TraceTool.findLookingEntity(player, 512); boolean lookAtEntity = false; double block_range = player.position().distanceTo((Vec3.atLowerCornerOf(player.level().clip( new ClipContext(new Vec3(player.getX(), player.getEyeY() + 1, player.getZ()), new Vec3(player.getX(), player.getEyeY() + 1, player.getZ()).add(player.getLookAngle().scale(512)), @@ -120,7 +139,11 @@ public class CannonHudOverlay { w / 2 + 14, h / 2 - 20, -1, false); } } - RenderHelper.preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/cannon_crosshair.png"), k, l, 0, 0.0F, i, j, i, j); + if (cannon instanceof AnnihilatorEntity) { + RenderHelper.preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/laser_cannon_crosshair.png"), k, l, 0, 0.0F, i, j, i, j); + } else { + RenderHelper.preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/cannon_crosshair.png"), k, l, 0, 0.0F, i, j, i, j); + } RenderHelper.preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/indicator.png"), k + (float) Math.tan(Mth.clamp(Mth.DEG_TO_RAD * diffY, -1.5, 1.5)) * 5 * i / 1.4f * (90 - Math.abs(player.getXRot())) / 90, l + (float) Math.tan(Mth.clamp(Mth.DEG_TO_RAD * diffX, -1.5, 1.5)) * 5 * j / 1.4f, 0, 0.0F, i, j, i, j); } else { RenderHelper.preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/cannon_crosshair_notzoom.png"), k, l, 0, 0.0F, i, j, i, j); @@ -130,18 +153,7 @@ public class CannonHudOverlay { .append(Component.literal(new DecimalFormat("##.#").format(-cannon.getXRot()) + "°")), w / 2 + 14, h / 2 - 29, -1, false); - GuiGraphics guiGraphics = event.getGuiGraphics(); - guiGraphics.pose().pushPose(); - guiGraphics.blit(ARMOR, w - 96, h - 14, 0, 0, 12, 12, 12, 12); - guiGraphics.blit(HEALTH_FRAME, w - 83, h - 12, 0, 0, 80, 8, 80, 8); - guiGraphics.blit(HEALTH, w - 83, h - 12, 0, 0, (int) (80 * health / maxHealth), 8, 80, 8); - guiGraphics.pose().popPose(); - RenderSystem.depthMask(true); - RenderSystem.defaultBlendFunc(); - RenderSystem.enableDepthTest(); - RenderSystem.disableBlend(); - RenderSystem.setShaderColor(1, 1, 1, 1); } private static boolean shouldRenderCrossHair(Player player) { diff --git a/src/main/java/com/atsuishio/superbwarfare/config/server/CannonConfig.java b/src/main/java/com/atsuishio/superbwarfare/config/server/CannonConfig.java index e6b7a81fa..b246cc8b3 100644 --- a/src/main/java/com/atsuishio/superbwarfare/config/server/CannonConfig.java +++ b/src/main/java/com/atsuishio/superbwarfare/config/server/CannonConfig.java @@ -21,6 +21,8 @@ public class CannonConfig { public static ForgeConfigSpec.IntValue MLE1934_HE_EXPLOSION_RADIUS; public static ForgeConfigSpec.IntValue ANNIHILATOR_HP; + public static ForgeConfigSpec.DoubleValue ANNIHILATOR_SHOOT_COST; + public static ForgeConfigSpec.DoubleValue ANNIHILATOR_MAX_ENERGY; public static void init(ForgeConfigSpec.Builder builder) { builder.push("mk_42"); @@ -75,8 +77,15 @@ public class CannonConfig { builder.push("annihilator"); - builder.comment("The HealthPoint of ANNIHILATOR"); + builder.comment("The HealthPoint of Annihilator"); ANNIHILATOR_HP = builder.defineInRange("annihilator_hp", 4000, 1, 10000000); + + builder.comment("The energy cost of Annihilator per shoot"); + ANNIHILATOR_SHOOT_COST = builder.defineInRange("annihilator_shoot_cost", 2000000d, 0d, Double.POSITIVE_INFINITY); + + builder.comment("The max energy storage of Annihilator"); + ANNIHILATOR_MAX_ENERGY = builder.defineInRange("annihilator_max_energy", 20000000d, 0d, Double.POSITIVE_INFINITY); + builder.pop(); } diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/AnnihilatorEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/AnnihilatorEntity.java index 337e27e2a..0aaa29672 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/AnnihilatorEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/AnnihilatorEntity.java @@ -13,6 +13,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.ClientGamePacketListener; import net.minecraft.network.syncher.EntityDataAccessor; @@ -58,11 +59,12 @@ public class AnnihilatorEntity extends Entity implements GeoEntity, ICannonEntit public static final EntityDataAccessor LASER_LEFT_LENGTH = SynchedEntityData.defineId(AnnihilatorEntity.class, EntityDataSerializers.FLOAT); public static final EntityDataAccessor LASER_MIDDLE_LENGTH = SynchedEntityData.defineId(AnnihilatorEntity.class, EntityDataSerializers.FLOAT); public static final EntityDataAccessor LASER_RIGHT_LENGTH = SynchedEntityData.defineId(AnnihilatorEntity.class, EntityDataSerializers.FLOAT); + public static final EntityDataAccessor ENERGY = SynchedEntityData.defineId(AnnihilatorEntity.class, EntityDataSerializers.FLOAT); private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); public static final float MAX_HEALTH = CannonConfig.ANNIHILATOR_HP.get(); - + public static final float SHOOT_COST = CannonConfig.ANNIHILATOR_SHOOT_COST.get().floatValue(); protected int interpolationSteps; protected double serverYRot; protected double serverXRot; @@ -83,17 +85,20 @@ public class AnnihilatorEntity extends Entity implements GeoEntity, ICannonEntit this.entityData.define(LASER_LEFT_LENGTH, 0f); this.entityData.define(LASER_MIDDLE_LENGTH, 0f); this.entityData.define(LASER_RIGHT_LENGTH, 0f); + this.entityData.define(ENERGY, 0f); } @Override public void addAdditionalSaveData(CompoundTag compound) { compound.putInt("CoolDown", this.entityData.get(COOL_DOWN)); compound.putFloat("Health", this.entityData.get(HEALTH)); + compound.putFloat("Energy", this.entityData.get(ENERGY)); } @Override public void readAdditionalSaveData(CompoundTag compound) { this.entityData.set(COOL_DOWN, compound.getInt("CoolDown")); + this.entityData.set(ENERGY, compound.getFloat("Energy")); if (compound.contains("Health")) { this.entityData.set(HEALTH, compound.getFloat("Health")); } else { @@ -101,12 +106,12 @@ public class AnnihilatorEntity extends Entity implements GeoEntity, ICannonEntit } } - // TODO 修改乘客的位置 @Override protected void positionRider(Entity pPassenger, MoveFunction pCallback) { if (this.hasPassenger(pPassenger)) { - double d0 = this.getY() + this.getPassengersRidingOffset() + pPassenger.getMyRidingOffset(); - pCallback.accept(pPassenger, this.getX(), d0, this.getZ()); + float f1 = (float)((this.isRemoved() ? 0.009999999776482582 : this.getPassengersRidingOffset()) + pPassenger.getMyRidingOffset()); + Vec3 vec3 = (new Vec3(1, 0.0, 0.0)).yRot(-this.getYRot() * 0.017453292F - 1.5707964F); + pCallback.accept(pPassenger, this.getX() + vec3.x, this.getY() + (double)f1, this.getZ() + vec3.z); } } @@ -187,6 +192,11 @@ public class AnnihilatorEntity extends Entity implements GeoEntity, ICannonEntit this.discard(); return InteractionResult.sidedSuccess(this.level().isClientSide()); } + if (player.getMainHandItem().is(ModItems.SHIELD_CELL.get())) { + this.entityData.set(ENERGY, (float)Mth.clamp(this.entityData.get(ENERGY) + 1000000 , 0, CannonConfig.ANNIHILATOR_MAX_ENERGY.get())); + player.displayClientMessage(Component.literal("Energy:" + new java.text.DecimalFormat("##").format(this.entityData.get(ENERGY))), true); + return InteractionResult.sidedSuccess(this.level().isClientSide()); + } return InteractionResult.PASS; } else { if (this.getFirstPassenger() == null) { @@ -196,7 +206,6 @@ public class AnnihilatorEntity extends Entity implements GeoEntity, ICannonEntit return InteractionResult.sidedSuccess(this.level().isClientSide()); } } - return InteractionResult.PASS; } @@ -296,6 +305,13 @@ public class AnnihilatorEntity extends Entity implements GeoEntity, ICannonEntit } travel(); + + Entity passenger = this.getPassengers().isEmpty() ? null : this.getPassengers().get(0); + + if (passenger instanceof ServerPlayer serverPlayer && this.entityData.get(COOL_DOWN) == 20) { + SoundTool.playLocalSound(serverPlayer, ModSounds.ANNIHILATOR_RELOAD.get(), 1, 1); + } + this.refreshDimensions(); } @@ -379,21 +395,25 @@ public class AnnihilatorEntity extends Entity implements GeoEntity, ICannonEntit return; } - Level level = player.level(); - if (level instanceof ServerLevel server) { - ItemStack stack = player.getMainHandItem(); + if (this.entityData.get(ENERGY) < SHOOT_COST) { + player.displayClientMessage(Component.literal("Not Enough Energy!"), true); + return; + } + Level level = player.level(); + if (level instanceof ServerLevel) { if (player instanceof ServerPlayer serverPlayer) { SoundTool.playLocalSound(serverPlayer, ModSounds.ANNIHILATOR_FIRE_1P.get(), 1, 1); -// SoundTool.playLocalSound(serverPlayer, ModSounds.MK_42_RELOAD.get(), 2, 1); -// serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.MK_42_FIRE_3P.get(), SoundSource.PLAYERS, 6, 1); -// serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.MK_42_FAR.get(), SoundSource.PLAYERS, 16, 1); -// serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.MK_42_VERYFAR.get(), SoundSource.PLAYERS, 32, 1); + serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.ANNIHILATOR_FIRE_3P.get(), SoundSource.PLAYERS, 6, 1); + serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.ANNIHILATOR_FAR.get(), SoundSource.PLAYERS, 16, 1); + serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.ANNIHILATOR_VERYFAR.get(), SoundSource.PLAYERS, 32, 1); } this.entityData.set(COOL_DOWN, 100); + this.entityData.set(ENERGY, this.entityData.get(ENERGY) - SHOOT_COST); + final Vec3 center = new Vec3(this.getX(), this.getEyeY(), this.getZ()); for (Entity target : level.getEntitiesOfClass(Entity.class, new AABB(center, center).inflate(20), e -> true).stream().sorted(Comparator.comparingDouble(e -> e.distanceToSqr(center))).toList()) { @@ -415,6 +435,7 @@ public class AnnihilatorEntity extends Entity implements GeoEntity, ICannonEntit public void travel() { Entity passenger = this.getPassengers().isEmpty() ? null : this.getPassengers().get(0); if (!(passenger instanceof LivingEntity entity)) return; + if (this.entityData.get(ENERGY) == 0) return; float passengerY = entity.getYHeadRot(); @@ -452,7 +473,7 @@ public class AnnihilatorEntity extends Entity implements GeoEntity, ICannonEntit } private PlayState movementPredicate(AnimationState event) { - if (this.entityData.get(COOL_DOWN) > 88) { + if (this.entityData.get(COOL_DOWN) > 80) { return event.setAndContinue(RawAnimation.begin().thenPlay("animation.annihilator.fire")); } return event.setAndContinue(RawAnimation.begin().thenLoop("animation.annihilator.idle")); diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModSounds.java b/src/main/java/com/atsuishio/superbwarfare/init/ModSounds.java index f15082569..1aafca1ba 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModSounds.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModSounds.java @@ -338,5 +338,9 @@ public class ModSounds { public static final RegistryObject CHARGE_RIFLE_FIRE_BOOM_3P = REGISTRY.register("charge_rifle_fire_boom_3p", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "charge_rifle_fire_boom_3p"))); public static final RegistryObject ANNIHILATOR_FIRE_1P = REGISTRY.register("annihilator_fire_1p", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "annihilator_fire_1p"))); + public static final RegistryObject ANNIHILATOR_FIRE_3P = REGISTRY.register("annihilator_fire_3p", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "annihilator_fire_3p"))); + public static final RegistryObject ANNIHILATOR_FAR = REGISTRY.register("annihilator_far", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "annihilator_far"))); + public static final RegistryObject ANNIHILATOR_VERYFAR = REGISTRY.register("annihilator_veryfar", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "annihilator_veryfar"))); + public static final RegistryObject ANNIHILATOR_RELOAD = REGISTRY.register("annihilator_reload", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "annihilator_reload"))); } diff --git a/src/main/java/com/atsuishio/superbwarfare/tools/TraceTool.java b/src/main/java/com/atsuishio/superbwarfare/tools/TraceTool.java index 1b817022f..ef87f8282 100644 --- a/src/main/java/com/atsuishio/superbwarfare/tools/TraceTool.java +++ b/src/main/java/com/atsuishio/superbwarfare/tools/TraceTool.java @@ -90,35 +90,4 @@ public class TraceTool { return null; } - - public static Entity cannonFindLookingEntity(Entity player, double entityReach) { - double distance = entityReach * entityReach; - Vec3 eyePos = new Vec3(player.getX(), player.getEyeY() + 1, player.getZ()); - HitResult hitResult = player.pick(entityReach, 1.0f, false); - if (hitResult.getType() != HitResult.Type.MISS) { - distance = hitResult.getLocation().distanceToSqr(eyePos); - double blockReach = 5; - if (distance > blockReach * blockReach) { - Vec3 pos = hitResult.getLocation(); - hitResult = BlockHitResult.miss(pos, Direction.getNearest(eyePos.x, eyePos.y, eyePos.z), BlockPos.containing(pos)); - } - } - Vec3 viewVec = player.getViewVector(1.0F); - Vec3 toVec = eyePos.add(viewVec.x * entityReach, viewVec.y * entityReach, viewVec.z * entityReach); - AABB aabb = player.getBoundingBox().expandTowards(viewVec.scale(entityReach)).inflate(1.0D, 1.0D, 1.0D); - EntityHitResult entityhitresult = ProjectileUtil.getEntityHitResult(player, eyePos, toVec, aabb, p -> !p.isSpectator(), distance); - if (entityhitresult != null) { - Vec3 targetPos = entityhitresult.getLocation(); - double distanceToTarget = eyePos.distanceToSqr(targetPos); - if (distanceToTarget > distance || distanceToTarget > entityReach * entityReach) { - hitResult = BlockHitResult.miss(targetPos, Direction.getNearest(viewVec.x, viewVec.y, viewVec.z), BlockPos.containing(targetPos)); - } else if (distanceToTarget < distance) { - hitResult = entityhitresult; - } - } - if (hitResult.getType() == HitResult.Type.ENTITY) { - return ((EntityHitResult) hitResult).getEntity(); - } - return null; - } } diff --git a/src/main/resources/assets/superbwarfare/lang/en_us.json b/src/main/resources/assets/superbwarfare/lang/en_us.json index ce6bb01d1..b3e865357 100644 --- a/src/main/resources/assets/superbwarfare/lang/en_us.json +++ b/src/main/resources/assets/superbwarfare/lang/en_us.json @@ -351,6 +351,7 @@ "entity.superbwarfare.mk_42": "5''/54 Mk42", "entity.superbwarfare.mle_1934": "138.6mm50 Mle1934 R1938", "entity.superbwarfare.drone": "Drone", + "entity.superbwarfare.annihilator": "Annihilator Energy Gun", "key.categories.superbwarfare": "Superb Warfare", "key.superbwarfare.hold_zoom": "Zoom(Hold)", diff --git a/src/main/resources/assets/superbwarfare/lang/zh_cn.json b/src/main/resources/assets/superbwarfare/lang/zh_cn.json index ae734ab02..c173c7dcf 100644 --- a/src/main/resources/assets/superbwarfare/lang/zh_cn.json +++ b/src/main/resources/assets/superbwarfare/lang/zh_cn.json @@ -351,6 +351,7 @@ "entity.superbwarfare.mk_42": "5''/54 Mk42", "entity.superbwarfare.mle_1934": "138.6mm50 Mle1934 R1938", "entity.superbwarfare.drone": "无人机", + "entity.superbwarfare.annihilator": "歼灭者能量炮", "key.categories.superbwarfare": "卓越前线", "key.superbwarfare.hold_zoom": "瞄准(按住)", diff --git a/src/main/resources/assets/superbwarfare/sounds.json b/src/main/resources/assets/superbwarfare/sounds.json index 74997346d..368241286 100644 --- a/src/main/resources/assets/superbwarfare/sounds.json +++ b/src/main/resources/assets/superbwarfare/sounds.json @@ -2397,5 +2397,37 @@ "stream": false } ] + }, + "annihilator_fire_3p": { + "sounds": [ + { + "name": "superbwarfare:annihilator/annihilator_fire_3p", + "stream": false + } + ] + }, + "annihilator_far": { + "sounds": [ + { + "name": "superbwarfare:annihilator/annihilator_far", + "stream": false + } + ] + }, + "annihilator_veryfar": { + "sounds": [ + { + "name": "superbwarfare:annihilator/annihilator_veryfar", + "stream": false + } + ] + }, + "annihilator_reload": { + "sounds": [ + { + "name": "superbwarfare:annihilator/annihilator_reload", + "stream": false + } + ] } } \ No newline at end of file diff --git a/src/main/resources/assets/superbwarfare/sounds/annihilator/annihilator_far.ogg b/src/main/resources/assets/superbwarfare/sounds/annihilator/annihilator_far.ogg new file mode 100644 index 000000000..2f3ab5b3d Binary files /dev/null and b/src/main/resources/assets/superbwarfare/sounds/annihilator/annihilator_far.ogg differ diff --git a/src/main/resources/assets/superbwarfare/sounds/annihilator/annihilator_fire_3p.ogg b/src/main/resources/assets/superbwarfare/sounds/annihilator/annihilator_fire_3p.ogg new file mode 100644 index 000000000..64dc49088 Binary files /dev/null and b/src/main/resources/assets/superbwarfare/sounds/annihilator/annihilator_fire_3p.ogg differ diff --git a/src/main/resources/assets/superbwarfare/sounds/annihilator/annihilator_reload.ogg b/src/main/resources/assets/superbwarfare/sounds/annihilator/annihilator_reload.ogg new file mode 100644 index 000000000..0e6268120 Binary files /dev/null and b/src/main/resources/assets/superbwarfare/sounds/annihilator/annihilator_reload.ogg differ diff --git a/src/main/resources/assets/superbwarfare/sounds/annihilator/annihilator_veryfar.ogg b/src/main/resources/assets/superbwarfare/sounds/annihilator/annihilator_veryfar.ogg new file mode 100644 index 000000000..5812c24c3 Binary files /dev/null and b/src/main/resources/assets/superbwarfare/sounds/annihilator/annihilator_veryfar.ogg differ diff --git a/src/main/resources/assets/superbwarfare/textures/screens/cannon/laser_cannon_crosshair.png b/src/main/resources/assets/superbwarfare/textures/screens/cannon/laser_cannon_crosshair.png new file mode 100644 index 000000000..aba659b97 Binary files /dev/null and b/src/main/resources/assets/superbwarfare/textures/screens/cannon/laser_cannon_crosshair.png differ diff --git a/src/main/resources/assets/superbwarfare/textures/screens/energy.png b/src/main/resources/assets/superbwarfare/textures/screens/energy.png new file mode 100644 index 000000000..767fd1ea3 Binary files /dev/null and b/src/main/resources/assets/superbwarfare/textures/screens/energy.png differ