DEADSOFTWARE

Some fluids fixes
authorfredboy <fredboy@protonmail.com>
Mon, 22 Apr 2024 15:35:26 +0000 (22:35 +0700)
committerfredboy <fredboy@protonmail.com>
Mon, 22 Apr 2024 15:35:26 +0000 (22:35 +0700)
android/assets/json/game_items.json
core/src/ru/deadsoftware/cavedroid/game/world/GameWorldFluidsLogicControllerTask.java

index 0e407860a4cee30667b02f1caadcccc9f8bb5545..4f08f56183628fc9674836bd784d56dfea209d46 100644 (file)
       "top": 4,
       "sprite_top": 4,
       "collision": false,
+      "transparent": true,
       "drop": "lava_12",
       "meta": "lava",
       "texture": "lava_flow",
       "top": 8,
       "sprite_top": 8,
       "collision": false,
+      "transparent": true,
       "drop": "lava_8",
       "meta": "lava",
       "texture": "lava_flow",
       "top": 12,
       "sprite_top": 12,
       "collision": false,
+      "transparent": true,
       "drop": "lava_4",
       "meta": "lava",
       "texture": "lava_flow",
index 99d1a046b51605b9e8570e408e69b4eb5105cbe8..416721f7c25b6c946b6e9768ef41afad42c12da7 100644 (file)
@@ -13,7 +13,9 @@ import java.util.*;
 @GameScope
 public class GameWorldFluidsLogicControllerTask extends Timer.Task {
 
-    public static final float FLUID_UPDATE_INTERVAL_SEC = 0.1f;
+    public static final float FLUID_UPDATE_INTERVAL_SEC = 0.25f;
+
+    private short mUpdateTick = 0;
 
     private final GameWorld mGameWorld;
     private final MobsController mMobsController;
@@ -21,6 +23,35 @@ public class GameWorldFluidsLogicControllerTask extends Timer.Task {
 
     private final Map<Class<? extends Block.Fluid>, List<? extends Block.Fluid>> mFluidStatesMap;
 
+    private final class UpdateCommand {
+        final Runnable command;
+        final int priority;
+
+        private UpdateCommand(int priority, Runnable command) {
+            this.priority = priority;
+            this.command = command;
+        }
+
+        private UpdateCommand(Block block, int x, int y, int priority) {
+            this(priority, () -> mGameWorld.setForeMap(x, y, block));
+        }
+
+        private UpdateCommand(Block.Fluid fluid, int x, int y) {
+            this(fluid, x, y, ((5 -fluid.getState() )+ 1) * (fluid.isLava() ? 2 : 1));
+        }
+
+        private int getPriority() {
+            return priority;
+        }
+
+        private void exec() {
+           command.run();
+        }
+    }
+
+    private final PriorityQueue<UpdateCommand> mUpdateQueue
+            = new PriorityQueue<>(Comparator.comparingInt(UpdateCommand::getPriority));
+
     @Inject
     GameWorldFluidsLogicControllerTask(GameWorld gameWorld,
                                        MobsController mobsController,
@@ -97,13 +128,13 @@ public class GameWorldFluidsLogicControllerTask extends Timer.Task {
 
         if (fluid.getState() > 0) {
             if (noFluidNearby(x, y)) {
-                @CheckForNull final Block nextState = getNextStateBlock(fluid);
+                @CheckForNull final Block.Fluid nextState = getNextStateBlock(fluid);
                 if (nextState == null) {
-                    mGameWorld.resetForeMap(x, y);
+                    mUpdateQueue.offer(new UpdateCommand(-1, () -> mGameWorld.resetForeMap(x, y)));
                     return true;
                 }
 
-                mGameWorld.setForeMap(x, y, nextState);
+                mUpdateQueue.offer(new UpdateCommand(nextState, x, y));
             }
         }
         return false;
@@ -119,15 +150,15 @@ public class GameWorldFluidsLogicControllerTask extends Timer.Task {
         final Block targetBlock = mGameWorld.getForeMap(x, y);
 
         if (fluidCanFlowThere(currentFluid, targetBlock)) {
-            mGameWorld.setForeMap(x, y, nextStateFluid);
+            mUpdateQueue.offer(new UpdateCommand(nextStateFluid, x, y));
         } else if (currentFluid.isWater() && targetBlock.isLava()) {
             if (((Block.Lava)targetBlock).getState() > 0) {
-                mGameWorld.setForeMap(x, y, mGameItemsHolder.getBlock("cobblestone"));
+                mUpdateQueue.offer(new UpdateCommand(100, () -> mGameWorld.setForeMap(x, y, mGameItemsHolder.getBlock("cobblestone"))));
             } else {
-                mGameWorld.setForeMap(x, y, mGameItemsHolder.getBlock("obsidian"));
+                mUpdateQueue.offer(new UpdateCommand(300, () -> mGameWorld.setForeMap(x, y, mGameItemsHolder.getBlock("obsidian"))));
             }
         } else if (currentFluid.isLava() && targetBlock.isWater()) {
-            mGameWorld.setForeMap(x, y, mGameItemsHolder.getBlock("stone"));
+            mUpdateQueue.offer(new UpdateCommand(200, () -> mGameWorld.setForeMap(x, y, mGameItemsHolder.getBlock("stone"))));
         }
     }
 
@@ -155,7 +186,8 @@ public class GameWorldFluidsLogicControllerTask extends Timer.Task {
     }
 
     private void updateFluids(int x, int y) {
-        if (!mGameWorld.getForeMap(x, y).isFluid()) {
+        final Block block = mGameWorld.getForeMap(x, y);
+        if (!block.isFluid() || (block.isLava() && mUpdateTick % 2 == 0)) {
             return;
         }
         if (drainFluid(x, y)) {
@@ -172,10 +204,20 @@ public class GameWorldFluidsLogicControllerTask extends Timer.Task {
                 updateFluids(midScreen - x, y);
             }
         }
+
+        while (!mUpdateQueue.isEmpty()) {
+            final UpdateCommand command = mUpdateQueue.poll();
+            command.exec();
+        }
     }
 
     @Override
     public void run() {
+        if (mUpdateTick < 0xFF) {
+            mUpdateTick ++;
+        } else {
+            mUpdateTick = 0;
+        }
         fluidUpdater();
     }
 }