YX100添加蜂群无人机

This commit is contained in:
Atsuishio 2025-04-07 07:12:11 +08:00 committed by Light_Quanta
parent 5fe6c96b01
commit 98fd33a17c
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
26 changed files with 2021 additions and 20 deletions

View file

@ -1,4 +1,4 @@
// 1.21.1 2025-04-02T18:07:51.8677118 Item Models: superbwarfare // 1.21.1 2025-04-08T06:51:00.2717304 Item Models: superbwarfare
13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/aa_12_blueprint.json 13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/aa_12_blueprint.json
13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/ak_12_blueprint.json 13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/ak_12_blueprint.json
13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/ak_47_blueprint.json 13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/ak_47_blueprint.json
@ -113,6 +113,7 @@ b4e009177af3af6ad6dda54e3e2fed43dc243ff2 assets/superbwarfare/models/item/steel_
28e5cc26e694d0cded97b343de94764b28f1651f assets/superbwarfare/models/item/steel_spring.json 28e5cc26e694d0cded97b343de94764b28f1651f assets/superbwarfare/models/item/steel_spring.json
7d3c98a32815191ef716a8595dda392a8dfea6ec assets/superbwarfare/models/item/steel_trigger.json 7d3c98a32815191ef716a8595dda392a8dfea6ec assets/superbwarfare/models/item/steel_trigger.json
13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/svd_blueprint.json 13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/svd_blueprint.json
99b1799c7a12767decc900e9fbeac5859be13b50 assets/superbwarfare/models/item/swarm_drone.json
dbba3ca532b6aa949c84ea8b3f10fe3a0bf472e7 assets/superbwarfare/models/item/target_deployer.json dbba3ca532b6aa949c84ea8b3f10fe3a0bf472e7 assets/superbwarfare/models/item/target_deployer.json
13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/taser_blueprint.json 13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/taser_blueprint.json
13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/trachelium_blueprint.json 13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/trachelium_blueprint.json

View file

@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "superbwarfare:item/swarm_drone"
}
}

View file

@ -0,0 +1,24 @@
package com.atsuishio.superbwarfare.client.model.entity;
import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.entity.projectile.SwarmDroneEntity;
import net.minecraft.resources.ResourceLocation;
import software.bernie.geckolib.model.GeoModel;
public class SwarmDroneModel extends GeoModel<SwarmDroneEntity> {
@Override
public ResourceLocation getAnimationResource(SwarmDroneEntity entity) {
return Mod.loc("animations/swarm_drone.animation.json");
}
@Override
public ResourceLocation getModelResource(SwarmDroneEntity entity) {
return Mod.loc("geo/swarm_drone.geo.json");
}
@Override
public ResourceLocation getTextureResource(SwarmDroneEntity entity) {
return Mod.loc("textures/entity/swamDrone.png");
}
}

View file

@ -48,6 +48,7 @@ import static com.atsuishio.superbwarfare.client.RenderHelper.preciseBlit;
import static com.atsuishio.superbwarfare.client.overlay.CrossHairOverlay.*; import static com.atsuishio.superbwarfare.client.overlay.CrossHairOverlay.*;
import static com.atsuishio.superbwarfare.entity.vehicle.Bmp2Entity.LOADED_MISSILE; import static com.atsuishio.superbwarfare.entity.vehicle.Bmp2Entity.LOADED_MISSILE;
import static com.atsuishio.superbwarfare.entity.vehicle.Bmp2Entity.MISSILE_COUNT; import static com.atsuishio.superbwarfare.entity.vehicle.Bmp2Entity.MISSILE_COUNT;
import static com.atsuishio.superbwarfare.entity.vehicle.Yx100Entity.LOADED_DRONE;
import static com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity.*; import static com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity.*;
@EventBusSubscriber(value = Dist.CLIENT) @EventBusSubscriber(value = Dist.CLIENT)
@ -187,6 +188,8 @@ public class VehicleHudOverlay {
preciseBlit(guiGraphics, Mod.loc("textures/screens/land/tank_cannon_cross_he.png"), k, l, 0, 0.0F, i, j, i, j); preciseBlit(guiGraphics, Mod.loc("textures/screens/land/tank_cannon_cross_he.png"), k, l, 0, 0.0F, i, j, i, j);
} else if (weaponVehicle.getWeaponIndex(0) == 2) { } else if (weaponVehicle.getWeaponIndex(0) == 2) {
preciseBlit(guiGraphics, Mod.loc("textures/screens/land/lav_gun_cross.png"), k, l, 0, 0.0F, i, j, i, j); preciseBlit(guiGraphics, Mod.loc("textures/screens/land/lav_gun_cross.png"), k, l, 0, 0.0F, i, j, i, j);
} else if (weaponVehicle.getWeaponIndex(0) == 3) {
preciseBlit(guiGraphics, Mod.loc("textures/screens/land/lav_missile_cross.png"), k, l, 0, 0.0F, i, j, i, j);
} }
} else if (weaponVehicle instanceof PrismTankEntity) { } else if (weaponVehicle instanceof PrismTankEntity) {
@ -288,6 +291,8 @@ public class VehicleHudOverlay {
} else if (weaponVehicle.getWeaponIndex(0) == 2) { } else if (weaponVehicle.getWeaponIndex(0) == 2) {
double heat = 1 - yx100.getEntityData().get(COAX_HEAT) / 100.0F; double heat = 1 - yx100.getEntityData().get(COAX_HEAT) / 100.0F;
guiGraphics.drawString(mc.font, Component.literal(" 12.7MM HMG " + (InventoryTool.hasCreativeAmmoBox(player) ? "" : yx100.getAmmoCount(player))), w / 2 - 33, h - 65, Mth.hsvToRgb((float) heat / 3.745318352059925F, 1.0F, 1.0F), false); guiGraphics.drawString(mc.font, Component.literal(" 12.7MM HMG " + (InventoryTool.hasCreativeAmmoBox(player) ? "" : yx100.getAmmoCount(player))), w / 2 - 33, h - 65, Mth.hsvToRgb((float) heat / 3.745318352059925F, 1.0F, 1.0F), false);
} else {
guiGraphics.drawString(mc.font, Component.literal(" SWARM " + yx100.getEntityData().get(LOADED_DRONE) + " " + (InventoryTool.hasCreativeAmmoBox(player) ? "" : yx100.getEntityData().get(AMMO))), w / 2 - 33, h - 65, 0x66FF00, false);
} }
} }
@ -343,7 +348,9 @@ public class VehicleHudOverlay {
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("HE SHELL " + yx100.getAmmoCount(player) + " " + (InventoryTool.hasCreativeAmmoBox(player) ? "" : yx100.getEntityData().get(AMMO))), 30, -9, -1, false); guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("HE SHELL " + yx100.getAmmoCount(player) + " " + (InventoryTool.hasCreativeAmmoBox(player) ? "" : yx100.getEntityData().get(AMMO))), 30, -9, -1, false);
} else if (weaponVehicle.getWeaponIndex(0) == 2) { } else if (weaponVehicle.getWeaponIndex(0) == 2) {
double heat2 = yx100.getEntityData().get(COAX_HEAT) / 100.0F; double heat2 = yx100.getEntityData().get(COAX_HEAT) / 100.0F;
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("7.62MM ПКТ " + (InventoryTool.hasCreativeAmmoBox(player) ? "" : yx100.getAmmoCount(player))), 30, -9, Mth.hsvToRgb(0F, (float) heat2, 1.0F), false); guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("12.7MM HMG " + (InventoryTool.hasCreativeAmmoBox(player) ? "" : yx100.getAmmoCount(player))), 30, -9, Mth.hsvToRgb(0F, (float) heat2, 1.0F), false);
} else {
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("SWARM " + yx100.getEntityData().get(LOADED_DRONE) + " " + (InventoryTool.hasCreativeAmmoBox(player) ? "" : yx100.getEntityData().get(AMMO))), 30, -9, -1, false);
} }
} }

