added all features of the newest 1.18.2

This commit is contained in:
Magistu
2024-02-03 22:45:49 +03:00
committed by Magistu
parent 46daaa5d56
commit b0d6185625
93 changed files with 12679 additions and 1207 deletions

View File

@@ -4,6 +4,7 @@ import ru.magistu.siegemachines.SiegeMachines;
import ru.magistu.siegemachines.entity.machine.*;
import ru.magistu.siegemachines.entity.projectile.Cannonball;
import ru.magistu.siegemachines.entity.projectile.GiantArrow;
import ru.magistu.siegemachines.entity.projectile.GiantStone;
import ru.magistu.siegemachines.entity.projectile.Stone;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.entity.Entity;
@@ -20,18 +21,27 @@ public class EntityTypes
public static final RegistryObject<EntityType<Cannonball>> CANNONBALL = addRegistry("cannonball", Cannonball::new, 0.5f, 0.5f);
public static final RegistryObject<EntityType<Stone>> STONE = addRegistry("stone", Stone::new, 0.6f, 0.6f);
public static final RegistryObject<EntityType<GiantStone>> GIANT_STONE = addRegistry("giant_stone", GiantStone::new, 1.1f, 1.1f);
public static final RegistryObject<EntityType<GiantArrow>> GIANT_ARROW = DEFERRED_REGISTER.register("giant_arrow", () -> EntityType.Builder.<GiantArrow>of(GiantArrow::new, MobCategory.MISC).clientTrackingRange(4).updateInterval(20).sized(0.5f, 0.5f).build(new ResourceLocation(SiegeMachines.ID, "giant_arrow").toString()));
public static final RegistryObject<EntityType<Mortar>> MORTAR = addRegistry("mortar", Mortar::new, 2.0f, 1.0f);
public static final RegistryObject<EntityType<Culverin>> CULVERIN = addRegistry("culverin", Culverin::new, 2.0f, 1.0f);
public static final RegistryObject<EntityType<Trebuchet>> TREBUCHET = addRegistry("trebuchet", Trebuchet::new, 5.0f, 9.0f);
public static final RegistryObject<EntityType<Catapult>> CATAPULT = addRegistry("catapult", Catapult::new, 3.0f, 3.0f);
public static final RegistryObject<EntityType<Ballista>> BALLISTA = addRegistry("ballista", Ballista::new, 1.5f, 1.5f);
public static final RegistryObject<EntityType<BatteringRam>> BATTERING_RAM = addRegistry("battering_ram", BatteringRam::new, 4.0f, 3.0f);
public static final RegistryObject<EntityType<Mortar>> MORTAR = addRegistry("mortar", Mortar::new, 2.0f, 1.0f, 10);
public static final RegistryObject<EntityType<Culverin>> CULVERIN = addRegistry("culverin", Culverin::new, 2.5f, 1.8f, 10);
public static final RegistryObject<EntityType<Trebuchet>> TREBUCHET = addRegistry("trebuchet", Trebuchet::new, 5.0f, 9.0f, 10);
public static final RegistryObject<EntityType<Catapult>> CATAPULT = addRegistry("catapult", Catapult::new, 3.0f, 3.0f, 10);
public static final RegistryObject<EntityType<Ballista>> BALLISTA = addRegistry("ballista", Ballista::new, 1.5f, 1.5f, 10);
public static final RegistryObject<EntityType<BatteringRam>> BATTERING_RAM = addRegistry("battering_ram", BatteringRam::new, 4.0f, 3.0f, 10);
public static final RegistryObject<EntityType<SiegeLadder>> SIEGE_LADDER = addRegistry("siege_ladder", SiegeLadder::new, 3.0f, 3.0f, 10);
public static final RegistryObject<EntityType<Seat>> SEAT = addRegistry("seat", Seat::new, 0.0f, 0.0f);
public static <T extends Entity> RegistryObject<EntityType<T>> addRegistry(String name, EntityType.EntityFactory<T> constructor, float sizex, float sizey)
{
return DEFERRED_REGISTER.register(name, () -> EntityType.Builder.of(constructor, MobCategory.MISC).sized(sizex, sizey).build(new ResourceLocation(SiegeMachines.ID, name).toString()));
return addRegistry(name, constructor, sizex, sizey, 1);
}
public static <T extends Entity> RegistryObject<EntityType<T>> addRegistry(String name, EntityType.EntityFactory<T> constructor, float sizex, float sizey, int trackingrange)
{
return DEFERRED_REGISTER.register(name, () -> EntityType.Builder.of(constructor, MobCategory.MISC).clientTrackingRange(trackingrange).sized(sizex, sizey).build(new ResourceLocation(SiegeMachines.ID, name).toString()));
}
public static void register(IEventBus eventBus)

View File

@@ -1,6 +1,6 @@
package ru.magistu.siegemachines.entity;
import ru.magistu.siegemachines.gui.machine.crosshair.Crosshair;
import ru.magistu.siegemachines.client.gui.machine.crosshair.Crosshair;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;

View File

@@ -2,8 +2,8 @@ package ru.magistu.siegemachines.entity.machine;
import ru.magistu.siegemachines.SiegeMachines;
import ru.magistu.siegemachines.client.SoundTypes;
import ru.magistu.siegemachines.gui.machine.crosshair.Crosshair;
import ru.magistu.siegemachines.gui.machine.crosshair.ReloadingCrosshair;
import ru.magistu.siegemachines.client.gui.machine.crosshair.Crosshair;
import ru.magistu.siegemachines.client.gui.machine.crosshair.ReloadingCrosshair;
import ru.magistu.siegemachines.item.ModItems;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
@@ -59,21 +59,21 @@ public class Ballista extends ShootingMachine implements IAnimatable
}
}
return PlayState.CONTINUE;
}
}
@Override
public void registerControllers(AnimationData data)
public void registerControllers(AnimationData data)
{
AnimationController<?> controller = new AnimationController<>(this, "controller", 1, (t) ->
{
if (this.state.equals(State.RELOADING))
{
return (double) (this.type.delaytime - this.delayticks) / this.type.delaytime;
return (double) (this.type.specs.delaytime.get() - this.delayticks) / this.type.specs.delaytime.get();
}
return t;
}, this::predicate);
data.addAnimationController(controller);
}
data.addAnimationController(controller);
}
@Override
public AnimationFactory getFactory()
@@ -90,11 +90,11 @@ public class Ballista extends ShootingMachine implements IAnimatable
}
if (!this.level.isClientSide() && !this.isVehicle())
{
player.startRiding(this);
return InteractionResult.SUCCESS;
}
player.startRiding(this);
return InteractionResult.SUCCESS;
}
return InteractionResult.PASS;
return InteractionResult.PASS;
}
public void startShooting(Player player)
@@ -106,7 +106,7 @@ public class Ballista extends ShootingMachine implements IAnimatable
this.shootingticks = this.type.userealisetime;
Vec3 pos = this.position();
this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.BALLISTA_SHOOTING.get(), SoundSource.BLOCKS, 1.4f, 1.0f, false);
this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.BALLISTA_SHOOTING.get(), this.getSoundSource(), 1.4f, 1.0f, false);
}
}
@@ -120,21 +120,21 @@ public class Ballista extends ShootingMachine implements IAnimatable
}
// @Override
// public void travel(Vec3 pos)
// public void travel(Vec3 pos)
// {
// if (this.isAlive())
// if (this.isAlive())
// {
// if (this.isVehicle())
// {
// LivingEntity livingentity = (LivingEntity) this.getControllingPassenger();
// LivingEntity livingentity = (LivingEntity) this.getControllingPassenger();
//
// this.setTurretRotationsDest(livingentity.getXRot(), livingentity.getYRot() - this.getYaw());
// this.updateTurretRotations();
// }
// }
// super.travel(pos);
// }
// }
//
// }
// }
@Override
public void travel(Vec3 pos)
@@ -163,7 +163,7 @@ public class Ballista extends ShootingMachine implements IAnimatable
{
this.state = State.RELOADING;
this.useticks = 0;
this.delayticks = this.type.delaytime;
this.delayticks = this.type.specs.delaytime.get();
}
if (this.shootingticks != 0 && --this.shootingticks <= 0)
@@ -182,7 +182,7 @@ public class Ballista extends ShootingMachine implements IAnimatable
if (this.delayticks % 21 == 0)
{
Vec3 pos = this.position();
this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.BALLISTA_RELOADING.get(), SoundSource.BLOCKS, 1.0f, 1.0f, false);
this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.BALLISTA_RELOADING.get(), this.getSoundSource(), 1.0f, 1.0f, false);
}
--this.delayticks;
}

View File

@@ -1,5 +1,9 @@
package ru.magistu.siegemachines.entity.machine;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.Entity;
import ru.magistu.siegemachines.SiegeMachines;
import ru.magistu.siegemachines.client.SoundTypes;
import ru.magistu.siegemachines.entity.Breakdown;
@@ -19,6 +23,7 @@ import net.minecraft.world.item.Item;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import ru.magistu.siegemachines.util.CartesianGeometry;
import software.bernie.geckolib3.core.IAnimatable;
import software.bernie.geckolib3.core.PlayState;
import software.bernie.geckolib3.core.builder.AnimationBuilder;
@@ -91,7 +96,7 @@ public class BatteringRam extends Machine implements IAnimatable
{
if (this.state.equals(State.RELOADING))
{
return (double) (this.type.delaytime - this.delayticks) / this.type.delaytime;
return (double) (this.type.specs.delaytime.get() - this.delayticks) / this.type.specs.delaytime.get();
}
return t;
}, this::reloading_predicate);
@@ -149,7 +154,7 @@ public class BatteringRam extends Machine implements IAnimatable
{
this.state = State.RELOADING;
this.useticks = 0;
this.delayticks = this.type.delaytime;
this.delayticks = this.type.specs.delaytime.get();
}
if (this.hittingticks != 0 && --this.hittingticks <= 0)
@@ -173,12 +178,17 @@ public class BatteringRam extends Machine implements IAnimatable
this.updateMachineRender();
this.renderupdateticks = SiegeMachines.RENDER_UPDATE_TIME;
}
// if (this.getWheelsSpeed() > 0.0081 && this.wheelssoundticks-- <= 0)
// {
// this.level.playLocalSound(this.getX(), this.getY(), this.getZ(), SoundTypes.RAM_WHEELS.get(), SoundCategory.NEUTRAL, 0.6f, 1.0f, true);
// this.wheelssoundticks = 20;
// }
if (this.level.isClientSide() && this.hasControllingPassenger() && this.getWheelsSpeed() > 0.0081 && this.wheelssoundticks-- <= 0)
{
Entity passenger = this.getControllingPassenger();
if (Minecraft.getInstance().player == passenger)
{
Vec3 pos = this.position();
this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.RAM_WHEELS.get(), this.getSoundSource(), 1.5f, 0.85f + this.level.random.nextFloat() * 0.3f, false);
this.wheelssoundticks = 20;
}
}
super.tick();
}
@@ -186,10 +196,14 @@ public class BatteringRam extends Machine implements IAnimatable
@Override
public void use(Player player)
{
if (!this.level.isClientSide())
if (this.deploymentticks > 0)
{
PacketHandler.sendPacketToAllInArea(new PacketMachineUse(this.getId()), this.blockPosition(), SiegeMachines.RENDER_UPDATE_RANGE_SQR);
player.sendSystemMessage(Component.translatable(SiegeMachines.ID + ".wait", this.deploymentticks / 20.0f).withStyle(ChatFormatting.RED));
return;
}
if (!this.level.isClientSide())
PacketHandler.sendPacketToAllInArea(new PacketMachineUse(this.getId()), this.blockPosition(), SiegeMachines.RENDER_UPDATE_RANGE_SQR);
if (this.delayticks <= 0 && this.useticks <= 0 && this.hittingticks <= 0)
{
@@ -198,7 +212,7 @@ public class BatteringRam extends Machine implements IAnimatable
this.hittingticks = this.type.userealisetime;
Vec3 pos = this.position();
this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.RAM_HITTING.get(), SoundSource.BLOCKS, 0.5f, 0.9f, false);
this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.RAM_HITTING.get(), this.getSoundSource(), 0.5f, 0.9f, false);
}
}
@@ -215,6 +229,9 @@ public class BatteringRam extends Machine implements IAnimatable
@Override
public void useRealise()
{
if (this.deploymentticks > 0)
return;
if (!this.level.isClientSide())
{
PacketHandler.sendPacketToAllInArea(new PacketMachineUseRealise(this.getId()), this.blockPosition(), SiegeMachines.RENDER_UPDATE_RANGE_SQR);
@@ -251,6 +268,6 @@ public class BatteringRam extends Machine implements IAnimatable
double pitch = this.getTurretPitch() * Math.PI / 180.0;
double yaw = (this.getViewYRot(0.5f) + this.getTurretYaw()) * Math.PI / 180.0;
return this.position().add(applyRotations(this.type.turretpivot, 0.0, yaw).add(applyRotations(this.type.turretvector, pitch, yaw)));
return this.position().add(CartesianGeometry.applyRotations(this.type.turretpivot, 0.0, yaw).add(CartesianGeometry.applyRotations(this.type.turretvector, pitch, yaw)));
}
}

