From bc6a7886325bc10d8782095847bc57f057af4918 Mon Sep 17 00:00:00 2001 From: BernardisGood Date: Thu, 16 Apr 2020 23:34:17 +0100 Subject: [PATCH] Optimised Craft movement in regards to WorldHandler (#23) * Created new class `ChunkDataManager` and phased out `WorldHandler` * Optimisation successful. 54k vtest type craft translating in 31ms. * WorldHandler reduced to WorldUtils due to remaining methods; locationToBlockPos and moveEntity * CraftRotateCommand and CraftTranslateCommand now have internal methods that directly utilise ChunkDataManager --- .../4.4/fileContent/annotation-processors.bin | Bin 20549 -> 20693 bytes .gradle/4.4/fileContent/fileContent.lock | Bin 17 -> 17 bytes .gradle/4.4/fileHashes/fileHashes.bin | Bin 320928 -> 321678 bytes .gradle/4.4/fileHashes/fileHashes.lock | Bin 17 -> 17 bytes .../4.4/fileHashes/resourceHashesCache.bin | Bin 33117 -> 33661 bytes .gradle/4.4/taskHistory/taskHistory.bin | Bin 892667 -> 915283 bytes .gradle/4.4/taskHistory/taskHistory.lock | Bin 17 -> 17 bytes .../buildOutputCleanup.lock | Bin 17 -> 17 bytes .../pulverizer/movecraft/WorldHandler.html | 2 +- .../pulverizer/movecraft/Movecraft.java | 12 +- .../pulverizer/movecraft/WorldHandler.java | 337 ------------------ .../movecraft/WorldHandler.java.disabled | 331 ----------------- .../movecraft/{ => craft}/CraftState.java | 2 +- .../mapUpdater/update/CraftRotateCommand.java | 39 +- .../update/CraftTranslateCommand.java | 36 +- .../update/EntityUpdateCommand.java | 3 +- .../movecraft/utils/WorldUtils.java | 33 ++ .../movecraft/world/ChunkDataManager.java | 272 ++++++++++++++ .../{ => world}/NextTickProvider.java | 5 +- .../movecraft/world/TileHolder.java | 29 ++ 20 files changed, 406 insertions(+), 695 deletions(-) delete mode 100644 src/main/java/io/github/pulverizer/movecraft/WorldHandler.java delete mode 100644 src/main/java/io/github/pulverizer/movecraft/WorldHandler.java.disabled rename src/main/java/io/github/pulverizer/movecraft/{ => craft}/CraftState.java (71%) create mode 100644 src/main/java/io/github/pulverizer/movecraft/utils/WorldUtils.java create mode 100644 src/main/java/io/github/pulverizer/movecraft/world/ChunkDataManager.java rename src/main/java/io/github/pulverizer/movecraft/{ => world}/NextTickProvider.java (91%) create mode 100644 src/main/java/io/github/pulverizer/movecraft/world/TileHolder.java diff --git a/.gradle/4.4/fileContent/annotation-processors.bin b/.gradle/4.4/fileContent/annotation-processors.bin index cbde5a85383e703a6dde6138fcd845263dec07b1..2ad5e5a62394d958aaed90ad778b38805566c3d1 100644 GIT binary patch delta 206 zcmX@Qfbr@=#tkMCj8&6OB`O4_++Xy6drHk@1~3RXym_g_LPq{=f?b!ttoc|vR4!w?3x$)J&1}a{?IaJD$nLlX31Rv!ex=_L1&8@PDO#GT= z+&S6PO`w9AoA1i+WaM8}%b>z{O#~{qadNNX34y$3zFGBu((<8#u9JP07BO)*ZdCjs TzR_R?&t^vt7LLjHJtqJFeXc{w delta 63 zcmV-F0Kos%p#jC90kAX}0dkWy7QwB;4Z200vBH03cff3;+NC literal 17 UcmZQJv=>QwB;4Z200vBc03bsG^Z)<= diff --git a/.gradle/4.4/fileHashes/fileHashes.bin b/.gradle/4.4/fileHashes/fileHashes.bin index 6039ccbd6f35a282e521410800f3cfd37b599ad3..94df867fe0ff520c14224907e4c66015e379a4aa 100644 GIT binary patch delta 6650 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 Bey{)l delta 5102 zcmb7I2~-rv7NvRyTmWGhm$6+K)IlY(D~pH-Boaq4f>9Ae1ec&F0-}f_ASi;0B9>4n zvTq_HOa|?ULB$US8I=tF7-OOaS6neM2Ek~4O;;uPAH>7&bEdnd-o5X=s;+*wy7#EX zxhiqxLd2Xf9cy9Q{ zoJZz%50|{{3i1b=fd1l$CzEf693y!!>V< z*4Woy^lmmFl(b8PGJON8brFh3K1{9hn)WEvwCce08A-xn8c>i$#9IP#MAmZ!VyVLe z+ohqKg1x^FSawI>Bi)*SHVA3(%`jk{7#bE^$L5%rdHCB9R#>i zjIS29_%t5>Of)~kw#%QLtqXan8)a(Re7Q9qP{ti>#D|U}K6PQ_tiC#_-gkHNf_cYX z*v(CPgpn@ANPGNSqUcU(e3InpaQgnN2~RTHw|xIHhEn!oBtAy_Dcg%}1n|2Ae)i_> zfKL-xsqd)8NcOZir>4-wYL22`2u-YtaO4YN)R73Ouewj}e$lieUxyA$+-MN|FA91= zK&E=Awgrfdr@z^*jIXwRbL#Bvk<*^%^Pq35)C6SFpmZ$SjqOj@})1@ZZW)8zoVpz$gUv>qpns1WaXLWqv z{!@bSJ>r*{JKCKhV5M*L?j0%E+`QxWL8%!&BkoyJ>r&!zz-eSX2#8}{tLx6&%pO~O zYNW?bHrbaZRYyRUukf|Y9i7_|->`hJp3d;+7qyp->gZ41Mi7Q*ZFh!|esW~{{H<2- zhSWVGe26n;L~9taT3UL;yHoZ&ce0nwKVIu#AAfZ8fmc^)T6CfJ-`Abt{Pe^4&{l^t zFVmcSkK6S-K^fOHLA12``QuZUfjC7B3U?Y7z0@hl&Z$Xeus)gQm8l_MiV}rQ#1kaY zEip5nHrCemVz!g-gOSwlO#%{)!PhQ+wL&T*HrOhenB?$n>J~pc>UJk#2%mRnWZhYD z(9u4nK7WY0N5W`NJWBpP&e1RgT3Ulpo|i!EU2)Lebf!)9MK|+xzolOBTSrlv#|R%f zpWsuMOoFX*gZ5^plz%d6N3zROUvJ6?;t5*pDwy}N*w`#?YM;QM(0#xCbpP4IkscHi zN-zdN$V(2yLv9P-W_z4!?UQM*AC=eQM?ubM)(i`SKP%$D$BRFpvuof%78g zpn`_ai5soe-IIG)jl>K{82?=(aqs>fYa}+N5z6~&h-fEzAfmZi8L;@(m?a~^S02BYV(5SH@s%3xWkrJ$hUD7;b1doG6tM_5wo zG3!{5r5+nANFct{^Mk8|ChJ*v=Ey)jZ2gj0`%Fa&xlnBU4k7pl^d2F=ASLl+(E#1c z_&8N?aWV@N%lHu-hdE_@<|m+(zk*@;EIMNbY=~;$u2Vg# zhQ`>lYGCWvB+36#4cuMRqiSH|>7G>sTh9=W?@F0<$D{TNbqKyl0qoP#css6(4$_Q7+8?6vbHq zwkPWX-pXCF0<8jR(*2>;>7gmRQscE3cqoS8A!#{OxcG4Zn7zOj#LS?@qJrz=!j0eCpyZ;84;7Rigjm%Z&WdrW5YG=;H*;d4kr5 zF{o)0&=f9}1ss;b&wS$}q%an;@{Qx{eoS4mqbzG%Lh;eW>kH^epAx3GQTJH=6SLh3ym_c6-5D-=r)I=u{y z(x2wMpx1U58preNLgfI<_OhtJp1=R9 z$uMUh3)}Y+n)@I>Otq~(o1!Y!;ss`+GOMs+X`@*`9E zLKS4C%O2N$Si8%6pk1!lxrqyY{DDqHAc4|8u!4=E`U0cXIkkQoyknc!noxuQs94hOQDJ< z?hN@Y1-e5q+u`msRx&ZpD$60GHmoEj{^!%JibCoy4gQkGN(YS4Ul;eK&F$E&{wKew ze|>`*5lwFc^6Fs3Xwy`%6gsDqJ6;NJeZk7FCH<6{S>t)r=A(p^4_sHzqQs+wI8fAm zT)KK&$}g8@&GNY`^1nD>$0o`+hT>8MEL<5wyq|z^_$}^BVPxwEF;b5WK9W#l^?0m3 z{2Wxn5r~!R*0k=qtDbP6@7qoRW17dmJK;H~A)$x5cMn~ua;WHd9x4cXao~yn!a`iO zd3W_N4zXU>=Vz?XaIG~j`nurcoIfnqP$RAFLveZOdWR|vn?=#vUau~=ke9DpZ}8XH zRU`p1N_7{Ajr-5CjH{hzc{4gz-+f%>uPdlq`td@HTq_u{Jlw!>c=#>mPW4GNXL4$PB<+Ek`qE`7`V`)-*_pI3_~(vDX8qxs zHoE*DNFLf}Fz+CX7P*s$ z>Nywg4uoUCV=gifjPJ{x3;}_Fa|i>aMqI~Ma9sq3qRl0Y45>>P2?B@lX$C%V9cds~ z0?N6-W58rMm)i(N>1pHI9$3ORBJhN(+{|p0aIR_0H3QDNh`Fu}tQ96d z1GL3XFo0`3%Cs`zA*ZZh77pab)G<4TGUg8zCgT`lzjTW!HU)RNbvlAn9d3laK&{K^ z3>6?TcYK0CqJye+fj|1lR?rE;6ehV0hn+@@0~fgV&jrAUGYk{7NEkDXKW*M$q9{ec oiBg2WjsbuZRtd*zD?gtU*^jF^Cyeh0#w$!(hj4~>g?qt&0BjqoD*ylh diff --git a/.gradle/4.4/fileHashes/fileHashes.lock b/.gradle/4.4/fileHashes/fileHashes.lock index 5c6c647cd4b9ec1665d9ffb8a9dde8704aefcbd1..2f1fbee763a78ee32a19437d78b03268ec5fc4d4 100644 GIT binary patch literal 17 WcmZQxxiR4HSA}yw7(jq=QYQdKyau8G literal 17 WcmZQxxiR4HSA}yw7(jrrHw6GijRtrC diff --git a/.gradle/4.4/fileHashes/resourceHashesCache.bin b/.gradle/4.4/fileHashes/resourceHashesCache.bin index e427483c6f683c65ec39935e783dcf6827fbabb2..dcc16227f4dd384431aaae5ea7c50061a3866ac1 100644 GIT binary patch delta 381 zcmccH#Pqj~X@iLbTlq2fzdsbRGEb?*li~^S~UUxP;!`lxPt>0{` zmdM0EKdf~7&$vAh!RF}AQ#F3D35cGXzH1`Ou3)IK8#lM=|77N`+{hpMDc})QFn4pQ z@j^!aJ5{IDTN#c*1=%O_n$F}e4y+4^nFkSKX!4#s*EEygeDA)!)pOLL>iQ@DHMJ11 zp7@W;Ku8+uqGs{Ux@H#`1$?dUUD`NVWIj}>=H{>Fj7ZEJofQ+4=EIGO25g%hJ!C8==jZcn J*3S@P0sw_oeg^;m delta 100 zcmV-q0Gt2)h63G!03AH97eKvqn1?1G9BLQ312wKQRIVC}FW7um`h2 GNE|tS5+t_( diff --git a/.gradle/4.4/taskHistory/taskHistory.bin b/.gradle/4.4/taskHistory/taskHistory.bin index a142472d948ee1ebd9c0cb878ac4714fbd27c3ba..ecd51eb1d9891822774fa42b2379b0cf7939777e 100644 GIT binary patch delta 5474 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 Wzvmp1<{Y#wC)Ht#8&yqutojdI#vt(k delta 1516 zcmYjQeNa?Y6zAUS^5MI$d3-2~nd^p{B8*@PV^o5gr3QkQl{CSUf@wM`l7NBB*Z}$m zEc1Y$W*}&(O%}UJzBENpr)g>iu+-89m7K(cWNETy@T;@C;J+dbu@$W;L~sO&8@RWbw5WNq z2=>JuY7T4x!iKa@)X}(42=>&7%NQ#BUmACJZ6%E-2MDE=JUtFi&Bw^Nnm*JVDsuBu~kER)=s z%Vd>+rB`ZbKc&2lwtrbTqASUh^{FUea5Qu3bp@K5d6nm%#@hkYA+ZI^sy&k(5(Vh? zXoHuORp{!I7T8>3m45X~Fz)1fI;WUfY7QJg- zm!cMZKosvbT&4u_BM_3Abr8*F`oO zYq$dKgkr+#F&B`vp+~T*LNJ=l3H;M>9vn2 zVOr1Gh4qnjEm5-<<@98%&K-flQt3_X4@avA*K8kE^!`wumD#};-YhyYcL`i}Qy607 z#VfF!6kGM2Aq^`xN{60wM?-3xDAL34KJ1RpNYgv-hQrn_y7edSYu?Im^eNNfzNJLy zmk2t0TAhld8O(b^ieB}=OQ#N=5hlYvpj2{0E0kG5(1MwU*`1;U7d={B6UB`W=gCIZ zAsNr{`6vQy=V)VeNTZQd!%VLv?jNO75j!xt7jSb?uguiKdj`nJ*UQjump5et3h~>!2)pb zNpcL%7R08p4B%QwRsjWO5mI)7g(yw-#Jm)KMvPuTvvIqBtc8mGgJ#pBi&f?*` z$AXYLi86W1dNGHhj>NisR91V6$lh-4)p9M)draRANHq}7D`J$^|JV0u*mw4gisqri zb5hFZ_}0=W)nH^!8E&v`vd}OtYPd?5E??A+@r^6?9*9>S-*)fSQ$-NaxE<>CWbURn{3ag5nz;D6Hf~)o=(qHuuD$kaNiJiZA$WfWB-AW zT_3lGn&-7!zeM#ZI^72|nXFsO0=1$ui*ueoGOKL%w%(;%h2N%j>(b;k1}##3qWDA2aMfiswy6Sc~kv`5(_3I1&H= diff --git a/.gradle/4.4/taskHistory/taskHistory.lock b/.gradle/4.4/taskHistory/taskHistory.lock index 7282afaef5702499b01eea6baf317dd7407aaf48..7c4f850c2f60344fc36056e8b77aa0ca56ed55b4 100644 GIT binary patch literal 17 VcmZS9{e92*`P`m)3}7Jq9soZA1^oa3 literal 17 VcmZS9{e92*`P`m)3}7I98~{Gr1=Rom diff --git a/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/.gradle/buildOutputCleanup/buildOutputCleanup.lock index a9b2d58c1061399979a792fc956854ff60060ef1..77c9825e88b3f9365093a10cfa27440d50a393b9 100644 GIT binary patch literal 17 VcmZRc*Xd~;U3lp$0~mClass WorldHandler
  • java.lang.Object
    • -
    • io.github.pulverizer.movecraft.WorldHandler
    • +
    • io.github.pulverizer.movecraft.world.WorldHandler
  • diff --git a/src/main/java/io/github/pulverizer/movecraft/Movecraft.java b/src/main/java/io/github/pulverizer/movecraft/Movecraft.java index 36fec6cdc..a584b3b2c 100644 --- a/src/main/java/io/github/pulverizer/movecraft/Movecraft.java +++ b/src/main/java/io/github/pulverizer/movecraft/Movecraft.java @@ -4,6 +4,7 @@ import com.google.inject.Inject; import io.github.pulverizer.movecraft.listener.*; import io.github.pulverizer.movecraft.sign.*; +import io.github.pulverizer.movecraft.utils.WorldUtils; import ninja.leaping.configurate.ConfigurationNode; import ninja.leaping.configurate.ConfigurationOptions; import ninja.leaping.configurate.loader.ConfigurationLoader; @@ -46,7 +47,6 @@ public class Movecraft { private static Movecraft instance; - private WorldHandler worldHandler; private ConfigurationLoader mainConfigLoader; private ConfigurationNode mainConfigNode; @@ -153,8 +153,6 @@ public void onLoad(GamePreInitializationEvent event) { Settings.PilotTool = pilotStick; } - worldHandler = new WorldHandler(); - Settings.SinkCheckTicks = mainConfigNode.getNode("SinkCheckTicks").getDouble(100.0); Settings.TracerRateTicks = mainConfigNode.getNode("TracerRateTicks").getDouble(5.0); @@ -266,12 +264,4 @@ public void initializeManagers(GameStartedServerEvent event) { .submit(this); } - /** - * Fetches the WorldHandler instance that the Plugin is using. - * @return WorldHandler instance. - */ - public WorldHandler getWorldHandler(){ - return worldHandler; - } - } diff --git a/src/main/java/io/github/pulverizer/movecraft/WorldHandler.java b/src/main/java/io/github/pulverizer/movecraft/WorldHandler.java deleted file mode 100644 index df3d31ddc..000000000 --- a/src/main/java/io/github/pulverizer/movecraft/WorldHandler.java +++ /dev/null @@ -1,337 +0,0 @@ -package io.github.pulverizer.movecraft; - -import com.flowpowered.math.vector.Vector3d; -import com.flowpowered.math.vector.Vector3i; -import io.github.pulverizer.movecraft.config.Settings; -import io.github.pulverizer.movecraft.craft.Craft; -import io.github.pulverizer.movecraft.enums.Rotation; -import io.github.pulverizer.movecraft.utils.CollectionUtils; -import io.github.pulverizer.movecraft.utils.MathUtils; -import net.minecraft.block.BlockFire; -import net.minecraft.block.state.IBlockState; -import net.minecraft.init.Blocks; -import net.minecraft.tileentity.TileEntity; -import net.minecraft.util.math.BlockPos; -import net.minecraft.world.NextTickListEntry; -import net.minecraft.world.WorldServer; -import net.minecraft.world.chunk.Chunk; -import net.minecraft.world.chunk.storage.ExtendedBlockStorage; -import org.spongepowered.api.block.BlockState; -import org.spongepowered.api.block.BlockTypes; -import org.spongepowered.api.entity.Entity; -import org.spongepowered.api.world.Location; -import org.spongepowered.api.world.World; - -import java.util.*; - -public class WorldHandler { - private static final net.minecraft.util.Rotation[] ROTATION; - - static { - ROTATION = new net.minecraft.util.Rotation[3]; - ROTATION[Rotation.NONE.ordinal()] = net.minecraft.util.Rotation.NONE; - ROTATION[Rotation.CLOCKWISE.ordinal()] = net.minecraft.util.Rotation.CLOCKWISE_90; - ROTATION[Rotation.ANTICLOCKWISE.ordinal()] = net.minecraft.util.Rotation.COUNTERCLOCKWISE_90; - } - - private static final NextTickProvider tickProvider = new NextTickProvider(); - - public WorldHandler() { - } - - /** - * Moves the Entity to the Location in the World that the Entity currently resides in and applies the Rotation to the Entity. - * - * @param entity Entity to be moved. - * @param newLocation Vector3d location to move the Entity to. - * @param rotation New Rotation of the Entity. - */ - public void moveEntity(Entity entity, Vector3d newLocation, float rotation) { - boolean entityMoved = entity.setLocationAndRotation(new Location<>(entity.getWorld(), newLocation), entity.getRotation().add(0, rotation, 0)); - - if (Settings.Debug && !entityMoved) - Movecraft.getInstance().getLogger().info("Failed to move Entity of type: " + entity.getType().getName()); - } - - public void rotateCraft(Craft craft, Vector3i originPoint, Rotation rotation) { - //******************************************* - //* Step one: Convert to Positions * - //******************************************* - HashMap rotatedPositions = new HashMap<>(); - Rotation counterRotation = rotation == Rotation.CLOCKWISE ? Rotation.ANTICLOCKWISE : Rotation.CLOCKWISE; - for (Vector3i newLocation : craft.getHitBox()) { - rotatedPositions.put(MathUtils.rotateVec(counterRotation, newLocation.sub(originPoint)).add(originPoint), newLocation); - } - //******************************************* - //* Step two: Get the tiles * - //******************************************* - World nativeWorld = craft.getWorld(); - HashSet tiles = gatherTiles(nativeWorld, rotatedPositions.keySet()); - - //******************************************* - //* Step three: Translate all the blocks * - //******************************************* - // blockedByWater=false means an ocean-going vessel - //TODO: Simplify - //TODO: go by chunks - //TODO: Don't move unnecessary blocks - //get the blocks and rotate them - Map blockMap = new HashMap<>(); - for (Vector3i position : rotatedPositions.keySet()) { - blockMap.put(position, (BlockState) ((WorldServer) nativeWorld).getBlockState(locationToBlockPos(position)).withRotation(ROTATION[rotation.ordinal()])); - } - //create the new block - blockMap.forEach((position, blockState) -> setBlockFast(nativeWorld, rotatedPositions.get(position), blockState)); - //******************************************* - //* Step four: replace all the tiles * - //******************************************* - //TODO: go by chunks - for (TileHolder tileHolder : tiles) { - moveTileEntity(nativeWorld, rotatedPositions.get(tileHolder.getTilePosition()), tileHolder.getTile()); - if (tileHolder.getNextTick() == null) - continue; - final long currentTime = ((WorldServer) nativeWorld).getWorldTime(); - ((WorldServer) nativeWorld).scheduleBlockUpdate(locationToBlockPos(rotatedPositions.get(tileHolder.getTilePosition())), tileHolder.getTile().getBlockType(), (int) (tileHolder.getNextTick().scheduledTime - currentTime), tileHolder.getNextTick().priority); - } - - //******************************************* - //* Step five: Destroy the leftovers * - //******************************************* - //TODO: add support for pass-through - Collection deletePositions = CollectionUtils.filter(rotatedPositions.keySet(), rotatedPositions.values()); - for (Vector3i position : deletePositions) { - setBlockFast(nativeWorld, position, BlockTypes.AIR.getDefaultState()); - } - //******************************************* - //* Step six: Process fire spread * - //******************************************* - processFireSpread(nativeWorld, blockMap.keySet()); - } - - public void translateCraft(Craft craft, Vector3i translateVector) { - //TODO: Add support for rotations - //A craftTranslateCommand should only occur if the craft is moving to a valid position - //******************************************* - //* Step one: Convert to Positions * - //******************************************* - Set positions = new HashSet<>(craft.getHitBox().asSet()); - //******************************************* - //* Step two: Get the tiles * - //******************************************* - World nativeWorld = craft.getWorld(); - HashSet tiles = gatherTiles(nativeWorld, positions); - //******************************************* - //* Step three: Translate all the blocks * - //******************************************* - // blockedByWater=false means an ocean-going vessel - //TODO: Simplify - //TODO: go by chunks - //TODO: Don't move unnecessary blocks - //get the blocks and translate the positions - Map blockMap = new HashMap<>(); - positions.forEach(position -> blockMap.put(position.add(translateVector), nativeWorld.getBlock(position))); - - //create the new blocks - blockMap.forEach((newPosition, blockState) -> setBlockFast(nativeWorld, newPosition, blockState)); - //******************************************* - //* Step four: replace all the tiles * - //******************************************* - replaceTilesTranslate(nativeWorld, tiles, translateVector); - //******************************************* - //* Step five: Destroy the leftovers * - //******************************************* - Collection deletePositions = CollectionUtils.filter(positions, blockMap.keySet()); - deletePositions.forEach(position -> setBlockFast(nativeWorld, position, BlockTypes.AIR.getDefaultState())); - - //******************************************* - //* Step six: Process fire spread * - //******************************************* - processFireSpread(nativeWorld, blockMap.keySet()); - } - - private HashSet gatherTiles(World world, Set positions) { - HashSet tiles = new HashSet<>(); - - //get the tiles - positions.forEach(position -> { - if (world.getBlockType(position) == BlockTypes.AIR) - return; - - TileEntity tile = removeTileEntity(world, position); - if (tile == null) - return; - //get the nextTick to move with the tile - - //world.getChunkAtWorldCoords(position).getTileEntities().remove(position); - tiles.add(new TileHolder(tile, tickProvider.getNextTick((WorldServer) world, position), position)); - }); - - return tiles; - } - - //TODO Rewrite to handle translations AND rotations - private void replaceTilesTranslate(World nativeWorld, Set tiles, Vector3i translateVector) { - //TODO: go by chunks - tiles.forEach(tileHolder -> { - moveTileEntity(nativeWorld, tileHolder.getTilePosition().add(translateVector), tileHolder.getTile()); - if (tileHolder.getNextTick() == null) - return; - final long currentTime = ((WorldServer) nativeWorld).getWorldTime(); - ((WorldServer) nativeWorld).scheduleBlockUpdate(tileHolder.getNextTick().position.add(locationToBlockPos(translateVector)), tileHolder.getTile().getBlockType(), (int) (tileHolder.getNextTick().scheduledTime - currentTime), tileHolder.getNextTick().priority); - }); - } - - private void processFireSpread(World world, Set positions) { - positions.forEach(position -> { - IBlockState type = ((WorldServer) world).getBlockState(locationToBlockPos(position)); - - if (!(type.getBlock() instanceof BlockFire)) { - return; - } - BlockFire fire = (BlockFire) type.getBlock(); - fire.randomTick((WorldServer) world, locationToBlockPos(position), type, ((WorldServer) world).rand); - }); - } - - private TileEntity removeTileEntity(World world, Vector3i position) { - WorldServer worldServer = (WorldServer) world; - BlockPos blockPos = new BlockPos(position.getX(), position.getY(), position.getZ()); - - TileEntity tile = null; - - // Optimized version of WorldServer#getTileEntity() - if (worldServer.processingLoadedTiles) { - for (TileEntity tileEntity : worldServer.addedTileEntityList) { - if (!tileEntity.isInvalid() && tileEntity.getPos().equals(blockPos)) { - tile = tileEntity; - break; - } - } - } - - if (tile == null) { - tile = worldServer.getChunk(blockPos).getTileEntity(blockPos, Chunk.EnumCreateEntityType.IMMEDIATE); - } - - if (tile == null) { - for (TileEntity tileEntity : worldServer.addedTileEntityList) { - if (!tileEntity.isInvalid() && tileEntity.getPos().equals(blockPos)) { - tile = tileEntity; - break; - } - } - } - // END - - if (tile == null) { - return null; - } - - //cleanup - //Optimized version of WorldServer#removeTileEntity(); - tile.invalidate(); - worldServer.addedTileEntityList.remove(tile); - worldServer.loadedTileEntityList.remove(tile); - - if (!worldServer.processingLoadedTiles) { - worldServer.tickableTileEntities.remove(tile); - - worldServer.getChunk(blockPos).getTileEntityMap().remove(blockPos); - } - // END - - return tile; - } - - public static BlockPos locationToBlockPos(Vector3i loc) { - return new BlockPos(loc.getX(), loc.getY(), loc.getZ()); - } - - public void setBlockFast(World world, Vector3i position, BlockState blockState) { - WorldServer worldServer = (WorldServer) world; - BlockPos blockPos = locationToBlockPos(position); - IBlockState iBlockState = (IBlockState) blockState; - - Chunk chunk = worldServer.getChunk(blockPos); - ExtendedBlockStorage chunkSection = chunk.getBlockStorageArray()[position.getY() >> 4]; - if (chunkSection == null) { - // Put a GLASS block to initialize the section. It will be replaced next with the real block. - chunk.setBlockState(blockPos, Blocks.GLASS.getDefaultState()); - chunkSection = chunk.getBlockStorageArray()[position.getY() >> 4]; - } - - chunkSection.set(position.getX() & 15, position.getY() & 15, position.getZ() & 15, iBlockState); - worldServer.notifyBlockUpdate(blockPos, iBlockState, iBlockState, 3); - - // Set the chunk to save - // Should just need to mark dirty - // chunk.setLastSaveTime(worldServer.getTotalWorldTime() - 600L); - chunk.markDirty(); - } - - public void setBlockFast(Location location, Rotation rotation, BlockState blockState) { - //TODO Clean this up - blockState = (BlockState) ((IBlockState) blockState).withRotation(ROTATION[rotation.ordinal()]); - - setBlockFast(location.getExtent(), location.getBlockPosition(), blockState); - } - - /*public void disableShadow(BlockType type) { - Method method; - try { - Block tempBlock = CraftMagicNumbers.getBlock(type.getId()); - method = Block.class.getDeclaredMethod("e", int.class); - method.setAccessible(true); - method.invoke(tempBlock, 0); - } catch (NoSuchMethodException | InvocationTargetException | IllegalArgumentException | IllegalAccessException | SecurityException e) { - e.printStackTrace(); - } - }*/ - - private void moveTileEntity(World world, Vector3i newPosition, TileEntity tile) { - // Cast Sponge's World to Minecraft's WorldServer - WorldServer worldServer = (WorldServer) world; - // Convert Vector3i to Minecraft's BlockPos - BlockPos blockPos = locationToBlockPos(newPosition); - - // Get the chunk - Chunk chunk = worldServer.getChunk(blockPos); - - // Same as Spigot's invalidateBlockCache() - tile.blockMetadata = -1; - tile.blockType = null; - // END - - // Optimised version of Chunk#addTileEntity(BlockPos, TileEntity) - tile.setWorld(worldServer); - tile.setPos(blockPos); - tile.validate(); - - chunk.getTileEntityMap().put(blockPos, tile); - // END - } - - private class TileHolder { - private final TileEntity tile; - private final NextTickListEntry nextTick; - private final Vector3i tilePosition; - - public TileHolder(TileEntity tile, NextTickListEntry nextTick, Vector3i tilePosition) { - this.tile = tile; - this.nextTick = nextTick; - this.tilePosition = tilePosition; - } - - public TileEntity getTile() { - return tile; - } - - public NextTickListEntry getNextTick() { - return nextTick; - } - - public Vector3i getTilePosition() { - return tilePosition; - } - } -} diff --git a/src/main/java/io/github/pulverizer/movecraft/WorldHandler.java.disabled b/src/main/java/io/github/pulverizer/movecraft/WorldHandler.java.disabled deleted file mode 100644 index 7f04d2a7c..000000000 --- a/src/main/java/io/github/pulverizer/movecraft/WorldHandler.java.disabled +++ /dev/null @@ -1,331 +0,0 @@ -package io.github.pulverizer.movecraft; - -import com.flowpowered.math.vector.Vector3d; -import com.flowpowered.math.vector.Vector3i; -import io.github.pulverizer.movecraft.config.Settings; -import io.github.pulverizer.movecraft.craft.Craft; -import io.github.pulverizer.movecraft.enums.Rotation; -import io.github.pulverizer.movecraft.utils.HashHitBox; -import org.spongepowered.api.block.BlockSnapshot; -import org.spongepowered.api.block.BlockState; -import org.spongepowered.api.block.BlockTypes; -import org.spongepowered.api.block.tileentity.TileEntityArchetype; -import org.spongepowered.api.data.key.Keys; -import org.spongepowered.api.entity.Entity; -import org.spongepowered.api.util.Direction; -import io.github.pulverizer.movecraft.utils.MathUtils; -import org.spongepowered.api.world.BlockChangeFlags; -import org.spongepowered.api.world.Location; -import org.spongepowered.api.world.World; -import org.spongepowered.api.world.extent.ArchetypeVolume; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.Map; - -/** - * An interface for all interactions with the World. - */ - -public class OldWorldHandler { - - /** - * Constructs an Instance of the WorldHandler. - */ - public OldWorldHandler() {} - - /** - * Moves the Entity to the Location in the World that the Entity currently resides in and applies the Rotation to the Entity. - * @param entity Entity to be moved. - * @param newLocation Vector3d location to move the Entity to. - * @param rotation New Rotation of the Entity. - */ - public void moveEntity(Entity entity, Vector3d newLocation, float rotation){ - boolean entityMoved = entity.setLocationAndRotation(new Location<>(entity.getWorld(), newLocation), entity.getRotation().add(0, rotation, 0)); - - if (Settings.Debug && !entityMoved) - Movecraft.getInstance().getLogger().info("Failed to move Entity of type: " + entity.getType().getName()); - } - - /** - * Rotates the Craft around the Location using the Rotation. - * @param craft Craft to be rotated. - * @param originPoint Vector3i that the Craft will be rotated around. - * @param rotation Rotation tha the Craft will be rotated by. - */ - public void rotateCraft(Craft craft, Vector3i originPoint, Rotation rotation) { - - World nativeWorld = craft.getWorld(); - - //******************************************* - //* Step one: Convert to Positions * - //******************************************* - - HashSet oldLocations = new HashSet<>(); - HashMap blocks = new HashMap<>(); - Rotation counterRotation = rotation == Rotation.CLOCKWISE ? Rotation.ANTICLOCKWISE : Rotation.CLOCKWISE; - LinkedHashMap> updates = new LinkedHashMap<>(); - - //get blocks and updates from old locations - for(Vector3i newPosition : craft.getHitBox()) { - Vector3i oldPosition = MathUtils.rotateVec(counterRotation, newPosition.sub(originPoint)).add(originPoint); - oldLocations.add(oldPosition); - - blocks.put(newPosition, nativeWorld.createSnapshot(oldPosition)); - - HashMap blockUpdates = new HashMap<>(); - nativeWorld.getScheduledUpdates(oldPosition).forEach(update -> blockUpdates.put(update.getPriority(), update.getTicks())); - - updates.put(newPosition, blockUpdates); - - nativeWorld.getScheduledUpdates(oldPosition) - .forEach(sbu -> nativeWorld.removeScheduledUpdate(oldPosition, sbu)); - } - - //create the new blocks - for(Map.Entry entry : blocks.entrySet()) { - Vector3i location = entry.getKey(); - final BlockSnapshot blockSnapshot = entry.getValue(); - nativeWorld.restoreSnapshot(rotateBlock(rotation, blockSnapshot).withLocation(new Location(nativeWorld, location)), true, BlockChangeFlags.NONE); - updates.get(location).forEach((key, value) -> nativeWorld.addScheduledUpdate(location, key, value)); - // Prune the replaced location from old locations - oldLocations.remove(location); - } - - //remove the old blocks - oldLocations.forEach(location -> BlockSnapshot.NONE.withLocation(new Location<>(nativeWorld, location)).restore(true, BlockChangeFlags.NONE)); - } - - /** - * Moves the Craft using the Vector3i. - * @param craft Craft to be moved. - * @param min - * @param max - * @param translateBlockVector 3D direction that the Craft is to be moved in. - * @param newHitBox New HitBox of the Craft after moving. - */ - public void translateCraft(Craft craft, final Vector3i min, final Vector3i max, final Vector3i translateBlockVector, HashHitBox newHitBox) { - - World nativeWorld = craft.getWorld(); - - Location origin = new Location<>(nativeWorld, min); - - ArchetypeVolume volume = nativeWorld.createArchetypeVolume(min, max, origin.getBlockPosition()); - - // get the old blocks and tile entities - HashSet oldLocations = new HashSet<>(); - HashMap blocks = new HashMap<>(); - HashMap tileEntityMap = new HashMap<>(); - - for(Vector3i blockPosition : craft.getHitBox()) { - Vector3i adjustedBlockPosition = blockPosition.sub(min); - - volume.getTileEntityArchetype(adjustedBlockPosition).ifPresent(tileEntity -> { - tileEntityMap.put(adjustedBlockPosition, tileEntity); - - volume.getTileEntityArchetypes().remove(adjustedBlockPosition); - BlockSnapshot.NONE.withLocation(new Location<>(nativeWorld, blockPosition)).restore(true, BlockChangeFlags.NONE); - }); - - oldLocations.add(adjustedBlockPosition); - blocks.put(adjustedBlockPosition.add(translateBlockVector), volume.getBlock(adjustedBlockPosition)); - } - - // create the new blocks - for(Map.Entry entry : blocks.entrySet()) { - volume.setBlock(entry.getKey(), entry.getValue()); - oldLocations.remove(entry.getKey()); - } - - // remove the old blocks - oldLocations.forEach(location -> volume.setBlockType(location, BlockTypes.AIR)); - - tileEntityMap.forEach((location, tileEntity) -> { - volume.getTileEntityArchetypes().put(location.add(translateBlockVector), tileEntity); - }); - - // Apply the changes to the world - volume.getEntityArchetypes().clear(); - volume.apply(origin, BlockChangeFlags.NONE); - } - - /** - * Rotates a BlockSnapshot using the Rotation. - * @param rotation Rotation that the BlockSnapshot will be rotated with. - * @param block BlockSnapshot to be rotated. - * @return New rotated BlockSnapshot. - */ - public BlockSnapshot rotateBlock(Rotation rotation, BlockSnapshot block) { - - if (rotation == Rotation.NONE || !block.supports(Keys.DIRECTION) || !block.get(Keys.DIRECTION).isPresent()) - return block; - - Direction oldBlockDirection = block.get(Keys.DIRECTION).get(); - Direction newBlockDirection = Direction.NONE; - - if (oldBlockDirection == Direction.DOWN || oldBlockDirection == Direction.UP || oldBlockDirection == Direction.NONE) - return block; - - if (rotation == Rotation.CLOCKWISE) { - switch (oldBlockDirection) { - case NORTH: - newBlockDirection = Direction.EAST; - break; - - case NORTH_NORTHEAST: - newBlockDirection = Direction.EAST_SOUTHEAST; - break; - - case NORTHEAST: - newBlockDirection = Direction.SOUTHEAST; - break; - - case EAST_NORTHEAST: - newBlockDirection = Direction.SOUTH_SOUTHEAST; - break; - - case EAST: - newBlockDirection = Direction.SOUTH; - break; - - case EAST_SOUTHEAST: - newBlockDirection = Direction.SOUTH_SOUTHWEST; - break; - - case SOUTHEAST: - newBlockDirection = Direction.SOUTHWEST; - break; - - case SOUTH_SOUTHEAST: - newBlockDirection = Direction.WEST_SOUTHWEST; - break; - - case SOUTH: - newBlockDirection = Direction.WEST; - break; - - case SOUTH_SOUTHWEST: - newBlockDirection = Direction.WEST_NORTHWEST; - break; - - case SOUTHWEST: - newBlockDirection = Direction.NORTHWEST; - break; - - case WEST_SOUTHWEST: - newBlockDirection = Direction.NORTH_NORTHWEST; - break; - - case WEST: - newBlockDirection = Direction.NORTH; - break; - - case WEST_NORTHWEST: - newBlockDirection = Direction.NORTH_NORTHEAST; - break; - - case NORTHWEST: - newBlockDirection = Direction.NORTHEAST; - break; - - case NORTH_NORTHWEST: - newBlockDirection = Direction.EAST_NORTHEAST; - break; - - default: - newBlockDirection = oldBlockDirection; - } - - } else if (rotation == Rotation.ANTICLOCKWISE) { - switch (oldBlockDirection) { - - case NORTH: - newBlockDirection = Direction.WEST; - break; - - case NORTH_NORTHWEST: - newBlockDirection = Direction.WEST_SOUTHWEST; - break; - - case NORTHWEST: - newBlockDirection = Direction.SOUTHWEST; - break; - - case WEST_NORTHWEST: - newBlockDirection = Direction.SOUTH_SOUTHWEST; - break; - - case WEST: - newBlockDirection = Direction.SOUTH; - break; - - case WEST_SOUTHWEST: - newBlockDirection = Direction.SOUTH_SOUTHEAST; - break; - - case SOUTHWEST: - newBlockDirection = Direction.SOUTHEAST; - break; - - case SOUTH_SOUTHWEST: - newBlockDirection = Direction.EAST_SOUTHEAST; - break; - - case SOUTH: - newBlockDirection = Direction.EAST; - break; - - case SOUTH_SOUTHEAST: - newBlockDirection = Direction.EAST_NORTHEAST; - break; - - case SOUTHEAST: - newBlockDirection = Direction.NORTHEAST; - break; - - case EAST_SOUTHEAST: - newBlockDirection = Direction.NORTH_NORTHEAST; - break; - - case EAST: - newBlockDirection = Direction.NORTH; - break; - - case EAST_NORTHEAST: - newBlockDirection = Direction.NORTH_NORTHWEST; - break; - - case NORTHEAST: - newBlockDirection = Direction.NORTHWEST; - break; - - case NORTH_NORTHEAST: - newBlockDirection = Direction.WEST_NORTHWEST; - break; - - default: - newBlockDirection = oldBlockDirection; - } - } - - if (newBlockDirection == Direction.NONE) - return block; - - return block.with(Keys.DIRECTION, newBlockDirection).get(); - } - - /* Temp Disabled - public void disableShadow(BlockType blockType) { - Method method; - try { - Block tempBlock = CraftMagicNumbers.getBlock(blockType.getId()); - method = Block.class.getDeclaredMethod("e", int.class); - method.setAccessible(true); - method.invoke(tempBlock, 0); - } catch (NoSuchMethodException | InvocationTargetException | IllegalArgumentException | IllegalAccessException | SecurityException e) { - e.printStackTrace(); - } - } - */ -} \ No newline at end of file diff --git a/src/main/java/io/github/pulverizer/movecraft/CraftState.java b/src/main/java/io/github/pulverizer/movecraft/craft/CraftState.java similarity index 71% rename from src/main/java/io/github/pulverizer/movecraft/CraftState.java rename to src/main/java/io/github/pulverizer/movecraft/craft/CraftState.java index 2736923ff..9d68bc00a 100644 --- a/src/main/java/io/github/pulverizer/movecraft/CraftState.java +++ b/src/main/java/io/github/pulverizer/movecraft/craft/CraftState.java @@ -1,4 +1,4 @@ -package io.github.pulverizer.movecraft; +package io.github.pulverizer.movecraft.craft; /** * An Enum of possible states of a Craft. diff --git a/src/main/java/io/github/pulverizer/movecraft/mapUpdater/update/CraftRotateCommand.java b/src/main/java/io/github/pulverizer/movecraft/mapUpdater/update/CraftRotateCommand.java index 37405fb59..4a38100a7 100644 --- a/src/main/java/io/github/pulverizer/movecraft/mapUpdater/update/CraftRotateCommand.java +++ b/src/main/java/io/github/pulverizer/movecraft/mapUpdater/update/CraftRotateCommand.java @@ -9,6 +9,7 @@ import io.github.pulverizer.movecraft.enums.Rotation; import io.github.pulverizer.movecraft.event.SignTranslateEvent; import io.github.pulverizer.movecraft.utils.*; +import io.github.pulverizer.movecraft.world.ChunkDataManager; import org.slf4j.Logger; import org.spongepowered.api.Sponge; import org.spongepowered.api.block.BlockSnapshot; @@ -54,8 +55,6 @@ public void doUpdate() { passthroughBlocks.add(BlockTypes.DOUBLE_PLANT); } - final WorldHandler handler = Movecraft.getInstance().getWorldHandler(); - if (!passthroughBlocks.isEmpty()) { MutableHitBox originalLocations = new HashHitBox(); final Rotation counterRotation = rotation == Rotation.CLOCKWISE ? Rotation.ANTICLOCKWISE : Rotation.CLOCKWISE; @@ -129,8 +128,8 @@ public void doUpdate() { } //add the craft + rotateCraft(); - handler.rotateCraft(craft, originLocation, rotation); //trigger sign event for (Vector3i location : craft.getHitBox()) { BlockType blockType = craft.getWorld().getBlockType(location); @@ -164,7 +163,7 @@ public void doUpdate() { } }else{ //add the craft - handler.rotateCraft(craft, originLocation, rotation); + rotateCraft(); //trigger sign event for (Vector3i location : craft.getHitBox()) { BlockType blockType = craft.getWorld().getBlockType(location); @@ -182,6 +181,38 @@ public void doUpdate() { craft.setProcessing(false); } + private void rotateCraft() { + //TODO - hitbox should not be getting set before this method is called! + + // Get old positions + HashSet oldPositions = new HashSet<>(); + Rotation counterRotation = rotation == Rotation.CLOCKWISE ? Rotation.ANTICLOCKWISE : Rotation.CLOCKWISE; + for (Vector3i newLocation : craft.getHitBox()) { + oldPositions.add(MathUtils.rotateVec(counterRotation, newLocation.sub(originLocation)).add(originLocation)); + } + + // Set up the chunk data manager + ChunkDataManager chunkDataManager = new ChunkDataManager(craft.getWorld(), oldPositions); + + // Get the tiles + chunkDataManager.fetchTilesAndRotate(rotation, originLocation); + + // Get the blocks and rotate them + chunkDataManager.fetchBlocksAndRotate(rotation, originLocation); + + // Create the new blocks + chunkDataManager.setBlocks(); + + // Place the tile entities + chunkDataManager.placeTiles(); + + // Destroy the leftovers + chunkDataManager.destroyLeftovers(); + + //Process fire spread + chunkDataManager.processFireSpread(); + } + public Craft getCraft() { return craft; } diff --git a/src/main/java/io/github/pulverizer/movecraft/mapUpdater/update/CraftTranslateCommand.java b/src/main/java/io/github/pulverizer/movecraft/mapUpdater/update/CraftTranslateCommand.java index d55f58d0a..b562a0e4b 100644 --- a/src/main/java/io/github/pulverizer/movecraft/mapUpdater/update/CraftTranslateCommand.java +++ b/src/main/java/io/github/pulverizer/movecraft/mapUpdater/update/CraftTranslateCommand.java @@ -3,7 +3,8 @@ import com.flowpowered.math.vector.Vector3i; import io.github.pulverizer.movecraft.enums.CraftState; import io.github.pulverizer.movecraft.Movecraft; -import io.github.pulverizer.movecraft.WorldHandler; +import io.github.pulverizer.movecraft.world.ChunkDataManager; +import io.github.pulverizer.movecraft.utils.WorldUtils; import io.github.pulverizer.movecraft.config.Settings; import io.github.pulverizer.movecraft.craft.Craft; import io.github.pulverizer.movecraft.craft.CraftManager; @@ -44,6 +45,8 @@ public CraftTranslateCommand(Craft craft, Vector3i displacement, HashHitBox newH @Override public void doUpdate() { + //A craftTranslateCommand should only occur if the craft is moving to a valid position + long time = System.currentTimeMillis(); //long timeTaken = 0; @@ -65,16 +68,13 @@ public void doUpdate() { passthroughBlocks.add(BlockTypes.DOUBLE_PLANT); } - WorldHandler handler = Movecraft.getInstance().getWorldHandler(); - if(passthroughBlocks.isEmpty()){ //timeTaken = System.currentTimeMillis() - time; //logger.info("Marker 1A: " + timeTaken + " ms"); //add the craft - //OLD Movecraft.getInstance().getWorldHandler().translateCraft(craft, min, max, displacement); - handler.translateCraft(craft, displacement); + translateCraft(); // update the craft hitbox craft.setHitBox(newHitBox); @@ -183,8 +183,7 @@ public void doUpdate() { //logger.info("Marker 5B: " + timeTaken + " ms"); //add the craft - //OLD handler.translateCraft(craft, min, max, displacement, newHitBox); - handler.translateCraft(craft, displacement); + translateCraft(); // update the craft hitbox craft.setHitBox(newHitBox); @@ -217,6 +216,7 @@ public void doUpdate() { } } + //TODO - remove these debug messages //timeTaken = System.currentTimeMillis() - time; //logger.info("Marker 7B: " + timeTaken + " ms"); @@ -241,6 +241,28 @@ public void doUpdate() { craft.setProcessing(false); } + private void translateCraft() { + // Set up the chunk data manager + ChunkDataManager chunkDataManager = new ChunkDataManager(craft.getWorld(), new HashSet<>(craft.getHitBox().asSet())); + + // Get the tile entities + chunkDataManager.fetchTilesAndTranslate(displacement); + //get the blocks and translate the positions + chunkDataManager.fetchBlocksAndTranslate(displacement); + + // Create the new blocks + chunkDataManager.setBlocks(); + + // Place the tiles in the new positions + chunkDataManager.placeTiles(); + + // Destroy the leftovers + chunkDataManager.destroyLeftovers(); + + //Process fire spread + chunkDataManager.processFireSpread(); + } + public Craft getCraft(){ return craft; } diff --git a/src/main/java/io/github/pulverizer/movecraft/mapUpdater/update/EntityUpdateCommand.java b/src/main/java/io/github/pulverizer/movecraft/mapUpdater/update/EntityUpdateCommand.java index 8c706d32c..130db8348 100644 --- a/src/main/java/io/github/pulverizer/movecraft/mapUpdater/update/EntityUpdateCommand.java +++ b/src/main/java/io/github/pulverizer/movecraft/mapUpdater/update/EntityUpdateCommand.java @@ -2,6 +2,7 @@ import com.flowpowered.math.vector.Vector3d; import io.github.pulverizer.movecraft.Movecraft; +import io.github.pulverizer.movecraft.utils.WorldUtils; import org.spongepowered.api.entity.Entity; import java.util.Objects; @@ -26,7 +27,7 @@ public Entity getEntity() { @Override public void doUpdate() { - Movecraft.getInstance().getWorldHandler().moveEntity(entity, newLocation, yaw); + WorldUtils.moveEntity(entity, newLocation, yaw); } @Override diff --git a/src/main/java/io/github/pulverizer/movecraft/utils/WorldUtils.java b/src/main/java/io/github/pulverizer/movecraft/utils/WorldUtils.java new file mode 100644 index 000000000..fd19d44e8 --- /dev/null +++ b/src/main/java/io/github/pulverizer/movecraft/utils/WorldUtils.java @@ -0,0 +1,33 @@ +package io.github.pulverizer.movecraft.utils; + +import com.flowpowered.math.vector.Vector3d; +import com.flowpowered.math.vector.Vector3i; +import io.github.pulverizer.movecraft.Movecraft; +import io.github.pulverizer.movecraft.config.Settings; +import net.minecraft.util.math.BlockPos; +import org.spongepowered.api.entity.Entity; +import org.spongepowered.api.world.Location; + +public class WorldUtils { + + public WorldUtils() { + } + + /** + * Moves the Entity to the Location in the World that the Entity currently resides in and applies the Rotation to the Entity. + * + * @param entity Entity to be moved. + * @param newLocation Vector3d location to move the Entity to. + * @param rotation New Rotation of the Entity. + */ + public static void moveEntity(Entity entity, Vector3d newLocation, float rotation) { + boolean entityMoved = entity.setLocationAndRotation(new Location<>(entity.getWorld(), newLocation), entity.getRotation().add(0, rotation, 0)); + + if (Settings.Debug && !entityMoved) + Movecraft.getInstance().getLogger().info("Failed to move Entity of type: " + entity.getType().getName()); + } + + public static BlockPos locationToBlockPos(Vector3i loc) { + return new BlockPos(loc.getX(), loc.getY(), loc.getZ()); + } +} diff --git a/src/main/java/io/github/pulverizer/movecraft/world/ChunkDataManager.java b/src/main/java/io/github/pulverizer/movecraft/world/ChunkDataManager.java new file mode 100644 index 000000000..3f2edca14 --- /dev/null +++ b/src/main/java/io/github/pulverizer/movecraft/world/ChunkDataManager.java @@ -0,0 +1,272 @@ +package io.github.pulverizer.movecraft.world; + +import com.flowpowered.math.vector.Vector2i; +import com.flowpowered.math.vector.Vector3i; +import io.github.pulverizer.movecraft.enums.Rotation; +import io.github.pulverizer.movecraft.utils.MathUtils; +import io.github.pulverizer.movecraft.utils.WorldUtils; +import net.minecraft.block.BlockFire; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.WorldServer; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.storage.ExtendedBlockStorage; +import org.spongepowered.api.world.World; + +import java.util.HashMap; +import java.util.HashSet; + +public class ChunkDataManager { + private WorldServer worldServer; + private final HashMap chunkMap = new HashMap<>(); + + private static final NextTickProvider tickProvider = new NextTickProvider(); + private static final net.minecraft.util.Rotation[] ROTATION; + + static { + ROTATION = new net.minecraft.util.Rotation[3]; + ROTATION[Rotation.NONE.ordinal()] = net.minecraft.util.Rotation.NONE; + ROTATION[Rotation.CLOCKWISE.ordinal()] = net.minecraft.util.Rotation.CLOCKWISE_90; + ROTATION[Rotation.ANTICLOCKWISE.ordinal()] = net.minecraft.util.Rotation.COUNTERCLOCKWISE_90; + } + + // Set of old block positions + private final HashSet oldPositions; + + // Chunk Position and Section : Set of Block Positions + private final HashMap> blockPosMap = new HashMap<>(); + // Block Positions : BlockState + private final HashMap blockStateMap = new HashMap<>(); + + // Chunk Position and Section : Set of Tile Positions + private final HashMap> tilePosMap = new HashMap<>(); + // Block Positions : TileHolder + private final HashMap tiles = new HashMap<>(); + + + + public ChunkDataManager(World world, HashSet oldPositions) { + worldServer = (WorldServer) world; + + this.oldPositions = oldPositions; + } + + public void fetchBlocksAndTranslate(Vector3i translateVector) { + HashSet positions = new HashSet<>(oldPositions); + positions.forEach(position -> addBlock(position.add(translateVector), worldServer.getBlockState(WorldUtils.locationToBlockPos(position)))); + } + + public void fetchBlocksAndRotate(Rotation rotation, Vector3i originPoint) { + HashSet positions = new HashSet<>(oldPositions); + positions.forEach(position -> addBlock(MathUtils.rotateVec(rotation, position.sub(originPoint)).add(originPoint), worldServer.getBlockState(WorldUtils.locationToBlockPos(position)).withRotation(ROTATION[rotation.ordinal()]))); + } + + public void fetchTilesAndTranslate(Vector3i translateVector) { + oldPositions.forEach(position -> { + BlockPos blockPos = WorldUtils.locationToBlockPos(position); + + if (!worldServer.getBlockState(blockPos).getBlock().hasTileEntity()) + return; + + TileEntity tile = removeTileEntity(position); + + if (tile == null) + return; + + //get the nextTick to move with the tile + addTile(position.add(translateVector), new TileHolder(tile, tickProvider.getNextTick(worldServer, position), position)); + }); + } + + public void fetchTilesAndRotate(Rotation rotation, Vector3i originPoint) { + oldPositions.forEach(position -> { + BlockPos blockPos = WorldUtils.locationToBlockPos(position); + + if (!worldServer.getBlockState(blockPos).getBlock().hasTileEntity()) + return; + + TileEntity tile = removeTileEntity(position); + if (tile == null) + return; + + //get the nextTick to move with the tile + addTile(MathUtils.rotateVec(rotation, position.sub(originPoint)).add(originPoint), new TileHolder(tile, tickProvider.getNextTick((WorldServer) worldServer, position), position)); + }); + } + + public void addBlock(Vector3i blockPosition, IBlockState blockState) { + //TODO - Don't move unnecessary blocks + Vector3i chunkBlockPos = new Vector3i(blockPosition.getX() >> 4, blockPosition.getY() >> 4, blockPosition.getZ() >> 4); + + if (!blockPosMap.containsKey(chunkBlockPos)) { + HashSet blockPosSet = new HashSet<>(); + blockPosMap.put(chunkBlockPos, blockPosSet); + } + + blockPosMap.get(chunkBlockPos).add(blockPosition); + blockStateMap.put(blockPosition, blockState); + oldPositions.remove(blockPosition); + } + + public void addTile(Vector3i blockPosition, TileHolder tileHolder) { + Vector3i chunkBlockPos = new Vector3i(blockPosition.getX() >> 4, blockPosition.getY() >> 4, blockPosition.getZ() >> 4); + + if (!tilePosMap.containsKey(chunkBlockPos)) { + HashSet tilePosSet = new HashSet<>(); + tilePosMap.put(chunkBlockPos, tilePosSet); + } + + tilePosMap.get(chunkBlockPos).add(blockPosition); + tiles.put(blockPosition, tileHolder); + } + + private Chunk getOrFetchChunk(int x, int z) { + Vector2i chunkPosition = new Vector2i(x, z); + + if (!chunkMap.containsKey(chunkPosition)) { + chunkMap.put(chunkPosition, worldServer.getChunk(x, z)); + } + + return chunkMap.get(chunkPosition); + } + + public void setBlocks() { + blockPosMap.forEach((chunkSectionPos, blockPosSet) -> { + Chunk chunk = getOrFetchChunk(chunkSectionPos.getX(), chunkSectionPos.getZ()); + + ExtendedBlockStorage chunkSection = chunk.getBlockStorageArray()[chunkSectionPos.getY()]; + + for (Vector3i newPosition : blockPosSet) { + BlockPos blockPos = WorldUtils.locationToBlockPos(newPosition); + IBlockState iBlockState = blockStateMap.get(newPosition); + + if (chunkSection == null) { + // Put a GLASS block to initialize the section. It will be replaced next with the real block. + chunk.setBlockState(blockPos, Blocks.GLASS.getDefaultState()); + chunkSection = chunk.getBlockStorageArray()[chunkSectionPos.getY()]; + } + + + chunkSection.set(newPosition.getX() & 15, newPosition.getY() & 15, newPosition.getZ() & 15, iBlockState); + worldServer.notifyBlockUpdate(blockPos, iBlockState, iBlockState, 3); + } + + chunk.markDirty(); + }); + } + + public void placeTiles() { + tilePosMap.forEach((chunkSectionPos, tilePosSet) -> { + Chunk chunk = getOrFetchChunk(chunkSectionPos.getX(), chunkSectionPos.getZ()); + + tilePosSet.forEach(newPosition -> { + TileHolder tileHolder = tiles.get(newPosition); + TileEntity tile = tileHolder.getTile(); + + // Convert Vector3i to Minecraft's BlockPos + BlockPos blockPos = WorldUtils.locationToBlockPos(newPosition); + + // Same as Spigot's invalidateBlockCache() + tile.blockMetadata = -1; + tile.blockType = null; + // END + + // Optimised version of Chunk#addTileEntity(BlockPos, TileEntity) + tile.setWorld(worldServer); + tile.setPos(blockPos); + tile.validate(); + + chunk.getTileEntityMap().put(blockPos, tile); + // END + + if (tileHolder.getNextTick() != null) { + final long currentTime = worldServer.getWorldTime(); + worldServer.scheduleBlockUpdate(blockPos, tileHolder.getTile().getBlockType(), (int) (tileHolder.getNextTick().scheduledTime - currentTime), tileHolder.getNextTick().priority); + } + }); + + }); + } + + public void destroyLeftovers() { + IBlockState airBlock = Blocks.AIR.getDefaultState(); + + oldPositions.forEach(position -> { + BlockPos blockPos = WorldUtils.locationToBlockPos(position); + Chunk chunk = getOrFetchChunk(position.getX() >> 4, position.getZ() >> 4); + + ExtendedBlockStorage chunkSection = chunk.getBlockStorageArray()[position.getY() >> 4]; + if (chunkSection == null) { + // Put a GLASS block to initialize the section. It will be replaced next with the real block. + chunk.setBlockState(blockPos, Blocks.GLASS.getDefaultState()); + chunkSection = chunk.getBlockStorageArray()[position.getY() >> 4]; + } + + + chunkSection.set(position.getX() & 15, position.getY() & 15, position.getZ() & 15, airBlock); + worldServer.notifyBlockUpdate(blockPos, airBlock, airBlock, 3); + chunk.markDirty(); + }); + } + + public void processFireSpread() { + blockStateMap.forEach((blockPosition, blockState) -> { + + if (blockState instanceof BlockFire) { + ((BlockFire) blockState).randomTick(worldServer, WorldUtils.locationToBlockPos(blockPosition), blockState, worldServer.rand); + } + }); + } + + private TileEntity removeTileEntity(Vector3i position) { + BlockPos blockPos = WorldUtils.locationToBlockPos(position); + Chunk chunk = getOrFetchChunk(position.getX() >> 4, position.getZ() >> 4); + + TileEntity tile = null; + + // Optimized version of WorldServer#getTileEntity() + if (worldServer.processingLoadedTiles) { + for (TileEntity tileEntity : worldServer.addedTileEntityList) { + if (!tileEntity.isInvalid() && tileEntity.getPos().equals(blockPos)) { + tile = tileEntity; + break; + } + } + } + + if (tile == null) { + tile = chunk.getTileEntity(blockPos, Chunk.EnumCreateEntityType.IMMEDIATE); + } + + if (tile == null) { + for (TileEntity tileEntity : worldServer.addedTileEntityList) { + if (!tileEntity.isInvalid() && tileEntity.getPos().equals(blockPos)) { + tile = tileEntity; + break; + } + } + } + // END + + if (tile == null) { + return null; + } + + //cleanup + //Optimized version of WorldServer#removeTileEntity(); + tile.invalidate(); + worldServer.addedTileEntityList.remove(tile); + worldServer.loadedTileEntityList.remove(tile); + + if (!worldServer.processingLoadedTiles) { + worldServer.tickableTileEntities.remove(tile); + + chunk.getTileEntityMap().remove(blockPos); + } + // END + + return tile; + } +} diff --git a/src/main/java/io/github/pulverizer/movecraft/NextTickProvider.java b/src/main/java/io/github/pulverizer/movecraft/world/NextTickProvider.java similarity index 91% rename from src/main/java/io/github/pulverizer/movecraft/NextTickProvider.java rename to src/main/java/io/github/pulverizer/movecraft/world/NextTickProvider.java index 46711fcf9..2559b4a4d 100644 --- a/src/main/java/io/github/pulverizer/movecraft/NextTickProvider.java +++ b/src/main/java/io/github/pulverizer/movecraft/world/NextTickProvider.java @@ -1,6 +1,7 @@ -package io.github.pulverizer.movecraft; +package io.github.pulverizer.movecraft.world; import com.flowpowered.math.vector.Vector3i; +import io.github.pulverizer.movecraft.utils.WorldUtils; import net.minecraft.init.Blocks; import net.minecraft.util.math.BlockPos; import net.minecraft.world.NextTickListEntry; @@ -24,7 +25,7 @@ private void registerWorld(WorldServer world) { } public NextTickListEntry getNextTick(WorldServer world, Vector3i vecPosition){ - BlockPos position = WorldHandler.locationToBlockPos(vecPosition); + BlockPos position = WorldUtils.locationToBlockPos(vecPosition); if(!isRegistered(world)) registerWorld(world); diff --git a/src/main/java/io/github/pulverizer/movecraft/world/TileHolder.java b/src/main/java/io/github/pulverizer/movecraft/world/TileHolder.java new file mode 100644 index 000000000..dadc495d9 --- /dev/null +++ b/src/main/java/io/github/pulverizer/movecraft/world/TileHolder.java @@ -0,0 +1,29 @@ +package io.github.pulverizer.movecraft.world; + +import com.flowpowered.math.vector.Vector3i; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.NextTickListEntry; + +public class TileHolder { + private final TileEntity tile; + private final NextTickListEntry nextTick; + private final Vector3i tilePosition; + + public TileHolder(TileEntity tile, NextTickListEntry nextTick, Vector3i tilePosition) { + this.tile = tile; + this.nextTick = nextTick; + this.tilePosition = tilePosition; + } + + public TileEntity getTile() { + return tile; + } + + public NextTickListEntry getNextTick() { + return nextTick; + } + + public Vector3i getTilePosition() { + return tilePosition; + } +} \ No newline at end of file