package Ġme . b scal . room api Ċ Ċ import Ġit . un imi . ds i . fast util . objects . Object ArrayList Ċ import Ġit . un imi . ds i . fast util . objects . Object Open HashSet Ċ import Ġkotlinx . coroutines . Coroutine Scope Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . launch Ċ import Ġorg . bukkit . Bu kkit Ċ import Ġorg . bukkit . Location Ċ import Ġorg . bukkit . Material Ċ import Ġorg . bukkit . World Ċ import Ġorg . bukkit . block . Block Ċ import Ġorg . bukkit . entity . Player Ċ import Ġorg . bukkit . util . Vector Ċ import Ġjava . util . logging . Level Ċ Ċ internal Ġval ĠNOR TH Ġ= ĠVector ( 1 , Ġ 0 , Ġ 0 ) Ċ internal Ġval ĠS OUT H Ġ= ĠVector (- 1 , Ġ 0 , Ġ 0 ) Ċ internal Ġval ĠUP Ġ= ĠVector ( 0 , Ġ 1 , Ġ 0 ) Ċ internal Ġval ĠDOWN Ġ= ĠVector ( 0 , Ġ- 1 , Ġ 0 ) Ċ internal Ġval ĠE AST Ġ= ĠVector ( 0 , Ġ 0 , Ġ 1 ) Ċ internal Ġval ĠW EST Ġ= ĠVector ( 0 , Ġ 0 , Ġ- 1 ) Ċ Ċ @ Jvm Record Ġdata Ġclass ĠF lood Fill Return Data ( val Ġis Room : ĠBoolean , Ġval Ġblocks Processed : ĠInt , Ġval Ġblocks : ĠObject ArrayList < Vector >) Ċ Ċ @ Deprecated (" Use ĠCreate Room () Ġinstead .") Ċ internal Ġfun ĠTest Wall Connect s ( player : ĠPlayer ) Ċ { Ċ ĉ val Ġscope Ġ= ĠCor outine Scope ( Dispatch ers . Default ) Ċ ĉ val Ġjob Ġ= Ġscope . launch Ġ{ Ċĉ ĉ val Ġscoped Location Ġ= Ġplayer . location . clone () Ċĉ ĉ val Ġworld Name Ġ= Ġscoped Location . world . name Ċĉ ĉ if Ġ( Does Location Exist ( scoped Location )) Ċĉ ĉ { Ċĉĉ ĉ Room Api Plugin . Log Debug ( Level . WARNING , Ġ" This Ġroom Ġseems Ġto Ġalready Ġexist !") Ċĉĉ ĉ return @ launch Ċĉ ĉ } Ċĉ ĉ val Ġstarted Ġ= ĠSystem . nano Time () Ċĉ ĉ val Ġfill Return Data : ĠF lood Fill Return Data Ġ= ĠF lood Fill ( scoped Location ) Ċĉ ĉ if Ġ( fill Return Data . is Room ) Ċĉ ĉ { Ċĉĉ ĉ val Ġroom Id Ġ= ĠInsert Room ( world Name , Ġplayer . unique Id ) Ċĉĉ ĉ Insert Block Batch ( roomId , Ġworld Name , Ġfill Return Data . blocks ) Ċĉĉ ĉ Room Api Plugin . Log Debug ( Level . INFO , Ġ" Room Id =$ roomId ") Ċĉ ĉ } ĊĊĉ ĉ val Ġdiff Ġ= ĠSystem . nano Time () Ġ- Ġstarted Ċĉ ĉ Room Api Plugin . Log Debug ( Level . INFO , Ċĉĉ ĉ " F lood Fill Ġtook : Ġ${ diff } ns Ġ(${ diff Ġ/ Ġ 1 0 0 0 0 0 0 } ms ), ĠPro cessed Ġ${ fill Return Data . blocks Processed } Ġblocks . ĠIs ĠRoom : Ġ${ fill Return Data . is Room }") Ċ ĉ } Ċ } Ċ Ċ private Ġfun ĠAdd Vec sTo New ( src : ĠVector , Ġadd : ĠVector ): ĠVector Ġ= ĠVector ( src . x Ġ+ Ġadd . x , Ġsrc . y Ġ+ Ġadd . y , Ġsrc . z Ġ+ Ġadd . z ) Ċ Ċ internal Ġfun ĠGet Block Async ( world : ĠWorld , Ġvector : ĠVector ): ĠBlock ? Ċ { Ċ ĉ val Ġx Ġ= Ġvector . block X Ċ ĉ val Ġy Ġ= Ġvector . block Y Ċ ĉ val Ġz Ġ= Ġvector . block Z Ċ ĉ val Ġfuture Ġ= Ġworld . get Chunk At Async ( x Ġshr Ġ 4 , Ġz Ġshr Ġ 4 , Ġfalse ) Ċ ĉ val Ġchunk Ġ= Ġfuture . join () Ċ ĉ if Ġ( chunk Ġ== Ġnull Ġ|| Ġ! chunk . is Loaded ) Ġreturn Ġnull Ċ ĉ return Ġchunk . getBlock ( x Ġand Ġ 1 5 , Ġy Ġand Ġ 2 5 5 , Ġz Ġand Ġ 1 5 ) Ċ } Ċ Ċ fun ĠGet Type Async ( world : ĠWorld , Ġvector : ĠVector ): ĠMaterial Ċ { Ċ ĉ val Ġx Ġ= Ġvector . block X Ċ ĉ val Ġy Ġ= Ġvector . block Y Ċ ĉ val Ġz Ġ= Ġvector . block Z Ċ ĉ val Ġfuture Ġ= Ġworld . get Chunk At Async ( x Ġshr Ġ 4 , Ġz Ġshr Ġ 4 , Ġfalse ) Ċ ĉ val Ġchunk Ġ= Ġfuture . join () Ċ ĉ if Ġ( chunk Ġ== Ġnull Ġ|| Ġ! chunk . is Loaded ) Ġreturn ĠMaterial . AIR Ċ ĉ return Ġchunk . getBlock ( x Ġand Ġ 1 5 , Ġy Ġand Ġ 2 5 5 , Ġz Ġand Ġ 1 5 ). type Ċ } Ċ Ċ fun ĠFind Blocks ( world Name : ĠString , Ġorigin : ĠVector ): ĠObject ArrayList < Vector > Ċ { Ċ ĉ val Ġworld Ġ= ĠBu kkit . get World ( world Name ) Ġ?: Ġreturn ĠObject ArrayList ( 0 ) Ċ ĉ val Ġlocation Ġ= ĠLocation ( world , Ġorigin . x , Ġorigin . y , Ġorigin . z ) Ċ ĉ val Ġblocks Ġ= ĠObject ArrayList < Vector >( 0 ) Ċ ĉ val Ġvisited : ĠObject Open HashSet < Vector > Ġ= ĠObject Open HashSet () Ċ ĉ val Ġstack : ĠObject ArrayList < Vector > Ġ= ĠObject ArrayList () Ċ ĉ stack . push ( origin ) Ċ ĉ while Ġ(! stack . isEmpty ) Ċ ĉ { Ċĉ ĉ val Ġvec Ġ= Ġstack . pop () Ċĉ ĉ location . set ( vec . x , Ġvec . y , Ġvec . z ) Ċĉ ĉ visited . add ( vec ) Ċĉ ĉ if Ġ(! location . is World Loaded ) Ċĉ ĉ { Ċĉĉ ĉ System . err . println (" World Ġnot Ġloaded ") Ċĉĉ ĉ return ĠObject ArrayList ( 0 ) Ċĉ ĉ } Ċĉ ĉ if Ġ( origin . distance Squared ( vec ) Ġ> ĠRoom Api Plugin . MAX _ SEARCH _ DISTANCE ) Ġreturn ĠObject ArrayList ( 0 ) ĊĊĉ ĉ blocks . add ( vec ) ĊĊĉ ĉ val Ġv 0 Ġ= ĠAdd Vec sTo New ( vec , ĠNOR TH ) Ċĉ ĉ if Ġ(! visited . contains ( v 0 ) Ġ&& ĠRoom Blocks . Is Excluded Or Air ( Get Block Async ( world , Ġv 0 )?. type Ġ?: ĠMaterial . AIR )) Ġstack . push ( v 0 ) ĊĊĉ ĉ val Ġv 1 Ġ= ĠAdd Vec sTo New ( vec , ĠS OUT H ) Ċĉ ĉ if Ġ(! visited . contains ( v 1 ) Ġ&& ĠRoom Blocks . Is Excluded Or Air ( Get Block Async ( world , Ġv 1 )?. type Ġ?: ĠMaterial . AIR )) Ġstack . push ( v 1 ) ĊĊĉ ĉ val Ġv 2 Ġ= ĠAdd Vec sTo New ( vec , ĠE AST ) Ċĉ ĉ if Ġ(! visited . contains ( v 2 ) Ġ&& ĠRoom Blocks . Is Excluded Or Air ( Get Block Async ( world , Ġv 2 )?. type Ġ?: ĠMaterial . AIR )) Ġstack . push ( v 2 ) ĊĊĉ ĉ val Ġv 3 Ġ= ĠAdd Vec sTo New ( vec , ĠW EST ) Ċĉ ĉ if Ġ(! visited . contains ( v 3 ) Ġ&& ĠRoom Blocks . Is Excluded Or Air ( Get Block Async ( world , Ġv 3 )?. type Ġ?: ĠMaterial . AIR )) Ġstack . push ( v 3 ) ĊĊĉ ĉ val Ġv 4 Ġ= ĠAdd Vec sTo New ( vec , ĠUP ) Ċĉ ĉ if Ġ(! visited . contains ( v 4 ) Ġ&& ĠRoom Blocks . Is Excluded Or Air ( Get Block Async ( world , Ġv 4 )?. type Ġ?: ĠMaterial . AIR )) Ġstack . push ( v 4 ) ĊĊĉ ĉ val Ġv 5 Ġ= ĠAdd Vec sTo New ( vec , ĠDOWN ) Ċĉ ĉ if Ġ(! visited . contains ( v 5 ) Ġ&& ĠRoom Blocks . Is Excluded Or Air ( Get Block Async ( world , Ġv 5 )?. type Ġ?: ĠMaterial . AIR )) Ġstack . push ( v 5 ) Ċ ĉ } Ċ ĉ return Ġblocks Ċ } Ċ Ċ fun ĠTest Room ( world Name : ĠString , Ġorigin : ĠVector ): ĠBoolean Ċ { Ċ ĉ val Ġworld Ġ= ĠBu kkit . get World ( world Name ) Ġ?: Ġreturn Ġfalse Ċ ĉ val Ġlocation Ġ= ĠLocation ( world , Ġorigin . x , Ġorigin . y , Ġorigin . z ) Ċ ĉ val Ġvisited : ĠObject Open HashSet < Vector > Ġ= ĠObject Open HashSet () Ċ ĉ val Ġstack : ĠObject ArrayList < Vector > Ġ= ĠObject ArrayList () Ċ ĉ stack . push ( origin ) Ċ ĉ while Ġ(! stack . isEmpty ) Ċ ĉ { Ċĉ ĉ val Ġvec Ġ= Ġstack . pop () Ċĉ ĉ location . set ( vec . x , Ġvec . y , Ġvec . z ) Ċĉ ĉ visited . add ( vec ) Ċĉ ĉ if Ġ(! location . is World Loaded ) Ċĉ ĉ { Ċĉĉ ĉ System . err . println (" World Ġnot Ġloaded ") Ċĉĉ ĉ return Ġfalse Ċĉ ĉ } Ċĉ ĉ if Ġ( origin . distance Squared ( vec ) Ġ> ĠRoom Api Plugin . MAX _ SEARCH _ DISTANCE ) Ġreturn Ġfalse ĊĊĉ ĉ val Ġv 0 Ġ= ĠAdd Vec sTo New ( vec , ĠNOR TH ) Ċĉ ĉ if Ġ(! visited . contains ( v 0 ) Ġ&& ĠRoom Blocks . Is Excluded Or Air ( Get Block Async ( world , Ġv 0 )?. type Ġ?: ĠMaterial . AIR )) Ġstack . push ( v 0 ) ĊĊĉ ĉ val Ġv 1 Ġ= ĠAdd Vec sTo New ( vec , ĠS OUT H ) Ċĉ ĉ if Ġ(! visited . contains ( v 1 ) Ġ&& ĠRoom Blocks . Is Excluded Or Air ( Get Block Async ( world , Ġv 1 )?. type Ġ?: ĠMaterial . AIR )) Ġstack . push ( v 1 ) ĊĊĉ ĉ val Ġv 2 Ġ= ĠAdd Vec sTo New ( vec , ĠE AST ) Ċĉ ĉ if Ġ(! visited . contains ( v 2 ) Ġ&& ĠRoom Blocks . Is Excluded Or Air ( Get Block Async ( world , Ġv 2 )?. type Ġ?: ĠMaterial . AIR )) Ġstack . push ( v 2 ) ĊĊĉ ĉ val Ġv 3 Ġ= ĠAdd Vec sTo New ( vec , ĠW EST ) Ċĉ ĉ if Ġ(! visited . contains ( v 3 ) Ġ&& ĠRoom Blocks . Is Excluded Or Air ( Get Block Async ( world , Ġv 3 )?. type Ġ?: ĠMaterial . AIR )) Ġstack . push ( v 3 ) ĊĊĉ ĉ val Ġv 4 Ġ= ĠAdd Vec sTo New ( vec , ĠUP ) Ċĉ ĉ if Ġ(! visited . contains ( v 4 ) Ġ&& ĠRoom Blocks . Is Excluded Or Air ( Get Block Async ( world , Ġv 4 )?. type Ġ?: ĠMaterial . AIR )) Ġstack . push ( v 4 ) ĊĊĉ ĉ val Ġv 5 Ġ= ĠAdd Vec sTo New ( vec , ĠDOWN ) Ċĉ ĉ if Ġ(! visited . contains ( v 5 ) Ġ&& ĠRoom Blocks . Is Excluded Or Air ( Get Block Async ( world , Ġv 5 )?. type Ġ?: ĠMaterial . AIR )) Ġstack . push ( v 5 ) Ċ ĉ } Ċ ĉ return Ġtrue Ċ } Ċ Ċ fun ĠF lood Fill ( location : ĠLocation ): ĠF lood Fill Return Data Ċ { Ċ ĉ val Ġorigin : ĠVector Ġ= Ġlocation . to Vector () Ċ ĉ val Ġvisited : ĠObject Open HashSet < Vector > Ġ= ĠObject Open HashSet () Ċ ĉ val Ġstack : ĠObject ArrayList < Vector > Ġ= ĠObject ArrayList () Ċ ĉ val Ġroom Blocks : ĠObject ArrayList < Vector > Ġ= ĠObject ArrayList () Ċ ĉ var Ġis Room Ġ= Ġtrue Ċ ĉ var Ġcounter Ġ= Ġ 0 ĊĊ ĉ if Ġ(! visited . contains ( origin )) Ġstack . push ( origin ) Ċ ĉ while Ġ(! stack . isEmpty ) Ċ ĉ { Ċĉ ĉ val Ġvec Ġ= Ġstack . pop () Ċĉ ĉ location . set ( vec . x , Ġvec . y , Ġvec . z ) Ċĉ ĉ visited . add ( vec ) Ċĉ ĉ counter ++ Ċĉ ĉ if Ġ(! location . is World Loaded Ġ|| Ġ! location . is Chunk Loaded ) Ċĉ ĉ { Ċĉĉ ĉ System . err . println (" Location 's Ġworld : Ġ${ location . world } Ġor Ġchunk : Ġ${ location . chunk } Ġis Ġnot Ġloaded . ĠCancel ing ĠF lood Fill ") Ċĉĉ ĉ return ĠF lood Fill Return Data ( false , Ġcounter , ĠObject ArrayList < Vector >( 1 )) Ċĉ ĉ } Ċĉ ĉ else Ġif Ġ( origin . distance Squared ( vec ) Ġ> ĠRoom Api Plugin . MAX _ SEARCH _ DISTANCE ) Ċĉ ĉ { Ċĉĉ ĉ is Room Ġ= Ġfalse Ċĉĉ ĉ continue Ċĉ ĉ } Ċĉ ĉ else Ġif Ġ( Room Blocks . Is Excluded Or Air ( location . block . type )) Ġ// ĠDo Ġlogic Ġhere Ċĉĉ ĉ room Blocks . add ( location . to Vector ()) Ċĉ ĉ else Ġcontinue ĊĊĉ ĉ val Ġv 0 Ġ= ĠAdd Vec sTo New ( vec , ĠNOR TH ) Ċĉ ĉ if Ġ(! visited . contains ( v 0 )) Ġstack . push ( v 0 ) ĊĊĉ ĉ val Ġv 1 Ġ= ĠAdd Vec sTo New ( vec , ĠS OUT H ) Ċĉ ĉ if Ġ(! visited . contains ( v 1 )) Ġstack . push ( v 1 ) ĊĊĉ ĉ val Ġv 2 Ġ= ĠAdd Vec sTo New ( vec , ĠE AST ) Ċĉ ĉ if Ġ(! visited . contains ( v 2 )) Ġstack . push ( v 2 ) ĊĊĉ ĉ val Ġv 3 Ġ= ĠAdd Vec sTo New ( vec , ĠW EST ) Ċĉ ĉ if Ġ(! visited . contains ( v 3 )) Ġstack . push ( v 3 ) ĊĊĉ ĉ val Ġv 4 Ġ= ĠAdd Vec sTo New ( vec , ĠUP ) Ċĉ ĉ if Ġ(! visited . contains ( v 4 )) Ġstack . push ( v 4 ) ĊĊĉ ĉ val Ġv 5 Ġ= ĠAdd Vec sTo New ( vec , ĠDOWN ) Ċĉ ĉ if Ġ(! visited . contains ( v 5 )) Ġstack . push ( v 5 ) Ċ ĉ } Ċ ĉ return ĠF lood Fill Return Data ( is Room , Ġcounter , Ġroom Blocks ) Ċ } Ċ Ċ // ĠMy Ġfirst Ġimplementation Ġof Ġf lood fill ĠI Ġtried Ġto Ġoptimize Ġwith Ġthe Ġnewer Ġversion . Ċ // ĠI Ġdid Ġsome Ġbasic Ġtests Ġand Ġfound Ġthat Ġit Ġwas Ġconsistently Ġfaster Ġby Ġ~ 1 0 - 3 0 % Ġfaster Ċ // private Ġfun ĠFill ( location : ĠLocation ) Ċ // { Ċ // ĉ val Ġorigin Ġ= Ġlocation . clone () Ċ // ĉ var Ġis Room Ġ= Ġtrue Ċ // Ċ // ĉ if Ġ( Should Process ( location )) ĠStack . push ( location ) Ċ // ĉ while Ġ(! Stack . isEmpty ) Ċ // ĉ { Ċ // ĉ ĉ val Ġstack Loc Ġ= ĠStack . pop () Ċ // ĉ ĉ val Ġx Ġ= Ġstack Loc . x Ċ // ĉ ĉ val Ġy Ġ= Ġstack Loc . y Ċ // ĉ ĉ val Ġz Ġ= Ġstack Loc . z Ċ // ĉ ĉ Vis ited . add ( stack Loc ) Ċ // ĉ ĉ Counter ++ Ċ // Ċ // ĉ ĉ if Ġ( origin . distance Squared ( stack Loc ) Ġ> ĠDistance ) Ċ // ĉ ĉ { Ċ // ĉĉ ĉ is Room Ġ= Ġfalse Ċ // ĉĉ ĉ continue Ċ // ĉ ĉ } Ċ // ĉ ĉ else Ġif Ġ( stack Loc . block . type Ġ== ĠMaterial . AIR ) Ġ// ĠDo Ġlogic Ġhere Ċ // ĉĉ ĉ Room Blocks . add ( stack Loc ) Ċ // ĉ ĉ else Ġcontinue Ċ // Ċ // ĉ ĉ // ĠChecks Ġsurrounding Ġblocks Ġand Ġcl ones Ġwhen Ġneeded Ċ // ĉ ĉ // ĠI Ġuse Ġthis Ġmethod Ġto Ġavoid Ġa Ġlot Ġof Ġunnecessary Ġcloning Ċ // ĉ ĉ var Ġloc : ĠLocation Ġ= Ġstack Loc . set ( x Ġ+ Ġ 1 , Ġy , Ġz ) Ċ // ĉ ĉ if Ġ( Should Process ( loc )) ĠStack . push ( loc . clone ()) Ċ // Ċ // ĉ ĉ loc Ġ= Ġstack Loc . set ( x Ġ- Ġ 1 , Ġy , Ġz ) Ċ // ĉ ĉ if Ġ( Should Process ( loc )) ĠStack . push ( loc . clone ()) Ċ // Ċ // ĉ ĉ loc Ġ= Ġstack Loc . set ( x , Ġy Ġ+ Ġ 1 , Ġz ) Ċ // ĉ ĉ if Ġ( Should Process ( loc )) ĠStack . push ( loc . clone ()) Ċ // Ċ // ĉ ĉ loc Ġ= Ġstack Loc . set ( x , Ġy Ġ- Ġ 1 , Ġz ) Ċ // ĉ ĉ if Ġ( Should Process ( loc )) ĠStack . push ( loc . clone ()) Ċ // Ċ // ĉ ĉ loc Ġ= Ġstack Loc . set ( x , Ġy , Ġz Ġ+ Ġ 1 ) Ċ // ĉ ĉ if Ġ( Should Process ( loc )) ĠStack . push ( loc . clone ()) Ċ // Ċ // ĉ ĉ loc Ġ= Ġstack Loc . set ( x , Ġy , Ġz Ġ- Ġ 1 ) Ċ // ĉ ĉ if Ġ( Should Process ( loc )) ĠStack . push ( loc . clone ()) Ċ // Ċ // ĉ ĉ // Ġreturns Ġstack Loc Ġto Ġoriginal Ġc ords Ċ // ĉ ĉ stack Loc . set ( x , Ġy , Ġz ) Ċ // ĉ } Ċ // Ċ // ĉ if Ġ( is Room ) Ċ // ĉ { Ċ // ĉ ĉ Bu kkit . getLogger (). info (" This Ġis Ġa Ġroom !") Ċ // ĉ } Ċ // Ċ // ĉ Vis ited . clear () Ċ // ĉ Vis ited . trim () Ċ // ĉ Stack . clear () Ċ // ĉ Stack . trim () Ċ // ĉ Room Blocks . clear () Ċ // ĉ Room Blocks . trim () Ċ //}