允许获取命中的OBB部件
This commit is contained in:
parent
869687d58a
commit
46e7c2b5e0
5 changed files with 57 additions and 15 deletions
|
@ -0,0 +1,21 @@
|
||||||
|
package com.atsuishio.superbwarfare.entity.mixin;
|
||||||
|
|
||||||
|
import com.atsuishio.superbwarfare.tools.OBB;
|
||||||
|
import net.minecraft.world.entity.Entity;
|
||||||
|
|
||||||
|
public interface OBBHitter {
|
||||||
|
|
||||||
|
static OBBHitter getInstance(Entity entity) {
|
||||||
|
return (OBBHitter) entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取当前命中部分
|
||||||
|
*/
|
||||||
|
OBB.Part sbw$getCurrentHitPart();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置当前命中部分
|
||||||
|
*/
|
||||||
|
void sbw$setCurrentHitPart(OBB.Part part);
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ package com.atsuishio.superbwarfare.entity.vehicle.base;
|
||||||
|
|
||||||
import com.atsuishio.superbwarfare.Mod;
|
import com.atsuishio.superbwarfare.Mod;
|
||||||
import com.atsuishio.superbwarfare.data.vehicle.VehicleData;
|
import com.atsuishio.superbwarfare.data.vehicle.VehicleData;
|
||||||
|
import com.atsuishio.superbwarfare.entity.mixin.OBBHitter;
|
||||||
import com.atsuishio.superbwarfare.entity.vehicle.DroneEntity;
|
import com.atsuishio.superbwarfare.entity.vehicle.DroneEntity;
|
||||||
import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier;
|
import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier;
|
||||||
import com.atsuishio.superbwarfare.entity.vehicle.weapon.VehicleWeapon;
|
import com.atsuishio.superbwarfare.entity.vehicle.weapon.VehicleWeapon;
|
||||||
|
@ -48,6 +49,7 @@ import net.minecraft.world.entity.LivingEntity;
|
||||||
import net.minecraft.world.entity.Pose;
|
import net.minecraft.world.entity.Pose;
|
||||||
import net.minecraft.world.entity.player.Player;
|
import net.minecraft.world.entity.player.Player;
|
||||||
import net.minecraft.world.entity.projectile.AbstractArrow;
|
import net.minecraft.world.entity.projectile.AbstractArrow;
|
||||||
|
import net.minecraft.world.entity.projectile.Projectile;
|
||||||
import net.minecraft.world.entity.vehicle.DismountHelper;
|
import net.minecraft.world.entity.vehicle.DismountHelper;
|
||||||
import net.minecraft.world.item.ItemStack;
|
import net.minecraft.world.item.ItemStack;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
|
@ -428,6 +430,12 @@ public abstract class VehicleEntity extends Entity {
|
||||||
repairCoolDown = maxRepairCoolDown();
|
repairCoolDown = maxRepairCoolDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO 这里可以获取击中的部位,给需要的载具加一个部位受伤方法
|
||||||
|
if (source.getDirectEntity() instanceof Projectile projectile) {
|
||||||
|
OBBHitter accessor = OBBHitter.getInstance(projectile);
|
||||||
|
// System.out.println(accessor.sbw$getCurrentHitPart());
|
||||||
|
}
|
||||||
|
|
||||||
this.onHurt(computedAmount, source.getEntity(), true);
|
this.onHurt(computedAmount, source.getEntity(), true);
|
||||||
return super.hurt(source, computedAmount);
|
return super.hurt(source, computedAmount);
|
||||||
}
|
}
|
||||||
|
@ -449,10 +457,8 @@ public abstract class VehicleEntity extends Entity {
|
||||||
|
|
||||||
if (attacker != null) {
|
if (attacker != null) {
|
||||||
Vec3 toVec = new Vec3(getX(), getY() + getBbHeight() / 2, getZ()).vectorTo(attacker.position()).normalize();
|
Vec3 toVec = new Vec3(getX(), getY() + getBbHeight() / 2, getZ()).vectorTo(attacker.position()).normalize();
|
||||||
float angle = (float) java.lang.Math.abs(VectorTool.calculateAngle(this.position().vectorTo(attacker.position()), this.getViewVector(1)));
|
return (float) Math.max(1f - multiply * toVec.dot(getViewVector(1)), 0.5f);
|
||||||
return (float) java.lang.Math.max(1f - multiply * toVec.dot(getViewVector(1)), 0.5f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package com.atsuishio.superbwarfare.mixins;
|
package com.atsuishio.superbwarfare.mixins;
|
||||||
|
|
||||||
|
import com.atsuishio.superbwarfare.entity.mixin.OBBHitter;
|
||||||
import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity;
|
import com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity;
|
||||||
|
import com.atsuishio.superbwarfare.tools.OBB;
|
||||||
import net.minecraft.world.entity.Entity;
|
import net.minecraft.world.entity.Entity;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
@ -11,7 +13,7 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
@Mixin(Entity.class)
|
@Mixin(Entity.class)
|
||||||
public class EntityMixin {
|
public class EntityMixin implements OBBHitter {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* From Automobility
|
* From Automobility
|
||||||
|
@ -38,6 +40,19 @@ public class EntityMixin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Unique
|
||||||
|
public OBB.Part sbw$currentHitPart;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public OBB.Part sbw$getCurrentHitPart() {
|
||||||
|
return this.sbw$currentHitPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sbw$setCurrentHitPart(OBB.Part part) {
|
||||||
|
this.sbw$currentHitPart = part;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO 优化后续逻辑
|
// TODO 优化后续逻辑
|
||||||
// @Redirect(method = "turn(DD)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;setXRot(F)V", ordinal = 1))
|
// @Redirect(method = "turn(DD)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/entity/Entity;setXRot(F)V", ordinal = 1))
|
||||||
// public void turn(Entity instance, float pXRot) {
|
// public void turn(Entity instance, float pXRot) {
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
package com.atsuishio.superbwarfare.mixins;
|
package com.atsuishio.superbwarfare.mixins;
|
||||||
|
|
||||||
import com.atsuishio.superbwarfare.entity.OBBEntity;
|
import com.atsuishio.superbwarfare.entity.OBBEntity;
|
||||||
import com.atsuishio.superbwarfare.entity.vehicle.Bmp2Entity;
|
import com.atsuishio.superbwarfare.entity.mixin.OBBHitter;
|
||||||
import com.atsuishio.superbwarfare.init.ModParticleTypes;
|
import com.atsuishio.superbwarfare.init.ModParticleTypes;
|
||||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||||
import com.atsuishio.superbwarfare.tools.OBB;
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.particles.ParticleTypes;
|
import net.minecraft.core.particles.ParticleTypes;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
|
@ -25,7 +24,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
import static com.atsuishio.superbwarfare.entity.vehicle.Bmp2Entity.TURRET_DAMAGED;
|
|
||||||
import static com.atsuishio.superbwarfare.tools.ParticleTool.sendParticle;
|
import static com.atsuishio.superbwarfare.tools.ParticleTool.sendParticle;
|
||||||
|
|
||||||
@Mixin(ProjectileUtil.class)
|
@Mixin(ProjectileUtil.class)
|
||||||
|
@ -47,6 +45,9 @@ public class ProjectileUtilMixin {
|
||||||
double d1 = pStartVec.distanceToSqr(new Vec3(optional.get()));
|
double d1 = pStartVec.distanceToSqr(new Vec3(optional.get()));
|
||||||
if (d1 < Double.MAX_VALUE) {
|
if (d1 < Double.MAX_VALUE) {
|
||||||
EntityHitResult hitResult = new EntityHitResult(entity, new Vec3(optional.get()));
|
EntityHitResult hitResult = new EntityHitResult(entity, new Vec3(optional.get()));
|
||||||
|
var acc = OBBHitter.getInstance(pProjectile);
|
||||||
|
acc.sbw$setCurrentHitPart(obb.part());
|
||||||
|
|
||||||
cir.setReturnValue(hitResult);
|
cir.setReturnValue(hitResult);
|
||||||
if (pLevel instanceof ServerLevel serverLevel && pProjectile.getDeltaMovement().lengthSqr() > 0.01) {
|
if (pLevel instanceof ServerLevel serverLevel && pProjectile.getDeltaMovement().lengthSqr() > 0.01) {
|
||||||
Vec3 hitPos = hitResult.getLocation();
|
Vec3 hitPos = hitResult.getLocation();
|
||||||
|
@ -55,9 +56,6 @@ public class ProjectileUtilMixin {
|
||||||
sendParticle(serverLevel, ParticleTypes.SMOKE, hitPos.x, hitPos.y, hitPos.z, 2, 0, 0, 0, 0.01, false);
|
sendParticle(serverLevel, ParticleTypes.SMOKE, hitPos.x, hitPos.y, hitPos.z, 2, 0, 0, 0, 0.01, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (obbEntity instanceof Bmp2Entity bmp2 && obb.part() == OBB.Part.TURRET) {
|
|
||||||
bmp2.getEntityData().set(TURRET_DAMAGED, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import java.util.Optional;
|
||||||
* @param center 旋转中心
|
* @param center 旋转中心
|
||||||
* @param extents 三个轴向上的半长
|
* @param extents 三个轴向上的半长
|
||||||
* @param rotation 旋转
|
* @param rotation 旋转
|
||||||
|
* @param part 部件
|
||||||
*/
|
*/
|
||||||
public record OBB(Vector3f center, Vector3f extents, Quaternionf rotation, Part part) {
|
public record OBB(Vector3f center, Vector3f extents, Quaternionf rotation, Part part) {
|
||||||
|
|
||||||
|
@ -257,10 +258,11 @@ public record OBB(Vector3f center, Vector3f extents, Quaternionf rotation, Part
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum Part {
|
public enum Part {
|
||||||
WHEEL_LEFT(),
|
EMPTY,
|
||||||
WHEEL_RIGHT(),
|
WHEEL_LEFT,
|
||||||
TURRET(),
|
WHEEL_RIGHT,
|
||||||
ENGINE(),
|
TURRET,
|
||||||
BODY();
|
ENGINE,
|
||||||
|
BODY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue