@@ -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