View file

@ -0,0 +1,38 @@
package com.atsuishio.superbwarfare.client.renderer.entity;
import com.atsuishio.superbwarfare.client.model.entity.SwarmDroneModel;
import com.atsuishio.superbwarfare.entity.projectile.SwarmDroneEntity;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.resources.ResourceLocation;
import software.bernie.geckolib.cache.object.BakedGeoModel;
import software.bernie.geckolib.renderer.GeoEntityRenderer;
public class SwarmDroneRenderer extends GeoEntityRenderer<SwarmDroneEntity> {
public SwarmDroneRenderer(EntityRendererProvider.Context renderManager) {
super(renderManager, new SwarmDroneModel());
}
@Override
public RenderType getRenderType(SwarmDroneEntity animatable, ResourceLocation texture, MultiBufferSource bufferSource, float partialTick) {
return RenderType.entityTranslucent(getTextureLocation(animatable));
}
@Override
public void preRender(PoseStack poseStack, SwarmDroneEntity entity, BakedGeoModel model, MultiBufferSource bufferSource, VertexConsumer buffer, boolean isReRender, float partialTick, int packedLight, int packedOverlay, int color) {
float scale = 1f;
this.scaleHeight = scale;
this.scaleWidth = scale;
super.preRender(poseStack, entity, model, bufferSource, buffer, isReRender, partialTick, packedLight, packedOverlay, color);
}
@Override
public void render(SwarmDroneEntity entityIn, float entityYaw, float partialTicks, PoseStack poseStack, MultiBufferSource bufferIn, int packedLightIn) {
poseStack.pushPose();
super.render(entityIn, entityYaw, partialTicks, poseStack, bufferIn, packedLightIn);
poseStack.popPose();
}
}

View file

@ -81,6 +81,7 @@ public class ModItemModelProvider extends ItemModelProvider {
simpleItem(ModItems.ROCKET_70); simpleItem(ModItems.ROCKET_70);
simpleItem(ModItems.WIRE_GUIDE_MISSILE); simpleItem(ModItems.WIRE_GUIDE_MISSILE);
simpleItem(ModItems.SMALL_SHELL); simpleItem(ModItems.SMALL_SHELL);
simpleItem(ModItems.SWARM_DRONE);
simpleItem(ModItems.SMALL_BATTERY_PACK); simpleItem(ModItems.SMALL_BATTERY_PACK);
simpleItem(ModItems.MEDIUM_BATTERY_PACK); simpleItem(ModItems.MEDIUM_BATTERY_PACK);
simpleItem(ModItems.LARGE_BATTERY_PACK); simpleItem(ModItems.LARGE_BATTERY_PACK);

View file

@ -0,0 +1,206 @@
package com.atsuishio.superbwarfare.entity.projectile;
import com.atsuishio.superbwarfare.config.server.ExplosionConfig;
import com.atsuishio.superbwarfare.init.ModDamageTypes;
import com.atsuishio.superbwarfare.init.ModEntities;
import com.atsuishio.superbwarfare.init.ModItems;
import com.atsuishio.superbwarfare.tools.CustomExplosion;
import com.atsuishio.superbwarfare.tools.EntityFindUtil;
import com.atsuishio.superbwarfare.tools.ParticleTool;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.projectile.ThrowableItemProjectile;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.EntityHitResult;
import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.event.EventHooks;
import org.jetbrains.annotations.NotNull;
import software.bernie.geckolib.animatable.GeoEntity;
import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.animation.*;
import software.bernie.geckolib.util.GeckoLibUtil;
import javax.annotation.Nullable;
public class SwarmDroneEntity extends FastThrowableProjectile implements GeoEntity {
public static final EntityDataAccessor<String> TARGET_UUID = SynchedEntityData.defineId(SwarmDroneEntity.class, EntityDataSerializers.STRING);
public static final EntityDataAccessor<Float> TARGET_X = SynchedEntityData.defineId(SwarmDroneEntity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<Float> TARGET_Y = SynchedEntityData.defineId(SwarmDroneEntity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<Float> TARGET_Z = SynchedEntityData.defineId(SwarmDroneEntity.class, EntityDataSerializers.FLOAT);
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
private float explosionDamage = 125f;
private float explosionRadius = 6f;
private float randomFloat;
private int guide_type = 0;
public SwarmDroneEntity(EntityType<? extends SwarmDroneEntity> type, Level level) {
super(type, level);
this.noCulling = true;
}
public SwarmDroneEntity(LivingEntity entity, Level level, float explosionDamage, float explosionRadius) {
super(ModEntities.SWARM_DRONE.get(), entity, level);
this.explosionDamage = explosionDamage;
this.explosionRadius = explosionRadius;
}
@Override
protected @NotNull Item getDefaultItem() {
return ModItems.DRONE.get();
}
public void setTargetUuid(String uuid) {
this.entityData.set(TARGET_UUID, uuid);
}
public void setGuideType(int guideType) {
this.guide_type = guideType;
}
public void setTargetVec(Vec3 targetPos) {
this.entityData.set(TARGET_X, (float) targetPos.x);
this.entityData.set(TARGET_Y, (float) targetPos.y);
this.entityData.set(TARGET_Z, (float) targetPos.z);
}
@Override
protected void defineSynchedData(SynchedEntityData.@NotNull Builder builder) {
super.defineSynchedData(builder);
builder.define(TARGET_UUID, "none")
.define(TARGET_X, 0f)
.define(TARGET_Y, 0f)
.define(TARGET_Z, 0f);
}
@Override
public boolean shouldRenderAtSqrDistance(double pDistance) {
return true;
}
@Override
protected void onHitEntity(@NotNull EntityHitResult result) {
if (this.level() instanceof ServerLevel) {
causeMissileExplode(this,
ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this.getOwner()),
this, this.explosionDamage, this.explosionRadius);
}
}
@Override
public void onHitBlock(@NotNull BlockHitResult blockHitResult) {
super.onHitBlock(blockHitResult);
if (this.level() instanceof ServerLevel) {
causeMissileExplode(this,
ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this.getOwner()),
this, this.explosionDamage, this.explosionRadius);
}
}
@Override
public void tick() {
super.tick();
Entity entity = EntityFindUtil.findEntity(this.level(), entityData.get(TARGET_UUID));
if (this.tickCount == 1) {
if (!this.level().isClientSide() && this.level() instanceof ServerLevel serverLevel) {
ParticleTool.sendParticle(serverLevel, ParticleTypes.CLOUD, this.xo, this.yo, this.zo, 15, 0.8, 0.8, 0.8, 0.01, true);
ParticleTool.sendParticle(serverLevel, ParticleTypes.CAMPFIRE_COSY_SMOKE, this.xo, this.yo, this.zo, 10, 0.8, 0.8, 0.8, 0.01, true);
}
}
if (tickCount > 10 && this.getOwner() != null) {
Entity shooter = this.getOwner();
Vec3 targetPos;
if (guide_type == 0 && entity != null) {
targetPos = entity.getEyePosition();
} else {
targetPos = new Vec3(this.entityData.get(TARGET_X), this.entityData.get(TARGET_Y), this.entityData.get(TARGET_Z));
}
if (tickCount % 5 == 0) {
randomFloat = random.nextFloat();
}
double dis = position().distanceTo(targetPos);
double disShooter = shooter.position().distanceTo(targetPos);
double randomPos = Mth.sin(0.25f * (tickCount + randomFloat)) * randomFloat * (dis / disShooter);
Vec3 toVec = this.position().vectorTo(targetPos).normalize().add(new Vec3(randomPos, 0, randomPos));
setDeltaMovement(getDeltaMovement().add(toVec.scale(0.5)));
this.setDeltaMovement(this.getDeltaMovement().multiply(0.85, 0.85, 0.85));
if (dis < 0.5) {
if (this.level() instanceof ServerLevel) {
causeMissileExplode(this,
ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this.getOwner()),
this, this.explosionDamage, this.explosionRadius);
}
this.discard();
}
}
if (this.tickCount > 300 || this.isInWater()) {
if (this.level() instanceof ServerLevel) {
causeMissileExplode(this,
ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this.getOwner()),
this, this.explosionDamage, this.explosionRadius);
}
this.discard();
}
}
@Override
protected void updateRotation() {
}
public static void causeMissileExplode(ThrowableItemProjectile projectile, @Nullable DamageSource source, Entity target, float damage, float radius) {
CustomExplosion explosion = new CustomExplosion(projectile.level(), projectile, source, damage,
target.getX(), target.getEyeY(), target.getZ(), radius, ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP).setDamageMultiplier(1.25f);
explosion.explode();
EventHooks.onExplosionStart(projectile.level(), explosion);
explosion.finalizeExplosion(false);
ParticleTool.spawnMediumExplosionParticles(projectile.level(), projectile.position());
projectile.discard();
}
private PlayState movementPredicate(AnimationState<SwarmDroneEntity> event) {
return event.setAndContinue(RawAnimation.begin().thenLoop("animation.sd.fly"));
}
@Override
protected double getDefaultGravity() {
return tickCount > 10 ? 0 : 0.1f;
}
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar data) {
data.add(new AnimationController<>(this, "movement", 0, this::movementPredicate));
}
@Override
public AnimatableInstanceCache getAnimatableInstanceCache() {
return this.cache;
}
@Override
public boolean shouldSyncMotion() {
return true;
}
}

