Skip to content

Commit beef742

Browse files
chore: let the dragon go through blocks
1 parent b7d511b commit beef742

File tree

4 files changed

+65
-30
lines changed

4 files changed

+65
-30
lines changed

type.generic/src/main/java/net/swofty/type/generic/entity/DragonEntity.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ public class DragonEntity extends LivingEntity {
3030
public DragonEntity() {
3131
super(EntityType.ENDER_DRAGON);
3232
setNoGravity(true);
33+
hasPhysics = false;
3334
}
3435

3536
public void setTarget(Pos target, double speed) {

type.generic/src/main/java/net/swofty/type/generic/utility/AnimatedExplosion.java

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import net.minestom.server.coordinate.Pos;
44
import net.minestom.server.coordinate.Vec;
55
import net.minestom.server.entity.Player;
6+
import net.minestom.server.entity.damage.DamageType;
67
import net.minestom.server.instance.Instance;
78
import net.minestom.server.instance.block.Block;
89
import net.swofty.type.generic.entity.ExplosionBlockEntity;
@@ -12,10 +13,14 @@
1213
public class AnimatedExplosion {
1314

1415
public static int create(Instance instance, Pos center, int radius, double knockbackStrength) {
15-
return create(instance, center, radius, knockbackStrength, null);
16+
return create(instance, center, radius, knockbackStrength, 0, null);
1617
}
1718

1819
public static int create(Instance instance, Pos center, int radius, double knockbackStrength, Player excludeFromKnockback) {
20+
return create(instance, center, radius, knockbackStrength, 0, excludeFromKnockback);
21+
}
22+
23+
public static int create(Instance instance, Pos center, int radius, double knockbackStrength, float maxDamage, Player exclude) {
1924
ThreadLocalRandom random = ThreadLocalRandom.current();
2025
int blockCount = 0;
2126

@@ -50,27 +55,36 @@ public static int create(Instance instance, Pos center, int radius, double knock
5055
}
5156
}
5257

53-
if (knockbackStrength > 0) {
54-
applyKnockback(instance, center, radius, knockbackStrength, excludeFromKnockback);
58+
if (knockbackStrength > 0 || maxDamage > 0) {
59+
applyEffects(instance, center, radius, knockbackStrength, maxDamage, exclude);
5560
}
5661

5762
return blockCount;
5863
}
5964

60-
public static void applyKnockback(Instance instance, Pos center, int radius, double knockbackStrength, Player exclude) {
65+
public static void applyEffects(Instance instance, Pos center, int radius, double knockbackStrength, float maxDamage, Player exclude) {
6166
for (Player p : instance.getPlayers()) {
6267
if (p.equals(exclude)) continue;
6368

6469
double dist = p.getPosition().distance(center);
6570
if (dist <= radius && dist > 0.1) {
66-
double kbMultiplier = (1 - (dist / radius)) * knockbackStrength;
67-
Vec direction = new Vec(
68-
p.getPosition().x() - center.x(),
69-
0.5,
70-
p.getPosition().z() - center.z()
71-
).normalize().mul(kbMultiplier * 20);
72-
73-
p.setVelocity(p.getVelocity().add(direction));
71+
double falloff = 1 - (dist / radius);
72+
73+
if (knockbackStrength > 0) {
74+
double kbMultiplier = falloff * knockbackStrength;
75+
Vec direction = new Vec(
76+
p.getPosition().x() - center.x(),
77+
0.5,
78+
p.getPosition().z() - center.z()
79+
).normalize().mul(kbMultiplier * 20);
80+
81+
p.setVelocity(p.getVelocity().add(direction));
82+
}
83+
84+
if (maxDamage > 0) {
85+
float damage = (float) (falloff * maxDamage);
86+
p.damage(DamageType.EXPLOSION, damage);
87+
}
7488
}
7589
}
7690
}

type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/game/SkywarsGame.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -907,10 +907,6 @@ public GameEvent skipToNextEvent() {
907907
return nextEvent;
908908
}
909909

910-
public GameEvent getCurrentEvent() {
911-
return currentEvent;
912-
}
913-
914910
public int getAvailableSlots() {
915911
return Math.max(0, gameType.getMaxPlayers() - players.size());
916912
}

type.skywarsgame/src/main/java/net/swofty/type/skywarsgame/manager/DragonManager.java

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,11 @@ public class DragonManager {
2828
private static final double RETURN_SPEED = 0.6;
2929
private static final double ATTACK_RANGE = 6.0;
3030
private static final float ATTACK_DAMAGE = 10f;
31+
private static final double DIVE_THROUGH_DISTANCE = 40;
3132
private static final int EXPLOSION_RADIUS = 8;
3233
private static final double EXPLOSION_KNOCKBACK = 6.0;
33-
private static final long EXPLOSION_INTERVAL_MS = 1000;
34+
private static final float EXPLOSION_DAMAGE = 6f;
35+
private static final long EXPLOSION_INTERVAL_MS = 250;
3436

3537
private final SkywarsGame game;
3638
private final Instance instance;
@@ -43,6 +45,8 @@ private enum DragonState { IDLE, DIVING, RETURNING }
4345
private DragonState state = DragonState.IDLE;
4446

4547
private SkywarsPlayer diveTarget = null;
48+
private Pos diveThroughPoint = null;
49+
private boolean hasHitPlayer = false;
4650
private long idleStartTime = 0;
4751
private long diveStartTime = 0;
4852
private long lastExplosionTime = 0;
@@ -103,7 +107,7 @@ private void dragonBehaviorTick() {
103107
long now = System.currentTimeMillis();
104108
if (now - lastExplosionTime >= EXPLOSION_INTERVAL_MS) {
105109
lastExplosionTime = now;
106-
AnimatedExplosion.create(instance, dragon.getPosition(), EXPLOSION_RADIUS, EXPLOSION_KNOCKBACK);
110+
AnimatedExplosion.create(instance, dragon.getPosition(), EXPLOSION_RADIUS, EXPLOSION_KNOCKBACK, EXPLOSION_DAMAGE, null);
107111
}
108112

109113
switch (state) {
@@ -121,39 +125,59 @@ private void handleIdle() {
121125
diveTarget = target;
122126
state = DragonState.DIVING;
123127
diveStartTime = now;
128+
hasHitPlayer = false;
124129
dragon.clearTarget();
130+
131+
Pos dragonPos = dragon.getPosition();
132+
Pos playerPos = target.getPosition();
133+
double dx = playerPos.x() - dragonPos.x();
134+
double dy = playerPos.y() - dragonPos.y();
135+
double dz = playerPos.z() - dragonPos.z();
136+
double dist = Math.sqrt(dx * dx + dy * dy + dz * dz);
137+
138+
if (dist > 0.1) {
139+
double nx = dx / dist;
140+
double ny = dy / dist;
141+
double nz = dz / dist;
142+
diveThroughPoint = playerPos.add(nx * DIVE_THROUGH_DISTANCE, ny * DIVE_THROUGH_DISTANCE * 0.3, nz * DIVE_THROUGH_DISTANCE);
143+
} else {
144+
diveThroughPoint = playerPos.add(DIVE_THROUGH_DISTANCE, 0, 0);
145+
}
146+
125147
broadcaster.accept(Component.text("The Ender Dragon is diving at " + target.getUsername() + "!", NamedTextColor.RED));
126148
}
127149
}
128150
}
129151

130152
private void handleDiving() {
131-
if (diveTarget == null || diveTarget.isEliminated() || !diveTarget.isOnline()) {
153+
if (diveThroughPoint == null) {
132154
state = DragonState.RETURNING;
133155
diveTarget = null;
134156
return;
135157
}
136158

137-
if (System.currentTimeMillis() - diveStartTime > 5000) {
159+
if (System.currentTimeMillis() - diveStartTime > 8000) {
138160
state = DragonState.RETURNING;
161+
diveTarget = null;
139162
return;
140163
}
141164

142-
Pos targetPos = diveTarget.getPosition();
143-
dragon.setTarget(targetPos.add(0, 2, 0), DIVE_SPEED);
165+
dragon.setTarget(diveThroughPoint, DIVE_SPEED);
144166

145-
double dist = dragon.getPosition().distance(diveTarget.getPosition());
146-
if (dist < ATTACK_RANGE) {
147-
diveTarget.damage(DamageType.MOB_ATTACK, ATTACK_DAMAGE);
148-
broadcaster.accept(Component.text(diveTarget.getUsername() + " was struck by the Ender Dragon!", NamedTextColor.RED));
149-
state = DragonState.RETURNING;
150-
diveTarget = null;
151-
return;
167+
if (!hasHitPlayer && diveTarget != null && !diveTarget.isEliminated() && diveTarget.isOnline()) {
168+
double dist = dragon.getPosition().distance(diveTarget.getPosition());
169+
if (dist < ATTACK_RANGE) {
170+
diveTarget.damage(DamageType.MOB_ATTACK, ATTACK_DAMAGE);
171+
broadcaster.accept(Component.text(diveTarget.getUsername() + " was struck by the Ender Dragon!", NamedTextColor.RED));
172+
hasHitPlayer = true;
173+
}
152174
}
153175

154-
if (dragon.getPosition().y() < targetPos.y() - 10) {
176+
double distToEnd = dragon.getPosition().distance(diveThroughPoint);
177+
if (distToEnd < 5) {
155178
state = DragonState.RETURNING;
156179
diveTarget = null;
180+
diveThroughPoint = null;
157181
}
158182
}
159183

0 commit comments

Comments
 (0)