View File

@@ -2,8 +2,8 @@ package ru.magistu.siegemachines.entity.machine;
import ru.magistu.siegemachines.SiegeMachines;
import ru.magistu.siegemachines.client.SoundTypes;
import ru.magistu.siegemachines.gui.machine.crosshair.Crosshair;
import ru.magistu.siegemachines.gui.machine.crosshair.ReloadingCrosshair;
import ru.magistu.siegemachines.client.gui.machine.crosshair.Crosshair;
import ru.magistu.siegemachines.client.gui.machine.crosshair.ReloadingCrosshair;
import ru.magistu.siegemachines.item.ModItems;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
@@ -73,21 +73,21 @@ public class Catapult extends ShootingMachine implements IAnimatable
}
return PlayState.CONTINUE;
}
}
@Override
public void registerControllers(AnimationData data)
public void registerControllers(AnimationData data)
{
AnimationController<?> controller = new AnimationController<>(this, "controller", 1, (t) ->
{
if (this.state.equals(State.RELOADING))
{
return (double) (this.type.delaytime - this.delayticks) / this.type.delaytime;
return (double) (this.type.specs.delaytime.get() - this.delayticks) / this.type.specs.delaytime.get();
}
return t;
}, this::predicate);
data.addAnimationController(controller);
}
data.addAnimationController(controller);
}
@Override
public AnimationFactory getFactory()
@@ -106,11 +106,11 @@ public class Catapult extends ShootingMachine implements IAnimatable
}
if (!this.level.isClientSide() && !this.isVehicle())
{
player.startRiding(this);
return InteractionResult.SUCCESS;
}
player.startRiding(this);
return InteractionResult.SUCCESS;
}
return InteractionResult.PASS;
return InteractionResult.PASS;
}
public void startShooting(Player player)
@@ -122,7 +122,7 @@ public class Catapult extends ShootingMachine implements IAnimatable
this.shootingticks = this.type.userealisetime;
Vec3 pos = this.position();
this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.CATAPULT_SHOOTING.get(), SoundSource.BLOCKS, 1.5f, 1.0f, false);
this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.CATAPULT_SHOOTING.get(), this.getSoundSource(), 1.5f, 1.0f, false);
}
}
@@ -136,23 +136,23 @@ public class Catapult extends ShootingMachine implements IAnimatable
}
@Override
public void travel(Vec3 pos)
public void travel(Vec3 pos)
{
if (this.isAlive())
if (this.isAlive())
{
if (this.isVehicle() && this.useticks <= 0 && this.delayticks <= 0)
{
LivingEntity livingentity = (LivingEntity) this.getControllingPassenger();
LivingEntity livingentity = (LivingEntity) this.getControllingPassenger();
this.setTurretRotations(livingentity.getXRot(), this.getTurretYaw());
this.updateTurretRotations();
this.setYawDest(livingentity.getYRot());
this.updateYaw();
}
}
super.travel(pos);
}
}
}
}
@Override
public void tick()
@@ -161,7 +161,7 @@ public class Catapult extends ShootingMachine implements IAnimatable
{
this.state = State.RELOADING;
this.useticks = 0;
this.delayticks = this.type.delaytime;
this.delayticks = this.type.specs.delaytime.get();
}
if (this.shootingticks != 0 && --this.shootingticks <= 0)
@@ -180,7 +180,7 @@ public class Catapult extends ShootingMachine implements IAnimatable
if (this.delayticks % 20 == 0)
{
Vec3 pos = this.position();
this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.CATAPULT_RELOADING.get(), SoundSource.BLOCKS, 1.0f, 1.0f, false);
this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.CATAPULT_RELOADING.get(), this.getSoundSource(), 1.0f, 1.0f, false);
}
if (--this.delayticks <= 0)
{

View File

@@ -1,14 +1,7 @@
package ru.magistu.siegemachines.entity.machine;
import ru.magistu.siegemachines.SiegeMachines;
import ru.magistu.siegemachines.client.SoundTypes;
import ru.magistu.siegemachines.entity.IReloading;
import ru.magistu.siegemachines.gui.machine.crosshair.Crosshair;
import ru.magistu.siegemachines.gui.machine.crosshair.ReloadingCrosshair;
import net.minecraft.ChatFormatting;
import net.minecraft.client.Minecraft;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.network.chat.Component;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
@@ -21,6 +14,12 @@ import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import ru.magistu.siegemachines.SiegeMachines;
import ru.magistu.siegemachines.client.SoundTypes;
import ru.magistu.siegemachines.entity.IReloading;
import ru.magistu.siegemachines.client.gui.machine.crosshair.Crosshair;
import ru.magistu.siegemachines.client.gui.machine.crosshair.ReloadingCrosshair;
import ru.magistu.siegemachines.item.ModItems;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import software.bernie.geckolib3.core.IAnimatable;
@@ -46,6 +45,9 @@ public class Culverin extends ShootingMachine implements IAnimatable, IReloading
public Culverin(EntityType<? extends Mob> entitytype, Level level)
{
super(entitytype, level, MachineType.CULVERIN);
this.turretpitch = -18.5f;
this.turretpitchprev = this.turretpitch;
this.turretpitchdest = this.turretpitch;
}
private <E extends IAnimatable> PlayState wheels_predicate(AnimationEvent<E> event)
@@ -53,18 +55,18 @@ public class Culverin extends ShootingMachine implements IAnimatable, IReloading
event.getController().setAnimation(MOVING_ANIM);
return PlayState.CONTINUE;
}
}
@Override
public void registerControllers(AnimationData data)
public void registerControllers(AnimationData data)
{
AnimationController<?> wheels_controller = new AnimationController<>(this, "wheels_controller", 1, (t) -> {
double d = this.getWheelsSpeed();
this.wheelsspeed = d > 0 ? Math.min(d, 1.0) : Math.max(d, -1.0);
return wheelspitch += 0.013 * this.wheelsspeed;
return wheelspitch += 0.015 * this.wheelsspeed;
}, this::wheels_predicate);
data.addAnimationController(wheels_controller);
}
data.addAnimationController(wheels_controller);
}
@Override
public AnimationFactory getFactory()
@@ -79,7 +81,7 @@ public class Culverin extends ShootingMachine implements IAnimatable, IReloading
if (stack.getItem().equals(Items.FLINT_AND_STEEL))
{
if (this.useticks <= 0 && this.shootingticks <= 0)
if (this.useticks < 0)
{
stack.hurtAndBreak(1, player, (p_213833_1_) ->
{
@@ -108,21 +110,21 @@ public class Culverin extends ShootingMachine implements IAnimatable, IReloading
}
if (!this.level.isClientSide() && !this.isVehicle())
{
player.startRiding(this);
return InteractionResult.SUCCESS;
}
player.startRiding(this);
return InteractionResult.SUCCESS;
}
return InteractionResult.PASS;
return InteractionResult.PASS;
}
@Override
public void travel(Vec3 pos)
public void travel(Vec3 pos)
{
if (this.isAlive())
if (this.isAlive())
{
if (this.isVehicle())
{
LivingEntity livingentity = (LivingEntity) this.getControllingPassenger();
LivingEntity livingentity = (LivingEntity) this.getControllingPassenger();
this.setTurretRotationsDest(livingentity.getXRot(), livingentity.getYRot() - this.getYaw());
this.setYawDest(livingentity.getYRot());
@@ -130,51 +132,31 @@ public class Culverin extends ShootingMachine implements IAnimatable, IReloading
this.updateYaw();
this.updateTurretRotations();
float f0 = livingentity.xxa * 0.2f;
float f1 = livingentity.zza;
if (f1 <= 0.0f)
{
f1 *= 0.5f;
}
this.setSpeed(0.04f);
float f0 = livingentity.xxa * 0.2f;
float f1 = livingentity.zza;
this.setSpeed(0.02f);
pos = new Vec3(f0, pos.y, f1);
}
}
super.travel(pos);
}
}
}
}
@Override
public void tick()
{
if (this.useticks != 0 && --this.useticks <= 0)
{
this.useticks = 0;
this.delayticks = this.type.delaytime;
}
if (this.shootingticks != 0 && --this.shootingticks <= 0)
{
if (this.inventory.containsItem(Items.GUNPOWDER))
{
this.useRealise();
}
else if (!this.level.isClientSide())
{
Entity passenger = this.getControllingPassenger();
if (passenger instanceof Player)
{
passenger.sendSystemMessage(Component.translatable(SiegeMachines.ID + ".no_gunpowder").withStyle(ChatFormatting.RED));
}
}
this.shootingticks = 0;
this.useticks = 0;
}
if (!level.isClientSide() && this.isOnGround())
if (!level.isClientSide() && (this.isOnGround() || this.isInWater()))
{
this.setDeltaMovement(this.getWheelsDeltaMovement());
}
if (this.delayticks > 0 && this.isVehicle())
{
--this.delayticks;
@@ -186,10 +168,15 @@ public class Culverin extends ShootingMachine implements IAnimatable, IReloading
this.renderupdateticks = SiegeMachines.RENDER_UPDATE_TIME;
}
if (this.getWheelsSpeed() > 0.0081 && this.wheelssoundticks-- <= 0)
if (this.level.isClientSide() && this.hasControllingPassenger() && this.getWheelsSpeed() > 0.0081 && this.wheelssoundticks-- <= 0)
{
this.level.playLocalSound(this.getX(), this.getY(), this.getZ(), SoundTypes.CANNON_WHEELS.get(), SoundSource.NEUTRAL, 0.3f, 1.0f, true);
this.wheelssoundticks = 20;
Entity passenger = this.getControllingPassenger();
if (Minecraft.getInstance().player == passenger)
{
Vec3 pos = this.position();
this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.CANNON_WHEELS.get(), this.getSoundSource(), 1.5f, 0.85f + this.level.random.nextFloat() * 0.3f, false);
this.wheelssoundticks = 20;
}
}
super.tick();
@@ -198,14 +185,13 @@ public class Culverin extends ShootingMachine implements IAnimatable, IReloading
@Override
public void startShooting(Player player)
{
if (this.delayticks <= 0 && this.useticks <= 0 && this.shootingticks <= 0)
if (this.delayticks <= 0 && this.useticks <= 0)
{
if (!this.level.isClientSide())
{
this.level.playSound(null, this.getX(), this.getY(), this.getZ(), SoundTypes.FUSE.get(), SoundSource.BLOCKS, this.getVolumeFromDist(this.distanceTo(player)), 0.8f);
this.level.playSound(null, this.getX(), this.getY(), this.getZ(), SoundTypes.FUSE.get(), this.getSoundSource(), this.getVolumeFromDist(this.distanceTo(player)), 0.8f);
}
this.useticks = this.type.usetime;
this.shootingticks = this.type.userealisetime;
}
}
@@ -224,8 +210,10 @@ public class Culverin extends ShootingMachine implements IAnimatable, IReloading
this.blowParticles(ParticleTypes.FLAME, 0.035, 25);
this.blowParticles(ParticleTypes.CLOUD, 0.2, 60);
Vec3 pos = this.position();
this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.MORTAR_SHOOTING.get(), SoundSource.BLOCKS, 1.5f/*this.getVolumeFromDist(1.5f, 64.0f, this.distanceTo(player))*/, 0.85f + this.level.random.nextFloat() * 0.3f, false);
this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.MORTAR_SHOOTING.get(), this.getSoundSource(), 1.5f/*this.getVolumeFromDist(1.5f, 64.0f, this.distanceTo(player))*/, 0.85f + this.level.random.nextFloat() * 0.3f, false);
}
this.delayticks = this.type.specs.delaytime.get();
}
public double getWheelsSpeed()
@@ -267,7 +255,6 @@ public class Culverin extends ShootingMachine implements IAnimatable, IReloading
@Override
public Item getMachineItem()
{
return null;
// return ModItems.CULVERIN.get();
return ModItems.CULVERIN.get();
}
}

View File

