Skip to content

Commit b073b38

Browse files
Merge pull request #6 from FluxCapacitor2/collision-method-abstraction
Abstract common collision logic across all Projectile implementations into AbstractProjectile
2 parents abb0dfa + 6eb0e1b commit b073b38

5 files changed

Lines changed: 35 additions & 139 deletions

File tree

src/main/java/ca/atlasengine/projectiles/AbstractProjectile.java

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package ca.atlasengine.projectiles;
22

3+
import net.minestom.server.MinecraftServer;
34
import net.minestom.server.ServerFlag;
45
import net.minestom.server.collision.*;
56
import net.minestom.server.coordinate.Point;
@@ -13,6 +14,7 @@
1314
import net.minestom.server.event.entity.projectile.ProjectileCollideWithEntityEvent;
1415
import net.minestom.server.instance.Chunk;
1516
import net.minestom.server.instance.block.Block;
17+
import net.minestom.server.instance.block.BlockHandler;
1618
import net.minestom.server.utils.chunk.ChunkCache;
1719
import net.minestom.server.utils.chunk.ChunkUtils;
1820
import org.jetbrains.annotations.NotNull;
@@ -21,12 +23,23 @@ public abstract class AbstractProjectile extends Entity implements Projectile {
2123
protected final Entity shooter;
2224
protected PhysicsResult previousPhysicsResult;
2325
protected Pos previousPosition;
26+
protected boolean inBlock = false;
2427

2528
public AbstractProjectile(EntityType type, Entity shooter) {
2629
super(type);
2730
this.shooter = shooter;
2831
}
2932

33+
@Override
34+
public void tick(long time) {
35+
if (removed || inBlock) return;
36+
updatePosition(time);
37+
38+
if (!callEntityCollision()) {
39+
callBlockCollision();
40+
}
41+
}
42+
3043
@Override
3144
public void shoot(Point from, double power, double spread) {
3245
var to = from.add(shooter.getPosition().direction());
@@ -140,16 +153,32 @@ protected void updatePosition(long time) {
140153
EventDispatcher.call(new EntityTickEvent(this));
141154
}
142155

156+
protected void handleBlockCollision(Block hitBlock, Point hitPos, Pos posBefore) {
157+
velocity = Vec.ZERO;
158+
setNoGravity(true);
159+
inBlock = true;
160+
161+
// if the value is zero, it will be unlit. If the value is more than 0.01, there will be noticeable pitch change visually
162+
position = new Pos(hitPos.x(), hitPos.y(), hitPos.z(), posBefore.yaw(), posBefore.pitch());
163+
MinecraftServer.getSchedulerManager().scheduleNextTick(this::synchronizePosition); // required as in rare situations there will be a slight disagreement with the client and server on if it hit or not | also scheduling next tick so it doesn't jump to the hit position until it has actually hit
164+
165+
callBlockCollisionEvent(Pos.fromPoint(hitPos), hitBlock);
166+
167+
BlockHandler blockHandler = hitBlock.handler();
168+
if (blockHandler == null) return;
169+
blockHandler.onTouch(new BlockHandler.Touch(hitBlock, instance, hitPos, this));
170+
}
171+
143172
/**
144173
* Handle entity collision
145-
* @param hitEntity the entity that was hit
174+
* @param result the entity that was hit
146175
* @param hitPos the position where the entity was hit
147176
* @param posBefore the position before the collision
148-
* @return true if block collisions should be ignored
177+
* @return true if block collisions should be ignored (i.e. the entity was removed while handling entity collision during the same tick)
149178
*/
150-
protected abstract boolean handleEntityCollision(EntityCollisionResult hitEntity, Point hitPos, Pos posBefore);
151-
152-
protected abstract void handleBlockCollision(Block hitBlock, Point hitPos, Pos posBefore);
179+
protected boolean handleEntityCollision(EntityCollisionResult result, Point hitPos, Pos posBefore) {
180+
return callEntityCollisionEvent(Pos.fromPoint(hitPos), result.entity());
181+
}
153182

154183
protected abstract @NotNull Vec updateVelocity(@NotNull Pos entityPosition, @NotNull Vec currentVelocity, @NotNull Block.@NotNull Getter blockGetter, @NotNull Aerodynamics aerodynamics, boolean positionChanged, boolean entityFlying, boolean entityOnGround, boolean entityNoGravity);
155184
}

src/main/java/ca/atlasengine/projectiles/entities/ArrowProjectile.java

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
package ca.atlasengine.projectiles.entities;
22

33
import ca.atlasengine.projectiles.AbstractProjectile;
4-
import net.minestom.server.MinecraftServer;
54
import net.minestom.server.ServerFlag;
65
import net.minestom.server.collision.Aerodynamics;
76
import net.minestom.server.collision.BoundingBox;
8-
import net.minestom.server.collision.EntityCollisionResult;
97
import net.minestom.server.coordinate.Point;
108
import net.minestom.server.coordinate.Pos;
119
import net.minestom.server.coordinate.Vec;
@@ -16,7 +14,6 @@
1614
import net.minestom.server.event.EventDispatcher;
1715
import net.minestom.server.event.entity.EntityShootEvent;
1816
import net.minestom.server.instance.block.Block;
19-
import net.minestom.server.instance.block.BlockHandler;
2017
import org.jetbrains.annotations.NotNull;
2118

2219
import java.util.Random;
@@ -29,7 +26,6 @@ public class ArrowProjectile extends AbstractProjectile {
2926

3027
private boolean critical = false;
3128
private boolean firstTick = true;
32-
private boolean inBlock = false;
3329

3430
public boolean isCritical() {
3531
return critical;
@@ -127,32 +123,6 @@ public void shoot(@NotNull Point from, @NotNull Point to, double power, double s
127123
});
128124
}
129125

130-
@Override
131-
protected void handleBlockCollision(Block hitBlock, Point hitPos, Pos posBefore) {
132-
velocity = Vec.ZERO;
133-
setNoGravity(true);
134-
135-
inBlock = true;
136-
velocity = Vec.fromPoint(hitPos.sub(posBefore));
137-
138-
Vec v = velocity.normalize().mul(0.01f); // required so the entity is lit (just outside the block)
139-
140-
// if the value is zero, it will be unlit. If the value is more than 0.01, there will be noticeable pitch change visually
141-
position = new Pos(hitPos.x()-v.x(), hitPos.y()-v.y(), hitPos.z()-v.z(), posBefore.yaw(), posBefore.pitch());
142-
MinecraftServer.getSchedulerManager().scheduleNextTick(this::synchronizePosition); // required as in rare situations there will be a slight disagreement with the client and server on if it hit or not | also scheduling next tick so it doesn't jump to the hit position until it has actually hit
143-
144-
callBlockCollisionEvent(Pos.fromPoint(hitPos), hitBlock);
145-
146-
BlockHandler blockHandler = hitBlock.handler();
147-
if (blockHandler == null) return;
148-
blockHandler.onTouch(new BlockHandler.Touch(hitBlock, instance, hitPos, this));
149-
}
150-
151-
@Override
152-
protected boolean handleEntityCollision(EntityCollisionResult result, Point hitPos, Pos posBefore) {
153-
return callEntityCollisionEvent(Pos.fromPoint(hitPos), result.entity());
154-
}
155-
156126
protected @NotNull Vec updateVelocity(@NotNull Pos entityPosition, @NotNull Vec currentVelocity, @NotNull Block.@NotNull Getter blockGetter, @NotNull Aerodynamics aerodynamics, boolean positionChanged, boolean entityFlying, boolean entityOnGround, boolean entityNoGravity) {
157127
if (!positionChanged) {
158128
return entityFlying ? Vec.ZERO : new Vec(0.0, entityNoGravity ? 0.0 : -aerodynamics.gravity() * aerodynamics.verticalAirResistance(), 0.0);

src/main/java/ca/atlasengine/projectiles/entities/FireballProjectile.java

Lines changed: 0 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package ca.atlasengine.projectiles.entities;
22

33
import ca.atlasengine.projectiles.AbstractProjectile;
4-
import net.minestom.server.MinecraftServer;
54
import net.minestom.server.ServerFlag;
65
import net.minestom.server.collision.Aerodynamics;
7-
import net.minestom.server.collision.EntityCollisionResult;
86
import net.minestom.server.coordinate.Point;
97
import net.minestom.server.coordinate.Pos;
108
import net.minestom.server.coordinate.Vec;
@@ -13,29 +11,17 @@
1311
import net.minestom.server.event.EventDispatcher;
1412
import net.minestom.server.event.entity.EntityShootEvent;
1513
import net.minestom.server.instance.block.Block;
16-
import net.minestom.server.instance.block.BlockHandler;
1714
import org.jetbrains.annotations.NotNull;
1815

1916
import java.util.Random;
2017
import java.util.concurrent.ThreadLocalRandom;
2118

2219
public class FireballProjectile extends AbstractProjectile {
23-
boolean inBlock = false;
24-
2520
public FireballProjectile(EntityType type, Entity shooter) {
2621
super(type, shooter);
2722
this.setNoGravity(true);
2823
}
2924

30-
@Override
31-
public void tick(long time) {
32-
if (removed || inBlock) return;
33-
34-
updatePosition(time);
35-
callEntityCollision();
36-
callBlockCollision();
37-
}
38-
3925
@Override
4026
public void shoot(@NotNull Point from, @NotNull Point to, double power, double spread) {
4127
var instance = shooter.getInstance();
@@ -86,30 +72,6 @@ public void shoot(@NotNull Point from, @NotNull Point to, double power, double s
8672
});
8773
}
8874

89-
@Override
90-
protected void handleBlockCollision(Block hitBlock, Point hitPos, Pos posBefore) {
91-
velocity = Vec.ZERO;
92-
setNoGravity(true);
93-
94-
velocity = Vec.fromPoint(hitPos.sub(posBefore));
95-
Vec v = velocity.normalize().mul(0.01f); // required so the entity is lit (just outside the block)
96-
97-
// if the value is zero, it will be unlit. If the value is more than 0.01, there will be noticeable pitch change visually
98-
position = new Pos(hitPos.x()-v.x(), hitPos.y()-v.y(), hitPos.z()-v.z(), posBefore.yaw(), posBefore.pitch());
99-
MinecraftServer.getSchedulerManager().scheduleNextTick(this::synchronizePosition); // required as in rare situations there will be a slight disagreement with the client and server on if it hit or not | also scheduling next tick so it doesn't jump to the hit position until it has actually hit
100-
101-
callBlockCollisionEvent(Pos.fromPoint(hitPos), hitBlock);
102-
103-
BlockHandler blockHandler = hitBlock.handler();
104-
if (blockHandler == null) return;
105-
blockHandler.onTouch(new BlockHandler.Touch(hitBlock, instance, hitPos, this));
106-
}
107-
108-
@Override
109-
protected boolean handleEntityCollision(EntityCollisionResult result, Point hitPos, Pos posBefore) {
110-
return callEntityCollisionEvent(Pos.fromPoint(hitPos), result.entity());
111-
}
112-
11375
protected @NotNull Vec updateVelocity(@NotNull Pos entityPosition, @NotNull Vec currentVelocity, @NotNull Block.@NotNull Getter blockGetter, @NotNull Aerodynamics aerodynamics, boolean positionChanged, boolean entityFlying, boolean entityOnGround, boolean entityNoGravity) {
11476
double x = currentVelocity.x();
11577
double y = currentVelocity.y();

src/main/java/ca/atlasengine/projectiles/entities/FollowProjectile.java

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package ca.atlasengine.projectiles.entities;
22

33
import ca.atlasengine.projectiles.AbstractProjectile;
4-
import net.minestom.server.MinecraftServer;
54
import net.minestom.server.ServerFlag;
65
import net.minestom.server.collision.Aerodynamics;
7-
import net.minestom.server.collision.EntityCollisionResult;
86
import net.minestom.server.coordinate.Point;
97
import net.minestom.server.coordinate.Pos;
108
import net.minestom.server.coordinate.Vec;
@@ -13,7 +11,6 @@
1311
import net.minestom.server.event.EventDispatcher;
1412
import net.minestom.server.event.entity.EntityShootEvent;
1513
import net.minestom.server.instance.block.Block;
16-
import net.minestom.server.instance.block.BlockHandler;
1714
import org.jetbrains.annotations.NotNull;
1815

1916
import java.util.Random;
@@ -24,8 +21,6 @@ public class FollowProjectile extends AbstractProjectile {
2421
private final float attractionAcceleration;
2522
private final float attractionVelocity;
2623

27-
boolean inBlock = false;
28-
2924
private long ticks = 0;
3025

3126
public FollowProjectile(EntityType type, Entity shooter, Entity target, float attractionVelocity, float attractionAcceleration) {
@@ -38,11 +33,7 @@ public FollowProjectile(EntityType type, Entity shooter, Entity target, float at
3833

3934
@Override
4035
public void tick(long time) {
41-
if (removed || inBlock) return;
42-
43-
updatePosition(time);
44-
callEntityCollision();
45-
36+
super.tick(time);
4637
ticks++;
4738
}
4839

@@ -102,28 +93,6 @@ public void shoot(@NotNull Point from, @NotNull Point to, double power, double s
10293
});
10394
}
10495

105-
@Override
106-
protected void handleBlockCollision(Block hitBlock, Point hitPos, Pos posBefore) {
107-
velocity = Vec.ZERO;
108-
setNoGravity(true);
109-
inBlock = true;
110-
111-
// if the value is zero, it will be unlit. If the value is more than 0.01, there will be noticeable pitch change visually
112-
position = new Pos(hitPos.x(), hitPos.y(), hitPos.z(), posBefore.yaw(), posBefore.pitch());
113-
MinecraftServer.getSchedulerManager().scheduleNextTick(this::synchronizePosition); // required as in rare situations there will be a slight disagreement with the client and server on if it hit or not | also scheduling next tick so it doesn't jump to the hit position until it has actually hit
114-
115-
callBlockCollisionEvent(Pos.fromPoint(hitPos), hitBlock);
116-
117-
BlockHandler blockHandler = hitBlock.handler();
118-
if (blockHandler == null) return;
119-
blockHandler.onTouch(new BlockHandler.Touch(hitBlock, instance, hitPos, this));
120-
}
121-
122-
@Override
123-
protected boolean handleEntityCollision(EntityCollisionResult result, Point hitPos, Pos posBefore) {
124-
return callEntityCollisionEvent(Pos.fromPoint(hitPos), result.entity());
125-
}
126-
12796
protected @NotNull Vec updateVelocity(@NotNull Pos entityPosition, @NotNull Vec currentVelocity, @NotNull Block.@NotNull Getter blockGetter, @NotNull Aerodynamics aerodynamics, boolean positionChanged, boolean entityFlying, boolean entityOnGround, boolean entityNoGravity) {
12897
Vec directionVector = entityPosition.sub(target.getPosition().add(0, target.getEyeHeight(), 0)).asVec().normalize().mul(attractionVelocity + attractionAcceleration * this.getAliveTicks());
12998

src/main/java/ca/atlasengine/projectiles/entities/ThrownItemProjectile.java

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package ca.atlasengine.projectiles.entities;
22

33
import ca.atlasengine.projectiles.AbstractProjectile;
4-
import net.minestom.server.MinecraftServer;
54
import net.minestom.server.ServerFlag;
65
import net.minestom.server.collision.Aerodynamics;
7-
import net.minestom.server.collision.EntityCollisionResult;
86
import net.minestom.server.coordinate.Point;
97
import net.minestom.server.coordinate.Pos;
108
import net.minestom.server.coordinate.Vec;
@@ -13,26 +11,16 @@
1311
import net.minestom.server.event.EventDispatcher;
1412
import net.minestom.server.event.entity.EntityShootEvent;
1513
import net.minestom.server.instance.block.Block;
16-
import net.minestom.server.instance.block.BlockHandler;
1714
import org.jetbrains.annotations.NotNull;
1815

1916
import java.util.Random;
2017
import java.util.concurrent.ThreadLocalRandom;
2118

2219
public class ThrownItemProjectile extends AbstractProjectile {
23-
boolean inBlock = false;
24-
2520
public ThrownItemProjectile(EntityType type, Entity shooter) {
2621
super(type, shooter);
2722
}
2823

29-
@Override
30-
public void tick(long time) {
31-
if (removed || inBlock) return;
32-
updatePosition(time);
33-
callEntityCollision();
34-
}
35-
3624
@Override
3725
public void shoot(@NotNull Point from, @NotNull Point to, double power, double spread) {
3826
var instance = shooter.getInstance();
@@ -84,28 +72,6 @@ public void shoot(@NotNull Point from, @NotNull Point to, double power, double s
8472
});
8573
}
8674

87-
@Override
88-
protected void handleBlockCollision(Block hitBlock, Point hitPos, Pos posBefore) {
89-
velocity = Vec.ZERO;
90-
setNoGravity(true);
91-
inBlock = true;
92-
93-
// if the value is zero, it will be unlit. If the value is more than 0.01, there will be noticeable pitch change visually
94-
position = new Pos(hitPos.x(), hitPos.y(), hitPos.z(), posBefore.yaw(), posBefore.pitch());
95-
MinecraftServer.getSchedulerManager().scheduleNextTick(this::synchronizePosition); // required as in rare situations there will be a slight disagreement with the client and server on if it hit or not | also scheduling next tick so it doesn't jump to the hit position until it has actually hit
96-
97-
callBlockCollisionEvent(Pos.fromPoint(hitPos), hitBlock);
98-
99-
BlockHandler blockHandler = hitBlock.handler();
100-
if (blockHandler == null) return;
101-
blockHandler.onTouch(new BlockHandler.Touch(hitBlock, instance, hitPos, this));
102-
}
103-
104-
@Override
105-
protected boolean handleEntityCollision(EntityCollisionResult result, Point hitPos, Pos posBefore) {
106-
return callEntityCollisionEvent(Pos.fromPoint(hitPos), result.entity());
107-
}
108-
10975
protected @NotNull Vec updateVelocity(@NotNull Pos entityPosition, @NotNull Vec currentVelocity, @NotNull Block.@NotNull Getter blockGetter, @NotNull Aerodynamics aerodynamics, boolean positionChanged, boolean entityFlying, boolean entityOnGround, boolean entityNoGravity) {
11076
double x = currentVelocity.x();
11177
double y = currentVelocity.y() - 0.03;

0 commit comments

Comments
 (0)