From 507e1ada0eb7ebf9d57cdac298d72f28917027c3 Mon Sep 17 00:00:00 2001 From: josua Date: Mon, 27 Jul 2020 11:13:24 +1000 Subject: [PATCH] Added a save menu, fixed issues with loading from saves, updated to BDF 3, started working on a crafting system. --- .classpath | 2 +- .gitignore | 3 +- src/projectzombie/Main.java | 116 ++--- src/projectzombie/display/Camera.java | 2 - .../display/DisplayLighting.java | 35 +- src/projectzombie/display/DisplayRender.java | 4 - .../display/DisplayRenderUI.java | 1 - src/projectzombie/entity/Entity.java | 31 +- src/projectzombie/entity/EntityBoss.java | 10 +- src/projectzombie/entity/EntityBullet.java | 8 +- src/projectzombie/entity/EntityContainer.java | 8 +- src/projectzombie/entity/EntityDummy.java | 2 + src/projectzombie/entity/EntityExplosion.java | 6 +- .../entity/EntityGrapplingHook.java | 6 +- src/projectzombie/entity/EntityHasArmor.java | 1 - .../entity/EntityHasClothing.java | 2 - .../entity/EntityHasInventory.java | 1 - src/projectzombie/entity/EntityItem.java | 7 +- src/projectzombie/entity/EntityTnt.java | 9 +- src/projectzombie/entity/EntityZombie.java | 12 +- .../entity/particle/ParticleSmokeTrail.java | 3 - .../entity/particle/ParticleWater.java | 1 - .../entity/player/EntityPlayer.java | 29 +- src/projectzombie/init/Layers.java | 28 -- src/projectzombie/init/Models.java | 7 +- .../input/CursorPosCallback.java | 6 +- src/projectzombie/input/JoystickCallback.java | 11 +- src/projectzombie/input/KeyCallback.java | 88 ++-- src/projectzombie/input/KeyCharCallback.java | 5 +- .../input/MouseButtonCallback.java | 2 - src/projectzombie/input/types/Input.java | 4 +- src/projectzombie/input/types/InputGUI.java | 28 +- .../input/types/InputGUITextBox.java | 12 + src/projectzombie/input/types/InputGame.java | 19 +- src/projectzombie/inventory/Crafting.java | 5 + src/projectzombie/inventory/Inventory.java | 4 +- .../inventory/InventoryArmor.java | 2 +- .../inventory/InventoryClothing.java | 2 +- .../inventory/recipe/Recipe.java | 13 + .../inventory/recipe/RecipeBasic.java | 57 +++ src/projectzombie/items/Item.java | 1 - src/projectzombie/items/ItemAmmo.java | 4 - src/projectzombie/items/ItemEmpty.java | 1 - src/projectzombie/items/ItemFlint.java | 1 - src/projectzombie/items/ItemRock.java | 3 - src/projectzombie/menu/MenuDeath.java | 4 +- src/projectzombie/menu/MenuGamePause.java | 53 +-- src/projectzombie/menu/MenuInventory.java | 38 +- .../menu/MenuInventoryBasic.java | 36 ++ src/projectzombie/menu/MenuMain.java | 10 +- src/projectzombie/menu/MenuSaves.java | 141 +++++- src/projectzombie/menu/MenuSettings.java | 7 +- src/projectzombie/menu/MenuWorldDelete.java | 116 +++++ src/projectzombie/menu/MenuWorldNew.java | 176 ++++++++ src/projectzombie/menu/gui/GUI.java | 121 ++++- src/projectzombie/menu/gui/GUIButton.java | 2 - .../menu/gui/GUIButtonGroup.java | 5 + .../menu/gui/GUIButtonGroupPause.java | 1 - src/projectzombie/menu/gui/GUIContainer.java | 1 + .../menu/gui/GUIContainerSlider.java | 38 +- src/projectzombie/menu/gui/GUIItemHolder.java | 2 - src/projectzombie/menu/gui/GUIItemSlot.java | 2 - src/projectzombie/menu/gui/GUISavesCard.java | 27 +- src/projectzombie/menu/gui/GUITextBox.java | 243 ++++++++++ src/projectzombie/model/Model.java | 3 +- src/projectzombie/model/ModelGrass.java | 1 - src/projectzombie/model/ModelRock.java | 1 - src/projectzombie/model/ModelTallGrass.java | 1 - src/projectzombie/settings/Settings.java | 21 +- src/projectzombie/task/Task.java | 15 +- src/projectzombie/task/TaskDeathScreen.java | 2 +- src/projectzombie/task/TaskLadderDown.java | 4 +- src/projectzombie/task/TaskLadderUp.java | 7 +- src/projectzombie/text/Text.java | 26 ++ src/projectzombie/tiles/TileGrass.java | 1 - src/projectzombie/tiles/TileLadderUp.java | 3 - src/projectzombie/tiles/TilePortalDown.java | 3 - src/projectzombie/tiles/TileRock.java | 5 - src/projectzombie/tiles/TileTree.java | 3 - src/projectzombie/tiles/TileWater.java | 1 - src/projectzombie/util/math/ItemStack.java | 6 +- src/projectzombie/worker/Worker.java | 42 +- src/projectzombie/world/World.java | 91 +++- src/projectzombie/world/chunk/Chunk.java | 69 +-- src/projectzombie/world/chunk/ChunkEmpty.java | 19 - src/projectzombie/world/layer/Layer.java | 37 +- .../layer/layergen/LayerGenBossArena.java | 2 - .../world/layer/layergen/LayerGenCaves.java | 1 - .../world/layer/layergen/LayerGenEarth.java | 1 - .../layer/layergen/LayerGenLavaCaves.java | 1 - src/resources/shader/environmentRenderer.fsh | 6 +- src/resources/texture/gui/selection_box.png | Bin 1205 -> 0 bytes .../texture/gui/selection_box_big.png | Bin 0 -> 2429 bytes .../texture/gui/selection_box_wide.png | Bin 0 -> 1999 bytes src/resources/texture/gui/text_box.png | Bin 0 -> 4650 bytes src/resources/texture/gui/text_cursor.png | Bin 0 -> 576 bytes src/resources/texture/list.txt | 426 +++++++++--------- src/resources/texture/text/char_and.png | Bin 0 -> 2107 bytes .../texture/text/char_apostrophe.png | Bin 0 -> 3037 bytes src/resources/texture/text/char_at.png | Bin 0 -> 2170 bytes src/resources/texture/text/char_ccbracket.png | Bin 0 -> 3050 bytes src/resources/texture/text/char_csbracket.png | Bin 0 -> 3011 bytes src/resources/texture/text/char_grave.png | Bin 0 -> 2438 bytes src/resources/texture/text/char_ocbracket.png | Bin 0 -> 3040 bytes src/resources/texture/text/char_osbracket.png | Bin 0 -> 3020 bytes src/resources/texture/text/char_pow.png | Bin 0 -> 2074 bytes src/resources/texture/text/char_quotation.png | Bin 0 -> 3042 bytes src/resources/texture/text/char_semicolon.png | Bin 0 -> 3038 bytes src/resources/texture/text/char_star.png | Bin 0 -> 2145 bytes src/resources/texture/text/char_tilde.png | Bin 0 -> 2394 bytes worker.jar | Bin 66838 -> 70241 bytes 111 files changed, 1648 insertions(+), 775 deletions(-) create mode 100644 src/projectzombie/input/types/InputGUITextBox.java create mode 100644 src/projectzombie/inventory/Crafting.java create mode 100644 src/projectzombie/inventory/recipe/Recipe.java create mode 100644 src/projectzombie/inventory/recipe/RecipeBasic.java create mode 100644 src/projectzombie/menu/MenuInventoryBasic.java create mode 100644 src/projectzombie/menu/MenuWorldDelete.java create mode 100644 src/projectzombie/menu/MenuWorldNew.java create mode 100644 src/projectzombie/menu/gui/GUITextBox.java delete mode 100644 src/resources/texture/gui/selection_box.png create mode 100644 src/resources/texture/gui/selection_box_big.png create mode 100644 src/resources/texture/gui/selection_box_wide.png create mode 100644 src/resources/texture/gui/text_box.png create mode 100644 src/resources/texture/gui/text_cursor.png create mode 100644 src/resources/texture/text/char_and.png create mode 100644 src/resources/texture/text/char_apostrophe.png create mode 100644 src/resources/texture/text/char_at.png create mode 100644 src/resources/texture/text/char_ccbracket.png create mode 100644 src/resources/texture/text/char_csbracket.png create mode 100644 src/resources/texture/text/char_grave.png create mode 100644 src/resources/texture/text/char_ocbracket.png create mode 100644 src/resources/texture/text/char_osbracket.png create mode 100644 src/resources/texture/text/char_pow.png create mode 100644 src/resources/texture/text/char_quotation.png create mode 100644 src/resources/texture/text/char_semicolon.png create mode 100644 src/resources/texture/text/char_star.png create mode 100644 src/resources/texture/text/char_tilde.png diff --git a/.classpath b/.classpath index 3f029df..a21c1f8 100755 --- a/.classpath +++ b/.classpath @@ -41,6 +41,6 @@ - + diff --git a/.gitignore b/.gitignore index fb5a5ff..adb385c 100755 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ /bin/ hs_err_pid* -settings.bdf -layer.bdf +*.bdf diff --git a/src/projectzombie/Main.java b/src/projectzombie/Main.java index 3405ca7..f0e2155 100755 --- a/src/projectzombie/Main.java +++ b/src/projectzombie/Main.java @@ -1,5 +1,7 @@ package projectzombie; +import java.awt.Toolkit; +import java.awt.datatransfer.Clipboard; import java.io.IOException; import java.util.Random; @@ -9,14 +11,11 @@ import projectzombie.audio.AudioEngine; import projectzombie.audio.AudioSources; import projectzombie.display.DisplayStatsEventHandler; import projectzombie.display.DisplayWindow; -import projectzombie.display.bossbar.BossBars; import projectzombie.entity.EntityEventHandler; import projectzombie.entity.player.EntityPlayer; import projectzombie.init.Entities; import projectzombie.init.Items; import projectzombie.init.LayerGenerators; -import projectzombie.init.Layers; -import projectzombie.init.Models; import projectzombie.init.Resources; import projectzombie.init.Sounds; import projectzombie.init.Tasks; @@ -38,6 +37,7 @@ import projectzombie.world.chunk.ChunkEventHandler; public class Main { + public static Clipboard clipboard; public static MainloopManager mainloop; public static DisplayWindow window; public static EntityPlayer player; @@ -51,56 +51,68 @@ public class Main public static void main(String[] args) throws IOException { - MathHelpers.init(); - Settings.init(); - Environment.init(args); - Cheats.init(args); + try + { + clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + + worker = new Worker(); + worker.start(); + + MathHelpers.init(); + Settings.init(); + Environment.init(args); + Cheats.init(args); + + Items.init(); + Entities.init(); + Tasks.init(); + Tiles.init(); + LayerGenerators.init(); + + // Create the display + window = new DisplayWindow(); + window.init(); + + // Load the resources + Resources.loadResources(); + + // Initialize the sound engine + audio = new AudioEngine(); + audio.init(); + + // Initialise the sounds + AudioSources.init(); + Sounds.init(); + + // Initialize the gamepad + JoystickCallback.JOYSTICK_CALLBACK.init(); + + // Create the mainloop + mainloop = new MainloopManager(MainloopEventHandler.MAINLOOP_EVENT_HANDLER); + mainloop.register(DisplayStatsEventHandler.DISPLAY_STATS_EVENT_HANDLER); + mainloop.register(MainloopEventHandler.MAINLOOP_EVENT_HANDLER); + mainloop.register(EntityEventHandler.ENTITY_EVENT_HANDLER); + mainloop.register(ChunkEventHandler.CHUNK_EVENT_HANDLER); + mainloop.register(JoystickCallback.JOYSTICK_CALLBACK); + mainloop.register(new MainloopHelpers()); + mainloop.register(new KeyCallback()); + mainloop.register(new GameTimer()); + mainloop.register(new NoSleep()); + mainloop.register(window); + + // Start the mainloop + menu = new MenuMain(); + mainloop.start(); + } - worker = new Worker(); - worker.start(); + catch(IOException e) { + e.printStackTrace(); + } - Items.init(); - Entities.init(); - Tasks.init(); - Tiles.init(); - LayerGenerators.init(); - - // Create the display - window = new DisplayWindow(); - window.init(); - - // Load the resources - Resources.loadResources(); - - // Initialize the sound engine - audio = new AudioEngine(); - audio.init(); - - // Initialise the sounds - AudioSources.init(); - Sounds.init(); - - // Initialize the gamepad - JoystickCallback.JOYSTICK_CALLBACK.init(); - - // Create the mainloop - mainloop = new MainloopManager(MainloopEventHandler.MAINLOOP_EVENT_HANDLER); - mainloop.register(DisplayStatsEventHandler.DISPLAY_STATS_EVENT_HANDLER); - mainloop.register(MainloopEventHandler.MAINLOOP_EVENT_HANDLER); - mainloop.register(EntityEventHandler.ENTITY_EVENT_HANDLER); - mainloop.register(ChunkEventHandler.CHUNK_EVENT_HANDLER); - mainloop.register(JoystickCallback.JOYSTICK_CALLBACK); - mainloop.register(new MainloopHelpers()); - mainloop.register(new KeyCallback()); - mainloop.register(new GameTimer()); - mainloop.register(new NoSleep()); - mainloop.register(window); - - // Start the mainloop - menu = new MenuMain(); - mainloop.start(); - - // Kill the worker thread - worker.kill(); + finally + { + // Kill the worker thread + worker.kill(); + } } } diff --git a/src/projectzombie/display/Camera.java b/src/projectzombie/display/Camera.java index d1b8a76..e148e7a 100755 --- a/src/projectzombie/display/Camera.java +++ b/src/projectzombie/display/Camera.java @@ -3,9 +3,7 @@ package projectzombie.display; import gl_engine.matrix.Matrix4; import gl_engine.vec.Vec3d; import projectzombie.Main; -import projectzombie.time.GameTimer; import projectzombie.world.chunk.Chunk; -import projectzombie.world.layer.Layer; public class Camera { diff --git a/src/projectzombie/display/DisplayLighting.java b/src/projectzombie/display/DisplayLighting.java index e2234fd..d890b4d 100755 --- a/src/projectzombie/display/DisplayLighting.java +++ b/src/projectzombie/display/DisplayLighting.java @@ -26,7 +26,7 @@ public class DisplayLighting int x, y; private int getID(int x, int y) { - return (x + y * w) * 4 + 1; + return (x + y * w) * 3; } } @@ -87,7 +87,7 @@ public class DisplayLighting lighting_dirty = false; int size = (Chunk.RENDER_DISTANCE * 2 + 1) * 16; - float[] lights = new float[size * size * 3]; + float[] lights = new float[size * size * 2]; for(int cx=-Chunk.RENDER_DISTANCE;cx<=Chunk.RENDER_DISTANCE;cx++) { for(int cy=-Chunk.RENDER_DISTANCE;cy<=Chunk.RENDER_DISTANCE;cy++) @@ -115,14 +115,11 @@ public class DisplayLighting ft.tile.getLightLevel(ft, tpos), bt.tile.getLightLevel(bt, tpos)); - float lightSun = ft.tile.passNaturalLight && bt.tile.passNaturalLight ? 1 : 0; - int id = ((cx * 16 + x + Chunk.RENDER_DISTANCE * 16) + - (cy * 16 + y + Chunk.RENDER_DISTANCE * 16) * size) * 3; + (cy * 16 + y + Chunk.RENDER_DISTANCE * 16) * size) * 2; - lights[id+0] = lightSun; - lights[id+1] = lightSrc; - lights[id+2] = transparency; + lights[id+0] = lightSrc; + lights[id+1] = transparency; } } } @@ -259,7 +256,7 @@ public class DisplayLighting if(lighting_new) { - for(int i=0;i 0) { pos.y = new_pos.y; - } else { + } else if(pos.y >= 0) { velocity.y *= -0.25; velocity.x *= slipperiness; velocity.z *= slipperiness; diff --git a/src/projectzombie/entity/EntityBoss.java b/src/projectzombie/entity/EntityBoss.java index 19e675d..ca42ca7 100755 --- a/src/projectzombie/entity/EntityBoss.java +++ b/src/projectzombie/entity/EntityBoss.java @@ -42,6 +42,8 @@ public class EntityBoss extends Entity implements IBossBar, EntityKillWithPartic public EntityBoss(BdfObject bdf) { super(bdf); + + BdfClassLoad(bdf); } @Override @@ -72,10 +74,10 @@ public class EntityBoss extends Entity implements IBossBar, EntityKillWithPartic super.BdfClassSave(bdf); BdfNamedList nl = bdf.getNamedList(); - nl.set("health", BdfObject.withDouble(health)); - nl.set("bullet_freq", BdfObject.withInteger(bullet_frequency)); - nl.set("spawn_freq", BdfObject.withInteger(spawn_frequency)); - nl.set("seed", BdfObject.withLong(seed)); + nl.set("health", bdf.newObject().setDouble(health)); + nl.set("bullet_freq", bdf.newObject().setInteger(bullet_frequency)); + nl.set("spawn_freq", bdf.newObject().setInteger(spawn_frequency)); + nl.set("seed", bdf.newObject().setLong(seed)); } public EntityBoss(Vec3d pos, Vec3d velocity) { diff --git a/src/projectzombie/entity/EntityBullet.java b/src/projectzombie/entity/EntityBullet.java index 503f02f..bad3bc1 100755 --- a/src/projectzombie/entity/EntityBullet.java +++ b/src/projectzombie/entity/EntityBullet.java @@ -7,10 +7,8 @@ import gl_engine.vec.Vec2d; import gl_engine.vec.Vec2i; import gl_engine.vec.Vec3d; import projectzombie.entity.particle.ParticleBlood; -import projectzombie.init.Models; import projectzombie.init.Resources; import projectzombie.init.Sounds; -import projectzombie.model.Model; import projectzombie.tiles.Tile; import projectzombie.tiles.TileBulletBreakable; import projectzombie.util.math.random.RandomHelpers; @@ -28,6 +26,8 @@ public class EntityBullet extends EntityParticle public EntityBullet(BdfObject bdf) { super(bdf); + + BdfClassLoad(bdf); } @Override @@ -44,8 +44,8 @@ public class EntityBullet extends EntityParticle super.BdfClassSave(bdf); BdfNamedList nl = bdf.getNamedList(); - nl.set("time", BdfObject.withInteger(time)); - nl.set("damage", BdfObject.withDouble(damage)); + nl.set("time", bdf.newObject().setInteger(time)); + nl.set("damage", bdf.newObject().setDouble(damage)); } public EntityBullet(Vec3d pos, Vec3d velocity, Entity parent, double damage, int despawn_time) { diff --git a/src/projectzombie/entity/EntityContainer.java b/src/projectzombie/entity/EntityContainer.java index 2cfc31d..28f6e81 100644 --- a/src/projectzombie/entity/EntityContainer.java +++ b/src/projectzombie/entity/EntityContainer.java @@ -15,6 +15,8 @@ public class EntityContainer extends Entity implements EntityHoldsEntities public EntityContainer(BdfObject bdf) { super(bdf); + + BdfClassLoad(bdf); } public EntityContainer(Vec3d pos, Vec3d velocity, Entity[] entities) { @@ -77,9 +79,9 @@ public class EntityContainer extends Entity implements EntityHoldsEntities super.BdfClassSave(bdf); BdfNamedList nl = bdf.getNamedList(); - BdfArray array = new BdfArray(); + BdfArray array = bdf.newArray(); - nl.set("entities", BdfObject.withArray(array)); + nl.set("entities", bdf.newObject().setArray(array)); for(int i=0;i(); + BdfClassLoad(bdf); } @Override @@ -88,6 +83,9 @@ public class EntityPlayer extends Entity implements angle = nl.get("angle").getDouble(); temperature = nl.get("temperature").getDouble(); hydration = nl.get("hydration").getDouble(); + in_animation = nl.get("inAnimation").getBoolean(); + moving = nl.get("moving").getBoolean(); + inventory_hand = nl.get("hand").getInteger(); tasks = new ArrayList(); @@ -106,15 +104,18 @@ public class EntityPlayer extends Entity implements public void BdfClassSave(BdfObject bdf) { super.BdfClassSave(bdf); BdfNamedList nl = bdf.getNamedList(); - nl.set("health", BdfObject.withDouble(health)); - nl.set("dead", BdfObject.withBoolean(dead)); + nl.set("health", bdf.newObject().setDouble(health)); + nl.set("dead", bdf.newObject().setBoolean(dead)); inventory.BdfClassSave(nl.get("inventory")); armor.BdfClassSave(nl.get("armor")); clothing.BdfClassSave(nl.get("clothing")); - nl.set("angle", BdfObject.withDouble(angle)); - nl.set("temperature", BdfObject.withDouble(temperature)); - nl.set("hydration", BdfObject.withDouble(hydration)); - nl.set("tasks", Task.saveTasks(tasks.toArray(new Task[0]))); + nl.set("angle", bdf.newObject().setDouble(angle)); + nl.set("temperature", bdf.newObject().setDouble(temperature)); + nl.set("hydration", bdf.newObject().setDouble(hydration)); + nl.set("tasks", Task.saveTasks(bdf.newObject(), tasks.toArray(new Task[0]))); + nl.set("inAnimation", bdf.newObject().setBoolean(in_animation)); + nl.set("moving", bdf.newObject().setBoolean(moving)); + nl.set("hand", bdf.newObject().setInteger(inventory_hand)); } public EntityPlayer() { @@ -133,8 +134,6 @@ public class EntityPlayer extends Entity implements inventory = new Inventory(42); armor = new InventoryArmor(); clothing = new InventoryClothing(); - - clothing.setShirt(new ItemStack(Items.SPAWN_ZOMBIE, 99, (short)0)); } @Override diff --git a/src/projectzombie/init/Layers.java b/src/projectzombie/init/Layers.java index fc42150..b1012f3 100755 --- a/src/projectzombie/init/Layers.java +++ b/src/projectzombie/init/Layers.java @@ -1,37 +1,9 @@ package projectzombie.init; -import java.util.Random; - -import projectzombie.Main; -import projectzombie.display.bossbar.BossBars; -import projectzombie.entity.player.EntityPlayer; -import projectzombie.time.GameTimer; -import projectzombie.world.World; import projectzombie.world.layer.Layer; -import projectzombie.world.layer.layergen.LayerGenBossArena; public class Layers { - public static void createWorld(String path, long seed) - { - // Create all the layers - EARTH = new Layer(new Random(seed), LayerGenerators.EARTH); - CAVES = new Layer(new Random(seed), LayerGenerators.CAVES); - LAVA_CAVES = new Layer(new Random(seed), LayerGenerators.LAVA_CAVES); - - // Create the world and set the earth as the default layer - Main.world = new World(path); - Main.world.addLayer(EARTH); - Main.world.addLayer(CAVES); - Main.world.addLayer(LAVA_CAVES); - Main.world.setLayer(0); - - // Initialize some other objects - Main.player = new EntityPlayer(); - GameTimer.resetTime(); - BossBars.clear(); - } - public static Layer EARTH; public static Layer CAVES; public static Layer LAVA_CAVES; diff --git a/src/projectzombie/init/Models.java b/src/projectzombie/init/Models.java index cee3c0a..bdbceec 100755 --- a/src/projectzombie/init/Models.java +++ b/src/projectzombie/init/Models.java @@ -17,7 +17,6 @@ import projectzombie.model.ModelTile; import projectzombie.model.ModelTree; import projectzombie.model.ModelTreeSnow; import projectzombie.model.ModelVertical; -import projectzombie.model.player.ModelPlayerHead; public class Models { @@ -94,6 +93,8 @@ public class Models new ModelVertical(Resources.ATLAS.get("/particle/smoke_4.png")), new ModelVertical(Resources.ATLAS.get("/particle/smoke_5.png"))); + public static final ModelGui UI_PIXEL_WHITE = new ModelGui(Resources.ATLAS.get("/gui/pixel_white.png")); + public static final ModelGui UI_PIXEL_BLACK = new ModelGui(Resources.ATLAS.get("/gui/pixel_black.png")); public static final ModelGui UI_BUTTON = new ModelGui(Resources.ATLAS.get("/gui/button_normal.png"), new Vec2d(12, 1.5)); public static final ModelGui UI_BUTTON_HOVER = new ModelGui(Resources.ATLAS.get("/gui/button_hover.png"), new Vec2d(12, 1.5)); public static final ModelGui UI_BUTTON_DELETE = new ModelGui(Resources.ATLAS.get("/gui/button_delete.png"), new Vec2d(1.875, 1.875)); @@ -101,6 +102,10 @@ public class Models public static final ModelGui UI_BUTTON_PLAY = new ModelGui(Resources.ATLAS.get("/gui/button_play.png"), new Vec2d(1.875, 1.875)); public static final ModelGui UI_BUTTON_PLAY_HOVER = new ModelGui(Resources.ATLAS.get("/gui/button_play_hover.png"), new Vec2d(1.875, 1.875)); public static final ModelGui UI_LABEL = new ModelGui(Resources.ATLAS.get("/gui/label.png"), new Vec2d(24, 3)); + public static final ModelGui UI_SELECTION_BOX_WIDE = new ModelGui(Resources.ATLAS.get("/gui/selection_box_wide.png"), new Vec2d(24, 12)); + public static final ModelGui UI_SELECTION_BOX_BIG = new ModelGui(Resources.ATLAS.get("/gui/selection_box_big.png"), new Vec2d(12, 12)); + public static final ModelGui UI_TEXT_BOX = new ModelGui(Resources.ATLAS.get("/gui/text_box.png"), new Vec2d(12, 1.5)); + public static final ModelGui UI_TEXT_CURSOR = new ModelGui(Resources.ATLAS.get("/gui/text_cursor.png"), 2, 50); public static final ModelGui UI_HEALTH_FG = new ModelGui(Resources.ATLAS.get("/gui/health_full.png"), new Vec2d(6, 0.375)); public static final ModelGui UI_HEALTH_BG = new ModelGui(Resources.ATLAS.get("/gui/health_empty.png"), new Vec2d(6, 0.375)); diff --git a/src/projectzombie/input/CursorPosCallback.java b/src/projectzombie/input/CursorPosCallback.java index 518b6dd..0a8807f 100755 --- a/src/projectzombie/input/CursorPosCallback.java +++ b/src/projectzombie/input/CursorPosCallback.java @@ -11,11 +11,13 @@ public class CursorPosCallback implements GLFWCursorPosCallbackI { public static double mx, my; + public static Vec2d getCursorPos() { + return new Vec2d(mx, my); + } + @Override public void invoke(long window, double x, double y) { - Main.menu.input.mousePos(new Vec2d(x, y)); - Main.window.setMouseVisibility(!Main.menu.keepMouse); InputMode.Controller = false; diff --git a/src/projectzombie/input/JoystickCallback.java b/src/projectzombie/input/JoystickCallback.java index dbc9f40..2fa2e72 100755 --- a/src/projectzombie/input/JoystickCallback.java +++ b/src/projectzombie/input/JoystickCallback.java @@ -1,6 +1,15 @@ package projectzombie.input; -import static projectzombie.input.GameInput.*; +import static projectzombie.input.GameInput.activateItem_last; +import static projectzombie.input.GameInput.activate_last; +import static projectzombie.input.GameInput.backButton_last; +import static projectzombie.input.GameInput.dropItem_last; +import static projectzombie.input.GameInput.hotbar_l; +import static projectzombie.input.GameInput.hotbar_r; +import static projectzombie.input.GameInput.moveDown; +import static projectzombie.input.GameInput.moveUp; +import static projectzombie.input.GameInput.move_last; +import static projectzombie.input.GameInput.startButton_last; import java.nio.ByteBuffer; import java.nio.FloatBuffer; diff --git a/src/projectzombie/input/KeyCallback.java b/src/projectzombie/input/KeyCallback.java index 289b433..f176cf4 100755 --- a/src/projectzombie/input/KeyCallback.java +++ b/src/projectzombie/input/KeyCallback.java @@ -15,11 +15,20 @@ import static org.lwjgl.glfw.GLFW.GLFW_KEY_D; import static org.lwjgl.glfw.GLFW.GLFW_KEY_E; import static org.lwjgl.glfw.GLFW.GLFW_KEY_ESCAPE; import static org.lwjgl.glfw.GLFW.GLFW_KEY_F11; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_LEFT_CONTROL; import static org.lwjgl.glfw.GLFW.GLFW_KEY_Q; +import static org.lwjgl.glfw.GLFW.GLFW_KEY_RIGHT_CONTROL; import static org.lwjgl.glfw.GLFW.GLFW_KEY_S; import static org.lwjgl.glfw.GLFW.GLFW_KEY_W; import static org.lwjgl.glfw.GLFW.GLFW_RELEASE; -import static projectzombie.input.GameInput.*; +import static projectzombie.input.GameInput.backButton_last; +import static projectzombie.input.GameInput.buttonL; +import static projectzombie.input.GameInput.buttonR; +import static projectzombie.input.GameInput.moveDown; +import static projectzombie.input.GameInput.moveLeft; +import static projectzombie.input.GameInput.moveRight; +import static projectzombie.input.GameInput.moveUp; +import static projectzombie.input.GameInput.move_last; import org.lwjgl.glfw.GLFWKeyCallbackI; @@ -27,7 +36,6 @@ import gl_engine.vec.Vec2d; import mainloop.task.IMainloopTask; import projectzombie.Main; import projectzombie.input.types.Input; -import projectzombie.menu.MenuInventory; public class KeyCallback implements GLFWKeyCallbackI, IMainloopTask { @@ -37,6 +45,8 @@ public class KeyCallback implements GLFWKeyCallbackI, IMainloopTask private boolean buttonL_last = false; private boolean buttonR_last = false; private boolean inventory_last = false; + private boolean lctrl_pressed = false; + private boolean rctrl_pressed = false; @Override public void invoke(long window, int key, int scancode, int action, int mods) @@ -46,6 +56,13 @@ public class KeyCallback implements GLFWKeyCallbackI, IMainloopTask InputMode.Controller = false; + if(key == GLFW_KEY_LEFT_CONTROL) { + lctrl_pressed = pressed; + } + if(key == GLFW_KEY_RIGHT_CONTROL) { + rctrl_pressed = pressed; + } + if(key == GLFW_KEY_W) { moveUp = pressed; } @@ -62,35 +79,44 @@ public class KeyCallback implements GLFWKeyCallbackI, IMainloopTask moveRight = pressed; } - if(key == GLFW_KEY_1 && pressed) { - input.hotbarGoto(true, 0); - } - if(key == GLFW_KEY_2 && pressed) { - input.hotbarGoto(true, 1); - } - if(key == GLFW_KEY_3 && pressed) { - input.hotbarGoto(true, 2); - } - if(key == GLFW_KEY_4 && pressed) { - input.hotbarGoto(true, 3); - } - if(key == GLFW_KEY_5 && pressed) { - input.hotbarGoto(true, 4); - } - if(key == GLFW_KEY_6 && pressed) { - input.hotbarGoto(true, 5); - } - if(key == GLFW_KEY_7 && pressed) { - input.hotbarGoto(true, 6); - } - if(key == GLFW_KEY_8 && pressed) { - input.hotbarGoto(true, 7); - } - if(key == GLFW_KEY_9 && pressed) { - input.hotbarGoto(true, 8); - } - if(key == GLFW_KEY_0 && pressed) { - input.hotbarGoto(true, 9); + if(pressed) + { + input.key(key); + + if(lctrl_pressed || rctrl_pressed) { + input.keyCtrl(key); + } + + if(key == GLFW_KEY_1) { + input.hotbarGoto(true, 0); + } + if(key == GLFW_KEY_2) { + input.hotbarGoto(true, 1); + } + if(key == GLFW_KEY_3) { + input.hotbarGoto(true, 2); + } + if(key == GLFW_KEY_4) { + input.hotbarGoto(true, 3); + } + if(key == GLFW_KEY_5) { + input.hotbarGoto(true, 4); + } + if(key == GLFW_KEY_6) { + input.hotbarGoto(true, 5); + } + if(key == GLFW_KEY_7) { + input.hotbarGoto(true, 6); + } + if(key == GLFW_KEY_8) { + input.hotbarGoto(true, 7); + } + if(key == GLFW_KEY_9) { + input.hotbarGoto(true, 8); + } + if(key == GLFW_KEY_0) { + input.hotbarGoto(true, 9); + } } if(key == GLFW_KEY_Q) { diff --git a/src/projectzombie/input/KeyCharCallback.java b/src/projectzombie/input/KeyCharCallback.java index 611d57d..dfd5e9e 100755 --- a/src/projectzombie/input/KeyCharCallback.java +++ b/src/projectzombie/input/KeyCharCallback.java @@ -2,12 +2,15 @@ package projectzombie.input; import org.lwjgl.glfw.GLFWCharCallbackI; +import projectzombie.Main; + public class KeyCharCallback implements GLFWCharCallbackI { @Override - public void invoke(long arg0, int arg1) { + public void invoke(long window, int character) { InputMode.Controller = false; + Main.menu.input.type((char)(character)); } } diff --git a/src/projectzombie/input/MouseButtonCallback.java b/src/projectzombie/input/MouseButtonCallback.java index 792c6e0..75f674c 100755 --- a/src/projectzombie/input/MouseButtonCallback.java +++ b/src/projectzombie/input/MouseButtonCallback.java @@ -3,8 +3,6 @@ package projectzombie.input; import org.lwjgl.glfw.GLFW; import org.lwjgl.glfw.GLFWMouseButtonCallbackI; -import projectzombie.Main; - public class MouseButtonCallback implements GLFWMouseButtonCallbackI { diff --git a/src/projectzombie/input/types/Input.java b/src/projectzombie/input/types/Input.java index 2b3d70a..775793a 100755 --- a/src/projectzombie/input/types/Input.java +++ b/src/projectzombie/input/types/Input.java @@ -4,6 +4,7 @@ import gl_engine.vec.Vec2d; public interface Input { + public void type(char character); public void move(boolean state, double angle); public void fire(boolean state); public void camera(boolean state, double amount); @@ -12,8 +13,9 @@ public interface Input public void pause(boolean state); public void hotbarGoto(boolean state, int pos); public void hotbarShift(boolean state, int amount); - public void mousePos(Vec2d pos); public void back(boolean state); public void activate(boolean state); public void openInventory(); + public void key(int key); + public void keyCtrl(int key); } diff --git a/src/projectzombie/input/types/InputGUI.java b/src/projectzombie/input/types/InputGUI.java index 13c86bb..69d9c76 100755 --- a/src/projectzombie/input/types/InputGUI.java +++ b/src/projectzombie/input/types/InputGUI.java @@ -15,6 +15,10 @@ public class InputGUI implements Input this.gui = gui; } + public GUI getGUI() { + return gui; + } + @Override public void move(boolean state, double angle) { this.gui.onMove(state, angle); @@ -60,15 +64,6 @@ public class InputGUI implements Input public void hotbarShift(boolean state, int amount) { gui.onScroll(amount); } - - @Override - public void mousePos(Vec2d pos) - { - double mx = (pos.x / Main.window.getWidth() * 20 - 10) * GlHelpers.getAspectRatio(); - double my = -pos.y / Main.window.getHeight() * 20 + 10; - - this.gui.updateMousePos(new Vec2d(mx, my)); - } @Override public void back(boolean state) { @@ -83,5 +78,20 @@ public class InputGUI implements Input @Override public void openInventory() { } + + @Override + public void type(char character) { + gui.type(character); + } + + @Override + public void key(int key) { + gui.keyPress(key); + } + + @Override + public void keyCtrl(int key) { + gui.keyPressCtrl(key); + } } diff --git a/src/projectzombie/input/types/InputGUITextBox.java b/src/projectzombie/input/types/InputGUITextBox.java new file mode 100644 index 0000000..299da6a --- /dev/null +++ b/src/projectzombie/input/types/InputGUITextBox.java @@ -0,0 +1,12 @@ +package projectzombie.input.types; + +public interface InputGUITextBox { + public void onBackspace(); + public void onDelete(); + public void onPressed(char character); + public void onMoveCursor(int direction); + public void setFocus(boolean focus); + public void onPaste(); + public void onHome(); + public void onEnd(); +} diff --git a/src/projectzombie/input/types/InputGame.java b/src/projectzombie/input/types/InputGame.java index 35181c2..0ffd613 100755 --- a/src/projectzombie/input/types/InputGame.java +++ b/src/projectzombie/input/types/InputGame.java @@ -5,6 +5,7 @@ import gl_engine.vec.Vec2d; import projectzombie.Main; import projectzombie.menu.MenuGamePause; import projectzombie.menu.MenuInventory; +import projectzombie.menu.MenuInventoryBasic; import projectzombie.world.chunk.ChunkEventHandler; public class InputGame implements Input @@ -65,10 +66,6 @@ public class InputGame implements Input Main.player.inventory_hand += amount; Main.player.inventory_hand = MathHelpers.mod(Main.player.inventory_hand, 10); } - - @Override - public void mousePos(Vec2d pos) { - } @Override public void back(boolean state) { @@ -80,7 +77,19 @@ public class InputGame implements Input @Override public void openInventory() { - Main.menu = new MenuInventory(Main.menu); + Main.menu = new MenuInventoryBasic(Main.menu); + } + + @Override + public void type(char character) { + } + + @Override + public void key(int key) { + } + + @Override + public void keyCtrl(int key) { } } diff --git a/src/projectzombie/inventory/Crafting.java b/src/projectzombie/inventory/Crafting.java new file mode 100644 index 0000000..1b6c2a5 --- /dev/null +++ b/src/projectzombie/inventory/Crafting.java @@ -0,0 +1,5 @@ +package projectzombie.inventory; + +public enum Crafting { + BASIC +} diff --git a/src/projectzombie/inventory/Inventory.java b/src/projectzombie/inventory/Inventory.java index 671972d..127b82a 100755 --- a/src/projectzombie/inventory/Inventory.java +++ b/src/projectzombie/inventory/Inventory.java @@ -158,11 +158,11 @@ public class Inventory implements IInventory, IBdfClassManager { BdfNamedList nl = bdf.getNamedList(); - nl.set("size", BdfObject.withInteger(items.length)); + nl.set("size", bdf.newObject().setInteger(items.length)); BdfArray array = nl.get("items").getArray(); for(ItemStack stack : items) { - BdfObject stack_bdf = new BdfObject(); + BdfObject stack_bdf = bdf.newObject(); stack.BdfClassSave(stack_bdf); array.add(stack_bdf); } diff --git a/src/projectzombie/inventory/InventoryArmor.java b/src/projectzombie/inventory/InventoryArmor.java index 09f8209..0ae2290 100644 --- a/src/projectzombie/inventory/InventoryArmor.java +++ b/src/projectzombie/inventory/InventoryArmor.java @@ -59,7 +59,7 @@ public class InventoryArmor implements IBdfClassManager, IInventoryArmor @Override public void BdfClassSave(BdfObject bdf) { - BdfNamedList nl = new BdfNamedList(); + BdfNamedList nl = bdf.newNamedList(); helmet.BdfClassSave(nl.get("helmet")); chest.BdfClassSave(nl.get("chest")); leggings.BdfClassSave(nl.get("leggings")); diff --git a/src/projectzombie/inventory/InventoryClothing.java b/src/projectzombie/inventory/InventoryClothing.java index 2f92e08..d60533b 100644 --- a/src/projectzombie/inventory/InventoryClothing.java +++ b/src/projectzombie/inventory/InventoryClothing.java @@ -59,7 +59,7 @@ public class InventoryClothing implements IBdfClassManager, IInventoryClothing @Override public void BdfClassSave(BdfObject bdf) { - BdfNamedList nl = new BdfNamedList(); + BdfNamedList nl = bdf.newNamedList(); shirt.BdfClassSave(nl.get("shirt")); pants.BdfClassSave(nl.get("pants")); boots.BdfClassSave(nl.get("boots")); diff --git a/src/projectzombie/inventory/recipe/Recipe.java b/src/projectzombie/inventory/recipe/Recipe.java new file mode 100644 index 0000000..4c6ce78 --- /dev/null +++ b/src/projectzombie/inventory/recipe/Recipe.java @@ -0,0 +1,13 @@ +package projectzombie.inventory.recipe; + +import projectzombie.inventory.Inventory; +import projectzombie.inventory.Crafting; +import projectzombie.util.math.ItemStack; + +public abstract class Recipe +{ + public abstract ItemStack getResult(); + public abstract boolean canCraft(Crafting tool); + public abstract boolean hasResourcesToCraft(Inventory inventory); + public abstract ItemStack craftResult(Inventory inventory); +} diff --git a/src/projectzombie/inventory/recipe/RecipeBasic.java b/src/projectzombie/inventory/recipe/RecipeBasic.java new file mode 100644 index 0000000..b473d75 --- /dev/null +++ b/src/projectzombie/inventory/recipe/RecipeBasic.java @@ -0,0 +1,57 @@ +package projectzombie.inventory.recipe; + +import projectzombie.inventory.Crafting; +import projectzombie.inventory.Inventory; +import projectzombie.util.math.ItemStack; + +public class RecipeBasic extends Recipe +{ + protected ItemStack[] stacks_required; + protected Crafting[] tools_required; + protected ItemStack result; + + public RecipeBasic(ItemStack[] stacks_required, Crafting[] tools_required, ItemStack result) + { + this.stacks_required = stacks_required; + this.tools_required = tools_required; + } + + @Override + public ItemStack getResult() { + return result.copy(); + } + + @Override + public boolean canCraft(Crafting tool) + { + for(Crafting tool_required : tools_required) { + if(tool == tool_required) { + return true; + } + } + + return false; + } + + @Override + public boolean hasResourcesToCraft(Inventory inventory) + { + for(ItemStack item : stacks_required) { + if(inventory.getItemCount(item) < item.count) { + return false; + } + } + + return true; + } + + @Override + public ItemStack craftResult(Inventory inventory) + { + for(ItemStack item : stacks_required) { + inventory.removeItem(item.copy()); + } + + return result.copy(); + } +} diff --git a/src/projectzombie/items/Item.java b/src/projectzombie/items/Item.java index 5111662..23a6d39 100755 --- a/src/projectzombie/items/Item.java +++ b/src/projectzombie/items/Item.java @@ -4,7 +4,6 @@ import projectzombie.entity.Entity; import projectzombie.entity.EntityHasInventory; import projectzombie.entity.player.EntityPlayer; import projectzombie.inventory.IInventory; -import projectzombie.inventory.Inventory; import projectzombie.model.ModelItem; import projectzombie.util.math.ItemStack; import projectzombie.world.chunk.Chunk; diff --git a/src/projectzombie/items/ItemAmmo.java b/src/projectzombie/items/ItemAmmo.java index 142f287..c3297e9 100755 --- a/src/projectzombie/items/ItemAmmo.java +++ b/src/projectzombie/items/ItemAmmo.java @@ -1,11 +1,7 @@ package projectzombie.items; -import projectzombie.entity.player.EntityPlayer; import projectzombie.init.Models; import projectzombie.model.ModelItem; -import projectzombie.util.math.ItemStack; -import projectzombie.world.chunk.Chunk; -import projectzombie.world.layer.Layer; public class ItemAmmo extends Item { diff --git a/src/projectzombie/items/ItemEmpty.java b/src/projectzombie/items/ItemEmpty.java index 75f1384..f4fa04d 100755 --- a/src/projectzombie/items/ItemEmpty.java +++ b/src/projectzombie/items/ItemEmpty.java @@ -1,7 +1,6 @@ package projectzombie.items; import projectzombie.entity.Entity; -import projectzombie.entity.player.EntityPlayer; import projectzombie.init.Models; import projectzombie.model.ModelItem; import projectzombie.util.math.ItemStack; diff --git a/src/projectzombie/items/ItemFlint.java b/src/projectzombie/items/ItemFlint.java index 82aba11..fbc5302 100644 --- a/src/projectzombie/items/ItemFlint.java +++ b/src/projectzombie/items/ItemFlint.java @@ -2,7 +2,6 @@ package projectzombie.items; import projectzombie.init.Models; import projectzombie.model.ModelItem; -import projectzombie.util.math.ItemStack; public class ItemFlint extends Item { diff --git a/src/projectzombie/items/ItemRock.java b/src/projectzombie/items/ItemRock.java index c9d6d92..82a092d 100755 --- a/src/projectzombie/items/ItemRock.java +++ b/src/projectzombie/items/ItemRock.java @@ -1,11 +1,8 @@ package projectzombie.items; -import projectzombie.entity.player.EntityPlayer; import projectzombie.init.Models; import projectzombie.model.ModelItem; import projectzombie.util.math.ItemStack; -import projectzombie.world.chunk.Chunk; -import projectzombie.world.layer.Layer; public class ItemRock extends Item implements ItemTool { diff --git a/src/projectzombie/menu/MenuDeath.java b/src/projectzombie/menu/MenuDeath.java index 8e39829..97871cc 100755 --- a/src/projectzombie/menu/MenuDeath.java +++ b/src/projectzombie/menu/MenuDeath.java @@ -2,10 +2,10 @@ package projectzombie.menu; import projectzombie.Main; import projectzombie.input.types.InputGUI; -import projectzombie.menu.gui.GUIButtonGroup; -import projectzombie.menu.gui.GUIButtonGroupPause; import projectzombie.menu.gui.GUI; import projectzombie.menu.gui.GUIButtonBasic; +import projectzombie.menu.gui.GUIButtonGroup; +import projectzombie.menu.gui.GUIButtonGroupPause; public class MenuDeath extends Menu { diff --git a/src/projectzombie/menu/MenuGamePause.java b/src/projectzombie/menu/MenuGamePause.java index 1eec8e5..01b65c9 100755 --- a/src/projectzombie/menu/MenuGamePause.java +++ b/src/projectzombie/menu/MenuGamePause.java @@ -1,17 +1,13 @@ package projectzombie.menu; -import java.io.FileOutputStream; -import java.util.zip.DeflaterOutputStream; - -import bdf.types.BdfObject; import projectzombie.Main; import projectzombie.input.types.InputGUI; -import projectzombie.menu.gui.GUIButtonGroup; -import projectzombie.menu.gui.GUIButtonGroupPause; -import projectzombie.menu.gui.GUILabelPause; import projectzombie.menu.gui.GUI; import projectzombie.menu.gui.GUIBackToMenu; import projectzombie.menu.gui.GUIButtonBasic; +import projectzombie.menu.gui.GUIButtonGroup; +import projectzombie.menu.gui.GUIButtonGroupPause; +import projectzombie.menu.gui.GUILabelPause; public class MenuGamePause extends Menu { @@ -44,48 +40,7 @@ public class MenuGamePause extends Menu public void saveAndQuit() { - long now, cur = 0; - - BdfObject bdf = new BdfObject(); - - now = System.currentTimeMillis(); - Main.world.BdfClassSave(bdf); - cur = System.currentTimeMillis(); - System.out.println("Time for BdfClassSave: " + (cur - now)); - now = cur; - - System.out.println("Size on file: " + bdf.serialize().size()); - //System.out.println(bdf.serializeHumanReadable()); - - try { - - /* - - FileOutputStream os = new FileOutputStream("./layer.hbdf"); - os.write(bdf.serializeHumanReadable(new BdfIndent("\t", "\n")).getBytes()); - os.close(); - - cur = System.currentTimeMillis(); - System.out.println("Time for HBDF: " + (cur - now)); - now = cur; - - */ - - FileOutputStream os2 = new FileOutputStream("./layer.bdf"); - DeflaterOutputStream dos = new DeflaterOutputStream(os2); - dos.write(bdf.serialize().getBytes()); - dos.close(); - os2.close(); - - cur = System.currentTimeMillis(); - System.out.println("Time for BDF: " + (cur - now)); - now = cur; - } - - catch(Exception e) { - e.printStackTrace(); - } - + Main.world.save(); Main.menu = new MenuMain(); } } diff --git a/src/projectzombie/menu/MenuInventory.java b/src/projectzombie/menu/MenuInventory.java index fc5d44d..694272c 100644 --- a/src/projectzombie/menu/MenuInventory.java +++ b/src/projectzombie/menu/MenuInventory.java @@ -1,12 +1,9 @@ package projectzombie.menu; -import gl_engine.MathHelpers; import gl_engine.matrix.Matrix4; import gl_engine.vec.Vec2d; import gl_engine.vec.Vec3d; import projectzombie.Main; -import projectzombie.display.Camera; -import projectzombie.init.Items; import projectzombie.init.Models; import projectzombie.input.CursorPosCallback; import projectzombie.input.types.InputGUI; @@ -15,24 +12,25 @@ import projectzombie.inventory.InventoryArmor; import projectzombie.inventory.InventoryClothing; import projectzombie.items.ItemArmor; import projectzombie.items.ItemClothing; -import projectzombie.menu.gui.GUIButton; +import projectzombie.menu.gui.GUI; +import projectzombie.menu.gui.GUIBackToMenu; import projectzombie.menu.gui.GUIItemHolder; import projectzombie.menu.gui.GUIItemSlot; import projectzombie.menu.gui.GUIItemSlotGetter; import projectzombie.menu.gui.GUIItemSlotGetterStorage; -import projectzombie.menu.gui.GUI; -import projectzombie.menu.gui.GUIBackToMenu; import projectzombie.model.Model; -import projectzombie.util.gl.GlHelpers; +import projectzombie.model.ModelGui; import projectzombie.util.math.ItemStack; -public class MenuInventory extends Menu +public abstract class MenuInventory extends Menu { - private Menu parent; - private GUI gui; + protected Menu parent; + protected GUIItemHolder itemHolder; + protected GUI gui; + private GUI top_gui; - private GUIItemSlot[] item_slots; - private GUIItemSlot[] armor_slots; + protected GUIItemSlot[] item_slots; + protected GUIItemSlot[] armor_slots; public MenuInventory(Menu parent) { @@ -44,12 +42,13 @@ public class MenuInventory extends Menu keepMouse = false; - gui = new GUIBackToMenu(parent); - input = new InputGUI(gui); + top_gui = new GUIBackToMenu(parent); + input = new InputGUI(top_gui); + gui = new GUI(); Inventory inventory = Main.player.getInventory(); - GUIItemHolder itemHolder = new GUIItemHolder(); + itemHolder = new GUIItemHolder(); item_slots = new GUIItemSlot[42]; armor_slots = new GUIItemSlot[6]; @@ -185,9 +184,8 @@ public class MenuInventory extends Menu } } - - - gui.add(itemHolder); + top_gui.add(gui); + top_gui.add(itemHolder); } @Override @@ -230,14 +228,14 @@ public class MenuInventory extends Menu player_matrix = Matrix4.multiply(Matrix4.rotate(ay, 1, 0, 0), player_matrix); player_matrix = Matrix4.multiply(Matrix4.translate(-width * (10.8 / 256.0), -height * (10.8 / 256.0), 0), player_matrix);*/ - gui.render(); + top_gui.render(); } @Override public void update() { super.update(); - gui.update(new Vec2d(CursorPosCallback.mx, CursorPosCallback.my)); + top_gui.update(new Vec2d(CursorPosCallback.mx, CursorPosCallback.my)); } } diff --git a/src/projectzombie/menu/MenuInventoryBasic.java b/src/projectzombie/menu/MenuInventoryBasic.java new file mode 100644 index 0000000..b6226df --- /dev/null +++ b/src/projectzombie/menu/MenuInventoryBasic.java @@ -0,0 +1,36 @@ +package projectzombie.menu; + +import gl_engine.matrix.Matrix4; +import gl_engine.vec.Vec2d; +import projectzombie.init.Models; +import projectzombie.menu.gui.GUIContainerSlider; + +public class MenuInventoryBasic extends MenuInventory +{ + private GUIContainerSlider slider; + + public MenuInventoryBasic(Menu parent) { + super(parent); + + slider = new GUIContainerSlider(new Vec2d( + Models.UI_INVENTORY.getWidth() * 1 / 256.0, + -Models.UI_INVENTORY.getHeight() * 127 / 256.0), new Vec2d( + Models.UI_INVENTORY.getWidth() * 254 / 256.0, + Models.UI_INVENTORY.getHeight() * 254 / 256.0), 100); + + gui.add(slider); + } + + @Override + public void render() + { + Matrix4 matrix = Matrix4.translate(0, -Models.UI_INVENTORY.getHeight() / 2, 0); + + // Render the inventory gui + Models.UI_SELECTION_BOX_BIG.setModel(matrix); + Models.UI_SELECTION_BOX_BIG.render(); + + super.render(); + } + +} diff --git a/src/projectzombie/menu/MenuMain.java b/src/projectzombie/menu/MenuMain.java index 8a377f0..a9279ed 100755 --- a/src/projectzombie/menu/MenuMain.java +++ b/src/projectzombie/menu/MenuMain.java @@ -2,14 +2,16 @@ package projectzombie.menu; import java.util.Random; +import gl_engine.vec.Vec2d; import gl_engine.vec.Vec3d; import projectzombie.Main; -import projectzombie.init.Layers; import projectzombie.input.types.InputGUI; -import projectzombie.menu.gui.GUIButtonGroup; -import projectzombie.menu.gui.GUILabelMain; import projectzombie.menu.gui.GUI; import projectzombie.menu.gui.GUIButtonBasic; +import projectzombie.menu.gui.GUIButtonGroup; +import projectzombie.menu.gui.GUILabelMain; +import projectzombie.menu.gui.GUITextBox; +import projectzombie.world.World; public class MenuMain extends Menu { @@ -45,7 +47,7 @@ public class MenuMain extends Menu gui.add(group); gui.setSelected(group.get(0)); - Layers.createWorld(null, rand.nextLong()); + World.createWorld(null, rand.nextLong()); Main.player.dead = true; } diff --git a/src/projectzombie/menu/MenuSaves.java b/src/projectzombie/menu/MenuSaves.java index 9a32069..eacff0f 100644 --- a/src/projectzombie/menu/MenuSaves.java +++ b/src/projectzombie/menu/MenuSaves.java @@ -1,33 +1,51 @@ package projectzombie.menu; +import java.io.File; +import java.util.ArrayList; import java.util.Random; -import org.lwjgl.opengl.GL33; - +import bdf.file.BdfFileManager; +import bdf.types.BdfArray; +import bdf.types.BdfNamedList; +import bdf.types.BdfObject; +import gl_engine.matrix.Matrix4; import gl_engine.vec.Vec2d; import projectzombie.Main; -import projectzombie.init.Layers; import projectzombie.init.Models; import projectzombie.input.types.InputGUI; import projectzombie.menu.gui.GUI; import projectzombie.menu.gui.GUIAlignment; -import projectzombie.menu.gui.GUIButton; +import projectzombie.menu.gui.GUIBackToMenu; import projectzombie.menu.gui.GUIButtonBasic; -import projectzombie.menu.gui.GUIButtonCallback; +import projectzombie.menu.gui.GUIContainerSlider; import projectzombie.menu.gui.GUILabel; import projectzombie.menu.gui.GUISavesCard; -import projectzombie.menu.gui.GUIButtonModel; -import projectzombie.menu.gui.GUIButtonSetting; -import projectzombie.menu.gui.GUIContainerSlider; +import projectzombie.model.ModelGui; +import projectzombie.world.World; public class MenuSaves extends Menu { private static final Random rand = new Random(); + private BdfFileManager reader; + private ArrayList saves; + private int saves_remove = -1; + private Menu parent; private GUIContainerSlider slider; private GUI gui; + private class SaveCard + { + String text, filename; + + public SaveCard(String text, String filename) + { + this.text = text; + this.filename = filename; + } + } + public MenuSaves(Menu parent) { this.parent = parent; @@ -36,8 +54,8 @@ public class MenuSaves extends Menu doGameRender = parent.doGameRender; showIngameGUI = parent.showIngameGUI; - gui = new GUI(); - + gui = new GUIBackToMenu(parent); + saves = new ArrayList(); input = new InputGUI(gui); keepMouse = false; @@ -47,14 +65,16 @@ public class MenuSaves extends Menu }); GUIButtonBasic buttonCreate = new GUIButtonBasic("Create", button -> { - Layers.createWorld(null, rand.nextLong()); - Main.menu = new MenuGame(); + createWorld(); }); - slider = new GUIContainerSlider(new Vec2d(-20, -5), new Vec2d(40, 10), 10); + slider = new GUIContainerSlider(new Vec2d( + -Models.UI_SELECTION_BOX_WIDE.getWidth() * 127 / 256.0, + -Models.UI_SELECTION_BOX_WIDE.getHeight() * 63 / 128.0), new Vec2d( + Models.UI_SELECTION_BOX_WIDE.getWidth() * 254 / 256.0, + Models.UI_SELECTION_BOX_WIDE.getHeight() * 126 / 128.0), 10); - GUISavesCard savesCard = new GUISavesCard(new Vec2d(0, 0)); - slider.add(savesCard); + reloadDatabase(); buttonBack.setAlign(GUIAlignment.RIGHT); buttonCreate.setAlign(GUIAlignment.LEFT); @@ -72,10 +92,100 @@ public class MenuSaves extends Menu gui.add(buttonCreate); gui.add(slider); } + + private void createWorld() { + Main.menu = new MenuWorldNew(this); + } + + private void loadSave(int index) + { + BdfObject bdf = reader.getObject(); + BdfNamedList nl = bdf.getNamedList(); + BdfArray array = nl.get("saves").getArray(); + + BdfObject save_bdf = array.remove(index); + array.add(save_bdf); + + reader.saveDatabase(); + + Main.world = new World(saves.get(index).filename); + Main.menu = new MenuGame(); + } + + private void deleteSave(int index) + { + SaveCard save = saves.get(index); + Main.menu = new MenuWorldDelete(this, save.text, save.filename); + } + + public void reloadDatabase() + { + saves.clear(); + reader = new BdfFileManager("./saves.bdf", true); + BdfNamedList nl = reader.getObject().getNamedList(); + BdfArray array = nl.get("saves").getArray(); + + for(BdfObject save_bdf : array) + { + BdfNamedList save_nl = save_bdf.getNamedList(); + + SaveCard save = new SaveCard( + save_nl.get("name").getString(), + save_nl.get("path").getString()); + + saves.add(save); + } + + generateSaveCards(); + } + + private void generateSaveCards() + { + double slider_length = Models.UI_LABEL.getHeight() * 18.0 * saves.size() / 16.0; + double selection_length = Models.UI_SELECTION_BOX_WIDE.getHeight() * 248 / 256.0; + + slider.clear(); + slider.setLength(slider_length > selection_length ? slider_length - selection_length : 0); + + for(int i=0;i { + Main.menu = parent; + }); + + GUIButtonBasic buttonDelete = new GUIButtonBasic("Delete", button -> { + deleteSave(); + }); + + buttonCancel.setAlign(GUIAlignment.RIGHT); + buttonDelete.setAlign(GUIAlignment.LEFT); + + buttonCancel.setPos(new Vec2d(-0.5, -4)); + buttonDelete.setPos(new Vec2d(0.5, -4)); + + { + // Delete world title + GUILabel label = new GUILabel(); + label.setText("Delete World"); + label.setSize(new Vec2d(1, 1)); + label.setPos(new Vec2d(0, 4)); + gui.add(label); + } + + { + // Delete world confirm message + GUILabel label = new GUILabel(); + label.setText("Are you sure you want to delete \"" + name + "\"?"); + label.setSize(new Vec2d(0.4, 0.4)); + label.setPos(new Vec2d(0, 3)); + gui.add(label); + } + + gui.add(buttonCancel); + gui.add(buttonDelete); + } + + private void deleteSave() + { + BdfFileManager reader = new BdfFileManager("./saves.bdf", true); + BdfObject bdf = reader.getObject(); + BdfNamedList nl = bdf.getNamedList(); + BdfArray array = nl.get("saves").getArray(); + + File save_file = new File("./saves/" + path + ".bdf"); + save_file.delete(); + + for(int i=0;i { + Main.menu = parent; + }); + + GUIButtonBasic buttonCreate = new GUIButtonBasic("Generate", button -> { + generateWorld(); + }); + + buttonBack.setAlign(GUIAlignment.RIGHT); + buttonCreate.setAlign(GUIAlignment.LEFT); + + buttonBack.setPos(new Vec2d(-0.5, -8)); + buttonCreate.setPos(new Vec2d(0.5, -8)); + + { + // New world title label + GUILabel label = new GUILabel(); + label.setText("Create New World"); + label.setSize(new Vec2d(1, 1)); + label.setPos(new Vec2d(0, 6.8)); + gui.add(label); + } + + { + // Set the world name + + double offset = -Models.UI_TEXT_BOX.getWidth() / 2; + + GUILabel label = new GUILabel(); + label.setAlign(GUIAlignment.RIGHT); + label.setText("World Name"); + label.setSize(new Vec2d(0.4, 0.4)); + label.setPos(new Vec2d(offset + Models.UI_TEXT_BOX.getWidth() * 2 / 128.0, 4)); + gui.add(label); + + world_name = new GUITextBox(new Vec2d(offset, 3.8 - Models.UI_TEXT_BOX.getHeight()), true); + world_name.setText(name); + gui.add(world_name); + } + + gui.add(buttonBack); + gui.add(buttonCreate); + } + + private void generateWorld() + { + name = world_name.getText(); + + String path = name; + path = path.toLowerCase(); + + char[] path_chars = path.toCharArray(); + + for(int i=0;i= '0' && c <= '9') || (c >= 'a' && c <= 'z')) { + path_chars[i] = c; + } else { + path_chars[i] = '_'; + } + } + + path = new String(path_chars); + + if(name.length() == 0) { + return; + } + + BdfFileManager reader = new BdfFileManager("./saves.bdf", true); + BdfObject bdf = reader.getObject(); + BdfNamedList nl = bdf.getNamedList(); + BdfArray array = nl.get("saves").getArray(); + + // Find a unique name and path + + String name_new = name; + String path_new = path; + + boolean duplicate = true; + + for(int i=1;duplicate;i++) + { + duplicate = false; + + for(BdfObject save_bdf : array) + { + BdfNamedList save_nl = save_bdf.getNamedList(); + String save_name = save_nl.get("name").getString(); + String save_path = save_nl.get("path").getString(); + + if(i > 1) { + name_new = name + " (" + i + ")"; + path_new = path + "_" + i; + } + + if(name_new.contentEquals(save_name) || path_new.contentEquals(save_path)) { + duplicate = true; + break; + } + } + } + + BdfObject save_bdf = bdf.newObject(); + BdfNamedList save_nl = save_bdf.getNamedList(); + + save_nl.set("name", bdf.newObject().setString(name_new)); + save_nl.set("path", bdf.newObject().setString(path_new)); + + array.add(save_bdf); + reader.saveDatabase(); + + World.createWorld(path_new, seed); + Main.menu = new MenuGame(); + } + + @Override + public void update() + { + super.update(); + parent.update(); + } + + @Override + public void render() { + gui.render(); + } + +} diff --git a/src/projectzombie/menu/gui/GUI.java b/src/projectzombie/menu/gui/GUI.java index 1111807..90bd14e 100755 --- a/src/projectzombie/menu/gui/GUI.java +++ b/src/projectzombie/menu/gui/GUI.java @@ -2,18 +2,26 @@ package projectzombie.menu.gui; import java.util.ArrayList; +import org.lwjgl.glfw.GLFW; + import gl_engine.matrix.Matrix4; import gl_engine.vec.Vec2d; +import projectzombie.input.CursorPosCallback; +import projectzombie.input.types.InputGUITextBox; public class GUI implements GUIContainer { private ArrayList components = new ArrayList(); - private Vec2d mousePos = new Vec2d(0, 0); public GUISelectable selected; + private InputGUITextBox text_box; private static boolean move_last = false; + public void setTextBox(InputGUITextBox text_box) { + this.text_box = text_box; + } + public void setSelected(GUISelectable selected) { if(this.selected != null) { this.selected.setSelected(false); @@ -31,8 +39,12 @@ public class GUI implements GUIContainer } } + public Vec2d getCursorPos() { + return CursorPosCallback.getCursorPos(); + } + public void render() { - this.render(Matrix4.identity(), mousePos, true); + this.render(Matrix4.identity(), getCursorPos(), true); } @Override @@ -40,10 +52,6 @@ public class GUI implements GUIContainer components.add(c); } - public void updateMousePos(Vec2d pos) { - this.mousePos = pos; - } - public void onMove(boolean status, double angle) { if(this.selected == null) { @@ -96,35 +104,56 @@ public class GUI implements GUIContainer } @Override - public void onMouseClick(Vec2d pos) { + public void onMouseClick(Vec2d pos) + { + if(text_box != null && text_box instanceof GUIComponent && !((GUIComponent)text_box).checkMouseHover(pos)) { + text_box.setFocus(false); + text_box = null; + } + + Vec2d cursorPos = getCursorPos(); + for(GUIComponent c : components) { - if(c.checkMouseHover(mousePos)) { - c.onMouseClick(mousePos); + if(c.checkMouseHover(cursorPos)) { + c.onMouseClick(cursorPos); } } } @Override - public void onRightClick(Vec2d pos) { + public void onRightClick(Vec2d pos) + { + Vec2d cursorPos = getCursorPos(); + for(GUIComponent c : components) { - if(c.checkMouseHover(mousePos)) { - c.onRightClick(mousePos); + if(c.checkMouseHover(cursorPos)) { + c.onRightClick(cursorPos); } } } public void onMouseClick() { - this.onMouseClick(mousePos); + this.onMouseClick(getCursorPos()); } public void onRightClick() { - this.onRightClick(mousePos); + this.onRightClick(getCursorPos()); } @Override - public void onBack() { - for(GUIComponent c : components) { - c.onBack(); + public void onBack() + { + if(text_box == null) + { + for(GUIComponent c : components) { + c.onBack(); + } + } + + else + { + text_box.setFocus(false); + text_box = null; } } @@ -150,7 +179,63 @@ public class GUI implements GUIContainer } public void onScroll(int amount) { - onScroll(mousePos, amount / 10.0); + onScroll(getCursorPos(), amount); + } + + @Override + public void clear() { + components.clear(); + } + + public void type(char character) { + if(text_box != null) { + text_box.onPressed(character); + } + } + + public void pasteKey() { + if(text_box != null) { + text_box.onDelete(); + } + } + + public void keyPress(int key) { + if(text_box != null) + { + switch(key) + { + case GLFW.GLFW_KEY_LEFT: + text_box.onMoveCursor(-1); + break; + case GLFW.GLFW_KEY_RIGHT: + text_box.onMoveCursor(1); + break; + case GLFW.GLFW_KEY_DELETE: + text_box.onDelete(); + break; + case GLFW.GLFW_KEY_BACKSPACE: + text_box.onBackspace(); + break; + case GLFW.GLFW_KEY_HOME: + text_box.onHome(); + break; + case GLFW.GLFW_KEY_END: + text_box.onEnd(); + break; + } + } + } + + public void keyPressCtrl(int key) { + if(text_box != null) + { + switch(key) + { + case GLFW.GLFW_KEY_V: + text_box.onPaste(); + break; + } + } } } diff --git a/src/projectzombie/menu/gui/GUIButton.java b/src/projectzombie/menu/gui/GUIButton.java index 217b3f8..0e225be 100755 --- a/src/projectzombie/menu/gui/GUIButton.java +++ b/src/projectzombie/menu/gui/GUIButton.java @@ -3,12 +3,10 @@ package projectzombie.menu.gui; import gl_engine.matrix.Matrix4; import gl_engine.vec.Vec2d; import gl_engine.vec.Vec3d; -import projectzombie.Main; import projectzombie.init.Models; import projectzombie.input.InputMode; import projectzombie.model.ModelGui; import projectzombie.text.Text; -import projectzombie.util.gl.GlHelpers; public class GUIButton implements GUIComponent, GUISelectable { diff --git a/src/projectzombie/menu/gui/GUIButtonGroup.java b/src/projectzombie/menu/gui/GUIButtonGroup.java index fde57f3..8296e5e 100755 --- a/src/projectzombie/menu/gui/GUIButtonGroup.java +++ b/src/projectzombie/menu/gui/GUIButtonGroup.java @@ -104,5 +104,10 @@ public class GUIButtonGroup implements GUIContainer c.onScroll(mousePos, amount); } } + + @Override + public void clear() { + buttons.clear(); + } } diff --git a/src/projectzombie/menu/gui/GUIButtonGroupPause.java b/src/projectzombie/menu/gui/GUIButtonGroupPause.java index d5643ef..7206e1a 100755 --- a/src/projectzombie/menu/gui/GUIButtonGroupPause.java +++ b/src/projectzombie/menu/gui/GUIButtonGroupPause.java @@ -9,7 +9,6 @@ public class GUIButtonGroupPause extends GUIButtonGroup public GUIButtonGroupPause() { add(new GUIButtonBasic("Settings", button -> { - Main.menu.input.mousePos(new Vec2d(0, 0)); Main.menu = new MenuSettings(Main.menu); })); diff --git a/src/projectzombie/menu/gui/GUIContainer.java b/src/projectzombie/menu/gui/GUIContainer.java index e4aef94..cdfd50b 100755 --- a/src/projectzombie/menu/gui/GUIContainer.java +++ b/src/projectzombie/menu/gui/GUIContainer.java @@ -3,4 +3,5 @@ package projectzombie.menu.gui; public interface GUIContainer extends GUIComponent { public void add(GUIComponent c); + public void clear(); } diff --git a/src/projectzombie/menu/gui/GUIContainerSlider.java b/src/projectzombie/menu/gui/GUIContainerSlider.java index 6d23cc1..e1d4a51 100644 --- a/src/projectzombie/menu/gui/GUIContainerSlider.java +++ b/src/projectzombie/menu/gui/GUIContainerSlider.java @@ -6,8 +6,9 @@ import org.lwjgl.opengl.GL33; import gl_engine.matrix.Matrix4; import gl_engine.vec.Vec2d; -import gl_engine.vec.Vec4d; +import gl_engine.vec.Vec3d; import projectzombie.Main; +import projectzombie.init.Models; public class GUIContainerSlider implements GUIComponent, GUIContainer { @@ -39,8 +40,8 @@ public class GUIContainerSlider implements GUIComponent, GUIContainer canHover = false; } - matrix = Matrix4.multiply(matrix, Matrix4.translate(0, -scroll, 0)); - mousePos = mousePos.add(new Vec2d(0, scroll)); + matrix = Matrix4.multiply(matrix, Matrix4.translate(0, scroll, 0)); + mousePos = mousePos.add(new Vec2d(0, -scroll)); GL33.glUniform1i(Main.window.glsl_do_discard_coords, 1); GL33.glUniform4f(Main.window.glsl_discard_coords, @@ -50,6 +51,26 @@ public class GUIContainerSlider implements GUIComponent, GUIContainer c.render(matrix, mousePos, canHover); } + if(length > 0) + { + GL33.glUniform4f(Main.window.glsl_color, 0.25f, 0.25f, 0.25f, 1); + + double start = size.y * scroll / (length + size.y); + double end = size.y * (scroll + size.y) / (length + size.y); + + Matrix4 matrix_scroll_bar = Matrix4.translate( + pos.x + size.x - 0.125f, + pos.y + size.y - end, 0); + + matrix_scroll_bar = Matrix4.multiply(Matrix4.scale( + new Vec3d(1, (float)(end - start), 1)), matrix_scroll_bar); + + Models.UI_PIXEL_WHITE.setModel(matrix_scroll_bar); + Models.UI_PIXEL_WHITE.render(); + + GL33.glUniform4f(Main.window.glsl_color, 1, 1, 1, 1); + } + GL33.glUniform1i(Main.window.glsl_do_discard_coords, 0); } @@ -60,7 +81,7 @@ public class GUIContainerSlider implements GUIComponent, GUIContainer return; } - mousePos = mousePos.add(new Vec2d(0, scroll)); + mousePos = mousePos.add(new Vec2d(0, -scroll)); for(GUIComponent c : components) { c.update(mousePos); @@ -79,7 +100,7 @@ public class GUIContainerSlider implements GUIComponent, GUIContainer return; } - mousePos = mousePos.add(new Vec2d(0, scroll)); + mousePos = mousePos.add(new Vec2d(0, -scroll)); for(GUIComponent c : components) { if(c.checkMouseHover(mousePos)) { @@ -95,7 +116,7 @@ public class GUIContainerSlider implements GUIComponent, GUIContainer return; } - mousePos = mousePos.add(new Vec2d(0, scroll)); + mousePos = mousePos.add(new Vec2d(0, -scroll)); for(GUIComponent c : components) { if(c.checkMouseHover(mousePos)) { @@ -141,5 +162,10 @@ public class GUIContainerSlider implements GUIComponent, GUIContainer c.onScroll(mousePos, amount); } } + + @Override + public void clear() { + components.clear(); + } } diff --git a/src/projectzombie/menu/gui/GUIItemHolder.java b/src/projectzombie/menu/gui/GUIItemHolder.java index e703a76..15e77e6 100644 --- a/src/projectzombie/menu/gui/GUIItemHolder.java +++ b/src/projectzombie/menu/gui/GUIItemHolder.java @@ -1,6 +1,5 @@ package projectzombie.menu.gui; -import gl_engine.MathHelpers; import gl_engine.matrix.Matrix4; import gl_engine.vec.Vec2d; import gl_engine.vec.Vec3d; @@ -8,7 +7,6 @@ import projectzombie.Main; import projectzombie.entity.EntityItem; import projectzombie.model.Model; import projectzombie.text.Text; -import projectzombie.util.gl.GlHelpers; import projectzombie.util.math.ItemStack; import projectzombie.world.layer.Layer; diff --git a/src/projectzombie/menu/gui/GUIItemSlot.java b/src/projectzombie/menu/gui/GUIItemSlot.java index 548f15d..ece97d9 100644 --- a/src/projectzombie/menu/gui/GUIItemSlot.java +++ b/src/projectzombie/menu/gui/GUIItemSlot.java @@ -3,12 +3,10 @@ package projectzombie.menu.gui; import gl_engine.matrix.Matrix4; import gl_engine.vec.Vec2d; import gl_engine.vec.Vec3d; -import projectzombie.Main; import projectzombie.init.Models; import projectzombie.model.Model; import projectzombie.model.ModelItem; import projectzombie.text.Text; -import projectzombie.util.gl.GlHelpers; import projectzombie.util.math.ItemStack; public class GUIItemSlot implements GUIComponent diff --git a/src/projectzombie/menu/gui/GUISavesCard.java b/src/projectzombie/menu/gui/GUISavesCard.java index ce2d75c..80501f3 100644 --- a/src/projectzombie/menu/gui/GUISavesCard.java +++ b/src/projectzombie/menu/gui/GUISavesCard.java @@ -2,8 +2,10 @@ package projectzombie.menu.gui; import gl_engine.matrix.Matrix4; import gl_engine.vec.Vec2d; +import gl_engine.vec.Vec3d; import projectzombie.init.Models; import projectzombie.model.ModelGui; +import projectzombie.text.Text; public class GUISavesCard implements GUIComponent { @@ -12,12 +14,12 @@ public class GUISavesCard implements GUIComponent private Vec2d pos = new Vec2d(0, 0); private GUIButtonModel buttonDelete; private GUIButtonModel buttonPlay; + private String text; - public GUISavesCard(Vec2d pos) + public GUISavesCard(String text, Vec2d pos) { - pos.x -= LABEL.getWidth() / 2; - this.pos = pos; + this.text = text; buttonDelete = new GUIButtonModel(Models.UI_BUTTON_DELETE, Models.UI_BUTTON_DELETE_HOVER, button -> { onDeletePressed(); @@ -27,8 +29,8 @@ public class GUISavesCard implements GUIComponent onPlayPressed(); }); - buttonPlay.setPos(new Vec2d(-LABEL.getWidth()*122/256.0, LABEL.getHeight()*6/32.0)); - buttonDelete.setPos(new Vec2d(LABEL.getWidth()*102/256.0, LABEL.getHeight()*6/32.0)); + buttonPlay.setPos(pos.add(new Vec2d(LABEL.getWidth()*10/256.0, LABEL.getHeight()*6/32.0))); + buttonDelete.setPos(pos.add(new Vec2d(LABEL.getWidth()*226/256.0, LABEL.getHeight()*6/32.0))); } public void onPlayPressed() { @@ -42,9 +44,19 @@ public class GUISavesCard implements GUIComponent @Override public void render(Matrix4 matrix, Vec2d mousePos, boolean canHover) { - LABEL.setModel(Matrix4.multiply(Matrix4.translate(pos.x, pos.y, 0), matrix)); + Matrix4 label_matrix = Matrix4.multiply(Matrix4.translate(pos.x, pos.y, 0), matrix); + + LABEL.setModel(label_matrix); LABEL.render(); + Matrix4 text_matrix = label_matrix; + text_matrix = Matrix4.multiply(text_matrix, Matrix4.translate( + LABEL.getWidth() * 38 / 256.0, + LABEL.getHeight() / 2 - 0.25, 0)); + text_matrix = Matrix4.multiply(Matrix4.scale(new Vec3d(0.5, 0.5, 0.5)), text_matrix); + + Text.render(text, text_matrix); + buttonDelete.render(matrix, mousePos, canHover); buttonPlay.render(matrix, mousePos, canHover); } @@ -57,8 +69,7 @@ public class GUISavesCard implements GUIComponent @Override public boolean checkMouseHover(Vec2d pos) { - return (this.pos.x > pos.x && this.pos.x + LABEL.getWidth() < pos.x && - this.pos.y > pos.y && this.pos.y + LABEL.getHeight() < pos.y); + return true; } @Override diff --git a/src/projectzombie/menu/gui/GUITextBox.java b/src/projectzombie/menu/gui/GUITextBox.java new file mode 100644 index 0000000..4ccd63a --- /dev/null +++ b/src/projectzombie/menu/gui/GUITextBox.java @@ -0,0 +1,243 @@ +package projectzombie.menu.gui; + +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.UnsupportedFlavorException; +import java.io.IOException; + +import org.lwjgl.opengl.GL33; + +import gl_engine.matrix.Matrix4; +import gl_engine.vec.Vec2d; +import gl_engine.vec.Vec3d; +import projectzombie.Main; +import projectzombie.init.Models; +import projectzombie.input.types.InputGUI; +import projectzombie.input.types.InputGUITextBox; +import projectzombie.model.ModelGui; +import projectzombie.text.Text; + +public class GUITextBox implements GUIComponent, InputGUITextBox +{ + private static final ModelGui BOX = Models.UI_TEXT_BOX; + private static final ModelGui CURSOR = Models.UI_TEXT_CURSOR; + + private Vec2d pos; + private String text = ""; + private int cursor_pos = 0; + private boolean in_focus = false; + private double offset = 0; + private int max; + + public GUITextBox(Vec2d pos, int max) { + this.pos = pos; + this.max = max; + } + + public GUITextBox(Vec2d pos, boolean max) { + this(pos, max ? 22 : -1); + } + + public GUITextBox(Vec2d pos) { + this(pos, -1); + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + @Override + public void render(Matrix4 matrix, Vec2d mousePos, boolean canHover) + { + Matrix4 box_matrix = Matrix4.multiply(matrix, Matrix4.translate(pos.x, pos.y, 0)); + + BOX.setModel(box_matrix); + BOX.render(); + + // Set text to black and make sure text gets clipped outside the text box + GL33.glUniform4f(Main.window.glsl_color, 0.1f, 0.1f, 0.1f, 1); + GL33.glUniform4f(Main.window.glsl_discard_coords, + (float)(pos.x + BOX.getWidth() * 2 / 128.0), + (float)(pos.y + BOX.getHeight() * 2 / 16.0), + (float)(pos.x + BOX.getWidth() * 126 / 128.0), + (float)(pos.y + BOX.getHeight() * 14 / 16.0)); + GL33.glUniform1i(Main.window.glsl_do_discard_coords, 1); + + Matrix4 text_matrix = box_matrix; + text_matrix = Matrix4.multiply(text_matrix, Matrix4.translate((1 - offset) * 0.5, 0.5, 0)); + text_matrix = Matrix4.multiply(Matrix4.scale(new Vec3d(0.5, 0.5, 0.5)), text_matrix); + + Text.render(text, text_matrix); + + if(in_focus) { + CURSOR.setModel(Matrix4.multiply(text_matrix, Matrix4.translate(cursor_pos * 0.5, 0, 0))); + CURSOR.render(); + } + + // Reset the settings back to default + GL33.glUniform4f(Main.window.glsl_color, 1, 1, 1, 1); + GL33.glUniform1i(Main.window.glsl_do_discard_coords, 0); + } + + @Override + public void update(Vec2d mousePos) { + } + + @Override + public boolean checkMouseHover(Vec2d mousePos) { + return (mousePos.x > this.pos.x && mousePos.x < this.pos.x + BOX.getWidth() && + mousePos.y > this.pos.y && mousePos.y < this.pos.y + BOX.getHeight()); + } + + @Override + public void onMouseClick(Vec2d mousePos) + { + ((InputGUI)Main.menu.input).getGUI().setTextBox(this); + in_focus = true; + + cursor_pos = (int)((mousePos.x - pos.x + offset * 0.5 - 0.5) * 2 + 0.5); + + if(cursor_pos > text.length()) { + cursor_pos = text.length(); + } + } + + private void updateText() + { + // Update the text fields offset to + // keep the cursor in the text field + double o = BOX.getWidth() - 1; + + if(cursor_pos - o < offset) { + offset = cursor_pos - o; + } + + if(cursor_pos - o * 2 > offset) { + offset = cursor_pos - o * 2; + } + + if(offset < 0) { + offset = 0; + } + } + + @Override + public void onPaste() + { + try + { + String clipboard = (String)(Main.clipboard.getData(DataFlavor.stringFlavor)); + + if(max == -1 || text.length() + clipboard.length() <= max) + { + text = text.substring(0, cursor_pos) + clipboard + text.substring(cursor_pos, text.length()); + cursor_pos += clipboard.length(); + + updateText(); + } + + else if(text.length() < max) + { + clipboard = clipboard.substring(0, max - text.length()); + + text = text.substring(0, cursor_pos) + clipboard + text.substring(cursor_pos, text.length()); + cursor_pos += clipboard.length(); + + updateText(); + } + } + + catch (UnsupportedFlavorException | IOException e) { + e.printStackTrace(); + } + } + + @Override + public void onBackspace() + { + if(cursor_pos == 0) { + return; + } + + text = text.substring(0, cursor_pos - 1) + text.substring(cursor_pos, text.length()); + cursor_pos -= 1; + + updateText(); + } + + @Override + public void onDelete() + { + if(cursor_pos == text.length()) { + return; + } + + text = text.substring(0, cursor_pos) + text.substring(cursor_pos + 1, text.length()); + + updateText(); + } + + @Override + public void onMoveCursor(int direction) + { + cursor_pos += direction; + + if(cursor_pos < 0) { + cursor_pos = 0; + } + + if(cursor_pos > text.length()) { + cursor_pos = text.length(); + } + + updateText(); + } + + @Override + public void onHome() { + cursor_pos = 0; + updateText(); + } + + @Override + public void onEnd() { + cursor_pos = text.length(); + updateText(); + } + + @Override + public void onPressed(char character) + { + if(max == -1 || text.length() < max) + { + text = text.substring(0, cursor_pos) + character + text.substring(cursor_pos, text.length()); + cursor_pos += 1; + + updateText(); + } + } + + @Override + public void setFocus(boolean focus) { + in_focus = focus; + } + + @Override + public void onScroll(Vec2d mousePos, double amount) { + } + + @Override + public void onRightClick(Vec2d mousePos) { + } + + @Override + public void onActivate() { + } + + @Override + public void onBack() { + } +} diff --git a/src/projectzombie/model/Model.java b/src/projectzombie/model/Model.java index db68cf7..331f30f 100644 --- a/src/projectzombie/model/Model.java +++ b/src/projectzombie/model/Model.java @@ -19,14 +19,13 @@ import gl_engine.MathHelpers; import gl_engine.matrix.Matrix4; import gl_engine.texture.TextureRef3D; import projectzombie.Main; -import projectzombie.init.Models; import projectzombie.init.Resources; public abstract class Model implements IModel { private static final Random rand = new Random(); - public static final float OFFSET = 0.001f; + public static final float OFFSET = 0.00001f; public static final int SIZE = 16; public static IModel bound = null; diff --git a/src/projectzombie/model/ModelGrass.java b/src/projectzombie/model/ModelGrass.java index bd9bdcb..e6c8642 100644 --- a/src/projectzombie/model/ModelGrass.java +++ b/src/projectzombie/model/ModelGrass.java @@ -1,6 +1,5 @@ package projectzombie.model; -import gl_engine.texture.TextureRef3D; import projectzombie.init.Resources; public class ModelGrass extends ModelTile diff --git a/src/projectzombie/model/ModelRock.java b/src/projectzombie/model/ModelRock.java index ca93b46..b94bb6d 100644 --- a/src/projectzombie/model/ModelRock.java +++ b/src/projectzombie/model/ModelRock.java @@ -1,7 +1,6 @@ package projectzombie.model; import gl_engine.texture.TextureRef3D; -import gl_engine.vec.Vec2d; public class ModelRock extends Model { diff --git a/src/projectzombie/model/ModelTallGrass.java b/src/projectzombie/model/ModelTallGrass.java index ba2a44f..3f1591d 100644 --- a/src/projectzombie/model/ModelTallGrass.java +++ b/src/projectzombie/model/ModelTallGrass.java @@ -1,6 +1,5 @@ package projectzombie.model; -import gl_engine.texture.TextureRef3D; import projectzombie.init.Resources; public class ModelTallGrass extends ModelCross diff --git a/src/projectzombie/settings/Settings.java b/src/projectzombie/settings/Settings.java index bcc74ee..4161bcf 100755 --- a/src/projectzombie/settings/Settings.java +++ b/src/projectzombie/settings/Settings.java @@ -1,21 +1,18 @@ package projectzombie.settings; -import bdf.classes.BdfClassManager; import bdf.classes.IBdfClassManager; import bdf.file.BdfFileManager; import bdf.types.BdfNamedList; import bdf.types.BdfObject; import bdf.types.BdfTypes; -import projectzombie.Main; import projectzombie.display.DisplayRender; import projectzombie.display.DisplayRenderUI; import projectzombie.display.DisplayWindow; -import projectzombie.entity.EntityParticle; import projectzombie.world.chunk.Chunk; public class Settings implements IBdfClassManager { - public static final BdfClassManager SETTINGS = new BdfClassManager(new Settings()); + public static final Settings SETTINGS = new Settings(); private static BdfFileManager FILE_MANAGER; @Override @@ -114,21 +111,21 @@ public class Settings implements IBdfClassManager } BdfNamedList nl = bdf.getNamedList(); - nl.set("render_distance", BdfObject.withInteger(Chunk.RENDER_DISTANCE)); - nl.set("show_fps", BdfObject.withBoolean(DisplayRenderUI.showFPS)); - nl.set("debug", BdfObject.withBoolean(DisplayRenderUI.debug)); - nl.set("shadow_size", BdfObject.withInteger(shadow_size)); - nl.set("fullscreen", BdfObject.withBoolean(DisplayWindow.fullscreen)); - nl.set("vsync", BdfObject.withBoolean(DisplayWindow.vsync)); + nl.set("render_distance", bdf.newObject().setInteger(Chunk.RENDER_DISTANCE)); + nl.set("show_fps", bdf.newObject().setBoolean(DisplayRenderUI.showFPS)); + nl.set("debug", bdf.newObject().setBoolean(DisplayRenderUI.debug)); + nl.set("shadow_size", bdf.newObject().setInteger(shadow_size)); + nl.set("fullscreen", bdf.newObject().setBoolean(DisplayWindow.fullscreen)); + nl.set("vsync", bdf.newObject().setBoolean(DisplayWindow.vsync)); } public static void init() { FILE_MANAGER = new BdfFileManager(Environment.gdir + "/settings.bdf", true); - SETTINGS.load(FILE_MANAGER); + SETTINGS.BdfClassLoad(FILE_MANAGER.getObject()); } public static void update() { - SETTINGS.save(FILE_MANAGER); + SETTINGS.BdfClassSave(FILE_MANAGER.getObject()); FILE_MANAGER.saveDatabase(); } diff --git a/src/projectzombie/task/Task.java b/src/projectzombie/task/Task.java index c173d57..c8fe267 100644 --- a/src/projectzombie/task/Task.java +++ b/src/projectzombie/task/Task.java @@ -2,14 +2,12 @@ package projectzombie.task; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; import bdf.classes.IBdfClassManager; import bdf.types.BdfArray; import bdf.types.BdfNamedList; import bdf.types.BdfObject; import projectzombie.entity.Entity; -import projectzombie.init.Entities; import projectzombie.init.Tasks; public abstract class Task implements IBdfClassManager @@ -50,7 +48,7 @@ public abstract class Task implements IBdfClassManager // Send back null if the id is out of range if(id < 0 || id >= Tasks.TASKS.size()) { - System.out.println("Warning: Invalid ID detected: " + id); + System.out.println("Invalid task ID found: " + id); return null; } @@ -85,7 +83,7 @@ public abstract class Task implements IBdfClassManager @Override public void BdfClassSave(BdfObject bdf) { BdfNamedList nl = bdf.getNamedList(); - nl.set("id", BdfObject.withInteger(getID())); + nl.set("id", bdf.newObject().setInteger(getID())); } public static Task[] loadTasks(Entity parent, BdfObject bdf) @@ -100,16 +98,17 @@ public abstract class Task implements IBdfClassManager return tasks; } - public static BdfObject saveTasks(Task[] tasks) + public static BdfObject saveTasks(BdfObject bdf, Task[] tasks) { - BdfArray array = new BdfArray(); + BdfArray array = bdf.getArray(); + bdf.setArray(array); for(int i=0;i'): l = CHAR_G_THAN; break; case('<'): l = CHAR_L_THAN; break; + case('`'): l = CHAR_GRAVE; break; + case('~'): l = CHAR_TILDE; break; + case('\''): l = CHAR_APOSTROPHE; break; + case('"'): l = CHAR_QUOTATION; break; + case(';'): l = CHAR_SEMICOLON; break; + case('@'): l = CHAR_AT; break; + case('&'): l = CHAR_AND; break; + case('*'): l = CHAR_STAR; break; + case('^'): l = CHAR_POW; break; + case('['): l = CHAR_BRACKET_OS; break; + case(']'): l = CHAR_BRACKET_CS; break; + case('{'): l = CHAR_BRACKET_OC; break; + case('}'): l = CHAR_BRACKET_CC; break; } if(l != null) diff --git a/src/projectzombie/tiles/TileGrass.java b/src/projectzombie/tiles/TileGrass.java index 2ddbc6b..95aae73 100755 --- a/src/projectzombie/tiles/TileGrass.java +++ b/src/projectzombie/tiles/TileGrass.java @@ -1,6 +1,5 @@ package projectzombie.tiles; -import gl_engine.vec.Vec2d; import gl_engine.vec.Vec2i; import projectzombie.init.Models; import projectzombie.init.Tiles; diff --git a/src/projectzombie/tiles/TileLadderUp.java b/src/projectzombie/tiles/TileLadderUp.java index 21890f6..44e7f24 100755 --- a/src/projectzombie/tiles/TileLadderUp.java +++ b/src/projectzombie/tiles/TileLadderUp.java @@ -1,16 +1,13 @@ package projectzombie.tiles; import gl_engine.vec.Vec2i; -import mainloop.task.IMainloopTask; import projectzombie.Main; import projectzombie.entity.Entity; import projectzombie.entity.player.EntityPlayer; import projectzombie.init.Models; -import projectzombie.mainloop.MainloopEventHandler; import projectzombie.model.Model; import projectzombie.task.TaskLadderUp; import projectzombie.util.math.TileState; -import projectzombie.world.chunk.ChunkEventHandler; import projectzombie.world.layer.Layer; public class TileLadderUp extends Tile diff --git a/src/projectzombie/tiles/TilePortalDown.java b/src/projectzombie/tiles/TilePortalDown.java index 527bbed..4cb6115 100755 --- a/src/projectzombie/tiles/TilePortalDown.java +++ b/src/projectzombie/tiles/TilePortalDown.java @@ -1,16 +1,13 @@ package projectzombie.tiles; import gl_engine.vec.Vec2i; -import mainloop.task.IMainloopTask; import projectzombie.Main; import projectzombie.entity.Entity; import projectzombie.entity.player.EntityPlayer; import projectzombie.init.Models; -import projectzombie.mainloop.MainloopEventHandler; import projectzombie.model.Model; import projectzombie.task.TaskLadderDown; import projectzombie.util.math.TileState; -import projectzombie.world.chunk.ChunkEventHandler; import projectzombie.world.layer.Layer; public class TilePortalDown extends Tile diff --git a/src/projectzombie/tiles/TileRock.java b/src/projectzombie/tiles/TileRock.java index 12e6561..31a892d 100755 --- a/src/projectzombie/tiles/TileRock.java +++ b/src/projectzombie/tiles/TileRock.java @@ -1,16 +1,11 @@ package projectzombie.tiles; -import gl_engine.vec.Vec2i; -import gl_engine.vec.Vec3d; -import projectzombie.entity.Entity; -import projectzombie.entity.EntityItem; import projectzombie.init.Items; import projectzombie.init.Models; import projectzombie.items.ItemTool; import projectzombie.model.Model; import projectzombie.util.math.ItemStack; import projectzombie.util.math.TileState; -import projectzombie.world.layer.Layer; public class TileRock extends Tile implements TileBulletBreakable { diff --git a/src/projectzombie/tiles/TileTree.java b/src/projectzombie/tiles/TileTree.java index a85bc75..a9dffbc 100755 --- a/src/projectzombie/tiles/TileTree.java +++ b/src/projectzombie/tiles/TileTree.java @@ -1,14 +1,11 @@ package projectzombie.tiles; -import gl_engine.vec.Vec2i; -import projectzombie.entity.Entity; import projectzombie.init.Items; import projectzombie.init.Models; import projectzombie.items.ItemTool; import projectzombie.model.Model; import projectzombie.util.math.ItemStack; import projectzombie.util.math.TileState; -import projectzombie.world.layer.Layer; public class TileTree extends Tile implements TileBulletBreakable { diff --git a/src/projectzombie/tiles/TileWater.java b/src/projectzombie/tiles/TileWater.java index b3845eb..a2dd176 100755 --- a/src/projectzombie/tiles/TileWater.java +++ b/src/projectzombie/tiles/TileWater.java @@ -1,7 +1,6 @@ package projectzombie.tiles; import gl_engine.vec.Vec2i; -import gl_engine.vec.Vec3d; import projectzombie.entity.Entity; import projectzombie.entity.particle.ParticleWater; import projectzombie.entity.player.EntityPlayer; diff --git a/src/projectzombie/util/math/ItemStack.java b/src/projectzombie/util/math/ItemStack.java index f8667b2..b4366c3 100755 --- a/src/projectzombie/util/math/ItemStack.java +++ b/src/projectzombie/util/math/ItemStack.java @@ -46,9 +46,9 @@ public class ItemStack implements IBdfClassManager @Override public void BdfClassSave(BdfObject bdf) { BdfNamedList nl = bdf.getNamedList(); - nl.set("meta", BdfObject.withShort(meta)); - nl.set("count", BdfObject.withInteger(count)); - nl.set("item", BdfObject.withInteger(item.id)); + nl.set("meta", bdf.newObject().setShort(meta)); + nl.set("count", bdf.newObject().setInteger(count)); + nl.set("item", bdf.newObject().setInteger(item.id)); } public ItemStack(BdfObject bdf) { diff --git a/src/projectzombie/worker/Worker.java b/src/projectzombie/worker/Worker.java index e7ce624..28d65c6 100644 --- a/src/projectzombie/worker/Worker.java +++ b/src/projectzombie/worker/Worker.java @@ -6,9 +6,10 @@ import java.io.OutputStream; import java.lang.ProcessBuilder.Redirect; import java.nio.ByteBuffer; -import bdf.data.BdfDatabase; +import bdf.data.IBdfDatabase; import bdf.types.BdfNamedList; import bdf.types.BdfObject; +import bdf.types.BdfReader; import projectzombie.display.DisplayLighting; public class Worker extends Thread @@ -24,9 +25,9 @@ public class Worker extends Thread public Worker() throws IOException { pb = new ProcessBuilder("java", "-jar", "worker.jar"); - pb.redirectError(Redirect.INHERIT); pb.redirectOutput(Redirect.PIPE); pb.redirectInput(Redirect.PIPE); + pb.redirectError(Redirect.INHERIT); process = pb.start(); @@ -38,39 +39,41 @@ public class Worker extends Thread public void processLighting(float[] lights, int width, int height, int x, int y) { - BdfObject bdf = new BdfObject(); + BdfReader reader = new BdfReader(); + BdfObject bdf = reader.getObject(); BdfNamedList nl = bdf.getNamedList(); - nl.set("task", BdfObject.withString("light")); - nl.set("light", BdfObject.withFloatArray(lights)); - nl.set("w", BdfObject.withInteger(width)); - nl.set("h", BdfObject.withInteger(height)); - nl.set("x", BdfObject.withInteger(x)); - nl.set("y", BdfObject.withInteger(y)); + nl.set("task", bdf.newObject().setString("light")); + nl.set("light", bdf.newObject().setFloatArray(lights)); + nl.set("w", bdf.newObject().setInteger(width)); + nl.set("h", bdf.newObject().setInteger(height)); + nl.set("x", bdf.newObject().setInteger(x)); + nl.set("y", bdf.newObject().setInteger(y)); - sendData(bdf); + sendData(reader); } public void updateTime() { - BdfObject bdf = new BdfObject(); + BdfReader reader = new BdfReader(); + BdfObject bdf = reader.getObject(); BdfNamedList nl = bdf.getNamedList(); - nl.set("task", BdfObject.withString("time")); - nl.set("millis", BdfObject.withLong(System.currentTimeMillis())); + nl.set("task", bdf.newObject().setString("time")); + nl.set("millis", bdf.newObject().setLong(System.currentTimeMillis())); - sendData(bdf); + sendData(reader); } - private void sendData(BdfObject bdf) + private void sendData(BdfReader reader) { - byte[] data = bdf.serialize().getBytes(); + IBdfDatabase data = reader.serialize(); ByteBuffer size_buff = ByteBuffer.allocate(4); - size_buff.putInt(0, data.length); + size_buff.putInt(0, data.size()); try { out.write(size_buff.array()); - out.write(data); + data.writeToStream(out); out.write('\n'); out.flush(); } @@ -97,7 +100,8 @@ public class Worker extends Thread in.read(data); in.read(new byte[1]); - BdfObject bdf = new BdfObject(new BdfDatabase(data)); + BdfReader reader = new BdfReader(data); + BdfObject bdf = reader.getObject(); BdfNamedList nl = bdf.getNamedList(); switch(nl.get("task").getString()) diff --git a/src/projectzombie/world/World.java b/src/projectzombie/world/World.java index 787c7e8..f5f01fa 100755 --- a/src/projectzombie/world/World.java +++ b/src/projectzombie/world/World.java @@ -1,13 +1,15 @@ package projectzombie.world; +import java.io.File; import java.nio.ByteBuffer; -import java.nio.FloatBuffer; import java.util.ArrayList; +import java.util.Random; import org.lwjgl.BufferUtils; import org.lwjgl.opengl.GL33; import bdf.classes.IBdfClassManager; +import bdf.file.BdfFileManager; import bdf.types.BdfArray; import bdf.types.BdfNamedList; import bdf.types.BdfObject; @@ -16,7 +18,10 @@ import gl_engine.vec.Vec3d; import projectzombie.Main; import projectzombie.display.Camera; import projectzombie.display.DisplayLighting; +import projectzombie.display.bossbar.BossBars; import projectzombie.entity.player.EntityPlayer; +import projectzombie.init.LayerGenerators; +import projectzombie.init.Layers; import projectzombie.model.Model; import projectzombie.time.GameTimer; import projectzombie.world.chunk.ChunkEventHandler; @@ -28,6 +33,7 @@ public class World implements IBdfClassManager private Layer loaded; private ArrayList layers = new ArrayList(); + private BdfFileManager file_manager; private String path; private int pool_vao, pool_vbo, pool_ibo; @@ -37,6 +43,48 @@ public class World implements IBdfClassManager public World(String path) { this.path = path; + + if(path != null) + { + path = "./saves/" + path + ".bdf"; + File save_file = new File(path); + File save_dir = save_file.getParentFile(); + + if(!save_dir.exists()) { + save_dir.mkdirs(); + } + + if(save_file.exists()) { + file_manager = new BdfFileManager(path); + BdfClassLoad(file_manager.getObject()); + } + + else { + file_manager = new BdfFileManager(path); + } + } + } + + public static void createWorld(String path, long seed) + { + // Create all the layers + Layers.EARTH = new Layer(new Random(seed), LayerGenerators.EARTH); + Layers.CAVES = new Layer(new Random(seed), LayerGenerators.CAVES); + Layers.LAVA_CAVES = new Layer(new Random(seed), LayerGenerators.LAVA_CAVES); + + // Create the world and set the earth as the default layer + Main.world = new World(path); + Main.world.addLayer(Layers.EARTH); + Main.world.addLayer(Layers.CAVES); + Main.world.addLayer(Layers.LAVA_CAVES); + Main.world.setLayer(0); + + // Initialize some other objects + Main.player = new EntityPlayer(); + GameTimer.resetTime(); + BossBars.clear(); + + Main.world.save(); } public String getSavePath() { @@ -181,6 +229,24 @@ public class World implements IBdfClassManager public Layer getLayer() { return loaded; } + + public void save() + { + if(file_manager != null) + { + BdfObject bdf = file_manager.resetObject(); + BdfClassSave(bdf); + + file_manager.saveDatabase(); + } + } + + public void free() + { + for(Layer layer : layers) { + layer.free(); + } + } @Override public void BdfClassLoad(BdfObject bdf) @@ -219,32 +285,25 @@ public class World implements IBdfClassManager } // Save layer data - BdfArray layers_bdf = new BdfArray(); - nl.set("loaded", BdfObject.withInteger(loaded_id)); - nl.set("layers", BdfObject.withArray(layers_bdf)); + BdfArray layers_bdf = bdf.newArray(); + nl.set("loaded", bdf.newObject().setInteger(loaded_id)); + nl.set("layers", bdf.newObject().setArray(layers_bdf)); for(Layer l : layers) { - BdfObject o = new BdfObject(); + BdfObject o = bdf.newObject(); l.BdfClassSave(o); layers_bdf.add(o); } // Save player data - BdfArray players = new BdfArray(); - nl.set("players", BdfObject.withArray(players)); + BdfArray players = bdf.newArray(); + nl.set("players", bdf.newObject().setArray(players)); - BdfObject player = new BdfObject(); + BdfObject player = bdf.newObject(); Main.player.BdfClassSave(player); players.add(player); // Save the game timer - nl.set("time", BdfObject.withLong(GameTimer.getTime())); - } - - public void free() - { - for(Layer layer : layers) { - layer.free(); - } + nl.set("time", bdf.newObject().setLong(GameTimer.getTime())); } } diff --git a/src/projectzombie/world/chunk/Chunk.java b/src/projectzombie/world/chunk/Chunk.java index 0ece4c1..1532004 100755 --- a/src/projectzombie/world/chunk/Chunk.java +++ b/src/projectzombie/world/chunk/Chunk.java @@ -49,8 +49,7 @@ public class Chunk implements IBdfClassManager private Tile tiles_front[] = new Tile[CHUNK_INDEX]; private byte tiles_front_meta[] = new byte[CHUNK_INDEX]; private byte tiles_back_meta[] = new byte[CHUNK_INDEX]; - private byte tiles_lighting_src[] = new byte[CHUNK_INDEX]; - private byte tiles_lighting_day[] = new byte[CHUNK_INDEX]; + private byte tiles_lighting[] = new byte[CHUNK_INDEX]; public ArrayList entities = new ArrayList(); private Layer layer; public Vec2i c_pos; @@ -93,10 +92,10 @@ public class Chunk implements IBdfClassManager BdfNamedList nl = bdf.getNamedList(); // Load all the tiles and meta - short[] tb = nl.get("tb").getShortArray(); - short[] tf = nl.get("tf").getShortArray(); - byte[] mb = nl.get("mb").getByteArray(); - byte[] mf = nl.get("mf").getByteArray(); + short[] tb = nl.get("tilesBack").getShortArray(); + short[] tf = nl.get("tilesFront").getShortArray(); + byte[] mb = nl.get("metaBack").getByteArray(); + byte[] mf = nl.get("metaFront").getByteArray(); for(int i=0;i chunk : dirty_chunks) { - BdfNamedList chunk_nl = new BdfNamedList(); + BdfNamedList chunk_nl = bdf.newNamedList(); chunk.pos.BdfClassSave(chunk_nl.get("pos")); chunk.o.BdfClassSave(chunk_nl.get("chunk")); - bdf_chunks.add(BdfObject.withNamedList(chunk_nl)); + bdf_chunks.add(bdf.newObject().setNamedList(chunk_nl)); } for(Map2DElement chunk : chunks) { @@ -330,10 +313,10 @@ public class Layer implements IBdfClassManager if(!chunk.o.isDirty()) continue; - BdfNamedList chunk_nl = new BdfNamedList(); + BdfNamedList chunk_nl = bdf.newNamedList(); chunk.pos.BdfClassSave(chunk_nl.get("pos")); chunk.o.BdfClassSave(chunk_nl.get("chunk")); - bdf_chunks.add(BdfObject.withNamedList(chunk_nl)); + bdf_chunks.add(bdf.newObject().setNamedList(chunk_nl)); } } diff --git a/src/projectzombie/world/layer/layergen/LayerGenBossArena.java b/src/projectzombie/world/layer/layergen/LayerGenBossArena.java index 7da37f0..2beec19 100755 --- a/src/projectzombie/world/layer/layergen/LayerGenBossArena.java +++ b/src/projectzombie/world/layer/layergen/LayerGenBossArena.java @@ -2,7 +2,6 @@ package projectzombie.world.layer.layergen; import java.util.Random; -import gl_engine.MathHelpers; import gl_engine.vec.Vec2d; import gl_engine.vec.Vec2i; import gl_engine.vec.Vec3d; @@ -19,7 +18,6 @@ import projectzombie.world.layer.Layer; public class LayerGenBossArena extends LayerGen implements LayerGenRememberPlayerPos { - private final Vec2i center = new Vec2i(0, 0); private final int size = 10; private Vec3d player_pos = new Vec3d(0, 0, 0); private Random rand = new Random(); diff --git a/src/projectzombie/world/layer/layergen/LayerGenCaves.java b/src/projectzombie/world/layer/layergen/LayerGenCaves.java index 5165308..b749816 100755 --- a/src/projectzombie/world/layer/layergen/LayerGenCaves.java +++ b/src/projectzombie/world/layer/layergen/LayerGenCaves.java @@ -15,7 +15,6 @@ import projectzombie.util.math.ColorRange; import projectzombie.util.math.TileState; import projectzombie.util.math.random.NoiseGenerator; import projectzombie.util.math.random.NoiseGeneratorSimplex; -import projectzombie.util.math.random.OpenSimplexNoise; import projectzombie.util.math.random.RandomHelpers; import projectzombie.world.World; import projectzombie.world.chunk.Chunk; diff --git a/src/projectzombie/world/layer/layergen/LayerGenEarth.java b/src/projectzombie/world/layer/layergen/LayerGenEarth.java index 9fff91f..6e810c7 100755 --- a/src/projectzombie/world/layer/layergen/LayerGenEarth.java +++ b/src/projectzombie/world/layer/layergen/LayerGenEarth.java @@ -10,7 +10,6 @@ import projectzombie.Main; import projectzombie.entity.Entity; import projectzombie.entity.EntityZombie; import projectzombie.init.Tiles; -import projectzombie.tiles.Tile; import projectzombie.time.GameTimer; import projectzombie.util.math.ColorRange; import projectzombie.util.math.TileState; diff --git a/src/projectzombie/world/layer/layergen/LayerGenLavaCaves.java b/src/projectzombie/world/layer/layergen/LayerGenLavaCaves.java index 5e3374b..b326de5 100755 --- a/src/projectzombie/world/layer/layergen/LayerGenLavaCaves.java +++ b/src/projectzombie/world/layer/layergen/LayerGenLavaCaves.java @@ -14,7 +14,6 @@ import projectzombie.util.math.ColorRange; import projectzombie.util.math.TileState; import projectzombie.util.math.random.NoiseGenerator; import projectzombie.util.math.random.NoiseGeneratorSimplex; -import projectzombie.util.math.random.OpenSimplexNoise; import projectzombie.util.math.random.RandomHelpers; import projectzombie.world.chunk.Chunk; import projectzombie.world.layer.Layer; diff --git a/src/resources/shader/environmentRenderer.fsh b/src/resources/shader/environmentRenderer.fsh index e9a3799..994933d 100644 --- a/src/resources/shader/environmentRenderer.fsh +++ b/src/resources/shader/environmentRenderer.fsh @@ -35,7 +35,7 @@ vec3 color_grass_hot_dry = vec3(1, 0.6, 0); vec3 color_grass_cold_wet = vec3(0.075, 0.533, 0.047); vec3 color_grass_cold_dry = vec3(0.812, 0.761, 0); -float depth_c = 0.001; +float depth_c = 0.0001; float map(float x, float in_min, float in_max, float out_min, float out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; @@ -81,11 +81,11 @@ void main() vec3 light_day = pSunDepth.z < (texture(depthmap, sunDepthTexPos).r * 2 - 1 + depth_c ) ? lighting_day_high : lighting_day_low; - vec3 light_src = vec3(1, 1, 1) * (scaleLight(max(0, light.g)) - abs(pLightMapPos.y) * 0.1); + vec3 light_src = vec3(1, 1, 1) * (scaleLight(max(0, light.r)) - abs(pLightMapPos.y) * 0.1); vec4 rgb = vec4((pRGB % 64) / 64.0, ((pRGB >> 6) % 64) / 64.0, ((pRGB >> 12) % 64) / 64.0, 1); vec4 color_grass = vec4(interpolate2RGB( - smoothStep(light.b), smoothStep(light.a), + smoothStep(light.g), smoothStep(light.b), color_grass_cold_dry, color_grass_hot_dry, color_grass_cold_wet, color_grass_hot_wet), 1); diff --git a/src/resources/texture/gui/selection_box.png b/src/resources/texture/gui/selection_box.png deleted file mode 100644 index 596591b6ff33cd44b2184da3ac33e5cee9d62d57..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1205 zcmeAS@N?(olHy`uVBq!ia0y~yU}OMc4mJh`hM1xiX$%aEEt$^F0iMpz3I#>^X_+~x z3=A3*YbV-z9Cna78h_a_So`NirhHAzI={ovLI z4~{2YJ$N)SoITu8;15G#QAtqAM4|uFMWT*W6x``A|1MYlo?&5J+A2v2_K>qiK_6$# zIJvItU^t6m1H-Nh>W0Ddz14(2$i#pD@bRnOsm*)N|Fx`|GUp`2d=Hz`C5M&nDa^aK zrR3c2BZ*;CL>?7CGHllK_;aH4=2P=?tnIAxB+V|ZtbAm!F(M;*XK&=ifX?L|%3Z4h z_f05_e7NUmq;7cR=Xrlx7tYzX=}hUY!yUy{IO7k2Z;#B4XISZ_Y^E3DtRjyN*#mT_Hz?S6g?!vH+fq{X+ zEM!&(0|NtRfk$L91B0G22s2hJwJ&2}U|=ut^mS!_!Y1w#U}E54P+*`IgL)>xT{LPWc_Hv2oMF`|p$jLz|14D9`Mk!5 eY44ouUhy3_#O9v6$Fl;I+C5$UT-G@yGywp|_c!JM diff --git a/src/resources/texture/gui/selection_box_big.png b/src/resources/texture/gui/selection_box_big.png new file mode 100644 index 0000000000000000000000000000000000000000..b88768feb60a5955fc05b5e09c39512eb22bebd2 GIT binary patch literal 2429 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 RF&R`}d%F6$taD0e0s!K{E_DC^ literal 0 HcmV?d00001 diff --git a/src/resources/texture/gui/text_box.png b/src/resources/texture/gui/text_box.png new file mode 100644 index 0000000000000000000000000000000000000000..11d8b309cae812ec4726513517b5b79271cf1d93 GIT binary patch literal 4650 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 S#})<#1_n=8KbLh*2~7awuNa#E literal 0 HcmV?d00001 diff --git a/src/resources/texture/gui/text_cursor.png b/src/resources/texture/gui/text_cursor.png new file mode 100644 index 0000000000000000000000000000000000000000..0546dcb479dca50f38bf8821d7629c3095fd3b21 GIT binary patch literal 576 zcmeAS@N?(olHy`uVBq!ia0y~yU=UznU{K&-V_;yA?)-6vfq}6l)7d$|)7e>}peR2r zGbfdSL1SX=L|c!;4l+mMFMGLa@s&+@B(T9MQb4ruik8Sirxl`6r3O2{aL3jRZ9)FqC)JRo3bve_QO-K4;!fomv#}q|Am>Fn1d!}-qQ1?>4Fsm6;eS0e=S***l zddh9tA9^l&&ep8nt?y38OK840?H#k+vO`2{0|%#)$dv#`Q8S?}ua-odxKMZLxP0+n zp`9W{p$ASF_VZ>;h_(MA|L5H`Ex(>>&xtA*zCN;$KkQH;o^eg~`R^Nrv(z0vNbb0F z`(H1c!C%j+y=#y5H|)!O@Mzas&FTYB`3yd!oLKh8%W;;|Mvgu6FPcAX{1?3-{p#zr zTl+7wD|p8)&2MOSPFUh{Gu!U{yLWHi-Zx(RuZ|&JxoCd)p1TPQ3=C{Z-tI08{~2B~ zFiaJheusg9fwRCPvY3H^TNs2H8D`CqU|?WiFY)wsWq-mh#ja+)Y2}JS1_lOOPZ!4! zkK@UI{{R19&&H9EQgQTzgH}S)0)c>=3>*JD-{W4)#>36rmXel~n2=D=QYdlMeR1KH ghCpVw4U7!EGVIMSl(@4Q7#J8lUHx3vIVCg!0Qo}iDgXcg literal 0 HcmV?d00001 diff --git a/src/resources/texture/list.txt b/src/resources/texture/list.txt index 9783435..e790977 100644 --- a/src/resources/texture/list.txt +++ b/src/resources/texture/list.txt @@ -1,216 +1,232 @@ -./tile/hemp6.png -./tile/hemp7.png -./tile/hemp1.png -./tile/rock.png -./tile/rock_ice.png -./tile/sapling3.png -./tile/ladder.png -./tile/tree_leaves_snow.png -./tile/ice_wall.png -./tile/water.png -./tile/sandstone_wall.png -./tile/ladder_up.png -./tile/cactus4.png -./tile/tall_grass.png -./tile/cactus2.png -./tile/grass_infested.png -./tile/tree_branch_leaves.png -./tile/dirt.png -./tile/wall.png -./tile/tree_base.png -./tile/cactus1.png -./tile/sapling4.png -./tile/hemp3.png -./tile/cactus_top.png -./tile/tunnel_down.png -./tile/stone.png -./tile/snow.png -./tile/boss_portal.png -./tile/hemp4.png -./tile/sand.png -./tile/lantern.png -./tile/ice.png -./tile/sapling1.png -./tile/chest.png -./tile/hemp2.png -./tile/hemp8.png -./tile/cactus3.png -./tile/lava.png -./tile/tree_leaves.png -./tile/hemp5.png -./tile/lava_flow.png -./tile/grass.png -./tile/tree_branch.png -./tile/sandstone.png -./tile/tree_branch_leaves_snow.png -./tile/rock_sandstone.png -./tile/sapling2.png +./text/char_question.png +./text/char_l_a.png +./text/char_u_j.png +./text/char_l_u.png +./text/char_u_s.png +./text/char_l_s.png +./text/char_apostrophe.png +./text/char_plus.png +./text/char_l_e.png +./text/char_7.png +./text/char_minus.png +./text/char_u_r.png +./text/char_u_l.png +./text/char_obracket.png +./text/char_pow.png +./text/char_u_m.png +./text/char_l_t.png +./text/char_percent.png +./text/char_l_y.png +./text/char_0.png +./text/char_4.png +./text/char_l_r.png +./text/char_l_m.png +./text/char_cbracket.png +./text/char_u_g.png +./text/char_u_q.png +./text/char_u_i.png +./text/char_tilde.png +./text/char_l_w.png +./text/char_l_v.png +./text/char_fslash.png +./text/char_u_p.png +./text/char_gthan.png +./text/char_8.png +./text/char_unknown.png +./text/char_and.png +./text/char_osbracket.png +./text/char_u_n.png +./text/char_l_i.png +./text/char_u_y.png +./text/char_l_p.png +./text/char_lthan.png +./text/char_l_g.png +./text/char_bslash.png +./text/char_1.png +./text/char_u_z.png +./text/char_l_f.png +./text/char_u_w.png +./text/char_9.png +./text/char_l_x.png +./text/char_ccbracket.png +./text/char_l_o.png +./text/char_equals.png +./text/char_l_d.png +./text/char_dollar.png +./text/char_hashtag.png +./text/char_l_q.png +./text/char_u_o.png +./text/char_6.png +./text/char_u_d.png +./text/char_u_e.png +./text/char_exclamation.png +./text/char_vertical.png +./text/char_ocbracket.png +./text/char_u_k.png +./text/char_u_c.png +./text/char_l_n.png +./text/char_semicolon.png +./text/char_u_b.png +./text/char_u_f.png +./text/char_l_h.png +./text/char_l_k.png +./text/char_u_t.png +./text/char_3.png +./text/char_u_v.png +./text/char_u_h.png +./text/char_quotation.png +./text/char_u_a.png +./text/char_l_b.png +./text/char_underscore.png +./text/char_u_x.png +./text/char_comma.png +./text/char_csbracket.png +./text/char_l_l.png +./text/char_5.png +./text/char_star.png +./text/char_colon.png +./text/char_l_z.png +./text/char_space.png +./text/char_2.png +./text/char_at.png +./text/char_grave.png +./text/char_l_j.png +./text/char_fullstop.png +./text/char_l_c.png +./text/char_u_u.png ./list.txt -./item/log.png -./item/rock.png -./item/acorn.png -./item/ammo_box.png -./item/plant_fibre.png -./item/hemp_seed.png -./item/shield_upgrade.png -./item/grappling_hook.png -./item/log_snow.png -./item/health_potion.png -./item/snow_pile.png -./item/gun_upgrade.png -./item/sandstone.png -./item/flint.png +./player/player_white_front_moving.png +./player/player_white_back_moving.png +./player/player_black_back_moving.png +./player/player_black_back_still.png ./player/player_white_back_still.png ./player/player_white_front_still.png ./player/player_black_front_moving.png ./player/player_black_front_still.png -./player/player_black_back_moving.png -./player/player_black_back_still.png -./player/player_white_back_moving.png -./player/player_white_front_moving.png -./gui/pixel_white.png -./gui/water.png -./gui/gun.png -./gui/button_delete.png -./gui/button_delete_hover.png -./gui/slot_armor_chest.png -./gui/pixel_black.png -./gui/slot_clothing_shirt.png -./gui/button_play.png -./gui/slot_armor_legs.png -./gui/inventory.png -./gui/selection_box.png -./gui/label.png -./gui/slot_clothing_pants.png -./gui/health_empty.png -./gui/hotbar_selected.png -./gui/health_full.png +./particle/smoke_trail.png +./particle/water.png +./particle/smoke_0.png +./particle/smoke_1.png +./particle/blood.png +./particle/lava.png +./particle/bullet.png +./particle/smoke_2.png +./particle/snow.png +./particle/rain.png +./particle/smoke_4.png +./particle/smoke_3.png +./particle/smoke_5.png ./gui/temperature.png -./gui/button_play_hover.png -./gui/slot_armor_helmet.png -./gui/slot_clothing_boots.png -./gui/hotbar.png -./gui/button_normal.png -./gui/shield.png +./gui/slot_armor_chest.png +./gui/health_empty.png ./gui/button_hover.png -./text/char_bslash.png -./text/char_dollar.png -./text/char_l_w.png -./text/char_u_d.png -./text/char_u_t.png -./text/char_space.png -./text/char_l_x.png -./text/char_l_k.png -./text/char_6.png -./text/char_unknown.png -./text/char_comma.png -./text/char_obracket.png -./text/char_u_w.png -./text/char_7.png -./text/char_l_f.png -./text/char_vertical.png -./text/char_plus.png -./text/char_u_a.png -./text/char_9.png -./text/char_u_k.png -./text/char_u_n.png -./text/char_percent.png -./text/char_u_m.png -./text/char_exclamation.png -./text/char_1.png -./text/char_l_q.png -./text/char_l_z.png -./text/char_l_h.png -./text/char_u_c.png -./text/char_l_g.png -./text/char_l_s.png -./text/char_fullstop.png -./text/char_u_j.png -./text/char_l_m.png -./text/char_l_t.png -./text/char_u_v.png -./text/char_colon.png -./text/char_l_i.png -./text/char_l_y.png -./text/char_u_l.png -./text/char_u_e.png -./text/char_5.png -./text/char_2.png -./text/char_3.png -./text/char_l_p.png -./text/char_fslash.png -./text/char_l_u.png -./text/char_u_f.png -./text/char_u_u.png -./text/char_l_e.png -./text/char_l_l.png -./text/char_u_g.png -./text/char_u_q.png -./text/char_u_b.png -./text/char_l_o.png -./text/char_minus.png -./text/char_l_v.png -./text/char_lthan.png -./text/char_u_s.png -./text/char_equals.png -./text/char_8.png -./text/char_underscore.png -./text/char_u_x.png -./text/char_0.png -./text/char_l_d.png -./text/char_l_c.png -./text/char_l_j.png -./text/char_u_z.png -./text/char_u_h.png -./text/char_hashtag.png -./text/char_gthan.png -./text/char_cbracket.png -./text/char_u_i.png -./text/char_question.png -./text/char_u_o.png -./text/char_u_y.png -./text/char_l_r.png -./text/char_l_b.png -./text/char_l_a.png -./text/char_l_n.png -./text/char_u_p.png -./text/char_u_r.png -./text/char_4.png -./entity/armored_zombie_back_moving.png -./entity/zombie_front_still.png -./entity/tnt.png +./gui/water.png +./gui/slot_armor_legs.png +./gui/selection_box_big.png +./gui/button_normal.png +./gui/label.png +./gui/hotbar.png +./gui/slot_armor_helmet.png +./gui/button_delete.png +./gui/text_cursor.png +./gui/inventory.png +./gui/button_delete_hover.png +./gui/button_play_hover.png +./gui/health_full.png +./gui/hotbar_selected.png +./gui/slot_clothing_shirt.png +./gui/pixel_white.png +./gui/pixel_black.png +./gui/slot_clothing_pants.png +./gui/text_box.png +./gui/shield.png +./gui/slot_clothing_boots.png +./gui/selection_box_wide.png +./gui/gun.png +./gui/button_play.png +./tile/cactus4.png +./tile/hemp1.png +./tile/dirt.png +./tile/lantern.png +./tile/hemp8.png +./tile/wall.png +./tile/cactus_top.png +./tile/cactus2.png +./tile/rock.png +./tile/water.png +./tile/hemp4.png +./tile/stone.png +./tile/tree_leaves.png +./tile/sapling2.png +./tile/ladder_up.png +./tile/sapling3.png +./tile/lava_flow.png +./tile/ice_wall.png +./tile/grass.png +./tile/chest.png +./tile/sapling4.png +./tile/lava.png +./tile/tall_grass.png +./tile/hemp5.png +./tile/sapling1.png +./tile/snow.png +./tile/sandstone_wall.png +./tile/rock_sandstone.png +./tile/hemp6.png +./tile/cactus1.png +./tile/tree_branch_leaves.png +./tile/tunnel_down.png +./tile/tree_branch_leaves_snow.png +./tile/tree_leaves_snow.png +./tile/rock_ice.png +./tile/boss_portal.png +./tile/ladder.png +./tile/hemp7.png +./tile/grass_infested.png +./tile/tree_branch.png +./tile/sand.png +./tile/tree_base.png +./tile/cactus3.png +./tile/sandstone.png +./tile/hemp3.png +./tile/hemp2.png +./tile/ice.png ./entity/flare.png -./entity/boss1/boss_walking.png +./entity/grappling_hook.png +./entity/zombie_back_moving.png +./entity/tnt.png +./entity/armored_zombie_back_moving.png +./entity/armored_zombie_front_moving.png +./entity/player/hair_side.png +./entity/player/head_top.png +./entity/player/head_side.png +./entity/player/head_back.png +./entity/player/head_bottom.png +./entity/player/hair_front.png +./entity/player/head_front.png +./entity/player/hair_back.png +./entity/player/hair_top.png +./entity/dummy.png +./entity/armored_zombie_front_still.png +./entity/armored_zombie_back_still.png +./entity/zombie_front_moving.png +./entity/boss1/boss_walking_firing.png ./entity/boss1/boss_firing.png ./entity/boss1/boss_still.png -./entity/boss1/boss_walking_firing.png -./entity/armored_zombie_back_still.png -./entity/armored_zombie_front_moving.png -./entity/player/head_back.png -./entity/player/hair_top.png -./entity/player/head_front.png -./entity/player/head_top.png -./entity/player/hair_side.png -./entity/player/head_side.png -./entity/player/hair_back.png -./entity/player/hair_front.png -./entity/player/head_bottom.png -./entity/grappling_hook.png +./entity/boss1/boss_walking.png ./entity/zombie_back_still.png -./entity/dummy.png -./entity/zombie_back_moving.png -./entity/armored_zombie_front_still.png -./entity/zombie_front_moving.png -./particle/smoke_1.png -./particle/water.png -./particle/rain.png -./particle/blood.png -./particle/snow.png -./particle/smoke_3.png -./particle/smoke_4.png -./particle/smoke_2.png -./particle/smoke_0.png -./particle/bullet.png -./particle/lava.png -./particle/smoke_trail.png -./particle/smoke_5.png +./entity/zombie_front_still.png +./item/acorn.png +./item/grappling_hook.png +./item/gun_upgrade.png +./item/shield_upgrade.png +./item/rock.png +./item/log.png +./item/log_snow.png +./item/hemp_seed.png +./item/ammo_box.png +./item/plant_fibre.png +./item/health_potion.png +./item/snow_pile.png +./item/flint.png +./item/sandstone.png diff --git a/src/resources/texture/text/char_and.png b/src/resources/texture/text/char_and.png new file mode 100644 index 0000000000000000000000000000000000000000..06a34e6684900c2cb3fc7478c56f0cf1525edca4 GIT binary patch literal 2107 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!s-uUCaclmsP~D-;yvr)B1( zDwI?fq$;FVWTr7NRNPt{9=So(|9Cote!Kn4_WKs?91T%b zmt|(NKfYg|`R`!+33p)&&ohQmHBNjpxzv)*tG|y=Km6~ibhYoj6KDT6D14ImyVKY8 zy7-Bo9}jJ9U!DKd?F(n8)-IFPPW#K$e12`7IN|cd-3z)tSxlaxYCAjXWsk3TUhtRK zm&0ncBfme36c7q{)e|}|qvHA7f4s+;>i4nUZ;AiJ`Ff4lk%WZ$NG6ASGVj?g*fD=$ zdy<`YZ*l$kdyW3CPyfkI3p70Rn_^PuX5|lLyKQ?H=myKc+R>O z4wuDMQ%uFJUd!sNX}I(L`l47ZGl1d)q$BCGE;BtiHeJd$!+(;_?VDzEd)B zKR+4mul{i=^;r(LQu@kj z=>D!#?;b|ieSWjC&v4#~0=3dmhK>#9hb5jLZ0J3=x%-^jq9-y1A_5@^mOmXtc`VXi z8BA*WKG8>M;a2l|o_Xt4mw9;i++k6=;eKRV!$PJ_P6+Xrere_JK9h^d{;^f>QZ0-pXu3(*Jo0dMlS@5xecAlP zPd&!IGb^XfHckC{_$yPkU*zJmSE8opT~jdCjMcj1rM}04Iax$T!oQo*!bJDnnjHce zhTAPR&lC{xF_j-xJ=s?~$A)|IzKfVY*mpeX}L=E4xqMIJ0Z7 z?%XD69k|0_tK3C%+Z@5*6-v*2{Q6kFA8q64VzSP2P@JZllazk4@O=8qx}dG8>$hLe zNa(r$*(zv;?X6dbgG45JlyW^{sImKe=|-ttG;c`7_M>uLDKfUQTej4ht=QS?w)y>2 zg~00y_wRD6*p%>}zA0m=bgTc?RTEC(idTVe&%1pV@VU~`?9|7gTVej~?F)@%U*9lp z`17bzUh%;GAA5`rd2L;lbtbef^8O1utvN+)?}PH>tX_T{ z-JOwLr(fRLl>5Ss?;!8icR9Bm+3xsM7H+TU=w7Lwy6NzRo*Q>&N1T2(>(9*{t8N#v zGACTpI4Xa5Q}NDKJ71jS>y?yzD#N#TQPXZOfwsTs>8rcn@f>sjgmdKqlPj^i|K#)lQxJlvUYx+}?BN ztnKdE5C6}0_p2*ndun&+yvng;Cw1wov-(agcD(uFHveKtTQ}RwViUbhT4!5D&8}CR zKEs`NWtYsP!!GkHZT7AEpR_1-@j_nRkiGV_*3~M zZ1K^BCs!WqO4zVALy2cyie1|mgBN}+%)H8(iw#c9TDZ@;`NY&sFG_?|c|I=Al)n~! ztEYd>v#r5doVklCinq(3eQdw@S$ERuyBiji=Dq94ULD>%v7mY=4kw7FIO$TvI&m_HdsXph!$Sa z5?Sc9LNuz>VCNU^SrU^(#N7{WeemFT($#}UBg5Il9R>a{6c&{Pl}r@+KV2m1NJYV& z{_^i~Mk9ZFa9gEQ=};LzzM^C-i!&c_CMtRyt}65*Hi5|QRTwdM;7vj z9V)~#uE{?CeWP%ey2A&_9hYwZ>t!?e>shsT?a}^*eYp=F?OLl@ec&md!H1L+%ief7 z&T`twv1k58^QVpfq8FrJeZ6*T|7CUs@7SgJ4b9F8OI&Vd+r5AH?#-zuwKGXTmZ8_r|Ei+dkA$vVzzQ?4~ zN)O(7we4}{U&|`q&zCoM!K~WX4wJWNs0RruO)O!b*wL%9oJsfKF2|*{x>{HN*S9bp Yi#FhkW6kGhU|?YIboFyt=akR{0B^k5RR910 literal 0 HcmV?d00001 diff --git a/src/resources/texture/text/char_apostrophe.png b/src/resources/texture/text/char_apostrophe.png new file mode 100644 index 0000000000000000000000000000000000000000..a6260163d6f656968b1910d5ebb434cb23597b5c GIT binary patch literal 3037 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 MPgg&ebxsLQ0FKF-k^lez literal 0 HcmV?d00001 diff --git a/src/resources/texture/text/char_at.png b/src/resources/texture/text/char_at.png new file mode 100644 index 0000000000000000000000000000000000000000..eabb3e56d4676dc802abb9517d20e37c50693406 GIT binary patch literal 2170 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 literal 0 HcmV?d00001 diff --git a/src/resources/texture/text/char_csbracket.png b/src/resources/texture/text/char_csbracket.png new file mode 100644 index 0000000000000000000000000000000000000000..74b1381c964b1f198661cc485647d37789034fc5 GIT binary patch literal 3011 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 literal 0 HcmV?d00001 diff --git a/src/resources/texture/text/char_grave.png b/src/resources/texture/text/char_grave.png new file mode 100644 index 0000000000000000000000000000000000000000..da039f326f8e858cb4108fb33fcedade44c2ac3e GIT binary patch literal 2438 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!uT{i;GDN`ey06$*;-(=u~X z6-p`#QWa7wGSe6sDsHWfh@5m(gYVCCky;iNvqG6`9Xk)o>=zcOTeq}&m+~^1^T#B( zHG^lL?)m>OeU|-)<9gALohQvm-tyz~&2&A94%_<5`6qwXUX!k7kAHUdbA#d2g3{+^ zqOtJ?@^<=nY**CHHDBZ(5prSb8m7CqW*WZ8S2aAJK5q}#smDA?)4qgl{j}38c1P&N z`QFiAlvD1`{@&v6u#$aE(V4>&H~)Uq&-U&QR~=`1S>f7ZzU22u-mqU+Vfb`(54*!} zwinzd%2W0&{@=5&@x1HvyXHEJlUfe0=hyhd_pj~8){WIBkJj`5IQ)Ts!t*yq&n>Qr z$~R_&^ly5$X!E^;hqzAMt z99_>h3$HuVdv~7jbc_^ctj^Wt!?S}1bbFXRW%AM2LzGv=h6^qWgRHQw3_iGPf+izEvK96IY+2~{VheNr~B;`q-@!+J@$ymx)YYhDoF=xH`+BR$!nM_5I8+ACn^18VSoC|yrQkC z>$iW;TF`U*vDKvcwzppW5fYi`QOfa%p~mj;3h?ZBm)H-yED@+5E@qn}+^- zu2s!nKN|*|6X;`{z3W!W%F?a*mKiIb=_LJFAX6-Sr^(@6q-gQh->mu37g;5k3d3G7 zFK{=Qx&Fre)zW%0*0bBy7aYowbZ~H=Ft4vsLwJS3CPSx!8)4_WT^}WjRkdxd@cFh_ z%P8mc-1%}rcgh5V*=|f)m*f)Q?Jc`%+n;BK`{U1=9o~QD#k!c)Y$bZ^my~p6Z%p8t z^C~iCN!8yMk1xE{$?13-a7Ft9gY12|sSC6E;|2FM{Hi&yPFb&i!YUW*gWf-HUH=gD zbI%lyy}c=wf=XY0T>NsjtTb<A8%VQqdy_BIkzUy(X&hHtkImw z&O27xTCdod-__n5*WS9DO_wV?tXA;d@#lM|JZ-z3bmdm0Pp7_*{QQOQCrZ`r+SgX0 zoU+;JnLz8@0K;|r=FPg^Arn@$J0v1isK_F2J%ht+Q-pRTBW?*99q`rcgj)v zvWx5DdhM0Z{}dQM>Uwrm$|5^3)%RO_ z@WPx=Hyn2-osa+5_&idvpn3Ljjr6m{GVTE{CRT3q^f15Y{VgqB^ZBMpH!r?E=l{q2 z`bCxbz84<7Dsj6Twq?oIC48MC*G+CP9`a8AKFR%(=uWemz~qa2gxmL#ZR&u%t_k6uaQf5OTq+A z?cZyk-d&t~QCE6HURRdm#QcXIW0I zTYV#I&9?W_A;zuZOD)^89hR-zdn7??XX;t!sYzT?a+0}sH!rU|sy@r=>6+i2^B!Dt z__Ww^?Qv$t*QF9~vmW(bcVXV=`8UO-=7E-n@X`+#o?bVhuis6H8K{p8a-u7 zeSTTIHpu&A|LO*XuQ@4ikN)lr*`|DNo2wkl{mi$`pB&zHeq(tX7Eyg>+J*iT*76UN ze|J{a_^z1zVD{pRx-+EvmQFl7zs=`+yQT2mKl2$FXC<`Mi`z3WFt%hmI|q0=JHu*L z1_q6ZwG(YU4m-#kjlb;Ws>N3};gP@wt4IOS!Yf)L3!PSoMwJ@u{K7p;Vv>ls`@yXb z9vn})dhlpuID5FGz#oRfqLQGJi9-LUi$oo%D7e#K{#~y8J;TDl)LEiZ%qDluj8`t1 zae95n!|)bCXAb9%lV^<5R5f|;e=O~1h<`6+bNc_C`HRDKBX~GEju@XY$bD4$Xr=G% z2YdWwQd1*U?bPK=Up5`-j|sP_dmK{~`Cw+C@$8w(eL~$!`NFJbO!e)pm}Ido%jzk& zWq;_o=s8=ndbhqi884yv;EssT0C>&#EBDA#2;KX;c`2uae#%vxs3ncm6V(N85kHCJYD@< J);T3K0RU9!gi8Pb literal 0 HcmV?d00001 diff --git a/src/resources/texture/text/char_ocbracket.png b/src/resources/texture/text/char_ocbracket.png new file mode 100644 index 0000000000000000000000000000000000000000..4f6f96ae8e19b9f26bc3b944176e3fd15e780ea3 GIT binary patch literal 3040 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 literal 0 HcmV?d00001 diff --git a/src/resources/texture/text/char_pow.png b/src/resources/texture/text/char_pow.png new file mode 100644 index 0000000000000000000000000000000000000000..80e90d37cded2ad0707a309f2cd548840bed2c71 GIT binary patch literal 2074 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 R85kHCJYD@<);T3K0RXVOrq%!e literal 0 HcmV?d00001 diff --git a/src/resources/texture/text/char_star.png b/src/resources/texture/text/char_star.png new file mode 100644 index 0000000000000000000000000000000000000000..f88a1892aaa441f787117f623515d2bd41da0b83 GIT binary patch literal 2145 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!uTM5{s~N`ey06$*;-(=u~X z6-p`#QWa7wGSe6sDsHU}kDT;IgXhn4kz$q!0;dZjl<)CA`!TuU&8oQg@Z(b!^Bhy? z^wGW1Q~%%RGk=}SMJav5R+*-w=hNq}Trl~~&!@HJ*WT~8yRrIn+MPT49L_z{&L`_w z?N5l2zg+GKRBlBN)Qv~Ez9|SSDyRFAMSsG<&Qcl!`z!357)dEZP;`39`Ax$wimo7 z!q4w<|Nm|;^Zc&9&(=E4NiFA=>(8m-``7lv)9}97#oOYlw|*pA|C+yfx#jVju^$;b z*uH9H>y=!S@>$a`=liAx?MM1Aj@PEfoD{q5;J5v3Sj^c}_k>ib=dtBSea*{m$251& zV`~&v$~sc5)414&_fNyo(w&|Yjm!NWtiNdR;EeIzZ9CSQ=hvQ9&3MNbeA02o;Ys@X zpYNUy*E3F!7O|)LKzgA@)`~M4mR-i9c4{d-qc%sz_4)v)9FszP=g09D-L^n zI@9R0#KqhEn#=a*lL8i)_S|7nYGF>&Zd}N;X^;31|1X?&AuUI{JtkR(iDPu>{D6<-K8q0aK_KJ`8!22 zZBFL1$h>P)uJT{!USpZsYZjaxwnR5favxM_#sUEO023+4M#cFo?+UTpv9tj90G{4eIu&MbQOKjB=%uKqo>hoa(3 z*X17b6Vdb0RsN-Rcv=cq=#x2`7XuF!Z?tPr()W`J;7H})mXdxl@q7A9o0YdVJ-@x$ z)S#_=f8UFA{%xD$o0x=FmO08aoL?S4YloiuRfpE{>KTd}y~@j*r(NrBnsqzFCgKvX7k7U+@y!$t3m^l*L~97wWv5iCU&0o$2GBjnuQ(qJJtmK&p7+L@%^nEvt%No zN;Zp3e_SbYyFkj4#r(>y#oL;BcFg?r=-tPOF&(yAlV#h|jywxXT03L)=iOzY+aGhW z9XJxmC4YER@y=B{EhfuK85^CtDN`6w5YBnXXz9)^nNgJ!pX*0$uGBw1Z|12-b0c_n zuKj#+Y27Zx>Fy7nw70eixV}6w?`oZxt9|y_xieo%ZD0V`+nA}ah&A+ z^M!lxVsmQ;PRX_Gcioq}=2T6z|6Jbm^Td?Q&Xh0w=-UFsD4$6 zdOx|1RaxYiDA$RK>DOx?-Q3U1DYMWBVczE= z^Y2gc&iR~rrPlH$Jm^i4<+6ljOTuM^`ksd>eG*q`E0D9kx!_sp6s6uvZPoT7=`vPX z=F7#{Ql@LK?7#LbxM=3hI8(+tEsL$Mf91?Se5yt~e1lO;*d;#xuJV~KR{KsrVTwMz zs+McvgeN~TMDv)BbL#3G`XLpNeory9t1aYdrrj|S{+*XP?q|AeIrHejl5Y_$2PBW| zJ0EzEK|amb;)AbDK%an2Qv~-jj&rJOoeQ2WSXy($=b$Dp^UoD47#*QR#wOt+RvpE}IX@Gnv2)(93 z_iIJFRAS&9lh4Om9tTw&*<E?54ZVPRnEEKwT;$pn~wCy zgxl0Tjwy0Gm(YB1 z+B;^sWrv8^1`bXokt+d?qGm!{UM-0@aiQ+garxrELOVr@LJyoU?B~sx5NrQK{?EH> zT7Es%o)c9re0^jgf7qcyJmZ?|^WQfLXQ?}UklbgTJ0td)FTAZ`han;L)zN zn$-uM@)>+cIkD`Gm*Xs_jU0RCUo?N(_%C`v`qkHKxAtFVSMZKqn%~guoUp{@X13k? zckkZ3y>GnsUmZida?$+oJ$Dlr7#P@+yxm9v?zCI0;M7b9yL@+Sio}v9=&fM8s85kHC NJYD@<);T3K0RRVq^y&Zr literal 0 HcmV?d00001 diff --git a/src/resources/texture/text/char_tilde.png b/src/resources/texture/text/char_tilde.png new file mode 100644 index 0000000000000000000000000000000000000000..29cb68164426ca0b0299de33a58d61b73afa7724 GIT binary patch literal 2394 zcmeAS@N?(olHy`uVBq!ia0y~yU=RRd4mJh`2Kmqb6B!uTMXEv~N`ey06$*;-(=u~X z6-p`#QWa7wGSe6sDsHWf$epC4&iCiMW(|u#{3DA;+DZ8vj+ZknT9tn9M%}#|D_`i% zTIO(SO3*9A$NT@!e8&H0;`tP(GjqJW#OfEeI5jce{v7^o_vXa?ui2~FQDOGGES5OIVrr>Vp z?7TPC#k^{4Qd0`mvz~mHQRe0{HDD9F{!}eBzUDj6Gbvu?Uro!8i)}xz`+Ltb3H9>! zrB61@Jgi(_IdlK-PxoWe&TUgDnkK&{L456rR>|(2U;9E8j`%*+&1-nS^vmu3AC4=U z4(>=yv(VT!PdBS1Kj-J!&Bu3j{65K*UUZ$8LGWCk!Ldq%gvp;Ts-_zUmho8_aR^2D z*#)pN>$$x$m^4AM(?@MtsoA`fdFz*YbY3&r!s+5Ne?l}*8%s*7fS|plL6XO!e#K)m zlKOIzIw#d|X)c>m6s4qo^ZA5iKg;xUs@&ClGM0sD&khBxsK`jrS^4D9QV~I;re>CE z&THIhTA}gIy{1=Vc23jceR$caTX*Z79aGij?s`9=b6(ZEJKobDo@of`F?i&m%rBRE z!ex!G{ox+tvo@8}H2Jenz0$wFKjExq_LiAZuRk4@O7lHe&b|GKir%>c60GdUJ|{6S z`gR+i)?mFI|^=%uh_uXRZ4;U;gMD9HANKdTt6n-h5+%LtuxV*@6iv{$|^Py>30$ zyz9Rz>|0g!d$wagY}YBb-<-VGZcVRHOGvu{-+}4I)5K!?pRZ`-djD<9aW|WDcCuTx z)bXuY+UvIY{Zoa&>kjYdvC7=r+unP0PG!m#`K_xnWz;@|gung%`^iGTTV~Zf>GvGs zkIPLJjSbA*kZ8yENm9w+L2&r|HQBL$qZzfX&T(y#c=9;UEy7|#b=cCNw{;3P)OImA zEBJBMvV8GS`z-pq`upMIkJGt3SVCs(Wf!<0Sa$xn;}p&iiF*=?mN~1RJ3jofqjlax z9l6PeR&?=1?)+?=Aim%E$O(q%JEhWTSAteLpM5r8>Dlw$H}hKf&38?IeYN3ik%DO6 z&jW0lAF`JJc=D=uvH61AkvAsX4m8oaz%ciQ+|-0D|9HWD4Q)jS)+w*;c(BT)`k3?6 zU)MiO*u$T?{Nl3;S3#pMM=tW5E#uAG#^_Y+Q~O5W!++~4@ z^;%4LzQN^Q8a`Dqf4ouE=#&b(;2GpT;qbbITRDQq z{25a>M|YgCVUOO@_E?jB*UXRCb{zIPTX6{ z>v(zU2Q&K{SucKz-tGA{PMEwoyPxkv`YyR1BkzjhQ`%22vz}nT zpDH`oKGRg=jIXpb=hc-?JCe4#-1=4|=l`ZNb?uF$V_9vFTR-_mg}CT$da>&E)K!-h zC#`bY>9p_gg&s3`uMZrJ#Vh_V&HD0K+@b35w^cuWv9~a_9LNi{HruFq%lgg3UeWI_ zOoJBhRu9hoc4}cu?}D4hVy>R}@$t`s9(nVl^*2uM;(oQfr9bRUsoN>(vp+lD`6den zF8X-gJ;Www$KMr`mp9LTv9J55@b0`iwnc}!CNnTFwq!ax2Y5O=!|F!{291fe6Ky>X zJIEZ3zwG6z#aA}rk-!G4NCDBpD_SB8omPlOl^X2)!aYl3l8Ctb!L1J-98bD>@MvT> zd$^;(ABMuBlAw}_LjR|WL>;LpxYJ+$U9S8+!@|JSS)x+RCU?z@S1y@xdVR;k@D@R5 z4(E=OXN=NRHF@uUEbV8Ae=lTn`v0Bzi^FvzcsM$a7@sl7eN_5rrSI(rd;DcmQzKRF z)a6WHHXZ4Y3Ad?x98(neU}m84?3v1aLfuRG!mMUY_3f>gWU(&G>M6Hnf9SdBIa{-O zx4t_WFQNJ3w0F#M%MKB-4IG?GB3A+&Ma_h^yjl`*;zHe}yAi3kx?SH*&27f)P_O3nJ z->@(D!J}PkHLDLi{6qQp9IkP@WvIU<%apJ@YCl5h8@kJGk@(S0h7dON)Fz^aXuxS5NFJWL{ OVDNPHb6Mw<&;$UYS!*=_ literal 0 HcmV?d00001 diff --git a/worker.jar b/worker.jar index fbd14901355c6ac5b4d446cec515db3445171f71..8e0d67696fc25674bf86b6e271c2ca1309f08380 100644 GIT binary patch delta 45901 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 aq)!klkWFU=N4GPBGlPl{1H+w9AR_@_L~c_6