@@ -0,0 +1,75 @@
package ru.magistu.siegemachines.entity.machine;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import ru.magistu.siegemachines.entity.EntityTypes;
public class LadderSeat extends Seat
{
public final float climbspeed = 0.02f;
private float highness = 0.0f;
public final SiegeLadder parent;
public LadderSeat(SiegeLadder parent)
{
super(EntityTypes.SEAT.get(), parent.level);
this.parent = parent;
}
public float getHighness()
{
return this.highness;
}
public void setHighness(float highness)
{
this.highness = highness;
}
@Override
public InteractionResult interact(Player player, InteractionHand hand)
{
InteractionResult result = super.interact(player, hand);
if (result.consumesAction())
return result;
if (player.isSecondaryUseActive())
return InteractionResult.PASS;
else if (this.isVehicle())
return InteractionResult.PASS;
else if (!this.level.isClientSide)
return player.startRiding(this) ? InteractionResult.CONSUME : InteractionResult.PASS;
else
return InteractionResult.SUCCESS;
}
@Override
public boolean shouldRiderSit()
{
return false;
}
@Override
protected void removePassenger(Entity entity)
{
this.highness = 0.0f;
super.removePassenger(entity);
}
public float climb()
{
if (this.getFirstPassenger() instanceof LivingEntity livingentity)
{
if (livingentity.zza < -this.climbspeed && this.highness >= this.climbspeed)
return this.highness - this.climbspeed;
if (livingentity.zza > this.climbspeed && this.highness <= 1.0f - this.climbspeed)
return this.highness + this.climbspeed;
}
return this.highness;
}
}

View File

