package Ġca . all an wang . minecraft . toolbox . helper Ċ Ċ import Ġca . all an wang . minecraft . toolbox . base . Plugin Scope Ċ import Ġca . all an wang . minecraft . toolbox . core . BoundingBox Ċ import Ġca . all an wang . minecraft . toolbox . core . Point Kt Ċ import Ġca . all an wang . minecraft . toolbox . core . Polygon Data Ċ import Ġkotlinx . coroutines . Dispatch ers Ċ import Ġkotlinx . coroutines . with Context Ċ import Ġorg . bukkit . block . Block Ċ import Ġorg . bukkit . block . Block Face Ċ import Ġjava . awt . Point Ċ import Ġjava . util . logging . Logger Ċ import Ġjavax . inject . Inject Ċ Ċ @ Plugin Scope Ċ class ĠTerraform Helper Ġ@ Inject Ġinternal Ġconstructor ( ĊĠĠĠ Ġprivate Ġval Ġlogger : ĠLogger Ċ ) Ġ{ ĊĊĠĠĠ Ġprivate Ġenum Ġclass ĠBlock Face 2 D ( ĊĠĠĠĠĠĠĠ Ġval Ġblock Face : ĠBlock Face , ĊĠĠĠĠĠĠĠ Ġval Ġopposite Block Face : ĠBlock Face ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ ĠNorth ( Block Face . NORTH , ĠBlock Face . SO UTH ), ĊĠĠĠĠĠĠĠ ĠSouth ( Block Face . SO UTH , ĠBlock Face . NORTH ), ĊĠĠĠĠĠĠĠ ĠEast ( Block Face . EAST , ĠBlock Face . WEST ), ĊĠĠĠĠĠĠĠ ĠWest ( Block Face . WEST , ĠBlock Face . EAST ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠRe strict Ġblock Ġsequence Ġsuch Ġthat Ġall Ġblocks Ġare Ġwithin Ġ[ maxSize ] Ġspaces Ġfrom Ġeach Ġother . ĊĠĠĠĠ Ġ* ĠUpdates Ġare Ġsent Ġthrough Ġ[ bounding Box ], Ġwhich Ġshould Ġbe Ġcentered Ġaround Ġthe Ġinitial Ġblock . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġprivate Ġfun ĠSequence < Block >. within Bounds ( ĊĠĠĠĠĠĠĠ Ġbounding Box : ĠBounding Box , ĊĠĠĠĠĠĠĠ ĠmaxSize : ĠInt ĊĠĠĠ Ġ): ĠSequence < Block > Ġ= Ġsequence Ġ{ ĊĠĠĠĠĠĠĠ Ġfor Ġ( element Ġin Ġthis @ within Bounds ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġbounding Box . bind ( element . x , Ġelement . z ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( bounding Box . maxSize Ġ<= ĠmaxSize ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġyield ( element ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ/** ĊĠĠĠĠ Ġ* ĠGets Ġa Ġlist Ġof Ġpoints Ġwithin Ġa Ġ 2 D Ġpath . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠA Ġpath Ġis Ġa Ġclosed Ġloop Ġof Ġconsecutive Ġblocks , ĊĠĠĠĠ Ġ* Ġwhere Ġall Ġblocks Ġin Ġthe Ġpath Ġare Ġon Ġthe Ġsame Ġy Ġ( elevation ) Ġplane , ĊĠĠĠĠ Ġ* Ġand Ġwhere Ġall Ġblocks Ġare Ġadjacent Ġto Ġexactly Ġtwo Ġother Ġblocks Ġin Ġthe Ġx , Ġz Ġplane . ĊĠĠĠĠ Ġ* ĠThis Ġmeans Ġthat Ġsegments Ġin Ġthe Ġpolygon Ġcannot Ġintersect Ġor Ġtouch , Ġmaking Ġthe Ġshape Ġun amb iguous . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* Ġ[ maxSize ] Ġrepresents Ġthe Ġmaximum Ġside Ġfor Ġa Ġbounding Ġbox . ĊĠĠĠĠ Ġ* ĠPath Ġsearching Ġis Ġcancelled Ġif Ġ[ maxSize ] Ġis Ġsur passed . ĊĠĠĠĠ Ġ* ĊĠĠĠĠ Ġ* ĠReturns Ġa Ġlist Ġof Ġpoints Ġin Ġthe Ġpolygon Ġif Ġit Ġexists , Ġor Ġnull Ġif Ġthe Ġblock Ġis Ġnot Ġpart Ġof Ġa Ġpath Ġdefined Ġabove . ĊĠĠĠĠ Ġ*/ ĊĠĠĠ Ġsuspend Ġfun Ġpoints In Polygon ( ĊĠĠĠĠĠĠĠ Ġblock : ĠBlock , ĊĠĠĠĠĠĠĠ ĠmaxSize : ĠInt Ġ= Ġ 1 0 0 ĊĠĠĠ Ġ): ĠList < Point >? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġblock Faces 2 D Ġ= ĠBlock Face 2 D . values () ĊĠĠĠĠĠĠĠ Ġval Ġbounding Box Ġ= ĠBounding Box ( block . x , Ġblock . z ) ĊĊĠĠĠĠĠĠĠ Ġval Ġpath Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠ Ġgenerate Sequence < Pair < Block , ĠBlock Face 2 D ?> >( block Ġto Ġnull ) Ġ{ Ġ( block , Ġblock Face 2 D ) Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcandidates Ġ= Ġblock Faces 2 D . map NotNull Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIgnore Ġcandidate Ġthat Ġwould Ġmap Ġback Ġto Ġprevious Ġblock ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( it . block Face Ġ== Ġblock Face 2 D ?. op pos ite Block Face ) Ġreturn @ map NotNull Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġnext Ġ= Ġblock . get Relative ( it . block Face ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( next . isEmpty ) Ġnull Ġelse Ġnext Ġto Ġit ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFirst Ġblock Ġwill Ġhave Ġ 2 Ġvalid Ġfaces ; Ġsubsequent Ġwill Ġonly Ġhave Ġone . ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( block Face 2 D Ġ== Ġnull Ġ&& Ġcandidates . size Ġ!= Ġ 2 ) Ġreturn @ generate Sequence Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( block Face 2 D Ġ!= Ġnull Ġ&& Ġcandidates . size Ġ!= Ġ 1 ) Ġreturn @ generate Sequence Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġcandidates . first () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. drop ( 1 ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. map Ġ{ Ġit . first Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. within Bounds ( bounding Box , ĠmaxSize ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. take While Ġ{ Ġit Ġ!= Ġblock Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. toList () ĊĊĠĠĠĠĠĠĠ Ġ// ĠCheck Ġif Ġpath Ġis Ġcomplete ĊĠĠĠĠĠĠĠ Ġif Ġ( path . size Ġ< Ġ 8 Ġ|| Ġpath . last OrNull () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . get Face ( block ) Ġ== Ġnull ĊĠĠĠĠĠĠĠ Ġ) Ġreturn Ġnull ĊĊĠĠĠĠĠĠĠ Ġlogger . info Ġ{ Ġ" Created Ġpath " Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġwith Context ( Dispatch ers . IO ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfull Path Ġ= Ġ( path Ġ+ Ġblock ). map Ġ{ ĠPoint Kt ( it . x , Ġit . z ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpoints In Polygon Ġ= ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠPolygon Data ( path Ġ= Ġfull Path , Ġbounding Box Ġ= Ġbounding Box ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġpoints In Polygon . points In Polygon (). map Ġ{ ĠPoint ( it . x , Ġit . y ) Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ Ċ } Ċ