View file

@ -1,7 +1,7 @@
package com.atsuishio.superbwarfare.entity.projectile; package com.atsuishio.superbwarfare.entity.projectile;
import com.atsuishio.superbwarfare.config.server.ExplosionConfig; import com.atsuishio.superbwarfare.config.server.ExplosionConfig;
import com.atsuishio.superbwarfare.entity.vehicle.Bmp2Entity; import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
import com.atsuishio.superbwarfare.init.ModDamageTypes; import com.atsuishio.superbwarfare.init.ModDamageTypes;
import com.atsuishio.superbwarfare.init.ModEntities; import com.atsuishio.superbwarfare.init.ModEntities;
import com.atsuishio.superbwarfare.init.ModItems; import com.atsuishio.superbwarfare.init.ModItems;
@ -9,18 +9,18 @@ import com.atsuishio.superbwarfare.init.ModSounds;
import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage; import com.atsuishio.superbwarfare.network.message.receive.ClientIndicatorMessage;
import com.atsuishio.superbwarfare.tools.CustomExplosion; import com.atsuishio.superbwarfare.tools.CustomExplosion;
import com.atsuishio.superbwarfare.tools.ParticleTool; import com.atsuishio.superbwarfare.tools.ParticleTool;
import com.atsuishio.superbwarfare.tools.VectorTool; import com.atsuishio.superbwarfare.tools.TraceTool;
import net.minecraft.core.particles.ParticleTypes; import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundSource; import net.minecraft.sounds.SoundSource;
import net.minecraft.util.Mth;
import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.projectile.ThrowableItemProjectile; import net.minecraft.world.entity.projectile.ThrowableItemProjectile;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.Explosion; import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
@ -123,24 +123,26 @@ public class WgMissileEntity extends FastThrowableProjectile implements GeoEntit
} }
} }
if (tickCount > 5 && this.getOwner() != null && getOwner().getVehicle() instanceof Bmp2Entity bmp2) { if (tickCount > 5 && this.getOwner() != null && getOwner().getVehicle() instanceof VehicleEntity vehicle) {
Entity shooter = this.getOwner(); Entity shooter = this.getOwner();
Vec3 lookVec = bmp2.getBarrelVector(1).normalize();
Vec3 toVec = shooter.getEyePosition().vectorTo(this.getEyePosition()).normalize();
Vec3 addVec = lookVec.add(toVec.scale(-0.85)).normalize();
double angle = Mth.abs((float) VectorTool.calculateAngle(lookVec, toVec));
setDeltaMovement(getDeltaMovement().add(addVec.scale(Math.min(0.1 + 0.15 * angle + distanceTo(getOwner()) * 0.003, tickCount < 15 ? 0.04 : 0.4))));
// 控制速度 Vec3 lookVec = vehicle.getBarrelVec(1).normalize();
if (this.getDeltaMovement().length() < 2.8) { Entity lookingEntity = TraceTool.vehiclefFindLookingEntity(vehicle, vehicle.getNewEyePos(1), 512);
this.setDeltaMovement(this.getDeltaMovement().multiply(1.06, 1.06, 1.06)); Vec3 toVec;
if (lookingEntity != null) {
toVec = this.position().vectorTo(lookingEntity.getEyePosition()).normalize();
} else {
BlockHitResult result = level().clip(new ClipContext(vehicle.getNewEyePos(1), vehicle.getNewEyePos(1).add(lookVec.scale(512)),
ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, shooter));
Vec3 hitPos = result.getLocation();
toVec = this.position().vectorTo(hitPos).normalize();
} }
if (this.getDeltaMovement().length() > 3) { setDeltaMovement(getDeltaMovement().add(toVec.scale(0.8)));
this.setDeltaMovement(this.getDeltaMovement().multiply(0.9, 0.9, 0.9));
}
this.setDeltaMovement(this.getDeltaMovement().multiply(0.96, 0.96, 0.96)); this.setDeltaMovement(this.getDeltaMovement().multiply(0.8, 0.8, 0.8));
} }
if (this.tickCount > 300 || this.isInWater()) { if (this.tickCount > 300 || this.isInWater()) {

View file

@ -496,6 +496,13 @@ public class Bmp2Entity extends ContainerMobileVehicleEntity implements GeoEntit
return new Vec3(worldPosition.x, worldPosition.y, worldPosition.z); return new Vec3(worldPosition.x, worldPosition.y, worldPosition.z);
} }
@Override
public Vec3 getNewEyePos(float pPartialTicks) {
Matrix4f transform = getTurretTransform(pPartialTicks);
Vector4f worldPosition = transformPosition(transform, 0, 1.65f, 0.75f);
return new Vec3(worldPosition.x, worldPosition.y, worldPosition.z);
}
@Override @Override
public Vec3 getBarrelVector(float pPartialTicks) { public Vec3 getBarrelVector(float pPartialTicks) {
Matrix4f transform = getBarrelTransform(pPartialTicks); Matrix4f transform = getBarrelTransform(pPartialTicks);

View file

@ -11,6 +11,7 @@ import com.atsuishio.superbwarfare.entity.vehicle.base.WeaponVehicleEntity;
import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier; import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier;
import com.atsuishio.superbwarfare.entity.vehicle.weapon.CannonShellWeapon; import com.atsuishio.superbwarfare.entity.vehicle.weapon.CannonShellWeapon;
import com.atsuishio.superbwarfare.entity.vehicle.weapon.ProjectileWeapon; import com.atsuishio.superbwarfare.entity.vehicle.weapon.ProjectileWeapon;
import com.atsuishio.superbwarfare.entity.vehicle.weapon.SwarmDroneWeapon;
import com.atsuishio.superbwarfare.entity.vehicle.weapon.VehicleWeapon; import com.atsuishio.superbwarfare.entity.vehicle.weapon.VehicleWeapon;
import com.atsuishio.superbwarfare.init.ModDamageTypes; import com.atsuishio.superbwarfare.init.ModDamageTypes;
import com.atsuishio.superbwarfare.init.ModItems; import com.atsuishio.superbwarfare.init.ModItems;
@ -42,10 +43,12 @@ import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.MoverType; import net.minecraft.world.entity.MoverType;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.ClipContext;
import net.minecraft.world.level.Explosion; import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.neoforged.neoforge.event.EventHooks; import net.neoforged.neoforge.event.EventHooks;
import net.neoforged.neoforge.network.PacketDistributor; import net.neoforged.neoforge.network.PacketDistributor;
@ -67,8 +70,9 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti
public static final EntityDataAccessor<Integer> LOADED_HE = SynchedEntityData.defineId(Yx100Entity.class, EntityDataSerializers.INT); public static final EntityDataAccessor<Integer> LOADED_HE = SynchedEntityData.defineId(Yx100Entity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Integer> LOADED_AMMO_TYPE = SynchedEntityData.defineId(Yx100Entity.class, EntityDataSerializers.INT); public static final EntityDataAccessor<Integer> LOADED_AMMO_TYPE = SynchedEntityData.defineId(Yx100Entity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Integer> GUN_FIRE_TIME = SynchedEntityData.defineId(Yx100Entity.class, EntityDataSerializers.INT); public static final EntityDataAccessor<Integer> GUN_FIRE_TIME = SynchedEntityData.defineId(Yx100Entity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Integer> LOADED_DRONE = SynchedEntityData.defineId(Yx100Entity.class, EntityDataSerializers.INT);
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
public int droneReloadCoolDown;
public Yx100Entity(EntityType<Yx100Entity> type, Level world) { public Yx100Entity(EntityType<Yx100Entity> type, Level world) {
super(type, world); super(type, world);
@ -116,6 +120,11 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti
.ammo(ModItems.HEAVY_AMMO.get()) .ammo(ModItems.HEAVY_AMMO.get())
.sound(ModSounds.INTO_CANNON.get()) .sound(ModSounds.INTO_CANNON.get())
.icon(Mod.loc("textures/screens/vehicle_weapon/gun_12_7mm.png")), .icon(Mod.loc("textures/screens/vehicle_weapon/gun_12_7mm.png")),
// 蜂群无人机
new SwarmDroneWeapon()
.explosionDamage(125)
.explosionRadius(6)
.sound(ModSounds.INTO_MISSILE.get()),
}, },
new VehicleWeapon[]{ new VehicleWeapon[]{
// 机枪 // 机枪
@ -145,6 +154,7 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti
builder.define(MG_AMMO, 0) builder.define(MG_AMMO, 0)
.define(LOADED_AP, 0) .define(LOADED_AP, 0)
.define(LOADED_HE, 0) .define(LOADED_HE, 0)
.define(LOADED_DRONE, 0)
.define(LOADED_AMMO_TYPE, 0) .define(LOADED_AMMO_TYPE, 0)
.define(GUN_FIRE_TIME, 0); .define(GUN_FIRE_TIME, 0);
} }
@ -154,6 +164,7 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti
super.addAdditionalSaveData(compound); super.addAdditionalSaveData(compound);
compound.putInt("LoadedAP", this.entityData.get(LOADED_AP)); compound.putInt("LoadedAP", this.entityData.get(LOADED_AP));
compound.putInt("LoadedHE", this.entityData.get(LOADED_HE)); compound.putInt("LoadedHE", this.entityData.get(LOADED_HE));
compound.putInt("LoadedDrone", this.entityData.get(LOADED_DRONE));
compound.putInt("LoadedAmmoType", this.entityData.get(LOADED_AMMO_TYPE)); compound.putInt("LoadedAmmoType", this.entityData.get(LOADED_AMMO_TYPE));
compound.putInt("WeaponType", getWeaponIndex(0)); compound.putInt("WeaponType", getWeaponIndex(0));
compound.putInt("PassengerWeaponType", getWeaponIndex(1)); compound.putInt("PassengerWeaponType", getWeaponIndex(1));
@ -164,6 +175,7 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti
super.readAdditionalSaveData(compound); super.readAdditionalSaveData(compound);
this.entityData.set(LOADED_AP, compound.getInt("LoadedAP")); this.entityData.set(LOADED_AP, compound.getInt("LoadedAP"));
this.entityData.set(LOADED_HE, compound.getInt("LoadedHE")); this.entityData.set(LOADED_HE, compound.getInt("LoadedHE"));
this.entityData.set(LOADED_DRONE, compound.getInt("LoadedDrone"));
this.entityData.set(LOADED_AMMO_TYPE, compound.getInt("LoadedAmmoType")); this.entityData.set(LOADED_AMMO_TYPE, compound.getInt("LoadedAmmoType"));
setWeaponIndex(0, compound.getInt("WeaponType")); setWeaponIndex(0, compound.getInt("WeaponType"));
setWeaponIndex(1, compound.getInt("PassengerWeaponType")); setWeaponIndex(1, compound.getInt("PassengerWeaponType"));
@ -256,6 +268,11 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti
)) { )) {
reloadCoolDown--; reloadCoolDown--;
} }
if (droneReloadCoolDown > 0) {
droneReloadCoolDown--;
}
this.handleAmmo(); this.handleAmmo();
} }
@ -340,6 +357,15 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti
} }
} }
} }
if ((hasItem(ModItems.SWARM_DRONE.get()) || hasCreativeAmmo) && droneReloadCoolDown == 0 && this.getEntityData().get(LOADED_DRONE) < 14) {
this.entityData.set(LOADED_DRONE, this.getEntityData().get(LOADED_DRONE) + 1);
droneReloadCoolDown = 20;
if (!hasCreativeAmmo) {
this.getItemStacks().stream().filter(stack -> stack.is(ModItems.SWARM_DRONE.get())).findFirst().ifPresent(stack -> stack.shrink(1));
}
this.level().playSound(null, this, ModSounds.MISSILE_RELOAD.get(), this.getSoundSource(), 1, 1);
}
} }
@Override @Override
@ -488,6 +514,87 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti
serverPlayer.playSound(ModSounds.M_2_VERYFAR.get(), 24, pitch); serverPlayer.playSound(ModSounds.M_2_VERYFAR.get(), 24, pitch);
} }
} }
} else if (getWeaponIndex(0) == 3) {
Matrix4f transformT = getTurretTransform(1);
Vector4f worldPosition = new Vector4f();
int ammo = this.getEntityData().get(LOADED_DRONE);
if (ammo == 1) {
worldPosition = transformPosition(transformT, -2.315275f, 0.71894375f, -0.25390625f);
}
if (ammo == 2) {
worldPosition = transformPosition(transformT, 2.315275f, 0.71894375f, -0.25390625f);
}
if (ammo == 3) {
worldPosition = transformPosition(transformT, -2.49105625f, 0.71894375f, -0.4296875f);
}
if (ammo == 4) {
worldPosition = transformPosition(transformT, 2.49105625f, 0.71894375f, -0.4296875f);
}
if (ammo == 5) {
worldPosition = transformPosition(transformT, -2.315275f, 0.71894375f, -0.60546875f);
}
if (ammo == 6) {
worldPosition = transformPosition(transformT, 2.315275f, 0.71894375f, -0.60546875f);
}
if (ammo == 7) {
worldPosition = transformPosition(transformT, -2.49105625f, 0.71894375f, -0.78125f);
}
if (ammo == 8) {
worldPosition = transformPosition(transformT, 2.49105625f, 0.71894375f, -0.78125f);
}
if (ammo == 9) {
worldPosition = transformPosition(transformT, -2.315275f, 0.71894375f, -0.95703125f);
}
if (ammo == 10) {
worldPosition = transformPosition(transformT, 2.315275f, 0.71894375f, -0.95703125f);
}
if (ammo == 11) {
worldPosition = transformPosition(transformT, -2.49105625f, 0.71894375f, -1.1328125f);
}
if (ammo == 12) {
worldPosition = transformPosition(transformT, 2.49105625f, 0.71894375f, -1.1328125f);
}
if (ammo == 13) {
worldPosition = transformPosition(transformT, -2.315275f, 0.71894375f, -1.30859375f);
}
if (ammo == 14) {
worldPosition = transformPosition(transformT, 2.315275f, 0.71894375f, -1.30859375f);
}
Vec3 lookVec = getBarrelVec(1).normalize();
Entity lookingEntity = SeekTool.vehicleSeekEntity(this, level(), 512, 4);
var swarmDroneEntity = ((SwarmDroneWeapon) getWeapon(0)).create(player);
Vector4f shootPosition1 = transformPosition(transformT, 0, 0, 0);
Vector4f shootPosition2 = transformPosition(transformT, 0, 1, 0);
Vec3 direct = new Vec3(shootPosition1.x, shootPosition1.y, shootPosition1.z).vectorTo(new Vec3(shootPosition2.x, shootPosition2.y, shootPosition2.z));
swarmDroneEntity.setPos(worldPosition.x, worldPosition.y, worldPosition.z);
swarmDroneEntity.shoot(direct.x, direct.y, direct.z, 1.2f, 10);
if (lookingEntity != null) {
swarmDroneEntity.setGuideType(0);
swarmDroneEntity.setTargetUuid(lookingEntity.getStringUUID());
swarmDroneEntity.setTargetVec(lookingEntity.getEyePosition());
} else {
swarmDroneEntity.setGuideType(1);
BlockHitResult result = level().clip(new ClipContext(getNewEyePos(1), getNewEyePos(1).add(lookVec.scale(512)),
ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this));
Vec3 hitPos = result.getLocation();
swarmDroneEntity.setTargetVec(hitPos);
}
player.level().addFreshEntity(swarmDroneEntity);
this.level().playSound(null, BlockPos.containing(new Vec3(worldPosition.x, worldPosition.y, worldPosition.z)), ModSounds.DECOY_FIRE.get(), SoundSource.PLAYERS, 1, random.nextFloat() * 0.05f + 1);
this.entityData.set(LOADED_DRONE, this.getEntityData().get(LOADED_DRONE) - 1);
droneReloadCoolDown = 100;
} }
} }
@ -646,6 +753,13 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti
return new Vec3(worldPosition.x, worldPosition.y, worldPosition.z); return new Vec3(worldPosition.x, worldPosition.y, worldPosition.z);
} }
@Override
public Vec3 getNewEyePos(float pPartialTicks) {
Matrix4f transform = getTurretTransform(pPartialTicks);
Vector4f worldPosition = transformPosition(transform, 0, 1.65f, 0.6076875f);
return new Vec3(worldPosition.x, worldPosition.y, worldPosition.z);
}
public int getMaxPassengers() { public int getMaxPassengers() {
return 3; return 3;
} }
@ -914,6 +1028,8 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti
return 15; return 15;
} else if (getWeaponIndex(0) == 2) { } else if (getWeaponIndex(0) == 2) {
return 500; return 500;
} else if (getWeaponIndex(0) == 3) {
return 600;
} }
} }
@ -932,6 +1048,8 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti
return this.entityData.get(LOADED_HE) > 0 && getEnergy() > VehicleConfig.YX_100_SHOOT_COST.get(); return this.entityData.get(LOADED_HE) > 0 && getEnergy() > VehicleConfig.YX_100_SHOOT_COST.get();
} else if (getWeaponIndex(0) == 2) { } else if (getWeaponIndex(0) == 2) {
return (this.entityData.get(MG_AMMO) > 0 || InventoryTool.hasCreativeAmmoBox(player)) && !cannotFireCoax; return (this.entityData.get(MG_AMMO) > 0 || InventoryTool.hasCreativeAmmoBox(player)) && !cannotFireCoax;
} else if (getWeaponIndex(0) == 3) {
return this.entityData.get(LOADED_DRONE) > 0;
} }
} }
@ -950,6 +1068,8 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti
return this.entityData.get(LOADED_HE); return this.entityData.get(LOADED_HE);
} else if (getWeaponIndex(0) == 2) { } else if (getWeaponIndex(0) == 2) {
return this.entityData.get(MG_AMMO); return this.entityData.get(MG_AMMO);
} else if (getWeaponIndex(0) == 3) {
return this.entityData.get(LOADED_DRONE);
} }
} }
@ -984,7 +1104,7 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti
var typeIndex = isScroll ? (value + getWeaponIndex(index) + count) % count : value; var typeIndex = isScroll ? (value + getWeaponIndex(index) + count) % count : value;
if (typeIndex != 2) { if (typeIndex == 0 || typeIndex == 1) {
if (entityData.get(LOADED_AP) > 0 && typeIndex == 1) { if (entityData.get(LOADED_AP) > 0 && typeIndex == 1) {
if (this.getFirstPassenger() instanceof Player player && !InventoryTool.hasCreativeAmmoBox(player)) { if (this.getFirstPassenger() instanceof Player player && !InventoryTool.hasCreativeAmmoBox(player)) {
this.insertItem(ModItems.AP_5_INCHES.get(), 1); this.insertItem(ModItems.AP_5_INCHES.get(), 1);

View file

@ -848,6 +848,10 @@ public abstract class VehicleEntity extends Entity {
public void push(double pX, double pY, double pZ) { public void push(double pX, double pY, double pZ) {
} }
public Vec3 getNewEyePos(float pPartialTicks) {
return getEyePosition();
}
public Vec3 getBarrelVector(float pPartialTicks) { public Vec3 getBarrelVector(float pPartialTicks) {
return this.calculateViewVector(this.getBarrelXRot(pPartialTicks), this.getBarrelYRot(pPartialTicks)); return this.calculateViewVector(this.getBarrelXRot(pPartialTicks), this.getBarrelYRot(pPartialTicks));
} }

View file

@ -0,0 +1,28 @@
package com.atsuishio.superbwarfare.entity.vehicle.weapon;
import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.entity.projectile.SwarmDroneEntity;
import net.minecraft.world.entity.LivingEntity;
public class SwarmDroneWeapon extends VehicleWeapon {
public float explosionDamage = 125, explosionRadius = 6;
public SwarmDroneWeapon() {
this.icon = Mod.loc("textures/screens/vehicle_weapon/swarm_drone.png");
}
public SwarmDroneWeapon explosionDamage(float explosionDamage) {
this.explosionDamage = explosionDamage;
return this;
}
public SwarmDroneWeapon explosionRadius(float explosionRadius) {
this.explosionRadius = explosionRadius;
return this;
}
public SwarmDroneEntity create(LivingEntity entity) {
return new SwarmDroneEntity(entity, entity.level(), explosionDamage, explosionRadius);
}
}

View file

@ -1,5 +1,6 @@
package com.atsuishio.superbwarfare.event; package com.atsuishio.superbwarfare.event;
import com.atsuishio.superbwarfare.entity.projectile.SwarmDroneEntity;
import com.atsuishio.superbwarfare.entity.vehicle.*; import com.atsuishio.superbwarfare.entity.vehicle.*;
import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity;
import com.atsuishio.superbwarfare.init.ModItems; import com.atsuishio.superbwarfare.init.ModItems;
@ -98,5 +99,26 @@ public class ClientSoundHandler {
} }
} }
} }
List<Entity> swarmDrone = SeekTool.getEntityWithinRange(player, player.level(), 64);
for (var e : swarmDrone) {
if (e instanceof SwarmDroneEntity swarmDroneEntity) {
Vec3 listener = player.getEyePosition();
Vec3 engineRealPos = e.getEyePosition();
Vec3 toVec = listener.vectorTo(engineRealPos).normalize();
double distance = listener.distanceTo(engineRealPos);
var engineSoundPos = new Vec3(listener.x + toVec.x, listener.y + toVec.y, listener.z + toVec.z);
SoundEvent engineSound = ModSounds.DRONE_SOUND.get();
float distanceReduce;
distanceReduce = (float) Math.max((1 - distance / 64), 0);
if (swarmDroneEntity.tickCount > 10) {
player.level().playLocalSound(BlockPos.containing(engineSoundPos), engineSound, swarmDroneEntity.getSoundSource(), distanceReduce * distanceReduce, (float) ((2 * Math.random() - 1) * 0.002f + 1.15), false);
}
}
}
} }
} }