@@ -1,7 +1,9 @@
package ru.magistu.siegemachines.entity.machine;
import net.minecraft.client.KeyMapping;
import ru.magistu.siegemachines.SiegeMachines;
import ru.magistu.siegemachines.gui.machine.MachineContainer;
import ru.magistu.siegemachines.client.KeyBindings;
import ru.magistu.siegemachines.client.gui.machine.MachineContainer;
import ru.magistu.siegemachines.network.PacketHandler;
import ru.magistu.siegemachines.network.PacketMachine;
import net.minecraft.advancements.CriteriaTriggers;
@@ -35,22 +37,21 @@ import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.network.NetworkHooks;
import org.jetbrains.annotations.NotNull;
import ru.magistu.siegemachines.util.CartesianGeometry;
import javax.annotation.Nullable;
public abstract class Machine extends Mob implements MenuProvider
{
public MachineInventory inventory = new MachineInventory();
public static int rows = 1;
public KeyMapping usekey;
public MachineInventory inventory;
public final MachineType type;
private float turretpitch = -25.0f;
private float turretpitchprev = this.turretpitch;
protected float turretpitch = -25.0f;
protected float turretpitchprev = this.turretpitch;
protected float turretpitchdest = this.turretpitch;
private float turretyaw = 0.0f;
private float turretyawprev = this.turretyaw;
protected float turretyaw = 0.0f;
protected float turretyawprev = this.turretyaw;
protected float turretyawdest = this.turretyaw;
protected float yawdest = this.getYRot();
@@ -63,13 +64,18 @@ public abstract class Machine extends Mob implements MenuProvider
{
super(entitytype, level);
this.type = type;
this.delayticks = this.type.delaytime;
rows = this.type.rows;
this.delayticks = this.type.specs.delaytime.get();
this.inventory = new MachineInventory(9 * this.type.containerrows);
if (level.isClientSide())
this.usekey = KeyBindings.getUseKey(type);
this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(type.specs.durability.get());
this.setHealth(type.specs.durability.get());
}
public static AttributeSupplier.Builder setEntityAttributes(MachineType type) {
return Mob.createMobAttributes()
.add(Attributes.MAX_HEALTH, type.health)
.add(Attributes.MAX_HEALTH, type.specs.durability.getDefault())
.add(Attributes.KNOCKBACK_RESISTANCE, 0.5F)
.add(Attributes.MOVEMENT_SPEED, 0.0D)
.add(Attributes.ATTACK_DAMAGE, 0.0D)
@@ -138,148 +144,141 @@ public abstract class Machine extends Mob implements MenuProvider
@Override
public boolean hurt(@NotNull DamageSource damagesource, float f) {
if (!net.minecraftforge.common.ForgeHooks.onLivingAttack(this, damagesource, f)) return false;
if (damagesource.getEntity() instanceof Player
&& !damagesource.isProjectile()
&& !damagesource.isExplosion()
&& !damagesource.isMagic()
&& this.getPassengers().isEmpty()) {
if (this.isInvulnerableTo(damagesource))
return false;
if (this.level.isClientSide)
return false;
if (this.isDeadOrDying())
return false;
if (damagesource.isFire() && this.hasEffect(MobEffects.FIRE_RESISTANCE))
return false;
if (damagesource.getEntity() instanceof Player && !damagesource.isProjectile() && !damagesource.isExplosion() && !damagesource.isMagic() && this.getPassengers().isEmpty())
{
this.spawnAtLocation(this.getMachineItemWithData());
this.remove();
return false;
}
if (this.isInvulnerableTo(damagesource)) {
return false;
} else if (this.level.isClientSide) {
return false;
} else if (this.isDeadOrDying()) {
return false;
} else if (damagesource.isFire() && this.hasEffect(MobEffects.FIRE_RESISTANCE)) {
return false;
} else {
f = adjustDamage(damagesource, f);
}
f = adjustDamage(damagesource, f);
this.noActionTime = 0;
this.noActionTime = 0;
this.animationSpeed = 1.5F;
boolean flag1 = true;
if ((float) this.invulnerableTime > 10.0F)
this.animationSpeed = 1.5F;
boolean flag1 = true;
if ((float) this.invulnerableTime > 10.0F)
{
if (f <= this.lastHurt)
{
if (f <= this.lastHurt)
{
return false;
}
this.actuallyHurt(damagesource, f - this.lastHurt);
this.lastHurt = f;
flag1 = false;
}
else
{
this.lastHurt = f;
this.invulnerableTime = 20;
this.actuallyHurt(damagesource, f);
this.hurtDuration = 10;
this.hurtTime = this.hurtDuration;
return false;
}
this.hurtDir = 0.0F;
Entity entity1 = damagesource.getEntity();
if (entity1 != null)
this.actuallyHurt(damagesource, f - this.lastHurt);
this.lastHurt = f;
flag1 = false;
}
else
{
this.lastHurt = f;
this.invulnerableTime = 20;
this.actuallyHurt(damagesource, f);
this.hurtDuration = 10;
this.hurtTime = this.hurtDuration;
}
this.hurtDir = 0.0F;
Entity entity1 = damagesource.getEntity();
if (entity1 != null)
{
if (entity1 instanceof LivingEntity)
{
if (entity1 instanceof LivingEntity)
{
this.setLastHurtByMob((LivingEntity) entity1);
}
if (entity1 instanceof Player)
{
this.lastHurtByPlayerTime = 1;
this.lastHurtByPlayer = (Player) entity1;
}
else if (entity1 instanceof TamableAnimal wolfEntity) {
if (wolfEntity.isTame()) {
this.lastHurtByPlayerTime = 100;
LivingEntity livingentity = wolfEntity.getOwner();
if (livingentity != null && livingentity.getType() == EntityType.PLAYER) {
this.lastHurtByPlayer = (Player) livingentity;
}
else {
this.lastHurtByPlayer = null;
}
}
}
this.setLastHurtByMob((LivingEntity) entity1);
}
if (flag1) {
if (damagesource instanceof EntityDamageSource && ((EntityDamageSource) damagesource).isThorns()) {
this.level.broadcastEntityEvent(this, (byte) 33);
}
if (entity1 instanceof Player)
{
this.lastHurtByPlayerTime = 1;
this.lastHurtByPlayer = (Player) entity1;
}
else {
byte b0;
else if (entity1 instanceof TamableAnimal wolfEntity) {
if (wolfEntity.isTame()) {
this.lastHurtByPlayerTime = 100;
LivingEntity livingentity = wolfEntity.getOwner();
if (damagesource.isFire()) {
b0 = 37;
}
else if (damagesource == DamageSource.SWEET_BERRY_BUSH) {
b0 = 44;
if (livingentity != null && livingentity.getType() == EntityType.PLAYER) {
this.lastHurtByPlayer = (Player) livingentity;
}
else {
b0 = 2;
this.lastHurtByPlayer = null;
}
this.level.broadcastEntityEvent(this, b0);
}
this.markHurt();
if (entity1 != null)
{
double d1 = entity1.getX() - this.getX();
double d0;
for (d0 = entity1.getZ() - this.getZ(); d1 * d1 + d0 * d0 < 1.0E-4D; d0 = (Math.random() - Math.random()) * 0.01D)
{
d1 = (Math.random() - Math.random()) * 0.01D;
}
this.hurtDir = (float) (Mth.atan2(d0, d1) * (double) (180F / (float) Math.PI) - (double) this.getYRot());
}
else
{
this.hurtDir = (float) ((int) (Math.random() * 2.0D) * 180);
}
}
if (this.isDeadOrDying())
{
SoundEvent soundevent = this.getDeathSound();
if (flag1 && soundevent != null)
{
this.playSound(soundevent, this.getSoundVolume(), this.getVoicePitch());
}
this.die(damagesource);
}
else if (flag1)
{
this.playHurtSound(damagesource);
}
if (entity1 instanceof ServerPlayer)
{
CriteriaTriggers.PLAYER_HURT_ENTITY.trigger((ServerPlayer) entity1, this, damagesource, f, f, false);
}
return true;
}
if (flag1) {
if (damagesource instanceof EntityDamageSource && ((EntityDamageSource) damagesource).isThorns()) {
this.level.broadcastEntityEvent(this, (byte) 33);
}
else {
byte b0;
if (damagesource.isFire()) {
b0 = 37;
}
else if (damagesource == DamageSource.SWEET_BERRY_BUSH) {
b0 = 44;
}
else {
b0 = 2;
}
this.level.broadcastEntityEvent(this, b0);
}
this.markHurt();
if (entity1 != null)
{
double d1 = entity1.getX() - this.getX();
double d0;
for (d0 = entity1.getZ() - this.getZ(); d1 * d1 + d0 * d0 < 1.0E-4D; d0 = (Math.random() - Math.random()) * 0.01D)
{
d1 = (Math.random() - Math.random()) * 0.01D;
}
this.hurtDir = (float) (Mth.atan2(d0, d1) * (double) (180F / (float) Math.PI) - (double) this.getYRot());
}
else
{
this.hurtDir = (float) ((int) (Math.random() * 2.0D) * 180);
}
}
if (this.isDeadOrDying())
{
SoundEvent soundevent = this.getDeathSound();
if (flag1 && soundevent != null)
{
this.playSound(soundevent, this.getSoundVolume(), this.getVoicePitch());
}
this.die(damagesource);
}
else if (flag1)
{
this.playHurtSound(damagesource);
}
if (entity1 instanceof ServerPlayer)
{
CriteriaTriggers.PLAYER_HURT_ENTITY.trigger((ServerPlayer) entity1, this, damagesource, f, f, false);
}
return true;
}
@Override
@@ -332,7 +331,7 @@ public abstract class Machine extends Mob implements MenuProvider
}
nbt.put("Items", listnbt);
nbt.put("TurretRotations", this.newFloatList(this.turretpitch, this.turretyaw));
nbt.putInt("DealyTicks", this.delayticks);
nbt.putInt("DelayTicks", this.delayticks);
nbt.putInt("UseTicks", this.useticks);
}
@@ -430,9 +429,9 @@ public abstract class Machine extends Mob implements MenuProvider
ListTag turretrotations = nbt.getList("TurretRotations", 5);
setTurretRotations(turretrotations.getFloat(0), turretrotations.getFloat(1));
}
if (nbt.contains("DealyTicks"))
if (nbt.contains("DelayTicks"))
{
this.delayticks = nbt.getInt("DealyTicks");
this.delayticks = nbt.getInt("DelayTicks");
}
if (nbt.contains("UseTicks"))
{
@@ -613,7 +612,7 @@ public abstract class Machine extends Mob implements MenuProvider
public Vec3 getDismountLocationForPassenger(LivingEntity entity) {
double yaw = (this.getGlobalTurretYaw()) * Math.PI / 180.0;
return this.position().add(applyRotations(this.type.passengerpos, 0.0, yaw));
return this.position().add(CartesianGeometry.applyRotations(this.type.passengerpos, 0.0, yaw));
}
@Override
@@ -626,18 +625,27 @@ public abstract class Machine extends Mob implements MenuProvider
MoveFunction setPos = Entity::setPos;
if (this.hasPassenger(entity)) {
double yaw = (this.getGlobalTurretYaw()) * Math.PI / 180.0;
Vec3 pos = this.position().add(applyRotations(this.type.passengerpos, 0.0, yaw));
Vec3 pos = this.position().add(CartesianGeometry.applyRotations(this.type.passengerpos, 0.0, yaw));
setPos.accept(entity, pos.x, pos.y, pos.z);
}
}
public static class MachineInventory implements Container, Nameable {
public NonNullList<ItemStack> items = NonNullList.withSize(9 * rows, ItemStack.EMPTY);
public static class MachineInventory implements Container, Nameable
{
private final int containersize;
public NonNullList<ItemStack> items;
public MachineInventory(int rows)
{
this.containersize = 9 * rows;
this.items = NonNullList.withSize(this.containersize, ItemStack.EMPTY);
}
@Override
public int getContainerSize() {
return 9 * rows;
public int getContainerSize()
{
return this.containersize;
}
@Override
@@ -675,8 +683,9 @@ public abstract class Machine extends Mob implements MenuProvider
}
@Override
public void clearContent() {
this.items = NonNullList.withSize(9 * rows, ItemStack.EMPTY);
public void clearContent()
{
this.items = NonNullList.withSize(this.containersize, ItemStack.EMPTY);
}
public boolean containsItem(Item item) {

View File

@@ -1,71 +1,99 @@
package ru.magistu.siegemachines.entity.machine;
import ru.magistu.siegemachines.entity.projectile.ProjectileBuilder;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.phys.Vec3;
import ru.magistu.siegemachines.config.SiegeMachineSpecs;
import ru.magistu.siegemachines.config.SpecsConfig;
import ru.magistu.siegemachines.entity.projectile.ProjectileBuilder;
import ru.magistu.siegemachines.item.ModItems;
public enum MachineType {
MORTAR(80, 1, 0.0f, 85.0f, 0.0f, 0.0f, 0.5f, 0.5f, true, 10, 10, 200,
public class MachineType
{
public static MachineType MORTAR = new MachineType(
SpecsConfig.MORTAR, 1, 0.0f, 85.0f, 0.0f, 0.0f, 0.5f, 0.5f, true, 10, 10,
new Vec3(17.0, 0.0, -10.0).scale(1 / 16.0), new Vec3(0.0, 17.0, 7.0).scale(1 / 16.0), new Vec3(0.0, 0.0, 12.0).scale(1 / 16.0),
2.5f, 0.2f, ProjectileBuilder.CANNON_AMMO, true),
CULVERIN(80, 1, 0.0f, 85.0f, 0.0f, 0.0f, 0.5f, 0.5f, true, 10, 10, 200,
new Vec3(30.0, 0.0, -40.0).scale(1 / 16.0), new Vec3(0.0, 17.0, 7.0).scale(1 / 16.0), new Vec3(0.0, 0.0, 12.0).scale(1 / 16.0),
3.0f, 0.2f, ProjectileBuilder.CANNON_AMMO, true),
TREBUCHET(300, 1, -45.0f, 75.0f, 0.0f, 0.0f, 0.1f, 0.5f, true, 38, 137, 400,
new Vec3(40.0, 0.0, -60.0).scale(1 / 16.0), new Vec3(0.0, 19.0, -3.0), new Vec3(0.0, 10.0, -1.0),
2.8f, 0.2f, ProjectileBuilder.THROWING_AMMO, false),
CATAPULT(100, 1, 0.0f, 75.0f, 0.0f, 0.0f, 0.2f, 1.0f, true, 2, 10, 200,
new Vec3(30.0, 0.0, -40.0).scale(1 / 16.0), new Vec3(0.0, 51.0, -5.0).scale(1 / 16.0), new Vec3(0.0, 0.0, 0.0),
2.0f, 0.2f, ProjectileBuilder.THROWING_AMMO, false),
BALLISTA(50, 1, -30.0f, 60.0f, -180.0f, 180.0f, 4.5f, 0.0f, false, 1, 20, 120,
new Vec3(0.0, 0.0, -30.0).scale(1 / 16.0), new Vec3(0.0, 22.5, 0.0).scale(1 / 16.0), new Vec3(0.0, 0.0, 17.0).scale(1 / 16.0),
4.5f, 0.04f, ProjectileBuilder.BALLISTA_AMMO, false),
BATTERING_RAM(250, 1, 0.0f, 0.0f, 0.0f, 0.0f, 0.1f, 0.0f, false, 5, 5, 100,
new Vec3(12.0, 0.0, -48.0).scale(1 / 16.0), new Vec3(0.0, 26.0, 36.0).scale(1 / 16.0), new Vec3(0.0, 0.0, 32.0).scale(1 / 16.0),
0.0f, 0.5f, ProjectileBuilder.NO_AMMO, false);
ProjectileBuilder.CANNON_AMMO, true,
new ItemStack[] {new ItemStack(Items.OAK_PLANKS, 2), new ItemStack(ModItems.BEAM.get(), 1), new ItemStack(Items.STICK, 5), new ItemStack(Items.IRON_NUGGET, 21)});
public final int health;
public final int rows;
public static MachineType CULVERIN = new MachineType(
SpecsConfig.CULVERIN, 1, 4.0f, 18.5f, 0.0f, 0.0f, 0.4f, 0.1f, true, 10, 10,
new Vec3(15.0, 0.0, -35.0).scale(1 / 16.0), new Vec3(0.0, 18.0, 18.0).scale(1 / 16.0), new Vec3(0.0, 8.0, 12.0).scale(1 / 16.0),
ProjectileBuilder.CANNON_AMMO, true,
new ItemStack[] {new ItemStack(Items.OAK_PLANKS, 3), new ItemStack(ModItems.BEAM.get(), 2), new ItemStack(Items.STICK, 10), new ItemStack(Items.IRON_NUGGET, 32)});
public static MachineType TREBUCHET = new MachineType(
SpecsConfig.TREBUCHET, 1, -45.0f, 75.0f, 0.0f, 0.0f, 0.05f, 0.5f, true, 38, 137,
new Vec3(40.0, 0.0, -60.0).scale(1 / 16.0), new Vec3(0.0, 19.0, -3.0), new Vec3(0.0, 10.0, -1.0),
ProjectileBuilder.GIANT_THROWING_AMMO, false,
new ItemStack[] {new ItemStack(Items.OAK_PLANKS, 8), new ItemStack(ModItems.BEAM.get(), 12), new ItemStack(Items.STICK, 20), new ItemStack(Items.IRON_NUGGET, 36), new ItemStack(Items.COBBLESTONE, 2)});
public static MachineType CATAPULT = new MachineType(
SpecsConfig.CATAPULT, 1, 0.0f, 75.0f, 0.0f, 0.0f, 0.2f, 1.0f, true, 2, 10,
new Vec3(30.0, 0.0, -40.0).scale(1 / 16.0), new Vec3(0.0, 51.0, -5.0).scale(1 / 16.0), new Vec3(0.0, 0.0, 0.0),
ProjectileBuilder.THROWING_AMMO, false,
new ItemStack[] {new ItemStack(Items.OAK_PLANKS, 5), new ItemStack(ModItems.BEAM.get(), 6), new ItemStack(Items.STICK, 10), new ItemStack(Items.IRON_NUGGET, 14)});
public static MachineType BALLISTA = new MachineType(
SpecsConfig.BALLISTA, 1, -30.0f, 60.0f, -180.0f, 180.0f, 0.0f, 4.5f, false, 1, 20,
new Vec3(0.0, 0.0, -30.0).scale(1 / 16.0), new Vec3(0.0, 22.5, 0.0).scale(1 / 16.0), new Vec3(0.0, 0.0, 17.0).scale(1 / 16.0),
ProjectileBuilder.BALLISTA_AMMO, false,
new ItemStack[] {new ItemStack(Items.OAK_PLANKS, 2), new ItemStack(ModItems.BEAM.get(), 1), new ItemStack(Items.STICK, 5), new ItemStack(Items.IRON_NUGGET, 8)});
public static MachineType BATTERING_RAM = new MachineType(
SpecsConfig.BATTERING_RAM, 1, 0.0f, 0.0f, 0.0f, 0.0f, 0.1f, 0.1f, false, 5, 5,
new Vec3(12.0, 0.0, -48.0).scale(1 / 16.0), new Vec3(0.0, 26.0, 36.0).scale(1 / 16.0), new Vec3(0.0, 0.0, 32.0).scale(1 / 16.0),
ProjectileBuilder.NO_AMMO, false,
new ItemStack[] {new ItemStack(Items.OAK_PLANKS, 6), new ItemStack(ModItems.BEAM.get(), 8), new ItemStack(Items.STICK, 12), new ItemStack(Items.IRON_NUGGET, 8)});
public static MachineType SIEGE_LADDER = new MachineType(
SpecsConfig.SIEGE_LADDER, 1, 0.0f, 0.0f, 0.0f, 0.0f, 0.1f, 0.1f, false, 5, 5,
new Vec3(0.0, 0.0, -56.0).scale(1 / 16.0), new Vec3(0.0, 26.0, 36.0).scale(1 / 16.0), new Vec3(0.0, 0.0, 32.0).scale(1 / 16.0),
ProjectileBuilder.NO_AMMO, false,
new ItemStack[] {new ItemStack(ModItems.BEAM.get(), 4), new ItemStack(Items.STICK, 20)});
public final SiegeMachineSpecs specs;
public final int containerrows;
public final float turretminpitch;
public final float turretmaxpitch;
public final float turretminyaw;
public final float turretmaxyaw;
public final float rotationspeed;
public final float turretspeed;
public final float rotationspeed;
public final boolean yawfirst;
public final int userealisetime;
public final int usetime;
public final int delaytime;
public final Vec3 passengerpos;
public final Vec3 turretpivot;
public final Vec3 turretvector;
public final float projectilespeed;
public final float inaccuracy;
public final ProjectileBuilder[] ammo;
public final ProjectileBuilder<?>[] ammo;
public final boolean usesgunpowder;
public final ItemStack[] wreckage;
MachineType(
int health,
int rows,
SiegeMachineSpecs specs,
int containerrows,
float turretminpitch,
float turretmaxpitch,
float turretminyaw,
float turretmaxyaw,
float rotationspeed,
float turretspeed,
float rotationspeed,
boolean yawfirst,
int shootingtime,
int usetime,
int delaytime,
Vec3 passengerpos,
Vec3 turretpivot,
Vec3 turretvector,
float projectilespeed,
float inaccuracy,
ProjectileBuilder[] ammo,
boolean usesgunpowder)
ProjectileBuilder<?>[] ammo,
boolean usesgunpowder,
ItemStack[] wreckage)
{
this.health = health;
this.rows = rows;
this.specs = specs;
this.containerrows = containerrows;
this.turretminpitch = turretminpitch;
this.turretmaxpitch = turretmaxpitch;
this.turretminyaw = turretminyaw;
@@ -75,13 +103,11 @@ public enum MachineType {
this.yawfirst = yawfirst;
this.userealisetime = shootingtime;
this.usetime = usetime;
this.delaytime = delaytime;
this.passengerpos = passengerpos;
this.turretpivot = turretpivot;
this.turretvector = turretvector;
this.projectilespeed = projectilespeed;
this.inaccuracy = inaccuracy;
this.ammo = ammo;
this.usesgunpowder = usesgunpowder;
this.wreckage = wreckage;
}
}

View File

@@ -1,14 +1,15 @@
package ru.magistu.siegemachines.entity.machine;
import net.minecraft.client.Minecraft;
import net.minecraft.network.chat.Component;
import ru.magistu.siegemachines.SiegeMachines;
import ru.magistu.siegemachines.client.SoundTypes;
import ru.magistu.siegemachines.entity.IReloading;
import ru.magistu.siegemachines.gui.machine.crosshair.Crosshair;
import ru.magistu.siegemachines.gui.machine.crosshair.ReloadingCrosshair;
import ru.magistu.siegemachines.client.gui.machine.crosshair.Crosshair;
import ru.magistu.siegemachines.client.gui.machine.crosshair.ReloadingCrosshair;
import ru.magistu.siegemachines.item.ModItems;
import net.minecraft.ChatFormatting;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.network.chat.Component;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
@@ -56,18 +57,18 @@ public class Mortar extends ShootingMachine implements IAnimatable, IReloading
event.getController().setAnimation(MOVING_ANIM);
return PlayState.CONTINUE;
}
}
@Override
public void registerControllers(AnimationData data)
public void registerControllers(AnimationData data)
{
AnimationController<?> wheels_controller = new AnimationController<>(this, "wheels_controller", 1, (t) -> {
double d = this.getWheelsSpeed();
this.wheelsspeed = d > 0 ? Math.min(d, 1.0) : Math.max(d, -1.0);
return wheelspitch += 0.013 * this.wheelsspeed;
}, this::wheels_predicate);
data.addAnimationController(wheels_controller);
}
data.addAnimationController(wheels_controller);
}
@Override
public AnimationFactory getFactory()
@@ -111,21 +112,21 @@ public class Mortar extends ShootingMachine implements IAnimatable, IReloading
}
if (!this.level.isClientSide() && !this.isVehicle())
{
player.startRiding(this);
return InteractionResult.SUCCESS;
}
player.startRiding(this);
return InteractionResult.SUCCESS;
}
return InteractionResult.PASS;
return InteractionResult.PASS;
}
@Override
public void travel(Vec3 pos)
public void travel(Vec3 pos)
{
if (this.isAlive())
if (this.isAlive())
{
if (this.isVehicle())
{
LivingEntity livingentity = (LivingEntity) this.getControllingPassenger();
LivingEntity livingentity = (LivingEntity) this.getControllingPassenger();
this.setTurretRotationsDest(livingentity.getXRot(), livingentity.getYRot() - this.getYaw());
this.setYawDest(livingentity.getYRot());
@@ -133,19 +134,19 @@ public class Mortar extends ShootingMachine implements IAnimatable, IReloading
this.updateYaw();
this.updateTurretRotations();
float f0 = livingentity.xxa * 0.2f;
float f1 = livingentity.zza;
if (f1 <= 0.0f)
float f0 = livingentity.xxa * 0.2f;
float f1 = livingentity.zza;
if (f1 <= 0.0f)
{
f1 *= 0.5f;
}
this.setSpeed(0.04f);
f1 *= 0.5f;
}
this.setSpeed(0.04f);
pos = new Vec3(f0, pos.y, f1);
}
}
super.travel(pos);
}
}
}
}
@Override
public void tick()
@@ -153,7 +154,7 @@ public class Mortar extends ShootingMachine implements IAnimatable, IReloading
if (this.useticks != 0 && --this.useticks <= 0)
{
this.useticks = 0;
this.delayticks = this.type.delaytime;
this.delayticks = this.type.specs.delaytime.get();
}
if (this.shootingticks != 0 && --this.shootingticks <= 0)
@@ -189,10 +190,15 @@ public class Mortar extends ShootingMachine implements IAnimatable, IReloading
this.renderupdateticks = SiegeMachines.RENDER_UPDATE_TIME;
}
if (this.getWheelsSpeed() > 0.0081 && this.wheelssoundticks-- <= 0)
if (this.level.isClientSide() && this.hasControllingPassenger() && this.getWheelsSpeed() > 0.0081 && this.wheelssoundticks-- <= 0)
{
this.level.playLocalSound(this.getX(), this.getY(), this.getZ(), SoundTypes.CANNON_WHEELS.get(), SoundSource.NEUTRAL, 0.3f, 1.0f, true);
this.wheelssoundticks = 20;
Entity passenger = this.getControllingPassenger();
if (Minecraft.getInstance().player == passenger)
{
Vec3 pos = this.position();
this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.CANNON_WHEELS.get(), this.getSoundSource(), 1.5f, 0.85f + this.level.random.nextFloat() * 0.3f, false);
this.wheelssoundticks = 20;
}
}
super.tick();
@@ -205,7 +211,7 @@ public class Mortar extends ShootingMachine implements IAnimatable, IReloading
{
if (!this.level.isClientSide())
{
this.level.playSound(null, this.getX(), this.getY(), this.getZ(), SoundTypes.FUSE.get(), SoundSource.BLOCKS, this.getVolumeFromDist(this.distanceTo(player)), 0.8f);
this.level.playSound(null, this.getX(), this.getY(), this.getZ(), SoundTypes.FUSE.get(), this.getSoundSource(), this.getVolumeFromDist(this.distanceTo(player)), 0.8f);
}
this.useticks = this.type.usetime;
this.shootingticks = this.type.userealisetime;
@@ -227,7 +233,7 @@ public class Mortar extends ShootingMachine implements IAnimatable, IReloading
this.blowParticles(ParticleTypes.FLAME, 0.035, 25);
this.blowParticles(ParticleTypes.CLOUD, 0.2, 60);
Vec3 pos = this.position();
this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.MORTAR_SHOOTING.get(), SoundSource.BLOCKS, 1.5f/*this.getVolumeFromDist(1.5f, 64.0f, this.distanceTo(player))*/, 0.85f + this.level.random.nextFloat() * 0.3f, false);
this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.MORTAR_SHOOTING.get(), this.getSoundSource(), 0.3f, 1.0f, false);
}
}

