Skip to content

Commit 11acb12

Browse files
committed
Make the laser use the actual beam's size for determining intersections with entities. Makes the tractor beam more easily able to pick up dropped items when a lot of power is going through it
1 parent aa80805 commit 11acb12

File tree

1 file changed

+23
-6
lines changed

1 file changed

+23
-6
lines changed

src/main/java/mekanism/common/tile/laser/TileEntityBasicLaser.java

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import net.minecraft.world.level.block.TntBlock;
5050
import net.minecraft.world.level.block.state.BlockState;
5151
import net.minecraft.world.level.gameevent.GameEvent;
52+
import net.minecraft.world.phys.AABB;
5253
import net.minecraft.world.phys.BlockHitResult;
5354
import net.minecraft.world.phys.HitResult.Type;
5455
import net.minecraft.world.phys.Vec3;
@@ -105,9 +106,7 @@ protected boolean onUpdateServer() {
105106

106107
float laserEnergyScale = getEnergyScale(firing);
107108
FloatingLong remainingEnergy = firing.copy();
108-
//TODO: Make the dimensions scale with laser size
109-
// (so that the tractor beam can actually pickup items that are on the ground underneath it)
110-
List<Entity> hitEntities = level.getEntitiesOfClass(Entity.class, Pos3D.getAABB(from, to));
109+
List<Entity> hitEntities = level.getEntitiesOfClass(Entity.class, getLaserBox(direction, from, to, laserEnergyScale));
111110
if (hitEntities.isEmpty()) {
112111
setEmittingRedstone(false);
113112
} else {
@@ -116,15 +115,19 @@ protected boolean onUpdateServer() {
116115
Pos3D finalFrom = from;
117116
hitEntities.sort(Comparator.comparingDouble(entity -> entity.distanceToSqr(finalFrom)));
118117
FloatingLong energyPerDamage = MekanismConfig.general.laserEnergyPerDamage.get();
118+
AABB adjustedAABB = null;
119119
for (Entity entity : hitEntities) {
120-
if (entity.isInvulnerableTo(MekanismDamageTypes.LASER.source(level))) {
120+
if (adjustedAABB != null && !entity.getBoundingBox().intersects(adjustedAABB)) {
121+
//If we have a smaller AABB than we started with, make sure the entity still is getting hit by the laser
122+
// before we do any processing related to behavior when hit
123+
continue;
124+
} else if (entity.isInvulnerableTo(MekanismDamageTypes.LASER.source(level))) {
121125
//The entity can absorb all the energy because they are immune to the damage
122126
remainingEnergy = FloatingLong.ZERO;
123127
//Update the position that the laser is going to
124128
to = from.adjustPosition(direction, entity);
125129
break;
126-
}
127-
if (entity instanceof ItemEntity item && handleHitItem(item)) {
130+
} else if (entity instanceof ItemEntity item && handleHitItem(item)) {
128131
//TODO: Allow the tractor beam to have an energy cost for pulling items?
129132
continue;
130133
}
@@ -252,6 +255,9 @@ protected boolean onUpdateServer() {
252255
laserEnergyScale = energyScale;
253256
//Update the from position to be where the entity is
254257
from = entityPos;
258+
//Mark we have a new AABB we have to check against, as the beam isn't as large anymore,
259+
// so it is possible some things no longer should be getting hit by it
260+
adjustedAABB = getLaserBox(direction, from, to, laserEnergyScale);
255261
}
256262
}
257263
}
@@ -307,6 +313,16 @@ protected boolean onUpdateServer() {
307313
return sendUpdatePacket;
308314
}
309315

316+
private AABB getLaserBox(Direction direction, Vec3 from, Vec3 to, float energyScale) {
317+
AABB aabb = new AABB(from, to);
318+
double halfDiameter = energyScale / 2;
319+
return switch (direction) {
320+
case DOWN, UP -> aabb.inflate(halfDiameter, 0, halfDiameter);
321+
case NORTH, SOUTH -> aabb.inflate(halfDiameter, halfDiameter, 0);
322+
case WEST, EAST -> aabb.inflate(0, halfDiameter, halfDiameter);
323+
};
324+
}
325+
310326
private void withFakePlayer(ServerLevel level, double x, double y, double z, BlockPos hitPos, BlockState hitState, Direction hitSide) {
311327
MekFakePlayer dummy = MekFakePlayer.setupFakePlayer(level, x, y, z);
312328
dummy.setEmulatingUUID(getOwnerUUID());//pretend to be the owner
@@ -356,6 +372,7 @@ private float damageShield(Level level, LivingEntity livingEntity, Pos3D from, f
356372
}
357373

358374
private float getEnergyScale(FloatingLong energy) {
375+
//Returned energy scale is between [0.1, 0.6]
359376
return Math.min(energy.divide(MekanismConfig.usage.laser.get()).divide(10).floatValue(), 0.6F);
360377
}
361378

0 commit comments

Comments
 (0)