View file

@ -74,6 +74,8 @@ public class ModEntities {
EntityType.Builder.<HeliRocketEntity>of(HeliRocketEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(false).setTrackingRange(64).setUpdateInterval(1).sized(0.5f, 0.5f)); EntityType.Builder.<HeliRocketEntity>of(HeliRocketEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(false).setTrackingRange(64).setUpdateInterval(1).sized(0.5f, 0.5f));
public static final DeferredHolder<EntityType<?>, EntityType<WgMissileEntity>> WG_MISSILE = register("wg_missile", public static final DeferredHolder<EntityType<?>, EntityType<WgMissileEntity>> WG_MISSILE = register("wg_missile",
EntityType.Builder.<WgMissileEntity>of(WgMissileEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(false).setTrackingRange(64).setUpdateInterval(3).fireImmune().sized(0.5f, 0.5f)); EntityType.Builder.<WgMissileEntity>of(WgMissileEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(false).setTrackingRange(64).setUpdateInterval(3).fireImmune().sized(0.5f, 0.5f));
public static final DeferredHolder<EntityType<?>, EntityType<SwarmDroneEntity>> SWARM_DRONE = register("swarm_drone",
EntityType.Builder.<SwarmDroneEntity>of(SwarmDroneEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(false).setTrackingRange(64).setUpdateInterval(1).fireImmune().sized(0.5f, 0.5f));
// Vehicles // Vehicles
public static final DeferredHolder<EntityType<?>, EntityType<Mk42Entity>> MK_42 = register("mk_42", public static final DeferredHolder<EntityType<?>, EntityType<Mk42Entity>> MK_42 = register("mk_42",

View file

@ -46,5 +46,6 @@ public class ModEntityRenderers {
event.registerEntityRenderer(ModEntities.YX_100.get(), Yx100Renderer::new); event.registerEntityRenderer(ModEntities.YX_100.get(), Yx100Renderer::new);
event.registerEntityRenderer(ModEntities.WATER_MASK.get(), WaterMaskEntityRenderer::new); event.registerEntityRenderer(ModEntities.WATER_MASK.get(), WaterMaskEntityRenderer::new);
event.registerEntityRenderer(ModEntities.PRISM_TANK.get(), PrismTankRenderer::new); event.registerEntityRenderer(ModEntities.PRISM_TANK.get(), PrismTankRenderer::new);
event.registerEntityRenderer(ModEntities.SWARM_DRONE.get(), SwarmDroneRenderer::new);
} }
} }

View file

@ -118,6 +118,7 @@ public class ModItems {
public static final DeferredHolder<Item, Item> SMALL_SHELL = AMMO.register("small_shell", () -> new Item(new Item.Properties())); public static final DeferredHolder<Item, Item> SMALL_SHELL = AMMO.register("small_shell", () -> new Item(new Item.Properties()));
public static final DeferredHolder<Item, Item> ROCKET_70 = AMMO.register("rocket_70", () -> new Item(new Item.Properties())); public static final DeferredHolder<Item, Item> ROCKET_70 = AMMO.register("rocket_70", () -> new Item(new Item.Properties()));
public static final DeferredHolder<Item, Item> WIRE_GUIDE_MISSILE = AMMO.register("wire_guide_missile", () -> new Item(new Item.Properties())); public static final DeferredHolder<Item, Item> WIRE_GUIDE_MISSILE = AMMO.register("wire_guide_missile", () -> new Item(new Item.Properties()));
public static final DeferredHolder<Item, Item> SWARM_DRONE = AMMO.register("swarm_drone", () -> new Item(new Item.Properties()));
public static final DeferredHolder<Item, BeamTest> BEAM_TEST = AMMO.register("beam_test", BeamTest::new); public static final DeferredHolder<Item, BeamTest> BEAM_TEST = AMMO.register("beam_test", BeamTest::new);
/** /**

View file

@ -1,5 +1,6 @@
package com.atsuishio.superbwarfare.tools; package com.atsuishio.superbwarfare.tools;
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
@ -23,6 +24,12 @@ public class SeekTool {
.toList(); .toList();
} }
public static List<Entity> getEntityWithinRange(Player player, Level level, double range) {
return StreamSupport.stream(EntityFindUtil.getEntities(level).getAll().spliterator(), false)
.filter(e -> e.position().distanceTo(player.getEyePosition()) <= range)
.toList();
}
public static Entity seekEntity(Entity entity, Level level, double seekRange, double seekAngle) { public static Entity seekEntity(Entity entity, Level level, double seekRange, double seekAngle) {
return StreamSupport.stream(EntityFindUtil.getEntities(level).getAll().spliterator(), false) return StreamSupport.stream(EntityFindUtil.getEntities(level).getAll().spliterator(), false)
.filter(e -> { .filter(e -> {
@ -68,6 +75,21 @@ public class SeekTool {
}).toList(); }).toList();
} }
public static Entity vehicleSeekEntity(VehicleEntity vehicle, Level level, double seekRange, double seekAngle) {
return StreamSupport.stream(EntityFindUtil.getEntities(level).getAll().spliterator(), false)
.filter(e -> {
if (e.distanceTo(vehicle) <= seekRange && calculateAngleVehicle(e, vehicle) < seekAngle
&& e != vehicle
&& baseFilter(e)
&& e.getVehicle() == null
&& (!e.isAlliedTo(vehicle) || e.getTeam() == null || e.getTeam().getName().equals("TDM"))) {
return level.clip(new ClipContext(vehicle.getNewEyePos(1), vehicle.getNewEyePos(1),
ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, vehicle)).getType() != HitResult.Type.BLOCK;
}
return false;
}).min(Comparator.comparingDouble(e -> calculateAngleVehicle(e, vehicle))).orElse(null);
}
public static List<Entity> seekLivingEntitiesThroughWall(Entity entity, Level level, double seekRange, double seekAngle) { public static List<Entity> seekLivingEntitiesThroughWall(Entity entity, Level level, double seekRange, double seekAngle) {
return StreamSupport.stream(EntityFindUtil.getEntities(level).getAll().spliterator(), false) return StreamSupport.stream(EntityFindUtil.getEntities(level).getAll().spliterator(), false)
.filter(e -> e.distanceTo(entity) <= seekRange && calculateAngle(e, entity) < seekAngle .filter(e -> e.distanceTo(entity) <= seekRange && calculateAngle(e, entity) < seekAngle
@ -90,6 +112,13 @@ public class SeekTool {
return VectorTool.calculateAngle(start, end); return VectorTool.calculateAngle(start, end);
} }
private static double calculateAngleVehicle(Entity entityA, VehicleEntity entityB) {
Vec3 entityBEyePos = entityB.getNewEyePos(1);
Vec3 start = new Vec3(entityA.getX() - entityBEyePos.x, entityA.getY() - entityBEyePos.y, entityA.getZ() - entityBEyePos.z);
Vec3 end = entityB.getBarrelVector(1);
return VectorTool.calculateAngle(start, end);
}
public static boolean baseFilter(Entity entity) { public static boolean baseFilter(Entity entity) {
return entity.isAlive() return entity.isAlive()
// && !(entity instanceof ItemEntity || entity instanceof ExperienceOrb || entity instanceof HangingEntity || entity instanceof Projectile || entity instanceof ArmorStand || entity instanceof ClaymoreEntity || entity instanceof C4Entity || entity instanceof AreaEffectCloud) // && !(entity instanceof ItemEntity || entity instanceof ExperienceOrb || entity instanceof HangingEntity || entity instanceof Projectile || entity instanceof ArmorStand || entity instanceof ClaymoreEntity || entity instanceof C4Entity || entity instanceof AreaEffectCloud)

View file

@ -1,9 +1,11 @@
package com.atsuishio.superbwarfare.tools; package com.atsuishio.superbwarfare.tools;
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
import net.minecraft.core.BlockPos; import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction; import net.minecraft.core.Direction;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.projectile.Projectile;
import net.minecraft.world.entity.projectile.ProjectileUtil; import net.minecraft.world.entity.projectile.ProjectileUtil;
import net.minecraft.world.level.ClipContext; import net.minecraft.world.level.ClipContext;
import net.minecraft.world.phys.*; import net.minecraft.world.phys.*;
@ -94,4 +96,28 @@ public class TraceTool {
public static boolean checkNoClip(Entity entity, Vec3 target) { public static boolean checkNoClip(Entity entity, Vec3 target) {
return entity.level().clip(new ClipContext(entity.getEyePosition(), target, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, entity)).getType() != HitResult.Type.BLOCK; return entity.level().clip(new ClipContext(entity.getEyePosition(), target, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, entity)).getType() != HitResult.Type.BLOCK;
} }
public static Entity vehiclefFindLookingEntity(VehicleEntity vehicle, Vec3 eye, double entityReach) {
double distance = entityReach * entityReach;
HitResult hitResult = pickNew(eye, 512, vehicle);
Vec3 viewVec = vehicle.getBarrelVector(1);
Vec3 toVec = eye.add(viewVec.x * entityReach, viewVec.y * entityReach, viewVec.z * entityReach);
AABB aabb = vehicle.getBoundingBox().expandTowards(viewVec.scale(entityReach)).inflate(1.0D, 1.0D, 1.0D);
EntityHitResult entityhitresult = ProjectileUtil.getEntityHitResult(vehicle, eye, toVec, aabb, p -> !p.isSpectator() && p.isAlive() && !(p instanceof Projectile), distance);
if (entityhitresult != null) {
hitResult = entityhitresult;
}
if (hitResult.getType() == HitResult.Type.ENTITY) {
return ((EntityHitResult) hitResult).getEntity();
}
return null;
}
public static HitResult pickNew(Vec3 pos, double pHitDistance, VehicleEntity vehicle) {
Vec3 vec31 = vehicle.getBarrelVector(1);
Vec3 vec32 = pos.add(vec31.x * pHitDistance, vec31.y * pHitDistance, vec31.z * pHitDistance);
return vehicle.level().clip(new ClipContext(pos, vec32, ClipContext.Block.COLLIDER, ClipContext.Fluid.ANY, vehicle));
}
} }

View file

@ -0,0 +1,123 @@
{
"format_version": "1.8.0",
"animations": {
"animation.sd.fly": {
"animation_length": 10.0083,
"bones": {
"main": {
"position": {
"0.0": [
0,
0,
0
],
"0.5": [
0,
0,
0
],
"0.6": [
0,
4,
0
]
}
},
"rot1": {
"rotation": {
"0.6": [
0,
0,
0
],
"0.9917": [
0,
750,
0
],
"10.0": [
0,
20000,
0
]
}
},
"bone": {
"rotation": {
"0.6": [
0,
0,
0
],
"0.7417": [
90,
0,
0
]
}
},
"bone2": {
"rotation": {
"0.6": [
0,
0,
0
],
"0.7417": [
-90,
0,
0
]
}
},
"rot2": {
"rotation": {
"0.6": [
0,
0,
0
],
"0.9917": [
0,
-750,
0
],
"10.0": [
0,
-20000,
0
]
}
},
"bone3": {
"rotation": {
"0.6": [
0,
0,
0
],
"0.7417": [
90,
0,
0
]
}
},
"bone4": {
"rotation": {
"0.6": [
0,
0,
0
],
"0.7417": [
-90,
0,
0
]
}
}
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -164,6 +164,7 @@
"item.superbwarfare.rocket_70": "70mm Rocket", "item.superbwarfare.rocket_70": "70mm Rocket",
"item.superbwarfare.small_shell": "Small Caliber Shells", "item.superbwarfare.small_shell": "Small Caliber Shells",
"item.superbwarfare.wire_guide_missile": "Wire Guide Missile", "item.superbwarfare.wire_guide_missile": "Wire Guide Missile",
"item.superbwarfare.swarm_drone": "Swarm Drone",
"item.superbwarfare.firing_parameters": "Firing Parameters", "item.superbwarfare.firing_parameters": "Firing Parameters",
"item.superbwarfare.ancient_cpu": "Ancient CPU", "item.superbwarfare.ancient_cpu": "Ancient CPU",
@ -441,6 +442,7 @@
"entity.superbwarfare.wg_missile": "Wire Guide Missile", "entity.superbwarfare.wg_missile": "Wire Guide Missile",
"entity.superbwarfare.laser_tower": "Laser Defense Tower", "entity.superbwarfare.laser_tower": "Laser Defense Tower",
"entity.superbwarfare.prism_tank": "Prism Tank", "entity.superbwarfare.prism_tank": "Prism Tank",
"entity.superbwarfare.swarm_drone": "Swarm Drone",
"key.categories.superbwarfare": "Superb Warfare", "key.categories.superbwarfare": "Superb Warfare",
"key.superbwarfare.hold_zoom": "Zoom (Hold)", "key.superbwarfare.hold_zoom": "Zoom (Hold)",

View file

@ -164,6 +164,7 @@
"item.superbwarfare.rocket_70": "70mm火箭弹", "item.superbwarfare.rocket_70": "70mm火箭弹",
"item.superbwarfare.small_shell": "小口径炮弹", "item.superbwarfare.small_shell": "小口径炮弹",
"item.superbwarfare.wire_guide_missile": "线控导弹", "item.superbwarfare.wire_guide_missile": "线控导弹",
"item.superbwarfare.swarm_drone": "蜂群无人机",
"item.superbwarfare.firing_parameters": "射击诸元", "item.superbwarfare.firing_parameters": "射击诸元",
"item.superbwarfare.ancient_cpu": "古代处理器", "item.superbwarfare.ancient_cpu": "古代处理器",
@ -439,6 +440,7 @@
"entity.superbwarfare.wg_missile": "线控导弹", "entity.superbwarfare.wg_missile": "线控导弹",
"entity.superbwarfare.laser_tower": "激光防御塔", "entity.superbwarfare.laser_tower": "激光防御塔",
"entity.superbwarfare.prism_tank": "光棱坦克", "entity.superbwarfare.prism_tank": "光棱坦克",
"entity.superbwarfare.swarm_drone": "蜂群无人机",
"key.categories.superbwarfare": "卓越前线", "key.categories.superbwarfare": "卓越前线",
"key.superbwarfare.hold_zoom": "瞄准(按住)", "key.superbwarfare.hold_zoom": "瞄准(按住)",

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View file

@ -0,0 +1,30 @@
{
"type": "minecraft:crafting_shaped",
"category": "misc",
"pattern": [
" a ",
"bcb",
"ded"
],
"key": {
"a": {
"item": "superbwarfare:seeker"
},
"b": {
"item": "superbwarfare:propeller"
},
"c": {
"item": "superbwarfare:motor"
},
"d": {
"item": "superbwarfare:high_energy_explosives"
},
"e": {
"item": "superbwarfare:cell"
}
},
"result": {
"id": "superbwarfare:swarm_drone",
"count": 4
}
}