View File

@@ -0,0 +1,78 @@
package ru.magistu.siegemachines.entity.machine;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientboundAddEntityPacket;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.level.Level;
public class Seat extends Entity
{
protected int lerpSteps;
protected double lerpX;
protected double lerpY;
protected double lerpZ;
protected double lerpYRot;
protected double lerpXRot;
public Seat(EntityType entitytype, Level level)
{
super(entitytype, level);
}
@Override
public Packet<?> getAddEntityPacket() {
return new ClientboundAddEntityPacket(this);
}
@Override
protected void defineSynchedData() {}
@Override
protected void readAdditionalSaveData(CompoundTag compound) {}
@Override
protected void addAdditionalSaveData(CompoundTag compound) {}
public boolean shouldRender(double x, double y, double z)
{
return false;
}
public boolean shouldRenderAtSqrDistance(double distance)
{
return false;
}
@Override
public void tick()
{
if (this.lerpSteps > 0)
{
double d0 = this.getX() + (this.lerpX - this.getX()) / (double) this.lerpSteps;
double d2 = this.getY() + (this.lerpY - this.getY()) / (double) this.lerpSteps;
double d4 = this.getZ() + (this.lerpZ - this.getZ()) / (double) this.lerpSteps;
double d6 = Mth.wrapDegrees(this.lerpYRot - (double) this.getYRot());
this.setYRot(this.getYRot() + (float) d6 / (float) this.lerpSteps);
this.setXRot(this.getXRot() + (float) (this.lerpXRot - (double) this.getXRot()) / (float) this.lerpSteps);
--this.lerpSteps;
this.setPos(d0, d2, d4);
this.setRot(this.getYRot(), this.getXRot());
}
super.tick();
}
@Override
public void lerpTo(double x, double y, double z, float yaw, float pitch, int posRotationIncrements, boolean teleport)
{
this.lerpX = x;
this.lerpY = y;
this.lerpZ = z;
this.lerpYRot = yaw;
this.lerpXRot = pitch;
this.lerpSteps = posRotationIncrements;
}
}

View File

