@@ -254,138 +254,243 @@ private void setUp(@NonNull Island island) {
254254 }
255255
256256 /**
257- * Main block processing method
257+ * Main block processing method that handles the magic block mechanics.
258+ * This includes phase changes, block spawning, and event handling.
258259 *
259- * @param e - event causing the processing
260- * @param i - island where it's happening
260+ * @param e - event causing the processing
261+ * @param i - island where it's happening
261262 * @param player - player who broke the block or who is involved - may be null
262- * @param world - world where the block is being broken
263+ * @param world - world where the block is being broken
263264 */
264265 private void process (@ NonNull Cancellable e , @ NonNull Island i , @ Nullable Player player , @ NonNull World world ) {
265- // Get the block that is being broken
266266 Block block = Objects .requireNonNull (i .getCenter ()).toVector ().toLocation (world ).getBlock ();
267-
268- // Get oneblock island
269267 OneBlockIslands is = getIsland (i );
268+
269+ // Process phase changes and requirements
270+ ProcessPhaseResult phaseResult = processPhase (e , i , is , player , world , block );
271+ if (e .isCancelled ()) {
272+ return ;
273+ }
270274
271- // Get the phase for current block number
272- OneBlockPhase phase = oneBlocksManager .getPhase (is .getBlockNumber ());
275+ // Initialize queue if needed
276+ initializeQueue (is , phaseResult .phase , phaseResult .isCurrPhaseNew );
277+
278+ // Process hologram and warning sounds
279+ processHologramAndWarnings (i , is , phaseResult .phase , block );
280+
281+ // Process the next block
282+ processNextBlock (e , i , player , block , is , phaseResult );
283+ }
284+
285+ private record ProcessPhaseResult (OneBlockPhase phase , boolean isCurrPhaseNew , int blockNumber ) {}
273286
274- // Save previous processing phase name
287+ /**
288+ * Processes phase changes and requirements for the magic block.
289+ * Returns a record containing phase info, whether it's a new phase, and block number.
290+ *
291+ * @param e - event being processed
292+ * @param i - island instance
293+ * @param is - oneblock island data
294+ * @param player - player involved
295+ * @param world - world where processing occurs
296+ * @param block - block being processed
297+ * @return ProcessPhaseResult containing phase details
298+ */
299+ private ProcessPhaseResult processPhase (Cancellable e , Island i , OneBlockIslands is , Player player , World world , Block block ) {
300+ OneBlockPhase phase = oneBlocksManager .getPhase (is .getBlockNumber ());
275301 String prevPhaseName = is .getPhaseName ();
276302
277- // Check if phase contains `gotoBlock`
278303 if (Objects .requireNonNull (phase ).getGotoBlock () != null ) {
279304 phase = handleGoto (is , phase .getGotoBlock ());
280305 }
281306
282- // Get current phase name
283307 String currPhaseName = phase .getPhaseName () == null ? "" : phase .getPhaseName ();
284-
285- // Get the phase for next block number
286- OneBlockPhase nextPhase = oneBlocksManager .getPhase (is .getBlockNumber () + 1 );
287-
288- // Check if nextPhase contains `gotoBlock` and override `nextPhase`
289- if (Objects .requireNonNull (nextPhase ).getGotoBlock () != null ) {
290- nextPhase = oneBlocksManager .getPhase (nextPhase .getGotoBlock ());
291- }
292-
293- // Get next phase name
294- String nextPhaseName = nextPhase == null || nextPhase .getPhaseName () == null ? "" : nextPhase .getPhaseName ();
295-
296- // If next phase is new, log break time of the last block of this phase
297- if (!currPhaseName .equalsIgnoreCase (nextPhaseName )) {
298- is .setLastPhaseChangeTime (System .currentTimeMillis ());
299- }
300-
308+ handlePhaseChange (is , phase , currPhaseName );
309+
301310 boolean isCurrPhaseNew = !is .getPhaseName ().equalsIgnoreCase (currPhaseName );
302-
303311 if (isCurrPhaseNew ) {
304-
305- // Check if requirements for new phase are met
306312 if (check .phaseRequirementsFail (player , i , is , phase , world )) {
307313 e .setCancelled (true );
308- return ;
314+ return new ProcessPhaseResult ( phase , true , 0 ) ;
309315 }
310-
311- check .setNewPhase (player , i , is , phase );
312- is .clearQueue ();
313-
314- // Set the biome for the block and one block above it
315- setBiome (block , phase .getPhaseBiome ());
316-
317- // Fire new phase event
318- Bukkit .getPluginManager ()
319- .callEvent (new MagicBlockPhaseEvent (i , player == null ? null : player .getUniqueId (), block ,
320- phase .getPhaseName (), prevPhaseName , is .getBlockNumber ()));
321- }
322-
323- if (!isCurrPhaseNew && is .getBlockNumber () % SAVE_EVERY == 0 ) {
324- // Save island data every MAX_LOOK_AHEAD blocks.
316+ handleNewPhase (player , i , is , phase , block , prevPhaseName );
317+ } else if (is .getBlockNumber () % SAVE_EVERY == 0 ) {
325318 saveIsland (i );
326319 }
327320
328- // Get the block number in this phase
329- int materialBlocksInQueue = ( int ) is . getQueue (). stream () .filter (obo -> obo .isMaterial () || obo .isCustomBlock ())
321+ int materialBlocksInQueue = ( int ) is . getQueue (). stream ()
322+ .filter (obo -> obo .isMaterial () || obo .isCustomBlock ())
330323 .count ();
331324 int blockNumber = is .getBlockNumber () - (phase .getBlockNumberValue () - 1 ) + materialBlocksInQueue ;
332325
333- // Fill a 5 block queue
326+ return new ProcessPhaseResult (phase , isCurrPhaseNew , blockNumber );
327+ }
328+
329+ /**
330+ * Handles the initialization of a new phase including biome setting and event firing.
331+ *
332+ * @param player - player triggering the phase change
333+ * @param i - island instance
334+ * @param is - oneblock island data
335+ * @param phase - new phase being entered
336+ * @param block - block being processed
337+ * @param prevPhaseName - name of the previous phase
338+ */
339+ private void handleNewPhase (Player player , Island i , OneBlockIslands is , OneBlockPhase phase , Block block , String prevPhaseName ) {
340+ check .setNewPhase (player , i , is , phase );
341+ is .clearQueue ();
342+ setBiome (block , phase .getPhaseBiome ());
343+ Bukkit .getPluginManager ().callEvent (new MagicBlockPhaseEvent (i ,
344+ player == null ? null : player .getUniqueId (),
345+ block , phase .getPhaseName (), prevPhaseName , is .getBlockNumber ()));
346+ }
347+
348+ /**
349+ * Handles phase transition mechanics including setting timestamps for phase changes.
350+ *
351+ * @param is - oneblock island data
352+ * @param phase - current phase
353+ * @param currPhaseName - name of current phase
354+ */
355+ private void handlePhaseChange (OneBlockIslands is , OneBlockPhase phase , String currPhaseName ) {
356+ OneBlockPhase nextPhase = oneBlocksManager .getPhase (is .getBlockNumber () + 1 );
357+ if (Objects .requireNonNull (nextPhase ).getGotoBlock () != null ) {
358+ nextPhase = oneBlocksManager .getPhase (nextPhase .getGotoBlock ());
359+ }
360+ String nextPhaseName = nextPhase == null || nextPhase .getPhaseName () == null ? "" : nextPhase .getPhaseName ();
361+ if (!currPhaseName .equalsIgnoreCase (nextPhaseName )) {
362+ is .setLastPhaseChangeTime (System .currentTimeMillis ());
363+ }
364+ }
365+
366+ /**
367+ * Initializes the block queue for a phase with upcoming blocks.
368+ *
369+ * @param is - oneblock island data
370+ * @param phase - current phase
371+ * @param isCurrPhaseNew - whether this is a new phase
372+ */
373+ private void initializeQueue (OneBlockIslands is , OneBlockPhase phase , boolean isCurrPhaseNew ) {
334374 if (is .getQueue ().isEmpty () || isCurrPhaseNew ) {
335- // Add initial 5 blocks
336375 for (int j = 0 ; j < MAX_LOOK_AHEAD ; j ++) {
337- is .add (phase .getNextBlock (addon , blockNumber ++ ));
376+ is .add (phase .getNextBlock (addon , j ));
338377 }
339378 }
379+ }
340380
341- // Manage Holograms
381+ /**
382+ * Updates holograms and plays warning sounds if configured.
383+ *
384+ * @param i - island instance
385+ * @param is - oneblock island data
386+ * @param phase - current phase
387+ * @param block - block being processed
388+ */
389+ private void processHologramAndWarnings (Island i , OneBlockIslands is , OneBlockPhase phase , Block block ) {
342390 addon .getHoloListener ().process (i , is , phase );
343-
344- // Play warning sound for upcoming mobs
345391 if (addon .getSettings ().getMobWarning () > 0 ) {
346392 warningSounder .play (is , block );
347393 }
394+ }
348395
349- // Get the next block
350- OneBlockObject nextBlock = (isCurrPhaseNew && phase .getFirstBlock () != null ) ? phase .getFirstBlock ()
351- : is .pollAndAdd (phase .getNextBlock (addon , blockNumber ));
396+ /**
397+ * Processes the next block in the sequence, handling entities and block changes.
398+ *
399+ * @param e - event being processed
400+ * @param i - island instance
401+ * @param player - player involved
402+ * @param block - block being processed
403+ * @param is - oneblock island data
404+ * @param phaseResult - result from phase processing
405+ */
406+ private void processNextBlock (Cancellable e , Island i , Player player , Block block , OneBlockIslands is , ProcessPhaseResult phaseResult ) {
407+ OneBlockObject nextBlock = (phaseResult .isCurrPhaseNew && phaseResult .phase .getFirstBlock () != null )
408+ ? phaseResult .phase .getFirstBlock ()
409+ : is .pollAndAdd (phaseResult .phase .getNextBlock (addon , phaseResult .blockNumber ));
352410
353- // Entity
354411 if (nextBlock .isEntity ()) {
355- if (!(e instanceof EntitySpawnEvent )) {
356- e .setCancelled (true );
357- }
358- // Entity spawns do not increment the block number or break the block
359- spawnEntity (nextBlock , block );
360- // Fire event
361- Bukkit .getPluginManager ().callEvent (new MagicBlockEntityEvent (i ,
362- player == null ? null : player .getUniqueId (), block , nextBlock .getEntityType ()));
412+ handleEntitySpawn (e , i , player , block , nextBlock );
363413 return ;
364414 }
365415
366- // Increment the block number
367416 is .incrementBlockNumber ();
417+ handleBlockBreak (e , i , player , block , nextBlock );
418+ }
419+
420+ /**
421+ * Handles entity spawning for entity-type blocks.
422+ *
423+ * @param e - event being processed
424+ * @param i - island instance
425+ * @param player - player involved
426+ * @param block - block where entity will spawn
427+ * @param nextBlock - next block object containing entity info
428+ */
429+ private void handleEntitySpawn (Cancellable e , Island i , Player player , Block block , OneBlockObject nextBlock ) {
430+ if (!(e instanceof EntitySpawnEvent )) {
431+ e .setCancelled (true );
432+ }
433+ spawnEntity (nextBlock , block );
434+ Bukkit .getPluginManager ().callEvent (new MagicBlockEntityEvent (i ,
435+ player == null ? null : player .getUniqueId (),
436+ block , nextBlock .getEntityType ()));
437+ }
368438
369- // Break the block
439+ /**
440+ * Handles different types of block breaking events.
441+ *
442+ * @param e - event being processed
443+ * @param i - island instance
444+ * @param player - player involved
445+ * @param block - block being broken
446+ * @param nextBlock - next block to spawn
447+ */
448+ private void handleBlockBreak (Cancellable e , Island i , Player player , Block block , OneBlockObject nextBlock ) {
370449 if (e instanceof BlockBreakEvent ) {
371- this . breakBlock (player , block , nextBlock , i );
450+ breakBlock (player , block , nextBlock , i );
372451 } else if (e instanceof PlayerBucketFillEvent ) {
373- Bukkit .getScheduler ().runTask (addon .getPlugin (), () -> spawnBlock (nextBlock , block ));
374- // Fire event
375- ItemStack tool = Objects .requireNonNull (player ).getInventory ().getItemInMainHand ();
376- Bukkit .getPluginManager ()
377- .callEvent (new MagicBlockEvent (i , player .getUniqueId (), tool , block , nextBlock .getMaterial ()));
378- } else if (e instanceof EntitySpawnEvent ) {
379- Bukkit .getScheduler ().runTask (addon .getPlugin (), () -> spawnBlock (nextBlock , block ));
380- } else if (e instanceof EntityInteractEvent ) {
381- // Minion breaking block
382- Bukkit .getScheduler ().runTask (addon .getPlugin (), () -> spawnBlock (nextBlock , block ));
383- // Fire event
384- Bukkit .getPluginManager ().callEvent (new MagicBlockEvent (i , null , null , block , nextBlock .getMaterial ()));
452+ handleBucketFill (player , i , block , nextBlock );
453+ } else if (e instanceof EntitySpawnEvent || e instanceof EntityInteractEvent ) {
454+ handleEntityBreak (i , block , nextBlock , e instanceof EntityInteractEvent );
385455 }
456+ }
386457
458+ /**
459+ * Handles bucket fill events including block spawning and event firing.
460+ *
461+ * @param player - player filling bucket
462+ * @param i - island instance
463+ * @param block - block being processed
464+ * @param nextBlock - next block to spawn
465+ */
466+ private void handleBucketFill (Player player , Island i , Block block , OneBlockObject nextBlock ) {
467+ Bukkit .getScheduler ().runTask (addon .getPlugin (), () -> spawnBlock (nextBlock , block ));
468+ ItemStack tool = Objects .requireNonNull (player ).getInventory ().getItemInMainHand ();
469+ Bukkit .getPluginManager ().callEvent (new MagicBlockEvent (i , player .getUniqueId (), tool , block , nextBlock .getMaterial ()));
387470 }
388471
472+ /**
473+ * Handles entity-related block breaking including minion interactions.
474+ *
475+ * @param i - island instance
476+ * @param block - block being broken
477+ * @param nextBlock - next block to spawn
478+ * @param isMinion - whether the breaker is a minion
479+ */
480+ private void handleEntityBreak (Island i , Block block , OneBlockObject nextBlock , boolean isMinion ) {
481+ Bukkit .getScheduler ().runTask (addon .getPlugin (), () -> spawnBlock (nextBlock , block ));
482+ if (isMinion ) {
483+ Bukkit .getPluginManager ().callEvent (new MagicBlockEvent (i , null , null , block , nextBlock .getMaterial ()));
484+ }
485+ }
486+
487+ /**
488+ * Handles goto block mechanics, updating block numbers and lifetime.
489+ *
490+ * @param is - oneblock island data
491+ * @param gotoBlock - target block number
492+ * @return OneBlockPhase for the target block
493+ */
389494 private OneBlockPhase handleGoto (OneBlockIslands is , int gotoBlock ) {
390495 // Store lifetime
391496 is .setLifetime (is .getLifetime () + gotoBlock );
0 commit comments