mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-11-13 05:54:17 +01:00
Casualty Control
- Attempted to reduce false positives for damage from carriage contraptions
This commit is contained in:
parent
eee9c509e3
commit
e6903a733d
@ -58,6 +58,8 @@ public class BlockBreakingMovementBehaviour implements MovementBehaviour {
|
|||||||
continue;
|
continue;
|
||||||
if (entity instanceof AbstractContraptionEntity)
|
if (entity instanceof AbstractContraptionEntity)
|
||||||
continue;
|
continue;
|
||||||
|
if (entity.isPassengerOfSameVehicle(context.contraption.entity))
|
||||||
|
continue;
|
||||||
if (entity instanceof AbstractMinecart)
|
if (entity instanceof AbstractMinecart)
|
||||||
for (Entity passenger : entity.getIndirectPassengers())
|
for (Entity passenger : entity.getIndirectPassengers())
|
||||||
if (passenger instanceof AbstractContraptionEntity
|
if (passenger instanceof AbstractContraptionEntity
|
||||||
|
@ -139,6 +139,10 @@ public abstract class AbstractContraptionEntity extends Entity implements IEntit
|
|||||||
public boolean collisionEnabled() {
|
public boolean collisionEnabled() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void registerColliding(Entity collidingEntity) {
|
||||||
|
collidingEntities.put(collidingEntity, new MutableInt());
|
||||||
|
}
|
||||||
|
|
||||||
public void addSittingPassenger(Entity passenger, int seatIndex) {
|
public void addSittingPassenger(Entity passenger, int seatIndex) {
|
||||||
for (Entity entity : getPassengers()) {
|
for (Entity entity : getPassengers()) {
|
||||||
|
@ -7,7 +7,6 @@ import java.util.List;
|
|||||||
|
|
||||||
import org.apache.commons.lang3.mutable.MutableBoolean;
|
import org.apache.commons.lang3.mutable.MutableBoolean;
|
||||||
import org.apache.commons.lang3.mutable.MutableFloat;
|
import org.apache.commons.lang3.mutable.MutableFloat;
|
||||||
import org.apache.commons.lang3.mutable.MutableInt;
|
|
||||||
import org.apache.commons.lang3.mutable.MutableObject;
|
import org.apache.commons.lang3.mutable.MutableObject;
|
||||||
|
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
@ -88,11 +87,12 @@ public class ContraptionCollider {
|
|||||||
if (playerType == PlayerType.REMOTE)
|
if (playerType == PlayerType.REMOTE)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
entity.getSelfAndPassengers().forEach(e -> {
|
entity.getSelfAndPassengers()
|
||||||
if (e instanceof ServerPlayer)
|
.forEach(e -> {
|
||||||
((ServerPlayer) e).connection.aboveGroundTickCount = 0;
|
if (e instanceof ServerPlayer)
|
||||||
});
|
((ServerPlayer) e).connection.aboveGroundTickCount = 0;
|
||||||
|
});
|
||||||
|
|
||||||
if (playerType == PlayerType.SERVER)
|
if (playerType == PlayerType.SERVER)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -329,50 +329,15 @@ public class ContraptionCollider {
|
|||||||
entityPosition.z + allowedMovement.z);
|
entityPosition.z + allowedMovement.z);
|
||||||
entityPosition = entity.position();
|
entityPosition = entity.position();
|
||||||
|
|
||||||
if (contraptionEntity instanceof CarriageContraptionEntity cce && entity.isOnGround()
|
entityMotion =
|
||||||
&& !(entity instanceof ItemEntity) && cce.nonDamageTicks == 0
|
handleDamageFromTrain(world, contraptionEntity, contraptionMotion, entity, entityMotion, playerType);
|
||||||
&& AllConfigs.SERVER.trains.trainsCauseDamage.get()) {
|
|
||||||
|
|
||||||
Vec3 diffMotion = contraptionMotion.subtract(entity.getDeltaMovement());
|
|
||||||
if (diffMotion.length() > 0.35f && contraptionMotion.length() > 0.35f) {
|
|
||||||
|
|
||||||
EntityDamageSource pSource = new EntityDamageSource("create.run_over", contraptionEntity);
|
|
||||||
double damage = diffMotion.length();
|
|
||||||
if (entity.getClassification(false) == MobCategory.MONSTER)
|
|
||||||
damage *= 2;
|
|
||||||
|
|
||||||
if (!(entity instanceof Player p) || !p.isCreative() && !p.isSpectator()) {
|
|
||||||
if (playerType == PlayerType.CLIENT) {
|
|
||||||
AllPackets.channel
|
|
||||||
.sendToServer(new TrainCollisionPacket((int) (damage * 16), contraptionEntity.getId()));
|
|
||||||
world.playSound((Player) entity, entity.blockPosition(), SoundEvents.PLAYER_ATTACK_CRIT,
|
|
||||||
SoundSource.NEUTRAL, 1, .75f);
|
|
||||||
} else {
|
|
||||||
entity.hurt(pSource, (int) (damage * 16));
|
|
||||||
world.playSound(null, entity.blockPosition(), SoundEvents.PLAYER_ATTACK_CRIT,
|
|
||||||
SoundSource.NEUTRAL, 1, .75f);
|
|
||||||
if (!entity.isAlive())
|
|
||||||
contraptionEntity.getControllingPlayer()
|
|
||||||
.map(world::getPlayerByUUID)
|
|
||||||
.ifPresent(AllAdvancements.TRAIN_ROADKILL::awardTo);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vec3 added = entityMotion.add(contraptionMotion.multiply(1, 0, 1)
|
|
||||||
.normalize()
|
|
||||||
.add(0, .25, 0)
|
|
||||||
.scale(damage * 4))
|
|
||||||
.add(diffMotion);
|
|
||||||
entityMotion = VecHelper.clamp(added, 3);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
entity.hurtMarked = true;
|
entity.hurtMarked = true;
|
||||||
Vec3 contactPointMotion = Vec3.ZERO;
|
Vec3 contactPointMotion = Vec3.ZERO;
|
||||||
|
|
||||||
if (surfaceCollision.isTrue()) {
|
if (surfaceCollision.isTrue()) {
|
||||||
|
contraptionEntity.registerColliding(entity);
|
||||||
entity.fallDistance = 0;
|
entity.fallDistance = 0;
|
||||||
contraptionEntity.collidingEntities.put(entity, new MutableInt(0));
|
|
||||||
boolean canWalk = bounce != 0 || slide == 0;
|
boolean canWalk = bounce != 0 || slide == 0;
|
||||||
if (canWalk || !rotation.hasVerticalRotation()) {
|
if (canWalk || !rotation.hasVerticalRotation()) {
|
||||||
if (canWalk)
|
if (canWalk)
|
||||||
@ -401,6 +366,57 @@ public class ContraptionCollider {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Vec3 handleDamageFromTrain(Level world, AbstractContraptionEntity contraptionEntity,
|
||||||
|
Vec3 contraptionMotion, Entity entity, Vec3 entityMotion, PlayerType playerType) {
|
||||||
|
|
||||||
|
if (!(contraptionEntity instanceof CarriageContraptionEntity cce))
|
||||||
|
return entityMotion;
|
||||||
|
if (!entity.isOnGround())
|
||||||
|
return entityMotion;
|
||||||
|
if (cce.collidingEntities.containsKey(entity))
|
||||||
|
return entityMotion;
|
||||||
|
if (entity instanceof ItemEntity)
|
||||||
|
return entityMotion;
|
||||||
|
if (cce.nonDamageTicks != 0)
|
||||||
|
return entityMotion;
|
||||||
|
if (!AllConfigs.SERVER.trains.trainsCauseDamage.get())
|
||||||
|
return entityMotion;
|
||||||
|
|
||||||
|
Vec3 diffMotion = contraptionMotion.subtract(entity.getDeltaMovement());
|
||||||
|
|
||||||
|
if (diffMotion.length() <= 0.35f || contraptionMotion.length() <= 0.35f)
|
||||||
|
return entityMotion;
|
||||||
|
|
||||||
|
EntityDamageSource pSource = new EntityDamageSource("create.run_over", contraptionEntity);
|
||||||
|
double damage = diffMotion.length();
|
||||||
|
if (entity.getClassification(false) == MobCategory.MONSTER)
|
||||||
|
damage *= 2;
|
||||||
|
|
||||||
|
if (entity instanceof Player p && (p.isCreative() || p.isSpectator()))
|
||||||
|
return entityMotion;
|
||||||
|
|
||||||
|
if (playerType == PlayerType.CLIENT) {
|
||||||
|
AllPackets.channel.sendToServer(new TrainCollisionPacket((int) (damage * 16), contraptionEntity.getId()));
|
||||||
|
world.playSound((Player) entity, entity.blockPosition(), SoundEvents.PLAYER_ATTACK_CRIT,
|
||||||
|
SoundSource.NEUTRAL, 1, .75f);
|
||||||
|
} else {
|
||||||
|
entity.hurt(pSource, (int) (damage * 16));
|
||||||
|
world.playSound(null, entity.blockPosition(), SoundEvents.PLAYER_ATTACK_CRIT, SoundSource.NEUTRAL, 1, .75f);
|
||||||
|
if (!entity.isAlive())
|
||||||
|
contraptionEntity.getControllingPlayer()
|
||||||
|
.map(world::getPlayerByUUID)
|
||||||
|
.ifPresent(AllAdvancements.TRAIN_ROADKILL::awardTo);
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3 added = entityMotion.add(contraptionMotion.multiply(1, 0, 1)
|
||||||
|
.normalize()
|
||||||
|
.add(0, .25, 0)
|
||||||
|
.scale(damage * 4))
|
||||||
|
.add(diffMotion);
|
||||||
|
|
||||||
|
return VecHelper.clamp(added, 3);
|
||||||
|
}
|
||||||
|
|
||||||
static boolean bounceEntity(Entity entity, Vec3 normal, AbstractContraptionEntity contraption, double factor) {
|
static boolean bounceEntity(Entity entity, Vec3 normal, AbstractContraptionEntity contraption, double factor) {
|
||||||
if (factor == 0)
|
if (factor == 0)
|
||||||
return false;
|
return false;
|
||||||
@ -473,10 +489,10 @@ public class ContraptionCollider {
|
|||||||
boolean flag = p_20273_.x != vec3.x;
|
boolean flag = p_20273_.x != vec3.x;
|
||||||
boolean flag1 = p_20273_.y != vec3.y;
|
boolean flag1 = p_20273_.y != vec3.y;
|
||||||
boolean flag2 = p_20273_.z != vec3.z;
|
boolean flag2 = p_20273_.z != vec3.z;
|
||||||
boolean flag3 = e.isOnGround() || flag1 && p_20273_.y < 0.0D;
|
boolean flag3 = flag1 && p_20273_.y < 0.0D;
|
||||||
if (e.getStepHeight() > 0.0F && flag3 && (flag || flag2)) {
|
if (e.getStepHeight() > 0.0F && flag3 && (flag || flag2)) {
|
||||||
Vec3 vec31 =
|
Vec3 vec31 = collideBoundingBox(e, new Vec3(p_20273_.x, (double) e.getStepHeight(), p_20273_.z), aabb,
|
||||||
collideBoundingBox(e, new Vec3(p_20273_.x, (double) e.getStepHeight(), p_20273_.z), aabb, e.level, list);
|
e.level, list);
|
||||||
Vec3 vec32 = collideBoundingBox(e, new Vec3(0.0D, (double) e.getStepHeight(), 0.0D),
|
Vec3 vec32 = collideBoundingBox(e, new Vec3(0.0D, (double) e.getStepHeight(), 0.0D),
|
||||||
aabb.expandTowards(p_20273_.x, 0.0D, p_20273_.z), e.level, list);
|
aabb.expandTowards(p_20273_.x, 0.0D, p_20273_.z), e.level, list);
|
||||||
if (vec32.y < (double) e.getStepHeight()) {
|
if (vec32.y < (double) e.getStepHeight()) {
|
||||||
|
@ -107,29 +107,38 @@ public abstract class EntityContraptionInteractionMixin extends CapabilityProvid
|
|||||||
if (stepped.get())
|
if (stepped.get())
|
||||||
this.nextStep = this.nextStep();
|
this.nextStep = this.nextStep();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(at = @At(value = "TAIL"), method = "move")
|
@Inject(at = @At(value = "TAIL"), method = "move")
|
||||||
private void movementMixin(MoverType mover, Vec3 movement, CallbackInfo ci) {
|
private void movementMixin(MoverType mover, Vec3 movement, CallbackInfo ci) {
|
||||||
if (self.level.isClientSide && !self.isOnGround()) { // involves client-side view bobbing animation on contraptions
|
// involves client-side view bobbing animation on contraptions
|
||||||
Vec3 worldPos = self.position()
|
if (!self.level.isClientSide)
|
||||||
.add(0, -0.2, 0);
|
return;
|
||||||
|
if (self.isOnGround())
|
||||||
|
return;
|
||||||
|
|
||||||
boolean staysOnAtLeastOneContraption = getIntersectionContraptionsStream().anyMatch(cEntity -> {
|
Vec3 worldPos = self.position()
|
||||||
Vec3 localPos = ContraptionCollider.getWorldToLocalTranslation(worldPos, cEntity);
|
.add(0, -0.2, 0);
|
||||||
|
boolean onAtLeastOneContraption = getIntersectionContraptionsStream().anyMatch(cEntity -> {
|
||||||
|
Vec3 localPos = ContraptionCollider.getWorldToLocalTranslation(worldPos, cEntity);
|
||||||
|
|
||||||
localPos = worldPos.add(localPos);
|
localPos = worldPos.add(localPos);
|
||||||
|
|
||||||
BlockPos blockPos = new BlockPos(localPos);
|
BlockPos blockPos = new BlockPos(localPos);
|
||||||
Contraption contraption = cEntity.getContraption();
|
Contraption contraption = cEntity.getContraption();
|
||||||
StructureTemplate.StructureBlockInfo info = contraption.getBlocks()
|
StructureTemplate.StructureBlockInfo info = contraption.getBlocks()
|
||||||
.get(blockPos);
|
.get(blockPos);
|
||||||
|
|
||||||
return info != null;
|
if (info == null)
|
||||||
});
|
return false;
|
||||||
|
|
||||||
|
cEntity.registerColliding(self);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
if (staysOnAtLeastOneContraption) {
|
if (!onAtLeastOneContraption)
|
||||||
self.setOnGround(true);
|
return;
|
||||||
}
|
|
||||||
}
|
self.setOnGround(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = { "spawnSprintParticle" }, at = @At(value = "TAIL"))
|
@Inject(method = { "spawnSprintParticle" }, at = @At(value = "TAIL"))
|
||||||
|
Loading…
Reference in New Issue
Block a user