@@ -21,6 +21,7 @@ import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import ru.magistu.siegemachines.util.CartesianGeometry;
import java.util.Arrays;
import java.util.Random;
@@ -53,13 +54,14 @@ public abstract class ShootingMachine extends Machine implements IReloading
return;
}
LivingEntity livingentity = (LivingEntity) this.getControllingPassenger();
Projectile projectile = projectilebuilder.factory.create(projectilebuilder.entitytype, this.level, new Vector3d(this.getShotPos().x, this.getShotPos().y, this.getShotPos().z), livingentity == null ? this : livingentity, projectilebuilder.projectilitem);
Vec3 shotpos = this.getShotPos();
Projectile projectile = projectilebuilder.build(this.level, new Vector3d(shotpos.x, shotpos.y, shotpos.z), livingentity == null ? this : livingentity);
if (projectile instanceof Missile)
{
Missile missile = (Missile) projectile;
missile.setItem(new ItemStack(missile.getDefaultItem()));
}
projectile.shootFromRotation(this, this.getTurretPitch(), this.getGlobalTurretYaw(), 0.0f, this.type.projectilespeed, this.type.inaccuracy);
projectile.shootFromRotation(this, this.getTurretPitch(), this.getGlobalTurretYaw(), 0.0f, this.type.specs.projectilespeed.get(), this.type.specs.inaccuracy.get());
this.level.addFreshEntity(projectile);
this.inventory.shrinkItem(projectilebuilder.item);
}
@@ -110,7 +112,7 @@ public abstract class ShootingMachine extends Machine implements IReloading
double pitch = this.getTurretPitch() * Math.PI / 180.0;
double yaw = (this.getViewYRot(0.5f) + this.getTurretYaw()) * Math.PI / 180.0;
return this.position().add(applyRotations(this.type.turretpivot, 0.0, yaw).add(applyRotations(this.type.turretvector, pitch, yaw)));
return this.position().add(CartesianGeometry.applyRotations(this.type.turretpivot, 0.0, yaw).add(CartesianGeometry.applyRotations(this.type.turretvector, pitch, yaw)));
}
protected Vec3 getShotView()
@@ -145,7 +147,7 @@ public abstract class ShootingMachine extends Machine implements IReloading
super.updateMachineRender();
if (!this.level.isClientSide())
{
for (int i = 0; i < rows * 9; ++i)
for (int i = 0; i < this.inventory.getContainerSize(); ++i)
{
if (this.isValidAmmo(this.inventory.getItem(i)))
{

View File

@@ -0,0 +1,290 @@
package ru.magistu.siegemachines.entity.machine;
import net.minecraft.core.BlockPos;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.Mob;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.minecraft.world.phys.shapes.Shapes;
import ru.magistu.siegemachines.SiegeMachines;
import ru.magistu.siegemachines.item.ModItems;
import ru.magistu.siegemachines.util.CartesianGeometry;
import software.bernie.geckolib3.core.IAnimatable;
import software.bernie.geckolib3.core.PlayState;
import software.bernie.geckolib3.core.builder.AnimationBuilder;
import software.bernie.geckolib3.core.builder.ILoopType;
import software.bernie.geckolib3.core.controller.AnimationController;
import software.bernie.geckolib3.core.event.predicate.AnimationEvent;
import software.bernie.geckolib3.core.manager.AnimationData;
import software.bernie.geckolib3.core.manager.AnimationFactory;
import software.bernie.geckolib3.util.GeckoLibUtil;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class SiegeLadder extends Machine implements IAnimatable
{
private final AnimationFactory factory = GeckoLibUtil.createFactory(this);
private static final Vec3 CLIMB_VECTOR = new Vec3(0.0, 130.0, 130.0).scale(1.0 / 16.0);
private static final Vec3 CLIMB_PIVOT_1 = new Vec3(-8.0, 0.0, -37.0).scale(1.0 / 16.0);
private static final Vec3 CLIMB_PIVOT_2 = new Vec3(8.0, 0.0, -37.0).scale(1.0 / 16.0);
private static final int NUMBER_OF_SEATS = 16;
private final List<LadderSeat> leftseats;
private final List<LadderSeat> rightseats;
public final List<LadderSeat> seats;
static AnimationBuilder MOVING_ANIM = new AnimationBuilder().addAnimation("Moving", ILoopType.EDefaultLoopTypes.LOOP);
private int wheelssoundticks = 10;
private double wheelspitch = 0.0;
private double wheelsspeed = 0.0;
public SiegeLadder(EntityType<? extends Mob> entitytype, Level level)
{
super(entitytype, level, MachineType.SIEGE_LADDER);
this.leftseats = Stream.generate(() -> new LadderSeat(this)).limit(NUMBER_OF_SEATS / 2).collect(Collectors.toList());
this.rightseats = Stream.generate(() -> new LadderSeat(this)).limit(NUMBER_OF_SEATS / 2).collect(Collectors.toList());
this.seats = Stream.of(this.leftseats, this.rightseats)
.flatMap(Collection::stream)
.collect(Collectors.toList());
}
private <E extends IAnimatable> PlayState wheels_predicate(AnimationEvent<E> event)
{
event.getController().setAnimation(MOVING_ANIM);
return PlayState.CONTINUE;
}
@Override
public void registerControllers(AnimationData data)
{
AnimationController<?> wheels_controller = new AnimationController<>(this, "wheels_controller", 1, (t) -> {
double d = this.getWheelsSpeed();
this.wheelsspeed = d > 0 ? Math.min(d, 1.0) : Math.max(d, -1.0);
return wheelspitch += 0.015 * this.wheelsspeed;
}, this::wheels_predicate);
data.addAnimationController(wheels_controller);
}
@Override
public AnimationFactory getFactory()
{
return this.factory;
}
@Override
protected InteractionResult mobInteract(Player player, InteractionHand hand)
{
if (player.level.isClientSide() || player.isPassenger())
return InteractionResult.PASS;
if (!this.isVehicle())
{
player.startRiding(this);
return InteractionResult.SUCCESS;
}
LadderSeat seat = this.getFreeSeat(player);
if (seat != null)
{
player.startRiding(seat);
return InteractionResult.SUCCESS;
}
return InteractionResult.FAIL;
}
@Override
public void travel(Vec3 pos)
{
if (this.isAlive())
{
if (this.isVehicle())
{
LivingEntity livingentity = (LivingEntity) this.getControllingPassenger();
this.setYawDest(livingentity.getYRot());
this.updateYaw();
float f1 = livingentity.zza;
if (f1 <= 0.0f)
f1 *= 0.25f;
this.setSpeed(0.04f);
pos = new Vec3(0.0f, pos.y, f1);
}
super.travel(pos);
}
}
@Override
public void tick()
{
if (this.renderupdateticks-- <= 0)
{
this.updateMachineRender();
this.renderupdateticks = SiegeMachines.RENDER_UPDATE_TIME;
}
// if (this.getWheelsSpeed() > 0.0081 && this.wheelssoundticks-- <= 0)
// {
// this.level.playLocalSound(this.getX(), this.getY(), this.getZ(), SoundTypes.RAM_WHEELS.get(), SoundCategory.NEUTRAL, 0.6f, 1.0f, true);
// this.wheelssoundticks = 20;
// }
this.seatsTick();
super.tick();
}
public void seatsTick()
{
this.leftseats.forEach(seat -> this.updateSeatPosition(seat, true));
this.rightseats.forEach(seat -> this.updateSeatPosition(seat, false));
}
public void updateSeatPosition(LadderSeat seat, boolean left)
{
double yaw = this.getYRot() * Math.PI / 180.0;
float highness = seat.climb();
Vec3 pos = this.getSeatPosititon(highness, yaw, left);
Optional<Vec3> freepos = this.level.findFreePosition(seat, Shapes.create(AABB.ofSize(pos, 0.1, 0.1, 0.1)), pos, 0.0, 0.0, 0.0);
if (freepos.isPresent() && pos.distanceTo(freepos.get()) < 0.5)
{
seat.setHighness(highness);
pos = freepos.get();
}
else
pos = this.getSeatPosititon(seat, yaw, left);
seat.moveTo(pos);
}
@Override
public void onRemovedFromWorld()
{
for (LadderSeat seat : this.seats)
seat.discard();
super.onRemovedFromWorld();
}
@Override
public void onAddedToWorld()
{
this.seats.forEach(seat -> this.getLevel().addFreshEntity(seat));
super.onAddedToWorld();
}
@Override
public void use(Player player)
{
if (this.getControllingPassenger() == player)
{
LadderSeat seat = this.getFreeSeat(player);
if (seat != null)
player.startRiding(seat);
}
}
@Override
public void useRealise()
{
}
public double getWheelsSpeed()
{
if (this.isOnGround())
{
return this.getViewVector(5.0f).multiply(1, 0, 1).dot(this.getDeltaMovement());
}
return 0.0;
}
@Override
public Item getMachineItem()
{
return ModItems.SIEGE_LADDER.get();
}
protected Vec3 getSeatPosititon(LadderSeat seat, double yaw, boolean left)
{
return getSeatPosititon(seat.getHighness(), yaw, left);
}
protected Vec3 getSeatPosititon(float highness, double yaw, boolean left)
{
return this.position().add(CartesianGeometry.applyRotations((left ? CLIMB_PIVOT_1 : CLIMB_PIVOT_2).add(CLIMB_VECTOR.scale(highness)), 0.0, yaw));
}
protected @Nullable LadderSeat getFreeSeat(Player player)
{
AtomicReference<LadderSeat> left = new AtomicReference<>(null);
AtomicReference<LadderSeat> right = new AtomicReference<>(null);
long l1 = this.leftseats.stream().filter(seat -> {
if (seat.isVehicle())
return true;
else
{
left.set(seat);
return false;
}}).count();
long l2 = this.rightseats.stream().filter(seat -> {
if (seat.isVehicle())
return true;
else
{
right.set(seat);
return false;
}}).count();
if (l1 < l2)
return left.get();
else if (l1 == l2 && player != null)
{
Vec3 view = this.getViewVector(0.0f);
return player.position().subtract(this.position()).dot(new Vec3(view.z, 0.0, -view.x).normalize()) > 0.0 ? right.get() : left.get();
}
return right.get();
}
@Override
public void push(Entity entity)
{
}
@Override
public void push(double x, double y, double z)
{
}
}

View File

@@ -2,8 +2,8 @@ package ru.magistu.siegemachines.entity.machine;
import ru.magistu.siegemachines.SiegeMachines;
import ru.magistu.siegemachines.client.SoundTypes;
import ru.magistu.siegemachines.gui.machine.crosshair.Crosshair;
import ru.magistu.siegemachines.gui.machine.crosshair.ReloadingCrosshair;
import ru.magistu.siegemachines.client.gui.machine.crosshair.Crosshair;
import ru.magistu.siegemachines.client.gui.machine.crosshair.ReloadingCrosshair;
import ru.magistu.siegemachines.item.ModItems;
import net.minecraft.sounds.SoundSource;
import net.minecraft.world.InteractionHand;
@@ -18,6 +18,7 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import ru.magistu.siegemachines.util.CartesianGeometry;
import software.bernie.geckolib3.core.IAnimatable;
import software.bernie.geckolib3.core.PlayState;
import software.bernie.geckolib3.core.builder.AnimationBuilder;
@@ -81,7 +82,7 @@ public class Trebuchet extends ShootingMachine implements IAnimatable
}
return PlayState.CONTINUE;
}
}
private void tickPart(MachinePartEntity subentity, double p_226526_2_, double p_226526_4_, double p_226526_6_)
{
@@ -93,7 +94,7 @@ public class Trebuchet extends ShootingMachine implements IAnimatable
{
Vec3[] avector3d = new Vec3[this.subentities.length];
Vec3 pos = this.position().add(applyRotations(this.backsidepos, 0.0, this.getYaw()));
Vec3 pos = this.position().add(CartesianGeometry.applyRotations(this.backsidepos, 0.0, this.getYaw()));
this.tickPart(this.backside, pos.x, pos.y, pos.z);
for(int i = 0; i < this.subentities.length; ++i)
@@ -103,20 +104,20 @@ public class Trebuchet extends ShootingMachine implements IAnimatable
for(int i = 0; i < this.subentities.length; ++i)
{
this.subentities[i].xo = avector3d[i].x;
this.subentities[i].yo = avector3d[i].y;
this.subentities[i].zo = avector3d[i].z;
this.subentities[i].xOld = avector3d[i].x;
this.subentities[i].yOld = avector3d[i].y;
this.subentities[i].zOld = avector3d[i].z;
this.subentities[i].xo = avector3d[i].x;
this.subentities[i].yo = avector3d[i].y;
this.subentities[i].zo = avector3d[i].z;
this.subentities[i].xOld = avector3d[i].x;
this.subentities[i].yOld = avector3d[i].y;
this.subentities[i].zOld = avector3d[i].z;
}
super.aiStep();
}
public MachinePartEntity[] getSubEntities() {
return this.subentities;
}
return this.subentities;
}
@Override
public net.minecraftforge.entity.PartEntity<?>[] getParts()
@@ -125,18 +126,18 @@ public class Trebuchet extends ShootingMachine implements IAnimatable
}
@Override
public void registerControllers(AnimationData data)
public void registerControllers(AnimationData data)
{
AnimationController<?> controller = new AnimationController<>(this, "controller", 1, (t) ->
{
if (this.state.equals(State.RELOADING))
{
return (double) (this.type.delaytime - this.delayticks) / this.type.delaytime;
return (double) (this.type.specs.delaytime.get() - this.delayticks) / this.type.specs.delaytime.get();
}
return t;
}, this::predicate);
data.addAnimationController(controller);
}
data.addAnimationController(controller);
}
@Override
public AnimationFactory getFactory()
@@ -155,11 +156,11 @@ public class Trebuchet extends ShootingMachine implements IAnimatable
}
if (!this.level.isClientSide() && !this.isVehicle())
{
player.startRiding(this);
return InteractionResult.SUCCESS;
}
player.startRiding(this);
return InteractionResult.SUCCESS;
}
return InteractionResult.PASS;
return InteractionResult.PASS;
}
public void startShooting(Player player)
@@ -171,7 +172,7 @@ public class Trebuchet extends ShootingMachine implements IAnimatable
this.shootingticks = this.type.userealisetime;
Vec3 pos = this.position();
this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.TREBUCHET_SHOOTING.get(), SoundSource.BLOCKS, 1.0f, 1.0f, false);
this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.TREBUCHET_SHOOTING.get(), this.getSoundSource(), 1.0f, 1.0f, false);
}
}
@@ -185,23 +186,23 @@ public class Trebuchet extends ShootingMachine implements IAnimatable
}
@Override
public void travel(Vec3 pos)
public void travel(Vec3 pos)
{
if (this.isAlive())
if (this.isAlive())
{
if (this.isVehicle() && this.useticks <= 0 && this.delayticks <= 0)
{
LivingEntity livingentity = (LivingEntity) this.getControllingPassenger();
LivingEntity livingentity = (LivingEntity) this.getControllingPassenger();
this.setTurretRotations(livingentity.getXRot(), this.getTurretYaw());
this.updateTurretRotations();
this.setYawDest(livingentity.getYRot());
this.updateYaw();
}
}
super.travel(pos);
}
}
}
}
@Override
public void tick()
@@ -210,7 +211,7 @@ public class Trebuchet extends ShootingMachine implements IAnimatable
{
this.state = State.RELOADING;
this.useticks = 0;
this.delayticks = this.type.delaytime;
this.delayticks = this.type.specs.delaytime.get();
}
if (this.shootingticks != 0 && --this.shootingticks <= 0)
@@ -229,7 +230,7 @@ public class Trebuchet extends ShootingMachine implements IAnimatable
if (this.delayticks % 40 == 0)
{
Vec3 pos = this.position();
this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.TREBUCHET_RELOADING.get(), SoundSource.BLOCKS, 1.0f, 1.0f, false);
this.level.playLocalSound(pos.x, pos.y, pos.z, SoundTypes.TREBUCHET_RELOADING.get(), this.getSoundSource(), 1.0f, 1.0f, false);
}
if (--this.delayticks <= 0)
{

View File

@@ -15,7 +15,7 @@ public class Cannonball extends Missile
this.item = ModItems.CANNONBALL.get();
}
public Cannonball(EntityType<Stone> entitytype, Level level, Vector3d pos, LivingEntity entity, Item item)
public Cannonball(EntityType<Cannonball> entitytype, Level level, Vector3d pos, LivingEntity entity, Item item)
{
super(entitytype, level, pos, entity, MissileType.CANNONBALL, item);
}

View File

@@ -0,0 +1,23 @@
package ru.magistu.siegemachines.entity.projectile;
import com.mojang.math.Vector3d;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.Level;
import ru.magistu.siegemachines.item.ModItems;
public class GiantStone extends Missile
{
public GiantStone(EntityType<GiantStone> entitytype, Level level)
{
super(entitytype, level);
this.item = ModItems.GIANT_STONE.get();
}
public GiantStone(EntityType<GiantStone> entitytype, Level level, Vector3d pos, LivingEntity entity, Item item)
{
super(entitytype, level, pos, entity, MissileType.GIANT_STONE, item);
}
}

View File

@@ -1,6 +1,7 @@
package ru.magistu.siegemachines.entity.projectile;
import com.mojang.math.Vector3d;
import net.minecraft.world.level.ExplosionDamageCalculator;
import ru.magistu.siegemachines.item.ModItems;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
@@ -32,18 +33,20 @@ import net.minecraft.world.phys.Vec3;
import net.minecraftforge.network.NetworkHooks;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
public abstract class Missile extends ThrowableItemProjectile
{
public MissileType type = MissileType.STONE;
public Item item = ModItems.STONE.get();
public Missile(EntityType<? extends Missile> entitytype, Level level)
{
{
super(entitytype, level);
}
public Missile(EntityType<? extends Missile> entitytype, Level level, Vector3d pos, LivingEntity entity, MissileType type, Item item)
{
{
super(entitytype, entity, level);
this.type = type;
this.item = item;
@@ -58,20 +61,20 @@ public abstract class Missile extends ThrowableItemProjectile
@Override
public @NotNull Packet<?> getAddEntityPacket()
{
{
return NetworkHooks.getEntitySpawningPacket(this);
}
@Override
public void onHit(HitResult result)
{
{
float f = 2.0F;
if (result.getType() == HitResult.Type.ENTITY)
{
{
EntityHitResult entityRTR = (EntityHitResult)result;
Vec3 pos = entityRTR.getLocation();
Entity entity = entityRTR.getEntity();
float damage = this.type.mass * (float) this.getDeltaMovement().length();
float damage = this.type.specs.mass.get() * (float) this.getDeltaMovement().length();
DamageSource damagesource = DamageSource.thrown(this, this.getOwner());
if (this.type.armorpiercing >= 1.0f)
@@ -86,12 +89,11 @@ public abstract class Missile extends ThrowableItemProjectile
}
}
damage -= (1.0f - this.type.armorpiercing) * (damage - CombatRules.getDamageAfterAbsorb(damage, 0, 0));
damagesource = damagesource.bypassArmor();
}
if (!this.level.isClientSide() && this.type.explosive)
{
this.level.explode(this.getOwner(), pos.x, pos.y, pos.z, 3.0F, Explosion.BlockInteraction.NONE);
{
this.explode(pos.x, pos.y, pos.z, 3.0F, Explosion.BlockInteraction.NONE);
this.remove(RemovalReason.KILLED);
}
@@ -104,24 +106,24 @@ public abstract class Missile extends ThrowableItemProjectile
}
if (result.getType() == HitResult.Type.BLOCK)
{
{
BlockHitResult blockRTR = (BlockHitResult)result;
BlockPos blockpos = blockRTR.getBlockPos();
BlockState blockstate = this.level.getBlockState(blockpos);
boolean smoothimpact = (blockstate == Blocks.SAND.defaultBlockState() ||
blockstate == Blocks.RED_SAND.defaultBlockState() ||
blockstate == Blocks.DIRT.defaultBlockState() ||
blockstate == Blocks.GRASS_BLOCK.defaultBlockState() ||
blockstate == Blocks.DIRT_PATH.defaultBlockState() ||
blockstate == Blocks.COARSE_DIRT.defaultBlockState() ||
blockstate == Blocks.SNOW_BLOCK.defaultBlockState()) &&
blockRTR.getDirection() == Direction.UP;
blockstate == Blocks.RED_SAND.defaultBlockState() ||
blockstate == Blocks.DIRT.defaultBlockState() ||
blockstate == Blocks.GRASS_BLOCK.defaultBlockState() ||
blockstate == Blocks.DIRT_PATH.defaultBlockState() ||
blockstate == Blocks.COARSE_DIRT.defaultBlockState() ||
blockstate == Blocks.SNOW_BLOCK.defaultBlockState()) &&
blockRTR.getDirection() == Direction.UP;
if (blockRTR.getDirection() == Direction.UP)
{
{
if (this.type.explosive)
{
for (int r = 0; r < this.type.explosionradius; ++r)
for (int r = 0; r < this.type.specs.explosionpower.get(); ++r)
{
for (float a = 0; a < 2 * Math.PI; a += Math.PI / 4)
{
@@ -139,30 +141,30 @@ public abstract class Missile extends ThrowableItemProjectile
if (smoothimpact && this.type.explosive)
{
this.level.explode(this.getOwner(), blockpos.getX(), blockpos.getY(), blockpos.getZ(), this.type.explosionradius * f, Explosion.BlockInteraction.NONE);
this.explode(blockpos.getX(), blockpos.getY(), blockpos.getZ(), this.type.specs.explosionpower.get() * f, Explosion.BlockInteraction.NONE);
}
}
else if (smoothimpact)
{
this.dustExplosion(new BlockParticleOption(ParticleTypes.BLOCK, blockstate).setPos(blockpos), blockpos, this.type.explosionradius / 2, 50);
this.dustExplosion(new BlockParticleOption(ParticleTypes.BLOCK, blockstate).setPos(blockpos), blockpos, this.type.specs.explosionpower.get() / 2, 50);
}
}
if (!this.level.isClientSide() && !smoothimpact && this.type.explosive)
{
this.level.explode(this.getOwner(), blockpos.getX(), blockpos.getY(), blockpos.getZ(), this.type.explosionradius * f, Explosion.BlockInteraction.BREAK);
this.explode(blockpos.getX(), blockpos.getY(), blockpos.getZ(), this.type.specs.explosionpower.get() * f, Explosion.BlockInteraction.BREAK);
}
}
if (result.getType() == HitResult.Type.MISS)
{
{
this.level.playSound((Player)this.getOwner(), this.getOnPos(), SoundEvents.ANVIL_BREAK, SoundSource.AMBIENT, 1.0f, 1.0f);
if(!this.level.isClientSide())
{
{
this.remove(RemovalReason.KILLED);
}
}
if (!this.level.isClientSide())
{
{
this.remove(RemovalReason.KILLED);
}
}
@@ -173,19 +175,19 @@ public abstract class Missile extends ThrowableItemProjectile
}
private void dustExplosion(ParticleOptions particle, double x, double y, double z, double speed, int amount)
{
for (int i = 0; i < amount; ++i)
{
{
for (int i = 0; i < amount; ++i)
{
Vec3 movement = this.getDeltaMovement();
double d0 = x - 0.05 + this.level.random.nextDouble() * 0.3;
double d1 = y + 1.0;
double d2 = z - 0.05 + this.level.random.nextDouble() * 0.3;
double d3 = movement.x * this.level.random.nextDouble() * speed;
double d4 = -movement.y * this.level.random.nextDouble() * speed * 10.0f;
double d5 = movement.z * this.level.random.nextDouble() * speed;
this.level.addParticle(particle, d0, d1, d2, d3, d4, d5);
}
}
double d0 = x - 0.05 + this.level.random.nextDouble() * 0.3;
double d1 = y + 1.0;
double d2 = z - 0.05 + this.level.random.nextDouble() * 0.3;
double d3 = movement.x * this.level.random.nextDouble() * speed;
double d4 = -movement.y * this.level.random.nextDouble() * speed * 10.0f;
double d5 = movement.z * this.level.random.nextDouble() * speed;
this.level.addParticle(particle, d0, d1, d2, d3, d4, d5);
}
}
@Override
public void tick()
@@ -197,4 +199,18 @@ public abstract class Missile extends ThrowableItemProjectile
super.tick();
}
public MissileExplosion explode(double x, double y, double z, float radius, Explosion.BlockInteraction mode)
{
return this.explode(null, null, x, y, z, radius, false, mode);
}
public MissileExplosion explode(@Nullable DamageSource source, @Nullable ExplosionDamageCalculator context, double x, double y, double z, float size, boolean fired, Explosion.BlockInteraction mode)
{
MissileExplosion explosion = new MissileExplosion(this.level, this.getOwner(), source, context, x, y, z, size, fired, mode);
if (net.minecraftforge.event.ForgeEventFactory.onExplosionStart(level, explosion)) return explosion;
explosion.explode();
explosion.finalizeExplosion(true);
return explosion;
}
}

View File

@@ -0,0 +1,430 @@
package ru.magistu.siegemachines.entity.projectile;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.mojang.datafixers.util.Pair;
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
import net.minecraft.core.BlockPos;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.item.ItemEntity;
import net.minecraft.world.entity.item.PrimedTnt;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.Projectile;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.enchantment.ProtectionEnchantment;
import net.minecraft.world.level.*;
import net.minecraft.world.level.block.BaseFireBlock;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.gameevent.GameEvent;
import net.minecraft.world.level.material.FluidState;
import net.minecraft.world.level.storage.loot.LootContext;
import net.minecraft.world.level.storage.loot.parameters.LootContextParams;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3;
import ru.magistu.siegemachines.entity.machine.Machine;
import javax.annotation.Nullable;
import java.util.*;
public class MissileExplosion extends Explosion
{
private static final ExplosionDamageCalculator EXPLOSION_DAMAGE_CALCULATOR = new ExplosionDamageCalculator();
private final boolean fire;
private final BlockInteraction blockInteraction;
private final Random random = new Random();
private final Level level;
private final double x;
private final double y;
private final double z;
@Nullable
private final Entity source;
private final float radius;
private final DamageSource damageSource;
private final ExplosionDamageCalculator damageCalculator;
private final List<BlockPos> toBlow = Lists.newArrayList();
private final Map<Player, Vec3> hitPlayers = Maps.newHashMap();
private final Vec3 position;
private float damagemultiplier = 1.0f;
public MissileExplosion(Level level, @Nullable Entity source, double x, double y, double z, float radius)
{
this(level, source, x, y, z, radius, false, BlockInteraction.DESTROY);
}
public MissileExplosion(Level level, @Nullable Entity source, double x, double y, double z, float radius, List<BlockPos> pPositions)
{
this(level, source, x, y, z, radius, false, BlockInteraction.DESTROY, pPositions);
}
public MissileExplosion(Level level, @Nullable Entity source, double x, double y, double z, float radius, boolean fired, BlockInteraction blockinteraction, List<BlockPos> pPositions)
{
this(level, source, x, y, z, radius, fired, blockinteraction);
this.toBlow.addAll(pPositions);
}
public MissileExplosion(Level level, @Nullable Entity source, double x, double y, double z, float radius, boolean fired, BlockInteraction blockinteraction)
{
this(level, source, null, null, x, y, z, radius, fired, blockinteraction);
}
public MissileExplosion(Level level, @Nullable Entity source, @Nullable DamageSource damagesource, @Nullable ExplosionDamageCalculator damagecalculator, double x, double y, double z, float radius, boolean fired, BlockInteraction blockinteraction)
{
super(level, source, damagesource, damagecalculator, x, y, z, radius, fired, blockinteraction);
this.level = level;
this.source = source;
this.radius = radius;
this.x = x;
this.y = y;
this.z = z;
this.fire = fired;
this.blockInteraction = blockinteraction;
this.damageSource = damagesource == null ? DamageSource.explosion(this) : damagesource;
this.damageCalculator = damagecalculator == null ? this.makeDamageCalculator(source) : damagecalculator;
this.position = new Vec3(this.x, this.y, this.z);
if (source != null && source.isPassenger())
{
Entity vehicle = source.getVehicle();
if (vehicle instanceof Machine)
{
this.damagemultiplier = ((Machine) vehicle).type.specs.damagemultiplier.get();
}
}
}
private ExplosionDamageCalculator makeDamageCalculator(@Nullable Entity pEntity)
{
return pEntity == null ? EXPLOSION_DAMAGE_CALCULATOR : new EntityBasedExplosionDamageCalculator(pEntity);
}
public static float getSeenPercent(Vec3 pExplosionVector, Entity pEntity)
{
AABB aabb = pEntity.getBoundingBox();
double d0 = 1.0D / ((aabb.maxX - aabb.minX) * 2.0D + 1.0D);
double d1 = 1.0D / ((aabb.maxY - aabb.minY) * 2.0D + 1.0D);
double d2 = 1.0D / ((aabb.maxZ - aabb.minZ) * 2.0D + 1.0D);
double d3 = (1.0D - Math.floor(1.0D / d0) * d0) / 2.0D;
double d4 = (1.0D - Math.floor(1.0D / d2) * d2) / 2.0D;
if (!(d0 < 0.0D) && !(d1 < 0.0D) && !(d2 < 0.0D))
{
int i = 0;
int j = 0;
for (double d5 = 0.0D; d5 <= 1.0D; d5 += d0)
{
for (double d6 = 0.0D; d6 <= 1.0D; d6 += d1)
{
for (double d7 = 0.0D; d7 <= 1.0D; d7 += d2)
{
double d8 = Mth.lerp(d5, aabb.minX, aabb.maxX);
double d9 = Mth.lerp(d6, aabb.minY, aabb.maxY);
double d10 = Mth.lerp(d7, aabb.minZ, aabb.maxZ);
Vec3 vec3 = new Vec3(d8 + d3, d9, d10 + d4);
if (pEntity.level.clip(new ClipContext(vec3, pExplosionVector, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, pEntity)).getType() == HitResult.Type.MISS)
{
++i;
}
++j;
}
}
}
return (float)i / (float)j;
}
else
{
return 0.0F;
}
}
/**
* Does the first part of the explosion (destroy blocks)
*/
@Override
public void explode()
{
this.level.gameEvent(this.source, GameEvent.EXPLODE, new BlockPos(this.x, this.y, this.z));
Set<BlockPos> set = Sets.newHashSet();
for (int j = 0; j < 16; ++j)
{
for (int k = 0; k < 16; ++k)
{
for (int l = 0; l < 16; ++l)
{
if (j == 0 || j == 15 || k == 0 || k == 15 || l == 0 || l == 15)
{
double d0 = (float) j / 15.0F * 2.0F - 1.0F;
double d1 = (float) k / 15.0F * 2.0F - 1.0F;
double d2 = (float) l / 15.0F * 2.0F - 1.0F;
double d3 = Math.sqrt(d0 * d0 + d1 * d1 + d2 * d2);
d0 /= d3;
d1 /= d3;
d2 /= d3;
float f = this.radius * (0.7F + this.level.random.nextFloat() * 0.6F);
double d4 = this.x;
double d6 = this.y;
double d8 = this.z;
for (; f > 0.0F; f -= 0.22500001F)
{
BlockPos blockpos = new BlockPos(d4, d6, d8);
BlockState blockstate = this.level.getBlockState(blockpos);
FluidState fluidstate = this.level.getFluidState(blockpos);
if (!this.level.isInWorldBounds(blockpos))
{
break;
}
Optional<Float> optional = this.damageCalculator.getBlockExplosionResistance(this, this.level, blockpos, blockstate, fluidstate);
if (optional.isPresent())
{
f -= (optional.get() + 0.3F) * 0.3F;
}
if (f > 0.0F && this.damageCalculator.shouldBlockExplode(this, this.level, blockpos, blockstate, f))
{
set.add(blockpos);
}
d4 += d0 * (double)0.3F;
d6 += d1 * (double)0.3F;
d8 += d2 * (double)0.3F;
}
}
}
}
}
this.toBlow.addAll(set);
float f2 = this.radius * 2.0F;
int k1 = Mth.floor(this.x - (double)f2 - 1.0D);
int l1 = Mth.floor(this.x + (double)f2 + 1.0D);
int i2 = Mth.floor(this.y - (double)f2 - 1.0D);
int i1 = Mth.floor(this.y + (double)f2 + 1.0D);
int j2 = Mth.floor(this.z - (double)f2 - 1.0D);
int j1 = Mth.floor(this.z + (double)f2 + 1.0D);
List<Entity> list = this.level.getEntities(this.source, new AABB(k1, i2, j2, l1, i1, j1));
net.minecraftforge.event.ForgeEventFactory.onExplosionDetonate(this.level, this, list, f2);
Vec3 vec3 = new Vec3(this.x, this.y, this.z);
for (Entity entity : list)
{
if (!entity.ignoreExplosion())
{
double d12 = Math.sqrt(entity.distanceToSqr(vec3)) / (double) f2;
if (d12 <= 1.0D)
{
double d5 = entity.getX() - this.x;
double d7 = (entity instanceof PrimedTnt ? entity.getY() : entity.getEyeY()) - this.y;
double d9 = entity.getZ() - this.z;
double d13 = Math.sqrt(d5 * d5 + d7 * d7 + d9 * d9);
if (d13 != 0.0D)
{
d5 /= d13;
d7 /= d13;
d9 /= d13;
double d14 = getSeenPercent(vec3, entity);
double d10 = (1.0D - d12) * d14;
entity.hurt(this.getDamageSource(), this.damagemultiplier * (int) ((d10 * d10 + d10) / 2.0D * 7.0D * (double) f2 + 1.0D));
double d11 = d10;
if (entity instanceof LivingEntity)
{
d11 = ProtectionEnchantment.getExplosionKnockbackAfterDampener((LivingEntity) entity, d10);
}
entity.setDeltaMovement(entity.getDeltaMovement().add(d5 * d11, d7 * d11, d9 * d11));
if (entity instanceof Player)
{
Player player = (Player) entity;
if (!player.isSpectator() && (!player.isCreative() || !player.getAbilities().flying))
{
this.hitPlayers.put(player, new Vec3(d5 * d10, d7 * d10, d9 * d10));
}
}
}
}
}
}
}
/**
* Does the second part of the explosion (sound, particles, drop spawn)
*/
@Override
public void finalizeExplosion(boolean pSpawnParticles)
{
if (this.level.isClientSide)
{
this.level.playLocalSound(this.x, this.y, this.z, SoundEvents.GENERIC_EXPLODE, SoundSource.BLOCKS, 4.0F, (1.0F + (this.level.random.nextFloat() - this.level.random.nextFloat()) * 0.2F) * 0.7F, false);
}
boolean flag = this.blockInteraction != BlockInteraction.NONE;
if (pSpawnParticles)
{
if (!(this.radius < 2.0F) && flag)
{
this.level.addParticle(ParticleTypes.EXPLOSION_EMITTER, this.x, this.y, this.z, 1.0D, 0.0D, 0.0D);
}
else
{
this.level.addParticle(ParticleTypes.EXPLOSION, this.x, this.y, this.z, 1.0D, 0.0D, 0.0D);
}
}
if (flag)
{
ObjectArrayList<Pair<ItemStack, BlockPos>> objectarraylist = new ObjectArrayList<>();
Collections.shuffle(this.toBlow, new Random(this.level.random.nextInt()));
for (BlockPos blockpos : this.toBlow)
{
BlockState blockstate = this.level.getBlockState(blockpos);
Block block = blockstate.getBlock();
if (!blockstate.isAir())
{
BlockPos blockpos1 = blockpos.immutable();
this.level.getProfiler().push("explosion_blocks");
if (blockstate.canDropFromExplosion(this.level, blockpos, this) && this.level instanceof ServerLevel)
{
BlockEntity blockentity = blockstate.hasBlockEntity() ? this.level.getBlockEntity(blockpos) : null;
LootContext.Builder lootcontext$builder = (new LootContext.Builder((ServerLevel)this.level)).withRandom(this.level.random).withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(blockpos)).withParameter(LootContextParams.TOOL, ItemStack.EMPTY).withOptionalParameter(LootContextParams.BLOCK_ENTITY, blockentity).withOptionalParameter(LootContextParams.THIS_ENTITY, this.source);
if (this.blockInteraction == BlockInteraction.DESTROY)
{
lootcontext$builder.withParameter(LootContextParams.EXPLOSION_RADIUS, this.radius);
}
blockstate.getDrops(lootcontext$builder).forEach((p_46074_) -> {
addBlockDrops(objectarraylist, p_46074_, blockpos1);
});
}
blockstate.onBlockExploded(this.level, blockpos, this);
this.level.getProfiler().pop();
}
}
for (Pair<ItemStack, BlockPos> pair : objectarraylist)
{
Block.popResource(this.level, pair.getSecond(), pair.getFirst());
}
}
if (this.fire)
{
for (BlockPos blockpos2 : this.toBlow)
{
if (this.random.nextInt(3) == 0 && this.level.getBlockState(blockpos2).isAir() && this.level.getBlockState(blockpos2.below()).isSolidRender(this.level, blockpos2.below()))
{
this.level.setBlockAndUpdate(blockpos2, BaseFireBlock.getState(this.level, blockpos2));
}
}
}
}
private static void addBlockDrops(ObjectArrayList<Pair<ItemStack, BlockPos>> pDropPositionArray, ItemStack pStack, BlockPos pPos)
{
int i = pDropPositionArray.size();
for (int j = 0; j < i; ++j)
{
Pair<ItemStack, BlockPos> pair = pDropPositionArray.get(j);
ItemStack itemstack = pair.getFirst();
if (ItemEntity.areMergable(itemstack, pStack))
{
ItemStack itemstack1 = ItemEntity.merge(itemstack, pStack, 16);
pDropPositionArray.set(j, Pair.of(itemstack1, pair.getSecond()));
if (pStack.isEmpty())
{
return;
}
}
}
pDropPositionArray.add(Pair.of(pStack, pPos));
}
@Override
public DamageSource getDamageSource()
{
return this.damageSource;
}
@Override
public Map<Player, Vec3> getHitPlayers()
{
return this.hitPlayers;
}
/**
* Returns either the entity that placed the explosive block, the entity that caused the explosion or null.
*/
@Nullable
@Override
public LivingEntity getSourceMob()
{
if (this.source == null)
{
return null;
}
else if (this.source instanceof PrimedTnt)
{
return ((PrimedTnt)this.source).getOwner();
}
else if (this.source instanceof LivingEntity)
{
return (LivingEntity)this.source;
}
else
{
if (this.source instanceof Projectile)
{
Entity entity = ((Projectile)this.source).getOwner();
if (entity instanceof LivingEntity)
{
return (LivingEntity)entity;
}
}
return null;
}
}
@Override
public void clearToBlow()
{
this.toBlow.clear();
}
@Override
public List<BlockPos> getToBlow()
{
return this.toBlow;
}
@Override
public Vec3 getPosition()
{
return this.position;
}
@Nullable
@Override
public Entity getExploder()
{
return this.source;
}
}

View File

@@ -1,24 +1,26 @@
package ru.magistu.siegemachines.entity.projectile;
import ru.magistu.siegemachines.config.MissileSpecs;
import ru.magistu.siegemachines.config.SpecsConfig;
public enum MissileType
{
CANNONBALL(15.0f, 1.5f, true, 3.0f, FlightType.SPINNING, 1.0f),
STONE(50.0f, 1.5f, true, 3.0f, FlightType.SPINNING, 1.0f),
GIANT_ARROW(5.0f, 1.5f, false, 0.0f, FlightType.AHEAD, 0.5f);
CANNONBALL(SpecsConfig.CANNONBALL, 1.5f, true, FlightType.SPINNING, 1.0f),
STONE(SpecsConfig.STONE, 1.5f, true, FlightType.SPINNING, 1.0f),
GIANT_STONE(SpecsConfig.GIANT_STONE, 3.0f, true, FlightType.SPINNING, 1.0f);
//GIANT_ARROW(SpecsConfig.GIANT_ARROW, 1.5f, false, FlightType.AHEAD, 0.5f);
public final float mass;
public final MissileSpecs specs;
public final float knockback;
public final boolean explosive;
public final float explosionradius;
public final boolean explosive;
public final FlightType flighttype;
public final float armorpiercing;
MissileType(float mass, float knockback, boolean explosive, float explosionradius, FlightType headingtype, float armorpiercing)
MissileType(MissileSpecs specs, float knockback, boolean explosive, FlightType headingtype, float armorpiercing)
{
this.mass = mass;
this.specs = specs;
this.knockback = knockback;
this.explosive = explosive;
this.explosionradius = explosionradius;
this.flighttype = headingtype;
this.armorpiercing = armorpiercing;
}

View File

@@ -1,5 +1,8 @@
package ru.magistu.siegemachines.entity.projectile;
import com.mojang.math.Vector3d;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.level.Level;
import ru.magistu.siegemachines.entity.EntityTypes;
import ru.magistu.siegemachines.item.ModItems;
import net.minecraft.world.entity.EntityType;
@@ -13,14 +16,16 @@ public class ProjectileBuilder<T extends Projectile>
{
public final static ProjectileBuilder<Stone> NONE = new ProjectileBuilder<>(Items.AIR, EntityTypes.STONE.get(), Stone::new);
public final static ProjectileBuilder[] NO_AMMO = new ProjectileBuilder[]{};
public final static ProjectileBuilder[] CANNON_AMMO = new ProjectileBuilder[]{
new ProjectileBuilder(ModItems.CANNONBALL.get(), EntityTypes.CANNONBALL.get(), Cannonball::new)};
public final static ProjectileBuilder[] THROWING_AMMO = new ProjectileBuilder[]{
new ProjectileBuilder(Items.COBBLESTONE, ModItems.STONE.get(), EntityTypes.STONE.get(), Stone::new)};
public final static ProjectileBuilder[] BALLISTA_AMMO = new ProjectileBuilder[]{
new ProjectileBuilder(ModItems.GIANT_ARROW.get(), EntityTypes.GIANT_ARROW.get(), GiantArrow::new),
new ProjectileBuilder(Items.ARROW, EntityType.ARROW, (entitytype, level, pos, entity, item) ->
public final static ProjectileBuilder<?>[] NO_AMMO = new ProjectileBuilder[]{};
public final static ProjectileBuilder<?>[] GIANT_THROWING_AMMO = new ProjectileBuilder[]{
new ProjectileBuilder<>(Items.COBBLESTONE, ModItems.GIANT_STONE.get(), EntityTypes.GIANT_STONE.get(), GiantStone::new)};
public final static ProjectileBuilder<?>[] CANNON_AMMO = new ProjectileBuilder[]{
new ProjectileBuilder<>(ModItems.CANNONBALL.get(), EntityTypes.CANNONBALL.get(), Cannonball::new)};
public final static ProjectileBuilder<?>[] THROWING_AMMO = new ProjectileBuilder[]{
new ProjectileBuilder<>(Items.COBBLESTONE, ModItems.STONE.get(), EntityTypes.STONE.get(), Stone::new)};
public final static ProjectileBuilder<?>[] BALLISTA_AMMO = new ProjectileBuilder[]{
new ProjectileBuilder<>(ModItems.GIANT_ARROW.get(), EntityTypes.GIANT_ARROW.get(), GiantArrow::new),
new ProjectileBuilder<>(Items.ARROW, EntityType.ARROW, (entitytype, level, pos, entity, item) ->
{
Arrow arrow = new Arrow(level, entity);
arrow.setPos(pos.x, pos.y, pos.z);
@@ -44,6 +49,9 @@ public class ProjectileBuilder<T extends Projectile>
this.entitytype = entitytype;
this.factory = factory;
}
public T build(Level level, Vector3d pos, LivingEntity entity)
{
return this.factory.create(this.entitytype, level, pos, entity, this.item);
}
}